221 lines
5.8 KiB
Markdown
221 lines
5.8 KiB
Markdown
|
|
# 协议插件
|
|||
|
|
|
|||
|
|
**路径:** `src/plugins`
|
|||
|
|
**构建目标:** `protocol_modbus`、`protocol_canopen`(SHARED 库)
|
|||
|
|
**层级:** L2 协议层
|
|||
|
|
|
|||
|
|
## 1. 概述
|
|||
|
|
|
|||
|
|
协议插件以动态库(`.so` / `.dll`)形式实现 `IFramer` 与 `IParser` 接口,由 `PluginLoader` 在运行时加载。守护进程 Pipeline 通过插件完成原始字节的分帧与语义解析。
|
|||
|
|
|
|||
|
|
## 2. CONSTRAINTS
|
|||
|
|
|
|||
|
|
- 插件须通过 C ABI 导出 `create_framer` / `create_parser` / `destroy_*` 函数。
|
|||
|
|
- 插件仅依赖 `softbus_core`,不得链接 daemon、opcua 或 transport。
|
|||
|
|
- 解析输出必须为 `DOMMessage`,不得引入传输层特定字段。
|
|||
|
|
- 新增协议插件须遵循相同目录结构与 CMake 宏 `softbus_add_plugin`。
|
|||
|
|
- Phase 1 modbus 插件硬编码寄存器 40001,不读取 ObjectModel 映射表。
|
|||
|
|
|
|||
|
|
## 3. 插件接口
|
|||
|
|
|
|||
|
|
### 3.1 IFramer
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
class IFramer {
|
|||
|
|
public:
|
|||
|
|
virtual FrameResult extract(const uint8_t* data, std::size_t size) = 0;
|
|||
|
|
virtual const char* protocolName() const = 0;
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**FrameResult 字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `success` | 是否成功提取完整帧 |
|
|||
|
|
| `consumedBytes` | 已消费字节数 |
|
|||
|
|
| `frameStartOffset` | 帧起始偏移 |
|
|||
|
|
| `frame` | 提取的完整帧数据 |
|
|||
|
|
|
|||
|
|
### 3.2 IParser
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
class IParser {
|
|||
|
|
public:
|
|||
|
|
virtual ParseResult parseFrame(const uint8_t* data, std::size_t size,
|
|||
|
|
const std::string& sourceId) = 0;
|
|||
|
|
virtual const char* protocolName() const = 0;
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**ParseResult 字段:**
|
|||
|
|
|
|||
|
|
| 字段 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| `success` | 是否解析成功 |
|
|||
|
|
| `message` | 输出的 `DOMMessage` |
|
|||
|
|
|
|||
|
|
### 3.3 C ABI 导出
|
|||
|
|
|
|||
|
|
每个插件须实现:
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
extern "C" SOFTBUS_PLUGIN_API IFramer* create_framer();
|
|||
|
|
extern "C" SOFTBUS_PLUGIN_API void destroy_framer(IFramer* framer);
|
|||
|
|
extern "C" SOFTBUS_PLUGIN_API IParser* create_parser();
|
|||
|
|
extern "C" SOFTBUS_PLUGIN_API void destroy_parser(IParser* parser);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 4. protocol_modbus
|
|||
|
|
|
|||
|
|
**路径:** `src/plugins/protocol_modbus`
|
|||
|
|
**输出:** `libprotocol_modbus.so`
|
|||
|
|
|
|||
|
|
### 4.1 组件
|
|||
|
|
|
|||
|
|
| 组件 | 文件 | 职责 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| `ModbusFramer` | `ModbusFramer.h/.cpp` | 识别 func=0x03 响应帧 |
|
|||
|
|
| `ModbusParser` | `ModbusParser.h/.cpp` | 解析寄存器值 → DOMMessage |
|
|||
|
|
| `modbus_plugin.cpp` | C ABI 导出 | 工厂函数 |
|
|||
|
|
|
|||
|
|
### 4.2 ModbusFramer
|
|||
|
|
|
|||
|
|
- 识别 Modbus RTU 功能码 0x03(读保持寄存器)响应帧
|
|||
|
|
- 根据字节计数与数据长度判断帧完整性
|
|||
|
|
- 输出完整帧供 Parser 消费
|
|||
|
|
|
|||
|
|
### 4.3 ModbusParser
|
|||
|
|
|
|||
|
|
- 解析 0x03 响应帧中的寄存器值
|
|||
|
|
- 应用缩放因子 0.1(硬编码)
|
|||
|
|
- 输出 `DOMMessage`:
|
|||
|
|
- `id` = sourceId
|
|||
|
|
- `value` = `{"registerValue": <scaled_value>}`
|
|||
|
|
- `quality` = `"Good"`
|
|||
|
|
|
|||
|
|
### 4.4 Phase 1 限制
|
|||
|
|
|
|||
|
|
- 仅支持功能码 0x03 响应
|
|||
|
|
- 硬编码寄存器地址 40001
|
|||
|
|
- 不读取 `ObjectModelRegistry` 的寄存器映射
|
|||
|
|
|
|||
|
|
### 4.5 数据流
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
RawPacket.payload (Modbus bytes)
|
|||
|
|
→ ModbusFramer.extract() → 完整帧
|
|||
|
|
→ ModbusParser.parseFrame() → DOMMessage
|
|||
|
|
→ UaModelBinder.bind()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 5. protocol_canopen
|
|||
|
|
|
|||
|
|
**路径:** `src/plugins/protocol_canopen`
|
|||
|
|
**输出:** `libprotocol_canopen.so`
|
|||
|
|
|
|||
|
|
### 5.1 组件状态
|
|||
|
|
|
|||
|
|
| 组件 | Phase 1 状态 |
|
|||
|
|
|------|-------------|
|
|||
|
|
| `CanopenFramer` | stub(空实现) |
|
|||
|
|
| `CanopenParser` | stub(空实现) |
|
|||
|
|
| `CanopenObjectDictionary` | stub |
|
|||
|
|
| `EdsDcfLoader` | stub |
|
|||
|
|
| `CanopenNodeManager` | stub |
|
|||
|
|
| `CanopenMapper` | stub |
|
|||
|
|
| `canopen_plugin.cpp` | C ABI 导出存在,功能未实现 |
|
|||
|
|
|
|||
|
|
### 5.2 规划结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
CanopenFramer ← CAN 帧分帧
|
|||
|
|
CanopenParser ← PDO/SDO 解析
|
|||
|
|
CanopenObjectDictionary ← 对象字典管理
|
|||
|
|
EdsDcfLoader ← EDS/DCF 文件加载
|
|||
|
|
CanopenNodeManager ← 节点状态管理
|
|||
|
|
CanopenMapper ← 对象字典 → DOMMessage 映射
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 集成状态
|
|||
|
|
|
|||
|
|
- `daemon_profile.json` 已配置 `"canopen": "protocol_canopen"`
|
|||
|
|
- `CoreService` Phase 1 **仅加载 modbus 插件**,canopen 未接入
|
|||
|
|
|
|||
|
|
## 6. 插件开发指南
|
|||
|
|
|
|||
|
|
### 6.1 目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/plugins/protocol_<name>/
|
|||
|
|
├── CMakeLists.txt
|
|||
|
|
├── include/<name>/
|
|||
|
|
│ ├── <Name>Framer.h
|
|||
|
|
│ └── <Name>Parser.h
|
|||
|
|
└── src/
|
|||
|
|
├── <Name>Framer.cpp
|
|||
|
|
├── <Name>Parser.cpp
|
|||
|
|
└── <name>_plugin.cpp
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.2 CMakeLists.txt 模板
|
|||
|
|
|
|||
|
|
```cmake
|
|||
|
|
softbus_add_plugin(protocol_<name>
|
|||
|
|
SOURCES
|
|||
|
|
src/<Name>Framer.cpp
|
|||
|
|
src/<Name>Parser.cpp
|
|||
|
|
src/<name>_plugin.cpp
|
|||
|
|
DEPENDS softbus_core
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.3 开发步骤
|
|||
|
|
|
|||
|
|
1. 实现 `IFramer::extract()` — 从字节流提取完整协议帧
|
|||
|
|
2. 实现 `IParser::parseFrame()` — 将帧解析为 `DOMMessage`
|
|||
|
|
3. 在 `<name>_plugin.cpp` 中导出 C ABI 工厂函数
|
|||
|
|
4. 在 `daemon_profile.json` → `plugins` 中注册插件名
|
|||
|
|
5. 在 `CoreService` 中加载并注入 `PipelineEngine`
|
|||
|
|
|
|||
|
|
### 6.4 DOMMessage 输出约定
|
|||
|
|
|
|||
|
|
| 字段 | 要求 |
|
|||
|
|
|------|------|
|
|||
|
|
| `id` | 设为 sourceId(objectRef 路径) |
|
|||
|
|
| `sourceId` | 保持传入值 |
|
|||
|
|
| `domain` | 来自模型或默认 `"Process"` |
|
|||
|
|
| `quality` | `"Good"` / `"Bad"` / `"Uncertain"` |
|
|||
|
|
| `value` | JSON 对象,至少含 `"value"` 或 `"registerValue"` 数值字段 |
|
|||
|
|
|
|||
|
|
## 7. 插件搜索与加载
|
|||
|
|
|
|||
|
|
守护进程通过 `CoreService::resolvePluginPath()` 搜索插件,配置文件 `daemon_profile.json`:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"plugins": {
|
|||
|
|
"modbus": "protocol_modbus",
|
|||
|
|
"canopen": "protocol_canopen"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
键名(如 `modbus`)用于代码中选择插件,值(如 `protocol_modbus`)用于文件名解析。
|
|||
|
|
|
|||
|
|
## 8. 构建
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cmake --build build --target protocol_modbus
|
|||
|
|
cmake --build build --target protocol_canopen
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
输出:`build/lib/libprotocol_modbus.so`、`build/lib/libprotocol_canopen.so`
|
|||
|
|
|
|||
|
|
## 9. Phase 2 规划
|
|||
|
|
|
|||
|
|
- modbus 插件读取 `ObjectModelRegistry` 寄存器映射
|
|||
|
|
- 实现 canopen 插件完整功能
|
|||
|
|
- 支持多插件并行加载与协议自动选择
|
|||
|
|
- 插件热加载与版本管理
|