#include "StdAfx.h" #include "SpanChannel.h" #include "DspChannel.h" #include "Config.h" #include "VoipChannel.h" #include "MC.h" #include "SessionShell.h" CSpanChannel::CSpanChannel(DEV_RES_CH_TYPE ChannelNo, DEV_RES_NO_TYPE SpanNo, DEV_RES_NO_TYPE NodeNo, DEV_RES_NO_TYPE BoardNo) : CChannelResource(DEV_RES_TYPE_TRUNK, NodeNo, BoardNo, SpanNo, ChannelNo), m_GcHandle(DEV_HANDLE_INVALID), m_CallId(0), m_IsBlocked(false), m_Mixer(*this) { } CSpanChannel::~CSpanChannel(void) { close(); } /***************************************************************** **【函数名称】 __freeBindingChan **【函数功能】 释放绑定的通道 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__freeBindingChan( void ) { m_Mixer.release(); } /***************************************************************** **【函数名称】 __clearCall **【函数功能】 清除呼叫 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::__clearCall( int Cause /*= GC_NORMAL_CLEARING*/ ) { if(m_CallId == 0) return false; m_State = GCST_DROPCALLING; if(m_MeetingInfo.MeetingId != MEETING_ID_INVALID) CMC::GetInstance().meetingRemove(this, m_MeetingInfo); __freeBindingChan(); if(ISX_gc_DropCall(m_CallId, Cause, EV_ASYNC) == 0) { m_CallId = 0; return true; } else return false; } /***************************************************************** **【函数名称】 __onOffered **【函数功能】 处理来电呼叫 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onOffered( METAEVENT* pMetaEvent ) { if(m_State != GCST_NULL) { ISX_gc_DropCall(pMetaEvent->crn, GC_CALL_REJECTED); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]检测到呼叫, 但通道状态异常, 呼叫将忽略"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return; } m_State = GCST_OFFERED; m_CallId = pMetaEvent->crn; GCPARAMEX_MAKECALL* pMakeCallEx = (GCPARAMEX_MAKECALL*)pMetaEvent->evtdatap; ASSERT(pMakeCallEx != NULL); // 获取主、被叫号码 CHAR DNIZ[GC_ADDRSIZE] = { 0 }; CHAR ANI[GC_ADDRSIZE] = { 0 }; ISX_gc_GetCallInfo(m_CallId, DESTINATION_ADDRESS, DNIZ); ISX_gc_GetCallInfo(m_CallId, ORIGINATION_ADDRESS, ANI); m_CallerNum = ANI; m_CalleeNum = DNIZ; CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_ALERTING, m_CallerNum, m_CalleeNum); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]检测到来电, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, ANI, DNIZ); if(ISX_gc_AcceptCall(m_CallId, 0, EV_ASYNC, NULL) != 0) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]释放, 应答中继来电失败, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, ANI, DNIZ); __clearCall(GC_CALL_REJECTED); } CMC::GetInstance().onDevResState(m_Id); } /***************************************************************** **【函数名称】 __onAccept **【函数功能】 接收远端呼叫 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onAccept( void ) { m_State = GCST_ACCEPTED; if(ISX_gc_AnswerCall(m_CallId, 0, EV_ASYNC, NULL) != 0) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]释放, 应答中继来电失败, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); __clearCall(GC_CALL_REJECTED); } } /***************************************************************** **【函数名称】 __onAlerting **【函数功能】 处理外呼远端振铃 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onAlerting( METAEVENT* pMetaEvent ) { if(m_State == GCST_ALERTING || m_State == GCST_DROPCALLING) return; m_State = GCST_ALERTING; CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_RING_BACK, m_CallerNum, m_CalleeNum); CMC::GetInstance().onDevResState(m_Id); } /***************************************************************** **【函数名称】 __onAnswered **【函数功能】 处理应答成功 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onAnswered( void ) { if(m_State == GCST_DROPCALLING) return; m_State = GCST_CONNECTED; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]应答成功, 开始通话, Caller = %s, Callee = %s,SessionCode=%lu"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum, m_SessionCode); CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum); CMC::GetInstance().onDevResState(m_Id); } /***************************************************************** **【函数名称】 __onConnected **【函数功能】 呼叫成功处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onConnected( void ) { if(m_State == GCST_DROPCALLING) return; m_State = GCST_CONNECTED; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]开始通话, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_TALKING, m_CallerNum, m_CalleeNum); CMC::GetInstance().onDevResState(m_Id); } /***************************************************************** **【函数名称】 __onProgressing **【函数功能】 呼叫进展处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onProgressing( void ) { if(m_State == GCST_PROGRESS || m_State == GCST_DROPCALLING) return; m_State = GCST_PROGRESS; CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_PROGRESSING, m_CallerNum, m_CalleeNum); } /***************************************************************** **【函数名称】 __onTaskFail **【函数功能】 呼叫失败处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onTaskFail( void ) { switch(ISX_sr_getevtopertype()) { case OPER_ANSWERCALL: { ASSERT(FALSE); __clearCall(); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]应答来电失败, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); } break; case OPER_MAKECALL: { ASSERT(FALSE); __clearCall(); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]外呼失败, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); } break; case OPER_DROPCALL: { ASSERT(FALSE); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]挂机失败, 已强制释放资源, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); __onCallFinished(); } break; } } /***************************************************************** **【函数名称】 __onCallFinished **【函数功能】 呼叫结束处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onCallFinished( void ) { m_State = GCST_NULL; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]空闲"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_FREE, NULL, NULL); reset(); m_CallId = 0; CMC::GetInstance().onDevResState(m_Id); } /***************************************************************** **【函数名称】 __onCallDisconnected **【函数功能】 呼叫中断处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::__onCallDisconnected( METAEVENT* pMetaEvent ) { GCPARAMEX_DROPCALL* pDropCall = (GCPARAMEX_DROPCALL*)pMetaEvent->evtdatap; ASSERT(pDropCall != NULL); GC_INFO gcInfo; ISX_gc_ResultInfo(pMetaEvent, &gcInfo); long Reason = gcInfo.ccValue & 0xff; if(m_State != GCST_CONNECTED) // 非通话中挂机 { int ErrCode; switch(Reason) { case UNASSIGNED_NUMBER: ErrCode = CALL_FAILED_CAUSE_NUM_INVALID; break; case USER_BUSY: ErrCode = CALL_FAILED_CAUSE_USER_BUSY; break; case NO_USER_RESPONDING: case NO_ANSWER_FROM_USER: ErrCode = CALL_FAILED_CAUSE_NO_ANSWER; break; case CALL_REJECTED: case NORMAL_CLEARING: ErrCode = CALL_FAILED_CAUSE_USER_HANGUP; break; case DEST_OUT_OF_ORDER: ErrCode = CALL_FAILED_CAUSE_DST_OFF; break; default: ErrCode = CALL_FAILED_CAUSE_NETWORK_ERR; break; } CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_CALL_FAILD_CAUSE, (LPCTSTR)ErrCode); } m_State = GCST_DISCONNECTED; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]检测到远端挂机, Caller = %s, Callee = %s, Cause = %d"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum, Reason); // 远端挂机,结束通道通话 __clearCall(); } /***************************************************************** **【函数名称】 open **【函数功能】 打开系统资源 **【参数】 **【返回值】 成功true,失败false ****************************************************************/ bool CSpanChannel::open( void ) { ASSERT(m_GcHandle == DEV_HANDLE_INVALID); ASSERT(m_Handle == DEV_HANDLE_INVALID); // 打开DTI channel m_Handle = ISX_dt_open(m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); if(m_Handle == -1) { m_Handle = DEV_HANDLE_INVALID; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SpanCh}: 数字中继通道[%d-%d-%d-%d]打开失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } if(ISX_gc_OpenEx(&m_GcHandle, m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, EV_SYNC, this) < 0) { m_GcHandle = DEV_HANDLE_INVALID; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SpanCh}: GC通道[%d-%d-%d-%d]打开失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } if(ISX_gc_WaitCall(m_GcHandle, NULL, NULL, -1, EV_ASYNC) < 0) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_ERROR, _T("{SpanCh}: GC通道[%d-%d-%d-%d]等待呼叫失败"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 数字中继通道[%d-%d-%d-%d]打开成功"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return true; } /***************************************************************** **【函数名称】 close **【函数功能】 关闭系统资源 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::close( void ) { if(m_GcHandle != DEV_HANDLE_INVALID) { ISX_gc_Close(m_GcHandle); m_GcHandle = DEV_HANDLE_INVALID; } if(m_Handle != DEV_HANDLE_INVALID) { ISX_dt_close(m_Handle); m_Handle = DEV_HANDLE_INVALID; } //LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 数字中继通道[%d-%d-%d-%d]关闭"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); } /***************************************************************** **【函数名称】 onDevEvent **【函数功能】 设备事件处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::onDevEvent( METAEVENT* pMetaEvent ) { ASSERT(pMetaEvent != NULL); switch(pMetaEvent->evttype) { case GCEV_OFFERED: __onOffered(pMetaEvent); break; case GCEV_DIALING: { m_State = GCST_DIALING; CMC::GetInstance().onDevResState(m_Id); } break; case GCEV_ACCEPT: __onAccept(); break; case GCEV_ALERTING: __onAlerting(pMetaEvent); break; case GCEV_CONNECTED: __onConnected(); break; case GCEV_ANSWERED: __onAnswered(); break; case GCEV_PROGRESSING: __onProgressing(); break; case GCEV_DROPCALL: __onCallFinished(); break; case GCEV_DISCONNECTED: __onCallDisconnected(pMetaEvent); break; case GCEV_TASKFAIL: __onTaskFail(); break; case GCEV_BLOCKED: { m_IsBlocked = true; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]阻塞"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); } break; case GCEV_UNBLOCKED: { m_IsBlocked = false; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]解除阻塞"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); } break; default: break; } } /***************************************************************** **【函数名称】 makeCall **【函数功能】 呼叫 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::makeCall( LPCTSTR Callee, LPCTSTR Caller, int AccountId ) { ASSERT(Callee != NULL); ASSERT(Caller != NULL); m_CallerNum = Caller; m_CalleeNum = Callee; if(m_State != GCST_NULL) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行呼叫请求失败, 通道状态非空闲, caller = %s, callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); return false; } LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行呼叫请求, caller = %s, callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); GCPARAMEX_MAKECALL MakeCallEx; MakeCallEx.Protocol = eGCPro_PRI; ISX_sr_default(PARMID_PRI_SETUP, &(MakeCallEx.u.PRISetup)); MakeCallEx.u.PRISetup.CallingNum.ucPlan = 0x01; // ISDN方案 MakeCallEx.u.PRISetup.CallingNum.ucType = 0x04; // 用户号码 MakeCallEx.u.PRISetup.CallingNum.ucSI = 0x01; // 主叫号码掩蔽显示: 0x01:用户提供,检验并传送 lstrcpy((LPTSTR)MakeCallEx.u.PRISetup.CallingNum.Num, Caller); MakeCallEx.u.PRISetup.CalledNum.ucPlan = 0x01; // ISDN方案 MakeCallEx.u.PRISetup.CalledNum.ucType = 0x04; // 用户号码 lstrcpy((LPTSTR)MakeCallEx.u.PRISetup.CalledNum.Num, Callee); if (ISX_gc_MakeCall(m_GcHandle, &m_CallId, NULL, NULL, -1, EV_ASYNC, &MakeCallEx) < 0) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]呼出失败, Reason = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, ISX_ATDV_ERRMSGP(m_GcHandle)); return false; } CSessionShell::GetInstance().onLineStateChanged(m_Id, m_SessionCode, VIRTUAL_LINE_STATE_DIALING, m_CallerNum, m_CalleeNum); #ifdef _DEBUG LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]拨号中, caller = %s, callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, Caller, Callee); #endif return true; } /***************************************************************** **【函数名称】 answer **【函数功能】 应答来电 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::answer( void ) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行应答请求, caller = %s, callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); if(m_State == GCST_OFFERED) return ISX_gc_AcceptCall(m_CallId, 0, EV_ASYNC) == 0; else return false; } /***************************************************************** **【函数名称】 dropCall **【函数功能】 挂机 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::dropCall( bool IsPassive/* = false*/ ) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行挂机请求, caller = %s, callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); return __clearCall(GC_NORMAL_CLEARING); } /***************************************************************** **【函数名称】 playVoice **【函数功能】 放音 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::playSound( PlayVoiceContent* pContent ) { ASSERT(pContent != NULL); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行放音请求, AudioFile = %s,caller = %s, callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, pContent->szFileName,m_CallerNum, m_CalleeNum); if(m_State != GCST_CONNECTED) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]放音失败, 通道未处于连接状态, AudioFile = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, pContent->szFileName); return false; } return m_Mixer.playSound(pContent); } /***************************************************************** **【函数名称】 playTone **【函数功能】 放Tone音 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::playTone( int Type ) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行Tone音请求, Tone = %d"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, Type); return m_Mixer.playTone(Type); } /***************************************************************** **【函数名称】 playStop **【函数功能】 停止放音 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::playStop( void ) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行停止放音请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return m_Mixer.playStop(); } /***************************************************************** **【函数名称】 startRecord **【函数功能】 开始录音 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::startRecord( RecordContent* pContent ) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行录音请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); if(m_State == GCST_NULL) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]录音失败, 通道状态空闲"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } return m_Mixer.startRecord(pContent); } /***************************************************************** **【函数名称】 stopRecord **【函数功能】 停止录音 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::stopRecord( void ) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行停止录音请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return m_Mixer.stopRecord(); } /***************************************************************** **【函数名称】 monitor **【函数功能】 监听 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::monitor( COneLeg* pTalker, bool IsStop ) { ASSERT(pTalker != NULL); if(IsStop) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行取消监听请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return pTalker->cancelMonitor(this); } else { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{SpanCh}: 通道[%d-%d-%d-%d]执行监听请求"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); if(m_State != GCST_CONNECTED) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]监听失败, 通道未处于连接状态"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } return pTalker->allowMonitor(this); } } /***************************************************************** **【函数名称】 allowMonitor **【函数功能】 允许监听 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::allowMonitor( COneLeg* pMonitorParty ) { if(m_State != GCST_CONNECTED) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]接受监听失败, 通道未处于连接状态"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } if(!m_Mixer.allowedMonitor()) { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]接受监听失败, 无空闲混音发端可连接"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo); return false; } return m_Mixer.setupMonitor(pMonitorParty->routeChannel()); } /***************************************************************** **【函数名称】 cancelMonitor **【函数功能】 取消监听 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::cancelMonitor( COneLeg* pMonitorParty ) { ASSERT(pMonitorParty != NULL); return m_Mixer.undoMonitor(pMonitorParty->routeChannel()); } /***************************************************************** **【函数名称】 onPlayEnd **【函数功能】 放音结束处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::onPlayEnd( LPCTSTR lpDtmf ) { // 通知呼叫控制层放音结束事件 CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_PLAY_END, lpDtmf); } /***************************************************************** **【函数名称】 onRecEnd **【函数功能】 录音结束处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::onRecEnd( UINT TaskId ) { // 通知呼叫控制层录音结束事件 CString strTmp; strTmp.Format(_T("%lu"), TaskId); CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, DEV_CH_EVT_REC_END, strTmp); } /***************************************************************** **【函数名称】 onToneEnd **【函数功能】 Tone结束处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::onToneEnd( int ToneTp ) { ASSERT(FALSE); } /***************************************************************** **【函数名称】 onFaxEnd **【函数功能】 传真结束处理函数 **【参数】 **【返回值】 ****************************************************************/ void CSpanChannel::onFaxEnd( bool IsSuccess, LPCTSTR Reason ) { CSessionShell::GetInstance().onLineChannelEvent(m_Id, m_SessionCode, IsSuccess ? DEV_CH_EVT_FAX_OK : DEV_CH_EVT_FAX_FAILED, Reason); __clearCall(GC_NORMAL_CLEARING); } /***************************************************************** **【函数名称】 state **【函数功能】 返回状态字符串 **【参数】 **【返回值】 ****************************************************************/ LPCTSTR CSpanChannel::getStateStr( void ) const { if(m_IsBlocked) return _T("block"); switch(m_State) { case GCST_NULL: return _T("free"); case GCST_DIALING: return _T("calling"); case GCST_OFFERED: return _T("alerting"); case GCST_ALERTING: return _T("ringback"); case GCST_CONNECTED: return _T("talking"); default: return _T("unknown"); } } /***************************************************************** **【函数名称】 reply **【函数功能】 响应呼叫 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::reply( void ) { if(m_State == GCST_CONNECTED) { if(!playTone(CHANNEL_TONE_RINGBACK)) // 对a-leg放振铃音 { LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{SpanCh}: 通道[%d-%d-%d-%d]播放回铃音失败, Caller = %s, Callee = %s"), m_Id.NodeNo, m_Id.BoardNo, m_Id.SpanNo, m_Id.ChanNo, m_CallerNum, m_CalleeNum); } } return true; } /***************************************************************** **【函数名称】 accept **【函数功能】 应答呼叫 **【参数】 **【返回值】 ****************************************************************/ bool CSpanChannel::accept( void ) { if(m_State == GCST_CONNECTED) { // 停止A-Leg的振铃音 playTone(CHANNEL_TONE_NULL); } return true; }