diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index 5edb991..d0fc054 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
* the remote peripheral.
*/
unsigned int svc_chngd_ind_id;
+ bool svc_chngd_registered;
struct queue *svc_chngd_queue; /* Queued service changed events */
bool in_svc_chngd;
&properties, NULL))
return NULL;
- /* Find the CCC characteristic */
- ccc = NULL;
- gatt_db_service_foreach_desc(attr, find_ccc, &ccc);
- if (!ccc)
- return NULL;
-
chrc = new0(struct notify_chrc, 1);
if (!chrc)
return NULL;
return NULL;
}
+ /*
+ * Find the CCC characteristic. Some characteristics that allow
+ * notifications may not have a CCC descriptor. We treat these as
+ * automatically successful.
+ */
+ ccc = NULL;
+ gatt_db_service_foreach_desc(attr, find_ccc, &ccc);
+ if (ccc)
+ chrc->ccc_handle = gatt_db_attribute_get_handle(ccc);
+
chrc->value_handle = value_handle;
- chrc->ccc_handle = gatt_db_attribute_get_handle(ccc);
chrc->properties = properties;
queue_push_tail(client->notify_chrcs, chrc);
util_debug(client->debug_callback, client->debug_data,
"Re-registered handler for \"Service Changed\" after "
"change in GATT service");
+ client->svc_chngd_registered = true;
return;
}
/* The GATT service was modified. Re-register the handler for
* indications from the "Service Changed" characteristic.
*/
+ client->svc_chngd_registered = false;
client->svc_chngd_ind_id = bt_gatt_client_register_notify(client,
gatt_db_attribute_get_handle(attr),
service_changed_reregister_cb,
goto done;
}
+ client->svc_chngd_registered = true;
client->ready = true;
success = true;
util_debug(client->debug_callback, client->debug_data,
service_changed_register_cb,
service_changed_cb,
client, NULL);
- client->ready = false;
+
+ if (!client->svc_chngd_registered)
+ client->ready = false;
if (client->svc_chngd_ind_id)
return;
util_debug(client->debug_callback, client->debug_data,
"Failed to register handler for \"Service Changed\"");
+ success = false;
fail:
util_debug(client->debug_callback, client->debug_data,
*/
if (notify_data->att_id) {
bt_att_cancel(notify_data->client->att, notify_data->att_id);
- notify_data_unref(notify_data);
- return;
+ goto done;
}
- if (__sync_sub_and_fetch(¬ify_data->chrc->notify_count, 1)) {
- notify_data_unref(notify_data);
- return;
- }
+ if (__sync_sub_and_fetch(¬ify_data->chrc->notify_count, 1) ||
+ !notify_data->chrc->ccc_handle)
+ goto done;
if (notify_data_write_ccc(notify_data, false, disable_ccc_callback))
return;
+done:
notify_data_unref(notify_data);
}
/* Add the handler to the bt_gatt_client's general list */
queue_push_tail(client->notify_list, notify_data);
- /* Assign an ID to the handler and notify the caller that it was
- * successfully registered.
- */
+ /* Assign an ID to the handler. */
if (client->next_reg_id < 1)
client->next_reg_id = 1;
/*
* If the ref count is not zero, then notifications are already enabled.
*/
- if (chrc->notify_count > 0) {
+ if (chrc->notify_count > 0 || !chrc->ccc_handle) {
complete_notify_request(notify_data);
return notify_data->id;
}