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

About the number of saved bonding information

Hello.
I am developing using nrf52832 (S132 v7.0.1, SDK v16.0.0).

I use whitelist to store bonding information. Is there an upper limit to the number that can be stored?
Also, how can I set it to increase the number that can be saved?

If you have any materials, please let me know.
Please let us know if you have any questions.
Thank you.

Parents
  • Hi Kei, 

    The number of peers can be handled by the peer manager is defined by the flash space that's the fds module has. 
    It's defined in sdk_config.h as FDS_VIRTUAL_PAGES (by default 3 pages) . So there isn't really a limit for number of peer in peer manager. You can just increase the number of page reserved for FDS.

    However, there is a limit for whitelisting. It's the limitation of the hardware. So the softdevice only allow a whitelist of max 8 devices (BLE_GAP_WHITELIST_ADDR_MAX_COUNT). 
    A workaround for this is to rotate this 8 devices list. So for example if you have 16 devices you want to put into the whitelist, you can scan/advertise with 8 devices in whitelist at a time, and then switch. 

  • thank you for your answer.

    When connecting to a BLE device and performing bonding, the information may be listed in the FDS using a white list.
    Therefore, I thought that all of them were registered on the white list.

    The action I want to do is receive advertisements from bonded BLE devices. For that purpose, I thought that by setting "filter_policy" to "BLE_GAP_SCAN_FP_WHITELIST", it would be possible to receive advertisements only for bonded BLE devices.

    How should I register for the white list?
    And how do you rotate the devices you want to whitelist?

    Thank you.

  • Hi Kei, 

    You can have a look at the ble_app_hids_mouse as an example on how you can setup the whitelist for scanning/advertising. The function to setup the whitelist is whitelist_set(): 

    /**@brief Function for setting filtered whitelist.
     *
     * @param[in] skip  Filter passed to @ref pm_peer_id_list.
     */
    static void whitelist_set(pm_peer_id_list_skip_t skip)
    {
        pm_peer_id_t peer_ids[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
        uint32_t     peer_id_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
    
        ret_code_t err_code = pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_INFO("\tm_whitelist_peer_cnt %d, MAX_PEERS_WLIST %d",
                       peer_id_count + 1,
                       BLE_GAP_WHITELIST_ADDR_MAX_COUNT);
    
        err_code = pm_whitelist_set(peer_ids, peer_id_count);
        APP_ERROR_CHECK(err_code);
    }
    

    However this code will load all peers and it will be limited by BLE_GAP_WHITELIST_ADDR_MAX_COUNT = 8. 

    If you want to rotate the list, you would need to study the code a little bit and call pm_whitelist_set() so that it will switch between peer_ids. I haven't tried, but it may work this way: 
    First call: 
    err_code = pm_whitelist_set(peer_ids, 8);
    APP_ERROR_CHECK(err_code);

    Second call (after you scan for  a while) 

    err_code = pm_whitelist_set(peer_ids+sizeof(uint16_t)*8, 8);
    APP_ERROR_CHECK(err_code);

    And so on. I suggest to look deeper into the code of the peer manager to understand how the whitelist setting works. 

  • Hello.

    I'm considering rotating the list.
    I am trying to do pm_whitelist_set 1 second after setting with pm_whitelist_set. (Switch peer_ids)
    However, when I make the second call, I get a BLE_GAP_ERROR_WHITELIST_IN_USE error.
    I tried to clear the whitelist before setting, but I got the same error.

    Is there any countermeasure?

    Thank you.

  • Hi Kei, 


    Could you try to stop scanning (and advertising if you also do advertising) before you change the whitelist ? It's mentioned in the documentation of sd_ble_gap_whitelist_set() that "The whitelist cannot be set if a BLE role is using the whitelist."

Reply Children
  • Hello.

    Changed to do sd_ble_gap_scan_stop before doing pm_whitelist_set. Thanks to you, BLE_GAP_ERROR_WHITELIST_IN_USE no longer occurs.
    However, the second call now causes an NRF_ERROR_NOT_FOUND.

    I described the process of rotating with reference to whitelist_load of ble_app_gatts. The source code is as follows.

    Which part should I fix?

    Thank you.

    #define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (1)
    static uint8_t whitelist_cnt;
    
    void whitelist_load(void)
    {
        ret_code_t   ret;
        pm_peer_id_t peers[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
        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 flash and whitelist them.
        peer_list_get(peers, &peer_cnt);
        
        if (whitelist_cnt >= pm_peer_count())
        {
            whitelist_cnt = 0;
        }
    
        ret = pm_whitelist_set(peers + (sizeof(uint16_t) * (BLE_GAP_WHITELIST_ADDR_MAX_COUNT * whitelist_cnt)), peer_cnt);
        APP_ERROR_CHECK(ret);
    
        // Setup the device identities list.
        // 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);
        }
    }

  • Hi Kei, 
    I don't really understand this part: 

    ret = pm_whitelist_set(peers + (sizeof(uint16_t) * (BLE_GAP_WHITELIST_ADDR_MAX_COUNT * whitelist_cnt)), peer_cnt);
    APP_ERROR_CHECK(ret);

    Could you explain ? What's the value of whitelist_cnt  ? and  peer_cnt ? 
    What's inside peer_list_get() ? 
    What you need to do is to feed the first 8 peers and then after that you feed the next 4 peers for example (if you have 12 peers in total). 
    What you do here with peer_cnt is just feed the whole 12 peers in at once which is not correct. 
    Please clearly show how you call the first whitelist set, and then how you call the second whitelist set. 

  • Hello.
    The explanation was not enough.

    Premise
    ・ Bonded to 2 devices
    ・The value of whitelist_cnt is 0
    ・ The value of peer_cnt is 1.

    Purpose
    ・ I want to be able to receive advice from one of the two devices, and disable advertising from the other.
    ・ I want to switch between receivable and unreceivable after a certain period of time.

    How to call whitelist_load (pm_whitelist_set)
    ・ Measure the time using App Timer and add 1 to the value of whitelist_cnt after a certain period of time.

    Inside peer_list_get ()
    ・ Please refer to the code below

    I think I can change the peers I set in whitelist by using whitelist_cnt.
    For example, when whitelist_cnt is 1, it will be "pm_whitelist_set (peer + (sizeof (uint16_t) * BLE_GAP_WHITELIST_ADDR_MAX_COUNT)), peer_cnt);", which means the same code as Hung Bui taught me.
    Since whitelist_cnt does not exceed the number of devices, it can only be 0 or 1. If it is 0, it will be the device that bonded first, and if it is 1, it will be the device that bonded the second time.

    Is this idea wrong?

    Thank you.

    /**@brief Retrive a list of peer manager peer IDs.
     *
     * @param[inout] p_peers   The buffer where to store the list of peer IDs.
     * @param[inout] p_size    In: The size of the @p p_peers buffer.
     *                         Out: The number of peers copied in the buffer.
     */
    static void peer_list_get(pm_peer_id_t * p_peers, uint32_t * p_size)
    {
        pm_peer_id_t peer_id;
        uint32_t     peers_to_copy;
    
        peers_to_copy = (*p_size < BLE_GAP_WHITELIST_ADDR_MAX_COUNT) ?
                         *p_size : BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
    
        peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
        *p_size = 0;
    
        while ((peer_id != PM_PEER_ID_INVALID) && (peers_to_copy--))
        {
            p_peers[(*p_size)++] = peer_id;
            peer_id              = pm_next_peer_id_get(peer_id);
        }
    }

  • Hi Kei, 
    I'm sorry that I was not aware that the peer_list_get() was taken from one of our example. 
    I assume you are planning to have more than 2 peer in the database right ? The scenario of 2 peers is just for testing  ? 

    Note that if you simply want to filter the advertising packets, you can also filter them in the NRF_BLE_SCAN_EVT_FILTER_MATCH event if you use a filter or  NRF_BLE_SCAN_EVT_NOT_FOUND event ( It's the event for all advertising packet if you don't use any filter). 

    Regarding your code:

    In the example the peer_list_get will return the number of peers, so in your case if you have 2 peers in the database, it will return 2, not 1. 
    So in your case the first call should be: 
     peer_list_get(peers, &peer_cnt);

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

    and the second call should be 

     peer_list_get(peers, &peer_cnt);

    ret = pm_whitelist_set(peers+sizeof(uint16_t), 1);
    APP_ERROR_CHECK(ret);

    Notice both time the number of peer count is 1. 

    if you plan to have more peers on each whitelist set, you need to change 1 to match with what you want. But it should not exceed the max number of peers (like what I described earlier, if you have 12 peers, on the first call you can call 8 peers, and the next one you use 4) 

  • Hello.

    Currently, we are confirming with bonding of 2 units as a study, but we are assuming bonding of 8 or more units in the future.
    I also use this filter because I want to communicate with a device that has been bonded once.

    I changed to the code you taught me and used nRF Connect to bond two devices. But I get the same error.
    After bonding two units and executing pm_list_get, when I checked the value of peer_cnt, it was 1 instead of 2.

    Why is peer_cnt 1 after running pm_list_get?

    Thank you.

Related