以下のサンプルプログラムを参考に、
Armadillo-640とBT/THオプションモジュールを使って、
周囲のビーコン情報をスキャンするアプリケーションを構築しました。
BLE iBeacon Scanner - iBeacon and Eddystone Beacons
まずは以下のように実行環境を整えます。
armadillo:~# apt-get install python3-pip python3-dev ipython armadillo:~# apt-get install bluetooth libbluetooth-dev armadillo:~# pip3 install pybluez
公開されているサンプルプログラムは、以下の2つのファイルに分かれます。
ScanUtility.py
BeaconScanner.py
ScanUtility.pyでhciコマンドの実行や取得したパケットの解析を行う関数を定義しており、
BeaconScanner.pyが実行用のファイルとなっています。
さっそくそれぞれのファイルをコピーして以下のコマンドで実行してみます。
armadillo:~# python3 BeaconScanner.py
本来なら取得したビーコン情報が列挙されるはずなのですが、
以下の表示のまま固まってしまいます。
*** Looking for BLE Beacons *** *** CTRL-C to Cancel ***
btmonを実行して動作を確認すると以下のようになります。
armadillo:~# btmon & [1] 558 armadillo:~# Bluetooth monitor ver 5.50 = Note: Linux version 4.14-at35 (armv7l) 0.579420 = Note: Bluetooth subsystem version 2.22 0.579440 = New Index: XX:XX:XX:XX:XX:XX (Primary,USB,hci0) [hci0] 0.579445 = Open Index: XX:XX:XX:XX:XX:XX [hci0] 0.579448 = Index Info: XX:XX:XX:XX:XX:XX (not assigned) [hci0] 0.579454 @ MGMT Open: bluetoothd (privileged) version 1.14 {0x0001} 0.579458 @ MGMT Open: btmon (privileged) version 1.14 {0x0002} 0.579527 armadillo:~# python3 BeaconScanner.py @ RAW Open: python3 (privileged) version 2.22 {0x0003} [hci0] 3.358681 *** Looking for BLE Beacons *** *** CTRL-C to Cancel *** < HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2 #1 [hci0] 3.359573 Scanning: Enabled (0x01) Filter duplicates: Disabled (0x00) > HCI Event: Command Complete (0x0e) plen 4 #2 [hci0] 3.360811 LE Set Scan Enable (0x08|0x000c) ncmd 1 Status: Command Disallowed (0x0c)
これを見ると、LE Set Scan Enableコマンドを実行したものの正常に実行できず止まってしまっているようです。
比較として、hcitool lescanコマンドを実行した場合の動作結果は以下のようになります。
armadillo:~# hcitool lescan @ RAW Open: hcitool (privileged) version 2.22 {0x0003} 5.571663 @ RAW Close: hcitool {0x0003} 5.572083 @ RAW Open: hcitool (privileged) version 2.22 {0x0003} [hci0] 5.572473 < HCI Command: LE Set Scan Parameters (0x08|0x000b) plen 7 #1 [hci0] 5.572751 Type: Active (0x01) Interval: 10.000 msec (0x0010) Window: 10.000 msec (0x0010) Own address type: Public (0x00) Filter policy: Accept all advertisement (0x00) > HCI Event: Command Complete (0x0e) plen 4 #2 [hci0] 5.573866 LE Set Scan Parameters (0x08|0x000b) ncmd 1 Status: Success (0x00) < HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2 #3 [hci0] 5.574339 Scanning: Enabled (0x01) Filter duplicates: Enabled (0x01) > HCI Event: Command Complete (0x0e) plen 4 #4 [hci0] 5.575843 LE Set Scan Enable (0x08|0x000c) ncmd 1 Status: Success (0x00)
こちらを見ると「LE Set Scan Enable」を実行する前に、
「LE Set Scan Parameters」を実行しています。
なので、サンプルプログラムも「LE Set Scan Parameters」を行うよう修正してみます。
ScanUtillity.pyに以下を追加します。
OGF_LE_SET_SCAN_PARAMETERS=0x000b def hci_le_set_scan_parameters(sock): cmd_pkt = struct.pack("<BHHBB",0x01,0x0010,0x0010,0x00,0x00) bluez.hci_send_cmd(sock, OGF_LE_CTL, OGF_LE_SET_SCAN_PARAMETERS, cmd_pkt)
さらに、BeaconScanner.pyの「ScanUtility.hci_enable_le_scan(sock)」の直前に以下を追加します。
ScanUtillity.hci_le_set_scan_parameters(sock)
上記適用した上で再度実行すると、
以下のように周囲のビーコンのUUID・Major・Minor等が表示されるようになります。
armadillo:~# python3 BeaconScanner.py *** Looking for BLE Beacons *** *** CTRL-C to Cancel *** {'type': 'iBeacon', 'uuid': 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', 'major': XX, 'minor': XX, 'rssi': -81, 'macAddress': 'XX:XX:XX:XX:XX:XX'}