2009年4月26日日曜日

E-mobile D21LCをOpenBSDで使う

少し前の話だがE-mobileのD21LCをしばらく借りることができたので、少し解析してOpenBSDで使えるようにしてみた。その時の話をメモとして残しておくことにする。

D21LCは中国のLongcheer社製のHSDPAモデムだ。E-mobileでは最初はHuawei社のモデムを使っていたが、しばらく前から2社の製品を投入している。D21LCも他のE-mobileのモデムと同様に「ゼロインストール」機能が搭載されている。ゼロインストールとはドライバが入っていないOS(つまり初回挿入時)にはモデムをUSBマスストレージデバイスとして認識させて必要なドライバをモデムから直接インストールさせる仕組みである。ドライバが動き始めると、そのドライバがモデムのモードを変更してモデムとして動作するようになる。Windowsなどからは大変便利な機能であるが、ほかのOSで使うためにはちょっとおせっかいだ。

Huawei社のモデムはメモ:D02HW解析で昔書いたように特別なUSBコマンドを発行すると、USBマスストレージモードからモデムモードに動作モードが切り替わった。D21LCの場合はどうだろうか?

D21LC:モデムモードへの切り替え

USBアナライザでUSBトランザクションをモニタしてみると、あるタイミングでデバイスがリセットされるタイミングがあった。これがモデムモードへの切り替えコマンドだろうと推測してもう少し中身を眺めてみる。


D21LCのモード変更コマンドはUSBマスストレージデバイスに対するコマンドとして実装されていた。(コマンドパケットの先頭の0x55 0x53 0x42 0x43:USBCが規定のマジックナンバー)といっても、USBマスストレージデバイスの仕様には定義されていない独自コマンドを発行している。
さらにモデムの動作を眺めてみたが、それ以降は普通の3Gモデムと同様の動作をしているようだ。
というわけで、このシーケンスを発行するようにデバイスドライバを拡張してやれば、ほかのOSでもモデムとして利用できるはずだ。

シリアルポート


D21LCではシリアルポートが3本生成される。モデムポートは3本目(openbsdの場合はttyU2)だった。

OpenBSDのデバイスドライバの拡張

実はすでにOpenBSDのumsm(4): 3Gモデム用デバイスドライバでは、このようなUSBマスストレージ型のモード変更デバイスを扱うための機能をすでに実装してある( umsm_umass_changemode() @umsm.c)。 似たようなデバイスを扱うために実装しておいたものだが、今回はこの関数を少し拡張して利用することにした。
すでにOpenBSDのCVSへマージされている(差分)を参照すればわかるが、上でキャプチャしたコマンドをタイミングよく発行するだけだ。
コマンド発行部分の差分を以下に載せておく。いままで2種類の同様なコマンドがあったので、3種類目として拡張しておいた。










おまけ:D21LC雑感

実際に使ったのは短い期間だったが、D21LCを使って気がついたのは、「デバイスがサポートしていないコマンドを受理するとフリーズすることがある」ということだ。正式に使えるコマンドセットが公開されているわけでもないのでバグというのは言いすぎだが、ちょっとした動作確認でハングアップしてしまうことが多くて困ることが多かった。最初はデバイスドライバ側が悪いのかと思ったが、Windowsでも同じ操作で同じ状態に陥ることが確認されたのでデバイス側に問題があるんだと思っている。