⚡
python:汎用のBLEドングルでアドバタイズの簡易解析
昔書いていたBLE通信の解析用Pythonスクリプトがあったので、備忘録として残しておきます。
BLE機器と手軽にやりとりしたい人向けに、安価なBLEドングル(BLED112)を使ってアドバタイズパケットの中身をシリアル通信で解析する方法です。
使用機器
-
BLED112
Silicon Labs製のUSBドングル。ATコマンドまたはBGAPI(シリアルバイナリ)でBLE通信が可能。

アリエク...
一応、BLEとはBluetooth Low Energyで省電力bluetoothの規格ですね。オーディオとか大容量でなければふつうはBLEの認識です。
スキャン開始コマンド
sendData = [0,1,6,2,2]
これは BGAPI 形式で以下のような意味になります:
| バイト | 値 | 意味 |
|---|---|---|
| 0 | 0x00 | コマンド種別(Command) |
| 1 | 0x01 | ペイロード長 |
| 2 | 0x06 | クラスID(le_gap) |
| 3 | 0x02 | コマンドID(le_gap_set_discovery_type) |
| 4 | 0x02 | モード(0x02 = observation) |
→ BLEのアドバタイズを受信するモードを設定します。
アドバタイズの受信形式
BLED112から受信するデータは、以下のような構造をしています:
| フィールド名 | 内容 |
|---|---|
type |
メッセージ種別(例:0x80 = イベント) |
length |
ペイロードの長さ |
class |
クラスID(例:0x06 = le_gap) |
id |
コマンドID(例:0x02 = scan_response) |
rssi |
RSSI 受信信号強度(例:0xB2 = -78 dBm) |
ad_type |
アドバタイズの種別(active/passive) |
bd_address |
発信元デバイスのアドレス(6バイト) |
data |
アドバタイズパケット本体(AD Structure) |
アドバタイズの解析用途
例えば、スマホや安価なビーコンをアドバタイズ発信源として使えば:
-
bd_addressでデバイス識別 -
rssiで信号強度を取得(簡易的な距離推定に利用可能)
RSSIは環境やデバイスの送信電力(Tx Power)によって変動するため、正確な距離測定には向かないですが、近接検知などの簡易用途くらいなら十分かなと。
コード抜粋(通信と解析)
ser = serial.Serial('/dev/tty.usbmodem11', 115200)
sendData = [0,1,6,2,2]
ser.write(sendData)
while True:
if ser.inWaiting() > 0:
type = ser.read(1)
length = ser.read(1)
class_ = ser.read(1)
id_ = ser.read(1)
rssi = ser.read(1)
ad_type = ser.read(1)
bd_address = ser.read(6)
data_len = int(length.encode('hex'), 16) - 8
data = ser.read(data_len)
print("BD Address:", bd_address.encode('hex'))
print("RSSI:", int(rssi.encode('hex'), 16))
print("Data:", data.encode('hex'))
まとめ
- 安価なBLEドングル(BLED112)でも、Python+シリアル通信で簡易的にアドバタイズの中身が取れる。
- 接続せずに受信だけなので、BLEの基本動作を知る上でも便利。
- RSSI使ってちょっとした測距やデバイス検出用途にも応用可能。
次回予告
次は接続してのGATT通信や、値の読み書きなど「connect以降」について、ソフトがあれば試して記事化したいと思います。
Discussion