#include "stdafx.h" #include "ConnectorFSM.h" #include "../include/ModuleMix.h" #define RELEASEING_TIMER_INTERVAL 1200 #define RELEASEING_SIP_TIMER 20000 #define SIP_CALL_TIMER 70000 //sip呼叫超时时间,20170314,增加超时时间解决坐席忽闪问题 #define RELEASEING_SIP_TIMEOUT 30000 #define SIP_CONNECT_FAIL_TIMES 10 #define LIVEDETECT_CONNECT_INTERVAL 5000 //live detection实体检测间隔5s #define LIVEDETECTION_TIMEOUT 60000 //活体检测超时时间60s class SyncServiceClient:public SyncService_ClientBase { public: SyncServiceClient(CEntityBase *pEntity, ACMCallFSM* fsm) : SyncService_ClientBase(pEntity), m_fsm(fsm) {} ACMCallFSM *m_fsm; }; class MyPhoneClient : public PhoneService_ClientBase { public: MyPhoneClient(CEntityBase *pEntity, ACMCallFSM* fsm) : PhoneService_ClientBase(pEntity), m_fsm(fsm) {} virtual void OnMessage(ErrorCodeEnum Error, PhoneService_PhoneState_Info &Msg, CSmartPointer pData) { Dbg("rx sip phone state = %d, status = %s", Msg.state, (LPCSTR)Msg.status); //LOG_TRACE("rx sip phone state = %d", Msg.state); if (Error == Error_Succeed) { switch (Msg.state) { case ePhone_Init: case ePhone_Terminated: { FSMEvent *e = new FSMEvent(USER_EVT_SIP_STATE_IDLE); m_fsm->PostEventFIFO(e); } break; case ePhone_Ready: { Dbg("sip channel connected"); FSMEvent *e = new FSMEvent(USER_EVT_SIP_STATE_CONNECTED); m_fsm->PostEventFIFO(e); } break; default: break; } } } ACMCallFSM *m_fsm; }; class MyChannelClient : public ChannelService_ClientBase { public: MyChannelClient(CEntityBase *pEntity, ACMCallFSM* fsm) : ChannelService_ClientBase(pEntity), m_fsm(fsm) {} virtual void OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer pData) { if (Error == Error_Succeed) { switch (Msg.state) { case eChannelState_Idle: { FSMEvent *e = new FSMEvent(USER_EVT_CHAN_STATE_IDLE); m_fsm->PostEventFIFO(e); } break; case eChannelState_Connected: { Dbg("CHAN_STATE_CONNECTED.param = %s", (LPCSTR)Msg.param); FSMEvent *e = new ChanStateConnectedEvent(Msg.param); m_fsm->PostEventFIFO(e); } break; default: break; } } } ACMCallFSM *m_fsm; }; ACMCallFSM::ACMCallFSM( ) : m_pPhoneClient(NULL), m_pChannelClient(NULL), m_bRing(FALSE),m_nCurSipServer(MAIN_SERVER),m_nCurChanServer(MAIN_SERVER) { } ACMCallFSM::~ACMCallFSM() { } ErrorCodeEnum ACMCallFSM::OnInit() { memset(m_strSIPProxyIP,0,sizeof(m_strSIPProxyIP)); memset(m_strSIPCallNum,0,sizeof(m_strSIPCallNum)); memset(m_iSIPProxyPort,0,sizeof(m_iSIPProxyPort)); memset(m_strChanCallNum,0,sizeof(m_strChanCallNum)); memset(m_strChanProxyIP,0,sizeof(m_strChanProxyIP)); memset(m_iSIPProxyPort,0,sizeof(m_iSIPProxyPort)); ErrorCodeEnum Error = LoadConfig(); if (Error != Error_Succeed) goto on_error; Dbg("LoadConfig success"); GetEntityBase()->GetFunction()->SetSysVar("CallState", "O"); // set to offline state Error = LoadTerminalId(); if (Error != Error_Succeed) goto on_error; Dbg("sip proxy ip1:%s,num1:%s,port1:%d;ip2:%s,num2:%s,port2:%d", (LPCSTR)m_strSIPProxyIP[0],(LPCSTR)m_strSIPCallNum[0], m_iSIPProxyPort[0],(LPCSTR)m_strSIPProxyIP[1],(LPCSTR)m_strSIPCallNum[1], m_iSIPProxyPort[1]); Dbg("chan proxy ip1:%s,num1:%s,port1:%d;ip2:%s,num2:%s,port2:%d", (LPCSTR)m_strChanProxyIP[0],(LPCSTR)m_strChanCallNum[0], m_iChanProxyPort[0],(LPCSTR)m_strChanProxyIP[1],(LPCSTR)m_strChanCallNum[1], m_iChanProxyPort[1]); Dbg("TerminalId: %s", (LPCSTR)m_strTerminalId); m_bHangup = FALSE; m_bHandFree = TRUE; m_bAgentHandFree = TRUE; m_bIsAgentControl = FALSE; m_nSipErrorNum = 0; m_nLiveDetctionTime = 0; memset(&m_CallingParam,0,sizeof(m_CallingParam)); m_pPhoneClient = new MyPhoneClient(m_pEntity, this); Error = m_pPhoneClient->Connect(); if (Error != Error_Succeed) goto on_error; PhoneService_BeginState_Sub PhoneSub; Error = m_pPhoneClient->BeginState(PhoneSub); if (Error != Error_Succeed) goto on_error; m_pSyncServiceClient = new SyncServiceClient(m_pEntity,this); Error = m_pSyncServiceClient->Connect(); if (Error != Error_Succeed) { Dbg("Connect SyncService Fail!"); m_pSyncServiceClient->SafeDelete(); m_pSyncServiceClient = NULL; //goto on_error; } m_nSysCallType = 0; m_pChannelClient = new MyChannelClient(m_pEntity, this); Error = m_pChannelClient->Connect(); if (Error != Error_Succeed) goto on_error; ChannelService_BeginState_Sub ChannelSub; Error = m_pChannelClient->BeginState(ChannelSub); if (Error != Error_Succeed) goto on_error; Dbg("fsm init ok!"); AddStateHooker(this); return Error; on_error: Dbg("on_error"); FSMEvent *e = new FSMEvent(USER_EVT_ERROR); PostEventFIFO(e); // jump to error state return Error; } BOOL ACMCallFSM::ReConnectionAssistchan() { if (m_pChannelClient != NULL) { m_pChannelClient->GetFunction()->CloseSession(); m_pChannelClient->SafeDelete(); m_pChannelClient = NULL; Dbg("Close AssistChannel Session "); } if (m_pChannelClient == NULL) { Dbg("ReConnection AssistChannel Session"); ErrorCodeEnum Error; m_pChannelClient = new MyChannelClient(m_pEntity, this); Error = m_pChannelClient->Connect(); if (Error != Error_Succeed) { m_pChannelClient->SafeDelete(); Dbg("m_channelClient connect fail!"); return FALSE; } if (Error == Error_Succeed) { ChannelService_BeginState_Sub ChannelSub; Error = m_pChannelClient->BeginState(ChannelSub); if (Error != Error_Succeed) { Dbg("BeginState biz channel failed!"); m_pChannelClient->GetFunction()->CloseSession(); m_pChannelClient->SafeDelete(); m_pChannelClient = NULL; return FALSE; } } } return TRUE; } BOOL ACMCallFSM::ReConnectionSipphone() { if (m_pPhoneClient != NULL) { m_pPhoneClient->GetFunction()->CloseSession(); m_pPhoneClient->SafeDelete(); m_pPhoneClient = NULL; Dbg("Close sip Session "); } if (m_pPhoneClient == NULL) { Dbg("ReConnection sip Session"); ErrorCodeEnum Error; m_pPhoneClient = new MyPhoneClient(m_pEntity, this); Error = m_pPhoneClient->Connect(); if (Error != Error_Succeed) { m_pPhoneClient->SafeDelete(); Dbg("m_phoneClient connect fail!"); return FALSE; } if (Error == Error_Succeed) { PhoneService_BeginState_Sub PhoneSub; Error = m_pPhoneClient->BeginState(PhoneSub); if (Error != Error_Succeed) { Dbg("BeginState sip failed!"); m_pPhoneClient->GetFunction()->CloseSession(); m_pPhoneClient->SafeDelete(); m_pPhoneClient = NULL; return FALSE; } } } return TRUE; } int ACMCallFSM::GetDelayTime() { ErrorCodeEnum error= Error_Unexpect; SyncService_GetMachineData_Req req; req.key = "DelayTime"; SyncService_GetMachineData_Ans ans; DWORD Timeout = 500; if (m_pSyncServiceClient) { error = m_pSyncServiceClient->GetMachineData(req,ans,Timeout); } if (error == Error_Succeed) { int delaytime = atoi(ans.value); return delaytime; } else { return -1; } } void ACMCallFSM::SetDelayTime() { if (m_pSyncServiceClient) { SyncService_SetMachineData_Info info; info.key = "DelayTime"; info.data = "0"; m_pSyncServiceClient->SetMachineData(info); Dbg("set delay time to 0"); } } ErrorCodeEnum ACMCallFSM::OnExit() { return Error_Succeed; } void ACMCallFSM::OnStateTrans(int iSrcState, int iDstState) { Dbg("FSM state from state %s to %s", GetStateName(iSrcState), GetStateName(iDstState)); if (CheckBeginRing(iSrcState, iDstState)) { StartRing(); } else { if (CheckEndRing(iSrcState, iDstState)) StopRing(); } if (iSrcState != FSM_STATE_INIT && iDstState != FSM_STATE_EXIT) { int st1 = TranslateState(iSrcState); int st2 = TranslateState(iDstState); if (st1 != st2) { PhoneState evt; evt.state = st2; evt.status = CSimpleStringA::Format("OnStateTrans from state %d to %d", st1, st2); //LOG_TRACE(evt.status); if (!((st2 == eState_Fail)&&(m_nCurChanServer!=Error_Server)&&(m_nCurSipServer!=Error_Server))||m_bHangup) { Dbg("Broadcast state from %d to %d", st1, st2); SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(PhoneState), SP_MSG_SIG_OF(PhoneState), evt); } SetCallState(st2); GetEntityBase()->GetFunction()->SetUserDefineState(st2+USER_SIP_OFFLINE); } } } ErrorCodeEnum ACMCallFSM::SetCallState(int state) { char *sts[] = { "O", // Offline "C", // Connecting "H", // HandFree "P", // Pickup "B", // Broken "F", // Fail "R", // Releasing "L" // LiveDetect }; char* strCallState = "O"; if (0 <= state && state < sizeof(sts)/sizeof(char*)){ strCallState = sts[state]; } Dbg("set call state to [%s].", strCallState); return GetEntityBase()->GetFunction()->SetSysVar("CallState", strCallState); } void ACMCallFSM::s0_on_entry() { m_strHintCallNum.Clear(); m_nCurChanServer = MAIN_SERVER; m_nCurSipServer = MAIN_SERVER; memset(&m_CallingParam,0,sizeof(m_CallingParam)); GetEntityBase()->GetFunction()->SetSysVar("CallType", "N"); //进入初始状态时设置呼叫模式为常规呼叫 m_nSysCallType = 0; } void ACMCallFSM::s0_on_exit() { m_bHangup = FALSE; } unsigned int ACMCallFSM::s0_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_PICKUP_CALL) { memset(&m_CallingParam,0,sizeof(m_CallingParam)); //正常呼叫 GetEntityBase()->GetFunction()->SetSysVar(SYSVAR_CALLTYPE, CALLTYPE_NORMAL); // 设置呼叫模式为常规呼叫 m_nSysCallType = 0; } else if (event->iEvt == USER_EVT_HANDFREE_CALL) { GetEntityBase()->GetFunction()->SetSysVar(SYSVAR_CALLTYPE,CALLTYPE_NORMAL); // 设置呼叫模式为常规呼叫 m_nSysCallType = 0; memset(&m_CallingParam,0,sizeof(m_CallingParam)); // 正常呼叫 } else if (event->iEvt == USER_EVT_COMMAND_CALL) { //由指令模块触发呼叫 GetEntityBase()->GetFunction()->SetSysVar(SYSVAR_CALLTYPE, CALLTYPE_MOBILE); // 设置呼叫模式为手机呼叫 m_nSysCallType = 1; Dbg("start command call!"); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == USER_EVT_STARTVIDEODISPLAY) { StartVideoDisplayEvent *e = static_cast(event); StartVideo((LPCSTR)e->m_param); } else if (event->iEvt == USER_EVT_SHOWLOACALVIDEO) { ShowLocalVideoEvent *e = static_cast(event); SetCallingType(NORMAL_CALLTYPE); StartVideo((LPCSTR)e->m_param); } else if (event->iEvt == USER_EVT_SHOWLOACALREMOTEVIDEO) { ShowLocalAndRemoteVideoEvent *e = static_cast(event); SetCallingType(NORMAL_CALLTYPE); StartVideo((LPCSTR)e->m_param); } else if (event->iEvt == USER_EVT_DOUBLE_RECORD_CALL) { m_CallingParam.nCallType = DOUBLERECORD_CALLTYPE; //GetEntityBase()->GetFunction()->SetSysVar(SYSVAR_CALLTYPE,CALLTYPE_RECORD); // 设置呼叫模式为双录呼叫 m_nSysCallType = 0; Dbg("start double record call,call type is %d.", m_CallingParam.nCallType); } else if (event->iEvt == USER_EVT_STOPLOACALREMOTEVIDEO) { Dbg("stop show local and remote video."); StopVideo(); SetCallingType(NORMAL_CALLTYPE); } return 0; } void ACMCallFSM::s7_on_entry() { } void ACMCallFSM::s7_on_exit() { } unsigned int ACMCallFSM::s7_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_STOPLOCALVIDEO) { Dbg("stop show local video"); StopVideo(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s9_on_entry() { Dbg("start liveness detection."); m_nLiveDetctionTime = 0; ScheduleTimer(9, 2*LIVEDETECT_CONNECT_INTERVAL); } void ACMCallFSM::s9_on_exit() { CancelTimer(9); m_nLiveDetctionTime = 0; } unsigned int ACMCallFSM::s9_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_STOPVIDEODISPLAY) { //ScheduleTimer(9,3000); Dbg("stop live detection display"); StopVideo(); LogEvent(Severity_Middle,LOG_EVT_RELEASELIVEDETECTION,"release live detection"); } else if (event->iEvt == EVT_TIMER) { m_nLiveDetctionTime += LIVEDETECT_CONNECT_INTERVAL; if (Error_InvalidState == GetLivenessDetectionStatus()){ StopLivenessDetection(); } else{ if (m_nLiveDetctionTime > LIVEDETECTION_TIMEOUT){ Dbg("liveness detection timeout."); StopLivenessDetection(); } else{ ScheduleTimer(9, LIVEDETECT_CONNECT_INTERVAL); } } } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s8_on_entry() { int time = GetDelayTime(); Dbg("get Delay time = %d",time); if (time > 0) { ScheduleTimer(8,time*1000); } else { PostEventFIFO(new FSMEvent(EVT_TIMER)); } } void ACMCallFSM::s8_on_exit() { CancelTimer(8); } unsigned int ACMCallFSM::s8_on_event(FSMEvent* event) { return 0; } void ACMCallFSM::s10_on_entry() { //LOG_FUNCTION(); ErrorCodeEnum Error = Error_Succeed; if (m_nCurSipServer == Error_Server) { Error = Error_NetBroken; } if (Error != Error_Succeed) { PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL)); } } void ACMCallFSM::s10_on_exit() {} unsigned int ACMCallFSM::s10_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == USER_EVT_STOPLOACALREMOTEVIDEO) { Dbg("hang up call and stop show local and remote video."); PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); m_bHangup=TRUE; StopVideo(); } return 0; } void ACMCallFSM::s11_on_entry() { ErrorCodeEnum Error = Error_Succeed; if (m_nCurSipServer == Error_Server) { Error = Error_NetBroken; } if (Error == Error_Succeed) { if (m_CallingParam.nCallType != NORMAL_CALLTYPE && m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE) { Dbg("Begin Make Distribute Call!"); Error = MakeCall(m_nCurSipServer,m_CallingParam); if (Error!=Error_Succeed) { m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER); } Dbg("make call result:0x%08x", Error); } else { if (NORMAL_CALLTYPE == m_CallingParam.nCallType){ Dbg("Begin Make Normal Call!"); } else{ Dbg("Begin Make Record Call!"); } Error = MakeCall(m_strHintCallNum.GetLength() > 0 ? (LPCSTR)m_strHintCallNum : (LPCSTR)m_strSIPCallNum[m_nCurSipServer],m_nCurSipServer); if (Error!=Error_Succeed) { m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER); } Dbg("make call result:0x%08x", Error); } } if (Error != Error_Succeed) { PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL)); } else { ScheduleTimer(11,SIP_CALL_TIMER); } } void ACMCallFSM::s11_on_exit() { CancelTimer(11); } unsigned int ACMCallFSM::s11_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_HANGUP) { m_bHangup = TRUE; } else if (event->iEvt == USER_EVT_SIP_STATE_IDLE) { m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER); m_nSipErrorNum++; //StopChannel(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { Dbg("sip call timeout,release call"); m_nSipErrorNum++; } else if (event->iEvt == USER_EVT_JMP_FAIL) { m_nSipErrorNum++; } else if (event->iEvt == USER_EVT_STOPLOACALREMOTEVIDEO) { Dbg("hang up call and stop show local and remote video."); PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); m_bHangup=TRUE; StopVideo(); } return 0; } void ACMCallFSM::s12_on_entry() { ErrorCodeEnum Error = Error_Succeed; if (m_nCurChanServer == Error_Server) { Error = Error_NetBroken; } m_nSipErrorNum = 0; Sleep(200); if (Error == Error_Succeed) { Dbg("begin start channel,m_nCurChanServer=%d",m_nCurChanServer); if (m_CallingParam.nCallType == NORMAL_CALLTYPE && m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE) { Error = StartChannel(m_nCurChanServer); } else { Error = StartChannel(m_nCurChanServer,m_CallingParam); if (DOUBLERECORD_CALLTYPE == m_CallingParam.nCallType){ if (FALSE == m_bHandFree){ StopSpeakerAudioCapture(); Dbg("double record call type, current is pick up mode, stop speaker audio capture."); } } } Dbg("start channel result:0x%08x", Error); if (Error != Error_Succeed) { Dbg("start channel failed:0x%08x,start hangup", Error); HangupCall(); m_nCurChanServer?(m_nCurChanServer=Error_Server):(m_nCurChanServer=BACK_SERVER); Dbg("hangup call result:0x%08x", Error); } } if (Error != Error_Succeed) { PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL)); } } void ACMCallFSM::s12_on_exit() {} unsigned int ACMCallFSM::s12_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_HANGUP) { m_bHangup = TRUE; } else if (event->iEvt == USER_EVT_SIP_STATE_IDLE) { m_nCurSipServer?(m_nCurSipServer=Error_Server):(m_nCurSipServer=BACK_SERVER); StopChannel(); } else if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { if (!m_bHangup) { m_nCurChanServer?(m_nCurChanServer=Error_Server):(m_nCurChanServer=BACK_SERVER); } HangupCall(); //StopVideo(); } else if (event->iEvt == USER_EVT_CHAN_STATE_CONNECTED) { ChanStateConnectedEvent *e = static_cast(event); StartVideo((LPCSTR)e->m_param); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == USER_EVT_STOPLOACALREMOTEVIDEO) { Dbg("hang up call and stop show local and remote video."); PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); m_bHangup=TRUE; StopVideo(); } return 0; } void ACMCallFSM::s13_on_entry() { if (m_bHandFree) { PostEventLIFO(new FSMEvent(USER_EVT_JMP_HANDFREE)); } else { PostEventLIFO(new FSMEvent(USER_EVT_JMP_PICKUP)); } } void ACMCallFSM::s13_on_exit() {} unsigned int ACMCallFSM::s13_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s14_on_entry() { } void ACMCallFSM::s14_on_exit() { } unsigned int ACMCallFSM::s14_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_STOPLOACALREMOTEVIDEO) { Dbg("stop show local and remote video."); StopVideo(); } else if (event->iEvt == USER_EVT_STOP_RECORD_BROADCAST) { Dbg("stop double record broadcast."); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s20_on_entry() { StopChannel(); } void ACMCallFSM::s20_on_exit() {} unsigned int ACMCallFSM::s20_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { StopVideo(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s21_on_entry() { ScheduleTimer(21,RELEASEING_SIP_TIMER); HangupCall(); } void ACMCallFSM::s21_on_exit() { CancelTimer(21); CancelTimer(210); } unsigned int ACMCallFSM::s21_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { if(event->param1 == 21) { Dbg("hangupcall timeout,release call"); ScheduleTimer(210,RELEASEING_SIP_TIMEOUT); ReleaseCall(0); } else if (event->param1 == 210) { Dbg("release call timeout,restart sipphone"); PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL)); //重启mod_sipphone //RealSipErrorCheck(); LogEvent(Severity_High,EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone "); } } return 0; } void ACMCallFSM::s22_on_entry() { StopChannel(); } void ACMCallFSM::s22_on_exit() {} unsigned int ACMCallFSM::s22_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { StopVideo(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s23_on_entry() { if((!m_bHangup)&&(((m_nCurSipServer==BACK_SERVER)&&(m_nCurChanServer!=Error_Server))||((m_nCurChanServer==BACK_SERVER)&&(m_nCurSipServer!=Error_Server)))) { PostEventLIFO(new FSMEvent(USER_EVT_RECONNECT)); } else { ScheduleTimer(23, RELEASEING_TIMER_INTERVAL); } } void ACMCallFSM::s23_on_exit() { CancelTimer(23); } unsigned int ACMCallFSM::s23_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { if (m_nSipErrorNum >= SIP_CONNECT_FAIL_TIMES) { m_nSipErrorNum = 0; //RealSipErrorCheck(); LogEvent(Severity_High,EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone "); } } return 0; } void ACMCallFSM::s24_on_entry() { ScheduleTimer(24, RELEASEING_TIMER_INTERVAL); } void ACMCallFSM::s24_on_exit() { CancelTimer(24); } unsigned int ACMCallFSM::s24_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s3_on_entry() {} void ACMCallFSM::s3_on_exit() {} unsigned int ACMCallFSM::s3_on_event(FSMEvent* event) { //LOG_TRACE("ACMCallFSM::s3_on_event, id = %d", event->iEvt); if (event->iEvt == USER_EVT_TO_HANDFREE) { //m_bHandFree = TRUE; } else if (event->iEvt == USER_EVT_TO_PICKUP) { //m_bHandFree = FALSE; } else if (event->iEvt == USER_EVT_SIP_STATE_IDLE) { StopChannel(); } else if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { HangupCall(); StopVideo(); } else if (event->iEvt == USER_EVT_AGENT_WRITABLE) { AllowAgentWrite(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s4_on_entry() {} void ACMCallFSM::s4_on_exit() {} unsigned int ACMCallFSM::s4_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_TO_HANDFREE) { //m_bHandFree = TRUE; } else if (event->iEvt == USER_EVT_TO_PICKUP) { //m_bHandFree = FALSE; } else if (event->iEvt == USER_EVT_SIP_STATE_IDLE) { StopChannel(); } else if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { HangupCall(); StopVideo(); } else if (event->iEvt == USER_EVT_AGENT_WRITABLE) { AllowAgentWrite(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s50_on_entry() {} void ACMCallFSM::s50_on_exit() {} unsigned int ACMCallFSM::s50_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { StopVideo(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s51_on_entry() {} void ACMCallFSM::s51_on_exit() {} unsigned int ACMCallFSM::s51_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { StopVideo(); } return 0; } void ACMCallFSM::s52_on_entry() { ScheduleTimer(52,RELEASEING_SIP_TIMER); } void ACMCallFSM::s52_on_exit() { CancelTimer(52); CancelTimer(520); } unsigned int ACMCallFSM::s52_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { if (event->param1 == 52) { ScheduleTimer(520,RELEASEING_SIP_TIMEOUT); Dbg("sip finished timeout,release call"); ReleaseCall(0); } else if (event->param1 == 520) { Dbg("release call timeout,restart sipphone"); PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL)); //重启mod_sipphone //RealSipErrorCheck(); LogEvent(Severity_High,EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone "); } } return 0; } void ACMCallFSM::s53_on_entry() { ScheduleTimer(53, RELEASEING_TIMER_INTERVAL); } void ACMCallFSM::s53_on_exit() { CancelTimer(53); } unsigned int ACMCallFSM::s53_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { if (m_nSipErrorNum >= SIP_CONNECT_FAIL_TIMES) { m_nSipErrorNum = 0; //RealSipErrorCheck(); LogEvent(Severity_High,EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone "); } } return 0; } void ACMCallFSM::s60_on_entry() { StopChannel(); HangupCall(); } void ACMCallFSM::s60_on_exit() {} unsigned int ACMCallFSM::s60_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { StopVideo(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s61_on_entry() {} void ACMCallFSM::s61_on_exit() {} unsigned int ACMCallFSM::s61_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_CHAN_STATE_IDLE) { StopVideo(); } else if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } return 0; } void ACMCallFSM::s62_on_entry() { ScheduleTimer(62,RELEASEING_SIP_TIMER); } void ACMCallFSM::s62_on_exit() { CancelTimer(62); CancelTimer(620); } unsigned int ACMCallFSM::s62_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { if (event->param1 == 62) { ScheduleTimer(620,RELEASEING_SIP_TIMEOUT); Dbg("sip hangup timeout,release call"); ReleaseCall(0); } else if (event->param1 == 620) { Dbg("release call timeout,restart sipphone"); PostEventFIFO(new FSMEvent(USER_EVT_JMP_FAIL)); //重启mod_sipphone //RealSipErrorCheck(); LogEvent(Severity_High,EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone "); } } return 0; } void ACMCallFSM::s63_on_entry() { ScheduleTimer(63, RELEASEING_TIMER_INTERVAL); } void ACMCallFSM::s63_on_exit() { CancelTimer(63); } unsigned int ACMCallFSM::s63_on_event(FSMEvent* event) { if (event->iEvt == USER_EVT_ASSISTCHAN_IDEL) { ReConnectionAssistchan(); } else if (event->iEvt == USER_EVT_SIPPHONE_IDEL) { ReConnectionSipphone(); } else if (event->iEvt == EVT_TIMER) { if (m_nSipErrorNum >= SIP_CONNECT_FAIL_TIMES) { m_nSipErrorNum = 0; //RealSipErrorCheck(); LogEvent(Severity_High,EVENT_MOD_RELEASESIP_TIMEOUT,"restart sipphone "); } } return 0; } int ACMCallFSM::TranslateState( int innerState ) { switch (innerState) { case s0: return eState_Offline; case s8: case s10: case s11: case s12: case s13: return eState_Connecting; case s20: case s21: case s22: case s23: case s24: return eState_Fail; case s3: return eState_HandFree; case s4: return eState_Pickup; case s50: case s51: case s52: case s53: return eState_Broken; case s7: case s14: case s60: case s61: case s62: case s63: return eState_Releasing; case s9: return eState_LiveDetect; default: assert(0); return 0; } }