#include "StdAfx.h" #include "IprControl.h" #include "LineRecordIpra.h" #include "LineRecordIprr.h" #include "Config.h" #include SINGLETON_IMPLEMENT(CIprControl) CIprControl::CIprControl(void) : m_IprBoardId(CONST_BOARD_NULL), m_IpaBoardId(CONST_BOARD_NULL), m_SlaverCount(0) { ZeroMemory(&m_IprSlaver, sizeof(IPR_SLAVERADDR)); } CIprControl::~CIprControl(void) { } /***************************************************************** **【函数名称】 __checkRecFileEnv **【函数功能】 检查录音文件环境 **【参数】 WaveFile: 文件路径 **【返回值】 ****************************************************************/ DWORD CIprControl::__checkRecFileEnv( LPCTSTR RecFile ) { struct stat st; if(stat(RecFile, &st) == 0) return st.st_size; else { if(errno == ENOENT) { CString tmpPath = RecFile; int index = tmpPath.ReverseFind('\\'); if (index == -1) index = tmpPath.ReverseFind('/'); tmpPath = tmpPath.Left(index + 1); SHCreateDirectoryEx(NULL, tmpPath, NULL); } return 0; } } /***************************************************************** **【函数名称】 __scanIprSlaver **【函数功能】 扫描slaver资源 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::__scanIprSlaver( void ) { m_SlaverCount = SsmIPRGetRecSlaverCount(m_IprBoardId); if(m_SlaverCount > 0) { // 目前仅考虑适用单路slaver if(SsmIPRGetRecSlaverList(m_IprBoardId, 1, &m_SlaverCount, &m_IprSlaver) < 0) { char szErrMsg[DEV_OP_BUF_LEN]; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 获取IPR Slaver信息失败, Cause = %s"), szErrMsg); } } } /***************************************************************** **【函数名称】 __openIprSlaver **【函数功能】 分配slaver资源 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::__openIprSlaver( void ) { if(m_SlaverCount > 0) { SYSTEM_INFO si; ZeroMemory(&si, sizeof(SYSTEM_INFO)); GetSystemInfo(&si); int ThreadPairs = si.dwNumberOfProcessors; int TotalResources = m_IprrLineArray.GetCount(); // 目前仅考虑适用单路slaver if(SsmIPRStartRecSlaver(m_IprBoardId, m_IprSlaver.nRecSlaverID, &TotalResources, &ThreadPairs) < 0) { char szErrMsg[DEV_OP_BUF_LEN]; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 启动IPR Slaver失败, Cause = %s"), szErrMsg); } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 启动IPR Slaver成功")); } } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 启动IPR Slaver失败, 无可用的Slaver")); } } /***************************************************************** **【函数名称】 __closeIprSlaver **【函数功能】 释放slaver资源 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::__closeIprSlaver( void ) { if(m_SlaverCount > 0) { // 目前仅考虑适用单路slaver SsmIPRCloseRecSlaver(m_IprBoardId, m_IprSlaver.nRecSlaverID); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 关闭IPR Slaver")); } } /***************************************************************** **【函数名称】 __findLineIpraBySessionId **【函数功能】 根据会话ID查找IPRA线路 **【参数】 **【返回值】 ****************************************************************/ CLineRecordIpra* CIprControl::__findLineIpraBySessionId( int SessionId ) { int Count = m_IpraLineArray.GetCount(); for (int i = 0; i < Count; ++i) { CLineRecordIpra* pLine = m_IpraLineArray[i]; ASSERT(pLine != NULL); if (pLine->sessionId() == SessionId) return pLine; } return NULL; } /***************************************************************** **【函数名称】 __findLineIprrByStationId **【函数功能】 根据Station ID查找IPRR线路 **【参数】 **【返回值】 ****************************************************************/ CLineRecordIprr* CIprControl::__findLineIprrByStationId( int StationId ) { int Count = m_IprrLineArray.GetCount(); for (int i = 0; i < Count; ++i) { CLineRecordIprr* pLine = m_IprrLineArray[i]; ASSERT(pLine != NULL); if (pLine->stationId() == StationId) return pLine; } return NULL; } /***************************************************************** **【函数名称】 __startRecord **【函数功能】 录音 **【参数】 pLine: 录音线路 FileName: 录音文件完全路径 **【返回值】 成功TRUE, 失败FALSE ****************************************************************/ bool CIprControl::__startRecord( CLineRecordIprr* pLine, LPCTSTR FileName ) { int LineID = pLine->id(); if(pLine->recState() == REC_STATE_ACTIVED) { // 当前正在录音,停止录音 __stopRecord(pLine); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]开始录音前已处于录音状态, 录音被终止"), LineID); return false; } // 当前已关联会话 if(pLine->isSessionActived()) { //检测文件环境 DWORD StartPos = __checkRecFileEnv(FileName); SsmIPRSetMixerType(LineID, 2); // 混音录音 int Res = SsmRecToFile(LineID, FileName, CONST_IPR_FILE_FORMAT, StartPos, -1, -1, 0); if(Res < 0) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]启动录音出错, Cause = %s"), LineID, szErrMsg); return false; } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]启动录音, FileName = %s, StartPos = %u"), LineID, FileName, StartPos); return true; } } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]启动录音时会话尚未激活, FileName = %s"), LineID, FileName); return true; } } /***************************************************************** **【函数名称】 __stopRecord **【函数功能】 停止留言 **【参数】 pLine: 线路 **【返回值】 ****************************************************************/ bool CIprControl::__stopRecord( CLineRecordIprr* pLine ) { int LineID = pLine->id(); switch(pLine->recState()) { case REC_STATE_ACTIVED: case REC_STATE_PAUSED: { pLine->resetRecContext(); if(SsmIPRDeActiveAndStopRecToFile(pLine->id()) < 0) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]停止录音失败, Cause = %s"), LineID, szErrMsg); return false; } } break; case REC_STATE_WAIT: { pLine->resetRecContext(); if(SsmIPRDeActiveSession(pLine->id()) < 0) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]去激活会话失败, Cause = %s"), LineID, szErrMsg); return false; } } break; default: pLine->resetRecContext(); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]停止录音时状态已空闲"), LineID); return false; } ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]停止录音成功"), LineID); return true; } /***************************************************************** **【函数名称】 __pauseRecord **【函数功能】 暂停录音 **【参数】 pLine: 线路 **【返回值】 成功TRUE, 失败FALSE ****************************************************************/ bool CIprControl::__pauseRecord( CLineRecordIprr* pLine ) { int LineID = pLine->id(); if(pLine->recState() != REC_STATE_ACTIVED) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]未进行录音或录音已暂停"), LineID); return false; } //暂停录音 if (SsmPauseRecToFile(LineID) == 0) { return true; } else { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]暂停录音失败, Cause = %s"), LineID, szErrMsg); return false; } } /***************************************************************** **【函数名称】 __resumeRecord **【函数功能】 继续录音 **【参数】 pLine: 线路 **【返回值】 成功TRUE, 失败FALSE ****************************************************************/ bool CIprControl::__resumeRecord( CLineRecordIprr* pLine ) { int LineID = pLine->id(); if(pLine->recState() != REC_STATE_PAUSED) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]没有被暂停的录音任务"), LineID); return false; } if (SsmRestartRecToFile(LineID) == -1) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]重启录音失败, Cause = %s"), LineID, szErrMsg); return false; } else { return true; } } /***************************************************************** **【函数名称】 init **【函数功能】 初始化 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::init( void ) { int TotalBoards = SsmGetMaxUsableBoard(); for(int i = 0; i < TotalBoards; ++i) { if(SsmGetBoardModel(i) == CONST_BOARD_IPRR) // IPRecorder card type is 0xfd { m_IprBoardId = i; break; } } if(m_IprBoardId == CONST_BOARD_NULL) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 未检测到IPRecorder卡")); return; } for(int i = 0; i < TotalBoards; ++i) { if(SsmGetBoardModel(i) == CONST_BOARD_IPRA) // IPAnalyzer card type is 0xfe { m_IpaBoardId = i; break; } } if(m_IpaBoardId == CONST_BOARD_NULL) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 未检测到IPAnalyzer卡")); return; } // 映射分机 CHAR ExtenNum[PHONE_NUM_LEN] = { 0 }; for(int i = 0; i < m_IprrLineArray.GetCount(); ++i) { CLineRecordIprr* pLine = m_IprrLineArray[i]; ASSERT(pLine != NULL); int IpoLineId = pLine->assoIpoId(); if(IpoLineId > 0) { ZeroMemory(ExtenNum, PHONE_NUM_LEN); sprintf_s(ExtenNum, _T("%d"), pLine->assoIpoId()); if(SsmIPRAddStationToMapEx(m_IpaBoardId, i, NULL, 0, ExtenNum, NULL) < 0) ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 映射分机[%d-%d]失败"), IpoLineId, i); else pLine->stationId() = i; } } } /***************************************************************** **【函数名称】 release **【函数功能】 释放资源 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::release( void ) { __closeIprSlaver(); for(int i = 0; i < m_IprrLineArray.GetCount(); ++i) { ASSERT(m_IprrLineArray[i] != NULL); delete m_IprrLineArray[i]; } m_IprrLineArray.RemoveAll(); for(int i = 0; i < m_IpraLineArray.GetCount(); ++i) { ASSERT(m_IpraLineArray[i] != NULL); delete m_IpraLineArray[i]; } m_IpraLineArray.RemoveAll(); } /***************************************************************** **【函数名称】 newIprrLine **【函数功能】 创建IPRR线路 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::newIprrLine( int LineID ) { CLineRecordIprr* pLine = new CLineRecordIprr(LineID); m_IprrLineArray.Add(pLine); CMsgCenter::GetInstance().pushMsg(VS_MSG_LINE_STATE_UPDATE, reinterpret_cast(LineID)); } /***************************************************************** **【函数名称】 newIpraLine **【函数功能】 创建IPRA线路 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::newIpraLine( int LineID ) { CLineRecordIpra* pLine = new CLineRecordIpra(LineID); m_IpraLineArray.Add(pLine); } /***************************************************************** **【函数名称】 findLineByID **【函数功能】 根据线路逻辑号查找线路对象 **【参数】 LineID:线路逻辑号 **【返回值】 线路对象 ****************************************************************/ CLine* CIprControl::findLineByID( int LineID ) { int Count = m_IprrLineArray.GetCount(); for (int i = 0; i < Count; ++i) { CLine* pLine = m_IprrLineArray[i]; ASSERT(pLine != NULL); if (pLine->id() == LineID) return pLine; } Count = m_IpraLineArray.GetCount(); for(int i = 0; i < Count; ++i) { CLine* pLine = m_IpraLineArray[i]; ASSERT(pLine != NULL); if (pLine->id() == LineID) return pLine; } return NULL; } /***************************************************************** **【函数名称】 findLineByIPOLineID **【函数功能】 根据IPO的线路ID查找线路 **【参数】 **【返回值】 ****************************************************************/ CLineRecordIprr* CIprControl::findLineByIPOLineID( int IpoLineID ) { // 仅查找IPRR线路 int Count = m_IprrLineArray.GetCount(); for (int i = 0; i < Count; ++i) { CLineRecordIprr* pLine = m_IprrLineArray[i]; ASSERT(pLine != NULL); if (pLine->assoIpoId() == IpoLineID) return pLine; } return NULL; } /***************************************************************** **【函数名称】 onCmdLineRecord **【函数功能】 录音线路命令处理 **【参数】 pLine 放音线路指针 pPdu 命令指针 **【返回值】 ****************************************************************/ void CIprControl::onCmdLineRecord( CLineRecordIprr* pLine, CPduEntity* pPdu ) { CString szRecFileName = pPdu->GetDataString(3); //录音文件名 switch(pPdu->GetDataInt(2)) { case RECORD_CONTROL_BEGIN: // 录音开始 { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]收到开始录音命令, RecFile = %s"), pLine->id(), szRecFileName); __startRecord(pLine, szRecFileName); pLine->setCmd(pPdu); } break; case RECORD_CONTROL_END: // 停止录音 { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]收到停止录音命令, RecFile = %s"), pLine->id(), szRecFileName); __stopRecord(pLine); } break; case RECORD_CONTROL_PAUSE: // 暂停录音 { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]收到暂停录音命令, RecFile = %s"), pLine->id(), szRecFileName); __pauseRecord(pLine); } break; case RECORD_CONTROL_RESUME: // 继续录音 { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]收到继续录音命令, RecFile = %s"), pLine->id(), szRecFileName); __resumeRecord(pLine); } break; } // end switch } /***************************************************************** **【函数名称】 onCmdLineControl **【函数功能】 录音线路控制命令处理 **【参数】 pLine 放音线路指针 pPduEntity 命令指针 **【返回值】 ****************************************************************/ void CIprControl::onCmdLineControl( CLineRecordIprr* pLine, CPduEntity* pPdu ) { int lineControl = pPdu->GetDataInt(1); if(lineControl == IVR_LINE_HANG_UP) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 录音线路[%d]收到挂机控制命令"), pLine->id()); pLine->freeCmd(); __stopRecord(pLine); } } /***************************************************************** **【函数名称】 onEventUsbKeyRemoved **【函数功能】 授权狗被移除事件处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventUsbKeyRemoved( PSSM_EVENT pEvent ) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 录音授权USB KEY被移除")); } /***************************************************************** **【函数名称】 onEventAuthOverflow **【函数功能】 授权溢出事件处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventAuthOverflow( PSSM_EVENT pEvent ) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 录音授权溢出")); } /***************************************************************** **【函数名称】 onEventSlaverConnected **【函数功能】 检测到录音Slaver连接的处理函数 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventSlaverConnected( PSSM_EVENT pEvent ) { if(m_SlaverCount == 0) { __scanIprSlaver(); __openIprSlaver(); } } /***************************************************************** **【函数名称】 onEventSlaverDisconnected **【函数功能】 检测到录音Slaver连接中断的处理函数 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventSlaverDisconnected( PSSM_EVENT pEvent ) { if((int)(pEvent->dwParam >> 16) == m_IprSlaver.nRecSlaverID) { __closeIprSlaver(); __scanIprSlaver(); } } /***************************************************************** **【函数名称】 onEventStartSlaverCb **【函数功能】 启动slaver反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventStartSlaverCb( PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode != 0) { __closeIprSlaver(); __scanIprSlaver(); __openIprSlaver(); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: IPR Slaver[%d]启动失败, ErrCode = %d"), SlaverId, CbCode); } } /***************************************************************** **【函数名称】 onEventCloseSlaverCb **【函数功能】 关闭slaver反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventCloseSlaverCb( PSSM_EVENT pEvent ) { #ifdef _DEBUG int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode == 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: IPR Slaver[%d]已关闭"), SlaverId); } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: IPR Slaver[%d]关闭失败, ErrCode = %d"), SlaverId, CbCode); } #endif } /***************************************************************** **【函数名称】 onEventStationAdd **【函数功能】 station添加事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventStationAdd( PSSM_EVENT pEvent ) { int PtlType = pEvent->dwXtraInfo >> 16; int StationId = pEvent->dwXtraInfo & 0xffff; if(PtlType != PTL_AVAYA_H323) return; CLineRecordIprr* pLine = __findLineIprrByStationId(StationId); ASSERT(pLine != NULL); if(pLine != NULL) ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 分机[%d]注册, StationId = %d"), pLine->assoIpoId(), StationId); } /***************************************************************** **【函数名称】 onEventStationRemoved **【函数功能】 station删除事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventStationRemoved( PSSM_EVENT pEvent ) { int PtlType = pEvent->dwXtraInfo >> 16; int StationId = pEvent->dwXtraInfo & 0xffff; if(PtlType != PTL_AVAYA_H323) return; CLineRecordIprr* pLine = __findLineIprrByStationId(StationId); ASSERT(pLine != NULL); if(pLine != NULL) ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 分机[%d]注销, StationId = %d"), pLine->assoIpoId(), StationId); } /***************************************************************** **【函数名称】 onEventDChannel **【函数功能】 D线路信令事件处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventDChannel( PSSM_EVENT pEvent ) { int PtlType = pEvent->dwXtraInfo >> 16; int StationId = pEvent->dwXtraInfo & 0xffff; if(PtlType != PTL_AVAYA_H323) return; switch(pEvent->dwParam) { case DST_CALL_IN_PROGRESS: case DE_CALL_ALERTING: case DE_CALL_CONNECTED: { CLineRecordIprr* pLineIprr = __findLineIprrByStationId(StationId); ASSERT(pLineIprr != NULL); if(pLineIprr != NULL) { TRACE(_T("IPO Call[0x%x-%d]: IpoLineId = %d \r\n"), pEvent->dwParam, StationId, pLineIprr->assoIpoId()); } } break; } } /***************************************************************** **【函数名称】 onEventIprState **【函数功能】 IPR录音事件处理 **【参数】 pLine IPR录音线路指针 int State 状态类型 **【返回值】 ****************************************************************/ void CIprControl::onEventIprState( CLineRecordIprr* pLine, int State ) { ASSERT(pLine != NULL); pLine->state() = State; switch(State) { case S_CALL_STANDBY: case S_CALL_UNAVAILABLE: case S_IPR_COMMUNICATING: case S_IPR_USING: pLine->show(); break; } } /***************************************************************** **【函数名称】 onEventIpaState **【函数功能】 IPA录音事件处理 **【参数】 pLine IPA录音线路指针 int State 状态类型 **【返回值】 ****************************************************************/ void CIprControl::onEventIpaState( CLineRecordIpra* pLine, int State ) { ASSERT(pLine != NULL); pLine->state() = State; } /***************************************************************** **【函数名称】 onEventStartRecCb **【函数功能】 开始录音反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventStartRecCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode != 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]录音失败, ErrCode = %d"), pLine->id(), CbCode); } else { pLine->recState() = REC_STATE_ACTIVED; ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]开始录音"), pLine->id()); } } /***************************************************************** **【函数名称】 onEventStopRecCb **【函数功能】 结束录音反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventStopRecCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode != 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]停止录音失败, ErrCode = %d"), pLine->id(), CbCode); } } /***************************************************************** **【函数名称】 onEventPauseRecCb **【函数功能】 暂停录音反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventPauseRecCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode != 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]暂停录音失败, ErrCode = %d"), pLine->id(), CbCode); } else { pLine->recState() = REC_STATE_PAUSED; ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]录音暂停"), pLine->id()); } } /***************************************************************** **【函数名称】 onEventRestartRecCb **【函数功能】 重启录音反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventRestartRecCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode != 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]重启录音失败, ErrCode = %d"), pLine->id(), CbCode); } else { pLine->recState() = REC_STATE_ACTIVED; ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: 线路[%d]已重启录音"), pLine->id()); } } /***************************************************************** **【函数名称】 onEventActiveSessionCb **【函数功能】 激活会话反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventActiveSessionCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; ASSERT(SlaverId == m_IprSlaver.nRecSlaverID); if(CbCode == 0) // 会话激活成功 { pLine->isSessionActived() = true; CString RecFile; if(pLine->isReady4Rec(RecFile)) // 已收到录音命令,可以开始录音 __startRecord(pLine, RecFile); else // 尚未收到录音命令,将录音状态置为等待 pLine->recState() = REC_STATE_WAIT; CLineRecordIpra* pLineIpra = __findLineIpraBySessionId(pLine->sessionId()); ASSERT(pLineIpra != NULL); if(pLineIpra == NULL) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]激活会话失败, 未找到关联IPRA线路, Session = %d"), pLine->id(), pLine->sessionId()); return; } CHAR AddrSlaver[IP_PORT_LEN] = { 0 }; sprintf_s(AddrSlaver, _T("%d.%d.%d.%d"), m_IprSlaver.ipAddr.S_un_b.s_b1, m_IprSlaver.ipAddr.S_un_b.s_b2, m_IprSlaver.ipAddr.S_un_b.s_b3, m_IprSlaver.ipAddr.S_un_b.s_b4); if(SsmIPRSendSession(pLineIpra->id(), AddrSlaver, pLine->forwardingPPort(), AddrSlaver, pLine->forwardingSPort()) < 0) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]激活会话时发送会话失败, Cause = %s"), pLine->id(), szErrMsg); } } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]激活会话失败, ErrCode = %d"), pLine->id(), CbCode); } } /***************************************************************** **【函数名称】 onEventDeactiveSessionCb **【函数功能】 去激活会话反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventDeactiveSessionCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; ASSERT(SlaverId == m_IprSlaver.nRecSlaverID); if(CbCode != 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]去激活会话失败, ErrCode = %d"), pLine->id(), CbCode); } } /***************************************************************** **【函数名称】 onEventActiveAndRecCb **【函数功能】 激活会话并录音反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventActiveAndRecCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; ASSERT(SlaverId == m_IprSlaver.nRecSlaverID); if(CbCode == 0) { CLineRecordIpra* pLineIpra = __findLineIpraBySessionId(pLine->sessionId()); ASSERT(pLineIpra != NULL); if(pLineIpra == NULL) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]激活会话并录音失败, 未找到关联IPRA线路, Session = %d"), pLine->id(), pLine->sessionId()); return; } CHAR AddrSlaver[IP_PORT_LEN] = { 0 }; sprintf_s(AddrSlaver, _T("%d.%d.%d.%d"), m_IprSlaver.ipAddr.S_un_b.s_b1, m_IprSlaver.ipAddr.S_un_b.s_b2, m_IprSlaver.ipAddr.S_un_b.s_b3, m_IprSlaver.ipAddr.S_un_b.s_b4); if(SsmIPRSendSession(pLineIpra->id(), AddrSlaver, pLine->forwardingPPort(), AddrSlaver, pLine->forwardingSPort()) < 0) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]激活会话并录音时发送会话失败, Cause = %s"), pLine->id(), szErrMsg); } } else { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]激活会话并录音失败, ErrCode = %d"), pLine->id(), CbCode); } } /***************************************************************** **【函数名称】 onEventDeactiveAndStopRecCb **【函数功能】 去激活停止录音反馈事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventDeactiveAndStopRecCb( CLineRecordIprr* pLine, PSSM_EVENT pEvent ) { int SlaverId = pEvent->dwParam >> 16; int CbCode = pEvent->dwParam & 0xffff; if(CbCode != 0) { ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: 线路[%d]去激活会话并停止录音失败, ErrCode = %d"), pLine->id(), CbCode); } } /***************************************************************** **【函数名称】 onEventMediaSessionStarted **【函数功能】 媒体会话开始事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventMediaSessionStarted( CLineRecordIpra* pLine, PSSM_EVENT pEvent ) { int Protocol = pEvent->dwXtraInfo >> 16; int StationId = pEvent->dwXtraInfo & 0xffff; pIPR_SessionInfo pSessionInfo = (pIPR_SessionInfo)pEvent->pvBuffer; ASSERT(pSessionInfo != NULL); if(Protocol != PTL_AVAYA_H323) return; pLine->stationId() = StationId; pLine->sessionId() = pSessionInfo->dwSessionId; CLineRecordIprr* pLineIprr = __findLineIprrByStationId(StationId); if(pLineIprr == NULL) return; CHAR AddrSlaver[IP_PORT_LEN] = { 0 }; sprintf_s(AddrSlaver, _T("%d.%d.%d.%d"), m_IprSlaver.ipAddr.S_un_b.s_b1, m_IprSlaver.ipAddr.S_un_b.s_b2, m_IprSlaver.ipAddr.S_un_b.s_b3, m_IprSlaver.ipAddr.S_un_b.s_b4); if(SsmIPRActiveSession(pLineIprr->id(), m_IprSlaver.nRecSlaverID, pSessionInfo->dwSessionId, AddrSlaver, 0, &pSessionInfo->nFowardingPPort, pSessionInfo->nPrimaryCodec, AddrSlaver, 0, &pSessionInfo->nFowardingSPort, pSessionInfo->nSecondaryCodec) < 0) { char szErrMsg[DEV_OP_BUF_LEN] = { 0 }; SsmGetLastErrMsg(szErrMsg); ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: IPRA线路[%d]处理媒体会话时激活会话失败, IPRR Line = %d, Cause = %s"), pLine->id(), pLineIprr->id(), szErrMsg); return; } pLineIprr->sessionId() = pSessionInfo->dwSessionId; pLineIprr->forwardingPPort() = pSessionInfo->nFowardingPPort; pLineIprr->forwardingSPort() = pSessionInfo->nFowardingSPort; ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{IprCtrl}: IPRA线路[%d]处理媒体会话时激活会话成功, IPRR Line = %d"), pLine->id(), pLineIprr->id()); } /***************************************************************** **【函数名称】 onEventMediaSessionStoped **【函数功能】 媒体会话结束事件的处理 **【参数】 **【返回值】 ****************************************************************/ void CIprControl::onEventMediaSessionStoped( CLineRecordIpra* pLine, PSSM_EVENT pEvent ) { int Protocol = pEvent->dwXtraInfo >> 16; int StationId = pEvent->dwXtraInfo & 0xffff; pIPR_SessionInfo pSessionInfo = (pIPR_SessionInfo)pEvent->pvBuffer; ASSERT(pSessionInfo != NULL); if(Protocol != PTL_AVAYA_H323) return; pLine->resetRecContext(); CLineRecordIprr* pLineIprr = __findLineIprrByStationId(StationId); if(pLineIprr == NULL) return; if(!__stopRecord(pLineIprr)) ILogger::getInstance().log(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{IprCtrl}: IPRA线路[%d]在媒体会话结束时停止录音失败, IPRR Line = %d"), pLine->id(), pLineIprr->id()); }