From 79b19ce6202f125586644961b58583199a58779f Mon Sep 17 00:00:00 2001 From: Thiago Camargo Date: Tue, 27 Feb 2007 13:23:21 +0000 Subject: [PATCH] More Refactoring git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7311 b35dd754-fafc-0310-a699-88a17e54d16e --- .../jingle/media/JingleMediaSession.java | 1 - .../smackx/jingle/nat/ICEResolver.java | 165 +++++++++--------- .../smackx/jingle/nat/TransportResolver.java | 10 +- .../jingleaudio/jmf/AudioChannel.java | 2 + .../jingleaudio/jmf/AudioFormatUtils.java | 4 +- .../jingleaudio/jmf/AudioMediaSession.java | 26 ++- .../jingleaudio/jmf/AudioReceiver.java | 6 +- .../jingleaudio/jmf/JmfMediaManager.java | 4 +- .../jingleaudio/jspeex/AudioMediaSession.java | 64 ++++--- .../jingleaudio/jspeex/SpeexMediaManager.java | 29 +-- 10 files changed, 186 insertions(+), 125 deletions(-) diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java index 0af97853f..0bc631c0d 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java @@ -54,7 +54,6 @@ public abstract class JingleMediaSession { this.local = local; this.remote = remote; this.payloadType = payloadType; - initialize(); } /** diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java index e4c52be2d..115fac632 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java @@ -45,6 +45,7 @@ public class ICEResolver extends TransportResolver { long sid; String server = "stun.xten.net"; int port = 3478; + ICENegociator iceNegociator = null; public ICEResolver(XMPPConnection connection, String server, int port) { super(); @@ -58,85 +59,11 @@ public class ICEResolver extends TransportResolver { if (!isResolving() && !isResolved()) { System.out.println("Initialized"); - ICENegociator cc = new ICENegociator((short) 1, server, port); + iceNegociator = new ICENegociator((short) 1, server, port); // gather candidates - cc.gatherCandidateAddresses(); + iceNegociator.gatherCandidateAddresses(); // priorize candidates - cc.prioritizeCandidates(); - - for (Candidate candidate : cc.getSortedCandidates()) - try { - Candidate.CandidateType type = candidate.getCandidateType(); - String typeString = "local"; - if (type.equals(Candidate.CandidateType.ServerReflexive)) - typeString = "srflx"; - else if (type.equals(Candidate.CandidateType.PeerReflexive)) - typeString = "prflx"; - else if (type.equals(Candidate.CandidateType.Relayed)) - typeString = "relay"; - else - typeString = "host"; - - TransportCandidate transportCandidate = new ICECandidate(candidate.getAddress().getInetAddress().getHostAddress(), 1, candidate.getNetwork(), "1", candidate.getPort(), "1", candidate.getPriority(), typeString); - transportCandidate.setLocalIp(candidate.getBase().getAddress().getInetAddress().getHostAddress()); - transportCandidate.setPort(getFreePort()); - try { - transportCandidate.addCandidateEcho(); - } - catch (SocketException e) { - e.printStackTrace(); - } - this.addCandidate(transportCandidate); - - System.out.println("C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority()); - - } - catch (UtilityException e) { - e.printStackTrace(); - } - catch (UnknownHostException e) { - e.printStackTrace(); - } - - if (RTPBridge.serviceAvailable(connection)) { - try { - String localIp = cc.getPublicCandidate().getBase().getAddress().getInetAddress().getHostAddress(); - - sid = Math.abs(random.nextLong()); - - RTPBridge rtpBridge = RTPBridge.getRTPBridge(connection, String.valueOf(sid)); - - TransportCandidate localCandidate = new ICECandidate( - rtpBridge.getIp(), 1, cc.getPublicCandidate().getNetwork(), "1", rtpBridge.getPortA(), "1", 0, "relay"); - localCandidate.setLocalIp(localIp); - - TransportCandidate remoteCandidate = new ICECandidate( - rtpBridge.getIp(), 1, cc.getPublicCandidate().getNetwork(), "1", rtpBridge.getPortB(), "1", 0, "relay"); - remoteCandidate.setLocalIp(localIp); - - localCandidate.setSymmetric(remoteCandidate); - remoteCandidate.setSymmetric(localCandidate); - - localCandidate.setPassword(rtpBridge.getPass()); - remoteCandidate.setPassword(rtpBridge.getPass()); - - localCandidate.setSessionId(rtpBridge.getSid()); - remoteCandidate.setSessionId(rtpBridge.getSid()); - - localCandidate.setConnection(this.connection); - remoteCandidate.setConnection(this.connection); - - addCandidate(localCandidate); - - } - catch (UtilityException e) { - e.printStackTrace(); - } - catch (UnknownHostException e) { - e.printStackTrace(); - } - - } + iceNegociator.prioritizeCandidates(); } this.setInitialized(); @@ -151,7 +78,89 @@ public class ICEResolver extends TransportResolver { */ public synchronized void resolve() throws XMPPException { this.setResolveInit(); - System.out.println("Resolve"); + + this.cancel(); + for (TransportCandidate candidate : this.getCandidatesList()) { + if (candidate instanceof ICECandidate) { + ICECandidate iceCandidate = (ICECandidate) candidate; + iceCandidate.removeCandidateEcho(); + } + } + + for (Candidate candidate : iceNegociator.getSortedCandidates()) + try { + Candidate.CandidateType type = candidate.getCandidateType(); + String typeString = "local"; + if (type.equals(Candidate.CandidateType.ServerReflexive)) + typeString = "srflx"; + else if (type.equals(Candidate.CandidateType.PeerReflexive)) + typeString = "prflx"; + else if (type.equals(Candidate.CandidateType.Relayed)) + typeString = "relay"; + else + typeString = "host"; + + TransportCandidate transportCandidate = new ICECandidate(candidate.getAddress().getInetAddress().getHostAddress(), 1, candidate.getNetwork(), "1", candidate.getPort(), "1", candidate.getPriority(), typeString); + transportCandidate.setLocalIp(candidate.getBase().getAddress().getInetAddress().getHostAddress()); + transportCandidate.setPort(getFreePort()); + try { + transportCandidate.addCandidateEcho(); + } + catch (SocketException e) { + e.printStackTrace(); + } + this.addCandidate(transportCandidate); + + System.out.println("C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority()); + + } + catch (UtilityException e) { + e.printStackTrace(); + } + catch (UnknownHostException e) { + e.printStackTrace(); + } + + if (RTPBridge.serviceAvailable(connection)) { + try { + String localIp = iceNegociator.getPublicCandidate().getBase().getAddress().getInetAddress().getHostAddress(); + + sid = Math.abs(random.nextLong()); + + RTPBridge rtpBridge = RTPBridge.getRTPBridge(connection, String.valueOf(sid)); + + TransportCandidate localCandidate = new ICECandidate( + rtpBridge.getIp(), 1, iceNegociator.getPublicCandidate().getNetwork(), "1", rtpBridge.getPortA(), "1", 0, "relay"); + localCandidate.setLocalIp(localIp); + + TransportCandidate remoteCandidate = new ICECandidate( + rtpBridge.getIp(), 1, iceNegociator.getPublicCandidate().getNetwork(), "1", rtpBridge.getPortB(), "1", 0, "relay"); + remoteCandidate.setLocalIp(localIp); + + localCandidate.setSymmetric(remoteCandidate); + remoteCandidate.setSymmetric(localCandidate); + + localCandidate.setPassword(rtpBridge.getPass()); + remoteCandidate.setPassword(rtpBridge.getPass()); + + localCandidate.setSessionId(rtpBridge.getSid()); + remoteCandidate.setSessionId(rtpBridge.getSid()); + + localCandidate.setConnection(this.connection); + remoteCandidate.setConnection(this.connection); + + addCandidate(localCandidate); + + } + catch (UtilityException e) { + e.printStackTrace(); + } + catch (UnknownHostException e) { + e.printStackTrace(); + } + + } + this.setResolveEnd(); } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolver.java index 859981c98..e308ab768 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolver.java @@ -72,6 +72,7 @@ import java.util.List; public abstract class TransportResolver { public enum Type { + rawupd, ice } @@ -91,7 +92,7 @@ public abstract class TransportResolver { public static final int CHECK_TIMEOUT = 2000; // Listeners for events - private final ArrayList listeners = new ArrayList(); + private final ArrayList listeners = new ArrayList(); // TRue if the resolver is working private boolean resolving; @@ -105,10 +106,7 @@ public abstract class TransportResolver { // We store a list of candidates internally, just in case there are several // possibilities. When the user asks for a transport, we return the best // one. - protected final List candidates = new ArrayList(); - - // Remote candidates that are being checked - private final static ArrayList candidatesChecking = new ArrayList(); + protected final List candidates = new ArrayList(); /** * Default constructor. @@ -355,7 +353,7 @@ public abstract class TransportResolver { * * @return the list of transport candidates */ - public List getCandidatesList() { + public List getCandidatesList() { ArrayList result = null; synchronized (candidates) { diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioChannel.java b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioChannel.java index 8a3074590..c0f2cab0a 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioChannel.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioChannel.java @@ -51,6 +51,8 @@ import java.util.List; * portB ---> portA *

* Transmit and Receive are interdependents. To receive you MUST trasmit. + * + * @author Thiago Camargo */ public class AudioChannel { diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioFormatUtils.java b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioFormatUtils.java index 70eb5db89..2c89dc508 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioFormatUtils.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioFormatUtils.java @@ -24,7 +24,9 @@ import org.jivesoftware.smackx.jingle.media.PayloadType; import javax.media.format.AudioFormat; /** - * Audio Format Ttils. + * Audio Format Utils. + * + * @author Thiago Camargo */ public class AudioFormatUtils { diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioMediaSession.java b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioMediaSession.java index d85a21168..af163af7d 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioMediaSession.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioMediaSession.java @@ -36,11 +36,15 @@ import java.net.ServerSocket; * But you could also use in any VOIP application. * For better NAT Traversal support this implementation donīt support only receive or only transmit. * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit() + * + * @author Thiago Camargo + * */ public class AudioMediaSession extends JingleMediaSession { private AudioFormat format; private AudioChannel audioChannel; + private String locator = "javasound://"; /** * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates @@ -50,8 +54,23 @@ public class AudioMediaSession extends JingleMediaSession { * @param local The local information. The candidate that will receive the jmf */ public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, - final TransportCandidate local) { + final TransportCandidate local) { + this(payloadType, remote, local, "javasound://"); + } + + /** + * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates + * + * @param payloadType Payload of the jmf + * @param remote The remote information. The candidate that the jmf will be sent to. + * @param local The local information. The candidate that will receive the jmf + */ + public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, + final TransportCandidate local, String locator) { super(payloadType, remote, local); + if (locator != null && !locator.equals("")) + this.locator = locator; + initialize(); } /** @@ -72,14 +91,15 @@ public class AudioMediaSession extends JingleMediaSession { System.out.println(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort); - } else { + } + else { ip = this.getRemote().getIp(); localIp = this.getLocal().getLocalIp(); localPort = this.getLocal().getPort(); remotePort = this.getRemote().getPort(); } - audioChannel = new AudioChannel(new MediaLocator("dsound://"), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType())); + audioChannel = new AudioChannel(new MediaLocator(locator), localIp, ip, localPort, remotePort, AudioFormatUtils.getAudioFormat(this.getPayloadType())); } /** diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioReceiver.java b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioReceiver.java index f7645bd8d..3d1cf5851 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioReceiver.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/AudioReceiver.java @@ -1,4 +1,4 @@ -package org.jivesoftware.jingleaudio.jmf; /** +/** * $RCSfile$ * $Revision: $ * $Date: 08/11/2006 @@ -18,6 +18,8 @@ package org.jivesoftware.jingleaudio.jmf; /** * limitations under the License. */ +package org.jivesoftware.jingleaudio.jmf; + import javax.media.*; import javax.media.protocol.DataSource; import javax.media.rtp.*; @@ -25,6 +27,8 @@ import javax.media.rtp.event.*; /** * This class implements receive methods and listeners to be used in AudioChannel + * + * @author Thiago Camargo */ public class AudioReceiver implements ReceiveStreamListener, SessionListener, ControllerListener { diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/JmfMediaManager.java b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/JmfMediaManager.java index adf4ea0ac..6c8167bad 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jmf/JmfMediaManager.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jmf/JmfMediaManager.java @@ -32,7 +32,9 @@ import java.io.IOException; /** * Implements a jingleMediaManager using JMF based API. * It supports GSM and G723 codecs. - * This API only currently works on windows. + * This API only currently works on windows and Mac. + * + * @author Thiago Camargo */ public class JmfMediaManager extends JingleMediaManager { diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/AudioMediaSession.java b/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/AudioMediaSession.java index 8add6aaf2..e274247c3 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/AudioMediaSession.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/AudioMediaSession.java @@ -1,3 +1,23 @@ +/** + * $RCSfile$ + * $Revision: $ + * $Date: 25/12/2006 + *

+ * Copyright 2003-2006 Jive Software. + *

+ * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.jivesoftware.jingleaudio.jspeex; import mil.jfcom.cie.media.session.MediaSession; @@ -19,23 +39,14 @@ import java.net.ServerSocket; import java.security.GeneralSecurityException; /** - * $RCSfile$ - * $Revision: $ - * $Date: 25/12/2006 + * This Class implements a complete JingleMediaSession. + * It sould be used to transmit and receive audio captured from the Mic. + * This Class should be automaticly controlled by JingleSession. + * But you could also use in any VOIP application. + * For better NAT Traversal support this implementation donīt support only receive or only transmit. + * To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit() * - * Copyright 2003-2006 Jive Software. - * - * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * @author Thiago Camargo */ public class AudioMediaSession extends JingleMediaSession implements MediaSessionListener { @@ -77,8 +88,9 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio * @param local The local information. The candidate that will receive the jmf */ public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, - final TransportCandidate local) { + final TransportCandidate local) { super(payloadType, remote, local); + initialize(); } /** @@ -99,7 +111,8 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio System.out.println(this.getLocal().getConnection() + " " + ip + ": " + localPort + "->" + remotePort); - } else { + } + else { ip = this.getRemote().getIp(); localIp = this.getLocal().getLocalIp(); localPort = this.getLocal().getPort(); @@ -108,13 +121,17 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio try { mediaSession = createSession(localIp, localPort, ip, remotePort, this, 2, false, true); - } catch (NoProcessorException e) { + } + catch (NoProcessorException e) { e.printStackTrace(); - } catch (UnsupportedFormatException e) { + } + catch (UnsupportedFormatException e) { e.printStackTrace(); - } catch (IOException e) { + } + catch (IOException e) { e.printStackTrace(); - } catch (GeneralSecurityException e) { + } + catch (GeneralSecurityException e) { e.printStackTrace(); } } @@ -126,7 +143,8 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio try { System.out.println("start"); mediaSession.start(true); - } catch (IOException e) { + } + catch (IOException e) { e.printStackTrace(); } } diff --git a/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/SpeexMediaManager.java b/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/SpeexMediaManager.java index 343e33999..ceb81b690 100644 --- a/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/SpeexMediaManager.java +++ b/jingle/media/source/org/jivesoftware/jingleaudio/jspeex/SpeexMediaManager.java @@ -1,14 +1,3 @@ -package org.jivesoftware.jingleaudio.jspeex; - -import org.jivesoftware.smackx.jingle.media.JingleMediaManager; -import org.jivesoftware.smackx.jingle.media.JingleMediaSession; -import org.jivesoftware.smackx.jingle.media.PayloadType; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.jingleaudio.JMFInit; - -import java.io.File; -import java.io.IOException; - /** * $RCSfile$ * $Revision: $ @@ -28,6 +17,24 @@ import java.io.IOException; * See the License for the specific language governing permissions and * limitations under the License. */ +package org.jivesoftware.jingleaudio.jspeex; + +import org.jivesoftware.smackx.jingle.media.JingleMediaManager; +import org.jivesoftware.smackx.jingle.media.JingleMediaSession; +import org.jivesoftware.smackx.jingle.media.PayloadType; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; +import org.jivesoftware.jingleaudio.JMFInit; + +import java.io.File; +import java.io.IOException; + +/** + * Implements a jingleMediaManager using JMF based API and JSpeex. + * It supports Speex codec. + * This API only currently works on windows. + * + * @author Thiago Camargo + */ public class SpeexMediaManager extends JingleMediaManager { public SpeexMediaManager() {