nRF52 BLE get scan response data

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
hasff
 
Posts: 5
Joined: Fri Feb 10, 2023 3:25 pm

nRF52 BLE get scan response data

Post by hasff »

Hello, I'm new to this and need help to read scan response.

I'm using a nRF52832 as peripheral and a nRF52840 as central.

In the peripheral device I add the device name to the ScanResponse:

Code: Select all

void setup() {

  Serial.begin(115200);
  while ( !Serial ) delay(10);

  if (!Bluefruit.begin()) {

    Serial.println("Unable to init Bluefruit");
    while(1) {

      digitalToggle(LED_RED);
      delay(100);
    }
  }
  else {
    
    Serial.println("Bluefruit initialized (peripheral mode)");
  }

  Bluefruit.setName(__NAME__);
  Bluefruit.autoConnLed(false);

  Bluefruit.setTxPower(4);
  
  battery_service.begin();
  battery_level_characteristic.setProperties(CHR_PROPS_READ);
  battery_level_characteristic.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
  battery_level_characteristic.setFixedLen(1);
  battery_level_characteristic.begin();

  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  
  Bluefruit.Advertising.addUuid(uuid);
  Bluefruit.Advertising.addService(battery_service);
  Bluefruit.ScanResponse.addName();  // <========================= HERE

  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in units of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start();

  Serial.println("Advertising started"); 
}
In the central device I set the Scanner rxCallback and useActiveScan to true:

Code: Select all

void setup() {

  Serial.begin(115200);
  delay(100); 

  if ( !Bluefruit.begin(2, 2) ) {

    Serial.println("Unable to init Bluefruit");
    while(1)
    {
      digitalToggle(LED_RED);
      delay(100);
    }
  }
  else {

    Serial.println("Bluefruit initialized (central mode)");
  }

  Bluefruit.setName(__NAME__);
  Bluefruit.setTxPower(TXPOWER); 
  Bluefruit.autoConnLed(false);

  clientUart.begin();
  clientUart.setRxCallback(bleuart_rx_callback);

  Bluefruit.Central.setConnectCallback(connect_callback);
  Bluefruit.Central.setDisconnectCallback(disconnect_callback);

  Bluefruit.Scanner.setRxCallback(scan_callback); // <==================== HERE
  Bluefruit.Scanner.restartOnDisconnect(true);
  Bluefruit.Scanner.filterUuid(tableUUID, relayUUID);   
  Bluefruit.Scanner.setInterval(160, 80);               
  Bluefruit.Scanner.useActiveScan(true);                // <==================== HERE
  Bluefruit.Scanner.start(0);                           
  Serial.println("Scanning ...!");
}
In the central device, in the scan_callback I try unsuccessfully to retrieve the device name, also I print the report->type.scan_response and it is always zero, is it supposed to be like this?

Code: Select all

void scan_callback(ble_gap_evt_adv_report_t* report) {

  Serial.printf("scan_response is: %u\n", report->type.scan_response); // <=========== HERE

  uint8_t buffer[10];
  memset(buffer, 0, sizeof(buffer));

  uint8_t res = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, buffer, sizeof(buffer) - 1); // <============ HERE
  Serial.printf("Got successfully device name? %u \n", res);

  if ( Bluefruit.Scanner.checkReportForUuid(report, relayUUID) ) {

    scan_callback_relay(report);
  }

  if ( Bluefruit.Scanner.checkReportForUuid(report, tableUUID) ) {

    scan_callback_table(report);
  }

  Bluefruit.Scanner.resume();
}
I know that the report->data.p_data constains the first 31 bytes of data added to Advertising, and if I include the device name in it (using Bluefruit.Advertising.addName() and removing something to have space for it), I can get the name successfully. On the other hand adding it to Bluefruit.ScanResponse.addName() I can't get in the central code but using the cell phone Adafruit app "Bluefruit LE Connect" I am actually able to get the device name from the ScanResponse, so I know that the data is being transmitted and that it is possible to retrieve it.
How to do it properly?

User avatar
hasff
 
Posts: 5
Joined: Fri Feb 10, 2023 3:25 pm

Re: nRF52 BLE get scan response data

Post by hasff »

I've been exploring and trying to understand what's going on.

I posted also in the discord Adafruit, a person replied that had found this two posts here:
viewtopic.php?p=787865
viewtopic.php?p=788223

Both unanswered.

I tried the example https://github.com/adafruit/Adafruit_nR ... vanced.ino is Adafruit code, but still cannot get the ScanResponse data.
Note that I can get the device name from scan response using both Bluefruit LE Connect and nRF Connect, in the scan phase, not connected to the device!

I also noticed a strange behavior, if I only set the Bluefruit.setName and not setting both Bluefruit.Advertising.addName and Bluefruit.ScanResponse.addName.
The nRF Connect cannot see the device name, that was expected! But the Bluefruit LE Connect is able somehow to get the device name, that was not expected!
Both apps get the same raw data: "02 01 06 02 0A 04 03 03 0F 18 11 07 4C 40 60 FC 9D D5 CA 92 FB 48 AB 11 89 65 FE 2F", is already full, it contains the:
BLE_GAP_AD_TYPE_FLAGS (01),
BLE_GAP_AD_TYPE_TX_POWER_LEVEL (0A),
BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE (03) and BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE (07).
Filling in total 28 bytes of the 31 available. It is needed 5 bytes to include the string "T01" (what I need to include), so no room for it.
I don't have a sniffer so I cannot go further. This is a mystery to me, how Bluefruit LE Connect is able to tell the device name? It was not added to the advertising, it doesn't go in the packet, is only set with Bluefruit.setName.

And why nRF52s are the only ones unable to detect a ScanResponse event?

Thank you in advance!

User avatar
hasff
 
Posts: 5
Joined: Fri Feb 10, 2023 3:25 pm

Re: nRF52 BLE get scan response data

Post by hasff »

So I guess that even Adafruit guys don't know this?!

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: nRF52 BLE get scan response data

Post by adafruit_support_mike »

The advertising packet is different from the scanResponse packet.

A BLE peripheral transmits advertising packets on its own, and nearby central devices can hear those packets without requesting them.

A central device that hears an advertising packet can identify the peripheral, connect to it, and send a 'scan request' message. The peripheral's scan response packet is the reply to that message.

It sounds like you've gotten the two mixed up, and are expecting to see scan response data in the advertising packet. BLE doesn't work that way.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”