Share this article:

What makes an iBeacon an iBeacon

It’s very simple, it just advertises a string which contains a few characters conforming to Apple’s iBeacon standard.

If you use a bluetooth pakket sniffer you will see the advertisement strings.

To make a beacon, all you need to do is insert a specific set of bytes into the optional Manufacturer Specific Data field of the advertising packet on your Bluetooth Low Energy device.

Inside this field, you need the following values:

ID (uint8_t) - This will always be 0x02

Data Length (uint8_t) - The number of bytes in the rest of the payload = 0x15 (21 in dec)

128-bit UUID (uint8_t[16]) - The 128-bit ID indentifying your company/store/etc

Major (uint16_t) - The major value (to differentiate individual stores, etc.)

Minor (uint16_t) - The minor value (to differentiate nodes withing one location, etc.)

TX Power (uint8_t) - This value is used to try to estimate distance based on the RSSI value

For example, the following is a valid iBeacon payload (separators added for clarity sake):

02 | 15 | E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 | 00 00 | 00 00 | C8

The only other missing piece is that, following the Bluetooth standard, the Manufacturer Specific Data needs to be preceded by the Company Identifier, which is 0x0016 for Apple.

Read about iBeacons in iOS Shop

Here is an example captured with pakketlogger

pakketloggerlogo

example_payload

This explanation is also very good on stackoverflow

http://stackoverflow.com/questions/18906988/what-is-the-ibeacon-bluetooth-profile

For an iBeacon with ProximityUUID E2C56DB5-DFFB-48D2-B060-D0F5A71096E0, major 0, minor 0, and calibrated Tx Power of -59 RSSI, the transmitted BLE advertisement packet looks like this:


d6 be 89 8e 40 24 05 a2 17 6e 3d 71 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5 52 ab 8d 38 a5

This packet can be broken down as follows:


d6 be 89 8e # Access address for advertising data (this is always the same fixed value)
40 # Advertising Channel PDU Header byte 0. Contains: (type = 0), (tx add = 1), (rx add = 0)
24 # Advertising Channel PDU Header byte 1. Contains: (length = total bytes of the advertising payload + 6 bytes for the BLE mac address.)
05 a2 17 6e 3d 71 # Bluetooth Mac address (note this is a spoofed address)
02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5 # Bluetooth advertisement
52 ab 8d 38 a5 # checksum

The key part of that packet is the Bluetooth Advertisement, which can be broken down like this:


02 01 1a 1a ff 4c 00 02 15 # Apple's fixed iBeacon advertising prefix
e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile uuid
00 00 # major
00 00 # minor
c5 # The 2's complement of the calibrated Tx Power

Any Bluetooth LE device that can be configured to send a specific advertisement can generate the above packet. I have configured a Linux computer using Bluez to send this advertisement, and iOS7 devices running Apple’s AirLocate test code pick it up as an iBeacon with the fields specified above. See: Use BlueZ Stack As A Peripheral (Advertiser)

This blog has full details about the reverse engineering process.