FeliCaのデータを読む (その5)

ついにNexus SからFeliCaカード(PASMO)のデータを読めるようになった。ひと通り試してみたが、

    • Polling
    • Request Service
    • Request Response
    • Read Without Encryption
    • Request System Code

FeliCaカード ユーザーズマニュアル - SONY

これらの認証を必要としないコマンドは全て発行に成功したことを確認できた。もちろんPASMOの履歴も読めることを確認した。

プログラミングとしては先日書いた通りのシーケンスで(先達の方々がそうしたように)ひと通り必要なフィールドやメソッドへの参照を取得して実行するだけだが、コマンドに問題がありPICC側(カード側)にコマンドが認識されない状態だった。

例えば、単純なコマンドとしてカードの存在を確認するRequest Responseコマンドがあるが、コマンドは以下のバイト列で生成する。

コマンドコード IDm
04 01010501CB01F31D

(ビッグエンディアン、16進表記、IDmは架空)

これを以下のようなコードでPICC側にtransceiveしてやれば良いはずなのだが、このままではNFCSTATUS_PENDINGである。

//transceive - request response
ByteBuffer buff = ByteBuffer.allocate(9);
buff.put((byte) 0x04) // requestResponse command
    .put(this.idm);   // IDm 
byte command = buff_requestResponse.array(); 
Method requestResponse = tagService.getClass().getMethod("transceive", Integer.TYPE, byte.class);
byte response = (byte)requestResponse.invoke(tagService, serviceHandle, command);

さて種明し、のつもりだったが今回は止めることにする。
そもそも既にこの問題を解いた方々がソースコードを公開していないこともあるが(だからこそ公開したかったが)、実はこのコマンドの問題について気がついたのは私ではないからだ。私も同じ部分を調べていたのだが、結局その方に教えて貰うまでそこに到達できなかった。(その方のことを知らなかったら未だに分かっていなかったかもしれない)

ヒントを書いておくのでFeliCaをNexus S(Android 2.3+NFC)で使ってみたい人は試行錯誤してみてほしい。

    • FeliCaのコマンドとは互換性がある
    • NFCFeliCaコマンドのバイト列だけを直接送っても駄目
    • 何かが足りなくてコマンドを解釈できない

こんな所だろうか。NFC関係のJNIのソースコードをすらすら読める人やPaSoRiを所持しておりFeliCaLib等を使って実際にFeliCaのプログラミングの経験のある方はすぐに気がつくと思う。(私が気がつかなかったのはPaSoRi未経験者であったことが影響していると思う※)

※今思い出すとSuicaPasmoもNDEFだと思っていたのも混乱した原因だった