#include "DriverConfigManager.h" #include #include #include #include #include "common_api.h" #include "LocalConfig.h" DriverConfigManager::DriverConfigManager() { } DriverConfigManager::~DriverConfigManager() { } int DriverConfigManager::GetAllConfigList(ResDataObject& resAll) { //bool ret = GetSpecificDriverConfigFiles(resAll, false); resAll.clear(); ResDataObject fileList; if (GetSpecificDriverConfigFiles(fileList, false)) { //mLog::FINFO("GetSpecificDriverConfigFiles ok"); //map ConflictBusIds; //map BusIdMap;//BusId <-> Dir //map> LoadDriverMap; //exist x64 for (size_t i = 0; i < fileList.size(); i++) { ResDataObject BusId, DriverPath; //TargetDriverInfo DrvInfo; if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverPath)) { resAll.add(DriverPath, fileList.GetKey(i)); } } } return resAll.size(); } static string GetCurTime64ToString() { time_t now; struct tm t1; time(&now); // 获取当前UTC时间 localtime_r(&now, &t1); // 转换为本地时间(线程安全) return FormatstdString("%04d%02d%02d%02d%02d%02d", t1.tm_year + 1900, t1.tm_mon + 1, t1.tm_mday, t1.tm_hour, t1.tm_min, t1.tm_sec); } /// /// 添加驱动 /// /// /// /// RET_STATUS DriverConfigManager::AddDriverConfig(const char* pszDriverpath, ResDataObject &resNewDevPath) { RET_STATUS ret = RET_FAILED; ResDataObject fileList; if (GetSpecificDriverConfigFiles(fileList, true)) { //check x64FLAG //assert(0);//NOT FINISHED YET //exist x64 for (size_t i = 0; i < fileList.size(); i++) { ResDataObject BusId; ResDataObject DriverBusId; //get ebus driver path if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverBusId)) { //for test //mLog::FINFO("file[{$}] File:{$} Buspath:{$}\n", i, fileList.GetKey(i), (const char*)DriverBusId); ///DevCareRayRF/Detector/driver/CareRay/1800RF/1234/{18CAB88A-C61C-4BB2-AC28-184FDD4FD160} // CCOS/DEVICE/Detecor/CareRay/1800RF vector items; SplitDevicePath(DriverBusId, items); string ccosPath = "CCOS/DEVICE/"; if(items.size() >= 5) ccosPath = ccosPath + items[1] + "/" + items[3] + "/" + items[4]; //mLog::FINFO("file[{$}] File:{$} CcosPath:{$}\n", i, fileList.GetKey(i), ccosPath); if (DriverBusId == pszDriverpath || ccosPath == pszDriverpath) { //mLog::FINFO("Got Driver with {$}", pszDriverpath); string FullFilePath = fileList.GetKey(i); //copy configuration //make new title string TargetFileTitle = GetFileTitle(FullFilePath); string TimePos = GetCurTime64ToString(); string NewTargetFileTitle = FormatstdString("\\%s_%s.xml", TargetFileTitle.c_str(), TimePos.c_str()); //make full filepath //ResDataObject DriverConfigPath = GetDriverConfigPath(); //string DriverConfigPath = GetFileDirectory(FullFilePath);//...\FullConfig //DriverConfigPath = GetFileDirectory(DriverConfigPath);//...procDir string DriverConfigPath = GetProcessDirectory(); DriverConfigPath += "\\DriverConfig"; string FullNewTargetFilePath = DriverConfigPath.c_str(); FullNewTargetFilePath += NewTargetFileTitle; //for test //mLog::FINFO("Got Match:{$}\nCopy: Org:{$}\nDes:{$}\n", FullFilePath.c_str(), fileList.GetKey(i), FullNewTargetFilePath.c_str()); if (std::filesystem::copy_file( fileList.GetKey(i), // 源文件路径 FullNewTargetFilePath.c_str(), // 目标文件路径 std::filesystem::copy_options::overwrite_existing))// 覆盖已存在文件 { //TargetDriverInfo DrvInfo; ResDataObject BusId; if (GetDriverEbusId(FullNewTargetFilePath.c_str(), BusId, resNewDevPath, true) == false) { return RET_FAILED; } if (ccosPath == pszDriverpath) { ccosPath += "/"; ccosPath += (const char*)BusId; //mLog::FINFO("Got new devPath {$} transfer to ccos path {$}", (const char*)resNewDevPath, ccosPath); resNewDevPath = ccosPath.c_str(); //这里检查? } return RET_SUCCEED; } } } } } return ret; } /// /// 移除驱动 /// /// /// RET_STATUS DriverConfigManager::DelDriverConfig(const char* pszDevPath) { if (unlink(GetConfigFile(pszDevPath).c_str()) == 0) return RET_SUCCEED; return RET_FAILED; } /// /// 从设备Path返回设备配置文件绝对路径 /// /// /// string DriverConfigManager::GetConfigFile(const char* pszDevPath) { RET_STATUS ret = RET_FAILED; ResDataObject fileList; if (GetSpecificDriverConfigFiles(fileList, false)) { //check x64FLAG //assert(0);//NOT FINISHED YET //exist x64 for (size_t i = 0; i < fileList.size(); i++) { ResDataObject BusId; ResDataObject DriverDevPath; //get ebus driver path if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverDevPath)) { //for test //mLog::FINFO("file[{$}] File:{$}\n Buspath:{$}\n", i, fileList.GetKey(i), (const char*)DriverDevPath); if (DriverDevPath == pszDevPath) { return fileList.GetKey(i); } } } } return ""; } typedef DriverDPC* (*GetDriverDPC)(); typedef void(*ReleaseDriverDPC)(DriverDPC* p); /// /// /// /// /// /// RET_STATUS DriverConfigManager::GetDriverConfigRes(const char* pszDevPath, ResDataObject& resConfig) { RET_STATUS ret = RET_FAILED; string ConfigFile = GetConfigFile(pszDevPath); //if (pResource != nullptr) { //加载Driver并获取配置项 ResDataObject config; string FilePath; if (config.loadFile(ConfigFile.c_str())) { string procdir; string drvpath; ResDataObject DrvConfig; procdir = GetProcessDirectory(); try { //load drvpath DrvConfig = config["CONFIGURATION"]; drvpath = (const char*)DrvConfig["driver"]; string temp("%ROOT%"); drvpath = ReplaceSubString(drvpath, temp, procdir); string DllFileTitle = GetFileTitle(drvpath); FilePath = GetFileDirectory(drvpath); //AddEnvPath(FilePath.c_str()); //oemdriver int oemidx = DrvConfig.GetFirstOf("oemdriver"); string oemdrvpath; if (oemidx >= 0) { //exist oemdrvpath = (const char*)DrvConfig["oemdriver"]; string temp("%ROOT%"); oemdrvpath = ReplaceSubString(oemdrvpath, temp, procdir); FilePath = GetFileDirectory(oemdrvpath); //AddEnvPath(FilePath.c_str()); DrvConfig["oemdriver"] = oemdrvpath.c_str(); } else { FilePath = ""; DrvConfig.add("oemdriver", ""); } // 收集所有需要添加的库路径 std::vector addPaths; std::string drvDir = GetFileDirectory(drvpath); if (!drvDir.empty()) { addPaths.push_back(drvDir); } if (!oemdrvpath.empty()) { std::string oemDir = GetFileDirectory(oemdrvpath); if (!oemDir.empty()) { addPaths.push_back(oemDir); } } // 准备环境变量修改(线程安全) static std::mutex envMutex; std::string oldLibPath; { std::lock_guard lock(envMutex); const char* envPath = getenv("LD_LIBRARY_PATH"); if (envPath) oldLibPath = envPath; if (!addPaths.empty()) { std::string newLibPath; for (const auto& path : addPaths) { if (!newLibPath.empty()) newLibPath += ":"; newLibPath += path; } if (!oldLibPath.empty()) { newLibPath += ":"; newLibPath += oldLibPath; } setenv("LD_LIBRARY_PATH", newLibPath.c_str(), 1); } } void* DllFileHandle = dlopen(drvpath.c_str(), RTLD_LAZY); if (!DllFileHandle) { const char* dlerr = dlerror(); // PRINTA_ERROR(m_pLogger, "Load lib:%s failed. Error: %s\n", drvpath.c_str(), dlerr ? dlerr : "unknown"); } // 立即恢复环境变量 { std::lock_guard lock(envMutex); if (oldLibPath.empty()) { unsetenv("LD_LIBRARY_PATH"); } else { setenv("LD_LIBRARY_PATH", oldLibPath.c_str(), 1); } } if (DllFileHandle) { // 获取函数指针 typedef DriverDPC* (*GetDriverDPC)(); typedef void (*ReleaseDriverDPC)(DriverDPC*); GetDriverDPC dpcfunc = (GetDriverDPC)dlsym(DllFileHandle, "GetDriverDPC"); const char* dlsym_error = dlerror(); if (dlsym_error) { // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry. Error: %s\n", drvpath.c_str(), dlsym_error); dlclose(DllFileHandle); return RET_FAILED; } if (dpcfunc) { DriverDPC* pDPC = dpcfunc(); if (pDPC) { pDPC->SetDriverConfigFilePath(ConfigFile.c_str()); //m_NotifyThread.m_pDPC = m_pDPC;//init dpc notify thread if (pDPC->DriverEntry(DrvConfig)) { //读取配置,并返回 LogicDriver* pDriver = (LogicDriver*)pDPC; ResDataObject pres; pDriver->GetDeviceResource(&pres); //加载配置文件 pDriver->GetDeviceConfig(&resConfig); //获取驱动配置 std::cout << "ConfigDriverLoader " << resConfig.encode() << endl; ReleaseDriverDPC relfunc = (ReleaseDriverDPC)dlsym(DllFileHandle, "ReleaseDriverDPC"); if (relfunc) relfunc(pDPC); ret = RET_SUCCEED; } else { // PRINTA_ERROR(m_pLogger, "lib:%s Call DriverEntry Failed\n", drvpath.c_str()); } } else { // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry\n", drvpath.c_str()); } } else { // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry\n", drvpath.c_str()); } dlclose(DllFileHandle); } } catch (ResDataObjectExption& exp) { //exp.what() //PRINTA_ERROR(m_pLogger, exp.what()); //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str()); return RET_FAILED; } catch (...) { //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str()); return RET_FAILED; } } } return ret; } /// /// /// /// /// /// RET_STATUS DriverConfigManager::SetDriverConfigRes(const char* pszDevPath, ResDataObject* resConfig) { RET_STATUS ret = RET_FAILED; string ConfigFile = GetConfigFile(pszDevPath); //if (pResource != nullptr) { //加载Driver并获取配置项 ResDataObject config; string FilePath; if (config.loadFile(ConfigFile.c_str())) { string procdir; string drvpath; ResDataObject DrvConfig; procdir = GetProcessDirectory(); try { //load drvpath DrvConfig = config["CONFIGURATION"]; drvpath = (const char*)DrvConfig["driver"]; string temp("%ROOT%"); drvpath = ReplaceSubString(drvpath, temp, procdir); string DllFileTitle = GetFileTitle(drvpath); FilePath = GetFileDirectory(drvpath); //AddEnvPath(FilePath.c_str()); //oemdriver string oemdrvpath; int oemidx = DrvConfig.GetFirstOf("oemdriver"); if (oemidx >= 0) { //exist oemdrvpath = (const char*)DrvConfig["oemdriver"]; string temp("%ROOT%"); oemdrvpath = ReplaceSubString(oemdrvpath, temp, procdir); FilePath = GetFileDirectory(oemdrvpath); //AddEnvPath(FilePath.c_str()); DrvConfig["oemdriver"] = oemdrvpath.c_str(); } else { FilePath = ""; DrvConfig.add("oemdriver", ""); } // 收集所有需要添加的库路径 std::vector addPaths; std::string drvDir = GetFileDirectory(drvpath); if (!drvDir.empty()) { addPaths.push_back(drvDir); } if (!oemdrvpath.empty()) { std::string oemDir = GetFileDirectory(oemdrvpath); if (!oemDir.empty()) { addPaths.push_back(oemDir); } } // 准备环境变量修改(线程安全) static std::mutex envMutex; std::string oldLibPath; { std::lock_guard lock(envMutex); const char* envPath = getenv("LD_LIBRARY_PATH"); if (envPath) oldLibPath = envPath; if (!addPaths.empty()) { std::string newLibPath; for (const auto& path : addPaths) { if (!newLibPath.empty()) newLibPath += ":"; newLibPath += path; } if (!oldLibPath.empty()) { newLibPath += ":"; newLibPath += oldLibPath; } setenv("LD_LIBRARY_PATH", newLibPath.c_str(), 1); } } //TryGetValue(DrvConfig, "connections", m_Connection); void* DllFileHandle = dlopen(drvpath.c_str(), RTLD_LAZY); if (!DllFileHandle) { const char* dlerr = dlerror(); // PRINTA_ERROR(m_pLogger, "Load lib:%s failed. Error: %s\n", drvpath.c_str(), dlerr ? dlerr : "unknown"); } // 立即恢复环境变量 { std::lock_guard lock(envMutex); if (oldLibPath.empty()) { unsetenv("LD_LIBRARY_PATH"); } else { setenv("LD_LIBRARY_PATH", oldLibPath.c_str(), 1); } } if (DllFileHandle) { // 获取函数指针 typedef DriverDPC* (*GetDriverDPC)(); typedef void (*ReleaseDriverDPC)(DriverDPC*); GetDriverDPC dpcfunc = (GetDriverDPC)dlsym(DllFileHandle, "GetDriverDPC"); const char* dlsym_error = dlerror(); if (dlsym_error) { // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry. Error: %s\n", drvpath.c_str(), dlsym_error); dlclose(DllFileHandle); return RET_FAILED; } if (dpcfunc) { DriverDPC* pDPC = dpcfunc(); if (pDPC) { pDPC->SetDriverConfigFilePath(ConfigFile.c_str()); //m_NotifyThread.m_pDPC = m_pDPC;//init dpc notify thread if (pDPC->DriverEntry(DrvConfig)) { //读取配置,并返回 LogicDriver* pDriver = (LogicDriver*)pDPC; ResDataObject pres; //pDriver-> pDriver->GetDeviceResource(&pres); //加载配置文件 pDriver->SetDeviceConfig(resConfig); //设置驱动配置 std::cout << "ConfigDriverLoader " << resConfig->encode() << endl; ReleaseDriverDPC relfunc = (ReleaseDriverDPC)dlsym(DllFileHandle, "ReleaseDriverDPC"); if (relfunc) relfunc(pDPC); ret = RET_SUCCEED; } else { const char* dlerr = dlerror(); // PRINTA_ERROR(m_pLogger, "lib:%s Call DriverEntry Failed. Error: %s\n", drvpath.c_str(), dlerr ? dlerr : "unknown"); } } else { // PRINTA_ERROR(m_pLogger, "lib:%s no DPC Object returned\n", drvpath.c_str()); } } else { // PRINTA_ERROR(m_pLogger, "lib:%s no GetDriverDPC entry\n", drvpath.c_str()); } dlclose(DllFileHandle); } } catch (ResDataObjectExption& exp) { //exp.what() //PRINTA_ERROR(m_pLogger, exp.what()); //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str()); return RET_FAILED; } catch (...) { //PRINTA_ERROR(m_pLogger, "Unknown Exp Happened while load drvfile:%s\n", drvpath.c_str()); return RET_FAILED; } } } return ret; }