Skip to content

Commit fa784a1

Browse files
committed
backends: bluez: handle address change after pairing
Devices with resolvable private addresses will change their address after pairing. So for the address property to return the "correct" value, we need to update the device's address after pairing. Fixes: #1737
1 parent fe82d06 commit fa784a1

3 files changed

Lines changed: 35 additions & 0 deletions

File tree

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Changed
2929

3030
Fixed
3131
-----
32+
* Fixed resolvable private address not updated after connecting in BlueZ backend. Fixes #1737.
3233
* Fixed possible ``KeyError`` when getting services in BlueZ backend. Fixes #1435.
3334
* Fix D-Bus connection leak when connecting to a device fails in BlueZ backend. Fixes #1698.
3435
* Fixed possible deadlock when connecting on WinRT backend when device is already connected. Fixes #1757.

bleak/backends/bluezdbus/client.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ async def disconnect_device() -> None:
284284
member="Pair",
285285
)
286286
)
287+
288+
# For resolvable private addresses, the address will
289+
# change after pairing, so we need to update that.
290+
# Hopefully there is no race condition here. D-Bus
291+
# traffic capture shows that Address change happens
292+
# at the same time as Paired property change and
293+
# that PropertiesChanged signal is sent before the
294+
# "Pair" reply is sent.
295+
self.address = manager.get_device_address(self._device_path)
287296
else:
288297
reply = await self._bus.call(
289298
Message(
@@ -509,6 +518,16 @@ async def pair(self, *args: Any, **kwargs: Any) -> None:
509518
assert reply
510519
assert_reply(reply)
511520

521+
# For resolvable private addresses, the address will
522+
# change after pairing, so we need to update that.
523+
# Hopefully there is no race condition here. D-Bus
524+
# traffic capture shows that Address change happens
525+
# at the same time as Paired property change and
526+
# that PropertiesChanged signal is sent before the
527+
# "Pair" reply is sent.
528+
manager = await get_global_bluez_manager()
529+
self.address = manager.get_device_address(self._device_path)
530+
512531
@override
513532
async def unpair(self) -> None:
514533
"""Unpair with the peripheral."""

bleak/backends/bluezdbus/manager.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,21 @@ def get_device_name(self, device_path: str) -> str:
753753
"""
754754
return self._get_device_property(device_path, defs.DEVICE_INTERFACE, "Name")
755755

756+
def get_device_address(self, device_path: str) -> str:
757+
"""
758+
Gets the value of the "Address" property for a device.
759+
760+
Args:
761+
device_path: The D-Bus object path of the device.
762+
763+
Returns:
764+
The current property value.
765+
766+
Raises:
767+
BleakError: if the device is not present in BlueZ
768+
"""
769+
return self._get_device_property(device_path, defs.DEVICE_INTERFACE, "Address")
770+
756771
def is_connected(self, device_path: str) -> bool:
757772
"""
758773
Gets the value of the "Connected" property for a device.

0 commit comments

Comments
 (0)