(Felica/Mifare/NFC チャレンジシリーズ) その他の記事はこちら 「Felica/Mifare/NFC でいろいろ実験」
https://qiita.com/nanbuwks/items/1f416d6e45a87250ee0a
PN532 のユーザマニュアル
https://www.nxp.com/docs/en/user-guide/141520.pdf
には命令がありますが、イマひとつわからないです。
なので直接ハードウェアに聞いてみます。
「PN532 NFC RFID module について調べる」
https://qiita.com/nanbuwks/items/ac02bb307c9850b5e5c4
に搭載されていた NXP PN532 コントローラは SPI,I2C,HSU でホストコントローラと通信できますが、これのHSUモードがUARTとして通信しています。
HSUでは、ピン27が RX として機能しています。ここの通信を調べてみます。
RX はホストコントローラから PN532 への命令が取れます。
PN532 からの返答を取得するには TX もモニターする必要がありますが、今回は RX のみを調べてみます。
「ESP32 で UART ダンプ」
https://qiita.com/nanbuwks/items/ac2454a19702a80b08b6
で行った、シリアル通信の内容のダンプの手法を使って中身を見てみましょう。
なお、 PN532には デバッグ用のUARTもありますが、今回はこちらは使用しませんでした。
ESP32 につなげる信号を取り出すために、基板を調べてみます。
白い線がHSUモードでのRXとなります。702と書いてあるチップに入ってますね。このチップは
SOT-363 パッケージの デュアル N-ch MOSFET 。
型番は2N7002DWです。
別会社ですがデータシートを見ればピン配置がわかります。
出力の1番ピンにつながっている抵抗の端子にはんだづけしました。
ESP32 を取り付けて分析します。
ESP32側のスケッチです。
char buff[50];
//HardwareSerial Serial1(2);
void setup() {
Serial.begin(115200);
Serial2.begin(115200);
}
void loop() {
int counter=0;
for (int counter=0;counter<65536;counter++){
sprintf(buff, "%08X: ",counter);
Serial.print(buff);
for (int address=0;address<16;address++){
if (Serial2.available()) {
int inByte = Serial2.read();
sprintf(buff, "%02X ",inByte);
Serial.print(buff);
}
delayMicroseconds(20);
}
Serial.println();
}
}
通信内容
0000260B:
0000260C: 55 55 00 00 00 00 00 FF 02 FE D4 02 2A 00 00 00
0000260D: FF 06 FA D4 32 05 FF 01 FF F6 00 00 00 FF 05 FB
0000260E: D4 14 01 14 01 02 00 00 00 FF 04 FC D4 4A 01 00
0000260F: 00 00 FF 06 FA D4 60 01 01 11 10 A9 00
00002610:
これを、読み解いていきます。
初期化
HSU wake up condition
55 55 00 00 00
GetFirmwareVersion
00 00 FF 02 FE D4 02 2A 00
これは以下のような構成になっています。
00 | プリアンブル |
00 FF | スタートコード |
02 | パケット長 |
FE | パケット長のチェックサム |
D4 02 | パケット内容 |
2A | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
02 | 命令:GetFirmwareVersion |
RFConfiguration
00 00 FF 06 FA D4 32 05 FF 01 FF F6 00
00 | プリアンブル |
00 FF | スタートコード |
06 | パケット長 |
FA | パケット長のチェックサム |
D4 32 05 FF 01 FF | パケット内容 |
F6 | パケット内容のチェックサム |
00 | ポストアンブル |
となり、パケット内容は以下の構成になっています。
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
32 | 命令:RFConfiguration |
05 | CfgItem = 0x05: MaxRetries |
FF | MxRtyATR = 0xFF: try eternally |
01 | MxRtyPSL = 0x01: PSL_REQ/PPS request is sent twice in case of need |
FF | MxRtyPassiveActivation = 0xFF: try eternally |
SAMConfiguration
00 00 FF 05 FB D4 14 01 14 01 02 00 : Mode=Normal mode,TIMEOUT=14,
00 | プリアンブル |
00 FF | スタートコード |
05 | パケット長 |
FB | パケット長のチェックサム |
D4 14 01 14 01 | パケット内容 |
02 | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
14 | 命令:SAMConfiguration |
01 | Mode = 0x01: Normal mode, the SAM is not used |
14 | TimeOut = 0x14: meaningless ? |
01 | IRQ = 0x01: P70_IRQ pin is driven by the PN532 |
ここまでが初期化。
AutoPoll
00 00 FF 04 FC D4 4A 01 00 E1 00 : InListPassiveTarget MaxTg=1,BrTy=106 kbps type A (ISO/IEC14443 Type A)
00 | プリアンブル |
00 FF | スタートコード |
04 | パケット長 |
FC | パケット長のチェックサム |
D4 4A 01 00 | パケット内容 |
E1 | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
4A | 命令:InListPassiveTarget |
01 | MaxTg = 0x01: Normal mode, the SAM is not used |
00 | BrTy = 0x00: 106 kbps type A (ISO/IEC14443 Type A) |
00 00 FF 06 FA D4 60 01 01 11 10 A9 00
00 | プリアンブル |
00 FF | スタートコード |
06 | パケット長 |
FA | パケット長のチェックサム |
D4 60 01 01 11 10 | パケット内容 |
A9 | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
60 | 命令:InAutoPoll |
01 | PollNr = 0x01: one polling, is a polling for each Type |
01 | Period = 0x01: polling period in 150 ms |
11 | Type 1 = 0x11: FeliCa 212 kbps card |
10 | Type 2 = 0x10: Mifare card |
Mifare Read with Key
00004C59:
00004C5A: 00 00 FF 04 FC D4 4A 01 00 E1 00
00004C5B:
...
00004C78:
00004C79: 00 00 FF 0F F1 D4 40 01 60 04 CE CF CE CF CE CF
00004C7A: FA FB FC FD FE 00 00 00 FF 05 FB
00004C7B: D4 40 01 30 04 B7 00
00004C7C:
これを解読してみます。
00 00 FF 04 FC D4 4A 01 00 E1 00
00 | プリアンブル |
00 FF | スタートコード |
04 | パケット長 |
FC | パケット長のチェックサム |
D4 4A 01 00 | パケット内容 |
E1 | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
4A | 命令:InListPassiveTarget |
01 | MaxTg = 0x01: Normal mode, the SAM is not used |
00 | BrTy = 0x00: 106 kbps type A (ISO/IEC14443 Type A) |
00 00 FF 0F F1 D4 40 01 60 04 CE CF CE CF CE CF FA FB FC FD FE 00
00 | プリアンブル |
00 FF | スタートコード |
0F | パケット長 |
F1 | パケット長のチェックサム |
D4 40 01 60 04 CE CF CE CF CE CF FA FB FC FD | パケット内容 |
FE | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
40 | 命令:InDataExchange |
01 | Tg = 0x01 |
60 04 CE CF CE CF CE CF FA FB FC FD | Mifare Card DataOut |
MifareCard DataOut | 意味 |
---|---|
60 | Authentication A |
04 | address |
CE CF CE CF CE CF | key |
FA FB FC FD | UID number |
00 00 FF 05 FB D4 40 01 30 04 B7 00
00 | プリアンブル |
00 FF | スタートコード |
05 | パケット長 |
FB | パケット長のチェックサム |
D4 40 01 30 04 | パケット内容 |
B7 | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
40 | 命令:InDataExchange |
01 | Tg = 0x01 |
30 | 16 byres reading |
04 | address 0x02 |
やあ、鍵がマル見えですね!
FeliCa Read without Encryption
サービスコード1A8Bのブロック 0x8000,0x8002,0x8003 を読んでみます。
0000E180:
0000E181: 00 00 FF
0000E182: 09 F7 D4 4A 01 01 00 FE 00 01 00 E1 00
0000E183.
.
.
0000E198:
0000E199: 00 00 FF 17 E9 D4 40 01 14 06 11 16 06 00 0A 1E
0000E19A: 77 03 01 8B 1A 03 80 00 80 02 80 03 D4 00
0000E19B:
これを解読してみます。
FeliCa Polling
00 00 FF 09 F7 D4 4A 01 01 00 FE 00 01 00 E1 00
00 | プリアンブル |
00 FF | スタートコード |
09 | パケット長 |
F7 | パケット長のチェックサム |
D4 4A 01 01 00 FE 00 01 00 | パケット内容 |
E1 | パケット内容のチェックサム |
00 | ポストアンブル |
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
4A | 命令:InListPassiveTarget |
01 | MaxTg = 0x01 |
01 | BrTy = 0x01 : : 212 kbps (FeliCa polling) |
00 FE 00 01 00 | InitiatorData |
InitiatorData | 意味 |
---|---|
00 | Command Code = 0x00:Polling |
FE 00 | System Code=0xFE00 |
00 | MaxTg = 0x01 |
01 | Request Code = 0x01 : System Code request |
00 | Time Slot = 0x00: Maximum number of slots is 1 |
00 00 FF 17 E9 D4 40 01 14 06 11 16 06 00 0A 1E 77 03 01 8B 1A 03 80 00 80 02 80 03 D4 00
00 | プリアンブル |
00 FF | スタートコード |
17 | パケット長 |
E9 | パケット長のチェックサム |
D4 40 01 14 06 11 16 06 00 0A 1E 77 03 01 8B 1A 03 80 00 80 02 80 03 | パケット内容 |
D4 | パケット内容のチェックサム |
00 | ポストアンブル |
FeliCa read
パケット内容 | 意味 |
---|---|
D4 | ホストからPN532の命令 |
40 | 命令:InDataExchange |
01 | Tg = 0x01 |
14 06 11 16 06 00 0A 1E 77 03 01 8B 1A 03 80 00 80 02 80 03 | DataOut = FeliCa Frame |
ここで、 FeliCa Frame の中身は以下のようになります。
FeliCa DataOut | 意味 |
---|---|
14 | Len |
06 | Cmd:Read without Encryption |
11 16 06 00 0a 1e 77 03 | IDm |
01 | Number of Service |
8b 1A | Service Code List(1つ分)=0x1A8B |
03 | Number of Block=3 |
80 00 | Block List 1 |
80 02 | Block List 2 |
80 03 | Block List 3 |
他の方法
今回はハードウェアに配線してデータを取り出しました。
しかしながらライブラリによっては同様の情報を取れるものがあるようです。
libnfc では、コンパイルオプションでログレベルをDEBUGにすることによって、データが取れるようになるようです。
また、シリアルポートを wireshark でキャプチャーする方法もあるらしいです。https://unix.stackexchange.com/questions/359500/wireshark-remote-capture-over-uart