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