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 !

Parents
  • Hi Quentin, 

    Could you post your full code in your main.c ? 
    The error you received could be related to that whitelist_load () (which calls pm_device_identities_list_set() ) has been called more than once with the same list. 

    I noticed that in  your log you have "Scanning parameters have been changed successfully" could you check how you get this log ? Usually it's the call nrf_ble_scan_params_set() that should not be called when whitelist is used. (at least in the hrs_c it's not called if there is something in the whitelist)

  • I have also taken inspiration in example rscs_c, where you can find :

    m_scan_param.filter_policy = BLE_GAP_SCAN_FP_WHITELIST;
    err_code = nrf_ble_scan_params_set(&m_scan, &m_scan_param);



    Here is additional code from my project :

    /**< Scan parameters requested for scanning and connection. */
    static ble_gap_scan_params_t m_scan_param =
    {
        .active        = 0x01,
        .interval      = NRF_BLE_SCAN_SCAN_INTERVAL,
        .window        = NRF_BLE_SCAN_SCAN_WINDOW,
        .filter_policy  = BLE_GAP_SCAN_FP_WHITELIST,
        .timeout       = SCAN_DURATION,
        .scan_phys     = BLE_GAP_PHY_1MBPS
        //.extended      = 1 // should it be set ? 
    };
    
    static void scan_start(void)
    {
        ret_code_t err_code;
    
        // If there is any pending write to flash, defer scanning until it completes.
        if (nrf_fstorage_is_busy(NULL))
        {
            m_memory_access_in_progress = true;
            return;
        }
    
        scale_scan_blink_start();
    
        m_scan_param.filter_policy = BLE_GAP_SCAN_FP_WHITELIST;
    
        err_code = nrf_ble_scan_params_set(&m_scan, &m_scan_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_scan_start(&m_scan);
        APP_ERROR_CHECK(err_code);
    }

  • Hi Quentin, 
    You have NRF_ERROR_CONN_COUNT  when you haven't setup the correct link count in sdk_config.h. 

    You have a potential of having up to 2 connections  (one as a peripheral and one as a central). So you need to configure that in sdk_config.h. Please check the following configuration: 

    - NRF_SDH_BLE_PERIPHERAL_LINK_COUNT

    - NRF_SDH_BLE_CENTRAL_LINK_COUNT

    - NRF_SDH_BLE_TOTAL_LINK_COUNT (this is the max concurrent connections)

  • My config is very simple :
    #define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1
    #define NRF_SDH_BLE_CENTRAL_LINK_COUNT 1
    #define NRF_SDH_BLE_TOTAL_LINK_COUNT 2

    So here the error would occur if I'm trying to advertise two times ? But that is not the case, as I'm stopping advertising as you can see.

  • Hei Quentin, 
    Is there any chance that the device is already in a connection as a peripheral when you starts advertising again  ?
     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 ? 

  • 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. 

Reply
  • 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. 

Children
  • 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 ?

     

  • I've tried with the same advertising_init than yours, the same on_whitelist_req, all my code pertaining to advertising/scanning is identical to yours, yet I still have the issue on my project, and not on yours.

    Here is the scenario for this issue :
    - peripheral advertises
    - central advertises
    - central starts scanning peripheral, a whitelist request is sent, we stop advertising, set the whitelist, start advertising again
    Expected => no error, central bonds to peripheral and advertises correctly
    Error => NRF_ERROR_COUNT when starting advertising after setting whitelist.

    If I just ignore the NRF_ERROR_COUNT error, it works fine, bonds, and advertises correctly ! I'd still want to understand why I get this error.

    What am I missing ? Some configuration ?

    Where in NRF components can I debug where this NRF_ERRROR_COUNT is generated ? I don't see where it is thrown.

    Thanks !

  • Hi Quentin, 


    Could you step in the code and check if the NRF_ERROR_CONN_COUNT  is returned by sd_ble_gap_adv_start() when calling ble_advertising_start() ? 

    If it's returned by sd_ble_gap_adv_start() you can't really step any further as it's a softdevice SVC call. 

    If you can modify our example to reproduce the issue then I can check here. Or please provide the simplified version of your application that we can run on a DK here.
    Without that it's very hard to know what could be wrong. 

Related