hbldh / bleak

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

No acknowledgement for Indication #223

Closed uched41 closed 4 years ago

uched41 commented 4 years ago

Description

I am trying to send indications from a BLE device (NRF52 Soc) to my python application. My initial solution used BLE Notifications, but a lot of packets were being dropped so I resorted to using indications. The BLeak Library doesn't seem to be sending acknowledgments for received indications.

Is this acknowledgment of indications handled internally by the Bleak Library or do we need to implement this at the user application level? If so which function do we need to acknowlege notifications?

What I Did

This is a simple application that I am using to test this. The "test_read_data" function has a 15-second delay loop that waits for multiple packets from the BLE device. When I use notifications, I am able to receive multiple packets but some of them are dropped. But when I use indications, I am stuck at the first packet because the BLE Microcontroller never receives an acknowledgment for the indication.

def notify_callback(handle, value):
    global result
    global target_length
    global recv_value
    print(len(value))
    print("Received data %s " % hexlify(value))

async def run(address, loop, debug=False):
    global client

    async with BleakClient(address, loop=loop) as client:
        x = await client.is_connected()
        print("Connected: {0}".format(x))

        await client.start_notify(CHARACTERISTIC_UUID, notify_callback)
        await test_read_data(0)
        await asyncio.sleep(1.0, loop=loop)
        await client.stop_notify(CHARACTERISTIC_UUID)
bsiever commented 4 years ago

I'm not sure about Windows, but I believe on macOS the acknowledgement is handled at the OS level.

Just to check, are you sure your device is working correctly? I usually test with a phone app, like LightBlue (on iOS) or nRF Connect (Android or iOS) and confirm that the indications/notifications work as expected.

uched41 commented 4 years ago

Yea, I test with nrf_connect and the indications work as expected.

hbldh commented 4 years ago

The intention is that no acknowledgements should be needed to be sent by the user. The Windows UWP Bluetooth library handles all that and also chooses indication if the device supports it; I have not experienced any problems with that before. Try running the service_explorer.py example on the device and post the results here.

Try rewriting you code without globals.

uched41 commented 4 years ago

Thanks for you help. Here is the result from the service_explorer.py example.

Connected: True [Service] 00001800-0000-1000-8000-00805f9b34fb: Generic Access Profile [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb: (read,write) | Name: , Value: b'NE_Base' [Characteristic] 00002a01-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'\x00\x00' [Characteristic] 00002a04-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'\x06\x00\x10\x00\x00\x00\x90\x01' [Characteristic] 00002aa6-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'\x01' [Service] 00001801-0000-1000-8000-00805f9b34fb: Generic Attribute Profile [Characteristic] 00002a05-0000-1000-8000-00805f9b34fb: (indicate) | Name: , Value: None [Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 13) | Value: b'\x02\x00' [Service] f3641400-00b0-4240-ba50-05ca45bf8abc: Unknown [Characteristic] f3641401-00b0-4240-ba50-05ca45bf8abc: (read,write,indicate) | Name: , Value: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' [Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 17) | Value: b'\x00\x00'

It is also worth mentioning that I get some errors when I run the code. But If I repeatedly try it, it works after some time. Here are some of the errors I get: Traceback (most recent call last): File "service_explorer.py", line 64, in <module> loop.run_until_complete(run(address, loop, True)) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete return future.result() File "service_explorer.py", line 29, in run async with BleakClient(address, loop=loop) as client: File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 109, in __next__ return self.gen.send(None) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\bleak\backends\client.py", line 48, in __aenter__ await self.connect() File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 109, in __next__ return self.gen.send(None) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\bleak\backends\dotnet\client.py", line 119, in connect "Device with address {0} was " "not found.".format(self.address) bleak.exc.BleakError: Device with address CC:0F:BD:D1:01:92 was not found.

I get this device not found error even when the device is visible on other Bluetooth scanners. The connection eventually succeeds after some trials.

File "service_explorer.py", line 64, in <module> loop.run_until_complete(run(address, loop, True)) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\base_events.py", line 466, in run_until_complete return future.result() File "service_explorer.py", line 29, in run async with BleakClient(address, loop=loop) as client: File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 109, in __next__ return self.gen.send(None) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\bleak\backends\client.py", line 48, in __aenter__ await self.connect() File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 109, in __next__ return self.gen.send(None) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\bleak\backends\dotnet\client.py", line 145, in connect services = await self.get_services() File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\asyncio\coroutines.py", line 109, in __next__ return self.gen.send(None) File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\bleak\backends\dotnet\client.py", line 236, in get_services raise BleakDotNetTaskError("Could not get GATT services.") bleak.exc.BleakDotNetTaskError: Could not get GATT services.

This is the second error. It also succeeds If I continue trying. I initially thought these might not be big issues. But I am beginning to suspect that they might be connected to the indication problem.

Note: I still get these 2 errors when I use the default examples (service_explorer).

It is also worth mentioning that I am using a while loop inside an async function to wait until all the indications are received. Could these be hindering the reception of indications?

hbldh commented 4 years ago

The bleak.exc.BleakError: Device with address CC:0F:BD:D1:01:92 was not found. simply means that the device could not be connected to, because it was not detected during scan when trying to connect. Try raising the timeout of the client of the connect call.

The second one could be due to that the device disconnects, but I am not sure. It is the Windows UWP libs that send that error. Try updating to latest version (0.7.1) and try this again; you should get a better error report now.

hbldh commented 4 years ago

The problems described in the discussion should be resolved in version 0.8.0. The bleak.exc.BleakDotNetTaskError: Could not get GATT services. might still happen due to communication issues with device though.

Will close this.