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

Combined scan filtering

Hi to everyone. I'm starting developing a bluetooth LE application based on the new Nordic SDK using Zephyr.

I currently have two nrf52_pca10040 boards and I'm trying to connect them using advertising scan filtering. I was able to connect them using filter by uuid and filter by name separately. However I don't understand why combined filtering doesn't work.

Here is the relevant code in my scanning init function:

	...
	
	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, SERVER_NAME);
	if (err)
	{
		printk("Scanning filters cannot be set\n");
		return;
	}
	
	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, uuid128);
	if (err)
	{
		printk("Scanning filters cannot be set\n");
		return;
	}

	//match_all parameters set to true it's not working for combined filtering
	err = bt_scan_filter_enable((BT_SCAN_NAME_FILTER | BT_SCAN_UUID_FILTER), true);
	if (err)
	{
		printk("Filters cannot be turned on\n");
		return;
	}
	
	...

As I have already said, I can connect the two boards using one of the following scan filter enable:
- err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, false);
- err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
- err = bt_scan_filter_enable((BT_SCAN_NAME_FILTER | BT_SCAN_UUID_FILTER), false);

However if I set the match_all parameter to true, connection can't be established because filters don't match.

This is the definition of the function:

/**@brief Function for enabling filtering.
 *
 * @details The filters can be combined with each other.
 *          For example, you can enable one filter or several filters.
 *          For example, (BT_SCAN_NAME_FILTER | BT_SCAN_UUID_FILTER)
 *          enables UUID and name filters.
 *
 * @param[in] mode Filter mode: @ref BT_SCAN_FILTER_MODE.
 * @param[in] match_all If this flag is set, all types of enabled filters
 *                      must be matched before generating
 *                      @ref BT_SCAN_EVT_FILTER_MATCH to the main
 *                      application. Otherwise, it is enough to
 *                      match one filter to trigger the filter match event.
 *
 * @return 0 If the operation was successful. Otherwise, a (negative) error
 *	     code is returned.
 *
 */
int bt_scan_filter_enable(u8_t mode, bool match_all);

In my project prj.conf file I am using the following keywords:

CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1
CONFIG_BT_SCAN_NAME_CNT=1

On the serial output of my client board scanning the advertising information from my server board I am receiving two callbacks on my scan_filter_no_match() function:

Filter not match. Address: fb:fc:06:b3:35:d2 (random) connectable: 1
Filter not match. Address: fb:fc:06:b3:35:d2 (random) connectable: 1

What am I missing?

  • Hi,

    I do not see that you are missing anything. It should work. I have not been able to test yet but will do so.

    Are you using an NCS release? If so, which?

  • Hi,

    I have not been able to reproduce this. Using the Bluetooth: Central UART sample as a reference with only the following modifications, it works as expected on my side when testing on an nRF52 DK.

    diff --git a/samples/bluetooth/central_uart/src/main.c b/samples/bluetooth/central_uart/src/main.c
    index fd3aca3e..01157785 100644
    --- a/samples/bluetooth/central_uart/src/main.c
    +++ b/samples/bluetooth/central_uart/src/main.c
    @@ -388,7 +388,13 @@ static int scan_init(void)
     		return err;
     	}
     
    -	err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
    +	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, "nRF Connect");
    +	if (err) {
    +		printk("Scanning filters cannot be set (err %d)\n", err);
    +		return err;
    +	}
    +
    +	err = bt_scan_filter_enable(BT_SCAN_UUID_FILTER | BT_SCAN_NAME_FILTER, true);
     	if (err) {
     		printk("Filters cannot be turned on (err %d)\n", err);
     		return err;
    

    diff --git a/samples/bluetooth/central_uart/prj.conf b/samples/bluetooth/central_uart/prj.conf
    index 455c2dea..98272edb 100644
    --- a/samples/bluetooth/central_uart/prj.conf
    +++ b/samples/bluetooth/central_uart/prj.conf
    @@ -23,6 +23,7 @@ CONFIG_BT_GATT_NUS_C=y
     CONFIG_BT_SCAN=y
     CONFIG_BT_SCAN_FILTER_ENABLE=y
     CONFIG_BT_SCAN_UUID_CNT=1
    +CONFIG_BT_SCAN_NAME_CNT=1
     CONFIG_BT_GATT_DM=y
     CONFIG_HEAP_MEM_POOL_SIZE=2048
     
    

    Log output:

    *** Booting Zephyr OS build v2.1.99-ncs1  ***
    Starting Bluetooth Central UART example
    I: 6 Sectors of 4096 bytes
    I: alloc wra: 0, fd8
    I: data wra: 0, 1c
    I: No ID address. App must call settings_load()
    Bluetooth initialized
    UART initialized
    Scan module initialized
    NUS Client module initialized
    Scanning successfully started
    Filters matched. Address: c6:a3:38:69:c3:45 (random) connectable: 1
    ...

  • If the UUID is in the scan response and not the advertising packet with the name then the match will fail; see this post for details get-device-name-from-filter-match-event

  • Thank you very much. That was the point!
    Filtering information must be on the advertising packet. Scan response information are not useful in the filtering procedure.

Related