STM32WB and STM32WBA GATT Caching feature

Revision as of 18:48, 21 April 2023 by Registered User (→‎Flag configuration on STM32WBA)

1. GATT Caching feature

Discovering the GATT database of a remote device every time a connection is made takes a lot of time and energy.
To avoid this, most Bluetooth devices use attribute caching, that means that once they discovered the GATT database of a remote device, they store the discovered attribute handles for future use (in other words they store a local copy of the remote database structure, or at least parts of it).
This works well as long as the remote device keeps its GATT database structure unchanged. If the database structure changes - for example because of a firmware update that introduces new features - the stored attribute handles become invalid.

There are two methods to notify peer devices about the change:

  • using Service Change Indication
  • using GATT Caching feature

Service Change Indication was introduced in Bluetooth 4.0.
The main disadvantage of this method is, that it works only if the peer devices are bonded.

GATT Caching feature was introduced in Bluetooth 5.1 to overcome the bonding problem. Using GATT caching, every device can make sure, if it stores the latest version of the GATT database structure. This is achieved by:

  • Adding two new characteristics to the Generic Attribute service (Database Hash and Client Supported Features)
  • Adding a new GATT error code (database out-of-sync)

GATT Caching feature is implemented for STM32WB and STM32WBA.

1.1. GATT Caching new capabilities

The GATT caching feature brings the following changes in the STM32WB and STM32WBA BLE stack.
GATT server implementation:

  • At GATT initialization, two new characteristics to the GATT service are added:
    • Client Supported Features (for “Robust Caching”)
    • Database Hash
  • New GATT error codes may be generated upon client requests:
    • database out-of-sync (for “Robust Caching”)
    • value not allowed (for “Robust Caching”)
  • New GATT information stored in NVM:
    • Client supported features (for “Robust Caching”)
    • Client “change aware/unaware” state (for “Robust Caching”)

1.1.1. Database Hash characteristic

The Database Hash characteristic stores a 128bit value, which is a AES-CMAC hash calculated from the database structure.
Any change in the database structure will result in a different hash value.

After discovering the database once, the client should store this value. Next time, when the client connects to the server, it should only check if the Database Hash has changed. If it hasn't, it is safe to assume, that the database structure in unchanged, and the cached attribute handles are still valid. If it has changed, the client needs to rediscover the GATT database.

1.1.2. Database out-of-sync error code

If the client enables Robust Caching, by setting the Robust Caching bit to 1 in the Client Supported Features characteristic, then the server can send a database out-of-sync error code as a response to a GATT operation whenever it assumes, that the client has an out-of-date database.

If the client and the server are bonded, then the server checks if the database has changed since the last connection and notifies the client about the change via Service Change Indication - just like before introducing GATT caching.
The only difference is, that if the client initiates a GATT operation before the indication is received and confirmed, the server can send a database out-of-sync error code. This helps avoid race condition if the client would like to initiate a GATT operation too quickly after connection establishment.

If the client and the server are not bonded, then the server assumes, that the client checks the Database Hash and/or discovers the GATT database upon each connection before initiating any GATT operation.
It means that the server assumes that the client is aware of database changes after the connection was established. If there is a change in the database during connection, the client gets change-unaware.
At the next GATT operation the server sends a database out-of-sync error code to the client to signal this (except if the client reads the Database Hash meanwhile). From the next GATT operation the server assumes that the client is change-aware again.

1.2. Flag configuration on STM32WB

To enable GATT Caching feature on STM32WB:
Use SHCI_C2_BLE_INIT_OPTIONS_GATT_CACHING_USED to configure CFG_BLE_OPTIONS in app_conf.h

Feature available only in "full extended" ble stack and certified in Cube 1.16.

1.3. Flag configuration on STM32WBA

To enable GATT Caching feature on STM32WB:
Use BLE_OPTIONS_GATT_CACHING to initialize "options" field in pInitParams structure in app_ble.c

1.4. how to implement on STM32WB and STM32WBA applications

1. Set the flag and build the application.

2. Set the variable CFG_BLE_NUM_LINK to 1 (BLE link) + Channel_Number (parameter in ACI_L2CAP_COC_CONNECT command).
This Channel_Number corresponds to the number of "bearers" we want to establish.

3. Pairing and bonding of BLE link.

4. Establish a Connection Oriented Channel (COC) over the BLE link.

5. If condition 2. is filled, Channel_Number x ACI_GATT_EATT_BEARER_EVENT are received on central and peripheral sides.

On central side, Channel_Index (in ACI_GATT_EATT_BEARER_EVENT) is included between 0x00 and 0x1F.

On peripheral side, Channel_Index (in ACI_GATT_EATT_BEARER_EVENT) is included between 0x20 and 0x3F.

To address separately each bearer:
The connection handle to apply is between 0xEA00 and 0xEA1F for the central.

The connection handle to apply is between 0xEA20 and 0xEA3F for the peripheral.

2. Example of EATT feature including 5 bearers and data exchange

BLE and COC link establishment with EATT (SPSM=0x0027)


EATT bearers events


GATT data exchange


3. References