前回 BLE Sniffer と Wireshark で BLE パケットをスニッフィングする方法を書きましたが、 Wireshark で確認できる内容から BLE の接続シーケンスを確認してみたいと思います。手元にあった BLE デバイスで簡単に確認してみた結果を書いてみます。
ADV_IND
BLE デバイスがアドバタイジングを開始するとアドバタイジング・パケットを送出し始めます。 PDU(プロトコル・データ・ユニット)のタイプとしては4タイプありますが、今回使用したデバイスでは ADV_IND となっていました。
ADV_IND を含め、アドバタイジング・パケットのタイプは下記の4タイプになります。
- ADV_IND:不特定多数のデバイスから接続可能
- ADV_NONCONN_IND:デバイスからの接続は不可能
- ADV_SCAN_IND:デバイスからのスキャン可能
- ADV_DIRECT_IND:特定デバイスから接続可能
SCAN_REQ
セントラルデバイスがペリフェラルデバイスからアドバタイジング・パケットを受け取った時に、アドバタイジング・パケットのペイロードのデータだけでは情報が不足している場合、 スキャン・リクエスト(SCAN_REQ)パケットを送信します。
SCAN_RSP
ペリフェラルデバイスが SCAN_REQ パケットを受け取ると、その応答として SCAN_RSP パケットを送信します。
CONNECT_REQ
アドバタイジング・パケットの送受信が完了し、セントラルデバイスからペリフェラルデバイスに対して接続要求が行われると、 CONNECT_REQ パケットが送信され、接続状態に切り替わります。セントラルとペリフェラルはそれぞれマスター(Master)とスレイブ(Slave)になり、 Wireshark での Source と Definition のデバイス表示も、 MAC アドレス表示から Master, Slave に切り替わります。
LL_VERSION_IND
リンク層の接続制御に使われるロジカル・リンク・コントロール PDU では、オペコード(Opcode)でその種別が表されています。 LL_VERSION_IND はコントローラのバージョン番号を示すためのものです。
Exchange MTU Request/Response
Exchange MTU Request/Reponse はアトリビュート・プロトコルの最大長(MTU: Maximum Transfer Unit)を決定するために使われます。まずはクライアント側から自身が扱える ATT_MTU をサーバ側に通知します。そのレスポンスとしてサーバからはサーバ側で扱える ATT_MTU を返します。
Read Request/Response
サーバのアトリビュートをクライアントから読み取るには Read Request/Response が使われます。 Read リクエストには下記の5種類があります。
- Read
- Read Multiple
- Read Blob
- Read By Type
- Read By Group Type
Read By Group Type ではアトリビュートのグループを読み出します。下記の例では GATT の Primary Service Declaration を読み取っています。
Read By Type ではアトリビュート・タイプを指定した読み出しに使用します。下記は GATT の Characteristic Declaration の例です。
アトリビュートが存在しない場合は下記のように Error Response が返ってくるようです。
Read ではアトリビュート・ハンドルを指定して値を読み出します。
長さが ATT_MTU を超えるアトリビュート・バリューを持つアトリビュートはロング・アトリビュートと呼ばれ、その値を読み出す場合には Read Blob が使われます。
Find Information Request/Response
アトリビュート・ハンドルの範囲を指定してアトリビュート・ハンドルとアトリビュート・タイプを読み出すには Find Information が使われます。アトリビュートのタイプとバリューが指定できる Find By Type Value リクエストもありますが、今回は使われていなかったようです。下記は Find Information の例です。
Write Request/Response
アトリビュート・ハンドルを指定して書き込みを行うには Write が使用されます。
Write には他にも下記の4種類がありますが、今回は使われていなかったようです。
- Prepare Write
- Execute Write
- Write Command
- Signed Write Command
Handle Value Notification
サーバからクライアントへの通知には Handle Value Notification が使われます。
Connection Parameter Update Request
コネクションのパラメータを変更する場合には Connection Parameter Update Request が送信されます。
オペコードとしては LL_CONNECTION_UPDATE_REQ が使われます。
パラメータが変更されると Connection Parameter Update Response が返されます。
LL_CHANNEL_MAP_REQ
コネクションのチャンネル・マッピングを変更する際には LL_CHANNEL_MAP_REQ というオペコードが使われます。
LL_TERMINATE_IND
コネクションを切断するには LL_TERMINATE_IND オペコードが使われます。
まとめ
ざっとですが手持ちの一デバイスで確認できた内容を書いてみました。 BLE デバイスを使ったサービスを開発する場合に、BLEデバイスとの接続に問題がありそうな場合には、今回のように接続シーケンスを確認することで何か解決への手がかりが見つかるかもしれません。使用方法もとても簡単なので、勉強のためにも今後色々と使ってみたいと思います。
今回は下記のサイトを参考にさせていただきました。