// mod_selfchecker.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" #include "mod_selfchecker.h" #include "EventCode.h" #include "ModuleMix.h" #include "SpHelper.h" //read from config file? oiltmp const int MAX_RESTART_COUNT = 5; void SelfCheckerSession::Handle_RealCheck(SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); m_pEntity->RealCheck(ctx); } void SelfCheckerSession::Handle_GetEntityErrorList(SpReqAnsContext::Pointer ctx) { m_pEntity->GetEntityErrorList(ctx); } ErrorCodeEnum CSelfCheckerEntity::GetLiveEntityList(CAutoArray &LiveEntitys) { ErrorCodeEnum errCode; errCode = m_fsm.GetAllLiveEntity(LiveEntitys); return errCode; } ErrorCodeEnum CSelfCheckerEntity::GetEntityTestCode(const char *pszEntityName,ErrorCodeEnum &LastTestError, TestActionEnum &eLastAction) { return Error_NotImpl; } ErrorCodeEnum CSelfCheckerEntity::ExamineEntity(const char *pszEntityName) { CSmartPointer pFunc = GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CSmartPointer spWait; //ErrorCodeEnum errCode; pFuncPrivilege->TestEntity(pszEntityName,Test_Examine,spWait); return Error_Succeed; } //ErrorCodeEnum CSelfCheckerEntity::AddEntity(const char *pszEntityName) //{ // if (pszEntityName == NULL) // return Error_Null; // return m_fsm.AddEntity(pszEntityName); //} //ErrorCodeEnum CSelfCheckerEntity::RemoveEntity(vector &entityVec, const char *pszEntityName) //{ // if (pszEntityName == NULL) // return Error_Null; // return m_fsm.RemoveEntity(pszEntityName); //} //ErrorCodeEnum CSelfCheckerEntity::CheckEntity() //{ // return Error_Succeed; //} // if pszTriggerEntity=null mean created by shell void CSelfCheckerEntity::OnCreated(const char *pszEntityName,ErrorCodeEnum eOnStartErrorCode,const char *pszCallerEntity) { m_fsm.DoOnCreated(pszEntityName,eOnStartErrorCode,pszCallerEntity); } //Call after the entity has close or killed, eOnCloseErrorCode notic if the entity do OnClose normally and resource has beed release void CSelfCheckerEntity::OnClosed(const char *pszEntityName,EntityCloseCauseEnum eCloseCause,ErrorCodeEnum eOnCloseErrorCode,const char *pszCallerEntity) { m_fsm.DoOnClosed(pszEntityName,eCloseCause,eOnCloseErrorCode,pszCallerEntity); } //the following OnException & OnEntityStateHook doing the same thing repeatly??? //1 case is entity raise exception and catch by framework,but not mean the entity will close,2 case is the entity is enter lost state void CSelfCheckerEntity::OnException(const char *pszEntityName,const char *pszFunctionName,EntityStateEnum eState,EntityStateEnum eLastState,ErrorCodeEnum eErrorCode) { m_fsm.DoOnException(pszEntityName,pszFunctionName,eState,eLastState,eErrorCode); } void CSelfCheckerEntity::OnEntityStateHook(const char *pszEntityName,const char *pszTriggerEntity,EntityStateEnum eState,EntityStateEnum eLastState) { Dbg("%s trigger by %s: from %s to %s",pszEntityName,pszTriggerEntity, SpStrEntityState(eLastState), SpStrEntityState(eState)); m_fsm.AddEntityState(pszEntityName,eState); CSmartPointer pFunc = GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); if (pFuncPrivilege == NULL) { Dbg("NoPrivilege"); return; } CSmartPointer spWait; ErrorCodeEnum errCode; int count = 0; //oiltest //if (!_strnicmp("MediaController",pszEntityName,strlen("MediaController"))) { switch(eState) { case EntityState_Lost: //doing nothing except for loading stage. HandShake will take it. //and only for MediaController module. if (m_bEverInMainPage && _strnicmp("TokenKeeper",pszEntityName,strlen("TokenKeeper")) == 0) { Dbg("TokenKeeper lost"); LogEvent(Severity_Middle,LOG_EVT_SELFCHECK_TOKEN_KEEPER_LOST,"TokenKeeper lost,restart and auth again."); break; } if (m_bEverInMainPage) break; if (_strnicmp("MediaController",pszEntityName,strlen("MediaController")) != 0) break; count = m_entityProcInfo[pszEntityName].restartTimes; if (count >= MAX_RESTART_COUNT) { Dbg("%s has restart %d times,give up to restart it again.",pszEntityName,count); char xxx[256] = {0}; sprintf(xxx,"%s restart %d times,give up.",(LPCTSTR)pszEntityName,count); Dbg("logwarn %s",xxx); LogWarn(Severity_Middle,Error_Unexpect,LOG_WARN_SELFCHECK_ENTITY_LOST_TIMES,xxx); break; } Dbg("%s lost count %d",pszEntityName,count); errCode = pFuncPrivilege->TerminateEntity(pszEntityName,spWait); if (errCode == Error_Succeed) { errCode = spWait->WaitAnswer(10000); Dbg("onlost kill wait %d",errCode); } else Dbg("onlost kill %d",errCode); Sleep(5000); Dbg("to start(lost)"); errCode = pFuncPrivilege->StartEntity(pszEntityName,NULL,spWait); if (errCode == Error_Succeed) { errCode = spWait->WaitAnswer(10000); Dbg("onlost start wait %d",errCode); } else Dbg("onlost start %d",errCode); m_entityProcInfo[pszEntityName].restartTimes = count + 1; break; case EntityState_Idle: if (!_strnicmp("AssistantChannel",pszEntityName,strlen("AssistantChannel"))) { if (m_pAssChanClient != NULL) { m_pAssChanClient->SafeDelete(); m_pAssChanClient = NULL; } Dbg("AssistantChannel change to idle."); LogEvent(Severity_Middle,LOG_EVT_SELFCHECK_ASSISTANTCHANNEL_IDLE,"AssistantChannel to idle."); ConnectToAssistChannel(); } if (!_strnicmp("SIPPhone",pszEntityName,strlen("SIPPhone"))) { Dbg("SIPPhone change to idle."); LogEvent(Severity_Middle,LOG_EVT_SELFCHECK_SIPPHONE_IDLE,"SIPPhone to idle."); } if (!_strnicmp("IEBrowser",pszEntityName,strlen("IEBrowser"))) { //Dbg("selfchecker to connect healthmanager..."); //ConnectToHealthManager(); Dbg("IEBrowser change to idle."); LogEvent(Severity_Middle,LOG_EVT_SELFCHECK_IEBROWSER_IDLE,"IEBrowser to idle."); m_bIEIdle = true; } if (!_strnicmp("HealthManager", pszEntityName, strlen("HealthManager"))) { //Dbg("selfchecker to connect healthmanager...after healthmanager have been restarted."); //ConnectToHealthManager(); } if (!_strnicmp("LocalMediaPlay",pszEntityName,strlen("LocalMediaPlay"))) { Dbg("LocalMediaPlay change to idle."); LogEvent(Severity_Middle,LOG_EVT_SELFCHECK_LOCALMEDIAPLAY_IDLE,"LocalMediaPlay to idle."); } break; default: break; } } } void CSelfCheckerEntity::OnUserStateHook(const char *pszEntityName,DWORD dwState,DWORD dwLastState) { } void CSelfCheckerEntity::OnCeateConnection(const char *pszCallerEntity,const char *pszServiceEntity) { } void CSelfCheckerEntity::OnCloseConnection(const char *pszCallerEntity,const char *pszServiceEntity) { } void CSelfCheckerEntity::RealCheck(SpReqAnsContext::Pointer ctx) { Dbg("Real check %s",(LPCTSTR)ctx->Req.name); m_fsm.CheckEntity(ctx->Req.name,Test_ShakeHand); ctx->Answer(Error_Succeed); } void CSelfCheckerEntity::GetEntityErrorList(SpReqAnsContext::Pointer ctx) { ErrorCodeEnum eErr = m_fsm.GetEntityErrorList(ctx->Ans.warmLevel,ctx->Ans.list); ctx->Answer(eErr); } void CSelfCheckerEntity::OnLog(const CAutoArray &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage) { //oilyang@20200304 add process FWB open suc. if (dwUserCode == LOG_EVT_CARDREADER_OPEN_SUC_FWB) { //Dbg("fwb user code %d,%s", dwUserCode, (LPCTSTR)pszMessage); //m_fsm.CheckEntity("PinPad", Test_ShakeHand); //m_fsm.CheckEntity("FingerPrint", Test_ShakeHand); //m_fsm.CheckEntity("IDCertificate", Test_ShakeHand); //m_fsm.CheckEntity("Sensors", Test_ShakeHand); //m_fsm.CheckEntity("DeviceControl", Test_ShakeHand); } //oilyang@20200407 move the following RestartModule from Healthmanager to here switch (dwUserCode) { case LOG_EVT_CARDSWIPER_PINPAD_RESTART: { RestartModule("PinPad"); } break; case LOG_EVT_CARDSWIPER_CARDSWIPER_RESTART: { RestartModule("CardSwiper"); } break; case LOG_EVT_CARDSWIPER_DEVICECONTROL_RESTART: { RestartModule("DeviceControl"); } break; case LOG_EVT_CARDSWIPER_IDCERTIFICATE_RESTART: { RestartModule("IDCertificate"); } break; case LOG_EVT_CARDSWIPER_FINGERPRINT_RESTART: { RestartModule("FingerPrint"); } break; case LOG_EVT_CARDSWIPER_SENSORS_RESTART: { RestartModule("Sensors"); } break; } //oilyang@20170918 only process the Log_Error of Severity_High if (eLogType != Log_Error || eLevel != Severity_High) return; Dbg("user code %d,%s",dwUserCode,(LPCTSTR)pszMessage); switch(dwUserCode) { //case LOG_ERR_CARDISSUER_FAILED: //case LOG_ERR_CARDREADER_FAILED: //case LOG_ERR_IDCERTIFICATE_FAILED: case LOG_ERR_PINPAD_FAILED: case ERROR_MOD_MEDIACONTROLLER_ENVCAMERA_BUG: case ERROR_MOD_MEDIACONTROLLER_OPECAMERA_BUG: case ERROR_MOD_MEDIACONTROLLER_ENVCAM_OPEN: case ERROR_MOD_MEDIACONTROLLER_OPTCAM_OPEN: case ERROR_MOD_MEDIACONTROLLER_ENVCAM_INITFAIL: case ERROR_MOD_MEDIACONTROLLER_OPTCAM_INITFAIL: MsgPushedByAssChannel(ACM_TYPE_DEVICE,ACM_DEVICE_ERROR,pszEntityName,pszMessage); break; default: break; } m_fsm.Proc(pszEntityName, ProcType_Warn, dwUserCode, pszMessage); } ErrorCodeEnum CSelfCheckerEntity::MsgPushedByAssChannel(const int type,const int sub_type,const char *pszEntityName,const char *pszMessage) { if (m_pAssChanClient == NULL) { ErrorCodeEnum eConn = ConnectToAssistChannel(); if (eConn != Error_Succeed) { Dbg("connect to AssistantChannel failed(%d).",eConn); return Error_Resource; } } ChannelService_Send_Info Info; Info.compress = false; Info.encrypt = false; Info.type = type;//; Info.id = 0; Info.sub_type = sub_type;//; Info.data.Alloc(sizeof(int)); SpBuffer buf; buf.OpenWrite(); CSimpleStringA csEntityName(pszEntityName),csBlack(" "),csMsg(pszMessage); buf & csEntityName & csBlack & csMsg; Info.data = buf.ToBlob(); m_pAssChanClient->Send(Info); Dbg("send msg %d %d:%s %s",type,sub_type,pszEntityName,pszMessage); return Error_Succeed; } ErrorCodeEnum CSelfCheckerEntity::GetEntityStatusStr(CSimpleStringA &result) { CSmartPointer pFunc = GetFunction(); CEntityRunInfo runInfo; ErrorCodeEnum eErr; vector::iterator it; for (it = m_vQueryStateEntity.begin(); it != m_vQueryStateEntity.end(); ++it) { eErr = pFunc->GetEntityRunInfo(*it,runInfo); if (eErr == Error_Succeed) { Dbg("%s,%d",(LPCTSTR)*it,runInfo.dwUserState); result += UserDefEntityMsg[runInfo.dwUserState][0]; result += " ;"; } } Dbg("state[%s]",(LPCTSTR)result); return Error_Succeed; } ErrorCodeEnum CSelfCheckerEntity::ConnectToAssistChannel() { LOG_FUNCTION(); if (m_pAssChanClient == NULL) { m_pAssChanClient = new AssistChannelSelfCheckerClient(this); ErrorCodeEnum ErrorConn = m_pAssChanClient->Connect(); if (ErrorConn != Error_Succeed) { m_pAssChanClient->SafeDelete(); m_pAssChanClient = NULL; return Error_Unexpect; } else { Dbg("AssistantChannel connected."); { ChannelService_BeginState_Sub Sub; ErrorConn = m_pAssChanClient->BeginState(Sub); if (ErrorConn != Error_Succeed) { Dbg("BeginState biz channel failed!"); m_pAssChanClient->GetFunction()->CloseSession(); m_pAssChanClient = NULL; return Error_Unexpect; } else { Dbg("BeginState biz channel success!"); } } { ChannelService_BeginRecv_Sub Sub; Sub.type = ACM_TYPE_DEVICE; ErrorConn = m_pAssChanClient->BeginRecv(Sub); if (ErrorConn != Error_Succeed) { Dbg("Begin BeginRecv ACM_TYPE_DEVICE failed!"); m_pAssChanClient->GetFunction()->CloseSession(); m_pAssChanClient = NULL; return Error_Unexpect; } else { Dbg("Begin BeginRecv ACM_TYPE_DEVICE success!"); } } } } return Error_Succeed; } ErrorCodeEnum CSelfCheckerEntity::RestartModule(const char* pEntityName) { Dbg("to RestartModule:%s",pEntityName); m_fsm.SetEntityRestarting(pEntityName, true); CSmartPointer pFunc = GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); if (pFuncPrivilege == NULL) { Dbg("restart mc NoPrivilege"); m_fsm.SetEntityRestarting(pEntityName, false); return Error_NoPrivilege; } CSmartPointer spWait; ErrorCodeEnum eErrCode = Error_Succeed; eErrCode = pFuncPrivilege->TerminateEntity(pEntityName, spWait); if (spWait != NULL) eErrCode = spWait->WaitAnswer(10000); if (eErrCode != Error_Succeed) { Dbg("kill %s %d", pEntityName, eErrCode); m_fsm.SetEntityRestarting(pEntityName, false); return eErrCode; } Sleep(1000); eErrCode = pFuncPrivilege->StartEntity(pEntityName, NULL, spWait); if (spWait != NULL) eErrCode = spWait->WaitAnswer(10000); if (eErrCode != Error_Succeed) { Dbg("start %s %d", pEntityName, eErrCode); m_fsm.SetEntityRestarting(pEntityName, false); return eErrCode; } m_fsm.SetEntityRestarting(pEntityName, false); return Error_Succeed; } void CSelfCheckerEntity::OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName) { if ((_strnicmp(pszKey, "UIState", strlen("UIState")) == 0)) { if (_strnicmp(pszValue, "M", strlen("M")) == 0) { m_bEverInMainPage = true; m_fsm.SetEverEnterMainPageFlag(); } } } void AssistChannelSelfCheckerClient::OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer pData) { } void AssistChannelSelfCheckerClient::OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer pData) { LOG_FUNCTION(); if (Error == Error_Succeed) { CSelfCheckerEntity *pEntity = static_cast(m_pEntityBase); switch(Msg.sub_type) { case ACM_ENTITY_STATE_REQ: { CSimpleStringA result; pEntity->GetEntityStatusStr(result); pEntity->MsgPushedByAssChannel(ACM_TYPE_DEVICE,ACM_ENTITY_STATE_ANS,result); } break; default: break; } } } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CSelfCheckerEntity) SP_END_ENTITY_MAP()