This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

how to bonding BLE in 52832?

I try to bonding func using ble_app_gls example.

just connect is fine.

here is ble_evt handler

for trying connect bonding, I use pm_handler_secure_on_connection(p_ble_evt)

but here is occur error : pm_conn_secure() failed because conn_handle 0 is not a valid connection.

I check conn_state using ble_conn_state_status()

example is fine.

but my code, first event is return invalid, after second the state change connected.

Could you give me advice?

ps) If you know more better example for bonding, please attach url or doc.

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t err_code;

    ble_conn_state_status_t st;
    pm_handler_secure_on_connection(p_ble_evt);

    st = ble_conn_state_status(p_ble_evt->evt.gap_evt.conn_handle);
    NRF_LOG_INFO("CONNECT STATE = %x\n", st);

    if(p_ble_evt->header.evt_id == BLE_GAP_EVT_CONNECTED)
      pm_handler_secure_on_connection(p_ble_evt);
    

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:  

            NRF_LOG_INFO("BLE_GAP_EVT_CONNECTED\n");

            bsp_board_led_off(BSP_BOARD_LED_2);
            bsp_board_led_on(BSP_BOARD_LED_1);
            
            peer_id = PM_PEER_ID_INVALID;

            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;

            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);           
            break;

  • Hi,

    The central (phone in this case) will usually start the pairing procedure after the connection is established (App dependent on Android). If not pm_handler_secure_on_connection() will send a pairing request to the central after the PM_HANDLER_SEC_DELAY_MS delay has expired to ask the central to initiate the pairing procedure. But I see from your code that pm_handler_secure_on_connection() is called twice. Do you get the same error if you comment out the second call? 

  • yes. remove second pm_handler_secure_on_connection in IF sentence, still happend error.

    I test 52832(peripheral) and nRF connect app (android).

    I reupload my code. 

    Goal is

    1. success bonding (just work, no lesc)

    2. add whitelist

    3.after disconnect, using whitelist connect one more.

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        ret_code_t err_code;
    
        ble_conn_state_status_t st;
        pm_handler_secure_on_connection(p_ble_evt);    
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GAP_EVT_CONNECTED:  
    
                NRF_LOG_INFO("BLE_GAP_EVT_CONNECTED\n");
    
                bsp_board_led_off(BSP_BOARD_LED_2);
                bsp_board_led_on(BSP_BOARD_LED_1);
                
                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    
                err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
                APP_ERROR_CHECK(err_code);           
                break;
    
            case BLE_GAP_EVT_DISCONNECTED:
                NRF_LOG_INFO("BLE_GAP_EVT_DISCONNECTED\n");
                bsp_board_led_off(BSP_BOARD_LED_1);
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                advertising_start(BLE_ADV_MODE_FAST);
    
                break;
    
            case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
              NRF_LOG_INFO("BLE_GAP_EVT_PHY_UPDATE_REQUEST\n");
            {
                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_AUTO,
                    .tx_phys = BLE_GAP_PHY_AUTO,
                };
    
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);
            } break;
    
    
            case BLE_GAP_EVT_SEC_INFO_REQUEST:
                NRF_LOG_INFO("BLE_GAP_EVT_SEC_INFO_REQUEST\n");
                err_code = sd_ble_gap_sec_info_reply(m_conn_handle, NULL, NULL, NULL);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                NRF_LOG_INFO("BLE_GAP_EVT_SEC_PARAMS_REQUEST\n");
                err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
                                                       BLE_GAP_SEC_STATUS_SUCCESS,
                                                       &sec_param,
                                                       &sec_key);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_ADV_SET_TERMINATED:
              NRF_LOG_INFO("BLE_GAP_EVT_ADV_SET_TERMINATED\n");
                if (p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason ==
                    BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT)
                {
                   bsp_board_led_off(BSP_BOARD_LED_2);
                   if(ble_adv_t.adv_mode_current == BLE_ADV_MODE_FAST)
                   {
                      advertising_start(BLE_ADV_MODE_SLOW);
                   }       
                    
                }
                break;
    
            case BLE_GATTS_EVT_SYS_ATTR_MISSING:
              NRF_LOG_INFO("BLE_GATTS_EVT_SYS_ATTR_MISSING\n");
                err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
                                                     NULL,
                                                     0,
                                                     BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
                APP_ERROR_CHECK(err_code);
                break;
    
            case BLE_GAP_EVT_TIMEOUT :
               NRF_LOG_INFO("BLE_GAP_EVT_TIMEOUT\n");
               break;
    
            case BLE_GAP_EVT_PHY_UPDATE  :
               NRF_LOG_INFO("BLE_GAP_EVT_PHY_UPDATE \n");
               break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE : 
              NRF_LOG_INFO("BLE_GAP_EVT_CONN_PARAM_UPDATE \n");
               break;
    
            case BLE_GAP_EVT_PASSKEY_DISPLAY  :      
              NRF_LOG_INFO("BLE_GAP_EVT_PASSKEY_DISPLAY passkey \n");
               break;
    
            case BLE_GAP_EVT_KEY_PRESSED  : 
              NRF_LOG_INFO("BLE_GAP_EVT_KEY_PRESSED  \n");
               break;
    
            case BLE_GAP_EVT_AUTH_KEY_REQUEST   : 
              NRF_LOG_INFO("BLE_GAP_EVT_AUTH_KEY_REQUEST   \n");
               break;
    
            case BLE_GAP_EVT_LESC_DHKEY_REQUEST   : 
              NRF_LOG_INFO("BLE_GAP_EVT_LESC_DHKEY_REQUEST   \n");
               break;
    
            case BLE_GAP_EVT_AUTH_STATUS  : 
    
              NRF_LOG_INFO("BLE_GAP_EVT_AUTH_STATUS  \n");
              NRF_LOG_INFO("BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x",
                             p_ble_evt->evt.gap_evt.params.auth_status.auth_status,
                             p_ble_evt->evt.gap_evt.params.auth_status.bonded,
                             p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4,
                             *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own),
                             *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer));
               break;
    
            case BLE_GAP_EVT_CONN_SEC_UPDATE   : 
              NRF_LOG_INFO("BLE_GAP_EVT_CONN_SEC_UPDATE   \n");
               break;  
                     
            case BLE_GAP_EVT_RSSI_CHANGED   : 
              NRF_LOG_INFO("BLE_GAP_EVT_RSSI_CHANGED   \n");
               break;
    
            case BLE_GAP_EVT_ADV_REPORT   : 
              NRF_LOG_INFO("BLE_GAP_EVT_ADV_REPORT   \n");
               break;
    
            case BLE_GAP_EVT_SEC_REQUEST    : 
              NRF_LOG_INFO("BLE_GAP_EVT_SEC_REQUEST    \n");
               break;
    
            case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST    : 
              NRF_LOG_INFO("BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST    \n");
               break;
    
            case BLE_GAP_EVT_SCAN_REQ_REPORT    : 
              NRF_LOG_INFO("BLE_GAP_EVT_SCAN_REQ_REPORT    \n");
               break;  
                   
            case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST    : 
              NRF_LOG_INFO("BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST    \n");
               break;
    
            case BLE_GAP_EVT_DATA_LENGTH_UPDATE    : 
              NRF_LOG_INFO("BLE_GAP_EVT_DATA_LENGTH_UPDATE    \n");
               break;
    
            case BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT    : 
              NRF_LOG_INFO("BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT    \n");
               break; 
                    
            default:
                NRF_LOG_INFO("DEFUALT %x\n" ,p_ble_evt->header.evt_id);
                // No implementation needed.
                break;
        }
    }
    
    static void peer_manager_init()
    {    
    
        memset(&whitelist, 0xFFFF , sizeof(whitelist)); // 0xFFFF = invalid peer id
        whitelist_count = 0;
        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); 
        // Until this function is called, all bonding procedures that are initiated by the peer are rejected.
        APP_ERROR_CHECK(err_code);    
    
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    
        err_code = pm_register(pm_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_INFO("PEER MANAGER INIT END\n");
    }
    
    static void pm_evt_handler(pm_evt_t const * p_evt)
    {
        pm_handler_on_pm_evt(p_evt);
    
        pm_handler_flash_clean(p_evt);
    
        ret_code_t err_code;
        pm_conn_sec_status_t conn_sec_status;
    
        switch (p_evt->evt_id)
        {
            case PM_EVT_BONDED_PEER_CONNECTED :
                NRF_LOG_INFO("PM_EVT_BONDED_PEER_CONNECTED \n");            
                break;
    
            case PM_EVT_CONN_SEC_START :
                NRF_LOG_INFO("PM_EVT_CONN_SEC_START \n");
                break;
    
            case PM_EVT_CONN_SEC_SUCCEEDED :
                
                // Check if the link is authenticated (meaning at least MITM).
                err_code = pm_conn_sec_status_get(p_evt->conn_handle, &conn_sec_status);
                APP_ERROR_CHECK(err_code);
    
                if (conn_sec_status.mitm_protected)
                {
                    NRF_LOG_INFO("Link secured. Role: %d. conn_handle: %d, Procedure: %d",
                                 ble_conn_state_role(p_evt->conn_handle),
                                 p_evt->conn_handle,
                                 p_evt->params.conn_sec_succeeded.procedure);
                }
                else
                {
                    // The peer did not use MITM.                
                    
    //                pm_peer_data_store(p_evt->peer_id, PM_PEER_DATA_ID_FIRST, )
    //
    //                whitelist[whitelist_count++] = p_evt->peer_id;
    //                err_code = pm_whitelist_set(whitelist,BLE_GAP_WHITELIST_ADDR_MAX_COUNT);
    //                APP_ERROR_CHECK(err_code);
    
                    ble_gap_addr_t addr;
                    uint32_t addr_cnt = sizeof(addr);
    
                  
                    err_code = pm_whitelist_get(&addr, &addr_cnt, NULL,NULL);
                    APP_ERROR_CHECK(err_code);
    
                    NRF_LOG_INFO("white list peer type = %x\n",addr.addr_type);
    
                }
                
                NRF_LOG_INFO("PM_EVT_CONN_SEC_SUCCEEDED \n");
                break;
    
            case PM_EVT_CONN_SEC_FAILED :
                NRF_LOG_INFO("PM_EVT_CONN_SEC_FAILED \n");
                m_conn_handle = BLE_CONN_HANDLE_INVALID;
                break;
    
            case PM_EVT_CONN_SEC_CONFIG_REQ :
                NRF_LOG_INFO("PM_EVT_CONN_SEC_CONFIG_REQ \n");
                break;
    
            case PM_EVT_CONN_SEC_PARAMS_REQ :
                NRF_LOG_INFO("PM_EVT_CONN_SEC_PARAMS_REQ \n");
                err_code = pm_conn_sec_params_reply(p_evt->conn_handle, &sec_param, p_evt->params.conn_sec_params_req.p_context);
                APP_ERROR_CHECK(err_code);
                break;
    
            case PM_EVT_STORAGE_FULL :
                NRF_LOG_INFO("PM_EVT_STORAGE_FULL \n");
                break;
    
            case PM_EVT_ERROR_UNEXPECTED :
                NRF_LOG_INFO("PM_EVT_ERROR_UNEXPECTED \n");
                break;
    
            case PM_EVT_PEER_DATA_UPDATE_FAILED  :
                NRF_LOG_INFO("PM_EVT_PEER_DATA_UPDATE_FAILED  \n");
                break;
    
            case PM_EVT_PEER_DELETE_SUCCEEDED  :
                NRF_LOG_INFO("PM_EVT_PEER_DELETE_SUCCEEDED  \n");
                break;
    
            case PM_EVT_PEER_DELETE_FAILED :
                NRF_LOG_INFO("PM_EVT_PEER_DELETE_FAILED \n");
                break;
    
            case PM_EVT_PEERS_DELETE_SUCCEEDED :
                NRF_LOG_INFO("PM_EVT_PEERS_DELETE_SUCCEEDED \n");
                advertising_start(BLE_ADV_MODE_FAST);
                break;
    
            case PM_EVT_PEERS_DELETE_FAILED :
                NRF_LOG_INFO("PM_EVT_PEERS_DELETE_FAILED \n");
                break;
    
            case PM_EVT_LOCAL_DB_CACHE_APPLIED :
                NRF_LOG_INFO("PM_EVT_LOCAL_DB_CACHE_APPLIED \n");
                break;
    
            case PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED :
                NRF_LOG_INFO("PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED \n");
                break;
    
            case PM_EVT_SERVICE_CHANGED_IND_SENT :
                NRF_LOG_INFO("PM_EVT_SERVICE_CHANGED_IND_SENT \n");
                break;
    
            case PM_EVT_SERVICE_CHANGED_IND_CONFIRMED :
                NRF_LOG_INFO("PM_EVT_SERVICE_CHANGED_IND_CONFIRMED \n");
                break;
    
            case PM_EVT_SLAVE_SECURITY_REQ :
                NRF_LOG_INFO("PM_EVT_SLAVE_SECURITY_REQ \n");
                break;
    
            case PM_EVT_FLASH_GARBAGE_COLLECTED :
                NRF_LOG_INFO("PM_EVT_FLASH_GARBAGE_COLLECTED \n");
                break;
    
            case PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED :
                NRF_LOG_INFO("PM_EVT_FLASH_GARBAGE_COLLECTION_FAILED \n");
                break; 
                  
            default:
                break;
        }
    }

    on peer_manager_init()

    SEC_PARAM_BOND = 1, other is 0

    1. first error is pm_handler_secure_on_connection()

    if second try to connect, it is normal. 

    2. if after bonding, the info don't need to add whitelist manually?

    3.now on nRF connect app, display bonded.

    and then disconnect, try to connect on BONDED tap

    sd_ble_gap_sec_info_reply return error NRF_ERROR_INVALID_STATE.

    thank you

  • Hi,

    Did you erase any existing bonds on the peripheral before this test? Note that the app data region holding the bond information will not be overwritten when you re-program the application.  

    Here's another thread that you might find relevant: https://devzone.nordicsemi.com/f/nordic-q-a/38663/keep-getting-failed-to-secure-connection-error 

Related