123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- #include "stdafx.h"
- #include "FlowControlFSM.h"
- #define LOG_EVT_EXIT_ACM_FLOW 0x30500002 //退出坐席控制流程
- //错误码
- #define LOG_ERR_S0_ANSACMFLOW 0x30500080
- #define LOG_ERR_S0_REQAGENTFLOW 0x30500081
- #define LOG_ERR_S1_REQAGENTFLOW_FAILED 0x30500082
- #define LOG_ERR_S2_ANSAGENTFLOW_FAILED 0x30500083
- #define LOG_ERR_S2_NTFENTFLOW_FAILED 0x30500084
- #define LOG_ERR_S3_ANSACMFLOW_FAILED 0x30500085
- #define LOG_ERR_S5_DISCTRL_FAILED 0x30500086
- #define LOG_ERR_S5_REQAGENTFLOW_FAILED 0x30500087
- #define LOG_ERR_S7_ENTRY 0x30500088
- #define LOG_ERR_S1_ASSIS_IDEL 0x30500089
- #define LOG_ERR_S2_ASSIS_IDEL 0x3050008A
- #define LOG_ERR_S3_ASSIS_IDEL 0x3050008B
- #define LOG_ERR_S5_ASSIS_IDEL 0x3050008C
- #define LOG_EVT_CONNEC_ASSISTCHAN_FAILED 0x3050008D
- #define LOG_ERR_S2_CHAN_OFF 0x3050008E
- #define LOG_ERR_S3_CHAN_OFF 0x3050008F
- void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer<IReleasable> pData )
- {
- if (Error == Error_Succeed) {
- if (Msg.state == eChannelState_Connected) {
- m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_CHAN_ON));
- }
- else if (Msg.state == eChannelState_Idle) {
- m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_CHAN_OFF));
- }
- }
- }
- void ChannelClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer<IReleasable> pData )
- {
- if (Error == Error_Succeed) {
- m_pFSM->ProcessPacket(Msg.sub_type, Msg.data);
- }
- }
- CFlowControlFSM::CFlowControlFSM(): m_pClient(NULL)
- {
-
- }
- CFlowControlFSM::~CFlowControlFSM()
- {
- }
- void CFlowControlFSM::OnStateTrans( int iSrcState, int iDstState )
- {
- ChanState evt;
- evt.state = iDstState;
- evt.status = CSimpleStringA::Format("OnStateTrans from state %d to %d", iSrcState, iDstState);
- SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(ChanState), SP_MSG_SIG_OF(ChanState), evt);
- switch (iDstState) {
- case s0:
- SetState("O", "Offline"); // offline
- break;
- case s1:
- SetState("F", "FrontFlow"); // frontflow
- break;
- case s2:
- SetState("B", "BackFlow"); // backflow
- break;
- case s3:
- SetState("C", "FrontCall"); // front call
- break;
- case s5:
- SetState("T", "Transferring"); // Transferring
- break;
- default:
- break;
- }
- }
- ErrorCodeEnum CFlowControlFSM::OnInit()
- {
- m_bConnectAssit = false;
-
- AddStateHooker(this);
- return Error_Succeed;
- }
- ErrorCodeEnum CFlowControlFSM::OnExit()
- {
- if (m_pClient != NULL) {
- m_pClient->GetFunction()->CloseSession();
- m_pClient = NULL;
- }
- RemoveStateHooker(this);
- void FinishClose(CEntityBase *pEntity, ErrorCodeEnum Error = Error_Succeed);
- FinishClose(m_pEntity);
- return Error_Succeed;
- }
- bool CFlowControlFSM::IsAssistchanEntityAvailable()
- {
- if (Error_Succeed == ConnectToAssistchan(false)) {
- return true;
- }
- else {
- return false;
- }
- }
- ErrorCodeEnum CFlowControlFSM::ConnectToAssistchan(bool blogevt)
- {
- if (!IsAssistchanConnectSessionOK()) {
- FreeAssistchanClient();
- m_pClient = new ChannelClient(m_pEntity, this);
- ErrorCodeEnum errorCode = m_pClient->Connect();
- if (Error_Succeed != errorCode) {
- m_pClient->SafeDelete();
- m_pClient = NULL;
- if (blogevt) {
- LogWarn(Severity_Middle, Error_InvalidState, LOG_EVT_CONNEC_ASSISTCHAN_FAILED,
- CSimpleStringA::Format("Connect to assistchan entity failed:0x%08x.", errorCode));
- }
- return Error_InvalidState;
- }
- else {
- if (blogevt) {
- DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Connect to assistchan Client Succeed!");
- }
-
- ChannelService_BeginState_Sub ChannelSub;
- errorCode = m_pClient->BeginState(ChannelSub);
- if (Error_Succeed != errorCode)
- {
- DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("BeginState biz channel failed!");
- m_pClient->GetFunction()->CloseSession();
- m_pClient = NULL;
- return errorCode;
- }
-
- ChannelService_BeginRecv_Sub Sub;
- Sub.type = ACM_TYPE_FLW;
- errorCode = m_pClient->BeginRecv(Sub);
- if (Error_Succeed != errorCode)
- {
- DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Register ACM_TYPE_FLW failed!");
- m_pClient->GetFunction()->CloseSession();
- m_pClient = NULL;
- return errorCode;
- }
- }
- }
- return Error_Succeed;
- }
- bool CFlowControlFSM::IsAssistchanConnectSessionOK()
- {
- return (m_pClient != NULL && !m_pClient->QuerySessionClosed());
- }
- void CFlowControlFSM::FreeAssistchanClient()
- {
- if (m_pClient) {
- m_pClient->GetFunction()->CloseSession();
- m_pClient = NULL;
- }
- }
- unsigned int CFlowControlFSM::s0_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_ANSACMFLOW) {
- AgentFlowResult evt;
- evt.error = Error_NetBroken;
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(AgentFlowResult), SP_MSG_SIG_OF(AgentFlowResult), evt);
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S0_ANSACMFLOW, "s0 receive ANSACMFLOW");
- } else if (event->iEvt == USER_EVT_REQAGENTFLOW) {
- AgentFlowResult evt;
- evt.error = Error_NetBroken;
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(AgentFlowResult), SP_MSG_SIG_OF(AgentFlowResult), evt);
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S0_REQAGENTFLOW, "s0 receive REQAGENTFLOW");
- }
- else if (event->iEvt == USER_EVT_ASSIS_IDEL)
- {
- if (Error_Succeed == ConnectToAssistchan(false)) {
- m_bConnectAssit = true;
- }
- }
- return 0;
- }
- unsigned int CFlowControlFSM::s1_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_REQAGENTFLOW) {
- ReqAgentFlowEvent *rafe = static_cast<ReqAgentFlowEvent*>(event);
- ErrorCodeEnum Error;
- if (m_pClient) {
- ChannelService_Send_Info Info;
- Info.compress = true;
- Info.encrypt = true;
- Info.sub_type = ACM_SUBTYPE_REQ_FLOW;
- Info.type = ACM_TYPE_FLW;
- SpBuffer buf;
- buf.OpenWrite();
- #if defined(RVC_OS_WIN)
- buf& rafe->req_context;
- #else
- CSimpleString16Bit reqContext = CSimpleStringW216Bit(rafe->req_context);
- buf& reqContext;
- #endif //RVC_OS_WIN
- Info.data = buf.ToBlob();
- Error = m_pClient->Send(Info);
- }
- else {
- Error = Error_NetBroken;
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S1_REQAGENTFLOW_FAILED, "s1 receive REQAGENTFLOW but chan is off.");
- }
- return Error == Error_Succeed ? 1 : 0;
- }
- else if (event->iEvt == USER_EVT_NTFENTFLOW) {
- NotifyEnterFlowEvent *nef = static_cast<NotifyEnterFlowEvent*>(event);
- NotifyEnterFlow evt;
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(NotifyEnterFlow), SP_MSG_SIG_OF(NotifyEnterFlow), evt);
- }
- else if (event->iEvt == USER_EVT_ASSIS_IDEL)
- {
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S1_ASSIS_IDEL, "s1 ASSIS_IDEL.");
- if (Error_Succeed == ConnectToAssistchan(false)) {
- m_bConnectAssit = true;
- }
- }
- return 0;
- }
- unsigned int CFlowControlFSM::s2_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_CHAN_OFF) {
- // notify UI to unlock the screen
- AgentFlowResult evt;
- evt.error = Error_NetBroken;
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(AgentFlowResult), SP_MSG_SIG_OF(AgentFlowResult), evt);
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S2_CHAN_OFF, "s2 chan off.");
- }
- else if (event->iEvt == USER_EVT_ANSAGENTFLOW) {
- AnsAgentFlowEvent *afe = static_cast<AnsAgentFlowEvent*>(event);
- AgentFlowResult evt;
- #if defined(RVC_OS_WIN)
- evt.ans_context = afe->ans_context;
- #else
- CSimpleStringW ans_context = CSimpleString16Bit2W(afe->ans_context);
- evt.ans_context = ans_context;
- #endif //RVC_OS_WIN
- evt.error = afe->err ? Error_Unexpect : Error_Succeed;
- if (evt.error != Error_Succeed){
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S2_ANSAGENTFLOW_FAILED, "s2 receive ANSAGENTFLOW error.");
- }
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(AgentFlowResult), SP_MSG_SIG_OF(AgentFlowResult), evt);
- }
- else if (event->iEvt == USER_EVT_REQACMFLOW) {
- ReqACMFlowEvent *afe = static_cast<ReqACMFlowEvent *>(event);
- ACMFlowInvoke evt;
- #if defined(RVC_OS_WIN)
- evt.req_context = afe->req_context;
- #else
- CSimpleStringW req_context = CSimpleString16Bit2W(afe->req_context);
- evt.req_context = req_context;
- #endif //RVC_OS_WIN
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(ACMFlowInvoke), SP_MSG_SIG_OF(ACMFlowInvoke), evt);
- }
- else if (event->iEvt == USER_EVT_NTFENTFLOW) {
- ErrorCodeEnum result = DisallowControl();
- if (result != Error_Succeed){
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S2_NTFENTFLOW_FAILED, "s2 send NTFENTFLOW error.");
- }
- }
- else if (event->iEvt == USER_EVT_ASSIS_IDEL){
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S2_ASSIS_IDEL, "s2 ASSIS_IDEL.");
- if (Error_Succeed == ConnectToAssistchan(false)) {
- m_bConnectAssit = true;
- }
- }
- return 0;
- }
- void CFlowControlFSM::s2_on_exit()
- {
- }
- void CFlowControlFSM::s3_on_entry()
- {
-
- }
- void CFlowControlFSM::s3_on_exit() {}
- unsigned int CFlowControlFSM::s3_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_ANSACMFLOW) {
- AnsACMFlowEvent *afe = static_cast<AnsACMFlowEvent*>(event);
- ErrorCodeEnum Error;
- if (m_pClient) {
- ChannelService_Send_Info Info;
- Info.compress = true;
- Info.encrypt = true;
- Info.sub_type = ACM_SUBTYPE_ANS_FLOW;
- Info.type = ACM_TYPE_FLW;
- SpBuffer buf;
- buf.OpenWrite();
- #if defined(RVC_OS_WIN)
- buf& afe->ans_context;
- #else
- CSimpleString16Bit ansContext = CSimpleStringW216Bit(afe->ans_context);
- buf& ansContext;
- #endif //RVC_OS_WIN
- Info.data = buf.ToBlob();
- Error = m_pClient->Send(Info);
- }
- else {
- Error = Error_NetBroken;
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S3_ANSACMFLOW_FAILED, "s3 send ANSACMFLOW error.");
- }
- return Error == Error_Succeed ? 1 : 0;
- }
- else if (event->iEvt == USER_EVT_CHAN_OFF) {
- AgentFlowResult evt;
- evt.error = Error_NetBroken;
- SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(AgentFlowResult), SP_MSG_SIG_OF(AgentFlowResult), evt);
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S3_CHAN_OFF, "s3 chan off.");
- }
- else if (event->iEvt == USER_EVT_ASSIS_IDEL)
- {
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S3_ASSIS_IDEL, "s3 ASSIS_IDEL.");
- if (Error_Succeed == ConnectToAssistchan(false)) {
- m_bConnectAssit = true;
- }
- }
- return 0;
- }
- void CFlowControlFSM::s5_on_entry()
- {
-
- }
- void CFlowControlFSM::s5_on_exit() { }
- unsigned int CFlowControlFSM::s5_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_DISCTRL) {
- ErrorCodeEnum result = DisallowControl();
- if (result != Error_Succeed) {
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S5_DISCTRL_FAILED, "s5 send DISCTRL error.");
- }
- }
- else if (event->iEvt == USER_EVT_REQAGENTFLOW) {
- ReqAgentFlowEvent* rafe = static_cast<ReqAgentFlowEvent*>(event);
- ErrorCodeEnum Error;
- if (m_pClient) {
- ChannelService_Send_Info Info;
- Info.compress = true;
- Info.encrypt = true;
- Info.sub_type = ACM_SUBTYPE_REQ_FLOW;
- Info.type = ACM_TYPE_FLW;
- SpBuffer buf;
- buf.OpenWrite();
- #if defined(RVC_OS_WIN)
- buf& rafe->req_context;
- #else
- CSimpleString16Bit reqContext = CSimpleStringW216Bit(rafe->req_context);
- buf& reqContext;
- #endif //RVC_OS_WIN
- Info.data = buf.ToBlob();
- Error = m_pClient->Send(Info);
- }
- else {
- Error = Error_NetBroken;
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S5_REQAGENTFLOW_FAILED, "s5 send REQAGENTFLOW error.");
- }
- return Error == Error_Succeed ? 1 : 0;
- }
- else if (event->iEvt == USER_EVT_ASSIS_IDEL)
- {
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S5_ASSIS_IDEL, "s5 ASSIS_IDEL.");
- if (Error_Succeed == ConnectToAssistchan(false)) {
- m_bConnectAssit = true;
- }
- }
- return 0;
- }
- void CFlowControlFSM::s7_on_entry()
- {
- LogWarn(Severity_Low, Error_Debug, LOG_ERR_S7_ENTRY, "s7 ENTRY.");
- }
- unsigned int CFlowControlFSM::s7_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_ASSIS_IDEL){
- if (Error_Succeed == ConnectToAssistchan(false)) {
- m_bConnectAssit = true;
- }
- }
- return 0;
- }
- void CFlowControlFSM::ProcessPacket( int sub_type, CBlob &blob )
- {
- if (sub_type == ACM_SUBTYPE_ANS_FLOW) {
- AnsAgentFlowEvent *e = new AnsAgentFlowEvent();
- SpBuffer buf;
- buf.OpenRead((const char*)blob.m_pData, blob.m_iLength);
- buf.SetLength(blob.m_iLength);
- buf & e->err & e->ans_context;
- PostEventFIFO(e);
- } else if (sub_type == ACM_SUBTYPE_REQ_FLOW) {
- ReqACMFlowEvent *e = new ReqACMFlowEvent();
- SpBuffer buf;
- buf.OpenRead((const char*)blob.m_pData, blob.m_iLength);
- buf.SetLength(blob.m_iLength);
- buf & e->req_context;
- PostEventFIFO(e);
- } else if (sub_type == ACM_SUBTYPE_NTF_ENTFLOW) {
- NotifyEnterFlowEvent *e = new NotifyEnterFlowEvent();
- e->m_pFSM = this;
- SpBuffer buf;
- buf.OpenRead((const char*)blob.m_pData, blob.m_iLength);
- buf.SetLength(blob.m_iLength);
- buf & e->context;
- PostEventFIFO(e);
- } else {
- DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown sub_type from agent!");
- }
- }
- ErrorCodeEnum CFlowControlFSM::SetState(const char *s, const char *sdesc)
- {
- return m_pEntity->GetFunction()->SetSysVar("BackInitiative", s);
- }
- ErrorCodeEnum CFlowControlFSM::DisallowControl()
- {
- if (m_pClient) {
- ChannelService_Send_Info Info;
- Info.compress = false;
- Info.encrypt = true;
- Info.id = 0;
- Info.sub_type = ACM_SUBTYPE_DIS_CONTROL;
- Info.type = ACM_TYPE_FLW;
- return m_pClient->Send(Info);
- } else {
- return Error_NetBroken;
- }
- }
- void NotifyEnterFlowEvent::OnUnhandled()
- {
- m_pFSM->DisallowControl();
- }
|