// BusUnitLogic.cpp : 定义 DLL 应用程序的导出函数。 // #include #include #include #include #include #include #include #include #include "common_api.h" #include "LocalConfig.h" #include "LogicDriver.h" #include "BusUnitLogic.h" #include "PacketAnalizer.h" #include "LogicClient.h" #include "DriverConfigManager.h" #define BusUnitGuidStr "{181F92D6-A546-4ACF-8EF1-2CCAA9EA974E}" // 这是导出变量的一个示例 BUSUNITLOGIC_API int nBusUnitLogic=0; // 这是导出函数的一个示例。 BUSUNITLOGIC_API int fnBusUnitLogic(void) { return 42; } static string CurrentDateTime2() { std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); char buf[100] = { 0 }; std::strftime(buf, sizeof(buf), " %Y-%m-%d_%H%M%S ", std::localtime(&now)); return buf; } /// /// 创建带Console显示的进程 /// /// 进程启动命令行 /// 工作路径 /// 返回进程Info /// 是否显示Console /// bool CreateTheProcess_Console_Config(const char* pfullFilePath, const char* pfullWorkPath, LinuxProcessInfo& pinfo, bool ShowWindow) { // 解析命令行参数 wordexp_t result; if (wordexp(pfullFilePath, &result, WRDE_NOCMD | WRDE_UNDEF) != 0) { return false; // 参数解析失败 } pid_t pid = fork(); if (pid < 0) { wordfree(&result); return false; // fork 失败 } // 子进程 if (pid == 0) { // 设置工作目录 if (pfullWorkPath && chdir(pfullWorkPath) != 0) { _exit(EXIT_FAILURE); } // 隐藏控制台输出 if (!ShowWindow) { int nullfd = open("/dev/null", O_RDWR); if (nullfd != -1) { dup2(nullfd, STDIN_FILENO); dup2(nullfd, STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); close(nullfd); } } // 执行程序 execvp(result.we_wordv[0], result.we_wordv); _exit(EXIT_FAILURE); // execvp 失败才会执行到这里 } // 父进程 else { wordfree(&result); pinfo.process_id = pid; // 存储子进程 PID return true; } } // 这是已导出类的构造函数。 // 有关类定义的信息,请参阅 BusUnitLogic.h BusUnitLogic::BusUnitLogic() { m_DevList = new DeviceDescriptList(); m_pCcosDevList = new DeviceDescriptList(); m_pCcosDevList->SetKey("CcosDeviceList"); m_pbusID = new BaseJsonDataObject(); m_pbusID->SetKey("BusId"); (*m_pbusID) = (const char*)getLocalEbusId(); m_pMachineID = new BaseJsonDataObject(); m_pMachineID->SetKey("MachineId"); (*m_pMachineID) = (const char*)getLocalMachineId(); m_pProcID = new BaseJsonDataObject(); m_pProcID->SetKey("ProcId"); (*m_pProcID) = (UINT64)getpid(); m_pGrpcPort = new BaseJsonDataObject(); m_pGrpcPort->SetKey("GrpcPort"); (*m_pGrpcPort) = 9000; m_pState = new BaseJsonDataObject(); m_pState->SetKey("Status"); (*m_pState) = 0; m_pExitFlag = new BaseJsonDataObject(); m_pExitFlag->SetKey("ExitFlag"); (*m_pExitFlag) = 0; m_pEnableEthBus = new BaseJsonDataObject(); m_pEnableEthBus->SetKey("EnableEthBus"); (*m_pEnableEthBus) = 0;//default is disconnect m_pEthBusRouterIp = new BaseJsonDataObject(); m_pEthBusRouterIp->SetKey("EthBusRouterIp"); (*m_pEthBusRouterIp) = (const char*)""; m_pForTest = new BaseJsonDataObject(); m_pForTest->SetKey("ForTestFlag"); (*m_pForTest) = 0;//default is 0 m_pFullDriverList = new DriverDescriptList(); m_pFullDriverList->SetKey("FullDriverList"); m_pConfigDriverList = new DriverDescriptList(); m_pConfigDriverList->SetKey("ConfigDriverList"); m_pProcessInfo = new map>(); m_bConfigRemoveDriver = false; m_DriverConfigMange = new DriverConfigManager(); bool ret = true; m_Actions.add("AddDeviceDescrpt", ""); m_Actions.add("DelDeviceDescrpt", ""); m_Actions.add("ExitDriverProc", ""); m_Actions.add("SetDeviceStatus", ""); m_Actions.add("SetEthBusSwitch", ""); m_Actions.add("SetEthBusRouterIp", ""); m_Actions.add("ForTest", ""); m_Actions.add("ConfigLoadDriver", ""); m_Actions.add("LoadAllConfigDriver", ""); m_Actions.add("ConfigRemoveDriver", ""); m_Actions.add("SubscribeTopic", ""); //DPC 订阅事件 m_Actions.add("Unsubscribe", ""); //取消订阅 m_Actions.add("GetAllConfigList",""); m_Actions.add("AddDriverConfig", ""); m_Actions.add("DelDriverConfig", ""); m_Actions.add("GetDriverConfigRes", ""); m_Actions.add("SetDriverConfigRes", ""); m_Actions.add("CheckAndKillLiveDriver", ""); } BusUnitLogic::~BusUnitLogic() { delete m_DevList; delete m_pCcosDevList; delete m_pbusID; delete m_pMachineID; delete m_pProcID; delete m_pGrpcPort; delete m_pState; delete m_pExitFlag; delete m_pEnableEthBus; delete m_pEthBusRouterIp; delete m_pForTest; delete m_pFullDriverList; delete m_pConfigDriverList; delete m_pProcessInfo; } /// /// 获取Bus单元逻辑设备的GUID类型 /// /// 返回值 /// bool SYSTEM_CALL BusUnitLogic::GetDeviceType(GUID &DevType) { return string_2_guid(BusUnitGuidStr, DevType); } /// /// 测试数据更新验证,如果值相同,则生成通知 /// /// 判定条件值 /// int DATA_ACTION BusUnitLogic::ForTest(bool Flag) { RET_STATUS ret = RET_SUCCEED; if ((*m_pForTest) != Flag) { (*m_pForTest) = Flag; ResDataObject NotifyData; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pForTest->GetKey(), m_pForTest->GetVal()); ret = CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } //get device resource /// /// 返回Bus单元逻辑设备的资源描述,这里新增了订阅Action /// /// 返回值 /// RET_STATUS SYSTEM_CALL BusUnitLogic::GetDeviceResource(ResDataObject PARAM_OUT *pDeviceResource) { bool ret = true; //make device type ret &= pDeviceResource->add("ClientType", DPC_UnitClient); ret &= pDeviceResource->add("DeviceType", BusUnitGuidStr); //make attributes ResDataObject AttrVal; AttrVal.add(m_pMachineID->GetKey(), m_pMachineID->GetVal()); AttrVal.add(m_pbusID->GetKey(), m_pbusID->GetVal()); AttrVal.add(m_pProcID->GetKey(), m_pProcID->GetVal()); AttrVal.add(m_pGrpcPort->GetKey(), m_pGrpcPort->GetVal()); AttrVal.add(m_pState->GetKey(), m_pState->GetVal()); AttrVal.add(m_pExitFlag->GetKey(), m_pExitFlag->GetVal()); AttrVal.add(m_pEnableEthBus->GetKey(), m_pEnableEthBus->GetVal()); AttrVal.add(m_pEthBusRouterIp->GetKey(), m_pEthBusRouterIp->GetVal()); AttrVal.add(m_pForTest->GetKey(), m_pForTest->GetVal()); ResDataObject arraylist; m_DevList->GetResDataObject(arraylist); AttrVal.add(m_DevList->GetKey(), arraylist); //full driver list arraylist.clear(); m_pFullDriverList->GetResDataObject(arraylist); AttrVal.add(m_pFullDriverList->GetKey(), arraylist); //ccos 设备列表 arraylist.clear(); m_pCcosDevList->GetResDataObject(arraylist); AttrVal.add(m_pCcosDevList->GetKey(), arraylist); //config driver list arraylist.clear(); m_pConfigDriverList->GetResDataObject(arraylist); AttrVal.add(m_pConfigDriverList->GetKey(), arraylist); ret &= pDeviceResource->add("Attribute", AttrVal); //Actions ResDataObject ActionVal; if (ret) { pDeviceResource->add("Action", m_Actions); return RET_SUCCEED; } return RET_FAILED; } int ProcessCcosProcConfig(string devType, string devVendor, string devProduct, string devSerilID, int& ccosProcBasePort, bool install); //ResourceCommand Request In and Response Out RET_STATUS SYSTEM_CALL BusUnitLogic::Request(ResDataObject PARAM_IN *pRequest, ResDataObject PARAM_OUT *pResponse) { ResDataObject res; RET_STATUS ret = RET_NOSUPPORT; //1. analize request PACKET_CMD cmd = PacketAnalizer::GetPacketCmd(pRequest); //cmd:get,set,add,del,exe, //ignore open/close //Action和Attr应该做成一个MAP,经过MAP访问这些资源,不应该是switch case //为了快速做一版,先保留switch case!!! string keystr = PacketAnalizer::GetPacketKey(pRequest); ACTION_SYNC_MODE syncmode = PacketAnalizer::GetPacketSyncMode(pRequest); PacketAnalizer::MakeResponseByReq(*pResponse, *pRequest, ret); //mLog::FINFO("BusUnit Request cmd [{$}] key [{$}]", (int)cmd, keystr); switch (cmd){ case PACKET_CMD_EXE: { if (keystr == "AddDeviceDescrpt") { bool result = true; ResDataObject obj1,obj2,obj3,obj4,obj5,obj6; result &= PacketAnalizer::GetParam(pRequest, 0, obj1); result &= PacketAnalizer::GetParam(pRequest, 1, obj2); result &= PacketAnalizer::GetParam(pRequest, 2, obj3); result &= PacketAnalizer::GetParam(pRequest, 3, obj4); result &= PacketAnalizer::GetParam(pRequest, 4, obj5); result &= PacketAnalizer::GetParam(pRequest, 5, obj6); if (result) { //2. call api ret = (RET_STATUS)AddDeviceDescrpt((const char *)obj1, (const char *)obj2, (const char *)obj3, (UINT64)obj4, (UINT64)obj5, (bool)obj6); } else { //put log here } } else if (keystr == "LoadAllConfigDriver") { ResDataObject resConfig; ret = (RET_STATUS)LoadAllConfigDriver(true, &resConfig); pResponse->update("CONTEXT", resConfig); } else if (keystr == "ConfigLoadDriver") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { ResDataObject value,resConfig; ResDataObject resCcosProcConf; if (!PacketAnalizer::GetParam(pRequest, 1, value)) { value = "0"; } //2. call api char szFixDrv[MAX_PATH]; memset(szFixDrv, 0, MAX_PATH); ret = (RET_STATUS)ConfigLoadDriver((const char *)obj, szFixDrv,MAX_PATH, value, resConfig, resCcosProcConf); //3. 打包 res.add("P0", szFixDrv); res.add("ConfigRes", resConfig); res.add("CcosProc", resCcosProcConf); pResponse->update("CONTEXT", res); } } else if (keystr == "ConfigRemoveDriver") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api bool bfind = false; ResDataObject DriverBusId; ResDataObject obj2,resReq,resRes; if (PacketAnalizer::GetParam(pRequest, 1, obj2)) { ResDataObject fileList; //如果有P1,则是子系统自己发的,CCOS路径 if (GetSpecificDriverConfigFiles(fileList, false)) { for (size_t i = 0; i < fileList.size(); i++) { ResDataObject BusId; //get ebus driver path if (GetDriverEbusId(fileList.GetKey(i), BusId, DriverBusId)) { //for test //mLog::FINFO("file[{$}] File:{$}\n 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() >= 6) ccosPath = ccosPath + items[1] + "/" + items[3] + "/" + items[4] + "/" + items[5]; //mLog::FINFO("file[{$}] File:{$} CcosPath:{$}\n", i, fileList.GetKey(i), ccosPath); if ( ccosPath == (const char*)obj) { bfind = true; //mLog::FINFO("Remove Driver {$} ", ccosPath); int basePort = 0; if (items.size() >= 6) ProcessCcosProcConfig(items[1], items[3], items[4], items[5], basePort, false); res.add("P0", DriverBusId); ResDataObject resConfig; resConfig.add(ccosPath.c_str(), ""); res.add("ConfigRes", resConfig); res.add("CcosProc", ""); pResponse->update("CONTEXT", res); break; } } } } if (bfind) { while (1) { //mLog::FINFO("Try Notify Channel to ConfigRemoveDriver {$}", (const char*)DriverBusId); string cltName = "RemoveDriver" + to_string(rand()); LogicClient startupClient(cltName, "", "TEMP", false); //std::function; //HANDLE hOk = CreateEvent(NULL, FALSE, FALSE, ""); if (startupClient.Open("/ccosChannel", ACTION, "", 2000, nullptr) == RET_SUCCEED) { //mLog::FINFO("Channel opened . try action. remove [{$}]", (const char*)DriverBusId); resReq.add("P0", (const char*)DriverBusId); startupClient.Action("ConfigRemoveDriver", resReq, resRes, 2000, "ccosChannel"); //mLog::FINFO("Channel Action ret ={$}. with resp {$}", (int)ret, resRes.encode()); //PacketAnalizer::UpdatePacketContext((*pResponse), resRes); startupClient.Close(); ret = RET_SUCCEED; break; } else { //mLog::FERROR("Open Channel failed. for {$} try again...", (const char*)DriverBusId); } } } } else { //mLog::FINFO("Real ConfigRemoveDriver {$}", (const char*)obj); ret = (RET_STATUS)ConfigRemoveDriver((const char *)obj); } //3. 打包 } } else if (keystr == "DelDeviceDescrpt") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = (RET_STATUS)DelDeviceDescrpt((const char *)obj); //3. 打包 } } else if (keystr == "ExitDriverProc") { ret = (RET_STATUS)ExitDriverProc(); } else if (keystr == "CheckAndKillLiveDriver") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { if (CheckAndKillLiveDriver((const char*)obj, false)) ret = RET_SUCCEED; else ret = RET_FAILED; } } else if (keystr == "SetDeviceStatus") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = (RET_STATUS)SetDeviceStatus((int)obj); //3. 打包 } } else if (keystr == "SetEthBusSwitch") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = (RET_STATUS)SetEthBusSwitch((int)obj); //3. 打包 } } else if (keystr == "SetEthBusRouterIp") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = (RET_STATUS)SetEthBusRouterIp((const char*)obj); //3. 打包 } } else if (keystr == "Get") { //1. 获取参数 ResDataObject Res; ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = (RET_STATUS)Get((const char*)obj,Res); //3. 打包 if (ret == RET_SUCCEED) { PacketAnalizer::UpdatePacketContext((*pResponse), Res); } } } else if (keystr == "ForTest") { ResDataObject Res; ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = (RET_STATUS)ForTest((bool)obj); } } else if (keystr == "SubscribeTopic") { // 收到 应用或者其他模块的 订阅消息 // 往MQTT broker 里订阅 } else if (keystr == "GetAllConfigList") { //int (ResDataObject& resAll); //RET_STATUS (const char* pszDevPath, ResDataObject& resNewDevPath); //RET_STATUS (const char* pszDevPath); //int (const char* pszDevPath, ResDataObject& resConfig); //int (const char* pszDevPath, ResDataObject* resConfig); ResDataObject resAll; m_DriverConfigMange->GetAllConfigList(resAll); ret = RET_SUCCEED; res.update("P0", resAll); pResponse->update("CONTEXT", res); } else if (keystr == "AddDriverConfig") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ResDataObject real; ret = m_DriverConfigMange->AddDriverConfig((const char*)obj, real); //3. 打包 res.update("P0", real); pResponse->update("CONTEXT", res); } } else if (keystr == "DelDriverConfig") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ret = m_DriverConfigMange->DelDriverConfig((const char*)obj); } } else if (keystr == "GetDriverConfigRes") { //1. 获取参数 ResDataObject obj; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { //2. call api ResDataObject resConfig; ret = m_DriverConfigMange->GetDriverConfigRes((const char*)obj, resConfig); //3. 打包 res.update("P0", resConfig); pResponse->update("CONTEXT", res); } } else if (keystr == "SetDriverConfigRes") { ResDataObject obj, resConfig; if (PacketAnalizer::GetParam(pRequest, 0, obj)) { if (PacketAnalizer::GetParam(pRequest, 1, resConfig)) { //2. call api ret = m_DriverConfigMange->SetDriverConfigRes((const char*)obj, &resConfig) ; //3. 打包 //res.update("P0", resConfig); //pResponse->update("CONTEXT", res); } } } } break; default: //对当前设备来讲,其他都是浮云 break; } //return status PacketAnalizer::MakeRetCode(ret, pResponse); return ret; } RET_STATUS BusUnitLogic::ProcessRequest(ResDataObject* pCmd, PACKET_CMD cmd) { ResDataObject resRes, resResponse; ResDataObject resTopic; PacketAnalizer::GetContextTopic(pCmd, resTopic); if (cmd == PACKET_CMD_OPEN ) { GetDeviceResource(&resRes); PacketAnalizer::MakeOpenResponse(*pCmd, resResponse, resRes); PacketAnalizer::UpdateDeviceNotifyResponse(resResponse, getLocalMachineId(), getLocalEbusId(), (UINT64)getpid(), (UINT64)m_pMqttConntion); std::cout << "TID [" << GetCurrentThreadId() << "] BusUnitLogic:: PACKET_CMD_OPEN [" << (const char*)resTopic << "] " << "msg body" << resResponse.encode() << endl; // PacketAnalizer::UpdatePacketTopic(&resResponse, (const char*)resTopic, m_strClientID.c_str()); PublishAction(&resResponse, (const char*)resTopic, m_pMqttConntion); //m_pPacketSendingQue->InQueue(resResponse); return RET_SUCCEED; } if (cmd == PACKET_CMD_CLOSE) { //CLOSE 客户端主动断开 } RET_STATUS ret = Request(pCmd, &resResponse); //PacketAnalizer::GetPacketRetCode(&resResponse, ret); std::cout << "BusUnitLogic::ProcessRequest get resp" << resResponse.encode() << endl; std::cout << "BusUnitLogic::ProcessRequest return by [" << (const char*)resTopic << "] resp" << resResponse.encode() << endl; PacketAnalizer::UpdatePacketTopic(&resResponse, (const char*)resTopic, m_strClientID.c_str()); PublishAction(&resResponse, (const char*)resTopic, m_pMqttConntion); //m_pPacketSendingQue->InQueue(resResponse); return ret; } //notify to lower layer RET_STATUS SYSTEM_CALL BusUnitLogic::CmdToLogicDev(ResDataObject PARAM_IN *pCmd) { assert(0);//not happening return RET_FAILED; } //errors,warnings void BusUnitLogic::SetErrorInfo(int errCode, char *pErrInfo) { } void BusUnitLogic::SetWarningInfo(int warningCode, char *pWarningInfo) { } bool SYSTEM_CALL BusUnitLogic::CheckBusIdsExistance(const char *pszBusId) { //ResDataObject ConfigDrvList; //GetDriverConfigFiles(ConfigDrvList); //map HitCheck; ////check static first //for (size_t i = 0; i < ConfigDrvList.size(); i++) //{ // ResDataObject BusId; // ResDataObject DriverBusId; // if (GetDriverEbusId(ConfigDrvList.GetKey(i), BusId, DriverBusId)) // { // map::iterator iter = HitCheck.find((const char*)BusId); // if (iter != HitCheck.end()) // { // //exist one // //mLog::Warn("Same BusId:%s on both Driver\nDrvA:%s\nDrvB:%s", (const char*)BusId, ConfigDrvList.GetKey(i), iter->second.c_str()); // } // HitCheck[(const char*)BusId] = ConfigDrvList.GetKey(i); // if (pszBusId) // { // iter = HitCheck.find(pszBusId); // if (iter != HitCheck.end()) // { // //exist one // //mLog::Warn("Same BusId:%s on Driver\nDrv:%s\nRequest BusId:%s", (const char*)BusId, ConfigDrvList.GetKey(i), pszBusId); // } // } // } //} if (pszBusId) { //check live second map>::iterator iter = m_pProcessInfo->begin(); while (iter != m_pProcessInfo->end()) { if (iter->first == pszBusId) { //mLog::Warn("Same BusId:{$} Already on the run...", pszBusId); return false; } ++iter; } } return true; } bool SYSTEM_CALL BusUnitLogic::LoadAllConfigDrivers() { bool ret = true; //get list of fulldrvlist ResDataObject FullDrvList; GetFullDriverConfigFiles(FullDrvList); //get list of configdrvlist ResDataObject ConfigDrvList; GetDriverConfigFiles(ConfigDrvList); if (CheckBusIdsExistance(0) == false) { return false; } //add second for (size_t i = 0; i < FullDrvList.size(); i++) { ResDataObject BusId; ResDataObject DriverBusId; //get ebus driver path if (GetDriverEbusId(FullDrvList.GetKey(i), BusId, DriverBusId)) { ret &= m_pFullDriverList->AddDriver(DriverBusId); if (ret == false) { //mLog::FERROR("AddDriver of FullDrv:{$} Failed.", FullDrvList.GetKey(i)); } } else { //mLog::FERROR("GetDriverEbusId configfile:{$} Failed.", FullDrvList.GetKey(i)); } } for (size_t i = 0; i < ConfigDrvList.size(); i++) { ResDataObject BusId; ResDataObject DriverBusId; if (GetDriverEbusId(ConfigDrvList.GetKey(i), BusId, DriverBusId)) { ret &= m_pConfigDriverList->AddDriver(DriverBusId); if (ret == false) { //mLog::FERROR("AddDriver of ConfigDrv:{$} Failed.", ConfigDrvList.GetKey(i)); } } else { //mLog::FERROR("GetDriverEbusId configfile:{$} Failed.", ConfigDrvList.GetKey(i)); } } return ret; } std::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); } int DATA_ACTION BusUnitLogic::MakeDriverNotify(const char *pszDriverpath, bool Add) { RET_STATUS ret = RET_SUCCEED; //exiting... if ((*m_pExitFlag) != 0) { return RET_INVALID; } ResDataObject NotifyData; ResDataObject theContext; theContext.add(pszDriverpath, ""); if (Add) { if (m_pConfigDriverList->AddDriver(pszDriverpath)) { //printf("AddDriver %s ok\n", pszDriverpath); //mLog::FINFO("AddDriver {$} ok\n", pszDriverpath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ADD, m_pConfigDriverList->GetKey(), theContext); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } else { //printf("AddDriver %s failed\n", pszDriverpath); //mLog::FERROR("AddDriver {$} failed\n", pszDriverpath); ret = RET_FAILED; } } else { if (m_pConfigDriverList->DelDriver(pszDriverpath)) { //printf("DelDriver %s ok\n", pszDriverpath); //mLog::FINFO("DelDriver {$} ok\n", pszDriverpath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_DEL, m_pConfigDriverList->GetKey(), theContext); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } else { //printf("DelDriver %s failed\n", pszDriverpath); //mLog::FERROR("DelDriver {$} failed\n", pszDriverpath); ret = RET_FAILED; } } return ret; } int GetGrpcPort() { int port = 9000; //Detector_ecomdemo_demo_1234.json if (GetConfigMode() == CCOS_PROC_CHANNEL) return port; string devType = GetMajorID(); string major,type; size_t pos = devType.find_first_of('_'); if (pos != string::npos) { major = devType.substr(0, pos); type = devType.substr(pos + 1); if (major.length() > 0 && type.length() > 0) { try { ResDataObject resSrvConf; string ccosDir = GetProcessDirectory(); ccosDir += "\\srvconf.json"; resSrvConf.loadFile(ccosDir.c_str()); if (resSrvConf.GetKeyCount("PortMap") > 0) { for (int x = 0; x < resSrvConf["PortMap"].size(); x++) { if ((string)resSrvConf["PortMap"][x]["Type"] == major) { int y = 0, idx; int ccosProcBasePort = (int)resSrvConf["PortMap"][x]["RPCPort"]; for (; y < resSrvConf["PortMap"][x]["ProcMap"].size(); y++) { idx = (int)resSrvConf["PortMap"][x]["ProcMap"][y]["Index"]; if ((string)resSrvConf["PortMap"][x]["ProcMap"][y]["Name"] == type) { //got it if (idx == -1) idx = 0; //mLog::FINFO("Got config for {$} port index {$} at srvconf.json",devType, idx); return ccosProcBasePort + 2 * idx; } } return ccosProcBasePort; } } } } catch (...) { } } } //mLog::FWARN("No found portmap for {$}", devType); return port; } int ProcessCcosProcConfig(string devType, string devVendor, string devProduct, string devSerilID, int &ccosProcBasePort, bool install) { string ccosDir = GetProcessDirectory(); ccosDir += "\\srvconf.json"; //mLog::FINFO("Try scan {$} for ccosproc portmap configration by {$}:{$}:{$} for {$}", ccosDir, devType, devVendor, devProduct, install?"install":"uninstall"); ResDataObject resConf; try { resConf.loadFile(ccosDir.c_str()); bool bFind = false; string findName = devVendor + "_" + devProduct + "_" + devSerilID; if (resConf.GetKeyCount("PortMap") > 0) { for (int x = 0; x < resConf["PortMap"].size(); x++) { if ((string)resConf["PortMap"][x]["Type"] == devType) { int y = 0, idx; int maxPort = 0; ccosProcBasePort = (int)resConf["PortMap"][x]["HTTPPort"]; for (; y < resConf["PortMap"][x]["ProcMap"].size(); y++) { idx = (int)resConf["PortMap"][x]["ProcMap"][y]["Index"]; if (idx > maxPort) maxPort = idx; if ((string)resConf["PortMap"][x]["ProcMap"][y]["Name"] == findName|| (string)resConf["PortMap"][x]["ProcMap"][y]["Name"] == "Default") { bFind = true; //got it //mLog::FINFO("Got config port index {$} at srvconf.json", idx); break; } } if (install && !bFind) { //需要添加 ResDataObject newconf; newconf.add("Name", findName.c_str()); newconf.add("Index", maxPort + 1 ); resConf["PortMap"][x]["ProcMap"].add("", newconf); //mLog::FINFO("Not found at srvconf for {$} add conf {$}", findName, newconf.encode()); resConf.SaveFile(ccosDir.c_str()); return maxPort + 1; } else if (install && bFind) { //已经有这个配置了,直接返回即可 if (idx == -1) { maxPort = 0; resConf["PortMap"][x]["ProcMap"].eraseOneOf("", 0); ResDataObject newconf; newconf.add("Name", findName.c_str()); newconf.add("Index", maxPort ); resConf["PortMap"][x]["ProcMap"].add("", newconf); //mLog::FINFO("Not found at srvconf for {$} add conf {$}", findName, newconf.encode()); resConf.SaveFile(ccosDir.c_str()); return maxPort; } //mLog::FINFO("found port=[{$}] at srvconf for {$} add conf ",maxPort, findName); return maxPort ; } else if(!install && bFind) { //需要卸载 resConf["PortMap"][x]["ProcMap"].eraseOneOf("", y); if (resConf["PortMap"][x]["ProcMap"].size() <= 0) { ResDataObject defut; defut.add("Name", "Default"); defut.add("Index", "-1"); resConf["PortMap"][x]["ProcMap"].add("", defut); } //mLog::FINFO("uninstall found index={$} at srvconf for {$} ", y, findName); resConf.SaveFile(ccosDir.c_str()); return y; } else { //mLog::FINFO("?? install=[{$}] found={$} index={$} at srvconf for {$} ", install, bFind, findName); } } } } } catch (...) { } //mLog::FINFO("INSTALL Driver had no right port"); return -1; } void TrimeSDKPath(string& sdkPath) { if (sdkPath.length() > 0) { if (sdkPath[0] == '\\' || sdkPath[0] == '/') sdkPath = sdkPath.substr(1); if (sdkPath.length() > 0) { if (sdkPath[sdkPath.length() - 1] == '\\' || sdkPath[sdkPath.length() - 1] == '/') { sdkPath = sdkPath.substr(0, sdkPath.length() - 1); } } } } string GetSDKPath(const char* pszDriverPath, int &nServerIdx) { string sdkPath; nServerIdx = -1; try { ResDataObject resCtx; resCtx.loadFile(pszDriverPath); if (resCtx.GetKeyCount("CONFIGURATION") <= 0) return ""; if (resCtx["CONFIGURATION"].GetKeyCount("SDKPath") <= 0) { return ""; } sdkPath = (const char*)resCtx["CONFIGURATION"]["SDKPath"]; TrimeSDKPath(sdkPath); if (resCtx["CONFIGURATION"].GetKeyCount("ServerID") > 0) { nServerIdx = (int)resCtx["CONFIGURATION"]["ServerID"]; } } catch (...) { } return sdkPath; } int CheckDuplicateSDK(const char* pszDriverPath) { int nCount = 0; ResDataObject resCtx; try { resCtx.loadFile(pszDriverPath); if (resCtx.GetKeyCount("CONFIGURATION") <= 0) { //mLog::FWARN("Driver {$} content no CONFIGURATION", pszDriverPath); return 0; } ResDataObject conf = resCtx["CONFIGURATION"]; string sdkPath; if (conf.GetKeyCount("SDKPath") <= 0) { //mLog::FDEBUG("Driver {$} content no SDKPath", pszDriverPath); return 0; } sdkPath = (const char*)conf["SDKPath"]; TrimeSDKPath(sdkPath); ResDataObject fileList; GetSpecificDriverConfigFiles(fileList, false); int idx[100], max = -1; //mLog::FINFO("Include Driver {$} Has {$} Devices", pszDriverPath, fileList.size()); for (int x = 0; x < fileList.size(); x++) { int nSrvIdx = -1; string dvrSDKPath = GetSDKPath(fileList.GetKey(x), nSrvIdx); //get ebus driver path idx[x] = -1; if (dvrSDKPath.length() > 0) { if (dvrSDKPath.substr(0, sdkPath.length()) == sdkPath) { //mLog::FINFO("Got Same SDK path of Driver {$} at Devices{$} of ServerIdx=[{$}]", pszDriverPath, fileList.GetKey(x), nSrvIdx); idx[x] = nSrvIdx; if (nSrvIdx > max) max = nSrvIdx; nCount++; } } } //没有洞 if (nCount == max + 2) { //mLog::FINFO("Driver {$} SDK Installed Sorted of mine index=[{$}]", pszDriverPath, nCount); resCtx["CONFIGURATION"].update("ServerID", nCount - 1); resCtx.SaveFile(pszDriverPath); return nCount - 1; } // sort(idx, idx + fileList.size() - 1); //肯定有-1, ImageSave/Demo设备/子系统等等 for (int x = 1; x < fileList.size(); x++) { if (idx[x] >= 0) { if ((idx[x] - idx[x - 1]) > 1) { //mLog::FINFO("Driver {$} SDK Installed unSorted ; Got mine index=[{$}]", pszDriverPath, idx[x - 1] + 1); //这里有洞,取洞的下一个值 resCtx["CONFIGURATION"].update("ServerID", idx[x - 1] + 1); resCtx.SaveFile(pszDriverPath); return idx[x-1] + 1; } } } //mLog::FINFO("Driver {$} SDK Installed Sorted 2 of mine index=[{$}]", pszDriverPath, nCount); resCtx["CONFIGURATION"].update("ServerID", nCount - 1); resCtx.SaveFile(pszDriverPath); return nCount - 1; } catch (...) { //mLog::FWARN("Driver {$} Configruation read content error", pszDriverPath); return 0; } } int DATA_ACTION BusUnitLogic::ConfigLoadDriver(const char *pszDriverpath, char *pszFixDriverpath, DWORD FixDrvLen, ResDataObject resValue, ResDataObject& resConfig, ResDataObject& resCcosProcConf) { int ret = RET_SUCCEED; bool X64Driver = true; ResDataObject fileList; //find driver from fulldrvlist //for test //mLog::FINFO("Enter ConfigLoadDriver:{$}\n", pszDriverpath); LogicDriver* pDPC = (LogicDriver*)GetDrvDPC(); if (pDPC == 0) { //mLog::FINFO("GetDrvDPC failed"); return RET_FAILED; } m_bConfigRemoveDriver = true; pDPC->Thread_Lock(2000); //mLog::FINFO("DPC lock ok"); //find x64 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:{$}\n 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) { 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 = GetProcessDirectory(); //GetFileDirectory(FullFilePath);//...\FullConfig //DriverConfigPath = GetFileDirectory(DriverConfigPath);//...procDir 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; if (GetDriverEbusId(FullNewTargetFilePath.c_str(), DrvInfo.m_RootBusId, DrvInfo.m_DriverBusId, true) == false) { return RET_FAILED; } items.clear(); SplitDevicePath((const char*)DrvInfo.m_DriverBusId, items); //这个时候item还在 //刷新端口 int newPort = -1; int basePort = 9001; if (items.size() >= 6) newPort = ProcessCcosProcConfig(items[1], items[3], items[4], items[5], basePort, true); if (ccosPath == pszDriverpath) { ///DevPSGRF/Generator/Dr/PSGRF/HF/05274E0D/{18FDF176-DECE-445F-A52C-A14BDD3AC2C1} vector idItems; SplitDevicePath((const char*)DrvInfo.m_DriverBusId, idItems); if (idItems.size() > 5) { ccosPath += "/"; ccosPath += idItems[5]; } //mLog::FINFO("Got new devPath {$} transfer to ccos path {$}", (const char*)DrvInfo.m_DriverBusId, ccosPath); //resNewDevPath = ccosPath.c_str(); } //got match if (CheckBusIdsExistance(DrvInfo.m_RootBusId) == false) { //exist bus id UnloadDriver(DrvInfo.m_RootBusId); } //reload //检查重复的SDK目录 CheckDuplicateSDK(FullNewTargetFilePath.c_str()); if ((int)resValue != 2) { resConfig.clear(); if ((int)resValue == 1) { ret = LoadAllConfigDriver(true, &resConfig); } else { ret = LoadAllConfigDriver(true); usleep(6000000);//must sleep 6s } } else { //mLog::FINFO("Notify Channel to startup the new driver proc."); //等于2的时候,不启进程,让Channel 启动进程 //std::function; //HANDLE hOk = CreateEvent(NULL, FALSE, FALSE, ""); while (1) { //mLog::FINFO("Try Notify Channel to LoadAllConfigDriver "); LogicClient startupClient("LoadConfigDriver_" + to_string(rand()), "", "TEMP", false); if (startupClient.Open("/ccosChannel", ACTION, "", 2000, nullptr) == RET_SUCCEED) { //mLog::FINFO("Channel opened . try action."); ResDataObject resReq,resRes; int ret = startupClient.Action("LoadAllConfigDriver", resReq, resRes, 2000, "ccosChannel"); //mLog::FINFO("Channel Action ret ={$}. with resp {$}", ret, resRes.encode()); startupClient.Close(); break; } else { //mLog::FERROR("Open Channel failed for {$} try again.", ccosPath); } } resConfig.clear(); resConfig.update(ccosPath.c_str(), basePort + newPort * 2); basePort; } if (ret >= RET_SUCCEED) { snprintf(pszFixDriverpath, FixDrvLen, "%s", DrvInfo.m_DriverBusId.encode()); } //mLog::FINFO("LoadAllConfigDriver return:{$}\n", ret); m_bConfigRemoveDriver = false; pDPC->Thread_UnLock(); //mLog::FINFO("DPC Unlock ok"); return ret; } else { //mLog::FERROR("CopyFile failed\n"); } } } else { //mLog::FERROR("GetDriverEbusId failed\n"); } } } else { //mLog::FERROR("GetSpecificDriverConfigFiles failed\n"); } pDPC->Thread_UnLock(); //mLog::FINFO("DPC Unlock ok"); m_bConfigRemoveDriver = false; return RET_SUCCEED; } bool SYSTEM_CALL BusUnitLogic::CheckAndKillLiveDriver(const char *pszDriverpath, bool bRemoveDriver) { //printf("Try Del Driver:%s\n", pszDriverpath); //mLog::FINFO("Try Del Driver:{$}\n", pszDriverpath); map>::iterator iter = m_pProcessInfo->begin(); while (iter != m_pProcessInfo->end()) { for (size_t DriverIdx = 0; DriverIdx < iter->second.size(); DriverIdx++) { string DrvBusId = (const char*)(iter->second)[DriverIdx].m_DriverBusId; //mLog::FINFO("Test Match:{$}\n", DrvBusId.c_str()); if (DrvBusId == pszDriverpath) { //mLog::FINFO("Got Match:{$}\n", DrvBusId.c_str()); //got one pid_t targetPid = iter->second[DriverIdx].m_info.process_id; if (kill(targetPid, 0) == 0) { //process exist //mLog::FINFO("Target Process Exist"); string strBusIdCopy = DrvBusId; LogicClient chClient1("CheckAndKillLiveDriver_temp","driver", "", false); chClient1.SetRouter(CCOS_PACKET_ROUTE_LOCAL); DrvBusId = "/"; DrvBusId += iter->first.c_str(); ////mLog::FINFO("DrvBusId :{$}\n", DrvBusId.c_str()); //mLog::FINFO("open :{$}\n", strBusIdCopy.c_str()); int nRet = -1; if (chClient1.Open(strBusIdCopy.c_str(), ALL_ACCESS, "", ONE_ACTION_TIMEOUT) >= RET_SUCCEED) { //if (strBusIdCopy.find("Detector"))//disconnect before Del //{ // bool bret = false; // ACTION_SYNC_MODE syncmode = chClient1.GetRequestSyncMode(); // //mLog::FINFO("RequestSyncMode is {$}\n",syncmode); // if (syncmode != ACTION_SYNC) // { // bret = chClient1.SetRequestSyncMode(ACTION_SYNC); // //mLog::FINFO("SetRequestSyncMode to sync\n"); // } // ResDataObject req, resp; // int nRet = chClient1.Action("DisConnect", req, resp, ONE_ACTION_TIMEOUT); // if (nRet >= RET_SUCCEED) // { // //mLog::FINFO("Succeed Action: DisConnect\n"); // Sleep(2000);//wait detector finish the disconnect.UI send cmd wait 3s // } // else // { // //mLog::FINFO("Failed Action: DisConnect ret = {$}\n", nRet); // } // if (bret) // { // chClient1.SetRequestSyncMode(syncmode); // //mLog::FINFO("SetRequestSyncMode back\n"); // } //} ResDataObject req; nRet = chClient1.Action_Req("ExitDriverProc", req, ONE_ACTION_TIMEOUT); if (nRet >= RET_SUCCEED) { chClient1.Close(); // 等待进程退出 int waitCount = 0; const int maxWait = ONE_ACTION_TIMEOUT / 100; // 转换为100ms单位 while (waitCount < maxWait) { if (kill(targetPid, 0) != 0 && errno == ESRCH) { break; // 进程已退出 } usleep(100 * 1000); // 100ms waitCount++; } // 超时后强制终止 if (kill(targetPid, 0) == 0) { kill(targetPid, SIGKILL); } if (bRemoveDriver) { const char* configPath = (const char*)(iter->second)[DriverIdx].m_CcosProcInfo["DriverConfigPath"]; if (unlink(configPath) == 0) { iter->second.erase(iter->second.begin() + DriverIdx); if (iter->second.empty()) { iter = m_pProcessInfo->erase(iter); } else { ++iter; } return true; } else { int err = errno; // 记录错误信息 } } else { if (iter->second.empty()) { iter = m_pProcessInfo->erase(iter); } else { ++iter; } return true; } } else { //printf("Failed Action:ExitDriverProc -> %s...\n", strBusIdCopy.c_str()); ////mLog::FERROR("Failed Action: ExitDriverProc -> %s ...\n", strBusIdCopy.c_str()); //mLog::FINFO("Failed Action: ExitDriverProc ret {$}-> {$} ...\n",nRet, strBusIdCopy.c_str()); chClient1.Close(); } //if (chClient1.Action(pszAction, req, res, Timeout) < RET_SUCCEED) //{ // printf("Failed Action:%s ...\n",pszAction); // //mLog::FERROR("Failed Action: {$} ...\n", pszAction); // chClient1.Close(); //} //else //{ // printf("Succeed Action:%s ...\n", pszAction); // //mLog::FINFO("Succeed Action: {$} ...\n", pszAction); // return true; //} //chClient1.Close(); } else { //printf("Open local %s Failed\n", DrvBusId.c_str()); //mLog::FINFO("Open local {$} Failed ret {$}\n", strBusIdCopy.c_str(),nRet); } } else { //mLog::FINFO("Target Process Not Exist"); //mLog::FINFO("Try Delete Driver File:{$}\n", (const char*)(iter->second)[DriverIdx].m_CcosProcInfo["DriverConfigPath"]); if (bRemoveDriver) { const char* configPath = (const char*)(iter->second)[DriverIdx].m_CcosProcInfo["DriverConfigPath"]; if (unlink(configPath) == 0) { iter->second.erase(iter->second.begin() + DriverIdx); if (iter->second.empty()) { iter = m_pProcessInfo->erase(iter); } else { ++iter; } return true; } } else { //mLog::FINFO("Do nothing"); return true; } } return false; } } ++iter; } return true; } int DATA_ACTION BusUnitLogic::ConfigRemoveDriver(const char *pszDriverpath) { int ret = RET_SUCCEED; //mLog::FINFO("Enter ConfigRemoveDriver:{$}\n", pszDriverpath); //find driver from configdrvlist if (m_pConfigDriverList->IsDriverExist(pszDriverpath) == false) { //not exist then return succeed. //mLog::FINFO("Target Driver Not Exist {$}",pszDriverpath); return RET_FAILED; } LogicDriver* pDPC = (LogicDriver*)GetDrvDPC(); if (pDPC == 0) { //mLog::FINFO("GetDrvDPC failed"); return RET_FAILED; } m_bConfigRemoveDriver = true; pDPC->Thread_Lock(3000); //mLog::FINFO("DPC lock ok"); try{ //check Live status if (CheckAndKillLiveDriver(pszDriverpath)) { ret = MakeDriverNotify(pszDriverpath, false); //reload ret = LoadAllConfigDriver(true); usleep(6000000);//must sleep 6s //mLog::FINFO("sleep over"); } else { ret = RET_FAILED; } } catch (...) { ret = RET_FAILED; //mLog::FINFO("crash"); } pDPC->Thread_UnLock(); //mLog::FINFO("DPC Unlock ok"); m_bConfigRemoveDriver = false; //mLog::FINFO("ConfigRemoveDriver over"); return ret; } //Data Access int DATA_ACTION BusUnitLogic::AddDeviceDescrpt(const char PARAM_IN *pDevPath, const char PARAM_IN *pTargetType, const char PARAM_IN *pMachineId, UINT64 ProcId, UINT64 Addr, bool forceAdd) { DeviceDescript dd; //mLog::FINFO("Begin with DevPath={$} TargetType={$} MachineID={$} ProcID={$} Addr={$} ForceAd={$}", pDevPath, pTargetType, pMachineId, ProcId, Addr, forceAdd); //exiting... if ((*m_pExitFlag) != 0) { //mLog::FINFO("End with ExitFlag {$}", (int)(*m_pExitFlag)); return RET_INVALID; } dd.SetKey(pDevPath); dd.m_TargetType = pTargetType; dd.m_ProcId = ProcId; dd.m_Address = Addr; dd.m_MachineId = pMachineId; ResDataObject NotifyData; ResDataObject theContext; dd.GetResDataObject(theContext); if(pDevPath[0] == '/') { //mLog::FINFO("Ebus Path {$}", pDevPath); if (m_DevList->AddDriver(dd)) { //mLog::FINFO("AddDriver ok {$}", pDevPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ADD, m_DevList->GetKey(), theContext); } else { //mLog::FERROR("AddDriver Failed {$}", pDevPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ONLINE, m_DevList->GetKey(), theContext); } //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } else { //ccos 的Key //mLog::FINFO("CCOS Path {$}", pDevPath); if (m_pCcosDevList->AddDriver(dd)) { //mLog::FINFO("AddDriver ok {$}", pDevPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ADD, m_pCcosDevList->GetKey(), theContext); } else { //mLog::FERROR("AddDriver Failed {$}", pDevPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_ONLINE, m_pCcosDevList->GetKey(), theContext); } //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } CmdFromLogicDev(&NotifyData); return RET_SUCCEED; } int DATA_ACTION BusUnitLogic::Get(const char PARAM_IN *pKey,ResDataObject &Res) { string Key = pKey; if (Key == m_DevList->GetKey()) { ResDataObject arraylist; m_DevList->GetResDataObject(arraylist); Res.add(m_DevList->GetKey(), arraylist); return RET_SUCCEED; } return RET_FAILED; } int DATA_ACTION BusUnitLogic::DelDeviceDescrpt(const char PARAM_IN *pDevPath) { if(pDevPath[0] == '/') { if (m_DevList->DelVal(pDevPath)) { //3. Notify ResDataObject NotifyData; ResDataObject theContext; theContext.add("DevicePath", pDevPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_DEL, m_DevList->GetKey(), theContext); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } } else { if (m_pCcosDevList->DelVal(pDevPath)) { //3. Notify ResDataObject NotifyData; ResDataObject theContext; theContext.add("DevicePath", pDevPath); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_DEL, m_pCcosDevList->GetKey(), theContext); CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } } return RET_SUCCEED; } int DATA_ACTION BusUnitLogic::SetDeviceStatus(int Status) { RET_STATUS ret = RET_SUCCEED; if ((*m_pState) != Status) { ResDataObject NotifyData; (*m_pState) = Status; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pState->GetKey(), m_pState->GetVal()); ret = CmdFromLogicDev(&NotifyData); //string notfiyTopic = m_strEBusRoot + "/Notify"; //PublishAction(&NotifyData, notfiyTopic.c_str() , m_pMqttConntion); } return ret; } int DATA_ACTION BusUnitLogic::SetEthBusSwitch(int Switch) { RET_STATUS ret = RET_SUCCEED; if ((*m_pEnableEthBus) != Switch) { ResDataObject NotifyData; (*m_pEnableEthBus) = Switch; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pEnableEthBus->GetKey(), m_pEnableEthBus->GetVal()); ret = CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } int DATA_ACTION BusUnitLogic::SetEthBusRouterIp(const char PARAM_IN *pRouterIp) { RET_STATUS ret = RET_SUCCEED; std::string Param = pRouterIp; std::string RouterIp = (*m_pEthBusRouterIp); if (RouterIp != Param) { ResDataObject NotifyData; (*m_pEthBusRouterIp) = Param; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pEthBusRouterIp->GetKey(), m_pEthBusRouterIp->GetVal()); ret = CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } int DATA_ACTION BusUnitLogic::ExitDriverProc() { RET_STATUS ret = RET_SUCCEED; if ((*m_pExitFlag) == 0) { ResDataObject NotifyData; SetExitFlag(1); PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pExitFlag->GetKey(), m_pExitFlag->GetVal()); ret = CmdFromLogicDev(&NotifyData); //PublishAction(&NotifyData, (m_strEBusRoot + "/Notify").c_str(), m_pMqttConntion); } return ret; } int SYSTEM_CALL BusUnitLogic::GetExitFlag() { return (*m_pExitFlag); } int SYSTEM_CALL BusUnitLogic::SetExitFlag(int ExitFlag) { (*m_pExitFlag) = ExitFlag; return 1; } int SYSTEM_CALL BusUnitLogic::GetbusId(ResDataObject &obj) { obj = m_pbusID->GetVal(); return RET_SUCCEED; } int SYSTEM_CALL BusUnitLogic::GetMachineId(ResDataObject &obj) { obj = m_pMachineID->GetVal(); return RET_SUCCEED; } int SYSTEM_CALL BusUnitLogic::GetProcId(UINT64 &obj) { obj = (*m_pProcID); return RET_SUCCEED; } int SYSTEM_CALL BusUnitLogic::SetbusId(ResDataObject &obj) { (*m_pbusID) = (const char *)obj; return RET_SUCCEED; } int SYSTEM_CALL BusUnitLogic::SetMachineId(ResDataObject &obj) { (*m_pMachineID) = (const char *)obj; return RET_SUCCEED; } int SYSTEM_CALL BusUnitLogic::SetProcId(UINT64 obj) { (*m_pProcID) = (UINT64)obj; return RET_SUCCEED; } DWORD SYSTEM_CALL BusUnitLogic::GetDeviceCount() { return (DWORD)m_DevList->m_DeviceList.size(); } bool SYSTEM_CALL BusUnitLogic::GetDeviceDescript(DWORD Idx, ResDataObject &DevPath, ResDataObject &DevType, ResDataObject &MachineId, UINT64 &ProcId, UINT64 &Addr) { if (m_DevList->m_DeviceList.size() > Idx) { DevPath = m_DevList->m_DeviceList[Idx].GetKey(); DevType = m_DevList->m_DeviceList[Idx].m_TargetType.GetVal(); MachineId = m_DevList->m_DeviceList[Idx].m_MachineId.GetVal(); ProcId = m_DevList->m_DeviceList[Idx].m_ProcId; Addr = m_DevList->m_DeviceList[Idx].m_Address; return true; } return false; } int SYSTEM_CALL BusUnitLogic::GetDeviceStatus() { return (*m_pState); } int SYSTEM_CALL BusUnitLogic::GetEthBusSwitch() { return (*m_pEnableEthBus); } int SYSTEM_CALL BusUnitLogic::GetEthBusRouterIp(ResDataObject &obj) { obj = (*m_pEthBusRouterIp).GetVal(); return 1; } /// /// 检查所有驱动进程,如果进程Crash了,需要根据配置重新拉起来 /// /// void SYSTEM_CALL BusUnitLogic::CheckAllLiveDriver() { map>::iterator iter = m_pProcessInfo->begin(); while (iter != m_pProcessInfo->end()) { if (m_bConfigRemoveDriver) { //Sleep(2000); //mLog::FINFO("ConfigDriver working"); return; } //for (size_t DriverIdx = 0; DriverIdx < iter->second.size(); DriverIdx++) { string DrvBusId = "/"; DrvBusId += (const char*)iter->first.c_str(); { //got one pid_t targetPid = iter->second[0].m_info.process_id; if (kill(targetPid, 0) == 0) { //process exist LogicClient chClient1("CheckAllLiveDriver_temp","driver","",false); chClient1.SetRouter(CCOS_PACKET_ROUTE_LOCAL); if (chClient1.Open(DrvBusId.c_str(), ALL_ACCESS, "", ONE_ACTION_TIMEOUT) >= RET_SUCCEED) { chClient1.Close(); } else { //printf("Open local %s Failed while check Live\n", DrvBusId.c_str()); //mLog::FERROR("Open local {$} Failed while check Live\n", DrvBusId.c_str()); } } else { if (m_bConfigRemoveDriver) { //mLog::FINFO("ConfigDriver working 2"); return; } //target process crashed //printf("Autoload Flag:%d \n BusId:%s\n", (bool)(iter->second)[0].m_CcosProcInfo["AutoLoad"], iter->first.c_str()); //do reload if ((bool)(iter->second)[0].m_CcosProcInfo["AutoLoad"]) { memset(&(iter->second)[0].m_info, 0, sizeof(LinuxProcessInfo)); if (CreateTheProcess_Console_Config((iter->second)[0].m_CcosProcInfo["DriverPath"], (iter->second)[0].m_CcosProcInfo["WorkPath"], (iter->second)[0].m_info, (iter->second)[0].m_CcosProcInfo["ShowWindow"]) == FALSE) { //printf("Reload Failed.Can't Create Process for config:%s\n", // (const char*)(iter->second)[0].m_CcosProcInfo["DriverConfigPath"]); //mLog::FERROR("Reload Failed.Can't Create Process for config:{$}", (const char*)(iter->second)[0].m_CcosProcInfo["DriverConfigPath"]); } else { //printf("Reload Succeed.Create Process for config:%s Succeed\n", // (const char*)(iter->second)[0].m_CcosProcInfo["DriverConfigPath"]); //mLog::FINFO("Reload Succeed.Create Process for config:{$} Succeed", (const char*)(iter->second)[0].m_CcosProcInfo["DriverConfigPath"]); usleep(6000000);//wait } } else { //kick iter; //printf("Kick crashed process. BusId:%s\n", iter->first.c_str()); //mLog::FINFO("Kick crashed process. BusId:{$}\n", iter->first.c_str()); DelDeviceDescrpt(DrvBusId.c_str()); iter = m_pProcessInfo->erase(iter); continue; } } } } ++iter; } return; } int SYSTEM_CALL BusUnitLogic::LoadAllConfigDriver(bool ForReload, ResDataObject* pResource) { RET_STATUS ret = RET_SUCCEED; //this is for dpc call bool FullDriverList = false; ResDataObject fileList; //find driver from fulldrvlist if (CheckBusIdsExistance(0) == false) { //mLog::FERROR("CheckBusIdsExistance(0) == false"); return RET_FAILED; } LogicDriver* pDPC = (LogicDriver*)GetDrvDPC(); if (pDPC == 0) { //mLog::FERROR("pDPC == 0"); return RET_FAILED; } //mLog::FINFO("GetDrvDPC ok"); //pDPC->Thread_Lock(); ////mLog::FINFO("DPC lock ok"); try{ //find x64 if (GetSpecificDriverConfigFiles(fileList, FullDriverList)) { //mLog::FINFO("GetSpecificDriverConfigFiles ok"); map ConflictBusIds; map BusIdMap;//BusId <-> Dir map> LoadDriverMap; //exist x64 for (size_t i = 0; i < fileList.size(); i++) { TargetDriverInfo DrvInfo; if (GetDriverEbusId(fileList.GetKey(i), DrvInfo.m_RootBusId, DrvInfo.m_DriverBusId)) { //get ebus driver path if (GetDriverProcInfo(fileList.GetKey(i), DrvInfo.m_CcosProcInfo)) { map::iterator BusIdsIter = BusIdMap.find((const char*)DrvInfo.m_RootBusId); if (BusIdsIter != BusIdMap.end()) { //same busId Exist if (BusIdsIter->second == (const char*)fileList[i]) { //same dir,ok } else { //different dir,ng ConflictBusIds[BusIdsIter->first] = 1; } } else { //no BusId exist BusIdMap[(const char*)DrvInfo.m_RootBusId] = (const char*)fileList[i]; } LoadDriverMap[(const char *)DrvInfo.m_RootBusId].push_back(DrvInfo); } else { //mLog::FINFO("GetDriverProcInfo failed {$} ", fileList.GetKey(i)); } } else { //mLog::FINFO("GetDriverEbusId failed {$} ", fileList.GetKey(i)); } } map>::iterator DelIter; //kick same busids drivers map::iterator ConflictIter = ConflictBusIds.begin(); while (ConflictIter != ConflictBusIds.end()) { DelIter = LoadDriverMap.find(ConflictIter->first); if (DelIter != LoadDriverMap.end()) { //mLog::FERROR("busid:{$} conflict", DelIter->first.c_str()); for (size_t DriverIdx = 0; DriverIdx < DelIter->second.size(); DriverIdx++) { const char *pszConfigFilepath = DelIter->second[DriverIdx].m_CcosProcInfo["DriverConfigPath"];//config file path //mLog::FERROR("busid:{$} conflict.Ignore ConfigFile:{$}", DelIter->first.c_str(),pszConfigFilepath); } LoadDriverMap.erase(DelIter); } ++ConflictIter; } ConflictBusIds.clear(); //mLog::FINFO("LoadDriverMap size {$} ", LoadDriverMap.size()); //kick condition like (same busid but not same procType) DelIter = LoadDriverMap.begin(); while (DelIter != LoadDriverMap.end()) { if (DelIter->second.size() > 1) { bool ConflictProc = false; //more than one driver exist for (size_t DriverIdx = 0; DriverIdx < DelIter->second.size() - 1; DriverIdx++) { if (ConflictProc) { break; } //compare each others driverproc string DriverProc = ""; ResDataObject DriverProcessPath; GetDriverProcessPath(DelIter->second[DriverIdx].m_CcosProcInfo["DriverConfigPath"], DriverProcessPath); DriverProc = (const char*)DriverProcessPath; for (size_t CompareIdx = DriverIdx + 1; CompareIdx < DelIter->second.size(); CompareIdx++) { if (ConflictProc) { break; } string CompareProc = ""; ResDataObject CompareProcessPath; GetDriverProcessPath(DelIter->second[CompareIdx].m_CcosProcInfo["DriverConfigPath"], CompareProcessPath); CompareProc = (const char*)CompareProcessPath; if (CompareProc != DriverProc) { ConflictBusIds[DelIter->first] = 1; ConflictProc = true; } } } } ++DelIter; } //kick again ConflictIter = ConflictBusIds.begin(); while (ConflictIter != ConflictBusIds.end()) { DelIter = LoadDriverMap.find(ConflictIter->first); if (DelIter != LoadDriverMap.end()) { //mLog::FERROR("busid:{$} processType conflict", DelIter->first.c_str()); for (size_t DriverIdx = 0; DriverIdx < DelIter->second.size(); DriverIdx++) { const char* pszConfigFilepath = DelIter->second[DriverIdx].m_CcosProcInfo["DriverConfigPath"];//config file path //mLog::FERROR("busid:{$} processType conflict.Ignore ConfigFile:{$}", DelIter->first.c_str(), pszConfigFilepath); } LoadDriverMap.erase(DelIter); } ++ConflictIter; } map>::iterator iter = LoadDriverMap.begin(); while (iter != LoadDriverMap.end()) { if (ForReload) { if (CheckBusIdsExistance(iter->first.c_str()) == false) { //target exist ++iter; continue; } } //make full process path bool FirstIn = true; string ConfigFile; string FullDriverPath = ""; for (size_t DriverIdx = 0; DriverIdx < iter->second.size(); DriverIdx++) { //make driverpath if (FirstIn) { ResDataObject DriverProcessPath; GetDriverProcessPath(iter->second[DriverIdx].m_CcosProcInfo["DriverConfigPath"], DriverProcessPath); FullDriverPath = (const char *)DriverProcessPath; FirstIn = false; } ConfigFile = (const char *)iter->second[DriverIdx].m_CcosProcInfo["DriverConfigPath"]; //get config file title string ConfigFileName = GetFileName(ConfigFile); FullDriverPath += " " + ConfigFileName; } //rest all of same busid for (size_t DriverIdx = 0; DriverIdx < iter->second.size(); DriverIdx++) { iter->second[DriverIdx].m_CcosProcInfo["DriverPath"] = FullDriverPath.c_str();//[fullpath of exe] [config1.xml config2.xml ...] } //create process if (CreateTheProcess_Console_Config(iter->second[0].m_CcosProcInfo["DriverPath"], iter->second[0].m_CcosProcInfo["WorkPath"], iter->second[0].m_info, iter->second[0].m_CcosProcInfo["ShowWindow"]) == FALSE) { //mLog::FERROR("Can't Create Process:{$}", FullDriverPath.c_str()); } else { //mLog::FINFO("Create Process:{$} ok", FullDriverPath.c_str()); for (size_t DriverIdx = 0; DriverIdx < iter->second.size(); DriverIdx++) { (*m_pProcessInfo)[(const char*)iter->second[DriverIdx].m_RootBusId].push_back(iter->second[DriverIdx]); MakeDriverNotify((const char *)iter->second[DriverIdx].m_DriverBusId, true); } } ++iter; } } else { //mLog::FERROR("GetSpecificDriverConfigFiles failed"); } } catch (...) { //mLog::FERROR("crash"); ret = RET_FAILED; } //pDPC->Thread_UnLock(); ////mLog::FINFO("DPC Unlock ok"); return ret; } void SYSTEM_CALL BusUnitLogic::UnloadDriver(const char *pszBusId) { //mLog::FINFO("Enter UnloadDriver:{$}", pszBusId); map>::iterator iter = m_pProcessInfo->find(pszBusId); if (iter != m_pProcessInfo->end()) { //found target busid. //notify target quit first string DrvBusId = "/"; DrvBusId += (const char*)iter->first.c_str(); { //got one pid_t targetPid = iter->second[0].m_info.process_id; if (kill(targetPid, 0) == 0) { //process exist LogicClient chClient1("UnloadDriver_temp","driver", "", false); chClient1.SetRouter(CCOS_PACKET_ROUTE_LOCAL); if (chClient1.Open(DrvBusId.c_str(), ALL_ACCESS, "", ONE_ACTION_TIMEOUT) >= RET_SUCCEED) { ResDataObject req; if (chClient1.Action_Req("ExitDriverProc", req, ONE_ACTION_TIMEOUT) >= RET_SUCCEED) { //printf("Succeed Action:ExitDriverProc %s ...\n", DrvBusId.c_str()); //mLog::FINFO("Succeed Action: ExitDriverProc {$} ...\n", DrvBusId.c_str()); chClient1.Close(); } else { //printf("Failed Action:ExitDriverProc -> %s...\n", DrvBusId.c_str()); //mLog::FERROR("Failed Action: ExitDriverProc -> {$} ...\n", DrvBusId.c_str()); chClient1.Close(); } } else { //printf("Open local %s Failed\n", DrvBusId.c_str()); //mLog::FERROR("Open local {$} Failed\n", DrvBusId.c_str()); } } } int waitCount = 0; const int maxWait = (ONE_ACTION_TIMEOUT - 1000) / 100; // 转换为100ms单位 while (waitCount < maxWait) { if (kill(iter->second[0].m_info.process_id, 0) != 0 && errno == ESRCH) { break; // 进程已退出 } usleep(100 * 1000); // 100ms waitCount++; } // 超时后强制终止 if (kill(iter->second[0].m_info.process_id, 0) == 0) { kill(iter->second[0].m_info.process_id, SIGKILL); } //make notify for (size_t DriverIdx = 0; DriverIdx < iter->second.size(); DriverIdx++) { MakeDriverNotify((const char *)iter->second[DriverIdx].m_DriverBusId, false); } //kick busid m_pProcessInfo->erase(iter); } //mLog::FINFO("Exit UnloadDriver:{$}", pszBusId); return; } void SYSTEM_CALL BusUnitLogic::UnloadAllRegistedDrivers() { map>::iterator iter = m_pProcessInfo->begin(); while (iter != m_pProcessInfo->end()) { string DrvBusId = "/"; DrvBusId += (const char*)iter->first.c_str(); { //got one pid_t targetPid = iter->second[0].m_info.process_id; if (kill(targetPid, 0) == 0) { //process exist LogicClient chClient1("UnloadAllRegistedDrivers_temp","driver", "", false); chClient1.SetRouter(CCOS_PACKET_ROUTE_LOCAL); if (chClient1.Open(DrvBusId.c_str(), ALL_ACCESS,"", ONE_ACTION_TIMEOUT) >= RET_SUCCEED) { ResDataObject req; if (chClient1.Action_Req("ExitDriverProc", req, ONE_ACTION_TIMEOUT) >= RET_SUCCEED) { //printf("Succeed Action:ExitDriverProc %s ...\n", DrvBusId.c_str()); //mLog::FINFO("Succeed Action: ExitDriverProc {$} ...\n", DrvBusId.c_str()); chClient1.Close(); } else { //printf("Failed Action:ExitDriverProc -> %s...\n", DrvBusId.c_str()); //mLog::FERROR("Failed Action: ExitDriverProc -> {$} ...\n", DrvBusId.c_str()); chClient1.Close(); } } else { //printf("Open local %s Failed\n", DrvBusId.c_str()); //mLog::FERROR("Open local {$} Failed\n", DrvBusId.c_str()); } } } ++iter; } DWORD Idx = 0; if (m_pProcessInfo->size() > 64) { //printf("\n\n\n\nthe process number out of 64\n\n\n\n"); //mLog::FERROR("the process number out of 64"); map>::iterator iter = m_pProcessInfo->begin(); while (iter != m_pProcessInfo->end()) { pid_t pid = iter->second[0].m_info.process_id; // 如果进程仍然存在,强制终止 if (kill(pid, 0) == 0) { kill(pid, SIGKILL); } ++iter; } } else { // 创建进程ID列表 std::vector pids; pids.reserve(m_pProcessInfo->size()); // 收集所有需要等待的进程ID for (auto& [key, drivers] : *m_pProcessInfo) { if (!drivers.empty()) { pids.push_back(drivers[0].m_info.process_id); } } // 使用 poll 实现多进程等待 bool allExited = false; int timeout = ONE_ACTION_TIMEOUT - 1000; // 毫秒 auto startTime = std::chrono::steady_clock::now(); while (!allExited && timeout > 0) { allExited = true; for (auto pid : pids) { // 检查进程状态 if (kill(pid, 0) == 0 || errno != ESRCH) { allExited = false; break; } } if (!allExited) { // 等待100ms usleep(100 * 1000); // 更新剩余时间 auto elapsed = std::chrono::duration_cast( std::chrono::steady_clock::now() - startTime); timeout -= elapsed.count(); } } // 如果超时仍有进程未退出 if (!allExited) { for (auto& [key, drivers] : *m_pProcessInfo) { if (!drivers.empty()) { pid_t pid = drivers[0].m_info.process_id; if (kill(pid, 0) == 0 || errno != ESRCH) { // 强制终止进程 kill(pid, SIGKILL); } } } } } return; } void BusUnitLogic::OnSetClientID() { m_strClientID = m_strClientID + "_bus_device"; //取得端口号 (*m_pGrpcPort) = GetGrpcPort(); } void BusUnitLogic::SubscribeSelf() { //assert(m_strEBusRoot.length() > 0); LogicDevice::SubscribeSelf(); SubscribeActions(); ResDataObject NotifyData; PacketAnalizer::MakeNotify(NotifyData, PACKET_CMD_UPDATE, m_pGrpcPort->GetKey(), m_pGrpcPort->GetVal()); CmdFromLogicDev(&NotifyData); }