# 数据流转

## 1. 概念约定

| 术语 | 类型/类 | 说明 |
|------|---------|------|
| **原始包** | `RawPacket` | 边缘上行边界类型，含 `traceId`、`timestampNs`、`runtimeDeviceId`、`sourceId`、`protocolTag`、`payload` |
| **语义消息** | `DOMMessage` | 协议解析后的统一业务消息，含 `id`、`sourceId`、`domain`、`quality`、`value`(JSON) |
| **对象引用** | `ObjectRef` | 五层寻址：`Site/System/Asset/Device/Point`，`toPath()` 生成路径字符串 |
| **控制命令** | `ExecuteCommand` | 下行控制面载荷，含 `objectRef`、`command`、`params` |
| **线消息** | `WireMessage` | TCP 传输层消息，类型为 `RawPacket` 或 `ExecuteCommand` |

---

## 2. 上行主链路（边缘 → OPC UA）

### 2.1 边缘采集

`softbus_edge` 主循环执行：

1. `MockModbusIngress::poll()` 生成模拟 Modbus RTU 0x03 响应帧
2. 构造 `RawPacket`：
   - `sourceId` = objectRef 路径（如 `DemoSite/DemoSystem/DemoAsset/SimModbusDevice/Temperature`）
   - `protocolTag` = `"modbus"`
   - `payload` = 原始 Modbus 字节
   - `traceId` = `trace-xxxxxxxx`（由 `DeviceIdentity` 生成）
3. `UplinkClient::sendRawPacket()` 调用传输层编码并发送

### 2.2 TCP 传输

`TcpUplinkClient` 将 `RawPacket` 编码为 JSON 行（详见 [UPLINK_WIRE_PROTOCOL.md](UPLINK_WIRE_PROTOCOL.md)），经 TCP 发送至守护进程 `:9000`。

### 2.3 守护进程接收

`TcpUplinkServer` 按行解码，触发 `rawHandler(RawPacket)` 回调，`CoreService` 将其投递至 `PipelineEngine::process()`。

### 2.4 Pipeline 处理

`PipelineEngine` 三阶段串行处理：

| 阶段 | 组件 | 输入 | 输出 |
|------|------|------|------|
| Stage 1 分帧 | `ModbusFramer` | 原始 payload 字节流 | 完整 Modbus 帧 |
| Stage 2 解析 | `ModbusParser` | 完整帧 + sourceId | `DOMMessage`（含 registerValue） |
| Stage 3 绑定 | `UaModelBinder` | `DOMMessage` | OPC UA Variable 写值 |

解析成功后补充 `traceId` 与 `timestampNs`，调用 `binder_->bind(parsed.message)`。

### 2.5 OPC UA 暴露

`UaModelBinder::bind()` 流程：

1. 以 `message.id`（或 `message.sourceId`）查 `pointNodes_` 映射表
2. 从 `message.value` 提取 `value` 或 `registerValue`（Double）
3. `UA_Server_writeValue()` 更新对应 Variable 节点
4. OPC UA 客户端可读最新值

---

## 3. 下行主链路（OPC UA → 边缘）

### 3.1 OPC UA 方法调用

客户端调用地址空间中的 `ExecuteCommand` Method：

- 节点路径：`ObjectsFolder/SoftBusControl/ExecuteCommand`
- 入参：JSON 字符串（`ExecuteCommand` 序列化）
- 出参：JSON 字符串 `{"success":true}` 或 `{"success":false,"error":"..."}`

### 3.2 守护进程分发

```
UaMethodBinder::executeCommandMethod()
  → ExecuteCommand::fromJson() + validate()
  → UaMethodBinder::dispatchCommand()
  → CommandDispatcher::dispatch()
  → TcpUplinkServer::sendCommand()
```

### 3.3 边缘接收

`TcpUplinkClient` 解码 `ExecuteCommand` 线消息，触发 `commandHandler`。Phase 1 仅日志输出，未写回真实设备。

---

## 4. 自测模式数据流

`softbus_daemon --self-test` 启动后自动执行一次下行写命令：

```json
{
  "type": "executeCommand",
  "traceId": "trace-selftest",
  "objectRef": "DemoSite/DemoSystem/DemoAsset/SimModbusDevice/Temperature",
  "command": "write",
  "params": {"value": 42.5}
}
```

用于验证 OPC UA Method → CommandDispatcher → TCP → Edge 全链路。

---

## 5. 字段映射对照

### 5.1 RawPacket → DOMMessage

| RawPacket 字段 | DOMMessage 字段 | 说明 |
|----------------|-----------------|------|
| `sourceId` | `sourceId` / `id` | 对象路径，解析器可能覆盖 `id` |
| `traceId` | `traceId` | Pipeline 补充 |
| `timestampNs` | `timestampNs` | Pipeline 补充 |
| `payload` | — | 经 Framer/Parser 消费 |
| — | `value` | 解析器输出 JSON，如 `{"registerValue": 25.3}` |
| — | `domain` | 来自模型定义，默认 `Process` |
| — | `quality` | 解析器设置，默认 `Good` |

### 5.2 DOMMessage → OPC UA Variable

| DOMMessage 字段 | OPC UA 属性 | 说明 |
|-----------------|-------------|------|
| `id` / `sourceId` | NodeId 查找键 | 映射表 `pointNodes_` |
| `value.value` 或 `value.registerValue` | Variable Value (Double) | `UaModelBinder` 提取 |
| `quality` | — | Phase 1 未映射至 StatusCode |
| `timestampNs` | — | Phase 1 未映射至 SourceTimestamp |

---

## 6. 与 soft_bus 主项目差异

| 环节 | soft_bus | softbus_OPC |
|------|----------|-------------|
| 边缘入口 | `SerialDevice` + `DriverIngressAdapter` | `MockModbusIngress` |
| 传输协议 | SBUP 二进制帧 | UplinkWire JSON 行 |
| 管道调度 | 多线程分帧 + 解析线程池 | 单线程同步 `process()` |
| 北向出口 | 消息总线 / HTTP API | OPC UA Variable 绑定 |
| 下行控制 | HTTP / D-Bus | OPC UA Method + TCP |
