core: Add support for setting the number of GATT bearers
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 7 Jan 2020 19:47:49 +0000 (11:47 -0800)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 12 Apr 2021 09:00:48 +0000 (14:30 +0530)
This adds option to set the numbers of GATT Channels/Bearers to be
connected in main.conf.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/device.c
src/gatt-client.c
src/gatt-database.c
src/hcid.h
src/main.c
src/main.conf

index 5ff3bef..e2d4139 100644 (file)
@@ -7350,6 +7350,11 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
        }
 
        if (dev->att) {
+               if (main_opts.gatt_channels == bt_att_get_channels(dev->att)) {
+                       DBG("EATT channel limit reached");
+                       return false;
+               }
+
                if (!bt_att_attach_fd(dev->att, g_io_channel_unix_get_fd(io))) {
                        DBG("EATT channel connected");
                        g_io_channel_set_close_on_unref(io, FALSE);
index 6dd7868..b55c1a9 100644 (file)
@@ -58,8 +58,6 @@
 #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;
@@ -2548,6 +2546,7 @@ static void eatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 
 static void eatt_connect(struct btd_gatt_client *client)
 {
+       struct bt_att *att = bt_gatt_client_get_att(client->gatt);
        struct btd_device *dev = client->device;
        struct btd_adapter *adapter = device_get_adapter(dev);
        GIOChannel *io;
@@ -2555,12 +2554,14 @@ static void eatt_connect(struct btd_gatt_client *client)
        char addr[18];
        int i;
 
+       if (bt_att_get_channels(att) == main_opts.gatt_channels)
+               return;
+
        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 */
+       for (i = bt_att_get_channels(att); i < main_opts.gatt_channels; i++) {
                io = bt_io_connect(eatt_connect_cb, client, NULL, &gerr,
                                        BT_IO_OPT_SOURCE_BDADDR,
                                        btd_adapter_get_address(adapter),
index d66d743..af50ce4 100644 (file)
@@ -1434,10 +1434,13 @@ static void populate_gatt_service(struct btd_gatt_database *database)
                                &uuid, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
                                db_hash_read_cb, NULL, database);
 
-       bt_uuid16_create(&uuid, GATT_CHARAC_SERVER_FEAT);
-       database->eatt = gatt_db_service_add_characteristic(service,
+       /* Only enable EATT if there is a socket listening */
+       if (database->eatt_io) {
+               bt_uuid16_create(&uuid, GATT_CHARAC_SERVER_FEAT);
+               database->eatt = gatt_db_service_add_characteristic(service,
                                &uuid, BT_ATT_PERM_READ, BT_GATT_CHRC_PROP_READ,
                                server_feat_read_cb, NULL, database);
+}
 
        gatt_db_service_set_active(service, true);
 
@@ -4223,6 +4226,10 @@ struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
                goto fail;
        }
 
+       /* If just just 1 channel is enabled EATT is not required */
+       if (main_opts.gatt_channels == 1)
+               goto bredr;
+
        /* EATT socket */
        database->eatt_io = bt_io_listen(connect_cb, NULL, NULL, NULL,
                                        &gerr,
@@ -4238,6 +4245,7 @@ struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
                goto fail;
        }
 
+bredr:
        /* BR/EDR socket */
        database->bredr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
                                        BT_IO_OPT_SOURCE_BDADDR, addr,
index b874c22..040eb3d 100755 (executable)
@@ -67,6 +67,7 @@ struct main_opts {
        bt_mode_t       mode;
        bt_gatt_cache_t gatt_cache;
        uint16_t        gatt_mtu;
+       uint8_t         gatt_channels;
 
        uint8_t         key_size;
 
index 5585f4f..389381b 100755 (executable)
@@ -113,6 +113,7 @@ static const char *gatt_options[] = {
        "Cache",
        "KeySize",
        "ExchangeMTU",
+       "EATTChannels",
        NULL
 };
 
@@ -501,6 +502,18 @@ static void parse_config(GKeyFile *config)
                DBG("ExchangeMTU=%d", val);
                main_opts.gatt_mtu = val;
        }
+
+       val = g_key_file_get_integer(config, "GATT", "Channels", &err);
+       if (err) {
+               DBG("%s", err->message);
+               g_clear_error(&err);
+       } else {
+               DBG("Channels=%d", val);
+               /* Ensure the channels is within a valid range. */
+               val = MIN(val, 5);
+               val = MAX(val, 1);
+               main_opts.gatt_channels = val;
+       }
 }
 
 static void init_defaults(void)
@@ -532,6 +545,7 @@ static void init_defaults(void)
 
        main_opts.gatt_cache = BT_GATT_CACHE_ALWAYS;
        main_opts.gatt_mtu = BT_ATT_MAX_LE_MTU;
+       main_opts.gatt_channels = 3;
 #endif
 }
 
index 9cdc6d5..4dbb60a 100755 (executable)
 # Defaults to 517
 #ExchangeMTU = 517
 
+# Number of ATT channels
+# Possible values: 1-5 (1 disables EATT)
+# Default to 3
+#Channels = 3
+
 [Policy]
 #
 # The ReconnectUUIDs defines the set of remote services that should try