Creating AltBeacon with Raspberry Pi using BlueZ Example Code


Update (Jul 9, 2019):
Step 1 is no longer required since Raspbian Buster (2019-06-20). Please check the updated steps in here.


 

A previous post showed the steps to make an iBeacon transmitter with Raspberry Pi using BlueZ example code (i.e. “example-advertisement). This post shows the steps for AltBeacon [1] in the same manner.

 

Here are the contents of this post.

Contents
– Prerequisites
– Steps
1. Enable experimental flag
2. Download BlueZ
3. Modify BLE Advertisement Example Code
4. Test
– Summary
– Reference

 

Prerequisites
Here are some prerequisites before start.

  • Raspberry Pi 3 B+ or Raspberry Pi Zero W
    Or any other model with Bluetooth adapter (e.g. Plugable BLE Adapter, Panda Bluetooth 4.0 Adapter)
  • Raspbian Stretch (March 2018)
    I would suggest to use Desktop version of Stretch because I got “DBus.Error.AccessDenied” for some reason when I ran “example-advertisement” on Raspbian Lite. It seems it’s similar to this but couldn’t figure out the cause/workaround.
  • Internet access
    It’s required to download BlueZ example code. Here is a Wi-Fi Setup steps. If you already have the code, you can work offline.

 

Steps
1. Enable experimental flag
Skip to Step 2 if you are using BlueZ 5.48 or higher. (update BlueZ to 5.48)

$ bluetoothd -v
5.48

If not, follow the steps below.

Bluetooth service needs to be executed with experimental flag since ‘LEAdvertisingManager1’ interface is an experimental feature until BlueZ 5.48 release.

1-1. Open the configuration file for Bluetooth service.

sudo nano /lib/systemd/system/bluetooth.service

1-2. Find a line starting with “ExecStart” and add “–experimental” at the end of the line. After modification, the line should look like this:

ExecStart=/usr/libexec/bluetooth/bluetoothd --experimental

1-3. Reload the configuration file and restart Bluetooth service.

sudo systemctl daemon-reload 
sudo systemctl restart bluetooth.service

1-4. Check the status of Bluetooth service. [Optional]

systemctl status bluetooth.service

You should see the experimental flag. (Line 9 in the example below)

pi@raspberrypi:~ $ systemctl status bluetooth.service 
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2018-02-21 14:31:19 UTC; 4s ago
     Docs: man:bluetoothd(8)
 Main PID: 1122 (bluetoothd)
   Status: "Running"
   CGroup: /system.slice/bluetooth.service
           └─1122 /usr/lib/bluetooth/bluetoothd --experimental

 

2. Download BlueZ
2-1. Download BlueZ source code.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.43.tar.xz

2-2. Extract the archive file.

tar xvf bluez-5.43.tar.xz

2-3. Run the sample code and make sure that it works. [Optional]

./bluez-5.43/test/example-advertisement

Output should be like this:

$ ./bluez-5.43/test/example-advertisement
GetAll
returning props
Advertisement registered

* Press Ctrl + C to stop the script.

 

3. Modify BLE Advertisement Example Code
3-1. Copy the example code.

cp ./bluez-5.43/test/example-advertisement ./example-altbeacon

3-2. Open the file and look for TestAdvertisement class.

3-3. Replace ‘__init__’ method:

    def __init__(self, bus, index):
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_uuid('180D')
        self.add_service_uuid('180F')
        self.add_manufacturer_data(0xffff, [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_service_data('9999', [0x00, 0x01, 0x02, 0x03, 0x04])
        self.include_tx_power = True

with:

    def __init__(self, bus, index):
        company_id =  0x0118
        type =       [0xBE, 0xAC]
        id1 =        [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                      0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]
        id2 =        [0x11, 0x22]
        id3 =        [0x33, 0x44]
        rssi_at_1m = [0xB3]
        feature  =   [0x00]
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_manufacturer_data(company_id, type + id1 + id2 + id3 + rssi_at_1m + feature)

 

4. Test
4-1. Run the code. The console output should be same as Step 2-3.

./example-altbeacon

4-2. Find your Raspberry Pi using a beacon scanner app. If everything goes well, the Raspberry Pi should be broadcasting AltBeacon message and it can be detected by app. Below are examples of apps.

‘nRF Connect’ for Android

 

‘Locate Beacon’ for iPhone

 

Summary
AltBeacon is an open source version of Apple’s iBeacon. It has the same functionality as iBeacon, and the two have similar data structure as below.

*2 : Bluetooth 4.0 Core Specification, Volume 3, Part C, Appendix C, 18.1 Flags
*4 Manufacture dependent value
*5 Application dependent value
*6 Device dependent value

 

References
[1] AltBeacon