Files

170 lines
12 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.
# 设备发现、基础信息与升级协议
仅在任务涉及设备网络发现、版本查询或 ROM 传输时读取本文件。优先使用用户提供的最新协议、现有已验证实现和抓包;文档歧义不得伪装成确定事实。
## 本机参考资料
存在时优先核对:
- `C:\Users\ZK\Documents\ChatGPT\日常开发\调试资料\设备端协议V2-工厂整合版本.md`
- `C:\Users\ZK\Documents\ChatGPT\日常开发\调试资料\设备端统一配置协议V2.md`
- `C:\Users\ZK\Downloads\设备端TCP文件传输类协议.md`
- `C:\Users\ZK\Downloads\工厂协议V1.md`
- `E:\CodeSpace\git-pro\eapil_qt_player_v2\EpProtocolDemo`
- `E:\CodeSpace\git-pro\eapil_public_library\EapilPanoC\src`(V1 命令、端口、数据结构和 Qt 客户端实现;以当前源码为实现依据,部署设备仍需实测)
## V1 协议(EapilPanoC)
V1 与 V2 使用不同端口和帧格式,不能把 `EPBP/EPTP/EPFP` 的 V2 帧头套用到 V1 通用配置接口。
| 功能 | 传输与端口 | 请求/响应格式 |
|---|---|---|
| 局域网搜索 | UDP `4942`,向广播地址 `4942` 发送并在本地 `4942` 接收 | `uint32 cmd + uint32 JSON长度 + UTF-8 JSON` |
| 通用配置获取/查询 | TCP 设备端 `4941` | `uint32 cmd + uint32 payload长度 + payload`;常见无参读取长度为 0;响应为 `uint32 cmd + uint32 JSON/数据长度 + payload` |
| 固件升级 | TCP 设备端 `4941` | `uint32 cmd + uint32 长度 + 32字节ASCII小写MD5十六进制文本 + ROM原始字节`;长度是 MD5 文本与 ROM 字节数之和 |
V1 多字节整数由源码中的 `QDataStream` 默认网络字节序编码(大端)。TCP 是字节流,必须先累积完整 8 字节响应头,再按头内长度读取完整 payload;不能假定一次 `recv` 返回一整帧。JSON 请求/响应的长度不包含 8 字节头。搜索响应也必须校验命令、长度和请求 `session`。
### V1 搜索
源码:`EpSearchPanocsInLan.cpp`、`json/SerachCameraRequest.cpp`、`json/SerachCameraResponse.cpp`。
请求命令 `0x5a0eff00`,响应命令 `0x5a0eff01`。请求 JSON 至少带随机 `session`:
```json
{"session":12345}
```
响应常见字段:`session`、`ip`、`dev_type`、`sn`、`mac`、`firmware`、`hardware`、`dev_id`、`dev_ver`,部分设备另有 `ipv6`、`wifi_ssid`、`wifi_quality`。按回显 session 过滤本轮响应。搜索会列出广播域中的多台设备;不得把第一个响应当目标。升级或其他写操作仍要求完整 SN 与型号核验。若设备 SN 为空,只能将搜索结果用于只读信息查询;SN 空值不构成设备身份核验,不能据此绕过写操作的身份保护。
### V1 通用配置读取命令
以下命令来自 `EapilPanoCHead.h` 的 V1 `MessageCMDType`,对应 `EpPanoCConfigure.cpp` 的 getter/query 实现。大部分请求使用空 payload;按返回命令和 JSON `code` 判定设备是否支持,`code=0` 表示设备成功应答,不代表每个可选字段都存在。
| 项目 | 命令 |
|---|---:|
| 获取 SN | `0x5a0e2100` |
| 获取模板 | `0x5a0e2102` |
| 获取基本信息 | `0x5a0e2104` |
| 获取圆心坐标 | `0x5a0e2110` |
| 查询视频参数范围 / 获取视频参数 | `0x5a0e2120` / `0x5a0e2121` |
| 查询音频参数范围 / 获取音频参数 | `0x5a0e2130` / `0x5a0e2131` |
| 查询 ISP 参数范围 / 获取 ISP 参数 | `0x5a0e2140` / `0x5a0e2141` |
| 获取缩略图 | `0x5a0e2150`(二进制 JPEG,不按 JSON 解析)|
| 获取 SD 卡信息 | `0x5a0e21a0` |
| 获取网络信息 | `0x5a0e21b0` |
| 获取 Wi-Fi 信息 | `0x5a0e21c0` |
| 获取时间信息 | `0x5a0e21d0` |
| 获取夜视信息 | `0x5a0e21e0` |
| 获取浪涛兼容 ID | `0x5a0e3100` |
| 获取大拿兼容 ID / danale.conf | `0x5a0e3200` / `0x5a0e3210` |
兼容平台接口可能返回“不支持平台/命令”;要记录为设备能力结果,不要当作传输层故障。`0x5a0e3210` 返回配置内容,可能包含敏感字段;仅在用户任务确需时调用,控制原始结果的保存、展示和转发范围。V1 还定义工厂/扩展类读命令(如 PTZ、MAC、IMEI、老化测试、设备密码等),不属于上述通用配置接口;有的需要特定参数,有的会暴露敏感信息。不要用零参数盲发或把它们当作通用 getter。先从目标型号对应实现核对参数、返回结构和敏感性,再按明确任务范围调用。绝不调用 SET 命令来“探测”支持能力。
### V1 固件升级
V1 升级命令为 `0x5a0e2170`,TCP 端口 `4941`。实现依据 `EpConnection::sendTcpFile`:计算 ROM MD5 并转为 32 字节 ASCII 十六进制文本,帧长度字段等于 `32 + ROM字节数`,随后发送 MD5 文本及 ROM 内容。响应仍按 V1 `cmd + length + payload` 解析,成功 JSON 示例为 `{"code":0,"desc":"update success"}`。这不是 V2 `EPFP/4001` 的状态轮询协议;不得把 V2 的 `status=2` 要求硬套到 V1。V1 成功应答后仍须检查串口重启、网络恢复、重新搜索与目标版本回查;缺项必须明确标为未验证。
执行升级前仍遵守本文“升级前保护”与主技能的用户确认要求。已有工具若只支持 V2,不能改参数伪装成 V1;应使用明确实现 V1 的客户端,并保留 ROM 路径、大小、MD5、SHA-256、目标 IP、型号、升级响应及升级后版本证据。完整 SN 缺失时不得以型号/IP 替代身份核验,也不得执行写操作。
### V1 现场验证样例(C4662)
2026-10-21 对一台 C4662 的实测仅作为该设备/固件的实例,不代表所有 V1 设备字段恒定:V1 搜索和基本信息返回 `dev_ver=2.0.20261021.1`、`firmware=1.0.4`、`dev_type=C4662`,但 SN 为空。常见 getter 中视频、音频、ISP、SD、网络、时间、夜视、缩略图和大拿 ID 接口有成功响应;模板、浪涛兼容接口和 danale.conf 在该设备返回失败或不支持。成功但无数据字段的响应(例如 Wi-Fi 信息)应如实记录,不推测配置值。
## 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:
```json
{"cmd":60000,"session":12345}
```
响应必须回显相同 `cmd/session`。身份字段包括 `sn`、顶层烧录 `mac`、`inner`、`outer`、`hardware` 和 `net`。顶层 `mac` 与 `net.mac` 可能不同。型号判断同时展示:
- `inner.type`
- `outer.type`
- `hardware.type`
非关键网络字段允许缺失。完整 SN 是升级身份核对的首要依据。V1 的端口与帧格式见上文 V1 章节,并以目标设备对应的 V1 文档或源码复核;不能套用 V2。
执行发现时使用 `scripts/v2_discover.py`,并遵守以下规则:
1. 默认枚举已启用、已连接且具有有效 IPv4 的物理网卡;回环、断开、APIPA、VPN、VMware、Npcap 等接口要列出并注明排除原因。用户明确要求所有活动接口时才加入虚拟接口。
2. 每个接口分别绑定其本地 IPv4 和客户端端口 `8951`,同时发送有限广播 `255.255.255.255` 和按前缀计算的定向广播。不能把 `/22` 的广播地址按 `/24` 猜测。
3. 如果 UDP `8951` 被 EapilCameraConfigurer 或其他进程占用,报告占用者,不结束进程;请用户释放端口,或使用已有工具明确支持的搜索结果。
4. 从临时源端口发包只可作为诊断。设备可能只向 `8951` 回复,因此临时端口无响应不能证明设备离线。
5. 打印所有合法候选并按完整 SN 精确匹配;不得选择第一台。响应需校验 `EPBP`、长度、`cmd/session`。只有 SN、源 IP、MAC 和型号都一致的重复响应可以合并;同一 SN 对应不同身份信息时报告冲突并禁止自动选择。
6. 未提供完整 `--expected-sn` 时脚本只是列表模式,即使退出码为 0 也不代表身份核验成功。Telnet、升级及其他设备写操作必须提供完整 SN,并根据任务要求同时传入型号。
## 基础信息
通过 TCP `8942` 发送 `cmd=30101`。响应必须满足:同步头正确、长度合理、`cmd/session` 匹配且 `code=0`。读取:
- `sn`、`mac`
- `inner.type/version`
- `outer.type/version`
- `hardware.type/version`
`hardware.version` 不是固件版本。升级后应根据 ROM 类型比较 `inner.version` 或 `outer.version`。如果无法从 ROM 或构建记录确定应变化的字段,必须明确说明并让用户确认预期。
`30102` 可能返回密码和密钥,只在调试任务确实需要时调用。用户选择保留原始调试数据,因此响应可原样写入本次任务日志,但不得写入 skill 本体。
## 固件升级 4001
请求:
```text
EPFP
+ uint32 4001
+ uint32 ROM字节数
+ ROM原始字节
```
ROM 前没有 MD5 或目标路径业务前缀。不要把普通文件写入 `2001` 的 MD5 机制声称为升级 `4001` 自带校验。
状态业务数据为 21 字节:
```text
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`,不绕过其保护参数。
串口登录可以确认现场设备、读取版本并恢复网络,但不能替代升级前的 `30101` 身份响应。即使 COM 口已由用户确认且串口内的 SN、型号看似匹配,`30101` 超时、返回不完整或不匹配时仍不得发送 ROM。先检查设备端端口监听、接口 MAC、关联、DHCP、PC 多网卡选路和二层可达性;恢复后重新运行标准预检。
## 已知协议歧义
- 状态章节没有明确说明每次状态是否带 EPFP 外层头,因此客户端兼容完整帧和裸状态。
- 没有规定分块大小、连接关闭方、断线恢复或统一总超时;使用可配置值并保存最后进度。
- 没有定义 ROM 与型号的自动匹配机制。
- TCP 是字节流,必须累积并按长度解析,不能把单次 `recv` 当作完整帧。