summaryrefslogtreecommitdiff
path: root/src/device.c
diff options
context:
space:
mode:
authorArchie Pusaka <apusaka@chromium.org>2021-09-23 16:18:23 +0800
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2021-09-23 16:20:28 -0700
commit0ba16aa232ccc7cca7a0b241be34a330ceb96bd6 (patch)
treef5b53ecde2908c65aab9689045b7444f13c560c1 /src/device.c
parent838741b884d9c43ab0099c54605462af252bbc5b (diff)
downloadbluez-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.c40
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;