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, 


    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. 

  • Sorry, I'm reading again your answers, and I made a mistake on one of my answers :

    Is there any chance that the device is already in a connection as a peripheral when you starts advertising again  ?
    N̶o̶  Yes ! A phone is connected to it while I get the error.

    So I guess atht is my issue : I can't advertise again when already connected as a peripheral (with a NRF_SDH_BLE_PERIPHERAL_LINK_COUNT = 1).

    What do you recommend ? Still try advertising, and just catch the NRF_ERROR_CONN_COUNT silently ?

    Best regards,
    Quentin 

  • Hi Quentin, 
    I assume you advertise as "connectable advertising" when you are in a connection as a peripheral ? 
    If it's the case the softdevice would need to expect that there will be another connection will be made. And you need to configure NRF_SDH_BLE_PERIPHERAL_LINK_COUNT  = 2


    Is there any reason you need to advertise as connectable ? If you plan to have a new connection and you plan to only have one connection (as a peripheral) at a time, you may want to disconnect before advertise. 
    Otherwise please advertise as non-connectable. 

  • I really want only one peripheral to be connected.

    I'm not fluent in "connectable advertising" and "non connectable advertising", sorry, not sure what you mean.

    I guess I should check on_whitelist_req if i'm already connected and not advertise in this case, but I don't think there is a function for that.

  • Hi Quentin, 

    So when you advertise as "connectable advertising", other central device can send a connect request and establish a new connection. 
    When you advertise as "non-connectable advertising" , your device is non-connectable, meaning other central won't send you a connect request and won't establish a new connection. 

    From my understanding, in your case, at the beginning you advertise as connectable and you has a connection as a peripheral to another central, correct ? 
    At the same time you scan to connect to other peripheral and you also advertise (without the need of establishing a new connection). Is it correct ? 

    If it's the case, you would need to do non-connectable advertising. The ble_advertising actually doesn't support this. So you would need to call sd_ble_gap_adv_set_configure(), sd_ble_gap_adv_start() directly. 

    You can have a look at this example from Awneil: devzone.nordicsemi.com/.../187695

Reply
  • Hi Quentin, 

    So when you advertise as "connectable advertising", other central device can send a connect request and establish a new connection. 
    When you advertise as "non-connectable advertising" , your device is non-connectable, meaning other central won't send you a connect request and won't establish a new connection. 

    From my understanding, in your case, at the beginning you advertise as connectable and you has a connection as a peripheral to another central, correct ? 
    At the same time you scan to connect to other peripheral and you also advertise (without the need of establishing a new connection). Is it correct ? 

    If it's the case, you would need to do non-connectable advertising. The ble_advertising actually doesn't support this. So you would need to call sd_ble_gap_adv_set_configure(), sd_ble_gap_adv_start() directly. 

    You can have a look at this example from Awneil: devzone.nordicsemi.com/.../187695

Children
No Data
Related