Files
Artemis-Plugins/plugins/artemis-device-test/skill/references/v1-protocol.md
T

8.3 KiB
Raw Blame History

V1 搜索、查询与固件下发

本页摘记已实现接口;来源文件、修订及摘要见 协议范围。完整原文保留在资料提供方本地,分发包不附其他配置章节。实现在 scripts/v1_protocol.py,由适配器 --protocol v1 路由,不发送 V2 报文。

报文与端口

报文头共 8 字节:CMD、Length 各为网络字节序 U32,随后是恰好 Length 字节的 Data。长度按字节计算。只读 JSON 响应须为 UTF-8 对象;实现拒绝命令/长度不符、超过 1 MiB、错误类型及未完整接收的报文。

操作 传输 请求 返回
搜索 设备 UDP 4942,广播 0x5a0eff00;JSON {"session":1234},每次使用新的随机整数 0x5a0eff01;同一整数 session,完整字符串 sn,以及 dev_type、ip、mac、firmware、hardware
基本/固件信息 设备 TCP 4941 0x5a0e2104;Length=0,无 Data;十六进制请求 5a0e210400000000 同命令 JSON;整数 code=0 成功,其他值失败
固件升级 设备 TCP 4941 0x5a0e2170;Data 为小写 ASCII MD5[32] + ROM,Length=32+ROM字节数 同命令、完整 JSON、整数 code=0;只确认协议应答,另行回读版本

TCP 查询处理报文分片,在连接/发送/接收阶段扣减同一时限,不自动重试。较新工厂文档建议查询 5 秒无响应超时,示例显式使用 --timeout 5。主机名解析及多地址尝试由系统 socket 负责,严格现场时限宜使用已确认的数字设备 IP。

广播接收绑定 0.0.0.0:<client-port>,默认 4942;请求从同一 socket 发到各选定 IPv4 网段的定向广播地址,目的端口 4942。默认枚举已启用物理网卡并排除回环/APIPA;可用 --interface IPv4/PREFIX 指定网段。相同网段只发一次,/31、/32 跳过。出接口服从 Windows 路由,特殊路由环境需现场核实。原文未规定客户端接收端口;默认 4942 是本机已验证的实现选择,--client-port 可调整,不能推广为所有固件的规范要求。

设备可能广播回复,因此接收 socket 不只绑定某个单播 IP。不启用端口复用、不结束占用进程;端口被占用时报告错误并释放本次 socket。忽略自身请求、错误 session/帧和非成功 code,精确筛选完整 SN/型号。按 SN、UDP 源 IP、MAC、型号去重;同 SN 出现冲突身份时阻断选择。后续连接使用实际 UDP 源 IP,报文中的 ip 只保留为观测。无响应只说明本轮未发现,不等于设备离线。

身份与版本字段

2104 保留文档字段 code、desc、sn、dev_type、firmware、hardware、dev_id、dev_ver。除整数 code 外均按字符串校验。如果设备额外直接上报 inner.version 或 outer.version 字符串,只保留该字面路径的版本值,供任务明确指定字段时观测;不保留其余未知字段。

字段 文档含义 用途
sn 设备 SN 与本次完整 SN 精确比较,不截尾、不去空格
dev_type 设备类型 V1 --expected-model 唯一匹配字段
dev_id 设备 ID 只保留,不代替型号
firmware 固件版本号 可由任务明确选择为原生固件验收字段
dev_ver 设备版本号 可由任务明确选择,不推断与 V2 字段的关系
hardware 硬件版本号 只观测,不作为固件验收

两份文档和 V1 查询源码没有 firmware/dev_ver 到 inner.version/outer.version 的对应关系。选择缺失的 outer.version 得到 INCOMPLETE,不会把 firmware 或 dev_ver 自动改名。如果设备直接上报所选字面路径,则可按该值比较。设备/文件名看起来可以猜出对应关系,也不能据此完成指定字段验收。

适配器用显式封套区分协议:

{"protocol":"v1","cmd":1510875396,"code":0,"data":{"code":0,"sn":"<完整SN>","dev_type":"<型号>","firmware":"<版本>"}}

1510875396 是 0x5a0e2104 的十进制值。封套是适配器输出格式;线上 Data 是内部 JSON 本身。verify-version --response 接受此封套,或含 response 的完整 CLI 输出;不能使用 V2 30101 文件冒充 V1 响应。

调用示例

在技能目录执行,下列值均为占位符。型号未知时先 identify,只证明 SN 一致并观察型号,返回 model_verified=false;再带实测型号执行 info/预检。

python scripts/device_adapter.py discover --protocol v1 --interface "<本机IPv4/前缀>" --expected-sn "<完整SN>" --timeout 5
python scripts/device_adapter.py identify --protocol v1 --host "<设备IP>" --expected-sn "<完整SN>" --timeout 5
python scripts/device_adapter.py info --protocol v1 --host "<设备IP>" --expected-sn "<完整SN>" --expected-model "<实测dev_type>" --timeout 5
python scripts/device_adapter.py upgrade --protocol v1 --host "<数字设备IP>" --expected-sn "<完整SN>" --expected-model "<实测dev_type>" --rom "<ROM路径>" --rom-sha256 "<64位SHA256>" --target-version "<目标版本>" --version-field firmware --timeout 5
python scripts/device_adapter.py upgrade --protocol v1 --host "<数字设备IP>" --expected-sn "<完整SN>" --expected-model "<实测dev_type>" --rom "<ROM路径>" --rom-sha256 "<审阅过的64位SHA256>" --target-version "<目标版本>" --version-field firmware --timeout 5 --execute
python scripts/device_adapter.py verify-version --protocol v1 --host "<设备IP>" --expected-sn "<完整SN>" --expected-model "<实测dev_type>" --target-version "<目标版本>" --version-field firmware --timeout 5

只有任务明确选择 firmware 时才使用示例字段;已有其他验收条件时保持原条件。V1 upgrade 默认返回 PREFLIGHT_ONLY,preflight_complete=true、write_supported=true、write_executed=false;selected_version_field_available 说明指定字段是否存在。当前任务已授权升级时,带审阅摘要及 --execute 才执行一次下发;不重复请求已给出的授权。

升级报文与完成含义

用户提供的 Qt 源码 EpConnection::sendTcpFile 补齐了文档第 21 节的空白 Data,线格式为:

U32_BE 0x5a0e2170
U32_BE (32 + ROM字节数)
MD5_hex_ascii[32]  # 全 ROM 的 MD5,小写十六进制文本;不是16字节原始摘要
ROM[ROM字节数]

总线上字节数为 ROM大小+40。没有 EPFP 前缀、文件名或自定义块头。源码使用约200 KiB块;TCP分块不改变线上字节序列,CLI采用256 KiB缓冲并处理部分send。不能把同一源码中的 sendTcpFileV2(protocol=1)(端口8940、EPFP/4001)混作此接口。

CLI 在完整 SN/dev_type 在线预检后重新验证 SHA-256。V1 发送器在同一个打开的文件上计算 MD5及SHA-256,核对大小/审阅摘要后才连接;回到文件开头发送,再对发送内容核对 SHA-256。Data长度必须适合 U32。总时限覆盖哈希、连接、发送、接收;各次 socket 操作还有连接/停滞时限。不会重连或自动重试传包,所有退出路径释放句柄。

收到完整 2170 JSON 且整数 code=0、客户端实际发送 ROM 字节数等于文件大小,才返回 PROTOCOL_SUCCESS_POSTCHECK_REQUIRED。acknowledged=true 和 desc 只记录设备应答,不能证明烧录或启动完成。之后有界等待并重新查询同一 SN 的指定版本字段;发送/接收超时、断开或错误也应先只读检查状态,不能自动重刷。缺失验收字段不阻断已授权传包,但必须在最终验收中保留 INCOMPLETE。

验证范围

2026-10-19,全部118项离线测试通过,其中 V1 查询/发现24项、升级14项、适配器28项。V1 测试运行实际编解码及发送器,覆盖已知 MD5报文、分片发送/响应、计数、错误应答、文件变化、总/停滞时限、精确身份、摘要门槛、默认不写入及无自动重刷。

同日,在一台用户授权 V1 设备上完成一次19,420,244字节 ROM 下发,收到同命令code=0/desc=update success。随后连续两次只读查询与原 SN/dev_type 一致,原生 firmware 从2.0.1变为2.0.2、dev_ver 从2.0.20260908.5变为2.0.20260908.6。指定 outer.version 仍缺失,验收为 INCOMPLETE;不改用原生字段冒充指定字段通过。该实测不代表所有 V1 固件兼容,现场身份及日志独立保存。