#include "StdAfx.h" #include "TapiLineExten.h" #include "DevControl.h" #include "VsControl.h" #include "LineOpExec.h" #include "TapiOpConsult.h" CTapiLineExten::CTapiLineExten(DWORD DevID, HLINE Handle, DWORD ApiVersion, CString ExtID, HLINEAPP LineApp) : CTapiLine(DevID, Handle, ApiVersion, ExtID, LineApp) { } CTapiLineExten::~CTapiLineExten(void) { } /***************************************************************** **【函数名称】 __onExtStatusChanged **【函数功能】 线路状态变化事件处理 **【参数】 pInfoS DevLink事件内容,可以不填 **【返回值】 ****************************************************************/ void CTapiLineExten::__onExtStatusChanged( DevLinkInfoS* pInfoS ) { // 通知业务逻辑线路状态变化 CDevControl::GetInstance().onEventResState(DEV_RES_TYPE_EXT, m_ExtenID, m_LineStatus, m_CallerNum, m_CalleeNum); // 如果线路空闲 if(m_LineStatus == INNER_STATE_FREE) { // 通知VS线路释放(并线录音时有效) CVsControl::GetInstance().notifyLineFree(atoi(m_ExtenID), DEV_RES_TYPE_EXT); } // end if } /***************************************************************** **【函数名称】 _procDevLinkEventS **【函数功能】 DevLink S事件后续处理 **【参数】 pInfoS DevLink S事件内容 **【返回值】 ****************************************************************/ void CTapiLineExten::_procDevLinkEventS( DevLinkInfoS* pInfoS ) { // 如果线路未附加任何操作且线路变为呼出振铃状态,则通知座席话机直呼操作 int Status = pInfoS->nResStatus & HELD_STATE_FILTER_MASK; if(m_pCurrTapiOp == NULL && (Status == INNER_STATE_DIALING || Status == INNER_STATE_RING_BACK)) { CLineOpExec::GetInstance().onDevDirectOpBegin(DEV_OP_CALL_OUT, this, pInfoS); } // 通知关联操作 if(m_pCurrTapiOp != NULL) { m_pCurrTapiOp->onDevLinkEventS(this, pInfoS); if(m_DevLinkCallId == CONST_DEV_LINK_SUSPEND) return; } // 不处理保持状态 if(pInfoS->nResStatus != INNER_STATE_HELD && pInfoS->nDevLinkCallId != m_DevLinkHeldId) { // 保存呼叫信息 if(pInfoS->nResStatus != INNER_STATE_FREE) m_DevLinkCallId = pInfoS->nDevLinkCallId; // 保存线路信息 m_CallerNum = pInfoS->szCallerNum; m_CalleeNum = pInfoS->szCalleeNum; m_LineStatus = ((m_DevLinkHeldId == CONST_DEV_LINK_CALL_NULL) ? pInfoS->nResStatus : (pInfoS->nResStatus | INNER_STATE_HELD)); // 线路状态日志 if(m_LineStatus == INNER_STATE_TALKING) { CDevControl::GetInstance().onEventLog(LOG_LEVEL_NORMAL, _T("{LineExt}: Line[%s]进入通话, CallerNum = %s, CalleeNum = %s, DevLinkCallId = %ld, Flag = %d, Op = %lu"), m_ExtenID, pInfoS->szCallerNum, pInfoS->szCalleeNum, pInfoS->nDevLinkCallId, pInfoS->nFlag, m_pCurrTapiOp); } // end if // 通知线路状态变化 __onExtStatusChanged(pInfoS); } // end if } /***************************************************************** **【函数名称】 __ProcDevLinkEventD **【函数功能】 DevLink D事件后续处理 **【参数】 **【返回值】 ****************************************************************/ void CTapiLineExten::_procDevLinkEventD( int DevLinkCallId ) { if(DevLinkCallId == m_DevLinkHeldId) // 被保持方挂机 { m_DevLinkHeldId = -1; m_HeldCall = NULL; m_LineStatus = m_LineStatus & HELD_STATE_FILTER_MASK; // 通知线路状态变化 __onExtStatusChanged(NULL); } else // 当前活动呼叫挂机 { m_DevLinkCallId = -1; // 更新DevLink CallId // 通知关联操作 if(m_pCurrTapiOp != NULL) { m_pCurrTapiOp->onDevLinkEventD(this, DevLinkCallId); if(m_DevLinkCallId == CONST_DEV_LINK_SUSPEND && dynamic_cast(m_pCurrTapiOp) == NULL) // 协商呼叫确认转移前,协商者物理挂机,发送线路信息 { return; } } // end if // 更新线路信息 if((m_LineStatus & HELD_STATE_FILTER_MASK) != INNER_STATE_FREE) { m_CallerNum.Empty(); m_CalleeNum.Empty(); m_LineStatus = (m_DevLinkHeldId != CONST_DEV_LINK_CALL_NULL) ? INNER_STATE_FREE|INNER_STATE_HELD : INNER_STATE_FREE; // 通知路状态变化 __onExtStatusChanged(NULL); } // end if(Line Status) } // end if } /***************************************************************** **【函数名称】 _procLineInitStatus **【函数功能】 初始化线路状态处理 **【参数】 **【返回值】 ****************************************************************/ void CTapiLineExten::_procLineInitStatus( HCALL CallId, DWORD CallState, DWORD CallStateDetail, DWORD CallPrivilege ) { // 得到活动呼叫状态 if(m_ActiveCall == NULL) // 如果活动呼叫为空 { m_LineStatus = INNER_STATE_FREE; } else // 如果活动呼叫不为空 { if(CallId == m_ActiveCall) // 如果当前呼叫等于活动呼叫 { m_LineStatus = _mapTapiCallState(CallState); } } // end if(m_hActiveCall) // 通知线路状态 __onExtStatusChanged(NULL); } /***************************************************************** **【函数名称】 regist **【函数功能】 注册线路 **【参数】 **【返回值】 ****************************************************************/ void CTapiLineExten::regist( void ) { // 通知业务逻辑线路创建事件 CDevControl::GetInstance().onEventResDetail(DEV_RES_TYPE_EXT, m_ExtenID); CDevControl::GetInstance().onEventResState(DEV_RES_TYPE_EXT, m_ExtenID, m_LineStatus); // 设置线路可响应的状态事件 HRESULT hRet = ::lineSetStatusMessages(m_Handle, LINE_DEV_STATE_ALL, LINE_ADDRESS_STATE_ALL); ASSERT(hRet == S_OK); } /***************************************************************** **【函数名称】 redoCallStatus **【函数功能】 强制重新处理线路状态 **【参数】 **【返回值】 ****************************************************************/ void CTapiLineExten::redoCallStatus( HCALL CallId, DWORD CallState, DWORD CallStateDetail ) { // 线路挂机事件的强制状态处理 if(CallId == m_ActiveCall && (CallState & LINECALLSTATE_DISCONNECTED)) { m_LineStatus = ((m_DevLinkHeldId == CONST_DEV_LINK_CALL_NULL) ? INNER_STATE_FREE : (INNER_STATE_FREE | INNER_STATE_HELD)); // 通知业务逻辑线路状态变化 __onExtStatusChanged(NULL); } // end if } /***************************************************************** **【函数名称】 setDevLinkHeldId **【函数功能】 设置当前线路被保持的 DevLinkCallId **【参数】 **【返回值】 ****************************************************************/ void CTapiLineExten::setDevLinkHeldId( const int DevLinkCallId ) { m_DevLinkHeldId = DevLinkCallId; if(m_DevLinkHeldId != CONST_DEV_LINK_CALL_NULL) // 保持开始 { m_DevLinkCallId = CONST_DEV_LINK_CALL_NULL; m_LineStatus = INNER_STATE_FREE | INNER_STATE_HELD; // 通知线路状态变化 __onExtStatusChanged(NULL); } // end if } /***************************************************************** **【函数名称】 setDevLinkCallId **【函数功能】 设置当前线路被活动的 DevLinkCallId **【参数】 **【返回值】 ****************************************************************/ void CTapiLineExten::setDevLinkCallId( const int DevLinkCallId ) { m_DevLinkCallId = DevLinkCallId; }