#pragma once #include "SpBase.h" #include "SpHelper.h" #include "SpFSM.h" #include "InitiativeTransfer_server_g.h" #include "InitiativeTransfer_msg_g.h" #include "AssistantChannel_client_g.h" #include "chan_protocol.h" using namespace AssistantChannel; #include "InitiativeTransfer_msg_g.h" using namespace InitiativeTransfer; #define USER_EVT_REQAGENTFLOW EVT_USER+1 #define USER_EVT_ANSAGENTFLOW EVT_USER+2 #define USER_EVT_CHAN_ON EVT_USER+3 #define USER_EVT_CHAN_OFF EVT_USER+4 #define USER_EVT_NTFENTFLOW EVT_USER+5 #define USER_EVT_DISCTRL EVT_USER+6 #define USER_EVT_REQACMFLOW EVT_USER+9 #define USER_EVT_ANSACMFLOW EVT_USER+10 #define USER_EVT_EXIT EVT_USER+50 #define USER_EVT_ASSIS_IDEL EVT_USER+60 #define USER_EVT_MENU_RETURN EVT_USER+70 #define USER_EVT_EXIT_BACKRUN EVT_USER+80 class CFlowControlFSM; class ChannelClient : public ChannelService_ClientBase { public: ChannelClient(CEntityBase *pEntity, CFlowControlFSM *pFSM) : ChannelService_ClientBase(pEntity), m_pFSM(pFSM) {} virtual void OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer pData); virtual void OnMessage(ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer pData); private: CFlowControlFSM *m_pFSM; }; struct ReqAgentFlowEvent : public FSMEvent { ReqAgentFlowEvent() : FSMEvent(USER_EVT_REQAGENTFLOW) {} virtual ~ReqAgentFlowEvent() {} CSimpleStringW req_context; virtual void OnUnhandled() { AgentFlowResult evt; evt.error = Error_InvalidState; SpSendBroadcast(m_pEntityBase->GetFunction(), SP_MSG_OF(AgentFlowResult),SP_MSG_SIG_OF(AgentFlowResult),evt); } CEntityBase *m_pEntityBase; }; struct AnsAgentFlowEvent : public FSMEvent { AnsAgentFlowEvent() : FSMEvent(USER_EVT_ANSAGENTFLOW) {} virtual ~AnsAgentFlowEvent() {} #if defined(RVC_OS_WIN) CSimpleStringW ans_context; #else CSimpleString16Bit ans_context; #endif //RVC_OS_WIN int err; }; struct NotifyEnterFlowEvent : public FSMEvent { NotifyEnterFlowEvent() : FSMEvent(USER_EVT_NTFENTFLOW) {} virtual ~NotifyEnterFlowEvent() {} virtual void OnUnhandled(); #if defined(RVC_OS_WIN) CSimpleStringW context; #else CSimpleString16Bit context; #endif //RVC_OS_WIN CFlowControlFSM *m_pFSM; }; struct AnsACMFlowEvent : public FSMEvent { AnsACMFlowEvent() : FSMEvent(USER_EVT_ANSACMFLOW) {} virtual ~AnsACMFlowEvent() {} CSimpleStringW ans_context; }; struct ReqACMFlowEvent : public FSMEvent { ReqACMFlowEvent() : FSMEvent(USER_EVT_REQACMFLOW) {} virtual ~ReqACMFlowEvent() {} #if defined(RVC_OS_WIN) CSimpleStringW req_context; #else CSimpleString16Bit req_context; #endif //RVC_OS_WIN }; class CFlowControlFSM : public FSMImpl, public IFSMStateHooker { public: enum {s0, s1, s2, s3, s5, s7}; BEGIN_FSM_STATE(CFlowControlFSM) FSM_STATE_ENTRY(s0, "Offline", s0_on_entry, s0_on_exit, s0_on_event) FSM_STATE_ENTRY(s1, "FrontFlow", s1_on_entry, s1_on_exit, s1_on_event) FSM_STATE_ENTRY(s2, "BackRun", s2_on_entry, s2_on_exit, s2_on_event) FSM_STATE_ENTRY(s3, "FrontCall", s3_on_entry, s3_on_exit, s3_on_event) FSM_STATE_ENTRY(s5, "Transferring", s5_on_entry, s5_on_exit, s5_on_event) FSM_STATE_ENTRY(s7, "Error", s7_on_entry, s7_on_exit, s7_on_event) END_FSM_STATE() BEGIN_FSM_RULE(CFlowControlFSM, s0) FSM_RULE_ENTRY_ANY(s0, s1, USER_EVT_CHAN_ON) FSM_RULE_ENTRY_ANY(s0, FSM_STATE_EXIT, USER_EVT_EXIT) FSM_RULE_ENTRY_ANY(s0, s0, USER_EVT_ANSACMFLOW) FSM_RULE_ENTRY_ANY(s0, s0, USER_EVT_REQAGENTFLOW) FSM_RULE_ENTRY(s1, s7, USER_EVT_REQAGENTFLOW, 0) FSM_RULE_ENTRY(s1, s2, USER_EVT_REQAGENTFLOW, 1) FSM_RULE_ENTRY_ANY(s1, s0, USER_EVT_CHAN_OFF) FSM_RULE_ENTRY_ANY(s1, s5, USER_EVT_NTFENTFLOW) FSM_RULE_ENTRY_ANY(s2, s0, USER_EVT_CHAN_OFF) FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_MENU_RETURN) FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_EXIT_BACKRUN) FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_ANSAGENTFLOW) FSM_RULE_ENTRY_ANY(s2, s3, USER_EVT_REQACMFLOW) FSM_RULE_ENTRY_ANY(s2, s2, USER_EVT_NTFENTFLOW) FSM_RULE_ENTRY_ANY(s2, s7, USER_EVT_REQAGENTFLOW) FSM_RULE_ENTRY(s3, s2, USER_EVT_ANSACMFLOW, 1) FSM_RULE_ENTRY(s3, s7, USER_EVT_ANSACMFLOW, 0) FSM_RULE_ENTRY_ANY(s3, s0, USER_EVT_CHAN_OFF) FSM_RULE_ENTRY_ANY(s5, s1, USER_EVT_DISCTRL) FSM_RULE_ENTRY_ANY(s5, s2, USER_EVT_REQAGENTFLOW) FSM_RULE_ENTRY_ANY(s5, s0, USER_EVT_CHAN_OFF) FSM_RULE_ENTRY_ANY(s7, s0, USER_EVT_CHAN_OFF) END_FSM_RULE() CFlowControlFSM(); ~CFlowControlFSM(); virtual void OnStateTrans(int iSrcState, int iDstState); 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 s5_on_entry(); void s5_on_exit(); unsigned int s5_on_event(FSMEvent* event); void s6_on_entry() {} void s6_on_exit() {} unsigned int s6_on_event(FSMEvent* event) {} void s7_on_entry(); void s7_on_exit() {} unsigned int s7_on_event(FSMEvent* event); void ProcessPacket(int sub_type, CBlob &blob); ErrorCodeEnum SetState(const char *s, const char *sdesc); bool IsAssistchanEntityAvailable(); ErrorCodeEnum ConnectToAssistchan(bool blogevt = false); bool IsAssistchanConnectSessionOK(); void FreeAssistchanClient(); ErrorCodeEnum DisallowControl(); bool m_bConnectAssit; private: bool m_bChanOff; ChannelClient *m_pClient; };