Skip to content

ESP32-S3 BLE Active Scan Regression: Failure to Process/Merge Scan Response Data (e.g., Service Data Type 0x16) #12075

@kamikazem

Description

@kamikazem

Board

ESP32-S3

Device Description

Working Device (Reference): ESP32-WROOM-32 (Classic ESP32, using older stable BLE stack)

Failing Device (Issue): ESP32-S3 (Running newer BLE 5.0 stack/NimBLE implementation)

Hardware Configuration

nothing

Version

latest stable Release (if not listed below)

Type

Bug

IDE Name

arduino

Operating System

windows11

Flash frequency

80mhz

PSRAM enabled

no

Upload speed

115200

Description

When performing an active BLE scan, the Classic ESP32 correctly receives and processes data contained in both the initial Advertisement (ADV) packet and the subsequent Scan Response (SR) packet. This allows clients to reliably access data records (ADRs) that exceed the 31-byte limit of the ADV packet, such as extended local names, or crucial sensor data stored in Service Data (AD Type 0x16).

However, on the ESP32-S3, the data contained in the Scan Response (SR) packet appears to be entirely ignored, truncated, or failed to be merged into the BLEAdvertisedDevice object during an active scan.

The primary symptom is that applications relying on data fields often placed in the SR packet (such as a device's custom Service Data with UUID 0x16) only receive the ADV packet contents. This represents a functional regression from the classic ESP32's BLE behavior and breaks compatibility with many devices that split their payload across ADV and SR packets.

Minimal Reproducible Code (Arduino Sketch)

This generic code performs an active scan and attempts to read the Service Data (AD Type 0x16), which is often placed in the Scan Response.

Sketch

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

// NOTE: Set this to the address or name of *any* BLE peripheral that you know
// splits its advertisement payload across the ADV and Scan Response packets,
// specifically putting Service Data (0x16) in the Scan Response.
// For testing, replace with a known device's filtering logic.
const char* TARGET_FILTER = "ExampleDeviceName"; 
const std::string SERVICE_DATA_UUID = "0000xxxx-0000-1000-8000-00805f9b34fb"; // Placeholder for testing

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
        std::string name = advertisedDevice.getName();
        
        // Filter for the target device (replace with address/UUID filter as needed)
        if (name.find(TARGET_FILTER) != std::string::npos) {
            
            Serial.printf("Found Target Device: %s\n", name.c_str());
            
            // --- CRITICAL TEST POINT: Check for Service Data (AD Type 0x16) ---
            // On a device that sends Service Data in the SR packet:
            // ESP32 (Reference) EXPECTED: Service Data length > 0
            // ESP32-S3 (Failing) ACTUAL: Service Data length is 0 (or absent)
            
            std::string serviceData = advertisedDevice.getServiceData();
            
            if (serviceData.length() > 0) {
                Serial.printf("PASS: Service Data (0x16) FOUND. Length: %d bytes\n", serviceData.length());
                Serial.print("Raw Data (Hex): ");
                for (char c : serviceData) {
                    Serial.printf("%02X ", (uint8_t)c);
                }
                Serial.println();
            } else {
                Serial.println("FAIL: Service Data (0x16) NOT found in advertisement result.");
            }
            Serial.println("------------------------------------");
        }
    }
};

void setup() {
    Serial.begin(115200);
    Serial.printf("--- Running on: %s ---\n", 
    #ifdef ARDUINO_ESP32_DEV
        "Classic ESP32 (Reference)"
    #elif defined(ARDUINO_ESP32S3_DEV)
        "ESP32-S3 (Failing)"
    #else
        "Unknown ESP32 variant"
    #endif
    );
    
    Serial.println("Starting Active BLE Scan to test Scan Response capture...");
    BLEDevice::init("");
    BLEScan* pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true); // Must be active to request the Scan Response (SR)
    pBLEScan->start(10, false); // Scan for 10 seconds
}

void loop() {
    delay(2000); 
}

Debug Message

nothing

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions