| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- #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);
- }
|