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 !

  • I'm not sure what could be wrong, if you can reproduce the issue with a minimum example so we can reproduce here it would be nice. 

    You mentioned that it works fine with the hrs_c and hrs. Have you tried to compare and try to match we have in hrs_c with your application, just so we can trace back what cause the issue ? 

  • I have already debugged and logged in hrs/hrs_c, whitelist_load is called at the same time as mine.
    Unfortunately I won't be able to provide my project...

    Could you check at least these questions ?
    - Should I always be in BLE_GAP_SCAN_FP_WHITELIST or should I switch between BLE_GAP_SCAN_FP_WHITELIST and BLE_GAP_SCAN_FP_ACCEPT_ALL ?
    - Should my scan parameters be in "extended" mode ?
    - What are the possible suspects that could be calling pm_device_identities_list_set without my knowledge ? The advertising ?  

  • Hi again Quentin, 

    - You can switch between. 

    - "extended" mode is only for extended advertising (Bluetooth 5.0 feature where you can advertise longer, or advertise only the header and the content will be transmitted in data channel. If you don't use extended advertising, you don't need to turn this on)

    - I did a quick search and found some cases:

    https://devzone.nordicsemi.com/f/nordic-q-a/32674/simultaneous-central-peripheral-with-whitelist-only-used-in-one-role


    https://devzone.nordicsemi.com/f/nordic-q-a/46268/error-12804-multipheripheral-bonding-whitelist/182613#182613

    So if you already doing advertising (or scanning) you would need to stop that before you start scanning (or advertising). Here a quote from my answer in the other case: 

    Sorry for the late response. I got the information from our staff. Quoted here: 

    You can not call sd_ble_gap_device_identities_set if the scanner is running. Even though you set use_whitelist=0 when stating the scanner, it will still use the identity list to resolve addresses.

     

    It seems that you would need to do the trick to start advertising first before you start scanning. Or stop scanning, start advertising and start scanning again. In my opinion,  scanning with whitelist = 0 shouldn't use identity list. 

  • I had already read these issues and tried some of those solutions (like stopping advertising before on_whitelist_request), without success.
    Besides, if I'm not wrong, hrs_c calls sd_ble_gap_device_identities_set without stopping advertising nor scanning.

    This is not clear to me what is the expected behaviour of the framework. Could you get some more definitive answers on what is working and what is not ?

    Why is the advertising in conflict with this whitelist at all ?

    So if you already doing advertising (or scanning) you would need to stop that before you start scanning (or advertising)
    Sorry, this is really not clear

    start advertising first before you start scanning
    This is not the case when I restart both peripheral and central, and it works fine. And it's not the case of HRS_C

    Or stop scanning, start advertising and start scanning again
    You mean stop advertising, then stop scanning, then start advertising, then start scanning again ?
    It looks very complicated 

  • Hi Quentin, 

    The key difference between the hrs_c and your application is that you do advertising and scanning at the same time. 
    When advertising there can be a whitelist used and when scanning whitelisting can also be used for scanning. 
    Only one whitelist can be used in the hardware, we don't have 2 different whitelist system for advertising and scanning.

    It could be the reason why you receive BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE when you start scanning ,it's because your advertising may already use a whitelist (?). You can find in both of the cases that I pointed to , the application does advertising + scanning at the same time. 

    It's hard for us to give you definite answer without knowing your application. We don't get a full picture from your code snippets.  My suggestion is to test scanning with whitelist without advertising just to check if you see the same error. 

    A good way to narrow down the issue is to get your application as close as possible to a working example. You then can trace back on which feature that you disable may cause the issue. 

Related