#include "stdafx.h" #define WIN32_LEAN_AND_MEAN #include #include "SelfCheckerFSM.h" #include "EventCode.h" #pragma comment(lib,"user32.lib") class CSelfCheckerEntity; const int MAX_AYSNC_TIMEOUT = 60000; const int MAX_CHECK_TIME = 60000; const int MAX_CPU_CHECK_TIME = 5000; const int TIMER_ID_CHECK = 0; const int TIMER_CPU_CHECK = 1; const int THOUSAND = 1024; const int MILLION = 1048576; int ActionStrToInt(const char* pAction) { int ret = 0; char x = *pAction; if (x >= '0' && x <= '9') return x - '0'; else return 0; } DWORD GetRadixProduct(int times, int radix) { DWORD dwRet = 1; if (times < 0 || (radix != 10 && radix != 16)) return 0; else { for (int i = 0; i < times; i++) dwRet *= radix; } return dwRet; } DWORD CodeStrToInt(const char* pCode) { CSimpleStringA csCode(pCode); csCode = csCode.Trim(); int len = csCode.GetLength(); if (len < 0 || len > 10) { return 0; } DWORD dwRet = 0; if (len > 2 && csCode[0] == '0' && (csCode[1] == 'x' || csCode[1] == 'X'))//"0x1234,0X12FF" { for (int i = 2; i < len; i++) { if (csCode[i] <= '9' && csCode[i] >= '0') dwRet += (csCode[i] - '0') * GetRadixProduct(len - i - 1, 16); else if (csCode[i] <= 'f' && csCode[i] >= 'a') dwRet += (csCode[i] - 'a' + 10) * GetRadixProduct(len - i - 1, 16); else if (csCode[i] <= 'F' && csCode[i] >= 'A') dwRet += (csCode[i] - 'A' + 10) * GetRadixProduct(len - i - 1, 16); else return 0;//because there is a invalid char,break process and return 0 } } else//"768" { for (int i = 0; i < len; i++) { if (csCode[i] <= '9' && csCode[i] >= '0') dwRet += (csCode[i] - '0') * GetRadixProduct(len - i - 1, 10); else return 0;//because there is a invalid char,break process and return 0 } } return dwRet; } ErrorCodeEnum CSelfCheckerFSM::OnInit() { m_xIdlePre = m_xKernelPre = m_xUserPre = 0; ErrorCodeEnum errCode = Initial(); if (errCode != Error_Succeed) return Error_IO; return Error_Succeed; } ErrorCodeEnum CSelfCheckerFSM::OnExit() { return Error_Succeed; } void CSelfCheckerFSM::s0_on_entry() { LOG_FUNCTION(); ErrorCodeEnum errCode; CAutoArray tmpInstIDs; CAutoArray tmpNames; errCode = GetEntityBase()->GetFunction()->GetAllRegistedEntity(tmpNames, tmpInstIDs); if (errCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get started entity failed.[%d]",errCode); } for (int i = 0; i < tmpNames.GetCount(); ++i) { ErrorCodeEnum eErr; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CEntityRunInfo runInfo; eErr = pFunc->GetEntityRunInfo(tmpNames[i], runInfo); if (runInfo.eState != EntityState_NoStart || tmpNames[i] == "Download" || tmpNames[i] == "UpgradeRun" || tmpNames[i] == "UpgradeManager") { m_allEntity.push_back(tmpNames[i]); } } FSMEvent* pEvt = new FSMEvent(USER_EVT_INIT); PostEventFIFO(pEvt); } void CSelfCheckerFSM::s0_on_exit() { } unsigned int CSelfCheckerFSM::s0_on_event(FSMEvent* pEvt) { LOG_FUNCTION(); switch (pEvt->iEvt) { case USER_EVT_INIT: pEvt->SetHandled(); break; default: break; } return 0; } void CSelfCheckerFSM::s1_on_entry() { LOG_FUNCTION(); void* pTmpData = NULL; ITimerListener* pListener = new TimerOutHelper(this, &CSelfCheckerFSM::OnNormalWorkTimerout, pTmpData); GetEntityBase()->GetFunction()->SetTimer(TIMER_ID_CHECK, pListener, MAX_CHECK_TIME); } void CSelfCheckerFSM::s1_on_exit() { LOG_FUNCTION(); } unsigned int CSelfCheckerFSM::s1_on_event(FSMEvent* evt) { LOG_FUNCTION(); return 0; } void CSelfCheckerFSM::s2_on_entry() { LOG_FUNCTION(); } void CSelfCheckerFSM::s2_on_exit() { LOG_FUNCTION(); } unsigned int CSelfCheckerFSM::s2_on_event(FSMEvent* evt) { LOG_FUNCTION(); return 0; } void CSelfCheckerFSM::s3_on_entry() { LOG_FUNCTION(); } void CSelfCheckerFSM::s3_on_exit() { LOG_FUNCTION(); } unsigned int CSelfCheckerFSM::s3_on_event(FSMEvent* evt) { LOG_FUNCTION(); return 0; } int ch2int(char ch) { if (ch >= '0' && ch <= '9') return ch - '0'; else if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10; else if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10; return 0; } long hexstr2int(const char* str, int len) { long result = 0; for (int i = 0; i < len; ++i) { result += (ch2int(str[i]) << ((len - i - 1) * 4)); } return result; } bool StrEqualNoCase(const char* s1, const char* s2, int len) { if (strlen(s1) != strlen(s2)) return false; for (int i = 0; i < len; ++i) { if (toupper(s1[i]) != toupper(s2[i])) return false; } return true; } ErrorCodeEnum CSelfCheckerFSM::Initial() { ErrorCodeEnum err; CSmartPointer spCenConfig; err = GetEntityBase()->GetFunction()->OpenConfig(Config_CenterSetting, spCenConfig); if (err != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open cfg file failed!"); return Error_IO; } m_restartNormal = 2; m_restartSpecial = 5; m_maxOsRestart = 5; m_maxPowerRestart = 5; do { int value(0); spCenConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "RestartNormal", value); if (value != 0) m_restartNormal = value; } while (false); do { int value(0); spCenConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "RestartSpecial", value); if (value != 0) m_restartSpecial = value; } while (false); do { int value(0); spCenConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "MaxOsRestart", value); if (value != 0) m_maxOsRestart = value; } while (false); do { int value(0); spCenConfig->ReadConfigValueInt(GetEntityBase()->GetEntityName(), "MaxPowerRestart", value); if (value != 0) m_maxPowerRestart = value; } while (false); //m_csKeyEntity = "PinPad"; //do { // CSimpleStringA value(true); // spCenConfig->ReadConfigValue(GetEntityBase()->GetEntityName(), "KeyEntity", value); // if (!value.IsNullOrEmpty()) m_csKeyEntity = value; //} while (false); ifstream is; CSimpleStringA cfgPath(""), cfgXml(""); err = GetEntityBase()->GetFunction()->GetPath("cfg", cfgPath); cfgXml = cfgPath + SPLIT_SLASH_STR + "SelfCheckerProc.xml"; ReadXmlFile(cfgXml); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("cfgxml[%s]", cfgXml); //auto list = m_csKeyEntity.Split(','); //for (int i = 0; i < list.GetCount(); ++i) //{ // CSimpleStringA entity = list[i]; // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", LPCTSTR(entity)); // m_vKeyEntity.push_back(entity); //} err = GetEntityBase()->GetFunction()->GetSystemStaticInfo(m_sysInfo); if (err != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get System Static info failed(%d).",err); return Error_Unexpect; } CSmartPointer spConfigRun; err = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); if (err == Error_Succeed) { spConfigRun->ReadConfigValueInt("WarnRecord", "disk", m_diskLastWarnHour); } m_activeEntity.push_back("Chromium"); return Error_Succeed; } ErrorCodeEnum CSelfCheckerFSM::ExceptionErrorProcess(const char* pszEntityName, ErrorCodeEnum eCode) { CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CSmartPointer spWait; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("proc:%s,%d", pszEntityName, eCode); //do nothing if (eCode == Error_Cancel) return Error_Succeed; bool bUpgrade = false; //need to do something ErrorCodeEnum eErrCode = Error_Succeed; if ((m_entCfgInfo.find(pszEntityName) != m_entCfgInfo.end()) && ((m_entCfgInfo[pszEntityName]).hsInfo.find(eCode) != (m_entCfgInfo[pszEntityName]).hsInfo.end())) { TestActionEnum eAction = (m_entCfgInfo[pszEntityName]).hsInfo.find(eCode)->second; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("action:%d", eAction); switch (eAction) { case ACTION_EXAMINE: break; case ACTION_RESET: break; case ACTION_CLOSE: eErrCode = pFuncPrivilege->CloseEntity(pszEntityName, spWait); if (eErrCode == Error_Succeed) { } break; case ACTION_ENTITY_RESTART: { if (m_entCfgInfo[pszEntityName].bWaitRestart) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("waiting restart..."); break; } //if (m_entRunInfo[pszEntityName].loadOpt == 99) //{ // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("not configure? name:[%s]", pszEntityName); // break; //} //LogErrInfo("restart ",pszEntityName,eCode); m_entCfgInfo[pszEntityName].entityRestartCount++; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("normalcount:%d,count:%d", m_restartNormal, m_entCfgInfo[pszEntityName].entityRestartCount); if (m_entCfgInfo[pszEntityName].entityRestartCount > m_restartNormal) { if ((!strnicmp(m_sysInfo.strMachineType.GetData(), "RVC.Pad", strlen("RVC.Pad")) && !strnicmp(m_sysInfo.strSite.GetData(), "cmb.FLB", strlen("cmb.FLB"))) || (!strnicmp(m_sysInfo.strMachineType.GetData(), "RPM.Stand1S", strlen("RPM.Stand1S")))) { if (m_entRunInfo[pszEntityName].loadOpt == 0) m_entCfgInfo[pszEntityName].entityRestartCount = 0; } else { LogErrInfo(pszEntityName, " restart too many,upgrade process.", eCode); bUpgrade = true; m_entCfgInfo[pszEntityName].bWaitRestart = true; } eErrCode = Error_Succeed; break; } eErrCode = pFuncPrivilege->StopEntity(pszEntityName, spWait); if (eErrCode == Error_Succeed) { eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait stop %s failed: %s.", pszEntityName, SpStrError(eErrCode)); eErrCode = pFuncPrivilege->TerminateEntity(pszEntityName, spWait); eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait terminate %s failed: %s.", pszEntityName, SpStrError(eErrCode)); break; } } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Stop %s failed(%d).", pszEntityName, eErrCode); break; } Sleep(2000); eErrCode = pFuncPrivilege->StartEntity(pszEntityName, NULL, spWait); if (eErrCode == Error_Succeed) { eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait start %s failed(%d).", pszEntityName, eErrCode); break; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Start entity %s suc.", pszEntityName); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("(re)Start %s failed(%d).", pszEntityName, eErrCode); break; } } break; case ACTION_OS_RESTART: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("test os restart"); if (m_entRunInfo[pszEntityName].loadOpt == 1 || m_entRunInfo[pszEntityName].loadOpt == 2) LogEvent(Severity_Middle, LOG_EVT_SELFCHECK_OS_RESTART, pszEntityName); break; case ACTION_POWER_RESTART: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("test power restart"); if (m_entRunInfo[pszEntityName].loadOpt == 1 || m_entRunInfo[pszEntityName].loadOpt == 2) LogEvent(Severity_Middle, LOG_EVT_SELFCHECK_POWER_RESTART, pszEntityName); break; default: break; } if (bUpgrade) { LogActionProcess(pszEntityName, eCode, eAction); } } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s not configured,use default setting(%d)", LPCTSTR(pszEntityName), eCode); switch (eCode) { case Error_TimeOut: case Error_Unexpect: case Error_InvalidState: { eErrCode = pFuncPrivilege->StopEntity(pszEntityName, spWait); if (eErrCode == Error_Succeed) { eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait stop %s failed: %s.", pszEntityName, SpStrError(eErrCode)); eErrCode = pFuncPrivilege->TerminateEntity(pszEntityName, spWait); eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait terminate %s failed: %s.", pszEntityName, SpStrError(eErrCode)); break; } } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Stop %s failed(%d).", pszEntityName, eErrCode); break; } Sleep(5000); eErrCode = pFuncPrivilege->StartEntity(pszEntityName, NULL, spWait); if (eErrCode == Error_Succeed) { eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait start %s failed(%d).", pszEntityName, eErrCode); break; } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("(re)Start %s failed(%d).", pszEntityName, eErrCode); break; } } break; default: break; } } return eErrCode; } ErrorCodeEnum CSelfCheckerFSM::CheckEntity(const char* pszEntityName, EntityTestEnum eTestType, bool bNormalCheck) { if (bNormalCheck) { //oilyang@20230426 ,常规自检时,针对"TerminalStage"做对应处理(自检分常规自检和即时自检) //"S":准入服务告知准入不过,不再进行实体自检 //非"A":其他启动失败导致进关门页,不再对硬件以及其他没必要自检的实体进行自检 CSimpleStringA tmpTerminalStage(""); GetEntityBase()->GetFunction()->GetSysVar("TerminalStage", tmpTerminalStage); if (tmpTerminalStage.Compare("S") == 0) return Error_Succeed; else if (tmpTerminalStage.Compare("A") != 0) { //the hardward entity and some other entity no need to test if (_strnicmp("PinPad", pszEntityName, strlen("PinPad")) == 0 || _strnicmp("CardIssuer", pszEntityName, strlen("CardIssuer")) == 0 || _strnicmp("CardSwiper", pszEntityName, strlen("CardSwiper")) == 0 || _strnicmp("ContactlessCard", pszEntityName, strlen("ContactlessCard")) == 0 || _strnicmp("IDCertificate", pszEntityName, strlen("IDCertificate")) == 0 || _strnicmp("gpio", pszEntityName, strlen("gpio")) == 0 || _strnicmp("HSPScanner", pszEntityName, strlen("HSPScanner")) == 0 || _strnicmp("FingerPrint", pszEntityName, strlen("FingerPrint")) == 0 ) return Error_Succeed; } } //oilyang@20170926 no need to check by self.Let the HealthManager entity to do it. //oilyang@20231106 no need to check VtmLoader if (pszEntityName != NULL && (strnicmp(pszEntityName, GetEntityBase()->GetEntityName(), strlen(GetEntityBase()->GetEntityName())) == 0 || strnicmp(pszEntityName, "VtmLoader", strlen("VtmLoader")) == 0)) return Error_Succeed; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CSmartPointer spWait; ErrorCodeEnum errCode; errCode = pFuncPrivilege->TestEntity(pszEntityName, eTestType, spWait); if (errCode == Error_Succeed) { callback_entry* entry = new callback_entry(); entry->pRawData = NULL; entry->EntityName = pszEntityName; entry->ErrorResult = Error_Unexpect; entry->op = Test_ShakeHand; spWait->SetCallback(this, entry); } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Test %s,%d", pszEntityName, errCode); return errCode; } void CSelfCheckerFSM::OnNormalWorkTimerout(void* pData) { if (!m_bFWBEntityAdd) { //oilyang@20220415 special process of RVC.PAD with FWB CSimpleStringA tmpFWBDevSN(""); GetEntityBase()->GetFunction()->GetSysVar("FWBDevSN", tmpFWBDevSN); if (m_sysInfo.strMachineType.Compare("RVC.PAD", true) == 0 && !tmpFWBDevSN.IsNullOrEmpty()) { AddFWBEntityToList(); m_bFWBEntityAdd = true; } } CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CSmartPointer spWait; ErrorCodeEnum errCode; int activeEnCount = m_activeEntity.size(); vector::iterator it; //oiltmp 20131219 //GetSystemCPUStatus(); //GetSystemMemoryStatus(); //GetSystemDiskStatus(); for (it = m_activeEntity.begin(); it != m_activeEntity.end(); ++it) { errCode = CheckEntity(*it, Test_ShakeHand); CEntityRunInfo runInfo; pFunc->GetEntityRunInfo(*it, runInfo); //CheckEntityResouce(*it, runInfo); } GetEntityBase()->GetFunction()->ResetTimer(TIMER_ID_CHECK, MAX_CHECK_TIME); } void CSelfCheckerFSM::DoOnCreated(const char* pszEntityName, ErrorCodeEnum eOnStartErrorCode, const char* pszCallerEntity) { } void CSelfCheckerFSM::DoOnClosed(const char* pszEntityName, EntityCloseCauseEnum eCloseCause, ErrorCodeEnum eOnCloseErrorCode, const char* pszCallerEntity) { } void CSelfCheckerFSM::DoOnException(const char* pszEntityName, const char* pszFunctionName, EntityStateEnum eState, EntityStateEnum eLastState, ErrorCodeEnum eErrorCode) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("OnException:%s,%s,%d,%d,%d", pszEntityName, pszFunctionName, eState, eLastState, eErrorCode); } void CSelfCheckerFSM::OnAnswer(CSmartPointer pAsynWaitSp) { CSmartPointer spCallback; CSmartPointer pData; pAsynWaitSp->GetCallback(spCallback, pData); //LOG_ASSERT(pData); callback_entry* entry = dynamic_cast((IReleasable*)pData.GetRawPointer()); entry->ErrorResult = pAsynWaitSp->AsyncGetAnswer(); callback_entry* new_entry = new callback_entry(); new_entry->EntityName = entry->EntityName; new_entry->ErrorResult = entry->ErrorResult; new_entry->op = entry->op; new_entry->state = entry->state; m_entRunInfo[new_entry->EntityName].eTest = new_entry->ErrorResult; //add test result oilyang 20150616 if (new_entry->op == Test_ShakeHand && new_entry->ErrorResult != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("oiltmp shakehand %s turns out %s, entity state: %s", (LPCTSTR)new_entry->EntityName, SpStrError(new_entry->ErrorResult), SpStrEntityState((EntityStateEnum)new_entry->state)); } if (new_entry->ErrorResult != Error_Succeed) { ErrorCodeEnum eErr; CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); if (_strnicmp("MediaController", (const char*)new_entry->EntityName, strlen("MediaController")) == 0 && !m_bEverInMainPage) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("On loading stage,don't process MediaController exception."); } else Proc((const char*)new_entry->EntityName, ProcType_Shake, new_entry->ErrorResult); } else { CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErr = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open run cfg file failed!"); return; } spConfig->WriteConfigValueInt(new_entry->EntityName, "OsRestart", 0); spConfig->WriteConfigValueInt(new_entry->EntityName, "PowerRestart", 0); } } void CSelfCheckerFSM::LogErrInfo(const char* msgHead, const char* msgBody, const int errCode) { //oiltest to redifine this DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s,%s,%d", msgHead, msgBody, errCode); } void CSelfCheckerFSM::LogActionProcess(const char* pszEntityName, ErrorCodeEnum errCode, TestActionEnum eAct) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("LogActionProcess:entity[%s],errCode[%d],eAction[%d]", pszEntityName, errCode, eAct); CSmartPointer spEntityFunction = GetEntityBase()->GetFunction(); CSmartPointer spConfig; ErrorCodeEnum eErr = spEntityFunction->OpenConfig(Config_Run, spConfig); if (eErr != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open run cfg file failed!"); return; } int osTimes, powerTimes; osTimes = powerTimes = 0; spConfig->ReadConfigValueInt(pszEntityName, "OsRestart", osTimes); spConfig->ReadConfigValueInt(pszEntityName, "PowerRestart", powerTimes); switch (eAct) { case ACTION_ENTITY_RESTART: if (osTimes > m_maxOsRestart || powerTimes > m_maxPowerRestart) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("restart too much,give up[%d][%d].", osTimes, powerTimes); break; } break; ///*TODO: cannot access (80374374@11/23/2023)*/ osTimes++; powerTimes++; spConfig->WriteConfigValueInt(pszEntityName, "OsRestart", osTimes); spConfig->WriteConfigValueInt(pszEntityName, "PowerRestart", powerTimes); //for simple and effective,use power restart only LogEvent(Severity_Middle, LOG_EVT_SELFCHECK_POWER_RESTART, pszEntityName); m_entCfgInfo[pszEntityName].bWaitRestart = true; break; default: break; } } void CSelfCheckerFSM::CheckEntityResouce(const char* pszEntityName, CEntityRunInfo& info) { if (info.eState != EntityState_Idle){ return; } #ifdef RVC_OS_WIN //HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, info.dwProcessID); //if (hProcess == NULL) //{ // DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("OpenProcess %s failed %d.", pszEntityName, GetLastError()); // return; //} ////GetSystemInfo //PIO_COUNTERS pIOCounters = new IO_COUNTERS; //BOOL ret = GetProcessIoCounters(hProcess, pIOCounters); //if (ret == 0) //{ // DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetProcessIoCounters %s failed %d.", pszEntityName, GetLastError()); //} //PROCESS_MEMORY_COUNTERS pmc; //const int showSize = 20; //if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) //{ // if ((pmc.WorkingSetSize / MILLION > showSize) && (pmc.PeakWorkingSetSize / MILLION > showSize) // && (pmc.PagefileUsage / MILLION > showSize) && (pmc.PeakPagefileUsage / MILLION > showSize)) // { // m_entRunInfo[pszEntityName].memoryHighCount++; // if (m_entRunInfo[pszEntityName].memoryHighCount > ((60000 / MAX_CPU_CHECK_TIME)) * 2)//more than 2 minutes // { // m_entRunInfo[pszEntityName].memoryHighCount = 0; // Dbg("%s,WorkingSetSize %u, Peak %u,PageFileUsage %u, Peak %u", (LPCTSTR)pszEntityName, pmc.WorkingSetSize / MILLION, pmc.PeakWorkingSetSize / MILLION, pmc.PagefileUsage / MILLION, pmc.PeakPagefileUsage / MILLION); // } // } //} //CloseHandle(hProcess); #else return;//oiltestlinux #endif //RVC_OS_WIN } //bool CSelfCheckerFSM::IsKeyEntity(const char* pszEntityName) //{ // vector::iterator it; // for (it = m_vKeyEntity.begin(); it != m_vKeyEntity.end(); ++it) // { // if (!_strnicmp(pszEntityName, *it, strlen(pszEntityName))) // return true; // } // return false; //} int CSelfCheckerFSM::AddEntityState(const char* pszEntityName, EntityStateEnum eState) { if (eState == EntityState_Starting) { m_entRunInfo[pszEntityName].bGetLoadOpt = false; m_entRunInfo[pszEntityName].bRestarting = false; m_entRunInfo[pszEntityName].loadOpt = 99; m_entRunInfo[pszEntityName].eState = eState; m_entRunInfo[pszEntityName].eTest = Error_Succeed; } else m_entRunInfo[pszEntityName].eState = eState; if (eState == EntityState_Idle) { m_entRunInfo[pszEntityName].eTest = Error_Succeed; m_entRunInfo[pszEntityName].memoryHighCount = 0; } m_entRunInfo[pszEntityName].cpuRatio = 0; return 0; } ErrorCodeEnum CSelfCheckerFSM::GetEntityErrorList(int& warmLevel, CSimpleStringA& strList) { map::iterator it; CSimpleStringA tmpStr(""); bool bLost = false; for (it = m_entRunInfo.begin(); it != m_entRunInfo.end(); ++it) { if (m_entRunInfo[it->first].eState == EntityState_Lost) bLost = true; char buf[16], bufTest[16]; ZeroMemory(buf, 16); ZeroMemory(bufTest, 16); if (m_entRunInfo[it->first].eState == EntityState_Lost || m_entRunInfo[it->first].eState == EntityState_Close || m_entRunInfo[it->first].eState == EntityState_Killed || m_entRunInfo[it->first].eTest != Error_Succeed) { tmpStr += it->first; tmpStr += "="; if (m_entRunInfo[it->first].eState == EntityState_Lost || m_entRunInfo[it->first].eState == EntityState_Close || m_entRunInfo[it->first].eState == EntityState_Killed) { _itoa(m_entRunInfo[it->first].eState, buf, 10); tmpStr += buf; } if (m_entRunInfo[it->first].eTest != Error_Succeed) { _itoa(m_entRunInfo[it->first].eTest, bufTest, 10); tmpStr += ",(selfcheck code):"; tmpStr += bufTest; } tmpStr += ";"; } } if (tmpStr.GetLength() < 2) m_warmLevel = warmLevel = 0; if (bLost) m_warmLevel = warmLevel = 3; m_warmLevel = warmLevel = 1;//for temp set 20150617 strList = tmpStr; if (strList.GetLength() > 2) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("warnlevel:%d,ErrorList [%s]", m_warmLevel, (LPCTSTR)strList); return Error_Succeed; } int CSelfCheckerFSM::Proc(string entity, ProcType eType, DWORD dwCode, const char* pszMessage) { map::iterator it; if ((it = m_mapEntity.find(entity.c_str())) == m_mapEntity.end()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("can't find entity %s configure setting,using default setting.", entity.c_str()); //Error_TimeOut: //Error_Unexpect: //Error_InvalidState: if (eType == ProcType_Shake && (dwCode == Error_TimeOut || dwCode == Error_Unexpect || dwCode == Error_InvalidState)) ExceptionErrorProcessXml(eType, entity.c_str(), ACTION_ENTITY_RESTART, true); else if (eType == ProcType_Warn) ExceptionErrorProcessXml(eType, entity.c_str(), dwCode, true, pszMessage); else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("What's this:type:%d,receive code:%x,msg:%s, from entity %s.", eType, dwCode, pszMessage, entity.c_str()); return -1; } vector::iterator vIt, vEnd; if (eType == ProcType_Shake) { vIt = it->second.vShake.begin(); vEnd = it->second.vShake.end(); } else if (eType == ProcType_Warn) { vIt = it->second.vWarn.begin(); vEnd = it->second.vWarn.end(); } for (; vIt != vEnd; vIt++) { if (vIt->code == dwCode) { if (vIt->upgradecount > 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("action size:%d,upgradecount:%d", vIt->proctime.size(), vIt->upgradecount); UINT64 happentime = SP::Module::Comm::RVCGetTickCount(); if (vIt->proctime.size() < vIt->upgradecount - 1)//just add record,do nothing { vIt->proctime.push_back(happentime); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("just add record"); return 0; } else { //to find the 1st record happened in last upgradetime minute //and remove the record happened far ago(upgradetime minutes before) vector::iterator ittime, itFisrtInPeriod, xxxIt; bool bFar = false; int count = 0; for (ittime = vIt->proctime.begin(); ittime != vIt->proctime.end(); ittime++) { itFisrtInPeriod = ittime; UINT64 difftime = happentime - *ittime; if (difftime / (1000 * 60) < vIt->upgradetime) break; else { count++; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("the %d th action", count); bFar = true; } } if (!bFar) { //to do upgrade action DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("to do upgrade action"); ExceptionErrorProcessXml(eType, entity.c_str(), vIt->upgradeaction); vIt->proctime.clear(); return 0; } else { if (count == 1 && vIt->proctime.size() == 1) vIt->proctime.clear(); else vIt->proctime.erase(vIt->proctime.begin(), itFisrtInPeriod); for (xxxIt = vIt->proctime.begin(); xxxIt != vIt->proctime.end(); xxxIt++) { cout << *xxxIt << " # "; } cout << endl; vIt->proctime.push_back(happentime); for (xxxIt = vIt->proctime.begin(); xxxIt != vIt->proctime.end(); xxxIt++) { cout << *xxxIt << " * "; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("after clear,add record"); return 0; } } } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Entity %s receive %d,to do action:%d", entity.c_str(), dwCode, vIt->action); ExceptionErrorProcessXml(eType, entity.c_str(), vIt->action, true, pszMessage); return 0; } } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("can't find corresponding action of entity %s,type:%d,code:%x", entity.c_str(), eType, dwCode); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("use default process..."); if (eType == ProcType_Shake && (dwCode == Error_TimeOut || dwCode == Error_Unexpect || dwCode == Error_InvalidState)) ExceptionErrorProcessXml(eType, entity.c_str(), ACTION_ENTITY_RESTART, true); else if (eType == ProcType_Warn) ExceptionErrorProcessXml(eType, entity.c_str(), dwCode, true, pszMessage); return -1; } bool CSelfCheckerFSM::ReadXmlFile(const char* szFileName) {//读取Xml文件,并遍历 //MessageBox(0, 0, 0, 0); LOG_FUNCTION(); tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument(); XMLError err = doc->LoadFile(szFileName); if (err != XML_SUCCESS) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open file %s failed.GetLastError:%d", szFileName, GetLastError()); return false; } //doc->GetDocument(); string out = ""; XMLNode* pF = doc->FirstChild(); XMLElement* pRoot = doc->RootElement(); //pF->FirstChildElement(); if (pRoot == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Get root element failed."); return false; } else pF = pRoot->FirstChild(); while (pF != NULL) { if (pF->ToElement() == NULL) { pF = pF->FirstChild(); continue; } const char* pName = pF->ToElement()->Name(); if (!strncmp(pName, "SelfCheckerConfig", strlen("SelfCheckerConfig"))) { pF = pF->FirstChild(); continue; } else if (!strncmp(pName, "Entity", strlen("Entity"))) { EntityCfg entity; const char* attrName = pF->ToElement()->Attribute("name"); out += const_cast(attrName); out += "\r\n"; XMLNode* pChild = pF->FirstChild(); while (pChild != NULL) { if (!strncmp(pChild->Value(), "shakehandproc", strlen("shakehandproc"))) { XMLNode* pProc = pChild->FirstChild(); while (pProc != NULL) { ProcItem item; const char* code, * action, * upgradeaction, * upgradetime, * upgradecount; code = action = upgradeaction = upgradetime = upgradecount = NULL; if (pProc->ToElement() != NULL) { code = pProc->ToElement()->Attribute("code"); action = pProc->ToElement()->Attribute("action"); upgradeaction = pProc->ToElement()->Attribute("upgradeaction"); upgradetime = pProc->ToElement()->Attribute("upgradetime"); upgradecount = pProc->ToElement()->Attribute("upgradecount"); } if (code != NULL) { item.code = CodeStrToInt(code); out += const_cast(code); out += " , "; } if (action != NULL) { item.action = ActionStrToInt(action); out += const_cast(action); out += " , "; } if (upgradeaction != NULL) { item.upgradeaction = ActionStrToInt(upgradeaction); out += const_cast(upgradeaction); } if (upgradetime != NULL) { item.upgradetime = atoi(upgradetime); } if (upgradecount != NULL) { item.upgradecount = atoi(upgradecount); } else item.upgradecount = 0; entity.vShake.push_back(item); out += "; "; pProc = pProc->NextSibling(); } } else if (!strncmp(pChild->Value(), "eventproc", strlen("eventproc"))) { XMLNode* pProc = pChild->FirstChild(); while (pProc != NULL) { ProcItem item; const char* code, * action, * upgradeaction, * upgradetime, * upgradecount; code = action = upgradeaction = upgradetime = upgradecount = NULL; if (pProc->ToElement() != NULL) { code = pProc->ToElement()->Attribute("code"); action = pProc->ToElement()->Attribute("action"); upgradeaction = pProc->ToElement()->Attribute("upgradeaction"); upgradetime = pProc->ToElement()->Attribute("upgradetime"); upgradecount = pProc->ToElement()->Attribute("upgradecount"); } if (code != NULL) { item.code = CodeStrToInt(code); out += const_cast(code); out += ","; } if (action != NULL) { item.action = ActionStrToInt(action); out += const_cast(action); out += ","; } if (upgradeaction != NULL) { item.upgradeaction = ActionStrToInt(upgradeaction); out += const_cast(upgradeaction); } if (upgradetime != NULL) { item.upgradetime = atoi(upgradetime); } if (upgradecount != NULL) { item.upgradecount = atoi(upgradecount); } else item.upgradecount = 0; entity.vWarn.push_back(item); out += "; "; pProc = pProc->NextSibling(); } } pChild = pChild->NextSibling(); } m_mapEntity[attrName] = entity; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("add %s,vShake size:%d,vWarn size:%d", attrName, entity.vShake.size(), entity.vWarn.size()); } out += "\r\n"; pF = pF->NextSibling(); } return true; } ErrorCodeEnum CSelfCheckerFSM::ExceptionErrorProcessXml(ProcType eType, const char* pszEntityName, DWORD dwAction, bool bDefault, const char* pszMessage) { CSmartPointer pFunc = GetEntityBase()->GetFunction(); CSmartPointer pFuncPrivilege = pFunc.ConvertCase(); CSmartPointer spWait; ErrorCodeEnum eErrCode = Error_Unexpect; switch (dwAction) { case ACTION_EXAMINE: break; case ACTION_RESET: break; case ACTION_CLOSE: eErrCode = pFuncPrivilege->CloseEntity(pszEntityName, spWait); if (eErrCode == Error_Succeed) { } break; case ACTION_ENTITY_RESTART: { if (m_entCfgInfo[pszEntityName].bWaitRestart) { if (!bDefault) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("waiting restart..."); break; } } //if (m_entRunInfo[pszEntityName].loadOpt == 99) //{ // DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("not configure? name:[%s]", pszEntityName); // break; //} //oilyang@20200407 if being restarted by selfchecker,break if (m_entRunInfo[pszEntityName].bRestarting) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s is being restarted by selfchecker.", pszEntityName); break; } //oilyang@20200403 //for fwb test,PinPad&CardSwiper can't be stop immediately //huchen@20210220,SIPPhone can't be stop immediately if (_strnicmp("PinPad", pszEntityName, strlen("PinPad")) == 0 || _strnicmp("CardSwiper", pszEntityName, strlen("CardSwiper")) == 0 //oilyang@20210220 for huchen add SIPPhone || _strnicmp("SIPPhone", pszEntityName, strlen("SIPPhone")) == 0 || _strnicmp("IDCertificate", pszEntityName, strlen("IDCertificate")) == 0 || _strnicmp("FingerPrint", pszEntityName, strlen("FingerPrint")) == 0 || _strnicmp("DeviceControl", pszEntityName, strlen("DeviceControl")) == 0) eErrCode = pFuncPrivilege->TerminateEntity(pszEntityName, spWait); else eErrCode = pFuncPrivilege->StopEntity(pszEntityName, spWait); if (eErrCode == Error_Succeed) { eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait stop %s failed: %s.", pszEntityName, SpStrError(eErrCode)); eErrCode = pFuncPrivilege->TerminateEntity(pszEntityName, spWait); eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait terminate %s failed: %s.", pszEntityName, SpStrError(eErrCode)); break; } } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Stop %s failed(%d).", pszEntityName, eErrCode); break; } Sleep(2000); eErrCode = pFuncPrivilege->StartEntity(pszEntityName, NULL, spWait); if (eErrCode == Error_Succeed) { eErrCode = spWait->WaitAnswer(MAX_AYSNC_TIMEOUT); if (eErrCode != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("spwait start %s failed(%d).", pszEntityName, eErrCode); break; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Start entity %s suc.", pszEntityName); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("(re)Start %s failed(%d).", pszEntityName, eErrCode); break; } } break; case ACTION_OS_RESTART: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("test os restart"); if (m_entRunInfo[pszEntityName].loadOpt == 1 || m_entRunInfo[pszEntityName].loadOpt == 2) LogEvent(Severity_Middle, LOG_EVT_SELFCHECK_OS_RESTART, pszEntityName); break; case ACTION_POWER_RESTART: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("test power restart"); if (m_entRunInfo[pszEntityName].loadOpt == 1 || m_entRunInfo[pszEntityName].loadOpt == 2) LogEvent(Severity_Middle, LOG_EVT_SELFCHECK_POWER_RESTART, pszEntityName); break; default: break; } return eErrCode; } void CSelfCheckerFSM::UpgradeActionProcess(const char* pszEntityName, const char* pAction) { return; } void CSelfCheckerFSM::SetEverEnterMainPageFlag(bool bValue) { m_bEverInMainPage = bValue; } void CSelfCheckerFSM::AddFWBEntityToList() { vector::iterator it, itAct; bool bPinPadFound(false),bIDCertFound(false),bFingerPrintFound(false) ,bActPinPadFound(false), bActIDCertFound(false), bActFingerPrintFound(false); //template ? for (it = m_allEntity.begin(); it != m_allEntity.end(); ++it) { if (!strnicmp("PinPad", *it, it->GetLength())) bPinPadFound = true; else if (!strnicmp("IDCertificate", *it, it->GetLength())) bIDCertFound = true; else if (!strnicmp("FingerPrint", *it, it->GetLength())) bFingerPrintFound = true; } if (!bPinPadFound) m_allEntity.push_back("PinPad"); if (!bIDCertFound) m_allEntity.push_back("IDCertificate"); if (!bPinPadFound) m_allEntity.push_back("FingerPrint"); for (itAct = m_activeEntity.begin(); itAct != m_activeEntity.end(); ++itAct) { if (!strnicmp("PinPad", *itAct, itAct->GetLength())) bActPinPadFound = true; else if (!strnicmp("IDCertificate", *itAct, itAct->GetLength())) bActIDCertFound = true; else if (!strnicmp("FingerPrint", *itAct, itAct->GetLength())) bActFingerPrintFound = true; } if (!bActPinPadFound) m_activeEntity.push_back("PinPad"); if (!bActIDCertFound) m_activeEntity.push_back("IDCertificate"); if (!bActFingerPrintFound) m_activeEntity.push_back("FingerPrint"); } void CSelfCheckerFSM::GetEntityList(CSimpleStringA csList) { CAutoArray arrStageList; arrStageList.Init(64); arrStageList = csList.Split('|'); for (int i = 0; i < arrStageList.GetCount(); ++i) { CAutoArray arrEntity; arrEntity.Init(2); arrEntity = arrStageList[i].Split('='); if (arrEntity.GetCount() < 2) break; //去重,防止前面已经加载了 if (find(m_activeEntity.begin(), m_activeEntity.end(), arrEntity[0].GetData()) != m_activeEntity.end()) continue; m_activeEntity.push_back(arrEntity[0]); m_entRunInfo[arrEntity[0]].bGetLoadOpt = true; if (arrEntity[1].Compare("1") == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s config with loadopt 1", arrEntity[0].GetData()); m_entRunInfo[arrEntity[0]].loadOpt = 1; } else if (arrEntity[1].Compare("2") == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s config with loadopt 2", arrEntity[0].GetData()); m_entRunInfo[arrEntity[0]].loadOpt = 2; } else m_entRunInfo[arrEntity[0]].loadOpt = 0; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("m_activeEntity has %d entity", m_activeEntity.size()); }