gatt: Enable connecting to EATT channel using Ext-Flowctl mode
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 16 Mar 2020 22:16:12 +0000 (15:16 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 12 Apr 2021 09:00:48 +0000 (14:30 +0530)
This makes use of BT_IO_MODE_EXT_FLOWCTL to connect to EATT channels.

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

index b55c1a9..d31d8a8 100644 (file)
@@ -2559,9 +2559,13 @@ static void eatt_connect(struct btd_gatt_client *client)
 
        ba2str(device_get_address(dev), addr);
 
-       DBG("Connection attempt to: %s", addr);
-
        for (i = bt_att_get_channels(att); i < main_opts.gatt_channels; i++) {
+               int defer_timeout = i + 1 < main_opts.gatt_channels ? 1 : 0;
+
+               DBG("Connection attempt to: %s defer %s", addr,
+                                       defer_timeout ? "true" : "false");
+
+               /* Attempt to connect using the Ext-Flowctl */
                io = bt_io_connect(eatt_connect_cb, client, NULL, &gerr,
                                        BT_IO_OPT_SOURCE_BDADDR,
                                        btd_adapter_get_address(adapter),
@@ -2571,15 +2575,35 @@ static void eatt_connect(struct btd_gatt_client *client)
                                        device_get_address(dev),
                                        BT_IO_OPT_DEST_TYPE,
                                        device_get_le_address_type(dev),
+                                       BT_IO_OPT_MODE, BT_IO_MODE_EXT_FLOWCTL,
                                        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_DEFER_TIMEOUT, defer_timeout,
                                        BT_IO_OPT_INVALID);
                if (!io) {
-                       error("EATT bt_io_connect(%s): %s", addr,
-                                                       gerr->message);
                        g_error_free(gerr);
-                       return;
+                       gerr = NULL;
+                       /* Fallback to legacy 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);