1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

PN532 NFC RFID module のインターフェースを直接叩いて Felica 学生カードを読む

Last updated at Posted at 2022-03-28

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


「RaspberryPiでPN532 NFC RFID module で Felica 学生カードを読む」
https://qiita.com/nanbuwks/items/3858283873e968316a2d

では、FCF Student カードに入っている学生証の学籍番号を読んでみました。

しかしながらちょっとスッキリしないです。


    tag.dump() # why need?

を入れないと学籍番号をうまく読まなかったり、ライブラリで何のコマンドを PN532 に送信しているのかよくわからなかったりします。

さて、
「libnfc で pn53x-tamashell を使ってみる」
https://qiita.com/nanbuwks/items/d2c47f6b24ec07f48dee

において、PN532とローレベルのやり取りを行いました。これで PN532 や カードに渡すコマンドは把握できたので、直接 PN532 とやり取りするプログラムを作ってみました。

環境

通信インターフェースは シリアル接続を使い、以下の記事のように設定しています。

「Raspberry Pi で nfcpy + PN532 NFC RFID module」
https://qiita.com/nanbuwks/items/e14d8fdd6f863d5b68fe

Pythonプログラム


import serial
import time


def makepredata(payload):
  predata=bytearray([0x00,0x00,0xFF])
  predata.append(len(payload))
  predata.append(256-(len(payload)))
  return(predata)
def makepostdata(payload):
  sum=0
  for i in range(len(payload)):
    sum=sum+payload[i]
  postdata=bytearray([256-(sum % 256)])
  postdata.append(0x00)
  return(postdata)

# ペイロードにプレデータ、ポストデータを追加しPN532へ送信する
def senddata(payload):
  predata=makepredata(payload)
  postdata=makepostdata(payload)
  alldata=predata+payload+postdata
  ser.write(alldata)

# PN532からの返事を受信する
def getreturn():
  result=bytearray([])
  while 1:
    time.sleep(0.01)
    result = result + ser.read_all()
    if len(result)<4:
         continue
    if ( 0x00==result[0] and 0xFF==result[1] and result[2]==256-result[3] ):
      if len(result)<result[2]+6:
         continue
    else:
      result=result[1:]
      continue
    break
#  print(result.hex())
  if  0xd5==result[4] and 0x00==result[-1] :
    # 返事のチェックサムを照合
    sum=0
    for i in result[4:-2]:
      sum=sum+i
    if (256-(sum%256))==result[-2]:
      return(result)
    else:
      return(bytearray([]))
  else:
    return(bytearray([]))


ser = serial.Serial("/dev/ttyAMA0", 115200)

# FeliCa Poll
payload=bytearray([0xD4])+bytearray([0x4A,0x01,0x01,0x00,0xFE,0x00,0x01,0x00])
senddata(payload)
#print("send:",senddata.hex())
result=getreturn()
#print(result.hex())
# get Idm
Idm=result[10:18]
print("Idm:",Idm.hex())

# FeliCa read
payload=bytearray([0xD4])+bytearray([0x40,0x01,0x14,0x06])+Idm+bytearray([0x01,0x8B,0x1A,0x03,0x80,0x00,0x80,0x02,0x80,0x03])
senddata(payload)
#print("send:",senddata.hex())
result=getreturn()
#print(result.hex())
print()
print("block 8000:",result[21:36].hex())
print("block 8002:",result[37:52].hex())
print("block 8003:",result[53:68].hex())
print()
print("block 8000:",bytes(result[21:36]))
print("block 8002:",bytes(result[37:52]))
print("block 8003:",bytes(result[53:68]))

ser.close()
                               

実行結果


Idm: 010106016702a515

block 8000: 313233343536373839303100003131
block 8002: 363031303039383736353433323130
block 8003: 303232303333313939393939393939

block 8000: b'12345678901\x00\x0011'
block 8002: b'601009876543210'
block 8003: b'022033199999999'

読めました

他の環境

今回は、Raspberry Pi とシリアル接続で行いました。
しかしながらPCやWindowsなどでも、ポート指定などの若干の変更で動くハズ。
また、SPI や I2C 対応も難しくないでしょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?