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

Starting scan error from application with whitelist

Hi Nordic, 

I want to establish a user controlled connection  to a ble_peripheral.  I am using the Sdk 15.3, s140 and the nrf52840.

I used as a reference the ble_app_interactive experimental example and the ble_central/ble_app_hrs_c. My intention is to connect to a peripheral based on the user selection as the ble_app_interactive example, but also having the whitelist enable as in the ble_app_hrs_c example. Is this possible?

The issue that i'm facing is on the very first call of the scan_start()

/**@brief Connection parameters requested for connection.
 */
static ble_gap_conn_params_t const m_connection_param =
{
    MIN_CONNECTION_INTERVAL,
    MAX_CONNECTION_INTERVAL,
    SLAVE_LATENCY,
    SUPERVISION_TIMEOUT
};

/**< Scan parameters requested for scanning and connection. */
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,
		.scan_phys     = BLE_GAP_PHY_1MBPS,
};

void scan_init(void)
{
    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.p_conn_param     = &m_connection_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);

}

void scan_start(void)
{
    ret_code_t err_code;
    if (nrf_fstorage_is_busy(NULL))
    {
        m_memory_access_in_progress = true;
        NRF_LOG_INFO("nrf_fstorage_is_busy");
        return;
    }

    NRF_LOG_INFO("scan_start");
    err_code = nrf_ble_scan_start(&m_scan);
    if(err_code!= NRF_SUCCESS){
        NRF_LOG_INFO("Starting scan error %d", err_code);
    }
    APP_ERROR_CHECK(err_code);

}

On application init I'm calling first the scan_init() and then scan_start(), however, i get inside this last function a return error of 7:

Starting scan error 7

It is related with the scan_parameter because when i remove them, the error goes away and the application works fine just that without whitelist. But I'm using the same settings as the ble_app_hrs_c example. 

Any ideas? 

Parents
  • Hello,

    Have you tried to debug into nrf_ble_scan_start() to see what function inside there that returns NRF_ERROR_INVALID_PARAMS, and compare it to the scan start function in ble_app_hrs_c? There is no reason why it shouldn't work, but it is probably not set up correctly.

    Perhaps you are trying to start scanning with an empty whitelist?

    BR,

    Edvin

  • ok yes, the whitelist is empty. But should it not enter in the case:


    case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
    {
    on_whitelist_req();
    m_whitelist_disabled = false;
    NRF_LOG_INFO("NRF_BLE_SCAN_EVT_WHITELIST_REQUEST");
    } break;

    from scan_evt_handler()? It is indeed the whitelist becue i did a delete_bonds() earlier

  • I guess you don't have any devices in your whitelist at this point? In that case, you should set m_whitelist_disabled = true;

    Look at how the first scan is called in the ble_app_hrs_c example. At this point there are no devices in the whitelist:

    main() -> scanning_start() -> scan_start() -> nrf_ble_scan_start() which triggers the NRF_BLE_SCAN_EVT_WHITELIST_REQUEST -> on_whitelist_req() -> which disables the whitelist if it is empty. 

    Try to implement the same, and if it doesn't work. Please upload a project that replicates your issue here. Please zip the project folder (the ble_app_interactive folder). Please also try to extract it to an unmodified SDK to make sure that it doesn't require any changes outside this folder in order to replicate it. Also mention what IDE you are using.

    Best regards,

    Edvin

Reply
  • I guess you don't have any devices in your whitelist at this point? In that case, you should set m_whitelist_disabled = true;

    Look at how the first scan is called in the ble_app_hrs_c example. At this point there are no devices in the whitelist:

    main() -> scanning_start() -> scan_start() -> nrf_ble_scan_start() which triggers the NRF_BLE_SCAN_EVT_WHITELIST_REQUEST -> on_whitelist_req() -> which disables the whitelist if it is empty. 

    Try to implement the same, and if it doesn't work. Please upload a project that replicates your issue here. Please zip the project folder (the ble_app_interactive folder). Please also try to extract it to an unmodified SDK to make sure that it doesn't require any changes outside this folder in order to replicate it. Also mention what IDE you are using.

    Best regards,

    Edvin

Children
  • Hi Edvin, thank you very much for your reply. 

    It turned out tat the issue was appearing only if I'm using 2Mbps 

    .scan_phys     = BLE_GAP_PHY_2MBPS,

    In the ble_app_hrs_c example the 1MBPS is used. When i comment this part it's working as expected. Any idea why this might be? since i have a high throughput, I'm interedted on using the 2Mbps.

    Other question: At the moment the application is behaving as expected, since i have the  init_scan.connect_if_match = true;
    it connects automatically to the devices saved in the whitelist. 

    Is there any option that i can enable to make the system able to scan ALL devices but only connect automatically to those that are saved in the whitelist. I can do this manually but i wanted to know if there was an option that had already this functionality. 

    Thanks

  • You need to advertise at 1MBPS (all scanners are scanning at 1MBPS as well). Then, once the connection is established, you can request to use 2MBPS. If the central supports 2MBPS, they will switch over to it. 

     

    User1321 said:
    Is there any option that i can enable to make the system able to scan ALL devices but only connect automatically to those that are saved in the whitelist. I can do this manually but i wanted to know if there was an option that had already this functionality. 

     No.

    The whitelist is a hardware based whitelist. This means that it will automatically filter out all advertisements not part of the whitelist. If you want to use a software based whitelist, you need to use the filters that are implemented (or create your own). The filters are based on the typical parameters that an advertisement holds, such as advertising name, advertising address, advertising UUIDs or similar (don't remember all by heart). 

    However, you can forward the advertisement events to your main.c file's ble_evt_handler. Just add the event in the switch(case). This is the way it was done in the SDKs that are a bit older. Then you can examine whatever part of the advertisement that you like, and then make the decision on whether you would like to connect or not. 

    User1321 said:
    Is there any option that i can enable to make the system able to scan ALL devices but only connect automatically to those that are saved in the whitelist. I can do this manually but i wanted to know if there was an option that had already this functionality. 

    Actually, it is sort of what it does, but when the whitelist is enabled the advertisements that doesn't fulfill the whitelist requirements (using one of the addresses in the whitelist), the advertisements are filtered out before the advertisement is propagated to the application. If you want all advertisements, in your application, you need to disable the whitelist.

Related