#ifndef __CUSTMNGRAUTH_FSM_H #define __CUSTMNGRAUTH_FSM_H #pragma once #include "SpFSM.h" #include "SpSecureClient.h" #include "CustMngrAuth_server_g.h" #include "CustMngrAuth_msg_g.h" #include "FingerPrint_client_g.h" #include "MaintainWatcher_client_g.h" #include "MaintainWatcher_msg_g.h" #include "DeviceControl_client_g.h" #include "CommEntityUtil.hpp" #include "json/json.h" using namespace CustMngrAuth; using namespace MaintainWatcher; using namespace DeviceControl; using namespace FingerPrint; using namespace SP::Module::Comm; struct FeatReq { char TerminalID[16]; char BranchID[16]; char CurrentAgent[16]; char UpdateTime[20]; }; struct FeatReply { int ResultCode; char BranchID[16]; char CurrentAgent[16]; char Data[0];//no more than 45k }; struct FeatureData { CAutoArray FingerIDArray; CAutoArray FingerIDLenArray; }; struct TemplateInfo { CSimpleStringA CustomerID; int TemplateNum; }; struct MatchParams { FingerPrintService_Match_Req sMatchReq; FingerPrintService_Match_Ans sMatchAns; vector sFingerCount; int sTotalNumOfTemplate; //Total Num of template which is not empty }; struct JsonParams { Json::Value Root; int Index; Json::Value FingerInfo; }; struct TempFeatureData { CSimpleStringA MaxUpdateTime; map tmpFeatureMap; }; struct RunInfoParams { CSimpleStringA LatestTime; CSimpleStringA UpdateTime; CSimpleStringA CurrentTime; bool IsFirstTimeQueryData; CSimpleStringA SrcFile; CSimpleStringA BackupFile; }; #pragma pack() enum EvtType{ USER_EVT_TEST = EVT_USER + 1, USER_EVT_QUIT, USER_EVT_INIT, USER_EVT_INIT_FINISHED, USER_EVT_AUTHORIZE_START, USER_EVT_AUTHORIZE_FINISHED, USER_EVT_AUTHORIZE_CANCEL, USER_EVT_COLLECTFINGERPRINT_START, USER_EVT_COLLECTFINGERPRINT_FINISHED, USER_EVT_COLLECTFINGERPRINT_CANCEL, USER_EVT_SAVEFINGERPRINT_START, USER_EVT_SAVEFINGERPRINT_FINISHED, USER_EVT_CHECKUKEY, USER_EVT_CHECKUKEY_FINISHED, USER_EVT_HOLDON, USER_EVT_EXIT, }; enum AuthByWhich//授权结果 { AuthByNone = 0, AuthByFngPrnt = 1, AuthByUkey = 2, }; struct AuthContext { AuthByWhich eAuthByWhich; CSimpleStringA UkeyID; CSimpleStringA CustomerID; }; class CCustMngrAuthEntity; class CCustMngrAuthFSM; class AuthorizeStartEvent : public FSMEvent { public: AuthorizeStartEvent() : FSMEvent(USER_EVT_AUTHORIZE_START){} ~AuthorizeStartEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled() { Dbg("authorize_start unhandled"); } protected: private: }; class AuthorizeFinishedEvent : public FSMEvent { public: AuthorizeFinishedEvent() : FSMEvent(USER_EVT_AUTHORIZE_FINISHED){} ~AuthorizeFinishedEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled() { Dbg("authorize_finished unhandled"); } protected: private: }; class AuthorizeCancelEvent : public FSMEvent { public: AuthorizeCancelEvent() : FSMEvent(USER_EVT_AUTHORIZE_CANCEL){} ~AuthorizeCancelEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled() { if (ctx!=NULL) { Dbg("authorize_cancel unhandled"); ctx->Answer(Error_InvalidState); } Dbg("authorize_cancel unhandled"); } protected: private: }; class CollectFingerPrintStartEvent : public FSMEvent { public: CollectFingerPrintStartEvent() : FSMEvent(USER_EVT_COLLECTFINGERPRINT_START){} ~CollectFingerPrintStartEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled() { if (ctx!=NULL) { Dbg("collect_finger_print unhandled"); ctx->Answer(Error_InvalidState); } } }; class CollectFingerPrintFinishedEvent : public FSMEvent { public: CollectFingerPrintFinishedEvent() : FSMEvent(USER_EVT_COLLECTFINGERPRINT_FINISHED){} ~CollectFingerPrintFinishedEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled() { if (ctx!=NULL) { Dbg("collect_finger_print_finished unhandled"); ctx->Answer(Error_InvalidState); } } protected: private: }; class CancelCollectFingerPrintEvent : public FSMEvent { public: CancelCollectFingerPrintEvent() : FSMEvent(USER_EVT_COLLECTFINGERPRINT_CANCEL){} ~CancelCollectFingerPrintEvent(){} virtual void OnUnhandled() { Dbg("cancel collect fingerprint unhandled"); } }; class SaveFingerPrintStartEvent : public FSMEvent { public: SaveFingerPrintStartEvent() : FSMEvent(USER_EVT_SAVEFINGERPRINT_START){} ~SaveFingerPrintStartEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled(){ if (ctx!=NULL) { Dbg("save_finger_print_start unhandled"); ctx->Answer(Error_InvalidState); } } }; class SaveFingerPrintFinishedEvent : public FSMEvent { public: SaveFingerPrintFinishedEvent() : FSMEvent(USER_EVT_SAVEFINGERPRINT_FINISHED){} ~SaveFingerPrintFinishedEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled() { if (ctx != NULL) { Dbg("save_finger_print_finished unhandled"); ctx->Answer(Error_InvalidState); } } }; class CheckUkeyEvent : public FSMEvent { public: CheckUkeyEvent() : FSMEvent(USER_EVT_CHECKUKEY){} ~CheckUkeyEvent(){} virtual void OnUnhandled() { Dbg("check_ukey unhandled"); } }; class CheckUkeyFinishedEvent : public FSMEvent { public: CheckUkeyFinishedEvent() : FSMEvent(USER_EVT_CHECKUKEY_FINISHED){} ~CheckUkeyFinishedEvent(){} virtual void OnUnhandled() { Dbg("check_ukey_finished unhandled"); } }; class HoldOnEvent : public FSMEvent { public: HoldOnEvent() : FSMEvent(USER_EVT_HOLDON){} ~HoldOnEvent(){} SpReqAnsContext::Pointer ctx; virtual void OnUnhandled(){ if (ctx != NULL) { Dbg("hold on unhandled"); ctx->Answer(Error_InvalidState); } } }; class FeatureUpdateConn; class CCustMngrAuthFSM : public FSMImpl { public: enum { s0, s1, s2, s3, s4, s5}; BEGIN_FSM_STATE(CCustMngrAuthFSM) FSM_STATE_ENTRY(s0, "Init", s0_on_entry, s0_on_exit, s0_on_event) FSM_STATE_ENTRY(s1, "Initializing", s1_on_entry, s1_on_exit, s1_on_event) FSM_STATE_ENTRY(s2, "Idle", s2_on_entry, s2_on_exit, s2_on_event) FSM_STATE_ENTRY(s3, "Authorizing", s3_on_entry, s3_on_exit, s3_on_event) FSM_STATE_ENTRY(s4, "Registering", 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(CCustMngrAuthFSM, s0) FSM_RULE_ENTRY(s0, s2, USER_EVT_TEST, 0) FSM_RULE_ENTRY(s0, s1, USER_EVT_INIT, 0) FSM_RULE_ENTRY(s0, FSM_STATE_EXIT, USER_EVT_QUIT, 0) FSM_RULE_ENTRY(s1, s2, USER_EVT_INIT_FINISHED, 0) FSM_RULE_ENTRY(s1, s5, USER_EVT_INIT_FINISHED, 1) FSM_RULE_ENTRY(s1, FSM_STATE_EXIT, USER_EVT_QUIT, 0) FSM_RULE_ENTRY(s2, s3, USER_EVT_AUTHORIZE_START, 0) FSM_RULE_ENTRY(s2, s4, USER_EVT_COLLECTFINGERPRINT_START, 0) FSM_RULE_ENTRY(s2, s4, USER_EVT_CHECKUKEY, 0) FSM_RULE_ENTRY(s2, s4, USER_EVT_SAVEFINGERPRINT_START, 0) FSM_RULE_ENTRY(s2, FSM_STATE_EXIT, USER_EVT_QUIT, 0) FSM_RULE_ENTRY(s3, s2, USER_EVT_EXIT, 0) FSM_RULE_ENTRY(s3, s2, USER_EVT_AUTHORIZE_FINISHED, 0) FSM_RULE_ENTRY(s4, s2, USER_EVT_COLLECTFINGERPRINT_START, 0) FSM_RULE_ENTRY(s4, s2, USER_EVT_COLLECTFINGERPRINT_FINISHED, 0) FSM_RULE_ENTRY(s4, s2, USER_EVT_SAVEFINGERPRINT_FINISHED, 0) FSM_RULE_ENTRY(s4, s2, USER_EVT_CHECKUKEY_FINISHED, 0) FSM_RULE_ENTRY(s3, FSM_STATE_EXIT, USER_EVT_QUIT, 0) FSM_RULE_ENTRY(s5, FSM_STATE_EXIT, USER_EVT_QUIT, 0) END_FSM_RULE() CCustMngrAuthFSM(): m_pMaintainWatcher(NULL), m_pFingerPrint(NULL), m_pDeviceControl(NULL), m_bCancelCollectFP(false) , m_bCancelAuthorize(false), m_bAuthorizeTimeout(false) { hStopUpdate = ::CreateEventA(NULL, TRUE, FALSE, NULL); m_TimeLimit = 55;//默认授权超时秒数 m_ctx = NULL; InitializeCriticalSection(&m_cs); } ~CCustMngrAuthFSM(){ DeleteCriticalSection(&m_cs); } virtual ErrorCodeEnum OnInit(); virtual ErrorCodeEnum OnExit(); void s0_on_entry(); void s0_on_exit(); unsigned int s0_on_event(FSMEvent* event); void s1_on_entry(); void s1_on_exit(); unsigned int s1_on_event(FSMEvent* event); void s2_on_entry(); void s2_on_exit(); unsigned int s2_on_event(FSMEvent* event); void s3_on_entry(); void s3_on_exit(); unsigned int s3_on_event(FSMEvent* event); void s4_on_entry(); void s4_on_exit(); unsigned int s4_on_event(FSMEvent* event); void s5_on_entry(); void s5_on_exit(); unsigned int s5_on_event(FSMEvent* event); HANDLE hStopUpdate; AuthContext m_authCtx; CSimpleStringA m_TerminalID; CSimpleStringA m_csMachineType; SpReqAnsContext::Pointer m_ctx; int Initial(); ErrorCodeEnum OpenRunInfoFile(); ErrorCodeEnum MatchFingerPrint(SpReqAnsContext::Pointer ctx, bool& bStopAuthorize); ErrorCodeEnum WaitForUkey(ErrorCodeEnum eErr); void CancelAuthorize(); void FeatureUpdate(); ErrorCodeEnum CollectFingerPrint(SpReqAnsContext::Pointer ctx, DWORD& dwUserErrCode); ErrorCodeEnum GetImgBlob(CBlob &data, CSimpleStringA imgPath); void BroadcastPressFinger(int times, bool bPressFinger); ErrorCodeEnum SwitchUSB(bool bOpen); ErrorCodeEnum SaveFingerPrint(SpReqAnsContext::Pointer); int CompareTime(CSimpleStringA time1, CSimpleStringA time2); int CompareUpdateTime(const char* time1, const char* time2); bool ReadDataIntoMemory(bool& bHasData); void UpdateDataIntoMemory(map tempFeature, bool bIsFirstTimeQueryData); string ClearStringSpaceHeadTail(string& line); CSimpleStringA GetCurrentDate(); ErrorCodeEnum ReceiveDataFromServer(CAutoArray& dataArray, RunInfoParams runInfoParam); bool BackupFile(CSimpleStringA srcFile, CSimpleStringA dstFile); CSimpleStringA GetMaxTime(CSimpleStringA maxTime, CSimpleStringA tempTime); CSimpleString GenerateAlarmJson(CSimpleString entityName, int cost); void BroadcastGetFinger(int status); void InitBeforeUpdateData(); ErrorCodeEnum ConnectFingerPrintEntity(); ErrorCodeEnum PrepareDataBeforeMatch(MatchParams *matchParam); ErrorCodeEnum MatchProcess(MatchParams* matchParam, bool& bStopAuthorize); ErrorCodeEnum AnalyzeMatchResult(MatchParams* matchParam, bool& bStopAuthorize); ErrorCodeEnum CollectProcess(SpReqAnsContext::Pointer &ctx, DWORD& dwUserErrCode); ErrorCodeEnum LoadRunConfig(CSmartPointer& spConfig); void InitTimeParams(RunInfoParams & runInfoParam, CSmartPointer &spConfig); ErrorCodeEnum InitBeforeQueryData(RunInfoParams& runInfoParam, CSmartPointer& spConfig); ErrorCodeEnum BackupBeforeWriteData(RunInfoParams& runInfoParam, CSmartPointer& spConfig); ErrorCodeEnum WriteData(RunInfoParams& runInfoParam, CAutoArray dataArray, CSmartPointer& spConfig); ErrorCodeEnum ProcessFeatureData(JsonParams &jsonParam, TempFeatureData &tmpFeatureData, RunInfoParams runinfoParam, CSmartPointer& spConfig); private: DeviceControlService_ClientBase *m_pDeviceControl; FingerPrintService_ClientBase *m_pFingerPrint; MaintainCertificate_ClientBase *m_pMaintainWatcher; FeatureUpdateConn *m_pConnection; CSimpleStringA m_FingerSection; CSimpleStringA m_RunInfoPath; bool m_bCancelCollectFP, m_bCancelAuthorize, m_bAuthorizeTimeout; int m_TimeLimit; map m_featureData; CRITICAL_SECTION m_cs; }; class FeatureUpdateConn : public SpSecureClient { public: FeatureUpdateConn(CEntityBase *pEntity, CCustMngrAuthFSM *pFSM) : SpSecureClient(pEntity) { m_pFSM = pFSM; m_jsonLen = 0; m_GetErrMsg = false; m_reply = NULL; m_hPkgAnswer = ::CreateEventA(NULL, TRUE, FALSE, NULL); } virtual ~FeatureUpdateConn() {} virtual void OnDisconnect() { Dbg("FeatureUpdateConnection disconnected"); } void SendFeatReq(const char* currAgent, const char* branchID, const char* lastTime = NULL) { LOG_FUNCTION(); m_reply = NULL; m_jsonLen = 0; FeatReq req = { 0 }; memcpy(req.BranchID, branchID, 16); memcpy(req.CurrentAgent, currAgent, 16);//transfer flag if (lastTime != NULL) { memcpy(req.UpdateTime, lastTime, 20); Dbg("req.UpdateTime:%s", req.UpdateTime); } #ifdef RVC_OS_WIN Dbg("req.TerminalID = %s, m_pFSM->m_TerminalID = %s", req.TerminalID, m_pFSM->m_TerminalID.GetData()); strncpy_s(req.TerminalID, sizeof(req.TerminalID), m_pFSM->m_TerminalID, m_pFSM->m_TerminalID.GetLength()); #else strncpy(req.TerminalID, m_pFSM->m_TerminalID, m_pFSM->m_TerminalID.GetLength()); #endif // RVC_OS_WIN CSmartPointer pkt = CreateNewPackage("FETQYREQ"); pkt->AddStruct("FETQYREQ", false, false, (LPBYTE)&req, sizeof(FeatReq)); SendPackage(pkt); } virtual void OnPkgAnswer(const CSmartPointer &pRecvPkg) { DWORD dwSysCode, dwUserCode; string errMsg; if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, errMsg)) { string serviceCode = pRecvPkg->GetServiceCode(); Dbg("receive %s ans packet is error, errormsg is %s", serviceCode.c_str(), errMsg.c_str()); m_GetErrMsg = true; SetEvent(m_hPkgAnswer); }else{ Dbg("success, no error message."); string serviceCode = pRecvPkg->GetServiceCode(); if (serviceCode == "FETQYREQ") { int dataLen = pRecvPkg->GetStructLen("FETQYANS"); if (dataLen > 0 ) { Dbg("GetStructData structlen: %d", dataLen); BYTE *pBuffer = new BYTE[dataLen]; memset(pBuffer, 0, dataLen); int arrayNum = 0; if (pRecvPkg->GetStructData("FETQYANS", pBuffer, &dataLen, &arrayNum)) { LPBYTE pData = new BYTE[dataLen +1]; memcpy(pData, pBuffer, dataLen); m_reply = (FeatReply*)pData; if (m_reply != NULL) { pData[dataLen] = 0; m_jsonLen = dataLen - sizeof(FeatReply); }else Dbg("ERROR: m_reply is null!"); }else Dbg("ERROR: getstructdata(FETQYANS) failed!"); delete pBuffer; }else Dbg("ERROR: getstructlen(FETQYANS) = 0!"); SetEvent(m_hPkgAnswer); }else Dbg("ERROR: wrong service code!"); } } private: CCustMngrAuthFSM *m_pFSM; public: HANDLE m_hPkgAnswer; bool m_GetErrMsg; FeatReply* m_reply; int m_jsonLen; }; struct InitTask : public ITaskSp { CCustMngrAuthFSM *fsm; InitTask(CCustMngrAuthFSM *f) : fsm(f) {} void Process() { LOG_FUNCTION(); FSMEvent *e = new FSMEvent(USER_EVT_INIT_FINISHED); e->param1 = fsm->Initial(); fsm->PostEventFIFO(e); } }; struct FeatureUpdateTask : public ITaskSp { CCustMngrAuthFSM *fsm; FeatureUpdateTask(CCustMngrAuthFSM *f) : fsm(f) {} void Process() { LOG_FUNCTION(); fsm->FeatureUpdate(); } }; struct MatchFingerPrintTask : public ITaskSp { CCustMngrAuthFSM *fsm; MatchFingerPrintTask(CCustMngrAuthFSM *f) : fsm(f) {} SpReqAnsContext::Pointer ctx; void Process() { bool bStopAuthorize = false; ErrorCodeEnum eErr = fsm->MatchFingerPrint(ctx, bStopAuthorize); if (bStopAuthorize) { AuthorizeFinishedEvent *e = new AuthorizeFinishedEvent(); e->ctx = ctx; e->param1 = eErr; fsm->PostEventFIFO(e); } else { AuthorizeFinishedEvent *e = new AuthorizeFinishedEvent(); e->ctx = ctx; e->param1 = fsm->WaitForUkey(eErr); fsm->PostEventFIFO(e);//指纹匹配异常停止,继续等到超时或ukey插入结束授权,如果是ukey插入,这个event就不会被处理 } } }; struct CollectFingerPrintTask : public ITaskSp { CCustMngrAuthFSM *fsm; SpReqAnsContext::Pointer ctx; CollectFingerPrintTask(CCustMngrAuthFSM *f) : fsm(f){} void Process() { LOG_FUNCTION(); CollectFingerPrintFinishedEvent *e = new CollectFingerPrintFinishedEvent(); e->ctx = ctx; DWORD dwUserErrorCode = 0; ErrorCodeEnum eErr = fsm->CollectFingerPrint(ctx, dwUserErrorCode); if(eErr == Error_Unexpect && dwUserErrorCode > 0) ctx->Answer(eErr, dwUserErrorCode); else ctx->Answer(eErr); fsm->PostEventFIFO(e); } }; struct SaveFingerPrintTask : public ITaskSp { CCustMngrAuthFSM *fsm; SpReqAnsContext::Pointer ctx; SaveFingerPrintTask(CCustMngrAuthFSM *f) : fsm(f) {} void Process() { LOG_FUNCTION(); SaveFingerPrintFinishedEvent *e = new SaveFingerPrintFinishedEvent(); e->ctx = ctx; ErrorCodeEnum eErr = fsm->SaveFingerPrint(ctx); ctx->Answer(eErr); fsm->PostEventFIFO(e); } }; #endif //__CUSTMNGRAUTH_FSM_H