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

TransferReq.cpp 5.4KB

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