#include "StdAfx.h" #include "CallSession.h" #include "LogicLine.h" #include "Record.h" #include "TaskMgr.h" #include "IvrFlow.h" #include "IvrFlowHolder.h" #include "StatisticsMgr.h" #include "LineHolder.h" CCallSession::CCallSession(ULONG CallId) : m_CallId(CallId), m_RecFile(_T("")), m_Data(_T("")) { } CCallSession::~CCallSession(void) { } /***************************************************************** **【函数名称】 __procLineRecord **【函数功能】 处理线路录音 **【参数】 pRecLine: 录音线路 RecFile:录音文件 **【返回值】 ****************************************************************/ void CCallSession::__procLineRecord( CLogicLine* pRecLine, CString& RecFile ) { // 设置会话中录音文件名 m_RecFile = RecFile; // 设置录音线路的录音文件名 pRecLine->setRecordFile(RecFile); // 设置关联线路的录音文件名 CLogicLine* pLine = NULL; CLineHolder& LineHolder = CLineHolder::GetInstance(); POSITION pos = m_LineList.GetHeadPosition(); while(pos != NULL) { pLine = LineHolder.getLogicLine(m_LineList.GetNext(pos)); ASSERT(pLine != NULL); if(pLine != NULL && pRecLine->type() != pLine->type() && pLine->recordFile() == _T("")) pLine->setRecordFile(RecFile); } } /***************************************************************** **【函数名称】 __onLineTalking **【函数功能】 开始通话后的处理函数 **【参数】 pLine:通话线路 **【返回值】 ****************************************************************/ void CCallSession::__onLineTalking( CLogicLine* pLine ) { ASSERT(pLine != NULL); //如果是监听 不再产生录音文件文件路径 if (pLine->opType() == PDU_CMD_AGENT_MONI_LISTEN) return; // 对该线路进行录音处理 CString RecFile = ""; if(CRecord::GetInstance().record(pLine, RecFile)) __procLineRecord(pLine, RecFile); else pLine->setRecordFile(m_RecFile); } /***************************************************************** **【函数名称】 __onLineHangUp **【函数功能】 处理线路挂机(离开会话) **【参数】 pLine:通话线路 **【返回值】 ****************************************************************/ void CCallSession::__onLineHangUp( CLogicLine* pLine ) { // 通知IVR线路挂机 if(pLine->type() == DEV_RES_TYPE_TRUNK || pLine->type() == DEV_RES_TYPE_VOIP) { // 显示日志 ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Session}: [外线挂机], Trunk = %d"), pLine->lineId()); // 通知IVR外线挂机 CIvrFlow* pIvrFlow = CIvrFlowHolder::GetInstance().getFlowByLineId(pLine->lineId()); if(pIvrFlow != NULL) pIvrFlow->procLineHangUp(); if (pLine->opType() != PDU_CMD_AGENT_FAX && pLine->opType() != PDU_CMD_IVR_FAX) { // 通知外线关联Task销毁,不在向IVR发返回消息 CTaskMgr::GetInstance().removeTask(pLine->taskIdBinded()); } } // 统计挂机 T_EvtHangUp repInfo; memset(&repInfo, 0, sizeof(repInfo)); repInfo.nHangUpFlag = (m_LineList.GetCount() > 1 ? 0:1); // 0本端先挂机 1对端先挂机 CStatisticsMgr::GetInstance().onCallDetail(m_CallId, REP_EVENT_HANG_UP, pLine->lineId(), &repInfo); // 移除线路 POSITION pos = m_LineList.Find(pLine->lineId()); if(pos != NULL) m_LineList.RemoveAt(pos); // 任务(协商转移)失败时,不重置发起方的逻辑线路信息 if (pLine->opResult() == FALSE && pLine->opType() == PDU_CMD_AGENT_CONSULTATION_CALL) pLine->opType() = PDU_CMD_UNKNOWN; else pLine->resetLine(); // 重置线路信息 } /***************************************************************** **【函数名称】 getAssoLineExt **【函数功能】 获取指定线路的关联线路 **【参数】 pHostLine:指定线路 **【返回值】 关联线路对象 ****************************************************************/ CLogicLine* CCallSession::getAssoLine( CLogicLine* pHostLine ) { if(m_LineList.GetCount() < 2) return NULL; CLineHolder& LineHolder = CLineHolder::GetInstance(); POSITION pos = m_LineList.GetHeadPosition(); while(pos != NULL) { CLogicLine* pLine = LineHolder.getLogicLine(m_LineList.GetNext(pos)); ASSERT(pLine != NULL); if(pLine != NULL && pLine != pHostLine) return pLine; } return NULL; } /***************************************************************** **【函数名称】 addLine **【函数功能】 会话中添加线路 **【参数】 pLine: 待添加线路 **【返回值】 ****************************************************************/ void CCallSession::addLine( CLogicLine *pLine ) { ASSERT(pLine != NULL); if(pLine == NULL) return; if(m_LineList.Find(pLine->lineId()) != NULL) return; m_LineList.AddTail(pLine->lineId()); pLine->callId() = m_CallId; } /***************************************************************** **【函数名称】 onLineStatusUpdated **【函数功能】 处理线路状态改变 **【参数】 pLine: 状态变化的线路 **【返回值】 ****************************************************************/ void CCallSession::onLineStatusUpdated( CLogicLine* pLine ) { // 保持状态过滤 UINT Status = (HELD_STATE_FILTER_MASK & pLine->status()); // 通话 if(Status == TRUNK_STATE_TALKING || Status == INNER_STATE_TALKING) { // 有至少两个线路通话时才录音 CLogicLine* pTempLine = NULL; CLineHolder& LineHolder = CLineHolder::GetInstance(); POSITION pos = m_LineList.GetHeadPosition(); while(pos) { pTempLine = LineHolder.getLogicLine(m_LineList.GetNext(pos)); ASSERT(pTempLine != NULL); if(pTempLine == NULL || pTempLine == pLine) continue; UINT nTempStatus = (HELD_STATE_FILTER_MASK & pTempLine->status()); if(nTempStatus == INNER_STATE_TALKING || nTempStatus == TRUNK_STATE_TALKING) { __onLineTalking(pLine); __onLineTalking(pTempLine); break; } } } // 空闲状态当挂机处理 if(Status == TRUNK_STATE_FREE || Status == INNER_STATE_FREE) __onLineHangUp(pLine); }