* [PATCH BlueZ 1/5] shared/gatt-client: Fix handling of services
2015-03-18 21:04 [PATCH BlueZ] build: Add missing docs to EXTRA_DIST Luiz Augusto von Dentz
@ 2015-03-18 21:04 ` Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 2/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test Luiz Augusto von Dentz
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-18 21:04 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] 9+ messages in thread* [PATCH BlueZ 2/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test
2015-03-18 21:04 [PATCH BlueZ] build: Add missing docs to EXTRA_DIST Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 1/5] shared/gatt-client: Fix handling of services Luiz Augusto von Dentz
@ 2015-03-18 21:04 ` Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 3/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test Luiz Augusto von Dentz
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-18 21:04 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] 9+ messages in thread* [PATCH BlueZ 3/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test
2015-03-18 21:04 [PATCH BlueZ] build: Add missing docs to EXTRA_DIST Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 1/5] shared/gatt-client: Fix handling of services Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 2/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-1 test Luiz Augusto von Dentz
@ 2015-03-18 21:04 ` Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 4/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-3 test Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery Luiz Augusto von Dentz
4 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-18 21:04 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] 9+ messages in thread* [PATCH BlueZ 4/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-3 test
2015-03-18 21:04 [PATCH BlueZ] build: Add missing docs to EXTRA_DIST Luiz Augusto von Dentz
` (2 preceding siblings ...)
2015-03-18 21:04 ` [PATCH BlueZ 3/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-2 test Luiz Augusto von Dentz
@ 2015-03-18 21:04 ` Luiz Augusto von Dentz
2015-03-18 21:04 ` [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery Luiz Augusto von Dentz
4 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-18 21:04 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This verify the code is able to parse services with different gaps
between handles.
---
unit/test-gatt.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 7bc2d25..d510f51 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -178,6 +178,36 @@ struct context {
raw_pdu(0x04, 0x09, 0x00, 0x0a, 0x00), \
raw_pdu(0x05, 0x01, 0x0a, 0x00, 0x01, 0x29)
+#define SERVICE_DATA_3_PDUS \
+ MTU_EXCHANGE_CLIENT_PDUS, \
+ raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x06, 0x00, 0x01, 0x21, 0x01, 0x00, 0x18, \
+ 0x00, 0x02, 0x00, 0x02, 0x01, 0x18), \
+ raw_pdu(0x10, 0x01, 0x02, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x11, 0x06, 0x00, 0x03, 0x20, 0x03, 0x0d, 0x18),\
+ raw_pdu(0x10, 0x21, 0x03, 0xff, 0xff, 0x00, 0x28), \
+ raw_pdu(0x01, 0x10, 0x21, 0x03, 0x0a), \
+ raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x01, 0x28), \
+ raw_pdu(0x01, 0x10, 0x01, 0x00, 0x0a), \
+ raw_pdu(0x08, 0x00, 0x01, 0x21, 0x01, 0x02, 0x28), \
+ raw_pdu(0x01, 0x08, 0x00, 0x01, 0x0a), \
+ raw_pdu(0x08, 0x00, 0x03, 0x20, 0x03, 0x02, 0x28), \
+ raw_pdu(0x01, 0x08, 0x00, 0x03, 0x0a), \
+ raw_pdu(0x08, 0x00, 0x01, 0x21, 0x01, 0x03, 0x28), \
+ raw_pdu(0x09, 0x07, 0x10, 0x01, 0x02, 0x11, 0x01, 0x00, \
+ 0x2a, 0x20, 0x01, 0x02, 0x21, 0x01, 0x01, 0x2a),\
+ raw_pdu(0x08, 0x21, 0x01, 0x21, 0x01, 0x03, 0x28), \
+ raw_pdu(0x01, 0x08, 0x21, 0x01, 0x0a), \
+ raw_pdu(0x04, 0x12, 0x01, 0x1f, 0x01), \
+ raw_pdu(0x01, 0x04, 0x12, 0x01, 0x0a), \
+ raw_pdu(0x08, 0x00, 0x03, 0x20, 0x03, 0x03, 0x28), \
+ raw_pdu(0x09, 0x07, 0x10, 0x03, 0x0a, 0x11, 0x03, 0x29, \
+ 0x2a), \
+ raw_pdu(0x08, 0x11, 0x03, 0x20, 0x03, 0x03, 0x28), \
+ raw_pdu(0x01, 0x08, 0x11, 0x03, 0x0a), \
+ raw_pdu(0x04, 0x12, 0x03, 0x20, 0x03), \
+ raw_pdu(0x01, 0x04, 0x12, 0x03, 0x0a) \
+
#define PRIMARY_DISC_SMALL_DB \
raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \
raw_pdu(0x11, 0x06, 0x10, 0xF0, 0x17, 0xF0, 0x00, 0x18, \
@@ -1256,6 +1286,42 @@ static struct gatt_db *make_service_data_2_db(void)
return make_db(specs);
}
+#define CHARACTERISTIC_AT(chr_handle, chr_uuid, permissions, properties, \
+ bytes...) \
+ { \
+ .valid = true, \
+ .handle = chr_handle, \
+ .type = CHARACTERISTIC, \
+ .uuid = STR(chr_uuid), \
+ .att_permissions = permissions, \
+ .char_properties = properties, \
+ .value = data(bytes), \
+ .len = sizeof(data(bytes)), \
+ }
+
+static struct gatt_db *make_service_data_3_db(void)
+{
+ const struct att_handle_spec specs[] = {
+ PRIMARY_SERVICE(0x0100, GAP_UUID, 0x0121 - 0x0100 + 1),
+ CHARACTERISTIC_STR_AT(0x0111, GATT_CHARAC_DEVICE_NAME,
+ BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, "BlueZ"),
+ CHARACTERISTIC_AT(0x0121, GATT_CHARAC_APPEARANCE,
+ BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ, 0x00, 0x00),
+ PRIMARY_SERVICE(0x0200, GATT_UUID, 0x0200 - 0x0200 + 1),
+ PRIMARY_SERVICE(0x0300, HEART_RATE_UUID, 0x0320 - 0x0300 + 1),
+ CHARACTERISTIC_STR_AT(0x0311,
+ GATT_CHARAC_MANUFACTURER_NAME_STRING,
+ BT_ATT_PERM_READ,
+ BT_GATT_CHRC_PROP_READ |
+ BT_GATT_CHRC_PROP_WRITE, ""),
+ { }
+ };
+
+ return make_db(specs);
+}
+
/*
* Defined Test database 1:
* Tiny database fits into a single minimum sized-pdu.
@@ -2049,13 +2115,14 @@ static const struct test_step test_indication_server_1 = {
int main(int argc, char *argv[])
{
- struct gatt_db *service_db_1, *service_db_2;
+ struct gatt_db *service_db_1, *service_db_2, *service_db_3;
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();
+ service_db_3 = make_service_data_3_db();
ts_small_db = make_test_spec_small_db();
ts_large_db_1 = make_test_spec_large_db_1();
@@ -2367,6 +2434,10 @@ int main(int argc, char *argv[])
service_db_2, NULL,
SERVICE_DATA_2_PDUS);
+ define_test_client("/TP/GAD/CL/BV-06-C/client-3", test_client,
+ service_db_3, NULL,
+ SERVICE_DATA_3_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] 9+ messages in thread* [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery
2015-03-18 21:04 [PATCH BlueZ] build: Add missing docs to EXTRA_DIST Luiz Augusto von Dentz
` (3 preceding siblings ...)
2015-03-18 21:04 ` [PATCH BlueZ 4/5] unit/test-gatt: Add /TP/GAD/CL/BV-06-C/client-3 test Luiz Augusto von Dentz
@ 2015-03-18 21:04 ` Luiz Augusto von Dentz
2015-03-19 7:36 ` Andrejs Hanins
4 siblings, 1 reply; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-18 21:04 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
The code should proceed to discover all descriptors before moving to
next service otherwise it may attempt to insert characteristics in the
wrong service which would probably fail.
---
src/shared/gatt-client.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 3e28c6e..729bd87 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -690,13 +690,13 @@ static void discover_descs_cb(bool success, uint8_t att_ecode,
goto failed;
}
+next:
if (!discover_descs(op, &discovering))
goto failed;
if (discovering)
return;
-next:
/* Done with the current service */
gatt_db_service_set_active(op->cur_svc, true);
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery
2015-03-18 21:04 ` [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery Luiz Augusto von Dentz
@ 2015-03-19 7:36 ` Andrejs Hanins
2015-03-19 10:17 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 9+ messages in thread
From: Andrejs Hanins @ 2015-03-19 7:36 UTC (permalink / raw)
To: Luiz Augusto von Dentz, linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 1492 bytes --]
Hi Luiz
On 2015.03.18. 23:04, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> The code should proceed to discover all descriptors before moving to
> next service otherwise it may attempt to insert characteristics in the
> wrong service which would probably fail.
> ---
> src/shared/gatt-client.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
> index 3e28c6e..729bd87 100644
> --- a/src/shared/gatt-client.c
> +++ b/src/shared/gatt-client.c
> @@ -690,13 +690,13 @@ static void discover_descs_cb(bool success, uint8_t att_ecode,
> goto failed;
> }
>
> +next:
> if (!discover_descs(op, &discovering))
> goto failed;
>
> if (discovering)
> return;
>
> -next:
> /* Done with the current service */
> gatt_db_service_set_active(op->cur_svc, true);
>
>
I tested this new patch-set and and results are the following:
1. Three characteristics (GAP, GATT and custom) do appear on D-BUs. This was not the case before.
2. CCC descriptor still does not appear on D-Bus. If I change handles on the peripheral back to sequential, then CCC appears on D-Bus also.
3. Reading of any characteristic times out with 'g-io-error-quark: Timeout was reached (24)'. Logs attached. Based on HCI dumps the ATT reading is OK, but for some reason result is not propagated to the D-Bus level, so D-Dbus method times out. With sequential handles reading works fine.
[-- Attachment #2: bluez_fix2.log --]
[-- Type: text/x-log, Size: 12884 bytes --]
bluetoothd[700]: Bluetooth daemon 5.29
bluetoothd[700]: src/main.c:parse_config() parsing main.conf
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'DiscoverableTimeout'
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'PairableTimeout'
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'AutoConnectTimeout'
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'Name'
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'Class'
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'DeviceID'
bluetoothd[700]: src/main.c:parse_config() Key file does not have key 'ReverseServiceDiscovery'
bluetoothd[700]: src/main.c:parse_config() ControllerMode=le
bluetoothd[700]: src/adapter.c:adapter_init() sending read version command
bluetoothd[700]: Starting SDP server
bluetoothd[700]: src/sdpd-service.c:register_device_id() Adding device id record for 0002:1d6b:0246:051d
bluetoothd[700]: src/plugin.c:plugin_init() Loading builtin plugins
bluetoothd[700]: src/plugin.c:add_plugin() Loading hostname plugin
bluetoothd[700]: Ignoring (cli) wiimote
bluetoothd[700]: Ignoring (cli) autopair
bluetoothd[700]: Ignoring (cli) policy
bluetoothd[700]: Ignoring (cli) gatt_example
bluetoothd[700]: Ignoring (cli) neard
bluetoothd[700]: Ignoring (cli) sap
bluetoothd[700]: Ignoring (cli) a2dp
bluetoothd[700]: Ignoring (cli) avrcp
bluetoothd[700]: Ignoring (cli) network
bluetoothd[700]: Ignoring (cli) input
bluetoothd[700]: Ignoring (cli) hog
bluetoothd[700]: Ignoring (cli) health
bluetoothd[700]: Ignoring (cli) gap
bluetoothd[700]: Ignoring (cli) scanparam
bluetoothd[700]: Ignoring (cli) deviceinfo
bluetoothd[700]: Ignoring (cli) alert
bluetoothd[700]: Ignoring (cli) time
bluetoothd[700]: Ignoring (cli) proximity
bluetoothd[700]: Ignoring (cli) thermometer
bluetoothd[700]: Ignoring (cli) heartrate
bluetoothd[700]: Ignoring (cli) cyclingspeed
bluetoothd[700]: src/plugin.c:plugin_init() Loading plugins /home/andrey/git/bluez/plugins/.libs
bluetoothd[700]: Ignoring (cli) external_dummy
bluetoothd[700]: src/main.c:main() Entering main loop
bluetoothd[700]: src/rfkill.c:rfkill_event() RFKILL event idx 4 type 2 op 0 soft 0 hard 0
bluetoothd[700]: Bluetooth management interface 1.8 initialized
bluetoothd[700]: src/adapter.c:read_version_complete() sending read supported commands command
bluetoothd[700]: src/adapter.c:read_version_complete() sending read index list command
bluetoothd[700]: src/adapter.c:read_commands_complete() Number of commands: 56
bluetoothd[700]: src/adapter.c:read_commands_complete() Number of events: 29
bluetoothd[700]: src/adapter.c:read_commands_complete() enabling kernel-side connection control
bluetoothd[700]: src/adapter.c:read_index_list_complete() Number of controllers: 1
bluetoothd[700]: src/adapter.c:read_index_list_complete() Found index 0
bluetoothd[700]: src/adapter.c:index_added() index 0
bluetoothd[700]: src/adapter.c:btd_adapter_new() System name: BlueZ 5.29
bluetoothd[700]: src/adapter.c:btd_adapter_new() Major class: 0
bluetoothd[700]: src/adapter.c:btd_adapter_new() Minor class: 0
bluetoothd[700]: src/adapter.c:btd_adapter_new() Modalias: usb:v1D6Bp0246d051D
bluetoothd[700]: src/adapter.c:btd_adapter_new() Discoverable timeout: 180 seconds
bluetoothd[700]: src/adapter.c:btd_adapter_new() Pairable timeout: 0 seconds
bluetoothd[700]: src/adapter.c:index_added() sending read info command for index 0
bluetoothd[700]: src/adapter.c:read_info_complete() index 0 status 0x00
bluetoothd[700]: src/adapter.c:clear_uuids() sending clear uuids command for index 0
bluetoothd[700]: src/adapter.c:clear_devices() sending clear devices command for index 0
bluetoothd[700]: src/gatt-database.c:btd_gatt_database_new() GATT Manager registered for adapter: /org/bluez/hci0
bluetoothd[700]: src/adapter.c:adapter_service_add() /org/bluez/hci0
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Adding record with handle 0x10001
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00000007-0000-1000-8000-00805f9
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00000100-0000-1000-8000-00805f9
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00001002-0000-1000-8000-00805f9
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00001800-0000-1000-8000-00805f9
bluetoothd[700]: src/adapter.c:adapter_service_insert() /org/bluez/hci0
bluetoothd[700]: src/adapter.c:add_uuid() sending add uuid command for index 0
bluetoothd[700]: src/gatt-database.c:gatt_db_service_added() GATT Service added to local database
bluetoothd[700]: Failed to obtain handles for "Service Changed" characteristic
bluetoothd[700]: src/adapter.c:adapter_service_add() /org/bluez/hci0
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Adding record with handle 0x10002
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00000007-0000-1000-8000-00805f9
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00000100-0000-1000-8000-00805f9
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00001002-0000-1000-8000-00805f9
bluetoothd[700]: src/sdpd-service.c:add_record_to_server() Record pattern UUID 00001801-0000-1000-8000-00805f9
bluetoothd[700]: src/adapter.c:adapter_service_insert() /org/bluez/hci0
bluetoothd[700]: src/adapter.c:add_uuid() sending add uuid command for index 0
bluetoothd[700]: src/gatt-database.c:gatt_db_service_added() GATT Service added to local database
bluetoothd[700]: plugins/hostname.c:hostname_probe()
bluetoothd[700]: src/adapter.c:btd_adapter_unblock_address() hci0 00:00:00:00:00:00
bluetoothd[700]: src/adapter.c:get_ltk_info() 20:73:6A:17:69:31
bluetoothd[700]: src/device.c:device_create_from_storage() address 20:73:6A:17:69:31
bluetoothd[700]: src/device.c:device_new() address 20:73:6A:17:69:31
bluetoothd[700]: src/device.c:device_new() Creating device /org/bluez/hci0/dev_20_73_6A_17_69_31
bluetoothd[700]: src/device.c:btd_device_set_temporary() temporary 0
bluetoothd[700]: src/device.c:device_probe_profiles() Probing profiles for device 20:73:6A:17:69:31
bluetoothd[700]: src/adapter.c:load_link_keys() hci0 keys 0 debug_keys 0
bluetoothd[700]: src/adapter.c:load_ltks() hci0 keys 0
bluetoothd[700]: src/adapter.c:load_irks() hci0 irks 0
bluetoothd[700]: src/adapter.c:load_conn_params() hci0 conn params 0
bluetoothd[700]: src/adapter.c:adapter_service_insert() /org/bluez/hci0
bluetoothd[700]: src/adapter.c:add_uuid() sending add uuid command for index 0
bluetoothd[700]: src/adapter.c:set_did() hci0 source 2 vendor 1d6b product 246 version 51d
bluetoothd[700]: src/adapter.c:adapter_register() Adapter /org/bluez/hci0 registered
bluetoothd[700]: src/adapter.c:set_dev_class() sending set device class command for index 0
bluetoothd[700]: src/adapter.c:set_name() sending set local name command for index 0
bluetoothd[700]: src/adapter.c:load_link_keys_complete() link keys loaded for hci0
bluetoothd[700]: src/adapter.c:load_ltks_complete() LTKs loaded for hci0
bluetoothd[700]: src/adapter.c:load_irks_complete() IRKs loaded for hci0
bluetoothd[700]: src/adapter.c:load_conn_params_complete() Connection Parameters loaded for hci0
bluetoothd[700]: src/adapter.c:local_name_changed_callback() Name: BlueZ 5.29
bluetoothd[700]: src/adapter.c:local_name_changed_callback() Short name:
bluetoothd[700]: src/adapter.c:local_name_changed_callback() Current alias: BlueZ 5.29
bluetoothd[700]: plugins/hostname.c:property_changed() static hostname: UFHR
bluetoothd[700]: plugins/hostname.c:property_changed() pretty hostname:
bluetoothd[700]: plugins/hostname.c:update_name() name: UFHR
bluetoothd[700]: src/adapter.c:adapter_set_name() name: UFHR
bluetoothd[700]: src/adapter.c:adapter_set_name() alias: UFHR
bluetoothd[700]: src/adapter.c:set_name() sending set local name command for index 0
bluetoothd[700]: plugins/hostname.c:property_changed() chassis: vm
bluetoothd[700]: src/adapter.c:local_name_changed_callback() Name: UFHR
bluetoothd[700]: src/adapter.c:local_name_changed_callback() Short name:
bluetoothd[700]: src/adapter.c:local_name_changed_callback() Current alias: UFHR
bluetoothd[700]: src/adapter.c:new_settings_callback() Settings: 0x00000a11
bluetoothd[700]: src/adapter.c:settings_changed() Changed settings: 0x00000001
bluetoothd[700]: src/adapter.c:adapter_start() adapter /org/bluez/hci0 has been enabled
bluetoothd[700]: src/adapter.c:trigger_passive_scanning()
bluetoothd[700]: src/adapter.c:start_discovery() sender :1.60
bluetoothd[700]: src/adapter.c:trigger_start_discovery()
bluetoothd[700]: src/adapter.c:cancel_passive_scanning()
bluetoothd[700]: src/adapter.c:start_discovery_timeout()
bluetoothd[700]: src/adapter.c:start_discovery_complete() status 0x00
bluetoothd[700]: src/adapter.c:discovering_callback() hci0 type 6 discovering 1
bluetoothd[700]: src/adapter.c:device_found_callback() hci0 addr 60:03:08:D2:5B:20, rssi -70 flags 0x0000 eir_len 15
bluetoothd[700]: src/device.c:device_create() dst 60:03:08:D2:5B:20
bluetoothd[700]: src/device.c:device_new() address 60:03:08:D2:5B:20
bluetoothd[700]: src/device.c:device_new() Creating device /org/bluez/hci0/dev_60_03_08_D2_5B_20
bluetoothd[700]: src/device.c:device_set_legacy() legacy 0
bluetoothd[700]: src/device.c:device_set_rssi() rssi -70
bluetoothd[700]: src/adapter.c:device_found_callback() hci0 addr 20:73:6A:17:69:31, rssi -67 flags 0x0000 eir_len 35
bluetoothd[700]: src/device.c:device_set_legacy() legacy 0
bluetoothd[700]: src/device.c:device_set_rssi() rssi -67
bluetoothd[700]: src/adapter.c:stop_discovery() sender :1.60
bluetoothd[700]: src/adapter.c:discovery_destroy() owner :1.60
bluetoothd[700]: src/device.c:device_set_rssi() rssi 0
bluetoothd[700]: src/device.c:device_set_rssi() rssi 0
bluetoothd[700]: src/adapter.c:stop_discovery_complete() status 0x00
bluetoothd[700]: src/adapter.c:trigger_passive_scanning()
bluetoothd[700]: src/adapter.c:discovering_callback() hci0 type 6 discovering 0
bluetoothd[700]: src/device.c:device_connect_le() Connection attempt to: 20:73:6A:17:69:31
bluetoothd[700]: src/adapter.c:connected_callback() hci0 device 20:73:6A:17:69:31 connected eir_len 0
bluetoothd[700]: attrib/gattrib.c:g_attrib_ref() 0x1f60d00: g_attrib_ref=1
bluetoothd[700]: src/device.c:gatt_debug() MTU exchange complete, with MTU: 23
bluetoothd[700]: src/device.c:gatt_debug() Primary services found: 3
bluetoothd[700]: src/device.c:gatt_debug() start: 0x0100, end: 0x0121, uuid: 00001800-0000-1000-8000-00805f9b34fb
bluetoothd[700]: src/device.c:gatt_debug() start: 0x0200, end: 0x0200, uuid: 00001801-0000-1000-8000-00805f9b34fb
bluetoothd[700]: src/device.c:gatt_debug() start: 0x0300, end: 0x0320, uuid: 8832ab08-ba2d-0184-004c-68c08e2190bf
bluetoothd[700]: src/device.c:gatt_debug() Secondary service discovery failed. ATT ECODE: 0x0a
bluetoothd[700]: src/device.c:gatt_debug() Characteristics found: 2
bluetoothd[700]: src/device.c:gatt_debug() start: 0x0110, end: 0x011f, value: 0x0111, props: 0x02, uuid: 00002a00-0000-1
bluetoothd[700]: src/device.c:gatt_debug() start: 0x0120, end: 0x0121, value: 0x0121, props: 0x02, uuid: 00002a01-0000-1
bluetoothd[700]: src/device.c:gatt_debug() Characteristics found: 1
bluetoothd[700]: src/device.c:gatt_debug() start: 0x0310, end: 0x0320, value: 0x0311, props: 0x3e, uuid: 361e118a-5524-2
bluetoothd[700]: src/device.c:gatt_debug() Descriptors found: 1
bluetoothd[700]: src/device.c:gatt_debug() handle: 0x0320, uuid: 00002902-0000-1000-8000-00805f9b34fb
bluetoothd[700]: src/device.c:gatt_client_ready_cb() status: success, error: 0
bluetoothd[700]: src/device.c:device_svc_resolved() /org/bluez/hci0/dev_20_73_6A_17_69_31 err 0
bluetoothd[700]: src/gatt-client.c:btd_gatt_client_ready() GATT client ready
bluetoothd[700]: src/gatt-client.c:btd_gatt_client_ready() Exporting services
bluetoothd[700]: src/gatt-client.c:create_services() Exporting objects for GATT services: 20:73:6A:17:69:31
bluetoothd[700]: src/gatt-client.c:service_create() Exported GATT service: /org/bluez/hci0/dev_20_73_6A_17_69_31/service0100
bluetoothd[700]: src/gatt-client.c:characteristic_create() Exported GATT characteristic: /org/bluez/hci0/dev_20_73_6A_17_69_31/service0100/char0110
bluetoothd[700]: src/gatt-client.c:characteristic_create() Exported GATT characteristic: /org/bluez/hci0/dev_20_73_6A_17_69_31/service0100/char0120
bluetoothd[700]: src/gatt-client.c:service_create() Exported GATT service: /org/bluez/hci0/dev_20_73_6A_17_69_31/service0200
bluetoothd[700]: src/gatt-client.c:service_create() Exported GATT service: /org/bluez/hci0/dev_20_73_6A_17_69_31/service0300
bluetoothd[700]: src/gatt-client.c:characteristic_create() Exported GATT characteristic: /org/bluez/hci0/dev_20_73_6A_17_69_31/service0300/char0310
[-- Attachment #3: noncons_handles_fix2.dump --]
[-- Type: application/octet-stream, Size: 1611 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery
2015-03-19 7:36 ` Andrejs Hanins
@ 2015-03-19 10:17 ` Luiz Augusto von Dentz
2015-03-19 10:56 ` Luiz Augusto von Dentz
0 siblings, 1 reply; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-19 10:17 UTC (permalink / raw)
To: Andrejs Hanins; +Cc: linux-bluetooth@vger.kernel.org
Hi Andrejs,
On Thu, Mar 19, 2015 at 9:36 AM, Andrejs Hanins <andrejs.hanins@ubnt.com> wrote:
> Hi Luiz
>
> On 2015.03.18. 23:04, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> The code should proceed to discover all descriptors before moving to
>> next service otherwise it may attempt to insert characteristics in the
>> wrong service which would probably fail.
>> ---
>> src/shared/gatt-client.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
>> index 3e28c6e..729bd87 100644
>> --- a/src/shared/gatt-client.c
>> +++ b/src/shared/gatt-client.c
>> @@ -690,13 +690,13 @@ static void discover_descs_cb(bool success, uint8_t att_ecode,
>> goto failed;
>> }
>>
>> +next:
>> if (!discover_descs(op, &discovering))
>> goto failed;
>>
>> if (discovering)
>> return;
>>
>> -next:
>> /* Done with the current service */
>> gatt_db_service_set_active(op->cur_svc, true);
>>
>>
>
> I tested this new patch-set and and results are the following:
> 1. Three characteristics (GAP, GATT and custom) do appear on D-BUs. This was not the case before.
> 2. CCC descriptor still does not appear on D-Bus. If I change handles on the peripheral back to sequential, then CCC appears on D-Bus also.
> 3. Reading of any characteristic times out with 'g-io-error-quark: Timeout was reached (24)'. Logs attached. Based on HCI dumps the ATT reading is OK, but for some reason result is not propagated to the D-Bus level, so D-Dbus method times out. With sequential handles reading works fine.
Strange for me it is working normally:
[NEW] Service /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011
Battery Service (Primary)
[NEW] Characteristic
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012 Battery
Level
[NEW] Descriptor
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
Client Characteristic Configuration
[Arc Touch Mouse SE]# select-attribute
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012
[Arc Touch Mouse SE:/service0011/char0012]# read
Attempting to read /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012
[CHG] Attribute
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012 Value: 0x5d
5d ]
[Arc Touch Mouse SE:/service0011/char0012]# select-attribute
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
[Arc Touch Mouse SE:/service0011/char0012/desc0014]# read
Attempting to read
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
[CHG] Attribute
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
Value: 0x00
[CHG] Attribute
/org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
Value: 0x00
00 00
But perhaps this is because the handles are in sequence as you said,
can you try with the following changes:
http://fpaste.org/199962/67601931/
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH BlueZ 5/5] shared/gatt-client: Fix service discovery
2015-03-19 10:17 ` Luiz Augusto von Dentz
@ 2015-03-19 10:56 ` Luiz Augusto von Dentz
0 siblings, 0 replies; 9+ messages in thread
From: Luiz Augusto von Dentz @ 2015-03-19 10:56 UTC (permalink / raw)
To: Andrejs Hanins; +Cc: linux-bluetooth@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 3361 bytes --]
Hi Andrejs,
On Thu, Mar 19, 2015 at 12:17 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Andrejs,
>
> On Thu, Mar 19, 2015 at 9:36 AM, Andrejs Hanins <andrejs.hanins@ubnt.com> wrote:
>> Hi Luiz
>>
>> On 2015.03.18. 23:04, Luiz Augusto von Dentz wrote:
>>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>>
>>> The code should proceed to discover all descriptors before moving to
>>> next service otherwise it may attempt to insert characteristics in the
>>> wrong service which would probably fail.
>>> ---
>>> src/shared/gatt-client.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
>>> index 3e28c6e..729bd87 100644
>>> --- a/src/shared/gatt-client.c
>>> +++ b/src/shared/gatt-client.c
>>> @@ -690,13 +690,13 @@ static void discover_descs_cb(bool success, uint8_t att_ecode,
>>> goto failed;
>>> }
>>>
>>> +next:
>>> if (!discover_descs(op, &discovering))
>>> goto failed;
>>>
>>> if (discovering)
>>> return;
>>>
>>> -next:
>>> /* Done with the current service */
>>> gatt_db_service_set_active(op->cur_svc, true);
>>>
>>>
>>
>> I tested this new patch-set and and results are the following:
>> 1. Three characteristics (GAP, GATT and custom) do appear on D-BUs. This was not the case before.
>> 2. CCC descriptor still does not appear on D-Bus. If I change handles on the peripheral back to sequential, then CCC appears on D-Bus also.
>> 3. Reading of any characteristic times out with 'g-io-error-quark: Timeout was reached (24)'. Logs attached. Based on HCI dumps the ATT reading is OK, but for some reason result is not propagated to the D-Bus level, so D-Dbus method times out. With sequential handles reading works fine.
>
> Strange for me it is working normally:
>
> [NEW] Service /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011
> Battery Service (Primary)
> [NEW] Characteristic
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012 Battery
> Level
> [NEW] Descriptor
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
> Client Characteristic Configuration
> [Arc Touch Mouse SE]# select-attribute
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012
> [Arc Touch Mouse SE:/service0011/char0012]# read
> Attempting to read /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012
> [CHG] Attribute
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012 Value: 0x5d
> 5d ]
> [Arc Touch Mouse SE:/service0011/char0012]# select-attribute
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
> [Arc Touch Mouse SE:/service0011/char0012/desc0014]# read
> Attempting to read
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
> [CHG] Attribute
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
> Value: 0x00
> [CHG] Attribute
> /org/bluez/hci0/dev_F3_43_74_B7_86_24/service0011/char0012/desc0014
> Value: 0x00
> 00 00
>
> But perhaps this is because the handles are in sequence as you said,
> can you try with the following changes:
>
> http://fpaste.org/199962/67601931/
See if the attachment works.
--
Luiz Augusto von Dentz
[-- Attachment #2: 0001-core-gatt-Fix-not-replying-if-db-operation-fail.patch --]
[-- Type: text/x-patch, Size: 1967 bytes --]
From dbad03bf1432f1eec3260f6db77c08aca58e2575 Mon Sep 17 00:00:00 2001
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: Thu, 19 Mar 2015 12:52:47 +0200
Subject: [PATCH BlueZ] core/gatt: Fix not replying if db operation fail
---
src/gatt-client.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/gatt-client.c b/src/gatt-client.c
index a85b9d2..80b9f47 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
@@ -778,20 +778,19 @@ static void chrc_read_cb(bool success, uint8_t att_ecode, const uint8_t *value,
struct async_dbus_op *op = user_data;
struct characteristic *chrc = op->data;
struct service *service = chrc->service;
+ DBusMessage *reply;
- if (!success) {
- DBusMessage *reply = create_gatt_dbus_error(op->msg, att_ecode);
-
- chrc->read_id = 0;
- g_dbus_send_message(btd_get_dbus_connection(), reply);
- return ;
- }
+ if (!success)
+ goto fail;
if (!op->offset)
gatt_db_attribute_reset(chrc->attr);
- gatt_db_attribute_write(chrc->attr, op->offset, value, length, 0, NULL,
- write_characteristic_cb, chrc);
+ if (!gatt_db_attribute_write(chrc->attr, op->offset, value, length, 0,
+ NULL, write_characteristic_cb, chrc)) {
+ error("Failed to store attribute");
+ goto fail;
+ }
/*
* If the value length is exactly MTU-1, then we may not have read the
@@ -814,7 +813,17 @@ static void chrc_read_cb(bool success, uint8_t att_ecode, const uint8_t *value,
chrc->read_id = 0;
/* Read the stored data from db */
- gatt_db_attribute_read(chrc->attr, 0, 0, NULL, read_op_cb, op);
+ if (!gatt_db_attribute_read(chrc->attr, 0, 0, NULL, read_op_cb, op)) {
+ error("Failed to read database");
+ goto fail;
+ }
+
+ return;
+
+fail:
+ reply = create_gatt_dbus_error(op->msg, att_ecode);
+ chrc->read_id = 0;
+ g_dbus_send_message(btd_get_dbus_connection(), reply);
}
static DBusMessage *characteristic_read_value(DBusConnection *conn,
--
2.1.0
^ permalink raw reply related [flat|nested] 9+ messages in thread