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

pm_conn_secure pairs to devices but eventually stops

Hi all,

I am using an NRF52 and SDK 13.0

I have an external device (central) that I am connecting to using my (peripheral) device.

My peer manager set up is

#define SEC_PARAM_BOND                   1                                          /**< Perform bonding. */
#define SEC_PARAM_MITM                   0                                          /**< Man In The Middle protection not required. */
#define SEC_PARAM_IO_CAPABILITIES        BLE_GAP_IO_CAPS_NONE                       /**< No I/O capabilities. */
#define SEC_PARAM_OOB                    0                                          /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE           7                                          /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE           16                                         /**< Maximum encryption key size. */
#define SEC_PARAM_LESC                   0                                           /**< LE Secure Connections not enabled. */
#define SEC_PARAM_KEYPRESS               0 

static void peer_manager_init(bool erase_bonds)
{
    ble_gap_sec_params_t sec_param;
    ret_code_t err_code;

    err_code = pm_init();
    APP_ERROR_CHECK(err_code);
    TRACE("NUM PEERS %d\r\n", pm_peer_count());

    if (erase_bonds)
    {
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    }

    memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));

    // Security parameters to be used for all security procedures.
    sec_param.bond              = SEC_PARAM_BOND;
    sec_param.mitm              = SEC_PARAM_MITM;
    sec_param.lesc              = SEC_PARAM_LESC;
    sec_param.keypress          = SEC_PARAM_KEYPRESS;
    sec_param.io_caps           = SEC_PARAM_IO_CAPABILITIES;
    sec_param.oob               = SEC_PARAM_OOB;
    sec_param.min_key_size      = SEC_PARAM_MIN_KEY_SIZE;
    sec_param.max_key_size      = SEC_PARAM_MAX_KEY_SIZE;
    sec_param.kdist_own.enc     = 1;
    sec_param.kdist_own.id      = 1;
    sec_param.kdist_peer.enc    = 1;
    sec_param.kdist_peer.id     = 1;

    err_code = pm_sec_params_set(&sec_param);
    APP_ERROR_CHECK(err_code);

    err_code = pm_register(pm_evt_handler);
    APP_ERROR_CHECK(err_code);
}

I can see that when I connect to the external device, I get the following events

  • PM_EVT_CONN_SEC_START
  • PM_EVT_CONN_SEC_SUCCEEDED peer count 6 peer id 3 procedure PM_LINK_SECURED_PROCEDURE_PAIRING
  • PM_EVT_PEER_DATA_UPDATE_SUCCEEDED

Cool, it works. However, when I disconnect the reconnect (by turning the external device off and on) it connects again with the peer count increased by 1.

If I keep turning the device on and off, eventually I no longer see any more peer manager events for the device. This seems to happen after about 10 times. my call to pm_conn_secure returns NRF_SUCCESS

If I turn my device off and on again, the peer count is reset and I see Peer manager events again when connecting to my external device.

My questions are:

  1. Why does pm_conn_secure stop having an effect after about 10 reconnections?
  2. Why can I only pair to my external device whereas I can bond to it using an android phone and the NRF Connect app?
  3. How can I verify if the external device supports bonding?
  4. Why does it create a new peer every time I reconnect the external device? I imagine its something to do with it only pairing so the LTK etc aren't stored. How could I handle this better?
  • Could you tell a little bit more about your external device ? Is it also running on nRF5 chip or it's a device that you don't have control over ?

    If the central device bond and then don't store bonding information properly to re-use it on the next connection, you may run into issue as the central will try to create new bond every time it connects.

    In your peripheral code, you can choose to reject those bond request in the pm_evt_handler(), look for PM_EVT_CONN_SEC_CONFIG_REQ event. You can choose to allow allow_repairing or not.

    It's easier if we can have a sniffer trace to understand what exactly happens over the air.

  • Hi Hung, thanks for the reply. To answer your questions:

    • The external device is a device I don't have any control over.

    • I don't see the PM_EVT_CONN_SEC_CONFIG_REQ when I connect or reconnect an external device, just the events listed in my question

    • I have never been able to get the sniffer trace stuff to work properly so can't give you that, sorry

  • Without a sniffer trace it's very hard to guess what happen with your device and the external device. If your central device only support pairing (no bonding) every connection it will be treated as a new device. This is obvious because bonding is not supported.

Related