diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2019-12-26 14:01:06 -0800 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2020-03-02 14:42:32 -0800 |
commit | 45219190617b8609171f5e216f7357c629820dd8 (patch) | |
tree | d96f6203cd98627132cee2c259b40b4bb0750ca1 /src/gatt-client.c | |
parent | 76d63c91b27ab27e28267b6e5ff252252efd537f (diff) | |
download | bluez-45219190617b8609171f5e216f7357c629820dd8.tar.gz |
gatt: Enable EATT bearer support
This adds support for EATT connections.
Diffstat (limited to 'src/gatt-client.c')
-rw-r--r-- | src/gatt-client.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/gatt-client.c b/src/gatt-client.c index 6bcdecf09..fae6f43e6 100644 --- a/src/gatt-client.c +++ b/src/gatt-client.c @@ -35,9 +35,11 @@ #include "lib/uuid.h" #include "gdbus/gdbus.h" +#include "btio/btio.h" #include "log.h" #include "error.h" +#include "hcid.h" #include "adapter.h" #include "device.h" #include "src/shared/io.h" @@ -57,8 +59,11 @@ #define GATT_CHARACTERISTIC_IFACE "org.bluez.GattCharacteristic1" #define GATT_DESCRIPTOR_IFACE "org.bluez.GattDescriptor1" +#define EATT_MAX_BEARERS 2 + struct btd_gatt_client { struct btd_device *device; + uint8_t features; bool ready; char devaddr[18]; struct gatt_db *db; @@ -2154,6 +2159,55 @@ static void register_notify(void *data, void *user_data) notify_client_free(notify_client); } +static void eatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) +{ + struct btd_gatt_client *client = user_data; + + if (gerr) + return; + + device_attach_att(client->device, io); +} + +static void eatt_connect(struct btd_gatt_client *client) +{ + struct btd_device *dev = client->device; + struct btd_adapter *adapter = device_get_adapter(dev); + GIOChannel *io; + GError *gerr = NULL; + char addr[18]; + int i; + + ba2str(device_get_address(dev), addr); + + DBG("Connection attempt to: %s", addr); + + for (i = 0; i < EATT_MAX_BEARERS; i++) { + /* Fallback to regular LE mode */ + io = bt_io_connect(eatt_connect_cb, client, NULL, &gerr, + BT_IO_OPT_SOURCE_BDADDR, + btd_adapter_get_address(adapter), + BT_IO_OPT_SOURCE_TYPE, + btd_adapter_get_address_type(adapter), + BT_IO_OPT_DEST_BDADDR, + device_get_address(dev), + BT_IO_OPT_DEST_TYPE, + device_get_le_address_type(dev), + BT_IO_OPT_PSM, BT_ATT_EATT_PSM, + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, + BT_IO_OPT_MTU, main_opts.gatt_mtu, + BT_IO_OPT_INVALID); + if (!io) { + error("EATT bt_io_connect(%s): %s", addr, + gerr->message); + g_error_free(gerr); + return; + } + + g_io_channel_unref(io); + } +} + void btd_gatt_client_ready(struct btd_gatt_client *client) { if (!client) @@ -2175,6 +2229,15 @@ void btd_gatt_client_ready(struct btd_gatt_client *client) 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) @@ -2197,6 +2260,11 @@ 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, |