2009-05-22 11:24:12

by alok barsode

[permalink] [raw]
Subject: [PATCH 1/2] Adding start_discovery functionality to hciops plugin.

From: Alok Barsode <[email protected]>

---
plugins/hciops.c | 56 ++++++++++++++++++++++++++
src/adapter.c | 115 +++--------------------------------------------------
src/adapter.h | 1 +
3 files changed, 64 insertions(+), 108 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 8f9ee06..c4c084e 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -561,6 +561,61 @@ done:
return err;
}

+static int hciops_start_discovery(int index)
+{
+ struct btd_adapter *adapter;
+ inquiry_cp inq_cp;
+ periodic_inquiry_cp cp;
+ uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
+ int dd, err = 0;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return dd;
+
+ if (main_opts.discov_interval)
+ goto standard;
+
+ memset(&cp, 0, sizeof(cp));
+ memcpy(&cp.lap, lap, 3);
+ cp.max_period = htobs(24);
+ cp.min_period = htobs(16);
+ cp.length = 0x08;
+ cp.num_rsp = 0x00;
+
+ err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY,
+ PERIODIC_INQUIRY_CP_SIZE, &cp);
+
+ goto done;
+
+standard:
+
+ adapter = manager_find_adapter_by_id(index);
+ if (!adapter) {
+ error("Unable to find matching adapter");
+ hci_close_dev(dd);
+ return -EINVAL;
+ }
+
+ pending_remote_name_cancel(adapter);
+
+ memset(&inq_cp, 0, sizeof(inq_cp));
+ memcpy(&inq_cp.lap, lap, 3);
+ inq_cp.length = 0x08;
+ inq_cp.num_rsp = 0x00;
+
+ err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY,
+ INQUIRY_CP_SIZE, &inq_cp);
+
+done:
+ if (err < 0)
+ err = -errno;
+
+ hci_close_dev(dd);
+
+ return err;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
@@ -570,6 +625,7 @@ static struct btd_adapter_ops hci_ops = {
.set_connectable = hciops_connectable,
.set_discoverable = hciops_discoverable,
.set_limited_discoverable = hciops_set_limited_discoverable,
+ .start_discovery = hciops_start_discovery,
};

static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 25ec33a..1a9dd76 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -945,108 +945,6 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
return adapter_create_device(conn, adapter, address);
}

-static int start_inquiry(struct btd_adapter *adapter)
-{
- 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;
-
- 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 (rp.status) {
- error("HCI_Inquiry command failed with status 0x%02x",
- rp.status);
- hci_close_dev(dd);
- return -bt_error(rp.status);
- }
-
- hci_close_dev(dd);
-
- if (main_opts.name_resolv)
- adapter->state |= RESOLVE_NAME;
-
- return 0;
-}
-
-static int start_periodic_inquiry(struct btd_adapter *adapter)
-{
- periodic_inquiry_cp cp;
- struct hci_request rq;
- uint8_t lap[3] = { 0x33, 0x8b, 0x9e };
- uint8_t status;
- int dd, err;
-
- dd = hci_open_dev(adapter->dev_id);
- if (dd < 0)
- return dd;
-
- memset(&cp, 0, sizeof(cp));
- memcpy(&cp.lap, lap, 3);
- cp.max_period = htobs(24);
- cp.min_period = htobs(16);
- cp.length = 0x08;
- cp.num_rsp = 0x00;
-
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_PERIODIC_INQUIRY;
- rq.cparam = &cp;
- rq.clen = PERIODIC_INQUIRY_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
- rq.event = EVT_CMD_COMPLETE;
-
- if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) {
- err = -errno;
- error("Unable to start periodic inquiry: %s (%d)",
- strerror(errno), errno);
- hci_close_dev(dd);
- return err;
- }
-
- if (status) {
- error("HCI_Periodic_Inquiry_Mode failed with status 0x%02x",
- status);
- hci_close_dev(dd);
- return -bt_error(status);
- }
-
- hci_close_dev(dd);
-
- if (main_opts.name_resolv)
- adapter->state |= RESOLVE_NAME;
-
- return 0;
-}
-
static DBusMessage *adapter_start_discovery(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1067,10 +965,10 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
if (adapter->disc_sessions)
goto done;

- if (main_opts.discov_interval)
- err = start_inquiry(adapter);
- else
- err = start_periodic_inquiry(adapter);
+ if (main_opts.name_resolv)
+ adapter->state |= RESOLVE_NAME;
+
+ err = adapter_ops->start_discovery(adapter->dev_id);

if (err < 0)
return failed_strerror(msg, -err);
@@ -2432,6 +2330,7 @@ void adapter_set_state(struct btd_adapter *adapter, int state)
{
gboolean discov_active = FALSE;
const char *path = adapter->path;
+ int index = adapter->dev_id;

if (adapter->state == state)
return;
@@ -2441,8 +2340,8 @@ 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,
- adapter);
+ (GSourceFunc) adapter_ops->start_discovery,
+ (gpointer) index);

/* Send out of range */
if (!discov_active)
diff --git a/src/adapter.h b/src/adapter.h
index a94edc6..516b4ac 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -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_discovery) (int index);
};

int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops);
--
1.5.6.3


2009-05-22 11:24:13

by alok barsode

[permalink] [raw]
Subject: [PATCH 2/2] Adding stop_discovery functionality to hciops plugin.

From: Alok Barsode <[email protected]>

---
plugins/hciops.c | 60 +++++++++++++++++++++
src/adapter.c | 37 +++++++------
src/adapter.h | 1 +
src/dbus-hci.c | 153 ------------------------------------------------------
src/dbus-hci.h | 6 --
5 files changed, 82 insertions(+), 175 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index c4c084e..bcf7e6a 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -616,6 +616,65 @@ done:
return err;
}

+static int remote_name_cancel(int dd, bdaddr_t *dba)
+{
+ int err = 0;
+ remote_name_req_cancel_cp cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+ bacpy(&cp.bdaddr, dba);
+
+ err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL,
+ REMOTE_NAME_REQ_CANCEL_CP_SIZE, &cp);
+
+ if (err < 0)
+ err = -errno;
+
+ return err;
+}
+
+static int hciops_stop_discovery(int index)
+{
+ struct btd_adapter *adapter;
+ struct remote_dev_info *dev, match;
+ int dd, err = 0;
+ int state;
+
+ dd = hci_open_dev(index);
+ if (dd < 0)
+ return -ENODEV;
+
+ adapter = manager_find_adapter_by_id(index);
+ /*
+ * If there is a pending read remote name request means
+ * that the inquiry complete event was already received
+ */
+ memset(&match, 0, sizeof(struct remote_dev_info));
+ bacpy(&match.bdaddr, BDADDR_ANY);
+ match.name_status = NAME_REQUESTED;
+
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev)
+ err = remote_name_cancel(dd, &dev->bdaddr);
+ else {
+ state = adapter_get_state(adapter);
+ if (state & STD_INQUIRY)
+ err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_INQUIRY_CANCEL,
+ 0, 0);
+ else
+ err = hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY,
+ 0, 0);
+ }
+
+ hci_close_dev(dd);
+
+ if (err < 0)
+ err = -errno;
+
+ return err;
+}
+
static struct btd_adapter_ops hci_ops = {
.setup = hciops_setup,
.cleanup = hciops_cleanup,
@@ -626,6 +685,7 @@ static struct btd_adapter_ops hci_ops = {
.set_discoverable = hciops_discoverable,
.set_limited_discoverable = hciops_set_limited_discoverable,
.start_discovery = hciops_start_discovery,
+ .stop_discovery = hciops_stop_discovery,
};

static int hciops_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 1a9dd76..fcda99f 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -553,12 +553,10 @@ static void session_remove(struct session_req *req)
g_slist_free(adapter->oor_devices);
adapter->oor_devices = NULL;

- if (adapter->state & STD_INQUIRY)
- cancel_discovery(adapter);
- else if (adapter->scheduler_id)
+ if (adapter->scheduler_id)
g_source_remove(adapter->scheduler_id);
- else
- cancel_periodic_discovery(adapter);
+
+ adapter_ops->stop_discovery(adapter->dev_id);
}
}

@@ -2030,18 +2028,31 @@ setup:
hci_send_cmd(dd, OGF_LINK_POLICY, OCF_READ_DEFAULT_LINK_POLICY,
0, NULL);

+ hci_close_dev(dd);
+
if (hci_test_bit(HCI_INQUIRY, &di.flags)) {
debug("inquiry_cancel at adapter startup");
- inquiry_cancel(dd, HCI_REQ_TIMEOUT);
+ adapter->state |= STD_INQUIRY;
} else if (!adapter->initialized && adapter->already_up) {
debug("periodic_inquiry_exit at adapter startup");
- periodic_inquiry_exit(dd, HCI_REQ_TIMEOUT);
+ adapter->state |= PERIODIC_INQUIRY;
}

+ adapter_ops->stop_discovery(adapter->dev_id);
+
adapter->state &= ~STD_INQUIRY;
+ adapter->state &= ~PERIODIC_INQUIRY;
+
+ dd = hci_open_dev(adapter->dev_id);
+ if (dd < 0) {
+ err = -errno;
+ error("Can't open adapter %s: %s (%d)",
+ adapter->path, strerror(errno), errno);
+ return err;
+ }

adapter_setup(adapter, dd);
- hci_close_dev(dd);
+ hci_close_dev(dd);

err = adapter_up(adapter);

@@ -2066,16 +2077,10 @@ static void reply_pending_requests(struct btd_adapter *adapter)
HCI_OE_USER_ENDED_CONNECTION);
}

- if (adapter->state & STD_INQUIRY) {
+ if (adapter->state & STD_INQUIRY || adapter->state & PERIODIC_INQUIRY) {
/* Cancel inquiry initiated by D-Bus client */
if (adapter->disc_sessions)
- cancel_discovery(adapter);
- }
-
- if (adapter->state & PERIODIC_INQUIRY) {
- /* Stop periodic inquiry initiated by D-Bus client */
- if (adapter->disc_sessions)
- cancel_periodic_discovery(adapter);
+ adapter_ops->stop_discovery(adapter->dev_id);
}
}

diff --git a/src/adapter.h b/src/adapter.h
index 516b4ac..1312596 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -158,6 +158,7 @@ struct btd_adapter_ops {
int (*set_limited_discoverable) (int index, const uint8_t *cls,
gboolean limited);
int (*start_discovery) (int index);
+ int (*stop_discovery) (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..27dc77c 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -1221,159 +1221,6 @@ int hcid_dbus_set_io_cap(bdaddr_t *local, bdaddr_t *remote,
return 0;
}

-int inquiry_cancel(int dd, int to)
-{
- struct hci_request rq;
- uint8_t status;
-
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_INQUIRY_CANCEL;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
- rq.event = EVT_CMD_COMPLETE;
-
- if (hci_send_req(dd, &rq, to) < 0)
- return -1;
-
- if (status) {
- errno = bt_error(status);
- return -1;
- }
-
- return 0;
-}
-
-static int remote_name_cancel(int dd, bdaddr_t *dba, int to)
-{
- remote_name_req_cancel_cp cp;
- struct hci_request rq;
- uint8_t status;
-
- memset(&rq, 0, sizeof(rq));
- memset(&cp, 0, sizeof(cp));
-
- bacpy(&cp.bdaddr, dba);
-
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL;
- rq.cparam = &cp;
- rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
- rq.event = EVT_CMD_COMPLETE;
-
- if (hci_send_req(dd, &rq, to) < 0)
- return -1;
-
- if (status) {
- errno = bt_error(status);
- return -1;
- }
-
- return 0;
-}
-
-int cancel_discovery(struct btd_adapter *adapter)
-{
- struct remote_dev_info *dev, match;
- int dd, err = 0;
- uint16_t dev_id = adapter_get_dev_id(adapter);
-
- dd = hci_open_dev(dev_id);
- if (dd < 0)
- return -ENODEV;
-
- /*
- * If there is a pending read remote name request means
- * that the inquiry complete event was already received
- */
- memset(&match, 0, sizeof(struct remote_dev_info));
- bacpy(&match.bdaddr, BDADDR_ANY);
- match.name_status = NAME_REQUESTED;
-
- dev = adapter_search_found_devices(adapter, &match);
- if (dev) {
- if (remote_name_cancel(dd, &dev->bdaddr,
- HCI_REQ_TIMEOUT) < 0) {
- err = -errno;
- error("Read remote name cancel failed: %s, (%d)",
- strerror(errno), errno);
- }
- } else {
- if (inquiry_cancel(dd, HCI_REQ_TIMEOUT) < 0) {
- err = -errno;
- error("Inquiry cancel failed:%s (%d)",
- strerror(errno), errno);
- }
- }
-
- hci_close_dev(dd);
-
- return err;
-}
-
-int periodic_inquiry_exit(int dd, int to)
-{
- struct hci_request rq;
- uint8_t status;
-
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_EXIT_PERIODIC_INQUIRY;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
- rq.event = EVT_CMD_COMPLETE;
-
- if (hci_send_req(dd, &rq, to) < 0)
- return -1;
-
- if (status) {
- errno = status;
- return -1;
- }
-
- return 0;
-}
-
-int cancel_periodic_discovery(struct btd_adapter *adapter)
-{
- struct remote_dev_info *dev, match;
- int dd, err = 0;
- uint16_t dev_id = adapter_get_dev_id(adapter);
-
- dd = hci_open_dev(dev_id);
- if (dd < 0)
- return -ENODEV;
-
- /* find the pending remote name request */
- memset(&match, 0, sizeof(struct remote_dev_info));
- bacpy(&match.bdaddr, BDADDR_ANY);
- match.name_status = NAME_REQUESTED;
-
- dev = adapter_search_found_devices(adapter, &match);
- if (dev) {
- if (remote_name_cancel(dd, &dev->bdaddr,
- HCI_REQ_TIMEOUT) < 0) {
- err = -errno;
- error("Read remote name cancel failed: %s, (%d)",
- strerror(errno), errno);
- }
- }
-
- /* ovewrite err if necessary: stop periodic inquiry has higher
- * priority */
- if (periodic_inquiry_exit(dd, HCI_REQ_TIMEOUT) < 0) {
- err = -errno;
- error("Periodic Inquiry exit failed:%s (%d)",
- strerror(errno), errno);
- }
-
- hci_close_dev(dd);
-
- return err;
-}
-
/* Most of the functions in this module require easy access to a connection so
* we keep it global here and provide these access functions the other (few)
* modules that require access to it */
diff --git a/src/dbus-hci.h b/src/dbus-hci.h
index 1cb10f3..ec9ac97 100644
--- a/src/dbus-hci.h
+++ b/src/dbus-hci.h
@@ -52,15 +52,9 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,

DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status);

-int cancel_discovery(struct btd_adapter *adapter);
-int cancel_periodic_discovery(struct btd_adapter *adapter);
-
int set_service_classes(int dd, const uint8_t *cls, uint8_t value);
int set_major_and_minor_class(int dd, const uint8_t *cls,
uint8_t major, uint8_t minor);
-int inquiry_cancel(int dd, int to);
-int periodic_inquiry_exit(int dd, int to);
-
const char *class_to_icon(uint32_t class);

void set_dbus_connection(DBusConnection *conn);
--
1.5.6.3