notify_data->invalid = true;
}
-static bool service_list_add_service(struct service_list **head,
- struct service_list **tail,
- bool primary, uint16_t start,
- uint16_t end,
+static struct service_list *new_service_list(uint16_t start, uint16_t end,
+ bool primary,
uint8_t uuid[BT_GATT_UUID_SIZE])
{
struct service_list *list;
list = new0(struct service_list, 1);
if (!list)
- return false;
+ return NULL;
list->service.primary = primary;
list->service.start_handle = start;
list->service.end_handle = end;
memcpy(list->service.uuid, uuid, UUID_BYTES);
+ return list;
+}
+
+static bool service_list_add_service(struct service_list **head,
+ struct service_list **tail,
+ bool primary, uint16_t start,
+ uint16_t end,
+ uint8_t uuid[BT_GATT_UUID_SIZE])
+{
+ struct service_list *list;
+
+ list = new_service_list(start, end, primary, uuid);
+ if (!list)
+ return false;
+
if (!(*head))
*head = *tail = list;
else {
struct bt_gatt_client *client;
struct service_list *result_head, *result_tail, *cur_service;
struct chrc_data *cur_chrc;
+ uint16_t start;
+ uint16_t end;
int cur_chrc_index;
int ref_count;
void (*complete_func)(struct discovery_op *op, bool success,
op->complete_func(op, success, att_ecode);
}
+static void discover_secondary_cb(bool success, uint8_t att_ecode,
+ struct bt_gatt_result *result,
+ void *user_data)
+{
+ struct discovery_op *op = user_data;
+ struct bt_gatt_client *client = op->client;
+ struct bt_gatt_iter iter;
+ uint16_t start, end;
+ uint8_t uuid[BT_GATT_UUID_SIZE];
+ char uuid_str[MAX_LEN_UUID_STR];
+ struct service_list *service;
+
+ if (!success) {
+ util_debug(client->debug_callback, client->debug_data,
+ "Secondary service discovery failed."
+ " ATT ECODE: 0x%02x", att_ecode);
+ switch (att_ecode) {
+ case BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND:
+ case BT_ATT_ERROR_UNSUPPORTED_GROUP_TYPE:
+ goto next;
+ default:
+ goto done;
+ }
+ }
+
+ if (!result || !bt_gatt_iter_init(&iter, result))
+ goto done;
+
+ util_debug(client->debug_callback, client->debug_data,
+ "Secondary services found: %u",
+ bt_gatt_result_service_count(result));
+
+ while (bt_gatt_iter_next_service(&iter, &start, &end, uuid)) {
+ uuid_to_string(uuid, uuid_str);
+ util_debug(client->debug_callback, client->debug_data,
+ "start: 0x%04x, end: 0x%04x, uuid: %s",
+ start, end, uuid_str);
+
+ /* Store the service */
+ service = new_service_list(start, end, false, uuid);
+ if (!service) {
+ util_debug(client->debug_callback, client->debug_data,
+ "Failed to create service");
+ goto done;
+ }
+
+ service_list_insert_services(&op->result_head, &op->result_tail,
+ service, service);
+ }
+
+next:
+ /* Sequentially discover the characteristics of all services */
+ op->cur_service = op->result_head;
+ if (bt_gatt_discover_characteristics(client->att,
+ op->cur_service->service.start_handle,
+ op->cur_service->service.end_handle,
+ discover_chrcs_cb,
+ discovery_op_ref(op),
+ discovery_op_unref))
+ return;
+
+ util_debug(client->debug_callback, client->debug_data,
+ "Failed to start characteristic discovery");
+ discovery_op_unref(op);
+
+done:
+ op->complete_func(op, false, att_ecode);
+}
+
static void discover_primary_cb(bool success, uint8_t att_ecode,
struct bt_gatt_result *result,
void *user_data)
if (!op->result_head)
goto done;
- /* Sequentially discover the characteristics of all services */
+ /* Discover secondary services */
op->cur_service = op->result_head;
- if (bt_gatt_discover_characteristics(client->att,
- op->cur_service->service.start_handle,
- op->cur_service->service.end_handle,
- discover_chrcs_cb,
- discovery_op_ref(op),
- discovery_op_unref))
+ if (bt_gatt_discover_secondary_services(client->att, NULL,
+ op->start, op->end,
+ discover_secondary_cb,
+ discovery_op_ref(op),
+ discovery_op_unref))
return;
util_debug(client->debug_callback, client->debug_data,
- "Failed to start characteristic discovery");
+ "Failed to start secondary service discovery");
discovery_op_unref(op);
success = false;
op->client = client;
op->complete_func = service_changed_complete;
+ op->start = start_handle;
+ op->end = end_handle;
if (!bt_gatt_discover_primary_services(client->att, NULL,
start_handle, end_handle,
op->client = client;
op->complete_func = init_complete;
+ op->start = 0x0001;
+ op->end = 0xffff;
/* Configure the MTU */
if (!bt_gatt_exchange_mtu(client->att, MAX(BT_ATT_DEFAULT_LE_MTU, mtu),