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

How to apply whitelist during advertisement?

Hi,

I am trying to apply a whitelist during advertisement on my peripheral device. Only one central should be whitelisted at a time. The whitelist is empty on initial boot up. I am using BLE_GAP_ADV_FP_FILTER_CONNREQ, but I always get NRF_ERROR_INVALID_PARAM, using my configuration. I am guessing this is because I haven't told the SoftDevice which whitelist to use (?). How can I adjust my setup in order to make this work? I appreciate any help.

Advertising Init:

static void advertising_init(void)
{
    ret_code_t               err_code;
    ble_advdata_t            advdata;
    ble_advdata_t            srdata;
    ble_gap_adv_params_t     adv_params;
    ble_advdata_manuf_data_t adv_manuf_data;

    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = true;
    advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    memset(&srdata, 0, sizeof(srdata));
    srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    srdata.uuids_complete.p_uuids  = m_adv_uuids;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    APP_ERROR_CHECK(err_code);

    memset(&adv_params, 0, sizeof(adv_params));
    adv_params.p_peer_addr   = NULL;
    adv_params.filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
    adv_params.interval      = APP_ADV_INTERVAL;

    adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    adv_params.duration        = APP_ADV_DURATION;
    adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);
}

Whitelisting:

static pm_peer_id_t m_peer_id;

static void whitelist_connected_peer()
{
    ret_code_t err_code;
    err_code = pm_whitelist_set(&m_peer_id, 1);
    APP_ERROR_CHECK(err_code);
}

Edit: Clear clumsy text.

Parents
  • Hi Robin, 

    Please correct me if I'm wrong. So what you want to do is to start advertising with no whitelist but with filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ; ? And then you will update the whitelist after you have bonded to the central ? 

    If it's the case it's will cause an error as it's described in the documentation of the sd_ble_gap_adv_set_configure() function: 

     * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
    * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t.
    * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
    * - Use of whitelist requested but whitelist has not been set, * see @ref sd_ble_gap_whitelist_set.

    I would suggest to advertise without the BLE_GAP_ADV_FP_FILTER_CONNREQ filter. After you have the central credential for whitelist, you can start advertising again with whitelist. You can have a look at the ble_app_hid_mouse to see an example when whitelist is used. 

  • Thanks for the help! That makes sense. I think I was confused since the advertising_init() is usually called once on startup. I thought these parameters couldn't/shouldn't be modified later.

    It helped looking into the ble_app_hid_keyboard example and using the methods in ble_advertising.h to manage advertising. I am now able to use whitelisting and bonding functionality as intended.

    However, I am unable to erase bonds without doing a full reset. I intend to use a button to remove bonding info and start advertising without a whitelist. In addition, I want maximum one central device to be in the whitelist. Do you have any tips on how I can remove bonds, whitelist and restart advertisements?

    I see the ble_advertising_restart_without_whitelist(), however, this function does not delete the peers first, right?

    After I disconnect from the bonded & whitelisted central and erasing all bonds using pm_peers_delete(), the ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST) returns INVALID_STATE. Do you have any idea why that might be?

    Edit: Unknown error code was thrown by pm_device_identities_list_set() as advertisement was automatically restarted by the ble_advertising.c/.h module after BLE_GAP_EVT_DISCONNECTED. Once I ensured advertising was switched off before setting the whitelist, everything worked perfectly.

  • Hi Robin, 

    ble_advertising_restart_without_whitelist() will not delete the peers. pm_peers_delete() does

    However , you need to wait until you receive PM_EVT_PEERS_DELETE_SUCCEEDED event after you call pm_peers_delete() before continue. 

    Note that whitelisting is independent from peer data. So after you delete peer data, you may want to remove or update whitelist as well. 
    When you remove or update whitelist, you need to make sure the device is not advertising or scanning. 

    Please try stepping into the code of ble_advertising_start() and check which exact function that throwing the error.  I'm not sure which error code is the UNKNOWN_ERROR_CODE, how did you catch that ? 

  • Thanks. That's very helpful! I believe I've managed to implement it as intended now. The reason for my error was that the ble_advertising.h/.c automatically restarts advertising when the device disconnects. I got INVALID_STATE because the device was already advertising.

Reply Children
Related