Bluetooth: GATT: Fix Find by Type response
This fixes bug where wrong service handles have been sent while discovering the primary services. We should skip Secondary Service contained in range 0x0006-0x0009 in this case: > ACL Data RX: Handle 64 flags 0x02 dlen 13 [hci0] 619772.398445 ATT: Find By Type Value Request (0x06) len 8 Handle range: 0x0001-0xffff Attribute type: Primary Service (0x2800) UUID: Generic Access Profile (0x1800) < ACL Data TX: Handle 64 flags 0x00 dlen 9 [hci0] 619772.403821 ATT: Find By Type Value Response (0x07) len 4 Handle range: 0x0001-0x0009 With this patch: > ACL Data RX: Handle 64 flags 0x02 dlen 13 [hci0] 618945.922607 ATT: Find By Type Value Request (0x06) len 8 Handle range: 0x0001-0xffff Attribute type: Primary Service (0x2800) UUID: Generic Access Profile (0x1800) < ACL Data TX: Handle 64 flags 0x00 dlen 9 [hci0] 618945.927933 ATT: Find By Type Value Response (0x07) len 4 Handle range: 0x0001-0x0005 Signed-off-by: Mariusz Skamra <mariusz.skamra@tieto.com> Change-Id: I7bb743e8787bc294ba447be5e21e250f0128ec68
This commit is contained in:
parent
6e8ab42997
commit
de6029ee25
1 changed files with 20 additions and 5 deletions
|
@ -372,6 +372,7 @@ struct find_type_data {
|
|||
struct bt_att_handle_group *group;
|
||||
const void *value;
|
||||
uint8_t value_len;
|
||||
uint8_t err;
|
||||
};
|
||||
|
||||
static uint8_t find_type_cb(const struct bt_gatt_attr *attr, void *user_data)
|
||||
|
@ -382,7 +383,13 @@ static uint8_t find_type_cb(const struct bt_gatt_attr *attr, void *user_data)
|
|||
int read;
|
||||
uint8_t uuid[16];
|
||||
|
||||
/* Skip if not a primary service */
|
||||
/* Skip secondary services */
|
||||
if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) {
|
||||
data->group = NULL;
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
/* Update group end_handle if not a primary service */
|
||||
if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY)) {
|
||||
if (data->group && attr->handle > data->group->end_handle) {
|
||||
data->group->end_handle = sys_cpu_to_le16(attr->handle);
|
||||
|
@ -405,10 +412,13 @@ static uint8_t find_type_cb(const struct bt_gatt_attr *attr, void *user_data)
|
|||
|
||||
/* Check if data matches */
|
||||
if (read != data->value_len || memcmp(data->value, uuid, read)) {
|
||||
/* If a group exists stop otherwise continue */
|
||||
return data->group ? BT_GATT_ITER_STOP : BT_GATT_ITER_CONTINUE;
|
||||
data->group = NULL;
|
||||
return BT_GATT_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
/* If service has been found, error should be cleared */
|
||||
data->err = 0x00;
|
||||
|
||||
/* Fast foward to next item position */
|
||||
data->group = net_buf_add(data->buf, sizeof(*data->group));
|
||||
data->group->start_handle = sys_cpu_to_le16(attr->handle);
|
||||
|
@ -433,16 +443,21 @@ static uint8_t att_find_type_rsp(struct bt_att *att, uint16_t start_handle,
|
|||
}
|
||||
|
||||
data.att = att;
|
||||
data.group = NULL;
|
||||
data.value = value;
|
||||
data.value_len = value_len;
|
||||
|
||||
/* Pre-set error in case no service will be found */
|
||||
data.err = BT_ATT_ERR_ATTRIBUTE_NOT_FOUND;
|
||||
|
||||
bt_gatt_foreach_attr(start_handle, end_handle, find_type_cb, &data);
|
||||
|
||||
if (!data.group) {
|
||||
/* If error has not been cleared, no service has been found */
|
||||
if (data.err) {
|
||||
net_buf_unref(data.buf);
|
||||
/* Respond since handle is set */
|
||||
send_err_rsp(conn, BT_ATT_OP_FIND_TYPE_REQ, start_handle,
|
||||
BT_ATT_ERR_ATTRIBUTE_NOT_FOUND);
|
||||
data.err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue