概要
Pasori は Sony が提供する Ferica 用の IC カードリーダでよく目にするやつだと Edy のチャージなどに使います
SDK for NFC というこれまた Sony が提供する SDK がありこれを使うと Pasori を使っていろいろな IC カードの情報を読み込んだり書き込んだりすることができます
今回は SDK を使った簡単なサンプルを作成してみました
環境
- Windows7 64bit
- Felica RC-S320
- Microsoft Visual Studio Express 2015 Community 14.0.24720.00 Update 1
- SDK for NFC 2.0.3
Visual Studio のインストール
詳細はこちらを御覧ください
SDK for NFC に含まれる nfc 用のライブラリを使うのですが、これが .lib ファイルという形式で提供されているため Visual Studio が必要になります
自分もよくわかっていないのですが、 .lib ファイルをリンカーとして登録して実行するには普通の gcc が実行できる環境だけではダメなようです
SDK for NFC のダウンロードとインストール
ダウンロードは以下のリンクからできます
http://www.sony.co.jp/Products/felica/business/products/ICS-D004_002_003.html
sdk4nfc_starter203J.zip
をダウンロードしたら解凍して、Cドライブ直下に保存します
C:\sdk4nfc_starter203J
あとは Pasori 用のドライバをインストールしましょう
SDK 内に含まれている exe ファイルを実行すれば OK です
C:\sdk4nfc_starter203J\driver\NFCPortWithDriver.exe
がそれになるのでを実行してドライバをインストールしてください
ドライバをインストールしたら一度再起動したほうが良いと思います
プロジェクトの作成と各種ライブラリの追加
Visual Studio を起動してプロジェクトを作成しましょう
作成するプロジェクトの種類は「Visual C++ -> Windows -> 全般 -> 空のプロジェクト」で OK です
プロジェクトを作成したインクルードパスとリンカーの設定をしましょう
インクルードパスの設定
プロジェクトのプロパティを開きます
C/C++ -> 全般 -> 追加のインクルードディレクトリ -> 編集
で追加ダイアログを開いて
新しい行 -> 参照ボタン
で以下のパスを追加します
- C:\sdk4nfc_starter203J\FeliCa_Library\include
- C:\sdk4nfc_starter203J\NFCAccessLibrary\include
追加できたら OK -> 適用しましょう
リンカーの設定
プロジェクトのプロパティを開きます
リンカー -> 入力 -> 追加の依存ライブラリ -> 編集
で追加のダイアログを開いて以下のライブラリを追加します
- C:\sdk4nfc_starter203J\FeliCa_Library\lib\x86\felica.lib
- C:\sdk4nfc_starter203J\NFCAccessLibrary\lib\x86\felica_nfc_library.lib
追加できたら OK -> 適用でプロパティを閉じましょう
ソースファイルの追加
ソースファイルをプロジェクトに追加します
プロジェクトを右クリック -> 追加 -> 新しい項目
で追加ダイアログを開いて
Visual C++ -> C++ ファイル (.cpp) -> 追加
でソースファイルを追加しましょう
デフォルトだと Source.cpp というファイルが追加されます
追加できたら早速サンプルコードを記載しましょう
コードの全容は以下の通りです
#include <cstdio>
#include <cstdlib>
#include "felica.h"
int main(void);
void error_routine(void);
void print_vector(char* title, unsigned char* vector, int length);
int main(void)
{
if (!initialize_library()) {
fprintf(stderr, "Can't initialize library.\n");
return EXIT_FAILURE;
}
printf("Complete initialize_library\r\n");
if (!open_reader_writer_auto()) {
fprintf(stderr, "Can't open reader writer.\n");
return EXIT_FAILURE;
}
printf("Complete open_reader_writer_auto\r\n");
structure_polling polling;
unsigned char system_code[2] = { 0xFF, 0xFF };
polling.system_code = system_code;
polling.time_slot = 0x00;
unsigned char number_of_cards = 0;
structure_card_information card_information;
unsigned char card_idm[8];
unsigned char card_pmm[8];
card_information.card_idm = card_idm;
card_information.card_pmm = card_pmm;
unsigned long timeout;
get_polling_timeout(&timeout);
printf("timeout: %lu\r\n", timeout);
timeout = 2000;
set_polling_timeout(timeout);
if (!polling_and_get_card_information(&polling, &number_of_cards, &card_information)) {
fprintf(stderr, "Can't find FeliCa.\n");
return EXIT_FAILURE;
}
fprintf(stdout, "number of cards: %d\n", number_of_cards);
print_vector("card IDm:", card_idm, sizeof(card_idm));
print_vector("card PMm:", card_pmm, sizeof(card_pmm));
if (!close_reader_writer()) {
fprintf(stderr, "Can't close reader writer.\n");
return EXIT_FAILURE;
}
if (!dispose_library()) {
fprintf(stderr, "Can't dispose library.\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
void error_routine(void) {
enumernation_felica_error_type felica_error_type;
enumernation_rw_error_type rw_error_type;
get_last_error_types(&felica_error_type, &rw_error_type);
printf("felica_error_type: %d\n", felica_error_type);
printf("rw_error_type: %d\n", rw_error_type);
close_reader_writer();
dispose_library();
}
void print_vector(char* title, unsigned char* vector, int length) {
if (title != NULL) {
fprintf(stdout, "%s ", title);
}
int i;
for (i = 0; i < length - 1; i++) {
fprintf(stdout, "%02x ", vector[i]);
}
fprintf(stdout, "%02x", vector[length - 1]);
fprintf(stdout, "\n");
}
SDK に含まれているサンプルのソースコードをほぼ流用しています
C:\sdk4nfc_starter203J\sample\FeliCa_Library\sample_06.cpp
サンプルコードの説明
以下ポイントを説明していきます
main メソッドの一番初めで NFC ライブラリの初期化をしています
if (!initialize_library()) {
fprintf(stderr, "Can't initialize library.\n");
return EXIT_FAILURE;
}
初期化が完了したら接続されている Pasori をオープンします
なので、これを実行するときに Pasori がパソコンに接続されて、正常に動作する状態になっている必要があります
if (!open_reader_writer_auto()) {
fprintf(stderr, "Can't open reader writer.\n");
return EXIT_FAILURE;
}
もし、Pasori が接続されていなかったりドライバインストールされていなくてうまく動作しない場合はここでエラーになります
カードのスキャンをスタートする前に Pasori がスキャンする時間を設定してます
unsigned long timeout;
get_polling_timeout(&timeout);
printf("timeout: %lu\r\n", timeout);
timeout = 2000;
set_polling_timeout(timeout);
デフォルトだと 100 ms しかスキャンしないので、カードを乗せた状態で実行しないと検知してくれません
なので、今回は少しスキャンに余裕を持たせて 2 秒間スキャンするようにしました
このあとでスキャンを開始します
if (!polling_and_get_card_information(&polling, &number_of_cards, &card_information)) {
fprintf(stderr, "Can't find FeliCa.\n");
return EXIT_FAILURE;
}
スキャンに成功してカードの情報が取得できると引数として渡している card_information
に値が設定されます
それをその後で参照します
print_vector("card IDm:", card_idm, sizeof(card_idm));
print_vector("card PMm:", card_pmm, sizeof(card_pmm));
最後に処理が完了したので終了処理をしています
if (!close_reader_writer()) {
fprintf(stderr, "Can't close reader writer.\n");
return EXIT_FAILURE;
}
if (!dispose_library()) {
fprintf(stderr, "Can't dispose library.\n");
return EXIT_FAILURE;
}
このあたりでコールしている関数の詳細は SDK に付属の pdf を参照するといいと思います
C:\Users\username\Downloads\sdk4nfc_starter203J\sdk4nfc_starter203J\doc\FeliCa_Library\M735_FeliCaLibrary_StarterKit_1.3j.pdf
ビルドして実際に試してみる
ソースを記載したビルドしましょう
プロジェクトを選択した状態で
ビルド -> ソリューションのビルド
でビルドが成功すれば OK です
失敗する場合はインクルードパストリンカーの設定を再度見なおしてください
今回の場合だと大抵はライブラリの読み込みに失敗してビルドが失敗します
コマンドプロンプトを開いて実際に実行してみましょう
実行するまでに Pasori を PC に接続してください
C:\Users\username\Documents\Visual Studio 2015\Projects\Project2\Debug>Project2.exe
で Pasori のスキャンがはじまります
今回はスキャンが 2 秒なのであらかじめ IC カードを置いておくといいと思います
スキャンに成功するとカードの IDm という識別番号が表示されると思います
自分は Pasumo がうまくスキャンできて IDm が取得できることは確認しました
最後に
今回スキャンして IDm を表示するとこまでやってみました
Pasumo の場合は乗車履歴とかも書き込まれているようで、それも取得できるみたいなので、次はそこまでやってみたいです
あとは、読み込みだけじゃなくて IC カードへの書き込みもやってみたいなと思います
ライブラリにはもう一つ lite 版というのがあり、関数とかの先頭に「felica_」がついた版があります
自分は初め lite 版を使っていたのですが、どうしても「 felicalib_nfc_open」で Pasori をオープンするところでこけてしまい、lite 版をあきらめました
これは予想ですが、Pasori のバージョンが RC-S320 というだいぶ古いバージョンを使っていたので失敗したのかもしれません
S370 や S380 という比較的新しいバージョンの Pasori を使えば lite 版でも動作するかもしれません