FeliCa の IDm を読む( python 編)

メモ:

Raspberry Pi に USBのカードリーダー( RC-S380 )を接続して Felica の IDm を読み取ります。

環境

  • Python 3.5.3
  • nfcpy 1.0.3

nfcpy パッケージのインストール

Python からカードリーダーが制御できるよう、 nfcpy パッケージをインストールします。

$ pip3 install nfcpy

カードリーダーの設定

カードリーダーの PaSoRi RC-S380 を RaspberryPi へ USB 接続します。

lsusb コマンドを実行し、カードリーダーが接続されていることを確認します。

$ lsusb
Bus 001 Device 006: ID 054c:06c1 Sony Corp. 
Bus 001 Device 004: ID 0424:7800 Standard Microsystems Corp. 
Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

正しく認識されていれば、「Bus 001 Device 006: ID 054c:06c1 Sony Corp. 」のように出力されます。

次のコマンドを実行し、カードリーダーが利用可能か確認します。

$ python3 -m nfc
This is the 1.0.3 version of nfcpy run in Python 3.5.3
on Linux-4.14.79-v7+-armv7l-with-debian-9.4
I'm now searching your system for contactless devices
** found usb:054c:06c1 at usb:001:006 but access is denied
-- the device is owned by 'root' but you are 'pi'
-- also members of the 'root' group would be permitted
-- you could use 'sudo' but this is not recommended
-- better assign the device to the 'plugdev' group
   sudo sh -c 'echo SUBSYSTEM==\"usb\", ACTION==\"add\", ATTRS{idVendor}==\"054c\", ATTRS{idProduct}==\"06c1\", GROUP=\"plugdev\" >> /etc/udev/rules.d/nfcdev.rules'
   sudo udevadm control -R # then re-attach device
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs
Sorry, but I couldn't find any contactless device

カードリーダーは見つかりましたが、「** found usb:054c:06c1 at usb:001:006 but access is denied」と出力されアクセスできないようです。 root 以外では、 USB へアクセスできないようになっているためログインしているユーザーの pi でもアクセスできるように設定を行います。

「/etc/udev/rules.d/」ディレクトリに nfc.rules というファイルを作成し次の設定を追加します。

ATTRS{idVendor}=="054c", ATTRS{idProduct}=="06c1", ACTION=="add", GROUP="pi", MODE="660"

ATTRS{idVendor} と ATTRS{idProduct} には、 lsusb コマンドで確認したカードリーダーのベンダーIDとプロダクトIDを指定します。GROUP には、対象ユーザのグループを指定し MODE には、パーミッションを指定します。

設定を作成したら udev を再起動し、カードリーダーを抜き差しします。

$ sudo systemctl restart udev

もう一度、「python3 -m nfc」コマンドを実行し確認してみます。

$ python3 -m nfc
This is the 1.0.3 version of nfcpy run in Python 3.5.3
on Linux-4.14.79-v7+-armv7l-with-debian-9.4
I'm now searching your system for contactless devices
** found SONY RC-S380/S NFC Port-100 v1.11 at usb:001:007
I'm not trying serial devices because you haven't told me
-- add the option '--search-tty' to have me looking
-- but beware that this may break other serial devs

今度は、アクセスできそうな感じです。これで準備は出来たので、 Felica の IDm を読み取ってみます。

FeliCa の IDm を読む

次のプログラムを作成し、実行すると入力待ちになります。

import nfc

clf = nfc.ContactlessFrontend('usb')
tag = clf.connect(rdwr={'on-connect': lambda tag: False})
print(tag)
clf.close()

clf.connect() に on-connect コールバック関数を指定し、カードが置かれたら関数が呼ばれるようにします。

※ lambda は、無名関数

カードリーダーに Felica のカードを置くとカードの情報が読み取られ次のように表示されます。

Type3Tag 'FeliCa Lite (RC-S965)' ID=01270076C84B5FC7 PMM=00F0000002060300 SYS=88B4

IDm のみ出力するよう少し修正してみます。

import nfc
import binascii

def connected(tag):
    idm = binascii.hexlify(tag.idm)
    print(idm)
    return False

clf = nfc.ContactlessFrontend('usb')
clf.connect(rdwr={'on-connect': connected})
clf.close()

プログラムを実行し、カードをかざすと次のように出力されます。

b'01270076c84b5fc7'

以上で FeliCa から IDm を読み取ることができました。