aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-02-24 00:13:21 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-24 00:46:57 +0200
commite2801dd6ad710fe3c470a44460a5d7f4eebd9858 (patch)
tree935e5b4eca5714a87b8ba2b83fd7fb19a0789fff /plugins
parent5a878d96f94a565a1675165a0d758f4f44fc5902 (diff)
downloadbluez-e2801dd6ad710fe3c470a44460a5d7f4eebd9858.tar.gz
bluez-e2801dd6ad710fe3c470a44460a5d7f4eebd9858.tar.xz
bluez-e2801dd6ad710fe3c470a44460a5d7f4eebd9858.zip
mgmtops: Add UUID queuing to avoid EBUSY errors
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mgmtops.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 84d9adcb..00dfd51b 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -52,6 +52,11 @@
#define MGMT_BUF_SIZE 1024
+struct pending_uuid {
+ uuid_t uuid;
+ uint8_t svc_hint;
+};
+
static int max_index = -1;
static struct controller_info {
gboolean valid;
@@ -64,6 +69,9 @@ static struct controller_info {
uint8_t dev_class[3];
GSList *connections;
uint8_t discov_type;
+
+ gboolean pending_uuid;
+ GSList *pending_uuids;
} *controllers = NULL;
static int mgmt_sock = -1;
@@ -826,11 +834,23 @@ static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_add_uuid)];
struct mgmt_hdr *hdr = (void *) buf;
struct mgmt_cp_add_uuid *cp = (void *) &buf[sizeof(*hdr)];
+ struct controller_info *info = &controllers[index];
uuid_t uuid128;
uint128_t uint128;
DBG("index %d", index);
+ if (info->pending_uuid) {
+ struct pending_uuid *pending = g_new0(struct pending_uuid, 1);
+
+ memcpy(&pending->uuid, uuid, sizeof(*uuid));
+ pending->svc_hint = svc_hint;
+
+ info->pending_uuids = g_slist_append(info->pending_uuids,
+ pending);
+ return 0;
+ }
+
uuid_to_uuid128(&uuid128, uuid);
memset(buf, 0, sizeof(buf));
@@ -846,6 +866,8 @@ static int mgmt_add_uuid(int index, uuid_t *uuid, uint8_t svc_hint)
if (write(mgmt_sock, buf, sizeof(buf)) < 0)
return -errno;
+ info->pending_uuid = TRUE;
+
return 0;
}
@@ -1147,6 +1169,34 @@ static void read_local_oob_data_failed(int sk, uint16_t index)
oob_read_local_data_complete(adapter, NULL, NULL);
}
+static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf,
+ size_t len)
+{
+ struct controller_info *info;
+ struct pending_uuid *pending;
+
+ DBG("add_uuid complete");
+
+ if (index > max_index) {
+ error("Unexpected index %u in add_uuid_complete event", index);
+ return;
+ }
+
+ info = &controllers[index];
+
+ info->pending_uuid = FALSE;
+
+ if (g_slist_length(info->pending_uuids) == 0)
+ return;
+
+ pending = info->pending_uuids->data;
+
+ mgmt_add_uuid(index, &pending->uuid, pending->svc_hint);
+
+ info->pending_uuids = g_slist_remove(info->pending_uuids, pending);
+ g_free(pending);
+}
+
static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
{
struct mgmt_ev_cmd_complete *ev = buf;
@@ -1192,7 +1242,7 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
DBG("set_le complete");
break;
case MGMT_OP_ADD_UUID:
- DBG("add_uuid complete");
+ mgmt_add_uuid_complete(sk, index, ev->data, len);
break;
case MGMT_OP_REMOVE_UUID:
DBG("remove_uuid complete");