diff --git a/Arduino-Chunithm-Reader.ino b/Arduino-Chunithm-Reader.ino index 647f96f..a81e733 100644 --- a/Arduino-Chunithm-Reader.ino +++ b/Arduino-Chunithm-Reader.ino @@ -23,13 +23,12 @@ void SerialCheck() { case SG_NFC_CMD_MIFARE_AUTHENTICATE: sg_res_init(); break; - case SG_NFC_CMD_MIFARE_SELECT_TAG: - sg_res_init(); - break; + // case 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: + case SG_NFC_CMD_MIFARE_SET_KEY_BANA://不处理 sg_res_init(); break; case SG_NFC_CMD_RADIO_ON: @@ -47,6 +46,10 @@ void SerialCheck() { case SG_RGB_CMD_SET_COLOR: sg_led_cmd_set_color(); break; + case 0: + break; + default: + sg_res_init(); } } @@ -55,9 +58,21 @@ void setup() { SerialUSB.setTimeout(0); FastLED.addLeds(leds, NUM_LEDS); nfc.begin(); + if (!nfc.getFirmwareVersion()) { + while (1) { + fill_solid(leds, NUM_LEDS, 0xFF0000); + FastLED[0].show(leds, NUM_LEDS, BRI); + delay(500); + fill_solid(leds, NUM_LEDS, 0x000000); + FastLED[0].show(leds, NUM_LEDS, BRI); + delay(500); + } + } nfc.SAMConfig(); memset(&req, 0, sizeof(req.bytes)); memset(&res, 0, sizeof(res.bytes)); + fill_solid(leds, NUM_LEDS, 0x0000FF); + FastLED[0].show(leds, NUM_LEDS, BRI); } void loop() { @@ -98,22 +113,30 @@ static uint8_t packet_read() { } static void packet_write() { - if (res.cmd == 0) + uint8_t checksum = 0, len = 0; + if (res.cmd == 0) { return; - uint8_t checksum = 0; + } SerialUSB.write(0xE0); - for (uint8_t i = 0; i < res.frame_len; i++) { - uint8_t w = res.bytes[i]; - checksum += w; - if (SerialUSB.availableForWrite() < 2) - return; + 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) { + if (SerialUSB.availableForWrite() < 2) + return; SerialUSB.write(0xD0); SerialUSB.write(--w); } else { + if (SerialUSB.availableForWrite() < 1) + return; SerialUSB.write(w); } + len++; } - SerialUSB.write(checksum); res.cmd = 0; } diff --git a/README.md b/README.md index b6e32b1..68be9d3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Arduino-Chunithm-Reader 使用 Arduino + PN532 + WS2812B 制作的 Chunithm 读卡器。 -使用 38400 波特率监听 COM12 端口和 aimeReaderHost 通信,通信数据格式可参考 [card.txt](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/card.txt) 和 [nfc.txt](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/nfc.txt)。 -替换 chunihook.dll 可在控制台输出通信数据,源码在 [sg-cmd.c](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/sg-cmd.c)。 +使用 38400 波特率监听 COM12 端口和 aimeReaderHost 通信,通信数据格式可参考 [card.txt](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/doc/card.txt) 和 [nfc.txt](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/doc/nfc.txt)。 +替换 chunihook.dll 可在控制台输出通信数据,源码在 [sg-cmd.c](https://github.com/Sucareto/Arduino-Chunithm-Reader/blob/main/tools/sg-cmd.c)。 #### 引用库: -[驱动WS2812B FastLED.h](https://github.com/FastLED/FastLED) -[驱动PN532 Adafruit_PN532.h](https://github.com/adafruit/Adafruit-PN532) +[驱动WS2812B FastLED.h](https://github.com/FastLED/FastLED) +[驱动PN532 Adafruit_PN532.h](https://github.com/adafruit/Adafruit-PN532) diff --git a/cmd.h b/cmd.h index d6066a3..e9ea852 100644 --- a/cmd.h +++ b/cmd.h @@ -5,32 +5,31 @@ CRGB leds[NUM_LEDS]; #include "Adafruit_PN532.h" -#define PN532_IRQ (4) +#define PN532_IRQ 4 Adafruit_PN532 nfc(PN532_IRQ, 16); -boolean readerDisabled = false; - +#define M2F_B 1 //指定从mifare读取第几block当作felica的IDm和PMm uint8_t AimeKey[6]; uint8_t MifareKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 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_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, + 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, + FELICA_CMD_GET_SYSTEM_CODE = 0x0C, + FELICA_CMD_NDA_A4 = 0xA4, }; typedef union packet_req { @@ -43,6 +42,7 @@ typedef union packet_req { uint8_t payload_len; union { uint8_t key[6];// sg_nfc_req_mifare_set_key + uint8_t color_payload[3];//sg_led_req_set_color struct {// sg_nfc_cmd_mifare_read_block uint8_t uid[4]; uint8_t block_no; @@ -53,7 +53,6 @@ typedef union packet_req { uint8_t code; uint8_t felica_payload[241]; }; - uint8_t color_payload[3];//sg_led_req_set_color }; }; @@ -70,30 +69,28 @@ typedef union packet_res { uint8_t payload_len; union { char version[23];// sg_nfc_res_get_fw_version,sg_nfc_res_get_hw_version + uint8_t reset_payload; //sg_led_res_reset + uint8_t info_payload[9]; //sg_led_res_get_info struct {// sg_nfc_res_poll uint8_t count; uint8_t type; uint8_t id_len; - union { - uint8_t uid[4]; - uint8_t IDPM[16]; - }; + uint8_t block[16]; }; - uint8_t block[16];// sg_nfc_res_mifare_read_block struct {// sg_nfc_res_felica_encap uint8_t encap_len; uint8_t code; - uint8_t IDm[8]; union { struct { - uint8_t PMm[8]; + uint8_t encap_block[16]; uint8_t system_code[2]; }; - uint8_t felica_payload[241]; + struct { + uint8_t encap_IDm[8]; + uint8_t felica_payload[241]; + }; }; }; - uint8_t reset_payload; //sg_led_res_reset - uint8_t info_payload[9]; //sg_led_res_get_info }; }; } packet_res_t; @@ -126,7 +123,7 @@ static void sg_nfc_cmd_get_hw_version() { memcpy(res.version, "TN32MSEC003S H/W Ver3.0J", sizeof(res.version)); } -static void sg_nfc_cmd_mifare_set_key_aime() { +static void sg_nfc_cmd_mifare_set_key_aime() { //设置aime的读取key sg_res_init(); memcpy(req.key, AimeKey, sizeof(AimeKey)); } @@ -139,8 +136,8 @@ static void sg_led_cmd_reset() { } static void sg_led_cmd_get_info() { - sg_res_init(sizeof(res.info_payload)); - static uint8_t info[] = {'1', '5', '0', '8', '4', 0xFF, 0x10, 0x00, 0x12}; + sg_res_init(9); + static uint8_t info[9] = {'1', '5', '0', '8', '4', 0xFF, 0x10, 0x00, 0x12}; memcpy(res.info_payload, info, 9); } @@ -154,70 +151,54 @@ static void sg_led_cmd_set_color() { static void sg_nfc_cmd_radio_on() { sg_res_init(); - if (!readerDisabled) { - return; - } - nfc.startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A); - readerDisabled = false; } static void sg_nfc_cmd_radio_off() { sg_res_init(); - readerDisabled = true; } static void sg_nfc_cmd_poll() { //卡号发送 - uint8_t uid[4]; - uint8_t t; - //读aime(实验性) + uint8_t uid[4], uL; + //读普通mifare当作felica nfc.startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A); - delay(10); + delay(50); if (!digitalRead(PN532_IRQ)) { - nfc.readDetectedPassiveTargetID(uid, &t); - if (nfc.mifareclassic_AuthenticateBlock(uid, t, 1, MIFARE_CMD_AUTH_B, AimeKey)) { //aime - res.type = 0x10; - res.id_len = t; - memcpy(res.uid, uid, t);//默认ID为0x01020304 - sg_res_init(7); + nfc.readDetectedPassiveTargetID(uid, &uL); + nfc.mifareclassic_AuthenticateBlock(uid, uL, M2F_B, MIFARE_CMD_AUTH_A, MifareKey); + if (nfc.mifareclassic_ReadDataBlock(M2F_B, res.block)) {//此处略过了IDm和PMm的分别读取 + sg_res_init(19);//count,type,id_len,IDm,PMm res.count = 1; + res.type = 0x20; + res.id_len = 0x10; return; } } - //读普通mifare当作felica - nfc.startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A); - delay(10); - if (!digitalRead(PN532_IRQ)) { - nfc.readDetectedPassiveTargetID(uid, &t); - if (nfc.mifareclassic_AuthenticateBlock(uid, t, 1, MIFARE_CMD_AUTH_A, MifareKey)) { - if (nfc.mifareclassic_ReadDataBlock(1, res.IDPM)) {//此处略过了IDm和PMm的分别读取 - res.type = 0x20; - res.id_len = sizeof(res.IDPM); - sg_res_init(19);//count,type,id_len,IDm,PMm - res.count = 1; - return; - } - } - } sg_res_init(1); res.count = 0; } static void sg_nfc_cmd_mifare_read_block() { - if (req.block_no > 3) - return; - sg_res_init(sizeof(res.block)); - if (nfc.mifareclassic_AuthenticateBlock(req.uid, 4, req.block_no, MIFARE_CMD_AUTH_B, AimeKey)) { - if (nfc.mifareclassic_ReadDataBlock(req.block_no, res.block)) { - return; - } - } sg_res_init(); } static void sg_nfc_cmd_felica_encap() { + uint8_t block[16]; + uint8_t uid[4], t; + nfc.startPassiveTargetIDDetection(PN532_MIFARE_ISO14443A); + delay(50); + if (!digitalRead(PN532_IRQ)) {//检测卡 + nfc.readDetectedPassiveTargetID(uid, &t); + nfc.mifareclassic_AuthenticateBlock(uid, t, M2F_B, MIFARE_CMD_AUTH_A, MifareKey); + nfc.mifareclassic_ReadDataBlock(M2F_B, block); + } + if (memcmp(&block, &req.IDm, 8)) {//确认卡是否正确 + sg_res_init(); + res.status = 1; + return; + } uint8_t code = req.code; res.code = code + 1; - memcpy(res.IDm, req.IDm, sizeof(req.IDm)); + memcpy(res.encap_block, block, 16); switch (code) { case FELICA_CMD_POLL: sg_res_init(0x14); diff --git a/card.txt b/doc/card.txt similarity index 100% rename from card.txt rename to doc/card.txt diff --git a/chunihook.dll b/tools/chunihook.dll similarity index 100% rename from chunihook.dll rename to tools/chunihook.dll diff --git a/sg-cmd.c b/tools/sg-cmd.c similarity index 100% rename from sg-cmd.c rename to tools/sg-cmd.c