Adds support for DTLS-SRTP with XMPP.

cusax-fix
Lyubomir Marinov 13 years ago
parent 9eec6e2305
commit ba4e6875f9

@ -6,8 +6,6 @@
*/
package net.java.sip.communicator.impl.protocol.jabber;
import ch.imvs.sdes4j.srtp.*;
import java.util.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
@ -18,11 +16,14 @@
import org.jitsi.service.neomedia.*;
import org.jivesoftware.smack.packet.*;
import ch.imvs.sdes4j.srtp.*;
/**
* An implementation of the <tt>CallPeerMediaHandler</tt> abstract class for the
* common part of Jabber and Gtalk protocols.
*
* @author Vincent Lucas
* @author Lyubomir Marinov
*/
public abstract class AbstractCallPeerMediaHandlerJabberGTalkImpl
<T extends AbstractCallPeerJabberGTalkImpl<?,?,?>>
@ -84,7 +85,7 @@ public void setLocalInputEvtAware(boolean enable)
* contains the PAYLOAD-TYPE and (more important here) the ENCRYPTION.
* @param mediaType The type of media (AUDIO or VIDEO).
*/
protected void addZRTPAdvertisedEncryptions(
protected void addZrtpAdvertisedEncryptions(
boolean isInitiator,
RtpDescriptionPacketExtension description,
MediaType mediaType)
@ -131,7 +132,7 @@ && getPeer().getCall().isSipZrtpAttribute())
* contains the PAYLOAD-TYPE and (more important here) the ENCRYPTION.
* @param mediaType The type of media (AUDIO or VIDEO).
*/
protected void addSDESAdvertisedEncryptions(
protected void addSDesAdvertisedEncryptions(
boolean isInitiator,
RtpDescriptionPacketExtension description,
MediaType mediaType)
@ -380,7 +381,7 @@ protected boolean setSDesEncryptionToDescription(
= accountID.getAccountPropertyString(
ProtocolProviderFactory.SDES_CIPHER_SUITES);
if (ciphers == null)
if (ciphers == null)
{
ciphers =
JabberActivator.getResources().getSettingsString(
@ -475,8 +476,8 @@ protected boolean setSDesEncryptionToDescription(
* @param localDescription The element containing the media DESCRIPTION and
* its encryption.
* @param remoteDescription The element containing the media DESCRIPTION and
* its encryption for the remote peer. Null, if the local peer is the
* initiator of the call.
* its encryption for the remote peer; <tt>null</tt> if the local peer is
* the initiator of the call.
*/
protected void setAndAddPreferredEncryptionProtocol(
MediaType mediaType,
@ -497,41 +498,71 @@ protected void setAndAddPreferredEncryptionProtocol(
ProtocolProviderFactory.ENCRYPTION_PROTOCOL.length()
+ 1);
// SDES
if(SDesControl.PROTO_NAME.equals(protoName))
if (setAndAddPreferredEncryptionProtocol(
protoName,
mediaType,
localDescription,
remoteDescription))
{
// Stop once an encryption advertisement has been chosen.
return;
}
}
}
/**
* Selects a specific encryption protocol if it is the preferred (only used
* by the callee).
*
* @param protoName the name of the encryption protocol which is to be
* selected
* @param mediaType The type of media (AUDIO or VIDEO).
* @param localDescription The element containing the media DESCRIPTION and
* its encryption.
* @param remoteDescription The element containing the media DESCRIPTION and
* its encryption for the remote peer; <tt>null</tt> if the local peer is
* the initiator of the call.
* @return <tt>true</tt> if the specified encryption protocol has been
* selected; <tt>false</tt>, otherwise
*/
protected boolean setAndAddPreferredEncryptionProtocol(
String protoName,
MediaType mediaType,
RtpDescriptionPacketExtension localDescription,
RtpDescriptionPacketExtension remoteDescription)
{
// SDES
if(SDesControl.PROTO_NAME.equals(protoName))
{
addSDesAdvertisedEncryptions(
false,
remoteDescription,
mediaType);
if(setSDesEncryptionToDescription(
mediaType,
localDescription,
remoteDescription))
{
// Stop once an encryption advertisement has been chosen.
return true;
}
}
// ZRTP
else if(ZrtpControl.PROTO_NAME.equals(protoName))
{
if(setZrtpEncryptionToDescription(
mediaType,
localDescription,
remoteDescription))
{
addSDESAdvertisedEncryptions(
addZrtpAdvertisedEncryptions(
false,
remoteDescription,
mediaType);
if(setSDesEncryptionToDescription(
mediaType,
localDescription,
remoteDescription))
{
// Stop once an encryption advertisement has been chosen.
return;
}
}
// ZRTP
else if(ZrtpControl.PROTO_NAME.equals(protoName))
{
boolean isZRTPAddedToDescription
= setZrtpEncryptionToDescription(
mediaType,
localDescription,
remoteDescription);
if(isZRTPAddedToDescription)
{
addZRTPAdvertisedEncryptions(
false,
remoteDescription,
mediaType);
// Stop once an encryption advertisement has been chosen.
return;
}
// Stop once an encryption advertisement has been chosen.
return true;
}
}
return false;
}
}

@ -979,7 +979,7 @@ public void processTransportInfo(JingleIQ jingleIQ)
}
getMediaHandler().processTransportInfo(
jingleIQ.getContentList());
jingleIQ.getContentList());
}
catch (OperationFailedException ofe)
{

@ -362,8 +362,8 @@ public void processAnswer(RtpDescriptionPacketExtension answer)
if(format == null)
continue;
addZRTPAdvertisedEncryptions(true, answer, mediaType);
addSDESAdvertisedEncryptions(true, answer, mediaType);
addZrtpAdvertisedEncryptions(true, answer, mediaType);
addSDesAdvertisedEncryptions(true, answer, mediaType);
// stream connector
StreamConnector connector
@ -521,7 +521,6 @@ public RtpDescriptionPacketExtension createDescription()
mediaType,
description,
null);
//ZRTP
setZrtpEncryptionToDescription(
mediaType,

@ -267,6 +267,8 @@ && isRTPTranslationEnabled(mediaType)))
RtpDescriptionPacketExtension description
= JingleUtils.getRtpDescription(content);
// DTLS-SRTP
setDtlsEncryptionToContent(mediaType, content, null);
//SDES
// It is important to set SDES before ZRTP in order to make GTALK
// application able to work with SDES.
@ -320,13 +322,13 @@ private ContentPacketExtension createContentForOffer(
{
ContentPacketExtension content
= JingleUtils.createDescription(
ContentPacketExtension.CreatorEnum.initiator,
supportedFormats.get(0).getMediaType().toString(),
JingleUtils.getSenders(direction, !getPeer().isInitiator()),
supportedFormats,
supportedExtensions,
getDynamicPayloadTypes(),
getRtpExtensionsRegistry());
ContentPacketExtension.CreatorEnum.initiator,
supportedFormats.get(0).getMediaType().toString(),
JingleUtils.getSenders(direction, !getPeer().isInitiator()),
supportedFormats,
supportedExtensions,
getDynamicPayloadTypes(),
getRtpExtensionsRegistry());
this.localContentMap.put(content.getName(), content);
return content;
@ -390,6 +392,8 @@ && isRTPTranslationEnabled(mediaType)))
RtpDescriptionPacketExtension description
= JingleUtils.getRtpDescription(content);
// DTLS-SRTP
setDtlsEncryptionToContent(mediaType, content, null);
//SDES
// It is important to set SDES before ZRTP in order to make
// GTALK application able to work with SDES.
@ -542,11 +546,10 @@ public Iterable<ContentPacketExtension> generateSessionAccept()
//user answered an incoming call so we go through whatever content
//entries we are initializing and init their corresponding streams
// First parse content so we know how may streams,
// and what type of content we have
Map<ContentPacketExtension, RtpDescriptionPacketExtension> contents
= new HashMap<ContentPacketExtension,
RtpDescriptionPacketExtension>();
// First parse content so we know how many streams and what type of
// content we have
Map<ContentPacketExtension,RtpDescriptionPacketExtension> contents
= new HashMap<ContentPacketExtension,RtpDescriptionPacketExtension>();
for(ContentPacketExtension ourContent : sessAccept)
{
@ -1065,7 +1068,6 @@ private List<ContentPacketExtension> harvestCandidates(
throws OperationFailedException
{
long startCandidateHarvestTime = System.currentTimeMillis();
TransportManagerJabberImpl transportManager = getTransportManager();
if (remote == null)
@ -1090,11 +1092,19 @@ private List<ContentPacketExtension> harvestCandidates(
}
long stopCandidateHarvestTime = System.currentTimeMillis();
long candidateHarvestTime
= stopCandidateHarvestTime - startCandidateHarvestTime;
if (logger.isInfoEnabled())
logger.info("End candidate harvest within "
+ candidateHarvestTime + " ms");
{
long candidateHarvestTime
= stopCandidateHarvestTime - startCandidateHarvestTime;
logger.info(
"End candidate harvest within " + candidateHarvestTime
+ " ms");
}
setDtlsEncryptionToTransports(local);
/*
* TODO Ideally, we wouldn't wrap up that quickly. We need to revisit
* this.
@ -1220,7 +1230,7 @@ public void processAnswer(List<ContentPacketExtension> answer)
RtpDescriptionPacketExtension description
= JingleUtils.getRtpDescription(content);
MediaType mediaType
= MediaType.parseString( description.getMedia() );
= MediaType.parseString(description.getMedia());
if(answer.size() > 1)
{
@ -1408,8 +1418,9 @@ private void processContent(
logger);
}
addZRTPAdvertisedEncryptions(true, description, mediaType);
addSDESAdvertisedEncryptions(true, description, mediaType);
addZrtpAdvertisedEncryptions(true, description, mediaType);
addSDesAdvertisedEncryptions(true, description, mediaType);
addDtlsAdvertisedEncryptions(true, content, mediaType);
StreamConnector connector
= transportManager.getStreamConnector(mediaType);
@ -1573,7 +1584,9 @@ public void processOffer(List<ContentPacketExtension> offer)
// intersect the MediaFormats of our device with remote ones
List<MediaFormat> mutuallySupportedFormats
= intersectFormats(remoteFormats, getLocallySupportedFormats(dev));
= intersectFormats(
remoteFormats,
getLocallySupportedFormats(dev));
// check whether we will be exchanging any RTP extensions.
List<RTPExtension> offeredRTPExtensions
@ -1649,14 +1662,14 @@ public void processOffer(List<ContentPacketExtension> offer)
getDynamicPayloadTypes(),
getRtpExtensionsRegistry());
RtpDescriptionPacketExtension localDescription =
JingleUtils.getRtpDescription(ourContent);
// Sets ZRTP or SDES, depending on the preferences for this account.
/*
* Sets ZRTP, SDES or DTLS-SRTP depending on the preferences for
* this account.
*/
setAndAddPreferredEncryptionProtocol(
mediaType,
localDescription,
description);
ourContent,
content);
// Got a content which has inputevt. It means that the peer requests
// a desktop sharing session so tell it we support inputevt.
@ -2163,4 +2176,343 @@ public void setLocallyOnHold(boolean locallyOnHold)
}
}
/**
* Detects and adds DTLS-SRTP available encryption method present in the
* content (description) given in parameter.
*
* @param isInitiator <tt>true</tt> if the local call instance is the
* initiator of the call; <tt>false</tt>, otherwise.
* @param content The CONTENT element of the JINGLE element which contains
* the TRANSPORT element
* @param mediaType The type of media (AUDIO or VIDEO).
*/
private boolean addDtlsAdvertisedEncryptions(
boolean isInitiator,
ContentPacketExtension content,
MediaType mediaType)
{
IceUdpTransportPacketExtension remoteTransport
= content.getFirstChildOfType(IceUdpTransportPacketExtension.class);
SrtpControls srtpControls = getSrtpControls();
boolean b = false;
if (remoteTransport != null)
{
List<DtlsFingerprintPacketExtension> remoteFingerpintPEs
= remoteTransport.getChildExtensionsOfType(
DtlsFingerprintPacketExtension.class);
if (!remoteFingerpintPEs.isEmpty())
{
AccountID accountID
= getPeer().getProtocolProvider().getAccountID();
if (accountID.getAccountPropertyBoolean(
ProtocolProviderFactory.DEFAULT_ENCRYPTION,
true)
&& accountID.isEncryptionProtocolEnabled(
DtlsControl.PROTO_NAME))
{
Map<String,String> remoteFingerprints
= new LinkedHashMap<String,String>();
for (DtlsFingerprintPacketExtension remoteFingerprintPE
: remoteFingerpintPEs)
{
String remoteFingerprint
= remoteFingerprintPE.getFingerprint();
String remoteHash = remoteFingerprintPE.getHash();
remoteFingerprints.put(
remoteHash,
remoteFingerprint);
}
DtlsControl dtlsControl;
int dtlsProtocol;
if (isInitiator)
{
dtlsControl
= (DtlsControl)
srtpControls.get(
mediaType,
SrtpControlType.DTLS_SRTP);
dtlsProtocol = DtlsControl.DTLS_SERVER_PROTOCOL;
}
else
{
dtlsControl
= (DtlsControl)
srtpControls.getOrCreate(
mediaType,
SrtpControlType.DTLS_SRTP);
dtlsProtocol = DtlsControl.DTLS_CLIENT_PROTOCOL;
}
if (dtlsControl != null)
{
dtlsControl.setDtlsProtocol(dtlsProtocol);
dtlsControl.setRemoteFingerprints(remoteFingerprints);
removeAndCleanupOtherSrtpControls(
mediaType,
SrtpControlType.DTLS_SRTP);
addAdvertisedEncryptionMethod(
SrtpControlType.DTLS_SRTP);
b = true;
}
}
}
}
/*
* If they haven't advertised DTLS-SRTP in their (media) description,
* then DTLS-SRTP shouldn't be functioning as far as we're concerned.
*/
if (!b)
{
SrtpControl dtlsControl
= srtpControls.get(mediaType, SrtpControlType.DTLS_SRTP);
if (dtlsControl != null)
{
srtpControls.remove(mediaType, SrtpControlType.DTLS_SRTP);
dtlsControl.cleanup();
}
}
return b;
}
/**
* Selects the preferred encryption protocol (only used by the callee).
*
* @param mediaType The type of media (AUDIO or VIDEO).
* @param localContent The element containing the media DESCRIPTION and
* its encryption.
* @param remoteContent The element containing the media DESCRIPTION and
* its encryption for the remote peer; <tt>null</tt> if the local peer is
* the initiator of the call.
*/
private void setAndAddPreferredEncryptionProtocol(
MediaType mediaType,
ContentPacketExtension localContent,
ContentPacketExtension remoteContent)
{
List<String> preferredEncryptionProtocols
= getPeer()
.getProtocolProvider()
.getAccountID()
.getSortedEnabledEncryptionProtocolList();
for (String preferredEncryptionProtocol : preferredEncryptionProtocols)
{
String protoName
= preferredEncryptionProtocol.substring(
ProtocolProviderFactory.ENCRYPTION_PROTOCOL.length()
+ 1);
// DTLS-SRTP
if (DtlsControl.PROTO_NAME.equals(protoName))
{
addDtlsAdvertisedEncryptions(
false,
remoteContent,
mediaType);
if (setDtlsEncryptionToContent(
mediaType,
localContent,
remoteContent))
{
// Stop once an encryption advertisement has been chosen.
return;
}
}
else
{
RtpDescriptionPacketExtension localDescription
= (localContent == null)
? null
: JingleUtils.getRtpDescription(localContent);
RtpDescriptionPacketExtension remoteDescription
= (remoteContent == null)
? null
: JingleUtils.getRtpDescription(remoteContent);
if (setAndAddPreferredEncryptionProtocol(
protoName,
mediaType,
localDescription,
remoteDescription))
{
// Stop once an encryption advertisement has been chosen.
return;
}
}
}
}
/**
* Sets DTLS-SRTP element(s) to the TRANSPORT element of the CONTENT for a
* given media.
*
* @param mediaType The type of media we are modifying the CONTENT to
* integrate the DTLS-SRTP element(s).
* @param localContent The element containing the media CONTENT and its
* TRANSPORT.
* @param remoteContent The element containing the media CONTENT and its
* TRANSPORT for the remote peer. Null, if the local peer is the initiator
* of the call.
* @return <tt>true</tt> if any DTLS-SRTP element has been added to the
* specified <tt>localContent</tt>; <tt>false</tt>, otherwise.
*/
private boolean setDtlsEncryptionToContent(
MediaType mediaType,
ContentPacketExtension localContent,
ContentPacketExtension remoteContent)
{
CallPeerJabberImpl peer = getPeer();
ProtocolProviderServiceJabberImpl protocolProvider
= peer.getProtocolProvider();
AccountID accountID = protocolProvider.getAccountID();
SrtpControls srtpControls = getSrtpControls();
boolean b = false;
if (accountID.getAccountPropertyBoolean(
ProtocolProviderFactory.DEFAULT_ENCRYPTION,
true)
&& accountID.isEncryptionProtocolEnabled(
DtlsControl.PROTO_NAME))
{
boolean addFingerprintToLocalTransport;
if (remoteContent == null) // initiator
{
addFingerprintToLocalTransport
= protocolProvider.isFeatureSupported(
peer.getAddress(),
ProtocolProviderServiceJabberImpl
.URN_XMPP_JINGLE_DTLS_SRTP);
}
else // responder
{
addFingerprintToLocalTransport
= addDtlsAdvertisedEncryptions(
false,
remoteContent,
mediaType);
}
if (addFingerprintToLocalTransport)
{
DtlsControl dtlsControl
= (DtlsControl)
srtpControls.getOrCreate(
mediaType,
SrtpControlType.DTLS_SRTP);
if (dtlsControl != null)
{
int dtlsProtocol
= (remoteContent == null)
? DtlsControl.DTLS_SERVER_PROTOCOL
: DtlsControl.DTLS_CLIENT_PROTOCOL;
dtlsControl.setDtlsProtocol(dtlsProtocol);
b = true;
setDtlsEncryptionToTransport(mediaType, localContent);
}
}
}
/*
* If we haven't advertised DTLS-SRTP in our (media) description, then
* DTLS-SRTP shouldn't be functioning as far as we're concerned.
*/
if (!b)
{
SrtpControl dtlsControl
= srtpControls.get(mediaType, SrtpControlType.DTLS_SRTP);
if (dtlsControl != null)
{
srtpControls.remove(mediaType, SrtpControlType.DTLS_SRTP);
dtlsControl.cleanup();
}
}
return b;
}
/**
* Sets DTLS-SRTP element(s) to the TRANSPORT element of the CONTENT for a
* given media.
*
* @param mediaType The type of media we are modifying the CONTENT to
* integrate the DTLS-SRTP element(s).
* @param localContent The element containing the media CONTENT and its
* TRANSPORT.
*/
private void setDtlsEncryptionToTransport(
MediaType mediaType,
ContentPacketExtension localContent)
{
SrtpControls srtpControls = getSrtpControls();
DtlsControl dtlsControl
= (DtlsControl)
srtpControls.get(
mediaType,
SrtpControlType.DTLS_SRTP);
if (dtlsControl != null)
{
IceUdpTransportPacketExtension localTransport
= localContent.getFirstChildOfType(
IceUdpTransportPacketExtension.class);
if (localTransport != null)
{
String localFingerprint = dtlsControl.getLocalFingerprint();
String localFingerprintHashFunction
= dtlsControl.getLocalFingerprintHashFunction();
{
DtlsFingerprintPacketExtension localFingerprintPE
= localTransport.getFirstChildOfType(
DtlsFingerprintPacketExtension.class);
if (localFingerprintPE == null)
{
localFingerprintPE
= new DtlsFingerprintPacketExtension();
localTransport.addChildExtension(
localFingerprintPE);
}
localFingerprintPE.setFingerprint(localFingerprint);
localFingerprintPE.setHash(
localFingerprintHashFunction);
}
}
}
}
/**
* Sets DTLS-SRTP element(s) to the TRANSPORT element of a specified list of
* CONTENT elements.
*
* @param localContents The elements containing the media CONTENT elements
* and their respective TRANSPORT elements.
*/
private void setDtlsEncryptionToTransports(
List<ContentPacketExtension> localContents)
{
for (ContentPacketExtension localContent : localContents)
{
RtpDescriptionPacketExtension description
= JingleUtils.getRtpDescription(localContent);
if (description != null)
{
MediaType mediaType = JingleUtils.getMediaType(localContent);
if (mediaType != null)
setDtlsEncryptionToTransport(mediaType, localContent);
}
}
}
}

@ -14,8 +14,6 @@
import net.java.sip.communicator.service.protocol.jabberconstants.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.util.*;
/**
* The Jabber implementation of the service.protocol.Contact interface.

@ -583,17 +583,18 @@ public void startCandidateHarvest(
transportInfoContent.addChildExtension(
createTransport(stream));
/* We send each media content in separate transport-info.
* It is absolutely not mandatory (we can simply send all
* content in one transport-info) but the XMPP Jingle client
* Empathy (via telepathy-gabble), which is present on many
* Linux distributions and N900 mobile phone, has a bug when
* it receives more than one content in transport-info.
/*
* We send each media content in separate transport-info. It is
* absolutely not mandatory (we can simply send all content in
* one transport-info) but the XMPP Jingle client Empathy (via
* telepathy-gabble), which is present on many Linux
* distributions and N900 mobile phone, has a bug when it
* receives more than one content in transport-info.
*
* The related bug has been fixed in mainstream but the
* Linux distributions have not updated their packages yet.
* That's why we made this modification to be fully
* interoperable with Empathy right now.
* The related bug has been fixed in mainstream but the Linux
* distributions have not updated their packages yet. That's why
* we made this modification to be fully interoperable with
* Empathy right now.
*
* In the future, we will get back to the original behavior:
* sending all content in one transport-info.
@ -1160,7 +1161,8 @@ public void propertyChange(PropertyChangeEvent evt)
transport.removeCandidate(candidate);
Collection<?> childExtensions
= transport.getChildExtensions();
= transport.getChildExtensionsOfType(
CandidatePacketExtension.class);
if ((childExtensions == null) || childExtensions.isEmpty())
{

@ -33,9 +33,10 @@
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.Logger;
import org.jitsi.service.configuration.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.util.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
@ -124,6 +125,13 @@ public class ProtocolProviderServiceJabberImpl
*/
public static final String URN_XMPP_JINGLE_COIN = "urn:xmpp:coin";
/**
* Jingle's Discovery Info URN for &quot;XEP-0320: Use of DTLS-SRTP in
* Jingle Sessions&quot;.
*/
public static final String URN_XMPP_JINGLE_DTLS_SRTP
= "urn:xmpp:jingle:apps:dtls:0";
/**
* Discovery Info URN for classic RFC3264-style Offer/Answer negotiation
* with no support for Trickle ICE and low tolerance to transport/payload
@ -1889,6 +1897,16 @@ private void addJingleFeatures()
// XEP-0251: Jingle Session Transfer
supportedFeatures.add(URN_XMPP_JINGLE_TRANSFER_0);
// XEP-0320: Use of DTLS-SRTP in Jingle Sessions
if (accountID.getAccountPropertyBoolean(
ProtocolProviderFactory.DEFAULT_ENCRYPTION,
true)
&& accountID.isEncryptionProtocolEnabled(
DtlsControl.PROTO_NAME))
{
supportedFeatures.add(URN_XMPP_JINGLE_DTLS_SRTP);
}
}
/**

@ -51,7 +51,7 @@ public abstract class AbstractPacketExtension
/**
* A list of extensions registered with this element.
*/
private List<PacketExtension> childExtensions
private final List<PacketExtension> childExtensions
= new ArrayList<PacketExtension>();
/**

@ -18,7 +18,8 @@
* @author Emil Ivov
* @author Lyubomir Marinov
*/
public class IceUdpTransportPacketExtension extends AbstractPacketExtension
public class IceUdpTransportPacketExtension
extends AbstractPacketExtension
{
/**
* The name of the "transport" element.
@ -128,24 +129,22 @@ public String getUfrag()
@Override
public List<? extends PacketExtension> getChildExtensions()
{
List<PacketExtension> childExtensions
= new ArrayList<PacketExtension>();
List<? extends PacketExtension> superChildExtensions
= super.getChildExtensions();
childExtensions.addAll(superChildExtensions);
synchronized (candidateList)
{
if(candidateList.size() > 0)
{
return candidateList;
}
if (candidateList.size() > 0)
childExtensions.addAll(candidateList);
else if (remoteCandidate != null)
{
List<RemoteCandidatePacketExtension> list
= new ArrayList<RemoteCandidatePacketExtension>();
list.add(remoteCandidate);
return list;
}
childExtensions.add(remoteCandidate);
}
//there are apparently no child elements.
return null;
return childExtensions;
}
/**
@ -191,7 +190,7 @@ public List<CandidatePacketExtension> getCandidateList()
{
synchronized(candidateList)
{
return new ArrayList<CandidatePacketExtension>(this.candidateList);
return new ArrayList<CandidatePacketExtension>(candidateList);
}
}
@ -221,7 +220,7 @@ public RemoteCandidatePacketExtension getRemoteCandidate()
* CandidatePacketExtension}, a {@link RemoteCandidatePacketExtension} or
* something else and then adds it as such.
*
* @param childExtension the extension we'd like to add here.
* @param childExtension the extension we'd like to add here.
*/
@Override
public void addChildExtension(PacketExtension childExtension)
@ -232,5 +231,8 @@ public void addChildExtension(PacketExtension childExtension)
else if(childExtension instanceof CandidatePacketExtension)
addCandidate((CandidatePacketExtension) childExtension);
else if (childExtension instanceof DtlsFingerprintPacketExtension)
super.addChildExtension(childExtension);
}
}

@ -47,6 +47,7 @@ public RawUdpTransportPacketExtension()
@Override
public List<? extends PacketExtension> getChildExtensions()
{
return getCandidateList();
// TODO Auto-generated method stub
return super.getChildExtensions();
}
}

@ -1443,6 +1443,17 @@ public boolean processKeyFrameRequest()
return mediaHandler.processKeyFrameRequest(this);
}
/**
* Removes from this instance and cleans up the <tt>SrtpControl</tt> which
* are not of a specific <tt>SrtpControlType</tt>.
*
* @param mediaType the <tt>MediaType</tt> of the <tt>SrtpControl</tt> to be
* examined
* @param srtpControlType the <tt>SrtpControlType</tt> of the
* <tt>SrtpControl</tt>s to not be removed from this instance and cleaned
* up. If <tt>null</tt>, all <tt>SrtpControl</tt>s are removed from this
* instance and cleaned up
*/
protected void removeAndCleanupOtherSrtpControls(
MediaType mediaType,
SrtpControlType srtpControlType)

Loading…
Cancel
Save