From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This makes use of gatt_db_attribute_notify to send indications of Service Changed. --- src/gatt-database.c | 73 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/src/gatt-database.c b/src/gatt-database.c index dc75762f3..d3518ebfc 100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -378,6 +378,18 @@ static bool get_dst_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type) return true; } +static struct device_state * +find_device_state_by_att(struct btd_gatt_database *database, struct bt_att *att) +{ + bdaddr_t bdaddr; + uint8_t bdaddr_type; + + if (!get_dst_info(att, &bdaddr, &bdaddr_type)) + return NULL; + + return find_device_state(database, &bdaddr, bdaddr_type); +} + static struct device_state *get_device_state(struct btd_gatt_database *database, struct bt_att *att) { @@ -1299,16 +1311,6 @@ static void populate_devinfo_service(struct btd_gatt_database *database) database_add_record(database, service); } -static void register_core_services(struct btd_gatt_database *database) -{ - gatt_db_ccc_register(database->db, gatt_ccc_read_cb, gatt_ccc_write_cb, - NULL, database); - - populate_gap_service(database); - populate_gatt_service(database); - populate_devinfo_service(database); -} - static void conf_cb(void *user_data) { GDBusProxy *proxy = user_data; @@ -1432,6 +1434,49 @@ remove: } } +static void gatt_notify_cb(struct gatt_db_attribute *attrib, + struct gatt_db_attribute *ccc, + const uint8_t *value, size_t len, + struct bt_att *att, void *user_data) +{ + struct btd_gatt_database *database = user_data; + struct notify notify; + + memset(¬ify, 0, sizeof(notify)); + + notify.database = database; + notify.handle = gatt_db_attribute_get_handle(attrib); + notify.ccc_handle = gatt_db_attribute_get_handle(ccc); + notify.value = (void *) value; + notify.len = len; + + if (attrib == database->svc_chngd) + notify.conf = service_changed_conf; + + /* If a specific att is provided notify only to that device */ + if (att) { + struct device_state *state; + + state = find_device_state_by_att(database, att); + if (!state) + return; + + send_notification_to_device(state, ¬ify); + } else + queue_foreach(database->device_states, + send_notification_to_device, ¬ify); +} + +static void register_core_services(struct btd_gatt_database *database) +{ + gatt_db_ccc_register(database->db, gatt_ccc_read_cb, gatt_ccc_write_cb, + gatt_notify_cb, database); + + populate_gap_service(database); + populate_gatt_service(database); + populate_devinfo_service(database); +} + static void send_notification_to_devices(struct btd_gatt_database *database, uint16_t handle, uint8_t *value, uint16_t len, uint16_t ccc_handle, @@ -1478,8 +1523,8 @@ static void send_service_changed(struct btd_gatt_database *database, put_le16(start, value); put_le16(end, value + 2); - send_notification_to_devices(database, handle, value, sizeof(value), - ccc_handle, service_changed_conf, NULL); + gatt_db_attribute_notify(database->svc_chngd, database->svc_chngd_ccc, + value, sizeof(value), NULL); } static void gatt_db_service_added(struct gatt_db_attribute *attrib, @@ -3917,6 +3962,6 @@ void btd_gatt_database_restore_svc_chng_ccc(struct btd_gatt_database *database) put_le16(0x0001, value); put_le16(0xffff, value + 2); - send_notification_to_devices(database, handle, value, sizeof(value), - ccc_handle, service_changed_conf, NULL); + gatt_db_attribute_notify(database->svc_chngd, database->svc_chngd_ccc, + value, sizeof(value), NULL); } -- 2.34.1