XNSim/XNMonitorServer/XNMonitorInterface.cpp

1007 lines
27 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file XNMonitorInterface.cpp
* @brief 监控服务器接口实现
*/
#include "XNMonitorInterface.h"
#include "SystemInfoMonitor.h"
#include "ModelInfoMonitor.h"
#include "SystemControl.h"
#include "DataMonitorFactory.h"
#include "DataInjectThread.h"
#include "CSVDataInjectThread.h"
#include "DataCollect.h"
#include "PluginManager.h"
#include "PluginGenerator.h"
// 全局变量
static bool g_initialized = false;
SystemInfoMonitor *systemInfoMonitor = nullptr;
bool g_systemInfoMonitorStarted = false;
ModelInfoMonitor *modelInfoMonitor = nullptr;
bool g_modelInfoMonitorStarted = false;
SystemControl *systemControl = nullptr;
bool g_systemControlStarted = false;
std::unordered_map<std::string, DataInjectThreadPtr> g_dataInjectThreads;
CSVDataInjectThread *g_csvDataInjectThread = nullptr;
DataCollect *g_dataCollect = nullptr;
/**
* @brief 生成插件
* @param confID 构型ID
* @param errorMsg 错误信息
* @param errorMsgSize 错误信息大小
* @return 0: 成功, -1: 失败
*/
int XN_GenPlugin(int confID, int forceGen, char *errorMsg, int errorMsgSize);
// 初始化函数实现
int XN_Initialize(const char *domainId, int domainIdLen, int confID, int forceGen, char *errorMsg,
int errorMsgSize)
{
if (g_initialized) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "DDSMonitor Initialized Successfully", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
}
try {
if (!domainId || domainIdLen <= 0) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Invalid domainId", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
// 创建临时字符串确保以null结尾
std::string domainIdStr(domainId, domainIdLen);
int domainIdInt = std::stoi(domainIdStr);
if (domainIdInt < 0 || domainIdInt > 232) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Invalid domainId", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
// 生成插件
if (XN_GenPlugin(confID, forceGen, errorMsg, errorMsgSize) != 0) {
return -1;
}
// 先初始化DDS参与者
XNDDSErrorCode ret = TopicManager::Instance()->initializeParticipant(domainIdInt);
if (ret != XNDDSErrorCode::SUCCESS) {
if (errorMsg && errorMsgSize > 0) {
std::string error = "Failed to initialize DDSMonitor, error code: "
+ std::to_string(static_cast<int>(ret));
strncpy(errorMsg, error.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
// 初始化插件管理器
auto &pluginManager = PluginManager::Instance();
// 加载生成的插件
if (!pluginManager.LoadPluginFromGenerator()) {
if (errorMsg && errorMsgSize > 0) {
std::string error = "Failed to load generated plugin";
strncpy(errorMsg, error.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
g_initialized = true;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "DDSMonitor Initialized Successfully", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
} catch (const std::exception &e) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, e.what(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
}
int XN_StartMonitorSystemInfo(char *errorMsg, int errorMsgSize)
{
if (!g_initialized) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "DDSMonitor Not Initialized", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
if (g_systemInfoMonitorStarted) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "System Info Monitor Already Started", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
try {
systemInfoMonitor = new SystemInfoMonitor();
std::string ret = systemInfoMonitor->Initialize();
if (ret == "Success") {
g_systemInfoMonitorStarted = true;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "System Info Monitor Started Successfully", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
} else {
delete systemInfoMonitor;
systemInfoMonitor = nullptr;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, ret.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
} catch (const std::exception &e) {
if (systemInfoMonitor) {
delete systemInfoMonitor;
systemInfoMonitor = nullptr;
}
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, e.what(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
}
int XN_GetSystemInfo(char *infoMsg, int infoMsgSize)
{
if (!g_systemInfoMonitorStarted) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "System Info Monitor Not Started", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
std::string info = systemInfoMonitor->GetSystemInfo();
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, info.c_str(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return 0;
} catch (const std::exception &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
}
int XN_GetAllThreadInfo(char *infoMsg, int infoMsgSize)
{
if (!g_systemInfoMonitorStarted) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "System Info Monitor Not Started", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
std::string info = systemInfoMonitor->GetAllThreadInfo();
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, info.c_str(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return 0;
} catch (const std::exception &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
}
void XN_StopMonitorSystemInfo()
{
if (g_systemInfoMonitorStarted) {
delete systemInfoMonitor;
systemInfoMonitor = nullptr;
g_systemInfoMonitorStarted = false;
}
}
int XN_StartMonitorModelInfo(char *errorMsg, int errorMsgSize)
{
if (!g_initialized) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "DDSMonitor Not Initialized", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
if (g_modelInfoMonitorStarted) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Model Info Monitor Already Started", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
try {
modelInfoMonitor = new ModelInfoMonitor();
std::string ret = modelInfoMonitor->Initialize();
if (ret == "Success") {
g_modelInfoMonitorStarted = true;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Model Info Monitor Started Successfully", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
} else {
delete modelInfoMonitor;
modelInfoMonitor = nullptr;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, ret.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
} catch (const std::exception &e) {
if (modelInfoMonitor) {
delete modelInfoMonitor;
modelInfoMonitor = nullptr;
}
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, e.what(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
}
int XN_GetModelInfo(char *infoMsg, int infoMsgSize)
{
if (!g_modelInfoMonitorStarted) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Model Info Monitor Not Started", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
std::string info = modelInfoMonitor->GetAllModelInfo();
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, info.c_str(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return 0;
} catch (const std::exception &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
}
void XN_StopMonitorModelInfo()
{
if (g_modelInfoMonitorStarted) {
delete modelInfoMonitor;
modelInfoMonitor = nullptr;
g_modelInfoMonitorStarted = false;
}
}
int XN_InitializeEngineControl(char *errorMsg, int errorMsgSize)
{
if (g_systemControlStarted) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Engine Control Already Started", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
}
systemControl = new SystemControl();
std::string ret = systemControl->Initialize();
if (ret == "Success") {
g_systemControlStarted = true;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Engine Control Initialized Successfully", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
} else {
delete systemControl;
systemControl = nullptr;
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, ret.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
}
void XN_PauseEngine(char *errorMsg, int errorMsgSize)
{
if (!g_systemControlStarted) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Engine Control Not Started", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return;
}
systemControl->Pause();
}
void XN_ResumeEngine(char *errorMsg, int errorMsgSize)
{
if (!g_systemControlStarted) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Engine Control Not Started", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return;
}
systemControl->Resume();
}
void XN_StopEngine(char *errorMsg, int errorMsgSize)
{
if (!g_systemControlStarted) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Engine Control Not Started", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return;
}
systemControl->Stop();
}
void XN_CleanupEngineControl()
{
if (g_systemControlStarted) {
systemControl->cleanup();
delete systemControl;
systemControl = nullptr;
g_systemControlStarted = false;
}
}
int XN_StartDataMonitor(const char *structName, const int structNameLen, char *errorMsg,
int errorMsgSize)
{
if (!g_initialized) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "DDSMonitor Not Initialized", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
std::string structNameStr(structName, structNameLen);
auto dataMonitor = DataMonitorFactory::GetInstance(structNameStr);
if (dataMonitor == nullptr) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Invalid struct name", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
if (!dataMonitor->isInitialized()) {
dataMonitor->Initialize(nullptr, 0, 0);
}
return 0;
}
void XN_StopDataMonitor(const char *structName, const int structNameLen, char *errorMsg,
int errorMsgSize)
{
if (!g_initialized) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "DDSMonitor Not Initialized", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return;
}
std::string structNameStr(structName, structNameLen);
DataMonitorFactory::ReleaseInstance(structNameStr);
return;
}
int XN_GetDataMonitorInfo(const char *structName, const int structNameLen,
const char *interfaceName, const int interfaceNameLen, char *data,
int dataLen, char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string structNameStr(structName, structNameLen);
auto dataMonitor = DataMonitorFactory::GetInstance(structNameStr);
if (dataMonitor == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid interface name", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (!dataMonitor->isInitialized()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Data Monitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string interfaceNameStr(interfaceName, interfaceNameLen);
try {
nlohmann::json interfaceNamesJson = nlohmann::json::parse(interfaceNameStr);
if (!interfaceNamesJson.is_array()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Interface name must be a JSON array", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::vector<std::string> interfaceNames;
for (const auto &name : interfaceNamesJson) {
if (!name.is_string()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Interface name must be a string", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
interfaceNames.push_back(name.get<std::string>());
}
std::unordered_map<std::string, std::string> resultData =
dataMonitor->getStringData(interfaceNames);
nlohmann::json resultJson;
for (const auto &pair : resultData) {
resultJson[pair.first] = pair.second;
}
std::string resultStr = resultJson.dump();
if (data && dataLen > 0) {
strncpy(data, resultStr.c_str(), dataLen - 1);
data[dataLen - 1] = '\0';
}
} catch (const nlohmann::json::parse_error &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid JSON format", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
int XN_InjectDataInterface(const char *structName, const int structNameLen,
const char *interfaceNameAndData, const int interfaceNameAndDataLen,
char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string structNameStr(structName, structNameLen);
auto dataMonitor = DataMonitorFactory::GetInstance(structNameStr);
if (dataMonitor == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid interface name", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (!dataMonitor->isInitialized()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Data Monitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string interfaceNameStr(interfaceNameAndData, interfaceNameAndDataLen);
try {
nlohmann::json interfaceNames = nlohmann::json::parse(interfaceNameStr);
std::unordered_map<std::string, std::string> dataMap;
for (const auto &[key, value] : interfaceNames.items()) {
dataMap[key] = value.get<std::string>();
}
dataMonitor->setDataByString(dataMap);
} catch (const nlohmann::json::parse_error &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid JSON format", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
int XN_StartInjectContinuous(const char *structName, const int structNameLen,
const char *interfaceNameAndData, const int interfaceNameAndDataLen,
double frequency, char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string structNameStr(structName, structNameLen);
auto dataMonitor = DataMonitorFactory::GetInstance(structNameStr);
if (dataMonitor == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid Struct Name", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (!dataMonitor->isInitialized()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Data Monitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string interfaceNameStr(interfaceNameAndData, interfaceNameAndDataLen);
try {
nlohmann::json interfaceNames = nlohmann::json::parse(interfaceNameStr);
std::unordered_map<std::string, std::string> dataMap;
for (const auto &[key, value] : interfaceNames.items()) {
dataMap[key] = value.get<std::string>();
}
auto it = g_dataInjectThreads.find(structNameStr);
if (it != g_dataInjectThreads.end()) {
it->second->updateData(dataMap);
it->second->updateFrequency(frequency);
} else {
DataInjectThreadPtr dataInjectThread =
std::make_shared<DataInjectThread>(dataMonitor, dataMap, frequency);
dataInjectThread->start();
g_dataInjectThreads[structNameStr] = dataInjectThread;
}
} catch (const nlohmann::json::parse_error &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid JSON format", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
int XN_StopInjectContinuous(const char *structName, const int structNameLen, char *infoMsg,
int infoMsgSize)
{
std::string structNameStr(structName, structNameLen);
auto it = g_dataInjectThreads.find(structNameStr);
if (it != g_dataInjectThreads.end()) {
it->second->stop();
g_dataInjectThreads.erase(it);
}
return 0;
}
void XN_CleanupInjectContinuous()
{
for (auto &it : g_dataInjectThreads) {
if (it.second) {
it.second->stop();
it.second.reset();
it.second = nullptr;
}
}
g_dataInjectThreads.clear();
}
// 从csv文件中注入数据接口
int XN_InjectDataInterfaceFromCsv(const char *injectDataInfo, const int injectDataInfoLen,
const char *csvFilePath, const int csvFilePathLen, char *infoMsg,
int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (g_csvDataInjectThread != nullptr) {
g_csvDataInjectThread->stop();
delete g_csvDataInjectThread;
g_csvDataInjectThread = nullptr;
}
std::vector<MonitorDataInfo> injectDataInfos;
std::string injectDataInfoStr(injectDataInfo, injectDataInfoLen);
try {
nlohmann::json injectDataInfoJson = nlohmann::json::parse(injectDataInfoStr);
for (const auto &[structName, interfaceInfo] : injectDataInfoJson.items()) {
MonitorDataInfo info;
info.structName = structName;
for (const auto &[interfaceName, size] : interfaceInfo.items()) {
info.interfaceNames.push_back(interfaceName);
if (size.is_array()) {
info.arraySizes.push_back({size[0].get<int>(), size[1].get<int>()});
} else {
info.arraySizes.push_back({0, 0});
}
}
injectDataInfos.push_back(info);
}
} catch (const nlohmann::json::parse_error &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid JSON format", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string csvFilePathStr(csvFilePath, csvFilePathLen);
if (csvFilePathStr.empty()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "CSV 文件路径为空", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (!std::filesystem::exists(csvFilePathStr)) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "CSV 文件不存在", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
g_csvDataInjectThread = new CSVDataInjectThread(csvFilePathStr);
if (!g_csvDataInjectThread->Initialize(injectDataInfos)) {
delete g_csvDataInjectThread;
g_csvDataInjectThread = nullptr;
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "CSV 注入线程初始化失败", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
g_csvDataInjectThread->start();
} catch (const std::exception &e) {
if (g_csvDataInjectThread) {
delete g_csvDataInjectThread;
g_csvDataInjectThread = nullptr;
}
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
int XN_GetCsvDataInjectStatus(char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (g_csvDataInjectThread == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "CSV 注入线程已不存在", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return g_csvDataInjectThread->isRunning() ? 1 : 0;
}
int XN_StopCsvDataInject(char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (g_csvDataInjectThread == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "CSV 注入线程已不存在", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
g_csvDataInjectThread->stop();
delete g_csvDataInjectThread;
g_csvDataInjectThread = nullptr;
} catch (const std::exception &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
void XN_CleanupCsvDataInject()
{
if (g_csvDataInjectThread != nullptr) {
g_csvDataInjectThread->stop();
delete g_csvDataInjectThread;
g_csvDataInjectThread = nullptr;
}
}
int XN_StartCollectData(const char *CollectDataInfo, const int CollectDataInfoLen,
const char *dcsFilePath, const int dcsFilePathLen, char *infoMsg,
int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (g_dataCollect != nullptr) {
g_dataCollect->stop();
delete g_dataCollect;
g_dataCollect = nullptr;
}
std::vector<MonitorDataInfo> collectDataInfos;
std::string collectDataInfoStr(CollectDataInfo, CollectDataInfoLen);
try {
nlohmann::json collectDataInfoJson = nlohmann::json::parse(collectDataInfoStr);
for (const auto &[structName, interfaceInfo] : collectDataInfoJson.items()) {
MonitorDataInfo info;
info.structName = structName;
for (const auto &[interfaceName, size] : interfaceInfo.items()) {
info.interfaceNames.push_back(interfaceName);
if (size.is_array()) {
info.arraySizes.push_back({size[0].get<int>(), size[1].get<int>()});
} else {
info.arraySizes.push_back({0, 0});
}
}
collectDataInfos.push_back(info);
}
} catch (const nlohmann::json::parse_error &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "Invalid JSON format", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
std::string dcsFilePathStr(dcsFilePath, dcsFilePathLen);
if (dcsFilePathStr.empty()) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DCS 文件路径为空", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (!std::filesystem::exists(dcsFilePathStr)) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DCS 文件不存在", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
g_dataCollect = new DataCollect();
if (!g_dataCollect->Initialize(collectDataInfos, dcsFilePathStr)) {
delete g_dataCollect;
g_dataCollect = nullptr;
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "数据采集线程初始化失败", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
g_dataCollect->start();
} catch (const std::exception &e) {
if (g_dataCollect) {
delete g_dataCollect;
g_dataCollect = nullptr;
}
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
int XN_GetCollectDataStatus(char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (g_dataCollect == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "数据采集线程已不存在", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return g_dataCollect->isRunning() ? 1 : 0;
}
int XN_StopCollectData(char *infoMsg, int infoMsgSize)
{
if (!g_initialized) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
if (g_dataCollect == nullptr) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, "数据采集线程已不存在", infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
try {
g_dataCollect->stop();
} catch (const std::exception &e) {
if (infoMsg && infoMsgSize > 0) {
strncpy(infoMsg, e.what(), infoMsgSize - 1);
infoMsg[infoMsgSize - 1] = '\0';
}
return -1;
}
return 0;
}
void XN_CleanupDataCollect()
{
if (g_dataCollect != nullptr) {
g_dataCollect->stop();
delete g_dataCollect;
g_dataCollect = nullptr;
}
}
// 生成插件函数实现
int XN_GenPlugin(int confID, int forceGen, char *errorMsg, int errorMsgSize)
{
try {
// 创建插件生成器
PluginGenerator generator;
// 从数据库加载插件信息
if (!generator.loadPluginFromDatabase(confID)) {
if (errorMsg && errorMsgSize > 0) {
std::string error =
"Failed to load plugin info from database: " + generator.getLastError();
strncpy(errorMsg, error.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
if (forceGen == 1) {
// 生成插件cpp文件
if (!generator.generatePluginCpp()) {
if (errorMsg && errorMsgSize > 0) {
std::string error =
"Failed to generate plugin cpp: " + generator.getLastError();
strncpy(errorMsg, error.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
// 生成CMakeLists.txt
if (!generator.generateCMakeLists()) {
if (errorMsg && errorMsgSize > 0) {
std::string error =
"Failed to generate CMakeLists: " + generator.getLastError();
strncpy(errorMsg, error.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
// 编译插件
if (!generator.compilePlugin()) {
if (errorMsg && errorMsgSize > 0) {
std::string error = "Failed to compile plugin: " + generator.getLastError();
strncpy(errorMsg, error.c_str(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
}
// 保存插件信息到插件管理器
PluginManager::Instance().SetGeneratedPluginInfo(generator.getPluginInfo());
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, "Plugin generated and compiled successfully", errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return 0;
} catch (const std::exception &e) {
if (errorMsg && errorMsgSize > 0) {
strncpy(errorMsg, e.what(), errorMsgSize - 1);
errorMsg[errorMsgSize - 1] = '\0';
}
return -1;
}
}
// 清理函数实现
void XN_Cleanup()
{
if (g_initialized) {
// 停止并清理系统信息监控
if (g_systemInfoMonitorStarted) {
XN_StopMonitorSystemInfo();
}
// 停止并清理模型信息监控
if (g_modelInfoMonitorStarted) {
XN_StopMonitorModelInfo();
}
// 停止并清理引擎控制
if (g_systemControlStarted) {
XN_CleanupEngineControl();
}
// 停止并清理数据注入
XN_CleanupInjectContinuous();
// 停止并清理CSV数据注入
XN_CleanupCsvDataInject();
// 停止并清理数据采集
XN_CleanupDataCollect();
// 先清理DDS参与者再卸载插件
TopicManager::cleanupParticipant();
// 卸载动态加载的插件
PluginManager::Instance().UnloadCurrentPlugin();
g_initialized = false;
}
}