This blog is to give an idea how to control the BLE peripheral either accept or reject the bonding request from the central role.

Nordic Softdevice Message Sequence

Nordic SoftDevice

Peripheral Security Request

msc_inline_mscgraph_11

https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.api.v7.0.1/group___b_l_e___g_a_p___p_e_r_i_p_h___s_e_c___r_e_q___m_s_c.html

Pairing failure: Pairing aborted by the application

When the application detects that the pairing should not be performed, for example an insufficient IO combination, it can use sd_ble_gap_sec_params_reply() to send SMP Pairing failed to the peer.

msc_inline_mscgraph_25

https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.api.v7.0.1/group___b_l_e___g_a_p___p_e_r_i_p_h___p_a_i_r_i_n_g___a_p_p___e_r_r_o_r___m_s_c.html

SDK Sequence

Here is the flow diagram internal with Peer Manager, Security Manager and Security Dispatcher.

Example

I would cover two difference examples how to accept or reject the bonding request from host.

  • ble_app_hids_keyboard (Pre-set the response before getting the security request)
  • ble_app_hids_keyboard_Yes_or_no (Real-time to give the response during security request flow)

Example 1 (ble_app_hids_keyboard)

I plan to use the ble_app_keyboard as the example code and run on the nRF52840 DK Board.

I would use the Button 3 to toggle the flag either accept or reject on the bonding request.

        case BSP_EVENT_KEY_3:
                if (m_allow_bonding)
                {
                        m_allow_bonding = false;
                        NRF_LOG_DEBUG("Force to reject bonding");
                }
                else
                {
                        m_allow_bonding = true;
                        NRF_LOG_DEBUG("Allow bonding");
                }

The key point is to reply the BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP after getting the BLE_GAP_EVT_SEC_PARAMS_REQUEST (Request to provide security parameters).

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

        NRF_LOG_DEBUG("%s, evt_id = %02x", __func__, p_evt->evt_id);
        ret_code_t err_code;

        switch (p_evt->evt_id)
        {
        case PM_EVT_CONN_SEC_PARAMS_REQ:               
        {
                // pm_conn_sec_params_reply(m_conn_handle, )
                NRF_LOG_DEBUG("PM_EVT_CONN_SEC_PARAMS_REQ");
                if (m_allow_bonding == false)
                {
                        err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, p_evt->params.conn_sec_params_req.p_context);
                        APP_ERROR_CHECK(err_code);
                }
        }
        break;
Reject the bonding request from the central

Example 2 (ble_app_hids_keyboard_Yes_or_no)

Add the configuration at the SDK_CONFIG.h on such feature

// <i> If set to true, it lets the customer to answer Yes/Non on Bonding Request from Central.

#ifndef PM_SECURITY_USER_SELECTION_ENABLED
#define PM_SECURITY_USER_SELECTION_ENABLED 1
#endif

Add one new enum (PM_EVT_CONN_SEC_PARAMS_REQ_PENDING)

In the example code, the user needs to press button 2 or 3 for give the bonding response to host within 30 seconds.

The example project can be found at https://github.com/jimmywong2003/nrf52-how-to-reject-bonding-from-central.

Welcome to give any feedback and comment here.