#include "StdAfx.h" #include "IvrCore.h" #include "FlowTemplate.h" #include "IvrFlow.h" #include "NetworkIvr.h" #include "Config.h" #include "../Public/Auth/AuthMgr.h" #include "../Public/DaemonClient/DaemonClient.h" SINGLETON_IMPLEMENT(CIvrCore) CIvrCore::CIvrCore(void) { } CIvrCore::~CIvrCore(void) { } /***************************************************************** **【函数名称】 __setupFlowEnvironment **【函数功能】 设置流程环境 **【参数】 **【返回值】 TRUE:解析成功,FALSE:解析失败 ****************************************************************/ bool CIvrCore::__setupFlowEnvironment( void ) { bool Res = true; IOtlConnection* pDbControl = IOtlConnection::getInstance(); IOtlRecordset *pRecordset = pDbControl->QueryRecords(_T("SELECT * FROM conf_ivr_flow")); if(NULL != pRecordset) { while(!pRecordset->IsEOF()) { pRecordset->MoveNextRow(); // 读取流程文件信息 CString FileName = pRecordset->GetValueStr(_T("FilePath")); Res &= m_TemplateMgr.parseIvrFile(FileName); } // end while } m_FlowMgr.createFlow(); IOtlRecordset::DestroyInstance(pRecordset); return Res; } /***************************************************************** **【函数名称】 __procMsgCtiCallIn **【函数功能】 处理CTI发过来的外线呼入消息 **【参数】 pPduEntity:外线呼入消息 **【返回值】 ****************************************************************/ void CIvrCore::__procMsgCtiCallIn( CPduEntity* pPduEntity ) { pPduEntity->SetToExecReturn(); CFlowTemplate *pTemplate = m_TemplateMgr.getTemplate(pPduEntity->GetDataUInt(5)); // 通过线路号查找关联流程模板 if(pTemplate == NULL) pTemplate = m_TemplateMgr.getTemplate(pPduEntity->GetDataString(4)); // 根据被叫号码查找关联流程模板 if(pTemplate != NULL) { CIvrFlow *pFlow = m_FlowMgr.getFreeFlow(); if(pFlow != NULL) { pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4)); pPduEntity->SetDataBool(0, TRUE); pPduEntity->SetDataInt(1, pFlow->id()); CNetworkIvr::GetInstance().send(*pPduEntity); pFlow->start(pTemplate); return; } else ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理外线来电时无空闲流程, Caller = %s"), pPduEntity->GetDataString(3)); } else ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理外线来电时找不到关联流程模板, Caller = %s"), pPduEntity->GetDataString(3)); pPduEntity->SetDataBool(0, FALSE); CNetworkIvr::GetInstance().send(*pPduEntity); } /***************************************************************** **【函数名称】 __procMsgCtiPredictiveCall **【函数功能】 处理CTI发过来的预测外呼消息 **【参数】 pPduEntity:外线呼入消息 **【返回值】 ****************************************************************/ void CIvrCore::__procMsgCtiPredictiveCall( CPduEntity* pPduEntity ) { pPduEntity->SetToExecReturn(); CFlowTemplate *pTemplate = m_TemplateMgr.getPreCallTemplate(); ASSERT(pTemplate != NULL); if(pTemplate != NULL) { CIvrFlow *pFlow = m_FlowMgr.getFreeFlow(); if(pFlow != NULL) { pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataInt(6), pPduEntity->GetDataUInt(7), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4)); pPduEntity->SetDataBool(0, TRUE); pPduEntity->SetDataInt(1, pFlow->id()); CNetworkIvr::GetInstance().send(*pPduEntity); pFlow->start(pTemplate); return; } else ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理预测外呼时无空闲流程, Callee = %s"), pPduEntity->GetDataString(4)); } else ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理预测外呼时找不到关联流程模板, Callee = %s"), pPduEntity->GetDataString(4)); pPduEntity->SetDataBool(0, FALSE); CNetworkIvr::GetInstance().send(*pPduEntity); } /***************************************************************** **【函数名称】 __procMsgCtiTurnIvr **【函数功能】 处理CTI发来的坐席转IVR消息 **【参数】 pPduEntity:坐席转IVR命令 **【返回值】 ****************************************************************/ void CIvrCore::__procMsgCtiTurnIvr( CPduEntity* pPduEntity ) { pPduEntity->SetToExecReturn(); CFlowTemplate* pTemplate = m_TemplateMgr.findTemplate(pPduEntity->GetDataString(8)); if(pTemplate != NULL) { CIvrFlow *pFlow = m_FlowMgr.getFreeFlow(); if(pFlow != NULL) { // 设置系统变量 pFlow->setFlowInfo(pPduEntity->GetDataULong(2), pPduEntity->GetDataUInt(5), pPduEntity->GetDataString(3), pPduEntity->GetDataString(4)); // 设置随路数据变量 pFlow->setFlowAssoData(pPduEntity->GetDataString(9)); pPduEntity->SetDataBool(0, TRUE); pPduEntity->SetDataInt(1, pFlow->id()); CNetworkIvr::GetInstance().send(*pPduEntity); pFlow->start(pTemplate); return; } else ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理跳转IVR时无空闲流程")); } else ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Core}: 处理跳转IVR时找不到目标流程模板")); pPduEntity->SetDataBool(0,FALSE); CNetworkIvr::GetInstance().send(*pPduEntity); } /***************************************************************** **【函数名称】 __procMsgCtiHangup **【函数功能】 处理CTI发来的外线挂机消息 **【参数】 pPduEntity:Pdu命令 **【返回值】 ****************************************************************/ void CIvrCore::__procMsgCtiHangup( CPduEntity* pPduEntity ) { int FlowId = pPduEntity->GetDataInt(1); CIvrFlow *pFlow = m_FlowMgr.getFlow(FlowId); if(pFlow != NULL && pFlow->state() == IVR_FLOW_STATE_RUN) pFlow->procPdu(pPduEntity); else ILogger::getInstance().log(LOG_CLASS_SOCKET,LOG_LEVEL_WARNING,_T("{Core}: 收到外线挂机消息, 但关联流程线路[%d]已释放"), FlowId); } /***************************************************************** **【函数名称】 stage1Start **【函数功能】 第一阶段启动 **【参数】 **【返回值】 ****************************************************************/ bool CIvrCore::stage1Start( void ) { // 连接配置数据库 if(!IOtlConnection::getInstance()->Connect()) { AfxMessageBox(STR_ERR_CORE_INIT_DB); return false; } // 加载配置 if(!CConfig::load()) { IOtlConnection::getInstance()->Disconnect(); AfxMessageBox(STR_ERR_CORE_INIT_CFG); return false; } return true; } /***************************************************************** **【函数名称】 stage2Start **【函数功能】 第一阶段启动 **【参数】 ErrInfo: 出错信息 **【返回值】 ****************************************************************/ bool CIvrCore::stage2Start( void ) { // 建立网络通讯 if(!CNetworkIvr::GetInstance().init()) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("%s"), STR_ERR_CORE_INIT_NETWORK); return false; } // #ifndef _DEBUG // CAuthMgr::GetInstance().init(); // #endif if(!__setupFlowEnvironment()) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("%s"), STR_ERR_CORE_INIT_FLOW); return false; } // 启动自动流程 m_TemplateMgr.execAutoFlowTemplate(m_FlowMgr); CDaemonClient::GetInstance().doWork(); return true; } /***************************************************************** **【函数名称】 exit **【函数功能】 退出IVR **【参数】 **【返回值】 ****************************************************************/ void CIvrCore::exit( void ) { CNetworkIvr::GetInstance().release(); IOtlConnection::getInstance()->Disconnect(); } /***************************************************************** **【函数名称】 procPdu **【函数功能】 处理CTI发过来的PDU消息 **【参数】 a_pPduEntity:PDU消息 **【返回值】 ****************************************************************/ void CIvrCore::procPdu( CPduEntity* pPduEntity ) { // 返回命令的处理 if(pPduEntity->GetIsExecReturn()) { if(pPduEntity->GetCmdType() == PDU_CMD_IVR_HANGUP) return; CIvrFlow *pFlow = m_FlowMgr.getFlow(pPduEntity->GetDataInt(1)); if(pFlow != NULL) { ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_NORMAL, _T("CTI -> IVR, CMD = Return[%d], IVR = %d, 执行结果 = %d"), pPduEntity->GetCmdType(), pPduEntity->GetDataInt(1), pPduEntity->GetDataBool(0)); pFlow->procPdu(pPduEntity); } else { ILogger::getInstance().log(LOG_CLASS_SOCKET, LOG_LEVEL_WARNING,_T("CTI -> IVR, CMD = Return[%d], IVR = %d, 执行结果 = %d, IVR线路已释放"), pPduEntity->GetCmdType(), pPduEntity->GetDataInt(1), pPduEntity->GetDataBool(0)); } } else { switch(pPduEntity->GetCmdType()) { case PDU_CMD_CTI_IVR_CALLIN: // CTI通知IVR外线来电 __procMsgCtiCallIn(pPduEntity); break; case PDU_CMD_CTI_IVR_PREDICTIVECALL: // CTI通知IVR预测外呼 __procMsgCtiPredictiveCall(pPduEntity); break; case PDU_CMD_CTI_IVR_TURNIVR: // CTI通知IVR转IVR __procMsgCtiTurnIvr(pPduEntity); break; case PDU_CMD_CTI_IVR_HANGUP: // CTI通知IVR外线挂机 __procMsgCtiHangup(pPduEntity); break; default: break; } // end switch } } /***************************************************************** **【函数名称】 onNetLinkUpdated **【函数功能】 响应网络连接成功或断开事件 **【参数】 IsConnect:网络连接成功或断开 **【返回值】 ****************************************************************/ void CIvrCore::onNetLinkUpdated( bool IsConnect ) { m_FlowMgr.onNetLinkUpdated(IsConnect); }