| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- #include "StdAfx.h"
- #include "LineHolder.h"
- #include "LogicLineExt.h"
- #include "LogicLineTrunk.h"
- #include "LogicLineVoip.h"
- #include "MsgCenter.h"
- #include "NetworkCti.h"
- #include <set>
- 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<UINT> 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<UINT> extCallResID;
- static int extRingCount = 0; // 来电振铃数量
- static std::set<UINT> 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);
- }
|