こんにちは。Yukiです。
今回はFelicaの情報を読んでみたいと思います。
目標
この記事での目標は、Felica内部(今回はSuica)の情報(IDmやPMmなど)を読んでみたいと思います。最終的な目標はSuicaの残高を見るが目標です。
最終的な目標としては、Felicaにデータを書き込むところまでやってみたいと思います。(多分この記事ではやりません)
今回の開発環境
- Windows11 Pro
- Visual Studio 2022 (多分Community)
- felicalib
- PaSoRi RC-S320
RC-S320について
RC-S320はSONYが出しているFelicaリーダー・ライター(PaSoRi)です。かなり昔の機種なのでWindows11には対応していないというのが公式の見解ですが、インストールできます。
ドライバの提供が終了しているのでWayback Machine等を使用し、ダウンロードするのが良いかと思います。(自己責任でお願いします)
今回、某中古ショップにて110円にて入手したので、Felica関連についてやってみようかなと思った形です。
ちなみにですが、RC-S320はnfcpyに対応してないとかしてるとか良くわからないですが、今回は使いません。(felicalibを使用します)
felicalibについて
felicalibは村上 卓弥様が作られたライブラリで、SDK for FeliCaを使わなくてもFeliCaのソフトウェアが作れちゃう!というものになります。(もちろん本運用などであれば、SDK for FeliCaを使ったほうが良いと思いますが、趣味程度で使うのであれば、felicalibでも全然問題ないかと思います)
昔はlibfelicaというと呼ばれるライブラリも存在したようなのですが、libusb-win32が必要なのと、そもそも配布サイトが封鎖されていることから、今回はfelicalibを使うことにしました。
felicalibの入手と導入
今回は.NET8 コンソールアプリ C#を使います。(.NET8はLTS対応なので)
felicalibはgithubから入手できます。
ただ、導入方法が若干ややこしいので、簡単に導入方法について書いておきます。
ここのfelicalib-0.4.2.zipみたいなのをDLします。
ZIPファイルを解凍するとfelicalib.dllが入手できます。また、src/csharpの中にあるFelicaLib.csも使用します。
felicalibはWin32系のDLLなので、DllImportなどを使わなければいけませんが、その辺はFelicaLib.csでやってくれています。


ということで、このファイル類をVisual Studioに取り込んで上げます。

ここにfelicalib.dllとFelicaLib.csをD&Dしてください。(勝手に入ります)
このままだと実行フォルダにdllファイルなどが自動で入らないので、実行してもエラーになります。
なので、自動でコピーさせます。

詳細→出力ディレクトリにコピーの欄を 新しい場合はコピーする にします。
次に、プログラムはx86にします。(felicalibがx86プログラムのため、x64でコンパイルすると、下のようなエラーがでてきて実行できない)

よって、x86プログラムにします。

構成マネージャーを開きます。

すでに追加されていますが、本来だとx86がないと思うので、新規作成… を押します。

x86を選択。設定のコピー元は空でOKです。(多分)

エラーは自分のプログラムのせいです。
dllファイルは読み込めたっぽいですね。ここまでできたら構築終了です。
IDmとPMmを読み取るプログラムを書く
プログラムはprogram.csに書きます。(要検証)
using System;
using System.Collections.Generic;
using System.Text;
using FelicaLib;
namespace Felica_dump_test
{
public class Nanaco
{
public static void Main()
{
Felica f = new Felica();
f.Polling((int)SystemCode.Any);
byte[] idm = f.IDm();
if (idm == null)
{
Console.WriteLine("IDmが読み取れなかった");
}
else
{
Console.Write("IDm:");
byte_print(idm);
}
byte[] pmm = f.PMm();
if (pmm == null)
{
Console.WriteLine("PMmが読み取れなかった");
}
else
{
Console.Write("PMm:");
byte_print(pmm);
}
byte[] data = f.ReadWithoutEncryption(0x008B, 0); //Suicaの残高らしい
if (data == null)
{
Console.WriteLine("読み取れなかった");
}
else
{
byte_print(data);
}
}
public static void byte_print(byte[] data)
{
string dump = "";
int i = 0;
foreach (byte b in data)
{
i++;
string text = string.Format("{0,3:X2}", b);
dump += text + " ";
//8毎に改行処理
if(i > 7)
{
i = 0;
dump += "\r\n";
}
}
Console.WriteLine(dump);
}
}
}
ちなみに、追加で残高が書かれている場所も読み出しています。

ちゃんと読み取れてるっぽいですね。
Suicaの残高は2199円でしたが、HEXで0x0897 リトルエンディアンなので97 08がちゃんと書き込まれていますね。
なかなかおもしろい
FeliCaっていままで何気なく使っていましたが、なかなか難しいですね。
実際にはSuica等のサイパネ規格には0x0003など値がついているみたいです。すごいですね。この辺は別のサイト見たほうがわかりやすいのと思うので、ここではあえて書きませんが。


コメント