Turning A Pi Into An iBeacon
What You’ll Need
A big thanks to Tony Smith at The Register for putting together his tutorial on configuring Bluez to transmit iBeacon data!
What is iBeacon?
The way it works is actually very simple. Any BLE device typically advertises a certain amount of data to let other devices (like your phone) know that they exist and they’re available. The advertising packet that these devices send out might include information like key services offered by the device, a human-readable short devices name, etc.
iBeacon takes this short advertising frame, and appends a custom payload in the “Manufacturer Specific Data” field which includes a unique 128-bit UUID to identify companies or unique entities, as well as two 16-bit values (called ‘Major’ and ‘Minor’) that allow you to differentiate specific stores/premises (Major) and individual iBeacon nodes (Minor).
That’s basically it. All the rest of the magic is on the app side where your phone listens for these advertising frames, and when it detect something it estimates the distance to the node and displays some sort of alert.
It’s terribly simple, but that’s probably what makes it so interesting and also so inexpensive to implement!
How Does it Work in Pratice?
Essentially, 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) – 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 0A39 F4 73 F5 4B C4 A1 2F17 D1 AD 07 A9 61|0000|0000| C8
Setting up the Pi
1. Install Required Libraries
- sudo apt–get install libusb–dev libdbus–1–dev libglib2.0–dev libudev–dev
- libical–dev libreadline–dev
2. Download Bluez
- sudo mkdir bluez
- cd bluez
- sudo wget www.kernel.org/pub/linux/bluetooth/bluez–5.11.tar.gz
3. Unzip and Compile Bluez
Next you need to actually build Bluez on the Pi. This step may take a while, but should work without any hiccups if you properly installed all the libraries in step one above:
- sudo unxz bluez–5.11.tar.xz
- sudo tar xvf bluez–5.11.tar
- cd bluez–5.11
- sudo ./configure —disable–systemd
- sudo make
- sudo make install
4. Insert the USB Module and Reset
Once Bluez has been built, shut down your computer withsudo shutdown -h now and once its Halted, insert yourBluetooth 4.0 USB Module and then reset the Raspberry Piso that all of the changes we have made can take effect.
Adding iBeacon Data
1. Check for your USB Module
This should give you a list of devices on your system:
2. Enable the USB Device
Next you can enable the device with the following commands, turning off device scanning since this can cause problems when advertising:
- sudo tools/hciconfig hciO up
- sudo tools/hciconfig hci0 leadv
- sudo tools/hciconfig hci0 noscan
3. Enter the iBeacon Advertising Data
The last thing to do is to enter the iBeacon advertising data, which we can do with the following command (which should all be on one line):
- sudo tools/hcitool –i hci0 cmd 0x080x00081E02011A1A
- FF 4C000215 E2 0A39 F4 73 F5 4B C4 A1 2F17 D1 AD 07 A9 6100000000 C8 00
Results on a Bluetooth Debugger
Just to show that this actually works, you can see the results using a Bluetooth Low Energy sniffer below:
Testing it on iOS
Start the app up, going into ‘Listen’ mode, and you should see a screen similar to the capture below, where the range will go in and out depending on your proximity to the node: