hbldh / bleak

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

Writing more than 20 bytes to a device causes the device to disconnect #1285

Open michaelFluid opened 1 year ago

michaelFluid commented 1 year ago

Description

I am using bleak to write to a characteristic on a Nordic device. Anything less than or equal to 20 bytes is able to be written but once I send anything greater than 20 bytes, bleak throws this error. OSError: [WinError -2147023673] The operation was canceled by the user

At first I thought it was the MTU size but when I used the bleak library to check MTU size, it says that the size is 247 bytes. This is also indicated by the Nordic device.

I am also able to read more than 20 bytes from other characteristics on the device.

What I Did

import asyncio
from bleak import BleakClient, BleakScanner

address = 'AA:BB:CC:DD:EE:FF'
UUID = '00000000-0000-0000-0000-000000000000'

async def main():
    client = BleakClient(address)
    await asyncio.sleep(1)
    await client.connect()
    await asyncio.sleep(1)
    await client.write_gatt_char(UUID, b'11111111111111111111', response=True)

asyncio.run(main())

Logs

Traceback (most recent call last):
  File "write_test.py", line 14, in <module>
    asyncio.run(main())
  File "AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "write_test.py", line 12, in main
    await client.write_gatt_char(UUID, b'111111111111111111111', response=True)
  File "AppData\Local\Programs\Python\Python311\Lib\site-packages\bleak\__init__.py", line 659, in write_gatt_char
    await self._backend.write_gatt_char(char_specifier, data, response)
  File "AppData\Local\Programs\Python\Python311\Lib\site-packages\bleak\backends\winrt\client.py", line 869, in write_gatt_char
    await characteristic.obj.write_value_with_result_async(buf, response),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [WinError -2147023673] The operation was canceled by the user
dlech commented 1 year ago

The error is coming from Windows, so you will need to do logging in Windows to see what could be triggering the problem. I would start with logging Bluetooth packets with Wireshark as described in the Bleak troubleshooting docs.

Also see https://github.com/microsoft/busiotools/tree/master/bluetooth/tracing

pymenow commented 1 year ago

Description

How can i get to know the reason for disconnect ? Everything works well including connect and disconnect notifications. But I need to know the reason for disconnect.

dlech commented 1 year ago

As far as I know, none of the OSes pass this information to the APIs we are using. You would have to spy on Bluetooth packets like Wireshark does to get this information.

Also, we have https://github.com/hbldh/bleak/discussions which is a better place to ask questions like this.

francescoolivieri commented 1 year ago
  • bleak version: 0.20.1
  • Python version: 3.11.0
  • Operating System: Windows 11

Description

I am using bleak to write to a characteristic on a Nordic device. Anything less than or equal to 20 bytes is able to be written but once I send anything greater than 20 bytes, bleak throws this error. OSError: [WinError -2147023673] The operation was canceled by the user

At first I thought it was the MTU size but when I used the bleak library to check MTU size, it says that the size is 247 bytes. This is also indicated by the Nordic device.

I am also able to read more than 20 bytes from other characteristics on the device.

What I Did

import asyncio
from bleak import BleakClient, BleakScanner

address = 'AA:BB:CC:DD:EE:FF'
UUID = '00000000-0000-0000-0000-000000000000'

async def main():
    client = BleakClient(address)
    await asyncio.sleep(1)
    await client.connect()
    await asyncio.sleep(1)
    await client.write_gatt_char(UUID, b'11111111111111111111', response=True)

asyncio.run(main())

Logs

Traceback (most recent call last):
  File "write_test.py", line 14, in <module>
    asyncio.run(main())
  File "AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "write_test.py", line 12, in main
    await client.write_gatt_char(UUID, b'111111111111111111111', response=True)
  File "AppData\Local\Programs\Python\Python311\Lib\site-packages\bleak\__init__.py", line 659, in write_gatt_char
    await self._backend.write_gatt_char(char_specifier, data, response)
  File "AppData\Local\Programs\Python\Python311\Lib\site-packages\bleak\backends\winrt\client.py", line 869, in write_gatt_char
    await characteristic.obj.write_value_with_result_async(buf, response),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [WinError -2147023673] The operation was canceled by the user

Have you solved this problem? I got that too.