From: Archie Pusaka <apusaka@xxxxxxxxxxxx> Because Link Key for BREDR can be transformed into LTK for LE (and vice versa), there is a possibility of getting 'paired' on either of BREDR/LE without actually connected using the aforementioned bearer. When removing the connection, we should check both bearers's paired and bonded status rather than just the one getting disconnected. Reviewed-by: Miao-chen Chou <mcchou@xxxxxxxxxxxx> --- src/device.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/device.c b/src/device.c index b29aa195d1..6a66fc9a23 100644 --- a/src/device.c +++ b/src/device.c @@ -3010,6 +3010,7 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type) struct bearer_state *state = get_state(device, bdaddr_type); DBusMessage *reply; bool remove_device = false; + bool paired_status_updated = false; if (!state->connected) return; @@ -3048,18 +3049,33 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type) dbus_message_unref(msg); } - if (state->paired && !state->bonded) { - btd_adapter_remove_bonding(device->adapter, &device->bdaddr, - bdaddr_type); - - state->paired = false; - - /* report change only if both bearers are unpaired */ - if (!device->bredr_state.paired && !device->le_state.paired) - g_dbus_emit_property_changed(dbus_conn, device->path, - DEVICE_INTERFACE, - "Paired"); - } + /* Check paired status of both bearers since it's possible to be + * paired but not connected via link key to LTK conversion. + */ + if (!device->bredr_state.connected && device->bredr_state.paired && + !device->bredr_state.bonded) { + btd_adapter_remove_bonding(device->adapter, + &device->bdaddr, + BDADDR_BREDR); + device->bredr_state.paired = false; + paired_status_updated = true; + } + + if (!device->le_state.connected && device->le_state.paired && + !device->le_state.bonded) { + btd_adapter_remove_bonding(device->adapter, + &device->bdaddr, + device->bdaddr_type); + device->le_state.paired = false; + paired_status_updated = true; + } + + /* report change only if both bearers are unpaired */ + if (!device->bredr_state.paired && !device->le_state.paired && + paired_status_updated) + g_dbus_emit_property_changed(dbus_conn, device->path, + DEVICE_INTERFACE, + "Paired"); if (device->bredr_state.connected || device->le_state.connected) return; -- 2.33.0.464.g1972c5931b-goog