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

Proper way to handle a bonded reconnect

According to the spec, this is how a bonded reconnect should work:

On first pass, the central client does discovery and enables descriptors to characteristics of interest. At sometime during this sequence, pairing occurs. The central saves the pairing data, services, etc,, and enabled state information. The peripheral server does the same.

On a reconnect, service discovery, pairing, and enabling descriptors is no longer needed as it is done and saved. One can get right down to data transfer after encryption is established.

Okay, in my pulse ox peripheral, I am having trouble with the restoring of the enabled states of the descriptors. This involves perhaps the most confusing of the sd_* procedures, the notorious

sd_ble_gatts_sys_attr_set

sd_ble_gatts_sys_attr_get 

and saving that info to a file between connections. One of the parameters in the calls is BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS or BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS or (and I am not sure here) entering nothing (0) or maybe the ORing?. I am not sure what I should be saving (and therefore restoring). My understanding is that the 'system services' are things like the service changed characteristic enabled state. 'user' services are things like the continuous measurement characteristic, spot measurement characteristic, and RACP characteristic but I am not sure.

I call the methods using BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS yet on a reconnect I get the error BLE_ERROR_GATTS_SYS_ATTR_MISSING and though I handle the BLE_GATTS_EVT_SYS_ATTR_MISSING event, it never gets signaled.

What do I need to do to fix this?

  • Should I call these methods with just a 0 value and that gives me both?
  • Since when I get the error I am trying to send a continuous measurement by notification should I just assume that the error BLE_ERROR_GATTS_SYS_ATTR_MISSING is misleading, it  really should be BLE_ERROR_GATTS_USR_ATTR_MISSING?

What is the procedure I should follow when disconnecting the first time connect?

  • call the sd_ble_gatts_sys_attr_get  method a couple of times to get the information with BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS or BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS or 0 or (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS)?
  • save the data to a file

On a reconnect, when should I restore the info by calling the sd_ble_gatts_sys_attr_set during the connection event? It better not be later because an RACP transaction can come real fast!

Do I also need to write to the client characteristic configuration descriptors myself on reconnect to restore their 'enabled' state?

  • Hi,

    First I just want to say that I am sorry for the late answer, we have been catching up on backlog from the Holidays.

    Second how come you are not using the peer manager (Architecture)? this SDK module would handle these things for you. If you take a look at the gatts_cache_manager module in our SDK you can see how we handle these attributes. More specifically the gscm_local_db_cache_apply function.

    If you are making your own "Peer manager": Did you see the Message sequence charts in our documentation?

    GATTS System Attributes Handling: Bonded Peer

    GATTS System Attributes Handling: Unknown Peer

  • There is no such support for the ble-pc-driver. Everything is based upon sd_* calls and that is all I have at my disposal. Besides, according to the documentation, what I am doing should work.

  • Hi,

    Unfortunately we do not have a bonding example for the pc-ble-driver. However serialization uses the same softdevice calls as the sdk does. In the SDK the Peer manager will create an event (PM_EVT_BONDED_PEER_CONNECTED) on connection that is forwarded to the gatts_cache_manager. This event will call a function local_db_apply_in_evt ( this will call gscm_local_db_cache_apply) that eventually results in sd_ble_gatts_sys_attr_set being called. Look at gatts_cache_manager.c:218

  • Pairing is not the problem.I have no problems with pairing or encryption on a reconnect. The problem is saving the 'enabled' state of the descriptors. On the first time connect, the peer pairs and then sets the CCCDs for indications or notifications (as needed). I save that information according to the documentation. On a reconnect I restore it according to the documentation. As I understand it, the peer should NOT have to re-set the CCCDs. But if the peer does not reset the CCCDs, no data will be sent and I get the above errors. So either my understanding of the pairing/bonding procedure is incorrect, or something is wrong with the documentation on how to restore the CCCD data.

    I guess I should add that when following the sequence diagram that you mention I never get the BLE_GATTS_EVT_SYS_ATTR_MISSING event. I submitted a ticket on that some time ago, but have received no resolution. So I am assuming that approach (as in the sequence diagram) does not work and I am trying to do what is done in the handling of that event in the connection event. I have long given up on the BLE_GATTS_EVT_SYS_ATTR_MISSING event.

    https://devzone.nordicsemi.com/f/nordic-q-a/54039/why-don-t-i-get-a-ble_gatts_evt_sys_attr_missing-event/223027#223027

  • Yes, you are correct. The peer should not have to re-set the CCCD's or perform service discovery on a reconnect when it is bonded.

    However I am a bit confused, as you say you do not get the BLE_ERROR_GATTS_SYS_ATTR_MISSING event? But is the peer actually trying to read something in this case?

    Also in case you call sd_ble_gatts_hvx, you can get an BLE_ERROR_GATTS_SYS_ATTR_MISSING error message. This is also a case where you need to set the system attribute.

    However, since this is serialization. Can you collect the content using system attribute get command, first before esthablishing a connection at all, then on disconnect. And then again after setting them after reestablishing the bond. Just want to check that it is actually updated during the connection and that the last get matches what you received on disconnect.

Related