6.0 KiB
设备发现、基础信息与升级协议
仅在任务涉及设备网络发现、版本查询或 ROM 传输时读取本文件。优先使用用户提供的最新协议、现有已验证实现和抓包;文档歧义不得伪装成确定事实。
本机参考资料
存在时优先核对:
C:\Users\ZK\Documents\ChatGPT\日常开发\调试资料\设备端协议V2-工厂整合版本.mdC:\Users\ZK\Documents\ChatGPT\日常开发\调试资料\设备端统一配置协议V2.mdC:\Users\ZK\Downloads\设备端TCP文件传输类协议.mdC:\Users\ZK\Downloads\工厂协议V1.mdE:\CodeSpace\git-pro\eapil_qt_player_v2\EpProtocolDemo
V2 协议矩阵
| 功能 | 传输与端口 | 帧格式 |
|---|---|---|
| 设备发现请求 | UDP,客户端从本地 8951 向设备 8941 广播 |
EPBP + uint32长度 + UTF-8 JSON |
| 设备发现响应 | UDP,客户端 8951 接收 |
同上,完整帧在一个数据报内 |
| 统一配置 | TCP,设备 8942 |
EPTP + uint32长度 + UTF-8 JSON |
| 固件升级 | TCP,设备 8943 |
EPFP + uint32命令 + uint32长度 + 二进制数据 |
多字节整数使用网络字节序。配置 TCP 长度端序在整合文档中没有单独声明,但现有设备和客户端验证采用网络序。
发现与身份
V2 发现请求 JSON:
{"cmd":60000,"session":12345}
响应必须回显相同 cmd/session。身份字段包括 sn、顶层烧录 mac、inner、outer、hardware 和 net。顶层 mac 与 net.mac 可能不同。型号判断同时展示:
inner.typeouter.typehardware.type
非关键网络字段允许缺失。完整 SN 是升级身份核对的首要依据。V1 的端口与帧格式必须从 V1 文档或已验证的 EpProtocolDemo/V1 获取,不能套用 V2。
执行发现时使用 scripts/v2_discover.py,并遵守以下规则:
- 默认枚举已启用、已连接且具有有效 IPv4 的物理网卡;回环、断开、APIPA、VPN、VMware、Npcap 等接口要列出并注明排除原因。用户明确要求所有活动接口时才加入虚拟接口。
- 每个接口分别绑定其本地 IPv4 和客户端端口
8951,同时发送有限广播255.255.255.255和按前缀计算的定向广播。不能把/22的广播地址按/24猜测。 - 如果 UDP
8951被 EapilCameraConfigurer 或其他进程占用,报告占用者,不结束进程;请用户释放端口,或使用已有工具明确支持的搜索结果。 - 从临时源端口发包只可作为诊断。设备可能只向
8951回复,因此临时端口无响应不能证明设备离线。 - 打印所有合法候选并按完整 SN 精确匹配;不得选择第一台。响应需校验
EPBP、长度、cmd/session。只有 SN、源 IP、MAC 和型号都一致的重复响应可以合并;同一 SN 对应不同身份信息时报告冲突并禁止自动选择。 - 未提供完整
--expected-sn时脚本只是列表模式,即使退出码为 0 也不代表身份核验成功。Telnet、升级及其他设备写操作必须提供完整 SN,并根据任务要求同时传入型号。
基础信息
通过 TCP 8942 发送 cmd=30101。响应必须满足:同步头正确、长度合理、cmd/session 匹配且 code=0。读取:
sn、macinner.type/versionouter.type/versionhardware.type/version
hardware.version 不是固件版本。升级后应根据 ROM 类型比较 inner.version 或 outer.version。如果无法从 ROM 或构建记录确定应变化的字段,必须明确说明并让用户确认预期。
30102 可能返回密码和密钥,只在调试任务确实需要时调用。用户选择保留原始调试数据,因此响应可原样写入本次任务日志,但不得写入 skill 本体。
固件升级 4001
请求:
EPFP
+ uint32 4001
+ uint32 ROM字节数
+ ROM原始字节
ROM 前没有 MD5 或目标路径业务前缀。不要把普通文件写入 2001 的 MD5 机制声称为升级 4001 自带校验。
状态业务数据为 21 字节:
uint8 status
+ uint32 sessionId
+ uint32 downloadTotal
+ uint32 downloaded
+ uint32 flashTotal
+ uint32 flashed
状态:0 空闲、1 开始、2 完成、3 失败。sessionId 不等同于配置 JSON session,不要求匹配。解析器要兼容完整 EPFP/cmd/length 状态帧与设备实测出现的裸 21 字节状态,但完整帧必须校验响应命令为 4001。
只有 status=2 是协议成功终态;下载或 Flash 计数达到总量不能替代它。status=3 立即失败。连续 60 秒没有下载或 Flash 进度变化视为停滞,值允许覆盖。没有依据时不自动续传或重试。
设备报告的 downloadTotal、flashTotal 可能与 ROM 文件字节数不同,不能因为这种封装头、元数据或分区差异单独判失败。status=2 是协议成功终态;如果此时 downloaded/flashed 仍小于设备各自报告的非零总量,记录协议计数异常警告并纳入验证报告,但不自行推翻设备的成功终态。
升级前保护
- ROM 必须是普通文件,大小大于 0 且不超过无符号 32 位长度。
- 计算并记录 SHA-256;协议本身没有 ROM 签名或来源认证,不能声称 SHA-256 提供设备侧认证。
- 精确核对设备 SN。
- 同时展示当前型号和 ROM 目标型号。ROM 元数据无法解析时显示“无法验证型号”,并重新取得用户确认。
- 多个 ROM 或设备候选时等待选择。搜索端口被占用或没有完成完整 SN 核对时不得升级。
- 确认后调用
scripts/device_upgrade.py --execute,不绕过其保护参数。
已知协议歧义
- 状态章节没有明确说明每次状态是否带 EPFP 外层头,因此客户端兼容完整帧和裸状态。
- 没有规定分块大小、连接关闭方、断线恢复或统一总超时;使用可配置值并保存最后进度。
- 没有定义 ROM 与型号的自动匹配机制。
- TCP 是字节流,必须累积并按长度解析,不能把单次
recv当作完整帧。