かぴぱらの日記

かぴぱらの雑貨置き場です。バイク(Honda Hornet250)や一眼(Nikon D5600)でいろいろしたものを載せていきます。晴れ時々電子工作… 某田舎の高専生だったりします。

NFCで認証するプリペイド型決済システムを作ってみる②

①→ NFCで認証するプリペイド型決済システムを作ってみる - かぴぱらの日記

③→ NFCで認証するプリペイド型決済システムを作ってみる③ -Ver2.00リリースと Python で データベース 接続 のお話- - かぴぱらの日記


お久しぶりです。

私事も忙しくなってきたことでなかなか更新してませんでした。

 長らく進捗をあげてなかったこの企画ですが,とりあえずNFCタグを得れるようになりました。

 

PN532のI2C通信はサンプルプログラムがちょっと実用には遅く,かと言ってCのヘッダーから処理を読むことも出来ず,断念しました…。

libnfc 1.7.1を使ってみようと思ったがサンプルがC言語しかないのと,いまいちIDmの部分だけを抽出するのは大変そうだったのでとりあえず却下です。

 

次に手をつけたのは,部室に転がっていたSONY NFCリーダー RC-S320

SONY RC-S320 非接触ICカードリーダ/ライタ PaSoRi 「パソリ」

SONY RC-S320 非接触ICカードリーダ/ライタ PaSoRi 「パソリ」

 

 「NFCリーダー」と言うのだからFelicaカードだけでなくISO14443系のカードなら読めると思っていた時期がありました……。WindowsではSONYの公式ソフトを使ってなんとかSuicaをいろいろ読めましたが,手元のNFC Type2カードは読めなかったのでこちらも却下。

 

そして本命のSONY NFCリーダー RC-S380

ソニー SONY 非接触ICカードリーダー/ライター PaSoRi RC-S380

ソニー SONY 非接触ICカードリーダー/ライター PaSoRi RC-S380

 

この子はとても良い子です。手元にあるSuicaPASMO,Type2カード×2は全て読んでくれました。

とりあえずRasPiに刺して読んでるか見てみます。

kapipi@raspberrypi:~/kapiNFC $ lsusb
Bus 001 Device 004: ID 054c:06c3 Sony Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

1行目がRC-S380君ですね。読むときと読まないときがあったS320君とは大違い…(やっぱり転がっていたのは壊れていたのでは…)
読むにはPython2.7のnfcpyを使います。とりあえずaptして持ってきます。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get python-pip
sudo pip install nfcpy

流れ的にはPython3を使った方がいいのでしょうが,探した限りでは見つからなかったのでNFCタグを読む処理はPython2で書きます。

#!/usr/bin/env python
#! -*- coding:utf-8 -*-

import nfc

def on_connect(tag):
    print tag

def on_startup(tag):
    print("[NFC reader] : ready")
    return tag

def main():
    with nfc.ContactlessFrontend('usb:054c:06c3') as clf:
        clf.connect(rdwr = {
            'on-startup':on_startup,
            'on-connect':on_connect
        })

if __name__  '__main__':
    main()

nfc.ContactlessFrontend()の中にはlsusbで出てきたデバイスのベンダIDを入れます。詳しくはこちらのサイトの方がご丁寧に書いてくださっています。
qiita.com

さて,このプログラムを実行するとこのように出してくれます。とりあえず私のSuicaをポン。

kapipi@raspberrypi:~/kapiNFC $ python test.py
No handlers could be found for logger "nfc.llcp.sec"
[NFC reader] : ready
Type3Tag 'FeliCa Standard (RC-S???)' ID=01100310******** PMM=100B4B42******** SYS=****

一応固有のIDらしいので****で伏せてありますが,実際はちゃんと表示できてます。SONY NFCリーダーのモデル番号が読めてないぽいですが,まあいいや。
ちなみにType2カードだとこうなります。

kapipi@raspberrypi:~/kapiNFC $ python test.py
No handlers could be found for logger "nfc.llcp.sec"
[NFC reader] : ready
Type2Tag ID=3CAD****

今回欲しいのはIDだけなので,splitしてID=の後を抽出します。

#!/usr/bin/env python
#! -*- coding: utf-8 -*-

import nfc 

def on_connect(tag):
    tmp = str(tag)
    splitOut = tmp.replace('=',' ').split()
    
    flag = 0

    for item in splitOut:
        if flag == 1:
            print item
            flag = 0
        if item.find("ID") is not -1:
            flag = 1

def on_startup(tag):
    print("[NFC reader] : ready")
    return tag

def main():
    with nfc.ContactlessFrontend('usb:054c:06c3') as clf:
        clf.connect(rdwr = {
            'on-startup':on_startup,
            'on-connect':on_connect
            })

if __name__ == '__main__':
    main()

うーんもの凄く冗長なコード!w
Pythonistaの皆さん,可読性があってもっと簡単な書き方があったらご教授ください……。
これにさっきと同じ私のSuicaを置いてみます。

kapipi@raspberrypi:~/kapiNFC $ python test.py
No handlers could be found for logger "nfc.llcp.sec"
[NFC reader] : ready
01100310********

やったぜ。
と,あたかも難題をクリアしたように書いてますが最初から大人しくこちらを使っておけば沼に沈むこともありませんでした。(おかげでNFCの知見を得られたのでまあ……)

次はGUI作成とユーザ管理データベースの作成です!



~開発現場談~
かぴぱら「うーんこの白いNFCリーダー(SONY RC-S320)読まないなあ」
後輩君「あっ,その白いのぶっ壊れるんでやめた方がいいですよ」
かぴぱら「ファッ!?そういえば君,NFCのコード書いてなかったっけ?PN532のコードとか残ってたりする?」
後輩君「うーん,自分らもPN532使おうとしてCのヘッダー辿れなくてやめたんですよね」
かぴぱら「すでにこの流れの先駆者がいたのか……(昇天)」
後輩君「こっちの黒いやつ(SONY RC-S380)は割と綺麗に保管されてたんでこれ使ってもいいっすよ」
かぴぱら「ありがとう……ありがとう……」

後輩君でさくら荘の美咲先輩を思い出した……

2018/07/05追記
なんか一番アクセスを頂いているのがこのページということで,驚いているのですが,8月辺りで完成させちゃいたいと思ってます。この記事の続編も書くつもりなので許してください……