LocalConfig.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112
  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. GetMajorIDInstance() = (const char*)val;
  475. }
  476. if (GetVendorID().empty()) {
  477. ResDataObject val = tryGetLocalOptions("VendorID");
  478. GetVendorID() = (const char*)val;
  479. }
  480. if (GetProductID().empty()) {
  481. ResDataObject val = tryGetLocalOptions("ProductID");
  482. GetProductID() = (const char*)val;
  483. }
  484. if (GetSerialID().empty()) {
  485. ResDataObject val = tryGetLocalOptions("SerialID");
  486. GetSerialID() = (const char*)val;
  487. }
  488. // 构建设备类型字符串
  489. GetDeviceType() = GetMajorIDInstance() + "_" + GetVendorID() + "_" + GetProductID() + "_" + GetSerialID();
  490. return GetDeviceType();
  491. }
  492. /**
  493. * 获取设备ID
  494. */
  495. LOCALCONFIG_API string GetDeviceID() {
  496. // 确保所有ID已加载
  497. if (GetMajorIDInstance().empty() || GetVendorID().empty() || GetProductID().empty() || GetSerialID().empty()) {
  498. GetMajorIDInstance(); // 加载ID
  499. }
  500. // 构建设备ID字符串
  501. if (!GetMajorIDInstance().empty()) {
  502. return GetMajorIDInstance() + "/" + GetVendorID() + "/" + GetProductID() + "/" + GetSerialID();
  503. }
  504. return "Channel/Channel"; // 默认值
  505. }
  506. // ================================================================
  507. LOCALCONFIG_API const char* GetDriverConfigFilepath(size_t idx) {
  508. return (idx < GetDriverConfigFilepath().size()) ? GetDriverConfigFilepath()[idx].c_str() : nullptr;
  509. }
  510. LOCALCONFIG_API CCOS_PROC_TYPE GetConfigMode() {
  511. return GetConfigModeInstance();
  512. }
  513. LOCALCONFIG_API ResDataObject tryGetLocalOptions(const char* pKey) {
  514. string dir = GetProcessDirectory() + "/LocalConfig.xml";
  515. ResDataObject config, result;
  516. if (config.loadFile(dir.c_str())) {
  517. int Idx = config["CONFIGURATION"].GetFirstOf(pKey);
  518. if (Idx >= 0) {
  519. result = config["CONFIGURATION"][Idx];
  520. }
  521. }
  522. return result;
  523. }
  524. LOCALCONFIG_API ResDataObject& getLocalEbusId() {
  525. static ResDataObject mn_LocalEbusId;
  526. if (GetConfigModeInstance() == CCOS_PROC_MASTER) {
  527. mn_LocalEbusId = GetLocalBusId().c_str();
  528. }
  529. else if (GetConfigModeInstance() == CCOS_PROC_CHANNEL) {
  530. mn_LocalEbusId = "ccosChannel";
  531. }
  532. return mn_LocalEbusId;
  533. }
  534. LOCALCONFIG_API ResDataObject& getChannelEbusId() {
  535. static ResDataObject mn_LocalEbusId;
  536. mn_LocalEbusId = "ccosChannel";
  537. return mn_LocalEbusId;
  538. }
  539. LOCALCONFIG_API ResDataObject& getChannelRootpath() {
  540. static ResDataObject mn_ChannelId;
  541. mn_ChannelId = "/ccosChannel";
  542. return mn_ChannelId;
  543. }
  544. LOCALCONFIG_API ResDataObject& getLocalEbusRouterIp() {
  545. static ResDataObject mn_EbusRouterIp;
  546. mn_EbusRouterIp = tryGetLocalOptions("RouterIp");
  547. return mn_EbusRouterIp;
  548. }
  549. LOCALCONFIG_API ResDataObject& getLocalEbusPort() {
  550. static ResDataObject mn_EbusPort;
  551. mn_EbusPort = tryGetLocalOptions("Port");
  552. return mn_EbusPort;
  553. }
  554. static ResDataObject g_LogRootPath;
  555. LOCALCONFIG_API void setLogRootpath(const char* pszRootPath) {
  556. g_LogRootPath = pszRootPath;
  557. }
  558. LOCALCONFIG_API ResDataObject& getLogRootpath() {
  559. return g_LogRootPath;
  560. }
  561. LOCALCONFIG_API ResDataObject& getRootpath() {
  562. static ResDataObject mn_Rootpath;
  563. string rootpath = "/" + string((const char*)getLocalEbusId());
  564. mn_Rootpath = rootpath.c_str();
  565. return mn_Rootpath;
  566. }
  567. LOCALCONFIG_API bool getEbusLogFlag() {
  568. ResDataObject val = tryGetLocalOptions("EnableEbusLog");
  569. return (bool)val;
  570. }
  571. LOCALCONFIG_API bool getP2pFlag() {
  572. ResDataObject val = tryGetLocalOptions("P2pEnable");
  573. return (bool)val;
  574. }
  575. LOCALCONFIG_API ResDataObject getP2pServerIp() {
  576. return tryGetLocalOptions("P2pServer");
  577. }
  578. LOCALCONFIG_API ResDataObject getP2pRole() {
  579. return tryGetLocalOptions("P2pClient");
  580. }
  581. LOCALCONFIG_API ResDataObject& GetFullDriverConfigPath() {
  582. static ResDataObject resRet;
  583. string ret = GetProcessDirectory() + "/FullConfig/";
  584. resRet = ret.c_str();
  585. return resRet;
  586. }
  587. LOCALCONFIG_API DWORD GetFullDriverConfigPathEx(ResDataObject& PathList) {
  588. DWORD ret = 1;
  589. PathList.clear();
  590. // 根目录
  591. string dir = GetProcessDirectory();
  592. dir += "/FullConfig/";
  593. PathList.add(dir.c_str(), "");
  594. // 子版本目录
  595. string subdir = GetProcessDirectory();
  596. subdir += "/SubVersions/";
  597. map<string, vector<string>> templist;
  598. if (FindSubVersionDirs(subdir, templist)) {
  599. ret += (DWORD)templist.size();
  600. map<string, vector<string>>::iterator iter = templist.begin();
  601. while (iter != templist.end()) {
  602. for (DWORD i = 0; i < iter->second.size(); i++) {
  603. string filename = iter->second[i];
  604. // 在Linux下保持原始大小写
  605. // 构建路径
  606. string dirPath = filename + "/FullConfig/";
  607. PathList.add(dirPath.c_str(), iter->first.c_str());
  608. }
  609. ++iter;
  610. }
  611. }
  612. return ret;
  613. }
  614. LOCALCONFIG_API ResDataObject& GetFullDriverConfigPathX32() {
  615. static ResDataObject resRet;
  616. string ret = GetProcessDirectory() + "/win32/FullConfig/";
  617. resRet = ret.c_str();
  618. return resRet;
  619. }
  620. LOCALCONFIG_API ResDataObject& GetDriverConfigPathX32() {
  621. static ResDataObject resRet;
  622. string ret = GetProcessDirectory() + "/win32/DriverConfig/";
  623. resRet = ret.c_str();
  624. return resRet;
  625. }
  626. LOCALCONFIG_API DWORD GetDriverConfigPathEx(ResDataObject& PathList) {
  627. DWORD ret = 1;
  628. PathList.clear();
  629. // 根目录
  630. string dir = GetProcessDirectory();
  631. dir += "/DriverConfig/";
  632. PathList.add(dir.c_str(), "");
  633. // 子版本目录
  634. string subdir = GetProcessDirectory();
  635. subdir += "/SubVersions/";
  636. map<string, vector<string>> templist;
  637. if (FindSubVersionDirs(subdir, templist)) {
  638. ret += (DWORD)templist.size();
  639. map<string, vector<string>>::iterator iter = templist.begin();
  640. while (iter != templist.end()) {
  641. for (DWORD i = 0; i < iter->second.size(); i++) {
  642. string filename = iter->second[i];
  643. // 在Linux下保持原始大小写
  644. // 构建路径
  645. string dirPath = filename + "/DriverConfig/";
  646. PathList.add(dirPath.c_str(), iter->first.c_str());
  647. }
  648. ++iter;
  649. }
  650. }
  651. return ret;
  652. }
  653. LOCALCONFIG_API ResDataObject& GetLogConfigPath() {
  654. static ResDataObject resRet;
  655. string ret = GetProcessDirectory() + "/logconfig.xml";
  656. resRet = ret.c_str();
  657. return resRet;
  658. }
  659. LOCALCONFIG_API bool GetDriverProcessPath(const char* pConfigFilepath, ResDataObject& DriverProcessPath) {
  660. ResDataObject Context;
  661. if (!Context.loadFile(pConfigFilepath)) {
  662. return false;
  663. }
  664. string WorkPath = GetFileDirectory(GetFileDirectory(string(pConfigFilepath)));
  665. WorkPath += "/CcosProc";
  666. string NodeName = (const char*)Context["CONFIGURATION"]["ProcType"];
  667. if (NodeName == "MFC") {
  668. WorkPath += "MFC";
  669. }
  670. NodeName = (const char*)Context["CONFIGURATION"]["Arch"];
  671. if (NodeName == "64") {
  672. WorkPath += "X64";
  673. }
  674. WorkPath += ".exe";
  675. DriverProcessPath = WorkPath.c_str();
  676. return true;
  677. }
  678. LOCALCONFIG_API string GetModuleConfigrateFilePath(ResDataObject& resHardware) {
  679. string MajorID = resHardware["MajorID"].encode();
  680. string VendorID = resHardware["VendorID"].encode();
  681. string ProductID = resHardware["ProductID"].encode();
  682. string SerialID = resHardware["SerialID"].encode();
  683. string strPath = GetProcessDirectory();
  684. strPath += "/DriverDefine/Config/";
  685. strPath += MajorID + "_" + VendorID + "_" + ProductID + "_" + SerialID + ".json";
  686. return strPath;
  687. }
  688. LOCALCONFIG_API string GetModuleConfigrateFilePath(string devDioPath) {
  689. vector<string> parts;
  690. char buffer[1024];
  691. strcpy(buffer, devDioPath.c_str());
  692. char* token = strtok(buffer, "/");
  693. while (token) {
  694. parts.push_back(token);
  695. token = strtok(NULL, "/");
  696. }
  697. if (parts.size() >= 6) {
  698. string MajorID = parts[1];
  699. string VendorID = parts[3];
  700. string ProductID = parts[4];
  701. string SerialID = parts[5];
  702. string strPath = GetProcessDirectory();
  703. strPath += "/DriverDefine/Config/";
  704. strPath += MajorID + "_" + VendorID + "_" + ProductID + "_" + SerialID + ".json";
  705. return strPath;
  706. }
  707. return "";
  708. }
  709. LOCALCONFIG_API string GetCcosModuleConfigrateFilePath(string devDioPath, bool useTemplate) {
  710. vector<string> parts;
  711. char buffer[1024];
  712. strcpy(buffer, devDioPath.c_str());
  713. char* token = strtok(buffer, "/");
  714. while (token) {
  715. parts.push_back(token);
  716. token = strtok(NULL, "/");
  717. }
  718. if (parts.size() >= 6) {
  719. string MajorID = parts[2];
  720. string VendorID = parts[3];
  721. string ProductID = parts[4];
  722. string SerialID = parts[5];
  723. string strPath = GetProcessDirectory();
  724. strPath += useTemplate ? "/DriverDefine/" : "/DriverDefine/Config/";
  725. strPath += MajorID + "_" + VendorID + "_" + ProductID;
  726. strPath += useTemplate ? "" : "_" + SerialID;
  727. strPath += ".json";
  728. return strPath;
  729. }
  730. return "";
  731. }
  732. LOCALCONFIG_API string GetModuleDevicePath(ResDataObject& resHardware) {
  733. string MajorID = resHardware["MajorID"].encode();
  734. string VendorID = resHardware["VendorID"].encode();
  735. string ProductID = resHardware["ProductID"].encode();
  736. string SerialID = resHardware["SerialID"].encode();
  737. return "CCOS/DEVICE/" + MajorID + "/" + VendorID + "/" + ProductID + "/" + SerialID;
  738. }
  739. LOCALCONFIG_API BOOL ClearAllModuleConfigrate() {
  740. string dirPath = GetProcessDirectory() + "/DriverDefine/Config/";
  741. DIR* dir = opendir(dirPath.c_str());
  742. if (!dir) return FALSE;
  743. struct dirent* ent;
  744. while ((ent = readdir(dir))) {
  745. if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
  746. continue;
  747. string fullPath = dirPath + ent->d_name;
  748. if (fullPath.size() > 5 && fullPath.substr(fullPath.size() - 5) == ".json") {
  749. remove(fullPath.c_str());
  750. }
  751. }
  752. closedir(dir);
  753. return TRUE;
  754. }
  755. LOCALCONFIG_API bool GetClientUniqEbusId(ResDataObject& res) {
  756. static string clientBusId;
  757. if (clientBusId.empty()) {
  758. ResDataObject obj;
  759. if (MakeUniqEbusId(obj)) {
  760. clientBusId = "Client" + string((const char*)obj);
  761. if (clientBusId.size() > 16) {
  762. clientBusId = clientBusId.substr(0, 16);
  763. }
  764. }
  765. }
  766. res = clientBusId.c_str();
  767. return !clientBusId.empty();
  768. }
  769. LOCALCONFIG_API bool GetFullDriverConfigFiles(ResDataObject& filelist) {
  770. return GetSpecificDriverConfigFiles(filelist, true);
  771. }
  772. LOCALCONFIG_API bool GetDriverConfigFiles(ResDataObject& filelist) {
  773. return GetSpecificDriverConfigFiles(filelist, false);
  774. }
  775. LOCALCONFIG_API bool GetSpecificDriverConfigFiles(ResDataObject& filelist, bool FullDriverList) {
  776. filelist.clear();
  777. ResDataObject PathList;
  778. DWORD pathCount = FullDriverList ?
  779. GetFullDriverConfigPathEx(PathList) :
  780. GetDriverConfigPathEx(PathList);
  781. for (DWORD i = 0; i < pathCount; i++) {
  782. string configPath = (const char*)PathList.GetKey(i);
  783. vector<string> files;
  784. if (FindSubFiles(configPath, files)) {
  785. for (const auto& file : files) {
  786. // 检查是否为XML文件
  787. string filenameLow = file;
  788. transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), ::tolower);
  789. if (filenameLow.size() > 4 && filenameLow.substr(filenameLow.size() - 4) == ".xml") {
  790. filelist.add(file.c_str(), PathList[i]);
  791. }
  792. }
  793. }
  794. }
  795. return filelist.size() > 0;
  796. }
  797. LOCALCONFIG_API bool GetDriverProcInfo(const char* pConfigFilepath, ResDataObject& DriverProcInfo) {
  798. ResDataObject procPath;
  799. if (!GetDriverProcessPath(pConfigFilepath, procPath)) {
  800. return false;
  801. }
  802. string WorkPath = GetFileDirectory(string(pConfigFilepath));
  803. WorkPath = GetFileDirectory(WorkPath);
  804. WorkPath += "/";
  805. DriverProcInfo.add("WorkPath", WorkPath.c_str());
  806. DriverProcInfo.add("DriverPath", procPath);
  807. DriverProcInfo.add("DriverConfigPath", pConfigFilepath);
  808. // 读取配置中的Console设置
  809. ResDataObject Context;
  810. if (Context.loadFile(pConfigFilepath)) {
  811. string Console = (const char*)Context["CONFIGURATION"]["Console"];
  812. DriverProcInfo.add("ShowWindow", (Console != "OFF"));
  813. string AutoLoad = (const char*)Context["CONFIGURATION"]["AutoLoad"];
  814. DriverProcInfo.add("AutoLoad", (AutoLoad != "OFF"));
  815. }
  816. else {
  817. DriverProcInfo.add("ShowWindow", true);
  818. DriverProcInfo.add("AutoLoad", true);
  819. }
  820. return true;
  821. }
  822. LOCALCONFIG_API bool GetLogPatternResource(ResDataObject& Pattern) {
  823. Pattern.clear();
  824. ResDataObject configFile;
  825. if (!configFile.loadFile(GetLogConfigPath())) {
  826. return false;
  827. }
  828. ResDataObject config = configFile["CONFIGURATION"];
  829. ResDataObject val;
  830. if (TryGetValue(config, "LEVEL", val)) {
  831. Pattern.add("LEVEL", (int)val);
  832. }
  833. else {
  834. Pattern.add("LEVEL", 3);
  835. }
  836. if (TryGetValue(config, "MAXFILESIZE", val)) {
  837. Pattern.add("MAXFILESIZE", ((int)val) * 1024 * 1024);
  838. }
  839. else {
  840. Pattern.add("MAXFILESIZE", 10 * 1024 * 1024);
  841. }
  842. if (TryGetValue(config, "MAXBACKUPCOUNT", val)) {
  843. Pattern.add("MAXBACKUPCOUNT", ((int)val));
  844. }
  845. else {
  846. Pattern.add("MAXBACKUPCOUNT", 1);
  847. }
  848. if (TryGetValue(config, "MAXTIMEPERIOD", val)) {
  849. Pattern.add("MAXTIMEPERIOD", ((int)val));
  850. }
  851. else {
  852. Pattern.add("MAXTIMEPERIOD", 0);
  853. }
  854. if (TryGetValue(config, "FILENAME", val)) {
  855. Pattern.add("FILENAME", ((int)val));
  856. }
  857. else {
  858. Pattern.add("FILENAME", 0);
  859. }
  860. if (TryGetValue(config, "FUNCTIONNAME", val)) {
  861. Pattern.add("FUNCTIONNAME", ((int)val));
  862. }
  863. else {
  864. Pattern.add("FUNCTIONNAME", 0);
  865. }
  866. if (TryGetValue(config, "LINE", val)) {
  867. Pattern.add("LINE", ((int)val));
  868. }
  869. else {
  870. Pattern.add("LINE", 0);
  871. }
  872. if (TryGetValue(config, "DATE", val)) {
  873. Pattern.add("DATE", ((int)val));
  874. }
  875. else {
  876. Pattern.add("DATE", 0);
  877. }
  878. if (TryGetValue(config, "PROC", val)) {
  879. Pattern.add("PROC", ((int)val));
  880. }
  881. else {
  882. Pattern.add("PROC", 0);
  883. }
  884. if (TryGetValue(config, "THREAD", val)) {
  885. Pattern.add("THREAD", ((int)val));
  886. }
  887. else {
  888. Pattern.add("THREAD", 0);
  889. }
  890. if (TryGetValue(config, "CACHE", val)) {
  891. Pattern.add("CACHE", ((int)val));
  892. }
  893. else {
  894. Pattern.add("CACHE", 1);
  895. }
  896. return true;
  897. }
  898. LOCALCONFIG_API bool GetShareMemSettings(DWORD& BigBlockSize, DWORD& BigBlockCount,
  899. DWORD& SmallBlockSize, DWORD& SmallBlockCount) {
  900. try {
  901. ResDataObject val;
  902. val = tryGetLocalOptions("BigBlockSize");
  903. BigBlockSize = (DWORD)val;
  904. val = tryGetLocalOptions("BigBlockCount");
  905. BigBlockCount = (DWORD)val;
  906. val = tryGetLocalOptions("SmallBlockSize");
  907. SmallBlockSize = (DWORD)val;
  908. val = tryGetLocalOptions("SmallBlockCount");
  909. SmallBlockCount = (DWORD)val;
  910. return true;
  911. }
  912. catch (...) {
  913. BigBlockSize = 1048576; // 1MB
  914. BigBlockCount = 10;
  915. SmallBlockSize = 4096; // 4KB
  916. SmallBlockCount = 100;
  917. return false;
  918. }
  919. }
  920. LOCALCONFIG_API bool GetShareMemLogLevel(int& LogLevel) {
  921. try {
  922. ResDataObject val = tryGetLocalOptions("LogLevel");
  923. LogLevel = (int)val;
  924. return true;
  925. }
  926. catch (...) {
  927. LogLevel = 3;
  928. return false;
  929. }
  930. }