diff options
author | Archie Pusaka <apusaka@chromium.org> | 2021-09-23 16:18:23 +0800 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2021-09-23 16:20:28 -0700 |
commit | 0ba16aa232ccc7cca7a0b241be34a330ceb96bd6 (patch) | |
tree | f5b53ecde2908c65aab9689045b7444f13c560c1 /src/device.c | |
parent | 838741b884d9c43ab0099c54605462af252bbc5b (diff) | |
download | bluez-0ba16aa232ccc7cca7a0b241be34a330ceb96bd6.tar.gz |
device: Check both bearers's paired status upon removal of connection
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@chromium.org>
Diffstat (limited to 'src/device.c')
-rw-r--r-- | src/device.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/device.c b/src/device.c index 313b5dab1..532978f9e 100644 --- a/src/device.c +++ b/src/device.c @@ -3074,6 +3074,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; @@ -3112,18 +3113,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; |