How to access all advertisement data in scan filter match callback?

I'm using nRF Connect v2.0.2 and running in Zephyr.

When scanning by filtering for UUID, I find the matching devices, and the scan filter match callback gets called.  However, when I try to parse the advertising data, I can only see one type.

Example: If I filter on UUID, the advertising data parse only contains UUID type

BT_SCAN_CB_INIT(scan_cbhs, scan_filter_match, NULL, NULL, NULL);

start_scanning_function()
{
    struct bt_scan_init_param scan_init = {
		.connect_if_match = 0,
		.scan_param = BT_LE_SCAN_ACTIVE,   // can this be passive?
		.conn_param = BT_LE_CONN_PARAM_DEFAULT
	};

	bt_scan_init(&scan_init);
	bt_scan_cb_register(&scan_cbhs);

    bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_DECLARE_128(BLE_UUID128_ENCODE(K_BLE_UUID_FILTER_VAL)));

	bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
   
    bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
}

static void scan_filter_match(struct bt_scan_device_info *device_info,
			      struct bt_scan_filter_match *filter_match,
			      bool connectable)
{
    bt_data_parse(device_info->adv_data, find_adv_data, NULL);
}

bool find_adv_data(struct bt_data *data, void *user_data)
{
    printk("Data type is %u \n", data->type);
    
    return true; // keep parsing
}

In the code example above, the only print is
Parse type 7
which is I think is BT_DATA_UUID128_ALL, but not other calls to the parser callback

Similarly if I filter on device name instead of UUID, then I only get
Parse type 1
which I think is BT_DATA_FLAGS and that's it.

If I scan and filter based on UUID, how do I access the advertised device name, manufacturer data, or other data from the device's advertisement?

Thanks

  • Hi Walt,

    Thanks for the clarification. The reason I used the name filter was to ensure the scan_filter_match() callback would be invoked for both the advertisement and scan response packet, but I realize now that it will not work for you.

    Just for reference, this is the data I had in my advertisement and scan response packet:

    From what I can tell by looking at the code, it will not be trivial to support your use case with our current implementation of the Scanning module. The only solution I can think of is to use the scan_filter_match() callback for parsing the packet with the UUID and scan_filter_no_match() for the one not containing the UUID. But this will require your application to keep track of the advertising addresses to know what packets to parse in scan_filter_no_match(). 

    Another alternative may be to have the app handle the filtering from the scan_filter_no_match() callback (i.e. not enable the scanner module filters.

    I can try to make a basic proof-of-concept of what I had in mind if it helps? 

    Best regards,

    Vidar

  • Vidar,

    Thanks for your timely responses.  It looks like we have an answer, though it may not be the one we expected, which is that on a scan filter match it is not possible to see the full contents of the advertising message.

    We have already been looking at just using the scan_filter_no_match() and doing the matching manually so the other advertisement fields can be inspected.  Based on your response, we'll move forward with that approach.  We appreciate your offer, but don't need a concept example.

    Regards,

    Walt

  • Hey man thanks for asking the question. Npw to clear this theory,is that how do you extract the data into the scan_filter_no_match()

Related