MVPen (Pegasus Mobile NoteTaker) の解析 (2)

MVPenLinux から使う試みシリーズ。おまちかね?の解析結果です。

※注意※ MVPen が故障する可能性があります

全般

USB デバイスとしての諸元は下記の通りです

  • ベンダ ID: 0x0e20
  • プロダクト ID: 0x0101
  • バイス名称: Pegasus Technologies Ltd. NoteTaker FW Ver 3.03
  • 制御用エンドポイント (IN) アドレスは 0x81
  • オンラインノートモードインタフェースデバイス用エンドポイント (IN) アドレスは 0x82
  • それ以外のエンドポイントアドレスは不明ないLinux の lsusb がうまくパースできていないため*1

MVPen の HID レポート構造を定義する Collection の内容は疑似コードで示すと下記のような感じです。以下の内容は Linux の hiddev に惑わされたため,冗長かつ不正確でした。より単純には MVPen (Pegasus Mobile NoteTaker) の解析 (3) - daily dayflower を参照してください。

CommunicationDefinition {
    ApplicationCollection extends Collection {
        type: CollectionType = APPLICATION_COLLECTION;
        usage: Usage = { 0xffa0, 0x0001 };

        InputReport extends Report {
            index = 0;
            direction: ReportDirection = IN;
            num_fields = 1;

            field[0]: Field = {
                Usage = { 0xffa0, 0x0002 };
                logical_min  = -128;
                logical_max  =  127;
                physical_min =    0;
                physical_max =    0;    /* 間違い? */
                max_usage = 64;
                
                values[max_usage]: signed int;
            };
        };

        OutputReport extends Report {
            index = 0;
            direction: ReportDirection = OUT;
            num_fields = 1;

            field[0]: Field = {
                Usage = { 0xffa0, 0x0003 };
                logical_min  = -128;
                logical_max  =  127;
                physical_min =    0;
                physical_max =  255;
                max_usage = 8;
                
                values[max_usage]: signed int;
            };
        };
    };
};


わたし自身いまひとつきちんと理解していないので,参考程度にとどめてください。理解できなくても使えます。

要点だけ抜き出すと,

  • Application Collection がフラットに 1 つ存在しているだけ
  • InputReport (ID = 0) が 1 つ定義されている
    • フィールドは 1 つ
      • フィールド内容は実質 signed char[64];
  • OutputReport (ID = 0) が 1 つ定義されている
    • フィールドは 1 つ
      • フィールド内容は実質 signed char[8];
  • FeatureReport は定義されていない

ということになります。

んーと,HID のレポートは(ID をかえることで)何種類か定義することができるのですが,そのようなファームウェアを用意するのが面倒だったのか,入力と出力で一種類ずつしか定義されていません。なるべく汎用的なデータ構造を用意して,それを使いまわしているわけです。

つまり,MVPen の場合,

  • バイスへの出力には char[8] のパケットを送る
  • バイスからの入力は char[64] のパケットでやってくる

のように簡略化して考えることができます。

したがって,以下のデータ例では入出力はすべて char[64] / char[8] とみなします。ただ,先頭部分しか意味をもたないデータもありますので,後続するバイト列は省略しています。


以下各レポートの [S/R] というのは Send and Receive,[R] というのは Receive,[S] というのは Send を示します。あっと,レポートというのは HID 用語です。コマンド列やパケット列,のように考えるといいかと思います。

[S/R] ステータスチェック

一番よくつかうレポートです。

PC からデバイス

02 02 95 95 00 00 00 00

というレポートを投げると,

80 A9 28 01 3E 01 09 7D 1C 0E xx 00 00 00 00 00 ...

というレポートを返します。

先頭部分のデータ内容は不明です(シリアルだったりして……だったら恥ずかしい)。

xx の部分は

  • 01 の場合,オンライン・ノートモードであること
  • 02 の場合,オンライン・マウスモードであること

を示します。

バイスがビジー状態の場合,デバイスからのレポートが送信されないことがあります。そのため,レディチェックとしては,ステータスレポートが帰ってくるまでステータスチェックレポートを送信することが推奨されます。

[R] ボタンイベント

バイスのボタン(ペン側ではなくてレシーバの液晶脇のボタン)を押すと,

80 B5 00 00 ...

というレポートが飛んできます。

Windows の NoteTaker を常駐させている環境では,このボタンを押すと,オンラインノートモードとオンラインマウスモードを切り替えることができますが,これはボタンを押すことによって自律的に動作を変更するわけではありません。このレポートを受信した際に,後述のモード切り替えパケットを送信することで能動的に変更しています。

[S] オンライン・ノートモードへの切り替え

PC からデバイス

02 04 80 B5 01 01 00 00

というレポートを送信すると,レシーバの内部モードをオンライン・ノートモードに変更します。次の例を見ればわかりますが 01 というのがノートモードを示す値と考えられます。

バイス側からレポートが帰ってくるわけではないので,前述のステータスチェックレポートを送信してステータスチェックを行うことが推奨されます。

[S] オンライン・マウスモードへの切り替え

PC からデバイス

02 04 80 B5 02 02 00 00

というレポートを送信すると,レシーバの内部モードをオンライン・マウスモードに変更します。02 というのがマウスモードを示す値と考えられます。

NoteTaker を常駐させずにレシーバを USB ポートにつなぐと,デフォルトではこのオンライン・マウスモードになります。NoteTaker ではレシーバの接続を監視していて,環境設定で設定したモードに設定しているだけです。

02 04 80 B5 01 02 00 00

のようなレポートも解析中に確認した気がするのですが,どういう意味があるのかはちょっとわかりません。

[S/R] モバイルノートデータ量の取得

PC からデバイス

02 01 B5 00 00 00 00 00

というレポートを送信すると,レシーバに格納されている全筆跡データのデータ量を返してきます。

バイス側が送信するレポートは,

AA AA AA AA AA xx xx 55 55 00 00 00 00 00 00 00 ...

のような感じです。AA55 が何を意味しているのかはわかりません。

xx xx の部分が後述するモバイルノートデータのレポート数(行数)です。MVPen の生データは基本的にリトリエンディアン(86系)なのですが,このレポート数に限ってはビッグエンディアン(68系)となっています。

いまのところ,モバイルノートの全ページのデータ量を検査するレポートしか判明していません。ページごとのデータ量はわかりません(後述しますが,ページごとの取得はできないと思われます)。

[S/R] モバイルノートデータの取得

PC からデバイス

02 01 B6 00 00 00 00 00

というレポートを送信すると,レシーバに格納されている全筆跡データをバルク転送してきます。

バイス側が送信するレポートは,

00 01 xx xx xx xx xx xx xx xx ...

00 02 xx xx xx xx xx xx xx xx ...

00 03 xx xx xx xx xx xx xx xx ...

...

01 23 xx xx xx xx xx xx xx xx ...

のようになります。行分けしてありますが,この例だと 0x0123 個のレポートにわけて送信してくるという意味です。

各レポートの先頭に 2 バイトの「行インデックス」が存在します。これはさきほどと同じようにビッグエンディアン(68系)であり,0x0001 からスタートします。

このように一応先頭ワードを確認するとデータの終了時点はわかるのですが,念のためにデータがこなくなってからステータス確認レポートを送信したほうがよいでしょう。また,そのように(一定時間)データがこなくなることがデータの終了,とみなすほうがプログラムを組みやすいこともあるでしょう。

ページごとの筆跡データを取得するレポートは判明していませんが,存在しないかと思われます。


なお,含まれるデータ(xx xx xx ...)ですが,後日ソフトウェアを記述するときに改めて解説します。

2008-08-20 追記: 直前に「モバイルノートデータ量の取得」を行っておかないと失敗する(データが帰ってこない)ようです。たとえば直前に「ステータスチェック」をするとうまくいきません。

[S] モバイルノートデータの削除

PC からデバイス

02 01 B0 00 00 00 00 00

というレポートを送信すると,レシーバに格納されている全筆跡データを消去します。

とくに返信レポートはありませんので,ステータスチェックをするなり,念を入れてモバイルノートデータ量の取得をおこなったりするのもよいでしょう。


ページごとの筆跡データを消去するレポートは判明していません。Windows NoteTaker Software にもそのような機能はないので,おそらくページごとに処理するレポートというのは定義されていないのではないかと思われます。

[R] オンラインノートモードの筆跡イベント

こはちゃんと調べていないのでおまけです。

オンライン・ノートモードでペンを動かしたり書いたりすると,レポートが飛んできます。これは 6 バイトを 1 つのパケットとし,いくつかのパケットをまとめてレポートとして送信してきます(もちろんひとつのレポートに 1 パケットのみ含まれる可能性もあります)。

これは HID 準拠スタイラスペンの情報として送っているようです。

40 01 xx xx yy yy

というのが,筆跡データ(ペンを紙に下ろした状態で動かした状況),

40 02 xx xx yy yy

というのが,ペンのクリックボタンを押したときのデータ,

40 08 xx xx yy yy

というのが,ペンを浮かした状態でのペンの位置情報データ,を示していると思われます。

xx xx というのが X 座標,yy yy というのが Y 座標です。これらはリトルエンディアン(86系)でエンコーディングされています。

おわりに

先日紹介した SimpleHIDWrite を使うと,以上の情報をもとに,いろいろやりとりすることができます。また,OS の HID ドライバの使い方がわかれば,筆跡データを取得するソフトウェアを書くこともできるでしょう。

*1:Windows で解析すればわかると思うのですがメモするの忘れてしまった。