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

BLE-Peripheral doesn't respond to Bonding Request

I'm evaluating possibilities of BLE-LESC Pairing/Bonding with the ble_app_hrs peripheral on the nRF52840-DK with SDK 12.3 and SoftDevice s132.

To see what's going on in the background I used the nRF BLE sniffer (on a nRF52840-PDK).

The parameters I used on the peripheral for pm_sec_params_set are:
sec_param.bond           = 0;
sec_param.io_caps        = BLE_GAP_IO_CAPS_NONE;
sec_param.lesc           = 1;
sec_param.oob            = 0;
sec_param.min_key_size   = 7;
sec_param.max_key_size   = 16;
sec_param.mitm           = 0;

sec_param.kdist_own.enc  = sec_param.bond;
sec_param.kdist_own.id   = sec_param.bond;
sec_param.kdist_peer.enc = sec_param.bond;
sec_param.kdist_peer.id  = sec_param.bond;

When I now call device.createBond() in the app, the Phone sends a Authentication Request with Bonding (MITM, IO Caps: Keyboard, Display, and all keys) and the DK doesn't respond to this request. The connection breaks after a few seconds.

When changing sec_params.bond to 1 on the peripheral, a Bonding response is sent, the connection is encrypted and data can be sent.

I already implemented the DH Key Exchange for lesc by overriding BLE_GAP_EVT_LESC_DHKEY_REQUEST as done in ble_app_multirole_lesc with the uECC implementation (works), and called createBond in the App via overriding onDeviceConnected() in HRSActivity.java.
I've put the source code on GitHub for reference:
  ble_app_hrs: https://github.com/dCSeven/BLE_HRS_LESC
  Android_nRF_Toolbox: github.com/.../develop

Since no bonding would be preferred, the question is: What should I do different, to get pairing working?

  • Hi,

    I do not have access to an Android device at the moment, so I have not been able to test, but it seems to me that the Bluetooth API in Android does not provide a way to pair without bonding. If that is the case, then it is expected that pairing fails when the nRF is configured to pair only and the Android device is configured to bond. We could verify this if you have a sniffer trace? The logs from the mobile side and nRF side might also show this. You can also attempt to only pair with the nRF Device using nRF Connect for Desktop, which allows you so select to only pair. That would essentially prove that pairing works with the nRF, and that the issue is with the mobile device.

  • I tried the nRF Connect for Desktop (previously only used the mobile one), but the Desktop one is much cooler and has more features.

    When trying around with the program and after setting up logging on the peripheral, I noticed, that a fatal error is thrown on the peripheral when no bonding is configured and I pair using LESC (without lesc everything works fine).
    This error occurs in pm_evt_handler: PM_EVT_ERROR_UNEXPECTED with error code 0x10 (which is NRF_ERROR_INVALID_ADDR if I look it up correctly).
    When setting the bond flag, this doesn't happen.

    Here is a sniffer trace with Bonding enabled on the peripheral connecting to my phone. Without bonding the peripheral doesn't respond after the Bonding Request (probably caused by the error mentioned above).
    HRM_LESC_Bonding_central_initiated.pcapng

    I've updated the repository to output the error position on a FATAL error.

  • I was able to reproduce this on my side as well. The issue seems to be that the Peer manager only allocates memory for holding keys when doing bonding, not pairing. You can see this by tracking the error code further: The NRF_ERROR_INVALID_ADDR is returned from the call to sd_ble_gap_sec_params_reply() on line 640 in security_dispatcher.c, which is caused by all pointers in sec_keyset.keys_own and sec_keyset.keys_peer being NULL. The following modifications seems to fix the issue (I have not tested thoroughly, though):

    diff --git a/components/ble/peer_manager/security_dispatcher.c b/components/ble/peer_manager/security_dispatcher.c
    index e115367..26b52de 100644
    --- a/components/ble/peer_manager/security_dispatcher.c
    +++ b/components/ble/peer_manager/security_dispatcher.c
    @@ -574,7 +574,7 @@ ret_code_t smd_params_reply(uint16_t                 conn_handle,
             // NULL params means reject pairing.
             sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP;
         }
    -    else if (p_sec_params->bond)
    +    else
         {
             // Bonding is to be performed, prepare to receive bonding data.
             pm_peer_data_t       peer_data;
    @@ -622,10 +622,6 @@ ret_code_t smd_params_reply(uint16_t                 conn_handle,
                 }
             }
         }
    -    else
    -    {
    -        // Pairing only, no action needed.
    -    }
     
         if (err_code == NRF_SUCCESS)
         {
    

    As a side note I suggest that you move to SDK 15 (or later), as that is the first SDK with full support for nRF52840.

  • Thank you, this solved my problem.

    But how did you track the error code down?

Related