Disabling a specific address filter

Hello everyone,

My name is Hamit and I'm seeking guidance on how to effectively manage scan filter match events.

I'm currently using address filters for several devices and I want to disable a specific address filter once the scan filter match event occurs for that particular device.

Is there a way to disable a specific address filter without having to disable all filters and then set the required ones again?

Thank you for your help.

Best regards, Hamit

Parents
  • Hi Hamit,

    Could you please let me know how you are setting things up? What is your SDK? Are you using a helper module such as the Scanning Module in the nRF5 SDK or the Scanning Module in the nRF Connect SDK (NCS)?

    The answer might depend on the exact solution you are using. I know of four filter methods for scanning, two in each of our SDK, and will answer about them. 

    For filtering with the two modules mentioned above, it seems that removal of specific filter is not possible.

    In the nRF5 SDK, filtering using sd_ble_gap_whitelist_set() also require a complete reset of the whitelist.

    However, for NCS's accept list API, it looks like you can remove specific address from the list with bt_le_filter_accept_list_remove().

    If you are using a different method, please let me know and I can investigate it.

    Hieu

  • Hello Hieu,

    Thank you for your response.

    I am currently using the scanning module within the nRF5 SDK, along with the softdevice s140.

    Please find below the scanning parameters I am currently implementing:

    static ble_gap_scan_params_t m_scan_param =                 /**< Scan parameters requested for scanning and connection. */
    {
        .active        = 0x01,
        .interval      = NRF_BLE_SCAN_SCAN_INTERVAL,
        .window        = NRF_BLE_SCAN_SCAN_WINDOW,
        .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
        .timeout       = NRF_BLE_SCAN_SCAN_DURATION,
        .scan_phys     = BLE_GAP_PHY_CODED,  // For Long Range, S=8, datarate 250k bits/s, througput not tested!!!
        .extended      = true,
    };

    setting up address filters:

    // LSB to MSB -- OR MSB bit 7 and 6 -- ex: 0x11000000
    const char targets[FILTERED_DEVICE_NUMBER][BLE_GAP_ADDR_LEN] = 
    {   {0x46,0x86,0xE3,0xD3,0x20,0xE9},  // Device 1
        {0x83,0x33,0xF2,0x71,0x71,0xF6},  // Device 2
        {0x7E,0xE8,0xC1,0x73,0x70,0xFD},  // Device 3
        {0xC3,0xCB,0x74,0xBD,0xF9,0xE6},  // Device 4
        {0xDD,0xC9,0x21,0xF3,0x1B,0xF0},  // Device 5
        {0xC6,0x97,0x47,0x0B,0x68,0xFA},  // Device 6
        {0x6D,0x78,0x5F,0x22,0x6E,0xC8},  // Device 7
        {0x52,0x95,0x30,0xF7,0xF1,0xF9},  // Device 8
        {0x2B,0xAD,0xA9,0xB1,0xFC,0xF7},  // Device 9
        {0xC0,0x74,0x42,0x45,0x07,0xF4},  // Device 10
        {0x77,0x3D,0xB9,0x68,0xC2,0xE0},  // Device 11
        {0xBB,0x06,0x75,0xF7,0xE4,0xC5},  // Device 12
        {0x58,0x2F,0x48,0x4C,0xA9,0xCC},  // Device 13
        {0xEB,0x8E,0x35,0xE4,0x31,0xEB},  // Device 14
        {0x9D,0x2D,0xD0,0x06,0x58,0xCD},  // Device 15
        {0x08,0x2D,0x99,0x4F,0x98,0xE1},  // Device 16
        {0x65,0x3C,0x13,0xDC,0x69,0xE9},  // Device 17
        {0xC8,0xE1,0x75,0xA2,0x82,0xD0},  // Device 18
        {0xB7,0x99,0xF4,0x9D,0x5D,0xC7},  // Device 19
        {0x0E,0xEF,0x7A,0x70,0xCF,0xE2},  // Device 20                                                                                               
    };
    
    /**@ Function for settings scan filters.
     */
    static void scan_filters_set(ble_gap_addr_t const target_periph)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, target_periph.addr);
        APP_ERROR_CHECK(err_code);
    }
    
    void scan_filter_enable( void )
    {
        ret_code_t err_code;
        err_code = nrf_ble_scan_filters_enable(&m_scan,NRF_BLE_SCAN_ADDR_FILTER,false);
        APP_ERROR_CHECK(err_code);
    }
    
    void scan_address_filter( void )
    {
        ble_gap_addr_t struct_addrs[FILTERED_DEVICE_NUMBER];
    
        for (int i = 0; i < FILTERED_DEVICE_NUMBER; i++) {
            struct_addrs[i].addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
            memcpy(struct_addrs[i].addr, targets[i], BLE_GAP_ADDR_LEN);
            scan_filters_set(struct_addrs[i]);
        }
    
        scan_filter_enable();
    
    }
    

    filter match interrupt.

            case NRF_BLE_SCAN_EVT_FILTER_MATCH:
            {  
                package_len = strlen(m_scan.scan_buffer_data)-7;
                filtered_adv_data = m_scan.scan_buffer.p_data;
    
                for(int i=1; i <= SENSOR_NUMBER; i++)
                {
                  sprintf(param, "$E&%d&", i);
                  if(strstr(m_scan.scan_buffer_data, param) != NULL)
                  {
                    memcpy(ADV_PACK_TMP[i-1], &m_scan.scan_buffer_data[7], package_len);
                    memset(&m_scan.scan_buffer_data,0,NRF_BLE_SCAN_BUFFER);
                    break;
                  }
                }
                  
            } break;

    I am capable of reading long-range extended advertisements from more than 20 sensors using the above method. However, I want to prevent payload loss. While the above method works, it is not very efficient, and we may experience some payload losses at times.

    Therefore, I am trying to disable the filter immediately after receiving the relevant data.

    Thank you again,

    Hamit

  • Hi Hamit,

    I am a little unclear if you still need support with this. If you meant the details as telling me what method you are using, then it looks like you are using the Scanning Module in the nRF5 SDK. With this method, unfortunately you cannot update the filters without completely clearing them first.

    Otherwise, just looking at the code without testing, your solution looks fine to me, and should filter so your device only report scan results from the 20 devices. When you mention "payload losses," do you mean payloads from outside of these 20 devices?

    Hieu

Reply
  • Hi Hamit,

    I am a little unclear if you still need support with this. If you meant the details as telling me what method you are using, then it looks like you are using the Scanning Module in the nRF5 SDK. With this method, unfortunately you cannot update the filters without completely clearing them first.

    Otherwise, just looking at the code without testing, your solution looks fine to me, and should filter so your device only report scan results from the 20 devices. When you mention "payload losses," do you mean payloads from outside of these 20 devices?

    Hieu

Children
  • Hi Hieu,

    Let me explain what I am trying to accomplish.

    I have a gateway and 20 sensors. The gateway acts as a receiver and scans long-range extended advertisers. The 20 sensors continuously send their data to the gateway with an advertising period of 62.5ms. Then, we aggregate all the data in the gateway in a 1-second period.

    Our expectation is to receive at least one data from each sensor during this 1-second period.

    when there is only one sensor and one gateway, everything works perfectly. When there are 20 sensors and one gateway, we lose approximately 50% of the data from each sensor.

    I suspect that the app cannot handle all the interrupts because the interrupt is disabled during the interrupt routine. (??)

    One possible solution could be to disable the scan filter of the related sensor after the data is received. So the scan filter match interrupt will not occcur again for that sensor.

    I hope I have explained myself clearly.

    I am wondering what the best approach would be for such an application.

    Regards,

    Hamit

  • Hi Hamit,

    I see. I understand your motivation now.

    hamit said:
    I suspect that the app cannot handle all the interrupts because the interrupt is disabled during the interrupt routine. (??)

    It has been a while since I deal with overlapping SoftDevice events. If I recall correctly, they should queue up and nothing is lost. I am not 100% sure, I will need to double check with someone once the Easter holiday is over.

    I think a likely issue is the advertisements from your 20 devices actually physically collide, which causes the loss you observe.

    Do you think you can setup a simple test where the device just rapidly prints out the address of devices it scanned, and from that see if the data is any better. If it is not better, then updating the filter likely will not help.

    Please also be informed that it is the Easter holiday this week, so DevZone responses can be delayed. I will also be out of office from tomorrow and will return next week to continue supporting you. My apology for the inconvenience.

    Regards,

    Hieu 

Related