Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Clear GATT Cache

I have a sensor that uses 3 different BLE mechanisms. It is part of a mesh, it sometimes sends beacons and it provides GATT services in a peripheral role. The project I'm working on needs to connect to this sensor. So, I set up a filter that filters on UUID (the GATT service that's needed runs NUS) and the sensor's address. 

Sometimes this works great, but sometimes it keeps telling me there is no match on the filter - I just get tons of NRF_BLE_SCAN_EVT_NOT_FOUND events from the scan event handler. It looks like the system doesn't check if the advertisement packets it sees are actually the same as the one it has seen before - e.g. is caches.

Is it possible to tell the scanning mechanism it should clear its cache? I set up the scanner to automatically stop after 30 seconds and than start it again, I would like to clear the cache before restarting it.

Parents
  • What SDK are you using? nRF5 SDK or NCS (nRF Connect SDK)? And what release version?

    My guess is that you are using the nRF5 SDK, is that correct?

    In our examples, the NRF_BLE_SCAN_EVT_NOT_FOUND event is not really used for anything. It really just means that an advertising report was found, but it didn't match your filter. It has no recognition of previous advertisements from the same device. So unless you need this event, I suggest you remove it from your scan event handler (don't use case: NRF_BLE_SCAN_EVT_NOT_FOUND).

    The event that you are actually looking for is the NRF_BLE_SCAN_EVT_FILTER_MATCH, which will occur if you actually get a match on your filters. But if you have the nrf_ble_scan_connect_with_target() in the event handler, you don't really need this either. Look at the end of the nrf_ble_scan_on_adv_report() in nrf_ble_scan.c:

        // In the multifilter mode, the number of the active filters must equal the number of the filters matched to generate the notification.
        if (all_filter_mode && (filter_match_cnt == filter_cnt))
        {
            scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_FILTER_MATCH;
            nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
        }
        // In the normal filter mode, only one filter match is needed to generate the notification to the main application.
        else if ((!all_filter_mode) && is_filter_matched)
        {
            scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_FILTER_MATCH;
            nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
        }
        else
        {
            scan_evt.scan_evt_id        = NRF_BLE_SCAN_EVT_NOT_FOUND;
            scan_evt.params.p_not_found = p_adv_report;
    
        }

    Most of our examples, such as the ble_app_uart_c doesn't use any of these events. Looking at this example, the scan_evt_handler() only checks for a few events:

    /**@brief Function for handling Scanning Module events.
     */
    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_CONNECTED:
             {
                  ble_gap_evt_connected_t const * p_connected =
                                   p_scan_evt->params.connected.p_connected;
                 // Scan is automatically stopped by the connection.
             } break;
    
             case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
             {
                 NRF_LOG_INFO("Scan timed out.");
                 scan_start();
             } break;
    
             default:
                 break;
        }
    }

    End neither of them are NRF_BLE_SCAN_EVT_NOT_FOUND nor NRF_BLE_SCAN_EVT_FILTER_MATCH. As you can see, the on_adv_report() function calls nrf_ble_scan_connect_with_target().

    So exactly what is not working sometimes? It doesn't connect? Are you sure that the device you are trying to connect to is advertising at that point in time?

    Best Regards,
    Edvin

Reply
  • What SDK are you using? nRF5 SDK or NCS (nRF Connect SDK)? And what release version?

    My guess is that you are using the nRF5 SDK, is that correct?

    In our examples, the NRF_BLE_SCAN_EVT_NOT_FOUND event is not really used for anything. It really just means that an advertising report was found, but it didn't match your filter. It has no recognition of previous advertisements from the same device. So unless you need this event, I suggest you remove it from your scan event handler (don't use case: NRF_BLE_SCAN_EVT_NOT_FOUND).

    The event that you are actually looking for is the NRF_BLE_SCAN_EVT_FILTER_MATCH, which will occur if you actually get a match on your filters. But if you have the nrf_ble_scan_connect_with_target() in the event handler, you don't really need this either. Look at the end of the nrf_ble_scan_on_adv_report() in nrf_ble_scan.c:

        // In the multifilter mode, the number of the active filters must equal the number of the filters matched to generate the notification.
        if (all_filter_mode && (filter_match_cnt == filter_cnt))
        {
            scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_FILTER_MATCH;
            nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
        }
        // In the normal filter mode, only one filter match is needed to generate the notification to the main application.
        else if ((!all_filter_mode) && is_filter_matched)
        {
            scan_evt.scan_evt_id = NRF_BLE_SCAN_EVT_FILTER_MATCH;
            nrf_ble_scan_connect_with_target(p_scan_ctx, p_adv_report);
        }
        else
        {
            scan_evt.scan_evt_id        = NRF_BLE_SCAN_EVT_NOT_FOUND;
            scan_evt.params.p_not_found = p_adv_report;
    
        }

    Most of our examples, such as the ble_app_uart_c doesn't use any of these events. Looking at this example, the scan_evt_handler() only checks for a few events:

    /**@brief Function for handling Scanning Module events.
     */
    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_CONNECTED:
             {
                  ble_gap_evt_connected_t const * p_connected =
                                   p_scan_evt->params.connected.p_connected;
                 // Scan is automatically stopped by the connection.
             } break;
    
             case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
             {
                 NRF_LOG_INFO("Scan timed out.");
                 scan_start();
             } break;
    
             default:
                 break;
        }
    }

    End neither of them are NRF_BLE_SCAN_EVT_NOT_FOUND nor NRF_BLE_SCAN_EVT_FILTER_MATCH. As you can see, the on_adv_report() function calls nrf_ble_scan_connect_with_target().

    So exactly what is not working sometimes? It doesn't connect? Are you sure that the device you are trying to connect to is advertising at that point in time?

    Best Regards,
    Edvin

Children
No Data
Related