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

Peer Manager fails to save bond

I am working on a BLE peripheral (nRF52832 & SDK 15) which uses the Peer Manager to handle encryption and bonding to a previously existing central device.  Sometimes bonding works, but often I am seeing a failure mode where the encryption and bonding process succeeds (the connection completes and data flows from central to peripheral and vice versa) but the Peer Manager doesn't save the bond.  I discover this when I disconnect and reconnect, and I get PM_EVT_CONN_SEC_FAILED with PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING.  

So far I have attempted to verify that the bond data isn't being stored by looking at what happens after I get PM_EVT_CONN_SEC_SUCCEEDED during bonding.  I went into peer_database.c and added some NRF_LOG()s in write_buf_store().  I see the write happen and no error is reported.  However I never get either PM_EVT_PEER_DATA_UPDATE_SUCCEEDED or PM_EVT_PEER_DATA_UPDATE_FAILED.  I put log msgs into pdb_pds_evt_handler() in peer_database.c, and in my own pm_evt_handler.  It appears that the bond save is failing silently.  This is very frustrating.

Sometimes the bond *is* successfully saved, and I'm able to reconnect to the central indefinitely.  I can't yet figure out why it sometimes succeeds.

I discovered this issue when starting to write code to handle a possible failure which could be caused by the central losing its bond data... the idea being that if the connection fails, both sides will the delete their bonds automatically and can then be manually rebonded by the user.  I test this scenario by manually deleting the bond in the central... on the next connection attempt, reestablishing the link fails and the peripheral deletes its bonds.  This all seems to be working as expected.  But when I manually rebond, I'm stuck... the nRF52 usually isn't saving the new bond.

This current project is to replace a remote control based on another vendor's BLE chip.  Encryption and bonding have worked for years with the central so I have no reason to distrust it.

Any advice on how to debug this further would be much appreciated.

Darren

  • I have one more specific question... I based my app on the proximity app so the code is basically identical with respect to pairing/bonding.  One question I have is why when the BLE_GAP_EVT_CONNECTED event happens, nrf_ble_qwr_conn_handle_assign() is called.  There are no comments in the example that explain why it would need queued writes.  There are no other references to qwr in the app.  Is it necessary for something else in the sd?  If I remove the calls and take queued write manager out of the makefile, no symbols are missing.  I've searched the sdk and online but can't find any obvious explanations.  I'm not using long writes in any characteristics.

  • I have spent many hours tracing the execution of fds and can now see what is failing, but not why.  When I write my config data, the write request is passed down into nrf_fstorage_sd.c.  The queue_process() function tries to write the header (FDS_OP_WRITE_HEADER_BEGIN) and calls write_execute().  The write_execute() function calls sd_flash_write() which returns NRF_SUCCESS, but the soft device doesn't generate an event, so the fstorage state machine cannot continue to process the write. There is a comment in nrf_fstorage_sd.c in the switch() case that handles the return value from write_execute():

                /* The operation was accepted by the SoftDevice.
                 * If the SoftDevice is enabled, wait for a system event. Otherwise,
                 * the SoftDevice call is synchronous and will not send an event so we simulate it. */
    

    Because the soft device is enabled, the code is waiting for a system event, and never gets one.

    I did the same trace exercise when pairing, and the store of the bond fails for the same reason, no event is generated.

    Do you have any advice about how to figure out why the soft device is not posting file system events but seems to otherwise work?

  • Hi Darren, 

    It's a very strange issue that you have. Could you try to use the same central to test with the unmodified ble_app_proximity ? I would suggest to try with a fresh copy of the SDK. Maybe you need to modify your central a little bit to work with ble_app_proximity. 

    What else you can try is to use a phone (use nRFConnect app) to connect to your device and bond to the device to see if bond info is stored or not. 

    Which connection parameter your central use ? We have this case where flash write api failed when the connection timeout was too short, maybe it's related ? 

    However, in your case , the API failed silently without anytime out, this is very strange. If you can provide a simple central and peripheral code that can reproduce the issue, it would be great help. 

    Regarding the qwr module, it's queued write assistance module we add to all the examples. It's not needed for all application, only needed if queued write is used. You can remove it. 

     

  • Hello,

    Here are the settings I'm using now

    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(7.5, UNIT_1_25_MS)          /**< Minimum acceptable connection interval. */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(30, UNIT_1_25_MS)         /**< Maximum acceptable connection interval. */
    #define SLAVE_LATENCY                   0                                       /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)         /**< Connection supervisory time-out (4 seconds). */
    

    I don't think this is the root of the problem though.  What I discovered yesterday is that my app can use fds to store data, if I *don't* enable the soft device first... the filesystem events flow as expected and the write succeeds.  However, when the soft device is enabled, my app cannot write data with fds, even if there is no active connection to a central.  This is very weird indeed.

    It would be quite a lot of work to modify our central, so I'm hoping I can find the answer another way.

    Searching online, I've seen many references to this problem from an earlier version of the SDK.  For example: this and this and this

    But with the current SDK doesn't appear to work this way since there isn't a softdevice_sys_evt_handler_set().

  • Hi Darren,

    The connection parameter looks fine. 

    Could you send a simplified version of your peripheral that reproduce the issue. Or you can modify the proximity application to add  some fds command to store some data. Similar to what we have here

     

Related