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

nRF52840 BLE Central - Not receiving some advertising packets

A few things to preface:

Hardware: nRF52840 Development Kit (PCA10056 - 2.0.1 - 2020.11)

Nordic SDK: nRF5_SDK_17.0.0_9d13099

Central example project I am using: nRF5_SDK_17.0.0_9d13099\examples\ble_central\ble_app_uart_c\pca10056\s140

Ble peripheral device I am trying to communicate with: BLE pressure sensor that sends sensor data as part of it's advertising report.

Hello,

In summary, I am trying to read sensor data from a BLE peripheral device that transmits it's sensor data in advertising packets. I am not trying to establish a connection with the device.

From what I have read online, I have configured the scanner in the following manner:

static ble_gap_scan_params_t scanParams =
{
   .extended = 1,
   .report_incomplete_evts = 0, 
   .active   = 1,
   .filter_policy       = BLE_GAP_SCAN_FP_ACCEPT_ALL,
   .scan_phys           = BLE_GAP_PHY_1MBPS,
   .interval            = NRF_BLE_SCAN_SCAN_INTERVAL,
   .window              = NRF_BLE_SCAN_SCAN_WINDOW,
   .timeout             = NRF_BLE_SCAN_SCAN_DURATION,
   .channel_mask        = {0,0,0,0,0},
};

/**
* Initializes the scanning parameters.
*/
void scanningInit(void)
{
   ret_code_t          errCode;
   nrf_ble_scan_init_t initScan;
   

   memset(&initScan, 0, sizeof(initScan));

   initScan.connect_if_match = false; // Don't connect on filter match. Only report advertising data
   initScan.conn_cfg_tag     = BleManagerNrf5::APP_BLE_CONN_CFG_TAG;

   // Enable extended advertisement scanning
   initScan.p_scan_param = &scanParams;

   errCode = nrf_ble_scan_init(&mScanning, &initScan, bleScanEventHandler);
   APP_ERROR_CHECK(errCode);
}

I have verified my peripheral device is advertising by using nRFConnect for desktop and the nRF52840 USB dongle to scan as seen below. The data I am interested in is the ServiceData as highlighted in red.

I also captured this data using Wireshark and the provided Nordic BLE sniffer firmware. The ServiceData can be seen in the lower red box below. Also note that there are "60 bytes on wire" which I will get to in a second.

The service data as indicated in the BLE peripheral sensor datasheet is the following format:

So the advertising data I am looking for is 0x0302FF180F16FF188B0000B116647F3897F98100

Where:

0302FF18 = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE (Length 3 bytes)

0F16FF188B0000B116647F3897F98100 = BLE_GAP_AD_TYPE_SERVICE_DATA (Length 15 bytes)

Lastly, this is how I am trying to find this service data in the nRF52840 firmware.

switch (pBleEvt->header.evt_id)
{
  case BLE_GAP_EVT_ADV_REPORT:
  {
     DEBUG_BLE("Advertising report received");
     
     // Initialize advertisement report for parsing.
     ble_data_t bleData = pBleEvt->evt.gap_evt.params.adv_report.data;
     u8 * p_encoded_data = bleData.p_data;
     u16 data_len = bleData.len;
     
     p_encoded_data = bleData.p_data;
     data_len = bleData.len;
     uint16_t data_offset = 0;
     uint16_t parsed_name_len = ble_advdata_search(p_encoded_data,
                                  data_len,
                                  &data_offset,
                                  BLE_GAP_AD_TYPE_SERVICE_DATA);
                                  
     if(parsed_name_len)
     {
        DEBUG_BLE("Service data found, length = %d", parsed_name_len);
     }
     break;
  }
}

I get service data for other BLE devices in my area in the firmware, just not for the BLE pressure sensor I am looking for even though I can see it fine in nRFConnect for desktop.

Note: I can use the ble_advdata_search() function to scan for BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME and I get a packet with the correct local name, but the ServiceData and other information is missing.

Questions:

1. Is there something obvious I am doing wrong based on the above?

2. Wireshark says the advertising packet is 60 bytes. Does this mean that it's actually 60 bytes or is this Wireshark combining the advertising data into a single packet for viewing purposes? I thought the advertising packet length was limited to 31 bytes if not using advertising extension?

3. I tried enabling support for advertising extensions as seen above in the "scanParams" structure. I also set NRF_BLE_SCAN_BUFFER to 255 in sdk_config.h. Same results.

4. If Wireshark is capable of capturing and organizing all of the received advertising data into a single structure, can the Nordic SDK / SoftDevice API do this? From what I have seen, the SoftDevice is piecemealing parts of the advertising data to the BLE callback via BLE_GAP_EVT_ADV_REPORT instead of passing up the full data payload that includes everything (Local Name, ServiceData, Flags, Etc).

5. Are scan requests sent by the central for every advertising packet received?

Thanks!

Derek

Parents
  • Hello,

    1: Let me get back to that.

    2: The 60 bytes refers to the entire frame received by wireshark, which includes the serial data from the sniffer (advertising address and more). The advertising data is maximum 31 bytes. The nRF Sniffer does not combine the advertisement and scan response. 

    3: -

    4: it doesn't do that.

    5: not necessarily, but every received scan response will result in it's own advertising report. 

    Have you tried to just print the entire advertisement in the advertising report? Do you see the data that you are looking for? I am not sure whether the issue is that the advertising data is not present in the packet that you are checking, or whether there is something wrong with the way you parce the advertising packet. 

    Best regards,

    Edvin

  • Hey Edvin,

    Thanks for your response. I have a few updates so you don't waste time investigating something I figured out:

    Updates:

    I now receive the expected ServiceData advertisement packet, it's just very infrequent. Sometimes 2 minutes between receiving these packets. I had to set my scan interval == scan window to eventually see these.

    These are the two packets I am seeing in the BLE_GAP_EVT_ADV_REPORT event for the BLE peripheral device I am interested in.

    1. Local Name (Device ID)

    15 09 38 38 39 31 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME
    02 0A 00 - BLE_GAP_AD_TYPE_TX_POWER_LEVEL

    2. ServiceData

    02 01 06 - BLE_GAP_AD_TYPE_FLAGS
    03 02 FF 18 - BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE
    0F 16 FF 18 85 01 00 93 15 64 0D B1 03 FC 20 F6 - BLE_GAP_AD_TYPE_SERVICE_DATA
    04 FF 0C 01 03 - BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA
    03 34 FC 00 - CRC?

    I am starting to think the ServiceData is being received in the scan response, but I am not sure.

    Regarding your questions:

    Q: "Have you tried to just print the entire advertisement in the advertising report?"

    Do you mean just the advertising data or the entire ble_gap_evt_adv_report_t structure? I have compared the advertising data as detailed in my parsing comments above.

    Q: "Do you see the data that you are looking for? I am not sure whether the issue is that the advertising data is not present in the packet that you are checking, or whether there is something wrong with the way you parce the advertising packet."

    It appears to me that the LOCAL NAME and SERVIC DATA advertising packets are coming in at different times with ServiceData being infrequent and inconsistent. I am suspecting that the ServiceData is sent by the peripheral device when it receives a scan request but this is just a guess at this point.

    Questions:

    1. How can I determine if an advertising packet received was due to a scan request / response?

    2. Any ideas as to why I would be seeing the ServiceData packets so infrequently (up to 2 minutes apart) within the firmware when compared to the Wireshark captures where they appear every 2 seconds consistently?

    I will do some more investigations based on your response. I am still learning the advertising packet structure and what data is reported and when.

    Thanks!

  • droberson said:
    1. How can I determine if an advertising packet received was due to a scan request / response?

     Try adding this to your BLE_GAP_EVT_ADV_REPORT:

    				case BLE_GAP_EVT_ADV_REPORT:
    				    adv_type = p_ble_evt->evt.gap_evt.params.adv_report.type;
    				    NRF_LOG_INFO("received sr:%d", adv_type.scan_response);
    			      break;

    It will print "received sr:1" if the adv report is a scan response, and "received sr:0" if it is not a scan response.

     

    droberson said:
    2. Any ideas as to why I would be seeing the ServiceData packets so infrequently (up to 2 minutes apart) within the firmware when compared to the Wireshark captures where they appear every 2 seconds consistently?

     Do you use the radio for anything else? E.g. connections, advertising, etc? What is the advertising interval on the peripheral? What is your scan interval and scan window on your central? Does it advertise as well? Are you in any connections? If so, what are the connection parameters? 

    BR,
    Edvin

Reply
  • droberson said:
    1. How can I determine if an advertising packet received was due to a scan request / response?

     Try adding this to your BLE_GAP_EVT_ADV_REPORT:

    				case BLE_GAP_EVT_ADV_REPORT:
    				    adv_type = p_ble_evt->evt.gap_evt.params.adv_report.type;
    				    NRF_LOG_INFO("received sr:%d", adv_type.scan_response);
    			      break;

    It will print "received sr:1" if the adv report is a scan response, and "received sr:0" if it is not a scan response.

     

    droberson said:
    2. Any ideas as to why I would be seeing the ServiceData packets so infrequently (up to 2 minutes apart) within the firmware when compared to the Wireshark captures where they appear every 2 seconds consistently?

     Do you use the radio for anything else? E.g. connections, advertising, etc? What is the advertising interval on the peripheral? What is your scan interval and scan window on your central? Does it advertise as well? Are you in any connections? If so, what are the connection parameters? 

    BR,
    Edvin

Children
No Data
Related