#pragma once #include "SpHelper.h" #include "SpFSM.h" #include "SpIni.h" #include "IHttpFunc.h" #include "Event.h" #include "../include/EventCode.h" #include "y2k_time.h" #include "CommEntityUtil.hpp" #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 #ifndef RVC_DEFAULT_VOIPSERVER_ADDR #ifdef DEVOPS_ON_PRD #define RVC_DEFAULT_VOIPSERVER_ADDR "sip:843235023@10.16.129.1,10.16.130.65 2334|sip:843235023@10.16.129.3,10.16.130.66 2334|sip:843235023@10.16.129.5,10.16.130.67 2334|sip:843235023@10.16.129.9,10.16.130.68 2334|sip:843235023@10.16.129.10,10.16.130.131 2334|sip:843235023@10.16.128.1,10.16.130.132 2334|sip:843235023@10.16.128.2,10.16.130.133 2334|sip:843235023@10.16.128.3,10.16.130.134 2334|sip:843235023@10.16.128.4,10.16.130.68 2334|sip:843235023@10.16.128.5,10.16.130.131 2334\0" #else #define RVC_DEFAULT_VOIPSERVER_ADDR "sip:843215022@55.9.188.83,55.9.188.83 2334|sip:843215022@55.9.188.83,55.9.188.83 2334\0" #endif// !DEVOPS_ON_PRD #endif // !RVC_DEFAULT_VOIPSERVER_ADDR #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_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 16 #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:双录连线 CallingTypeEnum nCallType; CSimpleStringA connect_session; CSimpleStringA connect_ip; int connect_port; CSimpleStringA subid; int assistant_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 class ACMCallFSM : public FSMImpl, public IFSMStateHooker { public: enum {s0,s7,s8,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(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, 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(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_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 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_uConnectTime; bool m_bConnected; long m_lConnectCostTime; 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; } PhoneService_SetCallingParam_Info info; info.CallType = eType; return (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->SetCallingParam(info); } bool IsCameraRenderState() { bool brender = false; if (!m_pPhoneClient) { return brender; } PhoneService_IsCameraRender_Req req; PhoneService_IsCameraRender_Ans ans; if (Error_Succeed == (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->IsCameraRender(req, ans, 5000)) { brender = ans.result; } return brender; } 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); 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); ifreq++; if (NULL != strIP) { if (NULL == strstr(strIP, "198.168.") && NULL == strstr(strIP, "127.0.0.1")) { strcpy(buff, strIP); error = Error_Succeed; break; } } } } close(sockfd); return error; #endif //RVC_OS_WIN } 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); ErrorCodeEnum Error = (*m_pPhoneClient)(EntityResource::getLink().upgradeLink())->MakeCall(Req, Ans, 10000); return Error; } ErrorCodeEnum HangupCall() { if (!m_pPhoneClient) { return Error_NetBroken; } PhoneService_HangupCall_Req Req; PhoneService_HangupCall_Ans Ans; 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_iChanProxyPort[nChanServer]==0)){ return Error_Param; } ChannelService_Connect_Req Req; ChannelService_Connect_Ans Ans; Req.ip = m_strChanProxyIP[nChanServer]; Req.port = m_iChanProxyPort[nChanServer]; return m_pChannelClient->Connect(Req, Ans, 10000); } 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_iChanProxyPort[nChanServer]==0)){ return Error_Param; } else{ Req.ip = m_strChanProxyIP[nChanServer]; Req.port = m_iChanProxyPort[nChanServer]; return m_pChannelClient->Connect(Req, Ans, 10000); } } ErrorCodeEnum StopChannel() { 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, serverip, serverport); } ErrorCodeEnum LoadConfig() { int iTimeOut = RVC_DEFAULT_HTTPTIMEOUT; int iPrintDbg = 0; SpIniMappingTable table; 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; int m_iFailedLastState; bool m_bConAssist; bool m_bConSipphone; CSimpleStringA m_strQueueName; CSimpleStringA m_strAddClientLevel; bool m_bNeedQueueName; private: unsigned int m_nStarttime; PhoneService_ClientBase *m_pPhoneClient; ChannelService_ClientBase *m_pChannelClient; SyncService_ClientBase*m_pSyncServiceClient; CSimpleStringA m_strTerminalId; CSimpleStringA m_strChanProxyIP[2]; int m_iChanProxyPort[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; };