Search code examples
arduinobluetooth-lowenergyesp32ibeaconbeacon

BLE raw data advertisment


I have a remote control that advertises BLE raw data:

nRF Connect screenshot

I need to make the exact advertisement (0x18f90...) using my raspberry pi or esp32 microcontroller. The problem is I can't find a way to advertise that exact raw data. Every library like espressif or sample code I use, kind of generates the raw data. Like this esp32 Arduino BLE iBeacon snippet:

BLEBeacon oBeacon = BLEBeacon();
oBeacon.setManufacturerId(0x5558); // fake Apple 0x004C LSB (ENDIAN_CHANGE_U16!)
oBeacon.setProximityUUID(BLEUUID(BEACON_UUID));
oBeacon.setMajor((bootcount & 0xFFFF0000) >> 16);
oBeacon.setMinor(bootcount&0xFFFF);
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();

Can anyone suggest a way to exactly clone a BLE advertiser?

The nRF Connect app has a feature to clone the advertiser, but no exporting is provided.


Solution

  • You can use BlueZ command line utilities on a Raspberry Pi to get pretty close to total control of recording and replaying a Bluetooth LE packet, but it still must have a valid BLE header. (See my related answer here that talks about the header.)

    The Raspberry Pi BlueZ library also lets you record advertisements sent over the air, but there are no CLI tools pre-installed on Raspberry Pi that do this -- only C APIs. So I made a command line tool called scan that makes it easy. You can download and install it here.

    Here's how that tool works:

    ./scanner
    
    B8:27:EB:1F:93:4D -68 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30
    71:5C:23:9D:BC:7F -68 02 01 1A 02 0A 0C 0B FF 4C 00 10 06 03 1A 3B D4 B2 EB
    B8:27:EB:1F:93:4D -68 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30
    

    In the above, the header is the MAC address of the BLE advertiser (e.g. B8:27:EB:1F:93:4D) followed by the RSSI (eg. -68) then the data bytes.

    If you then want to replay the first data packed on a Raspberry Pi (e.g. the bytes 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30) you can do so with this command on the Raspberry Pi:

    sudo hcitool -i hci0 cmd 0x08 0x0008 02 01 06 11 06 82 75 25 D9 37 9D D7 8F 5F 4A F4 20 00 00 75 30

    Note in the above, the bytes after 0x0008 are just cut and pasted from the output of the ./scanner tool.

    BTW, I am skeptical of the data shown in your Nordic NRF Connect screenshot -- that is normally a very good tool, but it is showing an advertisement that is longer than is usually supported for BLE 4.1. I would retry scanning it on a Raspberry Pi with the scanner tool mentioned above then you can try playing it back as shown.