2012/01/08

[nfc]SDK for NFC Starter KitでFeliCa Liteに読み書きする

SDK for NFC Starter Kitをちょっと使ってみたい、という人に向けて、FeliCa Lite用のサンプルを作りました。
https://github.com/hirokuma/NfcStarterKitWrap

PaSoRi(RC-S370)とFeliCa Liteがあれば、試せます。

ソース解説

主なソースファイルは、以下になります。
  • FelicaLiteReadWrite.cs
  • FelicaLite.cs
  • NfcStarterKit.cs
  • felica_nfc_dll_wrapper_basic.cs
ライブラリにあたるものは、青文字の3ファイル。
一番下にあるfelica_nfc_dll_wrapper_basic.csは、SDK for NFC Starter Kitに付属していたサンプルに手を加えた程度のものです。

NFCStarterKit.cs

Windowメッセージ処理と、SDK for NFC Starter Kitを使うときの基本処理を置いています。
これもまた、SDK for NFC Starter Kitのサンプルからけっこうな部分を持ってきています。
追加しているのは、NfcF_Read()とNfcF_Write()。
ここでFeliCa Liteに読み書きをしています。
bool NfcF_Read(ref byte[] buf, UInt16[] block, byte block_num, byte[] svc)

変更すればFeliCa Standardも読めるはずです。
サービス数を1固定にしているところが「NfcF」としている理由です。
サービス数が1固定なので、ブロックリストを返す関数CreateBlockList2()の第2引数が0になってます。
(先頭のサービスコードを使用する、という意味。)
svc[]はリトルエンディアンなので、ご注意を。
bool NfcF_Write(byte[] buf, UInt16[] block, byte block_num, byte[] svc)

Writeも同様。
サービス数は1固定です。

FelicaLite.cs

NfcStarterKit.csを、もう少しFeliCa Liteにカスタマイズしたクラス。
NfcF_Read()やNfcF_Write()のサービスコードは固定だし、書き込めるブロック数は1つだけなので、そこら辺を省略できるようにしてます。
bool Read(ref byte[] buf, UInt16 block)
bool Write(byte[] buf, UInt16 block)

そうそう、読み込みはNfcF_Read()内でバッファを確保して返すので、第1引数はnullが突っ込まれた変数とかでよいです。
それ以外は、1次発行向けの処理ばかりです。



コマンド解説

詳細はFeliCa Liteユーザーズマニュアルをダウンロードして参照してください。
・・・だけだと味気ないので、少し書いておきます。
まず注意点からですが、FeliCaLibNfcThru()でNFC-Fコマンドを使う場合にはバッファの先頭がバッファ長になります。
Mifareコマンドの場合はコマンドから始まるので、ちょっとはまりました。
なんで違うのか調べていたのですが「そういうものだから」という結論になりました。
NFC Forumの「Digital Protocol」ドキュメントに、NFC-A, B, Fの「Data and Payload Format」があるのですが、NFC-AとBはペイロードから始まっていて、NFC-Fはデータ長から始まっています。
せっかくライブラリになってるんだから吸収してくれてもいいんじゃないの、と思わなくもないですが、将来的な何かを気にしたのかもしれません。

Read without Encryption

「without」ということで、認証無しの読み込みができます。
もちろん、withoutなしのReadコマンドもあるのですが、使い方はよく知りません。
without有無の違いですが、認証されたところを読めるかどうかです。
携帯電話に搭載されているFeliCaチップは大部分が認証されたデータになっていますが、ところどころwithoutで読めるところもあります(確か)。
このコマンド、NFC Forumでは「CHECK」という名前になっています。
注意点は、サービスコードリストはリトルエンディアンで、ブロックリストはビッグエンディアンというところ。
サービスコードは、とりあえずRead Onlyのにしておけばいいでしょう。
Read/Writeでもいいけど、その場合はWriteできないブロックへのアクセスに失敗します。
FeliCa Liteの場合は最大で4ブロックまで同時に読めます。

Write without Encryption

Read w/o Encryptionとほぼ同じです。
書き込めるのは1ブロックのみ。
サービスコードは、当然Read/Writeです。

ステータスフラグ

結果にはステータスフラグが載ってくるので、それをチェックします。
ステータスフラグ1が0x00かどうかだけ見れば事足りるでしょう。
FeliCaのデータはEEPROMに保存されていると思うので、10万回か100万回くらい書き込みをすると「もうだめ」ということになると思います。
ステータス2の「致命的」なのは、そんな現象じゃないでしょうかね。
これはもう、ハードウェアの限界なので、交換しかなくなります。

ポーリング

読み書きする前に、カードを「捕捉する」という動作が必要になります。
それがポーリングです。
ポーリングについてはライブラリでサポートされているので、自前でコマンドを打たなくても大丈夫。

4 件のコメント:

  1. 匿名01:13

    こんにちは。いろいろと参考にさせていただいています。
    公式のSDK for NFC Starter Kitにはブロックへの書き込み関数はないのでしょうか?
    見てるんですがそれっぽい関数がなぜか見つからない。もともとstarter kitには付属してないのでしょうか?
    よろしくお願いします。

    返信削除
  2. そうですね、「ブロック書き込み」のような関数は用意されてません。
    PaSoRiはNFCのAやらBやらFやらを扱えるので、それぞれにブロックの考え方が違うからだろう、と勝手に思ってます。


    SDK for NFC Starter Kitの考え方としては、NFCのアクセスを用意するのではなく、PaSoRiへのアクセス手段を用意している、ということになります。
    NFCといっても、A, B, Fがあり、それぞれの関数を用意するのが大変なためかどうかは知りませんが、そういうのはユーザ任せになっています。
    サンプルソースがついているのは「こうやって使うんですよ」の説明だと思ってます。

    felicalib_nfc_thru()を使って、PaSoRiへコマンドを送信して、ブロックの読み書きなどができます。
    コマンドを作ったり、そのレスポンスを解析するには、PaSoRiの知識が必要になってきます。

    ここのブログで使い方の説明をしていたので、よろしければどうぞ。
    http://bs-nfc.blogspot.jp/

    返信削除
  3. 匿名00:56

    ご返答ありがとうございます。遅れてしまい申し訳ありません。
    felicalib_nfc_thru(command_packet_data, command_packet_data_length, presponse_packet_data, presponse_packet_data_length);
    これのことでしょうか?
    なるほど。sdk for nfcにはブロックへの書き込む用の関数が存在していないんですね。
    自作なされた
    bool Write(byte[] buf, UInt16 block)
    関数みたいに自力で書き込める関数を作らなければならない。ということなんですね・・・。
    それとbool Write(byte[] buf, UInt16 block)ですがテストプログラムに使用してもいいでしょうか?この関数をそのままソースへ貼り付ければ動きますか?
    あまりC#は長くやってないもので・・・。よろしくお願いします。

    返信削除
  4. thruは、確かそんな関数だったと思います。
    というのも、私は位置からライブラリを作ったのではなく、SDK for NFC Starter Kitに付属しているC#サンプルを拡張する形でライブラリに仕立て上げたからです。

    オリジナルのフォルダは、こういう感じのところにあります。
    \sample\NFC_and_PCSC\nfc_library_samples\ReadingMifareCard\src\Csharp\nfc_sample_01

    ここから、いろいろ足していって、これができたのでした。
    https://github.com/hirokuma/NfcStarterKitWrap

    ソースをそのまま持っていくのであれば、ここら辺の依存関係を確認していくことになると思います。
    https://github.com/hirokuma/NfcStarterKitWrap/tree/master/NfcStarterKitWrap/NfcStarterKitWrap
      felica_nfc_dll_wrapper_basic.cs
      NfcStarterKitWrap.cs

    返信削除

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。