Raspberry pi 3でiBeaconを受信するソフトを作成しました。Raspberry pi 3のRaspbian「buster」上でPython3言語、ライブラリ「 beacontools」を使用し、iBeaconはAndroid アプリ「 Beacon Simulator」を使用しました。

iBeaconの仕様

セントラルとしてアドバタイズ((定期的に情報を送信モード))をスキャン(アドバタイズをリッスンするモード)して、下記の特徴に当てはまるものを取得すればiBeaconを列挙できます。

内容
1A AD Structureの長さ
FF ADのタイプ
4C 00 企業識別子 0x004C(Apple)
02 iBeacon 識別子
15 iBeacon 識別子
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX UUID
XXXX major
XXXX minor
XX Power

Android アプリ「 Beacon Simulator」の設定

Android アプリ「 Beacon Simulator」を使って次のiBeaconを発生します。

uuid: 93c896d7-5a9e-45e1-92db-57b155cf576d
major: 1
minor: 2
tx_power: -80

Bluezのhcidump ユーティリティによるiBeaconのデータ表示

Bluezのhcidumpコマンドは、ターミナル上の Bluetooth パケットの内容を16進ダンプ表示します。「sudo hcitool lescan」コマンドでBLEスキャンします。

$  sudo hcidump -R &
[1] 1558
HCI sniffer - Bluetooth packet analyzer ver 5.50
device: hci0 snap_len: 1500 filter: 0xffffffff
sudo hcitool lescan
< 01 0B 20 07 01 10 00 10 00 00 00
> 04 0E 04 01 0B 20 00
< 01 0C 20 02 01 01
> 04 0E 04 01 0C 20 00
LE Scan ...
> 04 3E 1A 02 01 00 01 CA A0 41 5D BB 44 0E 02 01 1A 0A FF 4C
44:BB:5D:41:A0:CA (unknown)
  00 10 05 03 1C 4D 6C 5B B9
7E:4A:B2:CB:24:E9 (unknown)
> 04 3E 27 02 01 03 01 E9 24 CB B2 4A 7E 1B 1A FF 4C 00 02 15
  93 C8 96 D7 5A 9E 45 E1 92 DB 57 B1 55 CF 57 6D 00 01 00 02
  B0 C0
45:D0:E0:29:5B:BA (unknown)
> 04 3E 1A 02 01 00 01 BA 5B 29 E0 D0 45 0E 02 01 1A 0A FF 4C
  00 10 05 03 1C C4 BD 84 9E

ライブラリ「 beacontools」のインストール

ライブラリ「 beacontools」を次の手順でインストールします。

# install libbluetooth headers and libpcap2
sudo apt-get install python3-dev libbluetooth-dev libcap2-bin
# grant the python executable permission to access raw socket data
sudo setcap 'cap_net_raw,cap_net_admin+eip' "$(readlink -f "$(which python3)")"
# install beacontools with scanning support
pip3 install beacontools[scan]

BeaconScannerアプリの作成

サンプルスクリプト「BeaconScanner」を次に示します。

beacon.py

import time

from beacontools import BeaconScanner, IBeaconFilter, IBeaconAdvertisement

def callback(bt_addr, rssi, packet, additional_info):
    print("<%s, %d> %s %s" % (bt_addr, rssi, packet, additional_info))

# scan for all iBeacon advertisements from beacons with certain properties:
# - uuid
# - major
# - minor
# at least one must be specified.
scanner = BeaconScanner(callback, 
    device_filter=IBeaconFilter(uuid="e5b9e3a6-27e2-4c36-a257-7698da5fc140")
)
scanner.start()
time.sleep(5)
scanner.stop()

# scan for all iBeacon advertisements regardless from which beacon
scanner = BeaconScanner(callback,
    packet_filter=IBeaconAdvertisement
)
scanner.start()
time.sleep(5)
scanner.stop()

BeaconScannerアプリの実行

作成したサンプルスクリプト「BeaconScanner」を次のように実行します。hcidumpコマンドによる16進ダンプ表示と、対象とするiBeaconパケットを次のように表示します。

$ python3 beacon.py
> 04 3E 1B 02 01 00 00 3D 98 F3 81 56 70 0F 02 01 1A 0B FF 4C
  00 09 06 02 87 0A 00 01 07 A4
> 04 3E 0C 02 01 04 00 3D 98 F3 81 56 70 00 A4
> 04 3E 27 02 01 03 01 2A 00 40 34 17 41 1B 1A FF 4C 00 02 15
  93 C8 96 D7 5A 9E 45 E1 92 DB 57 B1 55 CF 57 6D 00 01 00 02
  B0 C8
<41:17:34:40:00:2a, -56> IBeaconAdvertisement<tx_power: -80, uuid: 93c896d7-5a9e-45e1-92db-57b155cf576d, major: 1, minor: 2> {'uuid': '93c896d7-5a9e-45e1-92db-57b155cf576d', 'major': 1, 'minor': 2}
> 04 3E 27 02 01 03 01 2A 00 40 34 17 41 1B 1A FF 4C 00 02 15
  93 C8 96 D7 5A 9E 45 E1 92 DB 57 B1 55 CF 57 6D 00 01 00 02
  B0 B5
<41:17:34:40:00:2a, -75> IBeaconAdvertisement<tx_power: -80, uuid: 93c896d7-5a9e-45e1-92db-57b155cf576d, major: 1, minor: 2> {'uuid': '93c896d7-5a9e-45e1-92db-57b155cf576d', 'major': 1, 'minor': 2}
> 04 3E 1A 02 01 00 01 BA 5B 29 E0 D0 45 0E 02 01 1A 0A FF 4C
  00 10 05 03 1C C4 BD 84 9E
> 04 3E 1A 02 01 00 01 CA A0 41 5D BB 44 0E 02 01 1A 0A FF 4C
  00 10 05 03 1C 4D 6C 5B A0
> 04 3E 0C 02 01 04 01 CA A0 41 5D BB 44 00 9D
> 04 3E 27 02 01 03 01 2A 00 40 34 17 41 1B 1A FF 4C 00 02 15
  93 C8 96 D7 5A 9E 45 E1 92 DB 57 B1 55 CF 57 6D 00 01 00 02
  B0 B5
<41:17:34:40:00:2a, -75> IBeaconAdvertisement<tx_power: -80, uuid: 93c896d7-5a9e-45e1-92db-57b155cf576d, major: 1, minor: 2> {'uuid': '93c896d7-5a9e-45e1-92db-57b155cf576d', 'major': 1, 'minor': 2}
> 04 3E 1A 02 01 00 01 CA A0 41 5D BB 44 0E 02 01 1A 0A FF 4C
  00 10 05 03 1C 4D 6C 5B A0
> 04 3E 0C 02 01 04 01 CA A0 41 5D BB 44 00 9E
> 04 3E 27 02 01 03 01 2A 00 40 34 17 41 1B 1A FF 4C 00 02 15
  93 C8 96 D7 5A 9E 45 E1 92 DB 57 B1 55 CF 57 6D 00 01 00 02
  B0 C4
<41:17:34:40:00:2a, -60> IBeaconAdvertisement<tx_power: -80, uuid: 93c896d7-5a9e-45e1-92db-57b155cf576d, major: 1, minor: 2> {'uuid': '93c896d7-5a9e-45e1-92db-57b155cf576d', 'major': 1, 'minor': 2}