BLE Notify Characteristic identification in change notification callback

Hello,

In my project I am creating a BLE service with 7 characteristics that are all NOTIFY only characteristics.

My service setup looks like the following:

BT_GATT_SERVICE_DEFINE(my_srvc, BT_GATT_PRIMARY_SERVICE(MY_SERVICE),
    BT_GATT_CHARACTERISTIC(MY_CHAR_1, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, NULL, NULL, NULL),
    BT_GATT_CCC(notifyStateChanged, BT_GATT_PERM_NONE),
    BT_GATT_CHARACTERISTIC(MY_CHAR_2, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_NONE, NULL, NULL, NULL),
    BT_GATT_CCC(notifyStateChanged, BT_GATT_PERM_NONE),
...etc...
As you can see from above, I'd like to use the same callback method (notifyStateChanged) to handle the enabling and disabling of the notifications. My issue is that it appears that the bt_gatt_attr object handed to the cb function cannot be used to identify the characteristic.
My callback looks like the following. I have attempted to use attr->uuid as well as the user_data->uuid in the bt_uuid_cmp() function but neither one works. When printing out those two uuid values, neither one represents the characteristic being enabled/disabled. Is there a way to accomplish my goal of using a single callback or must I create 7 different callback functions that all do the same thing other than having a different mask value?
static void notifyStateChanged(const struct bt_gatt_attr *attr, uint16_t value)
{
    struct bt_gatt_chrc *user_data = attr->user_data;
    bool enabled = (value==BT_GATT_CCC_NOTIFY);
    int mask = 0;


    if (bt_uuid_cmp(attr->uuid, MY_CHAR_1) == 0) {
        mask = MYCHAR1_NOTIFY_FLAG_SET;
    } else if (bt_uuid_cmp(attr->uuid, MY_CHAR_2) == 0) {
        mask = MYCHAR2_NOTIFY_FLAG_SET;
    } else ... {
        ...
    }

    if (enabled) {
        notificationFlags |= mask;
    } else {
        notificationFlags &= ~mask;
    }
}
I am developing with VSCode + nRF Connect for VS Code. I am using version 2.7.0 of the nRF toolchain and SDK.
Thank you for any guidance on this issue.
-Mike
  • Hi,

    I am not able to find any examples of this being done before, nor am I able to find a parameter you can filter on. While not exactly what you asked for, an option could perhaps be to use separate callback functions for each, that in turn call a common function but also pass an enum or something else you can use to determine from wher it came. That way you can still keep most of the implementation in one common function.

  • Einar,

    Thanks for the response. Seems that having the characteristic UUID available in the call back would be very helpful to keep the code base smaller and more succinct. But, in the meantime, I've taken your advice and created a bunch of 1 line functions that delegate to a central notification config handler function and it's working just fine.

    -Mike

Related