1
0
mirror of synced 2024-11-27 17:11:01 +01:00

Merge pull request #21 from nerimoe/main

再次修复游戏尝试给读卡器刷固件,更加正确的felica读取函数
This commit is contained in:
Sucareto 2024-11-05 15:32:34 +08:00 committed by GitHub
commit 03cd07ae73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 66 deletions

View File

@ -81,6 +81,7 @@ enum { // 命令标记
CMD_TO_UPDATER_MODE = 0x60, CMD_TO_UPDATER_MODE = 0x60,
CMD_SEND_HEX_DATA = 0x61, CMD_SEND_HEX_DATA = 0x61,
CMD_TO_NORMAL_MODE = 0x62, CMD_TO_NORMAL_MODE = 0x62,
CMD_FIRMWARE_UPDATE = 0x64,
// CMD_SEND_BINDATA_INIT = 0x63, // CMD_SEND_BINDATA_INIT = 0x63,
// CMD_SEND_BINDATA_EXEC = 0x64, // CMD_SEND_BINDATA_EXEC = 0x64,
// FeliCa // FeliCa
@ -235,6 +236,7 @@ uint8_t packet_read() { // 数据包读取函数
} }
req.bytes[++len] = r; req.bytes[++len] = r;
if (len == req.frame_len) { // 长度正确且校验通过,则返回命令标记,否则返回 STATUS_SUM_ERROR 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; return checksum == r ? req.cmd : STATUS_SUM_ERROR;
} }
checksum += r; // 包头后每位数据(不含转义)相加,作为校验值 checksum += r; // 包头后每位数据(不含转义)相加,作为校验值
@ -353,69 +355,17 @@ void nfc_mifare_read() { // 认证成功后,读取 MIFARE 指定的 block
} }
} }
// 游戏发送的0x71命令后面的包实际上是完整的与Felica卡片直接通信的包可以转发进PN532库直接用
// response也可以直接打包转发回游戏
void nfc_felica_through() { // FeliCa 处理函数 void nfc_felica_through() { // FeliCa 处理函数
uint16_t SystemCode; uint8_t response_length = 0xFF;
if (nfc.felica_Polling(0xFFFF, 0x01, res.encap_IDm, res.poll_PMm, &SystemCode, 200) == 1) { if (nfc.inDataExchange(&req.encap_len, req.encap_len, &res.encap_len, &response_length)) {
SystemCode = SystemCode >> 8 | SystemCode << 8; // 大小端数据翻转 res_init(response_length);
} else { // 如果读取 FeliCa 失败,则跳过后续操作 //如果成功的话 res.encap_len == response_length
res_init(); } else {
res_init(0);
res.status = STATUS_CARD_ERROR; 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;
} }

View File

@ -103,15 +103,20 @@ void loop() {
case CMD_CARD_SELECT: case CMD_CARD_SELECT:
case CMD_CARD_HALT: case CMD_CARD_HALT:
case CMD_EXT_TO_NORMAL_MODE: case CMD_EXT_TO_NORMAL_MODE:
case CMD_TO_UPDATER_MODE: // 作用未知,根据串口数据猜测 case CMD_TO_UPDATER_MODE:
res_init(); res_init();
break; break;
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 时,可能会触发固件更新逻辑 case CMD_SEND_HEX_DATA: // 非 TN32MSEC003S 时,可能会触发固件更新逻辑
res_init(); res_init();
res.status = STATUS_COMP_DUMMY_3RD; res.status = STATUS_COMP_DUMMY_3RD;
// 回复 STATUS_COMP_DUMMY_3RD 可以跳过更新 // 读卡器HW版本是837-15286时应该回复0x10, 837-15396回复0x20
// 如果因 fw、hw 变动导致触发更新该回复会导致更新失败amdaemon 崩溃
break; break;
case STATUS_SUM_ERROR: // 读取数据校验失败时的回复,未确认效果 case STATUS_SUM_ERROR: // 读取数据校验失败时的回复,未确认效果