This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ble-app-uart-c-multilink example with whitelist

Hi,

I use the ble-app-uart-c-multilink example with a nRF52840 DK and 5 custom nRF52840 peripheral devices.

For a test, I want to connect to only one of those peripherals with address  {0xDF, 0xF8, 0x94, 0x2B, 0x7D, 0x70} so I need to implement a whitelist in the multilink example like in the ble_app_hrs_c example.

So far I have included the following code parts to multilink example main.c file

#define SCAN_DURATION_WITELIST      3000                                /**< Duration of the scanning in units of 10 milliseconds. */
static uint16_t m_conn_handle;                                      /**< Current connection handle. */
static bool     m_whitelist_disabled;                               /**< True if whitelist has been temporarily disabled. */
static bool     m_memory_access_in_progress;                        /**< Flag to keep track of ongoing operations on persistent memory. */

static ble_gap_scan_params_t const 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_WITELIST,
    .scan_phys     = BLE_GAP_PHY_1MBPS,
};

/**@brief Names which the central applications will scan for, and which will be advertised by the peripherals.
 *  if these are set to empty strings, the UUIDs defined below will be used
 */
static char const m_target_periph_name[] = "";      /**< If you want to connect to a peripheral using a given advertising name, type its name here. */
static bool is_connect_per_addr = true;            /**< If you want to connect to a peripheral with a given address, set this to true and put the correct address in the variable below. */

static ble_gap_addr_t const m_target_periph_addr =
{
    /* Possible values for addr_type:
       BLE_GAP_ADDR_TYPE_PUBLIC,
       BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
       BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
       BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
    .addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
    .addr      = {0xDF, 0xF8, 0x94, 0x2B, 0x7D, 0x70}
};

I also modified the scan_init() function like this

    ret_code_t          err_code;
    nrf_ble_scan_init_t init_scan;

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

    init_scan.p_scan_param = &m_scan_param;
    init_scan.connect_if_match = true;
    init_scan.conn_cfg_tag     = APP_BLE_CONN_CFG_TAG;

    err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, m_target_periph_addr.addr);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
    APP_ERROR_CHECK(err_code);

When I run the code on the central (DK) an error pops up :  "    ble_scan: sd_ble_gap_scan_start returned 0x7  "

What is this error?

Thank you

  • Hi,

    The error is NRF_ERROR_INVALID_PARAM. It looks to me like you specify BLE_GAP_SCAN_FP_WHITELIST in one end, which indicates that the SoftDevice whitelisting feature should be enabled. But I do not see that you set a whitelist. Instead, I see that you configure the address filter feature of the scan module. This is not the same, though similar in functionality in some ways.

    If you want to use the proper whitelisting feature of the SoftDevice (which is needed in some cases, as for instance handles peers that use privacy, like any modern phone), you need to do a bit more. As you mentioned ble_app_hrs_c I suggest you use that as reference. If you take examples/ble_central/ble_app_hrs_c/main.c and search for whitelist you will find most of the relevant code.

    If you just want to filter a specific static BLE address, then using the scan module filter should be good enough. But in that case you should not set BLE_GAP_SCAN_FP_WHITELIST as you are not using whitelisting, but use BLE_GAP_SCAN_FP_ACCEPT_ALL all instead, and let the scan module do the filtering.

  • Hi thank you for the good explanation!

    I will perform the changes and I will come back.
    Also, Is it possible to filter more that one specific static BLE addresses? For example in case I want to connect to 2 or 3 specific devices out of the five peripherals I have in total, can I do it the same way as you describe in your last paragraph?

    Thank you for your time

  • Hi,

    Yes, you can add more than 1 address in the filter, with both approaches.

    Using the SoftDevice to do whitelisting the limit is 8, both for static addresses and random resolvable addresses (so based on IRK).

    If you filter in the scan module there is no hard limit, but you need to set NRF_BLE_SCAN_ADDRESS_CNT in sdk_config.h high enough. You simply add more addresses using more calls to nrf_ble_scan_filter_set().

  • YOu can refer to my blog (https://jimmywongiot.com/2019/10/18/ble-scanning-with-whitelist/).

    it has the code how to do it as the central.

  • Yes it worked! Thank you for the help!!.

    I Have one more question. When I try to send some characters to the connected peripheral I get 6 Connection handle invalid warnings. What is this?

Related