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.

868 lines
31 KiB

  1. #include "stdafx.h"
  2. #include "portmgmt.h"
  3. #include "timerval.h"
  4. #include "cbridge.h"
  5. #include "main.h"
  6. // destructor
  7. // virtual
  8. RTP_LOGICAL_CHANNEL::~RTP_LOGICAL_CHANNEL (void)
  9. {
  10. // close NAT mappings
  11. CloseNATMappings();
  12. // release reference to any associated channel or allocated ports
  13. ReleaseAssociationAndPorts();
  14. }
  15. /*++
  16. Release ports only if there is no associated channel. If there is an
  17. associated channel the ports will be freed when it is deleted. Note that
  18. a logical channel could be closed and reopened again.
  19. --*/
  20. inline void
  21. RTP_LOGICAL_CHANNEL::ReleaseAssociationAndPorts()
  22. {
  23. // if there is an associated logical channel
  24. if (NULL != m_pAssocLogicalChannel)
  25. {
  26. // release reference to it
  27. m_pAssocLogicalChannel->ResetAssociationRef();
  28. m_pAssocLogicalChannel = NULL;
  29. }
  30. else
  31. {
  32. if (m_OwnSourceRecvRTPPort != 0)
  33. PortPoolFreeRTPPort(m_OwnSourceRecvRTPPort);
  34. if (m_OwnAssocLCRecvRTPPort != 0)
  35. PortPoolFreeRTPPort(m_OwnAssocLCRecvRTPPort);
  36. if (m_OwnDestSendRTPPort != 0)
  37. PortPoolFreeRTPPort(m_OwnDestSendRTPPort);
  38. if (m_OwnAssocLCSendRTPPort != 0)
  39. PortPoolFreeRTPPort(m_OwnAssocLCSendRTPPort);
  40. m_OwnSourceRecvRTPPort = m_OwnSourceRecvRTCPPort = 0;
  41. m_OwnAssocLCRecvRTPPort = m_OwnDestRecvRTCPPort = 0;
  42. m_OwnDestSendRTPPort = m_OwnDestSendRTCPPort = 0;
  43. m_OwnAssocLCSendRTPPort = m_OwnSourceSendRTCPPort = 0;
  44. }
  45. }
  46. /*++
  47. This function is called after the OLC is received.
  48. --*/
  49. HRESULT
  50. RTP_LOGICAL_CHANNEL::SetPorts (void)
  51. {
  52. HRESULT HResult = E_FAIL;
  53. // if there is an associated LC, copy all the ports from that LC.
  54. // else, allocate them now
  55. if (NULL != m_pAssocLogicalChannel)
  56. {
  57. // tell the associated logical channel that we are associated
  58. // with it
  59. m_pAssocLogicalChannel->SetAssociationRef(*this);
  60. // save the associated channel's own source/dest ports
  61. // assoc channel's source ports become our dest ports and vice versa
  62. m_OwnDestRecvRTCPPort = m_pAssocLogicalChannel->m_OwnSourceRecvRTCPPort;
  63. m_OwnSourceRecvRTCPPort = m_pAssocLogicalChannel->m_OwnDestRecvRTCPPort;
  64. m_OwnDestSendRTCPPort = m_pAssocLogicalChannel->m_OwnSourceSendRTCPPort;
  65. m_OwnSourceSendRTCPPort = m_pAssocLogicalChannel->m_OwnDestSendRTCPPort;
  66. // Copy the RTP ports
  67. m_OwnSourceRecvRTPPort = m_pAssocLogicalChannel->m_OwnAssocLCRecvRTPPort;
  68. m_OwnAssocLCRecvRTPPort = m_pAssocLogicalChannel->m_OwnSourceRecvRTPPort;
  69. m_OwnDestSendRTPPort = m_pAssocLogicalChannel->m_OwnAssocLCSendRTPPort;
  70. m_OwnAssocLCSendRTPPort = m_pAssocLogicalChannel->m_OwnDestSendRTPPort;
  71. }
  72. else
  73. {
  74. // allocate own ports - the portmgt apis return an even port only (RTP)
  75. // and the assumption is that the RTCP port = RTP port + 1
  76. // however, we use the odd port for receiving RTCP and the even
  77. // port for sending RTP
  78. HResult = PortPoolAllocRTPPort (&m_OwnSourceRecvRTPPort);
  79. if (FAILED(HResult))
  80. {
  81. DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts")
  82. _T("failed to allocate m_OwnSourceRecvRTPPort, returning 0x%x\n"),
  83. HResult);
  84. goto cleanup;
  85. }
  86. m_OwnSourceRecvRTCPPort = m_OwnSourceRecvRTPPort + 1;
  87. HResult = PortPoolAllocRTPPort (&m_OwnAssocLCRecvRTPPort);
  88. if (FAILED(HResult))
  89. {
  90. DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts")
  91. _T("failed to allocate m_OwnAssocLCRecvRTPPort, returning 0x%x\n"),
  92. HResult);
  93. goto cleanup;
  94. }
  95. m_OwnDestRecvRTCPPort = m_OwnAssocLCRecvRTPPort + 1;
  96. HResult = PortPoolAllocRTPPort (&m_OwnDestSendRTPPort);
  97. if (FAILED(HResult))
  98. {
  99. DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts")
  100. _T("failed to allocate m_OwnDestSendRTPPort, returning 0x%x\n"),
  101. HResult);
  102. goto cleanup;
  103. }
  104. m_OwnDestSendRTCPPort = m_OwnDestSendRTPPort + 1;
  105. HResult = PortPoolAllocRTPPort (&m_OwnAssocLCSendRTPPort);
  106. if (FAILED(HResult))
  107. {
  108. DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts, ")
  109. _T("failed to allocate m_OwnAssocLCSendRTPPort, returning 0x%x\n"),
  110. HResult);
  111. goto cleanup;
  112. }
  113. m_OwnSourceSendRTCPPort = m_OwnAssocLCSendRTPPort + 1;
  114. }
  115. DebugF (_T("RTP : 0x%x using ports %04X, %04X, %04X, %04X.\n"),
  116. &GetCallBridge (),
  117. m_OwnSourceRecvRTPPort, m_OwnAssocLCRecvRTPPort,
  118. m_OwnDestSendRTPPort, m_OwnAssocLCSendRTPPort);
  119. DebugF (_T("RTCP: 0x%x using ports %04X, %04X, %04X, %04X.\n"),
  120. &GetCallBridge (),
  121. m_OwnSourceRecvRTCPPort, m_OwnDestRecvRTCPPort,
  122. m_OwnDestSendRTCPPort, m_OwnSourceSendRTCPPort);
  123. return S_OK;
  124. cleanup:
  125. if (m_OwnSourceRecvRTPPort != 0)
  126. PortPoolFreeRTPPort(m_OwnSourceRecvRTPPort);
  127. if (m_OwnAssocLCRecvRTPPort != 0)
  128. PortPoolFreeRTPPort(m_OwnAssocLCRecvRTPPort);
  129. if (m_OwnDestSendRTPPort != 0)
  130. PortPoolFreeRTPPort(m_OwnDestSendRTPPort);
  131. if (m_OwnAssocLCSendRTPPort != 0)
  132. PortPoolFreeRTPPort(m_OwnAssocLCSendRTPPort);
  133. m_OwnSourceRecvRTPPort = m_OwnSourceRecvRTCPPort = 0;
  134. m_OwnAssocLCRecvRTPPort = m_OwnDestRecvRTCPPort = 0;
  135. m_OwnDestSendRTPPort = m_OwnDestSendRTCPPort = 0;
  136. m_OwnAssocLCSendRTPPort = m_OwnSourceSendRTCPPort = 0;
  137. return HResult;
  138. }
  139. ///////////////////////////////////////////////////////////////////////////////
  140. // //
  141. // Routines for setting up and tearing down NAT Redirects //
  142. // //
  143. ///////////////////////////////////////////////////////////////////////////////
  144. // opens the forward RTP, forward RTCP and reverse RTCP streams
  145. // This function is called after the OLCAck is received.
  146. HRESULT
  147. RTP_LOGICAL_CHANNEL::OpenNATMappings(
  148. )
  149. {
  150. // open NAT mapping for source -> dest RTP stream
  151. // this is the forward RTP stream and we must always open this
  152. NTSTATUS Status;
  153. ULONG RedirectFlags = NatRedirectFlagNoTimeout;
  154. if (m_OwnDestIPv4Address == m_DestIPv4Address ||
  155. m_SourceIPv4Address == m_OwnSourceIPv4Address)
  156. {
  157. RedirectFlags |= NatRedirectFlagLoopback;
  158. }
  159. Status = NatCreateRedirectEx (
  160. NatHandle,
  161. RedirectFlags, // flags
  162. IPPROTO_UDP, // UDP
  163. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  164. htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
  165. htonl(0), // wildcard - source packet source address
  166. htons(0), // wildcard - source packet source port
  167. htonl(m_DestRTPIPv4Address), // NewDestinationAddress
  168. htons(m_DestRTPPort), // NewDestinationPort
  169. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  170. htons(m_OwnDestSendRTPPort), // NewSourcePort
  171. NULL, // RestrictedAdapterIndex
  172. NULL, // CompletionRoutine
  173. NULL, // CompletionContext
  174. NULL); // NotifyEvent
  175. if (Status != NO_ERROR) {
  176. DebugF (_T("RTP : 0x%x failed to set up redirect for forward RTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X). Error - %d.\n"),
  177. &GetCallBridge (),
  178. m_OwnSourceIPv4Address,
  179. m_OwnSourceRecvRTPPort,
  180. m_OwnDestIPv4Address,
  181. m_OwnDestSendRTPPort,
  182. m_DestRTPIPv4Address,
  183. m_DestRTPPort,
  184. Status);
  185. return E_FAIL;
  186. }
  187. else {
  188. DebugF (_T("RTP : 0x%x set up redirect for forward RTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"),
  189. &GetCallBridge (),
  190. m_OwnSourceIPv4Address,
  191. m_OwnSourceRecvRTPPort,
  192. m_OwnDestIPv4Address,
  193. m_OwnDestSendRTPPort,
  194. m_DestRTPIPv4Address,
  195. m_DestRTPPort);
  196. }
  197. // check to see if we must open the RTCP streams in both directions
  198. // source <-> dest
  199. // if there is no associated logical channel or the assoc logical
  200. // channel is in neither LC_STATE_OPEN_ACK_RCVD nor
  201. // LC_STATE_OPENED_CLOSE_RCVD, we must open the RTCP streams
  202. if ((!m_pAssocLogicalChannel) ||
  203. ((LC_STATE_OPEN_ACK_RCVD != m_pAssocLogicalChannel -> m_LogicalChannelState) &&
  204. (LC_STATE_OPENED_CLOSE_RCVD != m_pAssocLogicalChannel -> m_LogicalChannelState))) {
  205. // open NAT mapping for forward RTCP stream
  206. Status = NatCreateRedirectEx (
  207. NatHandle,
  208. RedirectFlags, // flags
  209. IPPROTO_UDP, // UDP
  210. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  211. htons(m_OwnSourceRecvRTCPPort), // source packet dest port (local)
  212. htonl(0), // wildcard - source packet source address
  213. htons(0), // wildcard - source packet source port
  214. htonl(m_DestRTCPIPv4Address), // NewDestinationAddress
  215. htons(m_DestRTCPPort), // NewDestinationPort
  216. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  217. htons(m_OwnDestSendRTCPPort), // NewSourcePort
  218. NULL, // RestrictedAdapterIndex
  219. NULL, // CompletionRoutine
  220. NULL, // CompletionContext
  221. NULL); // NotifyEvent
  222. if (Status != NO_ERROR) {
  223. // close the forward RTP stream
  224. // ignore error code
  225. DebugF (_T("RTCP: 0x%x failed to set up redirect for forward RCTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X). Error - %d.\n"),
  226. &GetCallBridge (),
  227. m_OwnSourceIPv4Address,
  228. m_OwnSourceRecvRTCPPort,
  229. m_OwnDestIPv4Address,
  230. m_OwnDestSendRTCPPort,
  231. m_DestRTCPIPv4Address,
  232. m_DestRTCPPort,
  233. Status);
  234. NatCancelRedirect (
  235. NatHandle,
  236. IPPROTO_UDP, // UDP
  237. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  238. htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
  239. htonl(0), // wildcard - source packet source address
  240. htons(0), // wildcard - source packet source port
  241. htonl(m_DestRTPIPv4Address), // NewDestinationAddress
  242. htons(m_DestRTPPort), // NewDestinationPort
  243. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  244. htons(m_OwnDestSendRTPPort)); // NewSourcePort
  245. return E_FAIL;
  246. }
  247. else {
  248. DebugF (_T("RTCP: 0x%x set up redirect for forward RCTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"),
  249. &GetCallBridge (),
  250. m_OwnSourceIPv4Address, // source packet dest address (local)
  251. m_OwnSourceRecvRTCPPort, // source packet dest port (local)
  252. m_OwnDestIPv4Address, // NewSourceAddress
  253. m_OwnDestSendRTCPPort, // NewSourcePort
  254. m_DestRTCPIPv4Address, // NewDestinationAddress
  255. m_DestRTCPPort); // NewDestinationPort
  256. }
  257. // open NAT mapping for reverse RTCP stream
  258. Status = NatCreateRedirectEx (
  259. NatHandle,
  260. RedirectFlags, // flags
  261. IPPROTO_UDP, // UDP
  262. htonl(m_OwnDestIPv4Address), // source packet dest address (local)
  263. htons(m_OwnDestRecvRTCPPort), // source packet dest port (local)
  264. htonl(0), // wildcard - source packet source address
  265. htons(0), // wildcard - source packet source port
  266. htonl(m_SourceRTCPIPv4Address), // NewDestinationAddress
  267. htons(m_SourceRTCPPort), // NewDestinationPort
  268. htonl(m_OwnSourceIPv4Address), // NewSourceAddress
  269. htons(m_OwnSourceSendRTCPPort), // NewSourcePort
  270. NULL, // RestrictedAdapterIndex
  271. NULL, // CompletionRoutine
  272. NULL, // CompletionContext
  273. NULL); // NotifyEvent
  274. if (Status != NO_ERROR) {
  275. DebugF (_T("RTCP: 0x%x failed to set up redirect for reverse RTCP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X). Error - %d.\n"),
  276. &GetCallBridge (),
  277. m_OwnDestIPv4Address,
  278. m_OwnDestRecvRTCPPort,
  279. m_OwnSourceIPv4Address,
  280. m_OwnSourceSendRTCPPort,
  281. m_SourceRTCPIPv4Address,
  282. m_SourceRTCPPort,
  283. Status);
  284. // close the forward RTP stream
  285. // ignore error code
  286. NatCancelRedirect(
  287. NatHandle,
  288. IPPROTO_UDP, // UDP
  289. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  290. htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
  291. htonl(0), // wildcard - source packet source address
  292. htons(0), // wildcard - source packet source port
  293. htonl(m_DestRTPIPv4Address), // NewDestinationAddress
  294. htons(m_DestRTPPort), // NewDestinationPort
  295. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  296. htons(m_OwnDestSendRTPPort) // NewSourcePort
  297. );
  298. // close the forward RTCP stream
  299. // ignore error code
  300. NatCancelRedirect(
  301. NatHandle,
  302. IPPROTO_UDP, // UDP
  303. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  304. htons(m_OwnSourceRecvRTCPPort), // source packet dest port (local)
  305. htonl(0), // wildcard - source packet source address
  306. htons(0), // wildcard - source packet source port
  307. htonl(m_DestRTCPIPv4Address), // NewDestinationAddress
  308. htons(m_DestRTCPPort), // NewDestinationPort
  309. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  310. htons(m_OwnDestSendRTCPPort) // NewSourcePort
  311. );
  312. return E_FAIL;
  313. }
  314. else {
  315. DebugF (_T("RTCP: 0x%x set up redirect for reverse RTCP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"),
  316. &GetCallBridge (),
  317. m_OwnDestIPv4Address,
  318. m_OwnDestRecvRTCPPort,
  319. m_OwnSourceIPv4Address,
  320. m_OwnSourceSendRTCPPort,
  321. m_SourceRTCPIPv4Address,
  322. m_SourceRTCPPort);
  323. }
  324. }
  325. return S_OK;
  326. }
  327. void
  328. RTP_LOGICAL_CHANNEL::CloseNATMappings(
  329. )
  330. {
  331. // if our current state is LC_STATE_OPEN_ACK_RCVD or
  332. // LC_STATE_OPENED_CLOSE_RCVD, we have a forward RTP NAT mapping
  333. // we may also have to close the RTCP mappings
  334. if ( (LC_STATE_OPEN_ACK_RCVD == m_LogicalChannelState) ||
  335. (LC_STATE_OPENED_CLOSE_RCVD == m_LogicalChannelState) )
  336. {
  337. DebugF (_T ("RTP : 0x%x cancels forward RTP redirect (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"),
  338. &GetCallBridge (),
  339. m_OwnSourceIPv4Address, // source packet dest address (local)
  340. m_OwnSourceRecvRTPPort, // source packet dest port (local)
  341. m_OwnDestIPv4Address, // NewSourceAddress
  342. m_OwnDestSendRTPPort, // NewSourcePort
  343. m_DestRTPIPv4Address, // NewDestinationAddress
  344. m_DestRTPPort // NewDestinationPort
  345. );
  346. // cancel forward RTP NAT mapping
  347. // ignore error code
  348. ULONG Win32ErrorCode = NO_ERROR;
  349. Win32ErrorCode = NatCancelRedirect(
  350. NatHandle,
  351. IPPROTO_UDP, // UDP
  352. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  353. htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
  354. htonl(0), // wildcard - source packet source address
  355. htons(0), // wildcard - source packet source port
  356. htonl(m_DestRTPIPv4Address), // NewDestinationAddress
  357. htons(m_DestRTPPort), // NewDestinationPort
  358. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  359. htons(m_OwnDestSendRTPPort) // NewSourcePort
  360. );
  361. // if we don't have an associated logical channel or its in neither
  362. // LC_STATE_OPEN_ACK_RCVD nor LC_STATE_OPENED_CLOSE_RCVD, we
  363. // must close the forward and reverse RTCP NAT mappings
  364. if ( (NULL == m_pAssocLogicalChannel) ||
  365. ( (LC_STATE_OPEN_ACK_RCVD !=
  366. m_pAssocLogicalChannel->m_LogicalChannelState) &&
  367. (LC_STATE_OPENED_CLOSE_RCVD !=
  368. m_pAssocLogicalChannel->m_LogicalChannelState) ) )
  369. {
  370. DebugF (_T ("RTCP: 0x%x cancels forward RTCP redirect (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"),
  371. &GetCallBridge (),
  372. m_OwnSourceIPv4Address, // source packet dest address (local)
  373. m_OwnSourceRecvRTCPPort, // source packet dest port (local)
  374. m_OwnDestIPv4Address, // NewSourceAddress
  375. m_OwnDestSendRTCPPort, // NewSourcePort
  376. m_DestRTCPIPv4Address, // NewDestinationAddress
  377. m_DestRTCPPort // NewDestinationPort
  378. );
  379. // cancel forward RTCP NAT mapping
  380. // ignore error code
  381. Win32ErrorCode = NatCancelRedirect(
  382. NatHandle,
  383. IPPROTO_UDP, // UDP
  384. htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
  385. htons(m_OwnSourceRecvRTCPPort), // source packet dest port (local)
  386. htonl(0), // wildcard - source packet source address
  387. htons(0), // wildcard - source packet source port
  388. htonl(m_DestRTCPIPv4Address), // NewDestinationAddress
  389. htons(m_DestRTCPPort), // NewDestinationPort
  390. htonl(m_OwnDestIPv4Address), // NewSourceAddress
  391. htons(m_OwnDestSendRTCPPort) // NewSourcePort
  392. );
  393. DebugF (_T ("RTCP: 0x%x cancels reverse RTCP redirect (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"),
  394. &GetCallBridge (),
  395. m_OwnDestIPv4Address, // source packet dest address (local)
  396. m_OwnDestRecvRTCPPort, // source packet dest port (local)
  397. m_OwnSourceIPv4Address, // NewSourceAddress
  398. m_OwnSourceSendRTCPPort, // NewSourcePort
  399. m_SourceRTCPIPv4Address, // NewDestinationAddress
  400. m_SourceRTCPPort // NewDestinationPort
  401. );
  402. // close the reverse RTCP stream
  403. // ignore error code
  404. Win32ErrorCode = NatCancelRedirect(
  405. NatHandle,
  406. IPPROTO_UDP, // UDP
  407. htonl(m_OwnDestIPv4Address),
  408. // source packet dest address (local)
  409. htons(m_OwnDestRecvRTCPPort),
  410. // source packet dest port (local)
  411. htonl(0), // wildcard - source packet source address
  412. htons(0), // wildcard - source packet source port
  413. htonl(m_SourceRTCPIPv4Address), // NewDestinationAddress
  414. htons(m_SourceRTCPPort), // NewDestinationPort
  415. htonl(m_OwnSourceIPv4Address), // NewSourceAddress
  416. htons(m_OwnSourceSendRTCPPort) // NewSourcePort
  417. );
  418. }
  419. }
  420. }
  421. ///////////////////////////////////////////////////////////////////////////////
  422. // //
  423. // Routines for processing H.245 PDUs //
  424. // //
  425. ///////////////////////////////////////////////////////////////////////////////
  426. HRESULT
  427. RTP_LOGICAL_CHANNEL::HandleOpenLogicalChannelPDU(
  428. IN H245_INFO &H245Info,
  429. IN MEDIA_TYPE MediaType,
  430. IN DWORD LocalIPv4Address,
  431. IN DWORD RemoteIPv4Address,
  432. IN DWORD OtherLocalIPv4Address,
  433. IN DWORD OtherRemoteIPv4Address,
  434. IN WORD LogicalChannelNumber,
  435. IN BYTE SessionId,
  436. IN RTP_LOGICAL_CHANNEL *pAssocLogicalChannel,
  437. IN DWORD SourceRTCPIPv4Address,
  438. IN WORD SourceRTCPPort,
  439. IN MultimediaSystemControlMessage *pH245pdu
  440. )
  441. /*++
  442. Routine Description:
  443. Arguments:
  444. Return Values:
  445. S_OK on success.
  446. E_INVALIDARG if the PDU is invalid.
  447. --*/
  448. {
  449. // this should be the first call to this instance after its
  450. // created - hence, these fields must be as asserted
  451. _ASSERTE(LC_STATE_NOT_INIT == m_LogicalChannelState);
  452. _ASSERTE(NULL == m_pH245Info);
  453. _ASSERTE(NULL == m_pAssocLogicalChannel);
  454. HRESULT HResult = E_FAIL;
  455. m_pH245Info = &H245Info;
  456. // the destructor will try to release associations, so assign the
  457. // associated logical channel now
  458. m_pAssocLogicalChannel = pAssocLogicalChannel;
  459. // set the local/remote addresses for our and the other h245 instance
  460. m_OwnSourceIPv4Address = LocalIPv4Address;
  461. m_SourceIPv4Address = RemoteIPv4Address;
  462. m_OwnDestIPv4Address = OtherLocalIPv4Address;
  463. m_DestIPv4Address = OtherRemoteIPv4Address;
  464. m_LogicalChannelNumber = LogicalChannelNumber;
  465. m_SessionId = SessionId;
  466. m_MediaType = MediaType; // XXX
  467. m_SourceRTCPIPv4Address = SourceRTCPIPv4Address;
  468. m_SourceRTCPPort = SourceRTCPPort;
  469. // set the rtp and rtcp ports on the source and dest side
  470. // if there is a logical channel, then, just the rtcp ports will be shared
  471. HResult = SetPorts();
  472. if (FAILED(HResult))
  473. {
  474. DebugF( _T("RTP_LOGICAL_CHANNEL::HandleOpenLogicalChannelPDU, ")
  475. _T("failed to set its ports, returning 0x%x\n"),
  476. HResult);
  477. return HResult;
  478. }
  479. //_ASSERTE(S_FALSE != HResult);
  480. OpenLogicalChannel &OlcPDU =
  481. pH245pdu->u.request.u.openLogicalChannel;
  482. OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters & MultiplexParams =
  483. OlcPDU.forwardLogicalChannelParameters.multiplexParameters;
  484. H2250LogicalChannelParameters &H2250Params =
  485. MultiplexParams.u.h2250LogicalChannelParameters;
  486. // modify the OLC PDU by replacing the RTCP address/port
  487. // with the h245 address and RTCP port
  488. FillH245TransportAddress(
  489. m_OwnDestIPv4Address,
  490. m_OwnDestRecvRTCPPort,
  491. H2250Params.mediaControlChannel);
  492. // Should the part below be pushed into H245_INFO::HandleOpenLogicalChannelPDU ?????
  493. // let the other H245 instance process the PDU
  494. HResult = m_pH245Info->GetOtherH245Info().ProcessMessage(
  495. pH245pdu
  496. );
  497. if (FAILED(HResult))
  498. {
  499. DebugF(_T("RTP_LOGICAL_CHANNEL::HandleOpenLogicalChannelPDU: other H245 instance failed to process OLC PDU, returning 0x%x\n"), HResult);
  500. return HResult;
  501. }
  502. // start timer for a response
  503. // TO DO *** creating timers after queueing the send is sufficient.
  504. // change back earlier policy of creating these only after the send
  505. // callback (to be consistent). creating timers that way would be too
  506. // complex for logical channels
  507. HResult = CreateTimer(LC_POST_OPEN_TIMER_VALUE);
  508. if (FAILED(HResult))
  509. {
  510. DebugF (_T("RTP : 0x%x failed to create timer for duration %d milliseconds ('Open Logical Channel'). Error - %x.\n"),
  511. &GetCallBridge (),
  512. LC_POST_OPEN_TIMER_VALUE,
  513. HResult);
  514. return HResult;
  515. }
  516. DebugF (_T("RTP : 0x%x created timer for duration %d milliseconds ('Open Logical Channel').\n"),
  517. &GetCallBridge (),
  518. LC_POST_OPEN_TIMER_VALUE);
  519. // transition state to LC_STATE_OPEN_RCVD
  520. m_LogicalChannelState = LC_STATE_OPEN_RCVD;
  521. return S_OK;
  522. }
  523. HRESULT
  524. RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU(
  525. IN MultimediaSystemControlMessage &H245pdu,
  526. OUT BYTE &SessionId,
  527. OUT DWORD &DestRTPIPv4Address,
  528. OUT WORD &DestRTPPort,
  529. OUT DWORD &DestRTCPIPv4Address,
  530. OUT WORD &DestRTCPPort
  531. )
  532. /*++
  533. Routine Description:
  534. Arguments:
  535. Return Values:
  536. S_OK on success.
  537. E_INVALIDARG if the PDU is invalid.
  538. --*/
  539. {
  540. // get the open logical channel ack PDU
  541. OpenLogicalChannelAck &OlcAckPDU = H245pdu.u.response.u.openLogicalChannelAck;
  542. // there shouldn't be reverse logical channel parameters
  543. if (OpenLogicalChannelAck_reverseLogicalChannelParameters_present &
  544. OlcAckPDU.bit_mask)
  545. {
  546. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, has ")
  547. _T("reverse logical channel params, returning E_INVALIDARG\n"));
  548. return E_INVALIDARG;
  549. }
  550. // there shouldn't be a separate stack
  551. if (OpenLogicalChannelAck_separateStack_present &
  552. OlcAckPDU.bit_mask)
  553. {
  554. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  555. _T("has a separate stack, returning E_INVALIDARG\n"));
  556. return E_INVALIDARG;
  557. }
  558. // we should have forward multiplex ack params - these contain the
  559. // H245 params
  560. if ( !(forwardMultiplexAckParameters_present &
  561. OlcAckPDU.bit_mask) )
  562. {
  563. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  564. _T("doesn't have forward multiplex ack params,")
  565. _T(" returning E_INVALIDARG\n"));
  566. return E_INVALIDARG;
  567. }
  568. // we should have the H245 params
  569. if (h2250LogicalChannelAckParameters_chosen !=
  570. OlcAckPDU.forwardMultiplexAckParameters.choice)
  571. {
  572. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  573. _T("doesn't have H2250 ack params, returning E_INVALIDARG\n"));
  574. return E_INVALIDARG;
  575. }
  576. H2250LogicalChannelAckParameters &H2250Params =
  577. OlcAckPDU.forwardMultiplexAckParameters.\
  578. u.h2250LogicalChannelAckParameters;
  579. // it should have media channel info
  580. if ( !(H2250LogicalChannelAckParameters_mediaChannel_present &
  581. H2250Params.bit_mask) )
  582. {
  583. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  584. _T("doesn't have media channel info, returning E_INVALIDARG\n"));
  585. return E_INVALIDARG;
  586. }
  587. // it should have control channel info
  588. if ( !(H2250LogicalChannelAckParameters_mediaControlChannel_present &
  589. H2250Params.bit_mask) )
  590. {
  591. DebugF(_T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  592. _T("doesn't have media control channel info,")
  593. _T(" returning E_INVALIDARG\n"));
  594. return E_INVALIDARG;
  595. }
  596. // save remote client RTP address/port
  597. HRESULT HResult = E_FAIL;
  598. HResult = GetH245TransportInfo(
  599. H2250Params.mediaChannel,
  600. DestRTPIPv4Address,
  601. DestRTPPort);
  602. if (FAILED(HResult))
  603. {
  604. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  605. _T("can't get media channel (RTP) address/port, returning 0x%x\n"),
  606. HResult);
  607. return HResult;
  608. }
  609. _ASSERTE(S_OK == HResult);
  610. // save remote client RTP address/port
  611. HResult = GetH245TransportInfo(
  612. H2250Params.mediaControlChannel,
  613. DestRTCPIPv4Address,
  614. DestRTCPPort);
  615. if (FAILED(HResult))
  616. {
  617. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  618. _T("can't get media control channel (RTCP) address/port, ")
  619. _T("returning 0x%x\n"),
  620. HResult);
  621. return HResult;
  622. }
  623. _ASSERTE(S_OK == HResult);
  624. // if there is a session id, save it
  625. if (sessionID_present & H2250Params.bit_mask)
  626. {
  627. // the PDU stores the session ID as an unsigned short
  628. // although the ITU spec requires it to be a BYTE value [0..255]
  629. // the cast to BYTE is intentional
  630. _ASSERTE(255 >= H2250Params.sessionID);
  631. SessionId = (BYTE)H2250Params.sessionID;
  632. // the session id must be non-zero
  633. if (0 == SessionId)
  634. {
  635. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  636. _T("has a session id of 0, returning E_INVALIDARG\n"));
  637. return E_INVALIDARG;
  638. }
  639. }
  640. else
  641. {
  642. // if no session id is supplied, the source must have supplied
  643. // a non-zero session id in OpenLogicalChannel
  644. if (0 == SessionId)
  645. {
  646. DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ")
  647. _T("the source supplied a session id of 0 and the dest hasn't")
  648. _T("supplied one, returning E_INVALIDARG\n"));
  649. return E_INVALIDARG;
  650. }
  651. }
  652. return HResult;
  653. }
  654. HRESULT
  655. RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU(
  656. IN MultimediaSystemControlMessage *pH245pdu
  657. )
  658. /*++
  659. Routine Description:
  660. Arguments:
  661. pH245pdu -
  662. Return Values:
  663. S_OK on success.
  664. E_INVALIDARG if the PDU is invalid.
  665. --*/
  666. {
  667. HRESULT HResult = E_FAIL;
  668. switch(m_LogicalChannelState)
  669. {
  670. case LC_STATE_OPEN_RCVD:
  671. {
  672. HResult = CheckOpenLogicalChannelAckPDU(
  673. *pH245pdu,
  674. m_SessionId,
  675. m_DestRTPIPv4Address,
  676. m_DestRTPPort,
  677. m_DestRTCPIPv4Address,
  678. m_DestRTCPPort
  679. );
  680. if (FAILED(HResult))
  681. {
  682. DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU")
  683. _T("(&%x), can't process OpenLogicalChannelAck, returning 0x%x\n"),
  684. pH245pdu, HResult);
  685. return HResult;
  686. }
  687. _ASSERTE(S_OK == HResult);
  688. HResult = OpenNATMappings();
  689. if (FAILED(HResult))
  690. {
  691. DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU")
  692. _T("(&%x), can't process OpenLogicalChannelAck, returning 0x%x\n"),
  693. pH245pdu, HResult);
  694. return HResult;
  695. }
  696. _ASSERTE(S_OK == HResult);
  697. OpenLogicalChannelAck &OlcAckPDU =
  698. pH245pdu->u.response.u.openLogicalChannelAck;
  699. H2250LogicalChannelAckParameters &H2250Params =
  700. OlcAckPDU.forwardMultiplexAckParameters.u.h2250LogicalChannelAckParameters;
  701. // replace the RTP address/port
  702. // with the H.245 address and RTP port
  703. FillH245TransportAddress(
  704. m_OwnSourceIPv4Address,
  705. m_OwnSourceRecvRTPPort,
  706. H2250Params.mediaChannel
  707. );
  708. // replace the RTCP address/port
  709. // with the h245 address and RTCP port
  710. FillH245TransportAddress(
  711. m_OwnSourceIPv4Address,
  712. m_OwnSourceRecvRTCPPort,
  713. H2250Params.mediaControlChannel);
  714. // reset timer, we must have one (ignore error code if any)
  715. _ASSERTE(NULL != m_TimerHandle);
  716. TimprocCancelTimer();
  717. DebugF (_T("RTP : 0x%x cancelled timer.\n"),
  718. &GetCallBridge ());
  719. // trasition to LC_STATE_OPEN_ACK_RCVD
  720. m_LogicalChannelState = LC_STATE_OPEN_ACK_RCVD;
  721. }
  722. break;
  723. case LC_STATE_CLOSE_RCVD:
  724. {
  725. // if we have received a close logical channel PDU, we must throw
  726. // OLC ACKs away and continue to wait
  727. DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU")
  728. _T("(&%x), in close state %d, returning E_INVALIDARG\n"),
  729. pH245pdu, m_LogicalChannelState);
  730. return E_INVALIDARG;
  731. }
  732. break;
  733. case LC_STATE_NOT_INIT:
  734. case LC_STATE_OPEN_ACK_RCVD:
  735. case LC_STATE_OPENED_CLOSE_RCVD:
  736. default:
  737. {
  738. DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU")
  739. _T("(&%x), in state %d, returning E_UNEXPECTED"),
  740. pH245pdu, m_LogicalChannelState);
  741. _ASSERTE(FALSE);
  742. return E_UNEXPECTED;
  743. }
  744. break;
  745. };
  746. return HResult;
  747. }