這裡介紹如何使用樹莓派實作一個 iBeacon 發射器,發送 iBeacon 訊號給手機等行動裝置。

Beacon 是一種以藍牙低功耗(BLE)資料傳輸技術為基礎,結合各種行動裝置的應用,這個技術可將少量的資料發送至附近的手機或平板等藍牙行動裝置,讓行動裝置上的應用程式獲得準確的位置相關資訊,非常適合用於室內定位、商場導覽等各種場合。


iBeacon 則是蘋果公司所推出的一種 Beacon 傳輸協定,是目前主流的 Beacon 通訊協定之一,以下我們以第三代樹莓派的測試環境,實作一個測試用的 iBeacon 發射器,發送 iBeacon 訊號至手機。

安裝 BlueZ

這裡我們需要安裝 BlueZ 5.11 以後的版本,如果 Linux 系統套件庫中的 BlueZ 套件版本,就可以使用 apt 安裝,如果系統套件庫的版本太舊,就必須下載 BlueZ 的原始碼自行編譯安裝。

以 apt 安裝 BlueZ

檢查 apt 套件庫中的 bluez 版本:

apt-cache show bluez
Package: bluez
Version: 5.23-2+rpi2
Architecture: armhf
[略]

如果版本夠新,就可以直接用 apt 安裝 BlueZ:

sudo apt-get install bluez

檢查安裝的 BlueZ 套件版本:

dpkg --status bluez | grep '^Version:'

從原始碼編譯安裝 BlueZ

在編譯 BlueZ 時會需要許多的系統函式庫,這些可用 apt 來安裝:

sudo apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev

準備好編譯環境之後,接著從 BlueZ 官方網站下載最新的原始碼:

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

解壓縮 BlueZ 原始碼:

tar Jxvf bluez-5.43.tar.xz
cd bluez-5.43/

編譯 BlueZ:

./configure --disable-systemd
make

編譯完成後,要不要安裝都可以:

sudo make install

若不安裝的話,可直接從 tools 目錄中取的所需的執行檔。

以藍牙發送 iBeacon 訊號

hciconfig 檢查自己的藍牙設備是否有正常被偵測到,我這裡的測試環境是第三代的樹莓派,所以有內建的藍牙裝置,如果是比較舊的樹莓派,則可另外安插 USB 的藍牙傳輸器,用法也都相同:

hciconfig
hci0:   Type: BR/EDR  Bus: UART
        BD Address: B8:27:EB:FE:07:91  ACL MTU: 1021:8  SCO MTU: 64:1
        DOWN 
        RX bytes:661 acl:0 sco:0 events:34 errors:0
        TX bytes:423 acl:0 sco:0 commands:34 errors:0

如果藍牙裝置的狀態處於未啟用的狀態(DOWN),可先將其啟用:

sudo hciconfig hci0 up

確認藍牙裝置處於 UP RUNNING 的狀態:

hciconfig
hci0:   Type: BR/EDR  Bus: UART
        BD Address: B8:27:EB:FE:07:91  ACL MTU: 1021:8  SCO MTU: 64:1
        UP RUNNING 
        RX bytes:5547 acl:0 sco:0 events:309 errors:0
        TX bytes:5754 acl:0 sco:0 commands:309 errors:0

啟用藍牙的低耗能廣告(LE advertising)模式,並關閉掃描功能:

sudo hciconfig hci0 leadv 3
sudo hciconfig hci0 noscan

設定要送出的 iBeacon 資料:

sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 C8 00
< HCI Command: ogf 0x08, ocf 0x0008, plen 32
  1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F
  17 D1 AD 07 A9 61 00 00 00 00 C8 00
> HCI Event: 0x0e plen 4
  01 08 20 00

這行指令指定的是封包的原始資料,比較跟使用者有關的有以下幾個欄位:

欄位 長度 說明 實際值(十六進位)
ID uint8_t 固定值 02
資料長度 uint8_t payload 長度 15
UUID uint8_t[16] 128 bits 的 UUID 值 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
Major uint16_t Major 值 00 00
Minor uint16_t Minor 值 00 00
TX Power uint8_t[16] 傳送訊號的強度 C8

我們可以使用 Wireshark 來將實際送出的封包抓下來看,封包中每個位置的欄位解釋可以從 Wireshark 中查看:

Wireshark

這時候我們就可以用手機上的 Beacon Scanner App 來檢查 iBeacon 的訊號了。

Beacon Scanner App

linux-ibeacon

linux-ibeacon 是一個以 Python 寫成的指令稿,可以讓使用者非常簡單地在 Linux 系統上以藍牙設備建立 iBeacon 發射器。

名稱:linux-ibeacon
描述:快速建立 iBeacon 的 Python 指令稿
網址:GitHub

使用這個 Python 指令稿可以很方便的指定各個 iBeacon 資料欄位,不需要自己換算十六進位碼:

sudo python ibeacon \
  --uuid=E20A39F473F54BC4A12F17D1AD07A961 \
  --major=123 --minor=456
Advertising on hci0 with:
       uuid: 0xE20A39F473F54BC4A12F17D1AD07A961
major/minor: 123/456 (0x007B/0x01C8)
      power: 200 (0xC8)
LE set advertise enable on hci0 returned status 12

這是從手機上接收到的訊號:

Beacon Scanner App

除了蘋果公司的 iBeacon 之外,Beacon 應用中其實還有其他的標準,例如 Google 所推出的 Eddystone 格式就比 iBeacon 更有彈性,還可以傳送 URL 網址,打造實體網頁,這部份可參考樹莓派 Raspberry Pi 以 Eddystone 傳送 URL 的教學文章。

參考資料:adafruitMUO
orange narwhalsIT 技術家阿舍