[PATCH BlueZ v1 12/13] shared/gatt-client: Implement descriptor discovery.

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

 



This patch implements characteristic descriptor discovery as part of the client
initialization flow.
---
 src/shared/gatt-client.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 6b18e91..ba27224 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -108,6 +108,8 @@ static void gatt_client_clear_services(struct bt_gatt_client *client)
 struct async_op {
 	struct bt_gatt_client *client;
 	struct service_list *cur_service;
+	bt_gatt_characteristic_t *cur_chrc;
+	int cur_chrc_index;
 	int ref_count;
 };
 
@@ -156,6 +158,112 @@ static void uuid_to_string(const uint8_t uuid[BT_GATT_UUID_SIZE],
 
 static void discover_chrcs_cb(bool success, uint8_t att_ecode,
 						struct bt_gatt_result *result,
+						void *user_data);
+
+static void discover_descs_cb(bool success, uint8_t att_ecode,
+						struct bt_gatt_result *result,
+						void *user_data)
+{
+	struct async_op *op = user_data;
+	struct bt_gatt_client *client = op->client;
+	struct bt_gatt_iter iter;
+	char uuid_str[MAX_LEN_UUID_STR];
+	unsigned int desc_count;
+	uint16_t desc_start;
+	unsigned int i;
+	bt_gatt_descriptor_t *descs;
+
+	if (!success) {
+		if (att_ecode == BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND) {
+			success = true;
+			goto next;
+		}
+
+		goto done;
+	}
+
+	if (!result || !bt_gatt_iter_init(&iter, result)) {
+		success = false;
+		goto done;
+	}
+
+	desc_count = bt_gatt_result_descriptor_count(result);
+	if (desc_count == 0) {
+		success = false;
+		goto done;
+	}
+
+	util_debug(client->debug_callback, client->debug_data,
+					"Descriptors found: %u", desc_count);
+
+	descs = new0(bt_gatt_descriptor_t, desc_count);
+	if (!descs) {
+		success = false;
+		goto done;
+	}
+
+	i = 0;
+	while (bt_gatt_iter_next_descriptor(&iter, &descs[i].handle,
+							descs[i].uuid)) {
+		uuid_to_string(descs[i].uuid, uuid_str);
+		util_debug(client->debug_callback, client->debug_data,
+						"handle: 0x%04x, uuid: %s",
+						descs[i].handle, uuid_str);
+		i++;
+	}
+
+	op->cur_chrc->num_descs = desc_count;
+	op->cur_chrc->descs = descs;
+
+	for (i = op->cur_chrc_index;
+				i < op->cur_service->service.num_chrcs; i++) {
+		op->cur_chrc_index = i;
+		op->cur_chrc++;
+		desc_start = op->cur_chrc->value_handle + 1;
+		if (desc_start > op->cur_chrc->end_handle)
+			continue;
+
+		if (bt_gatt_discover_descriptors(client->att,
+						desc_start,
+						op->cur_chrc->end_handle,
+						discover_descs_cb,
+						async_op_ref(op),
+						async_op_unref))
+			return;
+
+		util_debug(client->debug_callback, client->debug_data,
+					"Failed to start descriptor discovery");
+		async_op_unref(op);
+		success = false;
+
+		goto done;
+	}
+
+next:
+	if (!op->cur_service->next)
+		goto done;
+
+	/* Move on to the next service */
+	op->cur_service = op->cur_service->next;
+	if (bt_gatt_discover_characteristics(client->att,
+					op->cur_service->service.start_handle,
+					op->cur_service->service.end_handle,
+					discover_chrcs_cb,
+					async_op_ref(op),
+					async_op_unref))
+		return;
+
+	util_debug(client->debug_callback, client->debug_data,
+				"Failed to start characteristic discovery");
+	async_op_unref(op);
+	success = false;
+
+done:
+	async_op_complete(op, success, att_ecode);
+}
+
+static void discover_chrcs_cb(bool success, uint8_t att_ecode,
+						struct bt_gatt_result *result,
 						void *user_data)
 {
 	struct async_op *op = user_data;
@@ -164,6 +272,7 @@ static void discover_chrcs_cb(bool success, uint8_t att_ecode,
 	char uuid_str[MAX_LEN_UUID_STR];
 	unsigned int chrc_count;
 	unsigned int i;
+	uint16_t desc_start;
 	bt_gatt_characteristic_t *chrcs;
 
 	if (!success) {
@@ -212,6 +321,28 @@ static void discover_chrcs_cb(bool success, uint8_t att_ecode,
 	op->cur_service->service.chrcs = chrcs;
 	op->cur_service->service.num_chrcs = chrc_count;
 
+	for (i = 0; i < chrc_count; i++) {
+		op->cur_chrc_index = i;
+		op->cur_chrc = chrcs + i;
+		desc_start = chrcs[i].value_handle + 1;
+		if (desc_start > chrcs[i].end_handle)
+			continue;
+
+		if (bt_gatt_discover_descriptors(client->att,
+						desc_start, chrcs[i].end_handle,
+						discover_descs_cb,
+						async_op_ref(op),
+						async_op_unref))
+			return;
+
+		util_debug(client->debug_callback, client->debug_data,
+					"Failed to start descriptor discovery");
+		async_op_unref(op);
+		success = false;
+
+		goto done;
+	}
+
 next:
 	if (!op->cur_service->next)
 		goto done;
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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