diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index ab8da6a..997a280 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
"MTU exchange complete, with MTU: %u",
bt_att_get_mtu(client->att));
- if (bt_gatt_discover_primary_services(client->att, NULL,
+ if (bt_gatt_discover_all_primary_services(client->att, NULL,
discover_primary_cb,
discovery_op_ref(op),
discovery_op_unref))
diff --git a/src/shared/gatt-helpers.c b/src/shared/gatt-helpers.c
index 54876bc..55e6992 100644
--- a/src/shared/gatt-helpers.c
+++ b/src/shared/gatt-helpers.c
}
last_end = get_le16(pdu + length - data_length + 2);
- if (last_end != 0xffff) {
+ if (last_end < op->end_handle) {
uint8_t pdu[6];
put_le16(last_end + 1, pdu);
- put_le16(0xffff, pdu + 2);
+ put_le16(op->end_handle, pdu + 2);
put_le16(GATT_PRIM_SVC_UUID, pdu + 4);
if (bt_att_send(op->att, BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
goto done;
}
+ /* Some devices incorrectly return 0xffff as the end group handle when
+ * the read-by-group-type request is performed within a smaller range.
+ * Manually set the end group handle that we report in the result to the
+ * end handle in the original request.
+ */
+ if (last_end == 0xffff && last_end != op->end_handle)
+ put_le16(op->end_handle,
+ cur_result->pdu + length - data_length + 1);
+
success:
/* End of procedure */
final_result = op->result_head;
}
last_end = get_le16(pdu + length - 6);
- if (last_end != 0xffff) {
+ if (last_end < op->end_handle) {
uint8_t pdu[6 + get_uuid_len(&op->uuid)];
put_le16(last_end + 1, pdu);
- put_le16(0xffff, pdu + 2);
+ put_le16(op->end_handle, pdu + 2);
put_le16(GATT_PRIM_SVC_UUID, pdu + 4);
put_uuid_le(&op->uuid, pdu + 6);
op->callback(success, att_ecode, final_result, op->user_data);
}
-bool bt_gatt_discover_primary_services(struct bt_att *att,
- bt_uuid_t *uuid,
+bool bt_gatt_discover_all_primary_services(struct bt_att *att, bt_uuid_t *uuid,
+ bt_gatt_discovery_callback_t callback,
+ void *user_data,
+ bt_gatt_destroy_func_t destroy)
+{
+ return bt_gatt_discover_primary_services(att, uuid, 0x0001, 0xffff,
+ callback, user_data,
+ destroy);
+}
+
+bool bt_gatt_discover_primary_services(struct bt_att *att, bt_uuid_t *uuid,
+ uint16_t start, uint16_t end,
bt_gatt_discovery_callback_t callback,
void *user_data,
bt_gatt_destroy_func_t destroy)
return false;
op->att = att;
+ op->end_handle = end;
op->callback = callback;
op->user_data = user_data;
op->destroy = destroy;
if (!uuid) {
uint8_t pdu[6];
- put_le16(0x0001, pdu);
- put_le16(0xffff, pdu + 2);
+ put_le16(start, pdu);
+ put_le16(end, pdu + 2);
put_le16(GATT_PRIM_SVC_UUID, pdu + 4);
result = bt_att_send(att, BT_ATT_OP_READ_BY_GRP_TYPE_REQ,
/* Discover by UUID */
op->uuid = *uuid;
- put_le16(0x0001, pdu);
- put_le16(0xffff, pdu + 2);
+ put_le16(start, pdu);
+ put_le16(end, pdu + 2);
put_le16(GATT_PRIM_SVC_UUID, pdu + 4);
put_uuid_le(&op->uuid, pdu + 6);
diff --git a/src/shared/gatt-helpers.h b/src/shared/gatt-helpers.h
index c4a6578..f6f4b62 100644
--- a/src/shared/gatt-helpers.h
+++ b/src/shared/gatt-helpers.h
void *user_data,
bt_gatt_destroy_func_t destroy);
+bool bt_gatt_discover_all_primary_services(struct bt_att *att, bt_uuid_t *uuid,
+ bt_gatt_discovery_callback_t callback,
+ void *user_data,
+ bt_gatt_destroy_func_t destroy);
bool bt_gatt_discover_primary_services(struct bt_att *att, bt_uuid_t *uuid,
+ uint16_t start, uint16_t end,
bt_gatt_discovery_callback_t callback,
void *user_data,
bt_gatt_destroy_func_t destroy);