Correct configuration for secure connections pairing

Hi,

I want to implement a feature where the central device manually enters a fixed password (passkey) defined by the peripheral to establish a connection. I’m using the ble_app_hrs example from the nrf5_sdk_17.1.0_ddde560 SDK on the nRF52840-DK (using SEGGER Embedded Studio v8.24).

Below is my configuration in peer_manager_init() and the BLE_GAP_EVT_AUTH_KEY_REQUEST handling added to ble_evt_handler:

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 = 1;
    sec_param.lesc = SEC_PARAM_LESC;
    sec_param.keypress = SEC_PARAM_KEYPRESS;
    sec_param.io_caps = BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY;
    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);
}
case BLE_GAP_EVT_AUTH_KEY_REQUEST:
        {
            NRF_LOG_INFO("BLE_GAP_EVT_AUTH_KEY_REQUEST");
            //printf("BLE_GAP_EVT_AUTH_KEY_REQUEST.\n");
            uint8_t passkey[] = {'1','2','3','4','5','6'};  // Fixed 6-digit passkey
            err_code = sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle,
                                                 BLE_GAP_AUTH_KEY_TYPE_PASSKEY,
                                                 passkey);
            APP_ERROR_CHECK(err_code);
        } break;

When I set sec_param.io_caps = BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY, I receive the following on the central device (BlueZ) and in the peripheral’s RTT log:

BlueZ Output (Central):

[bluetooth]# info FC:E3:19:1A:8D:D3
Device FC:E3:19:1A:8D:D3
     Name: Nordic_HRM
     Paired: no ...
[bluetooth]# pair FC:E3:19:1A:8D:D3
Attempting to pair with FC:E3:19:1A:8D:D3
[CHG] Device FC:E3:19:1A:8D:D3 Connected: yes
[agent] Passkey: 991207 <-- Randomly generated
Failed to pair: org.bluez.Error.AuthenticationFailed
[CHG] Device FC:E3:19:1A:8D:D3 Connected: no

RTT Log from nRF52840-DK (Peripheral):

<info> app: BLE_GAP_EVT_AUTH_KEY_REQUEST
<info> peer_manager_handler: Connection security failed: role: Peripheral, conn_handle: 0x0, procedure: Bonding, error: 132
<warning> peer_manager_handler: Disconnecting conn_handle 0. <info> app: BLE_GAP_EVT_AUTH_STATUS: status=0x84 bond=0x0 lv4: 0 kdist_own:0x0 kdist_peer:0x0

How should I correctly configure sec_param.io_caps to make the central device prompt for a passkey input, allowing the user to manually enter the fixed passkey (e.g., 123456) so that pairing can succeed and look like the following? thank you.

Request passkey [agent] Enter passkey (number in 0999999): 123456


Related