# 协议插件 **路径:** `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": }` - `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_/ ├── CMakeLists.txt ├── include// │ ├── Framer.h │ └── Parser.h └── src/ ├── Framer.cpp ├── Parser.cpp └── _plugin.cpp ``` ### 6.2 CMakeLists.txt 模板 ```cmake softbus_add_plugin(protocol_ SOURCES src/Framer.cpp src/Parser.cpp src/_plugin.cpp DEPENDS softbus_core ) ``` ### 6.3 开发步骤 1. 实现 `IFramer::extract()` — 从字节流提取完整协议帧 2. 实现 `IParser::parseFrame()` — 将帧解析为 `DOMMessage` 3. 在 `_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 插件完整功能 - 支持多插件并行加载与协议自动选择 - 插件热加载与版本管理