Migrates SIP over to neomedia. (Work in progress). Parsing remote RTP+RTCP target from SDP

cusax-fix
Emil Ivov 16 years ago
parent 9300737244
commit d8e439eb41

@ -36,6 +36,11 @@ public class SdpUtils
*/
private static final SdpFactory sdpFactory = SdpFactory.getInstance();
/**
* The name of the SDP attribute that contains RTCP address and port.
*/
private static final String RTCP_ATTR = "rtcp";
/**
* Creates an empty instance of a <tt>SessionDescription</tt> with
* preinitialized <tt>s</tt>, <tt>v</tt>, and <tt>t</tt> parameters.
@ -448,10 +453,11 @@ public static MediaStreamTarget extractDefaultTarget(
"Couldn't extract connection address.", exc);
}
InetAddress inetAddress = null;
InetAddress rtpAddress = null;
try
{
inetAddress = NetworkUtils.getInetAddress(address);
rtpAddress = NetworkUtils.getInetAddress(address);
}
catch (UnknownHostException exc)
{
@ -459,11 +465,148 @@ public static MediaStreamTarget extractDefaultTarget(
"Failed to parse address " + address, exc);
}
//ip address (media or session level c)
//rtp port
//rtcp port ( and address? )
return null;
int rtpPort;
try
{
rtpPort = mediaDesc.getMedia().getMediaPort();
}
catch (SdpParseException exc)
{
throw new IllegalArgumentException(
"Couldn't extract port from a media description.", exc);
}
InetSocketAddress rtpTarget = new InetSocketAddress(
rtpAddress, rtpPort);
//by default RTP and RTCP will be going to the same address (which is
//actually going to be the case 99% of the time.
InetAddress rtcpAddress = rtpAddress;
int rtcpPort = rtpPort + 1;
String rtcpAttributeValue;
try
{
rtcpAttributeValue = mediaDesc.getAttribute(RTCP_ATTR);
}
catch (SdpParseException exc)
{
//this can't actually happen as there's no parsing here. the
//exception is just inherited from the jain-sdp api. we are
//rethrowing only because there's nothing else we could do.
throw new IllegalArgumentException(
"Couldn't extract attribute value.", exc);
}
InetSocketAddress rtcpTarget = determineRtcpAddress(
rtcpAttributeValue, rtcpAddress, rtcpPort);
return new MediaStreamTarget(rtpTarget, rtcpTarget);
}
/**
* Determines the address and port where our interlocutor would like to
* receive RTCP. The method uses the port, and possibly address, indicated
* in the <tt>rtcpAttribute</tt> or returns the default
* <tt>defaultAddr:defaultPort</tt> in case <tt>rtcpAttribute</tt> is null.
* We also use <tt>defaultAddr</tt> in case <tt>rtcpAttribute</tt> only
* contains a port number and no address.
*
* @param rtcpAttrValue the SDP <tt>Attribute</tt> where we are supposed
* to look for an RTCP address and port (could be <tt>null</tt> if there
* was no such field in the incoming SDP);
* @param defaultAddr the address that we should use to construct the result
* <tt>InetSocketAddress</tt> in case <tt>rtcpAttribute</tt> is
* <tt>null</tt> or in case <tt>rtcpAttribute</tt> only contains a port
* number.
* @param defaultPort the port that we should use to construct the result
* <tt>InetSocketAddress</tt> in case <tt>rtcpAttribute</tt> is
* <tt>null</tt>.
*
* @return an <tt>InetSocketAddress</tt> instance indicating the destination
* where should be sending RTCP.
*
* @throws IllegalArgumentException if an error occurs while parsing the
* <tt>rtcpAttribute</tt>.
*/
private static InetSocketAddress determineRtcpAddress(
String rtcpAttrValue,
InetAddress defaultAddr,
int defaultPort)
throws IllegalArgumentException
{
if (rtcpAttrValue == null)
{
//no explicit RTCP attribute means RTCP goes to RTP.port + 1
return new InetSocketAddress(defaultAddr, defaultPort);
}
if (rtcpAttrValue == null || rtcpAttrValue.trim().length() == 0)
{
//invalid attribute. return default port.
return new InetSocketAddress(defaultAddr, defaultPort);
}
StringTokenizer rtcpTokenizer
= new StringTokenizer(rtcpAttrValue.trim(), " ");
// RTCP attribtutes are supposed to look this way:
// rtcp-attribute = "a=rtcp:" port [nettype space addrtype space
// connection-address] CRLF
// which gives us 2 cases: port only (1 token), or port+addr (4 tokens)
int tokenCount = rtcpTokenizer.countTokens();
//a single token means we only have a port number.
int rtcpPort;
try
{
rtcpPort = Integer.parseInt( rtcpTokenizer.nextToken() );
}
catch (NumberFormatException exc)
{
//rtcp attribute is messed up.
throw new IllegalArgumentException(
"Error while parsing rtcp attribute: " + rtcpAttrValue, exc);
}
if ( tokenCount == 1 )
{
//that was all then. ready to return.
return new InetSocketAddress(defaultAddr, rtcpPort);
}
else if ( tokenCount == 4)
{
rtcpTokenizer.nextToken();//nettype
rtcpTokenizer.nextToken();//addrtype
//address
String rtcpAddrStr = rtcpTokenizer.nextToken();
InetAddress rtcpAddress = null;
try
{
rtcpAddress = NetworkUtils.getInetAddress(rtcpAddrStr);
}
catch (UnknownHostException exc)
{
throw new IllegalArgumentException(
"Failed to parse address " + rtcpAddress, exc);
}
return new InetSocketAddress(rtcpAddress, rtcpPort);
}
else
{
//rtcp attribute is messed up: too many tokens.
throw new IllegalArgumentException(
"Error while parsing rtcp attribute: "
+ rtcpAttrValue + ". Too many tokens! ("
+ tokenCount + ")");
}
}
public static MediaDirection getDirection( MediaDescription mediaDesc )
@ -576,7 +719,7 @@ public static MediaDescription createMediaDescription(
if ((rtpPort + 1) != rtcpPort)
{
Attribute rtcpAttr = sdpFactory.createAttribute("rtcp:", Integer
Attribute rtcpAttr = sdpFactory.createAttribute(RTCP_ATTR, Integer
.toString(rtcpPort));
mediaAttributes.add(rtcpAttr);
}

Loading…
Cancel
Save