2025-05-14 14:30:38 +08:00
|
|
|
|
/**
|
|
|
|
|
* @file XNMonitorInterface.cpp
|
|
|
|
|
* @brief 监控服务器接口实现
|
|
|
|
|
*/
|
|
|
|
|
#include "XNMonitorInterface.h"
|
|
|
|
|
#include "SystemInfoMonitor.h"
|
2025-05-14 20:18:44 +08:00
|
|
|
|
#include "ModelInfoMonitor.h"
|
2025-05-29 14:38:09 +08:00
|
|
|
|
#include "SystemControl.h"
|
2025-05-30 14:16:16 +08:00
|
|
|
|
#include "DataMonitorFactory.h"
|
|
|
|
|
#include "DataInjectThread.h"
|
2025-06-12 14:50:27 +08:00
|
|
|
|
#include "CSVDataInjectThread.h"
|
2025-06-16 16:19:12 +08:00
|
|
|
|
#include "DataCollect.h"
|
2025-06-24 16:07:07 +08:00
|
|
|
|
#include "PluginManager.h"
|
|
|
|
|
#include "PluginGenerator.h"
|
2025-05-14 14:30:38 +08:00
|
|
|
|
|
|
|
|
|
// 全局变量
|
|
|
|
|
static bool g_initialized = false;
|
|
|
|
|
|
|
|
|
|
SystemInfoMonitor *systemInfoMonitor = nullptr;
|
|
|
|
|
bool g_systemInfoMonitorStarted = false;
|
2025-05-14 20:18:44 +08:00
|
|
|
|
ModelInfoMonitor *modelInfoMonitor = nullptr;
|
|
|
|
|
bool g_modelInfoMonitorStarted = false;
|
2025-05-29 14:38:09 +08:00
|
|
|
|
SystemControl *systemControl = nullptr;
|
|
|
|
|
bool g_systemControlStarted = false;
|
2025-05-14 14:30:38 +08:00
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
std::unordered_map<std::string, DataInjectThreadPtr> g_dataInjectThreads;
|
2025-06-13 15:12:15 +08:00
|
|
|
|
CSVDataInjectThread *g_csvDataInjectThread = nullptr;
|
2025-06-16 16:19:12 +08:00
|
|
|
|
DataCollect *g_dataCollect = nullptr;
|
2025-06-12 14:50:27 +08:00
|
|
|
|
|
2025-06-24 16:07:07 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief 生成插件
|
|
|
|
|
* @param confID 构型ID
|
|
|
|
|
* @param errorMsg 错误信息
|
|
|
|
|
* @param errorMsgSize 错误信息大小
|
|
|
|
|
* @return 0: 成功, -1: 失败
|
|
|
|
|
*/
|
|
|
|
|
int XN_GenPlugin(int confID, int forceGen, char *errorMsg, int errorMsgSize);
|
|
|
|
|
|
2025-05-14 14:30:38 +08:00
|
|
|
|
// 初始化函数实现
|
2025-06-24 16:07:07 +08:00
|
|
|
|
int XN_Initialize(const char *domainId, int domainIdLen, int confID, int forceGen, char *errorMsg,
|
|
|
|
|
int errorMsgSize)
|
2025-05-14 14:30:38 +08:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-24 16:07:07 +08:00
|
|
|
|
// 生成插件
|
|
|
|
|
if (XN_GenPlugin(confID, forceGen, errorMsg, errorMsgSize) != 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 先初始化DDS参与者
|
2025-05-14 14:30:38 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-24 16:07:07 +08:00
|
|
|
|
// 初始化插件管理器
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-14 14:30:38 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-14 20:18:44 +08:00
|
|
|
|
if (g_systemInfoMonitorStarted) {
|
|
|
|
|
if (errorMsg && errorMsgSize > 0) {
|
|
|
|
|
strncpy(errorMsg, "System Info Monitor Already Started", errorMsgSize - 1);
|
|
|
|
|
errorMsg[errorMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-14 14:30:38 +08:00
|
|
|
|
try {
|
|
|
|
|
systemInfoMonitor = new SystemInfoMonitor();
|
|
|
|
|
std::string ret = systemInfoMonitor->Initialize();
|
|
|
|
|
if (ret == "Success") {
|
|
|
|
|
g_systemInfoMonitorStarted = true;
|
|
|
|
|
if (errorMsg && errorMsgSize > 0) {
|
2025-05-14 20:18:44 +08:00
|
|
|
|
strncpy(errorMsg, "System Info Monitor Started Successfully", errorMsgSize - 1);
|
2025-05-14 14:30:38 +08:00
|
|
|
|
errorMsg[errorMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
2025-05-14 20:18:44 +08:00
|
|
|
|
delete systemInfoMonitor;
|
|
|
|
|
systemInfoMonitor = nullptr;
|
2025-05-14 14:30:38 +08:00
|
|
|
|
if (errorMsg && errorMsgSize > 0) {
|
|
|
|
|
strncpy(errorMsg, ret.c_str(), errorMsgSize - 1);
|
|
|
|
|
errorMsg[errorMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::exception &e) {
|
2025-05-14 20:18:44 +08:00
|
|
|
|
if (systemInfoMonitor) {
|
|
|
|
|
delete systemInfoMonitor;
|
|
|
|
|
systemInfoMonitor = nullptr;
|
|
|
|
|
}
|
2025-05-14 14:30:38 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-14 20:18:44 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-29 14:38:09 +08:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
void XN_CleanupEngineControl()
|
|
|
|
|
{
|
|
|
|
|
if (g_systemControlStarted) {
|
|
|
|
|
systemControl->cleanup();
|
|
|
|
|
delete systemControl;
|
|
|
|
|
systemControl = nullptr;
|
|
|
|
|
g_systemControlStarted = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-30 14:16:16 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
void XN_CleanupInjectContinuous()
|
|
|
|
|
{
|
|
|
|
|
for (auto &it : g_dataInjectThreads) {
|
|
|
|
|
if (it.second) {
|
|
|
|
|
it.second->stop();
|
|
|
|
|
it.second.reset();
|
|
|
|
|
it.second = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
g_dataInjectThreads.clear();
|
|
|
|
|
}
|
2025-05-30 14:16:16 +08:00
|
|
|
|
// 从csv文件中注入数据接口
|
2025-06-18 17:13:19 +08:00
|
|
|
|
int XN_InjectDataInterfaceFromCsv(const char *injectDataInfo, const int injectDataInfoLen,
|
|
|
|
|
const char *csvFilePath, const int csvFilePathLen, char *infoMsg,
|
|
|
|
|
int infoMsgSize)
|
2025-05-30 14:16:16 +08:00
|
|
|
|
{
|
2025-06-13 15:12:15 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
2025-06-16 16:19:12 +08:00
|
|
|
|
std::vector<MonitorDataInfo> injectDataInfos;
|
2025-06-13 15:12:15 +08:00
|
|
|
|
std::string injectDataInfoStr(injectDataInfo, injectDataInfoLen);
|
2025-06-12 14:50:27 +08:00
|
|
|
|
try {
|
2025-06-13 15:12:15 +08:00
|
|
|
|
nlohmann::json injectDataInfoJson = nlohmann::json::parse(injectDataInfoStr);
|
|
|
|
|
for (const auto &[structName, interfaceInfo] : injectDataInfoJson.items()) {
|
2025-06-16 16:19:12 +08:00
|
|
|
|
MonitorDataInfo info;
|
2025-06-13 15:12:15 +08:00
|
|
|
|
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});
|
|
|
|
|
}
|
2025-06-12 14:50:27 +08:00
|
|
|
|
}
|
2025-06-13 15:12:15 +08:00
|
|
|
|
injectDataInfos.push_back(info);
|
2025-06-12 14:50:27 +08:00
|
|
|
|
}
|
|
|
|
|
} 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;
|
|
|
|
|
}
|
2025-06-13 15:12:15 +08:00
|
|
|
|
try {
|
|
|
|
|
g_csvDataInjectThread = new CSVDataInjectThread(csvFilePathStr);
|
|
|
|
|
if (!g_csvDataInjectThread->Initialize(injectDataInfos)) {
|
|
|
|
|
delete g_csvDataInjectThread;
|
|
|
|
|
g_csvDataInjectThread = nullptr;
|
2025-06-12 14:50:27 +08:00
|
|
|
|
if (infoMsg && infoMsgSize > 0) {
|
|
|
|
|
strncpy(infoMsg, "CSV 注入线程初始化失败", infoMsgSize - 1);
|
|
|
|
|
infoMsg[infoMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2025-06-13 15:12:15 +08:00
|
|
|
|
g_csvDataInjectThread->start();
|
|
|
|
|
} catch (const std::exception &e) {
|
|
|
|
|
if (g_csvDataInjectThread) {
|
|
|
|
|
delete g_csvDataInjectThread;
|
|
|
|
|
g_csvDataInjectThread = nullptr;
|
|
|
|
|
}
|
2025-06-12 14:50:27 +08:00
|
|
|
|
if (infoMsg && infoMsgSize > 0) {
|
2025-06-13 15:12:15 +08:00
|
|
|
|
strncpy(infoMsg, e.what(), infoMsgSize - 1);
|
2025-06-12 14:50:27 +08:00
|
|
|
|
infoMsg[infoMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 17:04:01 +08:00
|
|
|
|
int XN_GetCsvDataInjectStatus(char *infoMsg, int infoMsgSize)
|
|
|
|
|
{
|
2025-06-13 15:12:15 +08:00
|
|
|
|
if (!g_initialized) {
|
|
|
|
|
if (infoMsg && infoMsgSize > 0) {
|
|
|
|
|
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
|
|
|
|
|
infoMsg[infoMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 17:04:01 +08:00
|
|
|
|
if (g_csvDataInjectThread == nullptr) {
|
|
|
|
|
if (infoMsg && infoMsgSize > 0) {
|
|
|
|
|
strncpy(infoMsg, "CSV 注入线程已不存在", infoMsgSize - 1);
|
|
|
|
|
infoMsg[infoMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2025-06-13 15:12:15 +08:00
|
|
|
|
|
|
|
|
|
return g_csvDataInjectThread->isRunning() ? 1 : 0;
|
2025-06-12 17:04:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 14:50:27 +08:00
|
|
|
|
int XN_StopCsvDataInject(char *infoMsg, int infoMsgSize)
|
|
|
|
|
{
|
2025-06-13 15:12:15 +08:00
|
|
|
|
if (!g_initialized) {
|
|
|
|
|
if (infoMsg && infoMsgSize > 0) {
|
|
|
|
|
strncpy(infoMsg, "DDSMonitor Not Initialized", infoMsgSize - 1);
|
|
|
|
|
infoMsg[infoMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 14:50:27 +08:00
|
|
|
|
if (g_csvDataInjectThread == nullptr) {
|
|
|
|
|
if (infoMsg && infoMsgSize > 0) {
|
|
|
|
|
strncpy(infoMsg, "CSV 注入线程已不存在", infoMsgSize - 1);
|
|
|
|
|
infoMsg[infoMsgSize - 1] = '\0';
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-13 15:12:15 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 14:50:27 +08:00
|
|
|
|
return 0;
|
2025-05-30 14:16:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
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)
|
2025-05-30 14:16:16 +08:00
|
|
|
|
{
|
2025-06-16 16:19:12 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
int XN_GetCollectDataStatus(char *infoMsg, int infoMsgSize)
|
2025-06-16 16:19:12 +08:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
int XN_StopCollectData(char *infoMsg, int infoMsgSize)
|
2025-06-16 16:19:12 +08:00
|
|
|
|
{
|
|
|
|
|
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;
|
2025-06-18 17:13:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XN_CleanupDataCollect()
|
|
|
|
|
{
|
|
|
|
|
if (g_dataCollect != nullptr) {
|
|
|
|
|
g_dataCollect->stop();
|
|
|
|
|
delete g_dataCollect;
|
|
|
|
|
g_dataCollect = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-24 16:07:07 +08:00
|
|
|
|
|
|
|
|
|
// 生成插件函数实现
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
// 清理函数实现
|
|
|
|
|
void XN_Cleanup()
|
|
|
|
|
{
|
|
|
|
|
if (g_initialized) {
|
|
|
|
|
// 停止并清理系统信息监控
|
|
|
|
|
if (g_systemInfoMonitorStarted) {
|
|
|
|
|
XN_StopMonitorSystemInfo();
|
|
|
|
|
}
|
|
|
|
|
// 停止并清理模型信息监控
|
|
|
|
|
if (g_modelInfoMonitorStarted) {
|
|
|
|
|
XN_StopMonitorModelInfo();
|
|
|
|
|
}
|
|
|
|
|
// 停止并清理引擎控制
|
|
|
|
|
if (g_systemControlStarted) {
|
|
|
|
|
XN_CleanupEngineControl();
|
|
|
|
|
}
|
|
|
|
|
// 停止并清理数据注入
|
|
|
|
|
XN_CleanupInjectContinuous();
|
2025-06-24 16:07:07 +08:00
|
|
|
|
// 停止并清理CSV数据注入
|
|
|
|
|
XN_CleanupCsvDataInject();
|
|
|
|
|
// 停止并清理数据采集
|
|
|
|
|
XN_CleanupDataCollect();
|
2025-06-18 17:13:19 +08:00
|
|
|
|
|
2025-06-24 16:07:07 +08:00
|
|
|
|
// 先清理DDS参与者,再卸载插件
|
2025-06-18 17:13:19 +08:00
|
|
|
|
TopicManager::cleanupParticipant();
|
2025-06-24 16:07:07 +08:00
|
|
|
|
|
|
|
|
|
// 卸载动态加载的插件
|
|
|
|
|
PluginManager::Instance().UnloadCurrentPlugin();
|
|
|
|
|
|
2025-06-18 17:13:19 +08:00
|
|
|
|
g_initialized = false;
|
|
|
|
|
}
|
2025-05-30 14:16:16 +08:00
|
|
|
|
}
|