中航光电的中间件仓库

Session.cpp 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include "StdAfx.h"
  2. #include "Session.h"
  3. #include "FsProxy.h"
  4. #include "ChanExten.h"
  5. #include "ChanTrunk.h"
  6. CSession::CSession(CFsProxy* pParent, LPCTSTR Id) : m_pParent(pParent), m_Id(Id)
  7. {
  8. }
  9. CSession::~CSession(void)
  10. {
  11. }
  12. /*****************************************************************
  13. **【函数名称】 __getChan
  14. **【函数功能】 获取指定通道
  15. **【参数】
  16. **【返回值】
  17. *****************************************************************/
  18. CVirtualChan* CSession::__getChan(LPCTSTR ChanId)
  19. {
  20. std::lock_guard<std::mutex> lock(m_LockChan);
  21. POSITION Pos = m_ListChan.GetHeadPosition();
  22. while (Pos != NULL)
  23. {
  24. CVirtualChan* pChan = m_ListChan.GetNext(Pos);
  25. ASSERT(pChan != NULL);
  26. if (pChan != NULL)
  27. {
  28. if (lstrcmp(pChan->chanId(), ChanId) == 0)
  29. return pChan;
  30. }
  31. }
  32. return NULL;
  33. }
  34. /*****************************************************************
  35. **【函数名称】 __findChan
  36. **【函数功能】 查找通道
  37. **【参数】
  38. **【返回值】
  39. *****************************************************************/
  40. CVirtualChan* CSession::__findChan(PCHAN_EVENT_NOTIFY pNotify)
  41. {
  42. CVirtualChan* pChan = NULL;
  43. if (pNotify->EventId == CHANNEL_EVENT_CREATE)
  44. {
  45. UINT ExtenNo = 0;
  46. if (pNotify->Direction == CALL_DIRECTION_INBOUND)
  47. sscanf_s(pNotify->Caller, "%u", &ExtenNo); // 呼入FS
  48. else
  49. sscanf_s(pNotify->Callee, "%u", &ExtenNo); // FS呼出
  50. pChan = m_pParent->getExten(ExtenNo);
  51. if (pChan == NULL) // 分机通道中无,则说明是中继通道
  52. {
  53. pChan = m_pParent->getFreeTrunk();
  54. if (pChan == NULL)
  55. {
  56. LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session}: 处理通道事件时获取空闲中继通道失败, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee);
  57. m_pParent->onChanPoor(this, pNotify);
  58. }
  59. }
  60. }
  61. else
  62. {
  63. pChan = m_pParent->getBusyChan(pNotify->ChanId);
  64. }
  65. return pChan;
  66. }
  67. /*****************************************************************
  68. **【函数名称】 __addChan
  69. **【函数功能】 添加指定通道
  70. **【参数】
  71. **【返回值】
  72. *****************************************************************/
  73. void CSession::__addChan(CVirtualChan* pChan)
  74. {
  75. std::lock_guard<std::mutex> lock(m_LockChan);
  76. m_ListChan.AddTail(pChan);
  77. }
  78. /*****************************************************************
  79. **【函数名称】 __delChan
  80. **【函数功能】 删除指定通道
  81. **【参数】
  82. **【返回值】
  83. *****************************************************************/
  84. void CSession::__delChan(CVirtualChan* pChan)
  85. {
  86. std::lock_guard<std::mutex> lock(m_LockChan);
  87. POSITION Pos = m_ListChan.Find(pChan);
  88. if (Pos != NULL)
  89. m_ListChan.RemoveAt(Pos);
  90. }
  91. /*****************************************************************
  92. **【函数名称】 __clearChan
  93. **【函数功能】 清空通道
  94. **【参数】
  95. **【返回值】
  96. *****************************************************************/
  97. void CSession::__clearChan(void)
  98. {
  99. std::lock_guard<std::mutex> lock(m_LockChan);
  100. m_ListChan.RemoveAll();
  101. }
  102. /*****************************************************************
  103. **【函数名称】 __notifySessionChanEvent
  104. **【函数功能】 通知会话关联通道事件处理
  105. **【参数】
  106. **【返回值】
  107. *****************************************************************/
  108. void CSession::__notifySessionChanEvent(CVirtualChan* pChanHost, PCHAN_EVENT_NOTIFY pNotify)
  109. {
  110. std::lock_guard<std::mutex> lock(m_LockChan);
  111. POSITION Pos = m_ListChan.GetHeadPosition();
  112. while (Pos != NULL)
  113. {
  114. CVirtualChan* pChanInSession = m_ListChan.GetNext(Pos);
  115. ASSERT(pChanInSession != NULL);
  116. if (pChanInSession != pChanHost)
  117. pChanInSession->onSessionChanEvent(pChanHost, pNotify);
  118. }
  119. }
  120. /*****************************************************************
  121. **【函数名称】 __onChanFree
  122. **【函数功能】 通道空闲的处理函数
  123. **【参数】
  124. **【返回值】
  125. *****************************************************************/
  126. void CSession::__onChanFree(CVirtualChan* pChan, PCHAN_EVENT_NOTIFY pNotify)
  127. {
  128. if (m_Id == pNotify->ChanId) // 若会话主通道空闲则清空会话
  129. __clearChan();
  130. else
  131. __delChan(pChan);
  132. if (pChan->isVoid()) // 若通道已被丢弃,则删除
  133. m_pParent->delChan(pChan);
  134. }
  135. /*****************************************************************
  136. **【函数名称】 prepare
  137. **【函数功能】 会话准备
  138. **【参数】
  139. **【返回值】
  140. *****************************************************************/
  141. void CSession::prepare(PCHAN_EVENT_NOTIFY pNotify)
  142. {
  143. if (m_Id != pNotify->ChanId) // 触发会话的通道不是会话主通道,则查找并添加主通道
  144. {
  145. CVirtualChan* pChan = m_pParent->getBusyChan(m_Id);
  146. if (pChan != NULL)
  147. __addChan(pChan);
  148. }
  149. }
  150. /*****************************************************************
  151. **【函数名称】 onChanEvent
  152. **【函数功能】 通道事件处理
  153. **【参数】
  154. **【返回值】
  155. *****************************************************************/
  156. void CSession::onChanEvent(PCHAN_EVENT_NOTIFY pNotify)
  157. {
  158. ASSERT(pNotify != NULL);
  159. if (pNotify == NULL)
  160. return;
  161. CVirtualChan* pChan = __getChan(pNotify->ChanId);
  162. if (pChan == NULL)
  163. {
  164. pChan = __findChan(pNotify);
  165. if (pChan != NULL)
  166. __addChan(pChan);
  167. else
  168. {
  169. LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session}: 处理通道事件时查找对应通道失败, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee);
  170. return;
  171. }
  172. }
  173. //LOGGER(LOG_LEVEL_NORMAL, _T("{Fs.Session}: 处理通道事件,EventId=%d,ChanId=%s,CallId=%s,Caller = %s, Callee = %s,ChanState=%d"), pNotify->EventId, pNotify->ChanId, pNotify->CallId, pNotify->Caller, pNotify->Callee, pChan->state());
  174. __try
  175. {
  176. pChan->onChanEvent(pNotify);
  177. }
  178. __except (EXCEPTION_EXECUTE_HANDLER)
  179. {
  180. LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session.onChanEvent}: 处理通道事件时发生异常, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee);
  181. return;
  182. }
  183. // 过滤无效状态
  184. if (pChan->state() == CHAN_LOGIC_STATE_FREE && pNotify->EventId == CHANNEL_EVENT_CREATE)
  185. return;
  186. __try
  187. {
  188. __notifySessionChanEvent(pChan, pNotify);
  189. }
  190. __except (EXCEPTION_EXECUTE_HANDLER)
  191. {
  192. LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session.onChanEvent}: 通知会话关联通道事件处理发生异常, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee);
  193. return;
  194. }
  195. __try
  196. {
  197. if (pChan->isFree())
  198. __onChanFree(pChan, pNotify);
  199. }
  200. __except (EXCEPTION_EXECUTE_HANDLER)
  201. {
  202. LOGGER(LOG_LEVEL_WARNING, _T("{Fs.Session.onChanEvent}: 通道空闲处理函数执行发生异常, Caller = %s, Callee = %s"), pNotify->Caller, pNotify->Callee);
  203. return;
  204. }
  205. }
  206. /*****************************************************************
  207. **【函数名称】 onChanDtmf
  208. **【函数功能】 通道DTMF事件处理
  209. **【参数】
  210. **【返回值】
  211. *****************************************************************/
  212. void CSession::onChanDtmf(PDTMF_NOTIFY pNotify)
  213. {
  214. CVirtualChan* pChan = __getChan(pNotify->ChanId);
  215. if (pChan != NULL)
  216. {
  217. pChan->onChanDtmf(pNotify->DTMF);
  218. }
  219. }
  220. /*****************************************************************
  221. **【函数名称】 onChanHold
  222. **【函数功能】 通道保持事件处理
  223. **【参数】
  224. **【返回值】
  225. *****************************************************************/
  226. void CSession::onChanHold(PHOLD_NOTIFY pNotify)
  227. {
  228. CVirtualChan* pChan = __getChan(pNotify->ChanId);
  229. if (pChan != NULL)
  230. {
  231. pChan->onChanHold(pNotify->EvtType);
  232. }
  233. }
  234. /*****************************************************************
  235. **【函数名称】 getAssoChan
  236. **【函数功能】 获取关联通道
  237. **【参数】
  238. **【返回值】
  239. *****************************************************************/
  240. CVirtualChan* CSession::getAssoChan(CVirtualChan* pChan)
  241. {
  242. std::lock_guard<std::mutex> lock(m_LockChan);
  243. POSITION Pos = m_ListChan.GetHeadPosition();
  244. while (Pos != NULL)
  245. {
  246. CVirtualChan* pChanInSession = m_ListChan.GetNext(Pos);
  247. ASSERT(pChanInSession != NULL);
  248. if (pChanInSession != pChan)
  249. return pChanInSession;
  250. }
  251. return NULL;
  252. }