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.

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

Children
Related