hbldh / bleak

A cross platform Bluetooth Low Energy Client for Python using asyncio
MIT License
1.56k stars 275 forks source link

Extremely low timeout for bluetooth pairing on win11 #1528

Open userx14 opened 1 month ago

userx14 commented 1 month ago

Description

When trying to pair with a bluetooth device the timeout to accept the connection using the system dialog is extremely short (<2 seconds). When the dialog is not confirmed basically instantly I get various errors. This problem is not present on windows 10 or at least much less pronounced.

What I Did

import bleak, asyncio

async def main():
    bleAddr = "AA:BB:CC:DD:11:22"
    bleClient = bleak.BleakClient(bleAddr)
    try:
        await bleClient.connect()
        await asyncio.sleep(0.5)
        await bleClient.pair()
        print("do stuff with bluetooth device, same behavior if it is only a print statement")
    finally:
        print("unpair and disconnect")
        await bleClient.unpair()
        await bleClient.disconnect()
asyncio.run(main())

Execute this script, the bluetooth pairing request notification appears after 2 seconds. When waiting for 2 seconds before accepting it, unpair and disconnect is printed and the error Could not pair with device: 15 is raised. Sometimes the error code is Could not pair with device: 19 instead. According to the microsoft doc these correspond to 15 = OperationAlreadyInProgress, 19 = Failed.

Here is the first error with enabled logging:

2024-03-19 21:59:19,002 bleak.backends.winrt.scanner MainThread DEBUG: 4 devices found. Watcher status: <BluetoothLEAdvertisementWatcherStatus.STOPPED: 3>.
2024-03-19 21:59:19,002 bleak.backends.winrt.client MainThread DEBUG: Connecting to BLE device @ D3:07:19:90:29:00
2024-03-19 21:59:19,018 bleak.backends.winrt.client MainThread DEBUG: getting services (service_cache_mode=None, cache_mode=None)...
2024-03-19 21:59:19,973 bleak.backends.winrt.client Dummy-1 DEBUG: session_status_changed_event_handler: id: BluetoothLE#BluetoothLE5c:80:b6:0a:6d:91-d3:07:19:90:29:00, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.ACTIVE: 1>
2024-03-19 21:59:20,098 bleak.backends.winrt.client Dummy-2 DEBUG: max_pdu_size_changed_handler: 64
2024-03-19 21:59:20,380 bleak.backends.winrt.client Dummy-1 DEBUG: D3:07:19:90:29:00: services changed
2024-03-19 21:59:22,054 bleak.backends.winrt.client Dummy-2 DEBUG: D3:07:19:90:29:00: services changed
unpair and disconnect
2024-03-19 21:59:24,865 bleak.backends.winrt.client MainThread INFO: Unpaired with device.
2024-03-19 21:59:24,865 bleak.backends.winrt.client MainThread DEBUG: Disconnecting from BLE device...
2024-03-19 21:59:33,323 bleak.backends.winrt.client Dummy-3 DEBUG: max_pdu_size_changed_handler: 23
2024-03-19 21:59:33,323 bleak.backends.winrt.client Dummy-4 DEBUG: session_status_changed_event_handler: id: BluetoothLE#BluetoothLE5c:80:b6:0a:6d:91-d3:07:19:90:29:00, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.CLOSED: 0>
2024-03-19 21:59:34,075 bleak.backends.winrt.client MainThread DEBUG: closing requester
2024-03-19 21:59:34,075 bleak.backends.winrt.client MainThread DEBUG: closing session
Traceback (most recent call last):
  File "C:\Users\win11\Downloads\minWorkEx.py", line 14, in <module>
    asyncio.run(main())
  File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
    return future.result()
  File "C:\Users\win11\Downloads\minWorkEx.py", line 8, in main
    await bleClient.pair()
  File "C:\Users\win11\AppData\Roaming\Python\Python310\site-packages\bleak\__init__.py", line 629, in pair
    return await self._backend.pair(*args, **kwargs)
  File "C:\Users\win11\AppData\Roaming\Python\Python310\site-packages\bleak\backends\winrt\client.py", line 616, in pair
    raise BleakError(f"Could not pair with device: {pairing_result.status}")
bleak.exc.BleakError: Could not pair with device: 15

Here is the error which also occurs sometimes:

2024-03-19 21:52:58,241 bleak.backends.winrt.client MainThread DEBUG: Connecting to BLE device @ D3:07:19:90:29:00
2024-03-19 21:52:58,259 bleak.backends.winrt.client MainThread DEBUG: getting services (service_cache_mode=None, cache_mode=None)...
2024-03-19 21:52:58,874 bleak.backends.winrt.client Dummy-1 DEBUG: session_status_changed_event_handler: id: BluetoothLE#BluetoothLE5c:80:b6:0a:6d:91-d3:07:19:90:29:00, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.ACTIVE: 1>
2024-03-19 21:52:58,954 bleak.backends.winrt.client Dummy-1 DEBUG: max_pdu_size_changed_handler: 64
2024-03-19 21:52:59,190 bleak.backends.winrt.client Dummy-2 DEBUG: D3:07:19:90:29:00: services changed
2024-03-19 21:53:00,257 bleak.backends.winrt.client Dummy-3 DEBUG: D3:07:19:90:29:00: services changed
unpair and disconnect
2024-03-19 21:51:53,515 bleak.backends.winrt.client Dummy-4 DEBUG: session_status_changed_event_handler: id: BluetoothLE#BluetoothLE5c:80:b6:0a:6d:91-d3:07:19:90:29:00, error: <BluetoothError.SUCCESS: 0>, status: <GattSessionStatus.CLOSED: 0>
2024-03-19 21:51:53,515 bleak.backends.winrt.client Dummy-5 DEBUG: max_pdu_size_changed_handler: 23
2024-03-19 21:51:53,515 bleak.backends.winrt.client MainThread DEBUG: closing requester
2024-03-19 21:51:53,530 bleak.backends.winrt.client MainThread DEBUG: closing session
Traceback (most recent call last):
  File "C:\Users\win11\Downloads\minWorkEx.py", line 8, in main
    await bleClient.pair()
  File "C:\Users\win11\AppData\Roaming\Python\Python310\site-packages\bleak\__init__.py", line 629, in pair
    return await self._backend.pair(*args, **kwargs)
  File "C:\Users\win11\AppData\Roaming\Python\Python310\site-packages\bleak\backends\winrt\client.py", line 616, in pair
    raise BleakError(f"Could not pair with device: {pairing_result.status}")
bleak.exc.BleakError: Could not pair with device: 19

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\win11\Downloads\minWorkEx.py", line 14, in <module>
    asyncio.run(main())
  File "C:\Program Files\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Program Files\Python310\lib\asyncio\base_events.py", line 649, in run_until_complete
    return future.result()
  File "C:\Users\win11\Downloads\minWorkEx.py", line 12, in main
    await bleClient.unpair()
OSError: [WinError -2147024809] The parameter is incorrect
PS C:\Users\win11\Downloads>

When accepting the dialog very quickly the script behaves as expected, but the timeout of <2 seconds is unreasonably short.

Is this error caused by improper usage of the library, or is this an issue with the backend on windows 11? I already tried adding a timeout value of 30 when creating the bleak.BleakClient, but that did not make any difference.

dlech commented 1 month ago

Since these errors are coming from Windows and there is no timeout paramter to pass to the Windows APIs, I'm not sure what we could do in Bleak to work around this.

Also note that Bleak currently only support just-works pairing. See #1100