修改三方通话功能,在发起三方通话时,先保持住主叫,然后再拉回主叫到会议

DevIpm.cpp 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "StdAfx.h"
  2. #include "DevIpm.h"
  3. #include "IpmChannel.h"
  4. #include "Config.h"
  5. 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)
  6. {
  7. }
  8. CDevIpm::~CDevIpm(void)
  9. {
  10. }
  11. /*****************************************************************
  12. **【函数名称】 __openMix
  13. **【函数功能】 打开混音器
  14. **【参数】
  15. **【返回值】
  16. ****************************************************************/
  17. bool CDevIpm::__openMix( MIX_TYPE MixTp )
  18. {
  19. if(m_MixCap == MIXCAP_NORMAL)
  20. {
  21. MIX_PARAM set_mix_param;
  22. set_mix_param.ucMixType = MixTp;
  23. memset(set_mix_param.ucUnmixTimeSlot, 0xff, sizeof(set_mix_param.ucUnmixTimeSlot));
  24. return ISX_sr_SetMixParm(m_NodeNo, m_BoardNo, BT_XOIP, &set_mix_param) == 0;
  25. }
  26. return false;
  27. }
  28. /*****************************************************************
  29. **【函数名称】 __checkNetId
  30. **【函数功能】 检索网络标识
  31. **【参数】
  32. **【返回值】
  33. ****************************************************************/
  34. void CDevIpm::__checkNetId( void )
  35. {
  36. TCHAR IpAddr[IP_PORT_LEN] = { 0 };
  37. TCHAR NetMask[IP_PORT_LEN] = { 0 };
  38. ISX_sr_getnet2cfg(m_NodeNo, m_BoardNo, BT_XOIP, IpAddr, NetMask);
  39. BYTE IpA = 0;
  40. BYTE IpB = 0;
  41. BYTE IpC = 0;
  42. BYTE IpD = 0;
  43. BYTE MaskA = 0;
  44. BYTE MaskB = 0;
  45. BYTE MaskC = 0;
  46. BYTE MaskD = 0;
  47. TCHAR* lpNext = NULL;
  48. TCHAR* lpToken = strtok_s(IpAddr, ".", &lpNext);
  49. IpA = atoi(lpToken);
  50. lpToken = strtok_s(NULL, ".", &lpNext);
  51. IpB = atoi(lpToken);
  52. lpToken = strtok_s(NULL, ".", &lpNext);
  53. IpC = atoi(lpToken);
  54. lpToken = strtok_s(NULL, ".", &lpNext);
  55. IpD = atoi(lpToken);
  56. lpNext = NULL;
  57. lpToken = strtok_s(NetMask, ".", &lpNext);
  58. MaskA = atoi(lpToken);
  59. lpToken = strtok_s(NULL, ".", &lpNext);
  60. MaskB = atoi(lpToken);
  61. lpToken = strtok_s(NULL, ".", &lpNext);
  62. MaskC = atoi(lpToken);
  63. lpToken = strtok_s(NULL, ".", &lpNext);
  64. MaskD = atoi(lpToken);
  65. IpA &= MaskA;
  66. IpB &= MaskB;
  67. IpC &= MaskC;
  68. IpD &= MaskD;
  69. // 计算网络标识,和SIP板标识相同的则可以相互服务
  70. m_NetId = IpA;
  71. m_NetId = m_NetId << 8;
  72. m_NetId |= IpB;
  73. m_NetId = m_NetId << 8;
  74. m_NetId |= IpC;
  75. m_NetId = m_NetId << 8;
  76. m_NetId |= IpD;
  77. }
  78. /*****************************************************************
  79. **【函数名称】 getFreeIpmCh
  80. **【函数功能】 获取空闲通道
  81. **【参数】
  82. **【返回值】
  83. ****************************************************************/
  84. CIpmChannel* CDevIpm::getFreeIpmCh( void )
  85. {
  86. CSingleLock locker(&m_LockSection);
  87. locker.Lock(); // 本操作需锁定
  88. for(int i = 0; i < m_IpmChList.GetCount(); ++i) // 保证遍历一轮
  89. {
  90. if(m_CurPos >= m_IpmChList.GetCount())
  91. m_CurPos = 0;
  92. CIpmChannel* pChannel = m_IpmChList[m_CurPos++];
  93. ASSERT(pChannel != NULL);
  94. // 当前是否空闲
  95. if(pChannel->isValid() && pChannel->isFree())
  96. return pChannel;
  97. }
  98. return NULL;
  99. }
  100. /*****************************************************************
  101. **【函数名称】 findChan
  102. **【函数功能】 查找指定资源
  103. **【参数】
  104. **【返回值】
  105. ****************************************************************/
  106. CIpmChannel* CDevIpm::findChan( int ResId )
  107. {
  108. if(ResId < 0 || ResId >= m_IpmChList.GetCount())
  109. return NULL;
  110. else
  111. return m_IpmChList[ResId];
  112. }
  113. /*****************************************************************
  114. **【函数名称】 open
  115. **【函数功能】 IPM设备打开函数
  116. **【参数】
  117. **【返回值】
  118. ****************************************************************/
  119. bool CDevIpm::open( void )
  120. {
  121. if(m_state != STATUS_WORKING || m_IpmChList.GetCount() > 0)
  122. return false;
  123. SPEC_CAP spec_cap;
  124. if(ISX_sr_GetSpecCap(m_NodeNo, m_BoardNo, BT_XOIP, &spec_cap) == 0)
  125. m_MixCap = (MIX_CAP)spec_cap.Xoip.ucMixCap;
  126. if(!__openMix(MIXTYPE_RPBOTH))
  127. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_WARNING, _T("{DevIpm}: IPM[%d-%d]混音打开失败"), m_NodeNo, m_BoardNo);
  128. m_CurPos = 0;
  129. for(int i = 0; i < m_Capacity; ++i)
  130. {
  131. CIpmChannel* pChannel = new CIpmChannel(i, m_NodeNo, m_BoardNo);
  132. ASSERT(pChannel != NULL);
  133. if(pChannel != NULL)
  134. {
  135. if(pChannel->open())
  136. {
  137. m_IpmChList.Add(pChannel);
  138. CMC::GetInstance().onDevResCreate(pChannel->id());
  139. }
  140. else
  141. delete pChannel;
  142. }
  143. }
  144. __checkNetId();
  145. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevIpm}: IPM[%d-%d]成功打开%d条IPM通道"), m_NodeNo, m_BoardNo, m_IpmChList.GetCount());
  146. return true;
  147. }
  148. /*****************************************************************
  149. **【函数名称】 close
  150. **【函数功能】 IPM设备关闭函数
  151. **【参数】
  152. **【返回值】
  153. ****************************************************************/
  154. void CDevIpm::close( void )
  155. {
  156. __openMix(MIXTYPE_NULL);
  157. for(int i = 0; i < m_IpmChList.GetCount(); ++i)
  158. {
  159. CIpmChannel* pChannel = m_IpmChList[i];
  160. ASSERT(pChannel != NULL);
  161. CMC::GetInstance().onDevResDestroy(pChannel->id());
  162. pChannel->close();
  163. delete pChannel;
  164. }
  165. m_IpmChList.RemoveAll();
  166. m_CurPos = 0;
  167. LOGGER(LOG_CLASS_DEV, LOG_LEVEL_NORMAL, _T("{DevIpm}: IPM[%d-%d]通道全部关闭"), m_NodeNo, m_BoardNo);
  168. }
  169. /*****************************************************************
  170. **【函数名称】 isOk
  171. **【函数功能】 判断设备状态
  172. **【参数】
  173. **【返回值】
  174. ****************************************************************/
  175. bool CDevIpm::isOk( void ) const
  176. {
  177. return (m_state == STATUS_WORKING && m_IpmChList.GetCount() == m_Capacity);
  178. }