|
|
#include "stdafx.h"
#include "portmgmt.h"
#include "timerval.h"
#include "cbridge.h"
#include "main.h"
// destructor
// virtual
RTP_LOGICAL_CHANNEL::~RTP_LOGICAL_CHANNEL (void) { // close NAT mappings
CloseNATMappings();
// release reference to any associated channel or allocated ports
ReleaseAssociationAndPorts(); }
/*++
Release ports only if there is no associated channel. If there is an associated channel the ports will be freed when it is deleted. Note that a logical channel could be closed and reopened again. --*/
inline void RTP_LOGICAL_CHANNEL::ReleaseAssociationAndPorts() { // if there is an associated logical channel
if (NULL != m_pAssocLogicalChannel) { // release reference to it
m_pAssocLogicalChannel->ResetAssociationRef(); m_pAssocLogicalChannel = NULL; } else { if (m_OwnSourceRecvRTPPort != 0) PortPoolFreeRTPPort(m_OwnSourceRecvRTPPort); if (m_OwnAssocLCRecvRTPPort != 0) PortPoolFreeRTPPort(m_OwnAssocLCRecvRTPPort); if (m_OwnDestSendRTPPort != 0) PortPoolFreeRTPPort(m_OwnDestSendRTPPort); if (m_OwnAssocLCSendRTPPort != 0) PortPoolFreeRTPPort(m_OwnAssocLCSendRTPPort); m_OwnSourceRecvRTPPort = m_OwnSourceRecvRTCPPort = 0; m_OwnAssocLCRecvRTPPort = m_OwnDestRecvRTCPPort = 0; m_OwnDestSendRTPPort = m_OwnDestSendRTCPPort = 0; m_OwnAssocLCSendRTPPort = m_OwnSourceSendRTCPPort = 0; } }
/*++
This function is called after the OLC is received. --*/
HRESULT RTP_LOGICAL_CHANNEL::SetPorts (void) { HRESULT HResult = E_FAIL;
// if there is an associated LC, copy all the ports from that LC.
// else, allocate them now
if (NULL != m_pAssocLogicalChannel) { // tell the associated logical channel that we are associated
// with it
m_pAssocLogicalChannel->SetAssociationRef(*this);
// save the associated channel's own source/dest ports
// assoc channel's source ports become our dest ports and vice versa
m_OwnDestRecvRTCPPort = m_pAssocLogicalChannel->m_OwnSourceRecvRTCPPort; m_OwnSourceRecvRTCPPort = m_pAssocLogicalChannel->m_OwnDestRecvRTCPPort;
m_OwnDestSendRTCPPort = m_pAssocLogicalChannel->m_OwnSourceSendRTCPPort; m_OwnSourceSendRTCPPort = m_pAssocLogicalChannel->m_OwnDestSendRTCPPort;
// Copy the RTP ports
m_OwnSourceRecvRTPPort = m_pAssocLogicalChannel->m_OwnAssocLCRecvRTPPort; m_OwnAssocLCRecvRTPPort = m_pAssocLogicalChannel->m_OwnSourceRecvRTPPort;
m_OwnDestSendRTPPort = m_pAssocLogicalChannel->m_OwnAssocLCSendRTPPort; m_OwnAssocLCSendRTPPort = m_pAssocLogicalChannel->m_OwnDestSendRTPPort; } else { // allocate own ports - the portmgt apis return an even port only (RTP)
// and the assumption is that the RTCP port = RTP port + 1
// however, we use the odd port for receiving RTCP and the even
// port for sending RTP
HResult = PortPoolAllocRTPPort (&m_OwnSourceRecvRTPPort); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts") _T("failed to allocate m_OwnSourceRecvRTPPort, returning 0x%x\n"), HResult); goto cleanup; } m_OwnSourceRecvRTCPPort = m_OwnSourceRecvRTPPort + 1;
HResult = PortPoolAllocRTPPort (&m_OwnAssocLCRecvRTPPort); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts") _T("failed to allocate m_OwnAssocLCRecvRTPPort, returning 0x%x\n"), HResult); goto cleanup; } m_OwnDestRecvRTCPPort = m_OwnAssocLCRecvRTPPort + 1;
HResult = PortPoolAllocRTPPort (&m_OwnDestSendRTPPort); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts") _T("failed to allocate m_OwnDestSendRTPPort, returning 0x%x\n"), HResult); goto cleanup; } m_OwnDestSendRTCPPort = m_OwnDestSendRTPPort + 1;
HResult = PortPoolAllocRTPPort (&m_OwnAssocLCSendRTPPort); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::SetPorts, ") _T("failed to allocate m_OwnAssocLCSendRTPPort, returning 0x%x\n"), HResult); goto cleanup; } m_OwnSourceSendRTCPPort = m_OwnAssocLCSendRTPPort + 1; } DebugF (_T("RTP : 0x%x using ports %04X, %04X, %04X, %04X.\n"), &GetCallBridge (), m_OwnSourceRecvRTPPort, m_OwnAssocLCRecvRTPPort, m_OwnDestSendRTPPort, m_OwnAssocLCSendRTPPort);
DebugF (_T("RTCP: 0x%x using ports %04X, %04X, %04X, %04X.\n"), &GetCallBridge (), m_OwnSourceRecvRTCPPort, m_OwnDestRecvRTCPPort, m_OwnDestSendRTCPPort, m_OwnSourceSendRTCPPort);
return S_OK;
cleanup: if (m_OwnSourceRecvRTPPort != 0) PortPoolFreeRTPPort(m_OwnSourceRecvRTPPort); if (m_OwnAssocLCRecvRTPPort != 0) PortPoolFreeRTPPort(m_OwnAssocLCRecvRTPPort); if (m_OwnDestSendRTPPort != 0) PortPoolFreeRTPPort(m_OwnDestSendRTPPort); if (m_OwnAssocLCSendRTPPort != 0) PortPoolFreeRTPPort(m_OwnAssocLCSendRTPPort); m_OwnSourceRecvRTPPort = m_OwnSourceRecvRTCPPort = 0; m_OwnAssocLCRecvRTPPort = m_OwnDestRecvRTCPPort = 0; m_OwnDestSendRTPPort = m_OwnDestSendRTCPPort = 0; m_OwnAssocLCSendRTPPort = m_OwnSourceSendRTCPPort = 0; return HResult; }
///////////////////////////////////////////////////////////////////////////////
// //
// Routines for setting up and tearing down NAT Redirects //
// //
///////////////////////////////////////////////////////////////////////////////
// opens the forward RTP, forward RTCP and reverse RTCP streams
// This function is called after the OLCAck is received.
HRESULT RTP_LOGICAL_CHANNEL::OpenNATMappings( ) { // open NAT mapping for source -> dest RTP stream
// this is the forward RTP stream and we must always open this
NTSTATUS Status; ULONG RedirectFlags = NatRedirectFlagNoTimeout;
if (m_OwnDestIPv4Address == m_DestIPv4Address || m_SourceIPv4Address == m_OwnSourceIPv4Address) { RedirectFlags |= NatRedirectFlagLoopback; }
Status = NatCreateRedirectEx ( NatHandle, RedirectFlags, // flags
IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTPIPv4Address), // NewDestinationAddress
htons(m_DestRTPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTPPort), // NewSourcePort
NULL, // RestrictedAdapterIndex
NULL, // CompletionRoutine
NULL, // CompletionContext
NULL); // NotifyEvent
if (Status != NO_ERROR) { DebugF (_T("RTP : 0x%x failed to set up redirect for forward RTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X). Error - %d.\n"), &GetCallBridge (), m_OwnSourceIPv4Address, m_OwnSourceRecvRTPPort, m_OwnDestIPv4Address, m_OwnDestSendRTPPort, m_DestRTPIPv4Address, m_DestRTPPort, Status);
return E_FAIL; } else { DebugF (_T("RTP : 0x%x set up redirect for forward RTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"), &GetCallBridge (), m_OwnSourceIPv4Address, m_OwnSourceRecvRTPPort, m_OwnDestIPv4Address, m_OwnDestSendRTPPort, m_DestRTPIPv4Address, m_DestRTPPort); }
// check to see if we must open the RTCP streams in both directions
// source <-> dest
// if there is no associated logical channel or the assoc logical
// channel is in neither LC_STATE_OPEN_ACK_RCVD nor
// LC_STATE_OPENED_CLOSE_RCVD, we must open the RTCP streams
if ((!m_pAssocLogicalChannel) || ((LC_STATE_OPEN_ACK_RCVD != m_pAssocLogicalChannel -> m_LogicalChannelState) && (LC_STATE_OPENED_CLOSE_RCVD != m_pAssocLogicalChannel -> m_LogicalChannelState))) {
// open NAT mapping for forward RTCP stream
Status = NatCreateRedirectEx ( NatHandle, RedirectFlags, // flags
IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTCPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTCPIPv4Address), // NewDestinationAddress
htons(m_DestRTCPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTCPPort), // NewSourcePort
NULL, // RestrictedAdapterIndex
NULL, // CompletionRoutine
NULL, // CompletionContext
NULL); // NotifyEvent
if (Status != NO_ERROR) { // close the forward RTP stream
// ignore error code
DebugF (_T("RTCP: 0x%x failed to set up redirect for forward RCTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X). Error - %d.\n"), &GetCallBridge (), m_OwnSourceIPv4Address, m_OwnSourceRecvRTCPPort, m_OwnDestIPv4Address, m_OwnDestSendRTCPPort, m_DestRTCPIPv4Address, m_DestRTCPPort, Status);
NatCancelRedirect ( NatHandle, IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTPIPv4Address), // NewDestinationAddress
htons(m_DestRTPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTPPort)); // NewSourcePort
return E_FAIL; } else { DebugF (_T("RTCP: 0x%x set up redirect for forward RCTP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"), &GetCallBridge (), m_OwnSourceIPv4Address, // source packet dest address (local)
m_OwnSourceRecvRTCPPort, // source packet dest port (local)
m_OwnDestIPv4Address, // NewSourceAddress
m_OwnDestSendRTCPPort, // NewSourcePort
m_DestRTCPIPv4Address, // NewDestinationAddress
m_DestRTCPPort); // NewDestinationPort
}
// open NAT mapping for reverse RTCP stream
Status = NatCreateRedirectEx ( NatHandle, RedirectFlags, // flags
IPPROTO_UDP, // UDP
htonl(m_OwnDestIPv4Address), // source packet dest address (local)
htons(m_OwnDestRecvRTCPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_SourceRTCPIPv4Address), // NewDestinationAddress
htons(m_SourceRTCPPort), // NewDestinationPort
htonl(m_OwnSourceIPv4Address), // NewSourceAddress
htons(m_OwnSourceSendRTCPPort), // NewSourcePort
NULL, // RestrictedAdapterIndex
NULL, // CompletionRoutine
NULL, // CompletionContext
NULL); // NotifyEvent
if (Status != NO_ERROR) { DebugF (_T("RTCP: 0x%x failed to set up redirect for reverse RTCP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X). Error - %d.\n"), &GetCallBridge (), m_OwnDestIPv4Address, m_OwnDestRecvRTCPPort, m_OwnSourceIPv4Address, m_OwnSourceSendRTCPPort, m_SourceRTCPIPv4Address, m_SourceRTCPPort, Status); // close the forward RTP stream
// ignore error code
NatCancelRedirect( NatHandle, IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTPIPv4Address), // NewDestinationAddress
htons(m_DestRTPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTPPort) // NewSourcePort
);
// close the forward RTCP stream
// ignore error code
NatCancelRedirect( NatHandle, IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTCPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTCPIPv4Address), // NewDestinationAddress
htons(m_DestRTCPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTCPPort) // NewSourcePort
);
return E_FAIL; } else { DebugF (_T("RTCP: 0x%x set up redirect for reverse RTCP stream: (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"), &GetCallBridge (), m_OwnDestIPv4Address, m_OwnDestRecvRTCPPort, m_OwnSourceIPv4Address, m_OwnSourceSendRTCPPort, m_SourceRTCPIPv4Address, m_SourceRTCPPort); }
}
return S_OK; }
void RTP_LOGICAL_CHANNEL::CloseNATMappings( ) { // if our current state is LC_STATE_OPEN_ACK_RCVD or
// LC_STATE_OPENED_CLOSE_RCVD, we have a forward RTP NAT mapping
// we may also have to close the RTCP mappings
if ( (LC_STATE_OPEN_ACK_RCVD == m_LogicalChannelState) || (LC_STATE_OPENED_CLOSE_RCVD == m_LogicalChannelState) ) {
DebugF (_T ("RTP : 0x%x cancels forward RTP redirect (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"), &GetCallBridge (), m_OwnSourceIPv4Address, // source packet dest address (local)
m_OwnSourceRecvRTPPort, // source packet dest port (local)
m_OwnDestIPv4Address, // NewSourceAddress
m_OwnDestSendRTPPort, // NewSourcePort
m_DestRTPIPv4Address, // NewDestinationAddress
m_DestRTPPort // NewDestinationPort
); // cancel forward RTP NAT mapping
// ignore error code
ULONG Win32ErrorCode = NO_ERROR; Win32ErrorCode = NatCancelRedirect( NatHandle, IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTPIPv4Address), // NewDestinationAddress
htons(m_DestRTPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTPPort) // NewSourcePort
);
// if we don't have an associated logical channel or its in neither
// LC_STATE_OPEN_ACK_RCVD nor LC_STATE_OPENED_CLOSE_RCVD, we
// must close the forward and reverse RTCP NAT mappings
if ( (NULL == m_pAssocLogicalChannel) || ( (LC_STATE_OPEN_ACK_RCVD != m_pAssocLogicalChannel->m_LogicalChannelState) && (LC_STATE_OPENED_CLOSE_RCVD != m_pAssocLogicalChannel->m_LogicalChannelState) ) ) { DebugF (_T ("RTCP: 0x%x cancels forward RTCP redirect (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"), &GetCallBridge (), m_OwnSourceIPv4Address, // source packet dest address (local)
m_OwnSourceRecvRTCPPort, // source packet dest port (local)
m_OwnDestIPv4Address, // NewSourceAddress
m_OwnDestSendRTCPPort, // NewSourcePort
m_DestRTCPIPv4Address, // NewDestinationAddress
m_DestRTCPPort // NewDestinationPort
); // cancel forward RTCP NAT mapping
// ignore error code
Win32ErrorCode = NatCancelRedirect( NatHandle, IPPROTO_UDP, // UDP
htonl(m_OwnSourceIPv4Address), // source packet dest address (local)
htons(m_OwnSourceRecvRTCPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_DestRTCPIPv4Address), // NewDestinationAddress
htons(m_DestRTCPPort), // NewDestinationPort
htonl(m_OwnDestIPv4Address), // NewSourceAddress
htons(m_OwnDestSendRTCPPort) // NewSourcePort
);
DebugF (_T ("RTCP: 0x%x cancels reverse RTCP redirect (*:* -> %08X:%04X) => (%08X:%04X -> %08X:%04X).\n"), &GetCallBridge (), m_OwnDestIPv4Address, // source packet dest address (local)
m_OwnDestRecvRTCPPort, // source packet dest port (local)
m_OwnSourceIPv4Address, // NewSourceAddress
m_OwnSourceSendRTCPPort, // NewSourcePort
m_SourceRTCPIPv4Address, // NewDestinationAddress
m_SourceRTCPPort // NewDestinationPort
); // close the reverse RTCP stream
// ignore error code
Win32ErrorCode = NatCancelRedirect( NatHandle, IPPROTO_UDP, // UDP
htonl(m_OwnDestIPv4Address), // source packet dest address (local)
htons(m_OwnDestRecvRTCPPort), // source packet dest port (local)
htonl(0), // wildcard - source packet source address
htons(0), // wildcard - source packet source port
htonl(m_SourceRTCPIPv4Address), // NewDestinationAddress
htons(m_SourceRTCPPort), // NewDestinationPort
htonl(m_OwnSourceIPv4Address), // NewSourceAddress
htons(m_OwnSourceSendRTCPPort) // NewSourcePort
); } } }
///////////////////////////////////////////////////////////////////////////////
// //
// Routines for processing H.245 PDUs //
// //
///////////////////////////////////////////////////////////////////////////////
HRESULT RTP_LOGICAL_CHANNEL::HandleOpenLogicalChannelPDU( IN H245_INFO &H245Info, IN MEDIA_TYPE MediaType, IN DWORD LocalIPv4Address, IN DWORD RemoteIPv4Address, IN DWORD OtherLocalIPv4Address, IN DWORD OtherRemoteIPv4Address, IN WORD LogicalChannelNumber, IN BYTE SessionId, IN RTP_LOGICAL_CHANNEL *pAssocLogicalChannel, IN DWORD SourceRTCPIPv4Address, IN WORD SourceRTCPPort, IN MultimediaSystemControlMessage *pH245pdu ) /*++
Routine Description:
Arguments: Return Values:
S_OK on success. E_INVALIDARG if the PDU is invalid.
--*/ { // this should be the first call to this instance after its
// created - hence, these fields must be as asserted
_ASSERTE(LC_STATE_NOT_INIT == m_LogicalChannelState); _ASSERTE(NULL == m_pH245Info); _ASSERTE(NULL == m_pAssocLogicalChannel);
HRESULT HResult = E_FAIL;
m_pH245Info = &H245Info;
// the destructor will try to release associations, so assign the
// associated logical channel now
m_pAssocLogicalChannel = pAssocLogicalChannel;
// set the local/remote addresses for our and the other h245 instance
m_OwnSourceIPv4Address = LocalIPv4Address; m_SourceIPv4Address = RemoteIPv4Address; m_OwnDestIPv4Address = OtherLocalIPv4Address; m_DestIPv4Address = OtherRemoteIPv4Address;
m_LogicalChannelNumber = LogicalChannelNumber; m_SessionId = SessionId; m_MediaType = MediaType; // XXX
m_SourceRTCPIPv4Address = SourceRTCPIPv4Address; m_SourceRTCPPort = SourceRTCPPort;
// set the rtp and rtcp ports on the source and dest side
// if there is a logical channel, then, just the rtcp ports will be shared
HResult = SetPorts(); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::HandleOpenLogicalChannelPDU, ") _T("failed to set its ports, returning 0x%x\n"), HResult); return HResult; } //_ASSERTE(S_FALSE != HResult);
OpenLogicalChannel &OlcPDU = pH245pdu->u.request.u.openLogicalChannel; OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters & MultiplexParams = OlcPDU.forwardLogicalChannelParameters.multiplexParameters; H2250LogicalChannelParameters &H2250Params = MultiplexParams.u.h2250LogicalChannelParameters;
// modify the OLC PDU by replacing the RTCP address/port
// with the h245 address and RTCP port
FillH245TransportAddress( m_OwnDestIPv4Address, m_OwnDestRecvRTCPPort, H2250Params.mediaControlChannel);
// Should the part below be pushed into H245_INFO::HandleOpenLogicalChannelPDU ?????
// let the other H245 instance process the PDU
HResult = m_pH245Info->GetOtherH245Info().ProcessMessage( pH245pdu ); if (FAILED(HResult)) { DebugF(_T("RTP_LOGICAL_CHANNEL::HandleOpenLogicalChannelPDU: other H245 instance failed to process OLC PDU, returning 0x%x\n"), HResult); return HResult; }
// start timer for a response
// TO DO *** creating timers after queueing the send is sufficient.
// change back earlier policy of creating these only after the send
// callback (to be consistent). creating timers that way would be too
// complex for logical channels
HResult = CreateTimer(LC_POST_OPEN_TIMER_VALUE); if (FAILED(HResult)) { DebugF (_T("RTP : 0x%x failed to create timer for duration %d milliseconds ('Open Logical Channel'). Error - %x.\n"), &GetCallBridge (), LC_POST_OPEN_TIMER_VALUE, HResult); return HResult; } DebugF (_T("RTP : 0x%x created timer for duration %d milliseconds ('Open Logical Channel').\n"), &GetCallBridge (), LC_POST_OPEN_TIMER_VALUE);
// transition state to LC_STATE_OPEN_RCVD
m_LogicalChannelState = LC_STATE_OPEN_RCVD;
return S_OK; }
HRESULT RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU( IN MultimediaSystemControlMessage &H245pdu, OUT BYTE &SessionId, OUT DWORD &DestRTPIPv4Address, OUT WORD &DestRTPPort, OUT DWORD &DestRTCPIPv4Address, OUT WORD &DestRTCPPort ) /*++
Routine Description:
Arguments: Return Values:
S_OK on success. E_INVALIDARG if the PDU is invalid.
--*/ { // get the open logical channel ack PDU
OpenLogicalChannelAck &OlcAckPDU = H245pdu.u.response.u.openLogicalChannelAck;
// there shouldn't be reverse logical channel parameters
if (OpenLogicalChannelAck_reverseLogicalChannelParameters_present & OlcAckPDU.bit_mask) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, has ") _T("reverse logical channel params, returning E_INVALIDARG\n")); return E_INVALIDARG; }
// there shouldn't be a separate stack
if (OpenLogicalChannelAck_separateStack_present & OlcAckPDU.bit_mask) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("has a separate stack, returning E_INVALIDARG\n")); return E_INVALIDARG; }
// we should have forward multiplex ack params - these contain the
// H245 params
if ( !(forwardMultiplexAckParameters_present & OlcAckPDU.bit_mask) ) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("doesn't have forward multiplex ack params,") _T(" returning E_INVALIDARG\n")); return E_INVALIDARG; }
// we should have the H245 params
if (h2250LogicalChannelAckParameters_chosen != OlcAckPDU.forwardMultiplexAckParameters.choice) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("doesn't have H2250 ack params, returning E_INVALIDARG\n")); return E_INVALIDARG; }
H2250LogicalChannelAckParameters &H2250Params = OlcAckPDU.forwardMultiplexAckParameters.\ u.h2250LogicalChannelAckParameters;
// it should have media channel info
if ( !(H2250LogicalChannelAckParameters_mediaChannel_present & H2250Params.bit_mask) ) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("doesn't have media channel info, returning E_INVALIDARG\n")); return E_INVALIDARG; }
// it should have control channel info
if ( !(H2250LogicalChannelAckParameters_mediaControlChannel_present & H2250Params.bit_mask) ) { DebugF(_T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("doesn't have media control channel info,") _T(" returning E_INVALIDARG\n")); return E_INVALIDARG; }
// save remote client RTP address/port
HRESULT HResult = E_FAIL; HResult = GetH245TransportInfo( H2250Params.mediaChannel, DestRTPIPv4Address, DestRTPPort);
if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("can't get media channel (RTP) address/port, returning 0x%x\n"), HResult); return HResult; } _ASSERTE(S_OK == HResult);
// save remote client RTP address/port
HResult = GetH245TransportInfo( H2250Params.mediaControlChannel, DestRTCPIPv4Address, DestRTCPPort);
if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("can't get media control channel (RTCP) address/port, ") _T("returning 0x%x\n"), HResult); return HResult; } _ASSERTE(S_OK == HResult);
// if there is a session id, save it
if (sessionID_present & H2250Params.bit_mask) { // the PDU stores the session ID as an unsigned short
// although the ITU spec requires it to be a BYTE value [0..255]
// the cast to BYTE is intentional
_ASSERTE(255 >= H2250Params.sessionID); SessionId = (BYTE)H2250Params.sessionID;
// the session id must be non-zero
if (0 == SessionId) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("has a session id of 0, returning E_INVALIDARG\n")); return E_INVALIDARG; } } else { // if no session id is supplied, the source must have supplied
// a non-zero session id in OpenLogicalChannel
if (0 == SessionId) { DebugF( _T("RTP_LOGICAL_CHANNEL::CheckOpenLogicalChannelAckPDU, ") _T("the source supplied a session id of 0 and the dest hasn't") _T("supplied one, returning E_INVALIDARG\n")); return E_INVALIDARG; } }
return HResult; }
HRESULT RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU( IN MultimediaSystemControlMessage *pH245pdu ) /*++
Routine Description:
Arguments: pH245pdu - Return Values:
S_OK on success. E_INVALIDARG if the PDU is invalid.
--*/ { HRESULT HResult = E_FAIL; switch(m_LogicalChannelState) { case LC_STATE_OPEN_RCVD: { HResult = CheckOpenLogicalChannelAckPDU( *pH245pdu, m_SessionId, m_DestRTPIPv4Address, m_DestRTPPort, m_DestRTCPIPv4Address, m_DestRTCPPort ); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU") _T("(&%x), can't process OpenLogicalChannelAck, returning 0x%x\n"), pH245pdu, HResult); return HResult; } _ASSERTE(S_OK == HResult);
HResult = OpenNATMappings(); if (FAILED(HResult)) { DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU") _T("(&%x), can't process OpenLogicalChannelAck, returning 0x%x\n"), pH245pdu, HResult); return HResult; } _ASSERTE(S_OK == HResult);
OpenLogicalChannelAck &OlcAckPDU = pH245pdu->u.response.u.openLogicalChannelAck; H2250LogicalChannelAckParameters &H2250Params = OlcAckPDU.forwardMultiplexAckParameters.u.h2250LogicalChannelAckParameters;
// replace the RTP address/port
// with the H.245 address and RTP port
FillH245TransportAddress( m_OwnSourceIPv4Address, m_OwnSourceRecvRTPPort, H2250Params.mediaChannel );
// replace the RTCP address/port
// with the h245 address and RTCP port
FillH245TransportAddress( m_OwnSourceIPv4Address, m_OwnSourceRecvRTCPPort, H2250Params.mediaControlChannel);
// reset timer, we must have one (ignore error code if any)
_ASSERTE(NULL != m_TimerHandle); TimprocCancelTimer(); DebugF (_T("RTP : 0x%x cancelled timer.\n"), &GetCallBridge ());
// trasition to LC_STATE_OPEN_ACK_RCVD
m_LogicalChannelState = LC_STATE_OPEN_ACK_RCVD; } break;
case LC_STATE_CLOSE_RCVD: { // if we have received a close logical channel PDU, we must throw
// OLC ACKs away and continue to wait
DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU") _T("(&%x), in close state %d, returning E_INVALIDARG\n"), pH245pdu, m_LogicalChannelState); return E_INVALIDARG; } break;
case LC_STATE_NOT_INIT: case LC_STATE_OPEN_ACK_RCVD: case LC_STATE_OPENED_CLOSE_RCVD: default: { DebugF( _T("RTP_LOGICAL_CHANNEL::ProcessOpenLogicalChannelAckPDU") _T("(&%x), in state %d, returning E_UNEXPECTED"), pH245pdu, m_LogicalChannelState); _ASSERTE(FALSE); return E_UNEXPECTED; } break; };
return HResult; }
|