#include "StdAfx.h" #include "LineHolder.h" #include "LogicLineExt.h" #include "LogicLineTrunk.h" #include "LogicLineVoip.h" #include "MsgCenter.h" #include "NetworkCti.h" #include SINGLETON_IMPLEMENT(CLineHolder) CLineHolder::CLineHolder(void) { m_LineMap.InitHashTable(MAX_LENGTH_HASH); } CLineHolder::~CLineHolder(void) { } /***************************************************************** **【函数名称】 __deleteExten **【函数功能】 删除指定分机 **【参数】 **【返回值】 ****************************************************************/ void CLineHolder::__deleteExten( UINT ExtId ) { CLogicLine* pLine = NULL; // 不存在 if(!m_LineMap.Lookup(ExtId, pLine)) return; // 删除IP分机类 m_LineMap.RemoveKey(ExtId); delete pLine; pLine = NULL; } /***************************************************************** **【函数名称】 __procResDetail **【函数功能】 处理资源类型明细,创建相关线路实体类 **【参数】 EvtInfo: 资源信息 **【返回值】 ****************************************************************/ void CLineHolder::__procResDetail( const EventResDetail &EvtInfo ) { CLogicLine* pLine = NULL; switch(EvtInfo.nResType) { case DEV_RES_TYPE_EXT: // 内线分机 { UINT Ext = EvtInfo.nResID; if (Ext & DEL_EXT_DETAIL) // 删除分机 { // 去掉首位 Ext = Ext << 4; Ext = Ext >> 4; __deleteExten(Ext); } else { // 已存在 if(m_LineMap.Lookup(EvtInfo.nResID, pLine)) return; // 建立内线分机类 pLine = new(std::nothrow) CLogicLineExt(EvtInfo.nResID); m_LineMap.SetAt(EvtInfo.nResID, pLine); } } break; case DEV_RES_TYPE_TRUNK: // 外线 { if(m_LineMap.Lookup(EvtInfo.nResID, pLine)) return; // 建立外线类 pLine = new(std::nothrow) CLogicLineTrunk(EvtInfo.nResID); m_LineMap.SetAt(EvtInfo.nResID, pLine); } break; case DEV_RES_TYPE_VOIP: // VOIP线路 { if(m_LineMap.Lookup(EvtInfo.nResID, pLine)) return; // 建立外线类 pLine = new(std::nothrow) CLogicLineVoip(EvtInfo.nResID); m_LineMap.SetAt(EvtInfo.nResID, pLine); } break; default: break; } // end switch if(pLine != NULL) pLine->pushLineData2ACD(); } /***************************************************************** **【函数名称】 __procResStatus **【函数功能】 处理资源状态变化 **【参数】 EvtInfo:资源状态信息 **【返回值】 ****************************************************************/ void CLineHolder::__procResStatus( const EventResStatus &EvtInfo ) { CLogicLine* pLine = NULL; if(!m_LineMap.Lookup(EvtInfo.nResID, pLine)) return; ASSERT(pLine != NULL); if(pLine == NULL) return; // 计算呼入数量,空闲->通话中,说明是中继呼入 static int trunkCallIn = 0; // 中继呼入数量 static std::set trunkCallInResID; // 保存中继呼入的资源id if (EvtInfo.nResType == DEV_RES_TYPE_TRUNK) { if (EvtInfo.nState == TRUNK_STATE_ALERTING) // 来电振铃,中继呼入 { trunkCallInResID.emplace(EvtInfo.nResID); } else if (EvtInfo.nState == TRUNK_STATE_FREE) // 变空闲,中继释放 { auto it = trunkCallInResID.find(EvtInfo.nResID); if (it != trunkCallInResID.end()) trunkCallInResID.erase(it); } } trunkCallIn = trunkCallInResID.size(); //外呼数量计算 static int makeCallCount = 0; // 外呼数量 static std::set extCallResID; static int extRingCount = 0; // 来电振铃数量 static std::set extRingResID; // 振铃数量 if (EvtInfo.nResType == DEV_RES_TYPE_EXT) { if (EvtInfo.nState == INNER_STATE_RING_BACK || EvtInfo.nState == INNER_STATE_INIT || EvtInfo.nState == INNER_STATE_DIALING) // 外呼 { extCallResID.emplace(EvtInfo.nResID); } else if (EvtInfo.nState == INNER_STATE_FREE || EvtInfo.nState == INNER_STATE_REMOVE) { auto it = extCallResID.find(EvtInfo.nResID); if (it != extCallResID.end()) extCallResID.erase(it); } // 来电振铃 if (EvtInfo.nState == INNER_STATE_ALERTING) { extRingResID.emplace(EvtInfo.nResID); } else { auto it = extRingResID.find(EvtInfo.nResID); if (it != extRingResID.end()) extRingResID.erase(it); } } makeCallCount = extCallResID.size(); extRingCount = extRingResID.size(); // 发给相关线路类处理 pLine->onLineStatusUpdated(EvtInfo); if(EvtInfo.nState == INNER_STATE_REMOVE) __deleteExten(EvtInfo.nResID); __procTrunkNum(trunkCallIn, makeCallCount, extRingCount); } void CLineHolder::__procTrunkNum(int trunkCallIn,int makeCallCount,int extRingCount) { UINT key = 0; CLogicLine* value = NULL; int CurrTrunkUseNum = 0; POSITION pos = m_LineMap.GetStartPosition(); while (pos) { m_LineMap.GetNextAssoc(pos, key, value); if (value->type() == DEV_RES_TYPE_TRUNK) { if (value->status() == TRUNK_STATE_TALKING) { CurrTrunkUseNum += 1; } } } static int m_CurrTrunkUseNum = 0; //if (CurrTrunkUseNum == m_CurrTrunkUseNum) return; m_CurrTrunkUseNum = CurrTrunkUseNum; CPduEntity pdu(PDU_CMD_CTI_TRUNKUSE_COUNT); pdu.SetDataUInt(0, CurrTrunkUseNum); pdu.SetDataUInt(1, trunkCallIn); pdu.SetDataUInt(2, makeCallCount); pdu.SetDataUInt(3, extRingCount); CNetworkCti::GetInstance().send2ACD(pdu); } /***************************************************************** **【函数名称】 onAcdConnected **【函数功能】 ACD连接成功后的处理 **【参数】 **【返回值】 ****************************************************************/ void CLineHolder::onAcdConnected(void) { CLogicLine* pLogicLine = NULL; POSITION pos = m_LineMap.GetStartPosition(); while(pos != NULL) { UINT nKey; m_LineMap.GetNextAssoc(pos, nKey, pLogicLine); // 发送线路初始信息到ACD pLogicLine->pushLineData2ACD(); } // end while } /***************************************************************** **【函数名称】 getLogicLine **【函数功能】 获取逻辑线路实体类指针 **【参数】 LineId: 线路ID **【返回值】 ****************************************************************/ CLogicLine* CLineHolder::getLogicLine( UINT LineId ) { CLogicLine* pLogicLine = NULL; m_LineMap.Lookup(LineId, pLogicLine); return pLogicLine; } /***************************************************************** **【函数名称】 getLineAssoAgentId **【函数功能】 读取内线关联的座席工号 **【参数】 nLineId: 线路ID **【返回值】 座席工号 ****************************************************************/ UINT CLineHolder::getLineAssoAgentId( UINT nLineId ) { CLogicLine* pLine = getLogicLine(nLineId); return pLine == NULL ? 0 : pLine->getAgentNum(); } /***************************************************************** **【函数名称】 onMessage **【函数功能】 消息事件处理函数 **【参数】 MsgType: 消息事件类型 lpContent: 消息内容 **【返回值】 ****************************************************************/ void CLineHolder::onMessage( UINT MsgType, const PARAM lpContent ) { if(lpContent == NULL) return; switch(MsgType) { case DEV_EVENT_RES_DETAIL: // 设备资源明显 { __procResDetail(*(EventResDetail*)lpContent); } break; case DEV_EVENT_RES_STATUS: // 设备资源状态 { __procResStatus(*(EventResStatus*)lpContent); } break; default: break; } } /***************************************************************** **【函数名称】 init **【函数功能】 初始化 **【参数】 **【返回值】 ****************************************************************/ void CLineHolder::init(void) { // 注册底层设备消息 CMsgCenter& MsgCenter = CMsgCenter::GetInstance(); MsgCenter.regist(DEV_EVENT_RES_DETAIL, this); MsgCenter.regist(DEV_EVENT_RES_STATUS, this); } void CLineHolder::uninit(void) { // 注册底层设备消息 CMsgCenter& MsgCenter = CMsgCenter::GetInstance(); MsgCenter.unregist(DEV_EVENT_RES_DETAIL, this); MsgCenter.unregist(DEV_EVENT_RES_STATUS, this); }