BLE デバイス間の通信内容をパケットレベルで読み解いてみる
- 技適マークつき BLE パケットスニファを入手する
BLE の通信プロトコルは複雑ですが、パケットの内容を適宜精査すれば 座学的な情報の向こう側にある実像を捉えることが可能となるでしょう。
デバイス A の UI
操作内容
デバイス A と Android 端末を使って以下の操作を行いスニファで BLE パケットのログを採取しました。
- デバイス A の電源を入れる
- Android 端末上の対向アプリからデバイスを探索しデバイス A との接続を確立
- アプリからデバイス A の LED+ブザーを ON にする
- デバイス A のボタンを押しアプリへ通知を送る
- アプリ上でデバイス A との接続を切断
応酬の全体像
スニファの Wireshark ログより
上の操作時に収集したパケットログの全体図です。 (クリックで大きく表示)
要約
パケットログの内容の要約を以下に示します。 (クリックで大きく表示)
- デバイス A の電源を入れる
- デバイス A がアドバタイジングを開始 (ADV_IND)
- スマホ上の対向アプリからデバイスを探索しデバイス A との接続を確立
- デバイスのスキャン (SCAN_REQ / SCAN_RSP) を経て接続要求 (CONNECT_REQ) 〜接続が確立するとデバイス A はアドバタイジングを停止
- 機能情報を交換 (LL_FEATURE_REQ / LL_FEATURE_RSP)
- デバイス A の提供する GATT プライマリサービス一覧を取得
- 各サービス配下のエントリ(Included Service, キャラクタリスティック)一覧を取得
- 各キャラクタリスティック配下のデスクリプタを取得
- デバイス A のボタンが押された時に通知されるよう所定の Client Characteristic Configuration descriptor へアプリから Notification Bit 0x0001 を書き込む
- アプリからデバイス A の LED+ブザーを ON にする
- アプリ上の所定のボタンが押されたタイミングでアプリはデバイス A の Immediate Alert サービス配下の Alert Level キャラクタリスティックへ値 2 (High Alert)を書き込む。これにより一定時間 A の LED とブザーが ON になる
- デバイス A のボタンを押しアプリへ通知を送る
- デバイス A のボタンが押されたタイミングでデバイス A は自機のユーザ定義サービス 1 (UUID=0xFFE0) 配下のユーザ定義キャラクタリスティック (UUID=0xFFE1) へ値 1 を書き込む。当該キャラクタリスティック配下の Client Characteristic Configuration descriptor にはアプリ側から予め Notification Bit がセットされているためアプリへ通知される
- アプリ上でデバイス A との接続を切断
- アプリからデバイス A へ LL_TERMINATE_IND を送る
応酬の詳細
全体の流れを見渡したところで次に個々のパケットデータを読み進めていきます。
- 以下の記事には Wireshark のスクリーンショットをログとして添えています (それぞれクリックで大きく表示)
- ログには BLE パケットデータ本体に加え nRF Sniffer が解析の便宜のためにログへ出力する「Nordic BLE sniffer meta」ヘッダが含まれています
- nRF Sniffer User Guide v1.1 (PDF) - www.nordicsemi.com Page 8 より
4 Using Wireshark All BLE packets detected by the Sniffer are passed to Wireshark and are wrapped in a header which contains useful meta-information not present in the BLE packet itself. Wireshark dissects the packets and separates the actual packet from the meta-information. :
- nRF Sniffer User Guide v1.1 (PDF) - www.nordicsemi.com Page 8 より
- 記事には下記資料からの抜粋へのリンクを参照用に適宜挿入しています
- BLUETOOTH SPECIFICATION Version 4.2 (PDF) - www.bluetooth.org
- 随所に「https://developer.bluetooth.org/gatt/」下のサービス・キャラクタリスティックの記事へのリンクを張っていますが、2016年7月頃までは参照可能だった各記事が現在はリンク切れになっており(再構成中?)、さらに現時点では代替ページが見当たらないためリンク先はやむなく http://web.archive.org/ 上のキャッシュとしています。ただし web.archive.org 上にも保存履歴のない記事については一階層上のページへのリンクを張っています
例:「Link Loss」サービスの単独ページのキャッシュは web.archive.org にも見当たらないため、上位のサービス一覧ページのキャッシュをターゲットに
局面
- Scene 1: デバイス A のアドバタイジングと SCAN_REQ / SCAN_RSP
- Scene 2: 接続の確立と情報交換
- Scene 3: デバイス A の GATT サービス群の取得
- Scene 4: デバイス A 各サービス配下のキャラクタリスティック - デスクリプタの取得
- Scene 5: デバイス A ボタン押下時のアプリへの通知を設定
- Scene 6: アプリからデバイス A の LED・ブザーを操作
- Scene 7: デバイス A のボタンを押すとアプリへ通知
- Scene 8: アプリ側からデバイス A との接続を切断
Scene 1: デバイス A のアドバタイジングと SCAN_REQ / SCAN_RSP
Frame 124 - 126 はデバイス A 発のアドバタイジングパケット
- 全 40 チャネルのうちアドバタイジングパケット用の 37, 38, 39 の 3 チャネルが順次使用されていることが見てとれる
- 「0x8e89bed6」の Access Address はアドバタイジングチャネルパケットで使用される固定値
- デバイス A のアドバタイジングのタイプは Connectable Undirected(詳細: 1, 2, 3, 4) であることを示す一般的な「ADV_IND」である
- 「Advertising Data: 020106020a000702031802180418」に含まれる不完全 16ビットサービスクラス UUID は次の内容
- 16 bit uuid: 0x1803 --> 既定の「Link Loss」サービス
- 16 bit uuid: 0x1802 --> 既定の「Immediate Alert」サービス
- 16 bit uuid: 0x1804 --> 既定の「Tx Power」サービス
Frame 124 | Frame 125 | Frame 126 |
接続に際し対向アプリがデバイス A に対して SCAN_REQ を発行
デバイス A が対向アプリからの SCAN_REQ に対し SCAN_RSP を返信。ここでは ScanRspData としてデバイスのローカルネームが渡されている
Scene 2: 接続の確立と情報交換
対向アプリがデバイス A に対して CONNECT_REQ(詳細:1a, 2a, 1b, 2b)を発行して接続を試みる
- 「Connection Request」中の「Connection Access Address」には、接続確立後のデータ通信において Access Address として双方が一意に使用する任意のアドレスが含まれる。ここでは「0xa6a188c8」
- 「Connection Request」中の「Channel map」には接続確立後のデータ通信で使用するチャネル番号のリストが提示される。ここでは 0 - 36 の全データチャネルが指定されている
- その他のパラメータについては上のリンクの資料を参照のこと
- CONNECT_REQ に対する直接のレスポンスは発生しない。接続が確立するとデータ通信アイドル時にスレーブ - マスタ間で空パケット(Empty PDU)の応酬が始まるためこれが接続成否の判定に用いられる
Frame 218, 224 は接続確立後の最初の応酬。接続が確立すると対向アプリはマスタ、デバイス A はスレーブの位置づけとなる。ここでは リンク層制御 PDU の LL_FEATURE_REQ および LL_FEATURE_RSP によりマスタ - スレーブ間で Feature Exchange を行っている。ここでは双方とも「Supported feature: LE Encryption (0)」のみを提示(ただしここでは以降の通信において暗号化は行われていない)
Frame 218 | Frame 224 |
Frame 222 ではアプリ側が「Device Name」を要求し Frame 226 でデバイス A 側がそれに応えている。
「Device Name」は、既定の Generic Access(GAP)サービス配下の既定のキャラクタリスティック(UUID = 0x2A00)であり、GATT サーバは必ず GAP サービスを含んでいる(詳細:1, 2)
(GAP サービスおよび Device Name キャラクタリスティックは後続の Frame 231, Frame 266 であらためて表に現れる)
Scene 3: デバイス A の GATT サービス群の取得
(Scene 3, Scene 4 共通の基礎知識)
BLUETOOTH SPECIFICATION Version 4.2(PDF) [Vol 3, Part G] より
2.6 GATT PROFILE HIERARCHY
2.6.1 Overview, 2.6.2 Service, 2.6.3 Included Services, 2.6.4 Characteristic
3 SERVICE INTEROPERABILITY REQUIREMENTS
3.1 SERVICE DEFINITION, 3.2 INCLUDE DEFINITION, 3.3 CHARACTERISTIC DEFINITION
3.3.1 Characteristic Declaration
3.3.1.1 Characteristic Properties, 3.3.1.2 Characteristic Value Attribute Handle, 3.3.1.3 Characteristic UUID
3.3.2 Characteristic Value Declaration
初期処理として、マスタはスレーブの提供するサービス一覧を取得する (詳細:1, 2, 3)
- アプリ側が、デバイス A の GATT サーバの提供する公開サービス(プライマリサービス)の問合せを開始。 以降、GATT サーバ上の所定のサービスへアクセスするためのハンドルのアドレスと当該サービスの種類を識別する UUID を順次取得する
- ハンドルのアドレス空間は 0x0000 - 0xFFFF であり GATT サーバ側の応答に応じて照会範囲を絞っていく
まずハンドル 0x0001 - 0xffff 全範囲についてプライマリサービスを照会
Opcode: Read By Group Type Request (0x10)
Starting Handle: 0x0001
Ending Handle: 0xffff
UUID: GATT Primary Service Declaration (0x2800)
以下のみっつのサービスの情報が得られた
- ハンドルグループ 0x0001 - 0x000b:既定の「Generic Access」サービス(UUID = 0x1800)が使用
- ハンドルグループ 0x000c - 0x000f:既定の「Generic Attribute」サービス(UUID = 0x1801)が使用
- ハンドルグループ 0x0010 - 0x0022:既定の「Device Information」サービス(UUID = 0x180A)が使用
Opcode: Read By Group Type Response (0x11)
Length: 6
Attribute Data, Handle: 0x0001, Group End Handle: 0x000b
Handle: 0x0001
Group End Handle: 0x000b
Value: 0018
Attribute Data, Handle: 0x000c, Group End Handle: 0x000f
Handle: 0x000c
Group End Handle: 0x000f
Value: 0118
Attribute Data, Handle: 0x0010, Group End Handle: 0x0022
Handle: 0x0010
Group End Handle: 0x0022
Value: 0a18
続けてハンドル 0x0023 - 0xffff 範囲のプライマリサービスを照会
以下のみっつのサービスの情報が得られた
- ハンドルグループ 0x0023 - 0x0025:既定の「Immediate Alert」サービス(UUID = 0x1802)が使用
- ハンドルグループ 0x0026 - 0x002a:既定の「Tx Power」サービス(UUID = 0x1804)が使用
- ハンドルグループ 0x002b - 0x002d:既定の「Link Loss」サービス(UUID = 0x1803)が使用
続けてハンドル 0x002e - 0xffff 範囲のプライマリサービスを照会
以下のみっつのサービスの情報が得られた
- ハンドルグループ 0x002e - 0x0032:既定の「Battery Service」サービス(UUID = 0x180F)が使用
- ハンドルグループ 0x0033 - 0x0037:ユーザ定義のサービス 1(UUID = 0xFFE0)が使用
- ハンドルグループ 0x0038 - 0x003a:ユーザ定義のサービス 2(UUID = 0xFFF0)が使用
続けてハンドル 0x003b - 0xffff 範囲のプライマリサービスを照会
「Attribute Not Found (0x0a)」のエラーが返る。これ以上プライマリサービスが存在しないことを意味する。サービスの照会はここまで
Opcode: Error Response (0x01)
Request Opcode in Error: Read By Group Type Request (0x10)
Handle in Error: 0x003b
Error Code: Attribute Not Found (0x0a)
Scene 4: デバイス A 各サービス配下のキャラクタリスティック - デスクリプタの取得
(Scene 3, Scene 4 共通の基礎知識)
BLUETOOTH SPECIFICATION Version 4.2(PDF) [Vol 3, Part G] より
2.6 GATT PROFILE HIERARCHY
2.6.1 Overview, 2.6.2 Service, 2.6.3 Included Services, 2.6.4 Characteristic
3 SERVICE INTEROPERABILITY REQUIREMENTS
3.1 SERVICE DEFINITION, 3.2 INCLUDE DEFINITION, 3.3 CHARACTERISTIC DEFINITION
3.3.1 Characteristic Declaration
3.3.1.1 Characteristic Properties, 3.3.1.2 Characteristic Value Attribute Handle, 3.3.1.3 Characteristic UUID
3.3.2 Characteristic Value Declaration
次に、収集ずみの各プライマリサービスのハンドルグループごとに以下を行う (詳細:1, 2, 3, 4, 5, 6)
- 所定のサービスに含まれる Included Service の照会
- 所定のサービスに含まれるキャラクタリスティックの照会
前掲の Frame 231 の示すハンドルグループ 0x0001 - 0x000b の「Generic Access」サービス内の Included Service を照会
Opcode: Read By Type Request (0x08)
Starting Handle: 0x0001
Ending Handle: 0x000b
UUID: GATT Include Declaration (0x2802)
当該サービス内に Included Service は存在しない(注:図のログではスニファがパケットデータを取りこぼしている)
ハンドルグループ 0x0001 - 0x000b の「Generic Access」サービス内のキャラクタリスティックを照会
Opcode: Read By Type Request (0x08)
Starting Handle: 0x0001
Ending Handle: 0x000b
UUID: GATT Characteristic Declaration (0x2803)
以下のみっつのキャラクタリスティックの情報が得られた
(※キャラクタリスティック の Value フィールドの構成は前掲の「BLUETOOTH SPECIFICATION Version 4.2] - [Vol 3, Part G] p.532 「3.3.1 Characteristic Declaration」 に、プロパティ値の意味は同じく p.533 「3.3.1.1 Characteristic Properties」 に説明あり)
- ハンドル:0x0002
「value: 080300002a」より、プロパティ = 0x08 (Write), Characteristic Value Handle = 0x0003
UUID = 0x2A00 = 既定の「Device Name」 - ハンドル:0x0004
「value: 020500012a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0005
UUID = 0x2A01 = 既定の「Appearance」 - ハンドル:0x0006
「value: 020700042a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0007
UUID = 0x2A04 = 既定の「Peripheral Preferred Connection Parameters」
Opcode: Read By Type Response (0x09)
Length: 7
Attribute Data, Handle: 0x0002
Handle: 0x0002
Value: 080300002a
Attribute Data, Handle: 0x0004
Handle: 0x0004
Value: 020500012a
Attribute Data, Handle: 0x0006
Handle: 0x0006
Value: 020700042a
続けてハンドル 0x0007 - 0x000b 範囲のキャラクタリスティックを照会
以下のふたつのキャラクタリスティックの情報が得られた
- ハンドル:0x0008
「value: 020900022a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0009
UUID = 0x2A02 = 既定の「Peripheral Privacy Flag」 - ハンドル:0x000a
「value: 020b00032a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x000b
UUID = 0x2A03 = 既定の「Reconnection Address」
前掲の Frame 231 の示すハンドルグループ 0x000c - 0x000f の「Generic Attribute」サービス内の Included Service を照会
当該サービス内に Included Service は存在しない
ハンドルグループ 0x000c - 0x000f の「Generic Attribute」サービス内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x000d
「value: 200e00052a」より、プロパティ = 0x20 (Indicate), Characteristic Value Handle = 0x000e
UUID = 0x2A52 = 既定の「Service Changed」
続けてハンドル 0x000e - 0x000f 範囲のキャラクタリスティックを照会
当該サービス内にはこれ以上キャラクタリスティックは存在しない
Frame 289 の示す通り 0x0000e は Service Changed キャラクタリスティックの Value Handle であり、残る0x000f に関する情報を GATT に問い合わせてみる (詳細:1, 2)
Opcode: Find Information Request (0x04)
Starting Handle: 0x000f
Ending Handle: 0x000f
0x000f は Service Changed キャラクタリスティックの Client Characteristic Configuration Descriptor (UUID = 0x2902) (詳細:1, 2) である旨の情報が得られた
Opcode: Find Information Response (0x05)
UUID Format: 16-bit UUIDs (0x01)
Handle: 0x000f
UUID: Client Characteristic Configuration (0x2902)
前掲の Frame 231 の示すハンドルグループ 0x0010 - 0x0022 の「Device Information」サービス内の Included Service を照会
当該サービス内に Included Service は存在しない
ハンドルグループ 0x0010 - 0x0022 の「Device Information」サービス内のキャラクタリスティックを照会
以下のみっつのキャラクタリスティックの情報が得られた
- ハンドル:0x00011
「value: 021200292a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0012
UUID = 0x2A29 = 既定の「Manufacturer Name String」 - ハンドル:0x00013
「value: 021400242a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0014
UUID = 0x2A24 = 既定の「Model Number String」 - ハンドル:0x00015
「value: 021600252a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0014
UUID = 0x2A25 = 既定の「Serial Number String」
続けてハンドル 0x0016 - 0x0022 範囲のキャラクタリスティックを照会
以下のみっつのキャラクタリスティックの情報が得られた
- ハンドル:0x00017
「value: 021800262a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0018
UUID = 0x2A26 = 既定の「Firmware Revision String」 - ハンドル:0x00019
「value: 021a00272a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x001a
UUID = 0x2A27 = 既定の「Hardware Revision String」 - ハンドル:0x0001b
「value: 021c00282a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x001c
UUID = 0x2A28 = 既定の「Software Revision String」
続けてハンドル 0x001c - 0x0022 範囲のキャラクタリスティックを照会
以下のみっつのキャラクタリスティックの情報が得られた
- ハンドル:0x0001d
「value: 021e00232a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x001e
UUID = 0x2A23 = 既定の「System ID」 - ハンドル:0x0001f
「value: 0220002a2a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0020
UUID = 0x2A2A = 既定の「IEEE 11073-20601 Regulatory Certification Data List」 - ハンドル:0x00021
「value: 022200502a」より、プロパティ = 0x02 (Read), Characteristic Value Handle = 0x0022
UUID = 0x2A50 = 既定の「PnP ID」
前掲の Frame 238 の示すハンドルグループ 0x0023 - 0x0025 の「Immediate Alert」サービス内の Included Service を照会
(注:このリクエストに対する正しいレスポンスは「Attribute Not Found (0x0a)」だが、スニファ取りこぼしのためログが欠落している)
ハンドルグループ 0x0023 - 0x0025 の「Immediate Alert」サービス内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x0024
「value: 042500062a」より、
プロパティ = 0x04 (Write without Response),
Characteristic Value Handle = 0x0025
UUID = 0x2A06 = 既定の「Alert Level」
前掲の Frame 238 の示すハンドルグループ 0x0026 - 0x002a の「Tx Power」サービス内の Included Service を照会
(注:このリクエストに対する正しいレスポンスは「Attribute Not Found (0x0a)」だが、スニファ取りこぼしのためログが欠落している)
ハンドルグループ 0x0026 - 0x002a の「Tx Power」サービス内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x0027
「value: 122800072a」より、プロパティ = 0x12 (Read | Notify), Characteristic Value Handle = 0x0028
UUID = 0x2A07 = 既定の「Tx Power Level」
続けてハンドル 0x0028 - 0x002a 範囲のキャラクタリスティックを照会
当該サービス内にはこれ以上キャラクタリスティックは存在しない
Frame 359 の示す通り 0x00028 は Tx Power Level キャラクタリスティックの Value Handle であり後続の 0x0029 - 0x002a に関する情報を GATT に問い合わせてみる (詳細:1, 2)
0x0029 は Tx Power Level キャラクタリスティックの Client Characteristic Configuration Descriptor (UUID = 0x2902) (詳細:1, 2) である旨の情報が得られた
残る0x002a に関する情報を GATT に問い合わせてみる (詳細:1, 2)
0x002a は Tx Power Level キャラクタリスティックの Characteristic Presentation Format Descriptor (UUID = 0x2904) (詳細:1, 2, 3, 4) である旨の情報が得られた
Opcode: Find Information Response (0x05)
UUID Format: 16-bit UUIDs (0x01)
Handle: 0x002a
UUID: Characteristic Presentation Format (0x2904)
前掲の Frame 238 の示すハンドルグループ 0x002b - 0x002d の「Link Loss」サービス内の Included Service を照会
(注:このリクエストに対する正しいレスポンスは「Attribute Not Found (0x0a)」だが、スニファ取りこぼしのためログが欠落している)
ハンドルグループ 0x002b - 0x002d の「Link Loss」サービス内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x002c
「value: 0a2d00062a」より、プロパティ = 0x0a (Read | Write), Characteristic Value Handle = 0x002d
UUID = 0x2A06 = 既定の「Alert Level」
前掲の Frame 247 の示すハンドルグループ 0x002e - 0x0032 の「Battery Service」サービス内の Included Service を照会
当該サービス内に Included Service は存在しない
ハンドルグループ 0x002e - 0x0032 の「Battery Service」サービス内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x002f
「value: 123000192a」より、プロパティ = 0x12 (Read | Notify), Characteristic Value Handle = 0x0030
UUID = 0x2A19 = 既定の「Battery Level」
続けてハンドル 0x0030 - 0x0032 範囲のキャラクタリスティックを照会
当該サービス内にこれ以上キャラクタリスティックは存在しない
Frame 404 の示す通り 0x00030 は Battery Level キャラクタリスティックの Value Handle であり後続の 0x0031 - 0x0032 に関する情報を GATT に問い合わせてみる (詳細:1, 2)
0x0031 は Battery Level キャラクタリスティックの Client Characteristic Configuration Descriptor (UUID = 0x2902) (詳細:1, 2) である旨の情報が得られた
残る0x0032 に関する情報を GATT に問い合わせてみる (詳細:1, 2)
0x0032 は Battery Level キャラクタリスティックの Characteristic Presentation Format Descriptor (UUID = 0x2904) (詳細:1, 2, 3, 4) である旨の情報が得られた
前掲の Frame 247 の示すハンドルグループ 0x0033 - 0x0037 のユーザ定義サービス 1(UUID = 0xFFE0)内の Included Service を照会
当該サービス内に Included Service は存在しない
ハンドルグループ 0x0033 - 0x0037 のユーザ定義サービス 1 内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x0034
「value: 103500e1ff」より、
プロパティ = 0x10 (Notify),
Characteristic Value Handle = 0x0035
UUID = 0xFFE1 : ユーザ定義のキャラクタリスティック
続けてハンドル 0x0035 - 0x0037 範囲のキャラクタリスティックを照会
当該サービス内にこれ以上キャラクタリスティックは存在しない
Frame 439 の示す通り 0x00035 はユーザ定義キャラクタリスティック(UUID = 0xFFE1)の Value Handle であり後続の 0x0036 - 0x0037 に関する情報を GATT に問い合わせてみる (詳細:1, 2)
0x0036 はユーザ定義キャラクタリスティック(UUID = 0xFFE1)の Client Characteristic Configuration Descriptor (UUID = 0x2902) (詳細:1, 2) である旨の情報が得られた
残る0x0037 に関する情報を GATT に問い合わせてみる (詳細:1, 2)
0x0037 はユーザ定義キャラクタリスティック(UUID = 0xFFE1)の Characteristic User Description Descriptor (UUID = 0x2901)である旨の情報が得られた
前掲の Frame 247 の示すハンドルグループ 0x0038- 0x003a のユーザ定義サービス 2(UUID = 0xFFF0)内の Included Service を照会
当該サービス内に Included Service は存在しない
ハンドルグループ 0x0038 - 0x003a のユーザ定義サービス 2 内のキャラクタリスティックを照会
以下のキャラクタリスティックの情報が得られた
- ハンドル:0x0039
「value: 043a00f1ff」より、プロパティ = 0x04 (Write without Response), Characteristic Value Handle = 0x003a
UUID = 0xFFF1 : ユーザ定義のキャラクタリスティック
Scene 5: デバイス A ボタン押下時のアプリへの通知を設定
Frame 453、Frame 439、Frame 453 の示す通り、ハンドル 0x0036 は、 "ユーザ定義サービス 1(UUID = 0xFFE0)配下のユーザ定義キャラクタリスティック(UUID = 0xFFE1)配下の Client Characteristic Configuration Descriptor (CCCD)" である
当該ユーザ定義キャラクタリスティック(UUID = 0xFFE1)のプロパティには Notify が設定されており、クライアントである対向アプリから CCCD 0x0036 に Notification bit (0x0001) を書き込んでおくことで、このキャラクタリスティックの値が更新された時に Value Handle である 0x0035 経由でアプリ側へ通知(Notification)が行われるようになる
(詳細:
1a,
2a,
1b,
2b)
Opcode: Write Request (0x12)
Handle: 0x0026
Value: 0100
Opcode: Write Response (0x13)
Scene 6: アプリからデバイス A の LED・ブザーを操作
対向アプリ上の所定のボタンを押下すると、Frame 345, Frame 238 の示す、 "「Immediate Alert」サービス配下の「Alert Level」キャラクタリスティック" の Value Handle 0x0025 に値「2(High Alert)」が書き込まれる
デバイス A の LED・ブザーはファームウェアレベルでこの Alert Level キャラクタリスティックに紐づけられている模様。High Alert 値が書き込まれるとそれに反応して短時間 LED とブザーが ON になる
なお、Frame 345 の示すように Alert Level キャラクタリスティックのプロパティには「Write without Response」(0x04) が設定されているため、アプリから値を書き込んでもデバイス A からのレスポンスは発生しない
Opcode: Write Command (0x52)
Handle: 0x0025
Value: 02
Scene 7: デバイス A のボタンを押すとアプリへ通知
デバイス A の物理ボタンはファームウェアレベルで Frame 439 の示す "ユーザ定義サービス 1(UUID = 0xFFE0)配下のユーザ定義キャラクタリスティック(UUID = 0xFFE1)" に紐づけられている模様。このボタンを押すと当該キャラクタリスティックの値がデバイス内部で更新され Frame 491 での仕込みに基づきアプリ側へ通知が行われる
Opcode: Handle Value Notification (0x1b)
Handle: 0x0035
Value: 01
Scene 8: アプリ側からデバイス A との接続を切断
対向アプリ上の所定のボタンを押下するとリンク層制御 PDU の LL_TERMINATE_IND (0x02) がデバイス A 側に送出され両者間の接続が終了する(詳細:1, 2)
(tanabe)