From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> If the device is removed locally device_free would end up calling bt_att_unref which won't trigger any disconnect callback necessary to remove device states. --- src/device.c | 3 +++ src/gatt-database.c | 28 ++++++++++++++++++++++++++-- src/gatt-database.h | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/device.c b/src/device.c index ef5b8f86a..024e670e0 100644 --- a/src/device.c +++ b/src/device.c @@ -580,6 +580,9 @@ static void gatt_server_cleanup(struct btd_device *device) bt_gatt_server_unref(device->server); device->server = NULL; + + btd_gatt_database_att_disconnected( + btd_adapter_get_database(device->adapter), device); } static void attio_cleanup(struct btd_device *device) diff --git a/src/gatt-database.c b/src/gatt-database.c index febc2f840..783b692d5 100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -242,7 +242,7 @@ static bool dev_state_match(const void *a, const void *b) } static struct device_state * -find_device_state(struct btd_gatt_database *database, bdaddr_t *bdaddr, +find_device_state(struct btd_gatt_database *database, const bdaddr_t *bdaddr, uint8_t bdaddr_type) { struct device_info dev_info; @@ -357,8 +357,13 @@ static bool get_dst_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type) { GIOChannel *io = NULL; GError *gerr = NULL; + int fd; - io = g_io_channel_unix_new(bt_att_get_fd(att)); + fd = bt_att_get_fd(att); + if (fd < 0) + return false; + + io = g_io_channel_unix_new(fd); if (!io) return false; @@ -3349,6 +3354,25 @@ void btd_gatt_database_att_connected(struct btd_gatt_database *database, state->pending = NULL; } +void btd_gatt_database_att_disconnected(struct btd_gatt_database *database, + struct btd_device *device) +{ + struct device_state *state; + const bdaddr_t *addr; + uint8_t type; + + DBG(""); + + addr = device_get_address(device); + type = btd_device_get_bdaddr_type(device); + + state = find_device_state(database, addr, type); + if (!state) + return; + + att_disconnected(0, state); +} + static void restore_ccc(struct btd_gatt_database *database, const bdaddr_t *addr, uint8_t addr_type, uint16_t value) { diff --git a/src/gatt-database.h b/src/gatt-database.h index a6c3139c4..a77a0fb20 100644 --- a/src/gatt-database.h +++ b/src/gatt-database.h @@ -25,5 +25,7 @@ void btd_gatt_database_destroy(struct btd_gatt_database *database); struct gatt_db *btd_gatt_database_get_db(struct btd_gatt_database *database); void btd_gatt_database_att_connected(struct btd_gatt_database *database, struct bt_att *att); +void btd_gatt_database_att_disconnected(struct btd_gatt_database *database, + struct btd_device *device); void btd_gatt_database_restore_svc_chng_ccc(struct btd_gatt_database *database); -- 2.17.1