以前、Felicaを使ったシステムを企画してみたいなぁとふいに考えた。で、Felicaを使った(Felicaにアクセスする)開発には「SDK for Felica」という製品が必要だ。SDKにはLiteからEnterpriseまで出来ることの違う製品がいくつかある。
当時、いいタイミングで「IC CARD WORLD 2005」というのがビッグサイトでやっていたので、これに出かけていってソニーのブースでSDKの値段やら色々聞いてみた。Liteを使えばフリー領域のみではあるが読み書きが出来るというので、さっそく購入しようと代理店2社に電話した。そしたら「個人の方にはお売りできません」との返事。がっかりだ。
※ホントにシェアとりたいんだったらSDKは個人にも開放して、どんどんアプリやシステムを書かせればいいと思うんだけどね。

それから1.5年ほどたって、ふとオープンソースマガジンを手にとると、自前で解析して読み取りを成功させている人がいるじゃないか。恐ろしいことよ。(「SFCardPeeper」のことは以前から知っていたが、技術情報を整理して雑誌に載せた、というのがすごいと思う)さっそくプロジェクトのページからダウンロードしてSuicaを読ませてみる。自分が持っていたR/WはS310だったので見事に読めず。

やむを得ずビックカメラでS320をゲットしてきた。携帯にもFelicaが載るようになったせいか、S320の読み取り部分はフラットになった。なので、自分のように机の上が雑然としていて、水平にR/Wを置けない環境では、載せたカードがすべり落ちてしまう。この辺はS310の方がよかったなぁ、などと思いつつチャレンジ。S320に変えたらあっさり読めた。

じゃあ、早速何か書いてみよう、とlibpasoriを眺めたのだが、unixとソース共用を意識しているせいか開発環境がcygwinやMinGWなんだな。それに最近はC#が好きだし、C#からアクセスできるようにしたいなぁ、ということでlibpasori.NETを書いてみた。

注意:要するにラッパーを書いただけなので、Felicaおよびlibpasoriの技術的な情報は何もありません。libpasoriの情報はlibpasori - RC-S320操作コードを参照

方針

  • 目的:libpasoriをC#から使いたい。
    • まずVisual C++を使ってlibpasoriとインタフェースするためのDLLを作る。
    • このDLLをP/InvokeでC#から呼び出す。
  • libpasoriには読み書きのための関数がいくつかあるが、率直な話、プロトコルの解析には興味がないし、セキュアなR/W(特にW)はSDKがないと無理そうだ、と考えた。となれば「カードのIDを読み取る」機能だけがあればいいので、以下の関数だけ呼び出せるようにすることにした。
    • pasori_open()
    • pasori_init()
    • felica_polling()
    • pasori_close()
  • libpasoriはまだこれから変化していくはずなので、出来れば元のソースはいじらないで済ませる。

準備

  • LibUsb-Win32
    • Windows版のlibpasoriを動かすのに必要。事前にインストールしておく。
    • ちなみに僕のところではこれをインストールしたら、Windowsがシャットダウンしなくなった。(「シャットダウンしています」のままになる。)ので、自己責任で。USBsnoopも使ってるのでこれが競合しているのかもしれない。
    • 今回使ったのは「libusb-win32-filter-bin-20060518.exe」。リリース版で上記のようにシャットダウンしなくなったのでsnapshot版ならイケるかな、と思ったらそうでもなかった。
    • 上記のファイルをインストールすると、ソースとヘッダファイルもインストールされる。うれしいことにVC用のインポートライブラリも同梱されているのでありがたく利用する。
    • 上記のヘッダをインクルードできるよう、上記ライブラリをリンクできるようにVisualStudioのディレクトリ設定を追加する。
  • libpasori
    • 上記ページからソースをダウンロード。今回使ったのはlibpasori02.tar.bz2

libpasori.NET

  • cc.breeze.libpasori.Pasori
    • libpasoriのpasori型に相当します。
  • cc.breeze.libpasori.Felica
    • libpasoriのfelica型に相当
  • cc.breeze.libpasori.PasoriNotifier
    • 別スレッドを用いて、一定間隔でパソリをポーリングし、完了後にコールバックする。

簡単なサンプル

        static void Main(string[] args)
        {
            Pasori ps = null;

            try
            {
                ps = Pasori.Open();

            }
            catch (LibPasoriException ex)
            {
                Console.Error.WriteLine("パソリの初期化でエラー");
                return;
            }

            try
            {
                Felica fc = ps.Polling(SystemCode.ANY);
                Console.Out.WriteLine("IDm:" + fc.IDm_text);
                fc.Close();
            }
            catch (LibPasoriException ex)
            {
                /*
                 * 現在のところエラーなのか、何も読めなかったのかは区別がないので
                 * 例外を無視
                 */
            }
            
            ps.Close();
        }

で、サンプルがこれ。パソリをUSBポートに挿して、Felica(僕のところで試したのはSuicaとauのお財布ケータイ)をかざせば、カード固有のIDを読み取ることができる。

libpasori.NET(ソースとサンプルexe:約330KB)
  • Visual Studio 2005 on XP Proでコンパイルしたもの。他の環境で動くかどうかわかりません。
  • この配布物の使用は自己責任で。何が起こっても作者は責任を負いかねます。
  • NOD32アンチウイルス パターン1.1650(20060707)でチェック済み。
  • ただのラッパーにライセンスを謳うのも気が引けるけど、ソースの改変、配布は自由です。
    • libusb、libpasoriについては、上述の両プロジェクトのページを参照してください。