[Bluez PATCH 2/2] shared/gatt: Add descriptor insert function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



service->attributes has an assumption that it should look like:
|char_uuid|char_1|desc_1_1|desc_1_2|char_uuid|char_2|desc_2_1|char_uuid|...
where desc_x_y means a descriptor of char_x.

In monitor, an attribute is inserted as soon as it is found. It is not
guranteed that all the descriptors of a characteristic would be found
before another characteristic is found.

This adds a function to insert the descriptor with the given handle to
an appropriate place in its service attribute list and make monitor to
use this function when a descripter is found.

Reviewed-by: Archie Pusaka <apusaka@xxxxxxxxxxxx>
---

 monitor/att.c        |  2 +-
 src/shared/gatt-db.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
 src/shared/gatt-db.h |  9 ++++++
 3 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/monitor/att.c b/monitor/att.c
index ddeb54d9e..503099745 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -4153,7 +4153,7 @@ static struct gatt_db_attribute *insert_desc(const struct l2cap_frame *frame,
 	if (!db)
 		return NULL;
 
-	return gatt_db_append_descriptor(db, handle, uuid, 0, NULL, NULL, NULL);
+	return gatt_db_insert_descriptor(db, handle, uuid, 0, NULL, NULL, NULL);
 }
 
 static void att_find_info_rsp_16(const struct l2cap_frame *frame)
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 39bba9b54..f08c5afaa 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -1002,6 +1002,72 @@ service_append_descriptor(struct gatt_db_service *service,
 	return service->attributes[i];
 }
 
+struct gatt_db_attribute *
+gatt_db_insert_descriptor(struct gatt_db *db,
+					uint16_t handle,
+					const bt_uuid_t *uuid,
+					uint32_t permissions,
+					gatt_db_read_t read_func,
+					gatt_db_write_t write_func,
+					void *user_data)
+{
+	struct gatt_db_attribute *attrib, *iter_attr, *char_attr = NULL;
+	struct gatt_db_service *service;
+	int i, j, num_index, char_index;
+
+	attrib = gatt_db_get_service(db, handle);
+	if (!attrib)
+		return NULL;
+
+	service = attrib->service;
+	num_index = get_attribute_index(service, 0);
+	if (!num_index)
+		return NULL;
+
+	// Find the characteristic the descriptor belongs to.
+	for (i = 0; i < num_index; i++) {
+		iter_attr = service->attributes[i];
+		if (bt_uuid_cmp(&characteristic_uuid, &iter_attr->uuid))
+			continue;
+
+		if (iter_attr->handle > handle)
+			continue;
+
+		// Find the characteristic with the largest handle among those
+		// with handles less than the descriptor's handle.
+		if (!char_attr || iter_attr->handle > char_attr->handle) {
+			char_attr = iter_attr;
+			char_index = i;
+		}
+	}
+
+	// There is no characteristic contain this descriptor. Something went
+	// wrong
+	if (!char_attr)
+		return NULL;
+
+	// Find the end of this characteristic
+	for (i = char_index + 1; i < num_index; i++) {
+		iter_attr = service->attributes[i];
+
+		if (!bt_uuid_cmp(&characteristic_uuid, &iter_attr->uuid) ||
+			!bt_uuid_cmp(&included_service_uuid, &iter_attr->uuid))
+			break;
+	}
+
+	// Move all of the attributes after the end of this characteristic to
+	// its next index.
+	for (j = num_index; j > i; j--)
+		service->attributes[j] = service->attributes[j - 1];
+
+	service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0);
+
+	set_attribute_data(service->attributes[i], read_func, write_func,
+							permissions, user_data);
+
+	return service->attributes[i];
+}
+
 struct gatt_db_attribute *
 gatt_db_append_descriptor(struct gatt_db *db,
 					uint16_t handle,
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index ec0eccdfc..4c4e88d87 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -80,6 +80,15 @@ gatt_db_append_characteristic(struct gatt_db *db,
 					gatt_db_write_t write_func,
 					void *user_data);
 
+struct gatt_db_attribute *
+gatt_db_insert_descriptor(struct gatt_db *db,
+					uint16_t handle,
+					const bt_uuid_t *uuid,
+					uint32_t permissions,
+					gatt_db_read_t read_func,
+					gatt_db_write_t write_func,
+					void *user_data);
+
 struct gatt_db_attribute *
 gatt_db_append_descriptor(struct gatt_db *db,
 					uint16_t handle,
-- 
2.44.0.478.gd926399ef9-goog





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux