Skip to content

BLE on ESP32: BLEBeacon::getProximityUUID() returns reversed UUID string compared to expected value #7858

Closed
@johny-tee

Description

@johny-tee

Board

ESP32 Dev Module

Device Description

ESP-WROOM-32 board.

Hardware Configuration

No external connections except USB connection to the Host PC.

Version

v2.0.6

IDE Name

Arduino IDE 2.0

Operating System

Windows 10

Flash frequency

40 MHz

PSRAM enabled

yes

Upload speed

921600

Description

Calling BLEBeacon::getProximityUUID() after constructing BLEBeacon object returns reversed UUID string compared to what is expected.

The code:

  BLEBeacon oBeacon = BLEBeacon();
  oBeacon.setData(strManufacturerData);
  // strManufacturerData is obtained via calling advertisedDevice.getManufacturerData() during BLE Scan
  
  System.println(oBeacon.getProximityUUID().toString().c_str());

outputs: c1655d97-b7ac-d1b2-e940-23f200eb28d4
expected value is: d428eb00-f223-40e9-b2d1-acb7975d65c1

After analyzing the related code, the following was found in BLEBeacon.cpp:

BLEUUID BLEBeacon::getProximityUUID() {
	return BLEUUID(m_beaconData.proximityUUID, 16, **false**);
}

The last parameter decides whether bytes should be reversed in memory in the implementation of BLEUUID.

After modyfying getProximityUUID method to:

BLEUUID BLEBeacon::getProximityUUID() {
	return BLEUUID(m_beaconData.proximityUUID, 16, **true**);
}

The above code returns UUID value as expected:

outputs: d428eb00-f223-40e9-b2d1-acb7975d65c1
expected value is: d428eb00-f223-40e9-b2d1-acb7975d65c1

Conclusion:
the last parameter in BLEUUID constructor call in BLEBeacon::getProximityUUID should be changed to true.

Sketch

/*
   Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
   Ported to Arduino ESP32 by Evandro Copercini
   Changed to a beacon scanner to report iBeacon, EddystoneURL and EddystoneTLM beacons by beegee-tokyo
*/

#include <Arduino.h>

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

#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))

int scanTime = 5; //In seconds

BLEScan *pBLEScan;

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
        if (true == advertisedDevice.haveManufacturerData())
        {
          std::string strManufacturerData = advertisedDevice.getManufacturerData();

          uint8_t cManufacturerData[100];
          strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);

          int iRSSI = -9999;

          if (25 == strManufacturerData.length() && 0x4c == cManufacturerData[0] && 0x00 == cManufacturerData[1])
          {
            if (advertisedDevice.haveRSSI())
            {
              iRSSI = advertisedDevice.getRSSI();
            }

            Serial.println("Found an iBeacon!");
			      Serial.println("Raw data:");
			      Serial.print("    ");
			      for (int iCnt = 0; 25 > iCnt; iCnt++) 
			      {
              Serial.printf("[%02X]", cManufacturerData[iCnt]);
			      }
			      Serial.println();

            BLEBeacon oBeacon = BLEBeacon();

            oBeacon.setData(strManufacturerData);

			      Serial.println("\nDecoded data:");
            Serial.printf("    ID: %04X Major: %d Minor: %d UUID: %s Power: %d\n", oBeacon.getManufacturerId(), ENDIAN_CHANGE_U16(oBeacon.getMajor()), ENDIAN_CHANGE_U16(oBeacon.getMinor()), oBeacon.getProximityUUID().toString().c_str(), oBeacon.getSignalPower());
            Serial.printf("    RSSI: %04d\n", iRSSI);

         }
        }

        return;
      }
};

void setup()
{
  Serial.begin(115200);

  BLEDevice::init("");

  pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
  pBLEScan->setInterval(100);
  pBLEScan->setWindow(99); // less or equal setInterval value

  Serial.println("Configuration finished...");
}

void loop()
{
  Serial.println("******************************************************************************");

  // Start scanning
  BLEScanResults foundDevices = pBLEScan->start(scanTime, false);

  // Print scan results summary
  Serial.printf("Devices found: %d total\n", foundDevices.getCount());

  // Clear scanning results to release memory
  pBLEScan->clearResults();

  Serial.println("Scan done!");
  Serial.println("==============================================================================");

  delay(10000);
}

Debug Message

No error messages. This is output of the snip. You can clearly see how UUID is reversed compared to raw data (UUID start on index 4 and ends on index 19 of Manufacturer data for iBeacon). ID, Major, Minor and Power values are as expected:

Found an iBeacon!
Raw data:
    [4C][00][02][15][D4][28][EB][00][F2][23][40][E9][B2][D1][AC][B7][97][5D][65][C1][00][01][00][10][BF]

Decoded data:
    ID: 004C Major: 1 Minor: 16 UUID: c1655d97-b7ac-d1b2-e940-23f200eb28d4 Power: -65

Other Steps to Reproduce

Reproduced also on Linux.

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

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions