BLE: Establishing 0xfd6f contact detection service data transmission

Dear all,

just recently we started a project, with which we want to leverage the ArduinoBLE library to consume
the published service data payload by any contact detection service, which follows Google's and Apple's contact tracing bluetooth specification.

To summarize our post questions:

  • How can we use the ArduinoBLE library to establish this type of 0xfd6f Advertisement and Reception?
  • Why is our Arduino crashing when service data is set up to be advertised in GAP.cpp?
  • Why is our Arduino not able to read/consume other service data?
  • What needs to be changed in the core library for service data consumption?

What we have done:

  • Trying to initialize the GAP class with service data
  • Using the "nRF Connect" app to define and advertise service data
  • Using ArduinoBLE library's "PeripheralExplorer.ino" to read/consume service data

Currently, as it is possible to define service data in android BLE frameworks, which are using the internal
android.bluetooth.le BLE package/library to transmit and receive so called "service data".

Advertisement on Arduino:

I was wondering, what the equivalent of that service data is, having the ArduinoBLE library. In GAP.cpp line 267
you can find void GAPClass::setAdvertisedServiceData(uint16_t uuid, const uint8_t data[], int length), which is set to protected in it's corresponding header file.

By changing the constructor of GAP.cpp to the following:

GAPClass::GAPClass() :
  String uuid_string = "FD6F";
  uint16_t uuid = strtol(uuid_string, NULL, 16);
  uint8_t data[] = "ServiceDataTest_";
  setAdvertisedServiceData(uuid, data, sizeof(data));

The code is compiling without any errors, but the Arduino Nano 33 BLE Sense crashes for some reason and the usb connection needs to be reset by double pressing the board button.

Reception on Arduino:

On the other hand it is possible to mimic the service data pattern using the nRF Connect app and defining an advertising packet, follwing these steps:
1.) Enter a display name. In my case it was just "Smartphone".
2.) Add a record for "Service UUID": FD6F
3.) Add "Service Data" with UUID==FD6F and Data==7465737464617461, which equals to "testdata"
4.) Activate option "Scannable" by checking it at the bottom of the settings

Now running the PeripheralExplorer.ino and
changing from line 41 to the following, to apply a check for our specific service UUID fd6f:


if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    // see if peripheral is a LED
    if (peripheral.advertisedServiceUuid() == "fd6f") {
      Serial.println("Service FOUND!");
      Serial.print(" '");
      Serial.print("' ");

      // stop scanning


The output will be:

Service FOUND!
72:14:25:39:c5:3c 'HUAWEI P10' 

Connecting ...
Discovering attributes ...
Attributes discovered

Device name: HUAWEI P10
Appearance: 0x0

Service 1801
        Characteristic 2a05, properties 0x20
Service 1800
        Characteristic 2a00, properties 0x2, value 0x48554157454920503130
        Characteristic 2a01, properties 0x2, value 0x0000
        Characteristic 2aa6, properties 0x2, value 0x01
Service fe35
        Characteristic 2a00, properties 0xA
        Characteristic 2a01, properties 0x30
        Characteristic 2a02, properties 0x8
        Characteristic 2a03, properties 0x30
                Descriptor 2902, value 0x0000
Service 046a
        Characteristic 046c, properties 0xA, value 0x37613A36323A35363A66303A39333A6533

Disconnecting ...

You can use this hex2text converter to see the output.
Unfortunately, we are not able to retrieve our defined service data "testdata" in any of the displayed fields.

How can we use the ArduinoBLE library to establish this type of 0xfd6f Advertisement and Reception?