web-dev-qa-db-ja.com

hcitool lescanのようなbluetoothctlを使用して繰り返し近接ビーコンを報告する方法

--duplicatesフラグを指定してhcitool lescanを使用すると、近くの2つのBLEデバイスから定期的にLEアドバタイジングレポート(近接ビーコン)をキャプチャできます。

$ Sudo hcitool lescan --duplicates
LE Scan ...
C8:0F:10:29:4D:98 MI1S
C8:0F:10:29:4E:75 MI1S
C8:0F:10:29:4E:75 MI1S
C8:0F:10:29:4D:98 MI1S
C8:0F:10:29:4E:75 MI1S
C8:0F:10:29:4D:98 MI1S
<snip>

次に、そのスキャンを再度示します。周期性を示すためにタイムスタンプが追加されています。

$ Sudo stdbuf -i0 -o0 -e0 hcitool lescan --duplicates | Perl -nle 'print scalar(localtime), " ", $_'
Wed Apr 13 13:46:45 2016 LE Scan ...
Wed Apr 13 13:46:46 2016 C8:0F:10:29:4E:75 MI1S
Wed Apr 13 13:46:47 2016 C8:0F:10:29:4D:98 MI1S
Wed Apr 13 13:46:48 2016 C8:0F:10:29:4E:75 MI1S
Wed Apr 13 13:46:48 2016 C8:0F:10:29:4D:98 MI1S
Wed Apr 13 13:46:50 2016 C8:0F:10:29:4D:98 MI1S
Wed Apr 13 13:46:52 2016 C8:0F:10:29:4E:75 MI1S
<snip>

先週のEmbedded Linux ConferenceとIoT Summit(2016年4月)で、BlueZスタックで作業するプレゼンターは、hcitoolを使用せず、代わりにbluetoothctlを使用すると述べました。

今日試してみましたが、デバイスの最初のLEアドバタイズレポートのみが表示されます(--duplicatesオプションなしでhcitoolが行うように):

$ Sudo bluetoothctl
[NEW] Controller 5C:F3:70:62:68:28 BlueZ 5.38 [default]

[bluetooth]# power on
Changing power on succeeded
[CHG] Controller 5C:F3:70:62:68:28 Powered: yes

[bluetooth]# scan on
Discovery started
[CHG] Controller 5C:F3:70:62:68:28 Discovering: yes
[CHG] Device C8:0F:10:29:4E:75 RSSI: -72
[CHG] Device C8:0F:10:29:4D:98 RSSI: -65

[bluetooth]# devices
Device C8:0F:10:29:4D:98 MI1S
Device C8:0F:10:29:4E:75 MI1S

Bluetoothctlをどのように使用して、hcitoolが--duplicatesオプションで行うように、同じデバイスから繰り返しLE広告レポートをキャプチャしますか?

14
jfathman

あなたの提案をフロリアンに感謝します。

元の投稿以来、bluez 5.42を含むUbuntu 16.04.4組み込みLinuxディストリビューションに移行しました。残念ながら、このバージョンのbluetoothctlは「メニュースキャン」または「クリア」を認識しません。

[bluetooth]# menu scan
Invalid command

[bluetooth]# clear
Invalid command

ただし、「ほとんどの広告をブロックするデフォルトのスキャンフィルターアクティブ」の言及に勇気づけられて、-help出力で見られるように、私のバージョンのbluetoothctlで利用可能なコマンドを実験し、何かが機能するようにしました:

root@iot:~# bluetoothctl
[NEW] Controller 00:1A:7D:DA:71:13 iot #1 [default]
[NEW] Controller 70:2C:1F:31:F4:AF iot 

[bluetooth]# set-scan-filter-clear
SetDiscoveryFilter success

[bluetooth]# set-scan-filter-transport le
SetDiscoveryFilter success

[bluetooth]# scan on
Discovery started

[CHG] Controller 00:1A:7D:DA:71:13 Discovering: yes
[NEW] Device 0F:64:64:EE:E7:C4 0F-64-64-EE-E7-C4
[NEW] Device 0D:6F:45:77:87:F3 0D-6F-45-77-87-F3
[NEW] Device 40:CB:C0:F2:96:27 40-CB-C0-F2-96-27
[CHG] Device 0D:6F:45:77:87:F3 RSSI: -71
[CHG] Device FC:F1:36:73:77:B3 RSSI: -57
[CHG] Device 0F:64:64:EE:E7:C4 RSSI: -49

Bluetoothctlに入力するのに少し時間がかかり、希望どおりに構成することができます。また、ビーコンの多い環境では、bluetoothctlのロギングアクティビティによって入力がすぐに不明瞭になります。そこで、ヒアドキュメントを使用するbashスクリプトをまとめ、コマンドをbluetoothctlにフィードし、sed/grep/Perlが出力をマッサージすることを期待します。

$ cat beacon-scan.sh 
#!/bin/bash

# beacon-scan.sh
# Displays beacons including duplicates in real time.
# Uses expect to automate interaction with bluetoothctl.
# Uses sed to remove bluetoothctl colorization escape characters.
# Uses grep to filter out beacon manufacturer data logging.
# Uses Perl to prefix each beacon with a timestamp.

if [ "$(id -u)" != "0" ]; then
    echo "ERROR: must run as root"
    exit 1
fi

(cat <<'END' | /usr/bin/expect

    set Prompt "#"
    set timeout -1

    spawn bluetoothctl

    expect -re $Prompt
    send "scan off\r"

    expect -re $Prompt
    send "remove *\r"

    expect -re $Prompt
    send "set-scan-filter-clear\r"

    expect -re $Prompt
    send "set-scan-filter-transport le\r"

    expect -re $Prompt
    send "scan on\r"

    trap {
        expect -re $Prompt
        send "scan off\r"

        expect -re $Prompt
        send "remove *\r"

        expect -re $Prompt
        send "quit\r"
    } SIGINT

    expect eof

END
) | sed --unbuffered --quiet --expression 's/^.*Device //p' \
  | grep --line-buffered -v ManufacturerData \
  | Perl -nle 'print scalar(localtime), " ", $_'

できます:

$ Sudo ./beacon-scan.sh 
Wed Aug 22 19:34:07 2018 0F:64:64:EE:E7:C4 RSSI: -59
Wed Aug 22 19:34:07 2018 03:46:00:1D:E9:91 03-46-00-1D-E9-91
Wed Aug 22 19:34:07 2018 4E:20:6B:C7:68:D0 RSSI: -55
Wed Aug 22 19:34:07 2018 76:F1:1A:B9:ED:28 RSSI: -57
Wed Aug 22 19:34:07 2018 32:5D:8C:6A:72:C2 32-5D-8C-6A-72-C2
^C

繰り返し発生するビーコンがbluetoothctlによって報告されるようになりました。これは、hcitool lescanがduplicatesフラグを指定して実行された場合と同様です。

対話的に構成したり、より複雑なスクリプトに頼らなくても、コマンドラインからbluetoothctlを構成できれば、bluetoothctlの方が使いやすいと思います。

あなたの助けをありがとうフローリアン。

4
jfathman

ちょうど私のために機能する次のものを見つけました(Ubuntu 18.04.1、bluez 5.48):

$ bluetoothctl
[bluetooth]# scan on
[bluetooth]# menu scan
[bluetooth]# clear
SetDiscoveryFilter success
[NEW] Device de:ad:be:ef:ca:fe SampleDev
[CHG] Device de:ad:be:ef:ca:fe RSSI: -73
[CHG] Device de:ad:be:ef:ca:fe RSSI: -73
[CHG] Device de:ad:be:ef:ca:fe RSSI: -74

ほとんどの広告をブロックするデフォルトのスキャンフィルターがアクティブになっているようです。

2
Florian Echtler