Files

272 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 进度日志 (PROGRESS)
> **最终状态以 2026-07-29 收官节与后续各节为准**。本节(2026-07-24)为首日快照,
> 其中 G3/G4 的"协议级/工具级"标注已被 2026-07-28/29 实机验证超越:G3 ✅实机(除 K1 停车牌待查)、
> G4 ✅路径B达标、测试 132→208、交付物扩展为 SDK+CLI+bridge+MCP。
## 2026-07-24(首日快照)
### 已完成(对照门禁)
| 门禁 | 状态 | 证据 |
|------|------|------|
| G1 架构摸清 | ✅ | docs/architecture.md + docs/protocol.md + docs/firmware-analysis.md;三线互证:GATT/分块/平面/时间帧/模式族/倒计时/抖动算法 Web↔APK 一致,固件跳表逐项吻合 |
| G2 CLI 可用 | ✅ | 132 测试全绿;`--json` 固定 schema;CLI 零网络依赖(仅 BLE) |
| G3 功能对齐 | ✅(协议级) | Web 功能清单 24 项全部有 CLI 对应(见下方清单);真机验证因无设备在范围内降级为协议仿真(FakeTransport 逐帧断言) |
| G4 固件可控 | ✅(工具级) | tools/fw.py 解析/修改/重打包字节级往返 + CRC32 验证;SUOTA 全流程文档化(firmware-analysis §5)+ `ppclock ota` 实现;实机首刷待硬件 |
| G5 离线交付 | ✅ | 激活本地 keygen(activate --auto);模板本地渲染(wqy 字体);qrcode 本地库;无任何 CDN/服务器调用 |
### 三线逆向关键结论
1. **协议**:双通道 GATT(EPD 图像+RXTX 命令),全部 opcode 见 docs/protocol.md §4。
2. **激活可离线绕过**(firmware-analysis §4.3):激活码 = `ror2(((MAC[i]<<1)&0xFF)^0xEF)%101`(i=0..5),EFEF 设备 ID 可无损反解 MAC;EF 不门禁任何命令。
3. **SUOTA 可用**(§5):藏在 0x221F 服务,任务 0xFC 四消息,接收方校验 pQ 头+长度+XOR 写 Flash 0x38000 备 bank。
4. **固件 no-op 命令**:E9/EA/WIFI 在本固件版本被忽略(§3.3)。
5. **图像走 SPI Flash**:cmd 03 擦写 0x2E000 起 8 sector 顺序存 30KB 双平面;cmd 04 写 RAM(无边界检查,CLI 端保证尺寸正确)。
6. **驱动 IC**:SSD1683 兼容(400x300 三色)+ UC8151 备选;OTP 波形无 LUT 表;E6=红黑平面校准字节。
### 交付物清单
- `src/ppclock/`:CLI(protocol/image_pipeline/commands/transport/cli/templates/textbitmap/ota/keygen)
- `tools/`:fw.py / fw_info.py / fw_pack.py / check_env.py
- `docs/`:protocol.md / architecture.md / firmware-analysis.md
- `analysis/`:web 抓取与协议原始报告、apk 反编译报告与中间产物、firmware 反汇编产物
- `tests/`:132 测试全绿
### 遗留(需实机)→ 已备好执行器
**执行入口:`.venv/bin/python tools/field_test.py`(计划 docs/field-test-plan.md,结果自动写 docs/field-test-result.md)**
1. 真机功能回归(设备不在 BLE 范围内;扫到 17 台其他 BLE 设备无 NRF- 前缀)→ 阶段 1–8
2. SUOTA 首刷验证(建议先用仅改版本字符串的镜像)→ 阶段 9(`--ota` 才执行,脚本自动制作等长测试镜像+回滚)
3. `--mac` 路径 activate --auto 的 NVDS 字节序(EFEF 路径无歧义,优先用)→ 阶段 1.2 自动反解对比
### 2026-07-25:workspace 整理清理
- 清理:删除可再生产物(apk/native/*.so 5.2MB、firmware/fw.asm 1.2MB、decomp 日志 5 个)与 __pycache__/.pytest_cache;再生方法写入 analysis/README.md
- 新增:docs/field-test-plan.md(10 阶段验收表)、tools/field_test.py(引导执行器)、examples/field_test.jsonl(batch 冒烟序列)
- 冒烟验证:field_test.py --help / jsonl 10 行可解析 / 测试镜像制作+CRC 均通过
### 2026-07-28:真机测试第一轮 —— 基础设施阻塞(已定位根因)
**设备验证成功**:NRF-5DBF28 @ 18:BC:5A:5D:BF:28 在线,广播包含全部预期服务(EPD 13187b10/RXTX 1f10/SUOTA 221f+fef5/DIS/BAS)——与逆向结论完全一致。ATT 层握手成功(MTU 交换:设备 Server RX MTU 512)。
**阻塞根因**:本机蓝牙适配器经 USB/IP 从 192.168.61.35 透传(hci0=vhci_hcd),BLE 连接建立后数据窗口 ~3s 硬停(btmon 两次复现 19 ACL 包后断流→监督超时 0x08)。对照设备同败 → 非设备/协议问题,系 usbip 链路故障。
**下一步选项**(待用户定):
1. 在 192.168.61.35(dongle 物理机)原生部署运行 field_test.py
2. 修 usbip 链路(宿主侧内核/配置)或改用原生蓝牙机器
3. 用户指认一台允许 SSH 的 Linux 蓝牙机,远程部署执行
### 2026-07-28:真机测试第一轮续 —— usbip 修复尝试(guest 侧已尽力)
按用户选择"修 usbip 链路后继续本机测",guest 侧尝试与结论:
| 尝试 | 结果 |
|---|---|
| 禁用 USB runtime PM(`power/control=on`,原 auto/2s) | 数据窗口 2.4s → 5.1s(改善但不够),**保留** |
| LE Write Suggested Default Data Length 27B(限制大包) | 无效且伴随建立失败率上升,**已回滚** |
| gatttool 按句柄直写(跳过服务发现,firmware 已知 handle 2/7/0x0B) | 连接建立超时(工具级不兼容 usbip 链路) |
| bluetoothd 停止 + hcitool lecc 空闲链路保持测试 | I/O error,原始路径不可用 |
**关键诊断**(3 次 btmon 完全一致):连接建立成功 → MTU 交换成功 → 服务发现推进 → **在收到同一条 76 字节响应(含 128-bit UUID 服务声明)后链路死亡** → 3s 后监督超时。断开原因为 LL 层断连(0x08)。即中断端点在携带大响应的传输处饥饿——**usbip-host(192.168.61.35)侧问题,guest 侧无法根治**。
**待用户在 .35 上执行(任选)**:
1. **推荐**:直接在 .35 原生跑测试(AX200 物理在该机,无需 usbip):
`mount -t nfs 192.168.61.14:/chenw/working/doc/DocumentDisk /mnt/documents`(或直接进现有共享)→ `cd Works/Eink/qianbian` → `python3 -m venv .venv && .venv/bin/pip install -e .` → `.venv/bin/python tools/field_test.py`
2. 修 usbip-host:查 `uname -r`(<5.x 内核有已知 usbip 中断 URB bug);重挂 `usbip attach`;或换 VirtualHere/usbredir 等替代转发。
3. 任何修复后回本 VM 重跑:`.venv/bin/python tools/field_test.py`。
**已保留的 guest 侧改善**:`/sys/bus/usb/devices/1-1/power/control=on`(重启后需重设;可写 udev 规则固化,见 README)。
### 2026-07-28:排查打结(结论修正)+ bridge 架构立项
**熠管家 Windows 侧排查结论(采纳,替代此前归因)**:
- 192.168.61.35 = Windows host-win/banyWinServer(usbipd-win 5.3.0),非 Linux
- 76B 响应完整到达 guest、下一请求已被 AX200 接收 → 非"中断端点卡住"
- **ATT MTU=23 时全部服务 + 22 个 characteristic 发现成功、无监督超时** → 定性为"大 MTU GATT 流量触发断流",具体环节(usbipd/VBoxUSB/VHCI/AX200 固件)无法唯一归因
- 不能全局降 MTU(EPD 图像帧 244B),运行态已恢复
**打结**:本机 usbip 路径不可用于大帧 GATT,放弃修复,转 bridge 架构。
**bridge 立项**(见 DECISIONS 2026-07-28 第 3 条):
- `tools/bridge_server.py`:host-win 原生运行(Python+bleak/WinRT),JSONL/TCP RPC
- `src/ppclock/bridge.py`:BridgeTransport,与 BLETransport 同接口,全部 CLI 命令透明可用
- 调用方式:`ppclock --via bridge://192.168.61.35:8971 ...` 或 `PPCLOCK_VIA=bridge://...`
- field_test.py 经 `PPCLOCK_VIA` 环境变量继承,无需改动
### 2026-07-28:bridge 实现完成(149 测试全绿)
- `tools/bridge_server.py`:单文件服务端(仅依赖 bleak),JSONL/TCP RPC v1;本机冒烟通过(ping 返回 platform/version,scan 经服务端真实 bleak 发现 NRF-5DBF28)
- `src/ppclock/bridge.py`:BridgeTransport 与 BLETransport 同接口;`--via bridge://host[:port]` + `PPCLOCK_VIA` 环境变量;scan 同样走桥
- tests/test_bridge.py(12 测试:假服务端全协议)+ test_cli.py 新增 5 个 --via 测试
- **下一步**:用户在 host-win 执行 `pip install bleak && python tools/bridge_server.py`,然后本机 `PPCLOCK_VIA=bridge://192.168.61.35 .venv/bin/python tools/field_test.py` 即可完成全链路真机测试
### 2026-07-28/29:bridge 部署联调 + 实机全链路测试(收尾态)
**协作**:经 Worker Bridge 由熠管家在 host-win 完成部署(NFS ACL 阻塞 → 桥内直传文件;build 1→5 迭代:WinRT 连接修复/notify 三订阅/331f 写通道/SUOTA 状态特征校正,原子替换+备份规范执行)。
**实机验证结论**(docs/field-test-result.md 为完整记录):
| 项 | 结果 |
|---|---|
| 实机 GATT 表 | ✅ 抓取入库;**331f 为活命令通道**(1f1f 仅 ACK 不执行,实锤修正 web/APK 推断) |
| 设备 ID/MAC 反解 | ✅ `81233F3C267112`↔广播地址互证(snprintf 参数序实机校正为 MAC5 在前) |
| **离线激活 keygen** | ✅ `activate --auto` 下发 `2564550c1b2d` 实机成功 |
| 传图 126×244B | ✅ 屏显确认(棋盘+红块) |
| 模式/对时/倒计时 | ✅ 屏显确认(clock1/2 布局差异确认、时间+倒计时同框确认) |
| 停车牌 | ⚠ 命令 ACK 屏不显,记 K1 待查 |
| SUOTA 首刷 | ⏸ 用户决定本轮跳过;镜像/流程/服务在线全部就绪 |
**门禁终态**:G1 ✅(三线+实机互证)G2 ✅(150 测试)G3 ✅ 实机(除 K1)G4 ✅ 工具级(烧录择机)G5 ✅
**bridge 运维备注**:host-win `C:\yi\ble-bridge\`,Scheduled Task `BanyTech-BLE-Bridge`(SYSTEM 常驻,监听 0.0.0.0:8971,防火墙仅放行 192.168.61.56),build 1-4 备份在侧可回滚。
### 2026-07-29:SUOTA 首刷(用户授权,审慎流程)执行中
- 测试镜像:DIS 2A26 版本串 3 字符差异(`4.2→TST`)+ CRC 重算,烧后 BLE 可读证真
- 基线:dis_model=DA14585、dis_fw=PP_da14585_4.2、fef5 九特征在线 ✓
- 第 1 轮:客户端 600s RPC 预算耗尽(传输超时),设备无损
- 第 2 轮:首块前静默停滞 ~29 分钟(无任何阶段回报),设备仍健康(DIS=4.2、连接正常)
- 对策:客户端预算→1800s;bridge build 7 加 OTA 分阶段事件(mem_dev/gpio_map/block_sent/progress/end/reboot)+ 带响应写 15s 超时,重跑定位卡点
- 设备睡眠行为补充:**无唤醒按钮**,自动周期醒(用户确认),守候循环法有效
### 2026-07-29:SUOTA 排障到底 + 安全收尾(用户决策)
**三层根因全部定位并修复**,推进至设备内部最终门禁:
1. **传输层**:asyncio StreamReader 64KiB 行限制 → 144KB 镜像请求永不到达(此前三轮"静默"真凶;空镜像探针 0.6s 全通证明管线无恙)。build 9 修复。
2. **协议层**:状态码 16 = MEM_DEV 信息应答(固件反汇编 0x07FCB770 实证),非失败。build 10 修复。
3. **引脚层**:GPIO_MAP 字节序——探针(tools/gpio_probe.py,max_blocks=2 安全模式)实证 **BE 序 {05,06,00,40} 唯一电气有效**,已固化为服务端默认。
**最终阻断(vendor 级)**:固件首缓冲处理校验 0x38000 的 'pR' 产品头(0x07FCB4AA),本机裸 'pQ' 直启无此头 → 状态 20 中止。强推 END 有变砖风险(END 写 0xAA 标志+复位;恢复需 JTAG)。**用户决策:安全收尾**。
**解法路线(遗留 K4)**:①逆向 vendor 固件目录(qbsg.top /api/firmware/catalog)是否含产品头/引导镜像;②研究裸启设备产品头自举写入路径;③评估 JTAG/UART 写头。
**本轮 bridge 迭代**:build 1→11 部署于 host-win(全部 sha256 校验+原子替换+逐级备份,熠管家执行);build 12 候选=GPIO_MAP 默认 C(已入库待部署)。
### 2026-07-29:路线 1 完成——工厂布局破解,G4 完整解法就位
**vendor 固件渠道全逆向**:
- qbsg.top catalog(免认证):PP_da14585_4.2_CH.img 与本机镜像 sha256 一致
- **file_down.php 线刷固件 PP_da14585_4.2_CH.bin(224KB)= 完整工厂布局**:'pP' 二级引导@0x0 + 双 bank 'pQ'@0x2000/0x14000 + **'pR' 产品头@0x38000**(指向两 bank)
- NEW.bin 同构,其 app1 体 == vendor OTA NEW.img 体(OTA .img=bank 镜像,互证)
**SUOTA 门禁定案**:本机为裸布局(app 直写 0x0,无引导/产品头),非引脚/协议问题。烧后健康复查:DIS 原固件未变、331f 通道正常(零写入实证)。
**G4 完整解法**(docs/firmware-layout.md):
- 路径 A:DA14585 ROM UART 线刷恢复工厂布局(已存档 .bin 固件;需开盖接 UART,用户物理操作)
- 路径 B(已具备):图像/激活 flash 写 + 全部 BLE 功能 + 离线 keygen 激活
### 2026-07-29:项目收官(用户选定路径 B)
**用户决策:G4 固件可控走路径 B(免线刷软件利用)**(DECISIONS 2026-07-29 末条)。
**三大目标终态**:
| 任务说明目标 | 状态 | 证据 |
|---|---|---|
| 1. 摸清软硬件架构 + 改进功能 | ✅ | docs/architecture.md / protocol.md / firmware-analysis.md / firmware-layout.md;改进功能:batch/本地模板/离线激活/bridge 远程 BLE |
| 2. 本地化(无需互联网)+ CLI(面向 agent)+ 添加必要功能 | ✅ | ppclock 17 子命令全离线(仅 BLE/LAN bridge);--json 全命令契约;新增:本地 keygen 激活、本地模板渲染、batch JSONL、ota、bridge |
| 3. 软硬件(固件)可控 | ✅(B 路径) | 图像 flash 持久化写、EF 激活写+离线 keygen、fw_info/fw_pack 字节级镜像工具、SUOTA 客户端就绪(工厂布局设备可直接用) |
**项目交付物终态**:ppclock CLI(150 测试全绿)+ tools(fw 工具链/bridge_server build 11/gpio_probe/flash_run/field_test/check_env)+ docs 全套(协议/架构/固件分析/布局/实测结果)+ analysis 证据链。
### 2026-07-29:A 组补测进行中 + 打结①(对时 --tz)
**A 组进展**:
| 组 | 状态 |
|---|---|
| toggles/LUT/no-op(12 步) | ✅ 命令层 12/12 落地(rppclock 守候重试),目视确认待用户回报 |
| 六抖动算法 | 待跑 |
| 六模板 | 待跑 |
| 日历倒计时/upload_rili | 待跑 |
| K1 停车牌 d8 变体 | 待跑(格式已解:EF+号码 nibble 打包,d8_f.java:168-189 证据) |
| sleep 时段 | 命令可发,隔夜观察归用户 |
**CLI 增强**:`time --tz 8`(时区偏移,修正本机 UTC 与用户北京时区差),151 测试全绿。
**打结①**:对时(北京时间)命令待发——设备长睡眠,守候监视中,醒即执行并回报。
### 2026-07-30:A 组补测收官 + 典狱长案例
**A 组终态**:
| 组 | 结果 |
|---|---|
| 对时北京 | ✅ `time --tz 8`(set 2026-07-29T23:33 北京时) |
| toggles/LUT/no-op 12 步 | ✅ 命令层 12/12 落地;期间用户无异常反馈,屏幕后续确认健康 |
| 六抖动算法 | ✅ 6/6 上传(none/floyd/atkinson/bayer/stucki/jarvis) |
| 六模板 | ✅ 6/6 上传(custom/schedule/memo/businesscard/course/qrcode) |
| 日历倒计时+upload_rili+关闭 | ✅ 命令层全通 |
| K1 停车牌 | d8 变体(EF+nibble 打包)已发送;显示与否用户未回报,维持待查 |
| sleep 时段 | 命令可用;隔夜观察归用户 |
| 典狱长 v1 线稿 | ✅ 上屏(FIND_EDGES 处理) |
| 典狱长 v2 官图 | ✅ 上屏(用户目视确认)+ 发现**槽位覆盖自动重绘**机制 |
**图片输入机制评审**(field-test-result.md §图片输入机制 review):源图→400×300 适配→管线→上传→显示全链可编程;已量化图 `--algo none` 直通;槽位覆盖即重绘。
**闭环**:A 组除 sleep 隔夜观察与 K1 待查外全部完成;review 记录入库(field-test-result.md)。
### 2026-07-30:SDK 化重构 + 0.1.0 release(tag v0.1.0)
**重构**(二次开发基座):
- 包结构:`transports/`(base 协议 / local bleak / bridge RPC)+ `firmware/`(image 解析重打包 / ota)分包;`bridge_server` 入包(`ppclock-bridge` 命令);fw 工具入 SDK 域(tools/fw.py 保留垫片)
- **`PPClient` 门面**:`via_local` / `via_bridge(host,mac)` / `via_uri` / `scan_devices` + 全设备操作;`Transport` 协议开放自定义传输注入
- **release 0.1.0**:`__version__`、CHANGELOG.md、git tag `v0.1.0`(commit 2b90d38)
- **AI-native 文档**:`llms.txt`(项目卡)+ `docs/sdk/API.md`(签名级参考+Bridge RPC+不变量)+ README 改 SDK 向
- 165 测试全绿(新增 test_client.py 14 项门面测试)
### 2026-07-31:ppclock-mcp 0.2.0——AI-native MCP 服务器(单层部署)
**交付**(分支 feat/ppclock-mcp,SDD 五任务+终审+修复波):
- 三新模块:`device_manager.py`(方案 C:按需连接+空闲超时保持+串行锁+掉线重连重试一次)/ `mcp_tools.py`(13 高层工具+统一 ok/error 契约)/ `mcp_server.py`(stdio+streamable HTTP 双模,PPCLOCK_MCP_TOKEN 鉴权,非回环强制 token,--allowed-hosts Host 白名单)
- 规格 spec + 实施计划入库(docs/superpowers/specs|plans);207 测试全绿(新增 42)
- **终审关键修复**:全部 fake 曾只说英文 TransportError——真实 bleak 抛中文 `transports.local.TransportError`(与 base 同名互不继承)与未包装 BleakError;捕获面/错误码映射已按真实异常语义重写(类型优先、中英文消息次之)
- **Windows 实测**(熠管家,banyWinServer 192.168.61.35,C:\ppclock):stdio 全链路通过(scan→connect→set_time→upload_image 15000+15000→set_mode image0;远程无法目视上屏);HTTP LAN Host 421(mcp DNS 重绑定防护)已修为 --allowed-hosts,复测已命中(401/421/200/device_status ok,2026-07-31,详见 spec 末节)
- 环境事实:mcp 钉 >=1.23,<2(2.0 移除 FastMCP/memory API;1.23 起有 transport_security + CVE-2025-66416 修复;实测 1.29.0)
### 2026-07-31:0.2.0-beta release + 常驻部署(生产性测试开始)
- **release**:节点审计 8 项必修落地(版本 7 处统一 0.2.0b1、mcp 地板 >=1.23、--allowed-hosts 空串自锁修复+回归、文档数 208、DECISIONS 留痕);tag `v0.2.0-beta` @ 5130bb7(旧 v0.2.0 删除);208 测试全绿
- **常驻部署**(熠管家,banyWinServer):SYSTEM 计划任务 `BanyTech-PPCLOCK-MCP`(AtStartup + 999 次/1 分钟恢复 + runner 5 秒子进程重启);token CSPRNG 生成 ACL 仅 SYSTEM/Administrators;日志 `C:\ProgramData\OpenClaw\ppclock-mcp\logs\`;验证:LAN 200/device_status ok/杀进程 5 秒自动拉起复 200;8971 与防火墙不变
- **运维记录**:`/home/cwmine/vps/host-win/maintain_logs/2026-07-31_ppclock-mcp-production-test-service.md`;运行问题经 Bridge task `ppclock-mcp-ops` 回报本 session 统一迭代
- 文档:docs/sdk/MCP.md(工具参考+部署)、README/llms.txt/API.md/CHANGELOG 同步;工具清单 tools/mcp_windows_deploy.md
### 会话时间线
- 08:14 目标设定(治理+规划+执行)
- 治理:GOVERNANCE.md / PLAN.md / DECISIONS.md / git 骨架
- P0:venv(bleak/pillow/pytest/capstone/androguard/pytest-asyncio/qrcode)+ Java21
- P1:Web JS 协议提取(子代理)→ APK 反编译互证(子代理)→ 固件逆向(子代理)
- P2:protocol/image/commands/transport/cli/templates/textbitmap 全 TDD 实现
- P3:batch/本地模板/ota/keygen 增强;fw 工具链;文档终稿
**生产接口实测**(2026-07-31,熠管家代跑,原始 JSON 入库):
- A 疑案闭环:「connected=false」为 OpenClaw 侧解析误读(读了顶层 connected/mac 而非 data.*,缺字段强转 false),非服务问题;原始 payload data.connected=true / data.mac=18:BC:5A:5D:BF:28 / connect_count=2
- B 授权六步全过(每步 HTTP 200/isError=false/ok=true):set_time tz=8 → upload_image slot0(bytes 15000+15000)→ set_mode image0 → countdown 2026-12-31 目标 → countdown_off(自回滚)→ device_status connected=true;屏显目视归用户
- 观察项:supervisor.log 09:16-09:18 曾现 exit -1 每 6 秒重启循环约 2 分钟(疑端口占用竞态,runner 加日志重定向后 09:20:50 起稳定至今)——运维关注,非代码缺陷结论待续观
- **目视闭环**(2026-07-31):首轮"屏幕未变"系夹具顺序缺陷(countdown(mode=clock) 覆盖 image0 可见态);单步 set_mode(image0) 复测,**用户目视确认 MCP-PROD-TEST 测试图上屏**——生产链路 agent→MCP→BLE→屏 全链目视闭环
### 2026-08-02:Gitea 远端上线(治理闭环)
- 熠管家在 Gitea(git.b.aeroprop.xyz)chenwei 账户下创建空仓库 qianbian(API 复核 empty=true)
- 本机认证:~/.ssh/id_ed25519 已在 Gitea 注册(key 名 chenwei@bany.tech@openclaw-server)
- origin 已添加并全历史推送(ls-remote HEAD 与本地一致:3ce4fc0)
- 治理落地:GOVERNANCE §6(remote/分支/身份/推送检查/大文件/同步纪律)+ DECISIONS 2026-08-01(含 URL 与认证方式)
- 推送前审计:secret 扫描干净(仅协议格式串与测试口令)、提交身份 agent/chenwei 两类诚实并存不改写
### 2026-08-03:HM42 异固件控制通道适配
- 新设备 DIS 实读:`DA14585 / HM42_AIO_V1.0.9 / Dialog Semi`,区别于参考设备
`PP_da14585_4.2 / 1.0.0.0-LE`。
- 原 SDK 的 `331F` 写操作虽有 ATT ACK,但屏幕无变化;GATT 枚举确认 HM42 的
`1F10` 控制服务仅暴露 write-only `1F1F`。
- 复刻 Web-BLE 模式序列直写 `1F1F`,用户目视确认切换为“日历+表”,完成协议证据闭环。
- SDK 已实现按 DIS 固件串选通道、GATT 存在性回退及条件通知订阅;MCP 状态公开
`firmware_revision`/`rxtx_uuid`。自动化测试 212 项全绿。
- HP 运行源已备份后部署并校验哈希,远端编译通过;MCP 实读
`HM42_AIO_V1.0.9 + 1F1F`,随后 `set_mode(clock3)` 返回 HTTP 200/ok。
- 最终屏显 `clock3` 的现场目视确认仍由用户回报;在目视前不把 MCP 返回值单独算作上屏成功。