diff options
author | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2013-10-03 15:51:58 +0300 |
---|---|---|
committer | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2013-10-03 15:51:58 +0300 |
commit | 7a957a5ad5a6a0912c97cb7fac34b75f408104db (patch) | |
tree | fa56b79405a07104357a88c6067a504f51ccea9a /src/net/java/sip/communicator/service/protocol/media | |
parent | 5568ab8f898fa51078b4ce4aae66ed74b53efe8e (diff) | |
download | jitsi-7a957a5ad5a6a0912c97cb7fac34b75f408104db.zip jitsi-7a957a5ad5a6a0912c97cb7fac34b75f408104db.tar.gz jitsi-7a957a5ad5a6a0912c97cb7fac34b75f408104db.tar.bz2 |
Adds support for DTLS-SRTP with SIP.
Diffstat (limited to 'src/net/java/sip/communicator/service/protocol/media')
3 files changed, 127 insertions, 33 deletions
diff --git a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java index 11fcf31..9780393 100644 --- a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java @@ -13,8 +13,8 @@ import java.util.*; import java.util.List; import net.java.sip.communicator.service.protocol.*; - import net.java.sip.communicator.util.*; + import org.jitsi.service.neomedia.*; import org.jitsi.service.neomedia.codec.*; import org.jitsi.service.neomedia.control.*; @@ -980,7 +980,7 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>> * @return the <tt>SrtpControl</tt>s of the <tt>MediaStream</tt>s of this * instance */ - protected Map<MediaTypeSrtpControl, SrtpControl> getSrtpControls() + protected SrtpControls getSrtpControls() { return mediaHandler.getSrtpControls(this); } @@ -1443,6 +1443,24 @@ public abstract class CallPeerMediaHandler<T extends MediaAwareCallPeer<?,?,?>> return mediaHandler.processKeyFrameRequest(this); } + protected void removeAndCleanupOtherSrtpControls( + MediaType mediaType, + SrtpControlType srtpControlType) + { + SrtpControls srtpControls = getSrtpControls(); + + for (SrtpControlType i : SrtpControlType.values()) + { + if (!i.equals(srtpControlType)) + { + SrtpControl e = srtpControls.remove(mediaType, i); + + if (e != null) + e.cleanup(); + } + } + } + /** * Unregisters a specific <tt>VideoListener</tt> from this instance so that * it stops receiving notifications from it about changes in the diff --git a/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java index 62ecfa6..4b5db9e 100644 --- a/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java +++ b/src/net/java/sip/communicator/service/protocol/media/MediaHandler.java @@ -138,8 +138,8 @@ public class MediaHandler /** * The <tt>SrtpControl</tt>s of the <tt>MediaStream</tt>s of this instance. */ - private final SortedMap<MediaTypeSrtpControl, SrtpControl> srtpControls - = new TreeMap<MediaTypeSrtpControl, SrtpControl>(); + private final SrtpControls srtpControls + = new SrtpControls(); private final SrtpListener srtpListener = new SrtpListener() @@ -597,19 +597,7 @@ public class MediaHandler } // Clean up the SRTP controls used for the associated Call. - Iterator<Map.Entry<MediaTypeSrtpControl, SrtpControl>> iter - = srtpControls.entrySet().iterator(); - - while (iter.hasNext()) - { - Map.Entry<MediaTypeSrtpControl, SrtpControl> entry = iter.next(); - - if (entry.getKey().mediaType == mediaType) - { - entry.getValue().cleanup(); - iter.remove(); - } - } + callPeerMediaHandler.removeAndCleanupOtherSrtpControls(mediaType, null); } /** @@ -771,8 +759,8 @@ public class MediaHandler for(SrtpControlType srtpControlType : SrtpControlType.values()) { SrtpControl srtpControl - = getSrtpControls(callPeerMediaHandler).get( - new MediaTypeSrtpControl(mediaType, srtpControlType)); + = getSrtpControls(callPeerMediaHandler) + .get(mediaType, srtpControlType); if((srtpControl != null) && srtpControl.getSecureCommunicationStatus()) @@ -798,8 +786,7 @@ public class MediaHandler * @return the <tt>SrtpControl</tt>s of the <tt>MediaStream</tt>s of this * instance */ - Map<MediaTypeSrtpControl, SrtpControl> getSrtpControls( - CallPeerMediaHandler<?> callPeerMediaHandler) + SrtpControls getSrtpControls(CallPeerMediaHandler<?> callPeerMediaHandler) { return srtpControls; } @@ -884,17 +871,7 @@ public class MediaHandler MediaService mediaService = ProtocolMediaActivator.getMediaService(); - /* - * The default SrtpControlType is ZRTP. But if a SrtpControl exists - * already, it determines the SrtpControlType. - */ - SrtpControlType srtpControlType - = (srtpControls.size() > 0) - ? srtpControls.firstKey().srtpControlType - : SrtpControlType.ZRTP; - MediaTypeSrtpControl mediaTypeSrtpControl - = new MediaTypeSrtpControl(mediaType, srtpControlType); - SrtpControl srtpControl = srtpControls.get(mediaTypeSrtpControl); + SrtpControl srtpControl = srtpControls.findFirst(mediaType); // If a SrtpControl does not exist yet, create a default one. if (srtpControl == null) @@ -905,7 +882,9 @@ public class MediaHandler * Consequently, it needs to be linked to the srtpControls Map. */ stream = mediaService.createMediaStream(connector, device); - srtpControls.put(mediaTypeSrtpControl, stream.getSrtpControl()); + srtpControl = stream.getSrtpControl(); + if (srtpControl != null) + srtpControls.set(mediaType, srtpControl); } else { diff --git a/src/net/java/sip/communicator/service/protocol/media/SrtpControls.java b/src/net/java/sip/communicator/service/protocol/media/SrtpControls.java new file mode 100644 index 0000000..0e88007 --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/media/SrtpControls.java @@ -0,0 +1,97 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.service.protocol.media; + +import org.jitsi.service.neomedia.*; + +/** + * Represents a sorted set of <tt>SrtpControl</tt> implementations. + * + * @author Lyubomir Marinov + */ +public class SrtpControls +{ + private static final SrtpControlType[] SORTED_SRTP_CONTROL_TYPES + = { + SrtpControlType.ZRTP, + SrtpControlType.DTLS_SRTP, + SrtpControlType.MIKEY, + SrtpControlType.SDES + }; + + /** + * The <tt>SrtpControl</tt> implementations which are the elements of this + * sorted set. + */ + private final SrtpControl[][] elements + = new SrtpControl + [MediaType.values().length] + [SrtpControlType.values().length]; + + /** + * Initializes a new <tt>SrtpControls</tt> instance. + */ + public SrtpControls() + { + } + + public SrtpControl findFirst(MediaType mediaType) + { + SrtpControl element = null; + + for (SrtpControlType srtpControlType : SORTED_SRTP_CONTROL_TYPES) + { + element = get(mediaType, srtpControlType); + if (element != null) + break; + } + return element; + } + + public SrtpControl get(MediaType mediaType, SrtpControlType srtpControlType) + { + return elements[mediaType.ordinal()][srtpControlType.ordinal()]; + } + + public SrtpControl getOrCreate( + MediaType mediaType, + SrtpControlType srtpControlType) + { + SrtpControl[] elements = this.elements[mediaType.ordinal()]; + int index = srtpControlType.ordinal(); + SrtpControl element = elements[index]; + + if (element == null) + { + element + = ProtocolMediaActivator.getMediaService().createSrtpControl( + srtpControlType); + if (element != null) + elements[index] = element; + } + return element; + } + + public SrtpControl remove( + MediaType mediaType, + SrtpControlType srtpControlType) + { + SrtpControl[] elements = this.elements[mediaType.ordinal()]; + int index = srtpControlType.ordinal(); + SrtpControl element = elements[index]; + + elements[index] = null; + return element; + } + + public void set(MediaType mediaType, SrtpControl element) + { + SrtpControlType srtpControlType = element.getSrtpControlType(); + + elements[mediaType.ordinal()][srtpControlType.ordinal()] = element; + } +} |