This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

About GATT Server Context in HID mouse/keyboard example

Hi,

Sorry if these are silly questions but I've tried some searchings and still cannot figure out the answers for the questions below

  1. What is GATT Server Context? What is the data inside it specifically?

  2. What is the purpose of saving GATT Server Context to persistent memory for each bonded device and what happens if I lose it?

  3. I see in the example code that both gatts_context and bond_context are saved in persistent memory. And when there is a connect request from a previous bonded device, gatts_context will be loaded (applied) using sd_ble_gatts_sys_attr_set function. So, how about the bond_context (holds encryption info)? I dont see any function to load it.

I'm using Nordic nrf51822 chip with soft device s110 v7.0.0

Thank you for any help!

Parents
  • For bonded devices, you are required to remember the exchanged keys and the peer's "preferences" (i.e. GATT CCCD states like "notification enabled") shall be remembered between connections. This means that if a previously bonded device connects to you, you should be able to restore all the CCCD states as they were when you last communicated (this is done with sd_ble_gatts_sys_attr_set) and encrypt with the LTK received from earlier. I am not very familiar with the HID example, but I assume the two contexts refer to these two things. The GATT Server Context will contain every handle + value for each CCCD and the Bond Context I presume contain the encryption keys.

    Not remembering the encryption keys will lead to a new pairing happening each time, and might confuse the peer if you do not send a "Pin or key missing" response to the security key request (which should delete the bond on the peer side). Not remembering the CCCD states between connections with a bonded device is a spec violation, and will lead to interoperability problems down the road.

    Forgetting both the encryption keys and the CCCD context is allowed if you respond with "Pin or Key Missing", but this leads to a really slow ramp-up time. The bonding procedure exchanges a minimum of 6 packets + 1-2 for each key specified. It is also not possible to use IRK-based white-listing or Privacy 1.1/1.2 if you do not remember the Identity Resolving Key of your peer.

    So these contexts are needed for HID, and while losing both is fine from a "What's allowed" perspective, it will really hurt power usage, latency and interoperability. This could legitimately happen if the device is restored to factory settings or lose power before saving the contexts. Losing only one of them is not allowed however.

Reply
  • For bonded devices, you are required to remember the exchanged keys and the peer's "preferences" (i.e. GATT CCCD states like "notification enabled") shall be remembered between connections. This means that if a previously bonded device connects to you, you should be able to restore all the CCCD states as they were when you last communicated (this is done with sd_ble_gatts_sys_attr_set) and encrypt with the LTK received from earlier. I am not very familiar with the HID example, but I assume the two contexts refer to these two things. The GATT Server Context will contain every handle + value for each CCCD and the Bond Context I presume contain the encryption keys.

    Not remembering the encryption keys will lead to a new pairing happening each time, and might confuse the peer if you do not send a "Pin or key missing" response to the security key request (which should delete the bond on the peer side). Not remembering the CCCD states between connections with a bonded device is a spec violation, and will lead to interoperability problems down the road.

    Forgetting both the encryption keys and the CCCD context is allowed if you respond with "Pin or Key Missing", but this leads to a really slow ramp-up time. The bonding procedure exchanges a minimum of 6 packets + 1-2 for each key specified. It is also not possible to use IRK-based white-listing or Privacy 1.1/1.2 if you do not remember the Identity Resolving Key of your peer.

    So these contexts are needed for HID, and while losing both is fine from a "What's allowed" perspective, it will really hurt power usage, latency and interoperability. This could legitimately happen if the device is restored to factory settings or lose power before saving the contexts. Losing only one of them is not allowed however.

Children
  • Thank you for the swift response. I understand that sd_ble_gatts_sys_attr_set function is used to apply the gatt server context. But how about the bond context or encryption keys? When does it get applied? I mean, I only have the instance of it from persistent memory, but I dont see any function to apply it to the stack.

    One more question, I already asked a question about how to setup the paring/bonding again if one of the two devices lose the encryption info. This seems to be impossible as per a Nordic employee answered me but as you said that we can do this by sending a "Pin or key missing", I'm really confused now.

  • To my understanding, it should send a negative reply if you provide only null-pointers to the security fields of sec_info_reply().

  • Is it the function call sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL) that you're mentioning? If it is, the peer (an iPhone in my case) will still keep the connection, but it's unencrypted. As my application uses HID services that require encryption, doing so will make it got stuck with this iPhone (whenever I disconnect from my device's side, iPhone will automatically request a reconnecting if it see my device's advertising and get stuck in this unencrypted link again!)

  • After reading the spec, it does not explicitly mention deleting the bond when a rejection to re-encryption occurs. It only specifies to "abort the procedure". I think in cases where the bond is lost, you will have to manually delete the bond from the iPhone to make it re-encrypt.

  • Hi Ulrich, could you please give me some information about the need of storing and applying gatts_context to the system using sd_ble_gatts_sys_attr_set function?

    As my observation, when I reconnect to a previously bonded device, there seems to be no problem if I pass a NULL pointer to sd_ble_gatts_sys_attr_set function:

    sd_ble_gatts_sys_attr_set(conn_handle, NULL, 0);

    Everything still work fine even when my device switches the connection back and forth between its bonded peers (e.g. bond with peer 1 -> disconnect -> bond peer 2 -> disconnect -> reconnect with peer 1, ...) as long as I call the sd_ble_gatts_sys_attr_set upon BLE_GAP_EVT_CONN_SEC_UPDATE event (NULL pointer as parameter)

Related