This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Notification write (response) lost when bonding

This week I worked myself to a series of what seemed to be problems boiling down to one issue: The Notification Write Response is lost when bonding has to happen first.

I'll try to illustrate this in more detail:

  • custom service, derived from NUS
  • Peer Manager
  • Just Works Bonding
  • nRF51822
  • S130
  • SDK 12.3.0

I set up both the RX and the TX characteristic with BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM in both the read and the write permission. Also, the notification for RX is set with BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM on write, but BLE_GAP_CONN_SEC_MODE_SET_OPEN on read_perm (because of this) and

#define SEC_PARAM_BOND              1
#define SEC_PARAM_MITM              0
#define SEC_PARAM_LESC              0 // or 1, doesn't matter
#define SEC_PARAM_KEYPRESS          0
#define SEC_PARAM_IO_CAPABILITIES   BLE_GAP_IO_CAPS_NONE
#define SEC_PARAM_OOB               0   
#define SEC_PARAM_MIN_KEY_SIZE      7 
#define SEC_PARAM_MAX_KEY_SIZE      16         

As far as I understood bonding: A central (smartphone) can connect to the peer, but when trying to write/enable the notification on RX, Pairing and then Bonding is initiated automatically.

It took me a while to find out that that part actually works. But then, the write on the notification gets lost...

I can replicate this problem also with the nRF Connect Android app, when not bonded and trying to enable the notification, the bond is created, but I have to enable the notification again to actually change it on the peer.

Is it supposed to work this way? That the first interaction with a characteristic, that needs authentication starts Pairing/Bonding but then, this first interaction never actually is followed through?

My current workaround is to have Android wait for the response to this notification write, if it doesn't come in time it is assumed lost and tried again until a successful write is confirmed.

If someone could confirm that there is no bug/ false behavior from peer manager or softdevice I will continue to work this way, otherwise it would be nice how to get rid of it.

If necessary, I can try and make a simpler version of my application that shows this behavior for you to test.

  • Hi,

    This is indeed the intended way for this to work. When you send a write request, you will get a write response with a GATT status. Anything else than "Success" means that the write failed. When you set up the characteristics with BLE_GAP_CONN_SEC_MODE_SET_ENC_*, you are actually setting access restrictions on the characteristic. This means that it is disallowed to write to the characteristic when the GAP security mode is less than the requirement. So your first write request will get a GATT status that says "Insufficient Authentication".

    It is possible to avoid this in a few ways:

    1. You can send a security request from your device immediately upon connection. This should trigger a pairing as normal, and if it happens before the write request, it will not end up being lost.
    2. You can decide to not security protect the attribute, but enable write authorization on it instead. Whenever someone tries to write to it, you will be allowed to make a call whether the write should go through, or if an error code should be returned. If you also choose to store the characteristic in user-space (VLOC_USER), you will be able to see the data in the request and manually set it for later.

    In any case, you should assume that a write request can fail, so harden your application to handle it. The way the SoftDevice is handling this is the default behavior of Bluetooth.

Related