#include "StdAfx.h" #include "DevIpm.h" #include "IpmChannel.h" #include "Config.h" CDevIpm::CDevIpm(DEV_RES_NO_TYPE NodeNo, DEV_RES_NO_TYPE BoardNo) : CDevResource(NodeNo, BoardNo), m_MixCap(MIXCAP_NON), m_CurPos(0), m_NetId(0) { } CDevIpm::~CDevIpm(void) { } /***************************************************************** **【函数名称】 __openMix **【函数功能】 打开混音器 **【参数】 **【返回值】 ****************************************************************/ bool CDevIpm::__openMix( MIX_TYPE MixTp ) { if(m_MixCap == MIXCAP_NORMAL) { MIX_PARAM set_mix_param; set_mix_param.ucMixType = MixTp; memset(set_mix_param.ucUnmixTimeSlot, 0xff, sizeof(set_mix_param.ucUnmixTimeSlot)); return ISX_sr_SetMixParm(m_NodeNo, m_BoardNo, BT_XOIP, &set_mix_param) == 0; } return false; } /***************************************************************** **【函数名称】 __checkNetId **【函数功能】 检索网络标识 **【参数】 **【返回值】 ****************************************************************/ void CDevIpm::__checkNetId( void ) { TCHAR IpAddr[IP_PORT_LEN] = { 0 }; TCHAR NetMask[IP_PORT_LEN] = { 0 }; ISX_sr_getnet2cfg(m_NodeNo, m_BoardNo, BT_XOIP, IpAddr, NetMask); BYTE IpA = 0; BYTE IpB = 0; BYTE IpC = 0; BYTE IpD = 0; BYTE MaskA = 0; BYTE MaskB = 0; BYTE MaskC = 0; BYTE MaskD = 0; TCHAR* lpNext = NULL; TCHAR* lpToken = strtok_s(IpAddr, ".", &lpNext); IpA = atoi(lpToken); lpToken = strtok_s(NULL, ".", &lpNext); IpB = atoi(lpToken); lpToken = strtok_s(NULL, ".", &lpNext); IpC = atoi(lpToken); lpToken = strtok_s(NULL, ".", &lpNext); IpD = atoi(lpToken); lpNext = NULL; lpToken = strtok_s(NetMask, ".", &lpNext); MaskA = atoi(lpToken); lpToken = strtok_s(NULL, ".", &lpNext); MaskB = atoi(lpToken); lpToken = strtok_s(NULL, ".", &lpNext); MaskC = atoi(lpToken); lpToken = strtok_s(NULL, ".", &lpNext); MaskD = atoi(lpToken); IpA &= MaskA; IpB &= MaskB; IpC &= MaskC; IpD &= MaskD; // 计算网络标识,和SIP板标识相同的则可以相互服务 m_NetId = IpA; m_NetId = m_NetId << 8; m_NetId |= IpB; m_NetId = m_NetId << 8; m_NetId |= IpC; m_NetId = m_NetId << 8; m_NetId |= IpD; } /***************************************************************** **【函数名称】 getFreeIpmCh **【函数功能】 获取空闲通道 **【参数】 **【返回值】 ****************************************************************/ CIpmChannel* CDevIpm::getFreeIpmCh( void ) { CSingleLock locker(&m_LockSection); locker.Lock(); // 本操作需锁定 for(int i = 0; i < m_IpmChList.GetCount(); ++i) // 保证遍历一轮 { if(m_CurPos >= m_IpmChList.GetCount()) m_CurPos = 0; CIpmChannel* pChannel = m_IpmChList[m_CurPos++]; ASSERT(pChannel != NULL); // 当前是否空闲 if(pChannel->isValid() && pChannel->isFree()) return pChannel; } return NULL; } /***************************************************************** **【函数名称】 findChan **【函数功能】 查找指定资源 **【参数】 **【返回值】 ****************************************************************/ CIpmChannel* CDevIpm::findChan( int ResId ) { if(ResId < 0 || ResId >= m_IpmChList.GetCount()) return NULL; else return m_IpmChList[ResId]; } /***************************************************************** **【函数名称】 open **【函数功能】 IPM设备打开函数 **【参数】 **【返回值】 ****************************************************************/ bool CDevIpm::open( void ) { if(m_state != STATUS_WORKING || m_IpmChList.GetCount() > 0) return false; SPEC_CAP spec_cap; if(ISX_sr_GetSpecCap(m_NodeNo, m_BoardNo, BT_XOIP, &spec_cap) == 0) m_MixCap = (MIX_CAP)spec_cap.Xoip.ucMixCap; if(!__openMix(MIXTYPE_RPBOTH)) LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{DevIpm}: IPM[%d-%d]混音打开失败"), m_NodeNo, m_BoardNo); m_CurPos = 0; for(int i = 0; i < m_Capacity; ++i) { CIpmChannel* pChannel = new CIpmChannel(i, m_NodeNo, m_BoardNo); ASSERT(pChannel != NULL); if(pChannel != NULL) { if(pChannel->open()) { m_IpmChList.Add(pChannel); CMC::GetInstance().onDevResCreate(pChannel->id()); } else delete pChannel; } } __checkNetId(); LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevIpm}: IPM[%d-%d]成功打开%d条IPM通道"), m_NodeNo, m_BoardNo, m_IpmChList.GetCount()); return true; } /***************************************************************** **【函数名称】 close **【函数功能】 IPM设备关闭函数 **【参数】 **【返回值】 ****************************************************************/ void CDevIpm::close( void ) { __openMix(MIXTYPE_NULL); for(int i = 0; i < m_IpmChList.GetCount(); ++i) { CIpmChannel* pChannel = m_IpmChList[i]; ASSERT(pChannel != NULL); CMC::GetInstance().onDevResDestroy(pChannel->id()); pChannel->close(); delete pChannel; } m_IpmChList.RemoveAll(); m_CurPos = 0; LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevIpm}: IPM[%d-%d]通道全部关闭"), m_NodeNo, m_BoardNo); } /***************************************************************** **【函数名称】 isOk **【函数功能】 判断设备状态 **【参数】 **【返回值】 ****************************************************************/ bool CDevIpm::isOk( void ) const { return (m_state == STATUS_WORKING && m_IpmChList.GetCount() == m_Capacity); }