# softbus_edge

**路径：** `src/softbus_edge`  
**构建目标：** `softbus_edge`（EXECUTABLE）  
**层级：** L3 可执行层

## 1. 概述

`softbus_edge` 是边缘代理可执行文件，负责设备数据采集（ingress）、原始包上行（egress）与下行命令接收。Phase 1 使用 `MockModbusIngress` 模拟 Modbus 数据，无真实硬件依赖。

## 2. CONSTRAINTS

- 边缘代理不得直接操作 OPC UA 或插件解析，仅产生 `RawPacket` 并发送。
- ingress 实现须遵循 `IIngressPort` 接口，便于 Phase 2 替换为真实硬件驱动。
- 下行命令 Phase 1 仅日志输出，不得假装已写回设备。
- 边缘代理通过 CLI 参数配置连接地址，不读取 `daemon_profile.json`。

## 3. 组件架构

```
main.cpp
  ├── MockModbusIngress (IIngressPort)  ← 入站采集
  ├── UplinkClient (egress)             ← TCP 上行/下行
  ├── DeviceFactory                     ← 运行时设备 ID 生成
  └── DeviceDiscovery                   ← 设备发现（Phase 1 stub）
```

## 4. 核心组件

### 4.1 IIngressPort — 入站抽象

| 方法 | 说明 |
|------|------|
| `open()` | 打开采集通道 |
| `close()` | 关闭采集通道 |
| `poll()` | 轮询，返回 `vector<RawPacket>` |

**Phase 1 实现：** `MockModbusIngress`

- 生成递增的 Modbus RTU 0x03 响应帧
- 寄存器值按 0.1 缩放（与 `ModbusParser` 一致）
- `sourceId` 使用 CLI 指定的 objectRef

### 4.2 UplinkClient — 上行客户端

对 `TcpUplinkClient` 的薄封装：

| 方法 | 说明 |
|------|------|
| `connect(host, port)` | 连接守护进程 |
| `sendRawPacket(RawPacket)` | 发送上行原始包 |
| `poll()` | 轮询接收下行命令 |
| `setCommandHandler(handler)` | 注册命令回调 |

### 4.3 DeviceFactory

| 方法 | 说明 |
|------|------|
| `createRuntimeDevice()` | 生成 `runtime-xxxxxxxx` ID |

### 4.4 DeviceDiscovery（Phase 1 stub）

| 方法 | 说明 | Phase 1 行为 |
|------|------|-------------|
| `discover()` | 扫描可用设备 | 返回空列表 |

## 5. 主循环

```cpp
while (running) {
    // 1. 采集
    auto packets = ingress.poll();
    for (auto& packet : packets) {
        uplink.sendRawPacket(packet);
    }

    // 2. 接收命令
    uplink.poll();

    // 3. 平台信号检查
    if (PlatformSignal::interrupted()) break;
}
```

## 6. CLI 参数

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--daemon host:port` | `127.0.0.1:9000` | 守护进程地址 |
| `--object-ref path` | `DemoSite/DemoSystem/DemoAsset/SimModbusDevice/Temperature` | 模拟数据源对象路径 |

## 7. 数据流

### 7.1 上行

```
MockModbusIngress.poll()
  → RawPacket(sourceId=objectRef, protocolTag="modbus", payload=Modbus frame)
  → UplinkClient.sendRawPacket()
  → TcpUplinkClient → TCP JSON → Daemon
```

### 7.2 下行

```
Daemon CommandDispatcher
  → TCP JSON → TcpUplinkClient
  → UplinkClient.poll() → commandHandler
  → Phase 1: Logger 输出命令内容
```

## 8. 依赖

- `softbus_core`（RawPacket, DeviceIdentity, Logger, PlatformSignal）
- `softbus_transport`（TcpUplinkClient, UplinkWire）
- `softbus_api`（ExecuteCommand）
- `asio`

## 9. 运行示例

```bash
# 确保守护进程已启动
./build/bin/softbus_edge --daemon 127.0.0.1:9000

# 指定自定义对象路径
./build/bin/softbus_edge \
  --daemon 127.0.0.1:9000 \
  --object-ref DemoSite/DemoSystem/DemoAsset/SimModbusDevice/Temperature
```

## 10. Phase 2 规划

- 实现真实 `SerialIngress` / `CanIngress` 替换 Mock
- 下行 `ExecuteCommand` 写回设备（Modbus 写寄存器等）
- 设备发现与动态注册
- 支持 SBUP 二进制协议
