Diff between 1731729841700d7de9fb7053544bd319336bc850 and d3c9f0e9b008cb2458cea86ff7aa07530a673a82

Changed Files

File Additions Deletions Status
src/shared/gatt-client.c +45 -14 modified
src/shared/gatt-client.h +20 -12 modified
tools/btgatt-client.c +18 -13 modified

Full Patch

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 1a157ec..fd866b2 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -40,6 +40,8 @@
 
 struct service_list {
 	bt_gatt_service_t service;
+	bt_gatt_characteristic_t *chrcs;
+	size_t num_chrcs;
 	struct service_list *next;
 };
 
@@ -93,14 +95,14 @@ static bool gatt_client_add_service(struct bt_gatt_client *client,
 	return true;
 }
 
-static void service_destroy_characteristics(bt_gatt_service_t *service)
+static void service_destroy_characteristics(struct service_list *service)
 {
 	unsigned int i;
 
 	for (i = 0; i < service->num_chrcs; i++)
 		free((bt_gatt_descriptor_t *) service->chrcs[i].descs);
 
-	free((bt_gatt_characteristic_t *) service->chrcs);
+	free(service->chrcs);
 }
 
 static void gatt_client_clear_services(struct bt_gatt_client *client)
@@ -110,7 +112,7 @@ static void gatt_client_clear_services(struct bt_gatt_client *client)
 	l = client->svc_head;
 
 	while (l) {
-		service_destroy_characteristics(&l->service);
+		service_destroy_characteristics(l);
 		tmp = l;
 		l = tmp->next;
 		free(tmp);
@@ -229,8 +231,7 @@ static void discover_descs_cb(bool success, uint8_t att_ecode,
 	op->cur_chrc->num_descs = desc_count;
 	op->cur_chrc->descs = descs;
 
-	for (i = op->cur_chrc_index + 1;
-				i < op->cur_service->service.num_chrcs; i++) {
+	for (i = op->cur_chrc_index + 1; i < op->cur_service->num_chrcs; i++) {
 		op->cur_chrc_index = i;
 		op->cur_chrc++;
 		desc_start = op->cur_chrc->value_handle + 1;
@@ -332,8 +333,8 @@ static void discover_chrcs_cb(bool success, uint8_t att_ecode,
 		i++;
 	}
 
-	op->cur_service->service.chrcs = chrcs;
-	op->cur_service->service.num_chrcs = chrc_count;
+	op->cur_service->chrcs = chrcs;
+	op->cur_service->num_chrcs = chrc_count;
 
 	for (i = 0; i < chrc_count; i++) {
 		op->cur_chrc_index = i;
@@ -627,7 +628,7 @@ bool bt_gatt_service_iter_init(struct bt_gatt_service_iter *iter,
 }
 
 bool bt_gatt_service_iter_next(struct bt_gatt_service_iter *iter,
-						bt_gatt_service_t *service)
+					const bt_gatt_service_t **service)
 {
 	struct service_list *l;
 
@@ -644,18 +645,18 @@ bool bt_gatt_service_iter_next(struct bt_gatt_service_iter *iter,
 	if (!l)
 		return false;
 
-	*service = l->service;
+	*service = &l->service;
 	iter->ptr = l;
 
 	return true;
 }
 
 bool bt_gatt_service_iter_next_by_handle(struct bt_gatt_service_iter *iter,
-						uint16_t start_handle,
-						bt_gatt_service_t *service)
+					uint16_t start_handle,
+					const bt_gatt_service_t **service)
 {
 	while (bt_gatt_service_iter_next(iter, service)) {
-		if (service->start_handle == start_handle)
+		if ((*service)->start_handle == start_handle)
 			return true;
 	}
 
@@ -664,16 +665,46 @@ bool bt_gatt_service_iter_next_by_handle(struct bt_gatt_service_iter *iter,
 
 bool bt_gatt_service_iter_next_by_uuid(struct bt_gatt_service_iter *iter,
 					const uint8_t uuid[BT_GATT_UUID_SIZE],
-					bt_gatt_service_t *service)
+					const bt_gatt_service_t **service)
 {
 	while (bt_gatt_service_iter_next(iter, service)) {
-		if (memcmp(service->uuid, uuid, UUID_BYTES) == 0)
+		if (memcmp((*service)->uuid, uuid, UUID_BYTES) == 0)
 			return true;
 	}
 
 	return false;
 }
 
+bool bt_gatt_characteristic_iter_init(struct bt_gatt_characteristic_iter *iter,
+					const bt_gatt_service_t *service)
+{
+	if (!iter || !service)
+		return false;
+
+	memset(iter, 0, sizeof(*iter));
+	iter->service = (struct service_list *) service;
+
+	return true;
+}
+
+bool bt_gatt_characteristic_iter_next(struct bt_gatt_characteristic_iter *iter,
+					const bt_gatt_characteristic_t **chrc)
+{
+	struct service_list *service;
+
+	if (!iter || !chrc)
+		return false;
+
+	service = iter->service;
+
+	if (iter->pos >= service->num_chrcs)
+		return false;
+
+	*chrc = service->chrcs + iter->pos++;
+
+	return true;
+}
+
 struct read_op {
 	bt_gatt_client_read_callback_t callback;
 	void *user_data;
diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
index 8b0d334..417d964 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -53,6 +53,12 @@ bool bt_gatt_client_set_debug(struct bt_gatt_client *client,
 					bt_gatt_client_destroy_func_t destroy);
 
 typedef struct {
+	uint16_t start_handle;
+	uint16_t end_handle;
+	uint8_t uuid[BT_GATT_UUID_SIZE];
+} bt_gatt_service_t;
+
+typedef struct {
 	uint16_t handle;
 	uint8_t uuid[BT_GATT_UUID_SIZE];
 } bt_gatt_descriptor_t;
@@ -67,29 +73,31 @@ typedef struct {
 	size_t num_descs;
 } bt_gatt_characteristic_t;
 
-typedef struct {
-	uint16_t start_handle;
-	uint16_t end_handle;
-	uint8_t uuid[BT_GATT_UUID_SIZE];
-	const bt_gatt_characteristic_t *chrcs;
-	size_t num_chrcs;
-} bt_gatt_service_t;
-
 struct bt_gatt_service_iter {
 	struct bt_gatt_client *client;
 	void *ptr;
 };
 
+struct bt_gatt_characteristic_iter {
+	void *service;
+	size_t pos;
+};
+
 bool bt_gatt_service_iter_init(struct bt_gatt_service_iter *iter,
 						struct bt_gatt_client *client);
 bool bt_gatt_service_iter_next(struct bt_gatt_service_iter *iter,
-						bt_gatt_service_t *service);
+					const bt_gatt_service_t **service);
 bool bt_gatt_service_iter_next_by_handle(struct bt_gatt_service_iter *iter,
-						uint16_t start_handle,
-						bt_gatt_service_t *service);
+					uint16_t start_handle,
+					const bt_gatt_service_t **service);
 bool bt_gatt_service_iter_next_by_uuid(struct bt_gatt_service_iter *iter,
 					const uint8_t uuid[BT_GATT_UUID_SIZE],
-					bt_gatt_service_t *service);
+					const bt_gatt_service_t **service);
+
+bool bt_gatt_characteristic_iter_init(struct bt_gatt_characteristic_iter *iter,
+					const bt_gatt_service_t *service);
+bool bt_gatt_characteristic_iter_next(struct bt_gatt_characteristic_iter *iter,
+					const bt_gatt_characteristic_t **chrc);
 
 typedef void (*bt_gatt_client_read_callback_t)(bool success, uint8_t att_ecode,
 					const uint8_t *value, uint16_t length,
diff --git a/tools/btgatt-client.c b/tools/btgatt-client.c
index d1395b2..8bde1ee 100644
--- a/tools/btgatt-client.c
+++ b/tools/btgatt-client.c
@@ -169,16 +169,21 @@ static void print_uuid(const uint8_t uuid[16])
 
 static void print_service(const bt_gatt_service_t *service)
 {
+	struct bt_gatt_characteristic_iter iter;
 	const bt_gatt_characteristic_t *chrc;
-	size_t i, j;
+	size_t i;
+
+	if (!bt_gatt_characteristic_iter_init(&iter, service)) {
+		PRLOG("Failed to initialize characteristic iterator\n");
+		return;
+	}
 
 	printf(COLOR_RED "service" COLOR_OFF " - start: 0x%04x, "
 				"end: 0x%04x, uuid: ",
 				service->start_handle, service->end_handle);
 	print_uuid(service->uuid);
 
-	for (i = 0; i < service->num_chrcs; i++) {
-		chrc = service->chrcs + i;
+	while (bt_gatt_characteristic_iter_next(&iter, &chrc)) {
 		printf("\t  " COLOR_YELLOW "charac" COLOR_OFF
 				" - start: 0x%04x, end: 0x%04x, "
 				"value: 0x%04x, props: 0x%02x, uuid: ",
@@ -186,13 +191,13 @@ static void print_service(const bt_gatt_service_t *service)
 				chrc->end_handle,
 				chrc->value_handle,
 				chrc->properties);
-		print_uuid(service->chrcs[i].uuid);
+		print_uuid(chrc->uuid);
 
-		for (j = 0; j < chrc->num_descs; j++) {
+		for (i = 0; i < chrc->num_descs; i++) {
 			printf("\t\t  " COLOR_MAGENTA "descr" COLOR_OFF
 						" - handle: 0x%04x, uuid: ",
-						chrc->descs[j].handle);
-			print_uuid(chrc->descs[j].uuid);
+						chrc->descs[i].handle);
+			print_uuid(chrc->descs[i].uuid);
 		}
 	}
 
@@ -202,7 +207,7 @@ static void print_service(const bt_gatt_service_t *service)
 static void print_services(struct client *cli)
 {
 	struct bt_gatt_service_iter iter;
-	bt_gatt_service_t service;
+	const bt_gatt_service_t *service;
 
 	if (!bt_gatt_service_iter_init(&iter, cli->gatt)) {
 		PRLOG("Failed to initialize service iterator\n");
@@ -212,13 +217,13 @@ static void print_services(struct client *cli)
 	printf("\n");
 
 	while (bt_gatt_service_iter_next(&iter, &service))
-		print_service(&service);
+		print_service(service);
 }
 
 static void print_services_by_uuid(struct client *cli, const bt_uuid_t *uuid)
 {
 	struct bt_gatt_service_iter iter;
-	bt_gatt_service_t service;
+	const bt_gatt_service_t *service;
 
 	if (!bt_gatt_service_iter_init(&iter, cli->gatt)) {
 		PRLOG("Failed to initialize service iterator\n");
@@ -229,13 +234,13 @@ static void print_services_by_uuid(struct client *cli, const bt_uuid_t *uuid)
 
 	while (bt_gatt_service_iter_next_by_uuid(&iter, uuid->value.u128.data,
 								&service))
-		print_service(&service);
+		print_service(service);
 }
 
 static void print_services_by_handle(struct client *cli, uint16_t handle)
 {
 	struct bt_gatt_service_iter iter;
-	bt_gatt_service_t service;
+	const bt_gatt_service_t *service;
 
 	if (!bt_gatt_service_iter_init(&iter, cli->gatt)) {
 		PRLOG("Failed to initialize service iterator\n");
@@ -245,7 +250,7 @@ static void print_services_by_handle(struct client *cli, uint16_t handle)
 	printf("\n");
 
 	while (bt_gatt_service_iter_next_by_handle(&iter, handle, &service))
-		print_service(&service);
+		print_service(service);
 }
 
 static void ready_cb(bool success, uint8_t att_ecode, void *user_data)