读卡器 100 轮循环稳定性测试记录
| 项目 | 内容 |
|---|---|
| 测试日期 | 2026-08-23 |
| 测试时间 | 09:57:46–09:58:11 CST |
| 目标轮次 | 最多 100 轮 |
| 停止规则 | 任一轮任一阶段失败,立即停止,不重试 |
| Android 设备 | F700_HW(RK3568) |
| 读卡器 | New-CAP 0005 / HID RF Picc Reader |
| USB 标识 | VID 0x0610 / PID 0x2010 |
| 读卡卡片 | UID 92071FC9,CPU 卡 |
| 测试入口 | CardReaderStabilityInstrumentedTest |
| 测试结果 | 第 1–32 轮通过,第 33 轮失败并停止,未执行第 34–100 轮 |
1. 测试目标
验证当前 Android Java 封装在不人工干预的情况下,能否连续完成以下循环:
- 连接读卡器;
- 寻卡;
- 完整读卡;
- 关闭读卡器。
每轮还校验寻卡 UID 与读卡 UID 一致,并校验各轮 ASN、卡号、余额、主钱包消费计数、补助余额和补助消费计数保持稳定。
2. 执行结果
| 指标 | 结果 |
|---|---|
| 计划上限 | 100 轮 |
| 实际尝试 | 33 轮 |
| 完整通过 | 32 轮 |
| 失败 | 1 轮 |
| 未执行 | 67 轮 |
| 通过轮次占计划 | 32% |
| 首次失败轮次 | 第 33 轮 |
| 失败后是否继续 | 否 |
| 仪器测试总时间 | 24.368 秒 |
结论:当前实现可以连续完成 32 轮完整操作,但在第 33 轮发生协议异常,因此本轮测试结果不能判定为“100 轮稳定通过”。
3. 成功轮次数据一致性
第 1–32 轮读取结果始终一致:
| 字段 | 稳定值 |
|---|---|
| UID | 92071FC9 |
| 卡号 | 1705827 |
| 余额 | 604 分 |
| 主钱包消费计数 | 43 |
| 补助余额 | 0 分 |
| 补助消费计数 | 0 |
测试过程中没有观察到读操作导致余额或消费计数变化。
4. 性能统计
统计范围为第 1–32 轮完整成功周期:
| 指标 | 耗时 |
|---|---|
| 最小值 | 692 ms |
| 最大值 | 801 ms |
| 平均值 | 732.81 ms |
| 中位数 | 718.5 ms |
| P95 | 799 ms |
| 前 10 轮平均 | 698.5 ms |
| 后 10 轮平均 | 780.0 ms |
后 10 轮平均耗时比前 10 轮增加 81.5 ms。该现象只能作为“连续高频操作下耗时上升”的观察证据,不能单独证明具体根因。
5. 首次失败记录
| 项目 | 内容 |
|---|---|
| 轮次 | 第 33 轮 |
| 失败阶段 | readCard |
| 该轮耗时 | 832 ms |
| 错误分类 | PROTOCOL_ERROR |
| 错误信息 | APDU response is too short |
| 停止行为 | 捕获错误、关闭读卡器、终止测试 |
| 设备连接状态 | 测试停止后 USB 设备仍可枚举 |
精确调用位置:
readCard()
├─ findCard() 已完成
├─ readBaseData() 已完成
├─ readWallet(EC11 main wallet) 已完成
└─ readWallet(EC12 subsidy wallet)
├─ activateExpected() 已完成
└─ selectFile(EC01) 返回不足 4 字节的 APDU 响应
代码堆栈:
NewcapecProtocol.transmitApdu(NewcapecProtocol.java:117)
NewcapecProtocol.selectFile(NewcapecProtocol.java:100)
NewcapecProtocol.readWallet(NewcapecProtocol.java:76)
NewcapecProtocol.readCard(NewcapecProtocol.java:50)
6. 已确认与未确认
已确认:
- 失败不是 USB 设备拔出;
- 失败不是
IO_TIMEOUT、CRC_ERROR、NO_CARD或CARD_CHANGED; - 第 33 轮已完成寻卡、基础数据和主钱包读取;
- 补助钱包新会话激活成功;
- 失败发生在补助钱包阶段首次选择
EC01时; - 当前 APDU 包装层收到的逻辑响应长度小于 4 字节。
尚未确认:
- 不足 4 字节的原始响应究竟是空响应、两字节设备状态还是其他私有错误;
- 是否需要连接/读卡器关闭后的最小稳定间隔;
- 是否存在 HID 响应残留、设备内部节流或卡片射频会话恢复时间;
- 该问题在加入原始十六进制日志后是否稳定复现于同一轮次。
7. 后续建议
本次严格遵守“首次中断即停止”,没有继续第 34–100 轮,也没有自动重试。
如要进入下一轮排查,建议先增加失败响应的原始十六进制日志,再分别使用 0 ms、50 ms、100 ms、200 ms 的轮间间隔做独立对照测试。没有原始失败响应前,不建议直接把异常吞掉或无限重试。
8. 逐轮记录
| 轮次 | 结果 | 耗时(ms) | UID | 余额(分) | 消费计数 | 说明 |
|---|---|---|---|---|---|---|
| 1 | 通过 | 719 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 2 | 通过 | 697 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 3 | 通过 | 700 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 4 | 通过 | 692 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 5 | 通过 | 696 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 6 | 通过 | 696 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 7 | 通过 | 696 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 8 | 通过 | 696 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 9 | 通过 | 696 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 10 | 通过 | 697 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 11 | 通过 | 695 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 12 | 通过 | 697 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 13 | 通过 | 697 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 14 | 通过 | 701 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 15 | 通过 | 692 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 16 | 通过 | 696 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 17 | 通过 | 719 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 18 | 通过 | 759 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 19 | 通过 | 755 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 20 | 通过 | 752 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 21 | 通过 | 751 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 22 | 通过 | 751 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 23 | 通过 | 751 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 24 | 通过 | 797 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 25 | 通过 | 799 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 26 | 通过 | 792 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 27 | 通过 | 795 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 28 | 通过 | 796 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 29 | 通过 | 801 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 30 | 通过 | 779 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 31 | 通过 | 772 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 32 | 通过 | 718 | 92071FC9 | 604 | 43 | 连接、寻卡、读卡、关闭全部完成 |
| 33 | 失败并停止 | 832 | - | - | - | readCard / PROTOCOL_ERROR / APDU response is too short |
9. 原始数据
10. 验收结论
未达到 100 轮连续稳定通过。
本次有效结论为:32 轮连续通过,第 33 轮在补助钱包阶段选择 EC01 时出现 APDU response is too short,测试按约定停止并完整保留结果。
11. 后续诊断复现与报警假设
为确认第 33 轮短响应的原始内容,已增强诊断信息:如果 APDU 响应再次短于 4 字节,错误将同时输出 APDU 命令、原始响应十六进制和实际长度;协议时序、超时和重试策略均未改变。
诊断复现结果:
| 项目 | 结果 |
|---|---|
| 时间 | 2026-08-23 10:05:33–10:06:44 CST |
| 循环轮次 | 100 |
| 完整通过 | 100 |
| 失败 | 0 |
| 总耗时 | 71.702 秒(测试内部记录 71.683 秒) |
| 卡片数据 | UID、卡号、余额和消费计数始终一致 |
| 原短响应是否复现 | 否 |
用户观察到卡片长时间放置时读卡器会发出报警声,诊断循环期间/随后也再次发生报警。报警后保持卡片不动,立即执行一次“连接 → 寻卡 → 完整读卡 → 关闭”,结果仍为读卡成功,卡片数据正常。
因此当前证据支持以下判断:
- 报警不是导致读卡失败的充分条件,也不是“报警后必然不能读卡”;
- 第 33 轮失败不是固定计数溢出,因为同一设备、同一卡片、同一零间隔流程随后通过了 100 轮;
- 报警触发瞬间是否可能与 APDU 通讯形成极短暂的时序碰撞,现阶段仍不能完全排除;
- 原失败响应的字节在首次测试时没有记录,且后续未复现,所以具体是空响应、两字节状态还是错位响应仍未知。
更新后的准确结论是:首次测试出现一次偶发短响应;后续 100 轮和报警后的即时读卡均成功。报警与短响应存在时间上的可能关联,但目前没有因果证据。