1
0
mirror of synced 2024-11-14 11:57:34 +01:00

更新说明文件,更新引用链接。

This commit is contained in:
Sucareto 2023-07-02 01:25:39 +08:00
parent 7ab9ac6f3c
commit 7622d91901
4 changed files with 505 additions and 793 deletions

View File

@ -1,5 +1,6 @@
#include "cmd.h"
bool high_baudrate = true;//high_baudrate=true
#define high_baudrate
#include "Aime_Redaer.h"
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
@ -12,132 +13,83 @@ void setup() {
FastLED.showColor(0);
delay(500);
}
nfc.setPassiveActivationRetries(0x10);//设定等待次数
nfc.setPassiveActivationRetries(0x10);
nfc.SAMConfig();
memset(&req, 0, sizeof(req.bytes));
memset(&res, 0, sizeof(res.bytes));
memset(req.bytes, 0, sizeof(req.bytes));
memset(res.bytes, 0, sizeof(res.bytes));
SerialDevice.begin(high_baudrate ? 115200 : 38400);
FastLED.showColor(high_baudrate ? 0x0000FF : 0x00FF00);
SerialDevice.begin(baudrate);
FastLED.showColor(BootColor);
}
void loop() {
SerialCheck();
packet_write();
}
static uint8_t len, r, checksum;
static bool escape = false;
static uint8_t packet_read() {
while (SerialDevice.available()) {
r = SerialDevice.read();
if (r == 0xE0) {
req.frame_len = 0xFF;
continue;
}
if (req.frame_len == 0xFF) {
req.frame_len = r;
len = 0;
checksum = r;
continue;
}
if (r == 0xD0) {
escape = true;
continue;
}
if (escape) {
r++;
escape = false;
}
req.bytes[++len] = r;
if (len == req.frame_len && checksum == r) {
return req.cmd;
}
checksum += r;
}
return 0;
}
static void packet_write() {
uint8_t checksum = 0, len = 0;
if (res.cmd == 0) {
return;
}
SerialDevice.write(0xE0);
while (len <= res.frame_len) {
uint8_t w;
if (len == res.frame_len) {
w = checksum;
} else {
w = res.bytes[len];
checksum += w;
}
if (w == 0xE0 || w == 0xD0) {
SerialDevice.write(0xD0);
SerialDevice.write(--w);
} else {
SerialDevice.write(w);
}
len++;
}
res.cmd = 0;
}
void SerialCheck() {
switch (packet_read()) {
case SG_NFC_CMD_RESET:
sg_nfc_cmd_reset();
break;
case SG_NFC_CMD_GET_FW_VERSION:
sg_nfc_cmd_get_fw_version();
break;
case SG_NFC_CMD_GET_HW_VERSION:
sg_nfc_cmd_get_hw_version();
break;
case SG_NFC_CMD_POLL:
sg_nfc_cmd_poll();
break;
case SG_NFC_CMD_MIFARE_READ_BLOCK:
sg_nfc_cmd_mifare_read_block();
break;
case SG_NFC_CMD_FELICA_ENCAP:
sg_nfc_cmd_felica_encap();
break;
case SG_NFC_CMD_AIME_AUTHENTICATE:
sg_nfc_cmd_aime_authenticate();
break;
case SG_NFC_CMD_BANA_AUTHENTICATE:
sg_nfc_cmd_bana_authenticate();
break;
case SG_NFC_CMD_MIFARE_SELECT_TAG:
sg_nfc_cmd_mifare_select_tag();
break;
case SG_NFC_CMD_MIFARE_SET_KEY_AIME:
sg_nfc_cmd_mifare_set_key_aime();
break;
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
sg_nfc_cmd_mifare_set_key_bana();
break;
case SG_NFC_CMD_RADIO_ON:
sg_nfc_cmd_radio_on();
break;
case SG_NFC_CMD_RADIO_OFF:
sg_nfc_cmd_radio_off();
break;
case SG_RGB_CMD_RESET:
sg_led_cmd_reset();
break;
case SG_RGB_CMD_GET_INFO:
sg_led_cmd_get_info();
break;
case SG_RGB_CMD_SET_COLOR:
sg_led_cmd_set_color();
break;
case 0:
break;
case CMD_TO_NORMAL_MODE:
sys_to_normal_mode();
break;
case CMD_GET_FW_VERSION:
sys_get_fw_version();
break;
case CMD_GET_HW_VERSION:
sys_get_hw_version();
break;
// Card read
case CMD_START_POLLING:
nfc_start_polling();
break;
case CMD_STOP_POLLING:
nfc_stop_polling();
break;
case CMD_CARD_DETECT:
nfc_card_detect();
break;
// MIFARE
case CMD_MIFARE_KEY_SET_A:
memcpy(KeyA, req.key, 6);
res_init();
break;
case CMD_MIFARE_KEY_SET_B:
res_init();
memcpy(KeyB, req.key, 6);
break;
case CMD_MIFARE_AUTHORIZE_A:
nfc_mifare_authorize_a();
break;
case CMD_MIFARE_AUTHORIZE_B:
nfc_mifare_authorize_b();
break;
case CMD_MIFARE_READ:
nfc_mifare_read();
break;
// FeliCa
case CMD_FELICA_THROUGH:
nfc_felica_through();
break;
// LED
case CMD_EXT_BOARD_LED_RGB:
FastLED.showColor(CRGB(req.color_payload[0], req.color_payload[1], req.color_payload[2]));
break;
case CMD_EXT_BOARD_INFO:
sys_get_led_info();
break;
case CMD_EXT_BOARD_LED_RGB_UNKNOWN:
break;
default:
sg_res_init();
res_init();
}
packet_write();
}

View File

@ -1,30 +1,30 @@
# Arduino-Aime-Reader
使用 Arduino + PN532 + WS2812B 制作的 Aime 兼容读卡器。
**目前所有主要功能已经实现,如果没有 bug 应该不会再更新。**
使用 Arduino + PN532 制作的 Aime 兼容读卡器。
**当前更新内容未经过长时间测试,如果遇到问题可以回滚到[稳定的 v1.0 版本](https://github.com/Sucareto/Arduino-Aime-Reader/tree/v1.0)**
English: [lawliuwuu/Arduino-Aime-Reader](https://github.com/lawliuwuu/Arduino-Aime-Reader)
支持卡片类型: [FeliCa](https://zh.wikipedia.org/wiki/FeliCa)Amusement IC、Suica、八达通等和 [MIFARE](https://zh.wikipedia.org/wiki/MIFARE)AimeBanapassport
实现逻辑为官方读卡器串口数据对比 + 脑补,不保证正确实现。
通信数据格式参考了 [Segatools]() 和官方读卡器抓包数据,可在 [Example.txt](doc/Example.txt) 和 [nfc.txt](doc/nfc.txt) 查看。
一个使用例:[ESP32-CardReader](https://github.com/Sucareto/ESP32-CardReader)
- 支持卡片类型: [FeliCa](https://zh.wikipedia.org/wiki/FeliCa)Amusement IC、Suica、八达通等和 [MIFARE](https://zh.wikipedia.org/wiki/MIFARE)AimeBanapassport
- 逻辑实现是通过对官方读卡器串口数据进行分析猜测出来的,并非逆向,不保证正确实现
- 通信数据格式参考了 [Segatools](https://github.com/djhackersdev/segatools) 和官方读卡器抓包数据,可在 [Example.txt](doc/Example.txt) 和 [nfc.txt](https://github.com/djhackersdev/segatools/blob/master/doc/nfc.txt) 查看
- 定制使用例(主要的开发测试环境):[ESP32-CardReader](https://github.com/Sucareto/ESP32-CardReader)
### 使用方法:
1. 按照 [PN532](https://github.com/elechouse/PN532) 的提示安装库
2. 按照使用方式,在 Arduino 和 PN532 接好连接线I2C 或 SPI并调整 PN532 上的拨码开关
3. 接上 WS2812B 灯条(可选)
3. 接上 WS2812B 灯条(可选,不会影响正常读卡功能
4. 上传 [ReaderTest](tools/ReaderTest/ReaderTest.ino) 测试硬件是否工作正常
5. 若读卡正常,可按照支持列表打开设备管理器设置 COM 端口号
6. 按照游戏的波特率设置代码的`high_baudrate`选项,`115200`是`true``38400`是`false`
7. 上传程序打开游戏测试
8. 安装 [MifareClassicTool](https://github.com/ikarus23/MifareClassicTool),修改 [Aime 卡示例](doc/aime示例.mct) 后写入空白 MIFARE UID/CUID 卡
7. 如果有使用 [Segatools](https://github.com/djhackersdev/segatools),参考 [segatools.ini 设置教程](https://github.com/djhackersdev/segatools/blob/master/doc/config/common.md#enable) 关闭 Aime 模拟读卡器
8. 上传程序打开游戏测试
如果需要自定义 Aime 卡,安装 [MifareClassicTool](https://github.com/ikarus23/MifareClassicTool),修改 [Aime 卡示例](doc/aime示例.mct) 后写入空白 MIFARE UID/CUID 卡,即可刷卡使用。
某些 Arduino 可能需要在游戏主程序连接前给串口以正确的波特率发送 DTR/RTS需要先打开一次 Arduino 串口监视器再启动主程序。
如果是 SDBT可以在启动前运行一次 [DTR-RTS.exe](tools/DTR-RTS.exe) 以向 COM1 和 COM12 发送DTR/RTS。
如果需要向其他端口和特定的波特率发送,可以修改 [DTR-RTS.c](tools/DTR-RTS.c) 然后编译。
### 支持列表:
| 游戏代号 | COM端口号 | 支持的卡 | 默认波特率 |
### 支持游戏列表:
| 代号 | 默认 COM 号 | 支持的卡 | 默认波特率 |
| - | - | - | - |
| SDDT/SDEZ | COM1 | FeliCa,MIFARE | 115200 |
| SDEY | COM2 | MIFARE | 38400 |
@ -35,23 +35,27 @@ English: [lawliuwuu/Arduino-Aime-Reader](https://github.com/lawliuwuu/Arduino-Ai
- 如果读卡器没有正常工作,可以切换波特率试下
- 有使用 amdaemon 的,可以参考 config_common.json 内 aime > unit > port 确认端口号
- 如果 `"high_baudrate" : true` 则波特率是`115200`,否则就是`38400`
- 在 `"high_baudrate" : true` 的情况下,本读卡器程序支持 emoney 功能,端末认证和刷卡支付均正常(需要游戏和服务器支持)
### 已测试开发板:
- SparkFun Pro MicroATmega32U4需要发送 DTR/RTS
- SparkFun SAMD21 Dev BreakoutATSAMD21G18
- NodeMCU 1.0ESP-12E + CP2102 & CH340SDA=D2SCL=D1
- NodeMCU-32SESP32-S + CH340
### 开发板适配情况:
| 开发板名 | 主控 | 备注 |
| - | - | - |
| SparkFun Pro Micro | ATmega32U4 | 需要发送 DTR/RTS未完全测试 |
| SparkFun SAMD21 Dev Breakout | ATSAMD21G18 | 未完全测试 |
| NodeMCU 1.0 | ESP-12E + CP2102 & CH340 | SDA=D2SCL=D1 |
| NodeMCU-32S | ESP32-S + CH340 | 主要适配环境 |
| Arduino Uno | ATmega328P + CH340 | 未实际测试,据反馈不可用 |
### 已知问题:
- 在 NDA_08 命令的写入 Felica 操作没有实现,因为未确认是否会影响卡片后续使用
- 未确定`res.status`的意义,因此`res.status = 1;`可能是错误的
- 未实现`mifare_select_tag`,未支持多卡选择,只会读到最先识别的卡片
- 未确定`res.status`错误码的定义,因此`res.status`的值可能是错误的
- 因为 PN532 库不支持同时读取多张卡片,所以未实现`mifare_select_tag`,只会读到最先识别的卡片
### 引用库:
- 驱动 WS2812B[FastLED](https://github.com/FastLED/FastLED)
- 驱动 PN532[PN532](https://github.com/elechouse/PN532)
- 驱动 PN532[PN532](https://github.com/elechouse/PN532) 或 [Aime_Reader_PN532](https://github.com/Sucareto/Aime_Reader_PN532)
- 读取 FeliCa 参考:[PN532を使ってArduinoでFeliCa学生証を読む方法](https://qiita.com/gpioblink/items/91597a5275862f7ffb3c)
- 读取 FeliCa 数据的程序:[NFC TagInfo](https://play.google.com/store/apps/details?id=at.mroland.android.apps.nfctaginfo)[NFC TagInfo by NXP](https://play.google.com/store/apps/details?id=com.nxp.taginfolite)

View File

@ -1,244 +0,0 @@
N.B. Quoted strings are NOT NUL-terminated unless otherwise noted.
Useful reading: https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf
(AiMe branded cards are Mifare Classic cards. Other technologies exist though)
Summary
-------
Hardware:
Assembly connector:
5V Host in
Tx;Rx;GND Host RS232 in
Tx;Rx;GND Daisy-chain out
Main board (probably LED controller):
Silk "837-15084"
CN1: Host 5V power in, ?V NFC-sub power out
CN2: Host RS232 Tx;Rx;GND in, NFC-sub Tx;Rx out
CN3: LED-Sub power and data(?) out
DIPSW1: Set to hex nibble 8.
Contains ADM3222 RS232 transceiver IC
Contains ATMega32 MCU
NFC subboard:
Sticker: Model "TN32MSEC003S"
CN1: ?V power and Tx;Rx;GND in, Tx;Rx;GND ass'y CN daisy out.
DIPSW1: Set to hex nibble 0.
Contains ATmega168 MCU
Contains ADM3202A RS232 transceiver IC
Contains shielded RF circuit
Entire non-ground-plane PCB area is visible through the chassis
torx screws lol
LED subboard:
Silk: "837-15120"
CN1: ?V power and Tx;Rx;GND in.
Five RGB LEDs and a bunch of resistors
No visible logic ICs..?
No DIPSW.
JVS framing:
E0 sync
D0 escape (+1 to unescape)
Checksum is sum of bytes after unescaping
Frame header:
Frame length (including length byte itself)
Address
Sequence no, hopefully loops before hitting esc byte...
Command byte
Bus addressing:
Low nibble set using DIPSWs
High nibble ???
Daisy chaining mechanism unknown (RS232 wires probably multi-tap)
Startup
-------
Addr 00 Command 62:
Req:
00 Payload length
Resp:
00 Status byte
00 Payload length
Description:
Unknown. Reset?
Addr 00 Command 30:
Req:
00 Payload length
Resp:
00 Status byte
17 Payload length
.. "TN32MSEC003S F/W Ver1.2E"
Description:
Get firmware version
Addr 00 Command 32:
Req:
00 Payload length
Resp:
00 Status byte
17 Payload length
.. "TN32MSEC003S H/W Ver3.0J"
Description:
Get hardware version
Addr 08 Command f5:
Req:
00 Payload length
Resp:
00 Status byte
00 Payload length
Description:
LED sub-board reset.
Won't accept LED commands until you do this.
Addr 08 Command f0:
Req:
00 Payload length
Resp:
00 Status byte
09 Payload length
.. "15084" (part nr for LED board)
FF ??
11 ??
00 ??
12 ??
Description:
Get board "info"
Addr 00 Command 54:
Req:
06 Payload length
57 'W'
43 'C'
43 'C'
46 'F'
76 'v'
32 '2'
Resp:
00 Status byte?
00 ??
Description:
Set Mifare KeyA.
"WCCF" might refer this this SEGA arcade game:
https://en.wikipedia.org/wiki/World_Club_Champion_Football
It's quite old and has AiMe readers, maybe where they first appeared?
Addr 00 Command 50:
Req:
06 Payload length
60 ??
90 ??
D0 ?? (This is escaped of course)
06 ??
32 ??
F5 ??
Resp:
00 Status byte
00 Payload length
Description:
Possibly Mifare KeyB.
Polling
-------
Addr 00 Command 40:
Req:
01 Payload length
03 ??
Resp:
00 Status byte
00 Payload length
Description:
Poll some other NFC technology?
Addr 00 Command 42:
Req:
00 Payload length
Resp if no MiFare card:
00 Status byte
01 Payload length
00 (represents nothing i guess)
Resp if MiFare card:
00 Status byte?
07 Payload length
01 Chunk length?
10 ?? Block size maybe?
04 Chunk length?
.. Mifare UID, four bytes.
Description:
Check for Mifare card presence?
Addr 00 Command 41:
Req:
00 Payload length
Resp:
00 Status byte
00 Payload length
Description:
Unknown. Poll some other NFC technology?
Card read
---------
Addr 00 Command 43:
Req:
04 Payload length
.. Mifare UID, four bytes.
Resp:
00 Status byte
00 Payload length
Description:
Select MiFare by UID?
Addr 00 Command 55:
Req:
05 Payload length
.. Mifare UID, four bytes.
03 ??
Resp:
00 Status byte
00 Payload length
Description:
Unknown.
Block 3 on a Mifare sector contains keys and an access control list.
It is generally not accessed directly (unless being provisioned?)
Addr 00 Command 52:
Req:
05 Payload length
.. Mifare UID, four bytes.
.. Block number, 1 or 2.
Resp for Block 1:
00 Status byte
10 Payload length (1 block)
.. "SBSD"
00 00 00 00
00 00 00 00
00 4E C6 22
Resp for Block 2:
00 Status byte
10 Payload length (1 block)
.. 00 00 00 00 00 00 xx xx
xx xx xx xx xx xx xx xx
Description:
Probably reads blocks 1 and 2 from Mifare sector 0.
Block 0 contains the "vendor information" and UID.
Block 1 contents are unknown, probably AiMe DB info.
Block 2 last 10 bytes hex are printed on the card ("local unique id").
(Block 3 contains encryption keys so is not allowed to be read)
LED
---
Addr 08 Command 81:
Req:
03 Payload length
ff Red intensity
ff Green intensity
ff Blue intensity
Resp:
None! Command is not acknowledged
Description:
Set LED color