Jakeler / ble-serial

"RFCOMM for BLE" a UART over Bluetooth low energy (4+) bridge for Linux, Mac and Windows
https://blog.ja-ke.tech/tags/#bluetooth
MIT License
251 stars 37 forks source link

Failed to connect for reading - Failed to update the notification status for characteristic #57

Closed mcclymont closed 2 years ago

mcclymont commented 2 years ago

Describe the bug ble-serial fails to connect to device with fatal error when attempting to setup reading from serial characteristic. If I connect with writing only --permit wo then it works fine (at least, it does not error).

Only with reading does it fail. It seems to fail on trying to setup notifications for new messages receiving received from the characteristic.

The device is Bluno Mega.

According to this code snippet, the correct characteristic for serial communication should be 0000dfb1-0000-1000-8000-00805f9b34fb which does indeed support read, write and notify.

Note - in the below log output there is an additional stacktrace printed, that I added. So we can see where the error actually originates.

I have no idea why Apple CoreBluetooth system is responding with Code 1 "One or more parameters were invalid"

Log messages

$ ble-scan -d 17D7F1FD-B89F-450A-9FC7-DF0080474DC3
Started BLE scan

17D7F1FD-B89F-450A-9FC7-DF0080474DC3 (RSSI=-66): BlunoMega

Started deep scan of 17D7F1FD-B89F-450A-9FC7-DF0080474DC3

Found device 17D7F1FD-B89F-450A-9FC7-DF0080474DC3: BlunoMega (out of 1)
SERVICE 0000180a-0000-1000-8000-00805f9b34fb (Handle: 16): Device Information
     CHARACTERISTIC 00002a23-0000-1000-8000-00805f9b34fb (Handle: 17): System ID ['read']
     CHARACTERISTIC 00002a24-0000-1000-8000-00805f9b34fb (Handle: 19): Model Number String ['read']
     CHARACTERISTIC 00002a25-0000-1000-8000-00805f9b34fb (Handle: 21): Serial Number String ['read']
     CHARACTERISTIC 00002a26-0000-1000-8000-00805f9b34fb (Handle: 23): Firmware Revision String ['read']
     CHARACTERISTIC 00002a27-0000-1000-8000-00805f9b34fb (Handle: 25): Hardware Revision String ['read']
     CHARACTERISTIC 00002a28-0000-1000-8000-00805f9b34fb (Handle: 27): Software Revision String ['read']
     CHARACTERISTIC 00002a29-0000-1000-8000-00805f9b34fb (Handle: 29): Manufacturer Name String ['read']
     CHARACTERISTIC 00002a2a-0000-1000-8000-00805f9b34fb (Handle: 31): IEEE 11073-20601 Regulatory Cert. Data List ['read']
     CHARACTERISTIC 00002a50-0000-1000-8000-00805f9b34fb (Handle: 33): PnP ID ['read']
SERVICE 0000dfb0-0000-1000-8000-00805f9b34fb (Handle: 35): Vendor specific
     CHARACTERISTIC 0000dfb1-0000-1000-8000-00805f9b34fb (Handle: 36): Vendor specific ['read', 'write-without-response', 'write', 'notify']
         DESCRIPTOR 00002901-0000-1000-8000-00805f9b34fb (Handle: 38): Characteristic User Description
     CHARACTERISTIC 0000dfb2-0000-1000-8000-00805f9b34fb (Handle: 39): Vendor specific ['read', 'write-without-response', 'write', 'notify']
         DESCRIPTOR 00002901-0000-1000-8000-00805f9b34fb (Handle: 41): Characteristic User Description

Completed deep scan of 17D7F1FD-B89F-450A-9FC7-DF0080474DC3

Finished BLE scan
$ ble-serial -d 17D7F1FD-B89F-450A-9FC7-DF0080474DC3 -r 0000dfb1-0000-1000-8000-00805f9b34fb -w 0000dfb1-0000-1000-8000-00805f9b34fb -v
22:17:30.845 | DEBUG | main.py: Running: Namespace(verbose=1, port='/tmp/ttyBLE', timeout=5.0, adapter='hci0', mtu=20, device='17D7F1FD-B89F-450A-9FC7-DF0080474DC3', addr_type='public', service_uuid=None, write_uuid='0000dfb1-0000-1000-8000-00805f9b34fb', read_uuid='0000dfb1-0000-1000-8000-00805f9b34fb', mode='rw', filename=None, binlog=False)
22:17:30.846 | DEBUG | selector_events.py: Using selector: KqueueSelector
22:17:30.848 | INFO | linux_pty.py: Slave created on /tmp/ttyBLE -> /dev/ttys004
22:17:30.848 | INFO | ble_interface.py: Receiver set up
22:17:31.743 | INFO | ble_interface.py: Trying to connect with 17D7F1FD-B89F-450A-9FC7-DF0080474DC3: Apple, Inc. (b'\x02\x15\xe2\xc5m\xb5\xdf\xfbH\xd2\xb0`\xd0\xf5\xa7\x10\x96\xe0\x00\x00\x00\x00\xc5')
22:17:33.070 | INFO | ble_interface.py: Device 17D7F1FD-B89F-450A-9FC7-DF0080474DC3 connected
22:17:33.071 | DEBUG | ble_interface.py: Characteristic candidates for write:
    0000dfb1-0000-1000-8000-00805f9b34fb (Handle: 36): Vendor specific ['read', 'write-without-response', 'write', 'notify']
22:17:33.071 | INFO | ble_interface.py: Found write characteristic 0000dfb1-0000-1000-8000-00805f9b34fb (H. 36)
22:17:33.071 | DEBUG | ble_interface.py: Characteristic candidates for notify:
    0000dfb1-0000-1000-8000-00805f9b34fb (Handle: 36): Vendor specific ['read', 'write-without-response', 'write', 'notify']
22:17:33.071 | INFO | ble_interface.py: Found notify characteristic 0000dfb1-0000-1000-8000-00805f9b34fb (H. 36)
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/ble_serial/main.py", line 39, in _run
    await self.bt.setup_chars(args.write_uuid, args.read_uuid, args.mode)
  File "/usr/local/lib/python3.9/site-packages/ble_serial/bluetooth/ble_interface.py", line 47, in setup_chars
    await self.dev.start_notify(self.read_char, self.handle_notify)
  File "/usr/local/lib/python3.9/site-packages/bleak/backends/corebluetooth/client.py", line 387, in start_notify
    await self._delegate.start_notifications(characteristic.obj, bleak_callback)
  File "/usr/local/lib/python3.9/site-packages/bleak/backends/corebluetooth/PeripheralDelegate.py", line 215, in start_notifications
    await future
bleak.exc.BleakError: Failed to update the notification status for characteristic 36: Error Domain=CBErrorDomain Code=1 "One or more parameters were invalid." UserInfo={NSLocalizedDescription=One or more parameters were invalid.}

22:17:33.074 | ERROR | main.py: Bluetooth connection failed: Failed to update the notification status for characteristic 36: Error Domain=CBErrorDomain Code=1 "One or more parameters were invalid." UserInfo={NSLocalizedDescription=One or more parameters were invalid.}
22:17:33.075 | WARNING | main.py: Shutdown initiated
22:17:33.075 | INFO | linux_pty.py: Serial reader and symlink removed
Traceback (most recent call last):
  File "/usr/local/bin/ble-serial", line 8, in <module>
    sys.exit(launch())
  File "/usr/local/lib/python3.9/site-packages/ble_serial/main.py", line 81, in launch
    Main(args).start()
  File "/usr/local/lib/python3.9/site-packages/ble_serial/main.py", line 16, in start
    asyncio.run(self._run())
  File "/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.9/site-packages/ble_serial/main.py", line 65, in _run
    await self.bt.disconnect()
  File "/usr/local/lib/python3.9/site-packages/ble_serial/bluetooth/ble_interface.py", line 115, in disconnect
    await self.dev.stop_notify(self.read_char)
  File "/usr/local/lib/python3.9/site-packages/bleak/backends/corebluetooth/client.py", line 408, in stop_notify
    await self._delegate.stop_notifications(characteristic.obj)
  File "/usr/local/lib/python3.9/site-packages/bleak/backends/corebluetooth/PeripheralDelegate.py", line 230, in stop_notifications
    await future
bleak.exc.BleakError: Failed to update the notification status for characteristic 36: Error Domain=CBErrorDomain Code=1 "One or more parameters were invalid." UserInfo={NSLocalizedDescription=One or more parameters were invalid.}

Setup (please complete the following information):

Jakeler commented 2 years ago

Makes sense that only reading does not work, when the notification setup fails - as writing does not depend on notifications.

"Have you tried turning it off and on again" :smile: Seriously this is the only answer I found with the exact error and context: https://stackoverflow.com/questions/34690035/corebluetooth-setnotifyvalue-invalid-parameters

Is it maybe related to the macOS version? Can you try the Bluno Mega combined with a newer macOS or different machine? Also testing the same macbook with a different bluetooth device could be interesting. So we could rule out some variables.

In any case we probably have to report it to bleak and hope they can fix it. Please run ble-serial with -vv to obtain an even more verbose log and attach it for that.

mcclymont commented 2 years ago

Using the same macbook I'm able to connect successfully to my Oura ring over BLE. It says Running main loop! but I don't get anything over serial, the device probably doesn't support it.

So I guess this is something specific to the Bluno's implementation / bluetooth standards?

Do you think I should change any of these settings? https://wiki.dfrobot.com/Bluno_SKU_DFR0267#target_6

I have set it to the default peripheral mode settings, baud rate 115200, and I've also tried HID mode instead of transparent.

On my new Macbook (from this year, running 12.2 Monteray) ble-scan shows 0 devices. However, I am able to get a similar result if I connect using the service rather than the device ID. However it again only works for writing, not for reading. But with a different error message: Code 10 "the attribute could not be found"...

$ ble-serial -s 0000dfb0-0000-1000-8000-00805f9b34fb --permit ro -r 0000dfb1-0000-1000-8000-00805f9b34fb
15:41:15.444 | INFO | linux_pty.py: Slave created on /tmp/ttyBLE -> /dev/ttys022
15:41:15.444 | INFO | ble_interface.py: Receiver set up
15:41:15.444 | WARNING | ble_interface.py: Picking first device with matching service, consider passing a specific device address, especially if there could be multiple devices
15:41:15.529 | INFO | ble_interface.py: Trying to connect with 04C2B763-9DD8-EA75-5F9A-1CC421AA6D99: BlunoMega
15:41:16.404 | INFO | ble_interface.py: Device 04C2B763-9DD8-EA75-5F9A-1CC421AA6D99 connected
15:41:16.405 | INFO | ble_interface.py: Writing disabled, skipping write UUID detection
15:41:16.406 | INFO | ble_interface.py: Found notify characteristic 0000dfb1-0000-1000-8000-00805f9b34fb (H. 36)
15:41:16.409 | ERROR | main.py: Bluetooth connection failed: Failed to update the notification status for characteristic 36: Error Domain=CBATTErrorDomain Code=10 "The attribute could not be found." UserInfo={NSLocalizedDescription=The attribute could not be found.}
15:41:16.409 | WARNING | main.py: Shutdown initiated
15:41:16.411 | INFO | linux_pty.py: Serial reader and symlink removed
Traceback (most recent call last):
  File "/Users/chris/Library/Python/3.8/bin/ble-serial", line 8, in <module>
    sys.exit(launch())
  File "/Users/chris/Library/Python/3.8/lib/python/site-packages/ble_serial/main.py", line 78, in launch
    Main(args).start()
  File "/Users/chris/Library/Python/3.8/lib/python/site-packages/ble_serial/main.py", line 16, in start
    asyncio.run(self._run())
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/Users/chris/Library/Python/3.8/lib/python/site-packages/ble_serial/main.py", line 62, in _run
    await self.bt.disconnect()
  File "/Users/chris/Library/Python/3.8/lib/python/site-packages/ble_serial/bluetooth/ble_interface.py", line 113, in disconnect
    await self.dev.stop_notify(self.read_char)
  File "/Users/chris/Library/Python/3.8/lib/python/site-packages/bleak/backends/corebluetooth/client.py", line 406, in stop_notify
    await self._delegate.stop_notifications(characteristic.obj)
  File "/Users/chris/Library/Python/3.8/lib/python/site-packages/bleak/backends/corebluetooth/PeripheralDelegate.py", line 230, in stop_notifications
    await future
bleak.exc.BleakError: Failed to update the notification status for characteristic 36: Error Domain=CBATTErrorDomain Code=10 "The attribute could not be found." UserInfo={NSLocalizedDescription=The attribute could not be found.}
Jakeler commented 2 years ago

Yes, that suggests the Bluno is the problem. Looking at it's specifications is interesting - it contains a TI CC2540 BLE chip, same as the the HM-10/11 modules which I used countless times and definitely work fine. So the hardware should be ok. I am just wondering what firmware they use, if they wrote it from scratch? Compared with the HMSoft firmwares the basic AT commands like UART match, while most others are slightly different and there are specific features on both sides. We already saw in #46 that even small firmware updates can cause weird issues. I don't really see a obvious setting there, could also just guess and try...

Looking again at your scan output, I am wondering if you should use characteristic 0000dfb2-... instead? Maybe one is for reading only and the other for writing, then there would be just too many properties on both.

Though the android code snippet you posted suggests that indeed everything goes through the 1st characteristic. Another thing I noticed that while it enables notifications locally it does not enable it on the device with the CCCD (Client Characteristic Configuration Descriptor) like in my BLE app code. If you follow the BLE standard exactly this is required before receiving notifications, in reality that is not the case for all modules, for example the HMSoft stuff does not care either way. AFAIK the bleak/macOS stack does always write/enable it, so maybe it is not implemented on this devices and that is why it fails, would also fit to the error "the attribute could not be found". Edit: In the scan output I see there is no CCCD 00002902-... so that is quite obvious and most likely the reason. Edit 2: Same problem was discussed here: https://github.com/pauldemarco/flutter_blue/issues/185 Honestly this is a bad implementation by dfrobot/Bluno, disregarding BLE standards - they should fix it in the firmware.