#ifndef _COMM_DEVICE_FSM_BASE_HPP_ #define _COMM_DEVICE_FSM_BASE_HPP_ #include "DevEntityCommBase.hpp" #include "CommEntityUtil.hpp" #include "SpFSM.h" #include "RVCComm.h" #include "DevErrorCode.h" #include "DeviceBaseClass.h" #include "publicFunExport.h" #include #include #include #include #include "fileutil.h" #if defined(_MSC_VER) #pragma comment(lib, "Version.lib") typedef ErrorCodeEnum(*DevAdaptObjCreateFunc)(DeviceBaseClass*& baseObj); typedef ErrorCodeEnum(*DevAdaptObjReleaseFunc)(DeviceBaseClass*& pBaseObj); typedef void(*GetPrefixErrMsgFunc)(char* szErrMsg, DWORD* pMsgLen); #else //C/C++ Compiler using DevAdaptObjCreateFunc = ErrorCodeEnum(*)(DeviceBaseClass*& pOutDevAptObj); using DevAdaptObjReleaseFunc = ErrorCodeEnum(*)(DeviceBaseClass*& pInDevAptObj); using GetPrefixErrMsgFunc = void(*)(char* szErrMsg, DWORD* pMsgLen); #endif //_MSC_VER typedef ErrorCodeEnum(*GetDevAdapterVersionFunc)(DevSoftVersion& retVersion); #define HARDWARE_ENTITY_RESET_ENTITYID(ent, entityID) \ do{\ memset(&ent, 0, sizeof(ent)); \ ent.dwEntityId = entityID; \ } while (false) #define HARDWARE_ENTITY_SET_DEVCODE(ent, ec, reserved) \ do {\ ent.dwVendorErroCode = ec; \ ent.dwReserved = reserved; \ } while (false) #define HARDWARE_ENTITY_MAKE_ERRORCODE(ec) \ MAKE_SLV_ERRORCODE(ec.dwEntityId, (ec.dwVendorId), ec.dwVendorErroCode) #define HARDWARE_ENTITY_MAKE_ERRORCODE_TO_BUSINESS(ec) \ MAKE_SLV_ERRORCODE_TO_BUSINESS(ec.dwEntityId, ec.dwVendorErroCode, ec.dwReserved) /*class object must have 'LogErrMsg' function.*/ #define LOG_ERROR_MSG_MACRO(errCode, MethodSig, DeviceType)\ do {\ if(errCode != Error_Succeed) {\ LogErrMsg(CSimpleStringA::Format("%s::%s at line:%d", __FUNCTION__, #MethodSig, __LINE__), \ errCode, MEC_DEVAPI_##DeviceType##_(MethodSig), TRUE);\ }\ } while (false) #define LOG_CARDISSUER_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, CARDISSUER) #define LOG_THERMALPRINT_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, THERMALPRINT) #define LOG_DEVCONTROL_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, DEVCONTROL) #define LOG_PRINTSEAL_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, PRINTSEAL) #define LOG_FINGERPRINT_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, FINGERPRINT) #define LOG_HSPSCANNER_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, HSPSCANNER) #define LOG_UPS_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, UPS) #define LOG_GPIO_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, GPIO) #define LOG_IDCER_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, IDCER) #define LOG_RF_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, RF) #define LOG_PINPAD_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, EPP) #define LOG_WATCHDOG_ERROR_MSG_MACRO(errCode, MethodSig)\ LOG_ERROR_MSG_MACRO(errCode, MethodSig, WATCHDOG) enum PageType { PageType_Init, PageType_MainPage, PageType_UserDesktop, PageType_Other, }; template struct DevAdptLibHelper { private: bool CheckAndGetMapAdatperName(const CSimpleStringA& strPath, CSimpleStringA& replaceAdapterName) { bool result = false; CSimpleStringA strTest = m_strAdapterName.IsNullOrEmpty() ? strPath.GetData() : m_strAdapterName.GetData(); for (int i = 0; i < strTest.GetLength(); ++i) { if (strTest[i] >= 'A' && strTest[i] <= 'Z') strTest[i] = strTest[i] + ('a' - 'A'); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("strTest:%s", strPath.GetData()); if (strTest.IndexOf("pinpad") != -1) { replaceAdapterName = "PinPad.self.1.1.dll"; result = true; } else if (strTest.IndexOf("cardissuer") != -1) { replaceAdapterName = "CardIssuer.self.1.1.dll"; result = true; } else if (strTest.IndexOf("contactlesscard") != -1) { replaceAdapterName = "ContactlessCard.self.1.1.dll"; result = true; } else if (strTest.IndexOf("fingerprint") != -1) { replaceAdapterName = "FingerPrint.self.1.1.dll"; result = true; } else if (strTest.IndexOf("gpio") != -1) { replaceAdapterName = "GPIO.self.1.1.dll"; result = true; } else if (strTest.IndexOf("idcertificate") != -1) { replaceAdapterName = "IDCertificate.self.1.1.dll"; result = true; } else if (strTest.IndexOf("hspscanner") != -1) { replaceAdapterName = "HSPSCanner.self.1.1.dll"; result = true; } return result; } bool PreLoadLib(CSimpleStringA& strFullLibPath) { bool result(false); ///*TODO: Test (80374374@1/23/2024)*/ DWORD d1; DWORD d2; DWORD d3; DWORD d4; if (!ExistsFileA(strFullLibPath)) { return result; } #ifndef DEVOPS_ON_PRD GetDllVersionInfo(strFullLibPath, d1, d2, d3, d4); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("dll %s version: %d.%d.%d.%d", strFullLibPath.GetData(), d1, d2, d3, d4); //VC16.0 [1920,1929] VS2019 142 if (d4 >= 1920 && d4 <= 1929 && d3 == 142) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("detect it built with VS2019, skip latter procedure, version: %d.%d.%d.%d", d1, d2, d3, d4); return result; } #endif CSimpleStringA strTest = strFullLibPath.GetData(); CSimpleStringA strSelf(true); if (CheckAndGetMapAdatperName(strTest, strSelf)) { int index = -1; for (int i = 0; i < strTest.GetLength(); ++i) if (strTest[i] == '\\' || strTest[i] == '/') index = i; if (index != -1) { toolkit_setenv("INVOKE_VENDOR_ADAPTER_NAME", strFullLibPath.GetData()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("env:%s", strFullLibPath.GetData()); CSimpleStringA strAdapterName = strTest.SubString(index + 1); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("adapter name:%s", strAdapterName.GetData()); strTest[index + 1] = '\0'; //!!!! strFullLibPath = strTest.SubString(0, index + 1); strFullLibPath += strSelf; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("new adapter path:%s", strFullLibPath.GetData()); result = true; } } return result; } public: void SetAdapterName(const CSimpleStringA& strEntityName) { m_strAdapterName = strEntityName; } ErrorCodeEnum LoadLibAddress(const CSimpleStringA& strFullLibPath) { ErrorCodeEnum erroCode = Error_Succeed; CSimpleStringA strTemp = strFullLibPath.GetData(); #if defined(_MSC_VER) m_VS2010BridgeMode = PreLoadLib(strTemp); #endif //_MSC_VER do { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to load lib: %s", strTemp.GetData()); if (!ExistsFileA(strTemp)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("the lib file %s is not existed!", strTemp.GetData()); erroCode = Error_NotExist; break; } int res = toolkit_dlopen(strTemp, &m_lib); if (res != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("toolkit_dlopen[%s] failed with error %s.", strTemp.GetData(), toolkit_dlerror(&m_lib)); erroCode = Error_DevLoadFileFailed; break; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get CreateDevComponent pointer address..."); if ((res = toolkit_dlsym(&m_lib, "CreateDevComponent", (void**)&pFuncCreateAdapt)) != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Get 'CreateDevComponent' Func address failed with error: %s", toolkit_dlerror(&m_lib)); erroCode = Error_DevLoadFileFailed; break; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get ReleaseDevComponent pointer address..."); if ((res = toolkit_dlsym(&m_lib, "ReleaseDevComponent", (void**)&pFuncReleaseAdapt)) != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Get 'ReleaseDevComponent' Func address failed with error: %s", toolkit_dlerror(&m_lib)); erroCode = Error_DevLoadFileFailed; break; } #if defined(RVC_OS_WIN) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get GetMoreErrorDetail pointer address..."); if ((res = toolkit_dlsym(&m_lib, "GetMoreErrorDetail", (void**)&pFuncGetPrefixErr)) != 0) { pFuncGetPrefixErr = nullptr; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get 'GetMoreErrorDetail' Func address succ"); } #endif //RVC_OS_WIN } while (false); if (IS_FAILURED(erroCode)) { TearDown(); } return erroCode; } ErrorCodeEnum CreateDevAdptObject() { if (m_AdptObjPtr != nullptr) { return Error_AlreadyExist; } if (pFuncCreateAdapt == nullptr || pFuncReleaseAdapt == nullptr) { return Error_NotInit; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get Adapter object..."); ErrorCodeEnum erroCode = pFuncCreateAdapt((DeviceBaseClass*&)m_AdptObjPtr); if (IS_FAILURED(erroCode)) { if (pFuncGetPrefixErr != nullptr) { char szErrMsg[MAX_DEV_ERROR_MSG_LEN]; memset(szErrMsg, '\0', sizeof(szErrMsg)); DWORD dwLen = MAX_DEV_ERROR_MSG_LEN; pFuncGetPrefixErr(szErrMsg, &dwLen); DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Create device adapter object failed! EC=%s, Msg:[%s]" , SpStrError(erroCode), szErrMsg); } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Create device adapter object failed! EC=%s", SpStrError(erroCode)); } return erroCode; } LOG_ASSERT(m_AdptObjPtr != nullptr); return Error_Succeed; } /** Integrate function LoadLibAddress and CreateDevAdptObject, please use LoadUpAdapterLibrary replace with it*/ ErrorCodeEnum LoadUp(const CSimpleStringA& strFullLibPath) { ErrorCodeEnum erroCode = LoadLibAddress(strFullLibPath); if (IS_SUCCEED(erroCode)) { erroCode = CreateDevAdptObject(); if (!IS_SUCCEED(erroCode)) { TearDown(); } } return erroCode; } void TearDown() { LOG_FUNCTION(); if (m_AdptObjPtr != nullptr) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To DevClose..."); ErrorCodeEnum result = m_AdptObjPtr->DevClose(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("DevClose returned %s", SpStrError(result)); if (nullptr != pFuncReleaseAdapt) { DeviceBaseClass* devBasePtr = static_cast(m_AdptObjPtr); if (devBasePtr != nullptr) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To Release DevAdapter Object..."); pFuncReleaseAdapt(devBasePtr); m_AdptObjPtr = nullptr; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("static cast base dev class failed!"); } } } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to dlclose DevAdapter libs..."); toolkit_dlclose(&m_lib); pFuncReleaseAdapt = pFuncCreateAdapt = nullptr; pFuncGetPrefixErr = nullptr; } #if defined(RVC_OS_WIN) ErrorCodeEnum GetDllVersionInfo(LPCTSTR lpcszFilePath, DWORD& dwMajor, DWORD& dwMinor, DWORD& dwBuild, DWORD& dwRevision) { char* buf = NULL; dwMajor = dwMinor = dwBuild = dwRevision = (DWORD)(-1); DWORD dwHnd; DWORD dwVerInfoSize; if (0 >= (dwVerInfoSize = GetFileVersionInfoSizeA(lpcszFilePath, &dwHnd))) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetFileVersionInfoSizeA failed: %u", GetLastError()); return Error_Unexpect; } buf = new char[dwVerInfoSize]; if (NULL == buf) { return Error_Resource; } // get file version info if (!GetFileVersionInfo(lpcszFilePath, dwHnd, dwVerInfoSize, buf)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetFileVersionInfo failed: %u", GetLastError()); delete[] buf; return Error_Unexpect; } // get FileVersion string from resource VS_FIXEDFILEINFO* ptrVersion; unsigned int versionLen = 0; if (!VerQueryValue(buf, "\\", (void**)&ptrVersion, &versionLen)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("VS_FIXEDFILEINFO failed: %u", GetLastError()); delete[] buf; return Error_Unexpect; } dwMajor = (ptrVersion->dwFileVersionMS >> 16) & 0x0000FFFF; dwMinor = ptrVersion->dwFileVersionMS & 0x0000FFFF; dwBuild = (ptrVersion->dwFileVersionLS >> 16) & 0x0000FFFF; dwRevision = ptrVersion->dwFileVersionLS & 0x0000FFFF; delete[] buf; return Error_Succeed; } #else ErrorCodeEnum GetDllVersionInfo(LPCTSTR lpcszFilePath, DWORD& dwMajor, DWORD& dwMinor, DWORD& dwBuild, DWORD& dwRevision) { dwMajor = dwMinor = dwBuild = dwRevision = 0; return Error_NotSupport; } #endif //RVC_OS_WIN #if defined(_MSC_VER) operator bool() const { return (m_AdptObjPtr != nullptr); } #else /** Linux 下不加此会影响 编译 Gifur@2023329]*/ explicit operator bool() const { return (m_AdptObjPtr != nullptr); } #endif //_MSC_VER operator DeviceBaseClass* () { return m_AdptObjPtr; } TSubAdpt* GetDevPointer() { return m_AdptObjPtr; } TSubAdpt* operator->() { if (m_AdptObjPtr == nullptr) { throw std::runtime_error("the dev class pointer is nullptr!!"); } return m_AdptObjPtr; } bool operator !=(TSubAdpt* rhs) { return !(m_AdptObjPtr == rhs); } bool operator !=(const DevAdptLibHelper& rhs) { return !(m_AdptObjPtr == rhs.operator->()); } DevAdptLibHelper() : pFuncCreateAdapt(nullptr), pFuncReleaseAdapt(nullptr), pFuncGetPrefixErr(nullptr) , m_AdptObjPtr(nullptr), m_VS2010BridgeMode(false), m_strAdapterName(true) { memset(&m_lib, 0, sizeof(toolkit_lib_t)); } ~DevAdptLibHelper() { TearDown(); } #if defined(RVC_OS_LINUX) DevAdptLibHelper(const DevAdptLibHelper&) = delete; DevAdptLibHelper& operator=(const DevAdptLibHelper&) = delete; #endif //RVC_OS_LINUX private: toolkit_lib_t m_lib; DevAdaptObjCreateFunc pFuncCreateAdapt; DevAdaptObjReleaseFunc pFuncReleaseAdapt; GetDevAdapterVersionFunc pFuncGetDevAdapterVer; GetPrefixErrMsgFunc pFuncGetPrefixErr; TSubAdpt* m_AdptObjPtr; bool m_VS2010BridgeMode; CSimpleStringA m_strAdapterName; }; struct AdaptorInfo { public: CSimpleStringA strVendor; CSimpleStringA strVersion; CSimpleStringA strBatch; CSimpleStringA strPort; CSimpleStringA strBaudrate; CSimpleStringA strPortNum; CSimpleStringA strInOutDir; CSimpleStringA strCheckdata; CSimpleStringA strKeysn; CSimpleStringA strPureAdapterName; AdaptorInfo() :strVendor(true), strVersion(true), strBatch(true) , strPort(true), strBaudrate(true) , strPortNum(true), strInOutDir(true) , strCheckdata(true), strKeysn(true), strPureAdapterName(true) { } int GetVersionInt() const { int result = 0; if (!strVersion.IsNullOrEmpty()) { result = atoi(strVersion.GetData()); } return result; } int GetBatchInt() const { int result = 0; if (!strBatch.IsNullOrEmpty()) { result = atoi(strBatch.GetData()); } return result; } int GetPortInt() const { int result = 0; if (!strPort.IsNullOrEmpty()) { result = atoi(strPort.GetData()); } return result; } int GetBaudrateInt() const { int result = 0; if (!strBaudrate.IsNullOrEmpty()) { result = atoi(strBaudrate.GetData()); } return result; } int GetPortNumInt() const { int result = 0; if (!strPortNum.IsNullOrEmpty()) { result = atoi(strPortNum.GetData()); } return result; } int GetInOutDirInt() const { int result = 0; if (!strInOutDir.IsNullOrEmpty()) { result = atoi(strInOutDir.GetData()); } return result; } }; struct AdapterInfo : public AdaptorInfo { CSimpleStringA adapterFilePath; CSimpleStringA adapterFileName; DevCategoryInfo devCatInfo; AdapterInfo() :adapterFilePath(true), adapterFileName(true) { ZeroMemory(devCatInfo.szModel, sizeof(devCatInfo.szModel)); ZeroMemory(devCatInfo.szType, sizeof(devCatInfo.szType)); ZeroMemory(devCatInfo.szVendor, sizeof(devCatInfo.szVendor)); } void FulfillCategoryInfo(const DevCategoryInfo& rhs) { devCatInfo.eState = rhs.eState; devCatInfo.version.wMajor = rhs.version.wMajor; devCatInfo.version.wMinor = rhs.version.wMinor; devCatInfo.version.wRevision = rhs.version.wRevision; devCatInfo.version.wBuild = rhs.version.wBuild; strcpy(devCatInfo.szType, rhs.szType); strcpy(devCatInfo.szModel, rhs.szModel); strcpy(devCatInfo.szVendor, rhs.szVendor); CSimpleStringA strCatVersion = CSimpleStringA::Format("%d.%d.%d.%d", devCatInfo.version.wMajor, devCatInfo.version.wMinor, devCatInfo.version.wRevision, devCatInfo.version.wBuild); if (strlen(devCatInfo.szType) >= MAX_DEV_TYPE_LEN) { devCatInfo.szType[MAX_DEV_TYPE_LEN - 1] = '\0'; } if (strlen(devCatInfo.szModel) >= MAX_DEV_MODEL_LEN) { devCatInfo.szModel[MAX_DEV_MODEL_LEN - 1] = '\0'; } if (strlen(devCatInfo.szVendor) >= MAX_DEV_VENDOR_LEN) { devCatInfo.szVendor[MAX_DEV_VENDOR_LEN - 1] = '\0'; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetDevCategory")("{\"szVendor\":\"%s\",\"szType\":\"%s\",\"szModel\":\"%s\",\"szVersion\":\"%s\"}", devCatInfo.szVendor, devCatInfo.szType, devCatInfo.szModel, strCatVersion.GetData()); CheckCategoryInfoFormat(); } void CheckCategoryInfoFormat() { const int DEV_CATINFO_SUM = 3; char* devInfo[DEV_CATINFO_SUM] = { "szModel", "szVendor", "szType" }; for (int devSn = 0; devSn < DEV_CATINFO_SUM; devSn++) { CSimpleStringA strCatInfo; if (devSn == 0) strCatInfo = devCatInfo.szModel; else if (devSn == 1) strCatInfo = devCatInfo.szVendor; else if (devSn == 2) strCatInfo = devCatInfo.szType; if (!strCatInfo.IsNullOrEmpty()) { auto arr = strCatInfo.Split('#'); if (arr.GetCount() > 0) { for (int sec = 0; sec < arr.GetCount(); sec++) { auto arr2 = arr[sec].Split('='); if (arr2.GetCount() != 2) { if (devSn != 1)//szVendor 没有要求符合"key=value#"的格式 DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong section of %s:%s", devInfo[devSn], arr[sec].GetData()); continue; } if ((strnicmp((LPCTSTR)arr2[0], "MID", strlen("MID")) == 0 && arr2[1].Compare("1.0") != 0) || (strnicmp((LPCTSTR)arr2[0], "CODE", strlen("CODE")) == 0 && arr2[1].Compare("UCS2") != 0)) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData()); else if (strnicmp((LPCTSTR)arr2[0], "PID", strlen("PID")) == 0 || strnicmp((LPCTSTR)arr2[0], "FWID", strlen("FWID")) == 0) { string strData = arr2[1].GetData(); regex pattern(".{8,16}"); smatch sm; if (!regex_match(strData, sm, pattern)) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData()); } else if (strnicmp((LPCTSTR)arr2[0], "STYLE", strlen("STYLE")) == 0) { string strData = arr2[1].GetData(); regex pattern("CL|IG"); smatch sm; if (!regex_match(strData, sm, pattern)) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData()); } else if (strnicmp((LPCTSTR)arr2[0], "RF", strlen("RF")) == 0) { string strData = arr2[1].GetData(); regex pattern("Y|N"); smatch sm; if (!regex_match(strData, sm, pattern)) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData()); } else if (strnicmp((LPCTSTR)arr2[0], "FUNCTION", strlen("FUNCTION")) == 0) { string strData = arr2[1].GetData(); //regex pattern("^(I|T|F|Y|IT|TI|IF|FI|TF|FT|IY|TY|FY|ITF|IFT|FIT|FTI|FIT|FTI)$");//stupid,how to write the right... composite of 'I'/'T'/'F'/'Y' regex pattern("^[ITFY]{1,4}$"); smatch sm; if (!regex_match(strData, sm, pattern)) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData()); } } } else DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, can't split from %s:%s", devInfo[devSn], strCatInfo.GetData()); } else DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, %s is empty.", devInfo[devSn]); } } }; struct ErrorPackage { CSimpleStringA msgHead; ///*TODO(80374374@3/31/2023): to apply, replace the one defined at entity scope with it */ CSimpleStringA devSN; ErrorCodeEnum devErrCode; DWORD apiErrCode; ErrorPackage() :msgHead(true), devSN(true), devErrCode(Error_Succeed), apiErrCode(0) {} }; struct ErrorPackageEx {//or another name? or replace ErrorPackage ? ErrorCodeEnum errCode; DWORD apiUserCode; CSimpleStringA devApi; bool bInBusiness; int costTime; CSimpleStringA funPath; ErrorPackageEx() :errCode(Error_Succeed), apiUserCode(0), devApi(true), bInBusiness(false), costTime(0), funPath(true) {} }; struct DevEntityErrorCode { DWORD dwEntityId; DWORD dwVendorId; DWORD dwVendorErroCode; DWORD dwReserved; DevEntityErrorCode() :dwEntityId(0), dwVendorId(0), dwVendorErroCode(0), dwReserved(0) {} void ResetWithEntityID(WORD wEntityID) { dwEntityId = dwVendorId = dwVendorErroCode = dwReserved = 0; dwEntityId = wEntityID; } void SetDevCode(DWORD devErrorCode, DWORD dwReservedCode) { dwVendorErroCode = devErrorCode; dwReserved = dwReservedCode; } /*no used now!!*/ void SetVendorID(DWORD dwVendorID) { dwVendorId = dwVendorID; } DWORD GetCompleteErrorCode() const { return MAKE_SLV_ERRORCODE(dwEntityId, dwVendorId, dwVendorErroCode); } DWORD GetCompleteErrorCode2Business() const { return MAKE_SLV_ERRORCODE_TO_BUSINESS(dwEntityId, dwVendorErroCode, dwReserved); } }; template class CCommDevFSM : public FSMImpl { public: CCommDevFSM() :m_FirstStart(TRUE), m_iInWhatPage(PageType_Init),m_bOpened(false), m_bOpening(true), m_csAlarmMsg("No more information"), m_contiErrTimes(0) { m_WarnCodeMap.insert(std::make_pair("CardIssuerStand", 0x2030021f)); m_WarnCodeMap.insert(std::make_pair("CardIssuerStore", 0x2200021f)); m_WarnCodeMap.insert(std::make_pair("ContactlessCard", 0x21300203)); m_WarnCodeMap.insert(std::make_pair("FingerPrint", 0x20400211)); m_WarnCodeMap.insert(std::make_pair("IDCertificate", 0x20100202)); m_WarnCodeMap.insert(std::make_pair("PinPad", 0x20600207)); m_WarnCodeMap.insert(std::make_pair("Gpio", 0x20900201)); m_WarnCodeMap.insert(std::make_pair("HSPScanner", 0x21700207)); m_RootIniCodeMap.insert(std::make_pair("CardIssuerStand", 0x20300299)); m_RootIniCodeMap.insert(std::make_pair("CardIssuerStore", 0x22000299)); m_RootIniCodeMap.insert(std::make_pair("ContactlessCard", 0x21300224)); m_RootIniCodeMap.insert(std::make_pair("FingerPrint", 0x20400229)); m_RootIniCodeMap.insert(std::make_pair("IDCertificate", 0x2010021f)); m_RootIniCodeMap.insert(std::make_pair("PinPad", 0x2060021f)); m_RootIniCodeMap.insert(std::make_pair("Gpio", 0x20900203)); m_RootIniCodeMap.insert(std::make_pair("HSPScanner", 0x2170020f)); } ErrorCodeEnum GetAndSplitDevErrInfo( CSimpleStringA& csErrMsg, WORD& wdDevErrCode, LPCTSTR lpszFuncNameForDisplay = ""); ErrorCodeEnum LogDevErrInfo(LPCTSTR lpszFuncName = "") { CSimpleStringA csMsg; WORD wdErrorCode = 0; return GetAndSplitDevErrInfo(csMsg, wdErrorCode, lpszFuncName); } bool GetDevErrorCode(WORD& wdErrorCode) { CSimpleStringA csMsg; ErrorCodeEnum eRet = GetAndSplitDevErrInfo(csMsg, wdErrorCode); return (eRet == Error_Succeed); } void SetErrPackage(CSimpleStringA msgHead, CSimpleStringA devSN, ErrorCodeEnum errCode, DWORD apiCode) { m_errPkg.msgHead = msgHead; m_errPkg.devSN = devSN; m_errPkg.devErrCode = errCode; m_errPkg.apiErrCode = apiCode; } DWORD AlarmDEC(bool bToBusiness = false, bool alarmOrNot = true) { WORD wdErrCode = 0; CSimpleStringA csErrMsg(true); ErrorCodeEnum ec = GetAndSplitDevErrInfo(csErrMsg, wdErrCode, (LPCTSTR)m_errPkg.msgHead); if (ec == Error_Succeed && wdErrCode != 0) { //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly if ((m_errPkg.apiErrCode >> 20) == m_entCode.dwEntityId) UpdateDEC(m_errPkg.apiErrCode); else UpdateDEC(wdErrCode); } else if (m_errPkg.apiErrCode != 0) { UpdateDEC(m_errPkg.apiErrCode); } //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly DWORD dwCode = GetAlarmDEC(); if (alarmOrNot) { LogErrMsgEx(m_errPkg, csErrMsg, dwCode, bToBusiness); } else { DbgWithLink(bToBusiness ? LOG_LEVEL_ERROR : LOG_LEVEL_WARN, bToBusiness ? LOG_TYPE_USER : LOG_TYPE_SYSTEM).setAPI(m_errPkg.msgHead)("{\"DevSN\":\"%s\", \"Code\":\"%s\", \"Msg\":\"%s\"}" , m_errPkg.devSN.GetData(), SpStrError(m_errPkg.devErrCode), csErrMsg.GetData()); } return dwCode; } void SetErrorAndLog(ErrorCodeEnum errCode, DWORD userCode, CSimpleStringA devApi, CSimpleStringA funPath, bool bInBusiness = false, int costTime = 0, CSimpleStringA logCode = "", CSimpleStringA context = "") { //set error info m_errPkgEx.errCode = errCode; m_errPkgEx.apiUserCode = userCode; m_errPkgEx.devApi = devApi; m_errPkgEx.bInBusiness = bInBusiness; m_errPkgEx.costTime = costTime; m_errPkgEx.funPath = funPath; //get DevAdapter vendor errmsg and log info WORD wdErrCode = 0; CSimpleStringA csErrMsg(true); ErrorCodeEnum ec = GetAndSplitDevErrInfo(csErrMsg, wdErrCode, ""); if (ec == Error_Succeed && wdErrCode != 0) { //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly if ((m_errPkgEx.apiUserCode >> 20) == m_entCode.dwEntityId) UpdateDEC(m_errPkgEx.apiUserCode); else UpdateDEC(wdErrCode); } else if (m_errPkgEx.apiUserCode != 0) { UpdateDEC(m_errPkgEx.apiUserCode); } //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly const DWORD dwCode = GetAlarmDEC(); const CSimpleStringA alarmMsg = CSimpleStringA::Format("{\"Function\":\"%s\", \"DevApi\":\"%s\", \"ReturnCode\":\"%s\", \"Msg\":%s, \"Context\":%s}" , funPath.GetData(), devApi.GetData(), SpStrError(m_errPkgEx.errCode), csErrMsg.GetData(), context.GetData()); std::map msgInfo; msgInfo["ReturnCode"] = SpStrError(errCode); msgInfo["ErrMsg"] = csErrMsg.GetData(); msgInfo["Context"] = context.GetData(); std::pair strResult; strResult = generateJsonStr(msgInfo); CSimpleStringA csErrMsgWithReturnCode = strResult.second.c_str(); CSimpleStringA tmpRTA(true), tmpDesc(true); if (this->GetEntityBase()->GetFunction()->GetVTMErrMsg(dwCode, tmpDesc, tmpRTA) != Error_Succeed) tmpRTA = CSimpleStringA::Format("0x%X", dwCode);//if map failed, use dwCode instead if (bInBusiness) { LogError(Severity_High, m_errPkgEx.errCode, dwCode, alarmMsg.GetData()); DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(logCode).setAPI(devApi).setResultCode(tmpRTA.GetData()).setCostTime(costTime)(csErrMsgWithReturnCode.GetData()); } else { LogWarn(Severity_High, m_errPkgEx.errCode, dwCode, alarmMsg.GetData()); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(logCode).setAPI(devApi).setResultCode(tmpRTA.GetData()).setCostTime(costTime)(csErrMsgWithReturnCode.GetData()); } return; } //在旧dep路径下找到文件时告警 void UpdateAndWarnFileFindInDepBak(CSimpleStringA& newDepPath, const char* filename, DWORD userCode) { CSimpleStringA strOldPath; if (!ExistsFileA(newDepPath.GetData())) { ErrorCodeEnum eErrOld = this->GetEntityBase()->GetFunction()->GetPath("DepBak", strOldPath); if (eErrOld != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get [DepBak] Path failed! errcode:%s.", SpStrError(eErrOld)); } strOldPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strOldPath.GetData(), filename); if (ExistsFileA(strOldPath.GetData())) { newDepPath = strOldPath; CSimpleStringA warnMsg = CSimpleStringA::Format("Find %s in OLD dep path!", strOldPath.GetData()); LogWarn(Severity_Middle, Error_Unexpect, userCode, warnMsg.GetData()); } } } ErrorCodeEnum LoadUpAdapterLibrary(const CSimpleStringA& customDllPath = "") { m_hDevHelper.SetAdapterName(this->GetEntityBase()->GetEntityName()); ErrorCodeEnum rc = m_hDevHelper.LoadUp(customDllPath.IsNullOrEmpty() ? m_adapterInfo.adapterFilePath : customDllPath); return rc; } /*fulfill adapter elem, open param and adapter file name&absolute path */ void FulfillAdapterInfoFrom(const VendorLibInfo& vendorLib) { m_adapterInfo.strVendor = vendorLib.strVendor; m_adapterInfo.strVersion = vendorLib.strVersion; m_adapterInfo.strBatch = vendorLib.strBatch; m_adapterInfo.strPureAdapterName = vendorLib.strFileValue; CSmartPointer spConfigRoot; this->GetEntityBase()->GetFunction()->OpenConfig(Config_Root, spConfigRoot); CSimpleStringA entityName(this->GetEntityBase()->GetEntityName()); if (entityName.Compare("CardIssuerStore", true) == 0 || entityName.Compare("CardIssuerStand", true) == 0) { entityName = "CardIssuer"; } CSimpleStringA sectionName = CSimpleStringA::Format("Device.%s", entityName.GetData()); CSimpleStringA csPort(true), csBaudrate(true); spConfigRoot->ReadConfigValue(sectionName.GetData(), "Port", csPort); spConfigRoot->ReadConfigValue(sectionName.GetData(), "Baudrate", csBaudrate); m_adapterInfo.strPort = csPort; m_adapterInfo.strBaudrate = csBaudrate; CSimpleStringA csPortNum(true), csCheckData(true), csKeySN(true), csInOutDir(true); if (!entityName.Compare("Gpio")) { spConfigRoot->ReadConfigValue(sectionName.GetData(), "PortNum", csPortNum); spConfigRoot->ReadConfigValue(sectionName.GetData(), "InOutDir", csInOutDir); m_adapterInfo.strPortNum = csPortNum; m_adapterInfo.strInOutDir = csInOutDir; } else if (!entityName.Compare("PinPad")) { spConfigRoot->ReadConfigValue(sectionName.GetData(), "Checkdata", csCheckData); spConfigRoot->ReadConfigValue(sectionName.GetData(), "Keysn", csKeySN); m_adapterInfo.strCheckdata = csCheckData; m_adapterInfo.strKeysn = csKeySN; } m_adapterInfo.adapterFileName = vendorLib.toLibNameString(); CSimpleStringA strDepPath(true); this->GetEntityBase()->GetFunction()->GetPath("Dep", strDepPath); m_adapterInfo.adapterFilePath = CSimpleStringA::Format( "%s" SPLIT_SLASH_STR "%s", (LPCTSTR)strDepPath, (LPCTSTR)m_adapterInfo.adapterFileName); } ErrorCodeEnum FulfillAdapterDevCategory() { if (!!m_hDevHelper) { ErrorCodeEnum result(Error_Succeed); DevCategoryInfo devCat; ZeroMemory(devCat.szModel, sizeof(devCat.szModel)); ZeroMemory(devCat.szType, sizeof(devCat.szType)); ZeroMemory(devCat.szVendor, sizeof(devCat.szVendor)); result = m_hDevHelper->GetDevCategory(devCat); if (IS_SUCCEED(result)) { m_adapterInfo.FulfillCategoryInfo(devCat); } return result; } return Error_InvalidState; } #if defined(_MSC_VER) const char* LPCSTRSmartPrintString(const CSimpleStringA& str) { return str.IsNullOrEmpty() ? "" : str.GetData(); } CSimpleStringA GenerateJson(AdaptorInfo adaptorInfo, const CSimpleStringA& devDeviceName) { CSimpleStringA result(true); if (0 == devDeviceName.Compare("Gpio", true)) { result = CSimpleStringA::Format("{\"Vendor\":\"%s\", \"Version\":\"%s\", \"Batch\":\"%s\", \"Port\":\"%s\", \"Baudrate\":\"%s\", \"PortNum\":\"%s\", \"InOutDir\":\"%s\"}", LPCSTRSmartPrintString(adaptorInfo.strVendor), LPCSTRSmartPrintString(adaptorInfo.strVersion), LPCSTRSmartPrintString(adaptorInfo.strBatch), LPCSTRSmartPrintString(adaptorInfo.strPort), LPCSTRSmartPrintString(adaptorInfo.strBaudrate), LPCSTRSmartPrintString(adaptorInfo.strPortNum), LPCSTRSmartPrintString(adaptorInfo.strInOutDir)); } else if (0 == devDeviceName.Compare("PinPad", true)) { result = CSimpleStringA::Format("{\"Vendor\":\"%s\", \"Version\":\"%s\", \"Batch\":\"%s\", \"Port\":\"%s\", \"Baudrate\":\"%s\", \"Checkdata\":\"%s\", \"Keysn\":\"%s\"}", LPCSTRSmartPrintString(adaptorInfo.strVendor), LPCSTRSmartPrintString(adaptorInfo.strVersion), LPCSTRSmartPrintString(adaptorInfo.strBatch), LPCSTRSmartPrintString(adaptorInfo.strPort), LPCSTRSmartPrintString(adaptorInfo.strBaudrate), LPCSTRSmartPrintString(adaptorInfo.strCheckdata), LPCSTRSmartPrintString(adaptorInfo.strKeysn)); } else { result = CSimpleStringA::Format("{\"Vendor\":\"%s\", \"Version\":\"%s\", \"Batch\":\"%s\", \"Port\":\"%s\", \"Baudrate\":\"%s\"}", LPCSTRSmartPrintString(adaptorInfo.strVendor), LPCSTRSmartPrintString(adaptorInfo.strVersion), LPCSTRSmartPrintString(adaptorInfo.strBatch), LPCSTRSmartPrintString(adaptorInfo.strPort), LPCSTRSmartPrintString(adaptorInfo.strBaudrate)); } return result; } #endif //_MSC_VER void ToLogRootINIInfoOnce() { CSmartPointer spConfig; this->GetEntityBase()->GetFunction()->OpenConfig(Config_Cache, spConfig); CSimpleStringA entityName(this->GetEntityBase()->GetEntityName()); int nUploadTime(0); spConfig->ReadConfigValueInt("RootUploadFlag", entityName, nUploadTime); SYSTEMTIME stNow = CSmallDateTime::GetNow().ToSystemTime(); SYSTEMTIME lastUploadTime = CSmallDateTime(nUploadTime).ToSystemTime(); if (lastUploadTime.wYear != stNow.wYear || lastUploadTime.wMonth != stNow.wMonth || lastUploadTime.wDay != stNow.wDay) { ToLogRootINIInfo(); spConfig->WriteConfigValue("RootUploadFlag", entityName, CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow())); } } /** GPIO不调用此接口 [Gifur@20221025]*/ void ToLogRootINIInfo() { CSimpleStringA entityName(this->GetEntityBase()->GetEntityName()); std::map rootInfo; rootInfo["Vendor"] = m_adapterInfo.strVendor.GetData(); rootInfo["Version"] = m_adapterInfo.strVersion.GetData(); rootInfo["Batch"] = m_adapterInfo.strBatch.GetData(); rootInfo["Port"] = m_adapterInfo.strPort.GetData(); rootInfo["Baudrate"] = m_adapterInfo.strBaudrate.GetData(); if (!entityName.Compare("Gpio")) { rootInfo["PortNum"] = m_adapterInfo.strPortNum.GetData(); rootInfo["InOutDir"] = m_adapterInfo.strInOutDir.GetData(); } else if (!entityName.Compare("PinPad")) { rootInfo["Checkdata"] = m_adapterInfo.strCheckdata.GetData(); rootInfo["Keysn"] = m_adapterInfo.strKeysn.GetData(); } std::pair strResult; strResult = generateJsonStr(rootInfo); if (!entityName.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Debug, m_RootIniCodeMap[entityName.GetData()], strResult.second.c_str()); } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Entity Name is empty, please check!!!"); } return; } /** upload adapter file's hash value and open param as well as dev category information, return if information has uploaded this time*/ bool ToLogWarnInfoAboutTerm() { std::map emptys; return ToLogWarnInfoAboutTermExtend(emptys); } /** upload adapter file's hash value and open param as well as dev category information, return if information has uploaded this time extend from ToLogWarnInfoAboutTerm */ bool ToLogWarnInfoAboutTermExtend(std::map additionalParams) { bool bUpload(false); int fileSize = 0; //calculate file hash value std::map termInfo; char* strFileHash = new char[128]; if (ExistsFileA(m_adapterInfo.adapterFilePath)) { BYTE fileHash[32]; SM3File(const_cast(m_adapterInfo.adapterFilePath.GetData()), fileHash); ZeroMemory(strFileHash, 128); SP::Module::Util::HexBuf2StrBuf(fileHash, &strFileHash, 32); #if defined(_MSC_VER) HANDLE hFile; hFile = CreateFile(m_adapterInfo.adapterFilePath.GetData(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { fileSize = 0; } else { fileSize = GetFileSize(hFile, NULL); CloseHandle(hFile); } #else //calculate file size struct stat statbuf; ZeroMemory(&statbuf, sizeof(statbuf)); stat(m_adapterInfo.adapterFilePath.GetData(), &statbuf); fileSize = statbuf.st_size; #endif //_MSC_VER } else { memset(strFileHash, '\0', sizeof(char) * 128); } //necessary elements about adapter CSimpleStringA csPortNum(true), csCheckData(true), csKeySN(true), csInOutDir(true); termInfo["VendorDllName"] = m_adapterInfo.adapterFilePath.GetData(); termInfo["VendorDllFileHash"] = strFileHash; ZeroMemory(strFileHash, 128); termInfo["VendorDllFileSize"] = _itoa(fileSize, strFileHash, 10); termInfo["szModel"] = m_adapterInfo.devCatInfo.szModel; termInfo["szType"] = m_adapterInfo.devCatInfo.szType; termInfo["Port"] = m_adapterInfo.strPort.GetData(); termInfo["Baudrate"] = m_adapterInfo.strBaudrate.GetData(); if (strFileHash != nullptr) { delete[] strFileHash; strFileHash = nullptr; } CSimpleStringA entityName(this->GetEntityBase()->GetEntityName()); if (!entityName.Compare("Gpio")) { termInfo["PortNum"] = m_adapterInfo.strPortNum.GetData(); termInfo["InOutDir"] = m_adapterInfo.strInOutDir.GetData(); } else if (!entityName.Compare("PinPad")) { termInfo["CheckData"] = m_adapterInfo.strCheckdata.GetData(); termInfo["Keysn"] = m_adapterInfo.strKeysn.GetData(); } if (!additionalParams.empty()) { for (auto it = additionalParams.cbegin(); it != additionalParams.cend(); ++it) { termInfo[it->first.c_str()] = it->second; } } std::pair strResult; strResult = generateJsonStr(termInfo); CSmartPointer spConfigRun; CSimpleStringA csWarnMsg; this->GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun); spConfigRun->ReadConfigValue("Run", "WarnMsg", csWarnMsg); SYSTEMTIME localTime; GetLocalTime(&localTime); if (csWarnMsg.IsNullOrEmpty() || csWarnMsg.Compare(strResult.second.c_str()) != 0) { spConfigRun->WriteConfigValueInt("Run", "WarnDay", localTime.wDay); spConfigRun->WriteConfigValue("Run", "WarnMsg", strResult.second.c_str()); if (!entityName.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Unexpect, m_WarnCodeMap[entityName.GetData()], strResult.second.c_str()); bUpload = true; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Entity Name is empty, please check!!!"); } } else { int wDay = 99; spConfigRun->ReadConfigValueInt("Run", "WarnDay", wDay); if (wDay != localTime.wDay) { spConfigRun->WriteConfigValueInt("Run", "WarnDay", localTime.wDay); if (!entityName.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Unexpect, m_WarnCodeMap[entityName.GetData()], strResult.second.c_str()); bUpload = true; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Entity Name is empty, please check!!!"); } } } return bUpload; } void ResetRepeatErrTimes() { m_contiErrTimes = 0; } ErrorCodeEnum TransECWithRepeat(const ErrorCodeEnum& ec) { ErrorCodeEnum result(ec); if (ec != Error_Succeed) { if (!m_bOpened) { result = Error_DevNotAvailable; } else if (0 < CountDevError(this->GetEntityBase())) { result = Error_DevFailAddUp; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("exceed max allow repeat error times! 0x%x -> 0x%x", ec, result); } } return result; } virtual ErrorCodeEnum PreOpenDevice() { return Error_Succeed; } virtual ErrorCodeEnum ToOpenDevice() { return Error_NotImpl; } virtual ErrorCodeEnum PostOpenDevice() { return Error_Succeed; } //暂时未使用 ErrorCodeEnum OpenDevice() { if (m_bOpening) { return Error_Pending; } if (m_bOpened) { return Error_DevAlreadyConnected; } m_bOpening = true; ErrorCodeEnum result = PreOpenDevice(); if (IS_SUCCEED(result)) { result = ToOpenDevice(); if (IS_SUCCEED(result)) { m_bOpened = true; result = PostOpenDevice(); } } m_bOpening = false; return result; } virtual void SetInWhatPage(int iPageType) { m_iInWhatPage = iPageType; } public: bool m_bOpened; bool m_bOpening; protected: DevAdptLibHelper m_hDevHelper; DevEntityErrorCode m_entCode; BOOL m_FirstStart; int m_iInWhatPage/*在哪个页面,区分首页,用户桌面,其他页*/; ErrorPackage m_errPkg; ErrorPackageEx m_errPkgEx; CSimpleStringA m_csAlarmMsg; unsigned int m_contiErrTimes; AdapterInfo m_adapterInfo; void UpdateEntityIDIfZero() { if (m_entCode.dwEntityId == 0) { UpdateEntityID(); } } void UpdateEntityID() { CEntityStaticInfo esi = { 0 }; ErrorCodeEnum ec = this->GetEntityBase()->GetFunction()->GetEntityStaticInfo(this->GetEntityBase()->GetEntityName(), esi); if (ec == Error_Succeed) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("wEntityDevelopID: 0x%X", esi.wEntityDevelopID); m_entCode.ResetWithEntityID(esi.wEntityDevelopID); } } DWORD GetEntityID() { UpdateEntityIDIfZero(); return m_entCode.dwEntityId; } DWORD UpdateDEC(DWORD dwVal = 0) { UpdateEntityIDIfZero(); /** 14 is for entity define, FC(6bit) is reserved*/ int reserved = (dwVal & 0xFC000) >> 14; m_entCode.SetDevCode(dwVal, reserved); return GetDEC(); } DWORD GetDEC() const { return m_entCode.GetCompleteErrorCode(); } DWORD GetAlarmDEC(DWORD dwValue = 0) { if (dwValue > 0) UpdateDEC(dwValue); //if have been set ErrorCode of entity defined (not device),use it directly DWORD dwCode = 0; //if ((m_entCode.dwVendorErroCode >> 20) == m_entCode.dwEntityId) if(IsEntityIDSettle(m_entCode.dwVendorErroCode)) dwCode = m_entCode.dwVendorErroCode; else dwCode = HARDWARE_ENTITY_MAKE_ERRORCODE_TO_BUSINESS(m_entCode); return dwCode; } DWORD AlarmDECToBusiness(DWORD dwVal = 0) { if (dwVal > 0) { UpdateDEC(dwVal); } //oilyang@20200528 according the meeting result,throw a LogError while answering ctx //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly const DWORD dwCode = IsEntityIDSettle(m_entCode.dwVendorErroCode) ? m_entCode.dwVendorErroCode : m_entCode.GetCompleteErrorCode2Business(); ///**TODO(Gifur@9/10/2021): */ //LogWarn(Severity_Middle, Error_NotImpl, dwCode, CSimpleStringA::Format("%s TODO:", __FUNCTION__)); return dwCode; } void ClearRelatedDEC() { UpdateDEC(); m_csAlarmMsg = "No more information"; } bool IsEntityIDSettle(const DWORD& dwVal) const { return ((dwVal >> 20) == m_entCode.dwEntityId); } void LogErrMsg(const char* pMsgHead, ErrorCodeEnum eErrCode, DWORD defaultDevCode = 0, BOOL bAlarm = FALSE); void LogErrMsgEx(const ErrorPackage& errPkg, const char* pMsgBody, DWORD finalErrCode /*= 0*/, BOOL bToBusiness = FALSE); static void GetFileSizeAndCalcHashValue(const char* fileName, int& fileSize, BYTE fileHash[32]) { HANDLE hFile; hFile = CreateFile(fileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { fileSize = 0; return; } fileSize = GetFileSize(hFile, NULL); CloseHandle(hFile); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to calc vendor dll hash"); SM3File(const_cast(fileName), fileHash); return; } int CountDevError(CEntityBase *pEntityBase); bool IsInBusiness() const { return (m_iInWhatPage == PageType_Other); } private: std::map m_WarnCodeMap; std::map m_RootIniCodeMap; }; template inline ErrorCodeEnum CCommDevFSM::GetAndSplitDevErrInfo( CSimpleStringA& csErrMsg, WORD& wdDevErrCode, LPCTSTR lpszFuncNameForDisplay) { csErrMsg = ""; wdDevErrCode = 0; BOOL bDisplayFunName = TRUE; if (lpszFuncNameForDisplay == NULL || strlen(lpszFuncNameForDisplay) == 0) { bDisplayFunName = FALSE; } if (!m_hDevHelper) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("inst occurs nullptr !!!"); return Error_Param; } DevErrorInfo devErrInfo; ZeroMemory(&devErrInfo, sizeof(DevErrorInfo)); ErrorCodeEnum erroCode = m_hDevHelper->GetLastErr(devErrInfo); if (erroCode == Error_Succeed) { if (strlen(devErrInfo.szErrMsg) > 0) { csErrMsg = devErrInfo.szErrMsg; } if (devErrInfo.dwErrMsgLen > MAX_DEV_ERROR_MSG_LEN) { wdDevErrCode = (WORD)((devErrInfo.dwErrMsgLen >> 16) & 0x0000FFFF); } if (bDisplayFunName) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(lpszFuncNameForDisplay)("Invoke <%s> failed, Dev_GLE: DevErrCode[%d], ErrMsg[%s]", lpszFuncNameForDisplay, wdDevErrCode, (LPCTSTR)csErrMsg); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Dev_GLE: DevErrCode[%d], ErrMsg[%s]", wdDevErrCode, (LPCTSTR)csErrMsg); } } else { if (bDisplayFunName) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetLastErr")("Invoke <%s> failed, and unfortunately Dev_GLE failed returned EC: %s", lpszFuncNameForDisplay, SpStrError(erroCode)); csErrMsg = CSimpleStringA::Format("Invoke <%s> failed", lpszFuncNameForDisplay); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetLastErr")("Dev_GLE failed returned EC: %s", SpStrError(erroCode)); } } /** reset vendor device error code to stop reporting to alarm [12/11/2020 Gifur] */ wdDevErrCode = 0; return erroCode; } template inline void CCommDevFSM::LogErrMsg( const char* pMsgHead, ErrorCodeEnum eErrCode, DWORD defaultDevCode, BOOL bAlarm) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("%s failed, EC = %s", pMsgHead, SpStrError(eErrCode)); WORD wdErrCode = 0; CSimpleStringA csErrMsg(true); ErrorCodeEnum ec = GetAndSplitDevErrInfo(csErrMsg, wdErrCode); if (IsEntityIDSettle(defaultDevCode)) { UpdateDEC(defaultDevCode); } else if (ec == Error_Succeed && wdErrCode != 0) { UpdateDEC(wdErrCode); } else if (defaultDevCode != 0) { UpdateDEC(defaultDevCode); } m_csAlarmMsg = CSimpleStringA::Format("%s failed EC= %s : %s", pMsgHead, SpStrError(eErrCode), (LPCTSTR)csErrMsg); if (bAlarm) { LogWarn(Severity_Middle, eErrCode, AlarmDECToBusiness(), (LPCTSTR)m_csAlarmMsg); } return; } template inline void CCommDevFSM::LogErrMsgEx(const ErrorPackage& errPkg, const char* pMsgBody, DWORD finalErrCode /*= 0*/, BOOL bToBusiness) { const CSimpleStringA alarmMsg = CSimpleStringA::Format("{\"DevSN\":\"%s\", \"Prefix\":\"%s\", \"Code\":\"%s\", \"Msg\":\"%s\"}" , errPkg.devSN.GetData(), errPkg.msgHead.GetData(), SpStrError(errPkg.devErrCode), pMsgBody); if (bToBusiness) { LogError(Severity_High, errPkg.devErrCode, finalErrCode, alarmMsg.GetData()); } else { LogWarn(Severity_High, errPkg.devErrCode, finalErrCode, alarmMsg.GetData()); } return; } //1:报错累计到上限,需要返回错误码给业务 //0:报错累计未到上限,或者不需要计数 //-1:出现错误 template int CCommDevFSM::CountDevError(CEntityBase* pEntityBase) { static int iErrNumLimit = -1; if (iErrNumLimit == -1) { CSmartPointer spCenterConfig; ErrorCodeEnum eErrDev = pEntityBase->GetFunction()->OpenConfig(Config_CenterSetting, spCenterConfig); if (eErrDev != Error_Succeed) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open centersetting file failed!"); return -1; } else { int value(0); spCenterConfig->ReadConfigValueInt("Common", "ErrUpperLimit", value); if (0 == value) { iErrNumLimit = 5; } else if (0 > value) { iErrNumLimit = 0; } else { iErrNumLimit = value; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("iErrNumLimit=%d", iErrNumLimit); } } } m_contiErrTimes++; if (iErrNumLimit > 0 && m_contiErrTimes >= iErrNumLimit) { return 1; } else { return 0; } } #endif /*_COMM_DEVICE_FSM_BASE_HPP_*/