更新 Felica 支持。
This commit is contained in:
parent
d24e827657
commit
95a08d43f7
@ -1,68 +1,20 @@
|
||||
#include "cmd.h"
|
||||
|
||||
//#define SerialDevice SerialUSB //32u4,samd21
|
||||
#define SerialDevice Serial //esp8266
|
||||
|
||||
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_MIFARE_AUTHENTICATE:
|
||||
sg_res_init();
|
||||
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();
|
||||
break;
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
|
||||
sg_nfc_cmd_mifare_set_key();
|
||||
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;
|
||||
default:
|
||||
sg_res_init();
|
||||
}
|
||||
}
|
||||
//#define high_baudrate
|
||||
#define M2F //取消注释此行,将默认密钥的mifare模拟为felica
|
||||
#include "cmd.h"
|
||||
|
||||
void setup() {
|
||||
#ifdef high_baudrate
|
||||
SerialDevice.begin(115200);//high_baudrate=true
|
||||
#else
|
||||
SerialDevice.begin(38400);
|
||||
// SerialDevice.begin(115200);//high_baudrate=true
|
||||
#endif
|
||||
SerialDevice.setTimeout(0);
|
||||
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
|
||||
FastLED.setBrightness(50);
|
||||
FastLED.clear();
|
||||
FastLED.show();
|
||||
nfc.begin();
|
||||
while (!nfc.getFirmwareVersion()) {
|
||||
fill_solid(leds, NUM_LEDS, 0xFF0000);
|
||||
@ -76,7 +28,7 @@ void setup() {
|
||||
nfc.SAMConfig();
|
||||
memset(&req, 0, sizeof(req.bytes));
|
||||
memset(&res, 0, sizeof(res.bytes));
|
||||
fill_solid(leds, NUM_LEDS, 0x0000FF);
|
||||
fill_solid(leds, NUM_LEDS, 0xFFD700);
|
||||
FastLED.show();
|
||||
}
|
||||
|
||||
@ -135,16 +87,66 @@ static void packet_write() {
|
||||
checksum += w;
|
||||
}
|
||||
if (w == 0xE0 || w == 0xD0) {
|
||||
if (SerialDevice.availableForWrite() < 2)
|
||||
return;
|
||||
SerialDevice.write(0xD0);
|
||||
SerialDevice.write(--w);
|
||||
} else {
|
||||
if (SerialDevice.availableForWrite() < 1)
|
||||
return;
|
||||
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_MIFARE_AUTHENTICATE:
|
||||
sg_res_init();
|
||||
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();
|
||||
break;
|
||||
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
|
||||
sg_nfc_cmd_mifare_set_key();
|
||||
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;
|
||||
default:
|
||||
sg_res_init();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Arduino-Aime-Reader
|
||||
使用 Arduino + PN532 + WS2812B 制作的 Aime 读卡器。支持 Felica,Bana,Aime(Mifare 卡模拟 Felica 是可选功能)。
|
||||
使用 Arduino + PN532 + WS2812B 制作的 Aime 读卡器。支持 Felica,banapassport,Aime(Mifare 卡模拟 Felica 是可选功能)。
|
||||
通信数据格式可参考 [card.txt](https://github.com/Sucareto/Arduino-Aime-Reader/blob/main/doc/card.txt) 和 [nfc.txt](https://github.com/Sucareto/Arduino-Aime-Reader/blob/main/doc/nfc.txt)。
|
||||
替换 chunihook.dll 可在控制台输出通信数据,源码在 [sg-cmd.c](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/tools/sg-cmd.c)。
|
||||
|
||||
@ -11,7 +11,7 @@ Arduino 和 PN532 接好 VCC,GND,SDA,SCL;
|
||||
|
||||
打开设备管理器,设置 Arduino 的 COM 号,一些参考如下:
|
||||
- Chunithm:COM12,支持读取 Felica 和 Aime
|
||||
- Ongeki/Sinmai:COM1,仅支持读取 Aime
|
||||
- Ongeki/Sinmai:COM1,支持读取 Felica 和 Aime
|
||||
- MaiMai Finale:COM2,仅支持读取 Aime
|
||||
|
||||
某些 Arduino 可能需要在打开主程序前给串口发送 DTR/RTS,需要先打开一次 Arduino 串口监视器再启动主程序。
|
||||
@ -23,6 +23,11 @@ Arduino 和 PN532 接好 VCC,GND,SDA,SCL;
|
||||
- SparkFun SAMD21 Dev Breakout(ATSAMD21G18)
|
||||
- NodeMCU 1.0(ESP-12E + CP2102 & CH340),SDA=D2,SCL=D1
|
||||
|
||||
#### 待办事项:
|
||||
- [ ] 确认 Ongeki 读取 Felica 情况
|
||||
- [ ] 收集 banapassport 卡结构和读取数据
|
||||
- [ ] 确认 NDA_06 和 NDA_08 数据结构
|
||||
|
||||
#### 引用库:
|
||||
- [驱动WS2812B FastLED.h](https://github.com/FastLED/FastLED)
|
||||
- [驱动PN532 PN532.h](https://github.com/elechouse/PN532)
|
||||
|
107
cmd.h
107
cmd.h
@ -1,6 +1,6 @@
|
||||
#include "FastLED.h"
|
||||
#define NUM_LEDS 6
|
||||
#define DATA_PIN 14
|
||||
#define DATA_PIN D5//14
|
||||
CRGB leds[NUM_LEDS];
|
||||
|
||||
#include <Wire.h>
|
||||
@ -13,43 +13,47 @@ PN532 nfc(pn532i2c);
|
||||
uint8_t cardtype, uid[4], uL;
|
||||
uint16_t systemCode = 0xFFFF;
|
||||
uint8_t requestCode = 0x01;
|
||||
uint16_t systemCodeResponse;
|
||||
typedef union {
|
||||
uint8_t block[16];
|
||||
uint8_t block[18];
|
||||
struct {
|
||||
uint8_t IDm[8];
|
||||
uint8_t PMm[8];
|
||||
uint16_t SystemCode;
|
||||
};
|
||||
} Felica;
|
||||
Felica felica;
|
||||
uint8_t AimeKey[6], BanaKey[6];
|
||||
|
||||
#define M2F //取消注释此行,将默认密钥的mifare模拟为felica
|
||||
|
||||
#ifdef M2F
|
||||
#define M2F_B 1 //指定从mifare读取第几block当作felica的IDm和PMm
|
||||
uint8_t MifareKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
#endif
|
||||
|
||||
enum {
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,//获取FW版本
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,//获取HW版本
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,
|
||||
SG_NFC_CMD_POLL = 0x42,//发送卡号
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x50,
|
||||
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55, /* guess based on time sent */
|
||||
SG_NFC_CMD_RESET = 0x62,//重置读卡器
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
SG_RGB_CMD_SET_COLOR = 0x81,//LED颜色设置
|
||||
SG_RGB_CMD_RESET = 0xF5,//LED重置
|
||||
SG_RGB_CMD_GET_INFO = 0xF0,//LED信息获取
|
||||
FELICA_CMD_POLL = 0x00,//ENCAP用
|
||||
FELICA_CMD_GET_SYSTEM_CODE = 0x0C,
|
||||
FELICA_CMD_NDA_A4 = 0xA4,
|
||||
SG_NFC_CMD_GET_FW_VERSION = 0x30,//获取 FW 版本
|
||||
SG_NFC_CMD_GET_HW_VERSION = 0x32,//获取 HW 版本
|
||||
SG_RGB_CMD_GET_INFO = 0xF0,//获取 LED 信息
|
||||
|
||||
SG_NFC_CMD_RESET = 0x62,//重置读卡器
|
||||
SG_RGB_CMD_SET_COLOR = 0x81,//LED 颜色设置
|
||||
SG_RGB_CMD_RESET = 0xF5,//LED 重置
|
||||
SG_NFC_CMD_RADIO_ON = 0x40,//打开读卡器
|
||||
SG_NFC_CMD_RADIO_OFF = 0x41,//关闭读卡器
|
||||
SG_NFC_CMD_POLL = 0x42,//发送卡号
|
||||
|
||||
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x50,
|
||||
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
|
||||
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
|
||||
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55,
|
||||
SG_NFC_CMD_FELICA_ENCAP = 0x71,
|
||||
|
||||
//FELICA_ENCAP
|
||||
FELICA_CMD_POLL = 0x00,
|
||||
FELICA_CMD_GET_SYSTEM_CODE = 0x0C,
|
||||
FELICA_CMD_NDA_A4 = 0xA4,
|
||||
FELICA_CMD_NDA_06 = 0x06,//测试中,作用未知
|
||||
FELICA_CMD_NDA_08 = 0x08,//测试中,作用未知
|
||||
};
|
||||
|
||||
typedef union packet_req {
|
||||
@ -104,10 +108,15 @@ typedef union packet_res {
|
||||
uint8_t code;
|
||||
uint8_t encap_IDm[8];
|
||||
union {
|
||||
struct {
|
||||
struct {//FELICA_CMD_POLL
|
||||
uint8_t encap_PMm[8];
|
||||
uint8_t system_code[2];
|
||||
};
|
||||
struct {//NDA06
|
||||
uint8_t NDA06_code[3];
|
||||
uint8_t NDA06_IDm[8];
|
||||
uint8_t NDA06_Data[8];
|
||||
};
|
||||
uint8_t felica_payload[241];
|
||||
};
|
||||
};
|
||||
@ -143,13 +152,13 @@ static void sg_nfc_cmd_reset() {//重置读卡器
|
||||
|
||||
static void sg_nfc_cmd_get_fw_version() {
|
||||
sg_res_init(23);
|
||||
// memcpy(res.version, "TN32MSEC003S F/W Ver1.2E", 23);
|
||||
// memcpy(res.version, "TN32MSEC003S F/W Ver1.2", 23);
|
||||
memcpy(res.version, "Sucareto Aime Reader FW", 23);
|
||||
}
|
||||
|
||||
static void sg_nfc_cmd_get_hw_version() {
|
||||
sg_res_init(23);
|
||||
// memcpy(res.version, "TN32MSEC003S H/W Ver3.0J", 23);
|
||||
// memcpy(res.version, "TN32MSEC003S H/W Ver3.0", 23);
|
||||
memcpy(res.version, "Sucareto Aime Reader HW", 23);
|
||||
}
|
||||
|
||||
@ -163,9 +172,8 @@ static void sg_nfc_cmd_mifare_set_key() {
|
||||
}
|
||||
|
||||
static void sg_led_cmd_reset() {
|
||||
sg_res_init(1);
|
||||
res.reset_payload = 0;
|
||||
fill_solid(leds, NUM_LEDS, 0x000000);
|
||||
sg_res_init();
|
||||
FastLED.clear();
|
||||
FastLED.show();
|
||||
}
|
||||
|
||||
@ -198,7 +206,7 @@ static void sg_nfc_cmd_radio_on() {
|
||||
cardtype = 0x10;
|
||||
return;
|
||||
}
|
||||
if (nfc.felica_Polling(systemCode, requestCode, felica.IDm, felica.PMm, &systemCodeResponse, 200)) {
|
||||
if (nfc.felica_Polling(systemCode, requestCode, felica.IDm, felica.PMm, &felica.SystemCode, 200)) {
|
||||
cardtype = 0x20;
|
||||
return;
|
||||
}
|
||||
@ -224,7 +232,7 @@ static void sg_nfc_cmd_poll() { //卡号发送
|
||||
return;
|
||||
}
|
||||
if (cardtype == 0x20) {
|
||||
sg_res_init(19);//count,type,id_len,IDm,PMm
|
||||
sg_res_init(19);
|
||||
memcpy(res.IDm, felica.IDm, 8);
|
||||
memcpy(res.PMm, felica.PMm, 8);
|
||||
res.count = 1;
|
||||
@ -234,10 +242,12 @@ static void sg_nfc_cmd_poll() { //卡号发送
|
||||
}
|
||||
#ifdef M2F
|
||||
if (cardtype == 0x30) {
|
||||
sg_res_init(19);//count,type,id_len,IDm,PMm
|
||||
sg_res_init(19);
|
||||
nfc.mifareclassic_ReadDataBlock(M2F_B, felica.block);
|
||||
memcpy(res.IDm, felica.IDm, 8);
|
||||
memcpy(res.PMm, felica.PMm, 8);
|
||||
felica.block[16] = 0x00;
|
||||
felica.block[17] = 0x03;//suica
|
||||
res.count = 1;
|
||||
res.type = 0x20;
|
||||
res.id_len = 0x10;
|
||||
@ -275,22 +285,37 @@ static void sg_nfc_cmd_felica_encap() {
|
||||
sg_res_init(0x14);
|
||||
memcpy(res.encap_IDm, felica.IDm, 8);
|
||||
memcpy(res.encap_PMm, felica.PMm, 8);
|
||||
res.system_code[0] = 0x00;
|
||||
res.system_code[1] = 0x00;
|
||||
memcpy(res.system_code, &felica.SystemCode, 2);
|
||||
break;
|
||||
case FELICA_CMD_GET_SYSTEM_CODE:
|
||||
sg_res_init(0x0D);
|
||||
memcpy(res.IDm, felica.IDm, 8);
|
||||
res.felica_payload[0] = 0x01;
|
||||
res.felica_payload[1] = 0x00;
|
||||
res.felica_payload[2] = 0x00;//0x03
|
||||
res.felica_payload[0] = 0x01;//未知
|
||||
res.felica_payload[1] = felica.block[16];//SystemCode
|
||||
res.felica_payload[2] = felica.block[17];
|
||||
break;
|
||||
case FELICA_CMD_NDA_A4://pass
|
||||
// sg_res_init(0x0B);
|
||||
// res.felica_payload[0] = 0x00;
|
||||
case FELICA_CMD_NDA_A4:
|
||||
sg_res_init(0x0B);
|
||||
res.felica_payload[0] = 0x00;
|
||||
break;
|
||||
case FELICA_CMD_NDA_06:
|
||||
sg_res_init(0x1D);
|
||||
memcpy(res.encap_IDm, felica.IDm, 8);
|
||||
res.NDA06_code[0] = 0x00;
|
||||
res.NDA06_code[1] = 0x00;
|
||||
res.NDA06_code[2] = 0x01;//未知
|
||||
memcpy(res.NDA06_IDm, felica.IDm, 8);
|
||||
memcpy(res.NDA06_Data, felica.PMm, 8);//填补数据用
|
||||
break;
|
||||
case FELICA_CMD_NDA_08:
|
||||
sg_res_init(0x0C);
|
||||
memcpy(res.encap_IDm, felica.IDm, 8);
|
||||
res.felica_payload[0] = 0x00;
|
||||
res.felica_payload[1] = 0x00;
|
||||
break;
|
||||
default:
|
||||
sg_res_init();
|
||||
res.status = 1;
|
||||
break;
|
||||
}
|
||||
res.encap_len = res.payload_len;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user