ブログ

Armadillo-640:BT/THオプションモジュールを使用してビーコンデータを収集する

at_takuma.fukuda
2021年11月29日 7時29分

以下のサンプルプログラムを参考に、
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'}