| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- #include "StdAfx.h"
- #include "IvrFlowHolder.h"
- #include "IvrFlow.h"
- #include "CtiCore.h"
- #include "TaskMgr.h"
- #include "Inc/CallDetailInc.h"
- #include "StatisticsMgr.h"
- #include "NetworkCti.h"
- #include "LogicLine.h"
- #include "LineHolder.h"
- SINGLETON_IMPLEMENT(CIvrFlowHolder)
- CIvrFlowHolder::CIvrFlowHolder(void)
- {
- }
- CIvrFlowHolder::~CIvrFlowHolder(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __procCallInReturn
- **【函数功能】 处理CallIn命令返回
- **【参数】 PduEntity:消息实体
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::__procCallInReturn( CPduEntity &PduEntity )
- {
- // 显示日志
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("IVR->CTI, CMD = return[CallIn], \
- IVR = %d, Line = %d, CallerNum = %s, CalleeNum = %s, IsSuccess = %d"),
- PduEntity.GetDataInt(1),
- PduEntity.GetDataUInt(5),
- PduEntity.GetDataString(3),
- PduEntity.GetDataString(4),
- PduEntity.GetDataBool(0));
- // 转发给IvrFlow
- __transmitToIvrFlow(PduEntity);
- }
- /*****************************************************************
- **【函数名称】 __procTurnIvrReturn
- **【函数功能】 处理转Ivr命令返回
- **【参数】 PduEntity: 消息实体
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::__procTurnIvrReturn( CPduEntity &PduEntity )
- {
- // 显示日志
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL,_T("IVR->CTI, Cmd = return[TurnIVR], \
- IVR = %d, Line = %d, CallerNum = %s, CalleeNum = %s, IsSuccess = %d"),
- PduEntity.GetDataInt(1),
- PduEntity.GetDataUInt(5),
- PduEntity.GetDataString(3),
- PduEntity.GetDataString(4),
- PduEntity.GetDataBool(0));
- // 如果IVR不存在,通知Task转IVR失败
- if(PduEntity.GetDataInt(1) == -1)
- CTaskMgr::GetInstance().onTaskPduMsg(PduEntity.GetDataUInt(5), PduEntity);
- else
- __transmitToIvrFlow(PduEntity);
- }
- /*****************************************************************
- **【函数名称】 __transmitToIvrFlow
- **【函数功能】 命令转发给IvrFlow
- **【参数】 PduEntity: 消息实体
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::__transmitToIvrFlow( CPduEntity &PduEntity )
- {
- // 根据IvrId获取Ivr对象
- CIvrFlow *pIvrFlow = getFlowByIvrId(PduEntity.GetDataInt(1));
- if(pIvrFlow == NULL)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{IvrFlowHolder}: 向IVR转发命令时定位不到IvrFlow,IVR = %d"), PduEntity.GetDataInt(1));
- if (PDU_CMD_CTI_IVR_CALLIN == PduEntity.GetCmdType()) // 通知IVR外线来电消息返回,注:只有该类型添加的第二个字段数据其值为CallID
- {
- // 统计找不到IVR流程资源造成的呼入失败记录
- T_EvtError repInfo;
- memset(&repInfo, 0, sizeof(repInfo));
- repInfo.nErrorType = REP_ERROR_IVRFLOW;
- CStatisticsMgr::GetInstance().onCallDetail(PduEntity.GetDataULong(2), REP_EVENT_ERROR, PduEntity.GetDataUInt(5), &repInfo);
- }
- // 命令返回失败
- if(PduEntity.GetIsExecReturn()) return;
- PduEntity.SetToExecReturn();
- PduEntity.SetDataBool(0, false);
- CNetworkCti::GetInstance().send2IVR(PduEntity);
- }
- else
- {
- PDU_CMD_TYPE CmdType = PduEntity.GetCmdType();
- if (PDU_CMD_IVR_WANT_AGENT == CmdType)
- {
- // 在处理ACD相关消息时,添加判断是否与ACD正常连接,若没有正常连接则与ACD相关的操作数据记录为呼损数据。
- if (!CNetworkCti::GetInstance().isACDConnected())
- {
- // 显示日志
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("{IvrFlowHolder}: 执行来电排队操作失败,ACD未连接到系统,或ACD未启动!"));
- // 统计ACD未启动造成呼入失败记录
- T_EvtError repInfo;
- memset(&repInfo, 0, sizeof(repInfo));
- repInfo.nErrorType = REP_ERROR_ACD;
- CStatisticsMgr::GetInstance().onCallDetail(PduEntity.GetDataULong(2), REP_EVENT_ERROR, PduEntity.GetDataInt(5), &repInfo);
- }
- }
- pIvrFlow->onPduMessage(PduEntity);
- }
- }
- /*****************************************************************
- **【函数名称】 __procDevOpCallIn
- **【函数功能】 处理底层设备外线呼入
- **【参数】 DevOpInfo: 底层操作数据
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::__procDevOpCallIn( EventDevOperation &DevOpInfo )
- {
- T_EvtError repInfo;
- memset(&repInfo, 0, sizeof(repInfo));
- // 获取线路类指针
- CLogicLine *pLogicLine = CLineHolder::GetInstance().getLogicLine(DevOpInfo.nLineId);
- if(pLogicLine == NULL) return;
- if(pLogicLine->type() != DEV_RES_TYPE_TRUNK && pLogicLine->type() != DEV_RES_TYPE_VOIP)
- {
- repInfo.nErrorType = REP_ERROR_SYSTEM;
- CStatisticsMgr::GetInstance().onCallDetail(pLogicLine->callId(), REP_EVENT_ERROR, DevOpInfo.nLineId, &repInfo);
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING,_T("{IvrFlowHolder}: 外线呼入通知IVR时检测到线路类型非外线, Line Id = %u, type = %u"),
- pLogicLine->lineId(), pLogicLine->type());
- }
-
- // 判断IVR是否断开连接,如果断开连接则作为外线呼入失败记录
- if (!CNetworkCti::GetInstance().isIVRConnected())
- {
- // 显示日志
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("{IvrFlowHolder}: 外线呼入通知IVR失败,IVR未连接到系统,或IVR未启动"));
- // 统计IVR未启动造成呼入失败记录
- repInfo.nErrorType = REP_ERROR_IVR;
- CStatisticsMgr::GetInstance().onCallDetail(pLogicLine->callId(), REP_EVENT_ERROR, DevOpInfo.nLineId, &repInfo);
- }
- else
- {
- // 通知IVR程序外线来电
- CPduEntity CmdCallIn(PDU_CMD_CTI_IVR_CALLIN);
- CmdCallIn.SetDataULong(2, pLogicLine->callId());
- CmdCallIn.SetDataString(3, DevOpInfo.szCallerNum);
- CmdCallIn.SetDataString(4, DevOpInfo.szCalleeNum);
- CmdCallIn.SetDataUInt(5, DevOpInfo.nLineId);
- CNetworkCti::GetInstance().send2IVR(CmdCallIn);
- }
- }
- /*****************************************************************
- **【函数名称】 createIvrFlow
- **【函数功能】 创建IvrFlow
- **【参数】
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::createIvrFlow( int IvrFlowNum )
- {
- for(int i = 0; i < IvrFlowNum; i++)
- {
- CIvrFlow *pIvrFlow = new CIvrFlow(i);
- m_IvrFlowMap.SetAt(i, pIvrFlow);
- }
- }
- /*****************************************************************
- **【函数名称】 destroyIvrFlow
- **【函数功能】 销毁IvrFlow
- **【参数】
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::destroyIvrFlow( void )
- {
- UINT Key = 0;
- CIvrFlow *pIvrFlow = NULL;
- POSITION pos = m_IvrFlowMap.GetStartPosition();
- while (pos != NULL)
- {
- m_IvrFlowMap.GetNextAssoc(pos, Key, pIvrFlow);
- if (pIvrFlow != NULL)
- {
- delete pIvrFlow;
- pIvrFlow = NULL;
- }
- } // end while
- m_IvrFlowMap.RemoveAll();
- }
- /*****************************************************************
- **【函数名称】 onPduMessage
- **【函数功能】 Pdu命令处理接口
- **【参数】 PduEntity:消息实体
- **【返回值】
- ***************************************************************/
- void CIvrFlowHolder::onPduMessage( CPduEntity &PduEntity )
- {
- switch(PduEntity.GetCmdType())
- {
- case PDU_CMD_CTI_IVR_CALLIN: // CallIn命令返回
- __procCallInReturn(PduEntity);
- break;
- case PDU_CMD_CTI_IVR_TURNIVR: // 转Ivr命令
- __procTurnIvrReturn(PduEntity);
- break;
- default: // 命令转发给IvrFlow
- __transmitToIvrFlow(PduEntity);
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 onDevMessage
- **【函数功能】 底层设备事件
- **【参数】 EvtType 消息事件类型
- lpContent 消息内容
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::onDevMessage( EventDevOperation &DevOpInfo )
- {
- switch(DevOpInfo.nOpType)
- {
- case DEV_OP_CALL_IN:
- __procDevOpCallIn(DevOpInfo);
- break;
- default:
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 onIvrDisconnect
- **【函数功能】 处理Ivr连接断开
- **【参数】
- **【返回值】
- ****************************************************************/
- void CIvrFlowHolder::onIvrDisconnect(void)
- {
- UINT nIndex;
- CIvrFlow *pIvrFlow = NULL;
- POSITION pos = m_IvrFlowMap.GetStartPosition();
- // 循环遍历结束所有Ivrflow
- while(pos != NULL)
- {
- m_IvrFlowMap.GetNextAssoc(pos, nIndex, pIvrFlow);
- if(pIvrFlow == NULL) continue;
- // 向关联线路发送挂机命令
- if(pIvrFlow->assoLineId() != -1)
- CCtiCore::GetInstance().getDevLink().exec(-1, LINE_OP_HANG_UP, pIvrFlow->assoLineId(), NULL);
- // Ivrflow重置
- pIvrFlow->resetFlow();
- }
- }
- /*****************************************************************
- **【函数名称】 getFlowByIvrId
- **【函数功能】 通过IvrId获取关联的IVR流程
- **【参数】 IvrId: IVR ID
- **【返回值】 CIvrFlow对象
- ****************************************************************/
- CIvrFlow* CIvrFlowHolder::getFlowByIvrId( int IvrId )
- {
- CIvrFlow *pIvrFlow = NULL;
- m_IvrFlowMap.Lookup(IvrId, pIvrFlow);
- return pIvrFlow;
- }
- /*****************************************************************
- **【函数名称】 getFlowByLineId
- **【函数功能】 通过线路号获取关联的IVR流程
- **【参数】 LineId: 线路号
- **【返回值】 CIvrFlow对象
- ****************************************************************/
- CIvrFlow* CIvrFlowHolder::getFlowByLineId( int LineId )
- {
- UINT nIndex;
- CIvrFlow *pIvrFlow = NULL;
- POSITION pos = m_IvrFlowMap.GetStartPosition();
-
- while(pos != NULL)
- {
- m_IvrFlowMap.GetNextAssoc(pos, nIndex, pIvrFlow);
- if(pIvrFlow != NULL && pIvrFlow->assoLineId() == LineId)
- return pIvrFlow;
- }
- return NULL;
- }
|