summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2006-03-23 21:03:31 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2006-03-23 21:03:31 +0000
commit923976d833265decd9a3dd2b3aa7fca7c843c93a (patch)
tree38bf2e1fb11fe3b8389c3670f068ab6940c32f36 /hcid
parentb7fb0f9b9054c138a82e0843a8c82f550c6922eb (diff)
Removed create bonding queue, disconnect after the bonding finishes and code cleanup
Diffstat (limited to 'hcid')
-rw-r--r--hcid/dbus-adapter.c251
-rw-r--r--hcid/dbus.c189
-rw-r--r--hcid/dbus.h31
3 files changed, 217 insertions, 254 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index e3484c88..ad1d12c1 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -112,35 +112,21 @@ static int check_address(const char *addr)
return 0;
}
-int active_conn_find_by_bdaddr(const void *data, const void *user_data)
+static struct bonding_request_info *bonding_request_new(bdaddr_t *peer)
{
- const struct active_conn_info *con = data;
- const bdaddr_t *bdaddr = user_data;
-
- if (memcmp(con->bdaddr, bdaddr, sizeof(*bdaddr)) == 0)
- return 0;
-
- return -1;
-}
-
-static int bonding_requests_append(struct slist **list, bdaddr_t *bdaddr, DBusMessage *msg, int disconnect)
-{
- struct bonding_request_info *dev;
-
- dev = malloc(sizeof(*dev));
+ struct bonding_request_info *bonding;
+
+ bonding = malloc(sizeof(*bonding));
- if (!dev)
- return -1;
+ if (!bonding)
+ return NULL;
- memset(dev, 0, sizeof(*dev));
- dev->bdaddr = malloc(sizeof(*dev->bdaddr));
- bacpy(dev->bdaddr, bdaddr);
- dev->req_msg = msg;
- dev->disconnect = disconnect;
+ memset(bonding, 0, sizeof(*bonding));
- *list = slist_append(*list, dev);
+ bonding->bdaddr = malloc(sizeof(*bonding->bdaddr));
+ bacpy(bonding->bdaddr, peer);
- return 0;
+ return bonding;
}
static DBusHandlerResult handle_dev_get_address_req(DBusConnection *conn, DBusMessage *msg, void *data)
@@ -974,9 +960,14 @@ static DBusHandlerResult handle_dev_get_remote_name_req(DBusConnection *conn, DB
str2ba(peer_addr, &peer_bdaddr);
disc_device_append(&dbus_data->disc_devices, &peer_bdaddr, NAME_PENDING);
- /* check if there is a discover process running */
- if (dbus_data->discover_state == DISCOVER_OFF)
- disc_device_req_name(dbus_data);
+ /*
+ * if there is a discover process running, just queue the request.
+ * Otherwise, send the HCI cmd to get the remote name
+ */
+ if (dbus_data->discover_state == STATE_IDLE) {
+ if (!disc_device_req_name(dbus_data))
+ dbus_data->discover_state = STATE_RESOLVING_NAMES;
+ }
return error_request_deferred(conn, msg);
}
@@ -1232,8 +1223,7 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
char *peer_addr = NULL;
char *str;
struct hci_dbus_data *dbus_data = data;
- struct slist *lbon;
- struct slist *lconn;
+ struct slist *l;
bdaddr_t peer_bdaddr;
int dd, ecode, disconnect;
@@ -1254,12 +1244,11 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
str2ba(peer_addr, &peer_bdaddr);
/* check if there is a pending bonding request */
- lbon = slist_find(dbus_data->bonding_requests, &peer_bdaddr, bonding_requests_find);
-
- if (lbon)
+ if (dbus_data->bonding)
return error_bonding_in_progress(conn, msg);
- if (dbus_data->requestor_name)
+ /* check if there is a pending discover */
+ if (dbus_data->discover_state != STATE_IDLE || dbus_data->requestor_name)
return error_discover_in_progress(conn, msg);
ecode = get_device_address(dbus_data->dev_id, local_addr, sizeof(local_addr));
@@ -1296,9 +1285,9 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
rq.rlen = EVT_CMD_STATUS_SIZE;
/* check if there is an active connection */
- lconn = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);
+ l = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);
- if (!lconn) {
+ if (!l) {
memset(&cc_cp, 0, sizeof(cc_cp));
/* create a new connection */
bacpy(&cc_cp.bdaddr, &peer_bdaddr);
@@ -1312,12 +1301,11 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
rq.clen = CREATE_CONN_CP_SIZE;
disconnect = 1;
} else {
- struct active_conn_info *dev = lconn->data;
+ struct active_conn_info *dev = l->data;
+
memset(&ar_cp, 0, sizeof(ar_cp));
- /* active connection found */
ar_cp.handle = dev->handle;
-
rq.ocf = OCF_AUTH_REQUESTED;
rq.cparam = &ar_cp;
rq.clen = AUTH_REQUESTED_CP_SIZE;
@@ -1337,9 +1325,11 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
return error_failed(conn, msg, bt_error(rp.status));
}
- /* add in the bonding requests list */
- bonding_requests_append(&dbus_data->bonding_requests, &peer_bdaddr,
- dbus_message_ref(msg), disconnect);
+ dbus_data->bonding = bonding_request_new(&peer_bdaddr);
+ dbus_data->bonding->disconnect = disconnect;
+ dbus_data->bonding->rq = dbus_message_ref(msg);
+
+ dbus_data->requestor_name = strdup(dbus_message_get_sender(msg));
hci_close_dev(dd);
@@ -1349,14 +1339,8 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu
static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
- struct bonding_request_info *dev;
- struct slist *lconn;
- struct slist *lbon;
+ struct slist *l;
DBusMessage *reply = NULL;
- struct hci_request rq;
- create_conn_cancel_cp cc_cp;
- disconnect_cp dc_cp;
- evt_cmd_status rp;
DBusError err;
bdaddr_t peer_bdaddr;
const char *peer_addr;
@@ -1376,43 +1360,60 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu
if (check_address(peer_addr) < 0)
return error_invalid_arguments(conn, msg);
- /* FIXME: check authorization */
-
str2ba(peer_addr, &peer_bdaddr);
/* check if there is a pending bonding request */
- lbon = slist_find(dbus_data->bonding_requests, &peer_bdaddr, bonding_requests_find);
-
- if (!lbon) {
+ if ((!dbus_data->bonding) ||
+ (memcmp(dbus_data->bonding->bdaddr, &peer_bdaddr, sizeof(bdaddr_t)))) {
error("No bonding request pending.");
return error_unknown_address(conn, msg);
}
- lconn = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);
-
- dev = lbon->data;
+ if (strcmp(dbus_data->requestor_name, dbus_message_get_sender(msg)))
+ return error_not_authorized(conn, msg);
dd = hci_open_dev(dbus_data->dev_id);
if (dd < 0)
return error_no_such_adapter(conn, msg);
- memset(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.rparam = &rp;
- rq.rlen = EVT_CMD_STATUS_SIZE;
- rq.event = EVT_CMD_STATUS;
+ l = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);
- if (!lconn) {
+ if (!l) {
/* connection request is pending */
- memset(&cc_cp, 0, sizeof(cc_cp));
- bacpy(&cc_cp.bdaddr, dev->bdaddr);
- rq.ocf = OCF_CREATE_CONN_CANCEL;
- rq.cparam = &cc_cp;
- rq.clen = CREATE_CONN_CANCEL_CP_SIZE;
+ struct hci_request rq;
+ create_conn_cancel_cp cp;
+ evt_cmd_status rp;
- dev->cancel_msg = dbus_message_ref(msg);
+ memset(&rq, 0, sizeof(rq));
+ memset(&cp, 0, sizeof(cp));
+ memset(&rp, 0, sizeof(rp));
+
+ bacpy(&cp.bdaddr, dbus_data->bonding->bdaddr);
+
+ rq.ogf = OGF_LINK_CTL;
+ rq.ocf = OCF_CREATE_CONN_CANCEL;
+ rq.rparam = &rp;
+ rq.rlen = EVT_CMD_STATUS_SIZE;
+ rq.event = EVT_CMD_STATUS;
+ rq.cparam = &cp;
+ rq.clen = CREATE_CONN_CANCEL_CP_SIZE;
+
+ if (hci_send_req(dd, &rq, 100) < 0) {
+ error("Cancel bonding - unable to send the HCI request: %s (%d)",
+ strerror(errno), errno);
+ hci_close_dev(dd);
+ return error_failed(conn, msg, errno);
+ }
+
+ if (rp.status) {
+ error("Cancel bonding - Failed with status 0x%02x", rp.status);
+ hci_close_dev(dd);
+ return error_failed(conn, msg, bt_error(rp.status));
+ }
+
+ dbus_data->bonding->cancel = dbus_message_ref(msg);
} else {
- struct active_conn_info *cinfo = lconn->data;
+ struct active_conn_info *cinfo = l->data;
/* FIXME: if waiting remote PIN, which HCI cmd must be sent? */
/* reply to cancel bonding */
@@ -1420,36 +1421,16 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu
send_reply_and_unref(conn, reply);
/* Reply to the create bonding request */
- error_authentication_canceled(conn, dev->req_msg);
-
- dbus_data->bonding_requests = slist_remove(dbus_data->bonding_requests, dev);
- bonding_request_info_free(dev, NULL);
+ error_authentication_canceled(conn, dbus_data->bonding->rq);
/* disconnect from the remote device */
+ if (dbus_data->bonding->disconnect) {
+ if (hci_disconnect(dd, htobs(cinfo->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0)
+ error("Disconnect failed");
+ }
- /* FIXME: send the disconnect if the connection was created by a create
- * bonding procedure only. Otherwise, keep the connection active.
- */
- memset(&dc_cp, 0, sizeof(dc_cp));
- dc_cp.handle = cinfo->handle;
- dc_cp.reason = 0x05;
- rq.ocf = OCF_DISCONNECT;
- rq.cparam = &dc_cp;
- rq.clen = DISCONNECT_CP_SIZE;
- }
-
- if (hci_send_req(dd, &rq, 100) < 0) {
-
- error("Cancel bonding - unable to send the HCI request: %s (%d)",
- strerror(errno), errno);
- hci_close_dev(dd);
- return error_failed(conn, msg, errno);
- }
-
- if (rp.status) {
- error("Cancel bonding - Failed with status 0x%02x", rp.status);
- hci_close_dev(dd);
- return error_failed(conn, msg, bt_error(rp.status));
+ bonding_request_free(dbus_data->bonding);
+ dbus_data->bonding = NULL;
}
hci_close_dev(dd);
@@ -1459,13 +1440,13 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu
static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBusMessage *msg, void *data)
{
struct hci_dbus_data *dbus_data = data;
+ struct slist *l;
DBusConnection *connection = get_dbus_connection();
DBusMessage *reply;
DBusMessage *signal;
DBusError err;
char filename[PATH_MAX + 1];
char addr[18], *addr_ptr;
- struct hci_conn_info_req *cr;
bdaddr_t bdaddr;
int dd;
@@ -1500,29 +1481,16 @@ static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBu
/* Delete the link key from the Bluetooth chip */
hci_delete_stored_link_key(dd, &bdaddr, 0, 1000);
- /* Close active connections for the remote device */
- cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info));
- if (!cr) {
- error("Can't allocate memory");
- hci_close_dev(dd);
- return error_out_of_memory(conn, msg);
- }
-
- bacpy(&cr->bdaddr, &bdaddr);
- cr->type = ACL_LINK;
- if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) {
- /* Ignore when there isn't active connections, return success */
- hci_close_dev(dd);
- free(cr);
- return send_reply_and_unref(conn, dbus_message_new_method_return(msg));
- }
-
- /* Send the HCI disconnect command */
- if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0) {
- error("Disconnect failed");
- free(cr);
- hci_close_dev(dd);
- return error_failed(conn, msg, errno);
+ /* find the connection */
+ l = slist_find(dbus_data->active_conn, &bdaddr, active_conn_find_by_bdaddr);
+ if (l) {
+ struct active_conn_info *con = l->data;
+ /* Send the HCI disconnect command */
+ if (hci_disconnect(dd, htobs(con->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0) {
+ error("Disconnect failed");
+ hci_close_dev(dd);
+ return error_failed(conn, msg, errno);
+ }
}
/* FIXME: which condition must be verified before send the signal */
@@ -1537,8 +1505,6 @@ static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBu
reply = dbus_message_new_method_return(msg);
- free(cr);
-
hci_close_dev(dd);
return send_reply_and_unref(conn, reply);
@@ -1715,7 +1681,6 @@ static DBusHandlerResult handle_dev_get_encryption_key_size_req(DBusConnection *
static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, DBusMessage *msg, void *data)
{
DBusMessage *reply = NULL;
- const char *requestor_name;
const char *method;
inquiry_cp cp;
evt_cmd_status rp;
@@ -1725,15 +1690,12 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D
uint32_t lap = 0x9e8b33;
int dd;
- if (dbus_data->requestor_name)
+ if (dbus_data->discover_state != STATE_IDLE)
return error_discover_in_progress(conn, msg);
- method = dbus_message_get_member(msg);
- if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0)
- dbus_data->discover_state = DISCOVER_RUNNING;
- else
- dbus_data->discover_state = DISCOVER_RUNNING_WITH_NAMES;
-
+ if (dbus_data->bonding)
+ return error_bonding_in_progress(conn, msg);
+
dd = hci_open_dev(dbus_data->dev_id);
if (dd < 0)
return error_no_such_adapter(conn, msg);
@@ -1757,7 +1719,6 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D
if (hci_send_req(dd, &rq, 100) < 0) {
error("Unable to start inquiry: %s (%d)",
strerror(errno), errno);
- dbus_data->discover_state = DISCOVER_OFF;
hci_close_dev(dd);
return error_failed(conn, msg, errno);
}
@@ -1768,8 +1729,13 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D
return error_failed(conn, msg, bt_error(rp.status));
}
- requestor_name = dbus_message_get_sender(msg);
- dbus_data->requestor_name = strdup(requestor_name);
+ method = dbus_message_get_member(msg);
+ if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0)
+ dbus_data->discover_type = WITHOUT_NAME_RESOLVING;
+ else
+ dbus_data->discover_type = RESOLVE_NAMES;
+
+ dbus_data->requestor_name = strdup(dbus_message_get_sender(msg));
reply = dbus_message_new_method_return(msg);
@@ -1792,8 +1758,9 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D
requestor_name = dbus_message_get_sender(msg);
/* is there discover pending? */
- if (!dbus_data->requestor_name)
- return error_not_authorized(conn, msg);
+ if (dbus_data->discover_state != STATE_DISCOVER &&
+ dbus_data->discover_state != STATE_RESOLVING_NAMES)
+ return error_not_authorized(conn, msg); /* FIXME: find a better error name */
/* only the discover requestor can cancel the inquiry process */
if (strcmp(dbus_data->requestor_name, requestor_name))
@@ -1810,9 +1777,7 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D
rq.rlen = sizeof(status);
switch (dbus_data->discover_state) {
- case DISCOVER_OFF:
- goto failed;
- case RESOLVING_NAMES:
+ case STATE_RESOLVING_NAMES:
/* get the first element */
dev = (struct discovered_dev_info *) (dbus_data->disc_devices)->data;
@@ -1823,8 +1788,7 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D
rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;
rq.event = EVT_CMD_STATUS;
break;
- case DISCOVER_RUNNING:
- case DISCOVER_RUNNING_WITH_NAMES:
+ default: /* STATE_DISCOVER */
rq.ocf = OCF_INQUIRY_CANCEL;
break;
}
@@ -1843,13 +1807,14 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D
return error_failed(conn, msg, bt_error(status));
}
-failed:
slist_foreach(dbus_data->disc_devices, disc_device_info_free, NULL);
slist_free(dbus_data->disc_devices);
dbus_data->disc_devices = NULL;
- free(dbus_data->requestor_name);
- dbus_data->requestor_name = NULL;
+ if (dbus_data->requestor_name) {
+ free(dbus_data->requestor_name);
+ dbus_data->requestor_name = NULL;
+ }
reply = dbus_message_new_method_return(msg);
diff --git a/hcid/dbus.c b/hcid/dbus.c
index b9525ae1..f58697e2 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -108,16 +108,14 @@ void disc_device_info_free(void *data, void *user_data)
}
}
-void bonding_request_info_free(void *data, void *user_data)
+void bonding_request_free(struct bonding_request_info *dev )
{
- struct bonding_request_info *dev = data;
-
if (dev) {
free(dev->bdaddr);
- if (dev->req_msg)
- dbus_message_unref(dev->req_msg);
- if (dev->cancel_msg)
- dbus_message_unref(dev->cancel_msg);
+ if (dev->rq)
+ dbus_message_unref(dev->rq);
+ if (dev->cancel)
+ dbus_message_unref(dev->cancel);
free(dev);
}
}
@@ -132,18 +130,7 @@ static void active_conn_info_free(void *data, void *user_data)
}
}
-int bonding_requests_find(const void *data, const void *user_data)
-{
- const struct bonding_request_info *dev = data;
- const bdaddr_t *bdaddr = user_data;
-
- if (memcmp(dev->bdaddr, bdaddr, sizeof(*bdaddr)) == 0)
- return 0;
-
- return -1;
-}
-
-int disc_device_find_by_bdaddr(const void *data, const void *user_data)
+static int disc_device_find_by_bdaddr(const void *data, const void *user_data)
{
const struct discovered_dev_info *dev = data;
const bdaddr_t *bdaddr = user_data;
@@ -212,6 +199,17 @@ static int disc_device_remove(struct slist **list, bdaddr_t *bdaddr)
return ret_val;
}
+int active_conn_find_by_bdaddr(const void *data, const void *user_data)
+{
+ const struct active_conn_info *con = data;
+ const bdaddr_t *bdaddr = user_data;
+
+ if (memcmp(con->bdaddr, bdaddr, sizeof(*bdaddr)) == 0)
+ return 0;
+
+ return -1;
+}
+
static int active_conn_find_by_handle(const void *data, const void *user_data)
{
const struct active_conn_info *dev = data;
@@ -442,10 +440,9 @@ static gboolean unregister_dbus_path(const char *path)
pdata->disc_devices = NULL;
}
- if (pdata->bonding_requests) {
- slist_foreach(pdata->bonding_requests, bonding_request_info_free, NULL);
- slist_free(pdata->bonding_requests);
- pdata->bonding_requests = NULL;
+ if (pdata->bonding) {
+ bonding_request_free(pdata->bonding);
+ pdata->bonding = NULL;
}
if (pdata->active_conn) {
@@ -632,8 +629,6 @@ void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const u
struct hci_dbus_data *pdata;
DBusMessage *msg_reply = NULL;
DBusMessage *msg_signal = NULL;
- struct bonding_request_info *dev = NULL;
- struct slist *l;
char *local_addr, *peer_addr;
const char *name;
bdaddr_t tmp;
@@ -681,23 +676,36 @@ void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const u
goto failed;
}
- l = slist_find(pdata->bonding_requests, peer, bonding_requests_find);
-
- if (!l)
- goto failed;
-
- dev = l->data;
+ if (!pdata->bonding)
+ goto failed; /* skip: no bonding req pending */
- msg_reply = dbus_msg_new_authentication_return(dev->req_msg, status);
+ msg_reply = dbus_msg_new_authentication_return(pdata->bonding->rq, status);
if (dbus_connection_send(connection, msg_reply, NULL) == FALSE) {
error("Can't send D-Bus reply for create bonding request");
goto failed;
}
/* FIXME: disconnect if required */
+ if (pdata->bonding->disconnect) {
+ struct slist *l;
+
+ l = slist_find(pdata->active_conn, peer, active_conn_find_by_bdaddr);
+ if (l) {
+ struct active_conn_info *con = l->data;
+ int dd = hci_open_dev(pdata->dev_id);
+ /* Send the HCI disconnect command */
+ if (hci_disconnect(dd, con->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) {
+ error("Disconnect failed");
+ }
+ hci_close_dev(dd);
+ }
+ }
+
+ bonding_request_free(pdata->bonding);
+ pdata->bonding = NULL;
- pdata->bonding_requests = slist_remove(pdata->bonding_requests, dev);
- bonding_request_info_free(dev, NULL);
+ free(pdata->requestor_name);
+ pdata->requestor_name = NULL;
failed:
if (msg_signal)
@@ -720,10 +728,8 @@ void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr)
char path[MAX_PATH_LENGTH];
bdaddr_t tmp;
ret_param_conn_cancel *ret = ptr + sizeof(evt_cmd_complete);
- struct bonding_request_info *dev = NULL;
DBusMessage *reply;
char *local_addr, *peer_addr;
- struct slist *l;
struct hci_dbus_data *pdata;
int id;
@@ -742,24 +748,20 @@ void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr)
goto failed;
}
- l = slist_find(pdata->bonding_requests, &ret->bdaddr, bonding_requests_find);
-
- if (!l)
+ if (!pdata->bonding)
goto failed;
- dev = l->data;
-
+ if (memcmp(pdata->bonding->bdaddr, &ret->bdaddr, sizeof(bdaddr_t)))
+ goto failed;
+
if (!ret->status) {
- reply = dbus_message_new_method_return(dev->cancel_msg);
+ reply = dbus_message_new_method_return(pdata->bonding->cancel);
send_reply_and_unref(connection, reply);
} else
- error_failed(connection, dev->cancel_msg, bt_error(ret->status));
+ error_failed(connection, pdata->bonding->cancel, bt_error(ret->status));
- dbus_message_unref(dev->cancel_msg);
- dev->cancel_msg = NULL;
- /* Don't remove from the list. It will be necessary
- * to return the reply for create bonding request
- */
+ dbus_message_unref(pdata->bonding->cancel);
+ pdata->bonding->cancel = NULL;
failed:
bt_free(local_addr);
@@ -768,6 +770,7 @@ failed:
void hcid_dbus_inquiry_start(bdaddr_t *local)
{
+ struct hci_dbus_data *pdata;
DBusMessage *message = NULL;
char path[MAX_PATH_LENGTH];
char *local_addr;
@@ -784,6 +787,9 @@ void hcid_dbus_inquiry_start(bdaddr_t *local)
snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);
+ if (dbus_connection_get_object_path_data(connection, path, (void *) &pdata))
+ pdata->discover_state = STATE_DISCOVER;
+
message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
"DiscoveryStarted");
if (message == NULL) {
@@ -919,12 +925,14 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);
if (dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {
- if (!disc_device_req_name(pdata)) {
- pdata->discover_state = RESOLVING_NAMES;
- goto failed; /* skip - there is name to resolve */
- }
- pdata->discover_state = DISCOVER_OFF;
+ if (pdata->discover_type == RESOLVE_NAMES) {
+ if (!disc_device_req_name(pdata)) {
+ pdata->discover_state = STATE_RESOLVING_NAMES;
+ goto failed; /* skip - there is name to resolve */
+ }
+ }
+ pdata->discover_state = STATE_IDLE;
/* free discovered devices list */
slist_foreach(pdata->disc_devices, disc_device_info_free, NULL);
@@ -1063,26 +1071,13 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
free(name);
name_status = NAME_SENT;
-
- /*
- * Add in the discovered devices list to avoid
- * multiple remote name update signals
- */
- switch (pdata->discover_state) {
- case DISCOVER_RUNNING_WITH_NAMES:
- case DISCOVER_RUNNING:
- disc_device_append(&pdata->disc_devices, peer, name_status);
- break;
- default: /* ignore */
- break;
- }
+ }
+ /* queue only results triggered by D-Bus clients */
+ if (pdata->requestor_name)
+ disc_device_append(&pdata->disc_devices, peer, name_status);
- } else {
- /* check if the remote name needs be requested */
- if (pdata->discover_state == DISCOVER_RUNNING_WITH_NAMES)
- disc_device_append(&pdata->disc_devices, peer, name_status);
- }
+ disc_device_append(&pdata->disc_devices, peer, name_status);
failed:
if (signal_device)
@@ -1133,12 +1128,14 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char
if (!disc_device_req_name(pdata))
goto failed; /* skip if a new request has been sent */
+ pdata->discover_state = STATE_IDLE;
+
/* free discovered devices list */
slist_foreach(pdata->disc_devices, disc_device_info_free, NULL);
slist_free(pdata->disc_devices);
pdata->disc_devices = NULL;
- if (pdata->discover_state != DISCOVER_OFF) {
+ if (pdata->discover_type == RESOLVE_NAMES) {
message = dbus_message_new_signal(path, ADAPTER_INTERFACE,
"DiscoveryCompleted");
@@ -1148,8 +1145,6 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char
free(pdata->requestor_name);
pdata->requestor_name = NULL;
}
-
- pdata->discover_state = DISCOVER_OFF;
}
failed:
@@ -1165,8 +1160,6 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b
evt_cmd_status rp;
auth_requested_cp cp;
struct hci_dbus_data *pdata = NULL;
- const struct slist *l;
- struct bonding_request_info *dev = NULL;
char *local_addr, *peer_addr;
bdaddr_t tmp;
int dd = -1, id;
@@ -1177,14 +1170,14 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b
id = hci_devid(local_addr);
if (id < 0) {
error("No matching device id for %s", local_addr);
- goto failed;
+ goto done;
}
snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);
if (!dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {
error("Getting %s path data failed!", path);
- goto failed;
+ goto done;
}
if (!status) {
@@ -1202,21 +1195,21 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b
}
/* check if this connection request was requested by a bonding procedure */
- l = slist_find(pdata->bonding_requests, peer, bonding_requests_find);
- if (!l)
- goto failed;
+ if (!pdata->bonding)
+ goto done; /* skip */
- dev = l->data;
+ if (memcmp(pdata->bonding->bdaddr, peer, sizeof(bdaddr_t)))
+ goto done; /* skip */
if (status) {
- error_connection_attempt_failed(connection, dev->req_msg, bt_error(status));
- goto failed;
+ error_connection_attempt_failed(connection, pdata->bonding->rq, bt_error(status));
+ goto bonding_failed;
}
dd = hci_open_dev(pdata->dev_id);
if (dd < 0) {
- error_no_such_adapter(connection, dev->req_msg);
- goto failed;
+ error_no_such_adapter(connection, pdata->bonding->rq);
+ goto bonding_failed;
}
/* request authentication */
@@ -1237,22 +1230,24 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b
if (hci_send_req(dd, &rq, 100) < 0) {
error("Unable to send the HCI request: %s (%d)",
strerror(errno), errno);
- error_failed(connection, dev->req_msg, errno);
- goto failed;
+ error_failed(connection, pdata->bonding->rq, errno);
+ goto bonding_failed;
}
if (rp.status) {
error("Failed with status 0x%02x", rp.status);
- error_failed(connection, dev->req_msg, bt_error(rp.status));
- goto failed;
- }
- goto done;
-failed:
- /* remove from the list if the HCI pairing request was not sent */
- if (dev) {
- pdata->bonding_requests = slist_remove(pdata->bonding_requests, dev);
- bonding_request_info_free(dev, NULL);
+ error_failed(connection, pdata->bonding->rq, bt_error(rp.status));
+ goto bonding_failed;
}
+
+ goto done; /* skip: authentication requested */
+
+bonding_failed:
+ /* free bonding request if the HCI pairing request was not sent */
+ bonding_request_free(pdata->bonding);
+ pdata->bonding = NULL;
+ free(pdata->requestor_name);
+ pdata->requestor_name = NULL;
done:
hci_close_dev(dd);
diff --git a/hcid/dbus.h b/hcid/dbus.h
index c745fbee..da2d3af0 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -73,11 +73,14 @@ struct service_data {
typedef int (timeout_handler_func_t) (void *data);
typedef enum {
- DISCOVER_OFF,
- DISCOVER_RUNNING,
- DISCOVER_RUNNING_WITH_NAMES,
- RESOLVING_NAMES
-} discover_state_t;
+ STATE_IDLE,
+ STATE_DISCOVER,
+ STATE_RESOLVING_NAMES
+}discover_state_t;
+
+/* discover type */
+#define WITHOUT_NAME_RESOLVING 0
+#define RESOLVE_NAMES 1
typedef enum {
NAME_PENDING,
@@ -91,8 +94,8 @@ struct discovered_dev_info {
struct bonding_request_info {
bdaddr_t *bdaddr;
- DBusMessage *req_msg;
- DBusMessage *cancel_msg;
+ DBusMessage *rq;
+ DBusMessage *cancel;
int disconnect; /* disconnect after finish */
};
@@ -107,12 +110,13 @@ struct hci_dbus_data {
uint32_t discoverable_timeout;
uint32_t timeout_hits;
timeout_handler_func_t *timeout_handler;
- uint8_t mode; /* scan mode */
- discover_state_t discover_state;
+ uint8_t mode; /* scan mode */
+ discover_state_t discover_state; /* discover states */
+ int discover_type; /* with/without name resolving */
struct slist *disc_devices;
- char *requestor_name; /* requestor unique name */
+ char *requestor_name; /* requestor unique name */
struct slist *passkey_agents;
- struct slist *bonding_requests;
+ struct bonding_request_info *bonding;
struct slist *active_conn;
};
@@ -187,10 +191,9 @@ static inline DBusHandlerResult send_reply_and_unref(DBusConnection *conn, DBusM
return DBUS_HANDLER_RESULT_HANDLED;
}
+int active_conn_find_by_bdaddr(const void *data, const void *user_data);
+void bonding_request_free(struct bonding_request_info *dev);
void disc_device_info_free(void *data, void *user_data);
-void bonding_request_info_free(void *data, void *user_data);
-int bonding_requests_find(const void *data, const void *user_data);
-int disc_device_find_by_bdaddr(const void *data, const void *user_data);
int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status);
int disc_device_req_name(struct hci_dbus_data *dbus_data);