Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

How to advertise using a whitelist?

Hello.
I am developing using nrf52832 (S132 v7.0.1, SDK v17.0.0) as a peripheral device.

The program is created by referring to the whitelist of "ble_app_hids_mouse" which is an example of SDK.

At that time, when ble_advertising_start is executed, NRF_ERROR_INVALID_STATE occurs in ble_advertising_whitelist_reply in BLE_ADV_EVT_WHITELIST_REQUEST.

#define BLE_ADV_UUID_SERVICE            0xFFFF
BLE_ADVERTISING_DEF(m_advertising);

// Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs.
static ble_uuid_t m_adv_uuids[] = 
{
    {BLE_ADV_UUID, BLE_UUID_TYPE_VENDOR_BEGIN},
};

// Advertising data structure. This structure contains all options and data needed for encoding and setting the advertising data.
static ble_advdata_t m_adv_data = 
{
    .flags                        = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE,
    .uuids_complete.uuid_cnt      = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]),
    .uuids_complete.p_uuids       = m_adv_uuids,
};

// Options for the different advertisement modes.
static ble_adv_modes_config_t m_adv_init = 
{
    .ble_adv_whitelist_enabled      = true,
    .ble_adv_on_disconnect_disabled = true,
    .ble_adv_fast_enabled           = true,
    .ble_adv_fast_interval          = APP_ADV_INTERVAL,
    .ble_adv_fast_timeout           = APP_ADV_DURATION,
};


// Initialize the advertisement.
static void advertising_init(void)
{
    ret_code_t err_code;
    ble_advertising_init_t adv_init;

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

    adv_init.advdata     = m_adv_data;
    adv_init.config      = m_adv_init;
    adv_init.evt_handler = on_adv_evt;

    err_code = ble_advertising_init(&m_advertising, &adv_init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);

    return;
}

// Start advertising.
static void advertising_start(void)
{
    ret_code_t err_code;
    uint32_t   peer_cnt;

    peer_cnt = pm_peer_count();

    // Determine if there is a bonded device
    if (peer_cnt != 0x00) {
        // Since there is a bonded device, set the white list.
        whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
    }
    else {
        // Since there are no bonded devices, we will not use the white list in this advertisement.
        ble_advertising_restart_without_whitelist(&m_advertising);
    }

    // Start advertising.
    err_code = ble_advertising_start(m_advertising, BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

    return;
}

// Set a whitelist.
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);

    err_code = pm_whitelist_set(peer_ids, peer_id_count);
    APP_ERROR_CHECK(err_code);
}

// A function for handling PeerManager events.
static void pm_evt_handler(pm_evt_t const * p_evt)
{
    pm_handler_on_pm_evt(p_evt);
    pm_handler_flash_clean(p_evt);

    switch (p_evt->evt_id) {
        case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
            if (p_evt->params.peer_data_update_succeeded.data.id == PM_PEER_DATA_ID_BONDING) {
                if (p_evt->params.peer_data_update_succeeded.flash_chenged) {
                    whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
                }
            }
            break;

        default:
            break;
    }
}

// Advertise event handle.
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    ret_code_t     err_code;
    ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
    ble_gap_irk_t  whitelist_irks[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
    uint32_t       addr_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;
    uint32_t       irk_cnt  = BLE_GAP_WHITELIST_ADDR_MAX_COUNT;

    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_WHITELIST_REQUEST:

            memset(&whitelist_addrs, 0, BLE_GAP_WHITELIST_ADDR_MAX_COUNT);
            memset(&whitelist_irks, 0, BLE_GAP_WHITELIST_ADDR_MAX_COUNT);

            err_code = pm_whitelist_get(whitelist_addrs, &addr_cnt, whitelist_irks, &irk_cnt);
            APP_ERROR_CHECK(err_code);

            err_code = ble_advertising_whitelist_reply(&m_advertising_keyless, whitelist_addrs, addr_cnt, whitelist_irks, irk_cnt);
            APP_ERROR_CHECK(err_code);
            break;
    
        default:
            break;
    }

    return;
}

I have ported all the necessary processing, but is there any other necessary processing?
I would appreciate it if you could tell me.

Related