How to access scan response packets on a central device at either scan match or connection time?

Hello!

I am working with a BLE central device running on an nrf52832 using the S132 softdevice and sdk version 15.2.0

I need to pull the full device name out of the scan response packet sent by a peripheral and store a link between the device name and its corresponding connection handle.

I understand that I should be able to see scan response packets in the BLE_GAP_EVT_ADV_REPORT event, but there are a few issues with that approach

1) I am actually never getting a scan response packet for the device I am working with. I know that the device name IS sent in a scan response packet - I can see it in NRF CONNECT, but I never seem to actually get the packet. I DO have active scanning enabled in my scan params. and I do see scan responses for other devices.

2) Even if I got a scan response packet there, linking that packet to a connection would be difficult. The only way that I see to do it would be to cache them in a buffer and then check through them at connection time. That seems like a waste of ram and processor time since most of the scan response packets would be from stray devices I am uninterested in.

What I really need is access to the scan response packet at either in the event or in the NRF_BLE_SCAN_EVT_FILTER_MATCH event.

In the BLE_GAP_EVT_CONNECTED  event, it looks like the data would be there (in p_gap_evt->params.connected.adv_data) but on further inspection, that data only gets populated for perhipheral devices - not for centrals. 

if the NRF_BLE_SCAN_EVT_FILTER_MATCH  event I can get the normal advertising packet, but not the scan response packet.

I also saw the NRF_BLE_SCAN_EVT_CONNECTED event, but like the BLE_GAP_EVT_CONNECTED  event, the scan response packet is only populated there for peripherals.

This seems like the sort of thing that people must do all the time, am I missing something obvious here?

Is it possible that the the adv report that is available in the NRF_BLE_SCAN_EVT_FILTER_MATCH event DOES normally include scan response data, but that it is not showing up for me just because my peripheral is not actually sending a scan response pack?

Is it possible that the central is not requesting a scan response packet because it is getting a scan filter match without needing to?

am I missing some important piece of information on how active scanning is supposed to work?

thanks in advance,

Justin

Parents
  • I did a few tests using a BLE sniffer, and I think I can reduce the number of questions that I am asking - sorry about that.

    I should also mention that I am scanning for this device based on the service UUID, which is contained in the main advertising packet, not the scan response packet.

    In the sniffer, I can see that my central device IS sending a scan request, but before the peripheral can send a response, the central detects a scan filter match and it sends a connection request to the peripheral. It seems that the peripheral gives up on sending the scan response and instead deals with the connection request.

    If I scan for the peripheral by name rather than by UUID, things are different. the central sends the scan request and the peripheral sends the scan response. When I get the NRF_BLE_SCAN_EVT_FILTER_MATCH event, the advertising packet loaded into the event is actually the scan response packet, not the original advertising packet.

    SO

    Is it possible that the the adv report that is available in the NRF_BLE_SCAN_EVT_FILTER_MATCH event DOES normally include scan response data, but that it is not showing up for me just because my peripheral is not actually sending a scan response pack?

    Not exactly. The data sent along with the NRF_BLE_SCAN_EVT_FILTER_MATCH does not include the data from both the advertising packet and the scan response packet, it contains the data from whichever part of the packet resulted in a scan match.

    Is it possible that the central is not requesting a scan response packet because it is getting a scan filter match without needing to?

    Not exactly. The Central is requesting the scan response packet, but the connection request that we are sending in the filter match handler IS preventing the peripheral from sending a response.

    In practice, I cannot scan for this device based on the device name. For one thing, the device names are not consisted - the manufacturers put an ID number at the end of it. For another thing, the central device also supports similar devices from different manufacturers. They all have different names, but the all support the same service, so scanning by the service would be preferable to scanning by ALL the different device names.

    That leaves me with a clearer version of my original question:

    How can I get the information that I need from the scan response packet and link it to my connection handle?

    Clearly I need to wait to send my connection request until after I have received the packet, but that still leaves me with the problem of linking the packet to my pending connection.

  • Hello,

    I understand. Could the reason why you never see your periperal's scan response be that you are always trying to connect when you receive the initial advertising packet? If that is the case, it will never search for the scan response.

    I understand your statement about this must be a case all the time, but I don't think the advertising names are as much used as you would think. If you think about it, advertising names are great because they are human readable, but for an application scanning and connecting without human interaction, ascii characters are a lot of wasted data. 

    So you should think about whether you actually need the advertising name in your advertising data, or perhaps the data that you are already using to determine to connect after the initial advertising packet is enough? Perhaps you could add some ID consisting of a small handful of bytes, instead of a long advertising name that requires an additional advertising packet?

    If, however, you do need the advertising packet, please make sure that you don't try to connect to the device before you have received the advertising name. And please keep in mind that the connected event doesn't contain any of the advertising data at all. All it contains is the BLE address. Even, after this, your BLE events coming from a connected device doesn't even contain the address. Only the connection handle that was assigned in the connected event.

    The only way that I see to do it would be to cache them in a buffer and then check through them at connection time. That seems like a waste of ram and processor time since most of the scan response packets would be from stray devices I am uninterested in.

    Well, that depends on your connection. And if the scan reponse data for all devices was actually stored by the stack, then it would also be a waste of ram and processor times. The reason the events doesn't contain the advertising packet data is that it is stored, and it is not present in the event.

    If you want to keep track of advertising names, that in your case is coming from the scan response packet, you need to set up a system to store them. I would recommend that you create a table containing BLE addresses, and the advertising name. Then, only store the advertising names from devices that are interesting for you. So only if the content from the initial advertising packet is relevant, store the address. Then, if you later receive an advertising scan response from a device with it's address in your table, then add the advertising name to the table as well. This way, you will only use space for relevant devices. Then make sure to only try to connect after you have buffered the name from the scan response.

    And after writing that, I see your last reply. Sorry for that. 

    jrowe said:
    Not exactly. The data sent along with the NRF_BLE_SCAN_EVT_FILTER_MATCH does not include the data from both the advertising packet and the scan response packet, it contains the data from whichever part of the packet resulted in a scan match.

    That is correct. Every on_adv event only contains data from the current advertising. (If not it would have to buffer all advertising data for all devices, just in case they have a scan response packet. Then we would be talking about wasting RAM). 

    jrowe said:
    Not exactly. The Central is requesting the scan response packet, but the connection request that we are sending in the filter match handler IS preventing the peripheral from sending a response.

    Not directly stopping it from sending a response, but the scan response event is getting lost in the connection attempt. 

    It seems that you think you need to use the preexisting filters. You can add the BLE_GAP_EVT_ADV_REPORT event to your ble_evt_handler() in main.c, and you can look at the packets just as you like. So you can check the addresses to see if it has matched the UUID previously, and you can look up the UUID either manually (just print the advertising packet and check whether the UUID is in the byte number that you know it will be), or you can use adv_uuid_compare(), as it is done in nrf_ble_scan.c.

    Give it a go, and let me know if anything was unclear, or if you are stuck.

    BR,
    Edvin

  • Thanks for the information and the advice Edvin, after trying a few options out, in this case I found that it was a little more performant in terms of scanning and connecting quickly to get the information that I needed from the generic access service immediately after discovery than to fight to get the information before the connection.

    If I did absolutely need the information before connecting though, it's clear to be that your suggestion of implementing an alternate scanning system in the BLE_GAP_EVT_ADV_REPORT event handler.

Reply
  • Thanks for the information and the advice Edvin, after trying a few options out, in this case I found that it was a little more performant in terms of scanning and connecting quickly to get the information that I needed from the generic access service immediately after discovery than to fight to get the information before the connection.

    If I did absolutely need the information before connecting though, it's clear to be that your suggestion of implementing an alternate scanning system in the BLE_GAP_EVT_ADV_REPORT event handler.

Children
No Data
Related