opc source code
This commit is contained in:
220
docs/plugins.md
Normal file
220
docs/plugins.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# 协议插件
|
||||
|
||||
**路径:** `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 插件完整功能
|
||||
- 支持多插件并行加载与协议自动选择
|
||||
- 插件热加载与版本管理
|
||||
Reference in New Issue
Block a user