| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547 |
- #include "StdAfx.h"
- #include "DeviceMgr.h"
- #include "DevFax.h"
- #include "NetworkVs.h"
- #include "LineAudio.h"
- #include "LineRecordAna.h"
- #include "LineRecordDig.h"
- #include "LineRecordIpra.h"
- #include "LineRecordIprr.h"
- #include "Config.h"
- #include "IprControl.h"
- SINGLETON_IMPLEMENT(CDeviceMgr)
- CDeviceMgr::CDeviceMgr(void)
- {
- }
- CDeviceMgr::~CDeviceMgr(void)
- {
- __release();
- }
- /*****************************************************************
- **【函数名称】 __release
- **【函数功能】 释放资源
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDeviceMgr::__release( void )
- {
- for(int i = 0; i < m_LineArray.GetCount(); ++i)
- {
- ASSERT(m_LineArray[i] != NULL);
- delete m_LineArray[i];
- }
- m_LineArray.RemoveAll();
- while(!m_FaxList.IsEmpty())
- delete m_FaxList.RemoveHead();
- }
- /*****************************************************************
- **【函数名称】 __initLineObject
- **【函数功能】 初始化线路对象
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDeviceMgr::__initLineObject( void )
- {
- // 初始化线路对象
- int nTotalCH = SsmGetMaxCh(); // 系统通道总数
- for (int i = 0; i < nTotalCH; ++i)
- {
- int nType = SsmGetChType(i);
- switch(nType)
- {
- case CONST_CH_AUDIO_ANA: //模拟放音线路
- {
- CLineAudio * pLine = new CLineAudio(i);
- m_LineArray.Add(pLine);
- CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast<const PARAM>(i));
- }
- break;
- case CONST_CH_REC_ANA: //模拟录音线路
- {
- CLineRecordAna* pLine = new CLineRecordAna(i);
- m_LineArray.Add(pLine);
- CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast<const PARAM>(i));
- }
- break;
- case CONST_CH_REC_DIG: //数字录音线路
- {
- int nCicID = SpyChToCic(i);
- if (-1 == nCicID)
- break;
- if (NULL == __findLineByCicID(nCicID))
- {
- CLineRecordDig *pLine = new CLineRecordDig(i);
- m_LineArray.Add(pLine);
- CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast<const PARAM>(i));
- }
- }
- break;
- case CONST_CH_FAX: // 传真资源
- {
- CDevFax * pDevFax = new CDevFax(i);
- m_FaxList.AddTail(pDevFax);
- CMsgCenter::GetInstance().pushMsg(VS_MSG_DEV_FAX_STATE_UPDAET, reinterpret_cast<const PARAM>(i));
- }
- break;
- case CONST_CH_REC_IPR:
- {
- CIprControl::GetInstance().newIprrLine(i);
- }
- break;
- case CONST_CH_REC_IPA:
- {
- CIprControl::GetInstance().newIpraLine(i);
- }
- break;
- }
- } // end for
- }
- /*****************************************************************
- **【函数名称】 __findLineByCicID
- **【函数功能】 根据数字线路的逻辑编号查找指定数字中继线路
- **【参数】 int nCic 数字中继线路的逻辑编号
- **【返回值】
- ****************************************************************/
- CLine* CDeviceMgr::__findLineByCicID( int CicId )
- {
- int Count = m_LineArray.GetCount();
- for (int i = 0; i < Count; ++i)
- {
- CLine* pLine = m_LineArray[i];
- ASSERT(pLine != NULL);
- if(pLine->type() == DEV_VS_TYPE_RECDIG && pLine->cicId() == CicId)
- return pLine;
- }
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 __findLineByIPOLineID
- **【函数功能】 根据IPO的线路ID查找线路
- **【参数】
- **【返回值】
- ****************************************************************/
- CLine* CDeviceMgr::__findLineByIPOLineID( int IpoLineID )
- {
- int Count = m_LineArray.GetCount();
- for (int i = 0; i < Count; ++i)
- {
- CLine* pLine = m_LineArray[i];
- ASSERT(pLine != NULL);
- if (pLine->assoIpoId() == IpoLineID)
- return pLine;
- }
- return CIprControl::GetInstance().findLineByIPOLineID(IpoLineID);
- }
- /*****************************************************************
- **【函数名称】 __callBackProc
- **【函数功能】 回调函数
- **【参数】 wEvent:系统当前触发的事件,nReference:通道逻辑号,dwParam:事件输出参数dwUser:用户自定义参数
- **【返回值】
- ****************************************************************/
- void CDeviceMgr::__callBackProc( PSSM_EVENT pEvent )
- {
- CLine* pLine = NULL;
- switch(pEvent->wEventCode)
- {
- case E_CHG_ChState: //通道状态发生变化
- case E_PROC_PlayEnd: //放音任务完成
- case E_CHG_BusyTone: //检测到忙音,即挂机
- case E_PROC_WaitDTMF: //WaitDTMF任务完成
- case E_PROC_RecordEnd: //录音任务终止
- pLine = findLineByID(pEvent->nReference);
- break;
- case E_CHG_FaxPages:
- {
- int FaxEnd = SsmFaxCheckEnd(pEvent->nReference);
- if (FaxEnd == 3) // 已经完成全部传真的接收与发送,正在断开
- {
- CDevFax* pDevFax = getFaxByID(pEvent->nReference);
- ASSERT(pDevFax != NULL);
- pLine = pDevFax->getAssoLine();
- pEvent->dwParam = 1;
- }
- ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevMgr}: 传真设备[%d]结束第%d页收发, Result = %d"), pEvent->nReference, pEvent->dwParam, FaxEnd);
- }
- break;
- case E_PROC_FaxEnd: //传真操作结束事件
- {
- CDevFax * pDevFax = getFaxByID(pEvent->nReference);
- pLine = pDevFax->getAssoLine();
- ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevMgr}: 传真设备[%d]结束传真收发, Result = %d"), pEvent->nReference, pEvent->dwParam);
- }
- break;
- case E_CHG_SpyState:
- {
- pLine = __findLineByCicID(pEvent->nReference);
- }
- break;
- case E_IPR_LINK_REC_SLAVER_CONNECTED:
- CIprControl::GetInstance().onEventSlaverConnected(pEvent);
- break;
- case E_IPR_LINK_REC_SLAVER_DISCONNECTED:
- CIprControl::GetInstance().onEventSlaverDisconnected(pEvent);
- break;
- case E_IPR_START_SLAVER_CB:
- CIprControl::GetInstance().onEventStartSlaverCb(pEvent);
- break;
- case E_IPR_CLOSE_SLAVER_CB:
- CIprControl::GetInstance().onEventCloseSlaverCb(pEvent);
- break;
- // IP录音相关
- case E_IPR_START_REC_CB:
- case E_IPR_STOP_REC_CB:
- case E_IPR_PAUSE_REC_CB:
- case E_IPR_RESTART_REC_CB:
- case E_IPR_ACTIVE_SESSION_CB:
- case E_IPR_DEACTIVE_SESSION_CB:
- case E_IPR_ACTIVE_AND_REC_CB:
- case E_IPR_DEACTIVE_AND_STOPREC_CB:
- case E_RCV_IPR_MEDIA_SESSION_STARTED:
- case E_RCV_IPR_MEDIA_SESSION_STOPED:
- case E_RCV_IPR_AUX_MEDIA_SESSION_STARTED:
- case E_RCV_IPR_AUX_MEDIA_SESSION_STOPED:
- pLine = findLineByID(pEvent->nReference);
- break;
- case E_RCV_IPR_DONGLE_REMOVED:
- case E_RCV_IPA_DONGLE_REMOVED:
- CIprControl::GetInstance().onEventUsbKeyRemoved(pEvent);
- break;
- case E_RCV_IPR_AUTH_OVERFLOW:
- CIprControl::GetInstance().onEventAuthOverflow(pEvent);
- break;
- case E_RCV_IPR_STATION_ADDED:
- CIprControl::GetInstance().onEventStationAdd(pEvent);
- break;
- case E_RCV_IPR_STATION_REMOVED:
- CIprControl::GetInstance().onEventStationRemoved(pEvent);
- break;
- case E_CHG_CIDExBuf: //收到主叫号码
- case E_CHG_RcvDTMF:
- case E_SYS_ActualPickup: //摘机命令执行完毕
- break;
- }
- if(pLine != NULL)
- pLine->procDevMsg(pEvent);
- }
- /*****************************************************************
- **【函数名称】 __eventCallBackProc
- **【函数功能】 回调函数
- **【参数】 wEvent:系统当前触发的事件,nReference:通道逻辑号,dwParam:事件输出参数dwUser:用户自定义参数
- **【返回值】
- ****************************************************************/
- int CALLBACK CDeviceMgr::__eventCallBackProc( PSSM_EVENT pEvent )
- {
- CDeviceMgr* pDevManager = (CDeviceMgr*)pEvent->dwUser;
- pDevManager->__callBackProc(pEvent);
- return 1;
- }
- /*****************************************************************
- **【函数名称】 getFreeDevFax
- **【函数功能】 获取一空闲传真资源
- **【参数】
- **【返回值】
- ****************************************************************/
- CDevFax* CDeviceMgr::getFreeDevFax( void )
- {
- static POSITION posFaxStatic = m_FaxList.GetHeadPosition();
- for(int i= 0; i< m_FaxList.GetCount(); i++)
- {
- CDevFax * pDevFax = m_FaxList.GetNext(posFaxStatic);
- if(posFaxStatic == NULL)
- posFaxStatic = m_FaxList.GetHeadPosition();
- if(!pDevFax->isBusy())
- return pDevFax;
- }
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getFaxByID
- **【函数功能】 通过传真资源ID获取传真资源对象
- **【参数】
- **【返回值】
- ****************************************************************/
- CDevFax* CDeviceMgr::getFaxByID( int DevID )
- {
- POSITION pos = m_FaxList.GetHeadPosition();
- while(pos != NULL)
- {
- CDevFax * pDevFax = m_FaxList.GetNext(pos);
- if(pDevFax->id() == DevID)
- return pDevFax;
- }
- return NULL;
- }
- /*****************************************************************
- **【函数名称】 getDevType
- **【函数功能】 获取设备类型
- **【参数】
- **【返回值】
- ****************************************************************/
- int CDeviceMgr::getDevType( void )
- {
- int type = 0;
- int Count = m_LineArray.GetCount();
- for (int i = 0; i < Count; ++i)
- {
- CLine* pLine = m_LineArray[i];
- ASSERT(pLine != NULL);
- if (pLine->type() == DEV_VS_TYPE_AUDIO) //包含有放音模块
- {
- type = type | PDU_DEV_TYPE_VS_PLAY;
- }
- if ((pLine->type() == DEV_VS_TYPE_RECANA) ||
- (pLine->type() == DEV_VS_TYPE_RECDIG)) //包含的是录音模块
- {
- type = type | PDU_DEV_TYPE_VS_REC;
- }
- }
- if(CIprControl::GetInstance().getIprrLineCount() > 0)
- type = type | PDU_DEV_TYPE_VS_REC;
- return type;
- }
- /*****************************************************************
- **【函数名称】 findLineByID
- **【函数功能】 根据通道逻辑号查找线路对象
- **【参数】 LineID:通道逻辑号
- **【返回值】 线路对象
- ****************************************************************/
- CLine* CDeviceMgr::findLineByID( int LineID )
- {
- int Count = m_LineArray.GetCount();
- for (int i = 0; i < Count; ++i)
- {
- CLine* pLine = m_LineArray[i];
- ASSERT(pLine != NULL);
- if (pLine->id() == LineID)
- return pLine;
- }
- return CIprControl::GetInstance().findLineByID(LineID);
- }
- /*****************************************************************
- **【函数名称】 initDev
- **【函数功能】 设备初始化
- **【参数】
- **【返回值】 初始化成功或失败
- ****************************************************************/
- bool CDeviceMgr::initDev( void )
- {
- //设置事件回调类型
- EVENT_SET_INFO EventSet;
- EventSet.dwWorkMode = EVENT_CALLBACKA;
- EventSet.lpHandlerParam = __eventCallBackProc;
- EventSet.dwUser = (DWORD)this;
- // 系统初始化
- int IsSsmStartCtiOK = SsmStartCtiEx(SH_SSM_CFG_FILE, SH_IDX_CFG_FILE, TRUE, &EventSet);
- if(IsSsmStartCtiOK != 0)
- {
- char szErrMsg[DEV_OP_BUF_LEN];
- SsmGetLastErrMsg(szErrMsg);
- AfxMessageBox(szErrMsg, MB_OK, 0);
- return false;
- }
- // 是否所有板卡都初始化成功
- if(SsmGetMaxUsableBoard() != SsmGetMaxCfgBoard())
- {
- char szErrMsg[DEV_OP_BUF_LEN];
- SsmGetLastErrMsg(szErrMsg);
- CString ErrContent;
- ErrContent.Format(_T("警告:板卡总数=%d, 初始化成功板卡数=%d!\n 错误信息=\"%s\""), SsmGetMaxCfgBoard(), SsmGetMaxUsableBoard(), szErrMsg);
- AfxMessageBox(szErrMsg, MB_OK, 0);
- SsmCloseCti();
- return false;
- }
- //初始化线路对象
- __initLineObject();
- CIprControl::GetInstance().init();
- //设置回调事件 初始化已由SsmStartCti改为SsmStartCtiEx,后者包含了事件输出的设定,故该函数调用暂被注释
- //if(SsmSetEvent(0xffff, -1, TRUE, &EventSet) == -1) //Designates event
- //{
- // char szErrMsg[DEV_OP_BUF_LEN];
- // SsmGetLastErrMsg(szErrMsg); //Get wrong message
- // AfxMessageBox(szErrMsg, MB_OK, 0);
- // closeDev();
- // return false;
- //}
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{DevMgr}: 设备初始化成功"));
- return true;
- }
- /*****************************************************************
- **【函数名称】 closeDev
- **【函数功能】 关闭设备
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDeviceMgr::closeDev( void )
- {
- CIprControl::GetInstance().release();
- if (SsmCloseCti() != 1)
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 关闭设备时出错"));
- __release();
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 设备关闭"));
- }
- /*****************************************************************
- **【函数名称】 procCmd
- **【函数功能】 处理网络命令
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDeviceMgr::procCmd( CPduEntity* a_pPduEntity )
- {
- CLine* pLine = NULL;
-
- switch(a_pPduEntity->GetCmdType())
- {
- case PDU_CMD_IVR_PLAY_DTMF: // 放音收号
- {
- pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(3));
- if(pLine == NULL)
- {
- a_pPduEntity->SetToExecReturn();
- a_pPduEntity->SetDataBool(0, false);
- CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到放音收号命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
- a_pPduEntity->GetDataUInt(3));
- }
- }
- break;
- case PDU_CMD_IVR_LEAVE_WORD: // 留言
- {
- pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(3));
- if(pLine == NULL)
- {
- a_pPduEntity->SetToExecReturn();
- a_pPduEntity->SetDataBool(0, false);
- CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到留言命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
- a_pPduEntity->GetDataUInt(3));
- }
- }
- break;
- case PDU_CMD_IVR_FAX: // 传真
- {
- pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(3));
- if(pLine == NULL)
- {
- a_pPduEntity->SetToExecReturn();
- a_pPduEntity->SetDataBool(0, false);
- CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到传真命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
- a_pPduEntity->GetDataUInt(3));
- }
- }
- break;
- case PDU_CMD_CTI_VS_RECORD: // 录音
- {
- pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(1));
- if(pLine == NULL)
- {
- a_pPduEntity->SetToExecReturn();
- a_pPduEntity->SetDataBool(0, false);
- CNetworkVs::GetInstance().sendPduToCti(a_pPduEntity);
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到录音命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
- a_pPduEntity->GetDataUInt(1));
- }
- }
- break;
- case PDU_CMD_CTI_VS_LINECONTROL:
- {
- pLine = __findLineByIPOLineID(a_pPduEntity->GetDataUInt(0));
- if(pLine == NULL)
- {
- ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{DevMgr}: 收到线路控制命令, 但未找到对应VS线路[%d], 请确定FirstStep中配置是否正确"),
- a_pPduEntity->GetDataUInt(0));
- }
- }
- break;
- }
- if(pLine != NULL)
- pLine->procCmd(a_pPduEntity);
- }
- /*****************************************************************
- **【函数名称】 hangupAllLine
- **【函数功能】 对所有线路进行挂机操作
- **【参数】
- **【返回值】
- ****************************************************************/
- void CDeviceMgr::hangupAllLine( void )
- {
- int Count = m_LineArray.GetCount();
- for (int i = 0; i < Count; ++i)
- {
- CLine* pLine = m_LineArray[i];
- ASSERT(pLine != NULL);
- CPduEntity cmd(PDU_CMD_CTI_VS_LINECONTROL);
- cmd.SetDataInt(1, IVR_LINE_HANG_UP);
- pLine->procCmd(&cmd);
- }
- }
|