weliem / bluez_inc

A C library for Bluez (BLE) that hides all DBus communication. It doesn't get easier than this. This library can also be used in C++.
MIT License
84 stars 19 forks source link

Missing notification enable callback on android phone #24

Closed Kindzer closed 6 months ago

Kindzer commented 6 months ago

Hi @weliem

I'm using your bluz dbus project to build my application which can do stuff with mobile applications. My custom service contains some characteristics with notification property. When I run nrf connect I am able to enable disable notifications properly. But when I run custom application on Android the notifications are not enabled, however in nrfLog application I can see that write to ccc was done.

NOTE: the same application works fine on iphone,

I'll attach the log from nrfLogger app:

16:25:45.384 Connecting to C4:BD:E5:5C:38:C9... 16:25:45.384 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M) 16:25:45.398 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2) 16:25:45.398 Connected to C4:BD:E5:5C:38:C9 16:25:45.398 Discovering services... 16:25:45.398 gatt.discoverServices() 16:25:45.403 [Callback] Services discovered with status: 0 16:25:45.403 Services discovered 16:25:45.409 Generic Access (0x1800)

Do you have any idea what the possible issue can be?

MoldovanRaduOctavian22 commented 6 months ago

Hello @weliem and @Kindzer

I'm in a similar situation to the one described above, I use my Android app to write the CCC descriptor to 0100 in order to enable notifications, but when I run my BLE server on the RaspberryPi it sometimes seems to misinterpret the writing of that descriptor and not enable the characteristic notifications. I found this out by monitoring the DBUS Bluez messages:

When notifications get enabled and things work fine, the StartNotify method gets called when I write the CCC descriptor:

Type=method_call Endian=l Flags=1 Version=1 Cookie=2651 Sender=:1.16 Destination=:1.99 Path=/org/bluez/dbz_application/service_0/char_1 Interface=org.bluez.GattCharacteristic1 Member=StartNotify UniqueName=:1.16 MESSAGE "" { };

When the notifications don't trigger, the WriteValue for the descriptor method gets called:

Type=method_call Endian=l Flags=0 Version=1 Cookie=2844 Sender=:1.16 Destination=:1.107 Path=/org/bluez/dbz_application/service_0/char_1/desc_0 Interface=org.bluez.GattDescriptor1 Member=WriteValue UniqueName=:1.16 MESSAGE "aya{sv}" { ARRAY "y" { BYTE 1; BYTE 0; }; ARRAY "{sv}" { DICT_ENTRY "sv" { STRING "device"; VARIANT "o" { OBJECT_PATH "/org/bluez/hci0/dev_74_B0_0A_B8_27_BF"; }; }; DICT_ENTRY "sv" { STRING "link"; VARIANT "s" { STRING "LE"; }; }; DICT_ENTRY "sv" { STRING "mtu"; VARIANT "q" { UINT16 517; }; }; }; };

The problem gets encountered randomly, when I run my program notifications either work fine or not at all and I didn't find any particular reason for this.

I have also noticed that running the BLE server functionality by itself never made me run into this issue. I use the library to create a BLE server into a program that does many other things, and works on several threads. This is the cases in which the issue appears infrequently.

Did you find any cause for the problem ?

I'll try my best to find a solution and reach you out if I discover something.

weliem commented 6 months ago

Please share the code where you create your services and characteristics so that I can try to reproduce the issue.

MoldovanRaduOctavian22 commented 6 months ago

Please share the code where you create your services and characteristics so that I can try to reproduce the issue.

I have found the problem for my case. Bluez automatically creates CCC notification descriptor when you create a characteristic that has the 'notify' flag, but I thought that I have to manually create the CCC descriptor in code. Once I removed the code that creates the descriptor, the notifications started to work fine. It must have had a conflict between the 2 descriptors, the CCC one and the one that I was creating.

Kindzer commented 6 months ago

Hi everyone, I found out the issue after I got access to Android application source code. It turned out that the Android application is made with wrong approach. All requests are handled with Thread.sleep() which can probably work with rtos, but not with linux. I tried to make some changes there and made it work.

The second problem is that notification are actually enabled only on android side and there were no actual write requests to ccc descriptors for enabling them on linux side.