| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- #include "StdAfx.h"
- #include "NetworkCti.h"
- #include "LineHolder.h"
- #include "IvrFlowHolder.h"
- #include "Logger.h"
- #include "MsgCenter.h"
- #include "Config.h"
- #include "CtiDataDef.h"
- #include "TaskMgr.h"
- SINGLETON_IMPLEMENT(CNetworkCti)
- CNetworkCti::CNetworkCti(void) : m_IsAcdConnected(FALSE), m_IsIvrConnected(FALSE)
- {
- }
- CNetworkCti::~CNetworkCti(void)
- {
- }
- /*****************************************************************
- **【函数名称】 __procRegMsg
- **【函数功能】 处理注册命令
- **【参数】 a_PduEntity:注册命令
- **【返回值】
- ****************************************************************/
- void CNetworkCti::__procRegMsg( CPduEntity& a_PduEntity )
- {
- bool RegResult = false;
- switch(a_PduEntity.GetLocalDevType())
- {
- case PDU_DEV_TYPE_ACD:
- RegResult = m_DevAcd.DevId == -1 ? true : false;
- break;
- case PDU_DEV_TYPE_IVR:
- RegResult = m_DevIvr.DevId == -1 ? true : false;
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- // 发送注册结果
- a_PduEntity.SetToExecReturn();
- a_PduEntity.SetDataBool(0, RegResult);
- CInterfaceWindow::getIocpCommInstance()->Send(&a_PduEntity, a_PduEntity.GetLocalDevType(), a_PduEntity.GetLocalDevId());
- }
- /*****************************************************************
- **【函数名称】 __onRegSuccess
- **【函数功能】 设备注册成功处理函数
- **【参数】 linkContent:注册段信息
- **【返回值】
- ****************************************************************/
- void CNetworkCti::__onRegSuccess( const PduLinkContent& linkContent )
- {
- switch(linkContent.nFarType)
- {
- case PDU_DEV_TYPE_ACD:
- {
- // 保存设备信息
- m_DevAcd.DevId = linkContent.nLocalId;
- lstrcpy(m_DevAcd.szIpAddress, linkContent.szFarIp);
- m_DevAcd.Port = linkContent.nFarPort;
- m_IsAcdConnected = TRUE;
- // 通知线路类Acd连接成功
- CLineHolder::GetInstance().onAcdConnected();
- }
- break;
- case PDU_DEV_TYPE_IVR:
- {
- // 保存设备信息
- m_DevIvr.DevId = linkContent.nLocalId;
- lstrcpy(m_DevIvr.szIpAddress, linkContent.szFarIp);
- m_DevIvr.Port = linkContent.nFarPort;
- m_IsIvrConnected = TRUE;
- }
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 __onDisconnect
- **【函数功能】 设备连接断开处理函数
- **【参数】 linkContent:连接断开端信息
- **【返回值】
- ****************************************************************/
- void CNetworkCti::__onDisconnect( const PduLinkContent& linkContent )
- {
- switch(linkContent.nFarType)
- {
- case PDU_DEV_TYPE_ACD:
- {
- if(m_DevAcd.DevId != linkContent.nLocalId) return;
- if(strcmp(m_DevAcd.szIpAddress, linkContent.szFarIp) != 0) return;
- if(m_DevAcd.Port != linkContent.nFarPort) return;
- memset(&m_DevAcd, 0, sizeof(m_DevAcd));
- m_DevAcd.DevId = -1;
- m_IsAcdConnected = FALSE;
- }
- break;
- case PDU_DEV_TYPE_IVR:
- {
- if(m_DevIvr.DevId != linkContent.nLocalId) return;
- if(strcmp(m_DevIvr.szIpAddress, linkContent.szFarIp) != 0) return;
- if(m_DevIvr.Port != linkContent.nFarPort) return;
- memset(&m_DevIvr, 0, sizeof(m_DevIvr));
- m_DevIvr.DevId = -1;
- // 通知IvrFlow IVR连接断开
- CIvrFlowHolder::GetInstance().onIvrDisconnect();
- m_IsIvrConnected = FALSE;
- }
- break;
- default:
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 OnLinkStateChanged
- **【函数功能】 连接状态信息变化
- **【参数】
- **【返回值】
- ****************************************************************/
- void CNetworkCti::OnLinkStateChanged( const PduLinkContent& linkContent )
- {
- // 连接信息日志显示
- LOG_LEVEL nLogLevel = LOG_LEVEL_WARNING;
- CString Msg;
- switch(linkContent.nLinkState)
- {
- case PDU_LINK_STATE_ACCEPTED:
- {
- Msg = _T("{Net}: Far End Accepted, ");
- nLogLevel = LOG_LEVEL_NORMAL;
- }
- break;
- case PDU_LINK_STATE_DISCONNECTED:
- {
- Msg = _T("{Net}: Far End Disconnected, ");
- nLogLevel = LOG_LEVEL_WARNING;
- __onDisconnect(linkContent);
- }
- break;
- case PDU_LINK_STATE_REG_OK:
- {
- Msg = _T("{Net}: Far End Reg OK, ");
- nLogLevel = LOG_LEVEL_NORMAL;
- __onRegSuccess(linkContent);
- }
- break;
- case PDU_LINK_STATE_REG_FAILED:
- {
- Msg = _T("{Net}: Far End Reg Failed, ");
- nLogLevel = LOG_LEVEL_WARNING;
- }
- break;
- default:
- {
- ASSERT(FALSE);
- Msg = _T("{Net}: Unknown Netlink State, ");
- nLogLevel = LOG_LEVEL_WARNING;
- }
- break;
- }
- // 判断设备类型
- switch(linkContent.nFarType)
- {
- case PDU_DEV_TYPE_ACD:
- {
- CString Temp;
- Temp.Format(_T(" Far End[Type = ACD, Id = %d, Addr = %s:%d]"), linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort);
- Msg += Temp;
- }
- break;
- case PDU_DEV_TYPE_IVR:
- {
- CString Temp;
- Temp.Format(_T(" Far End[Type = IVR, Id = %d, Addr = %s:%d]"), linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort);
- Msg += Temp;
- }
- break;
- default:
- CString Temp;
- Temp.Format(_T(" Far End[Type = UnKnown, Id = %d, Addr = %s:%d]"), linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort);
- Msg += Temp;
- break;
- }
- // 通知日志
- ILogger::getInstance().log(LOG_CLASS_SOCKET, nLogLevel, _T("%s"), Msg);
- }
- /*****************************************************************
- **【函数名称】 OnRecvCommand
- **【函数功能】 Pdu命令处理接口
- **【参数】 a_pPduEntity:消息实体
- **【返回值】
- ****************************************************************/
- void CNetworkCti::OnRecvCommand( CPduEntity* a_pPduEntity )
- {
- ASSERT(a_pPduEntity != NULL);
- switch(a_pPduEntity->GetCmdType())
- {
- case PDU_CMD_REG: // 注册命令
- __procRegMsg(*a_pPduEntity);
- break;
- case PDU_CMD_CTI_IVR_CALLIN: // CallIn返回命令
- case PDU_CMD_CTI_IVR_TURNIVR: // 转IVR返回命令
- case PDU_CMD_IVR_HANGUP: // IVR通知CTI挂机
- case PDU_CMD_IVR_END: // IVR通知CTI流程结束
- case PDU_CMD_IVR_WANT_AGENT: // IVR通知CTI请求排队(包括ACD返回)
- case PDU_CMD_IVR_QUEUE_CONTINUE: // IVR通知CTI继续排队(包括ACD返回)
- case PDU_CMD_IVR_QUEUE_CANCEL: // IVR通知CTI取消排队
- case PDU_CMD_IVR_TURN_AGENT: // IVR通知CTI转坐席
- case PDU_CMD_IVR_PLAY_DTMF: // IVR通知CTI放音收按键
- case PDU_CMD_IVR_CALL_OUT: // IVR通知CTI自动呼叫某个号码
- case PDU_CMD_IVR_TURN_OUTLINE: // IVR呼叫转移
- case PDU_CMD_IVR_FAX: // IVR通知收发传真
- case PDU_CMD_IVR_LEAVE_WORD: // IVR通知留言
- CIvrFlowHolder::GetInstance().onPduMessage(*a_pPduEntity);
- break;
- case PDU_CMD_LISTEN:
- return;
- case PDU_CMD_IVR_WAITER_COUNT: //2019 - 9 - 6 配合4.0acd返回排队人数
- {
- send2ACD(*a_pPduEntity); //发送至ACD
- int WaiterCount = a_pPduEntity->GetDataUInt(0);
- // m_WaiterCount.onWaiterCount(WaiterCount);
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{NetWorkCti}:收到排队数量%d",WaiterCount);
- }
- break;
- default:
- {
- __try {
- CTaskMgr::GetInstance().onPduMessage(*a_pPduEntity);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{CNetworkCti}:OnRecvCommand,CTaskMgr异常,CmdType=%d,mdw5.1.19.1"), a_pPduEntity->GetCmdType());
- }
- break;
- }
- break;
- }
- }
- /*****************************************************************
- **【函数名称】 init
- **【函数功能】 初始化
- **【参数】
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- BOOL CNetworkCti::init()
- {
- // 初始化客户端设备信息
- memset(&m_DevAcd, 0, sizeof(m_DevAcd));
- memset(&m_DevIvr, 0, sizeof(m_DevIvr));
- m_DevAcd.DevId = -1;
- m_DevIvr.DevId = -1;
- // 初始化命令配置
- CPduDataFormat::getInstance()->UnLoad();
- #ifdef _DEBUG
- CPduDataFormat::getInstance()->Load("../NetLib/PDUFormat.ini"); //../NetLib/PDUFormat.ini
- #else
- CPduDataFormat::getInstance()->Load("./PDUFormat.ini");
- #endif
- CInterfaceWindow::getIocpLinkInstance()->RegistPduLinkProc(this, FALSE);
- CInterfaceWindow::getIocpCommInstance()->RegistPduCommProc(this, FALSE);
- // 注册Pdu消息接口
- CInterfaceWindow::getIocpLinkInstance()->RegistPduLinkProc(this, TRUE);
- CInterfaceWindow::getIocpCommInstance()->RegistPduCommProc(this, TRUE);
- //创建Socket服务器端
- UINT ListenPort = CConfig::GetInstance().listenPort();
- if (CInterfaceWindow::getIocpLinkInstance()->CreatePduServer(ListenPort, PDU_DEV_TYPE_CTI, 0))
- {
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, "{Net}: 创建网络服务端成功,ListenPort = %d", ListenPort);
- return TRUE;
- }
- else
- {
- ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_ERROR, "{Net}: 创建网络服务端失败,ListenPort = %d", ListenPort);
- return FALSE;
- }
- }
- /*****************************************************************
- **【函数名称】 release
- **【函数功能】 释放资源
- **【参数】
- **【返回值】 成功TRUE,失败FALSE
- ****************************************************************/
- void CNetworkCti::release( void )
- {
- CInterfaceWindow::getIocpLinkInstance()->StopAll();
- }
- /*****************************************************************
- **【函数名称】 send2ACD
- **【函数功能】 发送PDU到ACD
- **【参数】 a_PduEntity:待发送的PDU
- **【返回值】
- ****************************************************************/
- BOOL CNetworkCti::send2ACD( CPduEntity& a_PduEntity )
- {
- return CInterfaceWindow::getIocpCommInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_ACD, m_DevAcd.DevId);
- }
- /*****************************************************************
- **【函数名称】 send2IVR
- **【函数功能】 发送PDU到IVR
- **【参数】 a_PduEntity:待发送的PDU
- **【返回值】
- ****************************************************************/
- BOOL CNetworkCti::send2IVR( CPduEntity& a_PduEntity )
- {
- return CInterfaceWindow::getIocpCommInstance()->Send(&a_PduEntity, PDU_DEV_TYPE_IVR, m_DevIvr.DevId);
- }
|