26 lines
7.7 KiB
HTML
26 lines
7.7 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>device-link.md 修订附录 2026-10-19</title><style>
|
||
body{font-family:-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;margin:0;background:#f5f6f8;color:#1d2330;line-height:1.6}
|
||
.wrap{max-width:1180px;margin:0 auto;padding:28px 24px 60px}
|
||
h1{font-size:26px;margin:0 0 6px}h2{font-size:20px;margin:36px 0 12px;padding-bottom:6px;border-bottom:2px solid #d9dee8}
|
||
h3{font-size:16px;margin:22px 0 8px}
|
||
.meta{color:#5b6476;font-size:13px}
|
||
.card{background:#fff;border:1px solid #e1e5ec;border-radius:10px;padding:16px 18px;margin:12px 0}
|
||
table{border-collapse:collapse;width:100%;background:#fff;font-size:13px;margin:8px 0}
|
||
th,td{border:1px solid #e1e5ec;padding:6px 8px;vertical-align:top;text-align:left}
|
||
th{background:#eef1f6;font-weight:600}
|
||
code{font-family:Consolas,Menlo,monospace;font-size:12px;background:#f0f2f6;padding:1px 4px;border-radius:3px;word-break:break-all}
|
||
.sev{display:inline-block;padding:1px 8px;border-radius:10px;font-size:12px;font-weight:600;color:#fff;white-space:nowrap}
|
||
.s0{background:#b3261e}.s1{background:#e8710a}.s2{background:#3367d6}.s3{background:#5f6b7a}
|
||
.kpis{display:flex;gap:12px;flex-wrap:wrap}.kpi{flex:1;min-width:130px;background:#fff;border:1px solid #e1e5ec;border-radius:10px;padding:12px 14px}
|
||
.kpi b{display:block;font-size:26px}
|
||
.issue{background:#fff;border:1px solid #e1e5ec;border-left:5px solid #ccc;border-radius:8px;padding:12px 16px;margin:10px 0}
|
||
.issue.s0b{border-left-color:#b3261e}.issue.s1b{border-left-color:#e8710a}.issue.s2b{border-left-color:#3367d6}.issue.s3b{border-left-color:#5f6b7a}
|
||
.issue h4{margin:0 0 6px;font-size:15px}.issue dl{margin:0;display:grid;grid-template-columns:72px 1fr;gap:3px 10px;font-size:13px}
|
||
.issue dt{color:#5b6476}.issue dd{margin:0}
|
||
.st{white-space:nowrap;font-weight:600}.st-ok{color:#1e7e34}.st-part{color:#b26a00}.st-open{color:#b3261e}.st-na{color:#5f6b7a}.st-old{color:#6b4fbb}
|
||
pre.arch{background:#1f2430;color:#e6e9ef;padding:14px;border-radius:8px;overflow:auto;font-size:12.5px;line-height:1.45}
|
||
a{color:#2457c5}
|
||
.note{font-size:12.5px;color:#5b6476}
|
||
</style></head><body><div class="wrap"><h1>《device-link.md》修订附录 2026-10-19</h1><div class="meta"><a href="../device-link.md">原报告</a> · 核对基线 commit <code>eac3717</code> · 总评审:<a href="../../../review/DCU_DesktopController_专家评审_2026-10-19.html">DCU_DesktopController_专家评审_2026-10-19.html</a></div><div class="card"><b>原报告:</b>Device Link / ConnectionHub(全链路统一连接层)<br><b>时间线:</b>status: delivered,2026-09-16(670b833 → f950257)<br><b>原结论概要:</b>外壳 tabs.html 作为 Owner 持有链路健康轮询并经 BroadcastChannel 广播;端点(IP/网卡)集中在 deviceLink;外壳启动即 open+motor/start,失败 10s 退避。<p class="note">原文件保持不变;本附录逐条记录其结论在当前代码中的状态。</p></div><h2>逐条结论跟踪</h2><table><tr><th>编号</th><th>原结论 / 建议</th><th>当前状态</th><th>证据(文件:行号)</th><th>备注</th></tr><tr><td>DL-1</td><td>外壳 Owner + BroadcastChannel 快照</td><td class="st st-ok">已修复(已交付)</td><td><code>tabs.html:205; js/common/device-link.js:117, 389</code></td><td></td></tr><tr><td>DL-2</td><td>端点配置只在 ConnectionHub</td><td class="st st-part">部分修复</td><td><code>pages/can_monitor.html:55; js/can_monitor.js:60-68; js/app.js:63-71</code></td><td>CAN 监控页硬编码 IP 优先于 Hub(C-11);OTA 页 IP 输入可绕过</td></tr><tr><td>DL-3</td><td>功能页不再各自判定在线</td><td class="st st-part">部分修复</td><td><code>js/common/polling.js; js/can.js:424; js/can_monitor.js:487</code></td><td>多处仍独立轮询 /system/status(C-13)</td></tr><tr><td>DL-4</td><td>外壳启动强制开总线,失败 10s 退避</td><td class="st st-open">仍存在风险</td><td><code>js/common/device-link.js:32, 250-287</code></td><td>无 reason、unknown 视为需启动、OTA 闸读不到 iframe 标志(M-6、M-7)</td></tr><tr><td>DL-5</td><td>BLE 经 reportBle 上报</td><td class="st st-ok">已修复(已交付)</td><td><code>js/ble/gatt.js:119, 123, 128</code></td><td></td></tr></table><h2>相关新问题(详见总评审)</h2><div class="issue s1b" id="C-11"><h4><span class="sev s1">严重</span> [C-11] 独立 CAN 监控页无视所选设备</h4><dl><dt>模块</dt><dd>CAN/公共层</dd><dt>位置</dt><dd><code>pages/can_monitor.html:55; js/can_monitor.js:60-68; js/can/dbc.js:40-47</code></dd><dt>现象</dt><dd>页面输入框写死 value="192.168.31.127" 且优先于共享端点,监控标签总连 .127;绕过 IPv4 校验;与 dbc.js 优先级不一致,破坏 README 所述单端点写入者设计。</dd><dt>风险</dt><dd>监控的不是正在控制的设备。</dd><dt>修改建议</dt><dd>移除硬编码值,统一从 deviceLink 读取。</dd></dl></div><div class="issue s1b" id="M-6"><h4><span class="sev s1">严重</span> [M-6] 「谁可以动总线」红线被多处绕过</h4><dl><dt>模块</dt><dd>电机控制/故障保护</dd><dt>位置</dt><dd><code>js/motor/transport-ecat.js:394-459, 668; js/common/device-link.js:250-287, 322-327</code></dd><dt>现象</dt><dd>transport-ecat.ensureStarted 在 isBusHealthy 为 false(含 unknown)时调用 motor/start,不带 reason、不走 ensureEcatLoopRepair 预算,并重复实现 ecat-bus.resolveEcatStartBody 的周期/DC 逻辑;Owner bootstrapEcatBus 同样无 reason 且把 unknown 当需要启动;repairEcatDc 无间隔/次数预算,pollEcat 每 2 s 与 healthCheck 都可触发。</dd><dt>风险</dt><dd>健康总线被误重启、OTA/刷写期间总线被抢、DC 修复风暴。</dd><dt>修改建议</dt><dd>所有 start/repair 统一经 ecat-bus 单入口(带 reason、预算与 OTA 闸);unknown 状态不得触发启动;删除 transport-ecat 内重复的周期计算(与 host-code-quality R6 同源)。</dd></dl></div><div class="issue s1b" id="M-7"><h4><span class="sev s1">严重</span> [M-7] OTA 忙标志写在 iframe 窗口,外壳 Owner 读不到</h4><dl><dt>模块</dt><dd>电机控制/故障保护</dd><dt>位置</dt><dd><code>js/motor/transport-ecat.js:80-82; js/common/device-link.js:255</code></dd><dt>现象</dt><dd>setMotorOtaEcatBusy 写的是电机页 iframe 自身的 window.motorOtaEcatBusy;Owner 运行于 tabs.html 顶层窗口并读自己的 window,闸门永不生效;页面中途关闭时标志也不会清除。</dd><dt>风险</dt><dd>OTA 期间 Owner 仍可能 open/motor/start 抢总线,导致刷写失败或半截镜像。</dd><dt>修改建议</dt><dd>改用 BroadcastChannel/localStorage 带 TTL 的跨帧忙标志(与 boot_ecat.js:598 统一一处实现),Owner 读取同一来源。</dd></dl></div><div class="issue s2b" id="C-13"><h4><span class="sev s2">一般</span> [C-13] 对设备的并发轮询过多</h4><dl><dt>模块</dt><dd>CAN/公共层</dd><dt>位置</dt><dd><code>js/common/device-link.js:30; js/can.js:131, 424; js/can_monitor.js:487, 490; tabs.html:76-81; js/common/polling.js:350-352</code></dd><dt>现象</dt><dd>/system/status 被 Owner(1 Hz)、OTA 页(1 Hz)、can.js(5 s)、can_monitor(5 s) 同时轮询;/can/feedback 被抽屉与独立监控页各 1 Hz;隐藏 iframe 继续轮询,无可见性暂停与离线退避。README 称设备 httpd 仅 6 个 socket 且 lru_purge。</dd><dt>风险</dt><dd>连接被挤占驱逐,业务请求失败。</dd><dt>修改建议</dt><dd>状态统一由 Owner 广播;隐藏页暂停;离线指数退避。</dd></dl></div><h2>结论</h2><div class="card">共 5 条:已修复 2、部分修复 2、仍存在/存疑 1、已过时 0、无法在本仓库核实 0。</div></div></body></html>
|