12 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\EpProtocolDemoE:\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:
{"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:
{"cmd":60000,"session":12345}
响应必须回显相同 cmd/session。身份字段包括 sn、顶层烧录 mac、inner、outer、hardware 和 net。顶层 mac 与 net.mac 可能不同。型号判断同时展示:
inner.typeouter.typehardware.type
非关键网络字段允许缺失。完整 SN 是升级身份核对的首要依据。V1 的端口与帧格式见上文 V1 章节,并以目标设备对应的 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,不绕过其保护参数。
串口登录可以确认现场设备、读取版本并恢复网络,但不能替代升级前的 30101 身份响应。即使 COM 口已由用户确认且串口内的 SN、型号看似匹配,30101 超时、返回不完整或不匹配时仍不得发送 ROM。先检查设备端端口监听、接口 MAC、关联、DHCP、PC 多网卡选路和二层可达性;恢复后重新运行标准预检。
已知协议歧义
- 状态章节没有明确说明每次状态是否带 EPFP 外层头,因此客户端兼容完整帧和裸状态。
- 没有规定分块大小、连接关闭方、断线恢复或统一总超时;使用可配置值并保存最后进度。
- 没有定义 ROM 与型号的自动匹配机制。
- TCP 是字节流,必须累积并按长度解析,不能把单次
recv当作完整帧。