nRF Connect can connect nRF52832 without passkey

I refer to https://github.com/alc6/nrf52-pc10040-multiperipheral-passkey/blob/master/main.c for implementing static passkey. But nRF Connect can connect nRF52832 without passkey.

 0> <info> app: Version 1.0.0
 0>
 0> <info> app: ========| flash info |========
 0> <info> app: erase unit:   4096 bytes
 0> <info> app: program unit: 4 bytes
 0> <info> app: end address: 0x7FFFF
 0> <info> app: ==============================
 0> <info> app_timer: RTC: initialized.
 0> <debug> app: NOR_DATA_PERIOD=819
 0>
 0> <debug> app: NOR_RECORD_PERIOD=8192
 0>
 0> <info> app: bsp_button_longkey_handler 0.
 0> <warning> app: Battery volage 128mV is too low
 0>
 0> <warning> app: Battery volage 8mV is too low
 0>
 0> <warning> app: Battery volage -8mV is too low
 0>
 0> <debug> app: Battery volage 3981mV
 0>
 0> <info> app: POWER_ON.
 0> <info> app: External devices initializing start
 0> <info> app: External devices initializing finish
 0> <info> app: bsp_button_longkey_handler 1.
 0> <debug> nrf_ble_gatt: Requesting to update ATT MTU to 185 bytes on connection 0x0.
 0> <info> app: Connected.
 0> <debug> app: state=1
 0>
 0> <debug> nrf_ble_gatt: ATT MTU updated to 185 bytes on connection 0x0 (response).

  • #include "sdk_config.h"
    #include "advertising.h"
    #include "ble_conn_state.h"
    #include "error.h"
    #include "fds.h"
    #include "nrf_log.h"
    #include "peer_manager.h"
    #include "peer_manager_handler.h"
    #include "peer_manager_types.h"
    #include "security.h"
    
    #define SEC_PARAM_BOND                  1                                           /**< Perform bonding. */
    #define SEC_PARAM_MITM                  0                                           /**< Man In The Middle protection required (applicable when display module is detected). */
    #define SEC_PARAM_LESC                  0                                           /**< LE Secure Connections not 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. */
    
    
    #define PASSKEY_TXT                     "Passkey:"                                  /**< Message to be displayed together with the pass-key. */
    #define PASSKEY_TXT_LENGTH              8                                           /**< Length of message to be displayed together with the pass-key. */
    #define PASSKEY_LENGTH                  6                                           /**< Length of pass-key received by the stack for display. */
    
    static void _pmEvtHandler(pm_evt_t const * pEvt) {
        ret_code_t errCode;
    
        switch (pEvt->evt_id) {
            case PM_EVT_BONDED_PEER_CONNECTED:
            {
                NRF_LOG_INFO("Connected to a previously bonded device.");
            } break;
    
            case PM_EVT_CONN_SEC_SUCCEEDED:
            {
                NRF_LOG_INFO("Connection secured: role: %d, conn_handle: 0x%x, procedure: %d.",
                             ble_conn_state_role(pEvt->conn_handle),
                             pEvt->conn_handle,
                             pEvt->params.conn_sec_succeeded.procedure);
            } break;
    
    
            case PM_EVT_CONN_SEC_FAILED:
            {
                NRF_LOG_INFO("Faield to secure connection with handle 0%x.", pEvt->conn_handle);
                errCode = sd_ble_gap_disconnect(pEvt->conn_handle,
                                          BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
                if (errCode != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(errCode);
                }
                //pEvt->conn_handle = BLE_CONN_HANDLE_INVALID;
                /* Often, when securing fails, it shouldn't be restarted, for security reasons.
                 * Other times, it can be restarted directly.
                 * Sometimes it can be restarted, but only after changing some Security Parameters.
                 * Sometimes, it cannot be restarted until the link is disconnected and reconnected.
                 * Sometimes it is impossible, to secure the link, or the peer device does not support it.
                 * How to handle this error is highly application dependent. */
            } break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ:
            {
                // Reject pairing request from an already bonded peer.
                pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false};
                pm_conn_sec_config_reply(pEvt->conn_handle, &conn_sec_config);
            } break;
    
            case PM_EVT_STORAGE_FULL:
            {
                // Run garbage collection on the flash.
                errCode = fds_gc();
                if (errCode == FDS_ERR_NO_SPACE_IN_QUEUES)
                {
                    // Retry.
                }
                else
                {
                    APP_ERROR_CHECK(errCode);
                }
            } break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED:
            {
                NRF_LOG_DEBUG("PM_EVT_PEERS_DELETE_SUCCEEDED");
                advertisingStart();
            } break;
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(pEvt->params.peer_data_update_failed.error);
            } break;
    
            case PM_EVT_PEER_DELETE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(pEvt->params.peer_delete_failed.error);
            } break;
    
            case PM_EVT_PEERS_DELETE_FAILED:
            {
                // Assert.
                APP_ERROR_CHECK(pEvt->params.peers_delete_failed_evt.error);
            } break;
    
            case PM_EVT_ERROR_UNEXPECTED:
            {
                // Assert.
                APP_ERROR_CHECK(pEvt->params.error_unexpected.error);
            } break;
    
            case PM_EVT_CONN_SEC_START:
            case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            case PM_EVT_PEER_DELETE_SUCCEEDED:
            case PM_EVT_LOCAL_DB_CACHE_APPLIED:
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED:
                // This can happen when the local DB has changed.
            case PM_EVT_SERVICE_CHANGED_IND_SENT:
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED:
            default:
                break;
        }
    }
    
    
    /**@brief Function for the Peer Manager initialization.
     */
    int peerManagerInit(const bool eraseBonds) {
        ble_gap_sec_params_t secParam;
        ret_code_t errCode;
        
        errCode = pm_init();
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("pm_init() failed, errCode=0x%x\n", errCode);
            return ERROR_PEER_MANAGER_INITIALIZE_FAIL;
        }    
         
        if (eraseBonds) {
            errCode = pm_peers_delete();
            if (errCode != NRF_SUCCESS) {
                NRF_LOG_WARNING("pm_peers_delete() failed, errCode=0x%x\n", errCode);
                return ERROR_PEER_MANAGER_INITIALIZE_FAIL;
            } 
        }
        
            memset(&secParam, 0, sizeof(ble_gap_sec_params_t));
        
            // Security parameters to be used for all security procedures.
            secParam.bond           = SEC_PARAM_BOND;
            secParam.mitm           = SEC_PARAM_MITM;
            secParam.lesc           = SEC_PARAM_LESC;
            secParam.keypress       = SEC_PARAM_KEYPRESS;
            secParam.io_caps        = SEC_PARAM_IO_CAPABILITIES;
            secParam.oob            = SEC_PARAM_OOB;
            secParam.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
            secParam.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
            secParam.kdist_own.enc  = 1;
            secParam.kdist_own.id   = 1;
            secParam.kdist_peer.enc = 1;
            secParam.kdist_peer.id  = 1;
        
            errCode = pm_sec_params_set(&secParam);
            if (errCode != NRF_SUCCESS) {
                NRF_LOG_WARNING("pm_sec_params_set() failed, errCode=0x%x\n", errCode);
                return ERROR_PEER_MANAGER_INITIALIZE_FAIL;
            } 
        
            errCode = pm_register(_pmEvtHandler);
            if (errCode != NRF_SUCCESS) {
                NRF_LOG_WARNING("pm_register() failed, errCode=0x%x\n", errCode);
                return ERROR_PEER_MANAGER_INITIALIZE_FAIL;
            } 
    
        return 0;
    }
    
    
    gap.h
    #include "sdk_config.h"
    #include "ble.h"
    #include "ble_conn_params.h"
    #include "ble_gap.h"
    #include "gap.h"
    #include "error.h"
    #include "nrf_log.h"
    
    #define DEVICE_NAME       "ANCS2"                         /**< Name of the device. Will be included in the advertising data. */
    #define STATIC_PASSKEY    "123456"                        /**< Static passkey. */
    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.5 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) /**< Maximum acceptable connection interval (1 second). */
    #define SLAVE_LATENCY     0                               /**< Slave latency. */
    #define CONN_SUP_TIMEOUT  MSEC_TO_UNITS(3000, UNIT_10_MS) /**< Connection supervisory time-out (4 seconds). */
    
    static ble_opt_t _gStaticPasskeyOption;	/**< Pointer to the struct containing static pin option. */
    
    /**@brief Function for initializing GAP connection parameters.
     *
     * @details Use this function to set up all necessary GAP (Generic Access Profile)
     *          parameters of the device. It also sets the permissions and appearance.
     */
    int gapParamsInit(void) {
        ret_code_t              errCode;
        ble_gap_conn_params_t   gapConnParams;
        ble_gap_conn_sec_mode_t secMode;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&secMode);
    
        errCode = sd_ble_gap_device_name_set(&secMode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME));
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("sd_ble_gap_device_name_set() failed, errCode=0x%x", errCode);
            return ERROR_GAP_INITIALIZE_FAIL;
        }
    
        memset(&gapConnParams, 0, sizeof(gapConnParams));
    
        gapConnParams.min_conn_interval = MIN_CONN_INTERVAL;
        gapConnParams.max_conn_interval = MAX_CONN_INTERVAL;
        gapConnParams.slave_latency     = SLAVE_LATENCY;
        gapConnParams.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        errCode = sd_ble_gap_ppcp_set(&gapConnParams);
        if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("sd_ble_gap_ppcp_set() failed, errCode=0x%x", errCode);
            return ERROR_GAP_INITIALIZE_FAIL;
        }
    
        uint8_t passkey[] = STATIC_PASSKEY;
    	_gStaticPasskeyOption.gap_opt.passkey.p_passkey = passkey;
    	errCode = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &_gStaticPasskeyOption);
    	if (errCode != NRF_SUCCESS) {
            NRF_LOG_WARNING("sd_ble_opt_set() failed, errCode=0x%x", errCode);
            return ERROR_GAP_INITIALIZE_FAIL;
        }
    
        return 0;
    }
    
    
    
    7043.security.h

  • Hi Snowuyl, 
    I'm not familiar with the code provided. 
    However, what I can see in your log and your screenshot is that the two devices just connected and not bonded. 
    Note that the passkey bonding process only occurs when the two device bond, not when connect. 

    Usually bonding happens automatically when the central try to read/write an encrypted characteristic. 

    You can test bonding by click the lock button in nRF Connect: 

    For passkey bonding, please try to test with our ble_app_gls example. 

  • I can't find ble_app_gls example in nRF5_SDK_16.0.0 source code. Could you provide folder path? Besides, can I test pairing with passkey using nRF connect?

Related