Android USBマスストレージクラスのパケットを理解しよう!:実践しながら学ぶ Android USBガジェットの仕組み(12)(3/3 ページ)
今回は、USBマスストレージクラスのパケットを解析する上で前提となる「USBプロトコル」の基礎を理解し、解析作業を進める。果たして、Androidをリムーバブルディスクではなく、“CD-ROMドライブ”として認識させるための改造ポイントはどこか?
5.SCSIコマンドを追い掛けよう
それでは、前回解析したSCSIコマンドの解析を始めましょう。解析のポイントは以下の2点です。
- ポイント1:ホストはどうやってAndroidをリムーバブルディスクとして認識するのか
- ポイント2:AndroidをCD-ROMドライブとして認識させるにはどうすればよいのか
というわけで、早速、SCSIコマンドを1つずつコツコツと見ていきましょう……と、言いたいところですが、大量のパケットを1つ1つ見ていくのは現実的ではありません。そこで、筆者の方で、上から下までざっと眺めて、当たりを付けてみましたので、本稿ではポイントを絞って解説していきます。
SCSIコマンドの流れは、ユーザー操作と連動して、大きく分けて下図のように2つのフェーズに分類することができました。まずは、各フェーズのコマンドの流れの概要を把握してみましょう。
5.1.USB接続直後のコマンドの流れを把握する
まず、PC上での操作として、USB接続直後、PCはAndroidをリムーバブルディスクとして認識していました。しかし、ディスクへアクセスするとエラーとなりました。
このときのSCSIコマンドの流れは、INQUIRYというコマンドが1回だけ発行され、その後、「TEST UNIT READY」「REQUEST SENSE」「READ CAPACITY」が繰り返し発行され続けていました(注2)。
詳細は、コマンドの応答データを実際に見てみる必要がありますが、この流れから推測をめぐらすと、ホストがAndroidをリムーバブルディスクとして認識した原因としては、最初に1回だけ発行されたINQUIRYが大変怪しいですね。その後に繰り返し発行され続けているコマンドは、Android側でマウント操作が行われるのを監視しているからではないか? と考えると筋が通りそうです。
5.2.マウント直後のコマンドの流れを把握する
マウント直後は、PCからAndroid内のSDカードにアクセスできるようになりました。
このときのSCSIコマンドの流れはどうかというと、繰り返し発行されていた、TEST UNIT READY、REQUEST SENSE、READ CAPACITYコマンドが止まり、「READ10」が連続して発行されるようになりました。この流れから推測すると、Androidをマウントすることで、ホスト側のマウント監視が終わり、SDカードのデータをREAD10コマンドで取得し始めたと考えられます。
5.3.SCSIコマンドの応答データを解析する
以上が大まかなコマンドの流れと推測です。それでは、次にコマンド応答データとSCSIコマンド仕様を参照しながら、裏付け調査を行っていきましょう。
(1)INQUIRY応答データ
INQUIRY応答データを参照すると上図の通りでした。ポイントは、「PDT(Peripheral Device Type)」と「RMB(Removable Medium Bit)」です。PDTは、デバイスがその種類を宣言するためのメンバです。“PDT=0x0”の意味を仕様書で参照すると、「フロッピーディスクなどの直接アクセス可能なデバイス」と記載があります。RMBは、メディアを抜き差しできるかどうかのフラグであり、7bit目が1であると抜き差し可能という意味になります。以上より、AndroidはPCに対して、INQUIRYコマンド応答で「ボクは直接アクセス可能で、メディアを抜き差しされるデバイスです」と宣言していることになります。明らかに、これがリムーバブルディスクとして認識させる要因といえますよね!
ということは、INQUIRY応答で「ボクはCD-ROMドライブです」と宣言すれば、CD-ROMドライブになりそうな気がしませんか? 実際、仕様書を参照してみると、“PDT=0x5”はCD-ROMデバイスという記載がありました。ここがAndroidの最初の改造ポイントとなります。
(2)REQUESET SENSEの応答データ
REQUEST SENSE応答データを参照すると上図の通りでした。ポイントは、「SENSE KEY」と「ADDITIONAL SENSE CODE」です。これらの値は、マウント前後で値が変わっていました。仕様書の記載を確認した結果を以下に示します。
フェーズ | SENSE KEY | ADDITIONAL SENSE CODE | 説明 |
---|---|---|---|
USB接続直後 | 0x2 | 0x3A | MEDIUM NOT PRESENT |
マウント直後 | 0x6 | 0x28 | NOT READY TO READY TRANSITION - MEDIA CHANGED |
Androidは、REQUEST SENSEの応答で現在のデバイスの状態を返しており、USB接続直後は「メディアなし状態」と通知し、マウント後はSDカードへのアクセスが可能になったため、「メディア状態がREADYへ変化した」と通知したと解釈できます。つまり、ホストはREQUEST SENSEコマンドで、リムーバブルディスクにメディアが挿入されるかどうかを確認していたのですね。
(3)READ CAPACITYの応答データ
READ CAPACITYの変化は一目瞭然であり、マウント後にメディアの容量情報(ブロックサイズ=512バイト、最終ブロック番号=0x2edfff)を返すようになっています。この情報を基に、後続のREAD10コマンドでデータの読み込みを開始し、SDカードへのアクセスが可能になったといえます。
6.まとめ
今回は、UMSクラスのパケットを解析する上で前提となる基礎知識を概説した上で、前回積み残していた疑問点を調査しました。その結果、AndroidをCD-ROMドライブとして認識させるには、SCSIコマンドのINQUIRY応答データを改造すれば対応できそうであることが見えてきました。
とはいえ、INQUIRY応答データを変えると、ホストが送信するSCSIコマンドの種類や内容も変わってくることは容易に想像ができます。最終回となる次回では、AndroidのUMSクラスのドライバを改造し、CD-ROMドライブとして認識させたいと思います。お楽しみに! (次回に続く)
関連キーワード
組み込みAndroid開発 | 実践しながら学ぶ Android USBガジェットの仕組み | USB | Android | 組み込み | Androidケータイ | アプリケーション開発 | Androidがもたらす組み込み開発の新たな可能性 | 組み込み開発 | 作りながら理解するファイルシステムの仕組み
Copyright © ITmedia, Inc. All Rights Reserved.