#include "StdAfx.h" #include "Session.h" #include "FsProxy.h" #include "ChanExten.h" #include "ChanTrunk.h" CSession::CSession(CFsProxy* pParent, LPCTSTR Id) : m_pParent(pParent), m_Id(Id) { } CSession::~CSession(void) { } /***************************************************************** **【函数名称】 __getChan **【函数功能】 获取指定通道 **【参数】 **【返回值】 *****************************************************************/ CVirtualChan* CSession::__getChan( LPCTSTR ChanId ) { POSITION Pos = m_ListChan.GetHeadPosition(); while(Pos != NULL) { CVirtualChan* pChan = m_ListChan.GetNext(Pos); ASSERT(pChan != NULL); if(lstrcmp(pChan->chanId(), ChanId) == 0) return pChan; } return NULL; } /***************************************************************** **【函数名称】 __findChan **【函数功能】 查找通道 **【参数】 **【返回值】 *****************************************************************/ CVirtualChan* CSession::__findChan( PCHAN_EVENT_NOTIFY pNotify ) { CVirtualChan* pChan = NULL; if(pNotify->EventId == CHANNEL_EVENT_CREATE) { UINT ExtenNo = 0; if(pNotify->Direction == CALL_DIRECTION_INBOUND) sscanf_s(pNotify->Caller, "%u", &ExtenNo); // 呼入FS else sscanf_s(pNotify->Callee, "%u", &ExtenNo); // FS呼出 pChan = m_pParent->getExten(ExtenNo); if(pChan == NULL) // 分机通道中无,则说明是中继通道 { pChan = m_pParent->getFreeTrunk(); if(pChan == NULL) { LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session}: 处理通道事件时获取空闲中继通道失败, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee); m_pParent->onChanPoor(this, pNotify); } } } else { pChan = m_pParent->getBusyChan(pNotify->ChanId); } return pChan; } /***************************************************************** **【函数名称】 __addChan **【函数功能】 添加指定通道 **【参数】 **【返回值】 *****************************************************************/ void CSession::__addChan( CVirtualChan* pChan ) { m_ListChan.AddTail(pChan); } /***************************************************************** **【函数名称】 __delChan **【函数功能】 删除指定通道 **【参数】 **【返回值】 *****************************************************************/ void CSession::__delChan( CVirtualChan* pChan ) { POSITION Pos = m_ListChan.Find(pChan); if(Pos != NULL) m_ListChan.RemoveAt(Pos); } /***************************************************************** **【函数名称】 __clearChan **【函数功能】 清空通道 **【参数】 **【返回值】 *****************************************************************/ void CSession::__clearChan( void ) { m_ListChan.RemoveAll(); } /***************************************************************** **【函数名称】 __notifySessionChanEvent **【函数功能】 通知会话关联通道事件处理 **【参数】 **【返回值】 *****************************************************************/ void CSession::__notifySessionChanEvent( CVirtualChan* pChanHost, PCHAN_EVENT_NOTIFY pNotify ) { POSITION Pos = m_ListChan.GetHeadPosition(); while(Pos != NULL) { CVirtualChan* pChanInSession = m_ListChan.GetNext(Pos); ASSERT(pChanInSession != NULL); if(pChanInSession != pChanHost) pChanInSession->onSessionChanEvent(pChanHost, pNotify); } } /***************************************************************** **【函数名称】 __onChanFree **【函数功能】 通道空闲的处理函数 **【参数】 **【返回值】 *****************************************************************/ void CSession::__onChanFree( CVirtualChan* pChan, PCHAN_EVENT_NOTIFY pNotify ) { if(m_Id == pNotify->ChanId) // 若会话主通道空闲则清空会话 __clearChan(); else __delChan(pChan); if(pChan->isVoid()) // 若通道已被丢弃,则删除 m_pParent->delChan(pChan); } /***************************************************************** **【函数名称】 prepare **【函数功能】 会话准备 **【参数】 **【返回值】 *****************************************************************/ void CSession::prepare( PCHAN_EVENT_NOTIFY pNotify ) { if(m_Id != pNotify->ChanId) // 触发会话的通道不是会话主通道,则查找并添加主通道 { CVirtualChan* pChan = m_pParent->getBusyChan(m_Id); if(pChan != NULL) __addChan(pChan); } } /***************************************************************** **【函数名称】 onChanEvent **【函数功能】 通道事件处理 **【参数】 **【返回值】 *****************************************************************/ void CSession::onChanEvent( PCHAN_EVENT_NOTIFY pNotify ) { ASSERT(pNotify != NULL); if (pNotify == NULL) return; CVirtualChan* pChan = __getChan(pNotify->ChanId); if(pChan == NULL) { pChan = __findChan(pNotify); if(pChan != NULL) __addChan(pChan); else { LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session}: 处理通道事件时查找对应通道失败, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee); return; } } //LOGGER(LOG_LEVEL_NORMAL, _T("{Fs.Session}: 处理通道事件,EventId=%d,ChanId=%s,CallId=%s,Caller = %s, Callee = %s,ChanState=%d"), pNotify->EventId, pNotify->ChanId, pNotify->CallId, pNotify->Caller, pNotify->Callee, pChan->state()); pChan->onChanEvent(pNotify); // 过滤无效状态 if(pChan->state() == CHAN_LOGIC_STATE_FREE && pNotify->EventId == CHANNEL_EVENT_CREATE) return; __notifySessionChanEvent(pChan, pNotify); if(pChan->isFree()) __onChanFree(pChan, pNotify); } /***************************************************************** **【函数名称】 onChanDtmf **【函数功能】 通道DTMF事件处理 **【参数】 **【返回值】 *****************************************************************/ void CSession::onChanDtmf( PDTMF_NOTIFY pNotify ) { CVirtualChan* pChan = __getChan(pNotify->ChanId); if(pChan != NULL) { pChan->onChanDtmf(pNotify->DTMF); } } /***************************************************************** **【函数名称】 onChanHold **【函数功能】 通道保持事件处理 **【参数】 **【返回值】 *****************************************************************/ void CSession::onChanHold( PHOLD_NOTIFY pNotify ) { CVirtualChan* pChan = __getChan(pNotify->ChanId); if(pChan != NULL) { pChan->onChanHold(pNotify->EvtType); } } /***************************************************************** **【函数名称】 getAssoChan **【函数功能】 获取关联通道 **【参数】 **【返回值】 *****************************************************************/ CVirtualChan* CSession::getAssoChan( CVirtualChan* pChan ) { POSITION Pos = m_ListChan.GetHeadPosition(); while(Pos != NULL) { CVirtualChan* pChanInSession = m_ListChan.GetNext(Pos); ASSERT(pChanInSession != NULL); if(pChanInSession != pChan) return pChanInSession; } return NULL; }