hd

Session.cpp 7.1KB

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