Files
embedded-app-pc-debug/references/device-protocols.md
T

12 KiB
Raw Blame History

设备发现、基础信息与升级协议

仅在任务涉及设备网络发现、版本查询或 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:

{"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.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

请求:

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 当作完整帧。