summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2006-09-20 17:39:14 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2006-09-20 17:39:14 +0000
commitd43fabf399cf2f1c5d2def9ef76ba807397e2aca (patch)
tree5891e69ba9b72fc3ec31def172e6d6f51e5cf999
parent367f0cae6d60c10dfd168eeb68b7abd1b095f10c (diff)
remote name request cleanup
-rw-r--r--hcid/dbus-adapter.c24
-rw-r--r--hcid/dbus.c196
2 files changed, 108 insertions, 112 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index 2d51b22e..fb9da371 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -207,10 +207,7 @@ static int cancel_remote_name(struct hci_dbus_data *pdata)
{
struct discovered_dev_info *dev, match;
struct slist *l;
- struct hci_request rq;
- remote_name_req_cancel_cp cp;
int dd, err = 0;
- uint8_t status;
/* find the pending remote name request */
memset(&match, 0, sizeof(struct discovered_dev_info));
@@ -227,28 +224,11 @@ static int cancel_remote_name(struct hci_dbus_data *pdata)
dev = l->data;
- bacpy(&cp.bdaddr, &dev->bdaddr);
-
- rq.ogf = OGF_LINK_CTL;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
- rq.event = EVT_CMD_COMPLETE;
- rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL;
- rq.cparam = &cp;
- rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;
-
- if (hci_send_req(dd, &rq, 100) < 0) {
- error("Sending command failed: %s (%d)", strerror(errno), errno);
+ if (hci_read_remote_name_cancel(dd, &dev->bdaddr, 100) < 0) {
+ error("Remote name cancel failed: %s(%d)", strerror(errno), errno);
err = -errno;
- goto failed;
}
- if (status) {
- error("Cancel failed with status 0x%02x", status);
- err = -bt_error(status);
- }
-failed:
-
/* free discovered devices list */
slist_foreach(pdata->disc_devices, (slist_func_t) free, NULL);
slist_free(pdata->disc_devices);
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 55fbdf4a..aadb1206 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -411,7 +411,7 @@ static void reply_pending_requests(const char *path, struct hci_dbus_data *pdata
}
if (pdata->pdisc_active) {
- /* Send periodic discovery signal */
+ /* Send periodic discovery stopped signal exit or stop the device */
message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
"PeriodicDiscoveryStopped");
send_reply_and_unref(connection, message);
@@ -2146,60 +2146,94 @@ void discover_devices_req_exit(const char *name, struct hci_dbus_data *pdata)
cancel_discovery(pdata);
}
-int cancel_discovery(struct hci_dbus_data *pdata)
+static int inquiry_cancel(int dd, int to)
{
- struct discovered_dev_info *dev, match;
- struct slist *l;
struct hci_request rq;
- remote_name_req_cancel_cp cp;
- int dd, err = 0;
uint8_t status;
- if (!pdata->disc_active)
- goto cleanup;
+ 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;
- dd = hci_open_dev(pdata->dev_id);
- if (dd < 0) {
- err = -ENODEV;
- goto cleanup;
+ 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));
- rq.ogf = OGF_LINK_CTL;
+ 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;
- /* find the pending remote name request */
- memset(&match, 0, sizeof(struct discovered_dev_info));
- bacpy(&match.bdaddr, BDADDR_ANY);
- match.name_status = NAME_REQUESTED;
+ if (hci_send_req(dd, &rq, to) < 0)
+ return -1;
- l = slist_find(pdata->disc_devices, &match, (cmp_func_t) disc_device_find);
+ if (status) {
+ errno = bt_error(status);
+ return -1;
+ }
- if (l) {
- dev = l->data;
+ return 0;
+}
- bacpy(&cp.bdaddr, &dev->bdaddr);
+int cancel_discovery(struct hci_dbus_data *pdata)
+{
+ struct discovered_dev_info *dev, match;
+ struct slist *l;
+ int dd, err = 0;
- rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL;
- rq.cparam = &cp;
- rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;
- } else
- rq.ocf = OCF_INQUIRY_CANCEL;
+ if (!pdata->disc_active)
+ goto cleanup;
- if (hci_send_req(dd, &rq, 100) < 0) {
- error("Sending command failed: %s (%d)", strerror(errno), errno);
- err = -errno;
- hci_close_dev(dd);
+ dd = hci_open_dev(pdata->dev_id);
+ if (dd < 0) {
+ err = -ENODEV;
goto cleanup;
}
- if (status) {
- error("Cancel failed with status 0x%02x", status);
- err = -bt_error(status);
+ /*
+ * If there is a pending read remote name request means
+ * that the inquiry complete event was already received
+ */
+ memset(&match, 0, sizeof(struct discovered_dev_info));
+ bacpy(&match.bdaddr, BDADDR_ANY);
+ match.name_status = NAME_REQUESTED;
+
+ l = slist_find(pdata->disc_devices, &match, (cmp_func_t) disc_device_find);
+ if (l) {
+ dev = l->data;
+ if (remote_name_cancel(dd, &dev->bdaddr, 100) < 0) {
+ error("Read remote name cancel failed: %s, (%d)", strerror(errno), errno);
+ err = -errno;
+ }
+ } else {
+ if (inquiry_cancel(dd, 100) < 0) {
+ error("Inquiry cancel failed:%s (%d)", strerror(errno), errno);
+ err = -errno;
+ }
}
hci_close_dev(dd);
@@ -2224,94 +2258,76 @@ void periodic_discover_req_exit(const char *name, struct hci_dbus_data *pdata)
* Cleanup the discovered devices list and send the cmd to exit from periodic inquiry
* or cancel remote name request. The return value can be ignored.
*/
+
cancel_periodic_discovery(pdata);
+}
- if (pdata->pdiscovery_requestor) {
- free(pdata->pdiscovery_requestor);
- pdata->pdiscovery_requestor = NULL;
+static 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;
}
- pdata->pdisc_active = 0;
+ return 0;
}
int cancel_periodic_discovery(struct hci_dbus_data *pdata)
{
struct discovered_dev_info *dev, match;
struct slist *l;
- struct hci_request rq;
- remote_name_req_cancel_cp cp;
int dd, err = 0;
- uint8_t status = 0x00;
+ if (!pdata->pdisc_active)
+ goto cleanup;
+
dd = hci_open_dev(pdata->dev_id);
if (dd < 0) {
err = -ENODEV;
goto cleanup;
}
-
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_EXIT_PERIODIC_INQUIRY;
- rq.cparam = 0;
- rq.clen = 0;
- rq.rparam = &status;
- rq.rlen = sizeof(status);
- rq.event = EVT_CMD_COMPLETE;
-
- if (hci_send_req(dd, &rq, 100) < 0) {
- error("Sending command failed: %s (%d)", strerror(errno), errno);
- err = -errno;
- goto cleanup;
- }
-
- if (status) {
- error("exit periodic inquiry failed with status 0x%02x", status);
- err = -bt_error(status);
- goto cleanup;
- }
-
/* find the pending remote name request */
memset(&match, 0, sizeof(struct discovered_dev_info));
bacpy(&match.bdaddr, BDADDR_ANY);
match.name_status = NAME_REQUESTED;
l = slist_find(pdata->disc_devices, &match, (cmp_func_t) disc_device_find);
- if (!l)
- goto cleanup; /* no request pending */
-
- dev = l->data;
-
- memset(&rq, 0, sizeof(rq));
- memset(&cp, 0, sizeof(cp));
-
- bacpy(&cp.bdaddr, &dev->bdaddr);
-
- 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, 100) < 0) {
- error("Sending command failed: %s (%d)", strerror(errno), errno);
- err = -errno;
- goto cleanup;
+ if (l) {
+ dev = l->data;
+ if (remote_name_cancel(dd, &dev->bdaddr, 100) < 0) {
+ error("Read remote name cancel failed: %s, (%d)", strerror(errno), errno);
+ err = -errno;
+ }
}
- if (status) {
- error("Remote name cancel failed with status 0x%02x", status);
- err = -bt_error(status);
- goto cleanup;
+ /* ovewrite err if necessary: stop periodic inquiry has higher priority */
+ if (periodic_inquiry_exit(dd, 100) < 0) {
+ error("Periodic Inquiry exit failed:%s (%d)", strerror(errno), errno);
+ err = -errno;
}
+ hci_close_dev(dd);
cleanup:
+ /*
+ * Reset pdiscovery_requestor and pdisc_active is done when the
+ * cmd complete event for exit periodic inquiry mode cmd arrives.
+ */
slist_foreach(pdata->disc_devices, (slist_func_t) free, NULL);
slist_free(pdata->disc_devices);
pdata->disc_devices = NULL;
- hci_close_dev(dd);
-
return err;
}