Closed JeanPoll closed 2 years ago
In the past there has been some confusion/changing of which is the Rx characteristic UUID and which is the Tx characteristics UUID. There is also the same around if it is notify
or indicate
. You can get a flavour around this with: https://github.com/lancaster-university/microbit-dal/issues number 259
It may be that the combination of those settings aren't quite correct for the nRF tool you are using. My tools of choice tend to be either https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal or https://www.nordicsemi.com/Software-and-tools/Development-Tools/nRF-Connect-for-mobile
It has worked with them when I've used them. I suspect the answer is to adjust those values for your setting. As to what should be in the example in Bluezero; I'm not sure what is the best answer. It is probably whatever works the most broadly. But I don't know how that is discovered.
I have been running bluezero on a RPi 4 and the uart example has worked for me with the nRF Connect app as well as the nRF UART V2.0. However I have observed that the UART V2.0 app does not appear to request a notify so I have had to request notify in nRF connect within the TX characteristic.
I've taken some time to look at this today and I can't workout where the issue is. I can start the Bluezero Peripheral and then go into nRF Connect
and enable the notifications on the TX characteristic. If I disconnect in nRF Connect
and connect in UART V2.0
all works as expected.
Other experiments that I've tried are:
notifying=True
when creating/adding the characteristic to the peripheral doesn't seem to be enough.2902
“Client Characteristic Configuration Descriptor” (CCCD) but that just created 2 descriptors of that value.on_connect
callback to do StartNotify
on connection.StartNotify
just before publish.The StartNotify
experiments seemed to work on the second time of connecting with UART V2.0
I can't workout how doing a StartNotify
changes the CCCD on BlueZ. Maybe need to dive into the BlueZ code to better understand.
Any ideas or suggestions welcome.
I did the same experiments like you, but they failed.
Could you share how to use StartNotify
method to enable the notification?
Edited:
I checked why my Cypress chip can send notification automatically and I found it use this protocol which is highlighted in the Bluetooth official spec..
I think using this function is the major difference between RPI and Cypress chip.
I am not sure we can implement some functionality on RPI with BlueZ.
In BlueZ the CCCD in controlled by StartNotify
and StopNotify
characteristic methods. With the nRF UART 2.0
and Adafruit Bluefruit Connect
apps, they both send a request to start notifications when then first connect. If the current value on notifying
is False
then this works as expected. However, if the value has been set to True
then it fails. This is because Bluezero's implementation of StartNotify
does a test to see if calling the command toggles the state.
https://github.com/ukBaz/python-bluezero/blob/392a115ace80a6d7257b76708ec24b99ec9e2e5d/bluezero/localGATT.py#L373-L386
This is why the experiments I ran with notifying = True
only worked on the second attempt. On the first connection the CCCD never got changed to notifying because Bluezero thought it was already notifying and didn't change the state.
Reading the Bluetooth spec, it seems like 3.3.3.3 Client Characteristic Configuration
is the section that defines the behaviour:
It seems to be working as expected for the UART example as the clients expect to have to set the value of notifications on connection.
Are there any news? With iOS everything works as expected. Only my Android app returns 0x01 GATT_INVALID_HANDLE as error code while setting the descriptor. I found out that it works sometimes if I reboot the Raspi AND the android device
@jofleck: I think what I have found is that Notify
should not have been a value that add_characteristic
exposes. The characteristic should always be created with False
and then StartNotify
and StopNotify
takes care of changing the value.
I have not been able to repeatedly get it to fail. Can you say some more about the steps you are using to get it fail frequently on Android?
I found this issue while devoloping the Android app for our project.
Steps to reproduce:
Now nothing except restarting the Raspi and the Android device helps to get the Android smartphone working.
With iOS everything keeps working fine.
Have there been any updates on this issue? I'm running into the same thing with a Unity3D plugin. Thanks!
@dustinkerstein, I am not sure we are at the stage where we know where the error/issue is. Is it BlueZ, Bluezero, or maybe on the client side. What error reporting are you getting with the Unity3D plugin?
The GATT_INVALID_HANDLE
error that has been reported above makes me think it could be a cache issue. Are the clients bonding (pairing) with the peripheral?
Does refreshing the cache on the client help?
Does this issue exist if the BlueZ example is used? https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/test/example-gatt-server
Hey @ukBaz, I seem to think it's a mix of the client + maybe something else, possibly within bluezero or just the implementation of the ble-uart script. I tried that linked example-gatt-server but was unable to get it to show up in my BLE scans in nRF Toolbox under UART or the HeartRate category (and it also didn't show up in my Unity client). However, I have also been testing with a scripted derived from that example-gatt-server code, see here - https://scribles.net/creating-ble-gatt-server-uart-service-on-raspberry-pi/ - interestedly that code seems to run much more reliably, but I was having a little trouble adapting it to my uses (as it is currently based on stdin console input from the server). I'm sure it could be adapted, but I then found bluezero and it seems 10x simpler so I abandoned my work on that earlier script.
In my attempts to get the ble_uart script working, I went down a research hole around the importance of the descriptor in getting the notify behavior working. Ie. there's this special ID - "00002902-0000-1000-8000-00805f9b34fb" that Android particular seems to need. However, the script based on the example-gatt-server doesn't seem to use descriptors at all, at least in how the characteristics are interpreted on my Unity side. Though in the nRF Toolbox log, I can clearly see the notifications being enabled because of that descriptor...
I got a little impatient last night and just ended up ordering a couple of these - https://www.adafruit.com/product/2267 - which abstracts away all of this complex GATT / BLE stuff in favor of a simple serial interface, which for me, is all I need.
Good luck in figuring out the root cause. I would still love to use a python-based BLE solution, so I'll stay tuned to any updates here. Thanks again.
@ukBaz, oh and in reference to your question about refreshing the cache on the client, I don't think that had any help. I tried "Reset the Bluetooth Module" in MacOS, and even though I'm not entirely sure what it does, it did not have any effect. One thing that did seem to work, was connecting with nRF Toolbox and sending/receiving a few working messages, and then trying in Unity. The first time after using nRF, Unity would work, but on subsequent runs, it would get stuck in that state where the notifying flag was false.
This issue has sat here for while so closing. Please re-open with more information if it is still an issue.
My setup: raspberrypi 4 Model B BlueZ 5.50 Python3
When I try the uart example, I'm running into the followin issues. Nordic nrf tools can connect but fails later, hereby the llogging from nrf Toolbox:
gatt.WriteDescriptor(00002902-0000-1000-8-000-00805f9b43fb,value=0x01-00) Error(0x1): GATT INVALID HANDLE