Scan filtering with address

Dear all,

I'm new to BLE development and have as many others encountered some challenges when trying to scan for a peripheral device using the address filter in the scanning module.

When using the UUID filter and/or name filter there's no problem to find and connect to the peripheral device. 

When connected to the peripheral device a print out, in our test software, of the connected device address will be made and has the format of:

AA:BB:CC:DD:DD:EE.

As I have understood it should a BLE adress contains 6 bytes of the actual address and also 1 byte  which contains the adress type (public, random etc etc.)

  • This sums up to my first question, how should the input format be when adding the filter with the bt_scan_filter_add -function? (must the input data be of the type "bt_addr_le_t" ?)

If I then apply one of the working filters (naming filter for instance) and disables the ".connect_if_match" option I will be able to see a filter match by printing data in the callback function "

scan_filter_match". If I then print the adress type and adress array for the device matching the filter i will be given the following information:
addr->type:01
addr->a.val[0] = DD  
addr->a.val[1] = DD
addr->a.val[2] = CC
-       "       - [3] = BB
-       "       - [4] = AA
-       "       - [5] =  FF
Which sums up to the conclusion that my peripheral device currently is advertising with a random address of DD:DD:CC:BB:AA:FF. 
The adress sticks the same after reboot.
So to my question, how come I get one address when connected to the device(AA:BB:CC:DD:DD:EE) and another during advertising (DD:DD:CC:BB:AA:FF) ?
I also tried the advertising option "BT_LE_ADV_NCONN_IDENTITY" for the peripherial device but could not see any change in the data recived in the scan_filter_match function.
Kind regards,
Max
Parents
  • Found a solution to my issue,

    I was calling the incorrect function (bt_addr_to_str instead of bt_addr_le_to_str after connecting to perephiral) hence a deviation between the addresses.

    Also must the input type pointer to the bt_scan_filter_add be of type "bt_addr_le_t" when using the filter type "BT_SCAN_FILTER_TYPE_ADDR".

    I do, however, have another question;

    I would like the central unit to first scan for a generic name filter in order to list all mac-addresses (of the peripherals) which matches this filter but I don't want an automatic connection. Then I would like the central unit to apply one filter with a specific mac-address in order to connect to only one of the matching units.

    I'm trying this procedure and I do manage to get a filter match with only one mac address after first listing all devices matching the generic name filter. But the central unit is not connecting to the chosen peripheral. 

    For the first scanning i'm calling the scan_init function where I set the ".connect_if_match" to false, when changing the filter to an address-filter I'm first calling the scan_init function a second time and setting the ".connect_if_match" to true. Is this possible scenario or is it only possible to set the "bt_scan_init_param" one time?

    Kind regards,

Reply
  • Found a solution to my issue,

    I was calling the incorrect function (bt_addr_to_str instead of bt_addr_le_to_str after connecting to perephiral) hence a deviation between the addresses.

    Also must the input type pointer to the bt_scan_filter_add be of type "bt_addr_le_t" when using the filter type "BT_SCAN_FILTER_TYPE_ADDR".

    I do, however, have another question;

    I would like the central unit to first scan for a generic name filter in order to list all mac-addresses (of the peripherals) which matches this filter but I don't want an automatic connection. Then I would like the central unit to apply one filter with a specific mac-address in order to connect to only one of the matching units.

    I'm trying this procedure and I do manage to get a filter match with only one mac address after first listing all devices matching the generic name filter. But the central unit is not connecting to the chosen peripheral. 

    For the first scanning i'm calling the scan_init function where I set the ".connect_if_match" to false, when changing the filter to an address-filter I'm first calling the scan_init function a second time and setting the ".connect_if_match" to true. Is this possible scenario or is it only possible to set the "bt_scan_init_param" one time?

    Kind regards,

Children
  • You would have to reinitialize the scanner module with connect_if_match set. 

    Other was is to directly edit the structure defined in NRF_BLE_SCAN_DEF(X) to change its X->connect_if_match = true when you need it.

  • Thank you for you answer. Didn't really get your proposal to work.

    However I'm trying another apporach where the "connect_if_match" always is set to true and instead applying different name filters instead of an address filter.

    In order to separate between different units (peripherals) i want to use a similar name string for my units in the advertise data and scan filter which will have the format of some characters and two digits ex. "Filter01", "Filter02", "Filter03" etc. etc.

    I have a function in my central unit according to the code below in order to change between different filters and in that way connect to different peripherals:

    void update_filter(char filter_number[3]){
    	int err;
    	char connect_string[] = {'F', 'i', 'l', 't', 'e', 'r', filter_number[0], filter_number[1], 0 };
    	
    	printk("changing filter to %s \r\n", connect_string);
    	bt_scan_filter_remove_all();
    	bt_scan_filter_disable();
    	
    	
    	err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, connect_string);
    	if (err) {
    		printk("error adding filter %d \r\n", err);
    		LOG_ERR("Scanning filters cannot be set (err %d)", err);
    		return err;
    	}
    
    	err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, true);
    	if (err) {
    		printk("error enabling filter \r\n");
    		LOG_ERR("Filters cannot be turned on (err %d)", err);
    		return err;
    	}
    
    }

    Though when applying the filter it doesn't seem that a complete string match is needed in order to trigger a filter match. When applying a filter according to the code above (the scan_init functions has already been initialized) my central unit can connect to any random bluetooth unit in my office.

    I do not get any error message so I assume that the filter is properly added and enabled.

    Do I need to format my name filter in any certain way or doesn't a name filter require a complete match of the filter string in order to trigger a filter match?

    Kind regards,

  • Hi, I have been sick for few days and did not get time to test this. I do not know that format of the scan filter over the top of my head but I will try to test your code snippet this week when I am back to office. Sorry for the delays so far and thanks a lot of your patience.

  • Hello,

    Did some more investigations on my own and found out that, if you are using a name filter when scanning (using SDK 2.0.2) it will be up to the peripheral to decide on how many characthers to match in the filter.

    I.e. if the central device has a filter named "Filter01" and a perihperal device is advertising with the name "F" this will be considered as a filter match.

    I will instead use the ShortName filter since then the central device will control that the advertising name is fulfilling the "min_len" specified in the data type "bt_scan_short_name".

    kind regards,

Related