nfcpy を利用して Apple Pay の エクスプレスカード設定された Suica (以後エクスプレスカード)を扱おうとしたところ思いっきり躓いたので、ポイントを記事にしておきます。
導入方法や実際のデータの読み書きについてはわかりやすいまとめがあると思いますのでここでは記載しません。(参考リンクなどを参照してください)
環境
- Raspberry Pi 3 Model B (Rasbian jessie 8.0)
- Python 2.7.9
- nfcpy 0.11.0
- PaSoRi RC-S380
connect を使用した際の挙動
nfcpy を使用してデータの読み書きを行う際には nfc.ContactlessFrontend の connect メソッドを使用すると簡単に実装出来るようになっているのですが、これはエクスプレスカードでは正常に動作しません。
たとえば以下のようなコードの場合。
import nfc
def on_startup(targets):
for target in targets:
# 0003(Suica)
target.sensf_req = bytearray.fromhex("0000030000")
return targets
def on_connect(tag):
print tag
def main():
clf = nfc.ContactlessFrontend('usb')
# 212F(FeliCa)
clf.connect(rdwr={'targets': ['212F'], 'on-startup': on_startup, 'on-connect': on_connect})
clf.close()
if __name__ == '__main__':
main()
スリープ状態の iPhone をリーダーにかざすと、iPhone 側の画面では Suica と読み取り完了のチェックマークが表示されますが、プログラム側ではほぼ常に何も起きません。(ごくたまに on_connect が呼び出されることがあります)
connect で on-discover (対象が見つかった時に呼び出される)を指定しても同様となります。
この事象はエクスプレスカードの場合でのみ発生するようで、Wallet アプリを起動してカード指定してかざした場合には発生しません。
sense を使用する
nfcpy では connect 以外にも検出に使用するメソッドが提供されています。
これらを使用することでエクスプレスカードでも正常に検出ができます。
import binascii
import nfc
def main():
clf = nfc.ContactlessFrontend('usb')
# 212F(FeliCa)
target_req = nfc.clf.RemoteTarget("212F")
# 0003(Suica)
target_req.sensf_req = bytearray.fromhex("0000030000")
while True:
target_res = clf.sense(target_req, iterations=10, interval=0.01)
if target_res != None:
print binascii.hexlify(target_res.sensf_res)
tag = nfc.tag.tt3.Type3Tag(clf, target_res)
tag.sys = 3
print tag
break
clf.close()
if __name__ == '__main__':
main()
sense は指定された対象を interval 間隔で iterations 回検索し、結果を返します。
見つかった場合は対象の RemoteTarget、見つからなかった場合は None を返しますので、None であれば再度検索をします。
RemoteTarget オブジェクトの sensf_res には見つかった対象の IDM/PMM/SYS がまとめて格納されていますので、これらのみが必要な場合はこれ以降は必要ありません。
ここからデータの読み書きをできるようにするには Tag オブジェクトが必要です。
この Tag オブジェクトは nfc.tag.tt3.Type3Tag(clf, target) として定義されているので clf と RemoteTarget から生成してあげればよい事になります。
ただしここで生成した Tag には SYS の情報が入っていないので、改めて Suica の 0x0003 を代入してあげます。
これで connect を使用した場合に on-connect の引数として渡される Tag と同等の処理が可能になります。
参考リンク
- ・nfcpy で複数の System Code を持つ NFC タグを扱う方法
- http://uchan.hateblo.jp/entry/2016/11/18/190237
- ・FeliCaのPollingによるApplePayのWalletの動作
- http://qiita.com/bellx2/items/fb081c4bdd822c8d36fd