MAC Address BLE scan filter not working

Hello all,

Currently I am developing a code in which a central (nRF52840) scans and reads adverisement packets from 2 beacons (no connection required). I decided to use an adress filter to limit the amount of advertisement data received; however, it seems that it is not working because:
1. I´m getting TONS of advertisement packets that don´t look similar to what I´m expecting.
2. The event NRF_BLE_SCAN_EVT_FILTER_MATCH is never triggered.

Below I´ll show you some key points of the code: 

Declarition of the target MAC address (AC:23:3F:A9:EF:E2)

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      = {0xE2, 0xEF, 0xA9, 0x3F, 0x23, 0xAC}
    //.addr      = {0x41, 0x8C, 0xFE, 0x05, 0x1C, 0x00}
};

Filters settings

static void scan_init(void)
{
    ret_code_t          err_code;
    nrf_ble_scan_init_t init_scan;

    //static char const test_periph_addr[] = {0xEA, 0xEF, 0xA9, 0x3F, 0x23, 0xAC};

    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);

    ble_uuid_t uuid =
    {
        .uuid = TARGET_UUID,
        .type = BLE_UUID_TYPE_VENDOR_BEGIN,
    };

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

    if (strlen(m_target_periph_name) != 0)
    {
        err_code = nrf_ble_scan_filter_set(&m_scan,
                                           SCAN_NAME_FILTER,
                                           m_target_periph_name);
        APP_ERROR_CHECK(err_code);
    }

    if (is_connect_per_addr)
    {
       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_ALL_FILTER,
                                           false);
    APP_ERROR_CHECK(err_code);
}


ADV_REPORT EVENT

static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
    ret_code_t            err_code;
    ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_ADV_REPORT:
            NRF_LOG_INFO("Advertisement report");
            //on_adv_report(&p_gap_evt->params.adv_report);

            //if( p_gap_evt->params.adv_report.direct_addr.addr == m_target_periph_addr.addr)
            //{    
            //    NRF_LOG_INFO("Found");
            //}

           
            uint8_t data_length = p_gap_evt->params.adv_report.data.len;
            NRF_LOG_INFO("Data length: %d", data_length);

            uint8_t i;

            for (i=0; i<=data_length; i++)
            {
                uint8_t data = p_gap_evt->params.adv_report.data.p_data[i];
                NRF_LOG_INFO("0x%02X", data);
            }

            break;

...


Thank you so much in advance

Parents Reply Children
  • Hello, 

    Yes, I am getting the  NRF_BLE_SCAN_EVT_NOT_FOUND event, exactly.

  • Hello,

    OK, can you log the addresses of the advertisment packets that are received when you get NRF_BLE_SCAN_EVT_NOT_FOUND and see if your device shows up or not?

    /**@brief Function for handling Scaning events.
     *
     * @param[in]   p_scan_evt   Scanning event.
     */
    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        ret_code_t err_code;
    
        ble_gap_addr_t const * peer_addr = &p_scan_evt->params.p_not_found->peer_addr;
    
        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("Filter match")
                break;
            case NRF_BLE_SCAN_EVT_NOT_FOUND:
                 NRF_LOG_INFO("Address type: 0x%x, \nAddress: ", peer_addr->addr_type); 
                 NRF_LOG_HEXDUMP_INFO(peer_addr->addr, sizeof(peer_addr->addr));
                
                break;
            default:
              break;
        }
    }

  • Hello,

    Yes, the address is shown. And the type is 0x2 that. as you said in the first place, is "private resolvable". 
    So I guess I will need to find another strategy to filter the advertisement packets. 

    Thank you


  • Hello,

    This doesn't quite add up. A private address is typically updated every 15 minutes to a completely different one, so you should have noticed by now if the address was not static.  The address was registered as a public address as well, further indicating that it's not really a private address.

    The advertiser should set the TxAdd bit in the advertisement packet to indicate that it is using a public address type, and it's not doing that since the Softdevice thinks it's private address (it's not possible to tell if it's a public address by looking at the MSBs like with the other address types)

    That said, the scanner module appears to only care about the address and simply ignore the type, so it's still not clear to me why you are not getting a filter match.

    Edit: The address type is actually set to public. They type is printed before the address, not after. I suggest you try to build my sample with a fresh copy of SDK 17.1.0 in case there is a chance the scanner module may have been modified in your current copy.

  • Hello,

    I have run the code in the newest SDK version and it won´t work. I am even printing the address the filter is set to and it is correct; however, the same address and type appears in the not found list,


    Thanks

Related