#include "stdafx.h" #include "DiosSMachineV3.h" #include "PacketAnalizer.h" #include #define STATEMACHINE_ACQ_EVENTWAITEX_TIMEOUT (60000) string formatstdStringA(const char* fmt, ...) { std::string strResult = ""; { if (NULL != fmt) { va_list marker = NULL; va_start(marker, fmt); size_t nLength = _vscprintf(fmt, marker) + 1; std::vector vBuffer(nLength, '\0'); int nWritten = vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker); if (nWritten > 0) { strResult = &vBuffer[0]; } va_end(marker); } } return strResult; } //int FindEventResult(DiosStMEvt& evt, DiosStMRouteLine* pEvts[], DWORD size) //{ // int result = -1; // for (DWORD i = 0; i < size; i++) // { // if ((DiosStMEvt*)(*(pEvts[i])) != NULL && evt == (*(DiosStMEvt*)(*(pEvts[i])))) // { // result = i; // break; // } // } // return result; //} //int FindEventIndex(DiosStMEvt& Evt, DiosStMRouteLine* pLocalEvts[], DWORD CountOfLocal, // //DiosStMRouteLine* pExternalEvts[], DWORD CountOfExternal, // DiosStMRouteLine* pOutpathEvts[], DWORD CountOfOutpath) //{ // int result = FindEventResult(Evt, pLocalEvts, CountOfLocal); // if (result != -1) // { // return result; // } // //result = FindEventResult(Evt, pExternalEvts, CountOfExternal); // //if (result != -1) // //{ // // result += CountOfLocal; // // return result; // //} // result = FindEventResult(Evt, pOutpathEvts, CountOfOutpath); // if (result != -1) // { // result += CountOfLocal /*+ CountOfExternal*/; // return result; // } // return result; //} StateMachineDevicePool::StateMachineDevicePool() { m_pErrorInfoQue = new MsgQueue(); m_pDevpath = new map(); m_pDevlist = new map(); m_pActionDevList = new map(); //m_pActionMap = new map>>>(); //m_pEventMap = new map>>>(); //m_pHardwareEventMap = new map>>(); } StateMachineDevicePool::~StateMachineDevicePool() { ClearDevices(); delete m_pDevpath; delete m_pDevlist; //delete m_pActionMap; //delete m_pEventMap; //delete m_pHardwareEventMap; delete m_pErrorInfoQue; } //提取错误信息 bool StateMachineDevicePool::PopErrInfo(ResDataObject& info) { if (m_pErrorInfoQue->size() > 0) { return m_pErrorInfoQue->DeQueue(info); } return false; } //推入错误信息 void StateMachineDevicePool::PushErrInfo(const char* pszContext, DSMERRORTYPE ErrType) { ResDataObject Context; Context.add("code", ErrType); Context.add("desc", pszContext); m_pErrorInfoQue->InQueue(Context); } void StateMachineDevicePool::SetThreadExitHandle(HANDLE tHand) { m_ThreadExitHandle = tHand; } //通过设备路径 获取设备的下标索引 DWORD StateMachineDevicePool::GetDeviceIdx(const char* pszDevpath) { map::iterator iter = m_pDevpath->begin(); while (iter != m_pDevpath->end()) { if (iter->second == pszDevpath) { return iter->first; } ++iter; } return INVALID_DEVIDX; } //往设备池子中添加设备 bool StateMachineDevicePool::AddDevices(ResDataObject& Devices) { bool ret = true; //DWORD LockStatus = Thread_Lock(1000); //if (LockStatus == WAIT_TIMEOUT) //{ // mLog::FERROR("DevicePool is Locked"); // return false; //} ClearDevices(); for (INT i = 0; i < Devices.size(); i++) { const char* pDevice = Devices.GetKey(i); if (strlen(pDevice) == 0) { mLog::FERROR("The idx[%d]s Devicepath is empty", i); ClearDevices(); ret = false; break; } (*m_pDevpath)[i] = pDevice; } //Thread_UnLock(); if (ret) { ret = OpenDevices(); } return ret; } LogicClient* StateMachineDevicePool::FindClient(const char* pszDevShortPath) { auto iter = m_pDevpath->begin(); while (iter != m_pDevpath->end()) { if (iter->second.find_first_of(pszDevShortPath, 0) > 0) return (*m_pActionDevList)[iter->first]; iter++; } return nullptr; } //清空事件列表 void StateMachineDevicePool::ClearStateEventMaps() { //DWORD LockStatus = Thread_Lock(1000); //if (LockStatus == WAIT_TIMEOUT) //{ // mLog::FERROR("DevicePool is Locked"); //} //m_pEventMap->clear(); //m_pHardwareEventMap->clear(); //Thread_UnLock(); } //清空设备Action列表 void StateMachineDevicePool::ClearStateActionMaps() { //DWORD LockStatus = Thread_Lock(1000); //if (LockStatus == WAIT_TIMEOUT) //{ // mLog::FERROR("DevicePool is Locked"); //} //m_pActionMap->clear(); //Thread_UnLock(); } //添加Action列表,采用Map存储 //bool StateMachineDevicePool::AddStateActions(ResDataObject& ActionMaps) //{ // //DWORD LockStatus = Thread_Lock(1000); // //if (LockStatus == WAIT_TIMEOUT) // //{ // // mLog::FERROR("DevicePool is Locked"); // // return false; // //} // // //"ParentStateName":"StateName":"Devpath":ActionName:Params // for (INT ParentNameIdx = 0; ParentNameIdx < ActionMaps.size(); ParentNameIdx++) // { // for (INT NameIdx = 0; NameIdx < ActionMaps[ParentNameIdx].size(); NameIdx++) // { // for (INT DevIdx = 0; DevIdx < ActionMaps[ParentNameIdx][NameIdx].size(); DevIdx++) // { // for (INT ActionIdx = 0; ActionIdx < ActionMaps[ParentNameIdx][NameIdx][DevIdx].size(); ActionIdx++) // { // const char* pParentName = ActionMaps.GetKey(ParentNameIdx); // const char* pStateName = ActionMaps[ParentNameIdx].GetKey(NameIdx); // const char* pDevpath = ActionMaps[ParentNameIdx][NameIdx].GetKey(DevIdx); // const char* pAction = ActionMaps[ParentNameIdx][NameIdx][DevIdx].GetKey(ActionIdx); // ResDataObject& Params = ActionMaps[ParentNameIdx][NameIdx][DevIdx][ActionIdx]; // // if (strlen(pParentName) == 0 || strlen(pStateName) == 0 || strlen(pDevpath) == 0 || strlen(pAction) == 0) // { // mLog::FERROR("ParentName:%s\nStateName:%s\nDevPath:%s\n,Action:%s\n", pParentName, pStateName, pDevpath, pAction); // Thread_UnLock(); // return false; // } // // DWORD ClientIdx = GetDeviceIdx(pDevpath); // if (ClientIdx == INVALID_DEVIDX) // { // mLog::FERROR("Device not exist:%s", pDevpath); // // Thread_UnLock(); // return false; // } // // mLog::FDEBUG("ParentName:%s\nStateName:%s\nDevPath:%s\n,Action:%s,Param:%s\n", pParentName, pStateName, pDevpath, pAction, Params.encode()); // // if (ActionMaps[ParentNameIdx][NameIdx][DevIdx].size() > 1) // { // mLog::FERROR("Device[%s] has more than 1 action at a state[%s][%s].action count:%d", pDevpath, pParentName, pStateName, ActionMaps[ParentNameIdx][NameIdx][DevIdx].size()); // // Thread_UnLock(); // return false; // } // // // //ok // (*m_pActionMap)[pParentName][pStateName][ClientIdx][pAction] = Params; // // } // } // } // } // // //Thread_UnLock(); // return true; //} //添加事件列表 //bool StateMachineDevicePool::AddStateEvents(ResDataObject& EventMaps) //{ // DWORD LockStatus = Thread_Lock(1000); // if (LockStatus == WAIT_TIMEOUT) // { // mLog::FERROR("DevicePool is Locked"); // return false; // } // // //EventName:{ Need : 1 or 0,{Devpath : Key:Value}} // for (INT EventIdx = 0; EventIdx < EventMaps.size(); EventIdx++) // { // //get eventname // const char* pEventName = EventMaps.GetKey(EventIdx); // if (strlen(pEventName) == 0) // { // mLog::FERROR("EventName is Empty"); // Thread_UnLock(); // return false; // } // // //get need flag // INT NeedIdx = EventMaps[EventIdx].GetFirstOf("Need"); // if (NeedIdx < 0) // { // mLog::FERROR("Event:%s Missing Need Flag", pEventName); // Thread_UnLock(); // return false; // } // // bool NeedFlag = EventMaps[EventIdx][NeedIdx]; // // if (NeedFlag == 0) // { // //no need devices // (*m_pEventMap)[pEventName][SMEVT_PASS][INVALID_DEVIDX][""] = ""; // mLog::FINFO("Event:%s Set PASS", pEventName); // continue; // } // // //get readattr // INT ReadAttrIdx = EventMaps[EventIdx].GetFirstOf("ReadFromAttribute"); // if (ReadAttrIdx < 0) // { // mLog::FERROR("Event:%s Missing ReadFromAttribute Flag", pEventName); // Thread_UnLock(); // return false; // } // // bool ReadFlag = EventMaps[EventIdx][ReadAttrIdx]; // // bool EventMapExist = false; // // for (INT DevIdx = 0; DevIdx < EventMaps[EventIdx].size(); DevIdx++) // { // if (DevIdx == NeedIdx || DevIdx == ReadAttrIdx) // { // continue; // } // // // // const char* pDevpath = EventMaps[EventIdx].GetKey(DevIdx); // if (strlen(pDevpath) == 0) // { // mLog::FERROR("Event:%s Missing Devicepath", pEventName); // Thread_UnLock(); // return false; // } // // for (INT KeyIdx = 0; KeyIdx < EventMaps[EventIdx][DevIdx].size(); KeyIdx++) // { // const char* pKey = EventMaps[EventIdx][DevIdx].GetKey(KeyIdx); // if (strlen(pKey) == 0) // { // mLog::FERROR("Event:%s\nDevpath:%s Missing KeyTitle", pEventName, pDevpath); // Thread_UnLock(); // return false; // } // // const char* pVal = EventMaps[EventIdx][DevIdx][KeyIdx]; // // DWORD ClientIdx = GetDeviceIdx(pDevpath); // if (ClientIdx == INVALID_DEVIDX) // { // mLog::FERROR("Device not exist:%s", pDevpath); // // Thread_UnLock(); // return false; // } // if (ReadFlag) // { // (*m_pEventMap)[pEventName][SMEVT_READATTR][ClientIdx][pKey] = pVal; // } // else // { // (*m_pEventMap)[pEventName][SMEVT_NOTIFY][ClientIdx][pKey] = pVal; // } // mLog::FINFO("EventName:%s ReadFlag:%d,ClientIdx:%d,Key[%s]:val[%s]", pEventName, ReadFlag, ClientIdx, pKey, pVal); // // (*m_pHardwareEventMap)[ClientIdx][pKey][pVal] = pEventName; // // EventMapExist = true; // // // } // // } // // if (EventMapExist == false) // { // //no need devices // mLog::FINFO("Event[%s] no map Exist.set it as BLOCK", pEventName); // // (*m_pEventMap)[pEventName][SMEVT_BLOCK][INVALID_DEVIDX][""] = ""; // // } // // // } // // Thread_UnLock(); // return true; // //} //device init,清除所有设备 信息 bool StateMachineDevicePool::ClearDevices() { //DWORD LockStatus = Thread_Lock(1000); //if (LockStatus == WAIT_TIMEOUT) //{ // mLog::FERROR("DevicePool is Locked"); // return false; //} CloseDevices(); m_pErrorInfoQue->Clear(); m_pDevpath->clear(); m_pDevlist->clear(); //m_pActionMap->clear(); //m_pEventMap->clear(); //m_pHardwareEventMap->clear(); //Thread_UnLock(); return true; } //打开所有设备 bool StateMachineDevicePool::OpenDevices() { bool ret = true; //DWORD LockStatus = Thread_Lock(1000); //if (LockStatus == WAIT_TIMEOUT) //{ // mLog::FERROR("DevicePool is Locked"); // return false; //} if (m_pDevlist->size() > 0) { CloseDevices(); } //go open char szClientName[256]; map::iterator iter = m_pDevpath->begin(); while (iter != m_pDevpath->end()) { //用于接收通知的连接 sprintf(szClientName, "StateMachine_%s", iter->second.c_str()); LogicClient* pClient = new LogicClient((const char*)szClientName); if (pClient->Open(iter->second.c_str(), ALL_ACCESS, STATEMACHINE_ACTION_TIMEOUT) >= RET_SUCCEED) { std::cout << "\n\n StateMachine try open Device " << iter->second << "Succced..." << endl; (*m_pDevlist)[iter->first] = pClient; } else { std::cout << "\n\n StateMachine try open Device " << iter->second << "Failed..." << endl; mLog::FERROR("Can't Open:%s", iter->second.c_str()); CloseDevices(); ret = false; } //用于执行action的连接 sprintf(szClientName, "StateMachine_Action_%s", iter->second.c_str()); LogicClient* pActionClient = new LogicClient((const char*)szClientName, "SMA", false); if (pActionClient->Open(iter->second.c_str(), ALL_ACCESS, STATEMACHINE_ACTION_TIMEOUT) >= RET_SUCCEED) { std::cout << "\n\n StateMachine try open Device for action " << iter->second << "Succced..." << endl; (*m_pActionDevList)[iter->first] = pActionClient; } else { std::cout << "\n\n StateMachine try open Device " << iter->second << "Failed..." << endl; mLog::FERROR("Can't Open:%s", iter->second.c_str()); CloseDevices(); ret = false; } ++iter; } //Thread_UnLock(); return ret; } //关闭设备 bool StateMachineDevicePool::CloseDevices() { //DWORD LockStatus = Thread_Lock(1000); //if (LockStatus == WAIT_TIMEOUT) //{ // mLog::FERROR("DevicePool is Locked"); // return false; //} map::iterator iter = m_pDevlist->begin(); while (iter != m_pDevlist->end()) { iter->second->Close(); delete iter->second; ++iter; } m_pDevlist->clear(); iter = m_pActionDevList->begin(); while (iter != m_pActionDevList->end()) { iter->second->Close(); delete iter->second; ++iter; } m_pActionDevList->clear(); //Thread_UnLock(); return true; } //获取设备属性Action列表 //INT StateMachineDevicePool::GetDeviceActions(const char* pParentStatePos, const char* pStatePos, map>* pDeviceActions) //{ // INT ret = -1; // // if (m_pActionMap->size() == 0) // { // //no action match // if (pParentStatePos && pStatePos) // { // mLog::FERROR("state actionmap empty.request state[%s]:substate[%s]", pParentStatePos, pStatePos); // // } // return 0; // } // // //root state machine // map>>>::iterator iter = m_pActionMap->find(pParentStatePos); // if (iter == m_pActionMap->end()) // { // if (pParentStatePos && pStatePos) // { // mLog::FERROR("parentstate:%s no Action map", pParentStatePos); // } // // return 0; // } // // //this state machine // map>>::iterator iter1 = iter->second.find(pStatePos); // if (iter1 == iter->second.end()) // { // if (pParentStatePos && pStatePos) // { // mLog::FERROR("state[%s]:substate[%s] no Action map", pParentStatePos, pStatePos); // } // // return 0; // } // // ret = 0; // // map>::iterator iterDev = iter1->second.begin(); // while (iterDev != iter1->second.end()) // { // map::iterator iterAction = iterDev->second.begin(); // while (iterAction != iterDev->second.end()) // { // ret = 1; // // (*pDeviceActions)[iterDev->first][iterAction->first] = iterAction->second; // // ++iterAction; // } // // ++iterDev; // } // // return ret; // // //} /// /// 新版执行设备组的Action /// 状态机Action处理,调用设备的action /// /// 要执行的设备Action资源 /// 执行的结果保存 返回值:DeviceName.ActionName : resResp /// 输入用户变量 /// 超时时间 /// DIOSSMRET_OK 执行成功 DIOSSTMRET StateMachineDevicePool::StateMachineAction(ResDataObject* resActions, ResDataObject& resResult, ResDataObject* pVariable, DWORD Timeout) { DIOSSTMRET ret = DIOSSMRET_NG; //按顺序投递消息,并接收应答 int nActionCount = 0; DWORD dwStart = GetTickCount(); for (int devIdx = 0; devIdx < resActions->size(); devIdx++) { const char* pszDevName = resActions->GetKey(devIdx); LogicClient* pClient = FindClient(pszDevName); if (pClient == nullptr) { std::cout << "Cannot find Action Clinet.... ERROR... " << pszDevName << endl; } ResDataObject actions = resActions[devIdx]; ResDataObject resParam; for (int aIdx = 0; aIdx < actions.size(); aIdx++) { resParam = actions[aIdx]; string param = (const char*)resParam; int nParamStart = param.find('$'); if(nParamStart < 0) { pClient->Action_Req(actions.GetKey(aIdx), resParam); nActionCount++; } else { //需要处理用户变量 //必须以$$开头和结束 string paramName = param.substr(1, param.length() - 2); int nParamPos = paramName.find('.'); if (nParamPos > 0) { string devName = param.substr(0, nParamPos); string pName = param.substr(nParamPos + 1); //是2层参数 try { resParam = (*pVariable)[devName.c_str()][pName.c_str()]; pClient->Action_Req(actions.GetKey(aIdx), resParam); nActionCount++; } catch (...) { //变量取不到 } } else { //一层参数 try { resParam = (*pVariable)[paramName.c_str()]; pClient->Action_Req(actions.GetKey(aIdx), resParam); nActionCount++; } catch (...) { } } } } } //并将结果存入系统变量 while(nActionCount > 0) { for (int devIdx = 0; devIdx < resActions->size(); devIdx++) { const char* pszDevName = resActions->GetKey(devIdx); LogicClient* pClient = FindClient(pszDevName); ResDataObject actions = resActions[devIdx]; ResDataObject resResp; for (int aIdx = 0; aIdx < actions.size(); aIdx++) { if (pClient->IsDataArrived()) { pClient->ReadCmd(resResp); //返回值:DeviceName.ActionName : resResp resResult.add((string(pszDevName) + "." + (string(resResp["KEY"]))).c_str(), resResp); nActionCount--; } } } //超时了,还没取完返回值 if (GetTickCount() - dwStart > Timeout) return DIOSSMRET_TIMEOUT; } return DIOSSMRET_OK; } //通用的Action和Event处理 //DIOSSTMRET StateMachineDevicePool::StateMachineAction(const char* pParentStatePos, const char* pStatePos, DWORD timeout) //{ // Thread_Lock(); // //收集符合状态点的设备. // //收集对应设备的Actions. // //devidx:action:params // map> DeviceActions; // INT ret = GetDeviceActions(pParentStatePos, pStatePos, &DeviceActions); // if (ret < 0) // { // Thread_UnLock(); // return DIOSSMRET_NG; // } // // if (ret == 0) // { // Thread_UnLock(); // return DIOSSMRET_OK; // } // // if (DeviceActions.size() > MAXIMUM_WAIT_OBJECTS - 1) // { // string errinfo = formatstdStringA("Device Count Out of Windows Wait Count:%d,Limit:%d", DeviceActions.size(), MAXIMUM_WAIT_OBJECTS - 1); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str()); // // Thread_UnLock(); // return DIOSSMRET_NG; // } // // DWORD DevIndex = 0; // DWORD DevCount = (DWORD)DeviceActions.size(); // // vector ClientIdx; // vector ActionIdx; // vector ResHandle; // // vector ClientsObj; // // //线程退出事件 // ResHandle.push_back(m_ThreadExitHandle); // // //异步发起ActionReq // map>::iterator iter = DeviceActions.begin(); // while (iter != DeviceActions.end()) // { // LogicClient* pClient = (*m_pActionDevList)[iter->first]; // if (pClient == 0) // { // string errinfo = formatstdStringA("state:[%s][%s],device:%s no client exist", pParentStatePos, pStatePos, (*m_pDevpath)[iter->first].c_str()); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str()); // // Thread_UnLock(); // return DIOSSMRET_NG; // } // // map::iterator iterAction = (iter)->second.begin();// iter->second.begin(); // /*if (iter->second.size() > 1) // { // string errinfo = formatstdStringA("state:[%s][%s],device:%s has more than 1 action", pParentStatePos, pStatePos, (*m_pDevpath)[iter->first].c_str()); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str()); // // Thread_UnLock(); // return DIOSSMRET_NG; // }*/ // // while (iterAction != (iter)->second.end()) // { // RET_STATUS ActionReq = (RET_STATUS)pClient->Action_Req(iterAction->first.c_str(), iterAction->second, timeout); // if (ActionReq <= RET_FAILED) // { // string errinfo = formatstdStringA("state:[%s][%s] Action[%s] Req Failed.ret:%d,Device:%s", pParentStatePos, pStatePos, iterAction->first.c_str(), ActionReq, (*m_pDevpath)[iter->first].c_str()); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str(), DSM_ERROR_ACTION_FAILED); // // Thread_UnLock(); // return DIOSSMRET_NG; // } // // //ActionIdx.push_back(iterAction->first.c_str()); // //ClientIdx.push_back(iter->first); // //ResHandle.push_back(pClient->GetResponseHandle()); // ClientsObj.push_back(pClient); // // // ++iterAction; // } // // ++iter; // } // // //轮询接收ActionRes // bool bHaveError = false; // int idx = 0; // DWORD EntryTime = GetTickCount(); // while (ClientsObj.size() > 0) // { // //get client // LogicClient* pClient = ClientsObj[idx]; // // //try get res // if (pClient->IsDataArrived()) // { // ResDataObject res; // //收到应答了 // PACKET_CMD cmd = pClient->ReadCmd(res); // RET_STATUS ActionRet = RET_FAILED; // PacketAnalizer::GetPacketRetCode(&res, ActionRet); // // if ((ActionRet < RET_SUCCEED) && (ActionRet != RET_TIMEOUT)) // { // bHaveError = true; // ResDataObject path; // pClient->GetFilePath(path); // string errinfo = formatstdStringA("state:[%s][%s] Wait Action[%s] Res failed.ret:%d.device:%s", pParentStatePos, pStatePos, // PacketAnalizer::GetPacketKey(&res), ActionRet, (const char*)path); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str(), DSM_ERROR_ACTION_FAILED); // // //return DIOSSMRET_NG; // } // // ClientsObj.erase(ClientsObj.begin() + idx); // if (ActionRet >= RET_SUCCEED) // { // //Succeed get res.do the kick // if (ClientsObj.size() == 0) // { // Thread_UnLock(); // if (!bHaveError) // { // mLog::FDEBUG("state:[%s][%s] Action Succeed", pParentStatePos, pStatePos); // return DIOSSMRET_OK; // } // } // // } // } // else // { // idx++; // } // // //timeout here // // DWORD PassedTimePeriod = GetTickCount() - EntryTime; // if (timeout < PassedTimePeriod) // { // break; // } // timeout -= PassedTimePeriod; // // } // // mLog::FERROR("StateMachineAction Timeout"); // PushErrInfo("StateMachineAction Timeout", DSM_ERROR_ACTION_TIMEOUT); // // Thread_UnLock(); // return DIOSSMRET_TIMEOUT; // //} //wait event //从 Target状态机 全局In事件和当前状态的Out事件中等待 某个事件的发生 //如果状态出路由有直接跳转的,就直接过去了 //否则就等着事件发生 //int StateMachineDevicePool::StateMachineWaitForEvents( // DiosSMachineIF* pTarget, // DiosStMRouteLine* pLocalEvts[], DWORD CountOfLocal, // //DiosStMRouteLine* pExternalEvts[], DWORD CountOfExternal, // DiosStMRouteLine* pOutpathEvts[], DWORD CountOfOutpath, // DWORD timeout //) //{ // Thread_Lock(); // // //check outpath event status // for (DWORD OutIdx = 0; OutIdx < CountOfOutpath; OutIdx++) // { // //(empty,pass)->direct jump // DiosStMEvt* pEvt = (*(pOutpathEvts[OutIdx])); // if (pEvt->IsEmpty() == true) // { // //Hit empty // Thread_UnLock(); // // return (CountOfLocal /*+ CountOfExternal*/ + OutIdx); // } // else // { // const char* pszEvtName = pEvt->GetEvtContext().GetKey(0); // map>>>::iterator iter = m_pEventMap->find(pszEvtName); // if (iter != m_pEventMap->end()) // { // map>>::iterator iterEvtType = iter->second.begin(); // while (iterEvtType != iter->second.end()) // { // //Hit pass // if (iterEvtType->first == SMEVT_PASS) // { // Thread_UnLock(); // //return (CountOfLocal + CountOfExternal + OutIdx); // if (1 == iter->second.size()) // { // //如果当前状态点下所有触发事件都是自动触发的,则自动跳转到下一个状态点 // return (CountOfLocal +/* CountOfExternal +*/ OutIdx); // } // else // { // //已经确定状态点下还有手动触发的事件,没有必要继续判断,直接跳出当前循环 // break; // } // } // // ++iterEvtType; // // } // // } // else // { // //没有映射的话,认为BLOCK // mLog::Warn("no map for Event:%s", pszEvtName); // } // } // // } // // //优先处理 // int ReadEvetRet = ReadForDeviceEvents(pTarget, pLocalEvts, CountOfLocal, /*pExternalEvts, CountOfExternal,*/ pOutpathEvts, CountOfOutpath, timeout); // if (ReadEvetRet != -1) // { // Thread_UnLock(); // return ReadEvetRet; // } // // Thread_UnLock(); // // ReadEvetRet = WaitForDeviceEvents(pTarget, pLocalEvts, CountOfLocal, /*pExternalEvts, CountOfExternal,*/ pOutpathEvts, CountOfOutpath, timeout); // // return ReadEvetRet; //} //const char* StateMachineDevicePool::GetStateMachineEventName(DWORD DevIdx, const char* pKey, const char* pVal) //{ // map>>::iterator iter = m_pHardwareEventMap->find(DevIdx); // if (iter != m_pHardwareEventMap->end()) // { // map>::iterator iterkey = iter->second.find(pKey); // if (iterkey != iter->second.end()) // { // map::iterator iterval = iterkey->second.find(pVal); // if (iterval != iterkey->second.end()) // { // return iterval->second.c_str(); // } // } // } // // return NULL; //} int StateMachineDevicePool::ReadForDeviceEvents(ResDataObject& resNotfiy, DWORD timeout, int nMaxNotifyNum) { vector devList; vector waitList; //wait [threadexit]+[StateMachinesEvent]+[all device event] waitList.push_back(m_ThreadExitHandle); //waitList.push_back(pTarget->GetEvtNotifyHandle()); map::iterator iter = m_pDevlist->begin(); while (iter != m_pDevlist->end()) { devList.push_back(iter->first); waitList.push_back(iter->second->GetNotifyHandle()); ++iter; } int nNotifyCount = 0; DWORD FirstTick = GetTickCount(); DWORD waitUseTime = 0; long long waitTime = timeout; while(true) { DWORD wait_ret = WaitForMultipleObjects((DWORD)waitList.size(), waitList.data(), FALSE, waitTime); waitUseTime = GetTickCount() - FirstTick; waitTime = waitTime - waitUseTime; if (wait_ret == WAIT_TIMEOUT) { if (waitTime <= 0 || nNotifyCount >= nMaxNotifyNum) { //时间到了 if (nNotifyCount > 0) return nNotifyCount; return -1;//timeout error } } else if (wait_ret == WAIT_OBJECT_0) { return -3;//exit thread } //stepB1:got hardware event else if (wait_ret > WAIT_OBJECT_0) { DWORD HitIdx = wait_ret - WAIT_OBJECT_0 - 1; DWORD DevIdx = devList[HitIdx]; LogicClient* pClient = (*m_pDevlist)[DevIdx]; while (pClient->IsDataArrived()) { nNotifyCount++; ResDataObject ReadNotify; PACKET_CMD notifycmd = pClient->ReadNotify(ReadNotify); string strKey = PacketAnalizer::GetPacketKey(&ReadNotify); if (notifycmd == PACKET_CMD_UPDATE) { //将通知事件上报即可 ResDataObject resDevicePath; pClient->GetFilePath(resDevicePath); resNotfiy.add(((string)resDevicePath + "." + strKey).c_str(), ReadNotify); } if (nNotifyCount >= nMaxNotifyNum) return nNotifyCount; } } } return nNotifyCount; } //int StateMachineDevicePool::ReadForDeviceEventsEx( // DiosStMRouteLine* pEvts[], DWORD Count, // DWORD timeout //) //{ // //获取SMEVT_READATTR属性的状态机事件FROM [Outpath,External,Local]. // for (DWORD OutIdx = 0; OutIdx < Count; OutIdx++) // { // DiosStMEvt* pEvt = (*(pEvts[OutIdx])); // const char* pszEvtName = pEvt->GetEvtContext().GetKey(0); // map>>>::iterator iter = m_pEventMap->find(pszEvtName); // if (iter != m_pEventMap->end()) // { // //获取SMEVT_READATTR属性的状态机事件 // map>>::iterator iterEvtType = iter->second.find(SMEVT_READATTR); // if (iterEvtType != iter->second.end()) // { // //获取匹配的设备列表&属性列表. // map>::iterator iterDevice = iterEvtType->second.begin(); // while (iterDevice != iterEvtType->second.end()) // { // //check exit flag // if (WaitForSingleObject(m_ThreadExitHandle, 0) == WAIT_OBJECT_0) // { // mLog::FDEBUG("Exit Thread"); // return -3;//exit thread // } // // //更新资源 // ResDataObject DevRes; // LogicClient* pClient = (*m_pDevlist)[iterDevice->first]; // if (pClient->UpdateDeviceResource(timeout) >= RET_SUCCEED && pClient->GetDeviceResource(&DevRes) >= RET_SUCCEED) // { // //匹配 // try { // map::iterator iterkeyval = iterDevice->second.begin(); // while (iterkeyval != iterDevice->second.end()) // { // const char* pVal = DevRes["Attribute"][iterkeyval->first.c_str()]; // if (iterkeyval->second == pVal) // { // //got match // mLog::FINFO("Event[%s] hit match of read key[%s]:val[%s] on device:%s", // pszEvtName, // iterkeyval->first.c_str(), // iterkeyval->second.c_str(), // (*m_pDevpath)[iterDevice->first].c_str() // ); // // return OutIdx; // } // // ++iterkeyval; // } // // // // } // catch (ResDataObjectExption& exp) // { // //exp.what() // string errinfo = formatstdStringA("%s", exp.what()); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str()); // return -2;//device error // } // catch (...) // { // string errinfo = formatstdStringA("Unknown Exp Happened\n"); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str()); // return -2;//device error // } // // } // else // { // string errinfo = formatstdStringA("UpdateDeviceResource or GetDeviceResource failed on Device:%s", (*m_pDevpath)[iterDevice->first].c_str()); // mLog::FERROR("%s", errinfo.c_str()); // PushErrInfo(errinfo.c_str()); // return -2;//device error // } // // // ++iterDevice; // } // // // } // } // // } // // return -1;//timeout or not match //} //尝试检查 设备Notify事件,如果有皆大欢喜,如果没有,霸王硬上弓,更新设备属性获取新值 //这里先检查Out事件 //后检查in事件 //int StateMachineDevicePool::ReadForDeviceEvents( // DiosSMachineIF* pTarget, // DiosStMRouteLine* pLocalEvts[], DWORD CountOfLocal, // //DiosStMRouteLine* pExternalEvts[], DWORD CountOfExternal, // DiosStMRouteLine* pOutpathEvts[], DWORD CountOfOutpath, // DWORD timeout //) //{ // //尝试读取通知. // int WaitRet = WaitForDeviceEvents(pTarget, pLocalEvts, CountOfLocal, /*pExternalEvts, CountOfExternal,*/ pOutpathEvts, CountOfOutpath, 0); // if (WaitRet != -1) // { // return WaitRet; // } // // //got timeout // WaitRet = ReadForDeviceEventsEx(pOutpathEvts, CountOfOutpath, timeout); // if (WaitRet != -1) // { // if (WaitRet >= 0) // { // return (CountOfLocal + /*CountOfExternal +*/ WaitRet); // } // // return WaitRet; // } // // //WaitRet = ReadForDeviceEventsEx(pExternalEvts, CountOfExternal, timeout); // //if (WaitRet != -1) // //{ // // if (WaitRet >= 0) // // { // // return (CountOfLocal + WaitRet); // // } // // return WaitRet; // //} // // WaitRet = ReadForDeviceEventsEx(pLocalEvts, CountOfLocal, timeout); // if (WaitRet != -1) // { // return WaitRet; // } // // return WaitRet; //} //这里是等待 pTarget 状态机的事件发生 //如果是状态机的自己的状态发生了变化,也返回 // 或者是设备的Notify来了 //int StateMachineDevicePool::WaitForDeviceEvents( // DiosSMachineIF* pTarget, // DiosStMRouteLine* pLocalEvts[], DWORD CountOfLocal, // //DiosStMRouteLine* pExternalEvts[], DWORD CountOfExternal, // DiosStMRouteLine* pOutpathEvts[], DWORD CountOfOutpath, // DWORD timeout //) //{ // // vector devList; // vector waitList; // //wait [threadexit]+[StateMachinesEvent]+[all device event] // waitList.push_back(m_ThreadExitHandle); // waitList.push_back(pTarget->GetEvtNotifyHandle()); // map::iterator iter = m_pDevlist->begin(); // while (iter != m_pDevlist->end()) // { // devList.push_back(iter->first); // waitList.push_back(iter->second->GetNotifyHandle()); // ++iter; // } // // do // { // DWORD FirstTick = GetTickCount(); // // DWORD wait_ret = WaitForMultipleObjects((DWORD)waitList.size(), waitList.data(), FALSE, timeout); // // Thread_Lock();// // // if (wait_ret == WAIT_TIMEOUT) // { // // if (timeout != 0) // { // string errinfo = formatstdStringA("Wait Event Timeout(%d)", timeout); // mLog::FERROR("%s", errinfo.c_str()); // // PushErrInfo(errinfo.c_str(), DSM_ERROR_WAITEVENT_TIMEOUT); // } // else // { // //normal // mLog::FINFO("%s", "no Event in Que"); // } // // Thread_UnLock(); // return -1;//timeout error // } // else if (wait_ret == WAIT_OBJECT_0) // { // Thread_UnLock(); // return -3;//exit thread // } // else if (wait_ret == WAIT_OBJECT_0 + 1) // { // //stepA2:pop event,check the statemachine event exist in local&external&outpath,if so then return index. // DiosStMEvt Evt; // while (pTarget->PopEvent(Evt)) // { // ResDataObject& EvtContext = Evt.GetEvtContext(); // printf("PopEvt Key[%s]:Val[%s]", EvtContext.GetKey(0), (const char*)EvtContext[0]); // mLog::FDEBUG("PopEvt Key[%s]:Val[%s]", EvtContext.GetKey(0), (const char*)EvtContext[0]); // // int result = FindEventIndex(Evt, pLocalEvts, CountOfLocal, /*pExternalEvts, CountOfExternal,*/ pOutpathEvts, CountOfOutpath); // if (result != -1) // { // Thread_UnLock(); // return result; // } // } // } // //stepB1:got hardware event // else if (wait_ret > WAIT_OBJECT_0 + 1) // { // DWORD HitIdx = wait_ret - WAIT_OBJECT_0 - 2; // DWORD DevIdx = devList[HitIdx]; // LogicClient* pClient = (*m_pDevlist)[DevIdx]; // while (pClient->IsDataArrived()) // { // ResDataObject ReadNotify; // PACKET_CMD notifycmd = pClient->ReadCmd(ReadNotify); // // string strKey = PacketAnalizer::GetPacketKey(&ReadNotify); // // //if (notifycmd == PACKET_CMD_ADD) // //{ // // //stepB2:check Error Event,if so then return error index.(-1) // // if (strKey == "ErrorList") // // { // // Thread_UnLock(); // // return -2;//device error // // } // //} // if (notifycmd == PACKET_CMD_UPDATE) // { // ResDataObject ResNotify; // PacketAnalizer::GetPacketContext(&ReadNotify, ResNotify); // //stepB3:translate hardware event -> statemachine event. // //这里将设备通知通过 当前状态的 事件进行遍历,检查哪个事件符合 触发条件,则返回目标事件 // const char* pStateEventName = GetStateMachineEventName(DevIdx, strKey.c_str(), ResNotify); // if (pStateEventName) // { // DiosStMEvt Evt; // Evt.SetEvt(pStateEventName, NULL); // // mLog::FINFO("Trigger Event:%s\n", pStateEventName); // //stepB4:check the statemachine event exist in local&external&outpath,if so then return index. // int result = FindEventIndex(Evt, pLocalEvts, CountOfLocal, /*pExternalEvts, CountOfExternal,*/ pOutpathEvts, CountOfOutpath); // if (result != -1) // { // Thread_UnLock(); // mLog::FINFO("Event:%s maps[%d]\n", pStateEventName, result); // return result; // } // // // } // // } // // // // } // // } // // Thread_UnLock(); // // // // DWORD PassedTimePeriod = GetTickCount() - FirstTick; // // if (PassedTimePeriod < timeout) // { // timeout -= PassedTimePeriod; // } // else // { // break; // } // // // } while (timeout); // // if (timeout != 0) // { // string errinfo = formatstdStringA("Wait Event Timeout(%d)", timeout); // mLog::FERROR("%s", errinfo.c_str()); // // PushErrInfo(errinfo.c_str(), DSM_ERROR_WAITEVENT_TIMEOUT); // } // else // { // //normal // mLog::FINFO("%s", "no Event in Que"); // } // // return -1;//timeout error // //}