DriverConfigManager.cpp 15 KB

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