///////////////////////////////// ///// 连线服务 ///////////////////////////////// #include "stdafx.h" #include "ListEntry.h" #include "Event.h" #include "mod_counterconnector.h" #include "CounterConnector_msg_g.h" #include "../mod_interactivecontrol/Event.h" using namespace CounterConnector; #define EVT_CONVERTER "EventConverter" void CCounterConnectorEntity ::OnPreStart(CAutoArray strArgs,CSmartPointer pTransactionContext) { ErrorCodeEnum Error = __OnStart(Error_Succeed); CSmartPointer spFunction = GetFunction(); pTransactionContext->SendAnswer(Error); } void CCounterConnectorEntity ::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext) { ErrorCodeEnum Error = __OnClose(Error_Succeed); pTransactionContext->SendAnswer(Error); } void CCounterConnectorEntity ::OnSelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext) { if (Test_ShakeHand == eTestType) { pTransactionContext->SendAnswer(Error_Succeed); } } ErrorCodeEnum CCounterConnectorEntity ::__OnStart(ErrorCodeEnum preOperationError) { if (preOperationError != Error_Succeed) { return preOperationError; } //MessageBoxA(0, 0, 0, 0); //is Pad Version m_pCurrentSession = NULL; m_bIsSalesRecord = false; m_bIsRemoteRecord = false; m_bHasLaunched = false; CSmartPointer spFunction = GetFunction(); CSystemStaticInfo stStaticinfo; spFunction->GetSystemStaticInfo(stStaticinfo); m_fsm.Init(this); int i = 0; m_arrListener.Init(22); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_CALL,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_CALL,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANDFREE_TO_PICKUP); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_PICKUP_TO_HANDFREE); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_CONNECTING); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_HANNUP_BY_AGENT); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_PICKUP); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_GPIO_HANDFREE); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_MOD_SIPPHONE_STARTED_SUCCESS); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTRECORD,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPRECORD,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_STARTPHOTOGRAPH,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STARTREMOTERECORD,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, LOG_EVT_UI_STOPREMOTERECORD,NULL,false); spFunction->SubscribeLog(m_arrListener[i++], this, Log_Event, Severity_None, Error_IgnoreAll, EVENT_MOD_SIP_GET_VIDEO_FAILED, NULL, false); spFunction->RegistSysVarEvent("UIState", this); return Error_Succeed; } void CCounterConnectorEntity::OnStarted() { CSimpleStringA uiState; GetFunction()->GetSysVar("UIState", uiState); if (uiState.GetLength() > 0 && uiState[0] == 'M'){ if (false == m_bHasLaunched) { m_bHasLaunched = true; } } Sleep(500); m_pCounterConnectorChannel = new ChannelCounterConnectorClient(this); if (Error_Succeed == ConnectAssistChannel()){ m_bConnectAssist = true; } else { GetFunction()->SetTimer(1, this, 3600); } if (m_fsm.ReConnectionAssistchan()){ m_fsm.m_bConAssist = true; } else { GetFunction()->SetTimer(2, this, 3900); } Sleep(500); if (m_fsm.ReConnectionSipphone()){ m_fsm.m_bConSipphone = true; } else { GetFunction()->SetTimer(3, this, 3700); } m_fsm.ReConnectionSyncService(); LoadEntityConfig(); m_fsm.m_iCallRouteType = m_iRouteType; } ErrorCodeEnum CCounterConnectorEntity::ConnectAssistChannel() { if (NULL == m_pCounterConnectorChannel) { m_pCounterConnectorChannel = new ChannelCounterConnectorClient(this); } ErrorCodeEnum Error = m_pCounterConnectorChannel->Connect(); if (Error != Error_Succeed) { LogWarn(Severity_Low, Error_Debug, EVENT_MOD_CONNECT_ASSIST_ERROR, "connect assistant channel error"); #ifdef RVC_OS_WIN m_pCounterConnectorChannel->SafeDelete(); #endif m_pCounterConnectorChannel = NULL; return Error; } { ChannelService_BeginState_Sub Sub; Error = m_pCounterConnectorChannel->BeginState(Sub); if (Error != Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("BeginState biz channel failed!"); m_pCounterConnectorChannel->GetFunction()->CloseSession(); #ifdef RVC_OS_WIN m_pCounterConnectorChannel->SafeDelete(); #endif m_pCounterConnectorChannel = NULL; return Error; } } { ChannelService_BeginRecv_Sub Sub; Sub.type = ACM_TYPE_DEVICE; Error = m_pCounterConnectorChannel->BeginRecv(Sub); if (Error != Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Begin BeginRecv ACM_TYPE_DEVICE failed!"); m_pCounterConnectorChannel->GetFunction()->CloseSession(); #ifdef RVC_OS_WIN m_pCounterConnectorChannel->SafeDelete(); #endif m_pCounterConnectorChannel = NULL; return Error; } } { ChannelService_BeginRecv_Sub Sub; Sub.type = ACM_TYPE_AGENTVIDEOTYPE; Error = m_pCounterConnectorChannel->BeginRecv(Sub); if (Error != Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Begin BeginRecv ACM_TYPE_AGENTVIDEOTYPE failed!"); m_pCounterConnectorChannel->GetFunction()->CloseSession(); #ifdef RVC_OS_WIN m_pCounterConnectorChannel->SafeDelete(); #endif m_pCounterConnectorChannel = NULL; return Error; } } { ChannelService_BeginRecv_Sub Sub; Sub.type = ACM_TYPE_CALLTRANS; Error = m_pCounterConnectorChannel->BeginRecv(Sub); if (Error != Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Begin BeginRecv ACM_TYPE_CALLTRANS failed!"); m_pCounterConnectorChannel->GetFunction()->CloseSession(); #ifdef RVC_OS_WIN m_pCounterConnectorChannel->SafeDelete(); #endif m_pCounterConnectorChannel = NULL; return Error; } } return Error; } void CCounterConnectorEntity::OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName) { if (_stricmp(pszKey, "UIState") == 0) { if (pszValue[0] == 'M') { if (false == m_bHasLaunched){ m_bHasLaunched = true; } } } } ErrorCodeEnum CCounterConnectorEntity::LoadEntityConfig() { SpIniMappingTable table; int iRouteType = 0; int iPickUpCallType = 0; table.AddEntryInt("CounterConnector", "CallRouteType", iRouteType, 0); table.AddEntryInt("CounterConnector", "PickUpCallType", iPickUpCallType, 0); CSmartPointer spConfig; ErrorCodeEnum Error = GetFunction()->OpenConfig(Config_CenterSetting, spConfig); if (Error == Error_Succeed) { Error = table.Load(spConfig); } if (1 == iRouteType) { m_iRouteType = 1; } if (1 == iPickUpCallType) { m_iPickUpCallType = 1; } if (1 != m_iRouteType) { LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALLROUTE_TYPE, CSimpleStringA::Format("call route type is %d.", m_iRouteType).GetData()); } return Error; } ErrorCodeEnum CCounterConnectorEntity::SetCallRouteParams(CSimpleStringA strQueueName, CSimpleStringA strClientLevel) { ErrorCodeEnum Error = Error_Succeed; m_fsm.m_strQueueName = strQueueName; m_fsm.m_strAddClientLevel = strClientLevel; return Error; } void CCounterConnectorEntity::HandlePickUpCallEvent() { if (1 == m_iPickUpCallType) { PickUpCallMsg evt; evt.infos = "pickup call"; SpSendBroadcast(GetFunction(), SP_MSG_OF(PickUpCallMsg), SP_MSG_SIG_OF(PickUpCallMsg), evt); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("SpSendBroadcast PickUpCallMsg to UI."); } else { m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_PICKUP_CALL)); m_fsm.m_bNeedQueueName = false; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Terminate pickup call."); } } void CCounterConnectorEntity::HandleGetVideoFailedEvent() { MediaService_ClientBase* pMSClient = new MediaService_ClientBase(this); CSimpleStringA strCustomerBeing; GetFunction()->GetSysVar("CustomerBeing", strCustomerBeing); CSimpleStringA strCustomerHandle; GetFunction()->GetSysVar("CustomerHandle", strCustomerHandle); CSimpleStringA strCameraState; GetFunction()->GetSysVar("CameraState", strCameraState); CSimpleStringA strmsg(""); CSimpleStringA strinfo(""); if (pMSClient->Connect() != Error_Succeed){ strmsg = CSimpleStringA::Format("connect mediacontroller entity failed"); pMSClient->SafeDelete(); pMSClient = NULL; } else{ strmsg = CSimpleStringA::Format("connect mediacontroller entity success"); pMSClient->GetFunction()->CloseSession(); pMSClient->SafeDelete(); pMSClient = NULL; } strinfo = CSimpleStringA::Format("%s, and CustomerBeing is %s, CustomerHandle is %s, CameraState is %s.", strmsg, strCustomerBeing.GetData(), strCustomerHandle.GetData(), strCameraState.GetData()); LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_GET_VIDEO_FAILED_INFO, strinfo.GetData()); } void CCounterConnectorEntity::HandlePickUpMicroPhoneEvent(int iEvent, const char* strMsg) { PickUpMicroPhoneEvt evt; evt.state = iEvent; evt.infos = strMsg; SpSendBroadcast(GetFunction(), SP_MSG_OF(PickUpMicroPhoneEvt), SP_MSG_SIG_OF(PickUpMicroPhoneEvt), evt); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("%s", strMsg); } ErrorCodeEnum CCounterConnectorEntity ::__OnClose(ErrorCodeEnum preOperationError) { if (preOperationError != Error_Succeed) { return preOperationError; } CSmartPointer spFunction = GetFunction(); for (int i = 0; i < m_arrListener.GetCount(); ++i) { spFunction->UnsubscribeLog(m_arrListener[i]); } spFunction->UnregistSysVarEvent("UIState"); m_arrListener.Clear(); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_EXIT)); return Error_Succeed; } void CCounterConnectorEntity ::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) { switch (dwUserCode) { case EVENT_MOD_CONNECT_GPIO_PICKUP: { m_fsm.m_bHandFree = false; if (!m_fsm.m_bIsAgentControl) { m_fsm.m_bAgentHandFree = false; } CSimpleStringA strValue; GetFunction()->GetSysVar("CallState", strValue); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("摘机,and CallState is %s.", strValue.GetData()); HandlePickUpMicroPhoneEvent(1, "pick up microphone."); } break; case EVENT_MOD_CONNECT_GPIO_HANDFREE: { m_fsm.m_bHandFree = true; if (!m_fsm.m_bIsAgentControl) { m_fsm.m_bAgentHandFree = true; } CSimpleStringA strValue; GetFunction()->GetSysVar("CallState", strValue); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("挂机,and CallState is %s.", strValue.GetData()); HandlePickUpMicroPhoneEvent(0, "hang up microphone."); } break; case EVENT_MOD_CONNECT_PICKUP_CALL: // 提机呼叫 { if (m_bHasLaunched){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("提机呼叫"); HandlePickUpCallEvent(); } else{ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("UI has not launched, ignore it."); } } break; case EVENT_MOD_CONNECT_HANDFREE_CALL: // 免提呼叫 m_fsm.m_bNeedQueueName = true; if (m_fsm.m_bHandFree) { LogEvent(Severity_Middle,EVENT_MOD_CONNECT_SLV_HANDFREECALL,"handfree call"); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("界面拨号,免提呼叫"); if (pszMessage && strlen(pszMessage) > 0 && isdigit(pszMessage[0])) { char tmp[32]; int i = 0; const char *p = pszMessage; while (isdigit(*p) && i < 30) { tmp[i++] = *p++; } tmp[i] = 0; m_fsm.m_strHintCallNum = tmp; } else { m_fsm.m_strHintCallNum = ""; } //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv UI call num = %s",m_fsm.m_strHintCallNum.GetData()); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANDFREE_CALL)); } else { LogEvent(Severity_Middle,EVENT_MOD_CONNECT_SLV_PICKUPCALL,"from hand free to pickup call because pickup"); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("界面拨号,话筒呼叫"); if (pszMessage && strlen(pszMessage) > 0 && isdigit(pszMessage[0])) { char tmp[32]; int i = 0; const char *p = pszMessage; while (isdigit(*p) && i < 30) { tmp[i++] = *p++; } tmp[i] = 0; m_fsm.m_strHintCallNum = tmp; } else { m_fsm.m_strHintCallNum = ""; } //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv call num = %s",m_fsm.m_strHintCallNum); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_PICKUP_CALL)); } break; case EVENT_MOD_CONNECT_HANDFREE_TO_PICKUP: // 免提->提机 { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("免提->提机"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_PICKUP)); if (strcmp(m_fsm.GetCurrStateName(),"HandFree")==0){ m_fsm.m_bAgentHandFree = false; } SendCurAudioDevice(); } break; case EVENT_MOD_CONNECT_PICKUP_TO_HANDFREE: // 提机->免提 { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("提机->免提"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_HANDFREE)); if (strcmp(m_fsm.GetCurrStateName(),"Pickup")==0){ m_fsm.m_bAgentHandFree = true; } SendCurAudioDevice(); } break; case EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP: // 坐席控制免提->提机 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("免提->提机"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_PICKUP)); SendCurAudioDevice(); break; case EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE: // 坐席控制提机->免提 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("提机->免提"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_TO_HANDFREE)); SendCurAudioDevice(); break; case EVENT_MOD_CONNECT_BEGAIN_RECORD_CALL: { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("开始远程双录呼叫."); m_fsm.m_bNeedQueueName = true; m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_DOUBLE_RECORD_CALL)); if (m_fsm.m_bHandFree){ LogEvent(Severity_Middle,LOG_EVT_HANDFREE_MODE_REMOTE_CALL,"remote double call start with hand free mode."); } else{ LogEvent(Severity_Middle,LOG_EVT_PICKUP_MODE_REMOTE_CALL,"remote double call start with pick up mode."); } } break; case EVENT_MOD_CONNECT_STOP_RECORD_BROADCAST: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("双录播报完结束,重置电话状态"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOP_RECORD_BROADCAST)); break; case EVENT_MOD_CONNECT_HANNUP: // 挂机 { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("断开呼叫"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); m_fsm.m_bHangup=true; } break; case EVENT_MOD_CONNECT_HANNUP_BY_CONNECTING: // 话筒未接通时挂机 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("话筒未接通时断开呼叫"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); //m_fsm.m_bHandFree = TRUE; m_fsm.m_bHangup=true; break; case EVENT_MOD_CONNECT_HANNUP_BY_AGENT: // 授权操作 m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_AGENT_WRITABLE)); case LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS: //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv LOG_EVT_MOD_ASSISCHAN_STARTED_SUCCESS"); //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("current state name is %s.", m_fsm.GetCurrStateName()); Sleep(500); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_ASSISTCHAN_IDEL)); m_fsm.m_bConAssist = false; GetFunction()->SetTimer(2, this, 3900); if(NULL != m_pCounterConnectorChannel){ m_bConnectAssist = false; m_pCounterConnectorChannel->GetFunction()->CloseSession(); #ifdef RVC_OS_WIN m_pCounterConnectorChannel->SafeDelete(); #endif m_pCounterConnectorChannel = NULL; //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Close AssistChannel Session."); } if(NULL == m_pCounterConnectorChannel){ if (Error_Succeed == ConnectAssistChannel()){ m_bConnectAssist = true; } else{ m_bConnectAssist = false; GetFunction()->SetTimer(1, this, 3600); } } break; case LOG_EVT_MOD_SIPPHONE_STARTED_SUCCESS: //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv LOG_EVT_MOD_SIPPHONE_STARTED_SUCCESS"); Sleep(890); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_SIPPHONE_IDEL)); m_fsm.m_bConSipphone = false; GetFunction()->SetTimer(3, this, 3700); break; case LOG_EVT_UI_STARTRECORD: //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start sales record video,get pos = %s",pszMessage); Handle_StartRecord(pszMessage); break; case LOG_EVT_UI_STARTREMOTERECORD: { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start sales remote record video,get pos = %s",pszMessage); Handle_StartRemoteRecord(pszMessage); } break; case LOG_EVT_UI_STOPRECORD: //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("begin stop sales record video."); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOCALVIDEO)); m_bIsSalesRecord = false; break; case LOG_EVT_UI_STOPREMOTERECORD: //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("begin stop double record video,and cur state name is %s.",m_fsm.GetCurrStateName()); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOACALREMOTEVIDEO)); m_bIsRemoteRecord = false; break; case LOG_EVT_UI_RETURNMENU: if (m_bIsSalesRecord) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop sales record video by return menu"); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOCALVIDEO)); m_bIsSalesRecord = false; } if (m_bIsRemoteRecord) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop remote record video by return menu."); if (m_fsm.m_CallingParam.nCallType != DOUBLERECORD_CALLTYPE){ m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_STOPLOACALREMOTEVIDEO)); } else{ //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("hangup call by return menu, CurrStateName is %s.", m_fsm.GetCurrStateName()); m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); m_fsm.m_bHangup=true; } m_bIsRemoteRecord = false; } break; case LOG_EVT_UI_STARTPHOTOGRAPH: if (_stricmp(m_fsm.GetCurrStateName(),"Offline")!=0){ LogEvent(Severity_Middle,EVENT_MOD_CONNECT_HANNUP,"UI start photograph, hangup!"); } //else{ // DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("offline state,ignore UI_STARTPHOTOGRAPH hangup event"); //} break; case EVENT_MOD_SIP_GET_VIDEO_FAILED: HandleGetVideoFailedEvent(); break; default: break; } } CServerSessionBase*CCounterConnectorEntity::OnNewSession(const char* /*pszRemoteEntityName*/, const char* /*pszClass*/) { m_pCurrentSession = new CCounterConnectorSession(this); return m_pCurrentSession; } bool CCounterConnectorEntity ::IsService() const { return true; } void CCounterConnectorEntity::OnTimeout(DWORD dwTimerID) { if (1 == dwTimerID){ if (false == m_bConnectAssist) { if (Error_Succeed == ConnectAssistChannel()) { m_bConnectAssist = true; } } if (m_bConnectAssist) { GetFunction()->KillTimer(1); } } else if(2 == dwTimerID) { if (false == m_fsm.m_bConAssist) { if (m_fsm.ReConnectionAssistchan()) { m_fsm.m_bConAssist = true; } } if (true == m_fsm.m_bConAssist) { GetFunction()->KillTimer(2); } } else if (3 == dwTimerID) { if (false == m_fsm.m_bConSipphone) { if (m_fsm.ReConnectionSipphone(false)) { m_fsm.m_bConSipphone = true; } else { m_iConSipphoneFaileTimes++; GetFunction()->ResetTimer(3, m_iConSipphoneFaileTimes*3000); } } if (m_fsm.m_bConSipphone || m_iConSipphoneFaileTimes >= 5) { GetFunction()->KillTimer(3); } } } //change audio device message void CCounterConnectorEntity ::OnReceivePkt(int type, int sub_type, const char *buffer, int size) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv pkt type=%d,subtype=%d",type,sub_type); if (type == ACM_TYPE_DEVICE) { switch (sub_type) { //设备切换 //change to handfree case ACM_CHANGE_HANDFREE: DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv change audiodevice to handfree"); if (!m_fsm.m_bAgentHandFree) { LogEvent(Severity_Middle,EVENT_MOD_CONNECT_AGENT_PICKUP_HANDFREE,"agent change audio device to handfree"); m_fsm.m_bAgentHandFree = true; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("agent want change audiodevice to handfree,but the device is handfree now"); } break; //change to pickup case ACM_CHANGE_PICKUP: DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("recv change audio device to pickup"); if (m_fsm.m_bAgentHandFree) { LogEvent(Severity_Middle,EVENT_MOD_CONNECT_AGENT_HANDFREE_PICKUP,"agent change audio device to pickup"); m_fsm.m_bAgentHandFree = false; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("agent want change audio device to pickup,but the device is pickup now"); } break; default: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unknown sub_type %d from agent!", sub_type); break; } } else if (type == ACM_TYPE_CALLTRANS) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv ACM_TYPE_CALLTRANS"); if (sub_type == ACM_CALLTRANS_NUM) { //CALL transfer CallTransferInfo Callnum; SpBuffer buf; buf.OpenRead(buffer,size); Callnum.Serialize(buf); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("recv ACM_CALLTRANS_NUM = %s",Callnum.CallNum); //广播,业务中台接收 SpSendBroadcast(GetFunction(), SP_MSG_OF(CallTransferInfo), SP_MSG_SIG_OF(CallTransferInfo), Callnum); } } else if (type == ACM_TYPE_AGENTVIDEOTYPE) { if (sub_type == ACM_AGENTVIDEOTYPE_ONEWAY) { //广播单向视频 AgentVideoType agentvideotype; agentvideotype.VideoType = 0; //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Broadcast Oneway video"); SpSendBroadcast(GetFunction(), SP_MSG_OF(AgentVideoType), SP_MSG_SIG_OF(AgentVideoType), agentvideotype); } else if (sub_type == ACM_AGENTVIDEOTYPE_TWOWAY) { //广播双向视频 AgentVideoType agentvideotype; agentvideotype.VideoType = 1; //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Broadcast Twoway Video"); SpSendBroadcast(GetFunction(), SP_MSG_OF(AgentVideoType), SP_MSG_SIG_OF(AgentVideoType), agentvideotype); } } } CSimpleStringA CCounterConnectorEntity ::BuildVideoDesc(int local_view_x, int local_view_y, int local_view_cx, int local_view_cy) { char param[512] = {0}; snprintf(param, 512, "remote_ip:0\r\n" "remote_video_rtp:0\r\n" "remote_video_width:0\r\n" "remote_video_height:0\r\n" "remote_video_fps:0\r\n" "local_view_x:%d\r\n" "local_view_y:%d\r\n" "local_view_cx:%d\r\n" "local_view_cy:%d\r\n" "remote_view_x:0\r\n" "remote_view_y:0\r\n" "remote_view_cx:0\r\n" "remote_view_cy:0\r\n\r\n", local_view_x, local_view_y, local_view_cx, local_view_cy); return CSimpleStringA(param); } CSimpleStringA CCounterConnectorEntity ::BuildDoubleVideoDesc(int local_view_x, int local_view_y, int local_view_cx, int local_view_cy, int remote_view_x, int remote_view_y, int remote_view_cx, int remote_view_cy) { char param[512] = {0}; snprintf(param, 512, "remote_ip:0\r\n" "remote_video_rtp:0\r\n" "remote_video_width:0\r\n" "remote_video_height:0\r\n" "remote_video_fps:0\r\n" "local_view_x:%d\r\n" "local_view_y:%d\r\n" "local_view_cx:%d\r\n" "local_view_cy:%d\r\n" "remote_view_x:%d\r\n" "remote_view_y:%d\r\n" "remote_view_cx:%d\r\n" "remote_view_cy:%d\r\n\r\n", local_view_x, local_view_y, local_view_cx, local_view_cy, remote_view_x, remote_view_y, remote_view_cx, remote_view_cy); return CSimpleStringA(param); } CSimpleStringA CCounterConnectorEntity ::ConstructVideoParam(CSimpleStringA strMsg, bool bDoubleVideo) { int lxPos,lyPos,lwidth,lheight; CSimpleStringA strVideoParam; CSimpleStringA str; if (false == bDoubleVideo){ sscanf(strMsg.GetData(), "%d@%d@%d@%d@%d@%s", &lxPos, &lyPos, &lwidth, &lheight, &str); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("local video param : (x=%d,y=%d,width=%d,height=%d).",lxPos,lyPos,lwidth,lheight); strVideoParam = BuildVideoDesc(lxPos,lyPos,lwidth,lheight); } else{ int iPostionArr[4][2] = {0}; if (strMsg.GetLength() >0) { CAutoArray arrstr = strMsg.Split('@'); if (arrstr.GetCount() >= 4) { for(int i=0; i<4; i++) { sscanf(arrstr[i].GetData(), "%d|%d", &iPostionArr[i][0], &iPostionArr[i][1]); } } } //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("remote record local video param : (x=%d,y=%d,width=%d,height=%d), remote video param : (x=%d,y=%d,width=%d,height=%d)", // iPostionArr[0][0], iPostionArr[1][0],iPostionArr[2][0], iPostionArr[3][0],iPostionArr[0][1], iPostionArr[1][1],iPostionArr[2][1], iPostionArr[3][1]); strVideoParam = BuildDoubleVideoDesc(iPostionArr[0][0], iPostionArr[1][0],iPostionArr[2][0], iPostionArr[3][0],iPostionArr[0][1], iPostionArr[1][1],iPostionArr[2][1], iPostionArr[3][1]); } return strVideoParam; } void CCounterConnectorEntity::Handle_StartRecord(const char* pszMessage) { CSimpleStringA strMsg = pszMessage; CSimpleStringA strVideo; #ifdef RVC_OS_WIN strVideo = ConstructVideoParam(strMsg, false); #else strVideo = ConstructVideoRenderParam(strMsg, false); #endif m_fsm.PostEventFIFO(new ShowLocalVideoEvent(strVideo)); // 非连坐席双录 m_bIsSalesRecord = true; } void CCounterConnectorEntity::Handle_StartRemoteRecord(const char* pszMessage) { CSimpleStringA strMsg = pszMessage; #ifdef RVC_OS_WIN CSimpleStringA strVideo = ConstructVideoParam(strMsg, true); #else CSimpleStringA strVideo = ConstructVideoRenderParam(strMsg, true); #endif m_fsm.PostEventFIFO(new ShowLocalAndRemoteVideoEvent(strVideo)); // 连坐席双录 m_bIsRemoteRecord = true; m_bIsRemoteRecordStopSpeakerCapture = false; } void CCounterConnectorEntity::StopRemoteRecordSpeakerAudioCapture() { if(DOUBLERECORD_CALLTYPE == m_fsm.m_CallingParam.nCallType){ if (m_IsStandType){ if (false == m_bIsRemoteRecordStopSpeakerCapture){ if (Error_Succeed == m_fsm.StopSpeakerAudioCapture()){ m_bIsRemoteRecordStopSpeakerCapture = true; } } } } } void CCounterConnectorEntity::Handle_StartRecordPreview(const char* pszMessage) { CSimpleStringA strMsg = pszMessage; CSimpleStringA strVideo; #ifdef RVC_OS_WIN strVideo = ConstructVideoParam(strMsg, false); #else strVideo = ConstructVideoRenderParam(strMsg, false); #endif m_fsm.PostEventFIFO(new ShowLocalVideoEvent(strVideo)); // 非连坐席双录 m_bIsSalesRecord = true; } //send cur audio device to agent void CCounterConnectorEntity ::SendCurAudioDevice() { ChannelService_Send_Info Info; Info.compress = false; Info.encrypt = false; Info.type = ACM_TYPE_DEVICE; Info.id = 0; Info.sub_type = ACM_AUDIO_DEVICE; Info.data.Alloc(sizeof(int)); SpBuffer buf; buf.OpenWrite(); int nDevice = 0; if (m_fsm.m_bIsAgentControl) { if (m_fsm.m_bAgentHandFree) { nDevice = 0; } else { nDevice = 1; } } else { if (m_fsm.m_bHandFree) { nDevice = 0; } else { nDevice = 1; } } buf & nDevice; Info.data = buf.ToBlob(); m_pCounterConnectorChannel->Send(Info); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("send cur Audio device = %d",nDevice); } void CCounterConnectorEntity::SetCallType(CallingTypeEnum eType) { m_fsm.SetCallingType(eType); } DeviceTypeEnum CCounterConnectorEntity::RvcGetDeviceType() { DeviceTypeEnum eType = eStand2sType; CSmartPointer spFunction = GetFunction(); CSystemStaticInfo stStaticinfo; spFunction->GetSystemStaticInfo(stStaticinfo); if (_stricmp(stStaticinfo.strMachineType, "RVC.Stand1SPlus") == 0) { eType = eStand1SPlusType; } else if (_stricmp(stStaticinfo.strMachineType, "RVC.CardStore") == 0 || _stricmp(stStaticinfo.strMachineType, "RVC.CardPrinter") == 0) { eType = eCardStore; } else { eType = eStand2sType; } if (eType >= 0 && eType < sizeof(Device_Type_Table) / sizeof(char*)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("device type is %s.", Device_Type_Table[eType]); } return eType; } ChannelCounterConnectorClient::ChannelCounterConnectorClient( CCounterConnectorEntity *pEntity ) : ChannelService_ClientBase(pEntity) { m_eLastState = eChannelState_Idle; m_uConnectTime = 0; } void ChannelCounterConnectorClient::OnMessage(ErrorCodeEnum Error, ChannelService_State_Info &Msg, CSmartPointer pData) { if (Error == Error_Succeed) { CCounterConnectorEntity *pEntity = static_cast(m_pEntityBase); if (Msg.state == eChannelState_Idle) { pEntity->m_fsm.m_bIsAgentControl = false; //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("ChannelState is eChannelState_Idle"); if (eChannelState_Connected == m_eLastState){ LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_CALL_CONNECT_TIME, CSimpleStringA::Format("call connected time is %us.", y2k_time_now() - m_uConnectTime).GetData()); } if (eChannelState_Connecting == m_eLastState){ LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_ASSIST_CONNECT_FAILED,"make call failed for assistant channel connect failed!"); } } else if (Msg.state == eChannelState_Connected) { pEntity->m_fsm.m_bIsAgentControl = true; pEntity->SendCurAudioDevice(); //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("ChannelState is eChannelState_Connected"); m_uConnectTime = y2k_time_now(); } else if (eChannelState_Connecting == Msg.state){ //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("ChannelState is eChannelState_Connecting"); } else if(eChannelState_Closing == Msg.state){ //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("ChannelState is eChannelState_Closing"); if (eChannelState_Connecting == m_eLastState){ LogWarn(Severity_Low, Error_Debug, LOG_WARN_COUNTERCONNECT_ASSIST_CONNECT_FAILED,"make call failed for assistant channel closed."); } } m_eLastState = Msg.state; } } void ChannelCounterConnectorClient::OnMessage( ErrorCodeEnum Error, ChannelService_Packet_Info &Msg, CSmartPointer pData ) { if (Error == Error_Succeed) { CCounterConnectorEntity *pEntity = static_cast(m_pEntityBase); pEntity->OnReceivePkt(Msg.type, Msg.sub_type, (const char*)Msg.data.m_pData, Msg.data.m_iLength); } } void CCounterConnectorSession::Handle_StartCall(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); ErrorCodeEnum rc = Error_Succeed; m_pEntity->m_fsm.m_CallingParam.connect_ip = ctx->Req.connect_ip; m_pEntity->m_fsm.m_CallingParam.connect_port = ctx->Req.connect_port; m_pEntity->m_fsm.m_CallingParam.nCallType = (CallingTypeEnum)ctx->Req.callingtype; m_pEntity->m_fsm.m_CallingParam.connect_session = ctx->Req.connect_session; m_pEntity->m_fsm.m_CallingParam.assistant_port = ctx->Req.assistant_port; m_pEntity->m_fsm.m_CallingParam.subid = ctx->Req.subid; m_pEntity->m_fsm.m_bNeedQueueName = true; ctx->Answer((ErrorCodeEnum)rc); } void CCounterConnectorSession::Handle_StartCallExternal(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); ErrorCodeEnum rc = Error_Succeed; ctx->Answer((ErrorCodeEnum)rc); } void CCounterConnectorSession::Handle_StopCall(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); ErrorCodeEnum rc = Error_Succeed; m_pEntity->m_fsm.PostEventFIFO(new FSMEvent(USER_EVT_HANGUP)); ctx->Answer((ErrorCodeEnum)rc); } void CCounterConnectorSession::Handle_GetCallRouteType(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); ctx->Ans.RouteType = m_pEntity->m_iRouteType; ctx->Answer(Error_Succeed); } void CCounterConnectorSession::Handle_SetVideoCallRouteParams(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); if (m_pEntity->m_iRouteType) { m_pEntity->SetCallRouteParams(ctx->Req.BusinessName, ctx->Req.CallPriority); ctx->Ans.ErrorCode = Error_Succeed; ctx->Ans.ErrorMsg = CSimpleStringA2W("设置呼叫路由参数成功."); } else { ctx->Ans.ErrorCode = Error_Param; ctx->Ans.ErrorMsg = CSimpleStringA2W("该设备不支持新模式呼叫路由."); } ctx->Answer(Error_Succeed); } void CCounterConnectorSession::Handle_GetPickUpStatus(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); if (m_pEntity->m_fsm.m_bHandFree) { ctx->Ans.iStatus = 0; } else { ctx->Ans.iStatus = 1; } ctx->Answer(Error_Succeed); } void CCounterConnectorSession::OnClose(ErrorCodeEnum eErrorCode ) { } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CCounterConnectorEntity) SP_END_ENTITY_MAP()