Hi Marcel, Attaching a patch which adds start_inquiry functionality to the hciops plugin. I have made the following changes : * use hci_send_cmd instead of hci_send_req. * move the cmd_status callback from dbus-hci.c to adapter.c and call it adapter_start_inquiry_cb(). * hardcode the callback instead of passing a function pointer. If you are OK with this framework, i can start working on the periodic inquiry functionality. Let me know what you think. Cheers, Alok.
From 6276d589b01b24e8577b779fa124804e0d10b6d5 Mon Sep 17 00:00:00 2001 From: Alok Barsode <alok.barsode@xxxxxxxxxx> Date: Mon, 18 May 2009 19:59:40 +0530 Subject: [PATCH] Adding start_inquiry functionality to hciops plugin. --- lib/hci.c | 2 +- plugins/hciops.c | 24 +++++++++++++++ src/adapter.c | 85 ++++++++++++++++++++++++++++-------------------------- src/adapter.h | 3 +- src/dbus-hci.c | 29 ------------------ src/dbus-hci.h | 1 - src/security.c | 2 +- 7 files changed, 72 insertions(+), 74 deletions(-) diff --git a/lib/hci.c b/lib/hci.c index 6d25a8b..29ba319 100644 --- a/lib/hci.c +++ b/lib/hci.c @@ -981,7 +981,7 @@ int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) while (writev(dd, iv, ivn) < 0) { if (errno == EAGAIN || errno == EINTR) continue; - return -1; + return -errno; } return 0; } diff --git a/plugins/hciops.c b/plugins/hciops.c index 8f9ee06..239596b 100644 --- a/plugins/hciops.c +++ b/plugins/hciops.c @@ -561,6 +561,29 @@ done: return err; } +static int hciops_start_inquiry(int index) +{ + inquiry_cp cp; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + int dd, err = 0; + + dd = hci_open_dev(index); + if (dd < 0) + return dd; + + memset(&cp, 0, sizeof(cp)); + memcpy(&cp.lap, lap, 3); + cp.length = 0x08; + cp.num_rsp = 0x00; + + err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY, + INQUIRY_CP_SIZE, &cp); + + hci_close_dev(dd); + + return err; +} + static struct btd_adapter_ops hci_ops = { .setup = hciops_setup, .cleanup = hciops_cleanup, @@ -570,6 +593,7 @@ static struct btd_adapter_ops hci_ops = { .set_connectable = hciops_connectable, .set_discoverable = hciops_discoverable, .set_limited_discoverable = hciops_set_limited_discoverable, + .start_inquiry = hciops_start_inquiry, }; static int hciops_init(void) diff --git a/src/adapter.c b/src/adapter.c index 1c4bec5..1200ecd 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -945,55 +945,58 @@ struct btd_device *adapter_get_device(DBusConnection *conn, return adapter_create_device(conn, adapter, address); } -static int start_inquiry(struct btd_adapter *adapter) +void adapter_start_inquiry_cb(bdaddr_t *local, uint8_t status) { - inquiry_cp cp; - evt_cmd_status rp; - struct hci_request rq; - uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; - int dd, err; - - pending_remote_name_cancel(adapter); - - dd = hci_open_dev(adapter->dev_id); - if (dd < 0) - return dd; - - memset(&cp, 0, sizeof(cp)); - memcpy(&cp.lap, lap, 3); - cp.length = 0x08; - cp.num_rsp = 0x00; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_INQUIRY; - rq.cparam = &cp; - rq.clen = INQUIRY_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_CMD_STATUS_SIZE; - rq.event = EVT_CMD_STATUS; + struct btd_adapter *adapter; + int state; - if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) { - err = -errno; - error("Unable to start inquiry: %s (%d)", - strerror(errno), errno); - hci_close_dev(dd); - return err; + if (status) { + error("HCI_Inquiry command failed with status 0x%02x", + status); + return; } - if (rp.status) { - error("HCI_Inquiry command failed with status 0x%02x", - rp.status); - hci_close_dev(dd); - return -bt_error(rp.status); + adapter = manager_find_adapter(local); + if (!adapter) { + error("Unable to find matching adapter"); + return; } - hci_close_dev(dd); + state = adapter_get_state(adapter); + state |= STD_INQUIRY; + adapter_set_state(adapter, state); + /* + * Cancel pending remote name request and clean the device list + * when inquiry is supported in periodic inquiry idle state. + */ + if (adapter_get_state(adapter) & PERIODIC_INQUIRY) + pending_remote_name_cancel(adapter); + + /* Disable name resolution for non D-Bus clients */ + if (!adapter_has_discov_sessions(adapter)) { + state = adapter_get_state(adapter); + state &= ~RESOLVE_NAME; + adapter_set_state(adapter, state); + } if (main_opts.name_resolv) adapter->state |= RESOLVE_NAME; - return 0; +} + +static int adapter_start_inquiry(struct btd_adapter *adapter) +{ + int err; + + pending_remote_name_cancel(adapter); + + err = adapter_ops->start_inquiry(adapter->dev_id); + + if (err < 0) + error("Unable to start inquiry: %s (%d)", + strerror(-err), -err); + + return err; } static int start_periodic_inquiry(struct btd_adapter *adapter) @@ -1068,7 +1071,7 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn, goto done; if (main_opts.discov_interval) - err = start_inquiry(adapter); + err = adapter_start_inquiry(adapter); else err = start_periodic_inquiry(adapter); @@ -2443,7 +2446,7 @@ void adapter_set_state(struct btd_adapter *adapter, int state) else if (adapter->disc_sessions && main_opts.discov_interval) adapter->scheduler_id = g_timeout_add_seconds( main_opts.discov_interval, - (GSourceFunc) start_inquiry, + (GSourceFunc) adapter_start_inquiry, adapter); /* Send out of range */ diff --git a/src/adapter.h b/src/adapter.h index a94edc6..d3ae00f 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -145,7 +145,7 @@ const char *btd_adapter_any_request_path(void); void btd_adapter_any_release_path(void); gboolean adapter_is_pairable(struct btd_adapter *adapter); gboolean adapter_powering_down(struct btd_adapter *adapter); - +void adapter_start_inquiry_cb(bdaddr_t *local, uint8_t status); struct btd_adapter_ops { int (*setup) (void); @@ -157,6 +157,7 @@ struct btd_adapter_ops { int (*set_discoverable) (int index); int (*set_limited_discoverable) (int index, const uint8_t *cls, gboolean limited); + int (*start_inquiry) (int index); }; int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops); diff --git a/src/dbus-hci.c b/src/dbus-hci.c index 65ac12b..70fbbc6 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -434,35 +434,6 @@ void hcid_dbus_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, device_simple_pairing_complete(device, status); } -void hcid_dbus_inquiry_start(bdaddr_t *local) -{ - struct btd_adapter *adapter; - int state; - - adapter = manager_find_adapter(local); - if (!adapter) { - error("Unable to find matching adapter"); - return; - } - - state = adapter_get_state(adapter); - state |= STD_INQUIRY; - adapter_set_state(adapter, state); - /* - * Cancel pending remote name request and clean the device list - * when inquiry is supported in periodic inquiry idle state. - */ - if (adapter_get_state(adapter) & PERIODIC_INQUIRY) - pending_remote_name_cancel(adapter); - - /* Disable name resolution for non D-Bus clients */ - if (!adapter_has_discov_sessions(adapter)) { - state = adapter_get_state(adapter); - state &= ~RESOLVE_NAME; - adapter_set_state(adapter, state); - } -} - static int found_device_req_name(struct btd_adapter *adapter) { struct hci_request rq; diff --git a/src/dbus-hci.h b/src/dbus-hci.h index 1cb10f3..6dd9ab1 100644 --- a/src/dbus-hci.h +++ b/src/dbus-hci.h @@ -24,7 +24,6 @@ int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci); -void hcid_dbus_inquiry_start(bdaddr_t *local); void hcid_dbus_inquiry_complete(bdaddr_t *local); void hcid_dbus_periodic_inquiry_start(bdaddr_t *local, uint8_t status); void hcid_dbus_periodic_inquiry_exit(bdaddr_t *local, uint8_t status); diff --git a/src/security.c b/src/security.c index a61d75f..792a94c 100644 --- a/src/security.c +++ b/src/security.c @@ -550,7 +550,7 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) return; if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) - hcid_dbus_inquiry_start(sba); + adapter_start_inquiry_cb(sba, evt->status); } static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) -- 1.5.6.3