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

Calling pm_address_resolve in BLE_GAP_EVT_ADV_REPORT

Due to whitelist limitation of 8 peers, I am doing manual filtering of bonded devices. I am trying to use pm_address_resolve function to figure out whether I have previously bonded with this peer.

static bool try_resolve_peer_address(ble_gap_addr_t peer_addr){
    pm_peer_id_t         peer_id;
    pm_peer_data_flash_t peer_data;
    pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID;

    pds_peer_data_iterate_prepare();
    while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
    {
        if (pm_address_resolve(&peer_addr,
                               &peer_data.p_bonding_data->peer_ble_id.id_info))
        {
            bonded_matching_peer_id = peer_id;
            NRF_LOG_INFO("Found bonded peer with id %04X",peer_id);
            return true;
        }
    }
    
    return false;
}

static void on_adv_report(ble_evt_t const * p_ble_evt)
{
    ret_code_t err_code = NRF_SUCCESS;
    ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
    if(p_gap_evt->params.adv_report.primary_phy == BLE_GAP_PHY_CODED &&
     ble_advdata_uuid_find(p_gap_evt->params.adv_report.data.p_data,p_gap_evt->params.adv_report.data.len,&g_adv_uuids[0])){

      const ble_gap_evt_adv_report_t* const adv = &p_gap_evt->params.adv_report;

      if(fake_whitelisting){

        if(adv->peer_addr.addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE){
          // nothing to do

        }
        else if(try_resolve_peer_address(adv->peer_addr)){

          err_code = sd_ble_gap_connect(&adv->peer_addr,&m_scan_param,&g_conn_param,1);
          APP_ERROR_CHECK(err_code);
        }
      }
      else{

        err_code = sd_ble_gap_connect(&adv->peer_addr,&m_scan_param,&g_conn_param,1);
        APP_ERROR_CHECK(err_code);
      }
    }
    APP_ERROR_CHECK(sd_ble_gap_scan_start(NULL,&g_scan_buffer));
}

The application halts on sd_ble_gap_scan_start returning NRF_ERROR_INVALID_STATE, if I comment out the try_resolve_peer_address, it continues to scan just fine.

Could this be somehow related to id_manager.c::sd_ecb_block_encrypt? Since that's what pm_address_resolve calls internally.

  • Hi Darkenkade, 

    I don't think sd_ecb_block_encrypt() can cause an issue here. However, if try_resolve_peer_address() takes too long, it my run to this issue: "- The scanner has timed out when this function is called to continue scanning." 
    I would suggest to run the resolving in main context instead of inside the on_adv_report().

    In addition please make sure no sd_ble_gap_connect() is called before sd_ble_gap_scan_start() because as far as I know if you start the connect procedure you shouldn't continue scanning. 

  • You are correct, it was indeed taking too long, also correct about sd_ble_gap_scan_start after connecting. I'm not sure how I would run the resolving in main context, since the the advertisment needs to be responded with connection request, but my problem is solved.

Related