LocalConfig.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  1. // LocalConfig.cpp
  2. // 添加必要的头文件
  3. #include <unistd.h>
  4. #include <pthread.h>
  5. #include <sys/stat.h>
  6. #include <dirent.h>
  7. #include <sys/socket.h>
  8. #include <netdb.h>
  9. #include <arpa/inet.h>
  10. #include <ifaddrs.h>
  11. #include <netinet/in.h>
  12. #include <net/if.h>
  13. #include <sys/ioctl.h>
  14. #include <time.h>
  15. #include <errno.h>
  16. #include <algorithm>
  17. #include <cctype>
  18. #include <cstring>
  19. #include <cstdio>
  20. #include <cstdlib>
  21. #include <cstdarg>
  22. #include <map>
  23. #include <sys/types.h>
  24. #include <netpacket/packet.h> // 包含 sockaddr_ll 定义
  25. #include "common_api.h"
  26. #include "LocalConfig.h"
  27. #include "Crc64.h"
  28. #include <iostream>
  29. // 全局变量定义
  30. // ================================================================
  31. CCOS_PROC_TYPE& GetConfigModeInstance() {
  32. static CCOS_PROC_TYPE instance = CCOS_PROC_MASTER;
  33. return instance;
  34. }
  35. std::vector<std::string>& GetDriverConfigFilepath() {// 驱动配置文件路径列表
  36. static std::vector<std::string> instance;
  37. return instance;
  38. }
  39. std::string& GetLocalBusId() {// 本地总线ID
  40. static std::string instance;
  41. return instance;
  42. }
  43. std::string& GetMajorIDInstance() {// 主ID
  44. static std::string instance;
  45. return instance;
  46. }
  47. std::string& GetVendorID() {// 供应商ID
  48. static std::string instance;
  49. return instance;
  50. }
  51. std::string& GetProductID() {// 产品ID
  52. static std::string instance;
  53. return instance;
  54. }
  55. std::string& GetSerialID() { // 序列号ID
  56. static std::string instance;
  57. return instance;
  58. }
  59. std::string& GetDeviceType() { // 设备类型
  60. static std::string instance;
  61. return instance;
  62. }
  63. pthread_mutex_t& GetSectionMutex() { // 线程互斥锁
  64. static pthread_mutex_t instance = PTHREAD_MUTEX_INITIALIZER;
  65. return instance;
  66. }
  67. ResDataObject& GetResUid2TypeMap() { // GUID到类型的映射
  68. static ResDataObject instance;
  69. return instance;
  70. }
  71. /**
  72. * 递归创建目录
  73. * @param path 目录路径
  74. * @return 成功返回true,失败返回false
  75. */
  76. bool CreateDirectoryLinux(const char* path) {
  77. char tmp[256];
  78. char* p = NULL;
  79. size_t len;
  80. // 复制路径并确保不以斜杠结尾
  81. snprintf(tmp, sizeof(tmp), "%s", path);
  82. len = strlen(tmp);
  83. if (len > 0 && tmp[len - 1] == '/') {
  84. tmp[len - 1] = '\0';
  85. }
  86. // 逐级创建目录
  87. for (p = tmp + 1; *p; p++) {
  88. if (*p == '/') {
  89. *p = '\0'; // 临时截断路径
  90. // 创建中间目录(忽略已存在的目录)
  91. if (mkdir(tmp, 0755) != 0 && errno != EEXIST) {
  92. return false;
  93. }
  94. *p = '/'; // 恢复路径
  95. }
  96. }
  97. // 创建最终目录
  98. return mkdir(tmp, 0755) == 0 || errno == EEXIST;
  99. }
  100. /**
  101. * 检查文件或目录是否存在
  102. * @param path 路径
  103. * @return 存在返回true,否则返回false
  104. */
  105. bool FileExists(const char* path) {
  106. struct stat info;
  107. return stat(path, &info) == 0;
  108. }
  109. /**
  110. * 从完整路径中提取文件名
  111. * @param fullPath 完整路径
  112. * @return 文件名
  113. */
  114. string GetFileName(const string& fullPath) {
  115. size_t pos = fullPath.find_last_of("/");
  116. return (pos != string::npos) ? fullPath.substr(pos + 1) : fullPath;
  117. }
  118. /**
  119. * 从完整路径中提取目录路径
  120. * @param fullPath 完整路径
  121. * @return 目录路径
  122. */
  123. string GetFileDirectory(const string& fullPath) {
  124. size_t pos = fullPath.find_last_of("/");
  125. return (pos != string::npos) ? fullPath.substr(0, pos) : "";
  126. }
  127. /**
  128. * 获取当前时间戳(毫秒)
  129. * @return 毫秒时间戳
  130. */
  131. DWORD GetTickCount() {
  132. struct timespec ts;
  133. // 使用单调时钟获取时间
  134. clock_gettime(CLOCK_MONOTONIC, &ts);
  135. return (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
  136. }
  137. /**
  138. * 获取所有网络接口的MAC地址
  139. * @param vMacAddress 输出MAC地址列表
  140. * @return 找到的MAC地址数量
  141. */
  142. LOCALCONFIG_API DWORD GetMacAddress(vector<string>& vMacAddress) {
  143. struct ifaddrs* ifaddr, * ifa;
  144. vMacAddress.clear();
  145. if (getifaddrs(&ifaddr) == -1) {
  146. return 0;
  147. }
  148. for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
  149. if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_PACKET)
  150. continue;
  151. // 使用正确的类型转换
  152. struct sockaddr_ll* s = (struct sockaddr_ll*)ifa->ifa_addr;
  153. // 检查 MAC 地址长度
  154. if (s->sll_halen < 6) continue;
  155. // 格式化 MAC 地址
  156. char mac[32];
  157. snprintf(mac, sizeof(mac), "%02X:%02X:%02X:%02X:%02X:%02X",
  158. s->sll_addr[0], s->sll_addr[1], s->sll_addr[2],
  159. s->sll_addr[3], s->sll_addr[4], s->sll_addr[5]);
  160. vMacAddress.push_back(mac);
  161. }
  162. freeifaddrs(ifaddr);
  163. return vMacAddress.size();
  164. }
  165. // 主要功能函数实现
  166. // ================================================================
  167. /**
  168. * 添加驱动配置文件路径并解析EBus ID
  169. */
  170. LOCALCONFIG_API bool AddDriverConfig(const char* pszDriverConfig) {
  171. // 构造完整路径: 配置路径 + 文件名
  172. string FullPath = GetDriverConfigPath().encode();
  173. // std::cout << "[DEBUG] Construct the complete path: configuration path : " << FullPath << std::endl;
  174. FullPath += pszDriverConfig;
  175. // std::cout << "[DEBUG] Construct the complete path: configuration path + file name: " << FullPath << std::endl;
  176. // 添加到全局列表
  177. GetDriverConfigFilepath().push_back(FullPath);
  178. // 解析驱动文件获取EBus ID
  179. ResDataObject BusId, DriverPath;
  180. bool ret = GetDriverEbusId(FullPath.c_str(), BusId, DriverPath);
  181. if (ret) {
  182. GetLocalBusId() = (const char*)BusId;
  183. }
  184. return ret;
  185. }
  186. /**
  187. * 设置配置模式并加载GUID映射
  188. */
  189. LOCALCONFIG_API void SetConfigMode(CCOS_PROC_TYPE Master) {
  190. GetConfigModeInstance() = Master;
  191. string mapConf = GetProcessDirectory() + "/LocalConfig.xml";
  192. ResDataObject config;
  193. // 加载并解析配置文件
  194. if (config.loadFile(mapConf.c_str())) {
  195. // 查找GUID到类型的映射
  196. int Idx = config["CONFIGURATION"].GetFirstOf("GUID2Type");
  197. if (Idx >= 0) {
  198. GetResUid2TypeMap() = config["CONFIGURATION"][Idx];
  199. // std::cout << "[DEBUG SetConfigMode] GetResUid2TypeMap(): " << GetResUid2TypeMap().encode() << std::endl;
  200. }
  201. }
  202. }
  203. /**
  204. * 获取本地IP地址
  205. */
  206. LOCALCONFIG_API ResDataObject& getLocalIpAddress() {
  207. static ResDataObject mn_LocalIpAddress;
  208. struct ifaddrs* ifaddr, * ifa;
  209. // 获取网络接口列表
  210. if (getifaddrs(&ifaddr) != 0) {
  211. return mn_LocalIpAddress;
  212. }
  213. // 遍历网络接口
  214. for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
  215. // 只处理IPv4接口
  216. if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
  217. continue;
  218. // 获取IP地址
  219. void* tmpAddrPtr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
  220. char addressBuffer[INET_ADDRSTRLEN];
  221. inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
  222. // 跳过回环地址
  223. if (strcmp(addressBuffer, "127.0.0.1") != 0) {
  224. mn_LocalIpAddress = addressBuffer;
  225. break;
  226. }
  227. }
  228. // 释放资源
  229. freeifaddrs(ifaddr);
  230. return mn_LocalIpAddress;
  231. }
  232. /**
  233. * 获取当前可执行文件名
  234. */
  235. LOCALCONFIG_API ResDataObject& GetModuleTitle() {
  236. static ResDataObject mn_ModuleTitle;
  237. char path[1024] = { 0 };
  238. // 通过 /proc/self/exe 获取可执行文件路径
  239. ssize_t count = readlink("/proc/self/exe", path, sizeof(path) - 1);
  240. if (count > 0) {
  241. path[count] = '\0';
  242. char* last_slash = strrchr(path, '/');
  243. if (last_slash) {
  244. // 提取文件名
  245. mn_ModuleTitle = last_slash + 1;
  246. }
  247. }
  248. return mn_ModuleTitle;
  249. }
  250. /**
  251. * 获取主机名(大写形式)作为机器ID
  252. */
  253. LOCALCONFIG_API ResDataObject& getLocalMachineId() {
  254. static ResDataObject mn_LocalMachineId;
  255. char hostname[256] = { 0 };
  256. // 获取主机名
  257. if (gethostname(hostname, sizeof(hostname) - 1) == 0) {
  258. string filenameBig = hostname;
  259. // 转换为大写
  260. transform(filenameBig.begin(), filenameBig.end(), filenameBig.begin(), ::toupper);
  261. mn_LocalMachineId = filenameBig.c_str();
  262. }
  263. return mn_LocalMachineId;
  264. }
  265. /**
  266. * 创建工作路径
  267. */
  268. LOCALCONFIG_API ResDataObject MakeWorkPath(ResDataObject& probeInfo, ResDataObject& Connection,
  269. ResDataObject& ProcPath, bool ForWork) {
  270. ResDataObject ResRet;
  271. ResDataObject major, product, serial;
  272. // 获取必要字段
  273. if (!TryGetValue(probeInfo, "MajorID", major) ||
  274. !TryGetValue(probeInfo, "ProductID", product)) {
  275. return ResRet; // 返回空对象
  276. }
  277. // 处理序列号
  278. if (!TryGetValue(probeInfo, "SerialID", serial) || strlen((const char*)serial) == 0) {
  279. probeInfo.add("SerialID", GetTickCount());
  280. serial = (const char*)probeInfo["SerialID"];
  281. }
  282. // 确定目录结构
  283. vector<string> folders;
  284. folders.push_back(string("WorkPath"));
  285. folders.push_back((const char*)major);
  286. folders.push_back((const char*)product);
  287. folders.push_back((const char*)serial);
  288. // 构建完整路径
  289. string workpath = string((const char*)ProcPath) + "/";
  290. for (size_t i = 0; i < folders.size(); i++) {
  291. string dirPath = workpath + folders[i];
  292. // 创建目录(如果不存在)
  293. if (!FileExists(dirPath.c_str()) && !CreateDirectoryLinux(dirPath.c_str())) {
  294. return ResRet; // 创建失败返回空对象
  295. }
  296. workpath += folders[i] + "/";
  297. }
  298. // 返回构建的路径
  299. ResRet = workpath.c_str();
  300. return ResRet;
  301. }
  302. /**
  303. * 创建设备路径
  304. */
  305. LOCALCONFIG_API ResDataObject MakeDevicePath(ResDataObject& probeInfo, ResDataObject& Connection,
  306. ResDataObject& SubPath) {
  307. ResDataObject resRet;
  308. ResDataObject major, minor, vendor, product, serial;
  309. // 获取所有必要字段
  310. if (!TryGetValue(probeInfo, "MajorID", major) ||
  311. !TryGetValue(probeInfo, "MinorID", minor) ||
  312. !TryGetValue(probeInfo, "VendorID", vendor) ||
  313. !TryGetValue(probeInfo, "ProductID", product)) {
  314. return resRet;
  315. }
  316. // 处理序列号
  317. if (!TryGetValue(probeInfo, "SerialID", serial) || strlen((const char*)serial) == 0) {
  318. probeInfo.add("SerialID", GetTickCount());
  319. serial = (const char*)probeInfo["SerialID"];
  320. }
  321. // 构建设备路径
  322. string devicepath = "/" + string((const char*)getLocalEbusId()) + "/" +
  323. string((const char*)major) + "/" +
  324. string((const char*)minor) + "/" +
  325. string((const char*)vendor) + "/" +
  326. string((const char*)product) + "/" +
  327. string((const char*)serial) + "/" +
  328. string((const char*)SubPath);
  329. resRet = devicepath.c_str();
  330. return resRet;
  331. }
  332. /**
  333. * 创建CCOS路径
  334. */
  335. LOCALCONFIG_API ResDataObject MakeCcosPath(ResDataObject& probeInfo, ResDataObject& Connection,
  336. ResDataObject& SubPath, bool isDriver) {
  337. ResDataObject resRet;
  338. ResDataObject major, vendor, product, serial;
  339. // 获取必要字段
  340. if (!TryGetValue(probeInfo, "MajorID", major) ||
  341. !TryGetValue(probeInfo, "VendorID", vendor) ||
  342. !TryGetValue(probeInfo, "ProductID", product)) {
  343. return resRet;
  344. }
  345. // 处理序列号
  346. if (!TryGetValue(probeInfo, "SerialID", serial) || strlen((const char*)serial) == 0) {
  347. probeInfo.add("SerialID", GetTickCount());
  348. serial = (const char*)probeInfo["SerialID"];
  349. }
  350. // 构建CCOS路径
  351. string devicepath = isDriver ? "CCOS/DRIVER/" : "CCOS/DEVICE/";
  352. devicepath += string((const char*)major) + "/" +
  353. string((const char*)vendor) + "/" +
  354. string((const char*)product) + "/" +
  355. string((const char*)serial);
  356. resRet = devicepath.c_str();
  357. return resRet;
  358. }
  359. /**
  360. * 获取驱动配置路径
  361. */
  362. LOCALCONFIG_API ResDataObject& GetDriverConfigPath() {
  363. static ResDataObject resRet;
  364. std::string ret = GetProcessDirectory() + "/DriverConfig/";
  365. // std::cout << "[DEBUG] GetProcessDirectory() + / DriverConfig / : " << ret << std::endl;
  366. resRet = ret.c_str();
  367. //resRet = "/home/cxdz/code/diosproc/DriverConfig/";
  368. // std::cout << "[DEBUG] resRet : " << resRet.encode() << std::endl;
  369. return resRet;
  370. }
  371. /**
  372. * 获取驱动EBus ID
  373. */
  374. LOCALCONFIG_API bool GetDriverEbusId(const char* pConfigFilepath, ResDataObject& BusId,
  375. ResDataObject& DriverPath, bool ForceUpdate) {
  376. ResDataObject Context;
  377. // 加载配置文件
  378. if (!Context.loadFile(pConfigFilepath)) {
  379. return false;
  380. }
  381. // 提取配置中的各个ID
  382. string absContext = ""; // 用于生成唯一ID的上下文字符串
  383. char HighFive[6] = { 0 }; // 存储ID的首字符
  384. // 提取并验证各个ID
  385. string MajorID = (const char*)Context["CONFIGURATION"]["MajorID"];
  386. string MinorID = (const char*)Context["CONFIGURATION"]["MinorID"];
  387. string VendorID = (const char*)Context["CONFIGURATION"]["VendorID"];
  388. string ProductID = (const char*)Context["CONFIGURATION"]["ProductID"];
  389. string SerialID = (const char*)Context["CONFIGURATION"]["SerialID"];
  390. string GUID = (const char*)Context["CONFIGURATION"]["GUID"];
  391. // std::cout << "[DEBUG] Configuration IDs:" << std::endl;
  392. // std::cout << "[DEBUG] MajorID: " << MajorID << std::endl;
  393. // std::cout << "[DEBUG] MinorID: " << MinorID << std::endl;
  394. // std::cout << "[DEBUG] VendorID: " << VendorID << std::endl;
  395. // std::cout << "[DEBUG] ProductID: " << ProductID << std::endl;
  396. // std::cout << "[DEBUG] SerialID: " << SerialID << std::endl;
  397. // std::cout << "[DEBUG] GUID: " << GUID << std::endl;
  398. if (MajorID.empty() || MinorID.empty() || VendorID.empty() ||
  399. ProductID.empty() || SerialID.empty() || GUID.empty()) {
  400. return false;
  401. }
  402. // 更新全局ID缓存
  403. GetMajorIDInstance() = MajorID;
  404. GetVendorID() = VendorID;
  405. GetProductID() = ProductID;
  406. GetSerialID() = SerialID;
  407. // 构建唯一性上下文
  408. absContext = "/" + MajorID + "/" + MinorID + "/" + VendorID + "/" + ProductID + "/" + SerialID + "/" + GUID;
  409. HighFive[0] = MajorID[0];
  410. HighFive[1] = MinorID[0];
  411. HighFive[2] = VendorID[0];
  412. HighFive[3] = ProductID[0];
  413. HighFive[4] = SerialID[0];
  414. // 尝试获取配置中的BusId
  415. string OnlyBusId = "";
  416. int BusIdsIndex = Context["CONFIGURATION"].GetFirstOf("BusId");
  417. if (BusIdsIndex >= 0) {
  418. OnlyBusId = (const char*)Context["CONFIGURATION"][BusIdsIndex];
  419. }
  420. // 如未配置BusId,则生成一个
  421. if (OnlyBusId.empty()) {
  422. // 使用CRC32生成唯一ID
  423. int Crc32res = GetCrc32(absContext.c_str(), absContext.size());
  424. OnlyBusId = "D" + string(HighFive) + FormatstdString("%08X", Crc32res);
  425. }
  426. // 构建设备路径
  427. string TempPath = "/" + OnlyBusId + absContext;
  428. BusId = OnlyBusId.c_str();
  429. DriverPath = TempPath.c_str();
  430. return true;
  431. }
  432. /**
  433. * 生成唯一EBus ID
  434. */
  435. LOCALCONFIG_API bool MakeUniqEbusId(ResDataObject& res) {
  436. static DWORD l_PrevTime = 0; // 上次生成ID的时间戳
  437. ResDataObject mId = getLocalMachineId(); // 获取机器ID
  438. vector<string> maclist; // MAC地址列表
  439. // 获取MAC地址
  440. if (GetMacAddress(maclist) == 0) {
  441. return false;
  442. }
  443. // 加锁确保线程安全
  444. pthread_mutex_lock(&GetSectionMutex());
  445. // 获取唯一时间戳(避免重复)
  446. DWORD CurTime = GetTickCount();
  447. while (CurTime == l_PrevTime) {
  448. usleep(1000); // 休眠1毫秒
  449. CurTime = GetTickCount();
  450. }
  451. l_PrevTime = CurTime;
  452. // 释放锁
  453. pthread_mutex_unlock(&GetSectionMutex());
  454. // 构建唯一字符串
  455. string crcstr = (const char*)mId;
  456. for (size_t i = 0; i < maclist.size(); i++) {
  457. crcstr += maclist[i];
  458. }
  459. crcstr += FormatstdString("%08X", l_PrevTime); // 时间戳
  460. crcstr += FormatstdString("%08X", getpid()); // 进程ID
  461. crcstr += FormatstdString("%08X", (unsigned long)pthread_self()); // 线程ID
  462. // 计算CRC32作为唯一ID
  463. int crc = GetCrc32(crcstr.c_str(), crcstr.size());
  464. res = FormatstdString("%08X", crc).c_str();
  465. return true;
  466. }
  467. /**
  468. * 获取设备类型字符串
  469. */
  470. LOCALCONFIG_API string& GetMajorID() {
  471. // 从本地配置获取缺失的ID(添加空指针检查)
  472. if (GetMajorIDInstance().empty()) {
  473. ResDataObject val = tryGetLocalOptions("MajorID");
  474. const char* valStr = (const char*)val;
  475. GetMajorIDInstance() = valStr ? valStr : ""; // 避免空指针赋值
  476. }
  477. if (GetVendorID().empty()) {
  478. ResDataObject val = tryGetLocalOptions("VendorID");
  479. const char* valStr = (const char*)val;
  480. GetVendorID() = valStr ? valStr : "";
  481. }
  482. if (GetProductID().empty()) {
  483. ResDataObject val = tryGetLocalOptions("ProductID");
  484. const char* valStr = (const char*)val;
  485. GetProductID() = valStr ? valStr : "";
  486. }
  487. if (GetSerialID().empty()) {
  488. ResDataObject val = tryGetLocalOptions("SerialID");
  489. const char* valStr = (const char*)val;
  490. GetSerialID() = valStr ? valStr : "";
  491. }
  492. // 构建设备类型字符串(确保所有组件非空,避免无效拼接)
  493. std::string deviceType = GetMajorIDInstance();
  494. if (!GetVendorID().empty()) deviceType += "_" + GetVendorID();
  495. if (!GetProductID().empty()) deviceType += "_" + GetProductID();
  496. if (!GetSerialID().empty()) deviceType += "_" + GetSerialID();
  497. GetDeviceType() = deviceType;
  498. return GetDeviceType();
  499. }
  500. /**
  501. * 获取设备ID
  502. */
  503. LOCALCONFIG_API string GetDeviceID() {
  504. // 确保所有ID已加载
  505. if (GetMajorIDInstance().empty() || GetVendorID().empty() || GetProductID().empty() || GetSerialID().empty()) {
  506. GetMajorIDInstance(); // 加载ID
  507. }
  508. // 构建设备ID字符串
  509. if (!GetMajorIDInstance().empty()) {
  510. return GetMajorIDInstance() + "/" + GetVendorID() + "/" + GetProductID() + "/" + GetSerialID();
  511. }
  512. return "Channel/Channel"; // 默认值
  513. }
  514. // ================================================================
  515. LOCALCONFIG_API const char* GetDriverConfigFilepath(size_t idx) {
  516. return (idx < GetDriverConfigFilepath().size()) ? GetDriverConfigFilepath()[idx].c_str() : nullptr;
  517. }
  518. LOCALCONFIG_API CCOS_PROC_TYPE GetConfigMode() {
  519. return GetConfigModeInstance();
  520. }
  521. LOCALCONFIG_API ResDataObject tryGetLocalOptions(const char* pKey) {
  522. string dir = GetProcessDirectory() + "/LocalConfig.xml";
  523. ResDataObject config, result;
  524. if (config.loadFile(dir.c_str())) {
  525. int Idx = config["CONFIGURATION"].GetFirstOf(pKey);
  526. if (Idx >= 0) {
  527. result = config["CONFIGURATION"][Idx];
  528. }
  529. }
  530. return result;
  531. }
  532. LOCALCONFIG_API ResDataObject& getLocalEbusId() {
  533. static ResDataObject mn_LocalEbusId;
  534. if (GetConfigModeInstance() == CCOS_PROC_MASTER) {
  535. mn_LocalEbusId = GetLocalBusId().c_str();
  536. }
  537. else if (GetConfigModeInstance() == CCOS_PROC_CHANNEL) {
  538. mn_LocalEbusId = "ccosChannel";
  539. }
  540. return mn_LocalEbusId;
  541. }
  542. LOCALCONFIG_API ResDataObject& getChannelEbusId() {
  543. static ResDataObject mn_LocalEbusId;
  544. mn_LocalEbusId = "ccosChannel";
  545. return mn_LocalEbusId;
  546. }
  547. LOCALCONFIG_API ResDataObject& getChannelRootpath() {
  548. static ResDataObject mn_ChannelId;
  549. mn_ChannelId = "/ccosChannel";
  550. return mn_ChannelId;
  551. }
  552. LOCALCONFIG_API ResDataObject& getLocalEbusRouterIp() {
  553. static ResDataObject mn_EbusRouterIp;
  554. mn_EbusRouterIp = tryGetLocalOptions("RouterIp");
  555. return mn_EbusRouterIp;
  556. }
  557. LOCALCONFIG_API ResDataObject& getLocalEbusPort() {
  558. static ResDataObject mn_EbusPort;
  559. mn_EbusPort = tryGetLocalOptions("Port");
  560. return mn_EbusPort;
  561. }
  562. static ResDataObject g_LogRootPath;
  563. LOCALCONFIG_API void setLogRootpath(const char* pszRootPath) {
  564. g_LogRootPath = pszRootPath;
  565. }
  566. LOCALCONFIG_API ResDataObject& getLogRootpath() {
  567. return g_LogRootPath;
  568. }
  569. LOCALCONFIG_API ResDataObject& getRootpath() {
  570. static ResDataObject mn_Rootpath;
  571. string rootpath = "/" + string((const char*)getLocalEbusId());
  572. mn_Rootpath = rootpath.c_str();
  573. return mn_Rootpath;
  574. }
  575. LOCALCONFIG_API bool getEbusLogFlag() {
  576. ResDataObject val = tryGetLocalOptions("EnableEbusLog");
  577. return (bool)val;
  578. }
  579. LOCALCONFIG_API bool getP2pFlag() {
  580. ResDataObject val = tryGetLocalOptions("P2pEnable");
  581. return (bool)val;
  582. }
  583. LOCALCONFIG_API ResDataObject getP2pServerIp() {
  584. return tryGetLocalOptions("P2pServer");
  585. }
  586. LOCALCONFIG_API ResDataObject getP2pRole() {
  587. return tryGetLocalOptions("P2pClient");
  588. }
  589. LOCALCONFIG_API ResDataObject& GetFullDriverConfigPath() {
  590. static ResDataObject resRet;
  591. string ret = GetProcessDirectory() + "/FullConfig/";
  592. resRet = ret.c_str();
  593. return resRet;
  594. }
  595. LOCALCONFIG_API DWORD GetFullDriverConfigPathEx(ResDataObject& PathList) {
  596. DWORD ret = 1;
  597. PathList.clear();
  598. // 根目录
  599. string dir = GetProcessDirectory();
  600. dir += "/FullConfig/";
  601. PathList.add(dir.c_str(), "");
  602. // 子版本目录
  603. string subdir = GetProcessDirectory();
  604. subdir += "/SubVersions/";
  605. map<string, vector<string>> templist;
  606. if (FindSubVersionDirs(subdir, templist)) {
  607. ret += (DWORD)templist.size();
  608. map<string, vector<string>>::iterator iter = templist.begin();
  609. while (iter != templist.end()) {
  610. for (DWORD i = 0; i < iter->second.size(); i++) {
  611. string filename = iter->second[i];
  612. // 在Linux下保持原始大小写
  613. // 构建路径
  614. string dirPath = filename + "/FullConfig/";
  615. PathList.add(dirPath.c_str(), iter->first.c_str());
  616. }
  617. ++iter;
  618. }
  619. }
  620. return ret;
  621. }
  622. LOCALCONFIG_API ResDataObject& GetFullDriverConfigPathX32() {
  623. static ResDataObject resRet;
  624. string ret = GetProcessDirectory() + "/win32/FullConfig/";
  625. resRet = ret.c_str();
  626. return resRet;
  627. }
  628. LOCALCONFIG_API ResDataObject& GetDriverConfigPathX32() {
  629. static ResDataObject resRet;
  630. string ret = GetProcessDirectory() + "/win32/DriverConfig/";
  631. resRet = ret.c_str();
  632. return resRet;
  633. }
  634. LOCALCONFIG_API DWORD GetDriverConfigPathEx(ResDataObject& PathList) {
  635. DWORD ret = 1;
  636. PathList.clear();
  637. // 根目录
  638. string dir = GetProcessDirectory();
  639. dir += "/DriverConfig/";
  640. PathList.add(dir.c_str(), "");
  641. // 子版本目录
  642. string subdir = GetProcessDirectory();
  643. subdir += "/SubVersions/";
  644. map<string, vector<string>> templist;
  645. if (FindSubVersionDirs(subdir, templist)) {
  646. ret += (DWORD)templist.size();
  647. map<string, vector<string>>::iterator iter = templist.begin();
  648. while (iter != templist.end()) {
  649. for (DWORD i = 0; i < iter->second.size(); i++) {
  650. string filename = iter->second[i];
  651. // 在Linux下保持原始大小写
  652. // 构建路径
  653. string dirPath = filename + "/DriverConfig/";
  654. PathList.add(dirPath.c_str(), iter->first.c_str());
  655. }
  656. ++iter;
  657. }
  658. }
  659. return ret;
  660. }
  661. LOCALCONFIG_API ResDataObject& GetLogConfigPath() {
  662. static ResDataObject resRet;
  663. string ret = GetProcessDirectory() + "/logconfig.xml";
  664. resRet = ret.c_str();
  665. return resRet;
  666. }
  667. LOCALCONFIG_API bool GetDriverProcessPath(const char* pConfigFilepath, ResDataObject& DriverProcessPath) {
  668. ResDataObject Context;
  669. if (!Context.loadFile(pConfigFilepath)) {
  670. return false;
  671. }
  672. string WorkPath = GetFileDirectory(GetFileDirectory(string(pConfigFilepath)));
  673. WorkPath += "/CcosProc";
  674. string NodeName = (const char*)Context["CONFIGURATION"]["ProcType"];
  675. if (NodeName == "MFC") {
  676. WorkPath += "MFC";
  677. }
  678. NodeName = (const char*)Context["CONFIGURATION"]["Arch"];
  679. if (NodeName == "64") {
  680. WorkPath += "X64";
  681. }
  682. WorkPath += ".exe";
  683. DriverProcessPath = WorkPath.c_str();
  684. return true;
  685. }
  686. LOCALCONFIG_API string GetModuleConfigrateFilePath(ResDataObject& resHardware) {
  687. string MajorID = resHardware["MajorID"].encode();
  688. string VendorID = resHardware["VendorID"].encode();
  689. string ProductID = resHardware["ProductID"].encode();
  690. string SerialID = resHardware["SerialID"].encode();
  691. string strPath = GetProcessDirectory();
  692. strPath += "/DriverDefine/Config/";
  693. strPath += MajorID + "_" + VendorID + "_" + ProductID + "_" + SerialID + ".json";
  694. return strPath;
  695. }
  696. LOCALCONFIG_API string GetModuleConfigrateFilePath(string devDioPath) {
  697. vector<string> parts;
  698. char buffer[1024];
  699. strcpy(buffer, devDioPath.c_str());
  700. char* token = strtok(buffer, "/");
  701. while (token) {
  702. parts.push_back(token);
  703. token = strtok(NULL, "/");
  704. }
  705. if (parts.size() >= 6) {
  706. string MajorID = parts[1];
  707. string VendorID = parts[3];
  708. string ProductID = parts[4];
  709. string SerialID = parts[5];
  710. string strPath = GetProcessDirectory();
  711. strPath += "/DriverDefine/Config/";
  712. strPath += MajorID + "_" + VendorID + "_" + ProductID + "_" + SerialID + ".json";
  713. return strPath;
  714. }
  715. return "";
  716. }
  717. LOCALCONFIG_API string GetCcosModuleConfigrateFilePath(string devDioPath, bool useTemplate) {
  718. vector<string> parts;
  719. char buffer[1024];
  720. strcpy(buffer, devDioPath.c_str());
  721. char* token = strtok(buffer, "/");
  722. while (token) {
  723. parts.push_back(token);
  724. token = strtok(NULL, "/");
  725. }
  726. if (parts.size() >= 6) {
  727. string MajorID = parts[2];
  728. string VendorID = parts[3];
  729. string ProductID = parts[4];
  730. string SerialID = parts[5];
  731. string strPath = GetProcessDirectory();
  732. strPath += useTemplate ? "/DriverDefine/" : "/DriverDefine/Config/";
  733. strPath += MajorID + "_" + VendorID + "_" + ProductID;
  734. strPath += useTemplate ? "" : "_" + SerialID;
  735. strPath += ".json";
  736. return strPath;
  737. }
  738. return "";
  739. }
  740. LOCALCONFIG_API string GetModuleDevicePath(ResDataObject& resHardware) {
  741. string MajorID = resHardware["MajorID"].encode();
  742. string VendorID = resHardware["VendorID"].encode();
  743. string ProductID = resHardware["ProductID"].encode();
  744. string SerialID = resHardware["SerialID"].encode();
  745. return "CCOS/DEVICE/" + MajorID + "/" + VendorID + "/" + ProductID + "/" + SerialID;
  746. }
  747. LOCALCONFIG_API BOOL ClearAllModuleConfigrate() {
  748. string dirPath = GetProcessDirectory() + "/DriverDefine/Config/";
  749. DIR* dir = opendir(dirPath.c_str());
  750. if (!dir) return FALSE;
  751. struct dirent* ent;
  752. while ((ent = readdir(dir))) {
  753. if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
  754. continue;
  755. string fullPath = dirPath + ent->d_name;
  756. if (fullPath.size() > 5 && fullPath.substr(fullPath.size() - 5) == ".json") {
  757. remove(fullPath.c_str());
  758. }
  759. }
  760. closedir(dir);
  761. return TRUE;
  762. }
  763. LOCALCONFIG_API bool GetClientUniqEbusId(ResDataObject& res) {
  764. static string clientBusId;
  765. if (clientBusId.empty()) {
  766. ResDataObject obj;
  767. if (MakeUniqEbusId(obj)) {
  768. clientBusId = "Client" + string((const char*)obj);
  769. if (clientBusId.size() > 16) {
  770. clientBusId = clientBusId.substr(0, 16);
  771. }
  772. }
  773. }
  774. res = clientBusId.c_str();
  775. return !clientBusId.empty();
  776. }
  777. LOCALCONFIG_API bool GetFullDriverConfigFiles(ResDataObject& filelist) {
  778. return GetSpecificDriverConfigFiles(filelist, true);
  779. }
  780. LOCALCONFIG_API bool GetDriverConfigFiles(ResDataObject& filelist) {
  781. return GetSpecificDriverConfigFiles(filelist, false);
  782. }
  783. LOCALCONFIG_API bool GetSpecificDriverConfigFiles(ResDataObject& filelist, bool FullDriverList) {
  784. filelist.clear();
  785. ResDataObject PathList;
  786. DWORD pathCount = FullDriverList ?
  787. GetFullDriverConfigPathEx(PathList) :
  788. GetDriverConfigPathEx(PathList);
  789. for (DWORD i = 0; i < pathCount; i++) {
  790. string configPath = (const char*)PathList.GetKey(i);
  791. vector<string> files;
  792. if (FindSubFiles(configPath, files)) {
  793. for (const auto& file : files) {
  794. // 检查是否为XML文件
  795. string filenameLow = file;
  796. transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), ::tolower);
  797. if (filenameLow.size() > 4 && filenameLow.substr(filenameLow.size() - 4) == ".xml") {
  798. filelist.add(file.c_str(), PathList[i]);
  799. }
  800. }
  801. }
  802. }
  803. return filelist.size() > 0;
  804. }
  805. LOCALCONFIG_API bool GetDriverProcInfo(const char* pConfigFilepath, ResDataObject& DriverProcInfo) {
  806. ResDataObject procPath;
  807. if (!GetDriverProcessPath(pConfigFilepath, procPath)) {
  808. return false;
  809. }
  810. string WorkPath = GetFileDirectory(string(pConfigFilepath));
  811. WorkPath = GetFileDirectory(WorkPath);
  812. WorkPath += "/";
  813. DriverProcInfo.add("WorkPath", WorkPath.c_str());
  814. DriverProcInfo.add("DriverPath", procPath);
  815. DriverProcInfo.add("DriverConfigPath", pConfigFilepath);
  816. // 读取配置中的Console设置
  817. ResDataObject Context;
  818. if (Context.loadFile(pConfigFilepath)) {
  819. string Console = (const char*)Context["CONFIGURATION"]["Console"];
  820. DriverProcInfo.add("ShowWindow", (Console != "OFF"));
  821. string AutoLoad = (const char*)Context["CONFIGURATION"]["AutoLoad"];
  822. DriverProcInfo.add("AutoLoad", (AutoLoad != "OFF"));
  823. }
  824. else {
  825. DriverProcInfo.add("ShowWindow", true);
  826. DriverProcInfo.add("AutoLoad", true);
  827. }
  828. return true;
  829. }
  830. LOCALCONFIG_API bool GetLogPatternResource(ResDataObject& Pattern) {
  831. Pattern.clear();
  832. ResDataObject configFile;
  833. if (!configFile.loadFile(GetLogConfigPath())) {
  834. return false;
  835. }
  836. ResDataObject config = configFile["CONFIGURATION"];
  837. ResDataObject val;
  838. if (TryGetValue(config, "LEVEL", val)) {
  839. Pattern.add("LEVEL", (int)val);
  840. }
  841. else {
  842. Pattern.add("LEVEL", 3);
  843. }
  844. if (TryGetValue(config, "MAXFILESIZE", val)) {
  845. Pattern.add("MAXFILESIZE", ((int)val) * 1024 * 1024);
  846. }
  847. else {
  848. Pattern.add("MAXFILESIZE", 10 * 1024 * 1024);
  849. }
  850. if (TryGetValue(config, "MAXBACKUPCOUNT", val)) {
  851. Pattern.add("MAXBACKUPCOUNT", ((int)val));
  852. }
  853. else {
  854. Pattern.add("MAXBACKUPCOUNT", 1);
  855. }
  856. if (TryGetValue(config, "MAXTIMEPERIOD", val)) {
  857. Pattern.add("MAXTIMEPERIOD", ((int)val));
  858. }
  859. else {
  860. Pattern.add("MAXTIMEPERIOD", 0);
  861. }
  862. if (TryGetValue(config, "FILENAME", val)) {
  863. Pattern.add("FILENAME", ((int)val));
  864. }
  865. else {
  866. Pattern.add("FILENAME", 0);
  867. }
  868. if (TryGetValue(config, "FUNCTIONNAME", val)) {
  869. Pattern.add("FUNCTIONNAME", ((int)val));
  870. }
  871. else {
  872. Pattern.add("FUNCTIONNAME", 0);
  873. }
  874. if (TryGetValue(config, "LINE", val)) {
  875. Pattern.add("LINE", ((int)val));
  876. }
  877. else {
  878. Pattern.add("LINE", 0);
  879. }
  880. if (TryGetValue(config, "DATE", val)) {
  881. Pattern.add("DATE", ((int)val));
  882. }
  883. else {
  884. Pattern.add("DATE", 0);
  885. }
  886. if (TryGetValue(config, "PROC", val)) {
  887. Pattern.add("PROC", ((int)val));
  888. }
  889. else {
  890. Pattern.add("PROC", 0);
  891. }
  892. if (TryGetValue(config, "THREAD", val)) {
  893. Pattern.add("THREAD", ((int)val));
  894. }
  895. else {
  896. Pattern.add("THREAD", 0);
  897. }
  898. if (TryGetValue(config, "CACHE", val)) {
  899. Pattern.add("CACHE", ((int)val));
  900. }
  901. else {
  902. Pattern.add("CACHE", 1);
  903. }
  904. return true;
  905. }
  906. LOCALCONFIG_API bool GetShareMemSettings(DWORD& BigBlockSize, DWORD& BigBlockCount,
  907. DWORD& SmallBlockSize, DWORD& SmallBlockCount) {
  908. try {
  909. ResDataObject val;
  910. val = tryGetLocalOptions("BigBlockSize");
  911. BigBlockSize = (DWORD)val;
  912. val = tryGetLocalOptions("BigBlockCount");
  913. BigBlockCount = (DWORD)val;
  914. val = tryGetLocalOptions("SmallBlockSize");
  915. SmallBlockSize = (DWORD)val;
  916. val = tryGetLocalOptions("SmallBlockCount");
  917. SmallBlockCount = (DWORD)val;
  918. return true;
  919. }
  920. catch (...) {
  921. BigBlockSize = 1048576; // 1MB
  922. BigBlockCount = 10;
  923. SmallBlockSize = 4096; // 4KB
  924. SmallBlockCount = 100;
  925. return false;
  926. }
  927. }
  928. LOCALCONFIG_API bool GetShareMemLogLevel(int& LogLevel) {
  929. try {
  930. ResDataObject val = tryGetLocalOptions("LogLevel");
  931. LogLevel = (int)val;
  932. return true;
  933. }
  934. catch (...) {
  935. LogLevel = 3;
  936. return false;
  937. }
  938. }