pm_sec_params_set() failed, errCode=0x7

I refer to https://github.com/alc6/nrf52-pc10040-multiperipheral-passkey/blob/master/main.c for implementing static passkey. But pm_sec_params_set() returns errCode=0x7.

 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> <warning> app: pm_sec_params_set() failed, errCode=0x7

Parents
  • security.h

    #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                  1                                           /**< 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;
    }
    
    

  • When I change definition of SEC_PARAM_IO_CAPABILITIES to BLE_GAP_IO_CAPS_DISPLAY_ONLY as follows. pm_sec_params_set() returns NRF_SUCCESS.

    #define SEC_PARAM_IO_CAPABILITIES       BLE_GAP_IO_CAPS_DISPLAY_ONLY

    And I found sec_params_verify() return false when enabled MITM and setting IO capability to BLE_GAP_IO_CAPS_NONE.

    Why sec_params_verify() return false for this condition?

    static bool sec_params_verify(ble_gap_sec_params_t * p_sec_params) {

    ...

    // Must have either IO capabilities or OOB if MITM.
        if (p_sec_params->mitm && (p_sec_params->io_caps == BLE_GAP_IO_CAPS_NONE) && !p_sec_params->oob)
        {
            return false;
        }

    ...

    }

  • You cannot have both IO capabilities and MITM. Have you enabled MITM in your case?

Reply Children
No Data
Related