diff --git a/docs/PowerManager_Optimization_Design.md b/docs/PowerManager_Optimization_Design.md deleted file mode 100644 index 3089a34..0000000 --- a/docs/PowerManager_Optimization_Design.md +++ /dev/null @@ -1,128 +0,0 @@ -# PowerManager系统架构优化设计方案 - -## 1. 总体架构 -```mermaid -classDiagram - class PowerManagerCore { - +startup() - +shutdown() - +getSystemState() - } - - class StateMachineService { - +triggerEvent() - +getCurrentState() - +addStateListener() - } - - class CommunicationMediator { - +registerHandler() - +sendMessage() - +addMessageListener() - } - - PowerManagerCore --> StateMachineService - PowerManagerCore --> CommunicationMediator -``` - -## 2. 状态机重构方案 - -### 2.1 状态设计模式 -```cpp -class IPowerState { -public: - virtual void onEntry(PowerContext&) = 0; - virtual void handleEvent(PowerContext&, const Event&) = 0; - virtual void onExit(PowerContext&) = 0; -}; -``` - -### 2.2 状态转换规则 -```yaml -# states_config.yaml -transitions: - - from: STANDBY - event: START_CMD - to: OPERATING - - from: OPERATING - event: STOP_CMD - to: STANDBY -``` - -## 3. 通信中介者设计 - -### 3.1 核心架构 -```mermaid -sequenceDiagram - participant Upper as 上位机 - participant Mediator as 通信中介者 - participant Lower as 下位机 - - Upper->>Mediator: 控制命令(JSON) - Mediator->>Lower: 设备指令(ProtocolBuffer) - Lower->>Mediator: 状态更新 - Mediator->>Upper: 系统报告 -``` - -### 3.2 关键实现 -```cpp -class CommunicationMediator { - // 线程安全消息队列 - moodycamel::ConcurrentQueue queue; - - // 消息处理线程 - void processMessages() { - while (running) { - Message msg; - if (queue.try_dequeue(msg)) { - handlers[msg.type]->handle(msg); - } - } - } -}; -``` - -## 4. 数据库服务设计 - -### 4.1 日志策略模式 -```cpp -class ILogStrategy { -public: - virtual bool log(const SystemLog& log) = 0; -}; - -class SQLiteLogStrategy : public ILogStrategy { - // SQLite实现... -}; - -class FileLogStrategy : public ILogStrategy { - // 文件系统实现... -}; -``` - -## 5. 实施计划 - -### 5.1 阶段划分 -```mermaid -gantt - title 重构实施甘特图 - section 核心框架 - 接口定义 :2025-04-08, 3d - 基础实现 :2025-04-11, 5d - - section 模块重构 - 状态机 :2025-04-16, 5d - 通信模块 :2025-04-21, 5d - - section 测试验证 - 单元测试 :2025-04-26, 3d - 集成测试 :2025-04-29, 5d -``` - -## 6. 性能指标 - -| 模块 | 当前QPS | 目标QPS | 优化手段 | -|----------------|---------|---------|-----------------------| -| 状态机处理 | 100 | 500 | 无锁状态转换 | -| 消息处理 | 200 | 1000 | 批量处理+线程池 | -| 数据库写入 | 50 | 300 | 异步写入+批量提交 | \ No newline at end of file diff --git a/docs/PowerManager_UI_Design.md b/docs/PowerManager_UI_Design.md deleted file mode 100644 index 0c1597c..0000000 --- a/docs/PowerManager_UI_Design.md +++ /dev/null @@ -1,277 +0,0 @@ -# 上位机控制程序设计文档 - -## 1. 程序架构设计 - -采用MVC模式设计,主要分为以下模块: - -### 1.0 系统架构图 -```mermaid -graph TD - A[用户界面] -->|控制指令| B[控制器] - B -->|发送命令| C[通信模块] - C -->|UDP协议| D[下位机] - D -->|状态反馈| C - C -->|解析数据| B - B -->|更新状态| A - B -->|记录数据| E[数据库] -``` - -### 1.1 消息处理流程 -1. 接收原始UDP数据 -2. 根据消息ID选择解析器 -3. 验证校验码 -4. 解析为结构化数据 -5. 触发状态更新事件 -6. 存储到数据库 - -### 1.1 通信模块 (Model) - 详细设计 - -#### 消息类型映射表 -| 消息ID | 消息名称 | 处理函数 | 更新频率 | -|--------|----------|----------|----------| -| 0x0005 | 高压母线状态 | parse_high_vol_bus | 1Hz | -| 0x0006 | 高压A母线状态 | parse_high_a_vol_bus | 1Hz | -| 0x0007 | 低压主母线状态 | parse_low_main_bus | 1Hz | -| 0x0008 | 低压汇流排状态 | parse_low_bus | 1Hz | - -#### 异常处理机制 -1. 校验失败:丢弃数据并记录错误日志 -2. 超时处理:3次重试后标记设备离线 -3. 数据异常:触发告警并显示在界面 -```python -class UDPMessageHandler: - """UDP消息处理基类""" - def __init__(self, ip, port): - self.ip = ip - self.port = port - self.socket = None - - def connect(self): - """建立UDP连接""" - pass - - def send_message(self, msg): - """发送消息""" - pass - - def receive_message(self): - """接收消息""" - pass - - def close(self): - """关闭连接""" - pass - -class PowerMessageHandler(UDPMessageHandler): - """电源管理专用消息处理器""" - def __init__(self, ip, port): - super().__init__(ip, port) - self.message_parsers = { - 0x0005: self.parse_high_vol_bus, - 0x0006: self.parse_high_a_vol_bus, - # 其他消息类型... - } - - def parse_high_vol_bus(self, data): - """解析高压母线消息""" - pass - - # 其他消息解析方法... -``` - -### 1.2 界面模块 (View) - 详细设计 - -#### 主界面布局 -```mermaid -graph LR - A[标题栏] --> B[状态区] - B --> C[电压电流仪表盘] - B --> D[断路器状态指示灯] - A --> E[控制区] - E --> F[电源控制按钮组] - E --> G[参数设置面板] - A --> H[日志区] - H --> I[实时消息列表] - H --> J[历史记录查询] -``` - -#### 组件说明 -1. 电压电流仪表盘:实时显示各母线电压电流值 -2. 断路器状态指示灯:绿色-闭合,红色-断开 -3. 电源控制按钮组:带防误触保护(需长按3秒) -4. 参数设置面板:输入验证和范围检查 -```python -class MainWindow(tk.Tk): - """主窗口""" - def __init__(self): - super().__init__() - self.title("电源管理系统") - self.geometry("1200x800") - - self.create_widgets() - - def create_widgets(self): - """创建界面组件""" - self.status_frame = StatusFrame(self) - self.control_frame = ControlFrame(self) - self.log_frame = LogFrame(self) - - # 布局管理 - self.status_frame.pack(side=tk.TOP, fill=tk.X) - self.control_frame.pack(side=tk.LEFT, fill=tk.Y) - self.log_frame.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH) - -class StatusFrame(tk.Frame): - """状态显示面板""" - def update_status(self, data): - """更新状态显示""" - pass - -class ControlFrame(tk.Frame): - """控制面板""" - def create_buttons(self): - """创建控制按钮""" - pass -``` - -### 1.3 控制器模块 (Controller) - 详细设计 - -#### 状态管理机制 -1. 使用有限状态机(FSM)管理电源系统状态 -2. 状态转换规则: - - 仅当所有预检通过才允许上电 - - 故障时自动进入安全状态 - - 人工确认后才能复位 - -#### 命令处理流程 -```mermaid -sequenceDiagram - 用户->>界面: 点击控制按钮 - 界面->>控制器: 发送控制命令 - 控制器->>业务逻辑: 验证命令有效性 - 业务逻辑->>通信模块: 发送UDP指令 - 通信模块->>下位机: 传输控制报文 - 下位机-->>通信模块: 返回应答 - 通信模块->>控制器: 更新命令状态 - 控制器->>界面: 显示操作结果 - 控制器->>数据库: 记录操作日志 -``` -```python -class PowerManagerController: - """主控制器""" - def __init__(self): - self.message_handler = PowerMessageHandler("192.168.1.100", 5000) - self.view = MainWindow() - - # 绑定事件 - self.bind_events() - - def bind_events(self): - """绑定UI事件""" - self.view.control_frame.on_button_click = self.handle_control_command - - def handle_control_command(self, cmd): - """处理控制命令""" - pass - - def start(self): - """启动应用程序""" - self.message_handler.connect() - self.view.mainloop() -``` - -## 2. 接口规范 - -### 2.1 模块交互架构 -```mermaid -classDiagram - class Communication { - +send_command(cmd: dict) bool - +get_status() dict - +subscribe(callback: function) - +on_message_received(data: bytes) - } - - class Controller { - +handle_ui_event(event: dict) - +update_system_status(status: dict) - +log_operation(log: dict) - } - - class UI { - +update_status(data: dict) - +show_alert(level: int, msg: str) - +log_message(source: str, msg: str) - } - - Communication --> Controller : 状态更新通知 - Controller --> UI : 界面更新指令 - UI --> Controller : 用户操作事件 -``` - -### 2.2 详细接口定义 - -#### 通信模块 → 控制器 -```python -# 状态更新通知 -{ - "msg_type": "status_update", - "timestamp": "2025-05-04T10:20:00", - "data": { - "voltage": 220.5, - "current": 15.2, - "breaker_state": True - } -} - -# 错误通知 -{ - "msg_type": "error", - "code": 1001, - "message": "校验失败" -} -``` - -#### 控制器 → 界面 -```python -# 状态显示更新 -{ - "component": "voltage_meter", - "value": 220.5, - "unit": "V", - "normal_range": [210, 230] -} - -# 告警信息 -{ - "level": 2, # 1-警告 2-错误 3-严重 - "message": "A相电压过高", - "suggestion": "检查A相负载" -} -``` - -#### 界面 → 控制器 -```python -# 按钮操作事件 -{ - "event_type": "button_click", - "button_id": "power_on", - "timestamp": "2025-05-04T10:20:01" -} - -# 参数设置事件 -{ - "event_type": "param_set", - "param": "voltage_limit", - "value": 230, - "unit": "V" -} -``` - -### 2.3 错误处理规范 -1. 通信错误:自动重试3次后通知控制器 -2. 业务逻辑错误:记录详细日志并通知界面 -3. 界面错误:显示友好提示并保持最后正常状态 - -## 3. 数据库设计 -(之前已完成的数据库表结构...) \ No newline at end of file diff --git a/src/pPowerManger/LowerCommManager.cpp b/src/pPowerManger/LowerCommManager.cpp index a1b1935..c6ed56d 100644 --- a/src/pPowerManger/LowerCommManager.cpp +++ b/src/pPowerManger/LowerCommManager.cpp @@ -342,12 +342,13 @@ bool LowerCommManager::listenThreadFunc() { try { + memset(Buff, 0, sizeof(Buff)); int nRead = m_udpComm->udpScoket->iRecieveMessage(Buff, sizeof(Buff)); cout< 0) { try { - if(m_udpComm->pushMsgToQueue(Buff)) + if(m_udpComm->pushMsgToQueue(Buff, nRead)) { //更新当前状态 if(!updatePoweSystemStates()) diff --git a/src/pPowerManger/sqlit3/SQLite.cpp b/src/pPowerManger/sqlit3/SQLite.cpp index 369dd5f..9491eab 100644 --- a/src/pPowerManger/sqlit3/SQLite.cpp +++ b/src/pPowerManger/sqlit3/SQLite.cpp @@ -3,12 +3,322 @@ #include #include #include +#include #include "../logc/loguru.hpp" namespace { const int SCHEMA_VERSION = 1; } +//==================================================================== +// 列绑定宏:字段名 + SQL 类型 + 绑定器(无捕获函数指针,不抛异常、不分配) +//==================================================================== +#define COL(Struct, member) \ + SQLite::Column{ #member, "INTEGER", [](sqlite3_stmt* s, int& i, const void* o){ \ + sqlite3_bind_int64(s, i++, static_cast(static_cast(o)->member)); } } + +#define COL_AS(Struct, member, colname) \ + SQLite::Column{ colname, "INTEGER", [](sqlite3_stmt* s, int& i, const void* o){ \ + sqlite3_bind_int64(s, i++, static_cast(static_cast(o)->member)); } } + +#define COL_ARR(Struct, arr, index, colname) \ + SQLite::Column{ colname, "INTEGER", [](sqlite3_stmt* s, int& i, const void* o){ \ + sqlite3_bind_int64(s, i++, static_cast(static_cast(o)->arr[index])); } } + +//==================================================================== +// 表描述注册表:DDL(建表) 与 DML(插入) 共用的唯一数据源。 +// 每张协议结构表的数据列只在这里定义一次;id/timestamp 元列由建表逻辑自动追加。 +//==================================================================== +const std::vector& SQLite::allTables() +{ + static const std::vector tables = { + { "ccuState", { + COL(ccuState, fc_mode), + COL(ccuState, fc_status), + COL(ccuState, fc_fault_level), + COL(ccuState, output_power_limit), + COL(ccuState, total_generation_time), + COL(ccuState, total_generation_power), + COL(ccuState, fault_level_1), + COL(ccuState, fault_level_2), + COL(ccuState, fault_level_3), + COL(ccuState, fault_level_4), + COL(ccuState, hydrogen_capacity), + COL(ccuState, liquid_oxygen_capacity), + COL(ccuState, palladium_temp), + COL(ccuState, main_pipe_pressure), + COL(ccuState, aux_pipe_pressure), + COL(ccuState, cabin_pressure1), + COL(ccuState, cabin_pressure2), + COL(ccuState, cabin_temp1), + COL(ccuState, cabin_temp2), + COL(ccuState, cabin_humidity1), + COL(ccuState, cabin_humidity2), + COL(ccuState, flame_detector1), + COL(ccuState, flame_detector2), + COL(ccuState, h2_concentration1), + COL(ccuState, h2_concentration2), + COL(ccuState, h2_concentration3), + COL(ccuState, o2_concentration1), + COL(ccuState, o2_concentration2), + COL(ccuState, ch3oh_concentration1), + COL(ccuState, ch3oh_concentration2), + COL_ARR(ccuState, reserved1, 0, "reserved1_1"), + COL_ARR(ccuState, reserved1, 1, "reserved1_2"), + COL(ccuState, emergency_battery1_voltage), + COL(ccuState, emergency_battery1_current), + COL(ccuState, emergency_battery1_max_temp), + COL(ccuState, emergency_battery1_fault_word), + COL(ccuState, emergency_battery2_voltage), + COL(ccuState, emergency_battery2_current), + COL(ccuState, emergency_battery2_max_temp), + COL(ccuState, emergency_battery2_fault_word), + COL(ccuState, cabin_ox_concentration), + COL(ccuState, cabin_temperature), + COL(ccuState, cabin_humidity), + COL(ccuState, cabin_pressure), + COL(ccuState, power_cabin_ox_concentration), + COL(ccuState, power_cabin_temperature), + COL(ccuState, power_cabin_humidity), + COL(ccuState, power_cabin_pressure), + COL_ARR(ccuState, reserved2, 0, "reserved2"), + COL_ARR(ccuState, dyn_alarm_flag, 0, "dyn_alarm_flag1"), + COL_ARR(ccuState, dyn_alarm_flag, 1, "dyn_alarm_flag2"), + COL_ARR(ccuState, dyn_alarm_flag, 2, "dyn_alarm_flag3"), + COL_ARR(ccuState, dyn_alarm_flag, 3, "dyn_alarm_flag4"), + COL_ARR(ccuState, dyn_alarm_flag, 4, "dyn_alarm_flag5"), + COL_ARR(ccuState, dyn_alarm_flag, 5, "dyn_alarm_flag6"), + COL_ARR(ccuState, ins_alarm_flag, 0, "ins_alarm_flag1"), + COL_ARR(ccuState, ins_alarm_flag, 1, "ins_alarm_flag2"), + COL_ARR(ccuState, ins_alarm_flag, 2, "ins_alarm_flag3"), + COL_ARR(ccuState, ins_alarm_flag, 3, "ins_alarm_flag4"), + COL_ARR(ccuState, ins_alarm_flag, 4, "ins_alarm_flag5"), + COL_ARR(ccuState, ins_alarm_flag, 5, "ins_alarm_flag6"), + COL(ccuState, ins_relay_status1), + COL(ccuState, ins_relay_status2), + COL(ccuState, dyn_relay_status1), + COL(ccuState, dyn_relay_status2), + COL(ccuState, ins_max_discharge_power), + COL(ccuState, dyn_max_discharge_power), + COL(ccuState, ins_soc), + COL(ccuState, dyn_soc), + COL(ccuState, ins_total_energy), + COL(ccuState, dyn_total_energy), + COL(ccuState, ins_power_input), + COL(ccuState, dyn_power_input), + COL(ccuState, ins_charge_status), + COL(ccuState, dyn_charge_status), + COL(ccuState, ins_voltage_link), + COL(ccuState, ins_voltage_pack), + COL(ccuState, ins_current), + COL(ccuState, ins_resistance_pos), + COL(ccuState, ins_resistance_neg), + COL(ccuState, dyn_voltage_link), + COL(ccuState, dyn_voltage_pack), + COL(ccuState, dyn_current), + COL(ccuState, dyn_resistance_pos), + COL(ccuState, dyn_resistance_neg), + COL(ccuState, ins_emergency_status), + COL(ccuState, dyn_emergency_status), + COL_ARR(ccuState, reserved3, 0, "reserved3_1"), + COL_ARR(ccuState, reserved3, 1, "reserved3_2"), + COL(ccuState, ins_soc_threshold1), + COL(ccuState, ins_soc_threshold2), + COL(ccuState, ins_soc_threshold3), + COL(ccuState, dyn_soc_threshold1), + COL(ccuState, dyn_soc_threshold2), + COL(ccuState, dyn_soc_threshold3), + COL(ccuState, ins_power_limit1), + COL(ccuState, ins_power_limit2), + COL(ccuState, dyn_power_limit1), + COL(ccuState, dyn_power_limit2), + COL(ccuState, device_online_flag1), + COL(ccuState, device_online_flag2), + COL(ccuState, reserved4), + COL(ccuState, heartbeat), + }}, + { "disHighVolBusState", { + COL(disHighVolBusState, fuelCellCircuitBreaker), + COL(disHighVolBusState, powerLithiumBatteryCircuitBreaker), + COL(disHighVolBusState, propulsionMotorCircuitBreaker), + COL(disHighVolBusState, lithiumBatteryGroupInstrumentCircuitBreaker), + COL(disHighVolBusState, dcDc5ModuleCircuitBreaker), + COL(disHighVolBusState, bowHighVoltageDistributionBoxCircuitBreaker), + COL(disHighVolBusState, sternFTDevice45CircuitBreaker), + COL(disHighVolBusState, sternRudderSwitch1CircuitBreaker), + COL(disHighVolBusState, sternRudderSwitch2CircuitBreaker), + COL(disHighVolBusState, fbReservedCircuitBreaker), + COL(disHighVolBusState, tyzReservedCircuitBreaker), + COL(disHighVolBusState, reservedCircuitBreaker), + COL(disHighVolBusState, dcDcFaultWord1), + COL(disHighVolBusState, dcDcFaultWord2), + COL(disHighVolBusState, powerBusInsulationStatus), + COL(disHighVolBusState, aBusInsulationStatus), + COL(disHighVolBusState, meterPowerLossSignal), + COL(disHighVolBusState, emergencyPowerLossSignal), + COL(disHighVolBusState, powerBusVoltage), + COL(disHighVolBusState, dcDc5ModuleCurrent), + COL(disHighVolBusState, powerBusCurrent), + COL(disHighVolBusState, busbarAVoltage), + COL(disHighVolBusState, propulsionMotorControlBoxCurrent), + COL(disHighVolBusState, busbarACurrent), + COL(disHighVolBusState, lithiumBatteryGroupMeterCurrent), + COL(disHighVolBusState, bowHighVoltageDistributionBoxCurrent), + COL(disHighVolBusState, sternFTDevice45Current), + COL(disHighVolBusState, tyzReservedSwitchCurrent), + COL(disHighVolBusState, sternRudderSwitch1Current), + COL(disHighVolBusState, reservedCurrent1), + COL(disHighVolBusState, sternRudderSwitch2Current), + COL(disHighVolBusState, reservedCurrent2), + COL(disHighVolBusState, fbReservedSwitchCurrent), + COL(disHighVolBusState, reservedCurrent3), + COL(disHighVolBusState, coolWaterPressure), + }}, + { "disHighAVolBusState", { + COL(disHighAVolBusState, bowFTDevice123CircuitBreaker), + COL(disHighAVolBusState, actuatorCircuitBreaker), + COL(disHighAVolBusState, mastSteeringGearControlBoxCircuitBreaker), + COL(disHighAVolBusState, xczCircuitBreaker), + COL(disHighAVolBusState, bowRudderControlBoxCircuitBreaker), + COL(disHighAVolBusState, openWaterCoverStartCylinderCircuitBreaker), + COL(disHighAVolBusState, instrumentPowerFailureSignal), + COL(disHighAVolBusState, emergencyPowerFailureSignal), + COL(disHighAVolBusState, waterIngressionAlarm), + COL(disHighAVolBusState, busbarBVoltage), + COL(disHighAVolBusState, busbarBCurrent), + COL(disHighAVolBusState, bowFTDevice123Current), + COL(disHighAVolBusState, actuatorCurrent), + COL(disHighAVolBusState, mastSteeringGearControlBoxCurrent), + COL(disHighAVolBusState, xczCurrent), + COL(disHighAVolBusState, bowRudderControlBoxCurrent), + COL(disHighAVolBusState, openWaterCoverStartCylinderCurrent), + }}, + { "disLowMainBusState", { + COL(disLowMainBusState, lithiumBatteryGroupInstrumentCircuitBreaker), + COL(disLowMainBusState, bowLowVoltageDistributionBoxCircuitBreaker), + COL(disLowMainBusState, unit4InstrumentDC48VCircuitBreaker), + COL(disLowMainBusState, dcC1DCDistributionPanelCircuitBreaker), + COL(disLowMainBusState, reservedCircuitBreaker1), + COL(disLowMainBusState, reservedCircuitBreaker2), + COL(disLowMainBusState, emergencyLithiumBatteryGroup2CircuitBreaker), + COL(disLowMainBusState, instrumentPowerFailureSignal), + COL(disLowMainBusState, emergencyPowerFailureSignal), + COL(disLowMainBusState, instrumentBusbarInsulationLow), + COL(disLowMainBusState, instrumentBusbarVoltage), + COL(disLowMainBusState, bowLowVoltageDistributionBoxCurrent), + COL(disLowMainBusState, dcC1InstrumentDC48VCurrent), + COL(disLowMainBusState, reservedCurrent1), + COL(disLowMainBusState, emergencyLithiumBatteryGroup2Current), + COL(disLowMainBusState, lithiumBatteryGroupInstrumentCurrent), + COL(disLowMainBusState, unit4InstrumentDC48VCurrent), + COL(disLowMainBusState, reservedCurrent2), + COL(disLowMainBusState, emergency2BusbarVoltage), + COL(disLowMainBusState, compositeEnergyManagementSystemEmergencyDC48VCurrent), + COL(disLowMainBusState, fuelCellSecuritySystemEmergencyDC48VCurrent), + COL(disLowMainBusState, plcControlPowerCurrent), + }}, + { "disLowBusState", { + COL(disLowBusState, unit1CircuitBreaker), + COL(disLowBusState, unit2CircuitBreaker), + COL(disLowBusState, unit3CircuitBreaker), + COL(disLowBusState, unit5CircuitBreaker), + COL(disLowBusState, bowPZDeviceCircuitBreaker), + COL(disLowBusState, reservedCircuitBreaker1), + COL(disLowBusState, reservedCircuitBreaker2), + COL(disLowBusState, emergencyLithiumBatteryGroup1CircuitBreaker), + COL(disLowBusState, powerFailureSignal), + COL(disLowBusState, emergencyPowerFailureSignal), + COL(disLowBusState, waterIngressionAlarm), + COL(disLowBusState, instrumentBusbarVoltage), + COL(disLowBusState, instrumentBusbarCurrent), + COL(disLowBusState, unit1Current), + COL(disLowBusState, unit2Current), + COL(disLowBusState, unit3Current), + COL(disLowBusState, unit5Current), + COL(disLowBusState, bowPZDeviceCurrent), + COL(disLowBusState, emergencyLithiumBatteryGroup1Current), + COL(disLowBusState, emergency1BusbarVoltage), + }}, + { "ccuSetParmFb", { + COL(msg_CcuSetParmFbMsg, flag), + COL(msg_CcuSetParmFbMsg, failureCode), + }}, + { "ccuColCmd", { + COL_AS(ccuColCmd, fcmode, "workCondition"), + COL(ccuColCmd, fcuCmd), + COL(ccuColCmd, fcuPowerEfficiency), + COL(ccuColCmd, insChargeEnable), + COL(ccuColCmd, insBatCmd), + COL(ccuColCmd, powerBatCmd), + COL(ccuColCmd, powerBatEfficiency), + COL(ccuColCmd, heartbeat), + COL(ccuColCmd, masterState), + COL(ccuColCmd, paceholder1), + COL(ccuColCmd, paceholder2), + }}, + { "ccuSetParmCmd", { + COL(ccuSetParmCmd, insSocHold1), + COL(ccuSetParmCmd, insSocHold2), + COL(ccuSetParmCmd, insSocHold3), + COL(ccuSetParmCmd, fcuToInsLimit1), + COL_AS(ccuSetParmCmd, fcuToinsLimit2, "fcuToInsLimit2"), + COL(ccuSetParmCmd, powerSocHold1), + COL(ccuSetParmCmd, powerSocHold2), + COL(ccuSetParmCmd, powerSocHold3), + COL(ccuSetParmCmd, fcuToPowerLimit1), + COL(ccuSetParmCmd, fcuToPowerLimit2), + }}, + { "disHighVolBusCmd", { + COL(disHighVolBusCmd, fuelCellCircuitBreaker), + COL(disHighVolBusCmd, powerLithiumBatteryCircuitBreaker), + COL(disHighVolBusCmd, propulsionMotorCircuitBreaker), + COL(disHighVolBusCmd, lithiumBatteryGroupInstrumentCircuitBreaker), + COL(disHighVolBusCmd, dcDc5ModuleCircuitBreaker), + COL(disHighVolBusCmd, bowHighVoltageDistributionBoxCircuitBreaker), + COL(disHighVolBusCmd, sternFTDevice45CircuitBreaker), + COL(disHighVolBusCmd, sternRudderSwitch1CircuitBreaker), + COL(disHighVolBusCmd, sternRudderSwitch2CircuitBreaker), + COL(disHighVolBusCmd, fbReservedCircuitBreaker), + COL(disHighVolBusCmd, tyzReservedCircuitBreaker), + COL(disHighVolBusCmd, reservedCircuitBreaker), + COL(disHighVolBusCmd, dcdc5Module), + COL(disHighVolBusCmd, coolingSystem), + }}, + { "disHighAVolBusCmd", { + COL(disHighAVolBusCmd, bowFTDevice123CircuitBreaker), + COL(disHighAVolBusCmd, actuatorCircuitBreaker), + COL(disHighAVolBusCmd, mastSteeringGearControlBoxCircuitBreaker), + COL(disHighAVolBusCmd, xczCircuitBreaker), + COL(disHighAVolBusCmd, bowRudderControlBoxCircuitBreaker), + COL(disHighAVolBusCmd, openWaterCoverStartCylinderCircuitBreaker), + }}, + { "disLowMainBusCmd", { + COL(disLowMainBusCmd, lithiumBatteryGroupInstrumentCircuitBreaker), + COL(disLowMainBusCmd, bowLowVoltageDistributionBoxCircuitBreaker), + COL(disLowMainBusCmd, unit4InstrumentDC48VCircuitBreaker), + COL(disLowMainBusCmd, dcC1DCDistributionPanelCircuitBreaker), + COL(disLowMainBusCmd, reservedCircuitBreaker1), + COL(disLowMainBusCmd, reservedCircuitBreaker2), + COL(disLowMainBusCmd, emergencyLithiumBatteryGroup2CircuitBreaker), + }}, + { "disLowBusCmd", { + COL(disLowBusCmd, unit1CircuitBreaker), + COL(disLowBusCmd, unit2CircuitBreaker), + COL(disLowBusCmd, unit3CircuitBreaker), + COL(disLowBusCmd, unit5CircuitBreaker), + COL(disLowBusCmd, bowPZDeviceCircuitBreaker), + COL(disLowBusCmd, reservedCircuitBreaker1), + COL(disLowBusCmd, reservedCircuitBreaker2), + COL(disLowBusCmd, emergencyLithiumBatteryGroup1CircuitBreaker), + }}, + }; + return tables; +} + +#undef COL +#undef COL_AS +#undef COL_ARR + SQLite::SQLite(const std::string& dbPath) : m_db(nullptr), m_status(Status::Disabled), m_dbPath(dbPath) { @@ -150,336 +460,20 @@ bool SQLite::createTable() bool SQLite::createAllTablesUnlocked() { - // 1. ccuState - std::string ccuStateColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - fc_mode INTEGER, - fc_status INTEGER, - fc_fault_level INTEGER, - output_power_limit INTEGER, - total_generation_time INTEGER, - total_generation_power INTEGER, - fault_level_1 INTEGER, - fault_level_2 INTEGER, - fault_level_3 INTEGER, - fault_level_4 INTEGER, - hydrogen_capacity INTEGER, - liquid_oxygen_capacity INTEGER, - palladium_temp INTEGER, - main_pipe_pressure INTEGER, - aux_pipe_pressure INTEGER, - cabin_pressure1 INTEGER, - cabin_pressure2 INTEGER, - cabin_temp1 INTEGER, - cabin_temp2 INTEGER, - cabin_humidity1 INTEGER, - cabin_humidity2 INTEGER, - flame_detector1 INTEGER, - flame_detector2 INTEGER, - h2_concentration1 INTEGER, - h2_concentration2 INTEGER, - h2_concentration3 INTEGER, - o2_concentration1 INTEGER, - o2_concentration2 INTEGER, - ch3oh_concentration1 INTEGER, - ch3oh_concentration2 INTEGER, - reserved1_1 INTEGER, reserved1_2 INTEGER, - emergency_battery1_voltage INTEGER, - emergency_battery1_current INTEGER, - emergency_battery1_max_temp INTEGER, - emergency_battery1_fault_word INTEGER, - emergency_battery2_voltage INTEGER, - emergency_battery2_current INTEGER, - emergency_battery2_max_temp INTEGER, - emergency_battery2_fault_word INTEGER, - cabin_ox_concentration INTEGER, - cabin_temperature INTEGER, - cabin_humidity INTEGER, - cabin_pressure INTEGER, - power_cabin_ox_concentration INTEGER, - power_cabin_temperature INTEGER, - power_cabin_humidity INTEGER, - power_cabin_pressure INTEGER, - reserved2 INTEGER, - dyn_alarm_flag1 INTEGER, dyn_alarm_flag2 INTEGER, dyn_alarm_flag3 INTEGER, - dyn_alarm_flag4 INTEGER, dyn_alarm_flag5 INTEGER, dyn_alarm_flag6 INTEGER, - ins_alarm_flag1 INTEGER, ins_alarm_flag2 INTEGER, ins_alarm_flag3 INTEGER, - ins_alarm_flag4 INTEGER, ins_alarm_flag5 INTEGER, ins_alarm_flag6 INTEGER, - ins_relay_status1 INTEGER, - ins_relay_status2 INTEGER, - dyn_relay_status1 INTEGER, - dyn_relay_status2 INTEGER, - ins_max_discharge_power INTEGER, - dyn_max_discharge_power INTEGER, - ins_soc INTEGER, - dyn_soc INTEGER, - ins_total_energy INTEGER, - dyn_total_energy INTEGER, - ins_power_input INTEGER, - dyn_power_input INTEGER, - ins_charge_status INTEGER, - dyn_charge_status INTEGER, - ins_voltage_link INTEGER, - ins_voltage_pack INTEGER, - ins_current INTEGER, - ins_resistance_pos INTEGER, - ins_resistance_neg INTEGER, - dyn_voltage_link INTEGER, - dyn_voltage_pack INTEGER, - dyn_current INTEGER, - dyn_resistance_pos INTEGER, - dyn_resistance_neg INTEGER, - ins_emergency_status INTEGER, - dyn_emergency_status INTEGER, - reserved3_1 INTEGER, reserved3_2 INTEGER, - ins_soc_threshold1 INTEGER, - ins_soc_threshold2 INTEGER, - ins_soc_threshold3 INTEGER, - dyn_soc_threshold1 INTEGER, - dyn_soc_threshold2 INTEGER, - dyn_soc_threshold3 INTEGER, - ins_power_limit1 INTEGER, - ins_power_limit2 INTEGER, - dyn_power_limit1 INTEGER, - dyn_power_limit2 INTEGER, - device_online_flag1 INTEGER, - device_online_flag2 INTEGER, - reserved4 INTEGER, - heartbeat INTEGER - )"; - if (!createTableInternal("ccuState", ccuStateColumns)) return false; + // 由描述符生成各协议结构表的建表语句(自动追加 id/timestamp 元列) + for (const TableDesc& t : allTables()) { + std::string cols = "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "timestamp DATETIME DEFAULT (datetime('now', 'localtime'))"; + for (const Column& c : t.columns) { + cols += ", "; + cols += c.name; + cols += " "; + cols += c.sqlType; + } + if (!createTableInternal(t.name, cols)) return false; + } - // 2. disHighVolBusState - std::string disHighVolBusColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - fuelCellCircuitBreaker INTEGER, - powerLithiumBatteryCircuitBreaker INTEGER, - propulsionMotorCircuitBreaker INTEGER, - lithiumBatteryGroupInstrumentCircuitBreaker INTEGER, - dcDc5ModuleCircuitBreaker INTEGER, - bowHighVoltageDistributionBoxCircuitBreaker INTEGER, - sternFTDevice45CircuitBreaker INTEGER, - sternRudderSwitch1CircuitBreaker INTEGER, - sternRudderSwitch2CircuitBreaker INTEGER, - fbReservedCircuitBreaker INTEGER, - tyzReservedCircuitBreaker INTEGER, - reservedCircuitBreaker INTEGER, - dcDcFaultWord1 INTEGER, - dcDcFaultWord2 INTEGER, - powerBusInsulationStatus INTEGER, - aBusInsulationStatus INTEGER, - meterPowerLossSignal INTEGER, - emergencyPowerLossSignal INTEGER, - powerBusVoltage INTEGER, - dcDc5ModuleCurrent INTEGER, - powerBusCurrent INTEGER, - busbarAVoltage INTEGER, - propulsionMotorControlBoxCurrent INTEGER, - busbarACurrent INTEGER, - lithiumBatteryGroupMeterCurrent INTEGER, - bowHighVoltageDistributionBoxCurrent INTEGER, - sternFTDevice45Current INTEGER, - tyzReservedSwitchCurrent INTEGER, - sternRudderSwitch1Current INTEGER, - reservedCurrent1 INTEGER, - sternRudderSwitch2Current INTEGER, - reservedCurrent2 INTEGER, - fbReservedSwitchCurrent INTEGER, - reservedCurrent3 INTEGER, - coolWaterPressure INTEGER - )"; - if (!createTableInternal("disHighVolBusState", disHighVolBusColumns)) return false; - - // 3. disHighAVolBusState - std::string disHighAVolBusColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - bowFTDevice123CircuitBreaker INTEGER, - actuatorCircuitBreaker INTEGER, - mastSteeringGearControlBoxCircuitBreaker INTEGER, - xczCircuitBreaker INTEGER, - bowRudderControlBoxCircuitBreaker INTEGER, - openWaterCoverStartCylinderCircuitBreaker INTEGER, - instrumentPowerFailureSignal INTEGER, - emergencyPowerFailureSignal INTEGER, - waterIngressionAlarm INTEGER, - busbarBVoltage INTEGER, - busbarBCurrent INTEGER, - bowFTDevice123Current INTEGER, - actuatorCurrent INTEGER, - mastSteeringGearControlBoxCurrent INTEGER, - xczCurrent INTEGER, - bowRudderControlBoxCurrent INTEGER, - openWaterCoverStartCylinderCurrent INTEGER - )"; - if (!createTableInternal("disHighAVolBusState", disHighAVolBusColumns)) return false; - - // 4. disLowMainBusState - std::string disLowMainBusColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - lithiumBatteryGroupInstrumentCircuitBreaker INTEGER, - bowLowVoltageDistributionBoxCircuitBreaker INTEGER, - unit4InstrumentDC48VCircuitBreaker INTEGER, - dcC1DCDistributionPanelCircuitBreaker INTEGER, - reservedCircuitBreaker1 INTEGER, - reservedCircuitBreaker2 INTEGER, - emergencyLithiumBatteryGroup2CircuitBreaker INTEGER, - instrumentPowerFailureSignal INTEGER, - emergencyPowerFailureSignal INTEGER, - instrumentBusbarInsulationLow INTEGER, - instrumentBusbarVoltage INTEGER, - bowLowVoltageDistributionBoxCurrent INTEGER, - dcC1InstrumentDC48VCurrent INTEGER, - reservedCurrent1 INTEGER, - emergencyLithiumBatteryGroup2Current INTEGER, - lithiumBatteryGroupInstrumentCurrent INTEGER, - unit4InstrumentDC48VCurrent INTEGER, - reservedCurrent2 INTEGER, - emergency2BusbarVoltage INTEGER, - compositeEnergyManagementSystemEmergencyDC48VCurrent INTEGER, - fuelCellSecuritySystemEmergencyDC48VCurrent INTEGER, - plcControlPowerCurrent INTEGER - )"; - if (!createTableInternal("disLowMainBusState", disLowMainBusColumns)) return false; - - // 5. disLowBusState - std::string disLowBusColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - unit1CircuitBreaker INTEGER, - unit2CircuitBreaker INTEGER, - unit3CircuitBreaker INTEGER, - unit5CircuitBreaker INTEGER, - bowPZDeviceCircuitBreaker INTEGER, - reservedCircuitBreaker1 INTEGER, - reservedCircuitBreaker2 INTEGER, - emergencyLithiumBatteryGroup1CircuitBreaker INTEGER, - powerFailureSignal INTEGER, - emergencyPowerFailureSignal INTEGER, - waterIngressionAlarm INTEGER, - instrumentBusbarVoltage INTEGER, - instrumentBusbarCurrent INTEGER, - unit1Current INTEGER, - unit2Current INTEGER, - unit3Current INTEGER, - unit5Current INTEGER, - bowPZDeviceCurrent INTEGER, - emergencyLithiumBatteryGroup1Current INTEGER, - emergency1BusbarVoltage INTEGER - )"; - if (!createTableInternal("disLowBusState", disLowBusColumns)) return false; - - // 6. ccuColCmd - std::string ccuColCmdColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - workCondition INTEGER, - fcuCmd INTEGER, - fcuPowerEfficiency INTEGER, - insChargeEnable INTEGER, - insBatCmd INTEGER, - powerBatCmd INTEGER, - powerBatEfficiency INTEGER, - heartbeat INTEGER, - masterState INTEGER, - paceholder1 INTEGER, - paceholder2 INTEGER - )"; - if (!createTableInternal("ccuColCmd", ccuColCmdColumns)) return false; - - // 7. disHighVolBusCmd - std::string disHighVolBusCmdColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - fuelCellCircuitBreaker INTEGER, - powerLithiumBatteryCircuitBreaker INTEGER, - propulsionMotorCircuitBreaker INTEGER, - lithiumBatteryGroupInstrumentCircuitBreaker INTEGER, - dcDc5ModuleCircuitBreaker INTEGER, - bowHighVoltageDistributionBoxCircuitBreaker INTEGER, - sternFTDevice45CircuitBreaker INTEGER, - sternRudderSwitch1CircuitBreaker INTEGER, - sternRudderSwitch2CircuitBreaker INTEGER, - fbReservedCircuitBreaker INTEGER, - tyzReservedCircuitBreaker INTEGER, - reservedCircuitBreaker INTEGER, - dcdc5Module INTEGER, - coolingSystem INTEGER - )"; - if (!createTableInternal("disHighVolBusCmd", disHighVolBusCmdColumns)) return false; - - // 8. disHighAVolBusCmd - std::string disHighAVolBusCmdColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - bowFTDevice123CircuitBreaker INTEGER, - actuatorCircuitBreaker INTEGER, - mastSteeringGearControlBoxCircuitBreaker INTEGER, - xczCircuitBreaker INTEGER, - bowRudderControlBoxCircuitBreaker INTEGER, - openWaterCoverStartCylinderCircuitBreaker INTEGER - )"; - if (!createTableInternal("disHighAVolBusCmd", disHighAVolBusCmdColumns)) return false; - - // 9. disLowMainBusCmd - std::string disLowMainBusCmdColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - lithiumBatteryGroupInstrumentCircuitBreaker INTEGER, - bowLowVoltageDistributionBoxCircuitBreaker INTEGER, - unit4InstrumentDC48VCircuitBreaker INTEGER, - dcC1DCDistributionPanelCircuitBreaker INTEGER, - reservedCircuitBreaker1 INTEGER, - reservedCircuitBreaker2 INTEGER, - emergencyLithiumBatteryGroup2CircuitBreaker INTEGER - )"; - if (!createTableInternal("disLowMainBusCmd", disLowMainBusCmdColumns)) return false; - - // 10. disLowBusCmd - std::string disLowBusCmdColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - unit1CircuitBreaker INTEGER, - unit2CircuitBreaker INTEGER, - unit3CircuitBreaker INTEGER, - unit5CircuitBreaker INTEGER, - bowPZDeviceCircuitBreaker INTEGER, - reservedCircuitBreaker1 INTEGER, - reservedCircuitBreaker2 INTEGER, - emergencyLithiumBatteryGroup1CircuitBreaker INTEGER - )"; - if (!createTableInternal("disLowBusCmd", disLowBusCmdColumns)) return false; - - // 11. ccuSetParmCmd(复合管控参数设定下发) - std::string ccuSetParmCmdColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - insSocHold1 INTEGER, - insSocHold2 INTEGER, - insSocHold3 INTEGER, - fcuToInsLimit1 INTEGER, - fcuToInsLimit2 INTEGER, - powerSocHold1 INTEGER, - powerSocHold2 INTEGER, - powerSocHold3 INTEGER, - fcuToPowerLimit1 INTEGER, - fcuToPowerLimit2 INTEGER - )"; - if (!createTableInternal("ccuSetParmCmd", ccuSetParmCmdColumns)) return false; - - // 12. ccuSetParmFb(复合管控参数设定反馈) - std::string ccuSetParmFbColumns = R"( - id INTEGER PRIMARY KEY AUTOINCREMENT, - timestamp DATETIME DEFAULT (datetime('now', 'localtime')), - flag INTEGER, - failureCode INTEGER - )"; - if (!createTableInternal("ccuSetParmFb", ccuSetParmFbColumns)) return false; - - // 13. msg_log(原始收发帧日志) + // msg_log(原始收发帧日志,列类型多样,保持手写) std::string msgLogColumns = R"( id INTEGER PRIMARY KEY AUTOINCREMENT, ts REAL NOT NULL, @@ -502,23 +496,31 @@ bool SQLite::createAllTablesUnlocked() } //==================================================================== -// 泛化插入:所有类型共用这一条路径,列名与绑定器一一对应 +// 泛化插入:按表名在注册表中查找描述并绑定,所有类型共用这一条路径 //==================================================================== -bool SQLite::insertGeneric(const std::string& table, const std::vector& cols, const void* obj) +bool SQLite::insertGeneric(const char* tableName, const void* obj) { + const TableDesc* table = nullptr; + for (const TableDesc& t : allTables()) { + if (std::strcmp(t.name, tableName) == 0) { table = &t; break; } + } + if (!table) return false; + try { std::lock_guard lock(m_dbMutex); if (!m_db) { setError(SQLITE_MISUSE, "insert (db not open)"); return false; } if (m_status == Status::Disabled) return false; - if (cols.empty()) return false; + if (table->columns.empty()) return false; - std::string sql = "INSERT INTO " + table + " ("; - for (size_t i = 0; i < cols.size(); ++i) { + std::string sql = "INSERT INTO "; + sql += table->name; + sql += " ("; + for (size_t i = 0; i < table->columns.size(); ++i) { if (i) sql += ","; - sql += cols[i].name; + sql += table->columns[i].name; } sql += ") VALUES ("; - for (size_t i = 0; i < cols.size(); ++i) { + for (size_t i = 0; i < table->columns.size(); ++i) { if (i) sql += ","; sql += "?"; } @@ -529,8 +531,8 @@ bool SQLite::insertGeneric(const std::string& table, const std::vector& if (rc != SQLITE_OK) { setError(rc, "prepare"); return false; } int idx = 1; - for (size_t i = 0; i < cols.size(); ++i) { - cols[i].bind(stmt, idx, obj); + for (const Column& c : table->columns) { + c.bind(stmt, idx, obj); } rc = sqlite3_step(stmt); @@ -547,368 +549,25 @@ bool SQLite::insertGeneric(const std::string& table, const std::vector& } } -//==================================================================== -// 列绑定宏:字段名 + 绑定器(无捕获函数指针,不抛异常、不分配) -//==================================================================== -#define COL(Struct, member) \ - SQLite::Column{ #member, [](sqlite3_stmt* s, int& i, const void* o){ \ - sqlite3_bind_int64(s, i++, static_cast(static_cast(o)->member)); } } - -#define COL_AS(Struct, member, colname) \ - SQLite::Column{ colname, [](sqlite3_stmt* s, int& i, const void* o){ \ - sqlite3_bind_int64(s, i++, static_cast(static_cast(o)->member)); } } - -#define COL_ARR(Struct, arr, index, colname) \ - SQLite::Column{ colname, [](sqlite3_stmt* s, int& i, const void* o){ \ - sqlite3_bind_int64(s, i++, static_cast(static_cast(o)->arr[index])); } } - //==================================================================== // 状态反馈数据 //==================================================================== -bool SQLite::insertData(ccuState data) -{ - std::vector cols = { - COL(ccuState, fc_mode), - COL(ccuState, fc_status), - COL(ccuState, fc_fault_level), - COL(ccuState, output_power_limit), - COL(ccuState, total_generation_time), - COL(ccuState, total_generation_power), - COL(ccuState, fault_level_1), - COL(ccuState, fault_level_2), - COL(ccuState, fault_level_3), - COL(ccuState, fault_level_4), - COL(ccuState, hydrogen_capacity), - COL(ccuState, liquid_oxygen_capacity), - COL(ccuState, palladium_temp), - COL(ccuState, main_pipe_pressure), - COL(ccuState, aux_pipe_pressure), - COL(ccuState, cabin_pressure1), - COL(ccuState, cabin_pressure2), - COL(ccuState, cabin_temp1), - COL(ccuState, cabin_temp2), - COL(ccuState, cabin_humidity1), - COL(ccuState, cabin_humidity2), - COL(ccuState, flame_detector1), - COL(ccuState, flame_detector2), - COL(ccuState, h2_concentration1), - COL(ccuState, h2_concentration2), - COL(ccuState, h2_concentration3), - COL(ccuState, o2_concentration1), - COL(ccuState, o2_concentration2), - COL(ccuState, ch3oh_concentration1), - COL(ccuState, ch3oh_concentration2), - COL_ARR(ccuState, reserved1, 0, "reserved1_1"), - COL_ARR(ccuState, reserved1, 1, "reserved1_2"), - COL(ccuState, emergency_battery1_voltage), - COL(ccuState, emergency_battery1_current), - COL(ccuState, emergency_battery1_max_temp), - COL(ccuState, emergency_battery1_fault_word), - COL(ccuState, emergency_battery2_voltage), - COL(ccuState, emergency_battery2_current), - COL(ccuState, emergency_battery2_max_temp), - COL(ccuState, emergency_battery2_fault_word), - COL(ccuState, cabin_ox_concentration), - COL(ccuState, cabin_temperature), - COL(ccuState, cabin_humidity), - COL(ccuState, cabin_pressure), - COL(ccuState, power_cabin_ox_concentration), - COL(ccuState, power_cabin_temperature), - COL(ccuState, power_cabin_humidity), - COL(ccuState, power_cabin_pressure), - COL_ARR(ccuState, reserved2, 0, "reserved2"), - COL_ARR(ccuState, dyn_alarm_flag, 0, "dyn_alarm_flag1"), - COL_ARR(ccuState, dyn_alarm_flag, 1, "dyn_alarm_flag2"), - COL_ARR(ccuState, dyn_alarm_flag, 2, "dyn_alarm_flag3"), - COL_ARR(ccuState, dyn_alarm_flag, 3, "dyn_alarm_flag4"), - COL_ARR(ccuState, dyn_alarm_flag, 4, "dyn_alarm_flag5"), - COL_ARR(ccuState, dyn_alarm_flag, 5, "dyn_alarm_flag6"), - COL_ARR(ccuState, ins_alarm_flag, 0, "ins_alarm_flag1"), - COL_ARR(ccuState, ins_alarm_flag, 1, "ins_alarm_flag2"), - COL_ARR(ccuState, ins_alarm_flag, 2, "ins_alarm_flag3"), - COL_ARR(ccuState, ins_alarm_flag, 3, "ins_alarm_flag4"), - COL_ARR(ccuState, ins_alarm_flag, 4, "ins_alarm_flag5"), - COL_ARR(ccuState, ins_alarm_flag, 5, "ins_alarm_flag6"), - COL(ccuState, ins_relay_status1), - COL(ccuState, ins_relay_status2), - COL(ccuState, dyn_relay_status1), - COL(ccuState, dyn_relay_status2), - COL(ccuState, ins_max_discharge_power), - COL(ccuState, dyn_max_discharge_power), - COL(ccuState, ins_soc), - COL(ccuState, dyn_soc), - COL(ccuState, ins_total_energy), - COL(ccuState, dyn_total_energy), - COL(ccuState, ins_power_input), - COL(ccuState, dyn_power_input), - COL(ccuState, ins_charge_status), - COL(ccuState, dyn_charge_status), - COL(ccuState, ins_voltage_link), - COL(ccuState, ins_voltage_pack), - COL(ccuState, ins_current), - COL(ccuState, ins_resistance_pos), - COL(ccuState, ins_resistance_neg), - COL(ccuState, dyn_voltage_link), - COL(ccuState, dyn_voltage_pack), - COL(ccuState, dyn_current), - COL(ccuState, dyn_resistance_pos), - COL(ccuState, dyn_resistance_neg), - COL(ccuState, ins_emergency_status), - COL(ccuState, dyn_emergency_status), - COL_ARR(ccuState, reserved3, 0, "reserved3_1"), - COL_ARR(ccuState, reserved3, 1, "reserved3_2"), - COL(ccuState, ins_soc_threshold1), - COL(ccuState, ins_soc_threshold2), - COL(ccuState, ins_soc_threshold3), - COL(ccuState, dyn_soc_threshold1), - COL(ccuState, dyn_soc_threshold2), - COL(ccuState, dyn_soc_threshold3), - COL(ccuState, ins_power_limit1), - COL(ccuState, ins_power_limit2), - COL(ccuState, dyn_power_limit1), - COL(ccuState, dyn_power_limit2), - COL(ccuState, device_online_flag1), - COL(ccuState, device_online_flag2), - COL(ccuState, reserved4), - COL(ccuState, heartbeat), - }; - return insertGeneric("ccuState", cols, &data); -} - -bool SQLite::insertData(disHighVolBusState data) -{ - std::vector cols = { - COL(disHighVolBusState, fuelCellCircuitBreaker), - COL(disHighVolBusState, powerLithiumBatteryCircuitBreaker), - COL(disHighVolBusState, propulsionMotorCircuitBreaker), - COL(disHighVolBusState, lithiumBatteryGroupInstrumentCircuitBreaker), - COL(disHighVolBusState, dcDc5ModuleCircuitBreaker), - COL(disHighVolBusState, bowHighVoltageDistributionBoxCircuitBreaker), - COL(disHighVolBusState, sternFTDevice45CircuitBreaker), - COL(disHighVolBusState, sternRudderSwitch1CircuitBreaker), - COL(disHighVolBusState, sternRudderSwitch2CircuitBreaker), - COL(disHighVolBusState, fbReservedCircuitBreaker), - COL(disHighVolBusState, tyzReservedCircuitBreaker), - COL(disHighVolBusState, reservedCircuitBreaker), - COL(disHighVolBusState, dcDcFaultWord1), - COL(disHighVolBusState, dcDcFaultWord2), - COL(disHighVolBusState, powerBusInsulationStatus), - COL(disHighVolBusState, aBusInsulationStatus), - COL(disHighVolBusState, meterPowerLossSignal), - COL(disHighVolBusState, emergencyPowerLossSignal), - COL(disHighVolBusState, powerBusVoltage), - COL(disHighVolBusState, dcDc5ModuleCurrent), - COL(disHighVolBusState, powerBusCurrent), - COL(disHighVolBusState, busbarAVoltage), - COL(disHighVolBusState, propulsionMotorControlBoxCurrent), - COL(disHighVolBusState, busbarACurrent), - COL(disHighVolBusState, lithiumBatteryGroupMeterCurrent), - COL(disHighVolBusState, bowHighVoltageDistributionBoxCurrent), - COL(disHighVolBusState, sternFTDevice45Current), - COL(disHighVolBusState, tyzReservedSwitchCurrent), - COL(disHighVolBusState, sternRudderSwitch1Current), - COL(disHighVolBusState, reservedCurrent1), - COL(disHighVolBusState, sternRudderSwitch2Current), - COL(disHighVolBusState, reservedCurrent2), - COL(disHighVolBusState, fbReservedSwitchCurrent), - COL(disHighVolBusState, reservedCurrent3), - COL(disHighVolBusState, coolWaterPressure), - }; - return insertGeneric("disHighVolBusState", cols, &data); -} - -bool SQLite::insertData(disHighAVolBusState data) -{ - std::vector cols = { - COL(disHighAVolBusState, bowFTDevice123CircuitBreaker), - COL(disHighAVolBusState, actuatorCircuitBreaker), - COL(disHighAVolBusState, mastSteeringGearControlBoxCircuitBreaker), - COL(disHighAVolBusState, xczCircuitBreaker), - COL(disHighAVolBusState, bowRudderControlBoxCircuitBreaker), - COL(disHighAVolBusState, openWaterCoverStartCylinderCircuitBreaker), - COL(disHighAVolBusState, instrumentPowerFailureSignal), - COL(disHighAVolBusState, emergencyPowerFailureSignal), - COL(disHighAVolBusState, waterIngressionAlarm), - COL(disHighAVolBusState, busbarBVoltage), - COL(disHighAVolBusState, busbarBCurrent), - COL(disHighAVolBusState, bowFTDevice123Current), - COL(disHighAVolBusState, actuatorCurrent), - COL(disHighAVolBusState, mastSteeringGearControlBoxCurrent), - COL(disHighAVolBusState, xczCurrent), - COL(disHighAVolBusState, bowRudderControlBoxCurrent), - COL(disHighAVolBusState, openWaterCoverStartCylinderCurrent), - }; - return insertGeneric("disHighAVolBusState", cols, &data); -} - -bool SQLite::insertData(disLowMainBusState data) -{ - std::vector cols = { - COL(disLowMainBusState, lithiumBatteryGroupInstrumentCircuitBreaker), - COL(disLowMainBusState, bowLowVoltageDistributionBoxCircuitBreaker), - COL(disLowMainBusState, unit4InstrumentDC48VCircuitBreaker), - COL(disLowMainBusState, dcC1DCDistributionPanelCircuitBreaker), - COL(disLowMainBusState, reservedCircuitBreaker1), - COL(disLowMainBusState, reservedCircuitBreaker2), - COL(disLowMainBusState, emergencyLithiumBatteryGroup2CircuitBreaker), - COL(disLowMainBusState, instrumentPowerFailureSignal), - COL(disLowMainBusState, emergencyPowerFailureSignal), - COL(disLowMainBusState, instrumentBusbarInsulationLow), - COL(disLowMainBusState, instrumentBusbarVoltage), - COL(disLowMainBusState, bowLowVoltageDistributionBoxCurrent), - COL(disLowMainBusState, dcC1InstrumentDC48VCurrent), - COL(disLowMainBusState, reservedCurrent1), - COL(disLowMainBusState, emergencyLithiumBatteryGroup2Current), - COL(disLowMainBusState, lithiumBatteryGroupInstrumentCurrent), - COL(disLowMainBusState, unit4InstrumentDC48VCurrent), - COL(disLowMainBusState, reservedCurrent2), - COL(disLowMainBusState, emergency2BusbarVoltage), - COL(disLowMainBusState, compositeEnergyManagementSystemEmergencyDC48VCurrent), - COL(disLowMainBusState, fuelCellSecuritySystemEmergencyDC48VCurrent), - COL(disLowMainBusState, plcControlPowerCurrent), - }; - return insertGeneric("disLowMainBusState", cols, &data); -} - -bool SQLite::insertData(disLowBusState data) -{ - std::vector cols = { - COL(disLowBusState, unit1CircuitBreaker), - COL(disLowBusState, unit2CircuitBreaker), - COL(disLowBusState, unit3CircuitBreaker), - COL(disLowBusState, unit5CircuitBreaker), - COL(disLowBusState, bowPZDeviceCircuitBreaker), - COL(disLowBusState, reservedCircuitBreaker1), - COL(disLowBusState, reservedCircuitBreaker2), - COL(disLowBusState, emergencyLithiumBatteryGroup1CircuitBreaker), - COL(disLowBusState, powerFailureSignal), - COL(disLowBusState, emergencyPowerFailureSignal), - COL(disLowBusState, waterIngressionAlarm), - COL(disLowBusState, instrumentBusbarVoltage), - COL(disLowBusState, instrumentBusbarCurrent), - COL(disLowBusState, unit1Current), - COL(disLowBusState, unit2Current), - COL(disLowBusState, unit3Current), - COL(disLowBusState, unit5Current), - COL(disLowBusState, bowPZDeviceCurrent), - COL(disLowBusState, emergencyLithiumBatteryGroup1Current), - COL(disLowBusState, emergency1BusbarVoltage), - }; - return insertGeneric("disLowBusState", cols, &data); -} - -bool SQLite::insertData(const msg_CcuSetParmFbMsg& fb) -{ - std::vector cols = { - COL(msg_CcuSetParmFbMsg, flag), - COL(msg_CcuSetParmFbMsg, failureCode), - }; - return insertGeneric("ccuSetParmFb", cols, &fb); -} +bool SQLite::insertData(ccuState data) { return insertGeneric("ccuState", &data); } +bool SQLite::insertData(disHighVolBusState data) { return insertGeneric("disHighVolBusState", &data); } +bool SQLite::insertData(disHighAVolBusState data) { return insertGeneric("disHighAVolBusState", &data); } +bool SQLite::insertData(disLowMainBusState data) { return insertGeneric("disLowMainBusState", &data); } +bool SQLite::insertData(disLowBusState data) { return insertGeneric("disLowBusState", &data); } +bool SQLite::insertData(const msg_CcuSetParmFbMsg& fb) { return insertGeneric("ccuSetParmFb", &fb); } //==================================================================== // 下发指令数据 //==================================================================== -bool SQLite::insertData(ccuColCmd cmd) -{ - std::vector cols = { - COL_AS(ccuColCmd, fcmode, "workCondition"), - COL(ccuColCmd, fcuCmd), - COL(ccuColCmd, fcuPowerEfficiency), - COL(ccuColCmd, insChargeEnable), - COL(ccuColCmd, insBatCmd), - COL(ccuColCmd, powerBatCmd), - COL(ccuColCmd, powerBatEfficiency), - COL(ccuColCmd, heartbeat), - COL(ccuColCmd, masterState), - COL(ccuColCmd, paceholder1), - COL(ccuColCmd, paceholder2), - }; - return insertGeneric("ccuColCmd", cols, &cmd); -} - -bool SQLite::insertData(ccuSetParmCmd cmd) -{ - std::vector cols = { - COL(ccuSetParmCmd, insSocHold1), - COL(ccuSetParmCmd, insSocHold2), - COL(ccuSetParmCmd, insSocHold3), - COL(ccuSetParmCmd, fcuToInsLimit1), - COL(ccuSetParmCmd, fcuToinsLimit2), - COL(ccuSetParmCmd, powerSocHold1), - COL(ccuSetParmCmd, powerSocHold2), - COL(ccuSetParmCmd, powerSocHold3), - COL(ccuSetParmCmd, fcuToPowerLimit1), - COL(ccuSetParmCmd, fcuToPowerLimit2), - }; - return insertGeneric("ccuSetParmCmd", cols, &cmd); -} - -bool SQLite::insertData(disHighVolBusCmd cmd) -{ - std::vector cols = { - COL(disHighVolBusCmd, fuelCellCircuitBreaker), - COL(disHighVolBusCmd, powerLithiumBatteryCircuitBreaker), - COL(disHighVolBusCmd, propulsionMotorCircuitBreaker), - COL(disHighVolBusCmd, lithiumBatteryGroupInstrumentCircuitBreaker), - COL(disHighVolBusCmd, dcDc5ModuleCircuitBreaker), - COL(disHighVolBusCmd, bowHighVoltageDistributionBoxCircuitBreaker), - COL(disHighVolBusCmd, sternFTDevice45CircuitBreaker), - COL(disHighVolBusCmd, sternRudderSwitch1CircuitBreaker), - COL(disHighVolBusCmd, sternRudderSwitch2CircuitBreaker), - COL(disHighVolBusCmd, fbReservedCircuitBreaker), - COL(disHighVolBusCmd, tyzReservedCircuitBreaker), - COL(disHighVolBusCmd, reservedCircuitBreaker), - COL(disHighVolBusCmd, dcdc5Module), - COL(disHighVolBusCmd, coolingSystem), - }; - return insertGeneric("disHighVolBusCmd", cols, &cmd); -} - -bool SQLite::insertData(disHighAVolBusCmd cmd) -{ - std::vector cols = { - COL(disHighAVolBusCmd, bowFTDevice123CircuitBreaker), - COL(disHighAVolBusCmd, actuatorCircuitBreaker), - COL(disHighAVolBusCmd, mastSteeringGearControlBoxCircuitBreaker), - COL(disHighAVolBusCmd, xczCircuitBreaker), - COL(disHighAVolBusCmd, bowRudderControlBoxCircuitBreaker), - COL(disHighAVolBusCmd, openWaterCoverStartCylinderCircuitBreaker), - }; - return insertGeneric("disHighAVolBusCmd", cols, &cmd); -} - -bool SQLite::insertData(disLowMainBusCmd cmd) -{ - std::vector cols = { - COL(disLowMainBusCmd, lithiumBatteryGroupInstrumentCircuitBreaker), - COL(disLowMainBusCmd, bowLowVoltageDistributionBoxCircuitBreaker), - COL(disLowMainBusCmd, unit4InstrumentDC48VCircuitBreaker), - COL(disLowMainBusCmd, dcC1DCDistributionPanelCircuitBreaker), - COL(disLowMainBusCmd, reservedCircuitBreaker1), - COL(disLowMainBusCmd, reservedCircuitBreaker2), - COL(disLowMainBusCmd, emergencyLithiumBatteryGroup2CircuitBreaker), - }; - return insertGeneric("disLowMainBusCmd", cols, &cmd); -} - -bool SQLite::insertData(disLowBusCmd cmd) -{ - std::vector cols = { - COL(disLowBusCmd, unit1CircuitBreaker), - COL(disLowBusCmd, unit2CircuitBreaker), - COL(disLowBusCmd, unit3CircuitBreaker), - COL(disLowBusCmd, unit5CircuitBreaker), - COL(disLowBusCmd, bowPZDeviceCircuitBreaker), - COL(disLowBusCmd, reservedCircuitBreaker1), - COL(disLowBusCmd, reservedCircuitBreaker2), - COL(disLowBusCmd, emergencyLithiumBatteryGroup1CircuitBreaker), - }; - return insertGeneric("disLowBusCmd", cols, &cmd); -} - -#undef COL -#undef COL_ARR +bool SQLite::insertData(ccuColCmd cmd) { return insertGeneric("ccuColCmd", &cmd); } +bool SQLite::insertData(ccuSetParmCmd cmd) { return insertGeneric("ccuSetParmCmd", &cmd); } +bool SQLite::insertData(disHighVolBusCmd cmd) { return insertGeneric("disHighVolBusCmd", &cmd); } +bool SQLite::insertData(disHighAVolBusCmd cmd) { return insertGeneric("disHighAVolBusCmd", &cmd); } +bool SQLite::insertData(disLowMainBusCmd cmd) { return insertGeneric("disLowMainBusCmd", &cmd); } +bool SQLite::insertData(disLowBusCmd cmd) { return insertGeneric("disLowBusCmd", &cmd); } //==================================================================== // 原始收发帧落库 diff --git a/src/pPowerManger/sqlit3/SQLite.h b/src/pPowerManger/sqlit3/SQLite.h index 08f96fd..784f328 100644 --- a/src/pPowerManger/sqlit3/SQLite.h +++ b/src/pPowerManger/sqlit3/SQLite.h @@ -66,12 +66,22 @@ private: bool createTableInternal(const std::string& tableName, const std::string& columns); bool createAllTablesUnlocked(); - // 泛化插入:表名 + 列描述(名称 + 绑定器),所有类型共用这一条路径 + // 列描述:名称 + SQL 类型 + 绑定器(无捕获函数指针) struct Column { const char* name; + const char* sqlType; void (*bind)(sqlite3_stmt*, int& idx, const void* obj); }; - bool insertGeneric(const std::string& table, const std::vector& cols, const void* obj); + // 表描述:表名 + 数据列。建表(DDL)与插入(DML)共用这一份,作为唯一数据源。 + struct TableDesc { + const char* name; + std::vector columns; + }; + + // 泛化插入:按表名在注册表中查找描述并绑定,所有类型共用这一条路径 + bool insertGeneric(const char* tableName, const void* obj); + // 所有协议结构表的描述注册表(不含 msg_log 等特殊表) + static const std::vector& allTables(); }; #endif // SQLITE_H diff --git a/src/pPowerManger/udpcomm/udpComm.cpp b/src/pPowerManger/udpcomm/udpComm.cpp index fa4cb4c..838da93 100644 --- a/src/pPowerManger/udpcomm/udpComm.cpp +++ b/src/pPowerManger/udpcomm/udpComm.cpp @@ -36,8 +36,11 @@ Checksum udpComm::calculateChecksum(const unsigned char* data, int dataSize, int } return checksum; } -bool udpComm::getMsgId(char *m,unsigned short &id) +bool udpComm::getMsgId(char *m, size_t len, unsigned short &id) { + if (m == NULL || len < sizeof(m_header)) { + return false; + } m_header h; h = *reinterpret_cast(m); // 判断消息是否有效 @@ -56,7 +59,11 @@ bool udpComm::getMsgId(char *m,unsigned short &id) // LOG_F(ERROR, "Msg Header errar start1: %d, start2: %d", h.start1, h.start2); return false; } -bool udpComm::getMsgFromBuff(char *m, msg_CcuStateFbMsg &s) { +bool udpComm::getMsgFromBuff(char *m, size_t len, msg_CcuStateFbMsg &s) { + if (m == NULL || len < sizeof(msg_CcuStateFbMsg)) { + sError.push_back("CcuStat Msg length error"); + return false; + } Checksum sum; msg_CcuStateFbMsg *p; p = reinterpret_cast(m); @@ -69,8 +76,12 @@ bool udpComm::getMsgFromBuff(char *m, msg_CcuStateFbMsg &s) { return true; } -bool udpComm::getMsgFromBuff(char *m, msg_CcuSetParmFbMsg &s) +bool udpComm::getMsgFromBuff(char *m, size_t len, msg_CcuSetParmFbMsg &s) { + if (m == NULL || len < sizeof(msg_CcuSetParmFbMsg)) { + sError.push_back("CcuSetParm Msg length error"); + return false; + } Checksum sum; msg_CcuSetParmFbMsg *p; p = reinterpret_cast(m); @@ -85,8 +96,12 @@ bool udpComm::getMsgFromBuff(char *m, msg_CcuSetParmFbMsg &s) return true; } -bool udpComm::getMsgFromBuff(char *m, msg_disHighVolBusFbMsg &s) +bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disHighVolBusFbMsg &s) { + if (m == NULL || len < sizeof(msg_disHighVolBusFbMsg)) { + sError.push_back("DisSys HVBus Msg length error"); + return false; + } cChecksum sum; msg_disHighVolBusFbMsg *p; p = reinterpret_cast(m); @@ -101,8 +116,12 @@ bool udpComm::getMsgFromBuff(char *m, msg_disHighVolBusFbMsg &s) return true; } -bool udpComm::getMsgFromBuff(char *m, msg_disHighAVolBusFbMsg &s) +bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disHighAVolBusFbMsg &s) { + if (m == NULL || len < sizeof(msg_disHighAVolBusFbMsg)) { + sError.push_back("DisSys HVABus Msg length error"); + return false; + } cChecksum sum; msg_disHighAVolBusFbMsg *p; p = reinterpret_cast(m); @@ -115,8 +134,12 @@ bool udpComm::getMsgFromBuff(char *m, msg_disHighAVolBusFbMsg &s) s = *p; return true; } -bool udpComm::getMsgFromBuff(char *m, msg_disLowMainBusFbMsg &s) +bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disLowMainBusFbMsg &s) { + if (m == NULL || len < sizeof(msg_disLowMainBusFbMsg)) { + sError.push_back("DisSys HVBBus Msg length error"); + return false; + } cChecksum sum; msg_disLowMainBusFbMsg *p; p = reinterpret_cast(m); @@ -130,8 +153,12 @@ bool udpComm::getMsgFromBuff(char *m, msg_disLowMainBusFbMsg &s) return true; } -bool udpComm::getMsgFromBuff(char *m, msg_disLowBusFbMsg &s) +bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disLowBusFbMsg &s) { + if (m == NULL || len < sizeof(msg_disLowBusFbMsg)) { + sError.push_back("DisSys LVBus Msg length error"); + return false; + } cChecksum sum; msg_disLowBusFbMsg *p; p = reinterpret_cast(m); @@ -145,35 +172,29 @@ bool udpComm::getMsgFromBuff(char *m, msg_disLowBusFbMsg &s) return true; } -bool udpComm::pushMsgToQueue(unsigned char *m) +bool udpComm::pushMsgToQueue(unsigned char *m, size_t len) { - if(m==NULL) + if(m==NULL || len < sizeof(m_header)) { // sError.push_back("pushMsgToQueue faile,Msg is NULL"); - LOG_F(ERROR, "pushMsgToQueue faile,Msg is NULL m: %p", m); + LOG_F(ERROR, "pushMsgToQueue faile,Msg is NULL or too short m: %p len: %zu", m, len); return false; } unsigned char* Buff = m; //消息头鉴定 - char *header = new char[sizeof(m_header)]; unsigned short id; - memcpy(header,Buff,sizeof(m_header)); - if(!getMsgId(header,id)) + if(!getMsgId((char *)Buff, len, id)) { - // sError.push_back("pushMsgToQueue faile,Msg ID error"); - // LOG_F(INFO, "pushMsgToQueue faile,Msg ID error header: %p", header); - delete []header; return false; } - delete []header; //输入消息 switch (id) { case CCU_STATE_FB_ID: //CCU_STATE_FB 0x0051 { msg_CcuStateFbMsg s; - if(getMsgFromBuff((char *)Buff,s)) + if(getMsgFromBuff((char *)Buff, len, s)) { if (m_commLogger) m_commLogger->onFrame(0, id, "ccuState", Buff, sizeof(msg_CcuStateFbMsg), true); std::lock_guard lock(m_mutexCcuState); @@ -198,7 +219,7 @@ bool udpComm::pushMsgToQueue(unsigned char *m) case CCU_SET_PARM_FB_ID: //CCU_SET_PARM_FB 0x0040 { msg_CcuSetParmFbMsg s; - if(getMsgFromBuff((char *)Buff,s)) + if(getMsgFromBuff((char *)Buff, len, s)) { if (m_commLogger) m_commLogger->onFrame(0, id, "ccuSetParmFb", Buff, sizeof(msg_CcuSetParmFbMsg), true); std::lock_guard lock(m_mutexCcuSetParm); @@ -223,7 +244,7 @@ bool udpComm::pushMsgToQueue(unsigned char *m) case DIS_HVBUS_FB_ID: //DIS_HVBUS_FB 0x0020 { msg_disHighVolBusFbMsg s; - if(getMsgFromBuff((char *)Buff,s)) + if(getMsgFromBuff((char *)Buff, len, s)) { if (m_commLogger) m_commLogger->onFrame(0, id, "disHighVolBusState", Buff, sizeof(msg_disHighVolBusFbMsg), true); std::lock_guard lock(m_mutexDisHighVolBus); @@ -248,7 +269,7 @@ bool udpComm::pushMsgToQueue(unsigned char *m) case DIS_HVBUSA_FB_ID: //DIS_HVBUSA_FB 0x0006 { msg_disHighAVolBusFbMsg s; - if(getMsgFromBuff((char *)Buff,s)) + if(getMsgFromBuff((char *)Buff, len, s)) { if (m_commLogger) m_commLogger->onFrame(0, id, "disHighAVolBusState", Buff, sizeof(msg_disHighAVolBusFbMsg), true); std::lock_guard lock(m_mutexDisHighAVolBus); @@ -273,7 +294,7 @@ bool udpComm::pushMsgToQueue(unsigned char *m) case DIS_HVBUSB_FB_ID: //DIS_HVBUSB_FB 0x0007 { msg_disLowMainBusFbMsg s; - if(getMsgFromBuff((char *)Buff,s)) + if(getMsgFromBuff((char *)Buff, len, s)) { if (m_commLogger) m_commLogger->onFrame(0, id, "disLowMainBusState", Buff, sizeof(msg_disLowMainBusFbMsg), true); std::lock_guard lock(m_mutexDisHighBVolBus); @@ -298,7 +319,7 @@ bool udpComm::pushMsgToQueue(unsigned char *m) case DIS_LVBUS_FB_ID: //DIS_LVBUS_FB 0x0008 { msg_disLowBusFbMsg s; - if(getMsgFromBuff((char *)Buff,s)) + if(getMsgFromBuff((char *)Buff, len, s)) { if (m_commLogger) m_commLogger->onFrame(0, id, "disLowBusState", Buff, sizeof(msg_disLowBusFbMsg), true); std::lock_guard lock(m_mutexDisLowBus); diff --git a/src/pPowerManger/udpcomm/udpComm.h b/src/pPowerManger/udpcomm/udpComm.h index 62247c6..5bc5efc 100644 --- a/src/pPowerManger/udpcomm/udpComm.h +++ b/src/pPowerManger/udpcomm/udpComm.h @@ -27,15 +27,15 @@ public: string ccuHost; long int ccuPort; - bool pushMsgToQueue(unsigned char *m); + bool pushMsgToQueue(unsigned char *m, size_t len); bool clearMsgQueue(); - bool getMsgFromBuff(char *m, msg_CcuStateFbMsg &s); - bool getMsgFromBuff(char *m, msg_CcuSetParmFbMsg &s); - bool getMsgFromBuff(char *m, msg_disHighVolBusFbMsg &s); - bool getMsgFromBuff(char *m, msg_disHighAVolBusFbMsg &s); - bool getMsgFromBuff(char *m, msg_disLowMainBusFbMsg &s); - bool getMsgFromBuff(char *m, msg_disLowBusFbMsg &s); + bool getMsgFromBuff(char *m, size_t len, msg_CcuStateFbMsg &s); + bool getMsgFromBuff(char *m, size_t len, msg_CcuSetParmFbMsg &s); + bool getMsgFromBuff(char *m, size_t len, msg_disHighVolBusFbMsg &s); + bool getMsgFromBuff(char *m, size_t len, msg_disHighAVolBusFbMsg &s); + bool getMsgFromBuff(char *m, size_t len, msg_disLowMainBusFbMsg &s); + bool getMsgFromBuff(char *m, size_t len, msg_disLowBusFbMsg &s); bool popMsgFormQueue(double &time,msg_CcuStateFbMsg &m); bool popMsgFormQueue(double &time,msg_CcuSetParmFbMsg &m); @@ -78,7 +78,7 @@ public: return false; } - bool getMsgId(char *m,unsigned short &id); + bool getMsgId(char *m, size_t len, unsigned short &id); Checksum calculateChecksum(const unsigned char* data, int size); Checksum calculateChecksum(const unsigned char* data, int dataSize, int checkSize); diff --git a/test/until/UdpCommTest.cpp b/test/until/UdpCommTest.cpp index a651063..6cfb9c6 100644 --- a/test/until/UdpCommTest.cpp +++ b/test/until/UdpCommTest.cpp @@ -31,7 +31,7 @@ TEST(UdpCommTest, GetMsgId) h.start2 = DIS_MSG_HEAD2; h.id = DIS_HVBUS_FB_ID; memcpy(buf, &h, sizeof(h)); - EXPECT_TRUE(u.getMsgId(buf, id)); + EXPECT_TRUE(u.getMsgId(buf, sizeof(buf), id)); EXPECT_EQ(id, DIS_HVBUS_FB_ID); // CCU 头 @@ -39,14 +39,18 @@ TEST(UdpCommTest, GetMsgId) h.start2 = CCU_UDPMSG_START2; h.id = CCU_STATE_FB_ID; memcpy(buf, &h, sizeof(h)); - EXPECT_TRUE(u.getMsgId(buf, id)); + EXPECT_TRUE(u.getMsgId(buf, sizeof(buf), id)); EXPECT_EQ(id, CCU_STATE_FB_ID); // 非法头 h.start1 = 0x11; h.start2 = 0x22; memcpy(buf, &h, sizeof(h)); - EXPECT_FALSE(u.getMsgId(buf, id)); + EXPECT_FALSE(u.getMsgId(buf, sizeof(buf), id)); + + // 长度不足 m_header → 拒绝(不读越界) + EXPECT_FALSE(u.getMsgId(buf, sizeof(m_header) - 1, id)); + EXPECT_FALSE(u.getMsgId(NULL, sizeof(m_header), id)); } TEST(UdpCommTest, GetMsgFromBuffCcu) @@ -63,14 +67,34 @@ TEST(UdpCommTest, GetMsgFromBuffCcu) m.checkCode = u.calculateChecksum((unsigned char*)&m, sizeof(m)); msg_CcuStateFbMsg out{}; - EXPECT_TRUE(u.getMsgFromBuff((char*)&m, out)); + EXPECT_TRUE(u.getMsgFromBuff((char*)&m, sizeof(m), out)); EXPECT_EQ(out.data.ins_soc, 42u); EXPECT_EQ(out.data.dyn_soc, 66u); EXPECT_EQ(out.data.fc_status, 0x04u); // 篡改数据 → 校验失败 m.data.dyn_soc = 99; - EXPECT_FALSE(u.getMsgFromBuff((char*)&m, out)); + EXPECT_FALSE(u.getMsgFromBuff((char*)&m, sizeof(m), out)); + + // 截断帧(长度不足)→ 拒绝,不写输出 + m.data.dyn_soc = 66; + m.checkCode = u.calculateChecksum((unsigned char*)&m, sizeof(m)); + msg_CcuStateFbMsg untouched{}; + untouched.data.ins_soc = 0xEE; + EXPECT_FALSE(u.getMsgFromBuff((char*)&m, sizeof(m) - 1, untouched)); + EXPECT_EQ(untouched.data.ins_soc, 0xEEu); + + // 超长帧(长度超出)→ 接受,忽略尾字节 + unsigned char longBuf[sizeof(m) + 16]; + memset(longBuf, 0, sizeof(longBuf)); + memcpy(longBuf, &m, sizeof(m)); + msg_CcuStateFbMsg outLong{}; + EXPECT_TRUE(u.getMsgFromBuff((char*)longBuf, sizeof(longBuf), outLong)); + EXPECT_EQ(outLong.data.ins_soc, 42u); + + // 空指针 / 长度不足 → 拒绝 + EXPECT_FALSE(u.getMsgFromBuff(NULL, sizeof(m), out)); + EXPECT_FALSE(u.getMsgFromBuff((char*)&m, 0, out)); } TEST(UdpCommTest, GetMsgFromBuffDis) @@ -86,13 +110,50 @@ TEST(UdpCommTest, GetMsgFromBuffDis) m.checkCode = (cChecksum)(u.calculateChecksum((unsigned char*)&m, sizeof(m), sizeof(cChecksum)) & 0xFF); msg_disHighVolBusFbMsg out{}; - EXPECT_TRUE(u.getMsgFromBuff((char*)&m, out)); + EXPECT_TRUE(u.getMsgFromBuff((char*)&m, sizeof(m), out)); EXPECT_EQ(out.data.fuelCellCircuitBreaker, 0x55u); EXPECT_EQ(out.data.powerBusVoltage, 5200u); // 篡改 → 校验失败 m.data.fuelCellCircuitBreaker = 0xAA; - EXPECT_FALSE(u.getMsgFromBuff((char*)&m, out)); + EXPECT_FALSE(u.getMsgFromBuff((char*)&m, sizeof(m), out)); + + // 截断帧 → 拒绝 + m.data.fuelCellCircuitBreaker = 0x55; + m.checkCode = (cChecksum)(u.calculateChecksum((unsigned char*)&m, sizeof(m), sizeof(cChecksum)) & 0xFF); + EXPECT_FALSE(u.getMsgFromBuff((char*)&m, sizeof(m) - 1, out)); +} + +TEST(UdpCommTest, PushMsgToQueueLengthGuard) +{ + udpComm u; + msg_CcuStateFbMsg m; + memset(&m, 0, sizeof(m)); + m.header.start1 = CCU_UDPMSG_START1; + m.header.start2 = CCU_UDPMSG_START2; + m.header.id = CCU_STATE_FB_ID; + m.data.ins_soc = 42; + m.checkCode = u.calculateChecksum((unsigned char*)&m, sizeof(m)); + + // 合法帧入队成功 + EXPECT_TRUE(u.pushMsgToQueue((unsigned char*)&m, sizeof(m))); + EXPECT_EQ(u.m_qReceiveCcuStateBuffer.size(), 1u); + EXPECT_EQ(u.m_qReceiveCcuStateBuffer.front().second.data.ins_soc, 42u); + + // 空指针 / 长度不足 m_header → 拒绝 + EXPECT_FALSE(u.pushMsgToQueue(NULL, sizeof(m))); + EXPECT_FALSE(u.pushMsgToQueue((unsigned char*)&m, sizeof(m_header) - 1)); + + // 截断帧(合法头 + 校验和,但长度不足整包)→ 拒绝入队 + msg_CcuStateFbMsg shortM; + memset(&shortM, 0, sizeof(shortM)); + shortM.header.start1 = CCU_UDPMSG_START1; + shortM.header.start2 = CCU_UDPMSG_START2; + shortM.header.id = CCU_STATE_FB_ID; + shortM.checkCode = u.calculateChecksum((unsigned char*)&shortM, sizeof(shortM) - 8); + size_t before = u.m_qReceiveCcuStateBuffer.size(); + EXPECT_FALSE(u.pushMsgToQueue((unsigned char*)&shortM, sizeof(shortM) - 8)); + EXPECT_EQ(u.m_qReceiveCcuStateBuffer.size(), before); } TEST(UdpCommTest, GetDate)