@@ -5049,6 +5049,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);
@@ -59,8 +59,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;
@@ -2171,6 +2169,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;
@@ -2178,11 +2177,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++) {
+ for (i = bt_att_get_channels(att); i < main_opts.gatt_channels; i++) {
io = bt_io_connect(eatt_connect_cb, client, NULL, NULL,
BT_IO_OPT_SOURCE_BDADDR,
btd_adapter_get_address(adapter),
@@ -1215,10 +1215,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);
@@ -3564,6 +3567,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, NULL,
BT_IO_OPT_SOURCE_BDADDR, addr,
@@ -3591,6 +3598,7 @@ struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
}
}
+bredr:
/* BR/EDR socket */
database->bredr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, addr,
@@ -56,6 +56,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;
};
@@ -108,6 +108,7 @@ static const char *gatt_options[] = {
"Cache",
"KeySize",
"ExchangeMTU",
+ "EATTChannels",
NULL
};
@@ -444,6 +445,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)
@@ -470,6 +483,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;
}
static void log_handler(const gchar *log_domain, GLogLevelFlags log_level,
@@ -94,6 +94,11 @@
# 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
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This adds option to set the numbers of GATT Channels/Bearers to be connected in main.conf. --- src/device.c | 5 +++++ src/gatt-client.c | 8 +++++--- src/gatt-database.c | 12 ++++++++++-- src/hcid.h | 1 + src/main.c | 14 ++++++++++++++ src/main.conf | 5 +++++ 6 files changed, 40 insertions(+), 5 deletions(-)