2015年2月16日月曜日

「Bluetooth HCIスヌープログを有効にする」とは何なのか

全部読むのが嫌なせっかちな人へ

  • Android 4.4(API 19)以降の開発者向けオプションには、「Bluetooth HCIスヌープログを有効にする」というチェック項目がある。
  • 「Bluetooth HCIスヌープログを有効にする」をOnにした場合、BlueZのhcidump相当のログが出力される。
  • ログファイルの保存先はメーカーによる。/etc/bluetooth/bt_stack.confを確認すると保存先がわかる。
  • hcidumpのログはWiresharkで解析できる

いきさつ

2013年の11月頃に、Nexus5(当時4.4.0あたり)を入手できたまいむぞうは、開発者オプションに「Bluetooth HCIスヌープログを有効にする」というチェック項目を見つけ、当時からiBeaconやBLEに興味を持っていた私はこのオプションをいじくりまわしていた

なんとなく、正体を知れた私は、特にブログなどにまとめることもなく、そのうち誰かがブログにまとめてくれるだろう、と思いつつ、興味の対象を他に移した。

時は流れ、2015年2月に、仕事上BLEのパケットを解析する必要に迫られ、当初は手持ちのSenserTag付属の開発キット(CC2541 ミニ開発キット)に付属のPacket Snifferを使おうと思ってたんだけど、買ったまま使わずに置いといたら、ソフトウェア側がバージョンアップしてうまく動かなくなっていたので、どうしようか途方に暮れていた。

そんなときに「Bluetooth HCIスヌープログを有効にする」オプションの存在を思い出した。改めてググってみても、自分のTwitterがひっかかるだけであまり使っている人がいなさそうだったので、自分のメモ的にもこのオプションの使い方をまとめることにした。

「Bluetooth HCIスヌープログを有効にする」とは何なのか

まず、「Bluetooth HCIスヌープログを有効にする」オプションは、Android 4.4(API 19)あたりで増えた開発者オプションである。

「Bluetooth HCIスヌープログを有効にする」をOnにした時の挙動なのだが、公式ドキュメントをちゃんと読んでいないものの、これはhcidump相当のログを出力するオプションらしい。

元々AndroidのBluetooth周りは、Linux上のOSSであるBlueZを使っているのだが、Ubuntuや他のディストリビューションにBlueZをインストールした場合、HCI(Bluetoothのハードウェアとソフトウェアの境界線ぐらいに相当するレイヤ)上のコマンドラインデバッグツールとして、hcidumpというログ出力用プログラムが利用できるようになっている。

hcidumpを稼働させつつ、BlueZが入っているPCとBluetooth機器を通信させると、その間を飛び交っているパケットを記録しておく(パケットスニファ)のが、その役割となっている。

Androidの実装を確認はしていないものの、「Bluetooth HCIスヌープログを有効にする」をOnにした時に出力されるログのフォーマットは、hcidumpのものと同じっぽいので、Android内部でhcidumpそのもの、もしくはBlueZのライブラリを使ってhcidump相当のコードが動いているように見える。

Bluetooth HCIスヌープログを有効にするをOnにして、ログを取り込む

実際にログを取得してみよう。

「Bluetooth HCIスヌープログを有効にする」オプションは、Onにしている間のBluetooth通信を監視するものなので、最初にBluetooth機器をすべて切断し、Bluetoothを使うアプリも全て停止しておく必要がある。

Androidの設定アプリから、開発者オプションに入り、「Bluetooth HCIスヌープログを有効にする」にチェックを付けた後、デバッグしたいBluetooth機器と接続したり、iBeaconなどを扱うアプリを起動すると、その通信内容がログに記録される。

このログは、メーカーごとに保存先が異なっているようなので、以下のコマンドを使って確認することができる。

$ adb shell cat /etc/bluetooth/bt_stack.conf | grep BtSnoopFileName

例えば、Nexus5やNexus7は/sdcard/btsnoop_hci.logへ、Galaxy S4は/sdcard/Android/data/btsnoop_hci.logに出力されるようになっていた。
(/sdcardが指している先は本当にSDカードなのかどうかは、端末による。たとえばSDカードが無いNexus7も同じパスに保存される)

あとはADBなどで

$ adb pull /sdcard/btsnoop_hci.log . 

とすればPCに取り込むことができる。(USBケーブル経由でAndroid File Transferや、エクスプローラ経由でも取り込めそうだけど)

ちなみに、一度ログを保存した後、「Bluetooth HCIスヌープログを有効にする」オプションをOff→Onとすると上書きされてしまうので注意。
また、Onのまま放置するとストレージを食いつぶすので、使わない時はOffに戻しておこう。

hcidumpのログを解析する

OSSエコシステムとしては、hcidumpのログは、Wiresharkに取り込んで解析するのが一般的らしい。

まいむぞうはMac使いなので、MacOSX対応のWiresharkをインストールする必要があった。

Wiresharkのインストール自体は、各OSの手順に従って欲しいのだが、一昨年に試した時点ではWireshark本家提供のMacOSX用パッケージはうまく動かなかったので、Homebrewで入れた気がする。(うろ覚え)

Wiresharkが立ち上がってしまえば、File→Openで取り込んだbtsnoop_hci.logを読み込むだけで、通信内容が解析されて表示されるようになっている。

例として、BLE113を使ったiBeacon互換のアドバタイズパケットを解析したスクリーンショットは以下のようになる。


解析結果をクリックして行を反転させると、その行に相当するバイナリ列も反転されるので、なんとなく雰囲気は読み取れると思う。

ただ、Bluetooth規格に記載がある部分は解析されるのだが、当然ユーザ定義部分は解析されない。たとえば、iBeaconとして使うときのUUID/Major/Minor/TxPowerなどは解析できないので、Appleのドキュメントを読み解く必要がある。

また、当然解析された部分についても、その意味や選択肢は公式ドキュメントを参照する必要があるだろう。

0 件のコメント: