How to get pairing/bonding to work in e.g. ble_app_uart

   Hello List,

First some context: I am working with SDK 17.1.0 on a nrf52840 (arduino nano ble).

Created a variant of the ble_app_uart example and want to add pairing/bonding with it. Started looking at ble_app_hrs to start.

Basically I added functions "peer_manager_init" and "pm_evt_handler" and some changes to "sdk_config.h", but now am stuck. Please see below for that code.

With this code it just works, but without pairing/bonding.

If I remove the "pm_conn_sec_params_reply" call from "pm_evt_handler" the smartphone pops up a window and asks whether there should be a pairing, which then fails as can be seen using the RTT-log:

<error> peer_manager_sm: Could not perform security procedure. smd_params_reply() or smd_link_secure() returned NRF_ERROR_INVALID_ADDR. conn_handle: 0
<error> peer_manager_handler: Unexpected fatal error occurred: error: NRF_ERROR_INVALID_ADDR
<error> peer_manager_handler: Asserting.
<error> app: Fatal error

One thing that is missing is setting the pin code in the program, how is that to be done?

Hopefully someone can help me in the right direction.

Thanks in advance, Sietse

Here the code snipped.

// peer_manager stuff in main.c
      
#include "peer_manager.h"
#include "peer_manager_handler.h"
#include "fds.h"

#define SEC_PARAM_BOND                      1                                       /**< Perform bonding. */
#define SEC_PARAM_MITM                      0                                       /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC                      1                                       /**< LE Secure Connections enabled. */
#define SEC_PARAM_KEYPRESS                  0                                       /**< Keypress notifications not enabled. */
#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. */


static void pm_evt_handler(pm_evt_t const * p_evt)
{
    pm_handler_on_pm_evt(p_evt);
    pm_handler_disconnect_on_sec_failure(p_evt);
    pm_handler_flash_clean(p_evt);

    switch (p_evt->evt_id)
      {
      case PM_EVT_PEERS_DELETE_SUCCEEDED:
	advertising_start();
	break;

      case  PM_EVT_CONN_SEC_SUCCEEDED:
	NRF_LOG_INFO("--> PM_EVT_CONN_SEC_SUCCEEDED");
	break;
      case  PM_EVT_CONN_SEC_PARAMS_REQ:
	NRF_LOG_INFO("--> PM_EVT_CONN_SEC_PARAMS_REQ");
	pm_conn_sec_params_reply(p_evt->conn_handle,
				 p_evt->params.conn_sec_params_req.p_peer_params,
				 p_evt->params.conn_sec_params_req.p_context);
	break;
      default:
	NRF_LOG_INFO("--> pm_evt_handler %d", p_evt->evt_id);
	break;
    }
}



/**@brief Function for the Peer Manager initialization.
 */

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

    err_code = pm_init();
    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);
}


Parents
  • Hi

    This error seems very strange, as the  smd_params_reply() or smd_link_secure() don't have NRF_ERROR_INVALID_ADDR as a return value, so the error message doesn't make much sense to me. Have you checked out the Peer Manager documentation and the Usage chapter that shows how to typically add the Peer Manager and thus pairing/bonding to an application?

    The project you're making is for a peripheral device, is that correct? What device are you trying to pair/bond to exactly? Another nRF device or a phone/computer?

    Best regards,

    Simon

Reply
  • Hi

    This error seems very strange, as the  smd_params_reply() or smd_link_secure() don't have NRF_ERROR_INVALID_ADDR as a return value, so the error message doesn't make much sense to me. Have you checked out the Peer Manager documentation and the Usage chapter that shows how to typically add the Peer Manager and thus pairing/bonding to an application?

    The project you're making is for a peripheral device, is that correct? What device are you trying to pair/bond to exactly? Another nRF device or a phone/computer?

    Best regards,

    Simon

Children

  • Thanks for the reply!


    I am indeed trying do make a periphiral (ble_periphiral/ble_app_uart) and connect to android or PC (Linux).
    I now created a version that ONLY added the (hopefully) relevant parts from ble_app_hrs to ble_app_uart_pair.
    For completeness here the code.

    ble_app_uart_pair.zip

    See the diff between main.c and main.c_org for the additions.
    There also are some differences in sdk_config.h and the Makefile of course.
    The Makefile_pca10056 is a version for use with BOARD_PCA10056.
    Now to my problem.

    I re-read the documentation about the peer manager and found one error I think.
    I mistakenly had "PM_CENTRAL_ENABLE 1" in sdk_config.h. Changed this to 0, but nothing changed.

    So, the app works fine (with android and PC), but there is no pairing at all!
    Here RTT log from a short session:
    <info> app: --> PM_EVT_CONN_SEC_PARAMS_REQ
    <debug> app: --> pm_conn_secure return: 0
    <debug> nrf_ble_gatt: ATT MTU updated to 247 bytes on connection 0x0 (response).
    <info> app: Data len is set to 0xF4(244)
    <debug> app: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
    <debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 251
    <debug> nrf_ble_gatt: max_tx_octets: 251
    <debug> nrf_ble_gatt: max_rx_time: 2120
    <debug> nrf_ble_gatt: max_tx_time: 2120
    <debug> app: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
    <debug> nrf_ble_gatt: Peer on connection 0x0 requested an ATT MTU of 517 bytes.
    <debug> nrf_ble_gatt: Updating ATT MTU to 247 bytes (desired: 247) on connection 0x0.
    <info> app: Data len is set to 0xF4(244)
    <debug> app: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
    <debug> app: Received data from BLE NUS. Writing data on UART.
    <debug> app: 66 20 67 20 66 |f g f
    <info> app: Disconnected

    Note that pm_conn_service is called but there is no PM_EVT_CONN_SEC_START event!

    But, if the pairing is initiated on linux, by doing a "bluetoothctl pair E7:05:43:10:93:D3" I get the following reaction:
    On linux:
    Attempting to pair with E7:05:43:10:93:D3
    [CHG] Device E7:05:43:10:93:D3 Connected: yes
    [CHG] Device E7:05:43:10:93:D3 Connected: no
    Failed to pair: org.bluez.Error.AuthenticationCanceled

    and via RTT from the target:
    <info> app: --> PM_EVT_CONN_SEC_PARAMS_REQ
    <debug> app: --> pm_conn_secure return: 0
    <debug> nrf_ble_gatt: Data length updated to 251 on connection 0x0.
    <debug> nrf_ble_gatt: max_rx_octets: 251
    <debug> nrf_ble_gatt: max_tx_octets: 251
    <debug> nrf_ble_gatt: max_rx_time: 2120
    <debug> nrf_ble_gatt: max_tx_time: 2120
    <debug> app: ATT MTU exchange completed. central 0xF7 peripheral 0xF7
    <info> app: --> pm_evt_handler 2
    <info> app: --> PM_EVT_CONN_SEC_PARAMS_REQ
    <error> app: Fatal error

    Note that "pm_evt_handler 2" is PM_EVT_CONN_SEC_START
    So now we get a little bit further.
    But, why the fatal error?

    Thanks again, Sietse

    PS. And if it had worked, where could I have set the required pincode on the target?

Related