12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352 |
- #include "stdafx.h"
- #include "DiosSMachineV3.h"
- #include "PacketAnalizer.h"
- #include <functional>
- #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<char> 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<ResDataObject>();
- m_pDevpath = new map<DWORD, string>();
- m_pDevlist = new map<DWORD, LogicClient*>();
- m_pActionDevList = new map<DWORD, LogicClient*>();
- //m_pActionMap = new map<string, map<string, map<DWORD, map<string, ResDataObject>>>>();
- //m_pEventMap = new map<string, map<SMEVTTYPE, map<DWORD, map<string, string>>>>();
- //m_pHardwareEventMap = new map<DWORD, map<string, map<string, string>>>();
- }
- 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<DWORD, string>::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<DWORD, string>::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<DWORD, LogicClient*>::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<DWORD, map<string, ResDataObject>>* 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<string, map<string, map<DWORD, map<string, ResDataObject>>>>::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<string, map<DWORD, map<string, ResDataObject>>>::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<DWORD, map<string, ResDataObject>>::iterator iterDev = iter1->second.begin();
- // while (iterDev != iter1->second.end())
- // {
- // map<string, ResDataObject>::iterator iterAction = iterDev->second.begin();
- // while (iterAction != iterDev->second.end())
- // {
- // ret = 1;
- //
- // (*pDeviceActions)[iterDev->first][iterAction->first] = iterAction->second;
- //
- // ++iterAction;
- // }
- //
- // ++iterDev;
- // }
- //
- // return ret;
- //
- //
- //}
- /// <summary>
- /// 新版执行设备组的Action
- /// 状态机Action处理,调用设备的action
- /// </summary>
- /// <param name="resActions">要执行的设备Action资源</param>
- /// <param name="resResult">执行的结果保存 返回值:DeviceName.ActionName : resResp</param>
- /// <param name="pVariable">输入用户变量</param>
- /// <param name="Timeout">超时时间</param>
- /// <returns>DIOSSMRET_OK 执行成功</returns>
- 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<DWORD, map<string, ResDataObject>> 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<DWORD> ClientIdx;
- // vector<string> ActionIdx;
- // vector<HANDLE> ResHandle;
- //
- // vector<LogicClient*> ClientsObj;
- //
- // //线程退出事件
- // ResHandle.push_back(m_ThreadExitHandle);
- //
- // //异步发起ActionReq
- // map<DWORD, map<string, ResDataObject>>::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<string, ResDataObject>::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<string, map<SMEVTTYPE, map<DWORD, map<string, string>>>>::iterator iter = m_pEventMap->find(pszEvtName);
- // if (iter != m_pEventMap->end())
- // {
- // map<SMEVTTYPE, map<DWORD, map<string, string>>>::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<DWORD, map<string, map<string, string>>>::iterator iter = m_pHardwareEventMap->find(DevIdx);
- // if (iter != m_pHardwareEventMap->end())
- // {
- // map<string, map<string, string>>::iterator iterkey = iter->second.find(pKey);
- // if (iterkey != iter->second.end())
- // {
- // map<string, string>::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<DWORD> devList;
- vector<HANDLE> waitList;
- //wait [threadexit]+[StateMachinesEvent]+[all device event]
- waitList.push_back(m_ThreadExitHandle);
- //waitList.push_back(pTarget->GetEvtNotifyHandle());
- map<DWORD, LogicClient*>::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<string, map<SMEVTTYPE, map<DWORD, map<string, string>>>>::iterator iter = m_pEventMap->find(pszEvtName);
- // if (iter != m_pEventMap->end())
- // {
- // //获取SMEVT_READATTR属性的状态机事件
- // map<SMEVTTYPE, map<DWORD, map<string, string>>>::iterator iterEvtType = iter->second.find(SMEVT_READATTR);
- // if (iterEvtType != iter->second.end())
- // {
- // //获取匹配的设备列表&属性列表.
- // map<DWORD, map<string, string>>::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<string, string>::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<DWORD> devList;
- // vector<HANDLE> waitList;
- // //wait [threadexit]+[StateMachinesEvent]+[all device event]
- // waitList.push_back(m_ThreadExitHandle);
- // waitList.push_back(pTarget->GetEvtNotifyHandle());
- // map<DWORD, LogicClient*>::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
- //
- //}
|