DriverConfigManager.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. #include "DriverConfigManager.h"
  2. #include <iostream>
  3. #include <filesystem>
  4. #include <dlfcn.h>
  5. #include <mutex>
  6. #include "common_api.h"
  7. #include "LocalConfig.h"
  8. DriverConfigManager::DriverConfigManager()
  9. {
  10. }
  11. DriverConfigManager::~DriverConfigManager()
  12. {
  13. }
  14. int DriverConfigManager::GetAllConfigList(ResDataObject& resAll)
  15. {
  16. //bool ret = GetSpecificDriverConfigFiles(resAll, false);
  17. resAll.clear();
  18. ResDataObject fileList;
  19. if (GetSpecificDriverConfigFiles(fileList, false))
  20. {
  21. //mLog::FINFO("GetSpecificDriverConfigFiles ok");
  22. //map<string, int> ConflictBusIds;
  23. //map<string, string> BusIdMap;//BusId <-> Dir
  24. //map<string, vector<TargetDriverInfo>> LoadDriverMap;
  25. //exist x64
  26. for (size_t i = 0; i < fileList.size(); i++)
  27. {
  28. ResDataObject BusId, DriverPath;
  29. //TargetDriverInfo DrvInfo;
  30. if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverPath))
  31. {
  32. resAll.add(DriverPath, fileList.GetKey(i));
  33. }
  34. }
  35. }
  36. return resAll.size();
  37. }
  38. static string GetCurTime64ToString()
  39. {
  40. time_t now;
  41. struct tm t1;
  42. time(&now); // 获取当前UTC时间
  43. localtime_r(&now, &t1); // 转换为本地时间(线程安全)
  44. return FormatstdString("%04d%02d%02d%02d%02d%02d",
  45. t1.tm_year + 1900,
  46. t1.tm_mon + 1,
  47. t1.tm_mday,
  48. t1.tm_hour,
  49. t1.tm_min,
  50. t1.tm_sec);
  51. }
  52. /// <summary>
  53. /// 添加驱动
  54. /// </summary>
  55. /// <param name="pszDevPath"></param>
  56. /// <param name="resNewDevPath"></param>
  57. /// <returns></returns>
  58. RET_STATUS DriverConfigManager::AddDriverConfig(const char* pszDriverpath, ResDataObject &resNewDevPath)
  59. {
  60. RET_STATUS ret = RET_FAILED;
  61. ResDataObject fileList;
  62. if (GetSpecificDriverConfigFiles(fileList, true))
  63. {
  64. //check x64FLAG
  65. //assert(0);//NOT FINISHED YET
  66. //exist x64
  67. for (size_t i = 0; i < fileList.size(); i++)
  68. {
  69. ResDataObject BusId;
  70. ResDataObject DriverBusId;
  71. //get ebus driver path
  72. if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverBusId))
  73. {
  74. //for test
  75. //mLog::FINFO("file[{$}] File:{$} Buspath:{$}\n", i, fileList.GetKey(i), (const char*)DriverBusId);
  76. ///DevCareRayRF/Detector/driver/CareRay/1800RF/1234/{18CAB88A-C61C-4BB2-AC28-184FDD4FD160}
  77. // CCOS/DEVICE/Detecor/CareRay/1800RF
  78. vector<string> items;
  79. SplitDevicePath(DriverBusId, items);
  80. string ccosPath = "CCOS/DEVICE/";
  81. if(items.size() >= 5)
  82. ccosPath = ccosPath + items[1] + "/" + items[3] + "/" + items[4];
  83. //mLog::FINFO("file[{$}] File:{$} CcosPath:{$}\n", i, fileList.GetKey(i), ccosPath);
  84. if (DriverBusId == pszDriverpath || ccosPath == pszDriverpath)
  85. {
  86. //mLog::FINFO("Got Driver with {$}", pszDriverpath);
  87. string FullFilePath = fileList.GetKey(i);
  88. //copy configuration
  89. //make new title
  90. string TargetFileTitle = GetFileTitle(FullFilePath);
  91. string TimePos = GetCurTime64ToString();
  92. string NewTargetFileTitle = FormatstdString("\\%s_%s.xml", TargetFileTitle.c_str(), TimePos.c_str());
  93. //make full filepath
  94. //ResDataObject DriverConfigPath = GetDriverConfigPath();
  95. //string DriverConfigPath = GetFileDirectory(FullFilePath);//...\FullConfig
  96. //DriverConfigPath = GetFileDirectory(DriverConfigPath);//...procDir
  97. string DriverConfigPath = GetProcessDirectory();
  98. DriverConfigPath += "\\DriverConfig";
  99. string FullNewTargetFilePath = DriverConfigPath.c_str();
  100. FullNewTargetFilePath += NewTargetFileTitle;
  101. //for test
  102. //mLog::FINFO("Got Match:{$}\nCopy: Org:{$}\nDes:{$}\n", FullFilePath.c_str(), fileList.GetKey(i), FullNewTargetFilePath.c_str());
  103. if (std::filesystem::copy_file(
  104. fileList.GetKey(i), // 源文件路径
  105. FullNewTargetFilePath.c_str(), // 目标文件路径
  106. std::filesystem::copy_options::overwrite_existing))// 覆盖已存在文件
  107. {
  108. //TargetDriverInfo DrvInfo;
  109. ResDataObject BusId;
  110. if (GetDriverEbusId(FullNewTargetFilePath.c_str(), BusId, resNewDevPath, true) == false)
  111. {
  112. return RET_FAILED;
  113. }
  114. if (ccosPath == pszDriverpath)
  115. {
  116. ccosPath += "/";
  117. ccosPath += (const char*)BusId;
  118. //mLog::FINFO("Got new devPath {$} transfer to ccos path {$}", (const char*)resNewDevPath, ccosPath);
  119. resNewDevPath = ccosPath.c_str();
  120. //这里检查?
  121. }
  122. return RET_SUCCEED;
  123. }
  124. }
  125. }
  126. }
  127. }
  128. return ret;
  129. }
  130. /// <summary>
  131. /// 移除驱动
  132. /// </summary>
  133. /// <param name="pszDevPath"></param>
  134. /// <returns></returns>
  135. RET_STATUS DriverConfigManager::DelDriverConfig(const char* pszDevPath)
  136. {
  137. if (unlink(GetConfigFile(pszDevPath).c_str()) == 0)
  138. return RET_SUCCEED;
  139. return RET_FAILED;
  140. }
  141. /// <summary>
  142. /// 从设备Path返回设备配置文件绝对路径
  143. /// </summary>
  144. /// <param name="pszDevPath"></param>
  145. /// <returns></returns>
  146. string DriverConfigManager::GetConfigFile(const char* pszDevPath)
  147. {
  148. RET_STATUS ret = RET_FAILED;
  149. ResDataObject fileList;
  150. if (GetSpecificDriverConfigFiles(fileList, false))
  151. {
  152. //check x64FLAG
  153. //assert(0);//NOT FINISHED YET
  154. //exist x64
  155. for (size_t i = 0; i < fileList.size(); i++)
  156. {
  157. ResDataObject BusId;
  158. ResDataObject DriverDevPath;
  159. //get ebus driver path
  160. if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverDevPath))
  161. {
  162. //for test
  163. //mLog::FINFO("file[{$}] File:{$}\n Buspath:{$}\n", i, fileList.GetKey(i), (const char*)DriverDevPath);
  164. if (DriverDevPath == pszDevPath)
  165. {
  166. return fileList.GetKey(i);
  167. }
  168. }
  169. }
  170. }
  171. return "";
  172. }
  173. typedef DriverDPC* (*GetDriverDPC)();
  174. typedef void(*ReleaseDriverDPC)(DriverDPC* p);
  175. /// <summary>
  176. ///
  177. /// </summary>
  178. /// <param name="pszDevPath"></param>
  179. /// <param name="resConfig"></param>
  180. /// <returns></returns>
  181. RET_STATUS DriverConfigManager::GetDriverConfigRes(const char* pszDevPath, ResDataObject& resConfig)
  182. {
  183. RET_STATUS ret = RET_FAILED;
  184. string ConfigFile = GetConfigFile(pszDevPath);
  185. //if (pResource != nullptr)
  186. {
  187. //加载Driver并获取配置项
  188. ResDataObject config;
  189. string FilePath;
  190. if (config.loadFile(ConfigFile.c_str()))
  191. {
  192. string procdir;
  193. string drvpath;
  194. ResDataObject DrvConfig;
  195. procdir = GetProcessDirectory();
  196. try {
  197. //load drvpath
  198. DrvConfig = config["CONFIGURATION"];
  199. drvpath = (const char*)DrvConfig["driver"];
  200. string temp("%ROOT%");
  201. drvpath = ReplaceSubString(drvpath, temp, procdir);
  202. string DllFileTitle = GetFileTitle(drvpath);
  203. FilePath = GetFileDirectory(drvpath);
  204. //AddEnvPath(FilePath.c_str());
  205. //oemdriver
  206. int oemidx = DrvConfig.GetFirstOf("oemdriver");
  207. string oemdrvpath;
  208. if (oemidx >= 0)
  209. {
  210. //exist
  211. oemdrvpath = (const char*)DrvConfig["oemdriver"];
  212. string temp("%ROOT%");
  213. oemdrvpath = ReplaceSubString(oemdrvpath, temp, procdir);
  214. FilePath = GetFileDirectory(oemdrvpath);
  215. //AddEnvPath(FilePath.c_str());
  216. DrvConfig["oemdriver"] = oemdrvpath.c_str();
  217. }
  218. else
  219. {
  220. FilePath = "";
  221. DrvConfig.add("oemdriver", "");
  222. }
  223. // 收集所有需要添加的库路径
  224. std::vector<std::string> addPaths;
  225. std::string drvDir = GetFileDirectory(drvpath);
  226. if (!drvDir.empty()) {
  227. addPaths.push_back(drvDir);
  228. }
  229. if (!oemdrvpath.empty()) {
  230. std::string oemDir = GetFileDirectory(oemdrvpath);
  231. if (!oemDir.empty()) {
  232. addPaths.push_back(oemDir);
  233. }
  234. }
  235. // 准备环境变量修改(线程安全)
  236. static std::mutex envMutex;
  237. std::string oldLibPath;
  238. {
  239. std::lock_guard<std::mutex> lock(envMutex);
  240. const char* envPath = getenv("LD_LIBRARY_PATH");
  241. if (envPath) oldLibPath = envPath;
  242. if (!addPaths.empty()) {
  243. std::string newLibPath;
  244. for (const auto& path : addPaths) {
  245. if (!newLibPath.empty()) newLibPath += ":";
  246. newLibPath += path;
  247. }
  248. if (!oldLibPath.empty()) {
  249. newLibPath += ":";
  250. newLibPath += oldLibPath;
  251. }
  252. setenv("LD_LIBRARY_PATH", newLibPath.c_str(), 1);
  253. }
  254. }
  255. void* DllFileHandle = dlopen(drvpath.c_str(), RTLD_LAZY);
  256. if (!DllFileHandle) {
  257. const char* dlerr = dlerror();
  258. // PRINTA_ERROR(m_pLogger, "Load lib:%s failed. Error: %s\n", drvpath.c_str(), dlerr ? dlerr : "unknown");
  259. }
  260. // 立即恢复环境变量
  261. {
  262. std::lock_guard<std::mutex> lock(envMutex);
  263. if (oldLibPath.empty()) {
  264. unsetenv("LD_LIBRARY_PATH");
  265. }
  266. else {
  267. setenv("LD_LIBRARY_PATH", oldLibPath.c_str(), 1);
  268. }
  269. }
  270. if (DllFileHandle)
  271. {
  272. // 获取函数指针
  273. typedef DriverDPC* (*GetDriverDPC)();
  274. typedef void (*ReleaseDriverDPC)(DriverDPC*);
  275. GetDriverDPC dpcfunc = (GetDriverDPC)dlsym(DllFileHandle, "GetDriverDPC");
  276. const char* dlsym_error = dlerror();
  277. if (dlsym_error) {
  278. // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry. Error: %s\n", drvpath.c_str(), dlsym_error);
  279. dlclose(DllFileHandle);
  280. return RET_FAILED;
  281. }
  282. if (dpcfunc)
  283. {
  284. DriverDPC* pDPC = dpcfunc();
  285. if (pDPC)
  286. {
  287. pDPC->SetDriverConfigFilePath(ConfigFile.c_str());
  288. //m_NotifyThread.m_pDPC = m_pDPC;//init dpc notify thread
  289. if (pDPC->DriverEntry(DrvConfig))
  290. {
  291. //读取配置,并返回
  292. LogicDriver* pDriver = (LogicDriver*)pDPC;
  293. ResDataObject pres;
  294. pDriver->GetDeviceResource(&pres); //加载配置文件
  295. pDriver->GetDeviceConfig(&resConfig); //获取驱动配置
  296. std::cout << "ConfigDriverLoader " << resConfig.encode() << endl;
  297. ReleaseDriverDPC relfunc = (ReleaseDriverDPC)dlsym(DllFileHandle, "ReleaseDriverDPC");
  298. if (relfunc)
  299. relfunc(pDPC);
  300. ret = RET_SUCCEED;
  301. }
  302. else
  303. {
  304. // PRINTA_ERROR(m_pLogger, "lib:%s Call DriverEntry Failed\n", drvpath.c_str());
  305. }
  306. }
  307. else
  308. {
  309. // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry\n", drvpath.c_str());
  310. }
  311. }
  312. else
  313. {
  314. // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry\n", drvpath.c_str());
  315. }
  316. dlclose(DllFileHandle);
  317. }
  318. }
  319. catch (ResDataObjectExption& exp)
  320. {
  321. //exp.what()
  322. //PRINTA_ERROR(m_pLogger, exp.what());
  323. //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str());
  324. return RET_FAILED;
  325. }
  326. catch (...)
  327. {
  328. //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str());
  329. return RET_FAILED;
  330. }
  331. }
  332. }
  333. return ret;
  334. }
  335. /// <summary>
  336. ///
  337. /// </summary>
  338. /// <param name="pszDevPath"></param>
  339. /// <param name="resConfig"></param>
  340. /// <returns></returns>
  341. RET_STATUS DriverConfigManager::SetDriverConfigRes(const char* pszDevPath, ResDataObject* resConfig)
  342. {
  343. RET_STATUS ret = RET_FAILED;
  344. string ConfigFile = GetConfigFile(pszDevPath);
  345. //if (pResource != nullptr)
  346. {
  347. //加载Driver并获取配置项
  348. ResDataObject config;
  349. string FilePath;
  350. if (config.loadFile(ConfigFile.c_str()))
  351. {
  352. string procdir;
  353. string drvpath;
  354. ResDataObject DrvConfig;
  355. procdir = GetProcessDirectory();
  356. try {
  357. //load drvpath
  358. DrvConfig = config["CONFIGURATION"];
  359. drvpath = (const char*)DrvConfig["driver"];
  360. string temp("%ROOT%");
  361. drvpath = ReplaceSubString(drvpath, temp, procdir);
  362. string DllFileTitle = GetFileTitle(drvpath);
  363. FilePath = GetFileDirectory(drvpath);
  364. //AddEnvPath(FilePath.c_str());
  365. //oemdriver
  366. string oemdrvpath;
  367. int oemidx = DrvConfig.GetFirstOf("oemdriver");
  368. if (oemidx >= 0)
  369. {
  370. //exist
  371. oemdrvpath = (const char*)DrvConfig["oemdriver"];
  372. string temp("%ROOT%");
  373. oemdrvpath = ReplaceSubString(oemdrvpath, temp, procdir);
  374. FilePath = GetFileDirectory(oemdrvpath);
  375. //AddEnvPath(FilePath.c_str());
  376. DrvConfig["oemdriver"] = oemdrvpath.c_str();
  377. }
  378. else
  379. {
  380. FilePath = "";
  381. DrvConfig.add("oemdriver", "");
  382. }
  383. // 收集所有需要添加的库路径
  384. std::vector<std::string> addPaths;
  385. std::string drvDir = GetFileDirectory(drvpath);
  386. if (!drvDir.empty()) {
  387. addPaths.push_back(drvDir);
  388. }
  389. if (!oemdrvpath.empty()) {
  390. std::string oemDir = GetFileDirectory(oemdrvpath);
  391. if (!oemDir.empty()) {
  392. addPaths.push_back(oemDir);
  393. }
  394. }
  395. // 准备环境变量修改(线程安全)
  396. static std::mutex envMutex;
  397. std::string oldLibPath;
  398. {
  399. std::lock_guard<std::mutex> lock(envMutex);
  400. const char* envPath = getenv("LD_LIBRARY_PATH");
  401. if (envPath) oldLibPath = envPath;
  402. if (!addPaths.empty()) {
  403. std::string newLibPath;
  404. for (const auto& path : addPaths) {
  405. if (!newLibPath.empty()) newLibPath += ":";
  406. newLibPath += path;
  407. }
  408. if (!oldLibPath.empty()) {
  409. newLibPath += ":";
  410. newLibPath += oldLibPath;
  411. }
  412. setenv("LD_LIBRARY_PATH", newLibPath.c_str(), 1);
  413. }
  414. }
  415. //TryGetValue(DrvConfig, "connections", m_Connection);
  416. void* DllFileHandle = dlopen(drvpath.c_str(), RTLD_LAZY);
  417. if (!DllFileHandle) {
  418. const char* dlerr = dlerror();
  419. // PRINTA_ERROR(m_pLogger, "Load lib:%s failed. Error: %s\n", drvpath.c_str(), dlerr ? dlerr : "unknown");
  420. }
  421. // 立即恢复环境变量
  422. {
  423. std::lock_guard<std::mutex> lock(envMutex);
  424. if (oldLibPath.empty()) {
  425. unsetenv("LD_LIBRARY_PATH");
  426. }
  427. else {
  428. setenv("LD_LIBRARY_PATH", oldLibPath.c_str(), 1);
  429. }
  430. }
  431. if (DllFileHandle)
  432. {
  433. // 获取函数指针
  434. typedef DriverDPC* (*GetDriverDPC)();
  435. typedef void (*ReleaseDriverDPC)(DriverDPC*);
  436. GetDriverDPC dpcfunc = (GetDriverDPC)dlsym(DllFileHandle, "GetDriverDPC");
  437. const char* dlsym_error = dlerror();
  438. if (dlsym_error) {
  439. // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry. Error: %s\n", drvpath.c_str(), dlsym_error);
  440. dlclose(DllFileHandle);
  441. return RET_FAILED;
  442. }
  443. if (dpcfunc)
  444. {
  445. DriverDPC* pDPC = dpcfunc();
  446. if (pDPC)
  447. {
  448. pDPC->SetDriverConfigFilePath(ConfigFile.c_str());
  449. //m_NotifyThread.m_pDPC = m_pDPC;//init dpc notify thread
  450. if (pDPC->DriverEntry(DrvConfig))
  451. {
  452. //读取配置,并返回
  453. LogicDriver* pDriver = (LogicDriver*)pDPC;
  454. ResDataObject pres;
  455. //pDriver->
  456. pDriver->GetDeviceResource(&pres); //加载配置文件
  457. pDriver->SetDeviceConfig(resConfig); //设置驱动配置
  458. std::cout << "ConfigDriverLoader " << resConfig->encode() << endl;
  459. ReleaseDriverDPC relfunc = (ReleaseDriverDPC)dlsym(DllFileHandle, "ReleaseDriverDPC");
  460. if (relfunc)
  461. relfunc(pDPC);
  462. ret = RET_SUCCEED;
  463. }
  464. else
  465. {
  466. const char* dlerr = dlerror();
  467. // PRINTA_ERROR(m_pLogger, "lib:%s Call DriverEntry Failed. Error: %s\n", drvpath.c_str(), dlerr ? dlerr : "unknown");
  468. }
  469. }
  470. else
  471. {
  472. // PRINTA_ERROR(m_pLogger, "lib:%s no DPC Object returned\n", drvpath.c_str());
  473. }
  474. }
  475. else
  476. {
  477. // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry\n", drvpath.c_str());
  478. }
  479. dlclose(DllFileHandle);
  480. }
  481. }
  482. catch (ResDataObjectExption& exp)
  483. {
  484. //exp.what()
  485. //PRINTA_ERROR(m_pLogger, exp.what());
  486. //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str());
  487. return RET_FAILED;
  488. }
  489. catch (...)
  490. {
  491. //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str());
  492. return RET_FAILED;
  493. }
  494. }
  495. }
  496. return ret;
  497. }