#ifndef __HEARTBEAT_FSM_H #define __HEARTBEAT_FSM_H #pragma once #ifdef RVC_OS_WIN #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include #include #include #include #include #include #include #include #include #else #endif //RVC_OS_WIN #include "CardReadAdapter_client_g.h" #include "CardIssuerStore_client_g.h" #include "SpFSM.h" #include "HeartBeat_def_g.h" #include "HeartBeat_msg_g.h" using namespace HeartBeat; #include "SpSecureClient.h" #include "EventCode.h" #include "IHttpFunc.h" typedef DWORD (__stdcall *LpRestorePerfRegistryFromFile)(LPCWSTR szFileName, LPCWSTR szLangId); #pragma pack(1) // [StructName("FNTSTAT")] struct HandReq { char TerminalNo[16]; //TODO: CrossPlaform [Gifur@2025730] #ifdef RVC_OS_WIN unsigned long ip; #else uint32_t ip; #endif char WarningLevel; char RunState; char CustomerHandle; char CallState; char LocalMaintain; char RemoteMaintain; char TermStage; char PreTermStage; char NetState; char PreNetState; }; // [StructName("xxx")] struct HandErrListReq { int warnLevel; char reserved1;//用来存放交易控制标志 char reserved2; char reserved3; char reserved4; char errList[512]; }; //[StructName("HANDANS")] struct HandAns { //TODO: CrossPlaform [Gifur@2025730] #ifdef RVC_OS_WIN unsigned long EventCode; #else uint32_t EventCode; #endif char param1[16]; //int count; }; #ifdef RVC_OS_WIN struct CardActiveReq { unsigned long type; unsigned long slot; unsigned long reserved1; unsigned long reserved2; char Account[32]; char FromTerminalNo[16]; char TerminalNo[16]; unsigned long EvtCode; unsigned long ErrCode; unsigned long findCard; unsigned long cardPos; char Param1[16]; char Param2[1024]; char Reserved3[128]; char Reserved4[128]; }; #else struct CardActiveReq { uint32_t type; uint32_t slot; uint32_t reserved1; uint32_t reserved2; char Account[32]; char FromTerminalNo[16]; char TerminalNo[16]; uint32_t EvtCode; uint32_t ErrCode; uint32_t findCard; uint32_t cardPos; char Param1[16]; char Param2[1024]; char Reserved3[128]; char Reserved4[128]; }; #endif #pragma pack() enum EvtType { USER_EVT_TEST = EVT_USER+1, USER_EVT_QUIT, USER_EVT_START, USER_EVT_STARTFINISHED, USER_EVT_HANDSHAKEFINISHED, USER_EVT_INSTRUCTION, USER_EVT_LOST, USER_EVT_STOP, USER_EVT_REJECT, USER_EVT_EXIT, USER_EVT_CARD_ACTIVE, USER_EVT_CARD_ACTIVE_FINISHED, }; struct TerminalInfo { char TerminalNo[16]; //TODO: CrossPlaform [Gifur@2025730] #ifdef RVC_OS_WIN unsigned long ip; #else uint32_t ip; #endif char WarningLevel; char RunState; char CustomerHandle; char CallState; char LocalMaintain; char RemoteMaintain; char TermStage; char PreTermStage; char NetState; char PreNetState; }; // Terminal Performance Information Struct[Josephus in 9:09:47 2016/4/23] #ifdef RVC_OS_WIN struct TermianlCounter { DWORD serverIP; unsigned short totalMem; //MB unsigned short freeMem; //MB unsigned short procNum; unsigned short threadNum; DWORD handleNum; DWORD freeDisk; //MB char osStartTime[22]; unsigned short cpuLoad; }; #else struct TermianlCounter { DWORD serverIP; uint16_t totalMem; //MB uint16_t freeMem; //MB uint16_t procNum; uint16_t threadNum; DWORD handleNum; DWORD freeDisk; //MB char osStartTime[22]; uint16_t cpuLoad; }; #endif namespace HttpStruct { //发送心跳接口 struct SendHandShakeReq : CHTTPReq { string m_reqStr; string ToJson() { return m_reqStr; } }; struct SendHandShakeRet : CHTTPRet { string m_retStr; bool Parse(string strData) { m_retStr = strData; return true; } }; } struct CShakeHandVO { string terminalNo; long ip; string warningLevel; string runState; string customerHandle; string callState; string localMaintain; string remoteMaintain; string termStage; string preTermStage; string netState; string preNetState; }; struct CShakeHandSystemInfo { long serverIP; long totalMem; long freeMem; long procNum; long threadNum; long handleNum; long freeDisk; string osStartTime; long cpuLoad; }; struct CShakeHandErrorVO { long warnLevel; string reserved1; string errList; }; struct CHandShakeHttp { //存储到运行时 CShakeHandVO shakehandvo; CShakeHandSystemInfo shakeHandSystemInfo; CShakeHandErrorVO shakeHandErrorVO; }; enum InstructionType { INC_UNKNOWN = 0, INC_GLOBAL_SETTING_SYNC, INC_COMM_RECONNECT, INC_START_REMOTE_CONTROL, INC_UPDATE_CHECK, INC_RECOVER_SERVICE, INC_PAUSE_SERVICE, INC_AREA_SERVICE_SWITCH, INC_VERSION_ROLLBACK, INC_BRIDGE, INC_VEDIO_CONNECTING, INC_TRADE_MANAGER_NORMAL, INC_TRADE_MANAGER_ON, INC_TRADE_MANAGER_OFF, INC_DEVICE_LOCK_ON, INC_DEVICE_UNLOCK, INC_DEVICE_KICK_OFF, }; class CHeartBeatEntity; class CHeartBeatFSM; class InstructionEvent : public FSMEvent { public: InstructionEvent() : FSMEvent(USER_EVT_INSTRUCTION){} virtual ~InstructionEvent(){} SpReqAnsContext::Pointer ctx; protected: private: }; class CardActiveEvent : public FSMEvent { public: CardActiveEvent() : FSMEvent(USER_EVT_CARD_ACTIVE){} virtual ~CardActiveEvent(){} SpReqAnsContext::Pointer ctx; protected: private: }; class HeartBeatConnection; class CHeartBeatFSM : public FSMImpl { public: enum {s0,s1,s2,s3,s4,s5}; BEGIN_FSM_STATE(CHeartBeatFSM) FSM_STATE_ENTRY(s0,"Init",s0_on_entry,s0_on_exit,s0_on_event) FSM_STATE_ENTRY(s1,"Starting",s1_on_entry,s1_on_exit,s1_on_event) FSM_STATE_ENTRY(s2,"Connected",s2_on_entry,s2_on_exit,s2_on_event) FSM_STATE_ENTRY(s3,"Lost",s3_on_entry,s3_on_exit,s3_on_event) FSM_STATE_ENTRY(s4,"Reject",s4_on_entry,s4_on_exit,s4_on_event) FSM_STATE_ENTRY(s5,"Failed",s5_on_entry,s5_on_exit,s5_on_event) END_FSM_STATE() BEGIN_FSM_RULE(CHeartBeatFSM,s0) FSM_RULE_ENTRY(s0,s1,USER_EVT_START,0) FSM_RULE_ENTRY(s1,s2,USER_EVT_STARTFINISHED,0) FSM_RULE_ENTRY(s1,s0,USER_EVT_STARTFINISHED,1) FSM_RULE_ENTRY(s2,s0,USER_EVT_STOP,0) FSM_RULE_ENTRY(s2,s0,USER_EVT_START,0) FSM_RULE_ENTRY(s4,s0,USER_EVT_STOP,0) END_FSM_RULE() CHeartBeatFSM():m_initTimes(0),m_bUseBackup(false),m_testResult(Error_Succeed), m_warnLevel(0), m_entErrorList(""), m_nLodCtrFlag(0), m_pHandShakeConn(NULL) ,m_pCRAClient(NULL),m_pCISClient(NULL) , m_localDeviceNo(""), m_ILDeviceNo(""), m_tmpMultiBlob(""), m_terminalStage(""), m_strHandShakeUrl(""),m_bAlarmed(false), m_bCrossUseJS(false) ,m_longConnInterval(20000),m_handShakeConnInterval(20000){} ~CHeartBeatFSM(){} virtual ErrorCodeEnum OnInit(); virtual ErrorCodeEnum OnExit(); void s0_on_entry(); void s0_on_exit(); unsigned int s0_on_event(FSMEvent* pEvt); void s1_on_entry(); void s1_on_exit(); unsigned int s1_on_event(FSMEvent* pEvt); void s2_on_entry(); void s2_on_exit(); unsigned int s2_on_event(FSMEvent* pEvt); void s3_on_entry(); void s3_on_exit(); unsigned int s3_on_event(FSMEvent* pEvt); void s4_on_entry(); void s4_on_exit(); unsigned int s4_on_event(FSMEvent* pEvt); void s5_on_entry(); void s5_on_exit(); unsigned int s5_on_event(FSMEvent* pEvt); DWORD m_dwServIP; CSimpleStringA m_strHandShakeUrl;//心跳地址 int Starting(); int DoHandShake(); int DoNewHandShake(); bool HandShakeHttp(IHttpFunc* client,bool &isHeartBeatOk); string HandShakeJsonStr(); static void HttpsLogCallBack(const char* logtxt); void SetConnNULL(){} ErrorCodeEnum SetErrorList(int warmLevel,CSimpleStringA strList); void SelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext); int GetWarnLevel(){return m_warnLevel;} void SetTerminalStageState(CSimpleStringA stage) { m_terminalStage = stage; } CSimpleStringA GetTerminalStageState() { return m_terminalStage; } // Terminal Performance Counter component [Josephus in 9:17:13 2016/4/23] ErrorCodeEnum GetPerformCounter(TermianlCounter& counter); const CSimpleStringA GetRealIP() { return m_csServerIP; } const char* GetRunDiskPath() { return (LPCTSTR)m_csRunDiskName; } void SetLodCtrStatus(int val) { m_nLodCtrFlag = val; } int CardActive(SpReqAnsContext::Pointer ctx); void LocalPreOnline(int slot, CSimpleStringA fromTermNo, CSimpleStringA termNo, CSimpleStringA account, CSimpleStringA data, int type); void LocalPreOnlineJS(int slot, CSimpleStringA fromTermNo, CSimpleStringA termNo, CSimpleStringA account, CSimpleStringA data, int type); void ReceivePreOnlineBack(unsigned long errCode,CSimpleStringA data, unsigned long findCard, unsigned long cardPos, unsigned long userErrCode=0); void ProcessPreOnline(CardActiveReq* req); void ProcessCardActive(CardActiveReq* req); protected: void DoInstruction(SpReqAnsContext::Pointer ctx); private: ErrorCodeEnum GetServerAddr(CSmartPointer &spConfig, bool isCardStore); bool CheckCRASessionOrToConnect(); bool CheckCISSessionOrToConnect(); int m_tmpTestFlag; int m_longConnInterval;//长连接时间间隔 int m_handShakeConnInterval;//新心跳时间间隔 SOCKET m_ConnSocket; CSimpleStringA m_servStr,m_servIP,m_servStrB,m_servIPB,m_entErrorList,m_localDeviceNo,m_ILDeviceNo,m_tmpMultiBlob, m_terminalStage; int m_port,m_portB,m_initTimes,m_warnLevel; unsigned long m_ulServIP; HeartBeatConnection* m_pHandShakeConn; bool m_bUseBackup; ErrorCodeEnum m_testResult; CSimpleStringA m_csServerIP, m_csRunDiskName; int m_nLodCtrFlag; CardReadAdapter::CardReadAdapterService_ClientBase *m_pCRAClient; CardIssuerStore::CardIssuerStoreService_ClientBase* m_pCISClient; bool m_bCrossUseJS; bool m_bAlarmed; bool m_isCardStore; }; struct StartTask : public ITaskSp { CHeartBeatFSM* fsm; StartTask(CHeartBeatFSM* f) : fsm(f) {} void Process() { FSMEvent *e = new FSMEvent(USER_EVT_STARTFINISHED); e->param1 = fsm->Starting(); fsm->PostEventFIFO(e); } }; struct HandShakeTask : public ITaskSp { CHeartBeatFSM* fsm; HandShakeTask(CHeartBeatFSM* f) : fsm(f) {} void Process() { FSMEvent *e = new FSMEvent(USER_EVT_HANDSHAKEFINISHED); e->param1 = fsm->DoHandShake(); fsm->PostEventFIFO(e); } }; struct LodctrTask : public ITaskSp { CHeartBeatFSM* fsm; LodctrTask(CHeartBeatFSM* f) : fsm(f) {} void Process() { HMODULE hDll = LoadLibrary("loadperf.dll"); if(hDll == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load loadperf.dll failed %d", GetLastError()); return; } LpRestorePerfRegistryFromFile restoreFunc = (LpRestorePerfRegistryFromFile)GetProcAddress( hDll, "RestorePerfRegistryFromFileW"); if(restoreFunc == NULL) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetProcAddress of RestorePerfRegistryFromFileW failed %d", GetLastError()); return; } DWORD dwRet = restoreFunc(NULL, NULL); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("restoreFunc returned 0x%08x", dwRet); if(dwRet == 0) { fsm->SetLodCtrStatus(1); } else { fsm->SetLodCtrStatus(2); } return; } }; struct CardActiveTask : public ITaskSp { CHeartBeatFSM* fsm; SpReqAnsContext::Pointer ctx; CardActiveTask(CHeartBeatFSM* f) : fsm(f) {} void Process() { FSMEvent *e = new FSMEvent(USER_EVT_CARD_ACTIVE_FINISHED); e->param1 = fsm->CardActive(ctx); fsm->PostEventFIFO(e); } }; struct ProcessPreOnlineTask : public ITaskSp { CHeartBeatFSM* fsm; CardActiveReq* cardActiveReq; #ifdef RVC_OS_WIN ProcessPreOnlineTask(CHeartBeatFSM *f, CardActiveReq* req) : fsm(f) { cardActiveReq = req; } #else ProcessPreOnlineTask(CHeartBeatFSM* f, CardActiveReq* req) : fsm(f),cardActiveReq(NULL) { if (req != NULL) { cardActiveReq = (CardActiveReq*)malloc(sizeof(struct CardActiveReq)); if(cardActiveReq != NULL) memcpy(cardActiveReq, req, sizeof(struct CardActiveReq)); } } ~ProcessPreOnlineTask() { if (cardActiveReq != nullptr) { free((void*)cardActiveReq); cardActiveReq = nullptr; } } #endif void Process() { fsm->ProcessPreOnline(cardActiveReq); } }; struct NewHandShakeTask : public ITaskSp { CHeartBeatFSM* fsm; NewHandShakeTask(CHeartBeatFSM* f) : fsm(f) {} void Process() { fsm->DoNewHandShake(); } }; class HeartBeatConnection : public SpSecureClient { public: HeartBeatConnection(CEntityBase *pEntity, CHeartBeatFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM), m_TerminalNo("") { CSystemStaticInfo sysSInfo; m_pEntity->GetFunction()->GetSystemStaticInfo(sysSInfo); m_TerminalNo = sysSInfo.strTerminalID; } virtual ~HeartBeatConnection() {} void SendHandShake(); //type:0,send preonline; 1,result of preonline //errCSCode:CardStore returned UserErrorCode void SendCardActive(const int type, const int slot,unsigned long errCode, const char *termNo, const char *account, const int accSize , const char *data, const int dataSize,int findCard,int cardPos, unsigned long errCSCode=0); void PkgRcvProcHandAndInstruc(const CSmartPointer &pRecvPkg); void PkgRcvProcCardActive(const CSmartPointer &pRecvPkg); protected: virtual void OnDisconnect() { m_pFSM->SetConnNULL(); this->Close(); } virtual void OnPkgAnswer(const CSmartPointer &pRecvPkg); //virtual void OnReceivePackage(CSmartPointer &pRecvPkg) //{ // //oiltest //} private: CSimpleStringA m_TerminalNo; CHeartBeatFSM *m_pFSM; }; #endif //__HEARTBEAT_FSM_H