#はじめに
BLEのアドバタイズパケットをスキャンして中のデータがどうなっているか調べた時のメモです
#参考
-
オライリー Bluetooth Low Energyをはじめよう
Webの情報だけではかなりわかりづらかったですが、この本をみるとかなりスッキリするのでモヤモヤしている方は読むことをお勧めします
#環境
- OS=Windows10
- 開発環境=Visual Studio 2015
- C#
- .Net Framework 4.6.1
- WPFアプリケーション
- BLEデバイス
- iPhone Light Blue-Explorer でのVirual Peripherals(BLEデバイスエミュレータ)UUID
#プログラム
GitHubにソース上げています。
コチラ
#解説
要は BluetoothLEAdvertisementReceivedEventArgs の中はどうなっているのか、という話ですね。
以下でメンバの説明を簡単にします。
Timestamp
スキャン日時
BluetoothAddress
アドバタイズパケット発信元の Bluetoothデバイスアドレス
48bit(6byte)
RawSignalStrengthInDBm
シグナル強度、いわゆるRSSI。数値が大きいほどシグナルが強い、近くから発信されている、ということ。
AdvertisementType
- アドバタイズパケットの種別
- BluetoothLEAdvertisementTypeのenum
- コネクト可能とか、スキャン可能とかわかる。ここでコネクト×になっているデバイスへはコネクトしてもエラーになるだけとおもわれます。
スキャンしてGETしているのでスキャン×の場合はとれないはずかとおもわれますです。- スキャン可能のときはスキャン要求して追加情報を取得することができます。(詳細はこの次のセクションで)
定義 | 説明 | Bluetooth LE仕様での定義 |
---|---|---|
ConnectableUndirected | コネクション可能、スキャン可能 | ADV_IND |
ConnectableDirected | コネクション可能、スキャン× | ADV_DIRECT_IND |
ScannableUndirected | コネクション×、スキャン可能 | ADV_SCAN_IND |
NonConnectableUndirected | コネクション×、スキャン× | ADV_NONCONN_IND |
ScanResponse | スキャン要求に対するスキャン応答 | SCAN_RSP |
スキャン要求/応答について
- アドバタイズパケットは最大サイズが決まっていて、より多くの情報をアドバタイズする方法として「スキャン要求」があります。
-
AdvertisementType
がConnectableUndirected
、ScannableUndirected
なパケットはスキャン要求⇒スキャン応答として追加情報をGETできます。 - スキャン要求の結果として
ScanResponse
で追加データがGETできます。 - **じゃあ、どうやってスキャン要求するのか?**ということですが、アドバタイズを開始するときに設定すると自動的にスキャン要求してその応答をGETしてくれます。(楽)
- 具体的には
BluetoothLEAdvertisementWatcher
でStart()
する前にScanningMode
にBluetoothLEScanningMode.Active
をセットするだけです。 - 詳細はGitHubのソースにも書いてあります。
スキャン応答受信_ScanningModeをアクティブスキャンにする
// https://docs.microsoft.com/ja-jp/windows/uwp/devices-sensors/ble-beacon よりPickUp
BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();
watcher.Received += OnAdvertisementReceived;
watcher.ScanningMode = BluetoothLEScanningMode.Active;
watcher.Start();
Advertisement.DataSections
- アドバタイズデータ本体
- リスト構造で複数データあり
- データ数=Advertisement.DataSections.Count
- 各データはBluetoothLEAdvertisementDataSectionクラス
- プログラムで処理するとき、中を一個一個なめていくのはめんどいですよね。よく使われるものは別のメンバに展開されているのでそちらをみるといいです。
データ(BluetoothLEAdvertisementDataSection)
DataType
- データの種類を示す1byteのデータ
- AD TypeとしてBLE仕様で定義されている、一覧はBLE仕様を参照のこと
- よく使われるAD Type
DataType | 定義 | 説明 | 備考 |
---|---|---|---|
0x01 | Flags | 設定情報 | Advertisement.Flagsに展開されている |
0x03 | Service UUID | サービスUUID、1個辺り2byteで複数個入っている場合がある | Advertisement.ServiceUuidsに展開されている |
0x08 | Local Name | デバイスの名前(UTF8 - Shortened local name) | Advertisement.LocalNameに展開されている |
0x09 | Local Name | デバイスの名前(UTF8 - Complete local name) | Advertisement.LocalNameに展開されている |
0xFF | Manufacture Specific | 先頭2バイトがBluetooth SIGが企業に発行した識別子、以降は任意長のバイナリ・データ | Advertisement.ManufacturerDataに展開されている |
- サービスUUIDについて
- BLEデバイスがどんな機能(サービス)を持っているかを示す
- BLE仕様で定義されている2Byteの値
- サービスUUIDの一覧は以下BLE仕様を参照すべし
Data
- DataTypeに対応するデータ
- Data.Lengthがデータのバイト数
- Windows.Storage.Streams.DataReaderをつかってデータを読み出しましょう
Advertisement.Flags
- DataType=0x01のFlagsデータがここにBluetoothLEAdvertisementFlagsというEnumに展開されて入っています
- これの意味がまだわかりません・・・
- マイクロソフトの説明 → BluetoothLEAdvertisementFlags Enum
Advertisement.LocalName
- DataType=0x08 または 0x09 のLocalNameデータがここにstring展開されて入ります
- データセクションでどっちがあるかわかりませんが、ええ感じにチョイスしていれてくれるようです
- なので、DataType=0x08とか0x09のデータをいちいち検索する必要はないです
Advertisement.ServiceUuids
- DataType=0x03のサービスUUIDデータがここに展開されて入っています
Advertisement.ManufacturerData
- DataType=0xFFのフリーデータがここに展開されて入っています
- CompanyIdに企業識別子が入っている。なので、企業識別子の2Byte分はここに、3Byte目以降がDataメンバにちゃんと分割されて入ってます
- 企業識別子の一覧は以下BLE仕様を参照すべし
- ちなみにiBeaconはこの中にデータを格納しています
おつかれさまでした
BLEはWebの情報があまりないので苦労しますが、まとめてしまうとけっこう簡単です。
もっとわかりやすいまとめサイトがほしいところです。