#include "stdafx.h" #include "SpBase.h" #include "FlowControlFSM.h" #include "Event.h" #include "InitiativeTransfer_server_g.h" #include "InitiativeTransfer_msg_g.h" #include "EventCode.h" #include "../mod_interactivecontrol/Event.h" using namespace InitiativeTransfer; #ifndef RVC_CONNECT_ASSIST_ID #define RVC_CONNECT_ASSIST_ID 1 #endif class CFlowControlEntity; class FlowControlServiceSession : public FlowService_ServerSessionBase { public: FlowControlServiceSession(CFlowControlEntity *pEntity) : m_pEntity(pEntity) {} virtual void Handle_SwitchToAgentFlow(SpOnewayCallContext::Pointer ctx); virtual void Handle_DisallowControl(SpOnewayCallContext::Pointer ctx); virtual void Handle_ReturnAgent(SpOnewayCallContext::Pointer ctx); virtual void Handle_SwitchToFrontFlow(SpOnewayCallContext::Pointer ctx); private: CFlowControlEntity *m_pEntity; }; class CFlowControlEntity : public CEntityBase, public ILogListener, public ITimerListener { public: CFlowControlEntity() { } virtual ~CFlowControlEntity() {} virtual const char *GetEntityName() const { return "InitiativeTransfer"; } virtual bool IsService()const{return true;} virtual void OnPreStart(CAutoArray strArgs,CSmartPointer pTransactionContext) { //MessageBoxA(0, 0, 0, 0); m_fsm = new CFlowControlFSM(); ErrorCodeEnum Error = m_fsm->Init(this); int i = 0; CSmartPointer spFunction = GetFunction(); m_arrListener.Init(3); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_RETURNMENU,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_EXIT_BACKRUN,NULL,false); pTransactionContext->SendAnswer(Error); } void OnStarted() { if (Error_Succeed == m_fsm->ConnectToAssistchan(false)){ m_fsm->m_bConnectAssit = true; } else{ GetFunction()->SetTimer(RVC_CONNECT_ASSIST_ID, this, 5000); } } virtual void OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext) { m_fsm->PostEventFIFO(new FSMEvent(USER_EVT_EXIT)); m_pTransactionContext = pTransactionContext; // save for later use CSmartPointer spFunction = GetFunction(); for (int i = 0; i < m_arrListener.GetCount(); ++i) { spFunction->UnsubscribeLog(m_arrListener[i]); } m_arrListener.Clear(); } CSmartPointer m_pTransactionContext; void FinishClose(ErrorCodeEnum Error) { if (m_pTransactionContext != NULL) { m_pTransactionContext->SendAnswer(Error); } } virtual void OnLog(const CAutoArray &SubIDs, const CUUID nLogID,const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError,const DWORD dwUserCode,const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray &Param, const char *pszEntityName, const char *pszModuleName,const char *pszMessage, const linkContext &pLinkInfo) { if (dwUserCode == LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS) { GetFunction()->SetTimer(RVC_CONNECT_ASSIST_ID, this, 5000); m_fsm->m_bConnectAssit = false; Sleep(1000); m_fsm->PostEventFIFO(new FSMEvent(USER_EVT_ASSIS_IDEL)); } else if (dwUserCode == LOG_EVT_UI_RETURNMENU) { m_fsm->PostEventFIFO(new FSMEvent(USER_EVT_MENU_RETURN)); } else if (dwUserCode == LOG_EVT_UI_EXIT_BACKRUN) { m_fsm->PostEventFIFO(new FSMEvent(USER_EVT_EXIT_BACKRUN)); } } virtual CServerSessionBase *OnNewSession(const char* /*pszRemoteEntityName*/, const char * /*pszClass*/) { return new FlowControlServiceSession(this); } virtual void OnTimeout(DWORD dwTimerID) { if (RVC_CONNECT_ASSIST_ID == dwTimerID) { if (false == m_fsm->m_bConnectAssit) { if (Error_Succeed == m_fsm->ConnectToAssistchan(false)) { m_fsm->m_bConnectAssit = true; } } if (m_fsm->m_bConnectAssit) { GetFunction()->KillTimer(RVC_CONNECT_ASSIST_ID); } } } void SwitchToAgentFlow(CSimpleStringW req_context) { ReqAgentFlowEvent *e = new ReqAgentFlowEvent(); e->req_context = req_context; e->m_pEntityBase = this; m_fsm->PostEventFIFO(e); } void DisallowControl() { m_fsm->PostEventFIFO(new FSMEvent(USER_EVT_DISCTRL)); } void SwitchToFrontFlow() { m_fsm->PostEventFIFO(new FSMEvent(USER_EVT_EXIT_BACKRUN)); } void ReturnAgent(CSimpleStringW ans_ctx) { AnsACMFlowEvent *e = new AnsACMFlowEvent(); e->ans_context = ans_ctx; m_fsm->PostEventFIFO(e); } private: CFlowControlFSM *m_fsm; CAutoArray m_arrListener; }; void FlowControlServiceSession::Handle_SwitchToAgentFlow( SpOnewayCallContext::Pointer ctx ) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->SwitchToAgentFlow(ctx->Info.req_context); } void FlowControlServiceSession::Handle_DisallowControl( SpOnewayCallContext::Pointer ctx ) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->DisallowControl(); } void FlowControlServiceSession::Handle_ReturnAgent( SpOnewayCallContext::Pointer ctx ) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->ReturnAgent(ctx->Info.ans_context); } void FlowControlServiceSession::Handle_SwitchToFrontFlow(SpOnewayCallContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->SwitchToFrontFlow(); } void FinishClose(CEntityBase *pEntity, ErrorCodeEnum Error = Error_Succeed) { if (pEntity) { CFlowControlEntity *pFlowControlEntity = static_cast(pEntity); pFlowControlEntity->FinishClose(Error); } } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CFlowControlEntity) SP_END_ENTITY_MAP()