[RFC BlueZ 16/18] attrib: Avoid passing raw PDU to gatt_discover_char_desc() callback

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

 



By centralizing the PDU parsing and validation internally to GATT API,
the callbacks become simpler.
---
 attrib/gatt.c                        |   94 +++++++++++++++++++++++++++++++++-
 attrib/gatt.h                        |    7 ++-
 attrib/gatttool.c                    |   36 ++++---------
 attrib/interactive.c                 |   44 +++++-----------
 profiles/cyclingspeed/cyclingspeed.c |   43 ++++++----------
 profiles/gatt/gas.c                  |   35 +++++--------
 profiles/heartrate/heartrate.c       |   39 +++++---------
 profiles/input/hog.c                 |   79 ++++++++++------------------
 profiles/scanparam/scan.c            |   47 ++++++++---------
 profiles/thermometer/thermometer.c   |   58 +++++++++------------
 10 files changed, 239 insertions(+), 243 deletions(-)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index d68b26c..aeea2ca 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -948,9 +948,92 @@ guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu,
 									g_free);
 }
 
+struct discover_char_desc_data {
+	GAttrib *attrib;
+	uint16_t end;
+	gatt_cb_t func;
+	gpointer user_data;
+};
+
+static void gatt_discover_char_desc_cb(guint8 status, const guint8 *pdu,
+					guint16 plen, gpointer user_data)
+{
+	struct discover_char_desc_data *data = user_data;
+	struct att_data_list *list;
+	GSList *char_descs = NULL;
+	uint16_t last_handle = 0xffff;
+	bool continue_discovery;
+	uint8_t format;
+	unsigned int i;
+
+	if (status != 0)
+		goto done;
+
+	list = dec_find_info_resp(pdu, plen, &format);
+	if (list == NULL) {
+		status = ATT_ECODE_IO;
+		goto done;
+	}
+
+	for (i = 0; i < list->num; i++) {
+		uint8_t *value = list->data[i];
+		struct gatt_char_desc *desc;
+
+		desc = g_new0(struct gatt_char_desc, 1);
+		desc->handle = att_get_u16(value);
+		last_handle = desc->handle;
+
+		if (format == ATT_FIND_INFO_RESP_FMT_16BIT)
+			desc->uuid = att_get_uuid16(&value[2]);
+		else
+			desc->uuid = att_get_uuid128(&value[2]);
+
+		char_descs = g_slist_append(char_descs, desc);
+	}
+
+	att_data_list_free(list);
+
+	/* From the Core spec: "It is permitted to end the sub-procedure early
+	 * if a desired Characteristic Descriptor is found prior to discovering
+	 * all the characteristic descriptors of the specified characteristic."
+	 *
+	 * In other words, this callback will receive the partial list of
+	 * discovered descriptors, and if it returns false, the procedure is
+	 * interrupted.
+	 */
+	continue_discovery = data->func(char_descs, status, data->user_data);
+	g_slist_free_full(char_descs, g_free);
+
+	if (!continue_discovery)
+		goto data_free;
+
+	if (last_handle != 0xffff && last_handle < data->end) {
+		uint8_t *buf;
+		size_t buflen;
+		uint16_t plen;
+
+		buf = g_attrib_get_buffer(data->attrib, &buflen);
+		plen = enc_find_info_req(last_handle + 1, data->end, buf,
+									buflen);
+		g_attrib_send(data->attrib, 0, buf, plen,
+					gatt_discover_char_desc_cb, data, NULL);
+
+		return;
+	} else
+		/* Procedure has finished */
+		status = ATT_ECODE_ATTR_NOT_FOUND;
+
+done:
+	data->func(NULL, status, data->user_data);
+data_free:
+	g_attrib_unref(data->attrib);
+	g_free(data);
+}
+
 guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
-				GAttribResultFunc func, gpointer user_data)
+					gatt_cb_t func, gpointer user_data)
 {
+	struct discover_char_desc_data *data;
 	uint8_t *buf;
 	size_t buflen;
 	guint16 plen;
@@ -960,7 +1043,14 @@ guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
+	data = g_new0(struct discover_char_desc_data, 1);
+	data->attrib = g_attrib_ref(attrib);
+	data->end = end;
+	data->func = func;
+	data->user_data = user_data;
+
+	return g_attrib_send(attrib, 0, buf, plen, gatt_discover_char_desc_cb,
+								data, NULL);
 }
 
 guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 097d30d..97b38c6 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -79,6 +79,11 @@ struct gatt_char {
 	uint16_t value_handle;
 };
 
+struct gatt_char_desc {
+	uint16_t handle;
+	bt_uuid_t uuid;
+};
+
 guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
@@ -97,7 +102,7 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, const uint8_t *value,
 					void *user_data);
 
 guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
-				GAttribResultFunc func, gpointer user_data);
+					gatt_cb_t func, gpointer user_data);
 
 guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
 				GDestroyNotify notify, gpointer user_data);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 433a494..9049886 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -408,12 +408,12 @@ error:
 	return FALSE;
 }
 
-static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
-							gpointer user_data)
+static bool char_desc_cb(GSList *descs, guint8 status, gpointer user_data)
 {
-	struct att_data_list *list;
-	guint8 format;
-	int i;
+	GSList *l;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND)
+		goto done;
 
 	if (status != 0) {
 		g_printerr("Discover all characteristic descriptors failed: "
@@ -421,33 +421,19 @@ static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
 		goto done;
 	}
 
-	list = dec_find_info_resp(pdu, plen, &format);
-	if (list == NULL)
-		goto done;
-
-	for (i = 0; i < list->num; i++) {
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
 		char uuidstr[MAX_LEN_UUID_STR];
-		uint16_t handle;
-		uint8_t *value;
-		bt_uuid_t uuid;
-
-		value = list->data[i];
-		handle = att_get_u16(value);
-
-		if (format == 0x01)
-			uuid = att_get_uuid16(&value[2]);
-		else
-			uuid = att_get_uuid128(&value[2]);
 
-		bt_uuid_to_string(&uuid, uuidstr, MAX_LEN_UUID_STR);
-		g_print("handle = 0x%04x, uuid = %s\n", handle, uuidstr);
+		bt_uuid_to_string(&desc->uuid, uuidstr, sizeof(uuidstr));
+		g_print("handle = 0x%04x, uuid = %s\n", desc->handle, uuidstr);
 	}
 
-	att_data_list_free(list);
-
 done:
 	if (!opt_listen)
 		g_main_loop_quit(event_loop);
+
+	return true;
 }
 
 static gboolean characteristics_desc(gpointer user_data)
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 02c8167..f194e33 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -275,49 +275,31 @@ static bool char_cb(GSList *characteristics, guint8 status, gpointer user_data)
 	return true;
 }
 
-static void char_desc_cb(guint8 status, const guint8 *pdu, guint16 plen,
-							gpointer user_data)
+static bool char_desc_cb(GSList *descs, guint8 status, gpointer user_data)
 {
-	struct att_data_list *list;
-	guint8 format;
-	uint16_t handle = 0xffff;
-	int i;
+	GSList *l;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND) {
+		rl_forced_update_display();
+		return true;
+	}
 
 	if (status != 0) {
 		printf("Discover descriptors finished: %s\n",
 						att_ecode2str(status));
-		return;
+		return true;
 	}
 
-	list = dec_find_info_resp(pdu, plen, &format);
-	if (list == NULL)
-		return;
-
 	printf("\n");
-	for (i = 0; i < list->num; i++) {
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
 		char uuidstr[MAX_LEN_UUID_STR];
-		uint8_t *value;
-		bt_uuid_t uuid;
-
-		value = list->data[i];
-		handle = att_get_u16(value);
-
-		if (format == 0x01)
-			uuid = att_get_uuid16(&value[2]);
-		else
-			uuid = att_get_uuid128(&value[2]);
 
-		bt_uuid_to_string(&uuid, uuidstr, MAX_LEN_UUID_STR);
-		printf("handle: 0x%04x, uuid: %s\n", handle, uuidstr);
+		bt_uuid_to_string(&desc->uuid, uuidstr, sizeof(uuidstr));
+		printf("handle: 0x%04x, uuid: %s\n", desc->handle, uuidstr);
 	}
 
-	att_data_list_free(list);
-
-	if (handle != 0xffff && handle < end)
-		gatt_discover_char_desc(attrib, handle + 1, end, char_desc_cb,
-									NULL);
-	else
-		rl_forced_update_display();
+	return true;
 }
 
 static void char_read_cb(uint8_t status, const uint8_t *value, size_t vlen,
diff --git a/profiles/cyclingspeed/cyclingspeed.c b/profiles/cyclingspeed/cyclingspeed.c
index a845a1b..b24e3ab 100644
--- a/profiles/cyclingspeed/cyclingspeed.c
+++ b/profiles/cyclingspeed/cyclingspeed.c
@@ -399,42 +399,32 @@ static void read_location_cb(uint8_t status, const uint8_t *value, size_t vlen,
 					CYCLINGSPEED_INTERFACE, "Location");
 }
 
-static void discover_desc_cb(guint8 status, const guint8 *pdu,
-					guint16 len, gpointer user_data)
+static bool discover_desc_cb(GSList *descs, guint8 status, gpointer user_data)
 {
 	struct characteristic *ch = user_data;
-	struct att_data_list *list = NULL;
-	uint8_t format;
-	int i;
+	GSList *l;
 
 	if (status != 0) {
-		error("Discover %s descriptors failed: %s", ch->uuid,
+		if (status != ATT_ECODE_ATTR_NOT_FOUND)
+			error("Discover %s descriptors failed: %s", ch->uuid,
 							att_ecode2str(status));
-		goto done;
-	}
-
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		goto done;
 
-	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
-		goto done;
+		g_free(ch);
+		return true;
+	}
 
-	for (i = 0; i < list->num; i++) {
-		uint8_t *value;
-		uint16_t handle, uuid;
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
 		uint8_t attr_val[2];
+		bt_uuid_t uuid;
 		char *msg;
 
-		value = list->data[i];
-		handle = att_get_u16(value);
-		uuid = att_get_u16(value + 2);
-
-		if (uuid != GATT_CLIENT_CHARAC_CFG_UUID)
+		bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+		if (bt_uuid_cmp(&desc->uuid, &uuid) != 0)
 			continue;
 
 		if (g_strcmp0(ch->uuid, CSC_MEASUREMENT_UUID) == 0) {
-			ch->csc->measurement_ccc_handle = handle;
+			ch->csc->measurement_ccc_handle = desc->handle;
 
 			if (g_slist_length(ch->csc->cadapter->watchers) == 0) {
 				att_put_u16(0x0000, attr_val);
@@ -452,17 +442,14 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu,
 			break;
 		}
 
-		gatt_write_char(ch->csc->attrib, handle, attr_val,
+		gatt_write_char(ch->csc->attrib, desc->handle, attr_val,
 					sizeof(attr_val), char_write_cb, msg);
 
 		/* We only want CCC, can break here */
 		break;
 	}
 
-done:
-	if (list)
-		att_data_list_free(list);
-	g_free(ch);
+	return true;
 }
 
 static void discover_desc(struct csc *csc, struct gatt_char *c,
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 7b23a87..6313ea3 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -225,40 +225,31 @@ static void write_ccc(GAttrib *attrib, uint16_t handle, gpointer user_data)
 								user_data);
 }
 
-static void gatt_descriptors_cb(guint8 status, const guint8 *pdu, guint16 len,
+static bool gatt_descriptors_cb(GSList *descs, guint8 status,
 							gpointer user_data)
 {
 	struct gas *gas = user_data;
-	struct att_data_list *list;
-	int i;
-	uint8_t format;
+	GSList *l;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND)
+		return true;
 
 	if (status) {
 		error("Discover all GATT characteristic descriptors: %s",
 							att_ecode2str(status));
-		return;
+		return true;
 	}
 
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		return;
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
+		char uuidstr[MAX_LEN_UUID_STR];
 
-	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
-		goto done;
-
-	for (i = 0; i < list->num; i++) {
-		uint16_t uuid16, ccc;
-		uint8_t *value;
-
-		value = list->data[i];
-		ccc = att_get_u16(value);
-		uuid16 = att_get_u16(&value[2]);
-		DBG("CCC: 0x%04x UUID: 0x%04x", ccc, uuid16);
-		write_ccc(gas->attrib, ccc, user_data);
+		bt_uuid_to_string(&desc->uuid, uuidstr, sizeof(uuidstr));
+		DBG("CCC: 0x%04x UUID: %s", desc->handle, uuidstr);
+		write_ccc(gas->attrib, desc->handle, user_data);
 	}
 
-done:
-	att_data_list_free(list);
+	return true;
 }
 
 static bool gatt_characteristic_cb(GSList *characteristics, guint8 status,
diff --git a/profiles/heartrate/heartrate.c b/profiles/heartrate/heartrate.c
index e4b06ed..ab27d9b 100644
--- a/profiles/heartrate/heartrate.c
+++ b/profiles/heartrate/heartrate.c
@@ -380,41 +380,31 @@ static void notify_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	process_measurement(hr, pdu + 3, len - 3);
 }
 
-static void discover_ccc_cb(guint8 status, const guint8 *pdu,
-						guint16 len, gpointer user_data)
+static bool discover_ccc_cb(GSList *descs, guint8 status, gpointer user_data)
 {
 	struct heartrate *hr = user_data;
-	struct att_data_list *list;
-	uint8_t format;
-	int i;
+	GSList *l;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND)
+		return true;
 
 	if (status != 0) {
 		error("Discover Heart Rate Measurement descriptors failed: %s",
 							att_ecode2str(status));
-		return;
+		return true;
 	}
 
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		return;
-
-	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
-		goto done;
-
-	for (i = 0; i < list->num; i++) {
-		uint8_t *value;
-		uint16_t handle, uuid;
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
 		char *msg;
 		uint8_t attr_val[2];
+		bt_uuid_t uuid;
 
-		value = list->data[i];
-		handle = att_get_u16(value);
-		uuid = att_get_u16(value + 2);
-
-		if (uuid != GATT_CLIENT_CHARAC_CFG_UUID)
+		bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+		if (bt_uuid_cmp(&desc->uuid, &uuid) != 0)
 			continue;
 
-		hr->measurement_ccc_handle = handle;
+		hr->measurement_ccc_handle = desc->handle;
 
 		if (g_slist_length(hr->hradapter->watchers) == 0) {
 			att_put_u16(0x0000, attr_val);
@@ -424,14 +414,13 @@ static void discover_ccc_cb(guint8 status, const guint8 *pdu,
 			msg = g_strdup("Enable measurement");
 		}
 
-		gatt_write_char(hr->attrib, handle, attr_val,
+		gatt_write_char(hr->attrib, desc->handle, attr_val,
 					sizeof(attr_val), char_write_cb, msg);
 
 		break;
 	}
 
-done:
-	att_data_list_free(list);
+	return true;
 }
 
 static void discover_measurement_ccc(struct heartrate *hr,
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index 33c3aed..e04d4be 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -194,75 +194,52 @@ static void report_reference_cb(uint8_t status, const uint8_t *value,
 static void external_report_reference_cb(uint8_t status, const uint8_t *value,
 						size_t vlen, void *user_data);
 
-
-static void discover_descriptor_cb(guint8 status, const guint8 *pdu,
-					guint16 len, gpointer user_data)
+static bool discover_descriptor_cb(GSList *descs, guint8 status,
+							gpointer user_data)
 {
 	struct disc_desc_cb_data *ddcb_data = user_data;
-	struct report *report;
-	struct hog_device *hogdev;
-	struct att_data_list *list = NULL;
-	GAttrib *attrib = NULL;
-	uint8_t format;
-	uint16_t handle = 0xffff;
-	uint16_t end = ddcb_data->end;
-	int i;
-
-	if (status == ATT_ECODE_ATTR_NOT_FOUND) {
-		DBG("Discover all characteristic descriptors finished");
-		goto done;
-	}
+	GSList *l;
 
 	if (status != 0) {
-		error("Discover all characteristic descriptors failed: %s",
+		if (status != ATT_ECODE_ATTR_NOT_FOUND)
+			error("Characteristic descriptor discovery failed: %s",
 							att_ecode2str(status));
-		goto done;
-	}
-
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		return;
 
-	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
-		goto done;
-
-	for (i = 0; i < list->num; i++) {
-		uint16_t uuid16;
-		uint8_t *value;
+		g_free(ddcb_data);
+		return true;
+	}
 
-		value = list->data[i];
-		handle = att_get_u16(value);
-		uuid16 = att_get_u16(&value[2]);
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
+		struct report *report;
+		struct hog_device *hogdev;
+		GAttrib *attrib;
+		bt_uuid_t uuid;
 
-		switch (uuid16) {
-		case GATT_CLIENT_CHARAC_CFG_UUID:
+		bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+		if (bt_uuid_cmp(&desc->uuid, &uuid) == 0) {
 			report = ddcb_data->data;
-			attrib = report->hogdev->attrib;
-			write_ccc(handle, report);
-			break;
-		case GATT_REPORT_REFERENCE:
+			write_ccc(desc->handle, report);
+		}
+
+		bt_uuid16_create(&uuid, GATT_REPORT_REFERENCE);
+		if (bt_uuid_cmp(&desc->uuid, &uuid) == 0) {
 			report = ddcb_data->data;
 			attrib = report->hogdev->attrib;
-			gatt_read_char(attrib, handle,
+			gatt_read_char(attrib, desc->handle,
 						report_reference_cb, report);
-			break;
-		case GATT_EXTERNAL_REPORT_REFERENCE:
+		}
+
+		bt_uuid16_create(&uuid, GATT_EXTERNAL_REPORT_REFERENCE);
+		if (bt_uuid_cmp(&desc->uuid, &uuid) == 0) {
 			hogdev = ddcb_data->data;
 			attrib = hogdev->attrib;
-			gatt_read_char(attrib, handle,
+			gatt_read_char(attrib, desc->handle,
 					external_report_reference_cb, hogdev);
-			break;
 		}
 	}
 
-done:
-	att_data_list_free(list);
-
-	if (handle != 0xffff && handle < end)
-		gatt_discover_char_desc(attrib, handle + 1, end,
-					discover_descriptor_cb, ddcb_data);
-	else
-		g_free(ddcb_data);
+	return true;
 }
 
 static void discover_descriptor(GAttrib *attrib, uint16_t start, uint16_t end,
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index 8412d67..b21e92b 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -111,35 +111,36 @@ static void ccc_written_cb(uint8_t status, void *user_data)
 				refresh_value_cb, scan, NULL);
 }
 
-static void discover_descriptor_cb(guint8 status, const guint8 *pdu,
-					guint16 len, gpointer user_data)
+static bool discover_descriptor_cb(GSList *descs, guint8 status,
+							gpointer user_data)
 {
 	struct scan *scan = user_data;
-	struct att_data_list *list;
-	uint8_t *ptr;
-	uint16_t uuid16, handle;
-	uint8_t value[2];
-	uint8_t format;
-
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		return;
+	GSList *l;
+
+	if (status == ATT_ECODE_ATTR_NOT_FOUND)
+		return true;
+
+	if (status != 0) {
+		error("Discover all GATT characteristic descriptors failed: %s",
+							att_ecode2str(status));
+		return true;
+	}
 
-	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
-		goto done;
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
+		uint8_t value[2];
+		bt_uuid_t uuid;
 
-	ptr = list->data[0];
-	handle = att_get_u16(ptr);
-	uuid16 = att_get_u16(&ptr[2]);
+		bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+		if (bt_uuid_cmp(&desc->uuid, &uuid) != 0)
+			continue;
 
-	if (uuid16 != GATT_CLIENT_CHARAC_CFG_UUID)
-		goto done;
+		att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value);
+		gatt_write_char(scan->attrib, desc->handle, value,
+				sizeof(value), ccc_written_cb, user_data);
+	}
 
-	att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value);
-	gatt_write_char(scan->attrib, handle, value, sizeof(value),
-						ccc_written_cb, user_data);
-done:
-	att_data_list_free(list);
+	return true;
 }
 
 static bool refresh_discovered_cb(GSList *chars, guint8 status,
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index f506c69..ae89600 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -514,25 +514,28 @@ static void write_ccc_cb(uint8_t status, void *user_data)
 	g_free(msg);
 }
 
-static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
-								uint16_t handle)
+static void process_thermometer_desc(struct characteristic *ch,
+						struct gatt_char_desc *desc)
 {
 	uint8_t atval[2];
+	bt_uuid_t uuid;
 	uint16_t val;
 	char *msg;
 
-	if (uuid == GATT_CHARAC_VALID_RANGE_UUID) {
+	bt_uuid16_create(&uuid, GATT_CHARAC_VALID_RANGE_UUID);
+	if (bt_uuid_cmp(&desc->uuid, &uuid) == 0) {
 		if (g_strcmp0(ch->uuid, MEASUREMENT_INTERVAL_UUID) == 0)
-			gatt_read_char(ch->t->attrib, handle,
+			gatt_read_char(ch->t->attrib, desc->handle,
 						valid_range_desc_cb, ch->t);
 		return;
 	}
 
-	if (uuid != GATT_CLIENT_CHARAC_CFG_UUID)
+	bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
+	if (bt_uuid_cmp(&desc->uuid, &uuid) != 0)
 		return;
 
 	if (g_strcmp0(ch->uuid, TEMPERATURE_MEASUREMENT_UUID) == 0) {
-		ch->t->measurement_ccc_handle = handle;
+		ch->t->measurement_ccc_handle = desc->handle;
 
 		if (g_slist_length(ch->t->tadapter->fwatchers) == 0) {
 			val = 0x0000;
@@ -542,7 +545,7 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
 			msg = g_strdup("Enable Temperature Measurement ind");
 		}
 	} else if (g_strcmp0(ch->uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
-		ch->t->intermediate_ccc_handle = handle;
+		ch->t->intermediate_ccc_handle = desc->handle;
 
 		if (g_slist_length(ch->t->tadapter->iwatchers) == 0) {
 			val = 0x0000;
@@ -559,46 +562,31 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
 	}
 
 	att_put_u16(val, atval);
-	gatt_write_char(ch->t->attrib, handle, atval, sizeof(atval),
+	gatt_write_char(ch->t->attrib, desc->handle, atval, sizeof(atval),
 							write_ccc_cb, msg);
 }
 
-static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
-							gpointer user_data)
+static bool discover_desc_cb(GSList *descs, guint8 status, gpointer user_data)
 {
 	struct characteristic *ch = user_data;
-	struct att_data_list *list = NULL;
-	uint8_t format;
-	int i;
+	GSList *l;
 
 	if (status != 0) {
-		error("Discover all characteristic descriptors failed [%s]: %s",
-					ch->uuid, att_ecode2str(status));
-		goto done;
-	}
-
-	list = dec_find_info_resp(pdu, len, &format);
-	if (list == NULL)
-		goto done;
-
-	if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
-		goto done;
+		if (status != ATT_ECODE_ATTR_NOT_FOUND)
+			error("Discover %s descriptors failed: %s", ch->uuid,
+							att_ecode2str(status));
 
-	for (i = 0; i < list->num; i++) {
-		uint8_t *value;
-		uint16_t handle, uuid;
+		g_free(ch);
+		return true;
+	}
 
-		value = list->data[i];
-		handle = att_get_u16(value);
-		uuid = att_get_u16(value + 2);
+	for (l = descs; l != NULL; l = g_slist_next(l)) {
+		struct gatt_char_desc *desc = l->data;
 
-		process_thermometer_desc(ch, uuid, handle);
+		process_thermometer_desc(ch, desc);
 	}
 
-done:
-	if (list != NULL)
-		att_data_list_free(list);
-	g_free(ch);
+	return true;
 }
 
 static void discover_desc(struct thermometer *t, struct gatt_char *c,
-- 
1.7.9.5

--
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