とある案件の基礎段階で、Bluetoothの受信を研究しています。
Bluetooth® Low Energy(BLE)機器の多くは、自分の存在や情報を周囲へ知らせるため、「Advertisement(アドバタイズメント)」と呼ばれる告知データを定期的に送信しています。
Python+WinRTを使って、受信したAdvertisementを取り出し、BLEアドレス、RSSI、Local Name、AD Type、RAWデータを取りだしてみました。
サンプルコード
まずはパッケージの導入
pip install winrt-Windows.Devices.Bluetooth.Advertisement
pip install winrt-Windows.Storage.Streams上は、Windowsが持っているBLEのAdvertisement送受信機能
下は、Windows Runtimeで扱われるバイナリデータ(バッファやストリーム)を読み書きするため
です
(※この解説中、ライセンス表記などは省略しています)
from winrt.windows.devices.bluetooth.advertisement import (
BluetoothLEAdvertisementWatcher,
BluetoothLEScanningMode,
)
from winrt.windows.storage.streams import DataReader
def read_buffer(buffer):
reader = DataReader.from_buffer(buffer)
data = bytearray(reader.unconsumed_buffer_length)
reader.read_bytes(data)
reader.close()
return bytes(data)
def format_address(address):
text = f"{address:012X}"
return ":".join(text[i:i + 2] for i in range(0, 12, 2))
def on_received(sender, args):
ad = args.advertisement
data_list = []
for i in range(len(ad.data_sections)):
section = ad.data_sections[i]
raw = read_buffer(section.data)
data_list.append(
f"0x{section.data_type:02X}:{raw.hex(' ').upper()}"
)
print(
f"{format_address(args.bluetooth_address)} "
f"RSSI={args.raw_signal_strength_in_d_bm:4d} dBm "
f"NAME={ad.local_name or '-'} "
f"AD={' | '.join(data_list) or '-'}"
)
watcher = BluetoothLEAdvertisementWatcher()
watcher.scanning_mode = BluetoothLEScanningMode.ACTIVE
watcher.add_received(on_received)
watcher.start()
print("BLE Advertisementを受信中です。Enterで終了します。")
try:
input()
except KeyboardInterrupt:
pass
watcher.stop()WatcherとReceivedイベント
- BluetoothLEAdvertisementWatcherがWindowsのBLE Advertisement受信機能への入口です。
- Active scanでは、対応機器からScan Responseも受信できる場合があります。
- add_receivedで、Advertisementを受信するたびに呼ばれる関数(on_received)を登録します。
- 終了時にはWatcherを停止します。
BLEアドレスとRSSI
- Windowsから渡されるアドレスは整数なので、`format_address`で`AA:BB:CC:DD:EE:FF`形式にします。BLEではプライバシー保護のためアドレスが変化する機器もあり、アドレスだけで同じ物理機器だと断定はできません。
- RSSIは受信信号強度ですが、距離の厳密な測定値ではありません。機器の向き、遮蔽物、反射、送信出力でも変化します。
IBufferとRAWデータ
- Advertisementの各データ部分はWinRTのIBufferとして渡されます。read_bufferはDataReaderでPythonのbytesへコピーし、最後にReaderを閉じます。
- data_sectionsはWinRTのコレクションです。このサンプルは要素番号で取り出します。
- 各セクションはAD Type:RAWデータとして表示します。AD Typeに標準的な意味があっても、データ内部がメーカー独自または個別規格である場合があります。
取得できるのは、Windows APIがアプリへ渡したBLE Advertisement情報です。Bluetooth Classic、接続後のGATT通信全体、暗号化された接続データ、無線リンク層の全チャネル、他機器同士の通信は表示できません。
実行結果
BLE Advertisementを受信中です。Enterで終了します。
AA:BB:CC:DD:EE:01 RSSI= -66 dBm NAME=- AD=0x01:06 | 0xFF:E0 07 XX XX XX XX | 0x03:03 40
AA:BB:CC:DD:EE:01 RSSI= -67 dBm NAME=EDIFIER BLE AD=0x09:45 44 49 46 49 45 52 20 42 4C 45
AA:BB:CC:DD:EE:02 RSSI= -58 dBm NAME=- AD=0xFF:06 00 XX XX XX XX XX XXこんな感じで出力されます。
この表示から、周囲に少なくとも2台のBLE機器があり、電波を受信できていることがわかります。
AA:BB:CC:DD:EE:01などは機器を識別するためのBluetoothアドレス、RSSIは受信した電波の強さで、一般に0に近いほど強いことを示します。上の2行は同じBluetoothアドレスから受信したデータです。
NAMEから「EDIFIER BLE」という機器名も確認できます。
ADには、機器が周囲へ発信している各種情報が16進数で表示されています。
セキュリティとプライバシー
受信専用でも、BLEアドレス、Local Name、Manufacturer Dataなどは機器や場所の識別につながることがあります。
- 自分が管理する場所、または許可を得た環境で使用してください
- 人の追跡、認証回避、秘密情報の収集に使用しないでください
- 実在するアドレスやRAW値をWebへ載せる際は匿名化してください
- 法令、施設規則、機器の利用条件に従ってください
免責事項
本記事および掲載コードは、BLE Advertisementの受信方法を技術的に解説することを目的としたものです。動作や正確性、安全性を保証するものではありません。利用にあたっては、関連する法令、施設の規則、機器の利用条件等をご確認のうえ、ご自身の責任でご利用ください。本記事および掲載コードの利用によって生じた損害について、当社は責任を負いかねます。
ライセンスと商標
掲載コードとダウンロードサンプルはMIT Licenseです。PyWinRTもMIT Licenseですが、本サンプルとは別のプロジェクトです。公開・再配布時には各ライセンスを確認してください。
Bluetooth®のワードマークおよびロゴはBluetooth SIG, Inc.が所有する登録商標です。本記事およびサンプルはBluetooth SIG, Inc.の承認、提携または認定を示すものではありません。
応用アプリ:BLEInspector
ここまで紹介したBLE Advertisementの受信処理を応用して、周辺のBLE機器をGUIで確認できるWindowsアプリ「BLEInspector」を作成しました。
BLEアドレス、RSSI、Local Name、AD Type、Manufacturer Data、Service Data、UUID、RAWデータなどを画面上で確認できます。
Pythonの実行環境を用意せずに使用できるWindowsアプリとして公開します。
動作環境:Windows 11
[BLEInspectorをダウンロード(zip形式)] (http://sketlab.jp/download/BLEInspector/BLEInspector_0.3.0_Windows_x64.zip)
ファイル名:BLEInspector_0.3.0_Windows_x64.zip
SHA-256ハッシュ値:
AB7C69B30FD3B7B9FD57AEB697D332783EF8817F1E7CAC3546C39B18E7479D92
[ハッシュ値チェッカーを開く]
(https://sketlab.jp/script/Javascript/sha256-check.html)
ハッシュ値チェッカーでダウンロードしたZIPを選択し、上記のSHA-256ハッシュ値を入力すると、ファイルが配布時のものと一致するか確認できます。
ダウンロード後はZIPを展開し、フォルダー内の`BLEInspector.exe`を起動してください。
使い方詳細は同梱しているマニュアルを良くお読みください。
※本アプリはBLE Advertisementの観察・解析を目的としたツールです。使用にあたっては、本ページ記載の「セキュリティとプライバシー」および「免責事項」をご確認ください。
参考資料
Microsoft Learn:BluetoothLEAdvertisementWatcher.Received
Microsoft Learn:Bluetooth LE advertisements
PyWinRT公式リポジトリ
Bluetooth SIG:Brand and trademarks