|
@@ -0,0 +1,531 @@
|
|
|
+// common_api.cpp
|
|
|
+#include <time.h>
|
|
|
+#include <sys/time.h>
|
|
|
+#include <pthread.h>
|
|
|
+#include <dlfcn.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <limits.h>
|
|
|
+#include "common_api.h"
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+// 全局互斥锁初始化
|
|
|
+common_api::common_api(void) {
|
|
|
+ pthread_mutex_init(&m_NotifyMutex, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+common_api::~common_api(void) {
|
|
|
+ pthread_mutex_destroy(&m_NotifyMutex);
|
|
|
+}
|
|
|
+
|
|
|
+common_api g_common1_for_init;
|
|
|
+
|
|
|
+//=== 时间相关函数 ===//
|
|
|
+__time64_t GetCurrentRealTimeOfStk() {
|
|
|
+ return time(NULL);
|
|
|
+}
|
|
|
+
|
|
|
+UINT64 GetDay(UINT64 TheTime) {
|
|
|
+ struct tm tCur;
|
|
|
+ gmtime_r((time_t*)&TheTime, &tCur);
|
|
|
+ tCur.tm_sec = 0;
|
|
|
+ tCur.tm_min = 0;
|
|
|
+ tCur.tm_hour = 0;
|
|
|
+ return mktime(&tCur);
|
|
|
+}
|
|
|
+
|
|
|
+int CompareTimeByDay(UINT64 Prev, UINT64 Cur) {
|
|
|
+ return (Cur / (24 * 3600)) - (Prev / (24 * 3600));
|
|
|
+}
|
|
|
+
|
|
|
+//=== GUID转换 ===//
|
|
|
+bool string_2_guid(const char* pstr, GUID& stGuid) {
|
|
|
+ return sscanf(pstr, "{%8lx-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx}",
|
|
|
+ &stGuid.Data1, &stGuid.Data2, &stGuid.Data3,
|
|
|
+ &stGuid.Data4[0], &stGuid.Data4[1], &stGuid.Data4[2], &stGuid.Data4[3],
|
|
|
+ &stGuid.Data4[4], &stGuid.Data4[5], &stGuid.Data4[6], &stGuid.Data4[7]) == 11;
|
|
|
+}
|
|
|
+
|
|
|
+bool guid_2_string(GUID& stGuid, string& str) {
|
|
|
+ char szBuff[128];
|
|
|
+ snprintf(szBuff, sizeof(szBuff), "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
|
|
+ stGuid.Data1, stGuid.Data2, stGuid.Data3,
|
|
|
+ stGuid.Data4[0], stGuid.Data4[1], stGuid.Data4[2], stGuid.Data4[3],
|
|
|
+ stGuid.Data4[4], stGuid.Data4[5], stGuid.Data4[6], stGuid.Data4[7]);
|
|
|
+ str = szBuff;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+const char* secure_getenv_n(const char* name)
|
|
|
+{
|
|
|
+ static char buffer[4096];
|
|
|
+ if (name == nullptr) return nullptr;
|
|
|
+
|
|
|
+ // 使用文件流读取/proc/self/environ
|
|
|
+ FILE* f = fopen("/proc/self/environ", "r");
|
|
|
+ if (!f) return nullptr;
|
|
|
+
|
|
|
+ size_t name_len = strlen(name);
|
|
|
+ while (fgets(buffer, sizeof(buffer), f)) {
|
|
|
+ if (strncmp(buffer, name, name_len) == 0 && buffer[name_len] == '=') {
|
|
|
+ fclose(f);
|
|
|
+ return buffer + name_len + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(f);
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
+//=== 环境变量操作 ===//
|
|
|
+bool AddEnvPath(const char* pPath) {
|
|
|
+ UNUSED(pPath);
|
|
|
+ //// 1. 输入验证
|
|
|
+ //if (!pPath || *pPath == '\0') {
|
|
|
+ // std::cerr << "AddEnvPath: Invalid path" << std::endl;
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+
|
|
|
+ //// 2. 获取绝对路径
|
|
|
+ //char absPath[PATH_MAX];
|
|
|
+ //if (realpath(pPath, absPath) == nullptr) {
|
|
|
+ // // 如果路径不存在,仍然使用原始路径(但警告)
|
|
|
+ // std::cerr << "AddEnvPath: Warning - Path may not exist: " << pPath
|
|
|
+ // << " (" << strerror(errno) << ")" << std::endl;
|
|
|
+ // strncpy(absPath, pPath, PATH_MAX - 1);
|
|
|
+ // absPath[PATH_MAX - 1] = '\0';
|
|
|
+ //}
|
|
|
+
|
|
|
+ //// 3. 获取当前环境变量值
|
|
|
+ //const char* currentEnv = getenv("LD_LIBRARY_PATH");
|
|
|
+ //std::vector<std::string> pathList;
|
|
|
+
|
|
|
+ //// 4. 解析现有路径并去重
|
|
|
+ //if (currentEnv && *currentEnv != '\0') {
|
|
|
+ // std::istringstream iss(currentEnv);
|
|
|
+ // std::string item;
|
|
|
+
|
|
|
+ // while (std::getline(iss, item, ':')) {
|
|
|
+ // if (!item.empty()) {
|
|
|
+ // // 标准化现有路径
|
|
|
+ // char resolved[PATH_MAX];
|
|
|
+ // if (realpath(item.c_str(), resolved)) {
|
|
|
+ // // 去重检查
|
|
|
+ // if (strcmp(resolved, absPath) != 0) {
|
|
|
+ // pathList.push_back(resolved);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // else {
|
|
|
+ // // 无法解析的路径保留原样
|
|
|
+ // pathList.push_back(item);
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+
|
|
|
+ //// 5. 添加新路径到最前面(优先搜索)
|
|
|
+ //pathList.insert(pathList.begin(), absPath);
|
|
|
+
|
|
|
+ //// 6. 构建新环境变量字符串
|
|
|
+ //std::ostringstream newEnvStream;
|
|
|
+ //for (size_t i = 0; i < pathList.size(); ++i) {
|
|
|
+ // if (i > 0) newEnvStream << ':';
|
|
|
+ // newEnvStream << pathList[i];
|
|
|
+ //}
|
|
|
+ //std::string newEnv = newEnvStream.str();
|
|
|
+
|
|
|
+ //// 7. 更新环境变量
|
|
|
+ //if (setenv("LD_LIBRARY_PATH", newEnv.c_str(), 1) != 0) {
|
|
|
+ // std::cerr << "AddEnvPath: Failed to set LD_LIBRARY_PATH ("
|
|
|
+ // << strerror(errno) << ")" << std::endl;
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+
|
|
|
+ //// 8. 验证设置
|
|
|
+ //const char* verify = getenv("LD_LIBRARY_PATH");
|
|
|
+ //if (verify && std::string(verify).find(absPath) != std::string::npos) {
|
|
|
+ // std::cout << "AddEnvPath: Successfully updated LD_LIBRARY_PATH to: "
|
|
|
+ // << newEnv << std::endl;
|
|
|
+ // return true;
|
|
|
+ //}
|
|
|
+ //else {
|
|
|
+ // std::cerr << "AddEnvPath: Verification failed - path not found in LD_LIBRARY_PATH"
|
|
|
+ // << std::endl;
|
|
|
+ // return false;
|
|
|
+ //}
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool DelEnvPath(const char* pPath) {
|
|
|
+ UNUSED(pPath);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+static bool SplitStringSub(string& Path, char key, vector<string>& nodes) {
|
|
|
+ string node;
|
|
|
+
|
|
|
+ string::size_type firstHit = Path.find_first_of(key);
|
|
|
+ if (firstHit == string::npos) {
|
|
|
+ if (Path.size() > 0) {
|
|
|
+ nodes.push_back(Path);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (firstHit > 0) {
|
|
|
+ node = Path.substr(0, firstHit);
|
|
|
+ if (node.size() > 0) {
|
|
|
+ nodes.push_back(node);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ while (firstHit < Path.size()) {
|
|
|
+ firstHit += 1;
|
|
|
+ if (firstHit >= Path.size()) break;
|
|
|
+
|
|
|
+ string::size_type SecondHit = Path.find_first_of(key, firstHit);
|
|
|
+ if (SecondHit == string::npos) {
|
|
|
+ node = Path.substr(firstHit, Path.size() - firstHit);
|
|
|
+ if (node.size() > 0) {
|
|
|
+ nodes.push_back(node);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ node = Path.substr(firstHit, SecondHit - firstHit);
|
|
|
+ if (node.size() > 0) {
|
|
|
+ nodes.push_back(node);
|
|
|
+ }
|
|
|
+ firstHit = SecondHit;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (nodes.size() > 0);
|
|
|
+}
|
|
|
+
|
|
|
+//=== 字符串处理 ===//
|
|
|
+bool SplitString(const char* pString, string args, vector<string>& nodes) {
|
|
|
+ vector<string> req;
|
|
|
+ vector<string> res;
|
|
|
+ req.push_back(string(pString));
|
|
|
+
|
|
|
+ for (size_t i = 0; i < args.size(); i++)
|
|
|
+ {
|
|
|
+ //cut all req by key
|
|
|
+ for (size_t j = 0; j < req.size(); j++)
|
|
|
+ {
|
|
|
+ SplitStringSub(req[j], args[i], res);
|
|
|
+ }
|
|
|
+ //clear and reset
|
|
|
+ req.clear();
|
|
|
+ req = res;
|
|
|
+ res.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ nodes = req;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool SplitTo84422222222String(const char* pString, vector<string>& nodes) {
|
|
|
+ string total;
|
|
|
+ vector<string> thelist;
|
|
|
+ SplitString(pString, string("{}-"), thelist);
|
|
|
+ for (size_t i = 0; i < thelist.size(); i++)
|
|
|
+ {
|
|
|
+ total += thelist[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (total.size() != 32)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ string temp;
|
|
|
+
|
|
|
+ temp = total.substr(0, 8);//8
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(8, 4);//4
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(12, 4);//4
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(16, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(18, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(20, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(22, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(24, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(26, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(28, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ temp = total.substr(30, 2);//2
|
|
|
+ nodes.push_back(temp);
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+string FormatstdString(const char* fmt, ...) {
|
|
|
+ va_list args;
|
|
|
+ va_start(args, fmt);
|
|
|
+ char buffer[1024];
|
|
|
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
|
|
|
+ va_end(args);
|
|
|
+ return string(buffer);
|
|
|
+}
|
|
|
+
|
|
|
+bool getBusIdFromFilePath(const char* pFilePath, string& BusId)
|
|
|
+{
|
|
|
+ string Path = pFilePath;
|
|
|
+
|
|
|
+ size_t firstHit = Path.find_first_of('/');
|
|
|
+ if (firstHit == string::npos || firstHit != 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ size_t SecondHit = Path.find_first_of('/', 1);
|
|
|
+ if (SecondHit == string::npos)
|
|
|
+ {
|
|
|
+ BusId = Path.substr(1, Path.size() - 1);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ BusId = Path.substr(1, SecondHit - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (BusId.size() == 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+bool SplitDevicePath(const char* pDevicePath, vector<string>& nodes)
|
|
|
+{
|
|
|
+ string node;
|
|
|
+ string Path = pDevicePath;
|
|
|
+
|
|
|
+ nodes.clear();
|
|
|
+
|
|
|
+ string::size_type firstHit = Path.find_first_of('/');
|
|
|
+ if (firstHit == string::npos || firstHit != 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ while (firstHit < Path.size())
|
|
|
+ {
|
|
|
+ firstHit += 1;
|
|
|
+ string::size_type SecondHit = Path.find_first_of('/', firstHit);
|
|
|
+ if (SecondHit == string::npos)
|
|
|
+ {
|
|
|
+ node = Path.substr(firstHit, Path.size() - firstHit);
|
|
|
+ if (node.size() > 0)
|
|
|
+ {
|
|
|
+ nodes.push_back(node);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ node = Path.substr(firstHit, SecondHit - (firstHit));
|
|
|
+ if (node.size() > 0)
|
|
|
+ {
|
|
|
+ nodes.push_back(node);
|
|
|
+ }
|
|
|
+ firstHit = SecondHit;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return (nodes.size() > 0);
|
|
|
+}
|
|
|
+
|
|
|
+void SplitDeviceList(const char* deviceList, std::vector<std::string>& result)
|
|
|
+{
|
|
|
+ result.clear();
|
|
|
+
|
|
|
+ // 处理空输入情况
|
|
|
+ if (deviceList == nullptr || *deviceList == '\0') return;
|
|
|
+
|
|
|
+ // 创建可修改副本(strtok会破坏原字符串)
|
|
|
+ char* buffer = new char[strlen(deviceList) + 1];
|
|
|
+ strcpy(buffer, deviceList);
|
|
|
+
|
|
|
+ // 使用strtok分割字符串
|
|
|
+ const char* delimiter = ";";
|
|
|
+ char* token = strtok(buffer, delimiter);
|
|
|
+
|
|
|
+ while (token != nullptr) {
|
|
|
+ // 过滤空字符串(避免连续分号产生空项)
|
|
|
+ if (strlen(token) > 0) {
|
|
|
+ result.push_back(token);
|
|
|
+ }
|
|
|
+ token = strtok(nullptr, delimiter);
|
|
|
+ }
|
|
|
+
|
|
|
+ delete[] buffer; // 释放临时内存
|
|
|
+}
|
|
|
+
|
|
|
+//=== 文件路径操作 ===//
|
|
|
+std::string GetProcessDirectory() {
|
|
|
+ char path[PATH_MAX];
|
|
|
+ ssize_t len = readlink("/proc/self/exe", path, sizeof(path) - 1);
|
|
|
+
|
|
|
+ if (len == -1) {
|
|
|
+ std::cerr << "[ERROR] GetProcessDirectory failed to read /proc/self/exe" << std::endl;
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保字符串正确终止
|
|
|
+ path[len] = '\0';
|
|
|
+
|
|
|
+ // 现在可以安全地打印
|
|
|
+ std::cout << "[DEBUG] GetProcessDirectory() len: " << len << " path: " << path << std::endl;
|
|
|
+
|
|
|
+ // 找到最后一个斜杠并截断路径
|
|
|
+ char* last_slash = strrchr(path, '/');
|
|
|
+ if (last_slash) {
|
|
|
+ *last_slash = '\0';
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ std::cerr << "[WARNING] GetProcessDirectory: No directory separator found" << std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回一个新的字符串副本,而不是局部数组的指针
|
|
|
+ return std::string(path);
|
|
|
+}
|
|
|
+
|
|
|
+string GetFileDirectory(string& fullpath) {
|
|
|
+ size_t pos = fullpath.find_last_of('/');
|
|
|
+ return (pos != string::npos) ? fullpath.substr(0, pos) : "";
|
|
|
+}
|
|
|
+
|
|
|
+bool FindSubVersionDirs(string rootDir, map<string, vector<string>>& dirlist)
|
|
|
+{
|
|
|
+ UNUSED(rootDir);
|
|
|
+ UNUSED(dirlist);
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+string GetFileName(string& fullpath) {
|
|
|
+ size_t pos = fullpath.find_last_of('/');
|
|
|
+ return (pos != string::npos) ? fullpath.substr(pos + 1) : fullpath;
|
|
|
+}
|
|
|
+
|
|
|
+string GetFileTitle(string& fullpath) {
|
|
|
+ string filename = GetFileName(fullpath);
|
|
|
+ size_t dot = filename.find_last_of('.');
|
|
|
+ return (dot != string::npos) ? filename.substr(0, dot) : filename;
|
|
|
+}
|
|
|
+
|
|
|
+bool CreateFileDirectory(string& FullFilePath) {
|
|
|
+ string dir = GetFileDirectory(FullFilePath);
|
|
|
+ if (dir.empty()) return false;
|
|
|
+
|
|
|
+ string command = "mkdir -p " + dir;
|
|
|
+ return system(command.c_str()) == 0;
|
|
|
+}
|
|
|
+
|
|
|
+//=== 文件系统遍历 ===//
|
|
|
+bool FindSubFiles(string rootDir, vector<string>& filelist, bool Recursive, string strWildcard) {
|
|
|
+ DIR* dir = opendir(rootDir.c_str());
|
|
|
+ if (!dir) return false;
|
|
|
+
|
|
|
+ struct dirent* entry;
|
|
|
+ while ((entry = readdir(dir)) != nullptr) {
|
|
|
+ string name = entry->d_name;
|
|
|
+ if (name == "." || name == "..") continue;
|
|
|
+
|
|
|
+ string fullpath = rootDir + "/" + name;
|
|
|
+
|
|
|
+ if (entry->d_type == DT_DIR && Recursive) {
|
|
|
+ FindSubFiles(fullpath, filelist, Recursive, strWildcard);
|
|
|
+ }
|
|
|
+ else if (entry->d_type == DT_REG) {
|
|
|
+ filelist.push_back(fullpath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ closedir(dir);
|
|
|
+ return !filelist.empty();
|
|
|
+}
|
|
|
+
|
|
|
+//=== 其他辅助函数 ===//
|
|
|
+void RawToHex(const char* pRaw, DWORD RawLen, string& Hex) {
|
|
|
+ Hex.reserve(RawLen * 3);
|
|
|
+ for (DWORD i = 0; i < RawLen; i++) {
|
|
|
+ char buf[4];
|
|
|
+ snprintf(buf, sizeof(buf), "%02X ", pRaw[i] & 0xFF);
|
|
|
+ Hex.append(buf);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+string ReplaceSubString(string org, string& keystr, string& replacestr) {
|
|
|
+ size_t pos = 0;
|
|
|
+ while ((pos = org.find(keystr, pos)) != string::npos) {
|
|
|
+ org.replace(pos, keystr.length(), replacestr);
|
|
|
+ pos += replacestr.length();
|
|
|
+ }
|
|
|
+ return org;
|
|
|
+}
|
|
|
+
|
|
|
+//=== 动态库函数信息 ===//
|
|
|
+std::vector<export_functions> GetDllFunctionInfo(const char* moduleName) {
|
|
|
+ void* handle = dlopen(moduleName, RTLD_LAZY);
|
|
|
+ if (!handle) return {};
|
|
|
+
|
|
|
+ // 获取动态库信息
|
|
|
+ Dl_info info;
|
|
|
+ if (dladdr(handle, &info) == 0) {
|
|
|
+ dlclose(handle);
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ // 简化实现:仅获取动态库路径
|
|
|
+ std::vector<export_functions> result;
|
|
|
+ result.push_back(make_tuple(info.dli_fname, 0, 0));
|
|
|
+ dlclose(handle);
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+void TransferModuleJosnConfig2DriverConfig(ResDataObject& config)
|
|
|
+{
|
|
|
+ for (size_t x = 0; x < config.size(); x++)
|
|
|
+ {
|
|
|
+ if (config[x].GetKeyCount("Value") > 0)
|
|
|
+ {
|
|
|
+ if (config[x]["Value"].size() <= 0)
|
|
|
+ {
|
|
|
+ string va = (const char*)config[x]["Value"];
|
|
|
+ config[x] = va.c_str();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ResDataObject rest = config[x]["Value"];
|
|
|
+ config[x] = rest;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+// 将time_t类型时间转换为"YYYY-MM-DD HH:MM:SS"格式的字符串
|
|
|
+std::string DatetimeToString(time_t timeVal)
|
|
|
+{
|
|
|
+ // 将time_t转换为本地时间的tm结构体
|
|
|
+ struct tm* localTime = localtime(&timeVal);
|
|
|
+ if (localTime == nullptr)
|
|
|
+ {
|
|
|
+ // 处理转换失败的情况,返回空字符串或错误标识
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+
|
|
|
+ // 缓冲区,足够容纳格式化后的时间字符串(包含终止符)
|
|
|
+ char timeStr[32] = {0};
|
|
|
+
|
|
|
+ // 格式化时间字符串:年-月-日 时:分:秒
|
|
|
+ // %Y:四位年份,%m:两位月份,%d:两位日期
|
|
|
+ // %H:24小时制小时,%M:分钟,%S:秒
|
|
|
+ strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localTime);
|
|
|
+
|
|
|
+ return std::string(timeStr);
|
|
|
+}
|