Files
softbus_daemon/docs/EDGE_UPLINK_PROTOCOL_v1.md
flower_linux 238b814057 edge split
2026-05-13 16:45:31 +08:00

8.2 KiB
Raw Blame History

SoftBus 边缘上行协议 v1EDGE_UPLINK_PROTOCOL_v1

本文档定义 边缘 edge_agent → 核心 softbus_daemon 的 TCP 二进制帧格式,支持:

  • 数据面DATA_RAWBUS(载荷语义对齐 RawBusMessage
  • 控制面:会话、CTRL_TREE_*反向同步 CTRL_TREE_PROPOSE / CTRL_TREE_RESULT

边缘仓库应维护与本文档 字节级一致 的副本(如 docs/UPLINK_PROTOCOL_v1.md)。

1. 传输

  • 传输层TCP由核心监听edgeIngress.listenAddress / port),边缘主动连接。
  • 字节序:多字节整数均为 大端(网络序)
  • 帧大小上限:由核心配置 maxFrameBytes(默认 4MiB强制超限则断开连接。

2. 外层帧(所有 frame_kind 共用)

偏移 长度 字段 说明
0 4 magic 固定 ASCII SBUP0x53 0x42 0x55 0x50
4 2 wire_version 当前为 1
6 2 frame_kind 见 §3
8 4 reserved 填 0
12 4 payload_len 后续 payload 字节数
16 payload_len payload frame_kind 解析

3. frame_kind 枚举u16

名称 方向 说明
1 HELLO 边缘→核心 UTF-8 JSON见 §4
2 ACK 边缘→核心 UTF-8 JSON可选应用下行树后确认
3 DATA_RAWBUS 边缘→核心 二进制,见 §5
4 TREE_FULL 核心→边缘 UTF-8 JSON见 §4.1
5 TREE_PATCH 核心→边缘 UTF-8 JSON预留下行
6 TREE_PROPOSE 边缘→核心 UTF-8 JSON见 §6
7 TREE_RESULT 核心→边缘 UTF-8 JSON见 §7
8 REPORT 边缘→核心 UTF-8 JSON预留

4. HELLO边缘→核心

若核心配置了 authToken(非空),则 首帧必须是 HELLO,否则核心断开。

JSON 字段:

  • edgeIdstring必填与会话绑定后续 TREE_PROPOSE 须与此一致。
  • authTokenstring若核心配置了 token 则必填且相等)。
  • currentTreeRevisioninteger可选边缘当前已应用的 treeRevision,供核心决定是否下行全量。

核心响应:可紧跟发送 TREE_RESULTHELLO 成功后核心会再发送一帧 TREE_FULL(与 push_edge_tree 下行格式相同,见 §4.1)。

4.1 TREE_FULL核心→边缘

UTF-8 JSON置于外层 frame_kind=4 的 payload 中:

  • kind:固定字符串 "TREE_FULL"(便于与纯数组载荷区分)。
  • edgeIdstring与会话绑定边缘应校验与本地 edgeId 一致。
  • treeRevisioninteger导出子树时刻的全局 treeRevision(与 TREE_PROPOSEbaseTreeRevision 语义一致)。
  • treearray节点对象数组字段形状与核心 get_device_tree 中单节点一致(id/name/type/endpoint/driver/capabilitiesRef/params/enabled/children);仅包含 属于该 edge 作用域 的节点(规则同 §6.2)。

tree 表示核心当前未为该 edge 分配任何节点(仍合法)。

5. DATA_RAWBUS 的 payload二进制

外层 payload 内为定长头 + 变长 traceId + 变长 bus payload

偏移 长度 字段 类型
0 2 trace_len u16 BEUTF-8 字节数,最大 512
2 4 device_id i32 BE
6 4 endpoint_hash u32 BE
10 2 protocol u16 BEProtocolType 数值一致
12 2 reserved0 u16 BE0
14 4 logical_address u32 BE
18 8 routing_key u64 BE
26 8 protocol_header 8 字节原始拷贝至 ProtocolHeader union
34 8 timestamp_ms i64 BE
42 1 direction i8BusDirection 枚举数值
43 5 reserved1 填 0
48 trace_len trace_utf8 UTF-8
48+trace_len 剩余 bus_payload 写入 PayloadRef

总长度:48 + trace_len + bus_payload_len 须等于外层 payload_len

5.1 SocketCAN / CAN_RAW(边缘与核心本机可选)

  • endpoint 字符串:建议使用 can:<linux_ifname>,例如 can:vcan0。设备树节点 typecan 或仅依赖 endpoint 前缀推断时,边缘/核心 EdgeDeviceBus / DeviceBusManager 使用 Qt SocketCAN 插件(socketcan)打开对应接口;makeEndpointHash(endpoint) 与串口一致为 qHash(endpoint)
  • bus_payload:单帧 数据场 原始字节08 字节)。DLC=0 的数据帧合法;核心 EdgeTcpIngressServiceprotocol == CAN_RAWCAN_OPEN 时允许空 bus_payload,仍携带 protocol_header 中的 CAN id 元数据。
  • protocolu16:与 ProtocolType 枚举数值一致CAN 上行应使用 CAN_RAW(设备树 params.protocol 常用字符串 can_raw,与 protocolTypeFromHint 一致)。
  • protocol_header8 字节):与 ProtocolHeader::can 一致:cobId29 位有效)、isExtendedisRtr;编码侧将 RawBusMessage::header 按 8 字节写入再参与 DATA_RAWBUS 定长头(与现有 Modbus 头填法相同,见实现 encodeDataRawBusPayload)。

6. TREE_PROPOSE边缘→核心反向同步

UTF-8 JSON。

6.1 固定字段

  • edgeIdstring须与 HELLO 中一致。
  • baseTreeRevisioninteger全局树 revision(与核心 DeviceTreeModel::treeRevision() 一致);不一致则 CONFLICT
  • entriesarray必填每项为下列之一。

6.1.1 patch(默认,与历史行为一致)

  • op 省略或 "patch"
  • idstring必填须已存在于设备树。
  • patchobject必填字段规则与 D-Bus patch_device_tree_nodepatch 相同(name/type/endpoint/driver/capabilitiesRef/enabled/params 对象合并)。

6.1.2 upsert(边缘注册新节点或整节点合并)

  • op"upsert"
  • idstring必填目标节点 id。新建时 必须edges/<edgeId>edges/<edgeId>/... 前缀(与 §6.2 作用域一致);已存在节点则按作用域校验后 合并 node 字段。
  • nodeobject必填get_device_tree 单节点形状一致:id/name/type/endpoint/driver/capabilitiesRef/params/enabled/childrenchildren 为子节点 id 字符串数组)。新建时若省略 node.id 则使用条目 id;若 node.id 与条目 id 均非空则须相等。
  • 新建:核心在 params 中未带 edgeId 时自动写入会话 edgeId;合并后节点须满足 §6.2。
  • children:仅允许引用同一边缘子树内的 idedges/<edgeId> 或其前缀下的子 id否则 FORBIDDEN_SCOPE

6.2 作用域MVP

仅允许修改满足以下 任一 条件的节点:

  • node.params.edgeIdstring等于会话 edgeId;或
  • node.id 等于 edges/<edgeId> 或以 edges/<edgeId>/ 为前缀。

否则整批 拒绝FORBIDDEN_SCOPE)。

6.3 并发

与 D-Bus patch_device_tree_node 共用 DeviceTreeModel 写锁,保证 revision 单调、无丢失更新。成功应用后,核心还会向该会话 edgeId 的所有已 HELLO 连接 再发一帧 TREE_FULL(与 push_edge_tree 载荷一致),便于边缘落盘与 revision 对齐。

7. TREE_RESULT核心→边缘

UTF-8 JSON

  • okbool
  • codestringOK | CONFLICT | FORBIDDEN_SCOPE | INVALID_JSON | NODE_NOT_FOUND | VALIDATION_ERROR
  • messagestring可选
  • newTreeRevisioninteger成功时应用后的 revision
  • currentTreeRevisionintegerCONFLICT 时建议带):核心当前 revision

8. treeRevision 语义MVP

  • 核心在进程内维护单调递增的 treeRevision(从 1 起,每次成功变更设备树内存模型后 +1
  • 守护进程重启后 revision 重置MVP边缘应在 HELLO 后若收到 CONFLICT 或 revision 不明,依赖核心自动下发的 TREE_FULLpush_edge_tree 运维命令,或重新下发配置。

9. 与 orchestrator / D-Bus

核心侧设备树持久化与 reconcile 行为与现有 patch_device_tree_node 一致;本协议为 额外入口,不得绕过校验逻辑。