Reload GATT Handlers after reboot when GATT caching is active

Hi 

I'm using two nRF52840 devices, one central and one peripheral, and sdk version 3.0.1.

On the central side I enabled:

CONFIG_BT_GATT_CACHING=y

So far GATT caching works as expected, on normal reconnection, service and characteristic rediscovery is no needed to reuse attribute handlers. 

However, when I reboot the central, I’m not sure how attribute handle restoration is supposed to work.

After settings_load(), is there a way to restore previously discovered attribute handles automatically? Or must the central always perform full service discovery again after reboot? Currently I'm doing a rediscovery after each reboot as workaround. 

As I understand it, only the attribute database hash is stored but not the actual characteristic handles or discovery results.

Is that correct? What should be the correct workflow when central reboots?

Thanks

  • Hi

    This sounds like it's set up correctly to me. One thing though, from the bt_gatt_service_register() function in gatt.h. When using CONFIG_BT_GATT_CACHING and CONFIG_BT_SETTINGS, all services that are being included in the GATT database should be added before calling settings_load. All services registered after settings_load will trigger a new database hash calculation with a new hash stored. So where are you registering your services exactly?

    Can you also give some more information on how exactly the reboot in central is done. It doesn't do any erasing of pairing/bonding information when turned off, right?

    Best regards,

    Simon

  • Thank you Simon for you reply.


    I never call bt_gatt_service_register() in either the central or peripheral code.

    In central I defined all uuid of all the services and characteristics of interest using

    static const struct bt_uuid_128 my_char_uuid = BT_UUID_INIT_128(XXX); 

    and then during discovery I call gatt_discover_by_uuid(..) to get the handle and store it in a variable.

    In peripheral I define the services and characteristics using BT_GATT_SERVICE_DEFINE, BT_GATT_PRIMARY_SERVICE and BT_GATT_CHARACTERISTIC.  

    BT_GATT_SERVICE_DEFINE already registers the service, so bt_gatt_service_register() is not needed. 

    I reboot the central using the RST button. The bond information is stored in flash memory and loaded after rebooting, so no bonding information is erased.

    The only problem for me was the value of the attribute handles. I was wondering if there is a way to restore them. Something like this:

    settings_load();
    if ( central_bonded () ) {
           attr_handle = load_handle_by_uuid(my_char_uuid);
    }

    because at the end central needs the attr_handle value to write / read characteristics. 

    So how can I get the attr_handle in central without rediscovering the characteristics?  Is that even possible with the GATT API?

  • Hi

    If the central reboots and repopulates the attribute table there is no guarantee that the attribute handles stay the same I'm afraid. Using bt_gatt_resubscribe() on the central side would be the recommended way to handle reboots by the central here I think. The the attribute handle you get from attr_handle = load_handle_by_uuid(my_char_uuid) would be invalid after a server reboot as you are not getting the new handle from the central . Invalid here meaning it most likely won't point to the same attribute anymore. We cannot guarantee the central repopulates the attributes in the same order and the attribute of the interest is never guaranteed to have the same attribute handle after reboot on the server side.

    Best regards,

    Simon

Related