Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
6.4 KiB

  1. /*
  2. * File: t120chan.cpp
  3. *
  4. * T.120 implementation of ICommChannel, ICtrlCommChannel
  5. *
  6. * Revision History:
  7. *
  8. * 06/11/97 mikev created
  9. *
  10. */
  11. #include "precomp.h"
  12. ImpT120Chan::ImpT120Chan()
  13. :m_MediaID(MEDIA_TYPE_H323_T120),
  14. m_pCtlChan(NULL),
  15. m_pCapObject(NULL),
  16. m_pH323ConfAdvise(NULL),
  17. m_dwFlags(COMCH_ENABLED),
  18. dwhChannel(0),
  19. uRef(1)
  20. {
  21. ZeroMemory(&local_sin, sizeof(local_sin));
  22. ZeroMemory(&remote_sin, sizeof(remote_sin));
  23. }
  24. ImpT120Chan::~ImpT120Chan ()
  25. {
  26. }
  27. STDMETHODIMP ImpT120Chan::GetMediaType(LPGUID pGuid)
  28. {
  29. if(!pGuid)
  30. return CHAN_E_INVALID_PARAM;
  31. *pGuid = m_MediaID;
  32. return hrSuccess;
  33. }
  34. STDMETHODIMP ImpT120Chan::QueryInterface( REFIID iid, void ** ppvObject)
  35. {
  36. // this breaks the rules for the official COM QueryInterface because
  37. // the interfaces that are queried for are not necessarily real COM
  38. // interfaces. The reflexive property of QueryInterface would be broken in
  39. // that case.
  40. HRESULT hr = E_NOINTERFACE;
  41. if(!ppvObject)
  42. return hr;
  43. *ppvObject = 0;
  44. if(iid == IID_IUnknown)
  45. {
  46. *ppvObject = this;
  47. hr = hrSuccess;
  48. AddRef();
  49. }
  50. else if((iid == IID_ICommChannel))
  51. {
  52. *ppvObject = (ICommChannel *)this;
  53. hr = hrSuccess;
  54. AddRef();
  55. }
  56. else if((iid == IID_ICtrlCommChannel))
  57. {
  58. *ppvObject = (ICtrlCommChan *)this;
  59. hr = hrSuccess;
  60. AddRef();
  61. }
  62. return (hr);
  63. }
  64. ULONG ImpT120Chan::AddRef()
  65. {
  66. uRef++;
  67. return uRef;
  68. }
  69. ULONG ImpT120Chan::Release()
  70. {
  71. uRef--;
  72. if(uRef == 0)
  73. {
  74. delete this;
  75. return 0;
  76. }
  77. else
  78. {
  79. return uRef;
  80. }
  81. }
  82. HRESULT ImpT120Chan::BeginControlSession(IControlChannel *pCtlChan, LPIH323PubCap pCapObject)
  83. {
  84. // this channel is now "in a call".
  85. m_pCtlChan = pCtlChan;
  86. m_pCapObject = pCapObject;
  87. return hrSuccess;
  88. }
  89. HRESULT ImpT120Chan::EndControlSession()
  90. {
  91. // this channel is no longer "in a call".
  92. m_pCtlChan = NULL;
  93. m_pCapObject = NULL;
  94. return hrSuccess;
  95. }
  96. HRESULT ImpT120Chan::OnChannelClose(DWORD dwStatus)
  97. {
  98. HRESULT hr = hrSuccess;
  99. FX_ENTRY("ImpT120Chan::OnChannelClose");
  100. BOOL fCloseAction = FALSE;
  101. SHOW_OBJ_ETIME("ImpT120Chan::OnChannelClose");
  102. m_dwFlags &= ~COMCH_OPEN_PENDING;
  103. switch(dwStatus)
  104. {
  105. default:
  106. ERRORMESSAGE(("%s: unexpected unidirectional notification\r\n", _fx_));
  107. case CHANNEL_CLOSED:
  108. DEBUGMSG(ZONE_COMMCHAN,("%s:closing\r\n",_fx_));
  109. if(IsComchOpen())
  110. {
  111. fCloseAction = TRUE;
  112. m_dwFlags &= ~COMCH_OPEN;
  113. }
  114. else
  115. {
  116. ERRORMESSAGE(("%s: notification when not open\r\n", _fx_));
  117. }
  118. break;
  119. }
  120. // clear general purpose channel handle
  121. dwhChannel = 0;
  122. if(m_pH323ConfAdvise && m_pCtlChan)
  123. {
  124. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
  125. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
  126. }
  127. return hr;
  128. }
  129. HRESULT ImpT120Chan::OnChannelOpening()
  130. {
  131. m_dwFlags |= COMCH_OPEN_PENDING;
  132. return hrSuccess;
  133. }
  134. HRESULT ImpT120Chan::OnChannelOpen(DWORD dwStatus)
  135. {
  136. FX_ENTRY("ImpT120Chan::OnChannelOpen");
  137. SHOW_OBJ_ETIME("ImpICommChan::OnChannelOpen");
  138. // the open is no longer pending, regardless of success or failure
  139. m_dwFlags &= ~COMCH_OPEN_PENDING;
  140. if(IsComchOpen())
  141. {
  142. ERRORMESSAGE(("%s: %d notification when open\r\n", _fx_,
  143. dwStatus));
  144. }
  145. switch(dwStatus)
  146. {
  147. case CHANNEL_OPEN:
  148. m_dwFlags |= (COMCH_OPEN | COMCH_SUPPRESS_NOTIFICATION);
  149. break;
  150. default:
  151. dwStatus = CHANNEL_OPEN_ERROR;
  152. // fall through to notification
  153. case CHANNEL_REJECTED:
  154. case CHANNEL_NO_CAPABILITY:
  155. goto NOTIFICATION;
  156. break;
  157. }
  158. NOTIFICATION:
  159. if(m_pH323ConfAdvise && m_pCtlChan)
  160. {
  161. DEBUGMSG(ZONE_COMMCHAN,("%s:issuing notification 0x%08lX\r\n",_fx_, dwStatus));
  162. m_pH323ConfAdvise->ChannelEvent(this, m_pCtlChan->GetIConnIF(), dwStatus);
  163. }
  164. else
  165. DEBUGMSG(ZONE_COMMCHAN,("%s: *** not issuing notification 0x%08lX m_pH323ConfAdvise: 0x%08lX, m_pCtlChan:0x%08lX \r\n"
  166. ,_fx_, dwStatus,m_pH323ConfAdvise,m_pCtlChan));
  167. SHOW_OBJ_ETIME("ImpT120Chan::OnChannelOpen - done ");
  168. return hrSuccess;
  169. }
  170. BOOL ImpT120Chan::SelectPorts(LPIControlChannel pCtlChannel)
  171. {
  172. PSOCKADDR_IN psin;
  173. HRESULT hr;
  174. hr = pCtlChannel->GetLocalAddress(&psin);
  175. {
  176. if(!HR_SUCCEEDED(hr))
  177. return FALSE;
  178. }
  179. local_sin = *psin;
  180. // HACK uses well known port
  181. local_sin.sin_port = htons(1503);
  182. return TRUE;
  183. }
  184. HRESULT ImpT120Chan::AcceptRemoteAddress (PSOCKADDR_IN pSin)
  185. {
  186. if(!pSin)
  187. return CHAN_E_INVALID_PARAM;
  188. remote_sin = *pSin;
  189. return hrSuccess;
  190. }
  191. STDMETHODIMP ImpT120Chan::GetRemoteAddress(PSOCKADDR_IN pAddrOutput)
  192. {
  193. if (!pAddrOutput)
  194. {
  195. return CHAN_E_INVALID_PARAM;
  196. }
  197. *pAddrOutput = remote_sin;
  198. return hrSuccess;
  199. }
  200. HRESULT ImpT120Chan::EnableOpen(BOOL bEnable)
  201. {
  202. if(bEnable)
  203. {
  204. m_dwFlags |= COMCH_ENABLED;
  205. }
  206. else
  207. {
  208. m_dwFlags &= ~COMCH_ENABLED;
  209. }
  210. return hrSuccess;
  211. }
  212. HRESULT ImpT120Chan::IsChannelOpen(BOOL *pbOpen)
  213. {
  214. if(!pbOpen)
  215. return CHAN_E_INVALID_PARAM;
  216. *pbOpen = (IsComchOpen()) ? TRUE:FALSE;
  217. return hrSuccess;
  218. }
  219. HRESULT ImpT120Chan::Open(MEDIA_FORMAT_ID idLocalFormat, IH323Endpoint *pConnection)
  220. {
  221. HRESULT hr;
  222. IConfAdvise * pConfAdvise = NULL;
  223. if((m_dwFlags & COMCH_OPEN_PENDING) || IsComchOpen() || !pConnection)
  224. return CHAN_E_INVALID_PARAM;
  225. if(!m_pCtlChan) // this channel is not part of a call
  226. {
  227. hr = pConnection->QueryInterface(IID_IConfAdvise, (void **)&pConfAdvise);
  228. if(!HR_SUCCEEDED(hr))
  229. goto EXIT;
  230. hr = pConfAdvise->AddCommChannel(this);
  231. if(!HR_SUCCEEDED(hr))
  232. goto EXIT;
  233. ASSERT(m_pCtlChan && m_pCapObject);
  234. }
  235. // Start the control channel stuff needed to open the channel.
  236. // The media format ID arguments are irrelevant for T.120 channels
  237. hr = m_pCtlChan->OpenChannel((ICtrlCommChan*)this, m_pCapObject,
  238. idLocalFormat, INVALID_MEDIA_FORMAT);
  239. EXIT:
  240. if(pConfAdvise)
  241. pConfAdvise->Release();
  242. return hr;
  243. }
  244. HRESULT ImpT120Chan::Close()
  245. {
  246. HRESULT hr = CHAN_E_INVALID_PARAM;
  247. if(!IsComchOpen() || !m_pCtlChan)
  248. goto EXIT;
  249. hr = m_pCtlChan->CloseChannel((ICtrlCommChan*)this);
  250. EXIT:
  251. return hr;
  252. }
  253. HRESULT ImpT120Chan::SetAdviseInterface(IH323ConfAdvise *pH323ConfAdvise)
  254. {
  255. if (!pH323ConfAdvise)
  256. {
  257. return CHAN_E_INVALID_PARAM;
  258. }
  259. m_pH323ConfAdvise = pH323ConfAdvise;
  260. return hrSuccess;
  261. }