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

ConsultCallReq.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #include "StdAfx.h"
  2. #include "ConsultCallReq.h"
  3. #include "VirtualProxy.h"
  4. #include "SessionShell.h"
  5. #include "ProxyShell.h"
  6. #include "MC.h"
  7. CConsultCallReq::CConsultCallReq(CProxyShell* pParent, CPduEntity& ReqPdu) : CReqBase(pParent, ReqPdu), m_pAssoLine(NULL),
  8. m_PendingCallId(0), m_PeerLineType(DEV_RES_TYPE_EXT), m_Step(0), m_SipAccountId(INVALID_ID_SIP_ACCOUNT)
  9. {
  10. }
  11. CConsultCallReq::~CConsultCallReq(void)
  12. {
  13. }
  14. /*****************************************************************
  15. **【函数名称】 __pause
  16. **【函数功能】 当前操作阶段性完成,操作暂停并返回
  17. **【参数】 IsSucceed 阶段操作是否成功
  18. **【返回值】
  19. ****************************************************************/
  20. void CConsultCallReq::__pause( bool IsSucceed )
  21. {
  22. m_Step = 1;
  23. // 阶段完成日志
  24. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{LineReq}: 分机[%lu]协商呼叫目标线路成功, DestNum = %s"),
  25. m_pHostLine->lineId(), m_CalleeNum);
  26. // 返回第一阶段执行结果
  27. m_pParent->notifyReqResult(m_ReqPdu, m_InstanceCall, IsSucceed);
  28. }
  29. /*****************************************************************
  30. **【函数名称】 request
  31. **【函数功能】 发出请求(命令方式)
  32. **【参数】
  33. **【返回值】
  34. ****************************************************************/
  35. bool CConsultCallReq::request( void )
  36. {
  37. // 校验状态
  38. if(m_pHostLine->state() != VIRTUAL_LINE_STATE_TALKING)
  39. return false;
  40. // 保存主被叫信息
  41. CString CallerNum = m_ReqPdu.GetDataString(4);
  42. m_CalleeNum = m_ReqPdu.GetDataString(3);
  43. // 根据被叫号码查找对端线路且修正被叫号码
  44. m_pAssoLine = m_pParent->setEnv4Calling(CallerNum, m_CalleeNum, m_PeerLineType, m_SipAccountId);
  45. if(m_pAssoLine == NULL)
  46. {
  47. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{LineReq}: 分机[%lu]协商呼叫失败, 查找关联线路失败, DestNum = %s"),
  48. m_pHostLine->lineId(), m_CalleeNum);
  49. return false;
  50. } // end if
  51. if(m_pAssoLine->type() == DEV_RES_TYPE_EXT)
  52. CallerNum = m_pHostLine->callerNum();
  53. // 通知启动日志
  54. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{LineReq}: 分机[%lu]协商呼叫, DestNum = %s"), m_pHostLine->lineId(), m_CalleeNum);
  55. // 启动分机协商呼叫操作
  56. PendingCallInfo info;
  57. memset(&info, 0, sizeof(PendingCallInfo));
  58. info.nCall = m_pHostLine->activeCallId();
  59. info.nHostLine = m_pHostLine->devId();
  60. info.nAssoLine = m_pAssoLine->devId();
  61. lstrcpy(info.szCallerNum, CallerNum);
  62. lstrcpy(info.szCalleeNum, m_CalleeNum);
  63. lstrcpy(info.szPreCallerNum, m_pHostLine->callerNum());
  64. lstrcpy(info.szPreCalleeNum, m_pHostLine->calleeNum());
  65. info.nCallType = PENDING_CALL_CONSULT;
  66. info.nHostLineStatus = VIRTUAL_LINE_STATE_TALKING;
  67. info.nSipAccountId = m_SipAccountId;
  68. return CSessionShell::GetInstance().procReqDialSetup(m_PendingCallId, &info);
  69. }
  70. /*****************************************************************
  71. **【函数名称】 hangUp
  72. **【函数功能】 操作中挂机(命令方式)
  73. **【参数】
  74. **【返回值】
  75. ****************************************************************/
  76. bool CConsultCallReq::hangUp( long InstanceHangUp )
  77. {
  78. // 协商呼叫取消日志
  79. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{LineReq}: 分机[%lu]协商呼叫因挂机取消, DestNum = %s"),
  80. m_pHostLine->lineId(), m_CalleeNum);
  81. m_InstanceCancel = InstanceHangUp;
  82. return CMC::GetInstance().dropCall(m_pAssoLine->devId(), false);
  83. }
  84. /*****************************************************************
  85. **【函数名称】 resume
  86. **【函数功能】 继续执行当前操作
  87. **【参数】 InstanceResume 调用标识
  88. Data 关联信息 0 -> 转移,1 -> 三方
  89. **【返回值】
  90. *****************************************************************/
  91. bool CConsultCallReq::resume( long InstanceResume, int Data )
  92. {
  93. if(InstanceResume != m_InstanceCall || m_Step != 1)
  94. return false;
  95. // 协商呼叫确认
  96. if(CSessionShell::GetInstance().procReqConsultConfirm(m_pHostLine->activeCallId(), m_pHostLine->devId(), m_pAssoLine->devId(), Data))
  97. {
  98. end(true, NULL);
  99. }
  100. else
  101. {
  102. CMC::GetInstance().dropCall(m_pAssoLine->devId(), false);
  103. } // end if
  104. return true;
  105. }
  106. /*****************************************************************
  107. **【函数名称】 end
  108. **【函数功能】 操作完成
  109. **【参数】 IsSucceed 操作是否成功
  110. lpData 随路数据
  111. **【返回值】
  112. ****************************************************************/
  113. void CConsultCallReq::end( bool IsSucceed, LPCTSTR lpData )
  114. {
  115. if(IsSucceed)
  116. {
  117. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{LineReq}: 分机[%lu]协商呼叫成功, DestNum = %s"), m_pHostLine->lineId(), m_CalleeNum);
  118. }
  119. else
  120. {
  121. if(m_Step == 0)
  122. {
  123. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{LineReq}: 分机[%lu]协商呼叫失败, DestNum = %s"),
  124. m_pHostLine->lineId(), m_CalleeNum);
  125. }
  126. else
  127. {
  128. LOGGER(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{LineReq}: 分机[%lu]协商呼叫取消, DestNum = %s"),
  129. m_pHostLine->lineId(), m_CalleeNum);
  130. }
  131. } // end if
  132. // 返回执行结果
  133. if(m_InstanceCancel != 0)
  134. {
  135. m_pParent->notifyReqResult(m_ReqPdu, m_InstanceCancel, !IsSucceed, lpData);
  136. } // end if
  137. m_pParent->onLineReqEnd(this, IsSucceed, lpData);
  138. }
  139. /*****************************************************************
  140. **【函数名称】 onDevChEvent
  141. **【函数功能】 线路向上层发送的设备主动事件
  142. **【参数】 pEventLine 触发事件的线路
  143. EvtType 事件类型
  144. lpContent 事件内容
  145. **【返回值】
  146. *****************************************************************/
  147. void CConsultCallReq::onDevChEvent( CVirtualProxy* pEventLine, DEV_CH_EVT_TYPE EvtType, LPCTSTR lpContent )
  148. {
  149. }
  150. /*****************************************************************
  151. **【函数名称】 onLineStateChanged
  152. **【函数功能】 线路状态变化事件响应接口
  153. **【参数】 pEventLine 状态变化的线路实体指针
  154. LineState 线路当前状态
  155. Call 主呼叫ID
  156. SubCall 子呼叫ID
  157. lpCallerNum 主叫号码
  158. lpCalleeNum 被叫号码
  159. **【返回值】
  160. ****************************************************************/
  161. void CConsultCallReq::onLineStateChanged( CVirtualProxy* pEventLine, VIRTUAL_LINE_STATE LineState, long Call, long SubCall, LPCTSTR lpCallerNum, LPCTSTR lpCalleeNum )
  162. {
  163. // 协商呼叫主控方挂机
  164. if(SubCall == SESSION_INVALID_SUB_CALL && LineState == VIRTUAL_LINE_STATE_FREE)
  165. {
  166. CMC::GetInstance().dropCall(m_pAssoLine->devId(), false);
  167. } // end if
  168. // 根据子会话状态进行分类处理
  169. switch(LineState)
  170. {
  171. case VIRTUAL_LINE_STATE_RING_BACK: // 呼叫进展
  172. {
  173. // 只处理子会话事件
  174. if(SubCall == m_PendingCallId)
  175. _notifyOpProcess(m_pHostLine->lineId(), m_pAssoLine->lineId(), m_PeerLineType, lpCallerNum, lpCalleeNum);
  176. }
  177. break;
  178. case VIRTUAL_LINE_STATE_FREE: // 协商呼叫失败
  179. {
  180. end(false, NULL);
  181. }
  182. break;
  183. case VIRTUAL_LINE_STATE_TALKING: // 被叫已接通
  184. {
  185. // 只处理子会话事件
  186. if(SubCall == m_PendingCallId)
  187. __pause(true);
  188. }
  189. break;
  190. } // end switch
  191. }