diff mbox series

[BlueZ,v2,2/3] shared/gatt-db: Introduce gatt_db_clone

Message ID 20240603185312.162337-2-luiz.dentz@gmail.com (mailing list archive)
State Accepted
Commit 7e9816dd8c219f26f52fcb46fa13ecddfcf2d526
Headers show
Series [BlueZ,v2,1/3] shared/csip: Fix memory leak | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/IncrementalBuild success Incremental Build PASS

Commit Message

Luiz Augusto von Dentz June 3, 2024, 6:53 p.m. UTC
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 | 54 ++++++++++++++++++++++++++++++++++++++++++++
 src/shared/gatt-db.h |  1 +
 2 files changed, 55 insertions(+)
diff mbox series

Patch

diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 2c8e7d31eda1..d8d21392fee6 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -260,6 +260,60 @@  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 *attr = service->attributes[i];
+
+		/* Only clone values for characteristics since that is
+		 * cacheable.
+		 */
+		if (bt_uuid_len(&attr->uuid) == 2 &&
+				attr->uuid.value.u16 == GATT_CHARAC_UUID)
+			clone->attributes[i] = new_attribute(clone,
+							attr->handle,
+							&attr->uuid,
+							attr->value,
+							attr->value_len);
+		else
+			clone->attributes[i] = new_attribute(clone,
+							attr->handle,
+							&attr->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);