#pragma once #include "SpHelper.h" #include "SpFSM.h" #include "SpIni.h" #include "IHttpFunc.h" #include "Event.h" #include "../include/EventCode.h" #ifdef _WIN32 #include "resource.h" #else #include "uuid/uuid.h" #endif #include "http_callrouter.h" #include "../mod_assistantchannel/VideoDesc.h" #include "../mod_sipphone/SIPPhone_client_g.h" using namespace SIPPhone; #include "../mod_assistantchannel/AssistantChannel_client_g.h" using namespace AssistantChannel; #include "../mod_mediacontroller/MediaController_client_g.h" using namespace MediaController; #include "../mod_assistantchannel/chan_protocol.h" #include "CallType.h" #include "CounterConnector_def_g.h" #include "CounterConnector_msg_g.h" using namespace CounterConnector; #include "../mod_interactioncontext/InteractionContext_client_g.h" #include "../mod_interactioncontext/InteractionContext_def_g.h" using namespace InteractionContext; #include #include #ifndef RVC_DEFAULT_HTTPTIMEOUT #define RVC_DEFAULT_HTTPTIMEOUT 10 #endif // !RVC_DEFAULT_HTTPTIMEOUT #define USER_EVT_PICKUP_CALL EVT_USER+1 #define USER_EVT_HANDFREE_CALL EVT_USER+2 #define USER_EVT_HANGUP EVT_USER+3 #define USER_EVT_COMMAND_CALL EVT_USER+4 #define USER_EVT_DOUBLE_RECORD_CALL EVT_USER+5 #define USER_EVT_JMP_FAIL EVT_USER+11 #define USER_EVT_JMP_HANDFREE EVT_USER+12 #define USER_EVT_JMP_PICKUP EVT_USER+13 #define USER_EVT_TO_HANDFREE EVT_USER+14 #define USER_EVT_TO_PICKUP EVT_USER+15 #define USER_EVT_SIP_STATE_CONNECTED EVT_USER+21 #define USER_EVT_SIP_STATE_IDLE EVT_USER+22 #define USER_EVT_CHAN_STATE_CONNECTED EVT_USER+31 #define USER_EVT_CHAN_STATE_IDLE EVT_USER+33 #define USER_EVT_RECONNECT EVT_USER+40 #define USER_EVT_AGENT_WRITABLE EVT_USER+41 #define USER_EVT_ERROR EVT_USER+10 #define USER_EVT_EXIT EVT_USER+50 #define USER_EVT_STOP_RECORD_BROADCAST EVT_USER+55 #define USER_EVT_ASSISTCHAN_IDEL EVT_USER+60 #define USER_EVT_SIPPHONE_IDEL EVT_USER+61 #define USER_EVT_STARTVIDEODISPLAY EVT_USER+70 #define USER_EVT_STOPVIDEODISPLAY EVT_USER+71 #define USER_EVT_SHOWLOACALVIDEO EVT_USER+72 #define USER_EVT_STOPLOCALVIDEO EVT_USER+73 #define USER_EVT_SHOWLOACALREMOTEVIDEO EVT_USER+74 #define USER_EVT_STOPLOACALREMOTEVIDEO EVT_USER+75 enum CurServerNum { Error_Server = -1, MAIN_SERVER, BACK_SERVER }; #ifndef MAX_VOIP_SERVER_NUM #define MAX_VOIP_SERVER_NUM 10 #endif struct ChanStateConnectedEvent : public FSMEvent { ChanStateConnectedEvent(const char *param) : FSMEvent(USER_EVT_CHAN_STATE_CONNECTED), m_param(param) {} CSimpleStringA m_param; }; struct StartVideoDisplayEvent : public FSMEvent { StartVideoDisplayEvent(const char *param) : FSMEvent(USER_EVT_STARTVIDEODISPLAY), m_param(param) {} CSimpleStringA m_param; }; struct ShowLocalVideoEvent : public FSMEvent { ShowLocalVideoEvent(const char *param) : FSMEvent(USER_EVT_SHOWLOACALVIDEO), m_param(param) {} CSimpleStringA m_param; }; struct ShowLocalAndRemoteVideoEvent : public FSMEvent { ShowLocalAndRemoteVideoEvent(const char *param) : FSMEvent(USER_EVT_SHOWLOACALREMOTEVIDEO), m_param(param) {} CSimpleStringA m_param; }; struct CallingParam { //呼叫模式,0:可视柜台正常呼叫,1:PAD主动外呼,2:PAD被动呼叫,来源PAD,3:PAD被动呼叫,来源手机端,4:双录连线 CallingTypeEnum nCallType; // CSimpleStringA connect_session; CSimpleStringA connect_ip; int connect_port; CSimpleStringA subid; int assistant_port; }; // struct SessionParam { CSimpleStringA connect_session; //会话标识 CSimpleStringA connect_ip; //分行网关服务器ip int event_port; //分行网关挂断事件监听端口 }; #ifndef MAX_LENGTH_OF_BRANCHNO #define MAX_LENGTH_OF_BRANCHNO 4 #endif #ifndef MAX_LENGTH_OF_SESSIONID #define MAX_LENGTH_OF_SESSIONID 16 #endif #ifndef MAX_LENGTH_OF_CONNECTIP #define MAX_LENGTH_OF_CONNECTIP 16 #endif #ifndef MAX_LENGTH_OF_SUBID #define MAX_LENGTH_OF_SUBID 16 #endif #ifndef SUBID_LENGTH #define SUBID_LENGTH 8 #endif class ACMCallFSM : public FSMImpl, public IFSMStateHooker { public: enum {s0,s7,s8,s9,s10,s11,s12,s13,s14,s20,s21,s22,s23,s24,s3,s4,s50,s51,s52,s53,s60,s61,s62,s63}; BEGIN_FSM_STATE(ACMCallFSM) FSM_STATE_ENTRY(s0,"Offline",s0_on_entry,s0_on_exit,s0_on_event) FSM_STATE_ENTRY(s7,"ShowLocalVideo",s7_on_entry,s7_on_exit,s7_on_event) FSM_STATE_ENTRY(s9,"Livedetect",s9_on_entry,s9_on_exit,s9_on_event) FSM_STATE_ENTRY(s8,"Delay",s8_on_entry,s8_on_exit,s8_on_event) FSM_STATE_ENTRY(s10,"Calling_Start",s10_on_entry,s10_on_exit,s10_on_event) FSM_STATE_ENTRY(s11,"Calling_SipConnect",s11_on_entry,s11_on_exit,s11_on_event) FSM_STATE_ENTRY(s12,"Calling_ChanConnect",s12_on_entry,s12_on_exit,s12_on_event) FSM_STATE_ENTRY(s13,"Calling_AllReady",s13_on_entry,s13_on_exit,s13_on_event) FSM_STATE_ENTRY(s14,"ShowLocalRemoteVideo",s14_on_entry,s14_on_exit,s14_on_event) FSM_STATE_ENTRY(s20, "ExitCall_Start",s20_on_entry,s20_on_exit,s20_on_event) FSM_STATE_ENTRY(s21, "ExitChan_Finished",s21_on_entry,s21_on_exit,s21_on_event) FSM_STATE_ENTRY(s22, "ExitSip_Finished",s22_on_entry,s22_on_exit,s22_on_event) FSM_STATE_ENTRY(s23, "ExitCall_AllFinished",s23_on_entry,s23_on_exit,s23_on_event) FSM_STATE_ENTRY(s24, "ExitCall_Delay",s24_on_entry,s24_on_exit,s24_on_event) FSM_STATE_ENTRY(s3, "HandFree",s3_on_entry,s3_on_exit,s3_on_event) FSM_STATE_ENTRY(s4, "Pickup",s4_on_entry,s4_on_exit,s4_on_event) FSM_STATE_ENTRY(s50, "Broken0",s50_on_entry,s50_on_exit,s50_on_event) FSM_STATE_ENTRY(s51, "Broken_SipFinished",s51_on_entry,s51_on_exit,s51_on_event) FSM_STATE_ENTRY(s52, "Broken_ChanFinished",s52_on_entry,s52_on_exit,s52_on_event) FSM_STATE_ENTRY(s53, "Broken_AllFinished",s53_on_entry,s53_on_exit,s53_on_event) FSM_STATE_ENTRY(s60, "Hangup_Start",s60_on_entry,s60_on_exit,s60_on_event) FSM_STATE_ENTRY(s61, "Hangup_SipFinished",s61_on_entry,s61_on_exit,s61_on_event) FSM_STATE_ENTRY(s62, "Hangup_ChanFinished",s62_on_entry,s62_on_exit,s62_on_event) FSM_STATE_ENTRY(s63, "Hangup_AllFinished",s63_on_entry,s63_on_exit,s63_on_event) END_FSM_STATE() BEGIN_FSM_RULE(ACMCallFSM,s0) FSM_RULE_ENTRY_ANY(s0, s8, USER_EVT_PICKUP_CALL) FSM_RULE_ENTRY_ANY(s0, s9, USER_EVT_STARTVIDEODISPLAY) FSM_RULE_ENTRY_ANY(s0, s7, USER_EVT_SHOWLOACALVIDEO) FSM_RULE_ENTRY_ANY(s0, s14, USER_EVT_SHOWLOACALREMOTEVIDEO) FSM_RULE_ENTRY_ANY(s7, s0, USER_EVT_STOPLOCALVIDEO) FSM_RULE_ENTRY_ANY(s9, s0, USER_EVT_STOPVIDEODISPLAY) FSM_RULE_ENTRY_ANY(s14, s0, USER_EVT_STOPLOACALREMOTEVIDEO) FSM_RULE_ENTRY_ANY(s0, FSM_STATE_EXIT, USER_EVT_EXIT) FSM_RULE_ENTRY_ANY(s0, s8, USER_EVT_HANDFREE_CALL) FSM_RULE_ENTRY_ANY(s0, s8, USER_EVT_COMMAND_CALL) FSM_RULE_ENTRY_ANY(s0, s8, USER_EVT_DOUBLE_RECORD_CALL) FSM_RULE_ENTRY_ANY(s14, s0, USER_EVT_STOP_RECORD_BROADCAST) FSM_RULE_ENTRY_ANY(s8, s11, EVT_TIMER) FSM_RULE_ENTRY_ANY(s11, s12, USER_EVT_SIP_STATE_CONNECTED) FSM_RULE_ENTRY_ANY(s11, s23, USER_EVT_JMP_FAIL) FSM_RULE_ENTRY_ANY(s11, s21, EVT_TIMER) FSM_RULE_ENTRY_ANY(s11, s23, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s11, s21, USER_EVT_HANGUP) FSM_RULE_ENTRY_ANY(s21, s23, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s21, s23, USER_EVT_JMP_FAIL) FSM_RULE_ENTRY_ANY(s12, s13, USER_EVT_CHAN_STATE_CONNECTED) FSM_RULE_ENTRY_ANY(s12, s21, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s12, s22, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s12, s21, USER_EVT_JMP_FAIL) FSM_RULE_ENTRY_ANY(s22, s23, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s12, s20, USER_EVT_HANGUP) FSM_RULE_ENTRY_ANY(s20, s21, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s20, s22, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s13, s3, USER_EVT_JMP_HANDFREE) FSM_RULE_ENTRY_ANY(s13, s4, USER_EVT_JMP_PICKUP) FSM_RULE_ENTRY_ANY(s23, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s23, s24, USER_EVT_RECONNECT) FSM_RULE_ENTRY_ANY(s24, s11, EVT_TIMER) FSM_RULE_ENTRY_ANY(s3, s4, USER_EVT_TO_PICKUP) FSM_RULE_ENTRY_ANY(s3, s51, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s3, s52, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s3, s60, USER_EVT_HANGUP) FSM_RULE_ENTRY_ANY(s4, s3, USER_EVT_TO_HANDFREE) FSM_RULE_ENTRY_ANY(s4, s51, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s4, s52, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s4, s60, USER_EVT_HANGUP) FSM_RULE_ENTRY_ANY(s50, s51, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s50, s52, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s51, s53, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s52, s53, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s52, s53, USER_EVT_JMP_FAIL) FSM_RULE_ENTRY_ANY(s53, s0, EVT_TIMER) FSM_RULE_ENTRY_ANY(s60, s61, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s60, s62, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s61, s63, USER_EVT_CHAN_STATE_IDLE) FSM_RULE_ENTRY_ANY(s62, s63, USER_EVT_SIP_STATE_IDLE) FSM_RULE_ENTRY_ANY(s62, s63, USER_EVT_JMP_FAIL) FSM_RULE_ENTRY_ANY(s63, s0, EVT_TIMER) //assitchannel重启后,状态跳转到Offline FSM_RULE_ENTRY_ANY(s3, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s4, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s50, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s51, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s52, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s53, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s60, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s61, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s62, s0, USER_EVT_ASSISTCHAN_IDEL) FSM_RULE_ENTRY_ANY(s63, s0, USER_EVT_ASSISTCHAN_IDEL) //sipphone重启后,所有状态跳转到Offline FSM_RULE_ENTRY_ANY(s8, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s10, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s11, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s12, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s13, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s20, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s21, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s22, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s23, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s24, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s3, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s4, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s50, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s51, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s52, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s53, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s60, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s61, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s62, s0, USER_EVT_SIPPHONE_IDEL) FSM_RULE_ENTRY_ANY(s63, s0, USER_EVT_SIPPHONE_IDEL) //sipphone重启后,所有状态跳转到Offline //分布式呼叫场景,拒接主动挂断 FSM_RULE_ENTRY_ANY(s0, s60, USER_EVT_HANGUP) //分布式呼叫场景,拒接主动挂断 END_FSM_RULE() ACMCallFSM(); ~ACMCallFSM(); 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 s7_on_entry(); void s7_on_exit(); unsigned int s7_on_event(FSMEvent* event); void s8_on_entry(); void s8_on_exit(); unsigned int s8_on_event(FSMEvent* event); void s9_on_entry(); void s9_on_exit(); unsigned int s9_on_event(FSMEvent* event); void s10_on_entry(); void s10_on_exit(); unsigned int s10_on_event(FSMEvent* event); void s11_on_entry(); void s11_on_exit(); unsigned int s11_on_event(FSMEvent* event); void s12_on_entry(); void s12_on_exit(); unsigned int s12_on_event(FSMEvent* event); void s13_on_entry(); void s13_on_exit(); unsigned int s13_on_event(FSMEvent* event); void s14_on_entry(); void s14_on_exit(); unsigned int s14_on_event(FSMEvent* event); void s20_on_entry(); void s20_on_exit(); unsigned int s20_on_event(FSMEvent* event); void s21_on_entry(); void s21_on_exit(); unsigned int s21_on_event(FSMEvent* event); void s22_on_entry(); void s22_on_exit(); unsigned int s22_on_event(FSMEvent* event); void s23_on_entry(); void s23_on_exit(); unsigned int s23_on_event(FSMEvent* event); void s24_on_entry(); void s24_on_exit(); unsigned int s24_on_event(FSMEvent* event); void s3_on_entry(); void s3_on_exit(); unsigned int s3_on_event(FSMEvent* event); void s4_on_entry(); void s4_on_exit(); unsigned int s4_on_event(FSMEvent* event); void s50_on_entry(); void s50_on_exit(); unsigned int s50_on_event(FSMEvent* event); void s51_on_entry(); void s51_on_exit(); unsigned int s51_on_event(FSMEvent* event); void s52_on_entry(); void s52_on_exit(); unsigned int s52_on_event(FSMEvent* event); void s53_on_entry(); void s53_on_exit(); unsigned int s53_on_event(FSMEvent* event); void s60_on_entry(); void s60_on_exit(); unsigned int s60_on_event(FSMEvent* event); void s61_on_entry(); void s61_on_exit(); unsigned int s61_on_event(FSMEvent* event); void s62_on_entry(); void s62_on_exit(); unsigned int s62_on_event(FSMEvent* event); void s63_on_entry(); void s63_on_exit(); unsigned int s63_on_event(FSMEvent* event); BOOL m_bHangup; //sip呼叫失败次数,连续10次SIP呼叫失败触发自检重启SIPPHONE unsigned int m_nSipErrorNum; unsigned int m_nLiveDetctionTime; BOOL ReConnectionAssistchan(); BOOL ReConnectionSipphone(bool bLog = true); BOOL ReConnectionSyncService(); int GetCallRouteList(); ErrorCodeEnum StartVideo(const char *param) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Start Video"); if (!m_pPhoneClient) return Error_NetBroken; PhoneService_StartVideo_Info Info; ErrorCodeEnum Error = ParseVideoDesc(param, Info.remote_ip, Info.remote_port, Info.remote_width, Info.remote_height, Info.remote_fps, Info.local_view_x, Info.local_view_y, Info.local_view_cx, Info.local_view_cy, Info.remote_view_x, Info.remote_view_y, Info.remote_view_cx, Info.remote_view_cy); Info.local_hwd_move = 0; Info.remote_hwd_move = 1; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start video, remote width:%d, remote height:%d, local(%d,%d,%d,%d),remote(%d,%d,%d,%d), remote_fps:%d", Info.remote_width, Info.remote_height, Info.local_view_x, Info.local_view_y, Info.local_view_cx, Info.local_view_cy, Info.remote_view_x, Info.remote_view_y, Info.remote_view_cx, Info.remote_view_cy, Info.remote_fps); if (Error == Error_Succeed) { Error = (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->StartVideo(Info); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("parse video desc failed!"); } return Error; } ErrorCodeEnum StopVideo() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Stop Video"); if (!m_pPhoneClient) return Error_NetBroken; return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->StopVideo(); } ErrorCodeEnum StartVideoRender(const char* param) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Start Record Video Render, and param is %s.", param); if (!m_pPhoneClient) return Error_NetBroken; PhoneService_StartVideoRender_Info Info; ErrorCodeEnum Error = ParseVideoRenderDesc(param, Info.local_view_x, Info.local_view_y, Info.local_view_cx, Info.local_view_cy, Info.remote_view_x, Info.remote_view_y, Info.remote_view_cx, Info.remote_view_cy); Info.local_hwd_move = 0; Info.remote_hwd_move = 1; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("start record video render,local(%d,%d,%d,%d),remote(%d,%d,%d,%d)", Info.local_view_x, Info.local_view_y, Info.local_view_cx, Info.local_view_cy, Info.remote_view_x, Info.remote_view_y, Info.remote_view_cx, Info.remote_view_cy); if (Error == Error_Succeed) { Error = (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->StartVideoRender(Info); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("parse video desc failed!"); } return Error; } ErrorCodeEnum StopVideoRender() { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Stop Record Video Render"); if (!m_pPhoneClient) return Error_NetBroken; return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->StopVideoRender(); } ErrorCodeEnum RealSipErrorCheck() { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Sip connect Fail 6 times,RealSipErrorCheck!"); if (!m_pPhoneClient) return Error_NetBroken; return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->RealErrorCheck(); } ErrorCodeEnum SetCallingType(CallingTypeEnum eType) { if (!m_pPhoneClient) return Error_NetBroken; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("SetCallingType = %d.", eType); PhoneService_SetCallingParam_Info info; info.CallType = eType; return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->SetCallingParam(info); } ErrorCodeEnum StopSpeakerAudioCapture() { ErrorCodeEnum rc = Error_NotImpl; MediaService_ClientBase* pMSClient = new MediaService_ClientBase(m_pEntity); if(pMSClient->Connect() != Error_Succeed) { pMSClient->SafeDelete(); pMSClient = NULL; } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("MSClient connected success!"); rc = (*pMSClient)(EntityResource::getLink().upgradeLink())->StopSpeakerRender(); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("pMSClient StopSpeakerRender rc:0x%08x",rc); if(rc != Error_Succeed){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Stop Speaker Render failed return 0x%08x", rc); } pMSClient->GetFunction()->CloseSession(); pMSClient = NULL; } return rc; } private: int TranslateState(int innerState); ErrorCodeEnum SetCallState(int state); void get_format_uuid(char* strbuffer, size_t ulen) { #ifdef RVC_OS_WIN UUID uuid; size_t uuidlen = 0; RPC_CSTR buf; UuidCreate((UUID*)&uuid); UuidToString((UUID*)&uuid, &buf); uuidlen = strlen((const char*)buf); if (uuidlen < ulen) { memcpy(strbuffer, (const char*)buf, uuidlen); } RpcStringFree(&buf); #else uuid_t uuid; uuid_generate(uuid); uuid_unparse(uuid, strbuffer); #endif } ErrorCodeEnum GetLocalIP(char *buff, size_t ulen) { #if defined(RVC_OS_WIN) char tmp[MAX_PATH] = { 0 }; gethostname(tmp, sizeof(tmp)); hostent* ent = gethostbyname(tmp); if (ent) { int icount = 0; for (; ent->h_addr_list[icount]; ) { ++icount; } m_iNetAdapterNum = icount; for (int i = 0; ent->h_addr_list[i]; ++i) { if (ent->h_addrtype == AF_INET) { struct in_addr* in = (struct in_addr*)ent->h_addr_list[i]; char* p = inet_ntoa(*in); if (p[0] != '0') { if (strstr(p, "198.168.") == NULL && 0 != strncmp(p, "2.0.0.1", strlen("2.0.0.1"))) { strcpy(buff, p); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("local ip == %s", buff); return Error_Succeed; } } } } } return Error_Unexpect; #else ErrorCodeEnum error = Error_Unexpect; int sockfd = -1; struct ifconf ifconf; struct ifreq* ifreq = NULL; char strbuf[256] = { 0 }; ifconf.ifc_len = 256; ifconf.ifc_buf = strbuf; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("socket error"); return error; } ioctl(sockfd, SIOCGIFCONF, &ifconf); //get all socket info ifreq = (struct ifreq*)ifconf.ifc_buf; for (int i = (ifconf.ifc_len / sizeof(struct ifreq)); i > 0; i--) { if (ifreq->ifr_flags == AF_INET) { //for ipv4 char* strIP = inet_ntoa(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("name = %s, local addr = %s", ifreq->ifr_name, strIP); ifreq++; if (NULL != strIP) { if (NULL == strstr(strIP, "198.168.") && NULL == strstr(strIP, "127.0.0.1")) { strcpy(buff, strIP); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("local ip == %s", buff); error = Error_Succeed; break; } } } } close(sockfd); return error; #endif //RVC_OS_WIN } ErrorCodeEnum MakeCall(const char *hint_callnum,int nSipServer) { if (!m_pPhoneClient) { return Error_NetBroken; } if((m_strSIPCallNum[nSipServer]=="")&&(m_strSIPProxyIP[nSipServer]=="")&&(m_iSIPProxyPort[nSipServer]==0)){ return Error_Param; } CSimpleStringA strCode; PhoneService_MakeCall_Req Req; PhoneService_MakeCall_Ans Ans; Req.to_uri = MakeCallUri(hint_callnum,nSipServer); PhoneService_SetCallingParam_Info info; info.CallType = NORMAL_CALLTYPE; if (DOUBLERECORD_CALLTYPE == m_CallingParam.nCallType){ info.CallType = DOUBLERECORD_CALLTYPE; } (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->SetCallingParam(info); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("before make call, call type is %d, to_uri:%s", info.CallType, Req.to_uri.GetData()); ErrorCodeEnum Error = (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->MakeCall(Req, Ans, 10000); return Error; } ErrorCodeEnum MakeCall(const char *to_uri, const char *from_uri, const char *call_id, CallingParam callingparam) { if (!m_pPhoneClient){ return Error_NetBroken; } CSimpleStringA strCode; PhoneService_MakeCall_Req Req; PhoneService_MakeCall_Ans Ans; Req.to_uri = to_uri; Req.from_uri = from_uri; Req.call_id = call_id; //设置呼叫参数 PhoneService_SetCallingParam_Info info; info.CallType = callingparam.nCallType; info.connect_session = callingparam.connect_session; info.connect_ip = callingparam.connect_ip; info.connect_port = callingparam.connect_port; (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->SetCallingParam(info); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("before make call, call type is %d, to_uri:%s, from_uri:%s, call_id:%s", info.CallType, to_uri, from_uri, call_id); ErrorCodeEnum Error = (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->MakeCall(Req, Ans, 10000); return Error; } ErrorCodeEnum HangupCall() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Hangup Call!"); if (!m_pPhoneClient) { return Error_NetBroken; } PhoneService_HangupCall_Req Req; PhoneService_HangupCall_Ans Ans; if (!m_SessionParam.connect_session.IsNullOrEmpty()){ Req.session_num = m_SessionParam.connect_session; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Hangup Call connect_session = %s", m_SessionParam.connect_session.GetData()); } if (!m_SessionParam.connect_ip.IsNullOrEmpty()){ Req.branch_server_ip = m_SessionParam.connect_ip; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Hangup Call connect_ip = %s", m_SessionParam.connect_ip.GetData()); } if (m_SessionParam.event_port){ Req.branch_server_port = m_SessionParam.event_port; } return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->HangupCall(Req, Ans, 10000); } ErrorCodeEnum ReleaseCall(int type) { if (!m_pPhoneClient) return Error_NetBroken; PhoneService_ReleaseCall_Req Req; Req.type = type; PhoneService_ReleaseCall_Ans Ans; return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->ReleaseCall(Req, Ans, 10000); } ErrorCodeEnum StartChannel(int nChanServer) { if (!m_pChannelClient) { return Error_NetBroken; } if ((m_strChanProxyIP[nChanServer]=="")&&(m_strChanCallNum[nChanServer]=="")&&(m_iChanProxyPort[nChanServer]==0)){ return Error_Param; } ChannelService_Connect_Req Req; ChannelService_Connect_Ans Ans; Req.callno = m_strChanCallNum[nChanServer]; Req.ip = m_strChanProxyIP[nChanServer]; Req.port = m_iChanProxyPort[nChanServer]; return m_pChannelClient->Connect(Req, Ans, 10000); } CSimpleStringA MakeSubid(CSimpleStringA subid) { int idlen = subid.GetLength(); if (idlen > SUBID_LENGTH) { return subid.SubString(idlen - SUBID_LENGTH, SUBID_LENGTH); } else { return subid; } } ErrorCodeEnum StartChannel(int nChanServer,CallingParam callparam) { if (!m_pChannelClient) { return Error_NetBroken; } ChannelService_Connect_Req Req; ChannelService_Connect_Ans Ans; if ((m_strChanProxyIP[nChanServer]=="")&&(m_strChanCallNum[nChanServer]=="")&&(m_iChanProxyPort[nChanServer]==0)){ return Error_Param; } else{ Req.callno = m_strChanCallNum[nChanServer]; Req.ip = m_strChanProxyIP[nChanServer]; Req.port = m_iChanProxyPort[nChanServer]; Req.etype = NORMAL_CALLTYPE; return m_pChannelClient->Connect(Req, Ans, 10000); } } ErrorCodeEnum StopChannel() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop channel"); if (!m_pPhoneClient) { return Error_NetBroken; } ChannelService_Close_Req Req; ChannelService_Close_Ans Ans; return m_pChannelClient->Close(Req, Ans, 10000); } CSimpleStringA MakeCallUri(const char *callnum,const char *serverip,int serverport) { return CSimpleStringA::Format("sip:%s@%s:%d;transport=UDP", callnum, (LPCSTR)serverip,serverport); } CSimpleStringA MakeCallUri(const char *hint_callnum,int nServer) { if (m_iSIPProxyPort[nServer] == 5060) { return CSimpleStringA::Format("sip:%s@%s;transport=UDP", hint_callnum, (LPCSTR)m_strSIPProxyIP[nServer]); } else { return CSimpleStringA::Format("sip:%s@%s:%d;transport=UDP", hint_callnum, (LPCSTR)m_strSIPProxyIP[nServer], m_iSIPProxyPort[nServer]); } } ErrorCodeEnum LoadConfig() { int iTimeOut = RVC_DEFAULT_HTTPTIMEOUT; int iPrintDbg = 0; SpIniMappingTable table; table.AddEntryString("CounterConnector", "sip_proxy_ip", m_strSIPProxyIP[0], NULL); table.AddEntryInt("CounterConnector", "sip_proxy_port", m_iSIPProxyPort[0], 0); table.AddEntryString("CounterConnector", "sip_default_call_no", m_strSIPCallNum[0], NULL); table.AddEntryString("CounterConnector", "chan_proxy_ip", m_strChanProxyIP[0], NULL); table.AddEntryInt("CounterConnector", "chan_proxy_port", m_iChanProxyPort[0], 0); table.AddEntryString("CounterConnector", "chan_default_call_no", m_strChanCallNum[0], NULL); table.AddEntryString("CounterConnector", "sip_proxy_ip_backup", m_strSIPProxyIP[1], NULL); table.AddEntryInt("CounterConnector", "sip_proxy_port_backup", m_iSIPProxyPort[1], 0); table.AddEntryString("CounterConnector", "sip_default_call_no_backup", m_strSIPCallNum[1], NULL); table.AddEntryString("CounterConnector", "chan_proxy_ip_backup", m_strChanProxyIP[1], NULL); table.AddEntryInt("CounterConnector", "chan_proxy_port_backup", m_iChanProxyPort[1], 0); table.AddEntryString("CounterConnector", "chan_default_call_no_backup", m_strChanCallNum[1], NULL); table.AddEntryString("CounterConnector", "default_voip_server", m_strDefaultServer, NULL); table.AddEntryString("CounterConnector", "http_call_route_addr", m_strHttpCallRouteAddr, NULL); table.AddEntryInt("CounterConnector", "http_timeout", iTimeOut, 0); table.AddEntryInt("CounterConnector", "http_printdbg", iPrintDbg, 0); CSmartPointer spConfig; ErrorCodeEnum Error = m_pEntity->GetFunction()->OpenConfig(Config_CenterSetting, spConfig); if (Error == Error_Succeed) { Error = table.Load(spConfig); if (Error_Succeed == Error) { if (iTimeOut > 0 && iTimeOut < 20 * RVC_DEFAULT_HTTPTIMEOUT) { m_iHttpTimeOut = iTimeOut; } if (iPrintDbg) { m_bHttpPrinttDbg = true; } } } return Error; } ErrorCodeEnum LoadTerminalId() { CSystemStaticInfo Info; ErrorCodeEnum Error = m_pEntity->GetFunction()->GetSystemStaticInfo(Info); if (Error == Error_Succeed) { m_strTerminalId = Info.strTerminalID; } return Error; } ErrorCodeEnum AllowAgentWrite() { if (!m_pChannelClient) return Error_NetBroken; ChannelService_Send_Info Info; Info.compress = false; Info.encrypt = false; Info.id = 0; Info.sub_type = 0; Info.type = ACM_TYPE_MODE; return (*m_pChannelClient)(EntityResource::getLink().upgradeLink())->Send(Info); } ErrorCodeEnum StartRing() { #ifdef _WIN32 BOOL bRet = ::PlaySoundA(MAKEINTRESOURCEA(IDR_RINGOUT), ModuleBase::GetModuleBase()->GetInstance(), SND_ASYNC|SND_RESOURCE|SND_LOOP); if (bRet) { m_bRing = TRUE; return Error_Succeed; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("play sound failed!%d", GetLastError()); return Error_Unexpect; } #else m_bRing = TRUE; return Error_Succeed; #endif } void StopRing() { #ifdef _WIN32 if (m_bRing) { BOOL bRet = FALSE; int tries = 0; do { bRet = ::PlaySoundA(NULL, NULL, SND_ASYNC|SND_LOOP); } while (bRet == FALSE && (Sleep(100), tries < 3)); m_bRing = FALSE; } #else if (m_bRing) { m_bRing = FALSE; } #endif } BOOL CheckBeginRing(int iSrcState, int iDstState) { if (iSrcState == ACMCallFSM::s0 && iDstState == ACMCallFSM::s10) return TRUE; return FALSE; } BOOL CheckEndRing(int iSrcState, int iDstState) { if (m_bRing) { if (iSrcState == ACMCallFSM::s10 || iSrcState == ACMCallFSM::s12) { if (iDstState != ACMCallFSM::s10 && iDstState != ACMCallFSM::s12) return TRUE; } } return FALSE; } int GetDelayTime(); void SetDelayTime(); int ParseDefaultServer(const char* strServer); int GetFailedErrorCode(int iSrcState); int LogFailedWarns(int iFailedCode, const char* strmsg); public: BOOL m_bHandFree; //坐席控制话筒的当前状态 BOOL m_bAgentHandFree; BOOL m_bIsAgentControl; //流程拨号,带技能号 CSimpleStringA m_strHintCallNum; BOOL m_bAssistchanIdel; CurServerNum m_nCurSipServer; CurServerNum m_nCurChanServer; //呼叫类型,用于区分是分布式呼叫还是常规呼叫,由业务中台设置或者指令模块设置 CallingParam m_CallingParam; SessionParam m_SessionParam; int m_nSysCallType;//0:普通模式,1:p2p模式 int m_iFailedLastState; BOOL m_bIsPadDevice; BOOL m_bConAssist; BOOL m_bConSipphone; int m_iCallRouteType; CSimpleStringA m_strQueueName; CSimpleStringA m_strAddClientLevel; BOOL m_bNeedQueueName; private: DWORD m_nStarttime; PhoneService_ClientBase *m_pPhoneClient; ChannelService_ClientBase *m_pChannelClient; SyncService_ClientBase*m_pSyncServiceClient; CSimpleStringA m_strTerminalId; CSimpleStringA m_strSIPProxyIP[2]; int m_iSIPProxyPort[2]; CSimpleStringA m_strSIPCallNum[2]; CSimpleStringA m_strChanProxyIP[2]; int m_iChanProxyPort[2]; CSimpleStringA m_strChanCallNum[2]; //去分行化 node_list_head_t *m_pCallRouteList; CSimpleStringA m_strDefaultServer; std::vector m_voipserver; ErrorCodeEnum m_LastSipError; ErrorCodeEnum m_LastAssistError; int m_iNetAdapterNum; CSimpleStringA m_strHttpCallRouteAddr; CSimpleStringA m_strHttpServerAPI; int m_iHttpTimeOut; bool m_bHttpPrinttDbg; BOOL m_bRing; };