🚶‍♂️

Bluetoothログ解析の深淵へ一歩踏み出す 〜AndroidのHCIスヌープログから見える世界〜

2024/12/17に公開

この記事は 株式会社ビットキー Advent Calendar 2024 17日目の記事です。
モバイルアプリ開発者のsunadiusが担当します。

概要

当社ではBluetoothを使ったデバイス操作機能を頻繁に開発しています。しかし、私自身はこれまでBluetoothについて深く学んだことがありませんでした。そこで、Bluetoothを学ぶために実践したログ解析の知識の一部を共有することで、同様にBluetoothを学び始めた方の参考になればと思い、この記事を執筆しました。

この記事で書くこと

  • Wiresharkを用いたBluetooth LE (Low Energy)ログの解析例(フィルタリングまで)
    • 対象のログは、Androidスマートフォンから抽出したHCIスヌープログを想定しています
  • Wiresharkで表示されるprotocolの一部紹介
  • Wiresharkに表示されるプロトコルとBluetooth公式文書との紐付き紹介

この記事で書かないこと

  • Wiresharkを用いたBluetooth BR/EDRログの解析例
    • BR/EDR (Basic Rate / Enhanced Data Rate、あるいは Classic)には触れません
    • 例えばオーディオ接続にBluetoothを用いると、本記事とは別のProtocolが表示されます
  • AndroidからBluetoothログを抽出するための具体的な手順
    • 参考文献に一部資料/記事を記載しています
  • Bluetoothプロトコル、プロトコルスタックに関する詳細な解説
    • 詳細部分については解説サイトなどを確認してください
  • Wiresharkを用いたBluetooth LEログのデータ内容解析
    • ボリュームの都合でフィルタリングまでを切り出しています

表示されているログを眺めてみよう

ログ上には何が表示される?

AndroidによるBluetooth接続試験中、なんらかのエラーが発生したとします。Android視点でどういうエラーが発生したかをみるために、HCIスヌープログを抽出し、Wireshark上にて表示までできたとします。この時点で有益なログだけ抽出されていれば良いのですが、実際には検証上は必要ない情報も記録されるため、場合によっては以下のような画面になります。

特に初学者にとっては、このように同じような名目のログが列挙されていると、目的に関連するデータを探す一歩を踏み出すのが難しいのではないでしょうか?ここで注目していただきたいのは、「Protocol」列になります。この列には、該当データが持つ役割を端的に示す文字列が入っています。

まずはよく見るProtocol分類を整理することで、調査目的のデータを探す一助にしてみましょう。

LE解析時によく見るProtocol分類

HCI_EVT

HCIとは、「Host Controller Interface」の略称です。Hostは上位アプリケーション群を含む機器接続やコマンド送信の要求をする部分、Controllerは電波制御などの物理的な制御をする部分を意味します。HCIはHostとControllerに跨り、双方のコミュニケーションを補助する役割を担っているため、HCI上では実に多くの情報を見聞きできます。

特にEVT(Event)は、主にController側で"発生した"事象に関する情報で、例えば「パッシブスキャン(信号を受け取るだけのスキャン)をしている最中に、何らかのアドバタイズを受信した」ときなどに記録されます。後ほど説明するHCI_CMDと比べ、意図的な行動以外の情報を多く含むため、ログ上の表示数が多くなりやすいはずです。

HCIに関する仕様は、公式文書の"Host Controller Interface PartE, HOST CONTROLLER INTERFACE FUNCTIONAL SPECIFICATION"(1802p〜) にて説明がされており、特にEventは7.7節に一覧があるので、個別のEvent詳細はこちらを参考にしてください。

HCI_CMD

上述のHCI_EVTは"発生した"事象に関する情報でしたが、こちらのHCI_CMDは"実行した"事象に関する情報になります。例えば「Host部分で何らかのコマンド送信命令が出た場合」が該当します。アプリケーションの機能検証として"実行した機能が正常には発火したか"を見たい場合は、こちらの分類を確認する必要があるかもしれません。

公式文書内ではHCI_EVTと同じパート中で解説がされています。Eventに比べて節が細分化されており、例えばBluetooth LEにおける制御コマンドは7.8節に一覧があります。また、5.4.1項ではHCI_CMDのデータフレームワークが、5.4.4項ではHCI_EVTのデータフレームワークが公開されているので、余裕があればこちらも参考にしてください。

L2CAP

ここまでの説明で感じられていると思いますが、HCI_EVTとHCI_CMDは非常に多様な内容を含んでいます。また、物理的なレイヤー(Controller)が関わってきたり、デバイス内部に閉じた情報も多いという特徴があります。

一方で、L2CAPは外部デバイスとの通信に用いるプロトコルであり、Host側のみで組み立てられる特徴があります。そのため、例えば「何らかのアプリケーションによって、外部のデバイスを操作した時のパケットログを見たい」と思った時には、「L2CAPに関わるログ」を探す方針にした方が作業効率が良いかもしれません。

ただし、L2CAPが内包する上位プロトコルには複数のパターンがあり、その内容次第で役割が変わるため、L2CAP単体に着目することはあまりないと思います。Wiresharkのprotocol列表示でも、上位プロトコルを内包している場合はL2CAPとしてではなく、内包する上位プロトコルが表示され、直接L2CAPと表現される機会は少ないです。上位プロトコルの例としては、後述のATTが挙げられます。

ところで、L2CAPは略称なので、公式文書内では"Logical Link Control and Adaptation Protocol"と正式名称で記載されることも多いです。詳細な役割や機能の説明を見たい場合、"Host Specification Volume 3, Part A LOGICAL LINK CONTROL AND ADAPTATION PROTOCOL SPECIFICATION"(1080p〜)が参考になります。特に2.1節 Channel identifiersでは、ログ上からも確認できるCIDパラメータに関する解説がされているので、オススメのページになります。

ATT

L2CAPよりも上位のプロトコルで、"Bluetooth Low Energy"を使用する場合に用いられます。何らかの外部デバイスにLEで指示を送るアプリを作っている場合、ATTプロトコルに着目してログを確認することが多いのではないでしょうか。

ATTプロトコルを使うと、一方のデバイスをサーバ、もう一方のデバイスをクライアントとし、Attribute(属性)の読み書きや、通知のやり取りが行えます。このログが確認できるということは、相手デバイスとのやり取りが少なからず発生しているはずなので、一方のスマホだけでなく、通信対象デバイス側のログも確認する必要が出てくるかもしれません。

ATTはL2CAPと同じ""Host Specification Volume 3"の内、"Part F ATTRIBUTE PROTOCOL (ATT)"(1478p〜)にて説明がされています。状況次第だとは思いますが、3.4.1項のError handling(1490p〜)にて、エラーコードの一覧と意味があるので、確認の機会があるかもしれません。

どうやって絞り込めばいい?

絞り込みを行うにあたり、Wiresharkのフィルタリング欄を活用すればいいことは、すぐにイメージができると思います。

問題は、何をフィルタリング欄に記載すればいいか。WiresharkのDisplay Filter Referenceを見てみましょう。

ここでは、Bluetoothに関わるログは、先頭に「bt」をつける形で統一されています。そのため、例えば「btl2cap」を上記フィルタリング欄に記載すれば、「Bluetoothで用いられるL2CAP形式に該当するログ」を抽出することができます。同じように、「btatt」ならATT形式を抽出できるので、「bt+プロトコル名」として覚えておくと、Bluetoothログ調査において役立つかと思います。

誰から見たログなのかを忘れないように

例えば"Bluetooth Low Energy"に関するログを調査しているとき、「btatt」で絞り込みをしたとします。ここで表示されるログの内容には、ATTプロトコルが持つべきデータの他に、L2CAPフレーム、HCI_ACLフレーム、HCI_H4フレームのデータが含まれます。

これは、ログの記録をしているのがHCIであり、HCIが解釈したデータが記録されることに起因します。HCIスヌープログはHCI視点でのログであるため、「Androidスマートフォンの記録したログ」と解釈してしまうと、問題の考察に誤りが生じる可能性があります。

また、HCI視点という性質上、各ログデータにはHCIに関わるデータも含まれます。そのため、「hci_h4」のようなHCIに直結する形式でフィルタリングを行っても、表示されるログの数を効果的に減らせない可能性があります。

この場合、HCIから距離の離れた上位プロトコル(ATTなど)に着目したフィルタリングを実行することで、表示されるログ数を減らすことができます。

終わりに

当初は、データの内容や役割についてより深く掘り下げる予定でしたが、今回はボリュームの都合上、フィルタリングの方法までにとどまりました。機会があれば、今回触れられなかった詳細部分や、各種プロトコルに関する解説記事を執筆したいと考えています。

明日の18日の株式会社ビットキー Advent Calendar 2024は、UI / UXデザイナーのあぼねこ (@avocadoneko) が担当します。お楽しみに!🎉

参考文献

https://source.android.com/docs/core/connect/bluetooth/verifying_debugging?hl=ja
https://qiita.com/KentaHarada/items/42ed619e8f571d1de845
https://techweb.rohm.co.jp/product/wireless/bluetooth/3088/
https://www.silex.jp/library/blog/20161219-1

Bitkey Developers

Discussion