From e0b4fb35759aa094d42722437680116fc040f373 Mon Sep 17 00:00:00 2001 From: nerichan Date: Mon, 28 Oct 2024 14:14:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=88=91=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E9=80=86=E5=90=91=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Aime_Reader.h | 75 +++++++---------------------------------- Arduino-Aime-Reader.ino | 11 +++--- 2 files changed, 20 insertions(+), 66 deletions(-) diff --git a/Aime_Reader.h b/Aime_Reader.h index c0d9ee4..5309707 100644 --- a/Aime_Reader.h +++ b/Aime_Reader.h @@ -81,6 +81,7 @@ enum { // 命令标记 CMD_TO_UPDATER_MODE = 0x60, CMD_SEND_HEX_DATA = 0x61, CMD_TO_NORMAL_MODE = 0x62, + CMD_FIRMWARE_UPDATE = 0x64, // CMD_SEND_BINDATA_INIT = 0x63, // CMD_SEND_BINDATA_EXEC = 0x64, // FeliCa @@ -235,6 +236,7 @@ uint8_t packet_read() { // 数据包读取函数 } req.bytes[++len] = r; if (len == req.frame_len) { // 长度正确且校验通过,则返回命令标记,否则返回 STATUS_SUM_ERROR + if (req.cmd == CMD_FIRMWARE_UPDATE) return CMD_FIRMWARE_UPDATE; //如果命令为0x64,则不校验checksum return checksum == r ? req.cmd : STATUS_SUM_ERROR; } checksum += r; // 包头后每位数据(不含转义)相加,作为校验值 @@ -353,69 +355,18 @@ void nfc_mifare_read() { // 认证成功后,读取 MIFARE 指定的 block } } +// 游戏发送的0x71命令后面的包实际上是完整的与Felica卡片直接通信的包,可以转发进PN532库直接用 +// response也可以直接打包转发回游戏 void nfc_felica_through() { // FeliCa 处理函数 - uint16_t SystemCode; - if (nfc.felica_Polling(0xFFFF, 0x01, res.encap_IDm, res.poll_PMm, &SystemCode, 200) == 1) { - SystemCode = SystemCode >> 8 | SystemCode << 8; // 大小端数据翻转 - } else { // 如果读取 FeliCa 失败,则跳过后续操作 - res_init(); + uint8_t response_length = 0; + req.encap_code &= 0x0F; //把0xA4处理为0x04(FELICA_CMD_REQUEST_RESPONSE) + if (nfc.inDataExchange(&req.encap_len, req.encap_len, &res.encap_len, response_length)) { + res_init(response_length); + //如果成功的话 res.encap_len == response_length + } else { + res_init(0); res.status = STATUS_CARD_ERROR; - return; + // 数据交换失败时返回STATUS_CARD_ERROR触发重传 + // 不对数据交换失败时做特殊处理,直接返回STATUS_CARD_ERROR。可能导致部分卡片(国产手机+aicemu)读取失败。 } - uint8_t code = req.encap_code; - res.encap_code = code + 1; - switch (code) { - case FelicaPolling: // 作用未知,根据串口数据猜测 - { - res_init(0x14); - res.poll_systemCode[0] = SystemCode; - res.poll_systemCode[1] = SystemCode >> 8; - } - break; - case FelicaReqSysCode: // 作用未知,根据串口数据猜测 - { - res_init(0x0D); - res.felica_payload[0] = 0x01; - res.felica_payload[1] = SystemCode; - res.felica_payload[2] = SystemCode >> 8; - } - break; - case FelicaActive2: // 作用未知,根据串口数据猜测 - { - res_init(0x0B); - res.felica_payload[0] = 0x00; - } - break; - case FelicaReadWithoutEncryptData: - { - uint16_t serviceCodeList = req.serviceCodeList[1] << 8 | req.serviceCodeList[0]; - uint16_t blockList[4]; - for (uint8_t i = 0; i < req.numBlock; i++) { // 大小端数据翻转 - blockList[i] = (uint16_t)(req.blockList[i][0] << 8 | req.blockList[i][1]); - } - // 读取数据 - nfc.felica_ReadWithoutEncryption(1, &serviceCodeList, req.numBlock, blockList, res.blockData); - res.RW_status[0] = 0; - res.RW_status[1] = 0; - res.numBlock = req.numBlock; - res_init(0x0D + req.numBlock * 16); - } - break; - case FelicaWriteWithoutEncryptData: - { - // 大小端数据翻转 - uint16_t serviceCodeList = req.serviceCodeList[1] << 8 | req.serviceCodeList[0]; - uint16_t blockList = (uint16_t)(req.blockList[0][0] << 8 | req.blockList[0][1]); - // 写入数据 - nfc.felica_WriteWithoutEncryption(1, &serviceCodeList, 1, &blockList, &req.blockData); - res_init(0x0C); - res.RW_status[0] = 0; - res.RW_status[1] = 0; - } - break; - default: // 对于其他未知的数据默认处理方式,未确认效果 - res_init(); - res.status = STATUS_INVALID_COMMAND; - } - res.encap_len = res.payload_len; } diff --git a/Arduino-Aime-Reader.ino b/Arduino-Aime-Reader.ino index 19751de..bb89337 100644 --- a/Arduino-Aime-Reader.ino +++ b/Arduino-Aime-Reader.ino @@ -103,15 +103,18 @@ void loop() { case CMD_CARD_SELECT: case CMD_CARD_HALT: case CMD_EXT_TO_NORMAL_MODE: - case CMD_TO_UPDATER_MODE: // 作用未知,根据串口数据猜测 res_init(); + case CMD_FIRMWARE_UPDATE: + res_init(); + res.status = STATUS_FIRM_UPDATE_SUCCESS; + //当读卡器发送的FW版本与amdaemon要求的版本不一致时, + //游戏会发送0x60使读卡器进入update模式,再通过0x64再次更新, + //此时需要回复0x08方可再次跳过更新 break; - case CMD_SEND_HEX_DATA: // 非 TN32MSEC003S 时,可能会触发固件更新逻辑 res_init(); res.status = STATUS_COMP_DUMMY_3RD; - // 回复 STATUS_COMP_DUMMY_3RD 可以跳过更新 - // 如果因 fw、hw 变动导致触发更新,该回复会导致更新失败,amdaemon 崩溃 + // 读卡器HW版本是837-15286时应该回复0x10, 837-15396回复0x20 break; case STATUS_SUM_ERROR: // 读取数据校验失败时的回复,未确认效果