2009年6月22日月曜日

自作arduinoのための breadboard hack

lilypadのブートローダをつかえば、ブレッドボードでarduinoを組み立てるのは非常に簡単である。これをさらにonechip arduinoにしてしまうとブレッドボード上のパーツも非常に少なくなるので、小さなブレッドボード上にもかなりの回路をのせることが可能になるだろう。

しかしここで問題になるのは、ブレッドボード上においた AVRのチップのピンと、Arduinoのピンの対応がすぐにわからなくなることだ。何度もやって覚えてしまえればいいのだろうが、間違っていてはあまり意味もないことからこんなhackをやってみた。
ブレッドボードの裏にネットでみつけた ATmega と Arduinoのピン配列の対応表をそのまま貼付けておくだけである。対応図はいろんなところにあるので探してほしいが、たとえばこういうのである。

Make: blog本体ではこんなのが出ていた。この場合チップ単体で使うのならいいのだが、1chip arduinoをつくって部品をチップ上に盛ってしまった場合には下の文字が読めない。

これは undocumented 情報としてMake Tokyo Meeting 03 で初お披露目したのだが、なかなかウケたのでエントリーにもしておくことにする。



UNIX系OS用UQ wimaxドライバの作成(1)

MTM3が終わってから、今度は2週間ちょっとの出張がはいってしまってなかなかblogを書く時間をとれなかったが、いつまでも「MTM3参加中」のエントリがトップなのも寂しいので、最近のwimax関係のアップデートを書いてみる。


UQ Wimax解析の状況

GCT720X系のチップセットを使っているインターフェイス(UD01SSとかUD01OK)の解析はほぼ完了した。要素としては大きく分けると、
  • データ通信系(Ethernetフレームを交換する部分)
  • 認証系(EAPパケットを処理して通信に必要な鍵を生成する部分)
  • ネットワークエントリ系(認証系に加えてwimaxネットワークに参加する部分)
  • データストア系(加入者識別子、パスワード、デバイスのX509証明書の処理)
  • 管理系(通信状態把握、パラメータ設定)
くらいに分類される。通信に必要なのは最初のデータ通信系の機能だけだが、そこに至るために残りの部分を攻略しなければならかった。「データストア系」はネットワークに接続するために必須の部分であるのに関わらずまったく仕様が公開されていないため、比較的時間を費やしてしまった。

動作検証コード

解析結果はすべてOpenBSD上で検証コードを作成して、実際の動作を確認した。
未知のデバイスのドライバをカーネルドライバとしていきなり実装するのは開発効率が悪すぎる。今回は、ずいぶん前に「ugenでラピッドプロトタイピング(*BSDでUSB)」で書いたようにugen(4)を利用してユーザーランドで実装してみた。さらに、ethernetインターフェイスへのアクセスにもtuntap仮想インターフェイス(tun(4))を用いてユーザランドドライバとして実現した。
ugen(4)を用いてUSBバスをユーザランドドライバに見せたうえで、データフレームをtun(4)でカーネルに挿入するアプリケーションをかけば、実質上ユーザーランドだけでデバイスドライバを書くことができる。
この「ユーザランド」ドライバの構造(概略)を右図に示す。簡略化のために一個のプロセスで全部入りでつくったが、検証用には十分だろう。
機能としては、Wimaxのネットワークをスキャンして、UQ Wimax決めうちで接続処理を行う。デバイスから必要な情報を引きずり出して、認証機構がEAP-TTLS/MSCHAPv2でWimax-PKMv2を処理してログイン&鍵対の生成を行っている。
うまくつながれば、あとはugen(4)とtun(4)をブリッジしてEthernetインターフェイスとして動いてくれる。普通にDHCPでアドレスをもらって通信できるところまでは動作確認済みだ。
あ、あと、Ethernetブリッジしているのにtapじゃないのは、OpenBSDではtapがtun(4)に統合されているから。tunをLayer2モードで駆動している。

ユーザランドドライバの副次的な効果として「移植性の高さ」がある。たぶん、ほとんど変更しなくてもbsd系のOSでは動くだろうし、ugen(4)をlibusbかなにかに置き換えればOSXやlinuxでも動いちゃうんじゃないかなと予想している。だれかやってみないかな。
ソースは公開する予定だけど、作業の優先順位は要望によって変わります。

今後の予定

ちょっと落ち着いてきたので、解析結果のまとめをつらつらとblogに書きながら、(途中になっている)kernelドライバの作成をやってみようとおもっている。
変なNDAに縛られちゃう前に、知っていることは公知にしておくといいよね?

2009年5月23日土曜日

Make Tokyo Meeting 03 参加中


表題のとおり 今日からはじまったMake Tokyo Meeting 03 に本blogはhwhack.blogspot.com というまんまの名前で参加しています。本日も多数の訪問者ありがとうございました。

blogでは語れないあんなことやこんなこと、中の人の素顔、途中経過がわからなくなったプロジェクトの進捗など知りたいことがあればぜひおこし下さい。
One Chip Arduinoや USB BlinkM などわかりやすい展示品も取り揃えてあります。

体育館はいってすぐ、blog同様のとってもカオスなブースでお待ちしています。

2009年5月14日木曜日

UQ Wi-Fi Gatewayのバッテリ駆動


(念のために書いておきますが本記述は無保証です。バッテリ系はいろいろと危険があるのでよい子・良い大人の方々はまねをしないでくださいね)

UQ WimaxのWi-FI GatewayのWifiアクセスポイント側(UG01OK)のバッテリを入れる場所を眺めていたら、手元にあったクティオのバッテリがぴったりはいるような気がしてきたので試しにいれてみた。なんかぴったりはいります。ふたも閉まります。ふむ。

おそるおそる電源をいれてみると、うごくっぽい。
電源LEDもつきます。ACアダプタをつなげると「battery」LEDも点灯。充電もしてくれるっぽい。

すぐに切ったのでどのくらい使えるかは調べていませんが、3.7V 1900mAHしかないのであんまり持たないと思います。



OpenBSDでSoftbank C01SWを使う

週末に海外の見知らぬ人から「(俺の)sierra wirelessのHSDPAモデムがopenbsdで使えないんだけど」というメールが届いた。ちょうど他の作業で煮詰まっていたので息抜きに何通かメールをやりとりして、OpenBSDのumsm(4)で動くパッチを作ってみた。先方曰く「ちゃんと動いた!」と報告してくれたが、手元に無いデバイスなので不安は残る。ふと思い立ってgoogleするとSoftBankモバイルのC01SWはSierra wirelessのOEM製品らしい。周りを少し見渡すと持っている人が見つかったので、実際にためしてみた。


Tru-install

C01SWはsierra wirelessの「Tru-install」という機能を搭載している。これは、他の3Gモデムでもよくある「普段はUSBマスストレージのデバイスとしてみえて、そこにデバイスドライバがはいってる。そのデバイスドライバをつかってモデムモードに切り替える」という機能だ。windows以外ではあんまり便利ではないし、自分でモードを切り替えてあげないといけない。

Tru-installのモード変更方法

もうこの手の話は何回もしているので、簡潔にモード変更方法を書いておく。
  • USB requestType = Write/Vendor/Device
  • USB request = 0x0b
  • USB request wValue, wIndex, wLength = 0x1, 0, 0
というコントロールリクエストをデバイスに送ると、デバイスがUSBバスから切り離されて再度認識されたときにはモデムデバイス+マスストレージデバイスの複合デバイスに変化している。上記に対応する関数を抜粋すると、こんな感じ。


#define TRUINSTALL_CHANGEMODE_REQUEST 0x0b
usbd_status
umsm_truinstall_changemode(usbd_device_handle dev)
{
usb_device_request_t req;
usbd_status err;
req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
req.bRequest = TRUINSTALL_CHANGEMODE_REQUEST;
USETW(req.wValue, 0x1);
USETW(req.wIndex, 0);
USETW(req.wLength, 0);

err = usbd_do_request(dev, &req, 0);
if (err)
return (EIO);
return (0);
}


umsm.cに対する変更の全体はCVSで参照できる。

あと、OpenBSDではsys/dev/usb/usbdevsにこのデバイス用のProduct IDを追加しなければならなった。これは追ってコミットしておく。

C01SW概略

アタッチしてみてちょっと驚いたのはインターフェイスが7本出現したことだ。一般に3Gモデムは複数(2−3本)のインターフェイスを用意しているが7本出てきたのは初めてだった。
USBディスクリプタを見ると4-7本目のインターフェイスはインタラプトエンドポイントを含んでいるのでこれらのどれかが通信用のポートのはずだ。上から試してみたところ、4本目が通信用のポートだった。5−7本目のポートはエコーバックされないがATコマンドに反応しているので何らかの管理ポートだと推測される(詳細は見ていない)。

C01SWで通信する

OpenBSDのkernel ppp実装のpppdを使って通信を試みたところ、さっくりとつながった。
設定は昔「NetBSDでEmobile D02HWを使う(設定編)」で書いた物とほとんど同じで、
  • ifconfig ppp0 create でpppインターフェイスを作る
  • /etc/ppp/peers/に対応する設定ファイル(たとえばsoftbank )を作ってttyU3を通信ポートに設定する
  • ソフトバンク用のユーザIDとパスワードを/etc/ppp/chap-secretに書いておく
だけだった。pppd call softbankだけでpppがつながって通信できた。


2009年5月12日火曜日

E-mobile D12HWとD22HW

E-mobileの最近のモデムを触ってみる機会があったのですこし調べてみた。結果を共有。


触ったのはD12HWD22HWで両方ともHUAWEIのOEM製品だ。D22HWはHSUPAでアップリンクが最大1.4Mbpsまで使えるというのが特徴らしい。

OpenBSDで試してみる

HUAWEIの多くのモデムは同じUSBベンダIDとプロダクトIDを共有しているが、今回もその例に漏れず同じIDを利用していた。OpenBSDで試してみたところ、両者とも標準的なHUAWEIプロトコルでUSBマスストレージモードからモデムモードに遷移するようだ。umsm(4)としてデバイスは認識される。pppd経由でネットワーク接続もできたようなので何の工夫もせずに普通につかえる。

メモ:D12HW

D12HWに関してはUSBのディスクリプタの文字列が壊れている部分がある。利用する分には問題はないがUSBディスクリプタの文字列を信用してデバイス認識時に画面に出力してしまうとなんだかよくわからない文字列が表示されてしまうかもしれない。
しょうがないのでOpenBSDではディスクリプタ中の文字列を信用せずにusbdevsの中の文字列を利用するようにUSB_QUIRKS: UQ_NO_STRINGSを設定しておいた。本来はD12HWだけでこのquirksが使われるようにすべきだがみんな同じベンダIDとプロダクトIDを持っているのでほとんど全部のHUAWEIモデムにこのquriksが適用されてしまっている。


2009年5月10日日曜日

UQ WimaxのUD01SS解析 (4)

前回の続き。

一行まとめ「UD01SSの内部コンソールを取得する」話。

OKIネットワークスが出しているUD01OKの解析をしてみたところ、同じGCTセミコンダクタのGDM72XXを使っている製品なら、ほぼUD01SSと同様な構成になっているのではないかと予測を立てることができた。たぶんGCTセミコンダクタが提供するファームウェアおよびデバイスドライバのSDKがLinuxをベースとしたものになっているのだろう。ということで、今後もGDM72XXを使う製品が出るのなら今回の一連の解析も役に立つだろう、ということでよりディープなところもまとめてみたいと思う。

このエントリではUQのUD01SS(やUD01OKなどのGDM72XXベースのWimaxインターフェイス)内で動いている「Wimaxアプリケーション」の操作コンソールについて説明する。

UD01SSの内部ではLinuxが動いている、というのは(1)で 書いた。汎用OSであるLinuxをファームウェアとして利用している以上、カーネル内部だけではなくユーザランドでも何らかのアプリケーションが動いて いるのは当然だ。解析を進めている途中で、そのアプリケーションと対話的に通信していろいろな情報を取得できるようになった。右にWimaxアプリケーションのコマンド一覧(helpコマンドの出力)を載せる(長いので画面キャプチャ形式)


UD01SSの内部アプリケーション:/usr/wimax

UD01SSのユーザランドとしてWimax関連で動いているのは/usr/wimaxコマンドである。このコマンドがGDM72XXのいろいろな要素(内部の別プロセッサとかで動いているプロセスとか)と通信しながら、ホストインターフェイスを提供している。
ホストPC側にWimaxインターフェイスとしての機能をUSBバスを経由して見せているのもこのアプリケーションで、ホスト側からのコマンドはこのアプリケーションが処理している。さらに管理用の対話的コンソールも提供されている。対話的コンソールが受理するコマンド一覧を上の図に示した。使い方はまだわからないことも多いがUD01SS内部で処理しているWimax関連の機能の内部状態を見ることができるので大変便利だ。
右図の画面ダンプはparamコマンドの出力例(mac addressは隠してある)だ。paramコマンドはデバイスの設定パラメータをダンプしてくれる。Wimaxの物理層まで興味があれば役に立つこともあるかもしれない。
ヘルプ画面にあるshellコマンドは興味深い。/bin/shを立ち上げて(fork & exec)内部のlinuxに対するshellアクセスを提供してくれるはずだが、子プロセスとしてのshellはUSBバスに対する通信機構を持っていないのでこの方法でのアクセスでは使えない。大変残念だがUSB経由(wimaxアプリケーションを経由)のshell取得は原理上無理があるようだ。

Wimaxアプリケーションのコンソールでできること

できることは大体以下の通り。

  • 対話的にコマンドを発行してレスポンスを受け取る。たとえば「version」「param」「dump」コマンドはいろいろな内部状態を出力する。
  • 対話的にコマンドを発行して動作モードを変える。(詳細は不明)
  • メモリ状態などを読み込む(詳細は不明)。発行してもハングアップしてしまう場合が多い。
  • 「log on wimax」コマンドを発行すると、非同期メッセージを受け取れるようになる。たとえば、内部の状態遷移に付随して発生する様々なメッセージを受信できる。さらに「sc」「nds」コマンドでデバグメッセージを出力させることで、もっといろいろなことを教えてくれるようになる。
最後の機能は非常に強力だ。単純なUSBバス解析だとバイナリ列の{コマンド,レスポンス}の組を統計的に解析していって意味を抽出する作業が必要になるが、コマンドに対して人間が読める形のレスポンスや状態遷移のタイミングを取得できればシステマチックな解析が可能になる。

取得できる出力の例
2009/4月のファームウェアアップデート後のUD01SSのVersion

DM> version
version 0.3.8.0 (00030800)
DM> dump ver
FW : Rev=1.6.6.4, 2009/04/03 18:18:00 (build: 2009/04/06 16:58:33)
RF : srf72xx-081025(72050227,0), Default
CFG: PHY=0x602, SPEC=204, CPU=3, SD_AFC, UPT, DNT, ARQ2, IPC, FREQ2.5G, SAMSUNG
MAP: 2009-03-24-1613-WAVE2

ほかにも接続状況なども取得できるが、それらは今後対応した操作を説明するときに説明しようと思う。

アクセス方法(概略)

Wimaxアプリケーションのコンソールに対するアクセス方法の概略を載せておく。詳細はGDM72XX系のコマンド体系をまとめるときに補足する。

GDM72XXのコマンドは、大体
  • 2バイトのヘッダ(Command/Response Type)
  • 2バイトのペイロード長(データ部分だけ。ヘッダ部分は含まない)
  • データ
のTLV形式で定義されている。(USBなのでビッグエンディアン)
コンソールに対するデータ送信は、Type:0x030cで、送信したい文字列に"\n\0"文字をつけてデータとして送信する。
受信は非同期メッセージを扱う場合はちょっと複雑だが、普段はType:0x830dのデータの9バイト目から文字列として扱えばよい。継続行がある場合は文字列の最後が非NULL文字になるので、文字列の最後がNULL文字になるまで繰り返し読み込めば複数行のレスポンスも取得できる。

いまはとりあえずopenbsdのugenで書いたユーザランドアプリケーションで実験をしている。プログラムの長さで3-4KBくらい。もしUD01SSとかで遊びたい人がいたら適当に声をかけてほしい(一人だと飽きそう)。

次回

次回のエントリでは、GDM72XXのコマンド体系について説明しようとおもう。認証部分はそのあとになる予定。