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

Central connect to peripheral with sd_ble_gap_connect command

I am using SDK 17 and nrf52840. There is one central and multiple peripherals. The peripherals are divided into different groups with different names. The central can decide which group to connect to by checking the device name when the uuid matches. If the device name matches, then the central will use sd_ble_gap_connect function to connect to it. 

So here is my Scan_init function:

static 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.connect_if_match = false;
    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);

    m_scan_param.interval =  NRF_BLE_SCAN_SCAN_INTERVAL;
    m_scan_param.window   = NRF_BLE_SCAN_SCAN_WINDOW;

    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_UUID_FILTER, &m_nus_uuid);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_UUID_FILTER, false);
    APP_ERROR_CHECK(err_code);   // Remove scan filter on 9/21/2020 

}

Then in the scan_evt_handler function, when there is an uuid match, it will trigger the NRF_BLE_SCAN_EVT_FILTER_MATCH event.

If the device name matches the requirement(for example, the peripheral group that I would like to connect to is "group1", then I use sd_ble_gap_connect command

to connect to the peripherals in this group. I have looked around and did not find an example to do this. 

So my particular questions is: how to implement the sd_ble_gap_connect command inside the NRF_BLE_SCAN_EVT_FILTER_MATCH event?

Thanks in advance! Here is the code that I need help:

static void scan_evt_handler(scan_evt_t const * p_scan_evt)
{
    ret_code_t err_code;
    

    switch(p_scan_evt->scan_evt_id)
    {
         case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
         {
              err_code = p_scan_evt->params.connecting_err.err_code;
              APP_ERROR_CHECK(err_code);
         } break;

          case NRF_BLE_SCAN_EVT_FILTER_MATCH:
          {
            NRF_LOG_INFO("uuid Match found\n");
            // How to use sd_ble_gap_connect() function here? 
                       
          }
          break;

         case NRF_BLE_SCAN_EVT_CONNECTED:
         {
              ble_gap_evt_connected_t const * p_connected =
                               p_scan_evt->params.connected.p_connected;

             NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x",
                      p_connected->peer_addr.addr[5],
                      p_connected->peer_addr.addr[4],
                      p_connected->peer_addr.addr[3],
                      p_connected->peer_addr.addr[2],
                      p_connected->peer_addr.addr[1],
                      p_connected->peer_addr.addr[0]
                      );             
         } break;

         case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
         {
             NRF_LOG_INFO("Scan timed out.");
             scan_start();
         } break;

         default:
             break;
    }
}

Parents
  • I believe most of the central ble examples show how to scan and connect. I believe you can for instance find in nrf_ble_scan.c the implementation of nrf_ble_scan_connect_with_target() and use it as reference. The same implementation should be possible to do on NRF_BLE_SCAN_EVT_FILTER_MATCH event. Note that if you have configured .connect_if_match then nrf_ble_scan_connect_with_target() will do this for you already.

  • It is true that most of the central examples show how to scan and connect, but none of them show how to solve my problem: i.e, when the uuid matches, I need to check the device name of the peripheral that matches the uuid. If the device name matches the requirement, then I use the sd_ble_gap_connect() function to connect to the peripheral.

    Because the device name is not included in the ble_gap_evt_adv_report_t structure when the uuid matches, I am having trouble to do so. I have looked around and have not found an example to do so yet. 

    Thanks for your help. 

  • In such case I expect you may need to look at the nrf_ble_scan.c module as reference on how to implement or modify it to your needs.

    For instance when you receive the BLE_GAP_EVT_ADV_REPORT event, check how the scan module parse the advertisement packet for device name and UUID. Have in mind that the data you want to receive may be split over two consecutive BLE_GAP_EVT_ADV_REPORT events (the first will be the advertisement packet and the second will be the result of the scan response packet, both will trigger the BLE_GAP_EVT_ADV_REPORT event). You can check the p_ble_evt->evt.gap_evt.params.adv_report.type.scan_response; to find if it's the scan response packet that triggered the BLE_GAP_EVT_ADV_REPORT  event.

    In your case I expect you will need to buffer the latest received device name, and every time you receive the UUID check that the previous packet had the correct device name.

  • Thanks. So I need to check every scan response data at the BLE_GAP_EVT_ADV_REPORT event to see if there is a match? 

    I am wondering if there is a better way to do so. Since if there are many blue tooth devices that generates BLE_GAP_EVT_ADV_REPORT constantly, this slow down the central device a lot? The central device is handling data from multiple peripherals in the mean time. 

    In other words, is it possible to use the NRF_BLE_SCAN_EVT_FILTER_MATCH event to parse the scan response data from the peripheral?

Reply
  • Thanks. So I need to check every scan response data at the BLE_GAP_EVT_ADV_REPORT event to see if there is a match? 

    I am wondering if there is a better way to do so. Since if there are many blue tooth devices that generates BLE_GAP_EVT_ADV_REPORT constantly, this slow down the central device a lot? The central device is handling data from multiple peripherals in the mean time. 

    In other words, is it possible to use the NRF_BLE_SCAN_EVT_FILTER_MATCH event to parse the scan response data from the peripheral?

Children
Related