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

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

  • 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?

  • This is printed in ble_nus_c_string_send() in components/ble/ble_services/ble_nus_c/ble_nus_c.c if the connection handle you provided to ble_nus_c_string_send() is BLE_CONN_HANDLE_INVALID, which is the default value used to indicate that there is no connection. You need to provide the connection handle, which you first get with the  case BLE_GAP_EVT_CONNECTED event, and should configure the NUS service for using ble_nus_c_handles_assign().

  • Hi, I did manage to filter specific peripheral devices based on their address the way you said and it works!
    Now, how can I recognize which peripheral device is sending its data to the central when all devices send transmit at the same time and how can I send data only to a specific peripheral? (since I want to send different commands to each peripheral individually)

    Thank you

  • Hi,

    All events related to a connection includes a connection handle, and this is what you use to distinguish between different connections. The connection handle is created when the connection is created, and the application is informed of this when you get the BLE_GAP_EVT_CONNECTED event, and this is valid until you get a BLE_GAP_EVT_DISCONNECTED event for that connection. If you need to map connection handle to address later you should store this somewhere for future reference. That way you can always look up to connection handle and know which address it represents.

Reply
  • Hi,

    All events related to a connection includes a connection handle, and this is what you use to distinguish between different connections. The connection handle is created when the connection is created, and the application is informed of this when you get the BLE_GAP_EVT_CONNECTED event, and this is valid until you get a BLE_GAP_EVT_DISCONNECTED event for that connection. If you need to map connection handle to address later you should store this somewhere for future reference. That way you can always look up to connection handle and know which address it represents.

Children
Related