diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2021-08-25 14:03:50 -0700 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2021-08-25 15:10:42 -0700 |
commit | cb85f71b0dfd508947d3756626cd1d44add38884 (patch) | |
tree | 425d7068f20354f0aa6021bb93074a2831005793 /src/gatt-client.c | |
parent | e6f2ce8a05a76538cadc8e7477f400fce03d095a (diff) | |
download | bluez-cb85f71b0dfd508947d3756626cd1d44add38884.tar.gz |
gatt: Do not always attempt to connect EATT immediately
Wait the bt_gatt_client becomes ready (has performed service discovery)
before attempting to connect EATT when acting as peripheral/acceptor
since the central/initiator might actually attempt to connect EATT
channels in the same way which can potentially cause a collisions.
Diffstat (limited to 'src/gatt-client.c')
-rw-r--r-- | src/gatt-client.c | 74 |
1 files changed, 36 insertions, 38 deletions
diff --git a/src/gatt-client.c b/src/gatt-client.c index bec6e1ec0..6bed77793 100644 --- a/src/gatt-client.c +++ b/src/gatt-client.c @@ -2156,6 +2156,38 @@ static void register_notify(void *data, void *user_data) notify_client_free(notify_client); } +void btd_gatt_client_ready(struct btd_gatt_client *client) +{ + if (!client) + return; + + if (!client->gatt) { + struct bt_gatt_client *gatt; + + gatt = btd_device_get_gatt_client(client->device); + client->gatt = bt_gatt_client_clone(gatt); + if (!client->gatt) { + error("GATT client not initialized"); + return; + } + } + + client->ready = true; + + DBG("GATT client ready"); + + create_services(client); + + DBG("Features 0x%02x", client->features); + + if (!client->features) { + client->features = bt_gatt_client_get_features(client->gatt); + DBG("Update Features 0x%02x", client->features); + if (client->features & BT_GATT_CHRC_CLI_FEAT_EATT) + btd_gatt_client_eatt_connect(client); + } +} + static void eatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) { struct btd_gatt_client *client = user_data; @@ -2166,7 +2198,7 @@ static void eatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) device_attach_att(client->device, io); } -static void eatt_connect(struct btd_gatt_client *client) +void btd_gatt_client_eatt_connect(struct btd_gatt_client *client) { struct bt_att *att = bt_gatt_client_get_att(client->gatt); struct btd_device *dev = client->device; @@ -2176,6 +2208,9 @@ static void eatt_connect(struct btd_gatt_client *client) char addr[18]; int i; + if (!(client->features & BT_GATT_CHRC_CLI_FEAT_EATT)) + return; + if (bt_att_get_channels(att) == btd_opts.gatt_channels) return; @@ -2232,38 +2267,6 @@ static void eatt_connect(struct btd_gatt_client *client) } } -void btd_gatt_client_ready(struct btd_gatt_client *client) -{ - if (!client) - return; - - if (!client->gatt) { - struct bt_gatt_client *gatt; - - gatt = btd_device_get_gatt_client(client->device); - client->gatt = bt_gatt_client_clone(gatt); - if (!client->gatt) { - error("GATT client not initialized"); - return; - } - } - - client->ready = true; - - DBG("GATT client ready"); - - create_services(client); - - DBG("Features 0x%02x", client->features); - - if (!client->features) { - client->features = bt_gatt_client_get_features(client->gatt); - DBG("Update Features 0x%02x", client->features); - if (client->features & BT_GATT_CHRC_CLI_FEAT_EATT) - eatt_connect(client); - } -} - void btd_gatt_client_connected(struct btd_gatt_client *client) { struct bt_gatt_client *gatt; @@ -2284,11 +2287,6 @@ void btd_gatt_client_connected(struct btd_gatt_client *client) * for any pre-registered notification sessions. */ queue_foreach(client->all_notify_clients, register_notify, client); - - if (!(client->features & BT_GATT_CHRC_CLI_FEAT_EATT)) - return; - - eatt_connect(client); } void btd_gatt_client_service_added(struct btd_gatt_client *client, |