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

Error when loading whitelist on a central + peripheral when connected peripheral shutdowns

Hello,

I have a 52832 using SDK16.0.0, that acts as an advertising peripheral (anyone can connect to it), and as a central, connected with 1-1 bond to a peripheral (a 52811).

I have implemented this 1-1 bond using whitelist and peer_managers on both sides (central 52832 and peripheral 52811). This is based on HRS / HRS_C examples.

Everythings works fine when bonding and keeping connection.

Here is the scenario that doesn't work : when peripheral shutdowns. Then the central starts scanning again, a whitelist request is received, but when loading whitelist I get a 12804 error (BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE) on pm_device_identities_list_set.

If I restart the central with the peripheral still down, I get the same error.
I I restart the central with the peripheral up and avertising, it successfully connects. 

Here are the logs of succcessful initial pairing :

00> <debug> ble_scan: Scanning parameters have been changed successfully
00> <info> app: Whitelist request
00> <debug> ble_scan: Scanning parameters have been changed successfully
00> <debug> ble_scan: Scanning
00> <debug> ble_scan: Connecting
00> <debug> ble_scan: Connection status: 0
00> <info> app: Scan filter match.
00> <info> app: Central connected to Scale (mac address E3:30:0F:54:9A:DC)
00> <info> app: Attempt to find scale peripheral on conn_handle 0x0
00> <debug> nrf_ble_gq: Registering connection handle: 0x0000
00> <debug> ble_db_disc: Starting discovery of service with UUID 0x1 on connection handle 0x0.
00> <debug> nrf_ble_gq: Adding item to the request queue
00> <debug> nrf_ble_gq: GATTC Primary Services Discovery Request
00> <debug> nrf_ble_gq: SD GATT procedure (2) succeeded on connection handle: 0.
00> <debug> ble_db_disc: Found service UUID 0x1.
00> <debug> nrf_ble_gq: Adding item to the request queue
00> <debug> nrf_ble_gq: GATTC Characteristic Discovery Request
00> <debug> nrf_ble_gq: SD GATT procedure (3) succeeded on connection handle: 0.
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> nrf_ble_gq: Adding item to the request queue
00> <debug> nrf_ble_gq: GATTC Characteristic Discovery Request
00> <debug> nrf_ble_gq: SD GATT procedure (3) succeeded on connection handle: 0.
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> nrf_ble_gq: Adding item to the request queue
00> <debug> nrf_ble_gq: GATTC Characteristic Discovery Request
00> <debug> nrf_ble_gq: SD GATT procedure (3) succeeded on connection handle: 0.
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> nrf_ble_gq: Adding item to the request queue
00> <debug> nrf_ble_gq: GATTC Characteristic Descriptor Request
00> <debug> nrf_ble_gq: SD GATT procedure (4) succeeded on connection handle: 0.
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> ble_db_disc: Discovery of service with UUID 0x1 completed with success on connection handle 0x0.
00> <debug> app: Scale service discovered.
00> <info> app: Assigning scale ble handles
00> <debug> peer_manager_handler: Event PM_EVT_CONN_SEC_PARAMS_REQ
00> <debug> peer_manager_handler: Security parameter request
00> <debug> peer_manager_handler: Event PM_EVT_CONN_SEC_START
00> <debug> peer_manager_handler: Connection security procedure started: role: Central, conn_handle: 0, procedure: Bonding
00> <debug> nrf_ble_gq: Adding item to the request queue
00> <debug> nrf_ble_gq: GATTC Write Request
00> <debug> nrf_ble_gq: SD GATT procedure (1) succeeded on connection handle: 0.
00> <debug> app: Scale service notifications enabled
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> peer_manager_handler: Event PM_EVT_CONN_SEC_PARAMS_REQ
00> <debug> peer_manager_handler: Security parameter request
00> <debug> peer_manager_handler: Event PM_EVT_CONN_SEC_SUCCEEDED
00> <info> peer_manager_handler: Connection secured: role: Central, conn_handle: 0, procedure: Bonding
00> <info> app: Bonding with previous scale succeded
00> <debug> peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Bonding data, action: Update
00> <debug> peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Peer rank, action: Update
00> <debug> peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Local database, action: Update
00> <debug> app: Received data from BLE BOKS
00> <debug> app:  52                     |R       
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> nrf_ble_gq: Processing the request queue...
00> <debug> peer_manager_handler: Event PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
00> <info> peer_manager_handler: Peer data updated in flash: peer_id: 0, data_id: Central address resolution, action: Update

Here are the logs after shuting down the connected peripheral :

00> <debug> ble_scan: Scanning parameters have been changed successfully
00> <info> app: Whitelist request
00> <error> app: ERROR 12804 [Unknown error code] at ble_scale.c:280
00> PC at: 0x00037529
00> <error> app: End of error report


Here is the relevant code:

static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
    ret_code_t err_code;
    switch(p_scan_evt->scan_evt_id)
    {
        case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
        {
            NRF_LOG_INFO("Whitelist request");
            on_whitelist_req();
        } break;

        (....)
    }
}

static void on_whitelist_req(void)
{
    // Whitelist buffers.
    ble_gap_addr_t whitelist_addrs[8];
    ble_gap_irk_t  whitelist_irks[8];

    memset(whitelist_addrs, 0x00, sizeof(whitelist_addrs));
    memset(whitelist_irks,  0x00, sizeof(whitelist_irks));

    uint32_t addr_cnt = (sizeof(whitelist_addrs) / sizeof(ble_gap_addr_t));
    uint32_t irk_cnt  = (sizeof(whitelist_irks)  / sizeof(ble_gap_irk_t));

    // Reload the whitelist and whitelist all peers.
    whitelist_load();

    ret_code_t ret;

    // Get the whitelist previously set with pm_whitelist_set().
    ret = pm_whitelist_get(whitelist_addrs, &addr_cnt,
                           whitelist_irks,  &irk_cnt);

    if (((addr_cnt == 0) && (irk_cnt == 0)))
    {
        m_scan_param.filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL;

        ret = nrf_ble_scan_params_set(&m_scan, &m_scan_param);
        APP_ERROR_CHECK(ret);
    }
}

static void whitelist_load()
{
    ret_code_t   ret;
    pm_peer_id_t peers[8];
    uint32_t     peer_cnt;

    memset(peers, PM_PEER_ID_INVALID, sizeof(peers));
    peer_cnt = (sizeof(peers) / sizeof(pm_peer_id_t));

    // Load all peers from the flash and whitelist them.
    peer_list_get(peers, &peer_cnt);

    ret = pm_whitelist_set(peers, peer_cnt);
    APP_ERROR_CHECK(ret);

    // Setup the list of device identities.
    // Some SoftDevices do not support this feature.
    ret = pm_device_identities_list_set(peers, peer_cnt);
    if (ret != NRF_ERROR_NOT_SUPPORTED)
    {
        APP_ERROR_CHECK(ret);
    }
}

I do not reproduce with HRS / HRS_C examples.

Thanks !

  • Is there any chance that the device is already in a connection as a peripheral when you starts advertising again  ?
    No

    You mentioned that if you ignore the error when calling ble_advertising_start () it works fine, but would it advertise ? Or you need to call ble_advertising_start () again to make it work ? 

    As I mentionned, I only get the error the first time, before bonding the peripheral. I do not need to advertise again, it advertises correctly (exactly as if the advertising stopping did not work).


  • Hi Quentin, 

    It's quite strange that even with NRF_ERROR_CONN_COUNT  error the advertising still resume. Please try to debug and check if you only call sd_ble_gap_adv_stop() without calling ble_advertising_start() do you see the advertising stopped. 
    And then check again with ble_advertising_start(). I don't think the softdevice would do advertising if sd_ble_gap_adv_start() return NRF_ERROR_CONN_COUNT.
    Again, if possible please provide us the code so we can test here. 

  • I have provided all the code pertaining to advertising/scan

    You will be able to reproduce easily by making the HRS_C example advertise.

    I think this should be part of the standard examples, given how complicated this is to make it work and the number of related issues on this forum.

  • Hi Quentin, 

    Attached you can find the ble_app_hrs_c example that advertises. 
    In the example the nRF52 will advertise, then start scanning. Doing that I did receive error 12804  when adding whitelist as expected. 
    So I added the code to stop and start advertising again in NRF_BLE_SCAN_EVT_WHITELIST_REQUEST event handler  as you posted.

    However I didn't have any error when doing that regardless if it's the first time running or not, also regardless if it has any bond before. 

    Please try to test if you get any error. If it's not exactly what you are doing in your application, please modify the example attached so that it can reproduce the issue you are seeing. 
    ble_app_hrs_c_advertise.zip

    SDK v16.0 

  • Thank you for taking the time to provide this example !

    In your on_whitelist_req method,you do :

        if (((addr_cnt == 0) && (irk_cnt == 0)) ||
            (m_whitelist_disabled))
        {
            // Don't use whitelist.
            err_code = nrf_ble_scan_params_set(&m_scan, NULL);
            APP_ERROR_CHECK(err_code);
        }

    This disables the whitelist when no peer is bonded.

    But when a new peer is bonded (addr_cnt != 0), shouldn't you do the opposite and make the scan use the the whitelist ?

     

Related