Fail to connect to paired device
Problem: Connecting to a device that is already paired and is private advertising.
python version: 3.11.0 bleak version: 0.22.3 Windows 10
It works fine to connect to the device, pair, and then read from a characteristic that needs a bonding. If i un-pair and disconnects, there is no problem for me to connect again. Here is some sample code.
ble_device = BLEAKDeviceManager()
await ble_device.initilize()
await ble_device.pair()
await asyncio.sleep(2.0)
try:
raw_data = await ble_device.read_from_characteristic(BATTERY_LEVEL)
battery_level = parse_battery_data(raw_data)
print(battery_level)
except Exception as e:
print(f"Could not read battery level: {e}")
await ble_device.un_pair()
await ble_device.disconnect()
where the initilize basically looks like this:
target_address = "XX:XX:XX:XX"
self.client = BleakClient(device, winrt=dict(use_cached_services=True, address_type="public"), pair=False)
await self.client.connect(winrt=dict(use_cached_services=True))
CHAR_UUID = "00002a00-0000-1000-8000-00805f9b34fb"
char = self.client.services.get_characteristic(CHAR_UUID)
async with asyncio.timeout(10):
while char.max_write_without_response_size == 20:
print(char.max_write_without_response_size)
await asyncio.sleep(0.5)
And as I said, this works fine, here are the logs:
DEBUG:bleak.backends.winrt.client:Connecting to BLE device @ 70:54:64:D7:C5:86
DEBUG:bleak.backends.winrt.scanner:Received 68:AE:87:11:00:CF: .
DEBUG:bleak.backends.winrt.scanner:49 devices found. Watcher status: <BluetoothLEAdvertisementWatcherStatus.STOPPED: 3>.
DEBUG:bleak.backends.winrt.client:getting services (service_cache_mode=<BluetoothCacheMode.CACHED: 0>, cache_mode=<BluetoothCacheMode.CACHED: 0>)...
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLE68:c6:ac:54:96:23-70:54:64:d7:c5:86, error: <BluetoothError.SUCCESS: 0>,
status: <GattSessionStatus.ACTIVE: 1>
DEBUG:bleak.backends.winrt.client:max_pdu_size_changed_handler: 247
DEBUG:bleak.backends.winrt.client:70:54:64:D7:C5:86: services changed
DEBUG:bleak.backends.winrt.client:70:54:64:D7:C5:86: services changed
DEBUG:bleak.backends.winrt.client:70:54:64:D7:C5:86: services changed
DEBUG:bleak.backends.winrt.client:70:54:64:D7:C5:86: services changed
DEBUG:bleak.backends.winrt.client:70:54:64:D7:C5:86: services changed
DEBUG:bleak.backends.winrt.client:70:54:64:D7:C5:86: services changed
Connected to target
INFO:bleak.backends.winrt.client:Paired to device with protection level <DevicePairingProtectionLevel.ENCRYPTION: 2>.
Successfully paired
Paired with client
DEBUG:bleak.backends.winrt.client:Read Characteristic 001C : bytearray(b'\x00')
0
0
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLE68:c6:ac:54:96:23-70:54:64:d7:c5:86, error: <BluetoothError.SUCCESS: 0>,
status: <GattSessionStatus.CLOSED: 0>
DEBUG:bleak.backends.winrt.client:max_pdu_size_changed_handler: 23
DEBUG:bleak.backends.winrt.client:closing requester
DEBUG:bleak.backends.winrt.client:closing session
INFO:bleak.backends.winrt.client:Unpaired with device.
un-paired with client
DEBUG:bleak.backends.winrt.client:Disconnecting from BLE device...
Disconnected device
Now to my problem. I try to run the same code but remove the un-pairing, since i want to find the device when it is private advertising and be able to connect to it.
ble_device = BLEAKDeviceManager()
await ble_device.initilize()
await ble_device.pair()
await asyncio.sleep(2.0)
try:
raw_data = await ble_device.read_from_characteristic(BATTERY_LEVEL)
battery_level = parse_battery_data(raw_data)
print(battery_level)
except Exception as e:
print(f"Could not read battery level: {e}")
#await ble_device.un_pair()
await ble_device.disconnect()
It works and the device is still paired, but when i try to connect to it now i get the following error (I tried with and without setting pair=True to the BleakClient):
DEBUG:bleak.backends.winrt.client:Connecting to BLE device @ 70:54:64:D7:C5:86
DEBUG:bleak.backends.winrt.client:getting services (service_cache_mode=<BluetoothCacheMode.CACHED: 0>, cache_mode=<BluetoothCacheMode.CACHED: 0>)...
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLE68:c6:ac:54:96:23-70:54:64:d7:c5:86, error: <BluetoothError.SUCCESS: 0>,
status: <GattSessionStatus.ACTIVE: 1>
Connected to target
20
DEBUG:bleak.backends.winrt.client:session_status_changed_event_handler: id: BluetoothLE#BluetoothLE68:c6:ac:54:96:23-70:54:64:d7:c5:86, error: <BluetoothError.SUCCESS: 0>,
status: <GattSessionStatus.CLOSED: 0>
DEBUG:bleak.backends.winrt.client:closing requester
DEBUG:bleak.backends.winrt.client:closing session
Traceback (most recent call last):
File "C:\Users\8957\Documents\shuri-tools\ble_test\BLEDeviceManager\BLEAKDeviceManager.py", line 181, in <module>
asyncio.run(main())
File "C:\Users\8957\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "C:\Users\8957\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\8957\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\8957\Documents\shuri-tools\ble_test\BLEDeviceManager\BLEAKDeviceManager.py", line 165, in main
await ble_device.initilize()
File "C:\Users\8957\Documents\shuri-tools\ble_test\BLEDeviceManager\BLEAKDeviceManager.py", line 17, in initilize
await self._connect(target_device)
File "C:\Users\8957\Documents\shuri-tools\ble_test\BLEDeviceManager\BLEAKDeviceManager.py", line 119, in _connect
while char.max_write_without_response_size == 20:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\8957\Documents\tests\venv\Lib\site-packages\bleak\backends\characteristic.py", line 112, in max_write_without_response_size
return self._max_write_without_response_size()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\8957\Documents\tests\venv\Lib\site-packages\bleak\backends\winrt\client.py", line 770, in <lambda>
characteristic, lambda: self._session.max_pdu_size - 3
^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'max_pdu_size'
I am not sure if the problem is how i use Bleak, or my peripheral device.
From what I can see in the logs, in the unsuccessful attempt, the connection is actually successful, but as soon as Windows tries to enable encryption, the device disconnects.
So I'm not sure what Bleak could do about this. We don't manage the encryption. That is all handled automatically by Windows. My guess most likely, the device is doing it wrong (e.g. isn't storing the encryption keys) and disconnects because it got an unexpected request from Windows. Or, if this same Bleak program works on other OSes, maybe Windows is doing something wrong.