nimble/host: add server-side GATT caching support (Database Hash + robust caching)#2268
Open
gmarull wants to merge 6 commits into
Open
nimble/host: add server-side GATT caching support (Database Hash + robust caching)#2268gmarull wants to merge 6 commits into
gmarull wants to merge 6 commits into
Conversation
Add the ATT error code 0x12 (Core spec v5.4, Vol 3, Part F, 3.4.1.1), sent by a server to a change-unaware client as part of the GATT robust caching flow. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Add ble_gatts_calculate_hash(), which computes the GATT database hash as defined in Core spec v5.4, Vol 3, Part G, 7.3.1: an AES-CMAC (with an all-zero key) over the concatenation of the client-visible attribute database, in ascending handle order. Service declarations, includes, characteristic declarations and extended properties descriptors contribute handle, type and value; the 0x2901-0x2905 descriptors contribute handle and type only; all other attributes are excluded. Attributes hidden via ble_gatts_svc_set_visibility() are skipped, as they are not part of the client-visible database. The stream is fed incrementally into the Mbed TLS CMAC API, avoiding a heap allocation for a flattened copy of the database. Per-attribute values are read through ble_att_svr_read_local(), so declaration values come from the same access callbacks that serve regular ATT reads. The CMAC output is byte-swapped since the hash characteristic value is transmitted in little-endian byte order (matching PTS expectations and other stacks, e.g. Zephyr). The feature is gated behind the new BLE_GATT_CACHING syscfg setting, disabled by default. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Expose the Database Hash characteristic (0x2B2A) in the GATT service when BLE_GATT_CACHING is enabled, backed by ble_gatts_calculate_hash(). The hash is computed on each read; the database is static after ble_gatts_start(), and reads only happen when a caching client revalidates its cache, typically once per reconnection. This lets clients that cache the attribute database (notably iOS and Android) detect database changes across firmware updates deterministically, instead of relying only on Service Changed indications. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Add two store object types used by server-side GATT caching: - BLE_STORE_OBJ_TYPE_CSFC persists, per bonded peer, the Client Supported Features value written by the peer along with its change-aware state, both of which must survive reconnections for bonded clients (Vol 3, Part G, 2.5.2.1). - BLE_STORE_OBJ_TYPE_DB_HASH persists the local database hash, so the host can detect across reboots (e.g. firmware updates) that the database changed and mark bonded peers change-unaware. ble_store_util_delete_peer() now also removes the peer's CSFC record, tolerating stores that do not handle the new object type. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Store and load the CSFC and database hash records in the config store backend when BLE_GATT_CACHING is enabled. They are persisted under the ble_hs/csfc and ble_hs/db_hash settings, following the existing CCCD pattern; CSFC records are capped at BLE_STORE_MAX_BONDS. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Implement the server side of GATT robust caching (Vol 3, Part G, 2.5.2.1) on top of the Database Hash characteristic, enabled by the BLE_GATT_CACHING syscfg setting. The structure mirrors Zephyr's PTS-validated implementation. Each connection tracks a change-aware state in ble_gatts_conn. A change-unaware client that enabled Robust Caching in its Client Supported Features receives an ATT Database Out Of Sync error (0x12) once on the fixed bearer, and its commands are ignored; the error is gated centrally in ble_att_rx_extended() before dispatch. Read By Type requests over the full handle range, or for Include / Characteristic declarations, are exempt so the client can read the Database Hash and rediscover. A client becomes change-aware again when it reads the Database Hash and sends another request, confirms a Service Changed indication (only when using just the fixed ATT bearer, per spec), or sends another request after the error (fixed bearer only). Writing Client Supported Features also marks the client change-aware. Per-bearer tracking of the error on enhanced bearers is not maintained: change-unaware clients get the error on every EATT request until they revalidate via the hash. For bonded peers, the features and change-aware state persist through the CSFC store record: stored when bonding is established and on every state transition, restored when encryption with a bonded peer is re-established. State is not restored before encryption; before that, a reconnected bonded peer is served normally. On ble_gatts_start() the database hash is compared against the persisted copy and, on mismatch (e.g. after a firmware update), all persisted peers are marked change-unaware. Service visibility changes mark all peers, connected and persisted, change-unaware at runtime. Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
Contributor
|
Hi, is this from scratch or based on #2098 ? |
Contributor
Author
I was not aware of that PR, this is from scratch |
Contributor
Author
|
@sjanc what is the plan for this feature? I'd like to know if you're expecting to have something in-tree soon (be based on this PR or the other; I don't care really). I'm happy to iterate on this PR if needed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This series adds server-side support for GATT caching as defined in Core spec v5.4, Vol 3, Part G, 2.5.2 and 7.3:
Everything is gated behind the new BLE_GATT_CACHING syscfg setting, disabled by default.
Note: Briefly tested on PebbleOS, where we need this feature. We'll conduct more tests in the following days.