RaspberryPiでPN532 NFC RFID module で Felica 学生カードを読む

(Felica/Mifare/NFC チャレンジシリーズ) その他の記事はこちら 「Felica/Mifare/NFC でいろいろ実験」
https://qiita.com/nanbuwks/items/1f416d6e45a87250ee0a

-----

「elechouse/PN532 ライブラリで Felica 学生カードを読む追試」
https://qiita.com/nanbuwks/items/6396f09bf58840340bab

では Arduino UNO を使って Felica 学生カードから学籍番号を取得しました。
今回は RaspberryPi を使って同様なことをやってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/28586159-a516-ef63-7b10-22a904636862.png)

# 環境


- PN532 NFC RFID module
  - 電解コンデンサ追加加工済
  - cf., 「NFC モジュールの動作安定性を改善する」 
  - https://qiita.com/nanbuwks/items/a9217ba2e8f206b899b1
- Raspberry Pi Model B+ V1.2
  - Raspberry Pi OS Lite armhf-2020-12-04
- Python 3.7.3
- 1.0.4 version of nfcpy

# 元ネタ

「学生証で入退室管理するシステムを作った - ポタージュを垂れ流す。」
https://potaxyz.hatenablog.jp/entry/2020/12/15/004100
を元に、考えてみました。
この記事では京都大学の学生証から学籍番号などを読んでいます。
Arduino UNO の実験では、会津大学の学生証を読む記事を元ネタにしました。
「PN532を使ってArduinoでFeliCa学生証を読む方法」
https://qiita.com/gpioblink/items/91597a5275862f7ffb3c

どちらも サービスコードが 0x1A8B、ブロックリストは0x8000から0x8003 でした(nfcpy では bc として nfc.tag.tt3.BlockCode(0) と指定していますが、カード上のブロックリストは 0x8000-0x8003 となります )。

FCF-Student での サービスA はどの大学でも共通かな？
# インストール

nfcpy を以下の記事のようにしてインストールしました。
「Raspberry Pi で nfcpy + PN532 NFC RFID module」
https://qiita.com/nanbuwks/items/e14d8fdd6f863d5b68fe



# コード

```

# -*- coding: utf-8 -*-

import binascii
import nfc
import struct

#service_code = 0x090F # suica
service_code = 0x1A8B # student

def connected(tag):
#  print (tag)
  if isinstance(tag, nfc.tag.tt3.Type3Tag):
    try:
      sc = [nfc.tag.tt3.ServiceCode(service_code >> 6, service_code & 0x3f)]
      tag.dump() # why need?

# balance (suica)
#      bc = [nfc.tag.tt3.BlockCode(0)]
#      bd = tag.read_without_encryption(sc, bc)
#      print ("block: %s" % binascii.hexlify(bd))
#      student_id = int(bd[2:-4].decode("utf-8"))
#      print(student_id)
#      balance= struct.unpack( "<2B2H4BH4B", bd )[8]
#      print(balance)
# student id
      bc = [nfc.tag.tt3.BlockCode(0)]
      bd = tag.read_without_encryption(sc, bc)
#      print ("block: %s" % binascii.hexlify(bd))
      student_id = int(bd[2:-4].decode("utf-8"))
      print(student_id)
# name
      bc = [nfc.tag.tt3.BlockCode(1)]
      bd = tag.read_without_encryption(sc, bc)
#      print ("block: %s" % binascii.hexlify(bd))
      student_name = ( bd.decode("shift-jis").rstrip("\x00"))
      print(student_name)
# student id2
      bc = [nfc.tag.tt3.BlockCode(2)]
      bd = tag.read_without_encryption(sc, bc)
#      print ("block: %s" % binascii.hexlify(bd))
      student_id2 = int(bd[2:-4].decode("utf-8"))
      print(student_id2)
# date
      bc = [nfc.tag.tt3.BlockCode(3)]
      bd = tag.read_without_encryption(sc, bc)
#      print ("block: %s" % binascii.hexlify(bd))
      student_date = int(bd[2:-4].decode("utf-8"))
      print(student_date)

    except Exception as e:
      print ("error: %s" % e)
  else:
    print ("error: tag isn't Type3Tag")

clf = nfc.ContactlessFrontend('tty:AMA0')
try:
  clf.connect(rdwr={'on-connect': connected})
finally:
  clf.close()

```

# 実行結果

```

1234567890
ﾅﾝﾌﾞ ﾜｰｸｽ
987654321
2203319999

```

コメントアウトを直すことで、suica 残額と 学生カードの学籍番号などを表示できます。
しかしながら学生番号については、コードの途中に dump 処理を入れないと動きませんでした。

```

      tag.dump() # why need?

```

この処理があるので5秒ほど処理時間が余分にかかります。調査中・・・