# 修改记录 2026-09-05:真机联调——BLE 通道按特征值隔离 + SAF 选包 + 全链路日志 ## 背景 V1.00.23 协议适配(见 2026-09-04 修改记录)后真机联调,依次踩到并解决: 连接后读超时/写 10007、OTA 页读包失败(Android 10+ 分区存储)、 plus 桥 byte[] 不回写导致读包内容错误等。本轮全部修复并加了可定位问题的日志。 ## 改动清单 ### src/BluetoothManager.ts(核心:读写按特征值隔离成独立通道) - **读改为按特征 UUID 分键的独立队列**(`readQueues`/`readActiveMap`/`readTimers`): 同一特征上的读串行(e0003 分包读不与 e0004 轮询读交错);不同特征互不阻塞, 一路超时/失败不影响其他通道;`onBLECharacteristicValueChange` 按 characteristicId 直接分发到对应通道 - **写无任何跨特征等待**(`writeChar` 直接发);断连时逐通道排空各自队列 - **10007 "property not support" 延时重试**:读和写各一次(1600ms)——实测安卓 链路未稳定时会误报 10007(特征属性明明支持写),参考 DCloud 社区已知问题 - **链路稳定期**:`scanServices` 成功后 300ms 内不发出 GATT 操作(连接级一次性) - 全链路日志:连接/断开事件、`tx/rx <特征短名> <长度> `(截断标注总长)、 读发起/超时、10007 重试提示 实测根因记录:home 页曾在 `bleState=0` 时**并发**调 `setMtu` 与读 e0004, 读被安卓无声丢弃(3s 超时),后续写全部被拖进 10007;通道隔离 + 时序修正后消失。 ### src/mcm/McmCli.ts - 日志:`[CLI] >> 命令` / `[CLI] << (NB, status=0) `,失败带底层 errMsg 原文;`CliResult` 新增 `errMsg` 字段 ### src/mcm/McmInfo.ts - 日志:`[INFO] TLV NB parsed: {...}`;读失败打 `[INFO] read failed` ### src/mcm/McmOta.ts - 帧日志:BEGIN/END/ABORT 全帧 hex;每条 OTA_RSP 打 `echo/status/offset + hex`; 坏帧内容一并打出(DATA 帧体不逐条打,避免刷屏) ### pages/tabbar/home.vue - **Auto refresh (2s) 开关,缺省关闭**:不再自动周期读 e0004,避免轮询占用 GATT 干扰 OTA/CLI;开关打开才轮询(立即查一次 + 2s 周期); 连接就绪回调与 onShow 两个自动启动点都已按开关门控 - 连接初始化改串行:先 `setMtu(247)`,回调里再 `loadDeviceInfo()`(消除 GATT 并发撞车) ### pages/tabbar/ota.vue(选包/读包重做) Android 10+ 分区存储(targetSdk≥29)禁止直读 `/sdcard/Download`(plus 报 code 15),`uni.chooseFile` 在 App 端 vue3 又不存在,最终方案: - **Choose File 按钮**:plus.android 起 `Intent.ACTION_GET_CONTENT` 系统 SAF 选择器(免权限,可直接选 Download 里的包) - **读包**:`ContentResolver.openInputStream(uri)` → `java.util.Scanner` 按 ISO-8859-1 整流读成 String 过桥(字节 1:1 映射,规避 **byte[] 参数按值拷贝、 `read(buf)` 写不回 JS 侧**的桥限制——曾读出整块填充字节 0x41)→ 读回自验 magic(`11 BA 10 CA`)→ **不符自动重开流落逐字节 `read()` 直读**(int 返回值 过桥,二进制绝对精确,每 16KB 打进度) - 全程日志:picker 拉起/onActivityResult 返回码/uri 原文/读取模式/字节数/ 文件头 hex/magic 校验结论;失败分支带异常原文 - 手动路径方式保留:默认 `_doc/mothercup_ble_ota.bin`(应用私有目录,可 adb push 进去);解析失败时日志带实际读到的长度+头部 hex,便于区分"读错"与"格式错" - `window.plus` 改 `globalThis.plus`(App 端 vue3 无 window 对象) ## 验证(真机) - e0004 参数特征读通:TLV 33B 解析正确(V1.00.23 / APP1 / 21.2℃ / 3335mV / uptime / 堆剩余),10007 与读超时不再出现 - SAF 选包读通:111168B 与包文件一致 - parseCombo 逻辑在 PC 侧 node 用真实 `mothercup_ble_ota.bin` 逐字节验证: magic/hdr_len/total_size/payload_crc/逐 bank crc 全对(协议符合性确认无误) ## 待办 - BLE OTA 全流程真机(Start Upgrade → 复位 → 回连复核 PASS) - 修改记录 2026-09-04 的实机验证项随本轮一并闭环