查历史记录，给出关于key的报告文件路径


- update-config: Use this skill to configure the Claude Code harness via settings.json. Automated behaviors ("from now on when X", "each time X", "whenever X", "before/after X") require hooks configured in settings.json - the harness executes these, not Claude, so memory/preferences cannot fulfill them. Also use for: permissions ("allow X", "add permission", "move permission to"), env vars ("set X=Y"), hook troubleshooting, or any changes to settings.json/settings.local.json files. Examples: "allow npm commands", "add bq permission to global settings", "move permission to user settings", "set DEBUG=true", "when claude stops show X". For simple settings like theme/model, suggest the /config command.
- keybindings-help: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Examples: "rebind ctrl+s", "add a chord shortcut", "change the submit key", "customize keybindings".
- simplify: Review changed code for reuse, quality, and efficiency, then fix any issues found.
- fewer-permission-prompts: Scan your transcripts for common read-only Bash and MCP tool calls, then add a prioritized allowlist to project .claude/settings.json to reduce permission prompts.
- loop: Run a prompt or slash command on a recurring interval (e.g. /loop 5m /foo). Omit the interval to let the model self-pace. - When the user wants to set up a recurring task, poll for status, or run something repeatedly on an interval (e.g. "check the deploy every 5 minutes", "keep running /babysit-prs"). Do NOT invoke for one-off tasks.
- claude-api: Build, debug, and optimize Claude API / Anthropic SDK apps. Apps built with this skill should include prompt caching. Also handles migrating existing Claude API code between Claude model versions (4.5 → 4.6, 4.6 → 4.7, retired-model replacements).
TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`; user asks for the Claude API, Anthropic SDK, or Managed Agents; user adds/modifies/tunes a Claude feature (caching, thinking, compaction, tool use, batch, files, citations, memory) or model (Opus/Sonnet/Haiku) in a file; questions about prompt caching / cache hit rate in an Anthropic SDK project.
SKIP: file imports `openai`/other-provider SDK, filename like `*-openai.py`/`*-generic.py`, provider-neutral code, general programming/ML.
- init: Initialize a new CLAUDE.md file with codebase documentation
- review: Review a pull request
- security-review: Complete a security review of the pending changes on the current branch


The user is asking me to search through git history to find a report file related to "key". Let me search the git log for relevant commits and files.


Bash

git log --all --oneline --name-only -- '*.md' '*.txt' '*.xlsx' | head -200

Search git history for report/doc files mentioning key


git log --all --oneline --grep="key" -i | head -50

Search commit messages for key


bdd7dd0 fix(service): add INTERACT_ACROSS_USERS permission for singleUser cross-user routing
release/v1.0.0-beta6/INTEGRATION_GUIDE.md
f9cbf98 Fix MCU protocol consistency for beta6
release-template/API_REFERENCE.md
release/API_REFERENCE.md
release/RELEASE_INFO.txt
release/v1.0.0-beta6/API_REFERENCE.md
release/v1.0.0-beta6/INTERFACE_CONSISTENCY_REPORT.md
release/v1.0.0-beta6/README.md
release/v1.0.0-beta6/RELEASE_INFO.txt
release/v1.0.0-beta6/SHA256SUMS.txt
e779e6f release: v1.0.0-beta6 交付物补全与文档对齐
release-template/API_REFERENCE.md
release-template/INTEGRATION_GUIDE.md
release/API_REFERENCE.md
release/INTEGRATION_GUIDE.md
release/RELEASE_INFO.txt
release/VERSION.txt
release/v1.0.0-beta6/API_REFERENCE.md
release/v1.0.0-beta6/INTEGRATION_GUIDE.md
release/v1.0.0-beta6/README.md
release/v1.0.0-beta6/RELEASE_INFO.txt
release/v1.0.0-beta6/SHA256SUMS.txt
service/PACKAGING.md
794247e release: v1.0.0-beta6
docs/steering_wheel_control_summary.md
release/v1.0.0-beta6/API_REFERENCE.md
release/v1.0.0-beta6/INTEGRATION_GUIDE.md
release/v1.0.0-beta6/README.md
release/v1.0.0-beta6/RELEASE_INFO.txt
release/v1.0.0-beta6/SHA256SUMS.txt
release/v1.0.0-beta6/VERSION.txt
8b9d57d docs: add qsjnic service multi-user config guide
docs/qsjnic_service_user_config.md
acb2f74 beta5
release/v1.0.0-beta5/test_report_20260524_145449/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153439/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153448/report.md
d74334e Capture latest beta5 follow-up state
release/v1.0.0-beta4/qsmw_diag_20260519_232403/00_adb_devices.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/01_package_presence.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/02_package_dump.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/03_components.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/04_runtime_state.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/05_manual_start.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/06_serial_node.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/07_log_service.txt
af4c601 Prepare beta5 delivery package
docs/MCU_ARM_Reference/Key.xlsx
mcu_full_test/README.md
mcu_full_test/README_MCU_VENDOR_TEST.md
release/RELEASE_INFO.txt
release/VERSION.txt
release/mcu_full_test_for_vendor/OPEN_ISSUES.md
release/mcu_full_test_for_vendor/README.md
release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md
release/mcu_full_test_for_vendor/SHA256SUMS.txt
release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx
release/mcu_full_test_for_vendor/protocol_reference/MCU-ARM.xlsx
"release/mcu_full_test_for_vendor/protocol_reference/MCU_ARM_\346\216\245\345\217\243\346\226\207\346\241\243\346\270\205\345\215\225\344\270\216\346\230\216\347\273\206_20260513.md"
"release/mcu_full_test_for_vendor/protocol_reference/MCU\345\215\207\347\272\247-Update.xlsx"
release/mcu_full_test_for_vendor/protocol_reference/Public.xlsx
release/mcu_full_test_for_vendor/protocol_reference/Radio.xlsx
"release/mcu_full_test_for_vendor/protocol_reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt"
release/v1.0.0-beta4/QsmwService_192.168.0.66_Boot_Autostart_Analysis.md
release/v1.0.0-beta4/QsmwService_APK_System_Integration_Guide.md
release/v1.0.0-beta4/QsmwService_Startup_Signing_SELinux_Reference.md
release/v1.0.0-beta4/README.md
release/v1.0.0-beta5/API_REFERENCE.md
release/v1.0.0-beta5/INTEGRATION_GUIDE.md
release/v1.0.0-beta5/README.md
release/v1.0.0-beta5/RELEASE_INFO.txt
release/v1.0.0-beta5/SHA256SUMS.txt
release/v1.0.0-beta5/VERSION.txt
service/PACKAGING.md
482486c Prepare beta4 customer integration package
mcu_full_test/KEY_TEST_SOP.md
mcu_full_test/README.md
release/v1.0.0-beta4/MCU_INTERFACE_REFERENCE.md
"release/v1.0.0-beta4/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta4.md"
release/v1.0.0-beta4/README.md
release/v1.0.0-beta4/RELEASE_NOTES_BETA3_TO_BETA4.md
release/v1.0.0-beta4/SHA256SUMS.txt
release/v1.0.0-beta4/SystemService_Integration_Guide.md
release/v1.0.0-beta4/VALIDATION_REPORT.md
release/v1.0.0-beta4/demos/demos/ota-demo/README.md
release/v1.0.0-beta4/demos/demos/radio-demo/README.md
release/v1.0.0-beta4/demos/demos/vehicle-demo/README.md
83daa4e add beta4
"docs/Beta4_\345\217\221\345\270\203\345\256\236\346\226\275\350\256\241\345\210\222_20260518.md"
release/API_REFERENCE.md
release/INTEGRATION_GUIDE.md
release/RELEASE_INFO.txt
release/v1.0.0-beta4/demos/demos/ota-demo/README.md
release/v1.0.0-beta4/demos/demos/radio-demo/README.md
release/v1.0.0-beta4/demos/demos/vehicle-demo/README.md
d199154 chore(release): remove internal metadata from beta4 deliverables
"release/v1.0.0-beta4/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta4.md"
release/v1.0.0-beta4/README.md
release/v1.0.0-beta4/RELEASE_INFO.txt
release/v1.0.0-beta4/RELEASE_NOTES_BETA3_TO_BETA4.md
release/v1.0.0-beta4/SHA256SUMS.txt
release/v1.0.0-beta4/SystemService_Integration_Guide.md
release/v1.0.0-beta4/VALIDATION_REPORT.md
973279c docs(beta4): 对接文档与代码对齐修正 6 处
"release/v1.0.0-beta4/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta4.md"
release/v1.0.0-beta4/SHA256SUMS.txt
38494ff chore(beta4): SHA256SUMS 移除自指 + RELEASE_INFO 说明 + README 补 docx 说明
release/v1.0.0-beta4/README.md
release/v1.0.0-beta4/RELEASE_INFO.txt
release/v1.0.0-beta4/SHA256SUMS.txt
3d7293e chore(beta4): 更新 RELEASE_INFO commit + SHA256SUMS 含 docx
release/v1.0.0-beta4/RELEASE_INFO.txt
release/v1.0.0-beta4/SHA256SUMS.txt
bd82ea3 docs(beta4): 接入文档 + API + 集成指南 + 验证报告
release/v1.0.0-beta4/API_REFERENCE.md
release/v1.0.0-beta4/MCU_INTERFACE_REFERENCE.md
"release/v1.0.0-beta4/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta4.md"
release/v1.0.0-beta4/README.md
release/v1.0.0-beta4/SystemService_Integration_Guide.md
release/v1.0.0-beta4/VALIDATION_REPORT.md
8a121d5 test(beta4): 真机正式回归 + McuClient 版本探针 — 4 入口同源验证
release/v1.0.0-beta4/RELEASE_INFO.txt
release/v1.0.0-beta4/SHA256SUMS.txt
989f1b7 release: v1.0.0-beta4 — versionCode 104 + 版本号统一 + getServiceVersion/getSdkVersion API
release/v1.0.0-beta4/RELEASE_INFO.txt
release/v1.0.0-beta4/RELEASE_NOTES_BETA3_TO_BETA4.md
release/v1.0.0-beta4/SHA256SUMS.txt
eb2fdb9 docs: Beta4 发布实施计划(可由人工/Kimi/Codex 自包含执行)
"docs/Beta4_\345\217\221\345\270\203\345\256\236\346\226\275\350\256\241\345\210\222_20260518.md"
a504af8 test(beta3-v2): 真机端到端全按钮验证 + sendCommand entry log
release/v1.0.0-beta3/RELEASE_INFO.txt
release/v1.0.0-beta3/SHA256SUMS.txt
release/v1.0.0-beta3/test_evidence/README_v2.md
7d97bac fix(upgrade): UpgradeFeature 与 UpgradeManager 双 listener list 联通
release/v1.0.0-beta3/test_evidence/README.md
30e1aae test(beta3): 真机端到端验证证据 — 3 demo + OTA 全链路
release/v1.0.0-beta3/test_evidence/README.md
8627a2e chore(release): 用 HEAD 8fd6fa5 重打 release/v1.0.0-beta3/ 产物
release/v1.0.0-beta3/RELEASE_INFO.txt
release/v1.0.0-beta3/SHA256SUMS.txt
0c8b26c fix(release): P0 修复 beta3 交付包 + P1 验证文档/脚本升级
release/README.md
release/v1.0.0-beta3/RELEASE_INFO.txt
release/v1.0.0-beta3/SHA256SUMS.txt
release/v1.0.0-beta3/VALIDATION_REPORT.md
d7af846 beta3 hotfix-4: VehicleFeature.broadcastVehicle() 补全 typed listener 回调
release/v1.0.0-beta3/README.md
release/v1.0.0-beta3/RELEASE_INFO.txt
release/v1.0.0-beta3/SHA256SUMS.txt
release/v1.0.0-beta3/VALIDATION_REPORT.md
bde914c 更新架构.md: APK→MCU全链路/多APK流程/Service无root原因/4个bug修复记录
"test_Update/\346\236\266\346\236\204.md"
f3c46c1 feat(service): serial open retry with exponential backoff + demo cleanup
"docs/SystemService\345\261\202\346\236\266\346\236\204\347\254\246\345\220\210\346\200\247\345\210\206\346\236\220\346\212\245\345\221\212_20260516.md"
ef71253 style(docs): remove emoji from beta3 release docs for professional tone
release/v1.0.0-beta3/MCU_INTERFACE_REFERENCE.md
"release/v1.0.0-beta3/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta3.md"
release/v1.0.0-beta3/RELEASE_NOTES_BETA2_TO_BETA3.md
release/v1.0.0-beta3/VALIDATION_REPORT.md
18de6cd docs(release): add MCU_INTERFACE_REFERENCE for beta3
release/v1.0.0-beta3/MCU_INTERFACE_REFERENCE.md
release/v1.0.0-beta3/README.md
7236736 docs(release): add API_REFERENCE + VALIDATION_REPORT for beta3
release/v1.0.0-beta3/API_REFERENCE.md
release/v1.0.0-beta3/README.md
release/v1.0.0-beta3/VALIDATION_REPORT.md
c0f202b fix(ota): pause repeat probe during upgrade + fix empty projectId + enhance ota-demo UI
.deepseek/instructions.md
bfe19d8 kimi代码分析报告: 新增4个具体bug(循环探测无间隔/sendNormal fire-and-forget/M2A帧丢弃/sendAndWaitAck闲置)
"kimi\344\273\243\347\240\201\345\210\206\346\236\220\346\212\245\345\221\212.md"
b196dec WIP: update test files and scripts
test_Update/test_report.md
7d2d17f Merge remote-tracking branch 'origin/main'
c397715 chore: beta3 on-device validation on 192.168.0.66
docs/phase_a_validation_20260516_beta3.md
56b9b55 release: v1.0.0-beta3 — full build with domain module, AIDL v2, Feature architecture
release/VERSION.txt
"release/v1.0.0-beta3/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta3.md"
release/v1.0.0-beta3/README.md
release/v1.0.0-beta3/RELEASE_INFO.txt
release/v1.0.0-beta3/RELEASE_NOTES_BETA2_TO_BETA3.md
release/v1.0.0-beta3/SHA256SUMS.txt
release/v1.0.0-beta3/SystemService_Integration_Guide.md
c20d306 chore: Phase A — cpp refactor live validation report
docs/phase_a_validation_20260516.md
c77913f chore(release): 生产签名 + signature|privileged 权限 + composite-build demos + CI 脚本 + 文档
CHANGELOG.md
release-template/API_REFERENCE.md
release-template/INTEGRATION_GUIDE.md
e7145e8 test_report: AMS搜台补充-搜到4个电台
test_Update/test_report.md
15c32ad feat(contract): AIDL v2 — sendCommand/postCommand + IMcuFrameListener
"docs/\345\256\236\346\226\275\350\256\241\345\210\222_\345\256\242\346\210\267\344\272\244\344\273\230_20260516.md"
"docs/\346\236\266\346\236\204\350\257\204\344\274\260\344\270\216\346\224\271\350\277\233\346\226\271\346\241\210_20260516.md"
"docs/\347\274\226\347\250\213\345\256\236\346\226\275\350\256\241\345\210\222_\345\256\214\346\225\264\351\241\271\347\233\256_20260516.md"
mcu/README.md
mcu_full_test/README.md
f684fc5 test_report: 4条参数待确认移入危险跳过(tot_miles/work_mode/fuel_cal/veh_cfg), 更新统计
test_Update/test_report.md


bdd7dd0 fix(service): add INTERACT_ACROSS_USERS permission for singleUser cross-user routing
95aab7f fix: unify signing config, correct docs, rebuild release artifacts


Let me search more specifically for files with "key" in their name and look at relevant commits.


git log --all --oneline --name-only -- '**/Key*' '**/key*' '**/KEY*' | head -80

Search for Key/key files in git history


f9cbf98 Fix MCU protocol consistency for beta6
sdk/src/main/java/com/qsjnic/mcu/sdk/KeyListener.java
service/src/main/java/com/qsjnic/mcu/service/feature/KeyFeature.java
service/src/test/java/com/qsjnic/mcu/service/feature/KeyFeatureTest.java
af4c601 Prepare beta5 delivery package
docs/MCU_ARM_Reference/Key.xlsx
release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx
482486c Prepare beta4 customer integration package
mcu_full_test/KEY_TEST_SOP.md
aae7baf add mcu
docs/keystore/detail
docs/keystore/sim.jks
8015396 add ota
doc/keystore/detail
doc/keystore/sim.jks


git log --all --oneline --grep="Key" -i | head -30

Search commit messages mentioning Key


Let me get more details about the Key-related files in the history. The user seems to be looking for a report about "key" - let me check the relevant files:

1. `docs/MCU_ARM_Reference/Key.xlsx` - introduced in commit `af4c601`
2. `mcu_full_test/KEY_TEST_SOP.md` - introduced in commit `482486c`
3. `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` - introduced in `af4c601`

Let me also look for any reports specifically about keys. Let me check the test reports and the Phase A validation report, as well as other documents that might contain key-related content.


git log --all --oneline --name-only -- '**/test_report*' '**/VALIDATION*' '**/REPORT*' '**/*report*' '**/*分析*' '**/*评估*' | head -100

Search for report files in git history


acb2f74 beta5
release/v1.0.0-beta5/test_report_20260524_145449/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153439/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153448/report.md
af4c601 Prepare beta5 delivery package
release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md
482486c Prepare beta4 customer integration package
release/v1.0.0-beta4/VALIDATION_REPORT.md
d199154 chore(release): remove internal metadata from beta4 deliverables
release/v1.0.0-beta4/VALIDATION_REPORT.md
bd82ea3 docs(beta4): 接入文档 + API + 集成指南 + 验证报告
release/v1.0.0-beta4/VALIDATION_REPORT.md
0c8b26c fix(release): P0 修复 beta3 交付包 + P1 验证文档/脚本升级
release/v1.0.0-beta3/VALIDATION_REPORT.md
d7af846 beta3 hotfix-4: VehicleFeature.broadcastVehicle() 补全 typed listener 回调
release/v1.0.0-beta3/VALIDATION_REPORT.md
f3c46c1 feat(service): serial open retry with exponential backoff + demo cleanup
"docs/SystemService\345\261\202\346\236\266\346\236\204\347\254\246\345\220\210\346\200\247\345\210\206\346\236\220\346\212\245\345\221\212_20260516.md"
ef71253 style(docs): remove emoji from beta3 release docs for professional tone
release/v1.0.0-beta3/VALIDATION_REPORT.md
7236736 docs(release): add API_REFERENCE + VALIDATION_REPORT for beta3
release/v1.0.0-beta3/VALIDATION_REPORT.md
b196dec WIP: update test files and scripts
test_Update/test_report.md
7d2d17f Merge remote-tracking branch 'origin/main'
e7145e8 test_report: AMS搜台补充-搜到4个电台
test_Update/test_report.md
15c32ad feat(contract): AIDL v2 — sendCommand/postCommand + IMcuFrameListener
"docs/\346\236\266\346\236\204\350\257\204\344\274\260\344\270\216\346\224\271\350\277\233\346\226\271\346\241\210_20260516.md"
f684fc5 test_report: 4条参数待确认移入危险跳过(tot_miles/work_mode/fuel_cal/veh_cfg), 更新统计
test_Update/test_report.md
e56ae32 test_report: mcu_update_data移出跳过归入已测(完整升级已验证), A2M已测40/跳过4
test_Update/test_report.md
7f3dcc3 test_report: mcu_req_arm_reset修正描述(关机未重启)
test_Update/test_report.md
5becbe4 test_report: mcu_req_arm_reset测试通过(设备重启), A2M已测39/跳过5
test_Update/test_report.md
c1da735 test_report: mcu_req_sleep修正描述(ACK收到但未关机,需CAN配合)
test_Update/test_report.md
7678210 test_report: mcu_req_sleep测试通过(ACK+正常关机), A2M已测38/跳过6
test_Update/test_report.md
7bc3160 test_report: 跳过命令拆分为A2M危险7条 + M2A需CAN 25条, 含明细
test_Update/test_report.md
ff9d1a7 test_report: SEEK BWD/STOP测试完成(无ACK但未死锁), 待测归零, A2M全部37条已测
test_Update/test_report.md
ed8f3a9 test_report: SEEK FWD测试通过(PASS), 更新统计 A2M已测35/待测2/跳过7
test_Update/test_report.md
2210429 test_report: work_mode归入参数待确认, 待测归零
test_Update/test_report.md
6441f63 test_report: tot_miles/fuel_cal/veh_cfg改参数待确认, update_req/begin/end归入PASS, 剩余待测仅work_mode
test_Update/test_report.md
550f6f0 test_report: mcu_set_tot_miles确认死锁, 更新统计 A2M已测31/待测6/跳过7
test_Update/test_report.md
9a90020 test_report: 重写待测/跳过/死锁分类, 附adb命令示例
test_Update/test_report.md
b0a09e6 test_report: 重写78条分类 A2M 44条(30已测7待测7跳过) + M2A 34条(9已观测25需CAN)
test_Update/test_report.md
da49b43 test_report: 开头总结表格 + 已测31条/待测8条/跳过9条 + 测试观察
test_Update/test_report.md
d765a25 test_report: 补充Radio测试结果(5条PASS含M2A帧) + 版本号升级对比015→016 + 更新为27条已测
test_Update/test_report.md
28c8a42 Add test files and updates
test_Update/test_report.txt
test_Update/test_report_full.txt
3505cf3 test_report.md: 补充13条可测接口TX帧和参数说明, 细分S KIP/TIMEOUT分类
test_Update/test_report.md
e48d81a MCU 升级整合 + 78接口测试: mcu_upgrade_run完成211块验证, 28接口含回复帧数据, 新增升级文档/测试报告/mcu_helper/Service骨架
test_Update/test_report.md
df9070f add 79
test_Serial/dry_run_78_report.md
aae7baf add mcu
docs/acceptance_logs/REPORT.md
docs/deliverable_mcu_package/test_report_full_77_20260506.md
docs/deliverable_mcu_package/test_report_safe_baseline_20260506.md
docs/plan/full_77_interface_demo_test_report_20260511.md
docs/plan/phase1_phase2_test_report_20260511.md
"docs/\346\265\213\350\257\225\345\210\206\346\236\220\346\212\245\345\221\212_20260429.md"
test_Serial/test_report_safe_baseline_20260506.md
test_Serial/test_report_strict_20260506.md
test_Serial/test_report_summary_20260506.md
8015396 add ota
"doc/\346\265\213\350\257\225\345\210\206\346\236\220\346\212\245\345\221\212_20260429.md"


git log --all --format="%H %s" -- '**/KEY*' '**/Key*' '**/key*' 2>/dev/null | head -20

Commits that touched files named Key/key


f9cbf98057e8009ab4b19c4d83098c1f9d1384ee Fix MCU protocol consistency for beta6
af4c60197518df2ee063b2ad914b5148c9b15500 Prepare beta5 delivery package
482486ce6552a2d3b0136cdd4ee427f7bcd8035e Prepare beta4 customer integration package
aae7baf5fb994da5995faf605210ebe168a75312 add mcu
8015396770d5a62efa9bf70d06f766501739880d add ota


The user is asking about a "key report" file path. Let me look at relevant files more closely. The key files I see are:

1. `docs/MCU_ARM_Reference/Key.xlsx` - introduced in `af4c601` (Prepare beta5 delivery package)
2. `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` - also in `af4c601`
3. `mcu_full_test/KEY_TEST_SOP.md` - in `482486c` (Prepare beta4)
4. `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` - might contain key issues
5. `release/mcu_full_test_for_vendor/README.md` - might reference key

Let me also check the `docs/MCU_ARM_Reference/` directory to see what's been added/changed, and read the relevant files to understand the context better. The "关于序列号.txt" might be about Key.

Let me check for reports that are about the key or key-related testing. Let me also look at the KEY_TEST_SOP.md and the OPEN_ISSUES file.


git show af4c601:docs/MCU_ARM_Reference/Key.xlsx 2>/dev/null | file - 2>/dev/null; git show af4c601 --stat | head -30

Check Key.xlsx file and commit details


/dev/stdin: Microsoft Excel 2007+
commit af4c60197518df2ee063b2ad914b5148c9b15500
Author: hooperhu <hooper@qq.com>
Date:   Fri May 22 11:59:35 2026 +0800

    Prepare beta5 delivery package

 build.gradle.kts                                   |    2 +-
 .../aidl/com/qsjnic/mcu/contract/IMcuService.aidl  |    2 +-
 .../com/qsjnic/mcu/contract/McuServiceManager.java |    2 +-
 demos/ota-demo/app/build.gradle.kts                |    8 +-
 demos/radio-demo/app/build.gradle.kts              |    8 +-
 demos/vehicle-demo/app/build.gradle.kts            |    8 +-
 docs/MCU_ARM_Reference/Key.xlsx                    |  Bin 0 -> 197968 bytes
 .../100.png"                                       |  Bin 0 -> 272282 bytes
 .../98.png"                                        |  Bin 0 -> 217756 bytes
 .../AndroidManifest.xml"                           |   57 +
 .../BootCompleteReceiver.kt"                       |   33 +
 .../BootCompleteService.kt"                        |  105 +
 mcu_full_test/README.md                            |   22 +-
 mcu_full_test/README_MCU_VENDOR_TEST.md            |  142 +
 mcu_full_test/mcu_full_test                        |  Bin 73184 -> 68912 bytes
 mcu_full_test/mcu_full_test.c                      |  150 +-
 release/RELEASE_INFO.txt                           |   18 +-
 release/VERSION.txt                                |    2 +-
 release/mcu_full_test_for_vendor/OPEN_ISSUES.md    |   77 +
 release/mcu_full_test_for_vendor/README.md         |  319 ++
 .../mcu_full_test_for_vendor/REPORT_TEMPLATE.md    |  107 +
 release/mcu_full_test_for_vendor/SHA256SUMS.txt    |   13 +
 release/mcu_full_test_for_vendor/bin/mcu_full_test |  Bin 0 -> 68912 bytes
 .../protocol_reference/Key.xlsx                    |  Bin 0 -> 197968 bytes


git log --all --oneline --name-only -- '**/KEY_TEST*' '**/*key*report*' '**/*key*test*' '**/*Key*xlsx*' '**/关于*' | head -50

Search for key test/report related files


af4c601 Prepare beta5 delivery package
docs/MCU_ARM_Reference/Key.xlsx
release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx
"release/mcu_full_test_for_vendor/protocol_reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt"
482486c Prepare beta4 customer integration package
mcu_full_test/KEY_TEST_SOP.md
aae7baf add mcu
"docs/MCU_ARM_Reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt"


Let me now look at the content of relevant files about "key". Let me check:

1. The "关于序列号.txt" file - "序列号" could be translated as "serial number" which might be related to "key"
2. The KEY_TEST_SOP.md
3. The OPEN_ISSUES.md mentioned key issues in the transition from the commit messages

Let me also check the current status of these files in the working tree since some appear modified.


git show aae7baf:"docs/MCU_ARM_Reference/关于序列号.txt" 2>/dev/null | head -30

Check content of 关于序列号.txt from initial commit


关于序列号:
回复ACK[02]，使用对方发来的序列号
回复心跳HB[05]，使用对方发来的序列号
回复 SetupAck[03]，使用对方发来的序列号
数据帧[06]/Setup[01],使用自己的发送序列号
发送 Setup 帧时,发送和接收序列号回统一设置为1

关键规则
recvSerialNo：记录对方发来的最新序列号，回复时原样返回
sendSerialNo：记录自己已发送的序列号，收到对方ACK后递增
序列号从1开始：溢出回绕时若为0则强制置为1
Setup阶段特殊：握手时双方序列号同步为相同值

[Len=7] [ARM] FF AA 00 07 01 01 F6----------------[ARM 下发开始建链 0x01 Setup,将发送和接收序列号统一置1]
[Len=7] [MCU] FF AA 00 07 01 03 F4----------------[MCU 回复开始建链 0x03 SetupAck]
[Len=7] [ARM] FF AA 00 07 01 02 F5----------------[ARM 对SetAck回复确认 0x02 ACK],此时建链成功!]

[Len=9] [ARM] FF AA 00 09 02 06 01 81 6C----------[ARM 下发 public 0x81 指令,要求MCU发送初始化信息,如acc,brake,version等信息]
[Len=7] [MCU] FF AA 00 07 02 02 F4----------------[MCU 收到 public 0x81,用0x02 ACK指令进行回复,序列号使用收到的02]

[Len=10][MCU] FF AA 00 0A 02 06 01 05 00 E7-------[MCU 发送 public 0x05 首次上电状态,使用数据帧 Data 0x06]
[Len=7] [ARM] FF AA 00 07 02 02 F4----------------[ARM 收到 public 0x05,用0x02 ACK指令进行回复,序列号使用收到的02]

[Len=11][MCU] FF AA 00 0B 03 06 01 01 02 03 E4----[MCU 发送 public 0x01,检测状态如ACC,Brake,Reverse]
[Len=7] [MCU] FF AA 00 07 03 02 F3----------------[ARM 收到 public 0x01,用0x02 ACK指令进行回复,序列号使用收到的03]

代号		意义				数值
Setup		建链请求消息		0x01


git show 482486c:mcu_full_test/KEY_TEST_SOP.md 2>/dev/null | head -60

Check KEY_TEST_SOP.md content


# Key.xlsx Protocol Test SOP

## 1. Purpose

Validate all Key protocol interfaces defined in:

`docs/MCU_ARM_Reference/Key.xlsx`

Scope:

- A2M: `KEY_A2M_KEY`, `MT_KEY=0x02`, `cmd=0x81`
- M2A: `KEY_M2A_KEY`, `MT_KEY=0x02`, `cmd=0x01`
- Parameters: `P0=KeyValue`, `P1=KeyStatus`

## 2. Test Device

Default target:

```bash
adb connect 192.168.0.66
adb -s 192.168.0.66:5555 shell date
```

If the device date is wrong, set it before testing:

```bash
adb -s 192.168.0.66:5555 shell date MMDDhhmmYYYY.ss
```

Example:

```bash
adb -s 192.168.0.66:5555 shell date 051916302026.00
```

## 3. Build And Deploy

From repository root:

```bash
cd /Users/dapeng/Projects/yiren/qsjnic/mcu_full_test

make -B CC=/Users/dapeng/Library/Android/sdk/ndk/30.0.14904198/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang

adb -s 192.168.0.66:5555 push mcu_full_test /data/local/tmp/mcu_full_test
adb -s 192.168.0.66:5555 shell chmod +x /data/local/tmp/mcu_full_test
```

## 4. Offline Self-Test

Run:

```bash
adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test --selftest
```

Pass criteria:

```text
Self-tests: total=13 passed=13 failed=0


git diff HEAD -- "docs/MCU_ARM_Reference/关于序列号.txt" 2>/dev/null

Check current state of 关于序列号.txt in working tree


diff --git "a/docs/MCU_ARM_Reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt" "b/docs/MCU_ARM_Reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt"
index b44c7a6..4106dfe 100644
--- "a/docs/MCU_ARM_Reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt"
+++ "b/docs/MCU_ARM_Reference/\345\205\263\344\272\216\345\272\217\345\210\227\345\217\267.txt"
@@ -1,4 +1,4 @@
-关于序列号:
+qi关于序列号:
 回复ACK[02]，使用对方发来的序列号
 回复心跳HB[05]，使用对方发来的序列号
 回复 SetupAck[03]，使用对方发来的序列号


查历史记录，给出关于key的报告文件路径


Now let me get a more complete picture. The user asked "查历史记录，给出关于key的报告文件路径" which means "Check the history and give the file paths of reports about key."

Let me compile all the key-related files from the history:

1. **Key protocol Excel files**:
   - `docs/MCU_ARM_Reference/Key.xlsx` - introduced in commit `af4c601` (Prepare beta5 delivery package)
   - `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` - copy in the vendor delivery package, same commit

2. **Key test SOP**:
   - `mcu_full_test/KEY_TEST_SOP.md` - introduced in commit `482486c` (Prepare beta4 customer integration package)

3. **Key-related sequence number documentation**:
   - `docs/MCU_ARM_Reference/关于序列号.txt` - introduced in `aae7baf` (add mcu), modified in working tree

4. **Key-related source code**:
   - `sdk/src/main/java/com/qsjnic/mcu/sdk/KeyListener.java`
   - `service/src/main/java/com/qsjnic/mcu/service/feature/KeyFeature.java`
   - `service/src/test/java/com/qsjnic/mcu/service/feature/KeyFeatureTest.java`

5. **Keystore files**:
   - `docs/keystore/detail`
   - `docs/keystore/sim.jks`

But the user asked specifically about "报告文件" (report files) about key. Let me think about what reports exist that are specifically about key:

- `mcu_full_test/KEY_TEST_SOP.md` - this is a test SOP, not exactly a report
- `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` - might contain key issues
- `release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md` - template for vendor testing report

Let me also check if there are test reports that include key testing.


git show af4c601:release/mcu_full_test_for_vendor/OPEN_ISSUES.md 2>/dev/null | head -80

Check OPEN_ISSUES.md for key-related content


# MCU 厂商待确认问题清单

> 以下问题来源于车机方在联调过程中的实测发现与对协议文档的疑问。请 MCU 团队在测试反馈时一并回复每一条的处理意见。

---

## 一、已观测到的高风险命令

以下命令在前期联调中已观察到会导致 MCU 死锁 / 状态异常 / 需重刷固件。工具默认将其纳入 `--include-dangerous` 才会触发，希望 MCU 团队明确每条的合法取值、前置条件与恢复方式。

| # | 命令 | 域 | 协议号 | 观察到的现象 | 待确认 |
|---|------|----|--------|--------------|--------|
| 1 | `SET_TOT_MILES` | Public | `0x95` | 发送后 MCU 死锁，需重刷固件 | 合法取值范围？是否要求前置 `REQ_VEHICLE_CFG`？是否仅出厂阶段可写？ |
| 2 | `SET_WORK_MODE` | Public | `0x95` | `0x00 / 0x03` 两种取值均观察到死锁 | 与 `SET_TOT_MILES` 同 cmd 号是何用途区分？合法工作模式取值？ |
| 3 | `SET_FUEL_CAL` | Public | `0x96` | 死锁，需重刷 | 标定字段定义、合法范围、是否需要先进入标定模式？ |
| 4 | `SET_VEHICLE_CFG` | Public | `0x97` | 死锁，需重刷 | 车型配置字段、合法值表、写入条件？ |
| 5 | `REQ_ARM_RESET` | Public | `0x87` | 触发后 MCU 是否立即断链？预期 ACK 时序？ | ACK 是否在断链前回？是否可纳入自动化验收？ |
| 6 | `FACTORY_RESTORE` | Public | `0x89` | 恢复出厂后 MCU 行为？是否需要重新建链？ | 恢复完成回执？是否会清掉 RTC / 标定？ |
| 7 | `REQ_ARM_FORCE_UPGRADE` | Public | `0x90` | 触发后 MCU 状态？是否直接跳到 Bootloader？ | 调用前置条件、安全护栏？ |

---

## 二、协议文档结构疑问

| # | 问题 | 出处 | 当前工具处理方式 |
|---|------|------|-------------------|
| 1 | `Public 0x95` 在 Excel 中拆成 `SET_TOT_MILES` 与 `SET_WORK_MODE` 两条，请确认是否为同一命令的不同参数，还是两个独立业务接口？如独立，应分配不同 cmd 号 | `Public.xlsx` | 已注册为 2 条独立用例（`public.set_work_mode` / `public.set_tot_miles`） |
| 2 | `MCU升级-Update.xlsx` 来自 old 目录，是否仍是当前量产协议？BOOT 0x84-0x86 与 APP 0x80-0x83 在帧格式上有差异吗？ | `MCU升级-Update.xlsx` | 已纳入构帧目录与自测，实刷前需厂商确认 |
| 3 | Update BOOT `0x84 / 0x85 / 0x86` 的包长、checksum 算法、触发前置条件，是否与 APP 升级一致？ | `MCU升级-Update.xlsx` | 当前按 APP 升级流程兼容实现 |
| 4 | Key 域协议是否仅包含 `Byte6=0x02, Byte7=0x01/0x81, P0=KeyValue, P1=KeyStatus`？`0x00..0x0B` 键值是否完整？是否有未列出的 KeyValue / KeyStatus 组合？ | `Key.xlsx` | 当前实现 13 组合 A2M + 13 组合 M2A 期望 |
| 5 | MCU 主动上报的 `TRANSFER` 帧（FrameType=`0x07`）确认无需 ACK？是否所有 `0x07` 都是无 ACK 通道，还是仅特定 cmd？ | 实测观察 | 工具默认 `0x07` 不发 ACK |

---

## 三、占位 Payload 待确认实车合法值

工具中以下接口的 payload 当前为占位（全 0 或最小可识别值），意在跑通帧路径而非业务值校验。请提供实车合法默认值，或确认占位值不会对 MCU 造成副作用：

| 命令 | 域 | 当前 payload | 期望提供 |
|------|----|--------------|----------|
| `GPS_INFO` | Public `0x94` | 全 0 | 合法经纬度、速度、卫星数等字段格式 |
| `SET_SWITCH_STATUS` | Public `0x92` | 全 0 | 各开关位定义 |
| `SET_SPEED_RATIO` | Public `0x8F` | 全 0 | 速比合法范围 |
| `SET_VEHICLE_CFG` | Public `0x97` | 全 0 | 车型配置字段 |
| `SET_FUEL_CAL` | Public `0x96` | 全 0 | 标定字段定义 |
| `AUTO_CLEAR_METER` | Public `0x9B` | `0x00` | 各清零类型枚举 |
| `RESPONSE_FACTORY_CMD` | Public `0xA0` | 全 0 | 工厂命令响应格式 |
| `RESPONSE_TEST_CMD` | Public `0xA1` | 全 0 | 测试命令响应格式 |

---

## 四、运行环境疑问

| # | 问题 | 备注 |
|---|------|------|
| 1 | 量产样机 `/dev/ttyS7` 波特率是否锁定 460800？是否存在自适应/重协商机制？ | 工具默认 460800 |
| 2 | 车机侧系统服务（如 QsmwService）正常运行时与 MCU 通信是否独占串口？测试期间是否要求停服？ | 工具运行需独占 |
| 3 | 三步握手（SETUP → SETUPACK → 首个 ACK）的超时与重试策略 MCU 侧是怎么定的？是否有最大重试次数？ | 工具当前等待 1s |
| 4 | 心跳间隔与丢失多少次判断断链？ | 工具默认 1s 心跳 |

---

## 五、回填说明

请 MCU 团队对以上每一节、每一条问题，在反馈报告中以同样的编号给出回应，例如：

```
对一. 1 SET_TOT_MILES：合法取值为 4 字节小端无符号整数，范围 0~999999；写入前需先发送 REQ_VEHICLE_CFG；写入后必须 5 秒内 SET_VEHICLE_CFG 完成关闭。
对一. 2 SET_WORK_MODE：与 SET_TOT_MILES 不同 cmd，文档表已修正为 0x9C。新版协议见附件。
...
```

确认条目后，车机方会在下一版工具中：

- 把已澄清的危险命令从 `--include-dangerous` 默认列表中迁出（变为自动通过）
- 把占位 payload 替换为实车合法值
- 同步更新本仓库 `protocol_reference/` 下的协议文档


git show af4c601:release/mcu_full_test_for_vendor/README.md 2>/dev/null | head -100

Check vendor test README for key references


# MCU 全接口联调测试工具（厂商交付包）

> 交付方：ARM/Android 侧（车机方）
> 接收方：MCU 固件团队
> 交付日期：2026-05-20
> 工具版本：mcu_full_test v1.0.0-beta4

---

## 一、工具定位与使用目的

本工具运行在 **Android ARM64** 车机上，通过 `/dev/ttyS7` 串口与 MCU 进行通信，用于对 **MCU 团队已定义并实现的所有 MCU↔ARM 协议接口** 进行自动化联调验证。

工具会按协议文档列出的每一条接口逐一发送 A2M（ARM→MCU）请求帧、解析 MCU 的 ACK 与 M2A（MCU→ARM）回执，并把整个过程时间戳化地输出到终端与日志文件，便于 MCU 团队定位以下问题：

- MCU 端未按协议回执 ACK
- ACK 序列号、校验和、帧长度等字段不一致
- MCU 主动上报的 M2A 帧字段错误或缺失
- 个别命令导致 MCU 死锁、需重刷
- APP/BOOT 升级流程异常
- Key 按键 M2A 上报缺失或键值映射错误

**接口定义以 MCU 团队提供的协议文档为准**（见 `protocol_reference/`）。本工具不修改协议，只是按文档逐条触发并记录结果。

---

## 二、交付包内容

```
mcu_full_test_for_vendor/
├── README.md                        ← 本文档：使用说明、判定标准
├── REPORT_TEMPLATE.md               ← Bug 反馈模板（请填写后回传）
├── OPEN_ISSUES.md                   ← 等待 MCU 厂商确认的问题清单
├── SHA256SUMS.txt                   ← 文件完整性校验
├── bin/
│   └── mcu_full_test                ← Android ARM64 可执行文件（已编译，可直接 push）
├── src/
│   ├── mcu_full_test.c              ← 源码（约 3984 行，可按需重编）
│   └── Makefile                     ← 本地/交叉编译脚本
└── protocol_reference/              ← MCU 团队此前提供的协议文档
    ├── MCU_ARM_接口文档清单与明细_20260513.md
    ├── MCU-ARM.xlsx
    ├── Public.xlsx
    ├── Radio.xlsx
    ├── MCU升级-Update.xlsx
    ├── Key.xlsx
    └── 关于序列号.txt
```

---

## 三、协议接口覆盖范围

工具内置接口测试用例目录，与 `protocol_reference/` 中的协议文档一一对应：

| 域 | 方向 | 协议接口条目 | 工具内 A2M 用例 | M2A 期望/统计 |
|----|------|--------------|-----------------|----------------|
| Public | A→M | 30 | **31**（含 0x95 两个子条目：SET_TOT_MILES 与 SET_WORK_MODE） | 自动 ACK，按 cmd 统计上报 |
| Public | M→A | 26 | — | 接收期间按 cmd 计数 |
| Key    | A→M | 1 类 13 组合 | **13** | 13 组合期望覆盖 |
| Key    | M→A | 1 类 13 组合 | — | **13** 组合期望覆盖（需触发物理按键源） |
| Radio  | A→M | 7  | **11**（SEEK 子模式 + REG_MUTE 开关 + 频段值展开） | 自动 ACK，按 cmd 统计 |
| Radio  | M→A | 5  | — | 接收期间按 cmd 计数 |
| Update | A→M | 7  | **7**（默认作为危险命令跳过；走 `--live-upgrade` 完整状态机） | UPDATE_ACK / UPDATE_LEN / UPDATE_IND_AQUIRE |
| Update | M→A | 3  | — | `--live-upgrade` 中全程解析 |

**A2M 用例合计 62 条**（Public 31 + Key 13 + Radio 11 + Update 7），Key 域另有 13 条 M2A 期望覆盖。

---

## 四、运行环境要求

| 项 | 要求 |
|----|------|
| 设备 | Android ARM64 车机（量产样机） |
| ABI | `arm64-v8a` |
| 最低 API | Android 5.0（linker64 可用即可） |
| 串口 | `/dev/ttyS7`，默认波特率 460800（可改） |
| 权限 | 测试期间需要对串口节点的读写权限（推荐 `adb root` 或 SELinux permissive） |
| 占用冲突 | **测试前必须停止任何占用 `/dev/ttyS7` 的系统服务**（如车机侧 QsmwService），否则会与本工具抢字节，导致解析失败 |
| 主机 | 装有 adb 的 PC，能拉起 `adb shell` |

---

## 五、快速开始

### 5.1 推送二进制

```bash
adb push bin/mcu_full_test /data/local/tmp/
adb shell chmod +x /data/local/tmp/mcu_full_test
```

### 5.2 校验完整性（可选但推荐）

```bash
adb shell sha256sum /data/local/tmp/mcu_full_test
# 与 SHA256SUMS.txt 中 bin/mcu_full_test 行比对
```


Now I have a good picture. The user asked "查历史记录，给出关于key的报告文件路径" - "Check the history and give the file paths of reports about key."

Let me now compile all key-related report/document file paths from the git history:

Key-related files in the repository history:

1. Protocol files about Key:
   - `docs/MCU_ARM_Reference/Key.xlsx` - Key protocol definition (Excel)
   - `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` - Key protocol in vendor delivery package

2. Key test SOP:
   - `mcu_full_test/KEY_TEST_SOP.md` - Key protocol test SOP

3. Key sequence number document:
   - `docs/MCU_ARM_Reference/关于序列号.txt` - Key serial number documentation

4. Reports that cover Key testing:
   - `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` - Contains Key protocol issues (Section 2, Item 4)
   - `release/mcu_full_test_for_vendor/README.md` - References Key testing (13 A2M + 13 M2A combinations)
   - `release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md` - Bug report template for vendor testing

5. Source code for Key:
   - `sdk/src/main/java/com/qsjnic/mcu/sdk/KeyListener.java`
   - `service/src/main/java/com/qsjnic/mcu/service/feature/KeyFeature.java`
   - `service/src/test/java/com/qsjnic/mcu/service/feature/KeyFeatureTest.java`

6. Keystore:
   - `docs/keystore/detail`
   - `docs/keystore/sim.jks`

Let me also check if there are any specific test reports about Key testing.


git log --all --oneline --name-only -- '**/test_report_radio*' '**/test_report_2026*' | head -40

Check test report files for key-related content


acb2f74 beta5
release/v1.0.0-beta5/test_report_20260524_145449/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153439/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153448/report.md


git show acb2f74:release/v1.0.0-beta5/test_report_20260524_145449/report.md 2>/dev/null | head -60

Check beta5 test report for key content


# QSJNIC v1.0.0-beta5 设备测试报告

## 测试概览

| 项目 | 内容 |
|------|------|
| 测试版本 | v1.0.0-beta5 |
| 测试设备 | 192.168.0.67:5555 |
| 设备型号 | AUTO_on_RTD1861 |
| Android 版本 | 14 (API 34) |
| CPU 架构 | aarch64 |
| 测试时间 | 2026-05-24 14:54:57 |
| 测试人员 | Kimi CLI Auto-Test |

---

## 1. 版本验证

### SystemService
- **包名**: `com.qsjnic.mcu.service`
- **versionCode**: `105` ✅
- **versionName**: `1.0.0-beta5` ✅
- **安装路径**: `/system/priv-app/QsmwService/QsmwService.apk` ✅
- **minSdk**: 26 | **targetSdk**: 34
- **签名**: `b4addb29` (非 platform 签名)

### Demo 应用
| 应用 | 包名 | 状态 |
|------|------|------|
| Vehicle Demo | `com.qsjnic.demo.vehicle` | ✅ 已安装 |
| Radio Demo | `com.qsjnic.demo.radio` | ✅ 已安装 |
| OTA Demo | `com.qsjnic.demo.ota` | ✅ 已安装 |

### SDK/Contract 版本一致性
- Vehicle Demo: `SDK_VERSION = 1.0.0-beta5`, `Service version = 1.0.0-beta5`, `AIDL surface version = 2` ✅
- Radio Demo: `SDK_VERSION = 1.0.0-beta5`, `Service version = 1.0.0-beta5`, `AIDL surface version = 2` ✅
- OTA Demo: `SDK_VERSION = 1.0.0-beta5`, `Service version = 1.0.0-beta5`, `AIDL surface version = 2` ✅

---

## 2. 系统环境与权限

### 串口检查
```
crw-rw---- 1 root system 4, 71 /dev/ttyS7
SELinux: u:object_r:serial_device:s0
```
- **状态**: 存在 ✅
- **波特率**: 460800

### SELinux 状态（关键问题）
- **初始模式**: `Enforcing`
- **服务 SELinux 域**: `u:r:system_app:s0`
- **问题**: `system_app` 域没有 `serial_device` 的 `read write` 权限
- **AVC Denied 日志**:
  ```
  avc: denied { read write } for name="ttyS7"
  scontext=u:r:system_app:s0 tcontext=u:object_r:serial_device:s0 tclass=chr_file
  ```
- **影响**: 在 `Enforcing` 模式下，SystemService **无法打开 /dev/ttyS7**，导致 MCU 通信完全失败 ❌


Now let me also check the beta5 radio test reports and the test_Update/test_report.md for key-related content. But actually, the user's question is quite specific - they want "关于key的报告文件路径" (report file paths about key). Let me check more of the test reports and documentation.


git show acb2f74:release/v1.0.0-beta5/test_report_radio_20260524_153439/report.md 2>/dev/null | head -60

Check radio test report


# QSJNIC v1.0.0-beta5 收音机（Radio）测试报告

## 测试环境

| 项目 | 内容 |
|------|------|
| 测试版本 | v1.0.0-beta5 (versionCode=105) |
| 测试设备 | 192.168.0.67:5555 |
| 设备型号 | AUTO_on_RTD1861 |
| Android 版本 | 14 (API 34) |
| 串口 | /dev/ttyS7 @ 460800 |
| MCU 版本 | PAJERO69XZA0120017 |
| MCU 固件 | 0302_20260520 |

---

## 测试步骤

1. **停止旧服务**，安装 beta5 服务到 /system/priv-app/
2. **关闭 SELinux Enforcing**（测试环境使用 Permissive 模式，规避 system_app 无法访问 serial_device 的问题）
3. **启动 SystemService**，确认串口打开成功、Link Setup 握手通过
4. **安装并启动 Radio Demo** (com.qsjnic.demo.radio)
5. **模拟 UI 操作**（adb input tap）测试 FM/AM 切换、频率设置、搜台功能

---

## 测试结果

### ✅ 服务启动

- 串口打开：成功
- 链路握手：成功
- 心跳：正常

### ✅ MCU 数据接收（PUBLIC 帧）

服务正常接收并解析 MCU 主动推送的数据：

| 帧类型 | 内容 | 状态 |
|--------|------|------|
| SYS_STATUS | firstPwrOn=0 | ✅ |
| LINE_DETECT | IG=0 ACC=1 IIL=1 ... | ✅ |
| MCU Version | PAJERO69XZA0120017 | ✅ |
| VERSION_STR | 0302_20260520 / 03 | ✅ |
| TIME_INFO | 2025-01-01 00:14:06 | ✅ |
| TFT_DUTY | 0% | ✅ |
| KEY_PWR (0x06/0x07) | 周期性推送 | ✅ |

### ✅ 收音机功能测试

#### FM 模式
- **设置波段 FM**：成功
- **设置频率 87.5 MHz**：成功
- **Forward 搜台**：成功，MCU 连续推送搜台结果

**MCU 回传日志（FM 搜台）**：


git log --all --oneline --name-only --diff-filter=A -- '**/*key*' '**/*Key*' '**/*KEY*' | head -30

Find all key-related files ever added to the repo


f9cbf98 Fix MCU protocol consistency for beta6
contract/src/main/aidl/com/qsjnic/mcu/contract/IMcuKeyListener.aidl
sdk/src/main/java/com/qsjnic/mcu/sdk/KeyListener.java
sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java
service/src/main/java/com/qsjnic/mcu/service/feature/KeyFeature.java
service/src/test/java/com/qsjnic/mcu/service/feature/KeyFeatureTest.java
af4c601 Prepare beta5 delivery package
docs/MCU_ARM_Reference/Key.xlsx
release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx
482486c Prepare beta4 customer integration package
mcu_full_test/KEY_TEST_SOP.md
8015396 add ota
doc/keystore/detail
doc/keystore/sim.jks


Now I have a comprehensive picture of all key-related files in the repository history. Let me organize this information clearly for the user.

The user asked "查历史记录，给出关于key的报告文件路径" - Check the history and provide the file paths of reports about key.

Let me organize this into:
1. Protocol/Reference documents about Key
2. Test reports and SOPs about Key
3. Source code files about Key
4. Keystore files

Since the user specifically asked about "报告" (reports), let me focus on the report-type files and also provide the full list for context.


根据 git 历史记录，关于 **Key** 的文件路径如下：

## 协议/参考文档

| 文件路径 | 引入版本 | 说明 |
|----------|----------|------|
| `docs/MCU_ARM_Reference/Key.xlsx` | beta5 (`af4c601`) | Key 域协议定义（Excel） |
| `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` | beta5 (`af4c601`) | 厂商交付包中的 Key 协议副本 |
| `docs/MCU_ARM_Reference/关于序列号.txt` | 初始化 (`aae7baf`) | Key 帧序列号规则说明（工作区有未提交修改） |

## 测试 SOP / 报告

| 文件路径 | 引入版本 | 说明 |
|----------|----------|------|
| `mcu_full_test/KEY_TEST_SOP.md` | beta4 (`482486c`) | Key 协议测试标准操作流程 |
| `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` | beta5 (`af4c601`) | 含 Key 域协议疑问（第 2 节第 4 条：KeyValue/KeyStatus 是否完整） |
| `release/mcu_full_test_for_vendor/README.md` | beta5 (`af4c601`) | 涵盖 Key 测试范围（13 A2M + 13 M2A 组合） |
| `release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md` | beta5 (`af4c601`) | 厂商测试反馈报告模板 |

## 源码（Key 功能实现）

| 文件路径 | 说明 |
|----------|------|
| `contract/src/main/aidl/com/qsjnic/mcu/contract/IMcuKeyListener.aidl` | Key 监听器 AIDL 接口 |
| `sdk/src/main/java/com/qsjnic/mcu/sdk/KeyListener.java` | Key 监听器 SDK |
| `sdk/src/main/java/com/qsjnic/mcu/sdk/McuKeyClient.java` | Key 客户端 SDK |
| `service/src/main/java/com/qsjnic/mcu/service/feature/KeyFeature.java` | Key 功能服务端实现 |
| `service/src/test/java/com/qsjnic/mcu/service/feature/KeyFeatureTest.java` | Key 功能单元测试 |

## 签名密钥

| 文件路径 | 说明 |
|----------|------|
| `docs/keystore/sim.jks` | 签名密钥库 |
| `docs/keystore/detail` | 密钥库详细信息 |

---

**其中与 Key 直接相关的报告类文件**主要有：
1. `mcu_full_test/KEY_TEST_SOP.md` — Key 测试操作手册
2. `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` — 含 Key 协议待确认问题
3. `release/mcu_full_test_for_vendor/README.md` — 含 Key 域测试覆盖说明


key的bug报告路径


The user is asking specifically about "key的bug报告路径" - the bug report file path for Key. Let me search more specifically for bug reports related to Key in the git history.

Let me check the `release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md` and also look at the test reports that mention Key issues. I should also check the radio test report which mentioned KEY_PWR, and the OPEN_ISSUES.md which explicitly mentions Key protocol questions.

But the user seems to be asking about a specific bug report file. Let me search more carefully.


git log --all --oneline --grep="key" -i --name-only | head -40

Search for commits mentioning key bugs


git log --all --oneline -- '**/*key*bug*' '**/*Key*bug*' '**/*key*Bug*' '**/*key*issue*' '**/*Key*issue*' '**/*key*问题*' | head -20

Search for key bug/issue report files


git log --all --oneline --name-only -- '**/OPEN_ISSUES*' '**/*BUG*' '**/*bug*' '**/*问题*' | head -40

Search for bug/issue report files in history


bdd7dd0 fix(service): add INTERACT_ACROSS_USERS permission for singleUser cross-user routing
demos/vehicle-demo/app/src/main/java/com/qsjnic/demo/vehicle/MainActivity.java
release/v1.0.0-beta6/INTEGRATION_GUIDE.md
"release/v1.0.0-beta6/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta6.docx"
service/src/main/AndroidManifest.xml
95aab7f fix: unify signing config, correct docs, rebuild release artifacts
demos/ota-demo/app/build.gradle.kts
demos/radio-demo/app/build.gradle.kts
demos/vehicle-demo/app/build.gradle.kts
keystore/qsjnic_debug.jks
release/v1.0.0-beta1/DEPLOYMENT_TEST_REPORT_20260511.md
release/v1.0.0-beta1/MCU_INTERFACE_REFERENCE.md
"release/v1.0.0-beta1/QSJNIC_MCU_SDK_\345\274\200\345\217\221\345\257\271\346\216\245\346\226\207\346\241\243_v1.0.0-beta1.docx"
release/v1.0.0-beta1/README.md
release/v1.0.0-beta1/RELEASE_INFO.txt
release/v1.0.0-beta1/qsmw-demos.zip
release/v1.0.0-beta1/qsmw-service.apk
service/build.gradle.kts


(Bash completed with no output)


af4c601 Prepare beta5 delivery package
release/mcu_full_test_for_vendor/OPEN_ISSUES.md
1454ebb chore(demos): beta3 demo connectivity validation with screenshots
service/src/debug/AndroidManifest.xml
c397715 chore: beta3 on-device validation on 192.168.0.66
service/src/debug/AndroidManifest.xml
aae7baf add mcu
"docs/deliverable_mcu_package/02_MCU\345\233\272\344\273\266\351\227\256\351\242\230\347\225\214\345\256\232\344\270\216\346\225\264\346\224\271\351\234\200\346\261\202\344\271\246.md"
95aab7f fix: unify signing config, correct docs, rebuild release artifacts
keystore/qsjnic_debug.jks


Let me check the MCU firmware problem report file that was found: `docs/deliverable_mcu_package/02_MCU固件问题界定与整改需求书.md` - this might contain Key-related bug reports.


git show aae7baf:"docs/deliverable_mcu_package/02_MCU固件问题界定与整改需求书.md" 2>/dev/null | head -80

Check MCU firmware bug report for Key content


# MCU 固件问题界定与整改需求书

> **文档性质**：问题定界与整改通知书
> **发出方**：车机中间件开发组（ARM 侧）
> **接收方**：MCU 固件开发商 / 甲方客户（转达）
> **日期**：2026-05-06
> **涉及固件版本**：E112C069XZA0120015（SW: 0302_20260408）

---

## 1. 问题概述

自 2026-04-29 起，ARM 侧与 MCU 侧进行了多轮串口通信协议联调测试。测试发现：**MCU 固件当前版本存在严重的链路层状态机缺陷**，导致除心跳帧外，几乎所有业务指令的 ACK 响应极不稳定或完全缺失。

**关键背景**：
- **2026-05-03**：同一套测试工具、同一台车机、同一版 MCU 固件，Public 18 项 + Radio 7 项**全部通过**，链路层 SetupAck 6ms 内稳定到达，ACK 覆盖率 100%。
- **2026-05-06**：完全相同的测试环境，同一版 MCU 固件，链路层 SetupAck 基本消失，业务指令 ACK 覆盖率接近 0%。

> **结论：测试环境、测试工具、ARM 侧代码均未改变，变化的是 MCU 固件的运行状态。问题根源在 MCU 侧。**

---

## 2. 测试方法说明（排除 ARM 侧责任）

为避免"各说各话"，ARM 侧已采取以下措施确保测试结果客观、可复现：

### 2.1 测试工具完全开源

- 工具名称：`mcu_compliant_test.c`
- 代码量：约 400 行，单文件，无外部依赖
- 编译方式：Android NDK 标准交叉编译
- 协议符合性：**逐条对照 REF-03《MCU & Linux 通信链路设计.doc》审核通过**

ARM 侧已将源码完整交付，MCU 厂商可自行编译验证，也可在 PC 串口工具上模拟 ARM 行为复现问题。

### 2.2 两种独立工具交叉验证

| 工具 | 来源 | 协议实现 | 5月6日结果 |
|---|---|---|---|
| `qsjnic_test` | ARM 侧原有工具 | 基于项目历史代码 | 19 项中 1 项通过 |
| `mcu_compliant_test` | 本次独立重写 | 严格对照 REF-03 文档 | 严格模式：SetupAck 缺失，中止；兼容模式：15 项中 0~2 项通过 |

**两套独立代码得到一致结论**，排除了"ARM 侧测试工具 bug"的可能性。

### 2.3 环境隔离验证

- 测试前已确认 **SystemService 未运行**，串口无抢占
- 测试时无其他进程访问 `/dev/ttyS7`
- 波特率 460800、8N1 与文档一致
- 物理层收发双向可见（MCU 心跳正常到达 ARM，证明串口硬件无故障）

---

## 3. 问题清单（按优先级）

### 🔴 P0 阻断级：UPDATE_DATA (0x82) 导致 MCU 死锁

| 项目 | 描述 |
|---|---|
| **问题现象** | ARM 发送 UPDATE_DATA（FrameType=0x06, MsgType=0x07, Cmd=0x82, payload=1024 bytes + 2 bytes index）后，MCU **完全不回 ACK**，且后续不再响应任何业务指令 |
| **触发条件** | OTA 升级流程走到第 5 步（REQ→BEGIN→LEN→IND_AQUIRE 均正常，DATA 帧触发） |
| **后果严重性** | MCU 进入**不可逆异常状态**，必须整车断电 30 秒以上才能恢复。在此期间，车辆信号、收音机、 mute、背光等**所有功能无法通过串口控制** |
| **历史记录** | 2026-05-03 测试报告已记录此问题，反复验证 5~6 次，100% 复现 |
| **根因推测** | 从 mcu_app.bin 字符串中发现 `"gMcuUpgradeMsgQueue is NULL!"`，怀疑升级消息队列未初始化，或 cmd=0x82 处理函数未写完 |
| **整改要求** | 1. 修复 UPDATE_DATA 处理函数，确保收到 DATA 后正常 ACK 并继续 IND_AQUIRE 流程；2. 增加异常保护，任何单帧错误不得导致整个状态机崩溃 |
| **验收标准** | 使用真实 mcu_app.bin 完成完整 OTA 闭环（REQ→BEGIN→DATA→END），MCU 正常升级并返回 SUCCESS |

---

### 🔴 P0 阻断级：SetupAck (0x03) 不稳定 / 缺失

| 项目 | 描述 |
|---|---|
| **问题现象** | ARM 发送 Setup（FrameType=0x01）后，MCU **不回复 SetupAck（0x03）**。5月3日 6ms 内稳定收到，5月6日 3 次重试 × 3 秒均收不到 |
| **触发条件** | 任何冷启动或重新建链时 |
| **后果严重性** | 按 REF-03 文档 2.5.2，链路未建立前不得收发数据。SetupAck 缺失意味着**链路层未就绪**，所有业务测试无意义 |
| **根因推测** | 5月3日 OTA 死锁后，MCU 状态机未完全复位。即使整车重新上电（如果上电间隔不足 30 秒），MCU 可能仍携带残留异常状态 |
| **整改要求** | 1. 确保收到 Setup(0x01) 后 200ms 内回复 SetupAck(0x03)；2. 上电初始化时清零所有链路层状态变量；3. 增加看门狗或状态机自恢复机制 |
| **验收标准** | 连续 100 次冷启动，SetupAck 到达率 100%，延迟 ≤ 200ms |


git log --all --oneline --name-only -- '**/deliverable_mcu_package/*' | head -40

List all files in deliverable_mcu_package


7bf8426 release: v1.0.0-beta2 — 重打包交付 (协议 78 / AIDL 54 / Listener 34)
docs/deliverable_mcu_package/all_interfaces.json
aae7baf add mcu
"docs/deliverable_mcu_package/00_\344\272\244\344\273\230\347\211\251\346\270\205\345\215\225\344\270\216\346\200\273\350\247\210.md"
"docs/deliverable_mcu_package/01_MCU\344\270\262\345\217\243\351\200\232\344\277\241\345\215\217\350\256\256\346\265\213\350\257\225\350\247\204\350\214\203_v1.0.md"
"docs/deliverable_mcu_package/02_MCU\345\233\272\344\273\266\351\227\256\351\242\230\347\225\214\345\256\232\344\270\216\346\225\264\346\224\271\351\234\200\346\261\202\344\271\246.md"
"docs/deliverable_mcu_package/03_\346\265\213\350\257\225\345\267\245\345\205\267\345\214\205\344\275\277\347\224\250\350\257\264\346\230\216.md"
"docs/deliverable_mcu_package/04_MCU\345\216\202\345\225\206\344\272\244\344\273\230\350\246\201\346\261\202\344\270\216\347\250\263\345\256\232\346\200\247\351\252\214\346\224\266\346\240\207\345\207\206.md"
docs/deliverable_mcu_package/all_interfaces.json
docs/deliverable_mcu_package/mcu_compliant_test
docs/deliverable_mcu_package/mcu_compliant_test.c
docs/deliverable_mcu_package/mcu_deadlock_repro
docs/deliverable_mcu_package/mcu_deadlock_repro.c
docs/deliverable_mcu_package/mcu_test_toolkit_v1.0_20260506.zip
docs/deliverable_mcu_package/test_cases.json
docs/deliverable_mcu_package/test_report_full_77_20260506.md
docs/deliverable_mcu_package/test_report_safe_baseline_20260506.md


Let me now check the full 77 interface test report to see if it includes Key testing results or issues.


git show aae7baf:"docs/deliverable_mcu_package/test_report_full_77_20260506.md" 2>/dev/null | grep -n -i "key\|按键" | head -20

Check 77-interface test report for Key-related content


50:[FAIL] SET_KEY_BACKLIGHT_DUTY_CYCLE  ← 第10个命令不回复
70:| SET_KEY_BACKLIGHT | 需占空比值（未知长度） | `01 8B`（2字节） | **缺少占空比值** |


git show aae7baf:"docs/deliverable_mcu_package/test_report_full_77_20260506.md" 2>/dev/null | head -40

Check test report header


# MCU 全接口 77 命令探测测试报告

> **报告编号**：QSJNIC-FULL-77-20260506
> **测试日期**：2026-05-06
> **测试策略**：保守方案 A — 安全基线 12 用例验收，其余 65 接口推迟至 MCU 厂商提供精确 Payload 后测试
> **结论**：**MCU 固件对错误/不完整 Payload 的容错极差，使用最小 Payload 试探会导致状态逐步恶化直至死锁**

---

## 1. 测试背景与目的

在确认安全基线 12 用例可 100% 通过后，尝试扩展测试覆盖范围至全部 77 个接口命令。

**测试方法**：
- 对已知安全命令使用精确 Payload
- 对未知命令使用最小 Payload（仅 MsgType + Cmd，2 字节）进行基础 ACK 探测
- 每 5 个命令后执行 HealthCheck（重新发送 Setup 验证 SetupAck）

---

## 2. 测试结果

### 2.1 三步验证结果

| 步骤 | 测试内容 | SetupAck | A2M 通过 | A2M 失败 | 关键现象 |
|---|---|---|---|---|---|
| **Step 1** | 安全基线 12 用例 | ✅ 正常 | 11/12 | 1 | REQ_INIT_INFO 偶发超时，其余通过 |
| **Step 2** | 全接口 15 A2M + 34 M2A | 前段正常，后段死锁 | 5/15 | 9/15 | **MCU 状态逐步恶化** |
| **Step 3** | 安全基线复测 | ❌ 完全缺失 | 0/12 | 12 | 彻底死锁，需断电恢复 |

### 2.2 Step 2 恶化时间线

```
[Setup] PASS                        ← 建链正常
[PASS] REQ_INIT_INFO                ← 第1个命令 OK
[PASS] REQ_MUTE                     ← 第2个命令 OK
[PASS] TIME_INFO                    ← 第3个命令 OK
[PASS] TFT_DUTY_CYCLE               ← 第4个命令 OK
[PASS] REQ_SLEEP                    ← 第5个命令 OK
[HealthCheck] PASS                  ← MCU 仍健康


Now let me also check the `docs/plan/full_77_interface_demo_test_report_20260511.md` and `docs/plan/phase1_phase2_test_report_20260511.md` for key-related content, and also check if there are more recent bug reports related to Key.

Let me also look at the test_Update/test_report.md which had many iterations - it might contain Key testing results.


git show aae7baf:"docs/plan/full_77_interface_demo_test_report_20260511.md" 2>/dev/null | grep -n -i "key\|按键" | head -20

Check plan test report for Key content


40:| 11 | 0x8B | `setKeyBacklightDutyCycle` | `75` | 0 | 20:08:25.519 | ✅ |
42:| 13 | 0x8D | `setKeyPwrStatus` | `1` | 0 | 20:08:30.526 | ✅ |
114:| 6 | 0x06 | `onKeyEvent` | — | — | ⏸ 静态未按键 |
138:> - `onKeyEvent: 1`
196:20:08:25.519 [A2M] setKeyBacklightDutyCycle(75) -> rc=0
198:20:08:30.526 [A2M] setKeyPwrStatus(1) -> rc=0


git log --all --oneline --name-only -- '**/P20260513/*' '**/*ROM*' '**/*singleUser*' | head -20

Check recent issue report files


Now I have a comprehensive picture. Let me also check if there's a currently-existing bug report file for ROM singleUser issues.


cat "docs/P20260513/ROM_singleUser_issue_report.md" 2>/dev/null | head -30

Check ROM singleUser issue report


# QsMcuSystemService 多用户串口抢占问题技术报告

**报告日期：** 2026-05-27
**问题等级：** 高（导致串口通信冲突、MCU 指令重复/回包争抢）
**责任边界：** ROM / 系统框架层（APK 侧已正确配置）

---

## 1. 问题现象

车机重启后，`com.qsjnic.mcu.service` 的 `QsMcuSystemService` 会在 **User 0** 和 **User 10** 下各启动一个独立实例，两个进程同时读写 `/dev/ttyS7`，造成严重的串口抢占。

现场日志（重启后）：

```
User 0:  ServiceRecord{77eb77} pid=2613  ← BOOT_COMPLETED 触发
User 10: ServiceRecord{dde9559} pid=3233  ← BOOT_COMPLETED 触发 + com.auto.settings 绑定
```

两个进程同时打印 `FrameRouter` 日志，收到的 MCU 回包内容不一致（如 RADIO_FREQ 一个读到 11361，另一个读到 8750）。

---

## 2. APK 侧已做的正确配置

`service/src/main/AndroidManifest.xml` 中已明确声明：

```xml
<service
    android:name=".QsMcuSystemService"


git log --all --oneline --name-only -- '**/P20260513/*' | head -30

Check all P20260513 files in git history


Now I have a comprehensive picture. The user asked "key的bug报告路径" - the path of Key bug reports. Let me compile the relevant bug report files that mention or are specifically about Key issues.

Key-related bug reports in git history:

1. **`docs/deliverable_mcu_package/02_MCU固件问题界定与整改需求书.md`** - MCU firmware bug report from the initial delivery package, mentions `SET_KEY_BACKLIGHT_DUTY_CYCLE` failures
2. **`docs/deliverable_mcu_package/test_report_full_77_20260506.md`** - 77-interface test report, mentions Key backlight command failure
3. **`release/mcu_full_test_for_vendor/OPEN_ISSUES.md`** - Open issues list for MCU vendor, Section 2 Item 4 specifically asks about Key protocol completeness
4. **`docs/plan/full_77_interface_demo_test_report_20260511.md`** - Plan test report with Key test results

However, there isn't a dedicated "Key bug report" file. The Key-related bugs/issues are embedded within these broader test/issue reports.

Let me also look at whether there are MCU vendor feedback reports that specifically address Key issues.


根据 git 历史记录，Key 相关的 bug/问题报告分布在以下文件中：

## Key 相关问题报告

| 文件路径 | 引入版本 | 说明 |
|----------|----------|------|
| `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` | beta5 (`af4c601`) | **第 2 节第 4 条** — Key 域协议完整性问题（KeyValue 0x00~0x0B 是否完整、是否存在未列出的 KeyValue/KeyStatus 组合） |
| `docs/deliverable_mcu_package/02_MCU固件问题界定与整改需求书.md` | 初始化 (`aae7baf`) | **P0 阻断级** — `SET_KEY_BACKLIGHT_DUTY_CYCLE` 不回复 ACK，MCU 状态逐步恶化 |
| `docs/deliverable_mcu_package/test_report_full_77_20260506.md` | 初始化 (`aae7baf`) | 全接口 77 命令探测报告 — `SET_KEY_BACKLIGHT_DUTY_CYCLE` 为第 10 个命令不回复，列为 FAIL |

## Key 测试结果（非 bug 报告，但含 Key 状态）

| 文件路径 | 引入版本 | 说明 |
|----------|----------|------|
| `docs/plan/full_77_interface_demo_test_report_20260511.md` | 初始化 (`aae7baf`) | `setKeyBacklightDutyCycle` + `setKeyPwrStatus` 测试通过，`onKeyEvent` 静态未按键 |

## 厂商反馈模板

| 文件路径 | 说明 |
|----------|------|
| `release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md` | MCU 厂商填写的 bug 反馈模板（待回传） |

---

**核心结论**：Key 的 bug 问题主要集中在 **`OPEN_ISSUES.md`**（协议完整性质疑，待 MCU 厂商确认）和 **`02_MCU固件问题界定与整改需求书.md`**（Key 背光命令死锁问题）。目前仓库中没有单独的 Key bug 专项报告文件。


查看项目文件


The user wants to view the project files. Let me list the project structure to give them an overview.


List project root directory


total 424
drwxr-xr-x@ 47 admin  staff   1504 May 27 14:10 .
drwxr-xr-x@ 14 admin  staff    448 May 28 16:48 ..
-rw-r--r--@  1 admin  staff  18436 May 27 15:18 .DS_Store
drwxr-xr-x@  3 admin  staff     96 May 28 18:06 .claude
drwxr-xr-x@  3 admin  staff     96 May 23 14:30 .deepseek
drwxr-xr-x@ 16 admin  staff    512 May 28 16:36 .git
-rw-r--r--@  1 admin  staff   1183 May 19 12:14 .gitignore
drwxr-xr-x@  7 admin  staff    224 May 19 14:09 .gradle
-rw-r--r--@  1 admin  staff   2778 May 19 12:14 CHANGELOG.md
-rw-r--r--@  1 admin  staff   2992 May 19 12:14 README.md
drwxr-xr-x@  3 admin  staff     96 May 19 14:09 build
-rw-r--r--@  1 admin  staff   6319 May 27 14:10 build.gradle.kts
drwxr-xr-x@  6 admin  staff    192 May 19 14:09 contract
drwxr-xr-x@  4 admin  staff    128 May 19 15:02 deliverables
drwxr-xr-x@  6 admin  staff    192 May 19 19:15 demos
-rw-r--r--@  1 admin  staff   9050 May 19 12:14 deploy_headscale.py
drwxr-xr-x@ 51 admin  staff   1632 May 28 17:57 docs
-rw-r--r--@  1 admin  staff   7023 May 19 12:14 fail_reason.md
drwxr-xr-x@  3 admin  staff     96 May 19 12:14 files
drwxr-xr-x@  4 admin  staff    128 May 19 12:14 gradle
-rw-r--r--@  1 admin  staff    293 May 19 12:14 gradle.properties
-rwxr-xr-x@  1 admin  staff   8714 May 19 12:14 gradlew
-rw-r--r--@  1 admin  staff   2798 May 19 12:14 gradlew.bat
drwxr-xr-x@  4 admin  staff    128 May 19 12:14 keystore
-rw-r--r--@  1 admin  staff  15403 May 19 12:14 kimi代码分析报告.md
-rwxr-xr-x@  1 admin  staff   9760 May 19 12:14 link_manager
-rw-r--r--@  1 admin  staff   4642 May 19 12:14 link_manager.c
drwxr-xr-x@  3 admin  staff     96 May 19 17:37 logs
-rw-r--r--@  1 admin  staff  66392 May 19 12:14 main_test.o
drwxr-xr-x@  7 admin  staff    224 May 19 12:14 mcu
drwxr-xr-x@  8 admin  staff    256 May 25 15:22 mcu_full_test
drwxr-xr-x@  4 admin  staff    128 May 19 12:14 mcu_structured_test
drwxr-xr-x@ 18 admin  staff    576 May 19 12:14 mcu_test_toolkit
-rw-r--r--@  1 admin  staff    749 May 19 12:14 parse_xlsx.py
-rw-r--r--@  1 admin  staff   3328 May 19 12:14 protocol.o
drwxr-xr-x@ 22 admin  staff    704 May 27 14:12 release
drwxr-xr-x@  5 admin  staff    160 May 27 14:12 release-template
drwxr-xr-x@  5 admin  staff    160 May 27 14:20 scripts
drwxr-xr-x@  7 admin  staff    224 May 19 14:13 sdk
drwxr-xr-x@  4 admin  staff    128 May 25 15:22 sdk-smoketest
-rw-r--r--@  1 admin  staff   5360 May 19 12:14 serial_io.o
drwxr-xr-x@  9 admin  staff    288 May 27 14:10 service
-rw-r--r--@  1 admin  staff    894 May 19 12:14 settings.gradle.kts
-rw-r--r--@  1 admin  staff   3896 May 19 12:14 step_test.md
drwxr-xr-x@ 39 admin  staff   1248 May 19 12:14 test_Serial
drwxr-xr-x@ 38 admin  staff   1216 May 23 14:30 test_Update
-rw-r--r--@  1 admin  staff   2332 May 19 12:14 test_serial.c


The user just wants to see the project files. Let me present this clearly.


项目根目录结构如下：

```
qsjnic/
├── .claude/              # Claude Code 配置
├── .deepseek/            # DeepSeek 配置
├── .gitignore
├── .gradle/
├── CHANGELOG.md
├── README.md
├── build/                # 构建输出
├── build.gradle.kts      # Gradle 顶级构建脚本
├── contract/             # AIDL 接口契约模块
├── deliverables/         # 交付物
├── demos/                # Demo 应用 (vehicle/radio/ota)
├── deploy_headscale.py
├── docs/                 # 文档 (51 项)
├── fail_reason.md
├── files/
├── gradle/ gradlew gradlew.bat gradle.properties
├── keystore/             # 签名密钥库
├── kimi代码分析报告.md    # Kimi 代码分析报告
├── link_manager / link_manager.c
├── logs/
├── mcu/                  # MCU 相关
├── mcu_full_test/        # MCU 全接口测试工具
├── mcu_structured_test/
├── mcu_test_toolkit/     # MCU 测试工具包
├── parse_xlsx.py
├── release/              # 发布产物 (22 项)
├── release-template/     # 发布模板
├── scripts/              # 脚本
├── sdk/                  # SDK 库模块
├── sdk-smoketest/
├── service/              # SystemService 模块
├── settings.gradle.kts
├── step_test.md
├── test_Serial/          # 串口测试 (39 项)
└── test_Update/          # 升级测试 (38 项)
```

这是一个 Android 多模块 Gradle 项目（MCU 通信中间件），主要模块：
- **service** — `QsMcuSystemService` 系统服务
- **sdk** — 对外 SDK 库
- **contract** — AIDL 接口定义
- **demos** — 三个 Demo 应用（vehicle / radio / ota）


在项目文件中查找有关与key的报告


The user is asking me to search the project files for reports related to "key". Let me search through the actual files on disk (not just git history) for reports about Key.


find . -type f \( -iname '*key*' -o -iname '*KEY*' \) 2>/dev/null | grep -v '.git/' | grep -v '.gradle/' | grep -v build/

Find all files with key/KEY in name


grep -rl -i "key.*报告\|key.*bug\|key.*issue\|key.*问题\|key.*验证\|key.*test\|key.*测试\|KEY.*报告" --include='*.md' --include='*.txt' . 2>/dev/null | grep -v '.git/' | grep -v '.gradle/'

Search markdown/txt files mentioning Key with report context


mcu_full_test/README_MCU_VENDOR_TEST.md
mcu_full_test/KEY_TEST_SOP.md
mcu_full_test/README.md
release/mcu_full_test_for_vendor/README.md
release/v1.0.0-beta5/README.md
release/v1.0.0-beta4/qsmw_diag_20260519_232403/07_log_service.txt
release/v1.0.0-beta6/README.md
release/v1.0.0-beta6/INTEGRATION_GUIDE.md
release/v1.0.0-beta1/RELEASE_NOTES_BETA1_TO_BETA2.md
release/v1.0.0-beta1/DEPLOYMENT_TEST_REPORT_20260511_v2.md
release/v1.0.0-beta1/DEPLOYMENT_TEST_REPORT_20260511.md
docs/测试分析报告_20260429.md
docs/steering_wheel_control_summary.md
docs/实施计划_客户交付_20260516.md
docs/public_strings.txt
docs/MCU_ARM_Reference/1.方控和车速自测.txt
.deepseek/instructions.md
mcu_test_toolkit/TEST_PLAN.md


grep -rli "key" --include='*.md' --include='*.txt' . 2>/dev/null | grep -v '.git/' | grep -v '.gradle/' | grep -v build/ | grep -v '.claude/'

Search all md/txt files mentioning key


fail_reason.md
mcu_full_test/KEY_TEST_SOP.md
mcu_full_test/README.md
mcu_full_test/README_MCU_VENDOR_TEST.md
release/API_REFERENCE.md
release/mcu_full_test_for_vendor/SHA256SUMS.txt
release/RELEASE_NOTES_BETA1_TO_BETA2.md
release/mcu_full_test_for_vendor/README.md
release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md
release/mcu_full_test_for_vendor/OPEN_ISSUES.md
release/mcu_full_test_for_vendor/protocol_reference/MCU_ARM_接口文档清单与明细_20260513.md
release/v1.0.0-beta2/QSJNIC_MCU_SDK_开发对接文档_v1.0.0-beta2.md
release/v1.0.0-beta5/RELEASE_INFO.txt
release/v1.0.0-beta5/API_REFERENCE.md
release/v1.0.0-beta5/README.md
release/v1.0.0-beta5/test_report_radio_20260524_153439/report.md
release/v1.0.0-beta5/test_report_radio_20260524_153448/report.md
release/v1.0.0-beta4/API_REFERENCE.md
release/v1.0.0-beta4/QsmwService_Startup_Signing_SELinux_Reference.md
release/v1.0.0-beta4/QsmwService_APK_System_Integration_Guide.md
release/v1.0.0-beta4/QsmwService_192.168.0.66_Boot_Autostart_Analysis.md
release/v1.0.0-beta4/QSJNIC_MCU_SDK_开发对接文档_v1.0.0-beta4.md
release/v1.0.0-beta4/MCU_INTERFACE_REFERENCE.md
release/v1.0.0-beta4/qsmw_diag_20260519_232403/05_manual_start.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/07_log_service.txt
release/v1.0.0-beta4/qsmw_diag_20260519_232403/02_package_dump.txt
release/v1.0.0-beta3/README.md
release/v1.0.0-beta3/QSJNIC_MCU_SDK_开发对接文档_v1.0.0-beta3.md
release/v1.0.0-beta4/qsmw_diag_20260519_232403/06_serial_node.txt
release/v1.0.0-beta3/VALIDATION_REPORT.md
release/v1.0.0-beta3/RELEASE_INFO.txt
release/v1.0.0-beta3/SystemService_Integration_Guide.md
release/v1.0.0-beta3/API_REFERENCE.md
release/v1.0.0-beta3/MCU_INTERFACE_REFERENCE.md
release/v1.0.0-beta3/RELEASE_NOTES_BETA2_TO_BETA3.md
release/v1.0.0-beta6/INTERFACE_CONSISTENCY_REPORT.md
release/v1.0.0-beta6/RELEASE_INFO.txt
release/v1.0.0-beta6/README.md
release/v1.0.0-beta6/API_REFERENCE.md
release/v1.0.0-beta6/INTEGRATION_GUIDE.md
release/v1.0.0-beta1/QSJNIC_MCU_SDK_v1.0.0-beta1_测试计划.md
release/v1.0.0-beta1/DEPLOYMENT_TEST_REPORT_20260511_v2.md
release/v1.0.0-beta1/SystemService_Architecture_and_Interface_Design.md
release/v1.0.0-beta1/INTERFACE_CONSISTENCY_CHECK_REPORT.md
release/v1.0.0-beta1/QSJNIC_MCU_SDK_v1.0.0-beta1_测试报告.md
release/v1.0.0-beta1/README.md
release/v1.0.0-beta1/RELEASE_NOTES_BETA1_TO_BETA2.md
release/v1.0.0-beta1/MCU_INTERFACE_REFERENCE.md
release/v1.0.0-beta1/DEPLOYMENT_TEST_REPORT_20260511.md
release/v1.0.0-beta2-internal/INTERFACE_CONSISTENCY_CHECK_REPORT.md
release/v1.0.0-beta1/QSJNIC_MCU_SDK_开发对接文档_v1.0.0-beta1.md
docs/steering_wheel_control_summary.md
release/v1.0.0-beta2-internal/SystemService_Architecture_and_Interface_Design.md
docs/测试分析报告_20260429.md
docs/SystemService层架构符合性分析报告_20260516.md
docs/实施计划_客户交付_20260516.md
docs/public_strings.txt
docs/SystemService架构与接口设计.md
docs/架构评估与改进方案_20260516.md
docs/Beta4_发布实施计划_20260518.md
docs/编程实施计划_完整项目_20260516.md
docs/deliverable_mcu_package/test_report_full_77_20260506.md
docs/plan/service_77_interfaces_20260510.md
docs/plan/full_77_interface_demo_test_report_20260511.md
docs/plan/phase1_phase2_test_report_20260511.md
docs/plan/77_interface_coverage_proof.md
docs/MCU_ARM_Reference/1.方控和车速自测.txt
docs/MCU_ARM_Reference/20260513/MCU_ARM_接口文档清单与明细_20260513.md
test_Update/test_report.txt
test_Update/interface_class.md
test_Update/test_report.md
test_Update/interface_test.md
test_Update/qsjnic.md
release-template/API_REFERENCE.md
test_Serial/dry_run_78_report.md
files/interface.md
mcu_test_toolkit/TEST_PLAN.md
service/PACKAGING.md
.deepseek/instructions.md


The user is asking for reports specifically about "key" in the project files. Let me now read the most relevant files - the ones that are specifically Key-related reports. Let me check the key files:

1. `docs/MCU_ARM_Reference/1.方控和车速自测.txt` - This is about steering wheel control (方控) which is Key-related
2. `docs/steering_wheel_control_summary.md` - Steering wheel control summary
3. `mcu_full_test/KEY_TEST_SOP.md` - Key test SOP
4. `release/mcu_full_test_for_vendor/OPEN_ISSUES.md` - Key issues section
5. `release/mcu_full_test_for_vendor/REPORT_TEMPLATE.md` - Report template
6. Various test reports that mention key

Let me read the most relevant ones.


1	MCU版本:PAJERO69XZA0120018
2	shell工具:https://www.xshell.com/zh/xshell/
3	1.方控自测(前提条件:Android与MCU必须建链成功)
4	[1].实物测试
5		接线: 将方控板KEY线与尾线SWC_L相接,另外一根线接GND
6		测试: 每次按下方控,会将对应key值与状态发给android端,详细MCU打印日志如下:
7
8		I(0000025683) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[TRIGGER]
9		[ARM_CORE,write data:] ff,aa,00,0b,08,06,02,01,04,01,de
10		I(0000026043) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[IDLE]
11		[ARM_CORE,write data:] ff,aa,00,0b,09,06,02,01,04,00,de
12
13		I(0000115553) KEYMGR,keymgr_key_trigger_handle:key_type[0E] state[TRIGGER]
14		[ARM_CORE,write data:] ff,aa,00,0b,0c,06,02,01,0e,01,d0
15		I(0000116233) KEYMGR,keymgr_key_trigger_handle:key_type[0E] state[IDLE]
16		[ARM_CORE,write data:] ff,aa,00,0b,0d,06,02,01,0e,00,d0
17
18		I(0000178883) KEYMGR,keymgr_key_trigger_handle:key_type[0F] state[TRIGGER]
19		[ARM_CORE,write data:] ff,aa,00,0b,0e,06,02,01,0f,01,cd
20		I(0000179033) KEYMGR,keymgr_key_trigger_handle:key_type[0F] state[IDLE]
21		[ARM_CORE,write data:] ff,aa,00,0b,0f,06,02,01,0f,00,cd
22
23
24		I(0000223153) KEYMGR,keymgr_key_trigger_handle:key_type[09] state[TRIGGER]
25		[ARM_CORE,write data:] ff,aa,00,0b,10,06,02,01,09,01,d1
26		I(0000223493) KEYMGR,keymgr_key_trigger_handle:key_type[09] state[IDLE]
27		[ARM_CORE,write data:] ff,aa,00,0b,11,06,02,01,09,00,d1
28
29
30		I(0000266683) KEYMGR,keymgr_key_trigger_handle:key_type[08] state[TRIGGER]
31		[ARM_CORE,write data:] ff,aa,00,0b,12,06,02,01,08,01,d0
32		I(0000266973) KEYMGR,keymgr_key_trigger_handle:key_type[08] state[IDLE]
33		[ARM_CORE,write data:] ff,aa,00,0b,13,06,02,01,08,00,d0
34
35
36		I(0000302853) KEYMGR,keymgr_key_trigger_handle:key_type[03] state[TRIGGER]
37		[ARM_CORE,write data:] ff,aa,00,0b,14,06,02,01,03,01,d3
38		I(0000303023) KEYMGR,keymgr_key_trigger_handle:key_type[03] state[IDLE]
39		[ARM_CORE,write data:] ff,aa,00,0b,15,06,02,01,03,00,d3
40
41
42		I(0000332953) KEYMGR,keymgr_key_trigger_handle:key_type[18] state[TRIGGER]
43		[ARM_CORE,write data:] ff,aa,00,0b,16,06,02,01,18,01,bc
44		I(0000333113) KEYMGR,keymgr_key_trigger_handle:key_type[18] state[IDLE]
45		[ARM_CORE,write data:] ff,aa,00,0b,17,06,02,01,18,00,bc
46
47
48		I(0000357333) KEYMGR,keymgr_key_trigger_handle:key_type[19] state[TRIGGER]
49		[ARM_CORE,write data:] ff,aa,00,0b,18,06,02,01,19,01,b9
50		I(0000357473) KEYMGR,keymgr_key_trigger_handle:key_type[19] state[IDLE]
51		[ARM_CORE,write data:] ff,aa,00,0b,19,06,02,01,19,00,b9
52
53
54		I(0000380363) KEYMGR,keymgr_key_trigger_handle:key_type[25] state[TRIGGER]
55		[ARM_CORE,write data:] ff,aa,00,0b,1a,06,02,01,25,01,ab
56		I(0000380523) KEYMGR,keymgr_key_trigger_handle:key_type[25] state[IDLE]
57		[ARM_CORE,write data:] ff,aa,00,0b,1b,06,02,01,25,00,ab
58
59
60	[2]. 模拟测试:
61		接上MCU打印，shell命令行输入 KeyTest + 测试项 + 按键值 + 按键状态
62		如下是模拟按键挂电话按下和弹起的过程:
63		KeyTest命令识别字符串,1表示第1个测试项,0x19表示按键值KEY_REJECT,0x01表示按键按下/0x00表示按键弹起
64
65		xiexw:/$ KeyTest 1 0x19 0x01
66		I(0000490647) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x01
67		[ARM_CORE,write data:] ff,aa,00,0b,1c,06,02,01,19,01,b5
68
69		xiexw:/$ KeyTest 1 0x19 0x00
70		I(0000535107) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x00
71		[ARM_CORE,write data:] ff,aa,00,0b,1d,06,02,01,19,00,b5
72
73	[3]. 帕杰罗方控按键值如下:
74	typedef enum
75	{
76	    EN_KEYMGR_SWC_TYPE_IDLE             = 0x00,//空闲
77	    EN_KEYMGR_SWC_TYPE_VOLUME_DOWN      = 0x08,//音量减
78	    EN_KEYMGR_SWC_TYPE_VOLUME_UP        = 0x09,//音量加
79	    EN_KEYMGR_SWC_TYPE_NEXT             = 0x0F,//下一曲
80	    EN_KEYMGR_SWC_TYPE_PREV             = 0x0E,//上一曲
81	    EN_KEYMGR_SWC_TYPE_MUSIC            = 0x04,//音乐
82	    EN_KEYMGR_SWC_TYPE_SPEECH           = 0x03,//语音
83	    EN_KEYMGR_SWC_TYPE_ANSWER           = 0x18,//接听
84	    EN_KEYMGR_SWC_TYPE_REJECT           = 0x19,//挂断
85	    EN_KEYMGR_SWC_TYPE_CAMERA           = 0x25,//摄像头
86	} EN_KEYMGR_SWC_TYPE;
87
88	[4]. KEY_A2M_KEY暂时不用实现
89
90
91
92	2. 车速上报模拟测试:
93		接上MCU打印，shell命令行输入 PublicDebug + 23 + 车速 + 百分比,如下是MCU端打印:
94		xiexw:/$ PublicDebug 23 60 100
95		I(0001000191) PUBLIC_MGR,PublicDebug:Set car speed: 60, ratio: 100
96		Return: 0, 0x00000000
97

MCU版本:PAJERO69XZA0120018
shell工具:https://www.xshell.com/zh/xshell/
1.方控自测(前提条件:Android与MCU必须建链成功)
[1].实物测试
	接线: 将方控板KEY线与尾线SWC_L相接,另外一根线接GND
	测试: 每次按下方控,会将对应key值与状态发给android端,详细MCU打印日志如下:

	I(0000025683) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,08,06,02,01,04,01,de
	I(0000026043) KEYMGR,keymgr_key_trigger_handle:key_type[04] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,09,06,02,01,04,00,de

	I(0000115553) KEYMGR,keymgr_key_trigger_handle:key_type[0E] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,0c,06,02,01,0e,01,d0
	I(0000116233) KEYMGR,keymgr_key_trigger_handle:key_type[0E] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,0d,06,02,01,0e,00,d0

	I(0000178883) KEYMGR,keymgr_key_trigger_handle:key_type[0F] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,0e,06,02,01,0f,01,cd
	I(0000179033) KEYMGR,keymgr_key_trigger_handle:key_type[0F] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,0f,06,02,01,0f,00,cd

	I(0000223153) KEYMGR,keymgr_key_trigger_handle:key_type[09] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,10,06,02,01,09,01,d1
	I(0000223493) KEYMGR,keymgr_key_trigger_handle:key_type[09] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,11,06,02,01,09,00,d1

	I(0000266683) KEYMGR,keymgr_key_trigger_handle:key_type[08] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,12,06,02,01,08,01,d0
	I(0000266973) KEYMGR,keymgr_key_trigger_handle:key_type[08] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,13,06,02,01,08,00,d0

	I(0000302853) KEYMGR,keymgr_key_trigger_handle:key_type[03] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,14,06,02,01,03,01,d3
	I(0000303023) KEYMGR,keymgr_key_trigger_handle:key_type[03] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,15,06,02,01,03,00,d3

	I(0000332953) KEYMGR,keymgr_key_trigger_handle:key_type[18] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,16,06,02,01,18,01,bc
	I(0000333113) KEYMGR,keymgr_key_trigger_handle:key_type[18] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,17,06,02,01,18,00,bc

	I(0000357333) KEYMGR,keymgr_key_trigger_handle:key_type[19] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,18,06,02,01,19,01,b9
	I(0000357473) KEYMGR,keymgr_key_trigger_handle:key_type[19] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,19,06,02,01,19,00,b9

	I(0000380363) KEYMGR,keymgr_key_trigger_handle:key_type[25] state[TRIGGER]
	[ARM_CORE,write data:] ff,aa,00,0b,1a,06,02,01,25,01,ab
	I(0000380523) KEYMGR,keymgr_key_trigger_handle:key_type[25] state[IDLE]
	[ARM_CORE,write data:] ff,aa,00,0b,1b,06,02,01,25,00,ab

[2]. 模拟测试:
	接上MCU打印，shell命令行输入 KeyTest + 测试项 + 按键值 + 按键状态
	如下是模拟按键挂电话按下和弹起的过程:
	KeyTest命令识别字符串,1表示第1个测试项,0x19表示按键值KEY_REJECT,0x01表示按键按下/0x00表示按键弹起

	xiexw:/$ KeyTest 1 0x19 0x01
	I(0000490647) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x01
	[ARM_CORE,write data:] ff,aa,00,0b,1c,06,02,01,19,01,b5

	xiexw:/$ KeyTest 1 0x19 0x00
	I(0000535107) KEYMGR,KeyTest:KeyTest mode:1 key:0x19 value:0x00
	[ARM_CORE,write data:] ff,aa,00,0b,1d,06,02,01,19,00,b5

[3]. 帕杰罗方控按键值如下:
typedef enum
{
    EN_KEYMGR_SWC_TYPE_IDLE             = 0x00,//空闲
    EN_KEYMGR_SWC_TYPE_VOLUME_DOWN      = 0x08,//音量减
    EN_KEYMGR_SWC_TYPE_VOLUME_UP        = 0x09,//音量加
    EN_KEYMGR_SWC_TYPE_NEXT             = 0x0F,//下一曲
    EN_KEYMGR_SWC_TYPE_PREV             = 0x0E,//上一曲
    EN_KEYMGR_SWC_TYPE_MUSIC            = 0x04,//音乐
    EN_KEYMGR_SWC_TYPE_SPEECH           = 0x03,//语音
    EN_KEYMGR_SWC_TYPE_ANSWER           = 0x18,//接听
    EN_KEYMGR_SWC_TYPE_REJECT           = 0x19,//挂断
    EN_KEYMGR_SWC_TYPE_CAMERA           = 0x25,//摄像头
} EN_KEYMGR_SWC_TYPE;

[4]. KEY_A2M_KEY暂时不用实现

2. 车速上报模拟测试:
	接上MCU打印，shell命令行输入 PublicDebug + 23 + 车速 + 百分比,如下是MCU端打印:
	xiexw:/$ PublicDebug 23 60 100
	I(0001000191) PUBLIC_MGR,PublicDebug:Set car speed: 60, ratio: 100
	Return: 0, 0x00000000


1	# 方控（方向盘按键控制）信息汇总
2
3	## 一、概述
4
5	本项目中的"方控"涉及两套协议：
6	1. **Public 域（ModuleType=0x01）的 0x06 KEY_PWR_STATUS** —— Java Service 已实现
7	2. **Key 域（ModuleType=0x02）的按键协议** —— MCU 协议文档有定义，但 Java Service **尚未实现**
8
9	---
10
11	## 二、Public 域按键接口（已实现）
12
13	### 2.1 M2A（MCU → Android）
14
15	| 命令字 | 名称 | 方向 | 说明 |
16	|--------|------|------|------|
17	| `0x06` | `PUBLIC_M2A_KEY_PWR_STATUS` | M→A | MCU 上报按键电源状态 |
18
19	**Payload 格式**：1 字节 rawByte（具体含义由 MCU 定义）
20
21	**解码器**：`Decoders.parseKeyEvent(byte[] body) → int`
22
23	### 2.2 A2M（Android → MCU）
24
25	| 命令字 | 名称 | 方向 | 说明 |
26	|--------|------|------|------|
27	| `0x8B` | `PUBLIC_A2M_SET_KEY_BACKLIGHT_DUTY_CYCLE` | A→M | 设置按键背光百分比（0~100） |
28	| `0x8C` | `PUBLIC_A2M_SET_SUB_MUTE_ON_OFF` | A→M | 设置重低音静音开关 |
29	| `0x8D` | `PUBLIC_A2M_KEY_PWR_STATUS` | A→M | 发送按键电源状态 |
30
31	### 2.3 SDK API（Java 层）
32
33	**回调接口**：
34	```java
35	// AIDL: IMcuVehicleListener
36	void onKeyEvent(int rawByte);
37
38	// SDK: VehicleListener
39	default void onKeyEvent(int rawByte) {}
40	```
41
42	**控制方法（McuVehicleClient）**：
43	```java
44	int setKeyBacklightDutyCycle(int dutyPercent);  // 0~100
45	int setSubMute(boolean on);
46	int setKeyPwrStatus(int status);
47	```
48
49	### 2.4 Service 处理流程
50
51	```
52	MCU 发送帧
53	  └── FrameType=0x06 (DATA)
54	      └── ModuleType=0x01 (Public)
55	          └── Cmd=0x06 (KEY_EVENT)
56	              └── FrameRouter.dispatch()
57	                  └── VehicleFeature.onFrame()
58	                      └── Decoders.parseKeyEvent(body)
59	                          └── broadcastKeyEvent(rawByte)
60	                              └── IMcuVehicleListener.onKeyEvent(rawByte)
61	                                  └── App: VehicleListener.onKeyEvent()
62	```
63
64	**注意**：`VehicleSnapshot` 中**不包含按键状态**，按键事件只通过回调实时分发，不做持久化。
65
66	---
67
68	## 三、Key 域按键协议（协议有定义，Java Service 未实现）
69
70	### 3.1 协议定义（MCU 侧 / mcu_full_test.c）
71
72	**ModuleType = 0x02（Key 域）**
73
74	| 方向 | 命令字 | 名称 | 说明 |
75	|------|--------|------|------|
76	| M→A | `0x01` | `KEY_M2A_KEY` | MCU 上报具体按键事件 |
77	| A→M | `0x81` | `KEY_A2M_KEY` | ARM 发送按键指令给 MCU |
78
79	### 3.2 键值定义（Key Value）
80
81	| 值 | 名称 | 说明 |
82	|----|------|------|
83	| `0x00` | `KEY_VALUE_NONE` | 无按键 |
84	| `0x01` | `KEY_VALUE_MODE` | MODE 键 |
85	| `0x02` | `KEY_VALUE_MUTE` | MUTE 键 |
86	| `0x03` | `KEY_VALUE_WORKMODE` | WORKMODE 键 |
87	| `0x04` | `KEY_VALUE_CALL` | CALL 键 |
88	| `0x05` | `KEY_VALUE_VOICE_ASSISTANT` | 语音助手键 |
89	| `0x06` | `KEY_VALUE_HOME` | HOME 键 |
90	| `0x07` | `KEY_VALUE_OK` | OK 键 |
91	| `0x08` | `KEY_VALUE_CHANNEL_UP` | 频道+/上一曲 |
92	| `0x09` | `KEY_VALUE_CHANNEL_DOWN` | 频道-/下一曲 |
93	| `0x0A` | `KEY_VALUE_VOLUME_UP` | 音量+ |
94	| `0x0B` | `KEY_VALUE_VOLUME_DOWN` | 音量- |
95
96	### 3.3 按键状态定义（Key Status）
97
98	| 值 | 名称 | 说明 |
99	|----|------|------|
100	| `0x00` | `KEY_STATUS_RELEASE` | 按键释放 |
101	| `0x01` | `KEY_STATUS_SHORT_PRESS` | 短按 |
102	| `0x02` | `KEY_STATUS_STUCK` | 长按/卡住 |
103	| `0x03` | `KEY_STATUS_ENCODER_LEFT` | 编码器左旋 |
104	| `0x04` | `KEY_STATUS_ENCODER_RIGHT` | 编码器右旋 |
105
106	### 3.4 Key 域 Payload 格式
107
108	```
109	[ModuleType(1B)][Cmd(1B)][KeyValue(1B)][KeyStatus(1B)]
110	```
111
112	例如：MODE 短按
113	```
114	02 01 01 01   // ModuleType=Key, Cmd=KEY_M2A_KEY, Value=MODE, Status=SHORT_PRESS
115	```
116
117	### 3.5 mcu_full_test 测试用例
118
119	Key 域 A2M 有 **13 组测试用例**：
120
121	| 用例名 | KeyValue | KeyStatus | 说明 |
122	|--------|----------|-----------|------|
123	| `key.none.release` | NONE | RELEASE | 基准测试 |
124	| `key.mode.short` | MODE | SHORT_PRESS | MODE 短按 |
125	| `key.mute.short` | MUTE | SHORT_PRESS | MUTE 短按 |
126	| `key.workmode.short` | WORKMODE | SHORT_PRESS | WORKMODE 短按 |
127	| `key.call.short` | CALL | SHORT_PRESS | CALL 短按 |
128	| `key.voice.short` | VOICE_ASSISTANT | SHORT_PRESS | 语音助手短按 |
129	| `key.home.short` | HOME | SHORT_PRESS | HOME 短按 |
130	| `key.ok.short` | OK | SHORT_PRESS | OK 短按 |
131	| `key.channel_up.short` | CHANNEL_UP | SHORT_PRESS | 频道+短按 |
132	| `key.channel_down.short` | CHANNEL_DOWN | SHORT_PRESS | 频道-短按 |
133	| `key.volume_up.short` | VOLUME_UP | SHORT_PRESS | 音量+短按 |
134	| `key.volume_down.short` | VOLUME_DOWN | SHORT_PRESS | 音量-短按 |
135
136	另有 13 组 M2A 期望覆盖（需物理按键触发）。
137
138	---
139
140	## 四、Java Service 未实现 Key 域的原因分析
141
142	### 4.1 当前 MsgType 定义
143
144	```java
145	// MsgType.java
146	public static final int PUBLIC = 0x01;
147	public static final int RADIO  = 0x05;
148	public static final int UPDATE = 0x07;
149	// ❌ 缺少 KEY = 0x02
150	```
151
152	### 4.2 FrameRouter 只处理三个域
153
154	```java
155	// FrameRouter.java
156	switch (msgType) {
157	    case MSG_TYPE_PUBLIC:  // 0x01
158	    case MSG_TYPE_RADIO:   // 0x05
159	    case MSG_TYPE_UPDATE:  // 0x07
160	    // ❌ 没有 MSG_TYPE_KEY = 0x02
161	}
162	```
163
164	### 4.3 没有 KeyFeature 类
165
166	`service/src/main/java/com/qsjnic/mcu/service/feature/` 目录下只有：
167	- `VehicleFeature.java`
168	- `RadioFeature.java`
169	- `UpgradeFeature.java`
170
171	**缺少 `KeyFeature.java`**。
172
173	---
174
175	## 五、两套协议的关系
176
177	| 维度 | Public 0x06 KEY_PWR_STATUS | Key 域 0x01/0x81 |
178	|------|---------------------------|------------------|
179	| **ModuleType** | 0x01 (Public) | 0x02 (Key) |
180	| **方向** | M→A 单向上报 | M→A + A→M 双向 |
181	| **Payload** | 1 byte (rawByte) | 2 bytes (KeyValue + KeyStatus) |
182	| **键值细化** | ❌ 无，只有一个 rawByte | ✅ 有 11 个具体键值 + 5 种状态 |
183	| **Java Service** | ✅ 已实现 | ❌ 未实现 |
184	| **使用场景** | 简单按键电源状态上报 | 完整方向盘按键控制 |
185
186	**推测**：
187	- Public 0x06 可能是早期简化版按键接口
188	- Key 域 0x02 是完整版方控协议，但 Java 端尚未对接
189
190	---
191
192	## 六、相关文件位置
193
194	| 文件 | 说明 |
195	|------|------|
196	| `contract/src/main/java/com/qsjnic/mcu/domain/Cmds.java` | 命令字常量定义 |
197	| `contract/src/main/java/com/qsjnic/mcu/domain/Decoders.java` | 帧解码器（含 parseKeyEvent） |
198	| `contract/src/main/java/com/qsjnic/mcu/domain/MsgType.java` | 模块类型常量 |
199	| `contract/src/main/aidl/com/qsjnic/mcu/contract/IMcuVehicleListener.aidl` | AIDL 回调接口 |
200	| `sdk/src/main/java/com/qsjnic/mcu/sdk/VehicleListener.java` | SDK 回调接口 |
201	| `sdk/src/main/java/com/qsjnic/mcu/sdk/McuVehicleClient.java` | SDK 控制 Facade |
202	| `service/src/main/java/com/qsjnic/mcu/service/feature/VehicleFeature.java` | Service 按键事件处理 |
203	| `release/mcu_full_test_for_vendor/src/mcu_full_test.c` | MCU 侧完整协议实现（含 Key 域） |
204	| `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` | Key 域协议 Excel 文档 |
205	| `release/mcu_full_test_for_vendor/protocol_reference/MCU_ARM_接口文档清单与明细_20260513.md` | 接口清单文档 |
206
207	---
208
209	## 七、如果需要实现 Key 域
210
211	需补充以下代码：
212
213	1. **contract 层**：
214	   - `MsgType.java` 增加 `KEY = 0x02`
215	   - `Cmds.java` 增加 `Key` 类（`KEY_M2A_KEY=0x01`, `KEY_A2M_KEY=0x81`）
216
217	2. **service 层**：
218	   - 新增 `KeyFeature.java`（类似 VehicleFeature/RadioFeature）
219	   - `FrameRouter.java` 增加 `MSG_TYPE_KEY` 分支路由
220	   - 新增 `IMcuKeyListener.aidl` 和 `KeyListener.java`
221
222	3. **SDK 层**：
223	   - 新增 `McuKeyClient.java`
224	   - `McuClient` 暴露 `key()` 方法
225

# 方控（方向盘按键控制）信息汇总

## 一、概述

本项目中的"方控"涉及两套协议：
1. **Public 域（ModuleType=0x01）的 0x06 KEY_PWR_STATUS** —— Java Service 已实现
2. **Key 域（ModuleType=0x02）的按键协议** —— MCU 协议文档有定义，但 Java Service **尚未实现**

---

## 二、Public 域按键接口（已实现）

### 2.1 M2A（MCU → Android）

| 命令字 | 名称 | 方向 | 说明 |
|--------|------|------|------|
| `0x06` | `PUBLIC_M2A_KEY_PWR_STATUS` | M→A | MCU 上报按键电源状态 |

**Payload 格式**：1 字节 rawByte（具体含义由 MCU 定义）

**解码器**：`Decoders.parseKeyEvent(byte[] body) → int`

### 2.2 A2M（Android → MCU）

| 命令字 | 名称 | 方向 | 说明 |
|--------|------|------|------|
| `0x8B` | `PUBLIC_A2M_SET_KEY_BACKLIGHT_DUTY_CYCLE` | A→M | 设置按键背光百分比（0~100） |
| `0x8C` | `PUBLIC_A2M_SET_SUB_MUTE_ON_OFF` | A→M | 设置重低音静音开关 |
| `0x8D` | `PUBLIC_A2M_KEY_PWR_STATUS` | A→M | 发送按键电源状态 |

### 2.3 SDK API（Java 层）

**回调接口**：
```java
// AIDL: IMcuVehicleListener
void onKeyEvent(int rawByte);

// SDK: VehicleListener
default void onKeyEvent(int rawByte) {}
```

**控制方法（McuVehicleClient）**：
```java
int setKeyBacklightDutyCycle(int dutyPercent);  // 0~100
int setSubMute(boolean on);
int setKeyPwrStatus(int status);
```

### 2.4 Service 处理流程

```
MCU 发送帧
  └── FrameType=0x06 (DATA)
      └── ModuleType=0x01 (Public)
          └── Cmd=0x06 (KEY_EVENT)
              └── FrameRouter.dispatch()
                  └── VehicleFeature.onFrame()
                      └── Decoders.parseKeyEvent(body)
                          └── broadcastKeyEvent(rawByte)
                              └── IMcuVehicleListener.onKeyEvent(rawByte)
                                  └── App: VehicleListener.onKeyEvent()
```

**注意**：`VehicleSnapshot` 中**不包含按键状态**，按键事件只通过回调实时分发，不做持久化。

---

## 三、Key 域按键协议（协议有定义，Java Service 未实现）

### 3.1 协议定义（MCU 侧 / mcu_full_test.c）

**ModuleType = 0x02（Key 域）**

| 方向 | 命令字 | 名称 | 说明 |
|------|--------|------|------|
| M→A | `0x01` | `KEY_M2A_KEY` | MCU 上报具体按键事件 |
| A→M | `0x81` | `KEY_A2M_KEY` | ARM 发送按键指令给 MCU |

### 3.2 键值定义（Key Value）

| 值 | 名称 | 说明 |
|----|------|------|
| `0x00` | `KEY_VALUE_NONE` | 无按键 |
| `0x01` | `KEY_VALUE_MODE` | MODE 键 |
| `0x02` | `KEY_VALUE_MUTE` | MUTE 键 |
| `0x03` | `KEY_VALUE_WORKMODE` | WORKMODE 键 |
| `0x04` | `KEY_VALUE_CALL` | CALL 键 |
| `0x05` | `KEY_VALUE_VOICE_ASSISTANT` | 语音助手键 |
| `0x06` | `KEY_VALUE_HOME` | HOME 键 |
| `0x07` | `KEY_VALUE_OK` | OK 键 |
| `0x08` | `KEY_VALUE_CHANNEL_UP` | 频道+/上一曲 |
| `0x09` | `KEY_VALUE_CHANNEL_DOWN` | 频道-/下一曲 |
| `0x0A` | `KEY_VALUE_VOLUME_UP` | 音量+ |
| `0x0B` | `KEY_VALUE_VOLUME_DOWN` | 音量- |

### 3.3 按键状态定义（Key Status）

| 值 | 名称 | 说明 |
|----|------|------|
| `0x00` | `KEY_STATUS_RELEASE` | 按键释放 |
| `0x01` | `KEY_STATUS_SHORT_PRESS` | 短按 |
| `0x02` | `KEY_STATUS_STUCK` | 长按/卡住 |
| `0x03` | `KEY_STATUS_ENCODER_LEFT` | 编码器左旋 |
| `0x04` | `KEY_STATUS_ENCODER_RIGHT` | 编码器右旋 |

### 3.4 Key 域 Payload 格式

```
[ModuleType(1B)][Cmd(1B)][KeyValue(1B)][KeyStatus(1B)]
```

例如：MODE 短按
```
02 01 01 01   // ModuleType=Key, Cmd=KEY_M2A_KEY, Value=MODE, Status=SHORT_PRESS
```

### 3.5 mcu_full_test 测试用例

Key 域 A2M 有 **13 组测试用例**：

| 用例名 | KeyValue | KeyStatus | 说明 |
|--------|----------|-----------|------|
| `key.none.release` | NONE | RELEASE | 基准测试 |
| `key.mode.short` | MODE | SHORT_PRESS | MODE 短按 |
| `key.mute.short` | MUTE | SHORT_PRESS | MUTE 短按 |
| `key.workmode.short` | WORKMODE | SHORT_PRESS | WORKMODE 短按 |
| `key.call.short` | CALL | SHORT_PRESS | CALL 短按 |
| `key.voice.short` | VOICE_ASSISTANT | SHORT_PRESS | 语音助手短按 |
| `key.home.short` | HOME | SHORT_PRESS | HOME 短按 |
| `key.ok.short` | OK | SHORT_PRESS | OK 短按 |
| `key.channel_up.short` | CHANNEL_UP | SHORT_PRESS | 频道+短按 |
| `key.channel_down.short` | CHANNEL_DOWN | SHORT_PRESS | 频道-短按 |
| `key.volume_up.short` | VOLUME_UP | SHORT_PRESS | 音量+短按 |
| `key.volume_down.short` | VOLUME_DOWN | SHORT_PRESS | 音量-短按 |

另有 13 组 M2A 期望覆盖（需物理按键触发）。

---

## 四、Java Service 未实现 Key 域的原因分析

### 4.1 当前 MsgType 定义

```java
// MsgType.java
public static final int PUBLIC = 0x01;
public static final int RADIO  = 0x05;
public static final int UPDATE = 0x07;
// ❌ 缺少 KEY = 0x02
```

### 4.2 FrameRouter 只处理三个域

```java
// FrameRouter.java
switch (msgType) {
    case MSG_TYPE_PUBLIC:  // 0x01
    case MSG_TYPE_RADIO:   // 0x05
    case MSG_TYPE_UPDATE:  // 0x07
    // ❌ 没有 MSG_TYPE_KEY = 0x02
}
```

### 4.3 没有 KeyFeature 类

`service/src/main/java/com/qsjnic/mcu/service/feature/` 目录下只有：
- `VehicleFeature.java`
- `RadioFeature.java`
- `UpgradeFeature.java`

**缺少 `KeyFeature.java`**。

---

## 五、两套协议的关系

| 维度 | Public 0x06 KEY_PWR_STATUS | Key 域 0x01/0x81 |
|------|---------------------------|------------------|
| **ModuleType** | 0x01 (Public) | 0x02 (Key) |
| **方向** | M→A 单向上报 | M→A + A→M 双向 |
| **Payload** | 1 byte (rawByte) | 2 bytes (KeyValue + KeyStatus) |
| **键值细化** | ❌ 无，只有一个 rawByte | ✅ 有 11 个具体键值 + 5 种状态 |
| **Java Service** | ✅ 已实现 | ❌ 未实现 |
| **使用场景** | 简单按键电源状态上报 | 完整方向盘按键控制 |

**推测**：
- Public 0x06 可能是早期简化版按键接口
- Key 域 0x02 是完整版方控协议，但 Java 端尚未对接

---

## 六、相关文件位置

| 文件 | 说明 |
|------|------|
| `contract/src/main/java/com/qsjnic/mcu/domain/Cmds.java` | 命令字常量定义 |
| `contract/src/main/java/com/qsjnic/mcu/domain/Decoders.java` | 帧解码器（含 parseKeyEvent） |
| `contract/src/main/java/com/qsjnic/mcu/domain/MsgType.java` | 模块类型常量 |
| `contract/src/main/aidl/com/qsjnic/mcu/contract/IMcuVehicleListener.aidl` | AIDL 回调接口 |
| `sdk/src/main/java/com/qsjnic/mcu/sdk/VehicleListener.java` | SDK 回调接口 |
| `sdk/src/main/java/com/qsjnic/mcu/sdk/McuVehicleClient.java` | SDK 控制 Facade |
| `service/src/main/java/com/qsjnic/mcu/service/feature/VehicleFeature.java` | Service 按键事件处理 |
| `release/mcu_full_test_for_vendor/src/mcu_full_test.c` | MCU 侧完整协议实现（含 Key 域） |
| `release/mcu_full_test_for_vendor/protocol_reference/Key.xlsx` | Key 域协议 Excel 文档 |
| `release/mcu_full_test_for_vendor/protocol_reference/MCU_ARM_接口文档清单与明细_20260513.md` | 接口清单文档 |

---

## 七、如果需要实现 Key 域

需补充以下代码：

1. **contract 层**：
   - `MsgType.java` 增加 `KEY = 0x02`
   - `Cmds.java` 增加 `Key` 类（`KEY_M2A_KEY=0x01`, `KEY_A2M_KEY=0x81`）

2. **service 层**：
   - 新增 `KeyFeature.java`（类似 VehicleFeature/RadioFeature）
   - `FrameRouter.java` 增加 `MSG_TYPE_KEY` 分支路由
   - 新增 `IMcuKeyListener.aidl` 和 `KeyListener.java`

3. **SDK 层**：
   - 新增 `McuKeyClient.java`
   - `McuClient` 暴露 `key()` 方法


1	# Key.xlsx Protocol Test SOP
2
3	## 1. Purpose
4
5	Validate all Key protocol interfaces defined in:
6
7	`docs/MCU_ARM_Reference/Key.xlsx`
8
9	Scope:
10
11	- A2M: `KEY_A2M_KEY`, `MT_KEY=0x02`, `cmd=0x81`
12	- M2A: `KEY_M2A_KEY`, `MT_KEY=0x02`, `cmd=0x01`
13	- Parameters: `P0=KeyValue`, `P1=KeyStatus`
14
15	## 2. Test Device
16
17	Default target:
18
19	```bash
20	adb connect 192.168.0.66
21	adb -s 192.168.0.66:5555 shell date
22	```
23
24	If the device date is wrong, set it before testing:
25
26	```bash
27	adb -s 192.168.0.66:5555 shell date MMDDhhmmYYYY.ss
28	```
29
30	Example:
31
32	```bash
33	adb -s 192.168.0.66:5555 shell date 051916302026.00
34	```
35
36	## 3. Build And Deploy
37
38	From repository root:
39
40	```bash
41	cd /Users/dapeng/Projects/yiren/qsjnic/mcu_full_test
42
43	make -B CC=/Users/dapeng/Library/Android/sdk/ndk/30.0.14904198/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang
44
45	adb -s 192.168.0.66:5555 push mcu_full_test /data/local/tmp/mcu_full_test
46	adb -s 192.168.0.66:5555 shell chmod +x /data/local/tmp/mcu_full_test
47	```
48
49	## 4. Offline Self-Test
50
51	Run:
52
53	```bash
54	adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test --selftest
55	```
56
57	Pass criteria:
58
59	```text
60	Self-tests: total=13 passed=13 failed=0
61	```
62
63	Stop testing if any self-test fails.
64
65	## 5. A2M Automatic Full Test
66
67	Run:
68
69	```bash
70	adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test \
71	  --live-interface-full \
72	  --domain key \
73	  --log-file /data/local/tmp/mcu_key_a2m.log
74	```
75
76	Pass criteria:
77
78	```text
79	Interface Domain: KEY (13 tests)
80	Live-tests : total=13 passed=13 failed=0
81	```
82
83	Expected A2M coverage:
84
85	| Test item | Payload |
86	|---|---|
87	| `KEY_A2M_KEY(NONE,RELEASE)` | `02 81 00 00` |
88	| `KEY_A2M_KEY(MODE,SHORT)` | `02 81 01 01` |
89	| `KEY_A2M_KEY(MUTE,SHORT)` | `02 81 02 01` |
90	| `KEY_A2M_KEY(WORKMODE,SHORT)` | `02 81 03 01` |
91	| `KEY_A2M_KEY(CALL,SHORT)` | `02 81 04 01` |
92	| `KEY_A2M_KEY(VOICE,SHORT)` | `02 81 05 01` |
93	| `KEY_A2M_KEY(HOME,SHORT)` | `02 81 06 01` |
94	| `KEY_A2M_KEY(OK,SHORT)` | `02 81 07 01` |
95	| `KEY_A2M_KEY(CH_UP,SHORT)` | `02 81 08 01` |
96	| `KEY_A2M_KEY(CH_DOWN,SHORT)` | `02 81 09 01` |
97	| `KEY_A2M_KEY(VOL_UP,ENC_LEFT)` | `02 81 0A 03` |
98	| `KEY_A2M_KEY(VOL_DOWN,ENC_RIGHT)` | `02 81 0B 04` |
99	| `KEY_A2M_KEY(MUTE,STUCK)` | `02 81 02 02` |
100
101	Notes:
102
103	- ACK timeout followed by retry can happen when MCU emits Public M2A frames during the test.
104	- The item is still PASS if it eventually receives the matching ACK within retry limit.
105	- Any final `FAIL` means A2M is not accepted by MCU and must be investigated.
106
107	## 6. M2A Manual Coverage Test
108
109	This test requires a real key source. During the observation window, trigger every key/status combination listed below.
110
111	Run:
112
113	```bash
114	adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test \
115	  --live-key-observe \
116	  --observe-ms 30000 \
117	  --require-key-m2a \
118	  --log-file /data/local/tmp/mcu_key_m2a.log
119	```
120
121	Pass criteria:
122
123	```text
124	Key M2A Coverage
125	[PASS] ... 13 lines
126	Live-tests : total=13 passed=13 failed=0
127	```
128
129	Required M2A coverage:
130
131	| Test item | Expected M2A payload |
132	|---|---|
133	| `KEY_M2A_KEY(NONE,RELEASE)` | `02 01 00 00` |
134	| `KEY_M2A_KEY(MODE,SHORT)` | `02 01 01 01` |
135	| `KEY_M2A_KEY(MUTE,SHORT)` | `02 01 02 01` |
136	| `KEY_M2A_KEY(WORKMODE,SHORT)` | `02 01 03 01` |
137	| `KEY_M2A_KEY(CALL,SHORT)` | `02 01 04 01` |
138	| `KEY_M2A_KEY(VOICE,SHORT)` | `02 01 05 01` |
139	| `KEY_M2A_KEY(HOME,SHORT)` | `02 01 06 01` |
140	| `KEY_M2A_KEY(OK,SHORT)` | `02 01 07 01` |
141	| `KEY_M2A_KEY(CH_UP,SHORT)` | `02 01 08 01` |
142	| `KEY_M2A_KEY(CH_DOWN,SHORT)` | `02 01 09 01` |
143	| `KEY_M2A_KEY(VOL_UP,ENC_LEFT)` | `02 01 0A 03` |
144	| `KEY_M2A_KEY(VOL_DOWN,ENC_RIGHT)` | `02 01 0B 04` |
145	| `KEY_M2A_KEY(MUTE,STUCK)` | `02 01 02 02` |
146
147	Fail criteria:
148
149	```text
150	[MISS] key.m2a...
151	[FAIL] key.observe missing N/13 Key M2A expected combination(s)
152	```
153
154	If all entries are MISS, the device did not emit `MT_KEY=0x02, cmd=0x01` during the observation window.
155
156	## 7. One-Command Full Key Test
157
158	Use this when a tester can trigger physical/key-source inputs during the M2A observation window.
159
160	```bash
161	adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test \
162	  --live-key-full \
163	  --observe-ms 30000 \
164	  --require-key-m2a \
165	  --log-file /data/local/tmp/mcu_key_full_required.log
166	```
167
168	Pass criteria:
169
170	```text
171	KEY A2M (13 tests)
172	Live-tests : total=26 passed=26 failed=0
173	```
174
175	The total is 26 because it includes:
176
177	- 13 A2M automatic tests
178	- 13 M2A expected combinations
179
180	## 8. Log Collection
181
182	Pull logs after each run:
183
184	```bash
185	adb -s 192.168.0.66:5555 pull /data/local/tmp/mcu_key_a2m.log ./mcu_key_a2m.log
186	adb -s 192.168.0.66:5555 pull /data/local/tmp/mcu_key_m2a.log ./mcu_key_m2a.log
187	adb -s 192.168.0.66:5555 pull /data/local/tmp/mcu_key_full_required.log ./mcu_key_full_required.log
188	```
189
190	Required report fields:
191
192	- Device IP
193	- Test date/time
194	- Binary version or build timestamp
195	- A2M result summary
196	- M2A coverage summary
197	- List of any `[FAIL]`, `[MISS]`, `[WARN]`
198	- Attached log paths
199
200	## 9. Current Known Behavior
201
202	On `192.168.0.66`, previous execution showed:
203
204	```text
205	A2M: 13/13 PASS
206	M2A: 0/13 PASS, 13/13 MISS
207	```
208
209	The M2A result means no Key M2A frame was emitted during the observation window. Public M2A frames may still appear and are not a substitute for Key M2A coverage.
210
211	## 10. Troubleshooting
212
213	| Symptom | Action |
214	|---|---|
215	| `adb` cannot connect | Run `adb connect 192.168.0.66`; verify same network |
216	| Device time is wrong | Set date before test |
217	| `open /dev/ttyS7` fails | Verify serial device permissions and port name |
218	| A2M ACK timeout but retry PASS | Check M2A statistics; MCU may be busy sending status frames |
219	| A2M final FAIL | Inspect TX/RX around the failed item; verify MCU firmware accepts `MT_KEY=0x02` |
220	| M2A all MISS | Verify physical key/key source is connected and triggering MCU-side key reports |
221	| M2A partial MISS | Re-run only M2A observe and trigger the missing keys again |
222

# Key.xlsx Protocol Test SOP

## 1. Purpose

Validate all Key protocol interfaces defined in:

`docs/MCU_ARM_Reference/Key.xlsx`

Scope:

- A2M: `KEY_A2M_KEY`, `MT_KEY=0x02`, `cmd=0x81`
- M2A: `KEY_M2A_KEY`, `MT_KEY=0x02`, `cmd=0x01`
- Parameters: `P0=KeyValue`, `P1=KeyStatus`

## 2. Test Device

Default target:

```bash
adb connect 192.168.0.66
adb -s 192.168.0.66:5555 shell date
```

If the device date is wrong, set it before testing:

```bash
adb -s 192.168.0.66:5555 shell date MMDDhhmmYYYY.ss
```

Example:

```bash
adb -s 192.168.0.66:5555 shell date 051916302026.00
```

## 3. Build And Deploy

From repository root:

```bash
cd /Users/dapeng/Projects/yiren/qsjnic/mcu_full_test

make -B CC=/Users/dapeng/Library/Android/sdk/ndk/30.0.14904198/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang

adb -s 192.168.0.66:5555 push mcu_full_test /data/local/tmp/mcu_full_test
adb -s 192.168.0.66:5555 shell chmod +x /data/local/tmp/mcu_full_test
```

## 4. Offline Self-Test

Run:

```bash
adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test --selftest
```

Pass criteria:

```text
Self-tests: total=13 passed=13 failed=0
```

Stop testing if any self-test fails.

## 5. A2M Automatic Full Test

Run:

```bash
adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test \
  --live-interface-full \
  --domain key \
  --log-file /data/local/tmp/mcu_key_a2m.log
```

Pass criteria:

```text
Interface Domain: KEY (13 tests)
Live-tests : total=13 passed=13 failed=0
```

Expected A2M coverage:

| Test item | Payload |
|---|---|
| `KEY_A2M_KEY(NONE,RELEASE)` | `02 81 00 00` |
| `KEY_A2M_KEY(MODE,SHORT)` | `02 81 01 01` |
| `KEY_A2M_KEY(MUTE,SHORT)` | `02 81 02 01` |
| `KEY_A2M_KEY(WORKMODE,SHORT)` | `02 81 03 01` |
| `KEY_A2M_KEY(CALL,SHORT)` | `02 81 04 01` |
| `KEY_A2M_KEY(VOICE,SHORT)` | `02 81 05 01` |
| `KEY_A2M_KEY(HOME,SHORT)` | `02 81 06 01` |
| `KEY_A2M_KEY(OK,SHORT)` | `02 81 07 01` |
| `KEY_A2M_KEY(CH_UP,SHORT)` | `02 81 08 01` |
| `KEY_A2M_KEY(CH_DOWN,SHORT)` | `02 81 09 01` |
| `KEY_A2M_KEY(VOL_UP,ENC_LEFT)` | `02 81 0A 03` |
| `KEY_A2M_KEY(VOL_DOWN,ENC_RIGHT)` | `02 81 0B 04` |
| `KEY_A2M_KEY(MUTE,STUCK)` | `02 81 02 02` |

Notes:

- ACK timeout followed by retry can happen when MCU emits Public M2A frames during the test.
- The item is still PASS if it eventually receives the matching ACK within retry limit.
- Any final `FAIL` means A2M is not accepted by MCU and must be investigated.

## 6. M2A Manual Coverage Test

This test requires a real key source. During the observation window, trigger every key/status combination listed below.

Run:

```bash
adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test \
  --live-key-observe \
  --observe-ms 30000 \
  --require-key-m2a \
  --log-file /data/local/tmp/mcu_key_m2a.log
```

Pass criteria:

```text
Key M2A Coverage
[PASS] ... 13 lines
Live-tests : total=13 passed=13 failed=0
```

Required M2A coverage:

| Test item | Expected M2A payload |
|---|---|
| `KEY_M2A_KEY(NONE,RELEASE)` | `02 01 00 00` |
| `KEY_M2A_KEY(MODE,SHORT)` | `02 01 01 01` |
| `KEY_M2A_KEY(MUTE,SHORT)` | `02 01 02 01` |
| `KEY_M2A_KEY(WORKMODE,SHORT)` | `02 01 03 01` |
| `KEY_M2A_KEY(CALL,SHORT)` | `02 01 04 01` |
| `KEY_M2A_KEY(VOICE,SHORT)` | `02 01 05 01` |
| `KEY_M2A_KEY(HOME,SHORT)` | `02 01 06 01` |
| `KEY_M2A_KEY(OK,SHORT)` | `02 01 07 01` |
| `KEY_M2A_KEY(CH_UP,SHORT)` | `02 01 08 01` |
| `KEY_M2A_KEY(CH_DOWN,SHORT)` | `02 01 09 01` |
| `KEY_M2A_KEY(VOL_UP,ENC_LEFT)` | `02 01 0A 03` |
| `KEY_M2A_KEY(VOL_DOWN,ENC_RIGHT)` | `02 01 0B 04` |
| `KEY_M2A_KEY(MUTE,STUCK)` | `02 01 02 02` |

Fail criteria:

```text
[MISS] key.m2a...
[FAIL] key.observe missing N/13 Key M2A expected combination(s)
```

If all entries are MISS, the device did not emit `MT_KEY=0x02, cmd=0x01` during the observation window.

## 7. One-Command Full Key Test

Use this when a tester can trigger physical/key-source inputs during the M2A observation window.

```bash
adb -s 192.168.0.66:5555 shell /data/local/tmp/mcu_full_test \
  --live-key-full \
  --observe-ms 30000 \
  --require-key-m2a \
  --log-file /data/local/tmp/mcu_key_full_required.log
```

Pass criteria:

```text
KEY A2M (13 tests)
Live-tests : total=26 passed=26 failed=0
```

The total is 26 because it includes:

- 13 A2M automatic tests
- 13 M2A expected combinations

## 8. Log Collection

Pull logs after each run:

```bash
adb -s 192.168.0.66:5555 pull /data/local/tmp/mcu_key_a2m.log ./mcu_key_a2m.log
adb -s 192.168.0.66:5555 pull /data/local/tmp/mcu_key_m2a.log ./mcu_key_m2a.log
adb -s 192.168.0.66:5555 pull /data/local/tmp/mcu_key_full_required.log ./mcu_key_full_required.log
```

Required report fields:

- Device IP
- Test date/time
- Binary version or build timestamp
- A2M result summary
- M2A coverage summary
- List of any `[FAIL]`, `[MISS]`, `[WARN]`
- Attached log paths

## 9. Current Known Behavior

On `192.168.0.66`, previous execution showed:

```text
A2M: 13/13 PASS
M2A: 0/13 PASS, 13/13 MISS
```

The M2A result means no Key M2A frame was emitted during the observation window. Public M2A frames may still appear and are not a substitute for Key M2A coverage.

## 10. Troubleshooting

| Symptom | Action |
|---|---|
| `adb` cannot connect | Run `adb connect 192.168.0.66`; verify same network |
| Device time is wrong | Set date before test |
| `open /dev/ttyS7` fails | Verify serial device permissions and port name |
| A2M ACK timeout but retry PASS | Check M2A statistics; MCU may be busy sending status frames |
| A2M final FAIL | Inspect TX/RX around the failed item; verify MCU firmware accepts `MT_KEY=0x02` |
| M2A all MISS | Verify physical key/key source is connected and triggering MCU-side key reports |
| M2A partial MISS | Re-run only M2A observe and trigger the missing keys again |


Now I have a comprehensive picture of all Key-related reports in the project files. Let me also check the recent interface consistency report for beta6 that might mention Key.


grep -n -i "key\|按键\|方控" release/v1.0.0-beta6/INTERFACE_CONSISTENCY_REPORT.md 2>/dev/null | head -30

Check beta6 interface consistency report for Key mention


25:| Key domain | `KEY_A2M_KEY` / `KEY_M2A_KEY` | Added `msgType=0x02` constants, typed SDK facade, Service routing, and listener callback. |
32:- Generic `sendCommand()` remains available for raw diagnostics alongside the typed Key facade.


grep -n -i "key\|按键\|方控" release/v1.0.0-beta6/API_REFERENCE.md 2>/dev/null | head -20

Check beta6 API reference for Key mention


11:- `key()` → McuKeyClient
32:- `setKeyBacklightDutyCycle(duty)` → int
34:- `setKeyPwrStatus(status)` → int
63:- `onKeyEvent(int rawByte)` — 按键原始字节
85:## McuKeyClient
86:- `sendKeyEvent(keyValue, keyStatus)` → int
87:- `postKeyEvent(keyValue, keyStatus)` → int
88:- `addListener(KeyListener)` / `removeListener(KeyListener)`
90:### Key 常量
93:| `KEY_VALUE_NONE` | 0x00 | 无按键 |
94:| `KEY_VALUE_MODE` | 0x01 | MODE |
95:| `KEY_VALUE_MUTE` | 0x02 | MUTE |
96:| `KEY_VALUE_WORKMODE` | 0x03 | WORKMODE |
97:| `KEY_VALUE_CALL` | 0x04 | CALL |
98:| `KEY_VALUE_VOICE_ASSISTANT` | 0x05 | 语音助手 |
99:| `KEY_VALUE_HOME` | 0x06 | HOME |
100:| `KEY_VALUE_OK` | 0x07 | OK |
101:| `KEY_VALUE_CHANNEL_UP` | 0x08 | 频道+/上一曲 |
102:| `KEY_VALUE_CHANNEL_DOWN` | 0x09 | 频道-/下一曲 |
103:| `KEY_VALUE_VOLUME_UP` | 0x0A | 音量+ |


[Request interrupted by user]