bluekitchen / btstack

Dual-mode Bluetooth stack, with small memory footprint.
http://bluekitchen-gmbh.com
Other
1.64k stars 592 forks source link

Arduino Port: Subscribe to Notifications not Working. Function missing. #615

Open ullibak opened 2 weeks ago

ullibak commented 2 weeks ago

My setup: Raspberry Pi Pico on Arduino IDE, Board definition github.com/earlephilhower/arduino-pico

This board definition relies on the Arduino port of BTstack. The wrapper and the examples are derived from the files published in port/arduino.

The example port/arduino/examples/LECentral/LECentral.ino uses the function device->subscribeForNotifications() in line 252 to subscribe to notifications. This calls the lower level function BTstackManager::subscribeForNotifications() in line 665 of port/arduino/BTstack.cpp

The subscription is acknowledged, but the callback routine for notifications is not called when the server sends a notification.

Comparing to the example pico_w/bt/standalone/client.c, I find that when subscribing to notifications, an additional function of the BTstack library has to be called: _gatt_client_listen_for_characteristic_valueupdates() (line 119 of this example). This function, however, is not implemented in port/arduino/BTstack.cpp.

If I add the function _gatt_client_listen_for_characteristic_valueupdates() to BTstacklib.cpp in a quick and dirty way, the notifications work as expected.

static gatt_client_notification_t notification_listener;

int BTstackManager::subscribeForNotifications(BLEDevice * device, BLECharacteristic * characteristic) {
    gattAction = gattActionSubscribe;
    // ADDED
    gatt_client_listen_for_characteristic_value_updates(&notification_listener, gatt_client_callback,  device->getHandle(), (gatt_client_characteristic_t*) characteristic->getCharacteristic());
    // END ADDED
    return gatt_client_write_client_characteristic_configuration(gatt_client_callback, device->getHandle(), (gatt_client_characteristic_t*) characteristic->getCharacteristic(),
            GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION);
}

But this is probably not the correct way since there ist some bookkeeping around _notificationlistener involved in the example client.c mentioned above.

I guess that the solution might be to add the function _gatt_client_listen_for_characteristic_valueupdates() to BTstacklib.cpp either by adding it to BTstackManager::subscribeForNotifications() or by giving it a separate function definition. I tried both methods and they work. But there ist still the issue of keeping track of _notificationlistener and call

_gatt_client_stop_listening_for_characteristic_value_updates(&notificationlistener);

when disconnecting from the device.

I posted this issue in https://github.com/earlephilhower/arduino-pico/issues/2231 but later found that the function wrapper is based on the Arduino port of the BTstack library. Therefore, I am posting this issue here, hoping that the experts here can find a proper and reliable solution to this issue.

Thanks!

mringwal commented 1 week ago

Hi there.

I don't have a working setup to test this Arduino wrapper on my desktop (without using hardware) and never tried/played with Arduino on ESP32 or Pico W.

On both platforms, BTstack can be used directly.

Anywya, the missing call to gatt_client_listen_for_characteristic_value_updates has been reported before, but others haven't been able to test changes.

As your quick fix works, please try to add this call to BTstackManager::setup(void) after the call to gatt_client_init():

gatt_client_listen_for_characteristic_value_updates(&notification_listener, gatt_client_callback, GATT_CLIENT_ANY_CONNECTION, NULL);

This uses some kind of 'catch all' notification listener, which doesn't need to be removed.