* [PATCH BlueZ v1 2/3] shared/gatt-db: Introduce gatt_db_clone
2024-05-24 17:11 [PATCH BlueZ v1 1/3] shared/csip: Fix memory leak Luiz Augusto von Dentz
@ 2024-05-24 17:11 ` Luiz Augusto von Dentz
2024-05-24 17:11 ` [PATCH BlueZ v1 3/3] set: Attempt to use existing set gatt-db Luiz Augusto von Dentz
2024-05-24 19:55 ` [BlueZ,v1,1/3] shared/csip: Fix memory leak bluez.test.bot
2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2024-05-24 17:11 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This introduces gatt_db_clone which can be used to clonse/deep copy and
existing database.
---
src/shared/gatt-db.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/shared/gatt-db.h | 1 +
2 files changed, 43 insertions(+)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 2c8e7d31eda1..28da9488fedf 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -260,6 +260,48 @@ struct gatt_db *gatt_db_new(void)
return gatt_db_ref(db);
}
+static void service_clone(void *data, void *user_data)
+{
+ struct gatt_db_service *service = data;
+ struct gatt_db *db = user_data;
+ struct gatt_db_service *clone;
+ int i;
+
+ clone = new0(struct gatt_db_service, 1);
+ clone->db = db;
+ clone->active = service->active;
+ clone->num_handles = service->num_handles;
+ clone->attributes = new0(struct gatt_db_attribute *,
+ service->num_handles);
+
+ /* Clone attributes */
+ for (i = 0; i < service->num_handles; i++) {
+ struct gatt_db_attribute *attribute = service->attributes[i];
+
+ clone->attributes[i] = new_attribute(clone, attribute->handle,
+ &attribute->uuid,
+ NULL, 0);
+ }
+
+ queue_push_tail(db->services, clone);
+}
+
+struct gatt_db *gatt_db_clone(struct gatt_db *db)
+{
+ struct gatt_db *clone;
+
+ if (!db)
+ return NULL;
+
+ clone = gatt_db_new();
+ if (!clone)
+ return NULL;
+
+ queue_foreach(db->services, service_clone, clone);
+
+ return clone;
+}
+
static void notify_destroy(void *data)
{
struct notify *notify = data;
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index f7596e33529a..dc2daf7fc1ba 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -12,6 +12,7 @@ struct gatt_db;
struct gatt_db_attribute;
struct gatt_db *gatt_db_new(void);
+struct gatt_db *gatt_db_clone(struct gatt_db *db);
struct gatt_db *gatt_db_ref(struct gatt_db *db);
void gatt_db_unref(struct gatt_db *db);
--
2.45.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH BlueZ v1 3/3] set: Attempt to use existing set gatt-db
2024-05-24 17:11 [PATCH BlueZ v1 1/3] shared/csip: Fix memory leak Luiz Augusto von Dentz
2024-05-24 17:11 ` [PATCH BlueZ v1 2/3] shared/gatt-db: Introduce gatt_db_clone Luiz Augusto von Dentz
@ 2024-05-24 17:11 ` Luiz Augusto von Dentz
2024-05-24 19:55 ` [BlueZ,v1,1/3] shared/csip: Fix memory leak bluez.test.bot
2 siblings, 0 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2024-05-24 17:11 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Most sets should be clone of each other, or at least very similar, so
this attempts to clone the existing gatt-db of the first member found
when connecting new sets, this substantially speed up the process of
bonding sets if their database matches which is something that is
currently ranging from 20-30 seconds depending on the manufacturer and
with this changes it takes a good 5-10 seconds.
If the dbs don't really match bt_gatt_client instance will attempt to
rediscover the ranges that don't match.
---
src/device.c | 21 +++++++++++++++++++++
src/device.h | 1 +
src/set.c | 22 ++++++++++++++++++++--
3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/device.c b/src/device.c
index 620bbd55ebad..5dc1cd0cdbf2 100644
--- a/src/device.c
+++ b/src/device.c
@@ -6994,6 +6994,27 @@ struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
return device->db;
}
+bool btd_device_set_gatt_db(struct btd_device *device, struct gatt_db *db)
+{
+ struct gatt_db *clone;
+
+ if (!device)
+ return false;
+
+ clone = gatt_db_clone(db);
+ if (clone)
+ return false;
+
+ gatt_db_unregister(device->db, device->db_id);
+ gatt_db_unref(device->db);
+
+ device->db = clone;
+ device->db_id = gatt_db_register(device->db, gatt_service_added,
+ gatt_service_removed, device, NULL);
+
+ return true;
+}
+
struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
{
if (!device)
diff --git a/src/device.h b/src/device.h
index a2b7bb15d200..0794f92d0178 100644
--- a/src/device.h
+++ b/src/device.h
@@ -66,6 +66,7 @@ struct gatt_primary *btd_device_get_primary(struct btd_device *device,
const char *uuid);
GSList *btd_device_get_primaries(struct btd_device *device);
struct gatt_db *btd_device_get_gatt_db(struct btd_device *device);
+bool btd_device_set_gatt_db(struct btd_device *device, struct gatt_db *db);
struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device);
struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device);
bool btd_device_is_initiator(struct btd_device *device);
diff --git a/src/set.c b/src/set.c
index bf35ee403b39..4ca2f78c3702 100644
--- a/src/set.c
+++ b/src/set.c
@@ -28,6 +28,8 @@
#include "src/shared/queue.h"
#include "src/shared/ad.h"
#include "src/shared/crypto.h"
+#include "src/shared/att.h"
+#include "src/shared/gatt-db.h"
#include "log.h"
#include "error.h"
@@ -277,8 +279,24 @@ static void foreach_rsi(void *data, void *user_data)
bt_crypto_unref(crypto);
- if (!memcmp(ad->data, res, sizeof(res)))
- device_connect_le(set->device);
+ if (memcmp(ad->data, res, sizeof(res)))
+ return;
+
+ /* Attempt to use existing gatt_db from set if device has never been
+ * connected before.
+ *
+ * If dbs don't really match bt_gatt_client will attempt to rediscover
+ * the ranges that don't match.
+ */
+ if (gatt_db_isempty(btd_device_get_gatt_db(set->device))) {
+ struct btd_device *device;
+
+ device = queue_get_entries(set->devices)->data;
+ btd_device_set_gatt_db(set->device,
+ btd_device_get_gatt_db(device));
+ }
+
+ device_connect_le(set->device);
}
static void foreach_device(struct btd_device *device, void *data)
--
2.45.1
^ permalink raw reply related [flat|nested] 4+ messages in thread