From ef77cc7a527b3703783617d0afc75a5aad135771 Mon Sep 17 00:00:00 2001 From: Anderson Lizardo Date: Tue, 28 Jan 2014 11:51:37 -0400 Subject: [PATCH] core: Fix associating a GAttrib to a device on incoming connections If BlueZ is running as slave, incoming connections using ATT CID will have a GAttrib created for them. But this GAttrib will not be assigned to the underlying device (whose struct btd_device instance was created in response to the Device Connected mgmt event). This patch fixes this by assigning the GAttrib to the btd_device as soon as a connection is first requested, which is done using attio callbacks. Note that a new GAttrib reference is taken because attio callbacks "own" device->attrib and thus need their own reference. --- src/attrib-server.c | 22 ++++++++++++++++++++++ src/attrib-server.h | 1 + src/device.c | 5 +++++ 3 files changed, 28 insertions(+) diff --git a/src/attrib-server.c b/src/attrib-server.c index 200a8a761..3f68fea06 100644 --- a/src/attrib-server.c +++ b/src/attrib-server.c @@ -1106,6 +1106,28 @@ done: g_attrib_send(channel->attrib, 0, opdu, length, NULL, NULL, NULL); } +GAttrib *attrib_from_device(struct btd_device *device) +{ + struct btd_adapter *adapter = device_get_adapter(device); + struct gatt_server *server; + GSList *l; + + l = g_slist_find_custom(servers, adapter, adapter_cmp); + if (!l) + return NULL; + + server = l->data; + + for (l = server->clients; l; l = l->next) { + struct gatt_channel *channel = l->data; + + if (channel->device == device) + return g_attrib_ref(channel->attrib); + } + + return NULL; +} + guint attrib_channel_attach(GAttrib *attrib) { struct gatt_server *server; diff --git a/src/attrib-server.h b/src/attrib-server.h index 90ba17c37..063cb6621 100644 --- a/src/attrib-server.h +++ b/src/attrib-server.h @@ -37,5 +37,6 @@ int attrib_gap_set(struct btd_adapter *adapter, uint16_t uuid, uint32_t attrib_create_sdp(struct btd_adapter *adapter, uint16_t handle, const char *name); void attrib_free_sdp(struct btd_adapter *adapter, uint32_t sdp_handle); +GAttrib *attrib_from_device(struct btd_device *device); guint attrib_channel_attach(GAttrib *attrib); gboolean attrib_channel_detach(GAttrib *attrib, guint id); diff --git a/src/device.c b/src/device.c index a52faea6f..127b2803a 100644 --- a/src/device.c +++ b/src/device.c @@ -4674,6 +4674,11 @@ guint btd_device_add_attio_callback(struct btd_device *device, device_set_auto_connect(device, TRUE); + /* Check if there is no GAttrib associated to the device created by a + * incoming connection */ + if (!device->attrib) + device->attrib = attrib_from_device(device); + if (device->attrib && cfunc) { device->attios_offline = g_slist_append(device->attios_offline, attio); -- 2.47.3