The NRF52840 can not filter by MAC Address other BLE devices that are from other manufacturers.

Hi all!

I am working in a BLE scanner but I have enabled the filter by MAC ADDRESS.  I can filter  beacons that are produced  based in NRF52 and NRF51. But when i try set a MAC ADDRESS of a SOC produced by other company  the filter no match.

wich could be the problem?

Parents
  • Hi eudaldo!

    That should not happen at all. May I ask how you set up the other company device? Are you certain it is advertising? Can you see it on your phone, for example, with the nRF Connect app?

    Best regards,

    Hieu

  • I store the MAC ADDRESS in array of char, I put them in reverse (LSB  --> MSB) attach an example:

    char target_device[][6] = {
    {0x96, 0xEA, 0x57, 0x6E, 0x91, 0xDF},
    {0x13, 0x48, 0x35, 0x79, 0xBE, 0xEB},
    {0x68, 0xDA, 0xFC, 0x71, 0x77, 0x60},
    {0xBF, 0x92, 0xD9, 0x70, 0xAF, 0xFD},
    {0x8C, 0x4B, 0x7A, 0xD6, 0xAB, 0xFE},
    {0x0E, 0x2B, 0xE6, 0x5A, 0xA8, 0xE7},
    {0xC3, 0x6B, 0xD2, 0x56, 0x79, 0xEB}
    };

    I have try put the MAC ADDRESS in the normal form (MSB--->LSB), but it does not work.

    For set the filter I use the following code:

     //Setting filters for scanning.
    
    
        int rows =  sizeof (target_device) / 6;
    
        for (int t=0 ; t<rows; t++)
        {
              char td[] = { target_device[t][0],target_device[t][1]  ,target_device[t][2]  ,target_device[t][3] ,target_device[t][4]  ,target_device[t][5]};
              
              err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, td);
              
              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);

    I attach the devices that I want to scan:

  • Not sure I understood this correctly, but I don't see the addresses of the beacons in your filter list?

  • i do not place them, It is only a example of how I Set the ADDRESS filters. But, If I code the ADDRESS of the two beacons from the  images in the same formant, they does not work.

Reply Children
  • I just replicated your setup on my end, and it works just fine. I can see both my nRF52 DK and my headset, which most probably doesn't use a Nordic chip.

    One possibility is that the other devices are advertising with random addresses, which could change between when you recorded it into your filter code and when you run the test.

    If you force the advertising address of the nRF52 and nRF51 into one of the non-Nordic addresses you are expecting, does the filter work?

    If all fails, could you please get us a sniffer trace? We can try to see what is wrong.

  • One possibility is that the other devices are advertising with random addresses, which could change between when you recorded it into your filter code and when you run the test.

    The addresses of the devices are always the same, at least, in Nordic Connect  app.

    If you force the advertising address of the nRF52 and nRF51 into one of the non-Nordic addresses you are expecting, does the filter work?

    If I set a custom ADDRESS (one that I created) into nordic device, the filters work.

    I has been test other devices and I could filter a ble device from other company (Texas Instrument), but when I try set other filter of a diferent TI device, I can not filtered :(  for example:

    I have three beacons (attach photo and the information that NRF connect provide me):

    Beacon 1 (Nordic SOC):

    Beacon 2 (Texas Instrument):

    Beacon 3 (Texas Instrument):

    The beacon1 and the beacon 2 I could filtered with out problems, but the Beacon 3 I could not filtered and the filters are set  with the same metodh:

    store the ADDRESS in a array:

    char target_device[][6] = {
    {0x96, 0xEA, 0x57, 0x6E, 0x91, 0xDF},
    {0xEE, 0xA2, 0x65, 0xED, 0x04, 0x18},
    {0x68, 0xDA, 0xFC, 0x71, 0x77, 0x60}
    };

    set and enable the filters:

    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;
        init_scan.p_scan_param     = &m_scan_param;
    
        
    
        err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        //Setting filters for scanning.
    
    
        int rows =  sizeof (target_device) / 6;
    
        for (int t=0 ; t<rows; t++)
        {
              char td[] = { target_device[t][0],target_device[t][1]  ,target_device[t][2]  ,target_device[t][3] ,target_device[t][4]  ,target_device[t][5]};
              err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, td);
              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);
     
    }
    

    Enabling filters for the Scanning Module:

    // <e> NRF_BLE_SCAN_FILTER_ENABLE - Enabling filters for the Scanning Module.
    //==========================================================
    #ifndef NRF_BLE_SCAN_FILTER_ENABLE
    #define NRF_BLE_SCAN_FILTER_ENABLE 1
    #endif
    // <o> NRF_BLE_SCAN_UUID_CNT - Number of filters for UUIDs. 
    #ifndef NRF_BLE_SCAN_UUID_CNT
    #define NRF_BLE_SCAN_UUID_CNT 0
    #endif
    
    // <o> NRF_BLE_SCAN_NAME_CNT - Number of name filters. 
    #ifndef NRF_BLE_SCAN_NAME_CNT
    #define NRF_BLE_SCAN_NAME_CNT 0
    #endif
    
    // <o> NRF_BLE_SCAN_SHORT_NAME_CNT - Number of short name filters. 
    #ifndef NRF_BLE_SCAN_SHORT_NAME_CNT
    #define NRF_BLE_SCAN_SHORT_NAME_CNT 0
    #endif
    
    // <o> NRF_BLE_SCAN_ADDRESS_CNT - Number of address filters. 
    #ifndef NRF_BLE_SCAN_ADDRESS_CNT
    #define NRF_BLE_SCAN_ADDRESS_CNT 20
    #endif
    
    // <o> NRF_BLE_SCAN_APPEARANCE_CNT - Number of appearance filters. 
    #ifndef NRF_BLE_SCAN_APPEARANCE_CNT
    #define NRF_BLE_SCAN_APPEARANCE_CNT 0
    #endif

    but only the beacon 1 and beacons 2 trigger the NRF_BLE_SCAN_EVT_FILTER_MATCH. However, the beacons 3 I can see it int he NRF_BLE_SCAN_EVT_NOT_FOUND, with the same ADDRESS (but flip) that I set in the filter

    any idea what is the problem with beacon 3?

    Eudaldo

  • I think the address being flipped is just some not-obvious problem in extracting the data. In any cases, NRF_BLE_SCAN_EVT_NOT_FOUND means that the application never sees that beacon at all.

    I notice in the nRF Connect App screenshot, the beacon dBm and interval data is greyed out, indicating that the app hasn't seen it in a bit of time. That is typical for devices with long advertising interval, such as your Beacon 3 (~10ms).

    However, it could be that the scanning timeout'd before it sees Beacon 3. Or the timeout might seems enough for 2-3 advertising interval, but the scanner still could (very) unfortunately miss the packets.
    How do you setup the scan itself, as in how do your scanning init and start function calls look like?

    Can you try setting the timeout to unlimited and let the app run for a while?

    Also, if you could share how you extract the addresses out of the events, I can look into why addresses are flipped/not flipped.

  • I think the address being flipped is just some not-obvious problem in extracting the data. In any cases, NRF_BLE_SCAN_EVT_NOT_FOUND means that the application never sees that beacon at all.
    Also, if you could share how you extract the addresses out of the events, I can look into why addresses are flipped/not flipped.

    I misspoke, in the handler function scan_evt_handler I print via UART the MAC ADDRESS of the device, both  NRF_BLE_SCAN_EVT_NOT_FOUND and NRF_BLE_SCAN_EVT_FILTER_MATCH, but when I print them,  I flip them :

    static void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        ret_code_t err_code;
        char data_hex[10];
        char len[10];
        
    
        switch(p_scan_evt->scan_evt_id)
        {
    
            case NRF_BLE_SCAN_EVT_NOT_FOUND:           
    
    
                    unsigned char* addr       =  p_scan_evt->params.p_not_found->peer_addr.addr;      
                    
                   
    
                    uart_putstring("NFND:");
    
                    for (int a=5; a>=0; a--)
                    {
                      sprintf(data_hex,"%02x", addr[a] );
                      uart_putstring(data_hex);
                        
                    }
    
                    uart_putstring("\r\n");
                    
                }
                
    
            break;
    
    
    
            //  FILTER MATCH
            case NRF_BLE_SCAN_EVT_FILTER_MATCH:
    
                  
    
                 uint8_t *addr =  p_scan_evt->params.filter_match.p_adv_report->peer_addr.addr;      
                 
                    uart_putstring("ADDR:");
    
                    for (int a=5; a>=0; a--)
                    {
                      sprintf(data_hex,"%02x",addr[a] );
                      uart_putstring(data_hex);
                       
                    }
                    
                    uart_putstring("\r\n");
                    
                 
               break;
    
    
            
            default:
            break;
    
        }
    }

    the results are the follow (an example):

    NFND:1804ED65A2EE   //Not found
    ADDR:DF916E57EA97   //Filter match
    ADDR:607771FCDA68   //Filter match

    However, it could be that the scanning timeout'd before it sees Beacon 3. Or the timeout might seems enough for 2-3 advertising interval, but the scanner still could (very) unfortunately miss the packets.
    How do you setup the scan itself, as in how do your scanning init and start function calls look like?

    these are my functions:

    scan_params:

    #define SCAN_INTERVAL                   0x00A0                              /**< Determines scan interval in units of 0.625 millisecond. */
    #define SCAN_WINDOW                     0x009f                              /**< Determines scan window in units of 0.625 millisecond. */
    #define SCAN_DURATION                   0x0000                              /**< Timout when scanning. 0x0000 disables timeout. */
    
    #define MIN_CONNECTION_INTERVAL         MSEC_TO_UNITS(7.5, UNIT_1_25_MS)    /**< Determines minimum connection interval in milliseconds. */
    #define MAX_CONNECTION_INTERVAL         MSEC_TO_UNITS(30, UNIT_1_25_MS)     /**< Determines maximum connection interval in milliseconds. */
    #define SLAVE_LATENCY                   0                                   /**< Determines slave latency in terms of connection events. */
    #define SUPERVISION_TIMEOUT             MSEC_TO_UNITS(4000, UNIT_10_MS)     /**< Determines supervision time-out in units of 10 milliseconds. */
    
    #define APP_BLE_CONN_CFG_TAG            1                                   /**< A tag identifying the SoftDevice BLE configuration. */
    #define APP_BLE_OBSERVER_PRIO           3 
    
    
    
    static ble_gap_scan_params_t const m_scan_param =
    	{
    		.active        = 0x00,
    		.interval      = SCAN_INTERVAL,
    		.window        = SCAN_WINDOW,
    		.filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
    		.timeout       = SCAN_DURATION,
    		.scan_phys     = BLE_GAP_PHY_AUTO,
    		.extended      = false,
    	};

    scan_init  (in my previous comment , I write about it and the variables):

    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;
        init_scan.p_scan_param     = &m_scan_param;
    
        
    
        err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        //Setting filters for scanning.
    
    
        int rows =  sizeof (target_device) / 6;
    
        for (int t=0 ; t<rows; t++)
        {
              char td[] = { target_device[t][0],target_device[t][1]  ,target_device[t][2]  ,target_device[t][3] ,target_device[t][4]  ,target_device[t][5]};
              err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, td);
              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);
     
    }

    scan start:

    static void scan_start(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_scan_params_set(&m_scan, &m_scan_param);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_scan_start(&m_scan);
        APP_ERROR_CHECK(err_code);
    
        //USE LED TO INDICATE THE STATUS BLE AS SCANNER  <------
    }

    Can you try setting the timeout to unlimited and let the app run for a while?

    The scanning timeout already disable

  • I don't see anything wrong here. It really could just be that the nRF chip doesn't see beacon 3 at all...

    As a final test, could you reconfigure the scan module to print all BLE addresses it see without any filtering, and let it run for 1~2 minute?

    If beacon 3 still won't show up in that, perhaps we need to look at a sniffer trace

Related