diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 008bd3e..b8c4bd8 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
*/
struct queue *pending_requests;
unsigned int next_request_id;
+
+ struct bt_gatt_request *discovery_req;
+ unsigned int mtu_req_id;
};
struct request {
discovery_op_free(op);
}
+static void discovery_req_clear(struct bt_gatt_client *client)
+{
+ if (!client->discovery_req)
+ return;
+
+ bt_gatt_request_unref(client->discovery_req);
+ client->discovery_req = NULL;
+}
+
static void discover_chrcs_cb(bool success, uint8_t att_ecode,
struct bt_gatt_result *result,
void *user_data);
char uuid_str[MAX_LEN_UUID_STR];
unsigned int includes_count, i;
+ discovery_req_clear(client);
+
if (!success) {
if (att_ecode == BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND)
goto next;
goto failed;
op->cur_svc = attr;
- if (bt_gatt_discover_characteristics(client->att,
+
+ client->discovery_req = bt_gatt_discover_characteristics(
+ client->att,
start, end,
discover_chrcs_cb,
discovery_op_ref(op),
- discovery_op_unref))
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
if (start == end)
goto next;
- if (bt_gatt_discover_included_services(client->att, start, end,
+ client->discovery_req = bt_gatt_discover_included_services(client->att,
+ start, end,
discover_incl_cb,
discovery_op_ref(op),
- discovery_op_unref))
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
continue;
}
- if (bt_gatt_discover_descriptors(client->att, desc_start,
+ client->discovery_req = bt_gatt_discover_descriptors(
+ client->att, desc_start,
chrc_data->end_handle,
discover_descs_cb,
discovery_op_ref(op),
- discovery_op_unref)) {
+ discovery_op_unref);
+ if (client->discovery_req) {
*discovering = true;
goto done;
}
unsigned int desc_count;
bool discovering;
+ discovery_req_clear(client);
+
if (!success) {
if (att_ecode == BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND) {
success = true;
/* Move on to the next service */
op->cur_svc = attr;
- if (bt_gatt_discover_characteristics(client->att, start, end,
+
+ client->discovery_req = bt_gatt_discover_characteristics(client->att,
+ start, end,
discover_chrcs_cb,
discovery_op_ref(op),
- discovery_op_unref))
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
unsigned int chrc_count;
bool discovering;
+ discovery_req_clear(client);
+
if (!success) {
if (att_ecode == BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND) {
success = true;
/* Move on to the next service */
op->cur_svc = attr;
- if (bt_gatt_discover_characteristics(client->att, start, end,
+
+ client->discovery_req = bt_gatt_discover_characteristics(client->att,
+ start, end,
discover_chrcs_cb,
discovery_op_ref(op),
- discovery_op_unref))
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
bt_uuid_t uuid;
char uuid_str[MAX_LEN_UUID_STR];
+ discovery_req_clear(client);
+
if (!success) {
util_debug(client->debug_callback, client->debug_data,
"Secondary service discovery failed."
goto done;
}
- if (bt_gatt_discover_included_services(client->att, start, end,
+ client->discovery_req = bt_gatt_discover_included_services(client->att,
+ start, end,
discover_incl_cb,
discovery_op_ref(op),
- discovery_op_unref))
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
bt_uuid_t uuid;
char uuid_str[MAX_LEN_UUID_STR];
+ discovery_req_clear(client);
+
if (!success) {
util_debug(client->debug_callback, client->debug_data,
"Primary service discovery failed."
secondary:
/* Discover secondary services */
- if (bt_gatt_discover_secondary_services(client->att, NULL,
- op->start, op->end,
- discover_secondary_cb,
- discovery_op_ref(op),
- discovery_op_unref))
+ client->discovery_req = bt_gatt_discover_secondary_services(client->att,
+ NULL, op->start, op->end,
+ discover_secondary_cb,
+ discovery_op_ref(op),
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
struct bt_gatt_client *client = op->client;
op->success = success;
+ client->mtu_req_id = 0;
if (!success) {
util_debug(client->debug_callback, client->debug_data,
return;
}
- if (bt_gatt_discover_all_primary_services(client->att, NULL,
+ client->discovery_req = bt_gatt_discover_all_primary_services(
+ client->att, NULL,
discover_primary_cb,
discovery_op_ref(op),
- discovery_op_unref))
+ discovery_op_unref);
+ if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
static void service_changed_failure(struct discovery_op *op)
{
- gatt_db_clear_range(op->client->db, op->start, op->end);
+ struct bt_gatt_client *client = op->client;
+
+ gatt_db_clear_range(client->db, op->start, op->end);
}
static void process_service_changed(struct bt_gatt_client *client,
if (!op)
goto fail;
- if (bt_gatt_discover_primary_services(client->att, NULL,
- start_handle, end_handle,
+ client->discovery_req = bt_gatt_discover_primary_services(client->att,
+ NULL, start_handle, end_handle,
discover_primary_cb,
discovery_op_ref(op),
- discovery_op_unref)) {
+ discovery_op_unref);
+ if (client->discovery_req) {
client->in_svc_chngd = true;
return;
}
static void init_fail(struct discovery_op *op)
{
- gatt_db_clear(op->client->db);
+ struct bt_gatt_client *client = op->client;
+
+ gatt_db_clear(client->db);
}
static bool gatt_client_init(struct bt_gatt_client *client, uint16_t mtu)
return false;
/* Configure the MTU */
- if (!bt_gatt_exchange_mtu(client->att, MAX(BT_ATT_DEFAULT_LE_MTU, mtu),
- exchange_mtu_cb,
- discovery_op_ref(op),
- discovery_op_unref)) {
+ client->mtu_req_id = bt_gatt_exchange_mtu(client->att,
+ MAX(BT_ATT_DEFAULT_LE_MTU, mtu),
+ exchange_mtu_cb,
+ discovery_op_ref(op),
+ discovery_op_unref);
+ if (!client->mtu_req_id) {
discovery_op_free(op);
return false;
}
queue_remove_all(client->pending_requests, NULL, NULL, cancel_request);
+ if (client->discovery_req) {
+ bt_gatt_request_cancel(client->discovery_req);
+ bt_gatt_request_unref(client->discovery_req);
+ client->discovery_req = NULL;
+ }
+
+ if (client->mtu_req_id)
+ bt_att_cancel(client->att, client->mtu_req_id);
+
return true;
}