androidbluetoothbluetooth-lowenergyibeaconandroid-ble

Android BLE: Is it possible to add Service Data and Manufacturer Data at the same time when advertising an iBeacon packet?


I'm currently doing an experiment in order to trigger a beacon detection device. Here is the sample of a detected beacon that can be used to trigger that device.

Sample beacon

In my experiment, I'm trying to replicate the beacon like in the above picture by using Android BLE library and using iBeacon protocol, since the detection device claims that it follows iBeacon protocol. First, I try to set the service UUID and service data by using AdvertiseData object, then advertise it. The code roughly looks like this:

AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();

byte[] experimentData = {0x48, 0x6E, (byte) 0xDD, 0x2A, 0x40, (byte) 0xA6, (byte) 0xF0, 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00};
byte[] uuidBytes = {0x10, 0x02}
byte[] advertisingBytes = getAdvertisingBytes();

ParcelUuid parcelUuid = parseUuidFrom(uuidBytes);
dataBuilder.addServiceData(parcelUuid, experimentData);
dataBuilder.addServiceUuid(parcelUuid);
dataBuilder.setIncludeTxPowerLevel(false);
dataBuilder.setIncludeDeviceName(false);
//dataBuilder.addManufacturerData(manufacturerCode, advertisingBytes);

AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
settingsBuilder.setAdvertiseMode(0);
settingsBuilder.setTxPowerLevel(3);
settingsBuilder.setConnectable(false);
bluetoothLeAdvertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), null);

I commented the addManufacturerData() part for now. The result looks like this.

Result one

Now I modify the code so that instead of using Service UUID and Service Data, I use addManufacturerData to advertise the data. The code looks like this:

AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();    
byte[] experimentData = {0x48, 0x6E, (byte) 0xDD, 0x2A, 0x40, (byte) 0xA6, (byte) 0xF0, 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00};
byte[] uuidBytes = {0x10, 0x02}
byte[] advertisingBytes = getAdvertisingBytes();

//ParcelUuid parcelUuid = parseUuidFrom(uuidBytes);
//dataBuilder.addServiceData(parcelUuid, experimentData);
//dataBuilder.addServiceUuid(parcelUuid);
//dataBuilder.setIncludeTxPowerLevel(false);
//dataBuilder.setIncludeDeviceName(false);
dataBuilder.addManufacturerData(manufacturerCode, advertisingBytes);

AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
settingsBuilder.setAdvertiseMode(0);
settingsBuilder.setTxPowerLevel(3);
settingsBuilder.setConnectable(false);
bluetoothLeAdvertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), null);

The result is shown below. The "Service Data" part is gone, and it is now recognized as an iBeacon packet:

Result two

Now, in the first picture, there are "Service Data" section and "Beacon" section, so I though that by adding Service Data and Manufacturer Data, the two section will be shown. I uncomment all of the code, and now it looks like this:

AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();    
byte[] experimentData = {0x48, 0x6E, (byte) 0xDD, 0x2A, 0x40, (byte) 0xA6, (byte) 0xF0, 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00};
byte[] uuidBytes = {0x10, 0x02}
byte[] advertisingBytes = getAdvertisingBytes();

ParcelUuid parcelUuid = parseUuidFrom(uuidBytes);
dataBuilder.addServiceData(parcelUuid, experimentData);
dataBuilder.addServiceUuid(parcelUuid);
dataBuilder.setIncludeTxPowerLevel(false);
dataBuilder.setIncludeDeviceName(false);
dataBuilder.addManufacturerData(manufacturerCode, advertisingBytes);

AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
settingsBuilder.setAdvertiseMode(0);
settingsBuilder.setTxPowerLevel(3);
settingsBuilder.setConnectable(false);
bluetoothLeAdvertiser.startAdvertising(settingsBuilder.build(), dataBuilder.build(), null);

But then the advertising packet does not shown at all in the beacon detection app. No exception either, so I don't know whether the beacon is advertised or not

So, it is possible by using Android BLE library to replicate beacon as shown in the first picture (Service data and beacon/manufacturer data in one packet)?


Solution

  • A single advertisement packet has a data payload limited to about 23 data bytes so it does not have room for both manufacturer data and service data of the sizes you have in your example.

    Try advertising both at the same time each in its own advertisement. Android devices support transmitting multiple advertisements simultaneously.