Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow unpair without being connected on WinRT backend #1012

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
Changed
-------
* Relax ``async-timeout`` version to support different installations. Merged #1009.
* ``unpair`` function of ``BleakClient`` in WinRT backend can be called without being connected to remove stored device information

`0.17.0`_ (2022-09-12)
======================
Expand Down
63 changes: 42 additions & 21 deletions bleak/backends/winrt/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@
# protocol_error: typing.Optional[int]


def _address_to_int(address: str) -> int:
"""Converts the Bluetooth device address string to its representing integer

Args:
address (str): Bluetooth device address to convert

Returns:
int: integer representation of the given Bluetooth device address
"""
_address_separators = [":", "-"]
for char in _address_separators:
address = address.replace(char, "")

return int(address, base=16)


def _ensure_success(result: Any, attr: Optional[str], fail_msg: str) -> Any:
"""
Ensures that *status* is ``GattCommunicationStatus.SUCCESS``, otherwise
Expand Down Expand Up @@ -182,6 +198,18 @@ def __str__(self):

# Connectivity methods

def _create_requester(self, bluetooth_address: int):
args = [
bluetooth_address,
]
if self._address_type is not None:
args.append(
BluetoothAddressType.PUBLIC
if self._address_type == "public"
else BluetoothAddressType.RANDOM
)
return BluetoothLEDevice.from_bluetooth_address_async(*args)

async def connect(self, **kwargs) -> bool:
"""Connect to the specified GATT server.

Expand All @@ -206,16 +234,7 @@ async def connect(self, **kwargs) -> bool:

logger.debug("Connecting to BLE device @ %s", self.address)

args = [
self._device_info,
]
if self._address_type is not None:
args.append(
BluetoothAddressType.PUBLIC
if self._address_type == "public"
else BluetoothAddressType.RANDOM
)
self._requester = await BluetoothLEDevice.from_bluetooth_address_async(*args)
self._requester = await self._create_requester(self._device_info)

if self._requester is None:
# https://github.com/microsoft/Windows-universal-samples/issues/1089#issuecomment-487586755
Expand Down Expand Up @@ -452,27 +471,29 @@ async def unpair(self) -> bool:
Boolean on whether the unparing was successful.

"""

# New local device information object created since the object from the requester isn't updated
device_information = await DeviceInformation.create_from_id_async(
self._requester.device_information.id
device = await self._create_requester(
self._device_info
if self._device_info is not None
else _address_to_int(self.address)
)
if device_information.pairing.is_paired:
unpairing_result = await device_information.pairing.unpair_async()

if device is None:
raise BleakError(f"Device with address {self.address} was not found.")

try:
unpairing_result = await device.device_information.pairing.unpair_async()
if unpairing_result.status not in (
DeviceUnpairingResultStatus.UNPAIRED,
DeviceUnpairingResultStatus.ALREADY_UNPAIRED,
):
raise BleakError(
f"Could not unpair with device: {unpairing_result.status}"
)
logger.info("Unpaired with device.")
finally:
device.close()

else:
logger.info("Unpaired with device.")
return True

return not device_information.pairing.is_paired
return True

# GATT services methods

Expand Down