All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/3] shared/gatt-client: Fix handling of services
@ 2015-03-16 10:32 Luiz Augusto von Dentz
  2015-03-16 10:32 ` [PATCH BlueZ 2/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test Luiz Augusto von Dentz
  2015-03-16 10:32 ` [PATCH BlueZ 3/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test Luiz Augusto von Dentz
  0 siblings, 2 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-16 10:32 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Remote services may contain gaps between their handles so they need to be
inserted in a proper position.
---
 src/shared/gatt-client.c |   8 ++--
 src/shared/gatt-db.c     | 122 +++++++++++++++++++++++++++++++++++++++--------
 src/shared/gatt-db.h     |  17 +++++++
 3 files changed, 123 insertions(+), 24 deletions(-)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index f33d8c9..3e28c6e 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -588,7 +588,8 @@ static bool discover_descs(struct discovery_op *op, bool *discovering)
 	*discovering = false;
 
 	while ((chrc_data = queue_pop_head(op->pending_chrcs))) {
-		attr = gatt_db_service_add_characteristic(op->cur_svc,
+		attr = gatt_db_service_insert_characteristic(op->cur_svc,
+							chrc_data->value_handle,
 							&chrc_data->uuid, 0,
 							chrc_data->properties,
 							NULL, NULL, NULL);
@@ -679,8 +680,9 @@ static void discover_descs_cb(bool success, uint8_t att_ecode,
 						"handle: 0x%04x, uuid: %s",
 						handle, uuid_str);
 
-		attr = gatt_db_service_add_descriptor(op->cur_svc, &uuid, 0,
-							NULL, NULL, NULL);
+		attr = gatt_db_service_insert_descriptor(op->cur_svc, handle,
+							&uuid, 0, NULL, NULL,
+							NULL);
 		if (!attr)
 			goto failed;
 
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index eb81372..29361af 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -158,6 +158,7 @@ static void attribute_destroy(struct gatt_db_attribute *attribute)
 }
 
 static struct gatt_db_attribute *new_attribute(struct gatt_db_service *service,
+							uint16_t handle,
 							const bt_uuid_t *type,
 							const uint8_t *val,
 							uint16_t len)
@@ -169,6 +170,7 @@ static struct gatt_db_attribute *new_attribute(struct gatt_db_service *service,
 		return NULL;
 
 	attribute->service = service;
+	attribute->handle = handle;
 	attribute->uuid = *type;
 	attribute->value_len = len;
 	if (len) {
@@ -371,6 +373,7 @@ static bool le_to_uuid(const uint8_t *src, size_t len, bt_uuid_t *uuid)
 }
 
 static struct gatt_db_service *gatt_db_service_create(const bt_uuid_t *uuid,
+							uint16_t handle,
 							bool primary,
 							uint16_t num_handles)
 {
@@ -399,7 +402,8 @@ static struct gatt_db_service *gatt_db_service_create(const bt_uuid_t *uuid,
 
 	len = uuid_to_le(uuid, value);
 
-	service->attributes[0] = new_attribute(service, type, value, len);
+	service->attributes[0] = new_attribute(service, handle, type, value,
+									len);
 	if (!service->attributes[0]) {
 		gatt_db_service_destroy(service);
 		return NULL;
@@ -533,7 +537,7 @@ struct gatt_db_attribute *gatt_db_insert_service(struct gatt_db *db,
 	if (!find_insert_loc(db, handle, handle + num_handles - 1, &after))
 		return NULL;
 
-	service = gatt_db_service_create(uuid, primary, num_handles);
+	service = gatt_db_service_create(uuid, handle, primary, num_handles);
 
 	if (!service)
 		return NULL;
@@ -663,8 +667,9 @@ static void set_attribute_data(struct gatt_db_attribute *attribute,
 	attribute->user_data = user_data;
 }
 
-struct gatt_db_attribute *
-gatt_db_service_add_characteristic(struct gatt_db_attribute *attrib,
+static struct gatt_db_attribute *
+service_insert_characteristic(struct gatt_db_service *service,
+					uint16_t handle,
 					const bt_uuid_t *uuid,
 					uint32_t permissions,
 					uint8_t properties,
@@ -672,35 +677,38 @@ gatt_db_service_add_characteristic(struct gatt_db_attribute *attrib,
 					gatt_db_write_t write_func,
 					void *user_data)
 {
-	struct gatt_db_service *service;
 	uint8_t value[MAX_CHAR_DECL_VALUE_LEN];
 	uint16_t len = 0;
 	int i;
 
-	if (!attrib)
+	/* Check if handle is in within service range */
+	if (handle && handle <= service->attributes[0]->handle)
 		return NULL;
 
-	service = attrib->service;
-
 	i = get_attribute_index(service, 1);
 	if (!i)
 		return NULL;
 
+	if (!handle)
+		handle = get_handle_at_index(service, i - 1) + 2;
+
 	value[0] = properties;
 	len += sizeof(properties);
+
 	/* We set handle of characteristic value, which will be added next */
-	put_le16(get_handle_at_index(service, i - 1) + 2, &value[1]);
+	put_le16(handle, &value[1]);
 	len += sizeof(uint16_t);
 	len += uuid_to_le(uuid, &value[3]);
 
-	service->attributes[i] = new_attribute(service, &characteristic_uuid,
-								value, len);
+	service->attributes[i] = new_attribute(service, handle - 1,
+							&characteristic_uuid,
+							value, len);
 	if (!service->attributes[i])
 		return NULL;
 
-	attribute_update(service, i++);
+	i++;
 
-	service->attributes[i] = new_attribute(service, uuid, NULL, 0);
+	service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0);
 	if (!service->attributes[i]) {
 		free(service->attributes[i - 1]);
 		return NULL;
@@ -709,37 +717,109 @@ gatt_db_service_add_characteristic(struct gatt_db_attribute *attrib,
 	set_attribute_data(service->attributes[i], read_func, write_func,
 							permissions, user_data);
 
-	return attribute_update(service, i);
+	return service->attributes[i];
 }
 
 struct gatt_db_attribute *
-gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib,
+gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib,
+					uint16_t handle,
 					const bt_uuid_t *uuid,
 					uint32_t permissions,
+					uint8_t properties,
 					gatt_db_read_t read_func,
 					gatt_db_write_t write_func,
 					void *user_data)
 {
-	struct gatt_db_service *service;
-	int i;
+	if (!attrib || !handle)
+		return NULL;
 
+	return service_insert_characteristic(attrib->service, handle, uuid,
+						permissions, properties,
+						read_func, write_func,
+						user_data);
+}
+
+struct gatt_db_attribute *
+gatt_db_service_add_characteristic(struct gatt_db_attribute *attrib,
+					const bt_uuid_t *uuid,
+					uint32_t permissions,
+					uint8_t properties,
+					gatt_db_read_t read_func,
+					gatt_db_write_t write_func,
+					void *user_data)
+{
 	if (!attrib)
 		return NULL;
 
-	service = attrib->service;
+	return service_insert_characteristic(attrib->service, 0, uuid,
+						permissions, properties,
+						read_func, write_func,
+						user_data);
+}
+
+static struct gatt_db_attribute *
+service_insert_descriptor(struct gatt_db_service *service,
+					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)
+{
+	int i;
 
 	i = get_attribute_index(service, 0);
 	if (!i)
 		return NULL;
 
-	service->attributes[i] = new_attribute(service, uuid, NULL, 0);
+	/* Check if handle is in within service range */
+	if (handle && handle <= service->attributes[0]->handle)
+		return NULL;
+
+	if (!handle)
+		handle = get_handle_at_index(service, i - 1) + 1;
+
+	service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0);
 	if (!service->attributes[i])
 		return NULL;
 
 	set_attribute_data(service->attributes[i], read_func, write_func,
 							permissions, user_data);
 
-	return attribute_update(service, i);
+	return service->attributes[i];
+}
+
+struct gatt_db_attribute *
+gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib,
+					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)
+{
+	if (!attrib || !handle)
+		return NULL;
+
+	return service_insert_descriptor(attrib->service, handle, uuid,
+					permissions, read_func, write_func,
+					user_data);
+}
+
+struct gatt_db_attribute *
+gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib,
+					const bt_uuid_t *uuid,
+					uint32_t permissions,
+					gatt_db_read_t read_func,
+					gatt_db_write_t write_func,
+					void *user_data)
+{
+	if (!attrib)
+		return NULL;
+
+	return service_insert_descriptor(attrib->service, 0, uuid,
+					permissions, read_func, write_func,
+					user_data);
 }
 
 struct gatt_db_attribute *
@@ -781,7 +861,7 @@ gatt_db_service_add_included(struct gatt_db_attribute *attrib,
 	if (!index)
 		return NULL;
 
-	service->attributes[index] = new_attribute(service,
+	service->attributes[index] = new_attribute(service, 0,
 							&included_service_uuid,
 							value, len);
 	if (!service->attributes[index])
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index 74b37bc..96cceb9 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -67,6 +67,15 @@ gatt_db_service_add_characteristic(struct gatt_db_attribute *attrib,
 					gatt_db_read_t read_func,
 					gatt_db_write_t write_func,
 					void *user_data);
+struct gatt_db_attribute *
+gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib,
+					uint16_t handle,
+					const bt_uuid_t *uuid,
+					uint32_t permissions,
+					uint8_t properties,
+					gatt_db_read_t read_func,
+					gatt_db_write_t write_func,
+					void *user_data);
 
 struct gatt_db_attribute *
 gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib,
@@ -75,6 +84,14 @@ gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib,
 					gatt_db_read_t read_func,
 					gatt_db_write_t write_func,
 					void *user_data);
+struct gatt_db_attribute *
+gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib,
+					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_service_add_included(struct gatt_db_attribute *attrib,
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH BlueZ 2/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test
  2015-03-16 10:32 [PATCH BlueZ 1/3] shared/gatt-client: Fix handling of services Luiz Augusto von Dentz
@ 2015-03-16 10:32 ` Luiz Augusto von Dentz
  2015-03-16 10:32 ` [PATCH BlueZ 3/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test Luiz Augusto von Dentz
  1 sibling, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-16 10:32 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This is similar to TP/GAD/CL/BV-06-C but using bt_gatt_client to
discover everything.
---
 unit/test-gatt.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 93ee2c7..33d4b9f 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -2269,6 +2269,10 @@ int main(int argc, char *argv[])
 			raw_pdu(0x05, 0x01, 0x15, 0x00, 0x04, 0x29, 0x16, 0x00,
 					0x05, 0x29));
 
+	define_test_client("/TP/GAD/CL/BV-06-C/client-1", test_client,
+			service_db_1, NULL,
+			SERVICE_DATA_1_PDUS);
+
 	define_test_server("/TP/GAD/SR/BV-06-C/small", test_server,
 			ts_small_db, NULL,
 			raw_pdu(0x03, 0x00, 0x02),
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH BlueZ 3/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test
  2015-03-16 10:32 [PATCH BlueZ 1/3] shared/gatt-client: Fix handling of services Luiz Augusto von Dentz
  2015-03-16 10:32 ` [PATCH BlueZ 2/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test Luiz Augusto von Dentz
@ 2015-03-16 10:32 ` Luiz Augusto von Dentz
  1 sibling, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-16 10:32 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This veryfy we the code is able to parse services with gaps between
handles.
---
 unit/test-gatt.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 109 insertions(+), 15 deletions(-)

diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 33d4b9f..7bc2d25 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -149,6 +149,35 @@ struct context {
 		raw_pdu(0x04, 0x08, 0x00, 0x08, 0x00),			\
 		raw_pdu(0x05, 0x01, 0x08, 0x00, 0x01, 0x29)
 
+#define SERVICE_DATA_2_PDUS						\
+		MTU_EXCHANGE_CLIENT_PDUS,				\
+		raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),	\
+		raw_pdu(0x11, 0x06, 0x01, 0x00, 0x04, 0x00, 0x01, 0x18),\
+		raw_pdu(0x10, 0x05, 0x00, 0xff, 0xff, 0x00, 0x28),	\
+		raw_pdu(0x11, 0x06, 0x05, 0x00, 0x0a, 0x00, 0x0d, 0x18),\
+		raw_pdu(0x10, 0x0b, 0x00, 0xff, 0xff, 0x00, 0x28),	\
+		raw_pdu(0x01, 0x10, 0x0b, 0x00, 0x0a),			\
+		raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28),	\
+		raw_pdu(0x01, 0x10, 0x01, 0x00, 0x0a),			\
+		raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x02, 0x28),	\
+		raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a),			\
+		raw_pdu(0x08, 0x05, 0x00, 0x0a, 0x00, 0x02, 0x28),	\
+		raw_pdu(0x01, 0x08, 0x05, 0x00, 0x0a),			\
+		raw_pdu(0x08, 0x01, 0x00, 0x04, 0x00, 0x03, 0x28),	\
+		raw_pdu(0x09, 0x07, 0x02, 0x00, 0x02, 0x03, 0x00, 0x00,	\
+				0x2a),					\
+		raw_pdu(0x08, 0x03, 0x00, 0x04, 0x00, 0x03, 0x28),	\
+		raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a),			\
+		raw_pdu(0x04, 0x04, 0x00, 0x04, 0x00),			\
+		raw_pdu(0x05, 0x01, 0x04, 0x00, 0x01, 0x29),		\
+		raw_pdu(0x08, 0x05, 0x00, 0x0a, 0x00, 0x03, 0x28),	\
+		raw_pdu(0x09, 0x07, 0x07, 0x00, 0x0a, 0x08, 0x00, 0x29,	\
+				0x2a),					\
+		raw_pdu(0x08, 0x08, 0x00, 0x0a, 0x00, 0x03, 0x28),	\
+		raw_pdu(0x01, 0x08, 0x08, 0x00, 0x0a),			\
+		raw_pdu(0x04, 0x09, 0x00, 0x0a, 0x00),			\
+		raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x01, 0x29)
+
 #define PRIMARY_DISC_SMALL_DB						\
 		raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28),	\
 		raw_pdu(0x11, 0x06, 0x10, 0xF0, 0x17, 0xF0, 0x00, 0x18,	\
@@ -966,16 +995,23 @@ static void att_write_cb(struct gatt_db_attribute *att, int err,
 	g_assert(!err);
 }
 
-static struct gatt_db_attribute *add_char_with_value(struct gatt_db *db,
-					struct gatt_db_attribute *service_att,
-					bt_uuid_t *uuid,
-					uint32_t att_permissions,
-					uint8_t char_properties,
-					const void *value, size_t len)
+static struct gatt_db_attribute *
+add_char_with_value(struct gatt_db_attribute *service_att, uint16_t handle,
+				bt_uuid_t *uuid, uint32_t att_permissions,
+				uint8_t char_properties, const void *value,
+				size_t len)
 {
 	struct gatt_db_attribute *attrib;
 
-	attrib = gatt_db_service_add_characteristic(service_att, uuid,
+	if (handle)
+		attrib = gatt_db_service_insert_characteristic(service_att,
+								handle, uuid,
+								att_permissions,
+								char_properties,
+								NULL, NULL,
+								NULL);
+	else
+		attrib = gatt_db_service_add_characteristic(service_att, uuid,
 								att_permissions,
 								char_properties,
 								NULL, NULL,
@@ -990,14 +1026,19 @@ static struct gatt_db_attribute *add_char_with_value(struct gatt_db *db,
 }
 
 static struct gatt_db_attribute *
-add_desc_with_value(struct gatt_db_attribute *att, bt_uuid_t *uuid,
-				uint32_t att_perms, const uint8_t *value,
-				size_t len)
+add_desc_with_value(struct gatt_db_attribute *att, uint16_t handle,
+					bt_uuid_t *uuid, uint32_t att_perms,
+					const uint8_t *value, size_t len)
 {
 	struct gatt_db_attribute *desc_att;
 
-	desc_att = gatt_db_service_add_descriptor(att, uuid, att_perms, NULL,
-								NULL, NULL);
+	if (handle)
+		desc_att = gatt_db_service_insert_descriptor(att, handle, uuid,
+							att_perms, NULL, NULL,
+							NULL);
+	else
+		desc_att = gatt_db_service_add_descriptor(att, uuid, att_perms,
+							NULL, NULL, NULL);
 
 	gatt_db_attribute_write(desc_att, 0, value, len, 0x00, NULL,
 							att_write_cb, NULL);
@@ -1124,7 +1165,7 @@ static struct gatt_db *make_db(const struct att_handle_spec *spec)
 		case CHARACTERISTIC:
 			bt_string_to_uuid(&uuid, spec->uuid);
 
-			add_char_with_value(db, att, &uuid,
+			add_char_with_value(att, spec->handle, &uuid,
 							spec->att_permissions,
 							spec->char_properties,
 							spec->value, spec->len);
@@ -1134,7 +1175,8 @@ static struct gatt_db *make_db(const struct att_handle_spec *spec)
 		case DESCRIPTOR:
 			bt_string_to_uuid(&uuid, spec->uuid);
 
-			add_desc_with_value(att, &uuid, spec->att_permissions,
+			add_desc_with_value(att, spec->handle, &uuid,
+							spec->att_permissions,
 							spec->value, spec->len);
 
 			break;
@@ -1168,6 +1210,52 @@ static struct gatt_db *make_service_data_1_db(void)
 	return make_db(specs);
 }
 
+#define CHARACTERISTIC_STR_AT(chr_handle, chr_uuid, permissions, properties, \
+								string) \
+	{								\
+		.valid = true,						\
+		.handle = chr_handle,					\
+		.type = CHARACTERISTIC,					\
+		.uuid = STR(chr_uuid),					\
+		.att_permissions = permissions,				\
+		.char_properties = properties,				\
+		.value = (uint8_t *)string,				\
+		.len = strlen(string),					\
+	}
+
+#define DESCRIPTOR_STR_AT(desc_handle, desc_uuid, permissions, string)	\
+	{								\
+		.valid = true,						\
+		.handle = desc_handle,					\
+		.type = DESCRIPTOR,					\
+		.uuid = STR(desc_uuid),					\
+		.att_permissions = permissions,				\
+		.value = (uint8_t *)string,				\
+		.len = strlen(string),					\
+	}
+
+static struct gatt_db *make_service_data_2_db(void)
+{
+	const struct att_handle_spec specs[] = {
+		PRIMARY_SERVICE(0x0001, GATT_UUID, 4),
+		CHARACTERISTIC_STR(GATT_CHARAC_DEVICE_NAME, BT_ATT_PERM_READ,
+					BT_GATT_CHRC_PROP_READ, "BlueZ"),
+		DESCRIPTOR_STR(GATT_CHARAC_USER_DESC_UUID, BT_ATT_PERM_READ,
+								"Device Name"),
+		PRIMARY_SERVICE(0x0005, HEART_RATE_UUID, 6),
+		CHARACTERISTIC_STR_AT(0x0008,
+					GATT_CHARAC_MANUFACTURER_NAME_STRING,
+					BT_ATT_PERM_READ,
+					BT_GATT_CHRC_PROP_READ |
+					BT_GATT_CHRC_PROP_WRITE, ""),
+		DESCRIPTOR_STR_AT(0x000a, GATT_CHARAC_USER_DESC_UUID,
+					BT_ATT_PERM_READ, "Manufacturer Name"),
+		{ }
+	};
+
+	return make_db(specs);
+}
+
 /*
  * Defined Test database 1:
  * Tiny database fits into a single minimum sized-pdu.
@@ -1961,11 +2049,13 @@ static const struct test_step test_indication_server_1 = {
 
 int main(int argc, char *argv[])
 {
-	struct gatt_db *service_db_1, *ts_small_db, *ts_large_db_1;
+	struct gatt_db *service_db_1, *service_db_2;
+	struct gatt_db *ts_small_db, *ts_large_db_1;
 
 	tester_init(&argc, &argv);
 
 	service_db_1 = make_service_data_1_db();
+	service_db_2 = make_service_data_2_db();
 	ts_small_db = make_test_spec_small_db();
 	ts_large_db_1 = make_test_spec_large_db_1();
 
@@ -2273,6 +2363,10 @@ int main(int argc, char *argv[])
 			service_db_1, NULL,
 			SERVICE_DATA_1_PDUS);
 
+	define_test_client("/TP/GAD/CL/BV-06-C/client-2", test_client,
+			service_db_2, NULL,
+			SERVICE_DATA_2_PDUS);
+
 	define_test_server("/TP/GAD/SR/BV-06-C/small", test_server,
 			ts_small_db, NULL,
 			raw_pdu(0x03, 0x00, 0x02),
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-03-16 10:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-16 10:32 [PATCH BlueZ 1/3] shared/gatt-client: Fix handling of services Luiz Augusto von Dentz
2015-03-16 10:32 ` [PATCH BlueZ 2/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test Luiz Augusto von Dentz
2015-03-16 10:32 ` [PATCH BlueZ 3/3] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.