#include "StdAfx.h" #include "DevControl.h" #include "resource.h" #include "eHangConfig.h" #include "NetCtrlInterface.h" #include "PduDataFormat.h" #include "PduLinkInc.h" #include "PduEntity.h" SINGLETON_IMPLEMENT(CDevControl) IDeviceLink& IDeviceLink::getInstance( void ) { return CDevControl::GetInstance(); } CDevControl::CDevControl(void) : m_pOperator(NULL), m_IsConnected2Sc(false), m_IsDevOK(false) { } CDevControl::~CDevControl(void) { } /***************************************************************** **【函数名称】 __initNetLink **【函数功能】 初始化网络连接 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__initNetLink( void ) { // 初始化命令配置 #ifdef _DEBUG CPduDataFormat::getInstance()->Load("../StableCore/ScPduFormat.ini"); #else CPduDataFormat::getInstance()->Load("./ScPduFormat.ini"); #endif // 注册事件响应接口 CInterfaceWindow::getLinkInstance()->RegistPduLinkProc(this, TRUE); CInterfaceWindow::getCommInstance()->RegistPduCommProc(this, TRUE); // 连接到CTI CString Ip = CeHangConfig::scAddr(); int Port = CeHangConfig::scPort(); if(!CInterfaceWindow::getLinkInstance()->CreatePduClient(Ip, Port, PDU_DEV_TYPE_SC_CLIENT, 0, PDU_DEV_TYPE_SC_SERVER, 0, false)) { __onLog(LOG_LEVEL_ERROR, _T("{Dev}: 连接SC服务[%s:%d]失败, 请检查网络配置是否正常!"), Ip, Port); return false; } // end if return true; } /***************************************************************** **【函数名称】 __shutNetLink **【函数功能】 关闭网络连接 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__shutNetLink( void ) { CInterfaceWindow::getLinkInstance()->StopAll(); } /***************************************************************** **【函数名称】 __notifyResType **【函数功能】 通知资源类型 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__notifyResType( void ) { EventResType node; ASSERT(m_pOperator != NULL); // 内线分机 node.nResType = DEV_RES_TYPE_EXT; m_pOperator->onDeviceEvent(DEV_EVENT_RES_TYPE, &node); // 中继线路 node.nResType = DEV_RES_TYPE_TRUNK; m_pOperator->onDeviceEvent(DEV_EVENT_RES_TYPE, &node); // VOIP资源 node.nResType = DEV_RES_TYPE_VOIP; m_pOperator->onDeviceEvent(DEV_EVENT_RES_TYPE, &node); } /***************************************************************** **【函数名称】 onLog **【函数功能】 日志处理 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onLog( UINT Level, CHAR* lpszFormat, ... ) { // 得到消息内容 CHAR szMsg[1024]; ZeroMemory(szMsg, 1024); va_list ap; va_start(ap, lpszFormat); vsprintf_s(szMsg, lpszFormat, ap); if(strlen(szMsg) == 0) // 如果内容为空,不打印日志 return; // 通知日志显示 EventLog node; memset(&node, 0, sizeof(EventLog)); node.nLevel = Level; lstrcpy(node.szContent, szMsg); ASSERT(m_pOperator != NULL); m_pOperator->onDeviceEvent(DEV_EVENT_LOG, &node); } /***************************************************************** **【函数名称】 onDevInvalid **【函数功能】 设备不可用 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevStateUpdated( UINT DevState ) { if(DevState == DEVICE_STATE_ENABLE) { __onLog(LOG_LEVEL_NORMAL, _T("{Dev}: 设备状态正常, 可响应CTI控制")); m_IsDevOK = true; ASSERT(m_pOperator != NULL); m_pOperator->onDeviceEvent(DEV_EVENT_INIT_END, NULL); } else { __onLog(LOG_LEVEL_ERROR, _T("{Dev}: 失去与PBX设备的连接, 或设备处于无效状态")); m_IsDevOK = false; ASSERT(m_pOperator != NULL); m_pOperator->onDeviceEvent(DEV_EVENT_DEV_CLOSED, NULL); } } /***************************************************************** **【函数名称】 __onNetLinkDisconnected **【函数功能】 连接断开后续处理 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onNetLinkDisconnected( PduLinkContent linkContent ) { m_IsConnected2Sc = false; __onDevStateUpdated(DEVICE_STATE_DISABLE); } /***************************************************************** **【函数名称】 __onOpResult **【函数功能】 设备操作执行结果 **【参数】 Instance 调用标识 IsSucceed 是否成功 Data 执行结果返回的随路数据 **【返回值】 ****************************************************************/ void CDevControl::__onOpResult( long Instance, BOOL IsSucceed, LPCTSTR Data ) { // 生成执行结果内容 EventOpResult node; memset(&node, 0, sizeof(EventOpResult)); node.nInstance = Instance; node.bIsSucceed = IsSucceed; if(Data != NULL) lstrcpy(node.szData, Data); // 返回执行结果 m_pOperator->onDeviceEvent(DEV_EVENT_LINE_OP_RESULT, &node); } /***************************************************************** **【函数名称】 __onDevResDetail **【函数功能】 设备资源状态处理 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevResDetail( CPduEntity* a_pPduEntity ) { EventResDetail node; memset(&node, 0, sizeof(EventResDetail)); node.nResType = a_pPduEntity->GetDataUInt(0); node.nResID = a_pPduEntity->GetDataUInt(1); m_pOperator->onDeviceEvent(DEV_EVENT_RES_DETAIL, &node); } /***************************************************************** **【函数名称】 __onDevResState **【函数功能】 设备资源状态处理 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevResState( CPduEntity* a_pPduEntity ) { DEV_RES_TYPE ResTp = (DEV_RES_TYPE)a_pPduEntity->GetDataUInt(0); UINT State = a_pPduEntity->GetDataUInt(2); if(ResTp == DEV_RES_TYPE_MB) { __onDevStateUpdated(State); } else { EventResStatus node; memset(&node, 0, sizeof(EventResStatus)); node.nResType = ResTp; node.nResID = a_pPduEntity->GetDataUInt(1); node.nState = State; lstrcpy(node.szCallerNum, a_pPduEntity->GetDataString(3)); lstrcpy(node.szCalleeNum, a_pPduEntity->GetDataString(4)); m_pOperator->onDeviceEvent(DEV_EVENT_RES_STATUS, &node); } } /***************************************************************** **【函数名称】 __onDevOpProcess **【函数功能】 操作进展返回 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevOpProcess( CPduEntity* a_pPduEntity ) { // 生成执行进展内容 EventOpProcess node; memset(&node, 0, sizeof(EventOpProcess)); node.nInstance = a_pPduEntity->GetDataLong(0); node.nHostLine = a_pPduEntity->GetDataUInt(1); node.nAssoLine = a_pPduEntity->GetDataUInt(2); node.nAssoLineType = a_pPduEntity->GetDataUInt(3); lstrcpy(node.szCallerNum, a_pPduEntity->GetDataString(4)); lstrcpy(node.szCalleeNum, a_pPduEntity->GetDataString(5)); // 返回执行结果 m_pOperator->onDeviceEvent(DEV_EVENT_LINE_OP_PROCESS, &node); } /***************************************************************** **【函数名称】 __onDevOpResult **【函数功能】 设备操作执行结果 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevOpResult( CPduEntity* a_pPduEntity ) { // 生成执行结果内容 EventOpResult node; memset(&node, 0, sizeof(EventOpResult)); node.nInstance = a_pPduEntity->GetDataLong(0); node.bIsSucceed = a_pPduEntity->GetDataBool(1); lstrcpy(node.szData, a_pPduEntity->GetDataString(2)); // 返回执行结果 m_pOperator->onDeviceEvent(DEV_EVENT_LINE_OP_RESULT, &node); } /***************************************************************** **【函数名称】 __onDevActiveEvent **【函数功能】 设备主动事件处理 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevActiveEvent( CPduEntity* a_pPduEntity ) { // 生成执行事件内容 EventDevOperation node; memset(&node, 0, sizeof(EventDevOperation)); node.nLineId = a_pPduEntity->GetDataUInt(0); node.nOpType = a_pPduEntity->GetDataUInt(1); lstrcpy(node.szCallerNum, a_pPduEntity->GetDataString(2)); lstrcpy(node.szCalleeNum, a_pPduEntity->GetDataString(3)); // 通知事件 m_pOperator->onDeviceEvent(DEV_EVENT_DEV_OPERATOR, &node); } /***************************************************************** **【函数名称】 __onDevReqReturn **【函数功能】 设备请求返回处理 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::__onDevReqReturn( CPduEntity* a_pPduEntity ) { bool ReqRes = a_pPduEntity->GetDataBool(1); if(!ReqRes) { if(a_pPduEntity->GetCmdType() == PDU_CMD_SC_REQ_RECORD) // 录音命令失败不再通知上层,因为录音是由会话发起并非任务发起 { __onLog(LOG_LEVEL_WARNING, _T("{Dev}: 设备录音失败, HostLine = %d, RecordFile = %s"), a_pPduEntity->GetDataUInt(2), a_pPduEntity->GetDataString(3)); } else { // 生成执行结果内容 EventOpResult node; memset(&node, 0, sizeof(EventOpResult)); node.nInstance = a_pPduEntity->GetDataLong(0); node.bIsSucceed = ReqRes; // 返回执行结果 m_pOperator->onDeviceEvent(DEV_EVENT_LINE_OP_RESULT, &node); } } } #pragma region 设备操作 /***************************************************************** **【函数名称】 __procOpInfoTransaction **【函数功能】 数据交互 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpInfoTransaction( long Instance, ULONG ResID, LineOpParam* pParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_INFOTRANSFER); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpPlayVoice **【函数功能】 线路放音收号 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__procOpPlayVoice( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_PLAY); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataInt(3, pLineOpParam->nParam1); Pdu.SetDataInt(4, pLineOpParam->nParam2); Pdu.SetDataInt(5, pLineOpParam->nParam3); Pdu.SetDataInt(6, pLineOpParam->nParam4); Pdu.SetDataInt(7, pLineOpParam->nParam5); Pdu.SetDataInt(8, pLineOpParam->nParam6); Pdu.SetDataInt(9, pLineOpParam->nParam7); Pdu.SetDataInt(10, pLineOpParam->nParam8); Pdu.SetDataString(11, pLineOpParam->szParam1); Pdu.SetDataString(12, pLineOpParam->szParam3); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpMakeCall **【函数功能】 坐席外呼处理 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__procOpMakeCall( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_MAKECALL); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam2); Pdu.SetDataString(4, pLineOpParam->szParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpHangUp **【函数功能】 挂机操作处理 **【参数】 nInstance 调用标识 nResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpHangUp( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_HANGUP); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpTrunkTurn **【函数功能】 外线呼叫转移 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__procOpTrunkTurn( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_TRUNKTURN); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam2); Pdu.SetDataString(4, pLineOpParam->szParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpTurnAgent **【函数功能】 外线转坐席 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__procOpTurnAgent( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_TURNAGENT); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam2); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpAnswerCall **【函数功能】 应答呼叫 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__procOpAnswerCall( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_ANSWER); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpAutoCall **【函数功能】 自动外呼 **【参数】 **【返回值】 ****************************************************************/ bool CDevControl::__procOpPCall( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_PCALL); Pdu.SetDataLong(0, Instance); Pdu.SetDataString(2, pLineOpParam->szParam2); Pdu.SetDataString(3, pLineOpParam->szParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpTransfer **【函数功能】 座席呼叫转移 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpTransfer( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_TRANSFER); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam2); Pdu.SetDataString(4, pLineOpParam->szParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpConf **【函数功能】 单步会议 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpConf( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_MEETING); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam2); Pdu.SetDataString(4, pLineOpParam->szParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpTurnIvr **【函数功能】 转IVR **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpTurnIvr( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_TURNIVR); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpInstead **【函数功能】 代接 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpInstead( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_INSTEAD); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); UINT ExtNum = 0; sscanf_s(pLineOpParam->szParam2, _T("%u"), &ExtNum); Pdu.SetDataUInt(3, ExtNum); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpGrab **【函数功能】 强截 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpGrab( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_INTERCEPT); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); UINT ExtNum = 0; sscanf_s(pLineOpParam->szParam2, _T("%u"), &ExtNum); Pdu.SetDataUInt(3, ExtNum); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpInsert **【函数功能】 强插 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpInsert( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_INSERT); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); UINT ExtNum = 0; sscanf_s(pLineOpParam->szParam2, _T("%u"), &ExtNum); Pdu.SetDataUInt(3, ExtNum); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpListen **【函数功能】 监听 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpListen( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_LISTEN); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); UINT ExtNum = 0; sscanf_s(pLineOpParam->szParam2, _T("%u"), &ExtNum); Pdu.SetDataUInt(3, ExtNum); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpReset **【函数功能】 监听 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpReset( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_RESET); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __ProcOpFax **【函数功能】 传真 **【参数】 nInstance 调用标识 nResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpFax( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_FAX); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataUInt(3, pLineOpParam->nParam1); Pdu.SetDataString(4, pLineOpParam->szParam3); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpRecord **【函数功能】 线路录音 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpRecord( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_RECORD); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam3); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpLeaveWord **【函数功能】 留言录音 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpLeaveWord( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_LEAVEWORD); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataUInt(3, pLineOpParam->nParam3); Pdu.SetDataString(4, pLineOpParam->szParam1); Pdu.SetDataString(5, pLineOpParam->szParam3); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpMuteOn **【函数功能】 静音启动 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpMuteOn( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_MUTE); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataUInt(3, 0); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpMuteOff **【函数功能】 静音结束 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpMuteOff( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_MUTE); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataUInt(3, 1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpSelfCheck **【函数功能】 线路自检(当前只对模拟外线有效) **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpSelfCheck( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { CPduEntity Pdu(PDU_CMD_SC_REQ_LINECHECK); Pdu.SetDataLong(0, Instance); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpConsultCallBegin **【函数功能】 协商呼叫启动 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpConsultCallBegin( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_CONSULTCALL); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataString(3, pLineOpParam->szParam2); Pdu.SetDataString(4, pLineOpParam->szParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } /***************************************************************** **【函数名称】 __procOpConsultCallConfirm **【函数功能】 协商呼叫确认 **【参数】 Instance 调用标识 ResID 操作的主控资源ID LineOpParam* 操作信息 **【返回值】 启动操作是否成功 ****************************************************************/ bool CDevControl::__procOpConsultCallConfirm( long Instance, ULONG ResID, LineOpParam* pLineOpParam ) { ASSERT(pLineOpParam != NULL); CPduEntity Pdu(PDU_CMD_SC_REQ_CONSULTCONFIRM); Pdu.SetDataLong(0, Instance); Pdu.SetDataUInt(2, ResID); Pdu.SetDataInt(3, pLineOpParam->nParam1); return CInterfaceWindow::getCommInstance()->Send(&Pdu, PDU_DEV_TYPE_SC_SERVER, 0) == TRUE; } #pragma endregion /***************************************************************** **【函数名称】 open **【函数功能】 设备打开 **【参数】 a_pOperator:设备操作者对象 **【返回值】 成功true,失败false ****************************************************************/ bool CDevControl::open( IDeviceOperator* a_pOperator ) { if(m_pOperator != NULL) return false; CeHangConfig::load(); ASSERT(a_pOperator != NULL); m_pOperator = a_pOperator; __onLog(LOG_LEVEL_NORMAL, _T("{DevCtrl}: 开始连接毅航PBX, DevLink版本号: 4.0.0.2")); if(!__initNetLink()) { m_pOperator = NULL; return false; } __notifyResType(); return true; } /***************************************************************** **【函数名称】 close **【函数功能】 设备关闭 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::close( void ) { if(m_pOperator != NULL) { __onLog(LOG_LEVEL_NORMAL, _T("{DevCtrl}: 设备链路关闭")); __shutNetLink(); m_pOperator = NULL; } } /***************************************************************** **【函数名称】 operate **【函数功能】 线路控制 **【参数】 Instance 调用标识 OpType 操作类型 ResID 线路ID pLineOpParam 操作参数 **【返回值】 成功true,失败false ****************************************************************/ bool CDevControl::operate( LONG Instance, LINE_OP OpType, ULONG ResID, LineOpParam* pLineOpParam ) { bool Res = false; // 根据操作类型进行分类处理 switch(OpType) { case LINE_OP_MAKE_CALL: // 座席外呼 Res = __procOpMakeCall(Instance, ResID, pLineOpParam); break; case LINE_OP_ANSWER_CALL: // 应答呼叫 Res = __procOpAnswerCall(Instance, ResID, pLineOpParam); break; case LINE_OP_PREDICTION_CALL: // 预测外呼 Res = __procOpPCall(Instance, ResID, pLineOpParam); break; case LINE_OP_HANG_UP: // 挂机 Res = __procOpHangUp(Instance, ResID, pLineOpParam); break; case LINE_OP_TRANSFER: // 呼叫转移 Res = __procOpTransfer(Instance, ResID, pLineOpParam); break; case LINE_OP_TURNOUT: // 转外线 Res = __procOpTrunkTurn(Instance, ResID, pLineOpParam); break; case LINE_OP_TURNAGENT: // 转坐席 Res = __procOpTurnAgent(Instance, ResID, pLineOpParam); break; case LINE_OP_TURNIVR: // 转IVR Res = __procOpTurnIvr(Instance, ResID, pLineOpParam); break; case LINE_OP_CONFERENCE: // 单步会议 Res = __procOpConf(Instance, ResID, pLineOpParam); break; case LINE_OP_LISTEN: // 监听 Res = __procOpListen(Instance, ResID, pLineOpParam); break; case LINE_OP_INSERT: // 强插 Res = __procOpInsert(Instance, ResID, pLineOpParam); break; case LINE_OP_RESET: // 重置 Res = __procOpReset(Instance, ResID, pLineOpParam); break; case LINE_OP_INSTEAD: // 代接 Res = __procOpInstead(Instance, ResID, pLineOpParam); break; case LINE_OP_GRAB: // 强截 Res = __procOpGrab(Instance, ResID, pLineOpParam); break; case LINE_OP_TRANSFER_INFO: // 信息交互 Res = __procOpInfoTransaction(Instance, ResID, pLineOpParam); break; case LINE_OP_PLAY_VOICE: // 放音收号 Res = __procOpPlayVoice(Instance, ResID, pLineOpParam); break; case LINE_OP_FAX: // 传真 Res = __procOpFax(Instance, ResID, pLineOpParam); break; case LINE_OP_RECORD: // 录音 Res = __procOpRecord(Instance, ResID, pLineOpParam); break; case LINE_OP_LEAVEWORD: // 留言 Res = __procOpLeaveWord(Instance, ResID, pLineOpParam); break; case LINE_OP_MUTE_BEGIN: // 静音启动 Res = __procOpMuteOn(Instance, ResID, pLineOpParam); break; case LINE_OP_MUTE_END: // 静音结束 Res = __procOpMuteOff(Instance, ResID, pLineOpParam); break; case LINE_OP_SELF_CHECK: // 线路自检 Res = __procOpSelfCheck(Instance, ResID, pLineOpParam); break; case LINE_OP_CONSULT_CALL_BEGIN: // 协商呼叫启动 Res = __procOpConsultCallBegin(Instance, ResID, pLineOpParam); break; case LINE_OP_CONSULT_CALL_CONFIRM: // 协商呼叫确认 Res = __procOpConsultCallConfirm(Instance, ResID, pLineOpParam); break; case LINE_OP_IVRFAX_TRANSFER: __onOpResult(Instance, TRUE, _T("")); return TRUE; } // end switch return Res; } /***************************************************************** **【函数名称】 OnLinkStateChanged **【函数功能】 网络链路状态变化处理函数 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::OnLinkStateChanged( const PduLinkContent& linkContent ) { CString Msg; LOG_LEVEL Level = LOG_LEVEL_NORMAL; switch(linkContent.nLinkState) { case PDU_LINK_STATE_SUCCESSED: // 请求连接成功 Msg.Format(_T("Far End[IP = %s, Port = %d], Hint = 网络连接成功..."), linkContent.szFarIp, linkContent.nFarPort); break; case PDU_LINK_STATE_FAILED: // 请求连接失败 Msg.Format(_T("Far End[IP = %s, Port = %d], Hint = 网络连接失败..."), linkContent.szFarIp, linkContent.nFarPort); Level = LOG_LEVEL_ERROR; break; case PDU_LINK_STATE_DISCONNECTED: // 连接已断开 Msg.Format(_T("Far End[IP = %s, Port = %d], Hint = 网络连接已断开..."), linkContent.szFarIp, linkContent.nFarPort); __onNetLinkDisconnected(linkContent); // 后续处理 Level = LOG_LEVEL_ERROR; break; case PDU_LINK_STATE_REG_OK: // 注册成功 { Msg.Format(_T("Far End[Type = %d, ID = %d, IP = %s, Port = %d], Hint = 网络连接注册成功..."), linkContent.nFarType, linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort); if(linkContent.nFarType == PDU_DEV_TYPE_SC_SERVER) m_IsConnected2Sc = true; } break; case PDU_LINK_STATE_REG_FAILED: // 注册失败 Msg.Format(_T("Far End[IP = %s, Port = %d], Hint = 网络连接注册失败,通讯禁止..."), linkContent.szFarIp, linkContent.nFarPort); Level = LOG_LEVEL_ERROR; break; default: Msg.Format(_T("Far End[Type = %d, ID = %d, IP = %s, Port = %d]"), linkContent.nFarType, linkContent.nFarId, linkContent.szFarIp, linkContent.nFarPort); break; } // end switch __onLog(Level, _T("{Dev}: %s"), Msg); } /***************************************************************** **【函数名称】 OnRecvCommand **【函数功能】 网络命令处理函数 **【参数】 **【返回值】 ****************************************************************/ void CDevControl::OnRecvCommand( CPduEntity* a_pPduEntity ) { ASSERT(a_pPduEntity != NULL); switch(a_pPduEntity->GetCmdType()) { case PDU_CMD_SC_RES_DETAIL: __onDevResDetail(a_pPduEntity); break; case PDU_CMD_SC_RES_STATE: __onDevResState(a_pPduEntity); break; case PDU_CMD_SC_ACTIVE_EVENT: __onDevActiveEvent(a_pPduEntity); break; case PDU_CMD_SC_REQ_PROCESS: __onDevOpProcess(a_pPduEntity); break; case PDU_CMD_SC_REQ_RESULT: __onDevOpResult(a_pPduEntity); break; case PDU_CMD_SC_REQ_PCALL: case PDU_CMD_SC_REQ_MAKECALL: case PDU_CMD_SC_REQ_ANSWER: case PDU_CMD_SC_REQ_HANGUP: case PDU_CMD_SC_REQ_TRANSFER: case PDU_CMD_SC_REQ_TRUNKTURN: case PDU_CMD_SC_REQ_PLAY: case PDU_CMD_SC_REQ_CONSULTCALL: case PDU_CMD_SC_REQ_CONSULTCONFIRM: case PDU_CMD_SC_REQ_MUTE: case PDU_CMD_SC_REQ_INSTEAD: case PDU_CMD_SC_REQ_INTERCEPT: case PDU_CMD_SC_REQ_INSERT: case PDU_CMD_SC_REQ_LISTEN: case PDU_CMD_SC_REQ_LEAVEWORD: case PDU_CMD_SC_REQ_MEETING: case PDU_CMD_SC_REQ_FAX: case PDU_CMD_SC_REQ_TURNIVR: case PDU_CMD_SC_REQ_RESET: case PDU_CMD_SC_REQ_RECORD: case PDU_CMD_SC_REQ_LINECHECK: case PDU_CMD_SC_REQ_INFOTRANSFER: case PDU_CMD_SC_REQ_TURNAGENT: __onDevReqReturn(a_pPduEntity); break; } }