sd: handle system attibutes on reconnect by ysoldak · Pull Request #86 · tinygo-org/bluetooth

So, I did my research and this is what I've found out.

Additionally, CCCDs have two special properties that separate them from other attributes:

Their values are unique per connection
In multi-connection scenarios, in which a central is connected to multiple peripherals and also acting as a GATT server, each peripheral will receive its own copy of the CCCD's value when reading it with ATT.

Their values are preserved across connections with bonded devices
Attribute Caching discusses attribute caching in more detail, but that concerns only attribute handles. Values are typically not stored per-device and the GATT server can reset them between connections. This is not the case with CCCDs among bonded devices: the last value written by a client to a CCCD on the server is guaranteed to be restored upon reconnection, regardless of the time elapsed between connections.

From "Getting Started with Bluetooth Low Energy by Kevin Townsend, Carles Cufí, Akiba, Robert Davidson"

Also, from NordicSemi forums:

By "system attributes" we primarily mean the Client Characteristic Configuration Descriptors (CCCD), i.e. attributes that are handled by the SoftDevice and have special requirements. It is mandated by Bluetooth specification that CCCD values are altered only by the peer, so you cannot change them from the application. Since CCCD values for a bonded peer should be stored between connections, an API exist for the application to store the values after disconnection, and to restore them on connection.

While you are in a connection, the SoftDevice will handle the CCCD as appropriate. When the peer writes to CCCD, that will be handled by SoftDevice.

The only thing related to the CCCD that you have to do from the application, is to store the data you get from sd_ble_gatts_sys_attr_get() on disconnection, and provide it back to the SoftDevice with sd_ble_gatts_sys_attr_set() on the BLE_GATTS_EVT_SYS_ATTR_MISSING event. You should treat the data as a blob of data of unknown format, i.e. you should store it as is and provide it back as is, without changing it. You should not try to write to the CCCD directly from the application.

https://devzone.nordicsemi.com/f/nordic-q-a/53548/what-is-a-system-attribute/217385


See also GATTS System Attributes Handling: Bonded Peer


This PR implements the logic of storing system attributes (think CCCD + checksum, but we treat the data as blob of unknown format) on disconnect and restoring them on SYS_ATTR_MISSING event.

System attributes is a unique thing for SoftDevice, no such thing exist for other targets. I don't really know how other implementations satisfy CCCD state restore on reconnect, probably it is hidden/abstracted from application layer.

No new API introduced, everything is internal.


In my project, to hack the subscription state, I'm calling respective SoftDevice function directly via CGo. No extra API needed from bluetooth package.