スキップしてメイン コンテンツに移動

12年前の非接触型ICカードリーダPaSoRiで遊ぶ

最近ずっとリモートワークだったので、これを機に書斎の整理整頓を行った。段ボールに無造作に放り込まれたPC関連機器や電子ガジェットを漁っていると、2004年10月に発売されたソニーの非接触型ICカードリーダPaSoRi RC-S320が出てきた。2008年3月に購入したので実に12年以上前のモノだ。



このまま捨て置くのは勿体ないし、ちょっと興味をそそられたので、以前のブログ記事に上げたコードがちゃんと使えるか、最近新調したWindows 10搭載PCで確認してみた。

当然、ドライバが入っていないのでそのままでは動かない。早速最新のドライバを入れようと思ったが、実はRC-S320はとっくに販売終了していて、新しいPaSoRiとはドライバが違う。まあ、そりゃそうか。調べたところ古いドライバ(NFCポートソフトウェア Version 5.4.8.6)を落としてくれば動くことが分かった。動作確認環境はWindows 8.1までみたいだけど、まあ、大丈夫でしょ。

ドライバを入れたところ、デバイスマネージャーでちゃんと認識された。よし、これで準備OKだ。動かしてみよう! …いやまてよ? 今時Python2は許されない。ということでPython3のコードにちょこちょこっと修正して、これで良し。PaSoRiの上にモバイルSuica機能を搭載したAndroid端末を置いて、さっそく実行 python read_felica.py (カタカタカタッターン!)

OSError: [WinError 193] %1 は有効な Win32 アプリケーションではありません。

あ、これよく見るやつだ。実行パス名にスペースとか入ってちゃんと認識しないやつだ。と思ったけど調べてみるとパス名は問題ないみたい。あとは、そうそう、64ビット環境で32ビットのライブラリ使ったとか。それだ! 実行環境はPython3の64ビット版なので読み込むDLLも64ビットじゃないと。でも、利用させてもらった felicalib は32ビット版しかないみたい。0.4.3から64ビット版にも対応するみたいだけど、最新版の0.4.2が2008年6月リリースでそれ以降出ていないということはもう出ない可能性が高い。ちなみにソニーのドライバは当時64ビット版が存在しなかったみたいだけど、今は入っているようだ。

それならとりあえず32ビット版Pythonで動くか確認してみよう。ちなみに、Pythonの64ビット版と32ビット版の共存は簡単。Anaconda (64ビット版)を入れているので、以下のように環境を作ってしまえば良い。

> set CONDA_FORCE_32BIT=1 > conda create -n py37_win32 python=3.7 > set CONDA_FORCE_32BIT=

利用するときは conda activate py32_win32 とすれば32ビット版環境が立ち上がる。

さっそく実行してみると問題なく動いた。めでたしめでたし。…とは思えないのがエンジニアの性(さが)。普段64ビット環境を利用していて、RC-S320用の64ビット版ドライバが用意されていて、32ビット版環境で妥協するのは許されない感じ。なので、まずはfelicalib以外で対応されていないか確認してみた。

PythonでNFCタグを読み書きするのにnfcpyというライブラリが近年ではよく使われているらしい。ただ、前準備も必要で、Zadigを使ってNFC Port/PaSoRiをWinUSBとして再インストールし、libusbを入れて初めて使えるようになる。

それでnfcpyを使ってみたけど、認識しない。何故だとよくよく調べてみると、古いPaSoRiであるRC-S320には対応していないらしい。うーん、無駄骨か。動作したとしても、一般ユーザにプログラムを利用してもらう場合、libusbを入れること自体がそもそもハードルが高い。libusbで使えるようにするとNFCポートソフトウェア付属のNFCポート自己診断も当然ながら失敗するし。結局、「ドライバーを元に戻す」でlibusbは使わないことにした。

なら、felicalibを64ビットネイティブでビルドするしかない。幸いソースコードとVS2008用のプロジェクトファイルは付属しているので、それをVS2019で開いてみる。適当に変換されたのでビルドしてみたらコンパイルエラー。

RC1015 cannot open include file 'afxres.h'

どうやらMFC用ヘッダファイルの afxres.h がないということらしい。ならこれを winres.h に変更してリビルド。普通に通った。次にプラットフォームのWin32からx64を追加してビルド。問題なく64ビット用DLLが生成された。念のためdumpbinコマンドでドライバのDLLの中身を確認したけど、64ビット版と32ビット版で構成は同一だった。

64ビット用DLLが用意できたので、64ビットPython環境でread_felica.pyを実行してみる。そうすると型が合わないよというエラーが出て実行できない。なるほど、ctypesを使っているので、ちゃんと argtypesで指定しないとね。きちんと指定したところ、実行することができた。初めから64ビット環境用にfelicalibをビルドすればよかった。

というわけで、12年前のPaSoRiでも現役で利用できた。実行するにあたって、64ビット版felicalibをパスの通った場所に置く。そして、サイバネ駅コードが入ったCSVファイル(stationcode.csv)を実行ディレクトリに置く。stationcode.csvは、IC SFCard Fan路線・駅コード一覧・登録からダウンロードしてきたExcelファイルをCSVフォーマット(UTF-8)に変換したファイルだけど、現在のところダウンロード時にタイムアウトが出てデータが落とせなくなっているようだ。南無三。仕方がないので、Webスクレイピング用のコードを書いて対処した。

最後に、作成したコードを以下のリポジトリに上げておく。興味があればいじってみてほしい。

https://github.com/foota/felica-pasori

コメント