From 51fb81926ef1e1f28adfd85d8ba37940103debbf Mon Sep 17 00:00:00 2001 From: Gaston Dombiak Date: Mon, 19 May 2008 22:54:19 +0000 Subject: [PATCH] Updated Jingle implementation. SMACK-240. Thanks to Jeff Williams. git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@10407 b35dd754-fafc-0310-a699-88a17e54d16e --- .../smackx/jingle/IncomingJingleSession.java | 471 ------ .../smackx/jingle/JingleManager.java | 274 ++-- .../smackx/jingle/JingleNegotiator.java | 309 ++-- .../smackx/jingle/JingleSession.java | 1289 +++++++++-------- .../smackx/jingle/JingleSessionRequest.java | 42 +- .../smackx/jingle/OutgoingJingleSession.java | 478 ------ .../CreatedJingleSessionListener.java | 4 +- .../jingle/listeners/JingleListener.java | 6 +- .../listeners/JingleMediaInfoListener.java | 6 +- .../jingle/listeners/JingleMediaListener.java | 6 +- .../listeners/JingleSessionListener.java | 6 +- .../JingleSessionRequestListener.java | 6 +- .../listeners/JingleSessionStateListener.java | 49 - .../listeners/JingleTransportListener.java | 6 +- .../smackx/jingle/media/ContentInfo.java | 6 +- .../jingle/media/JingleMediaManager.java | 36 +- .../jingle/media/JingleMediaSession.java | 10 +- .../smackx/jingle/media/MediaNegotiator.java | 725 +++++---- .../jingle/media/MediaReceivedListener.java | 6 +- .../smackx/jingle/media/PayloadType.java | 51 +- .../smackx/jingle/mediaimpl/demo/Demo.java | 45 +- .../jingle/mediaimpl/jmf/AudioChannel.java | 12 +- .../mediaimpl/jmf/AudioFormatUtils.java | 4 +- .../mediaimpl/jmf/AudioMediaSession.java | 6 +- .../jingle/mediaimpl/jmf/AudioReceiver.java | 4 +- .../jingle/mediaimpl/jmf/JmfMediaManager.java | 24 +- .../mediaimpl/jspeex/AudioMediaSession.java | 6 +- .../mediaimpl/jspeex/SpeexMediaManager.java | 20 +- .../mediaimpl/multi/MultiMediaManager.java | 20 +- .../sshare/ScreenShareMediaManager.java | 18 +- .../mediaimpl/sshare/ScreenShareSession.java | 58 +- .../smackx/jingle/nat/BasicResolver.java | 6 +- .../jingle/nat/BasicTransportManager.java | 4 +- .../smackx/jingle/nat/BridgedResolver.java | 13 +- .../jingle/nat/BridgedTransportManager.java | 4 +- .../smackx/jingle/nat/DatagramListener.java | 4 +- .../smackx/jingle/nat/FixedResolver.java | 4 +- .../smackx/jingle/nat/HttpServer.java | 12 +- .../smackx/jingle/nat/ICECandidate.java | 10 +- .../smackx/jingle/nat/ICEResolver.java | 6 +- .../jingle/nat/ICETransportManager.java | 10 +- .../jingle/nat/JingleTransportManager.java | 4 +- .../smackx/jingle/nat/RTPBridge.java | 12 +- .../smackx/jingle/nat/ResultListener.java | 6 +- .../jivesoftware/smackx/jingle/nat/STUN.java | 16 +- .../smackx/jingle/nat/STUNResolver.java | 4 +- .../jingle/nat/STUNTransportManager.java | 4 +- .../smackx/jingle/nat/TcpUdpBridgeClient.java | 14 +- .../smackx/jingle/nat/TestResult.java | 6 +- .../smackx/jingle/nat/TransportCandidate.java | 11 +- .../jingle/nat/TransportNegotiator.java | 611 ++++---- .../smackx/jingle/nat/TransportResolver.java | 10 +- .../jingle/nat/TransportResolverListener.java | 4 +- .../jivesoftware/smackx/packet/Jingle.java | 229 +-- .../smackx/packet/JingleContentInfo.java | 8 +- .../smackx/packet/JingleError.java | 10 +- .../smackx/packet/JingleTransport.java | 32 +- .../provider/JingleContentInfoProvider.java | 10 +- .../smackx/provider/JingleProvider.java | 53 +- .../provider/JingleTransportProvider.java | 8 +- .../smackx/jingle/JingleManagerTest.java | 579 ++++---- .../smackx/jingle/JingleMediaTest.java | 339 +++-- .../smackx/jingle/JingleSessionTest.java | 32 +- .../smackx/jingle/JingleSupportTests.java | 6 +- .../jingle/nat/BridgedResolverTest.java | 10 - .../smackx/jingle/nat/STUNResolverTest.java | 124 +- 66 files changed, 2440 insertions(+), 3778 deletions(-) delete mode 100644 jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java delete mode 100644 jingle/extension/source/org/jivesoftware/smackx/jingle/OutgoingJingleSession.java delete mode 100644 jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionStateListener.java diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java deleted file mode 100644 index 018e8f951..000000000 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java +++ /dev/null @@ -1,471 +0,0 @@ -/** - * $RCSfile$ - * $Revision$ - * $Date$ - * - * Copyright (C) 2002-2006 Jive Software. All rights reserved. - * ==================================================================== - * The Jive Software License (based on Apache Software License, Version 1.1) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by - * Jive Software (http://www.jivesoftware.com)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Smack" and "Jive Software" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please - * contact webmaster@jivesoftware.com. - * - * 5. Products derived from this software may not be called "Smack", - * nor may "Smack" appear in their name, without prior written - * permission of Jive Software. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - */ - -package org.jivesoftware.smackx.jingle; - -import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smackx.jingle.listeners.JingleMediaListener; -import org.jivesoftware.smackx.jingle.listeners.JingleTransportListener; -import org.jivesoftware.smackx.jingle.listeners.JingleSessionStateListener; -import org.jivesoftware.smackx.jingle.media.JingleMediaManager; -import org.jivesoftware.smackx.jingle.media.MediaNegotiator; -import org.jivesoftware.smackx.jingle.media.PayloadType; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.nat.TransportNegotiator; -import org.jivesoftware.smackx.jingle.nat.TransportResolver; -import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; -import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleContentDescription; -import org.jivesoftware.smackx.packet.JingleContentDescription.JinglePayloadType; -import org.jivesoftware.smackx.packet.JingleError; - -import javax.swing.*; -import java.util.List; - -/** - * An incoming Jingle Session implementation. - * This class has especific bahavior to accept and establish a received Jingle Session Request. - *

- * This class is not directly used by users. Instead, users should refer to the - * JingleManager class, that will create the appropiate instance... - * - * @author Alvaro Saurin - * @author Thiago Camargo - */ -public class IncomingJingleSession extends JingleSession { - - // states - private final Accepting accepting; - - private final Pending pending; - - private final Active active; - - private JingleSessionRequest initialSessionRequest; - - /** - * Constructor for a Jingle incoming session - * - * @param conn the XMPP connection - * @param responder the responder - * @param transportManager The transport manager - * @param initialJingleSessionRequest the initial Jingle Session Request - */ - protected IncomingJingleSession(XMPPConnection conn, String responder, - List payloadTypes, JingleTransportManager transportManager, JingleSessionRequest initialJingleSessionRequest) throws XMPPException { - - super(conn, responder, conn.getUser()); - - setSid(initialJingleSessionRequest.getSessionID()); - - // Create the states... - - accepting = new Accepting(this); - pending = new Pending(this); - active = new Active(this); - - TransportResolver resolver = null; - try { - resolver = transportManager.getResolver(this); - } - catch (XMPPException e) { - e.printStackTrace(); - } - - setMediaNeg(new MediaNegotiator(this, payloadTypes)); - if (resolver.getType().equals(TransportResolver.Type.rawupd)) { - setTransportNeg(new TransportNegotiator.RawUdp(this, resolver)); - } - if (resolver.getType().equals(TransportResolver.Type.ice)) { - setTransportNeg(new TransportNegotiator.Ice(this, resolver)); - } - - } - - /** - * Constructor for a Jingle Incoming session with a defined Media Manager - * - * @param conn the XMPP connection - * @param responder the responder - * @param transportManager The transport manager - * @param jingleMediaManager The Media Manager for this Session - * @param initialJingleSessionRequest the initial Jingle Session Request - */ - protected IncomingJingleSession(XMPPConnection conn, String responder, - List payloadTypes, JingleTransportManager transportManager, JingleMediaManager jingleMediaManager, JingleSessionRequest initialJingleSessionRequest) throws XMPPException { - this(conn, responder, payloadTypes, transportManager, initialJingleSessionRequest); - this.jingleMediaManager = jingleMediaManager; - } - - /** - * Start the session for a initial Jingle request packet. - * - * @param initialJingleSessionRequest the initial Jingle Session Request - * @throws XMPPException - */ - public void start(JingleSessionRequest initialJingleSessionRequest) throws XMPPException { - // Establish the default state - setState(accepting); - - updatePacketListener(); - - Jingle packet = initialJingleSessionRequest.getJingle(); - if (packet != null) { - - // Initialize the session information - setSid(packet.getSid()); - - respond(packet); - } - else { - throw new XMPPException( - "Session request with null Jingle packet."); - } - - } - - /** - * Start the session using initial Jingle Session Request used to create this session.. - * - * @throws XMPPException - */ - public void start() throws XMPPException { - start(getInitialSessionRequest()); - } - - /** - * Get the initial Jingle packet request - * - * @return - */ - public JingleSessionRequest getInitialSessionRequest() { - return initialSessionRequest; - } - - /** - * Get the initial Jingle packet request - * - * @param initialRequest the initial Jingle packet - */ - public void setInitialSessionRequest(JingleSessionRequest initialRequest) { - this.initialSessionRequest = initialRequest; - } - - // States - - /** - * First stage when we have received a session request, and we accept the - * request. We start in this stage, as the instance is created when the user - * accepts the connection... - */ - public class Accepting extends JingleNegotiator.State { - - public Accepting(JingleNegotiator neg) { - super(neg); - } - - /** - * Initiate the incoming session. We have already sent the ACK partially - * accepting the session... - * - * @throws XMPPException - */ - public Jingle eventInitiate(Jingle inJingle) throws XMPPException { - // Set the new session state - setState(pending); - return super.eventInitiate(inJingle); - } - - /** - * An error has occurred. - * - * @throws XMPPException - */ - public void eventError(IQ iq) throws XMPPException { - triggerSessionClosedOnError(new JingleException(iq.getError().getMessage())); - super.eventError(iq); - } - - /** - * Terminate the connection. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventTerminate(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventTerminate(Jingle jin) throws XMPPException { - triggerSessionClosed("Closed Remotely"); - return super.eventTerminate(jin); - } - } - - /** - * "Pending" state: we are waiting for the transport and content - * negotiators. - */ - public class Pending extends JingleNegotiator.State { - - JingleMediaListener jingleMediaListener; - - JingleTransportListener jingleTransportListener; - - public Pending(JingleNegotiator neg) { - super(neg); - - // Create the listeners that will send a "session-accept" when the - // sub-negotiators are done. - jingleMediaListener = new JingleMediaListener() { - public void mediaClosed(PayloadType cand) { - } - - public void mediaEstablished(PayloadType pt) { - checkFullyEstablished(); - } - }; - - jingleTransportListener = new JingleTransportListener() { - public void transportEstablished(TransportCandidate local, - TransportCandidate remote) { - checkFullyEstablished(); - } - - public void transportClosed(TransportCandidate cand) { - } - - public void transportClosedOnError(XMPPException e) { - } - }; - } - - /** - * Enter in the pending state: wait for the sub-negotiators. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventEnter() { - // Add the listeners to the sub-negotiators... - addMediaListener(jingleMediaListener); - addTransportListener(jingleTransportListener); - super.eventEnter(); - } - - /** - * Exit of the state - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventExit() - */ - public void eventExit() { - removeMediaListener(jingleMediaListener); - removeTransportListener(jingleTransportListener); - super.eventExit(); - } - - /** - * Check if the session has been fully accepted by all the - * sub-negotiators and, in that case, send an "accept" message... - */ - private void checkFullyEstablished() { - if (isFullyEstablished()) { - - PayloadType.Audio bestCommonAudioPt = getMediaNeg() - .getBestCommonAudioPt(); - TransportCandidate bestRemoteCandidate = getTransportNeg() - .getBestRemoteCandidate(); - - TransportCandidate acceptedLocalCandidate = getTransportNeg() - .getAcceptedLocalCandidate(); - - if (bestCommonAudioPt != null && bestRemoteCandidate != null - && acceptedLocalCandidate != null) { - // Ok, send a packet saying that we accept this session - Jingle jout = new Jingle(Jingle.Action.SESSIONACCEPT); - - // ... with the audio payload type and the transport - // candidate - jout.addDescription(new JingleContentDescription.Audio( - new JinglePayloadType(bestCommonAudioPt))); - jout.addTransport(getTransportNeg().getJingleTransport( - bestRemoteCandidate)); - - addExpectedId(jout.getPacketID()); - sendFormattedJingle(jout); - } - } - } - - /** - * The other endpoint has accepted the session. - */ - public Jingle eventAccept(Jingle jin) throws XMPPException { - - PayloadType acceptedPayloadType = null; - TransportCandidate acceptedLocalCandidate = null; - - // We process the "accepted" if we have finished the - // sub-negotiators. Maybe this is not needed (ie, the other endpoint - // can take the first valid transport candidate), but otherwise we - // must cancel the negotiators... - // - if (isFullyEstablished()) { - acceptedPayloadType = getAcceptedAudioPayloadType(jin); - acceptedLocalCandidate = getAcceptedLocalCandidate(jin); - - if (acceptedPayloadType != null && acceptedLocalCandidate != null) { - if (acceptedPayloadType.equals(getMediaNeg().getBestCommonAudioPt()) - && acceptedLocalCandidate.equals(getTransportNeg() - .getAcceptedLocalCandidate())) { - setState(active); - } - } - else { - throw new JingleException(JingleError.MALFORMED_STANZA); - } - } - - return super.eventAccept(jin); - } - - /** - * We have received a confirmation. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ) - */ - public Jingle eventAck(IQ iq) throws XMPPException { - setState(active); - return super.eventAck(iq); - } - - /** - * An error has occurred. - * - * @throws XMPPException - */ - public void eventError(IQ iq) throws XMPPException { - if (iq == null) return; - triggerSessionClosedOnError(new XMPPException(iq.getError())); - super.eventError(iq); - } - - /** - * Terminate the connection. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventTerminate(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventTerminate(Jingle jin) throws XMPPException { - triggerSessionClosed("Closed Remotely"); - return super.eventTerminate(jin); - } - } - - /** - * "Active" state: we have an agreement about the session. - */ - public class Active extends JingleNegotiator.State { - - public Active(JingleNegotiator neg) { - super(neg); - } - - /** - * We have a established session: notify the listeners - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventEnter() { - PayloadType.Audio bestCommonAudioPt = getMediaNeg().getBestCommonAudioPt(); - TransportCandidate bestRemoteCandidate = getTransportNeg() - .getBestRemoteCandidate(); - TransportCandidate acceptedLocalCandidate = getTransportNeg() - .getAcceptedLocalCandidate(); - - // Trigger the session established flag - triggerSessionEstablished(bestCommonAudioPt, bestRemoteCandidate, - acceptedLocalCandidate); - - super.eventEnter(); - } - - /** - * Terminate the connection. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventTerminate(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventTerminate(Jingle jin) throws XMPPException { - triggerSessionClosed("Closed Remotely"); - return super.eventTerminate(jin); - } - - /** - * An error has occurred. - * - * @throws XMPPException - */ - public void eventError(IQ iq) throws XMPPException { - triggerSessionClosedOnError(new XMPPException(iq.getError().getMessage())); - super.eventError(iq); - } - } - - public IQ sendFormattedError(JingleError error){ - IQ perror = null; - if (error != null) { - perror = createIQ(getSid(), getInitiator(), getResponder(), IQ.Type.ERROR); - - // Fill in the fields with the info from the Jingle packet - perror.addExtension(error); - - getConnection().sendPacket(perror); - System.err.println(perror.toXML()); - } - return perror; - } -} diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java index b8b0a85c4..724580d89 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: JingleManager.java,v $ + * $Revision: 1.4 $ + * $Date: 2007/07/17 22:13:16 $ * * Copyright 2003-2005 Jive Software. * @@ -25,9 +25,7 @@ import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.ProviderManager; -import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.ServiceDiscoveryManager; import org.jivesoftware.smackx.jingle.listeners.CreatedJingleSessionListener; @@ -36,14 +34,11 @@ import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener; import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; import org.jivesoftware.smackx.jingle.media.JingleMediaManager; import org.jivesoftware.smackx.jingle.media.PayloadType; -import org.jivesoftware.smackx.jingle.nat.BasicResolver; -import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.nat.TransportResolver; import org.jivesoftware.smackx.packet.DiscoverInfo; import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleError; -import org.xmlpull.v1.XmlPullParser; +import org.jivesoftware.smackx.provider.JingleProvider; import java.util.ArrayList; import java.util.Collection; @@ -174,13 +169,13 @@ import java.util.List; * * @author Thiago Camargo * @author Alvaro Saurin + * @author Jeff Williams * @see JingleListener * @see TransportResolver - * @see org.jivesoftware.smackx.jingle.nat.JingleTransportManager - * @see OutgoingJingleSession - * @see IncomingJingleSession + * @see JingleSession + * @see JingleSession * @see JingleMediaManager - * @see org.jivesoftware.smackx.jingle.nat.BasicTransportManager , STUNTransportManager, BridgedTransportManager, TransportResolver, BridgedResolver, ICEResolver, STUNResolver and BasicResolver. + * @see BasicTransportManager , STUNTransportManager, BridgedTransportManager, TransportResolver, BridgedResolver, ICEResolver, STUNResolver and BasicResolver. */ public class JingleManager implements JingleSessionListener { @@ -197,40 +192,12 @@ public class JingleManager implements JingleSessionListener { // The XMPP connection private XMPPConnection connection; - // The Media Manager - private JingleMediaManager jingleMediaManager; - - // The Jingle transport manager - private final JingleTransportManager jingleTransportManager; + // The Media Managers + private List jingleMediaManagers; static { - ProviderManager providerManager = ProviderManager.getInstance(); - - providerManager.addIQProvider("jingle", "http://jabber.org/protocol/jingle", - new org.jivesoftware.smackx.provider.JingleProvider()); - - providerManager.addExtensionProvider("description", "http://jabber.org/protocol/jingle/description/audio", - new org.jivesoftware.smackx.provider.JingleContentDescriptionProvider.Audio()); - - providerManager.addExtensionProvider("description", "http://jabber.org/protocol/jingle/description/audio", - new org.jivesoftware.smackx.provider.JingleContentDescriptionProvider.Audio()); - - providerManager.addExtensionProvider("transport", "http://jabber.org/protocol/jingle/transport/ice", - new org.jivesoftware.smackx.provider.JingleTransportProvider.Ice()); - providerManager.addExtensionProvider("transport", "http://jabber.org/protocol/jingle/transport/raw-udp", - new org.jivesoftware.smackx.provider.JingleTransportProvider.RawUdp()); - - providerManager.addExtensionProvider("busy", "http://jabber.org/protocol/jingle/info/audio", - new org.jivesoftware.smackx.provider.JingleContentInfoProvider.Audio.Busy()); - providerManager.addExtensionProvider("hold", "http://jabber.org/protocol/jingle/info/audio", - new org.jivesoftware.smackx.provider.JingleContentInfoProvider.Audio.Hold()); - providerManager.addExtensionProvider("mute", "http://jabber.org/protocol/jingle/info/audio", - new org.jivesoftware.smackx.provider.JingleContentInfoProvider.Audio.Mute()); - providerManager.addExtensionProvider("queued", "http://jabber.org/protocol/jingle/info/audio", - new org.jivesoftware.smackx.provider.JingleContentInfoProvider.Audio.Queued()); - providerManager.addExtensionProvider("ringing", "http://jabber.org/protocol/jingle/info/audio", - new org.jivesoftware.smackx.provider.JingleContentInfoProvider.Audio.Ringing()); + providerManager.addIQProvider("jingle", "http://www.xmpp.org/extensions/xep-0166.html#ns", new JingleProvider()); // Enable the Jingle support on every established connection // The ServiceDiscoveryManager class should have been already @@ -247,13 +214,11 @@ public class JingleManager implements JingleSessionListener { * If a fully implemented JingleMediaSession is entered, JingleManager manage Jingle signalling and jmf * * @param connection XMPP Connection to be used - * @param jingleTransportManager transport resolver to be used * @param jingleMediaManager an implemeted JingleMediaManager to be used. */ - public JingleManager(XMPPConnection connection, JingleTransportManager jingleTransportManager, JingleMediaManager jingleMediaManager) { + public JingleManager(XMPPConnection connection, List jingleMediaManagers) { this.connection = connection; - this.jingleTransportManager = jingleTransportManager; - this.jingleMediaManager = jingleMediaManager; + this.jingleMediaManagers = jingleMediaManagers; connection.getRoster().addRosterListener(new RosterListener() { @@ -271,16 +236,14 @@ public class JingleManager implements JingleSessionListener { String xmppAddress = presence.getFrom(); JingleSession aux = null; for (JingleSession jingleSession : jingleSessions) { - if (jingleSession.getInitiator().equals(xmppAddress) || - jingleSession.getResponder().equals(xmppAddress)) { + if (jingleSession.getInitiator().equals(xmppAddress) || jingleSession.getResponder().equals(xmppAddress)) { aux = jingleSession; } } if (aux != null) try { aux.terminate(); - } - catch (XMPPException e) { + } catch (XMPPException e) { e.printStackTrace(); } } @@ -290,43 +253,31 @@ public class JingleManager implements JingleSessionListener { } /** - * Default constructor with a defined XMPPConnection and a Transport Resolver - * - * @param connection XMPP Connection to be used - * @param jingleTransportManager transport resolver to be used - */ - public JingleManager(XMPPConnection connection, JingleTransportManager jingleTransportManager) { - this(connection, jingleTransportManager, null); - } - - /** - * Default constructor with a defined XMPPConnection. - * A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport. - * - * @param connection XMPP Connection to be used - */ - public JingleManager(XMPPConnection connection) { - this(connection, new JingleTransportManager() { - protected TransportResolver createResolver(JingleSession session) { - return new BasicResolver(); - } - }); - } - + * Default constructor with a defined XMPPConnection. + * A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport. + * + * @param connection XMPP Connection to be used + */ + // public JingleManager(XMPPConnection connection) { + // this(connection, new JingleTransportManager() { + // protected TransportResolver createResolver(JingleSession session) { + // return new BasicResolver(); + // } + // }); + // } /** * Default constructor with a defined XMPPConnection and a defined Resolver. * A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport. * * @param connection XMPP Connection to be used */ - public JingleManager(XMPPConnection connection, final TransportResolver resolver) { - this(connection, new JingleTransportManager() { - protected TransportResolver createResolver(JingleSession session) { - return resolver; - } - }); - } - + // public JingleManager(XMPPConnection connection, final TransportResolver resolver) { + // this(connection, new JingleTransportManager() { + // protected TransportResolver createResolver(JingleSession session) { + // return resolver; + // } + // }); + // } /** * Enables or disables the Jingle support on a given connection. *

@@ -339,19 +290,15 @@ public class JingleManager implements JingleSessionListener { * disabled * @param enabled indicates if the service will be enabled or disabled */ - public synchronized static void setServiceEnabled(XMPPConnection connection, - boolean enabled) { + public synchronized static void setServiceEnabled(XMPPConnection connection, boolean enabled) { if (isServiceEnabled(connection) == enabled) { return; } if (enabled) { - ServiceDiscoveryManager.getInstanceFor(connection).addFeature( - Jingle.NAMESPACE); - } - else { - ServiceDiscoveryManager.getInstanceFor(connection).removeFeature( - Jingle.NAMESPACE); + ServiceDiscoveryManager.getInstanceFor(connection).addFeature(Jingle.NAMESPACE); + } else { + ServiceDiscoveryManager.getInstanceFor(connection).removeFeature(Jingle.NAMESPACE); } } @@ -363,8 +310,7 @@ public class JingleManager implements JingleSessionListener { * given connection */ public static boolean isServiceEnabled(XMPPConnection connection) { - return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature( - Jingle.NAMESPACE); + return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(Jingle.NAMESPACE); } /** @@ -378,53 +324,41 @@ public class JingleManager implements JingleSessionListener { */ public static boolean isServiceEnabled(XMPPConnection connection, String userID) { try { - DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection) - .discoverInfo(userID); + DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(userID); return result.containsFeature(Jingle.NAMESPACE); - } - catch (XMPPException e) { + } catch (XMPPException e) { e.printStackTrace(); return false; } } /** - * Get the JingleTransportManager of this JingleManager + * Get the Media Managers of this Jingle Manager * * @return */ - public JingleTransportManager getJingleTransportManager() { - return jingleTransportManager; + public List getMediaManagers() { + return jingleMediaManagers; } /** - * Get the Media Manager of this Jingle Manager - * - * @return - */ - public JingleMediaManager getMediaManager() { - return jingleMediaManager; - } - - /** - * Set the Media Manager of this Jingle Manager + * Set the Media Managers of this Jingle Manager * * @param jingleMediaManager JingleMediaManager to be used for open, close, start and stop jmf streamings */ - public void setMediaManager(JingleMediaManager jingleMediaManager) { - this.jingleMediaManager = jingleMediaManager; + public void setMediaManagers(List jingleMediaManagers) { + this.jingleMediaManagers = jingleMediaManagers; } /** - * Add a Jingle session request listenerJingle to listen to incoming session - * requests. - * - * @param jingleSessionRequestListener an implemented JingleSessionRequestListener - * @see #removeJingleSessionRequestListener(JingleSessionRequestListener) - * @see JingleListener - */ - public synchronized void addJingleSessionRequestListener( - final JingleSessionRequestListener jingleSessionRequestListener) { + * Add a Jingle session request listenerJingle to listen to incoming session + * requests. + * + * @param jingleSessionRequestListener an implemented JingleSessionRequestListener + * @see #removeJingleSessionRequestListener(JingleSessionRequestListener) + * @see JingleListener + */ + public synchronized void addJingleSessionRequestListener(final JingleSessionRequestListener jingleSessionRequestListener) { if (jingleSessionRequestListener != null) { if (jingleSessionRequestListeners == null) { initJingleSessionRequestListeners(); @@ -482,8 +416,7 @@ public class JingleManager implements JingleSessionListener { for (CreatedJingleSessionListener createdJingleSessionListener : creationListeners) { try { createdJingleSessionListener.sessionCreated(jingleSession); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -531,7 +464,7 @@ public class JingleManager implements JingleSessionListener { if (iq.getType().equals(IQ.Type.SET)) { if (iq instanceof Jingle) { Jingle jin = (Jingle) pin; - if (jin.getAction().equals(Jingle.Action.SESSIONINITIATE)) { + if (jin.getAction().equals(JingleActionEnum.SESSION_INITIATE)) { return true; } } @@ -561,8 +494,7 @@ public class JingleManager implements JingleSessionListener { for (JingleSession jingleSession : sessions) try { jingleSession.terminate(); - } - catch (XMPPException e) { + } catch (XMPPException e) { e.printStackTrace(); } @@ -601,22 +533,14 @@ public class JingleManager implements JingleSessionListener { * @param payloadTypes list of supported payload types * @return The session on which the negotiation can be run. */ - public OutgoingJingleSession createOutgoingJingleSession(String responder, - List payloadTypes) throws XMPPException { + public JingleSession createOutgoingJingleSession(String responder) throws XMPPException { - if (responder == null || StringUtils.parseName(responder).length() <= 0 - || StringUtils.parseServer(responder).length() <= 0 + if (responder == null || StringUtils.parseName(responder).length() <= 0 || StringUtils.parseServer(responder).length() <= 0 || StringUtils.parseResource(responder).length() <= 0) { - throw new IllegalArgumentException( - "The provided user id was not fully qualified"); + throw new IllegalArgumentException("The provided user id was not fully qualified"); } - OutgoingJingleSession session; - - if (jingleMediaManager != null) - session = new OutgoingJingleSession(connection, responder, payloadTypes, jingleTransportManager, jingleMediaManager); - else - session = new OutgoingJingleSession(connection, responder, payloadTypes, jingleTransportManager); + JingleSession session = new JingleSession(connection, (JingleSessionRequest) null, connection.getUser(), responder, jingleMediaManagers); triggerSessionCreated(session); @@ -630,11 +554,10 @@ public class JingleManager implements JingleSessionListener { * user. * @return the session on which the negotiation can be run. */ - public OutgoingJingleSession createOutgoingJingleSession(String responder) throws XMPPException { - if (this.getMediaManager() == null) return null; - return createOutgoingJingleSession(responder, this.getMediaManager().getPayloads()); - } - + // public OutgoingJingleSession createOutgoingJingleSession(String responder) throws XMPPException { + // if (this.getMediaManagers() == null) return null; + // return createOutgoingJingleSession(responder, this.getMediaManagers()); + // } /** * When the session request is acceptable, this method should be invoked. It * will create an JingleSession which allows the negotiation to procede. @@ -643,20 +566,12 @@ public class JingleManager implements JingleSessionListener { * @param payloadTypes the list of supported Payload types that can be accepted * @return the session which manages the rest of the negotiation. */ - IncomingJingleSession createIncomingJingleSession( - JingleSessionRequest request, List payloadTypes) throws XMPPException { + public JingleSession createIncomingJingleSession(JingleSessionRequest request) throws XMPPException { if (request == null) { throw new NullPointerException("Received request cannot be null"); } - IncomingJingleSession session; - - if (jingleMediaManager != null) - session = new IncomingJingleSession(connection, request - .getFrom(), payloadTypes, jingleTransportManager, jingleMediaManager, request); - else - session = new IncomingJingleSession(connection, request - .getFrom(), payloadTypes, jingleTransportManager, request); + JingleSession session = new JingleSession(connection, request, request.getFrom(), connection.getUser(), jingleMediaManagers); triggerSessionCreated(session); @@ -671,16 +586,15 @@ public class JingleManager implements JingleSessionListener { * @param request the remote request that is being accepted. * @return the session which manages the rest of the negotiation. */ - IncomingJingleSession createIncomingJingleSession(JingleSessionRequest request) throws XMPPException { - if (request == null) { - throw new NullPointerException("JingleMediaManager is not defined"); - } - if (jingleMediaManager != null) - return createIncomingJingleSession(request, jingleMediaManager.getPayloads()); - - return createIncomingJingleSession(request, null); - } - + // IncomingJingleSession createIncomingJingleSession(JingleSessionRequest request) throws XMPPException { + // if (request == null) { + // throw new NullPointerException("JingleMediaManager is not defined"); + // } + // if (jingleMediaManager != null) + // return createIncomingJingleSession(request, jingleMediaManager.getPayloads()); + // + // return createIncomingJingleSession(request, null); + // } /** * Get a session with the informed JID. If no session is found, return null. * @@ -689,31 +603,35 @@ public class JingleManager implements JingleSessionListener { */ public JingleSession getSession(String jid) { for (JingleSession jingleSession : jingleSessions) { - if (jingleSession instanceof OutgoingJingleSession) { - if (jingleSession.getResponder().equals(jid)) { - return jingleSession; - } - } - else if (jingleSession instanceof IncomingJingleSession) { - if (jingleSession.getInitiator().equals(jid)) { - return jingleSession; - } + if (jingleSession.getResponder().equals(jid)) { + return jingleSession; } } return null; } /** - * Reject the session. If we don't want to accept the new session, send an - * appropriate error packet. + * Reject the session. If we don't want to accept the new session then we have to + * result/ack the session-initiate and send a session-terminate. * * @param request the request to be rejected. */ protected void rejectIncomingJingleSession(JingleSessionRequest request) { - Jingle initiation = request.getJingle(); - IQ rejection = JingleSession.createError(initiation.getPacketID(), initiation - .getFrom(), initiation.getTo(), 403, "Declined"); - connection.sendPacket(rejection); + JingleSession session = getSession(request.getSessionID()); + if (session != null) { + + // First send the result/Ack + IQ result = session.createAck(request.getJingle()); + connection.sendPacket(result); + + // Now send the session-terminate. + try { + session.terminate("Declined"); + } catch (XMPPException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } } \ No newline at end of file diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleNegotiator.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleNegotiator.java index 8de22bb69..88f020227 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleNegotiator.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleNegotiator.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: JingleNegotiator.java,v $ + * $Revision: 1.6 $ + * $Date: 2007/07/17 22:13:16 $ * * Copyright 2003-2005 Jive Software. * @@ -23,10 +23,9 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.jingle.listeners.JingleListener; -import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleError; import java.util.ArrayList; +import java.util.List; /** * Basic Jingle negotiator. @@ -40,17 +39,20 @@ import java.util.ArrayList; *

* * @author Alvaro Saurin + * @author Jeff Williams */ public abstract class JingleNegotiator { - private State state; // Current negotiation state + //private XMPPConnection connection; // The connection associated - private XMPPConnection connection; // The connection associated + protected JingleSession session; - private final ArrayList listeners = new ArrayList(); + private final List listeners = new ArrayList(); private String expectedAckId; + private JingleNegotiatorState state; + /** * Default constructor. */ @@ -63,18 +65,53 @@ public abstract class JingleNegotiator { * * @param connection the connection associated */ - public JingleNegotiator(XMPPConnection connection) { - this.connection = connection; - state = null; + public JingleNegotiator(JingleSession session) { + this.session = session; + state = JingleNegotiatorState.PENDING; + } + + public JingleNegotiatorState getNegotiatorState() { + return state; + } + + public void setNegotiatorState(JingleNegotiatorState stateIs) { + + JingleNegotiatorState stateWas = state; + + System.out.println("Negotiator state change: " + stateWas + "->" + stateIs + "(" + this.getClass().getSimpleName() + ")"); + + switch (stateIs) { + case PENDING: + break; + + case FAILED: + break; + + case SUCCEEDED: + break; + + default: + break; + } + + this.state = stateIs; + } + + public XMPPConnection getConnection() { + if (session != null) { + return session.getConnection(); + } else { + return null; + } } /** - * Get the XMPP connection associated with this negotiation. - * - * @return the connection - */ - public XMPPConnection getConnection() { - return connection; + * Get the XMPP connection associated with this negotiation. + * + * @return the connection + */ + public JingleSession getSession() { + return session; } /** @@ -82,60 +119,8 @@ public abstract class JingleNegotiator { * * @param connection the connection to set */ - public void setConnection(XMPPConnection connection) { - this.connection = connection; - } - - /** - * Inform if current state is null - * - * @return true if current state is null - */ - public boolean invalidState() { - return state == null; - } - - /** - * Return the current state - * - * @return the state - */ - public State getState() { - return state; - } - - /** - * Return the current state class - * - * @return the state - */ - public Class getStateClass() { - if (state != null) { - return state.getClass(); - } - else { - return Object.class; - } - } - - /** - * Set the new state. - * - * @param newState the state to set - * @throws XMPPException - */ - protected void setState(State newState) { - boolean transition = newState != state; - - if (transition && state != null) { - state.eventExit(); - } - - state = newState; - - if (transition && state != null) { - state.eventEnter(); - } + public void setSession(JingleSession session) { + this.session = session; } // Acks management @@ -158,8 +143,7 @@ public abstract class JingleNegotiator { public boolean isExpectedId(String id) { if (id != null) { return id.equals(expectedAckId); - } - else { + } else { return false; } } @@ -204,175 +188,54 @@ public abstract class JingleNegotiator { * * @return a copy of the listeners */ - protected ArrayList getListenersList() { - ArrayList result; + protected List getListenersList() { + ArrayList result; synchronized (listeners) { - result = new ArrayList(listeners); + result = new ArrayList(listeners); } return result; } /** - * Dispatch an incomming packet. This method is responsible for recognizing - * the packet type and, depending on the current state, deliverying the - * packet to the right event handler and wait for a response. + * Dispatch an incoming packet. + * + * The negotiators form a tree relationship that roughly matches the Jingle packet format: + * + * JingleSession + * Content Negotiator + * Media Negotiator + * Transport Negotiator + * Content Negotiator + * Media Negotiator + * Transport Negotiator + * + * + * + * + * + * + * + * + * + * This way, each segment of a Jingle packet has a corresponding negotiator that know how to deal with that + * part of the Jingle packet. It also allows us to support Jingle packets of arbitraty complexity. + * + * Each parent calls dispatchIncomingPacket for each of its children. The children then pass back a List<> of + * results that will get sent when we reach the top level negotiator (JingleSession). * * @param iq the packet received * @param id the ID of the response that will be sent * @return the new packet to send (either a Jingle or an IQ error). * @throws XMPPException */ - public abstract IQ dispatchIncomingPacket(IQ iq, String id) - throws XMPPException; + public abstract List dispatchIncomingPacket(IQ iq, String id) throws XMPPException; /** * Close the negotiation. */ public void close() { - setState(null); - } - /** - * A Jingle exception. - * - * @author Alvaro Saurin - */ - public static class JingleException extends XMPPException { - - private final JingleError error; - - /** - * Default constructor. - */ - public JingleException() { - super(); - error = null; - } - - /** - * Constructor with an error message. - * - * @param msg The message. - */ - public JingleException(String msg) { - super(msg); - error = null; - } - - /** - * Constructor with an error response. - * - * @param error The error message. - */ - public JingleException(JingleError error) { - super(); - this.error = error; - } - - /** - * Return the error message. - * - * @return the error - */ - public JingleError getError() { - return error; - } - } - - /** - * Negotiation state and events. - *

- *

- *

- * Describes the negotiation stage. - */ - public static class State { - - private JingleNegotiator neg; // The negotiator - - /** - * Default constructor, with a reference to the negotiator. - * - * @param neg The negotiator instance. - */ - public State(JingleNegotiator neg) { - this.neg = neg; - } - - /** - * Get the negotiator - * - * @return the negotiator. - */ - public JingleNegotiator getNegotiator() { - return neg; - } - - /** - * Set the negotiator. - * - * @param neg the neg to set - */ - public void setNegotiator(JingleNegotiator neg) { - this.neg = neg; - } - - // State transition events - - public Jingle eventAck(IQ iq) throws XMPPException { - // We have received an Ack - return null; - } - - public void eventError(IQ iq) throws XMPPException { - throw new JingleException(iq.getError().getMessage()); - } - - public Jingle eventInvite() throws XMPPException { - throw new IllegalStateException( - "Negotiation can not be started in this state."); - } - - public Jingle eventInitiate(Jingle jin) throws XMPPException { - return null; - } - - public Jingle eventAccept(Jingle jin) throws XMPPException { - return null; - } - - public Jingle eventRedirect(Jingle jin) throws XMPPException { - return null; - } - - public Jingle eventModify(Jingle jin) throws XMPPException { - return null; - } - - public Jingle eventDecline(Jingle jin) throws XMPPException { - return null; - } - - public Jingle eventInfo(Jingle jin) throws XMPPException { - return null; - } - - public Jingle eventTerminate(Jingle jin) throws XMPPException { - if (neg != null && !neg.invalidState()) { - neg.close(); - } - return null; - } - - public void eventEnter() { - } - - public void eventExit() { - if (neg != null) { - neg.removeExpectedId(null); - } - } } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java index b5b704c57..9bbeb158b 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: JingleSession.java,v $ + * $Revision: 1.20 $ + * $Date: 2007/07/18 18:29:21 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -59,31 +59,31 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; +import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.XMPPError; -import org.jivesoftware.smackx.jingle.listeners.*; +import org.jivesoftware.smackx.jingle.listeners.JingleListener; +import org.jivesoftware.smackx.jingle.listeners.JingleMediaListener; +import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener; +import org.jivesoftware.smackx.jingle.listeners.JingleTransportListener; import org.jivesoftware.smackx.jingle.media.*; +import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.nat.TransportNegotiator; +import org.jivesoftware.smackx.jingle.nat.TransportResolver; import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleContentDescription; -import org.jivesoftware.smackx.packet.JingleContentDescription.JinglePayloadType; -import org.jivesoftware.smackx.packet.JingleContentInfo; import org.jivesoftware.smackx.packet.JingleError; -import org.jivesoftware.smackx.packet.JingleTransport.JingleTransportCandidate; import java.util.*; /** - * An abstract Jingle session. - *

- * This class contains some basic properties of every Jingle session. However, - * the concrete implementation can be found in subclasses. - * + * An abstract Jingle session.

This class contains some basic properties of + * every Jingle session. However, the concrete implementation can be found in + * subclasses. + * * @author Alvaro Saurin - * @see IncomingJingleSession - * @see OutgoingJingleSession + * @author Jeff Williams */ -public abstract class JingleSession extends JingleNegotiator implements MediaReceivedListener { +public class JingleSession extends JingleNegotiator implements MediaReceivedListener { // static private static final HashMap sessions = new HashMap(); @@ -98,43 +98,56 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec private String sid; // A unique id that identifies this session - private MediaNegotiator mediaNeg; // The description... - - private TransportNegotiator transNeg; // and transport negotiators - PacketListener packetListener; PacketFilter packetFilter; - protected JingleMediaManager jingleMediaManager = null; - - protected JingleMediaSession jingleMediaSession = null; + protected List jingleMediaManagers = null; private boolean closed = false; - private List stateListeners = new ArrayList(); + private JingleSessionState sessionState; + + private List contentNegotiators; + + private JingleSessionRequest sessionRequest; + + private XMPPConnection connection; + + private String sessionInitPacketID; + + private Map mediaSessionMap; /** * Full featured JingleSession constructor - * - * @param conn XMPPConnection - * @param initiator the initiator JID - * @param responder the responder JID - * @param sessionid the session ID - * @param jingleMediaManager the jingleMediaManager + * + * @param conn + * XMPPConnection + * @param initiator + * the initiator JID + * @param responder + * the responder JID + * @param sessionid + * the session ID + * @param jingleMediaManager + * the jingleMediaManager */ - protected JingleSession(XMPPConnection conn, String initiator, String responder, - String sessionid, JingleMediaManager jingleMediaManager) { - super(conn); - - this.mediaNeg = null; - this.transNeg = null; + public JingleSession(XMPPConnection conn, String initiator, String responder, String sessionid, + List jingleMediaManagers) { + super(); this.initiator = initiator; this.responder = responder; this.sid = sessionid; + this.jingleMediaManagers = jingleMediaManagers; + this.setSession(this); + this.connection = conn; - this.jingleMediaManager = jingleMediaManager; + // Initially, we don't known the session state. + setSessionState(JingleSessionStateUnknown.getInstance()); + + contentNegotiators = new ArrayList(); + mediaSessionMap = new HashMap(); // Add the session to the list and register the listeneres registerInstance(); @@ -142,41 +155,41 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec } /** - * JingleSession constructor - * - * @param conn XMPPConnection - * @param initiator the initiator JID - * @param responder the responder JID + * JingleSession constructor (for an outgoing Jingle session) + * + * @param conn + * XMPPConnection + * @param initiator + * the initiator JID + * @param responder + * the responder JID + * @param jingleMediaManager + * the jingleMediaManager */ - protected JingleSession(XMPPConnection conn, String initiator, String responder) { - this(conn, initiator, responder, null, null); - } - - /** - * JingleSession constructor - * - * @param conn XMPPConnection - * @param initiator the initiator JID - * @param responder the responder JID - * @param jingleMediaManager the jingleMediaManager - */ - protected JingleSession(XMPPConnection conn, String initiator, String responder, JingleMediaManager jingleMediaManager) { - this(conn, initiator, responder, null, jingleMediaManager); + public JingleSession(XMPPConnection conn, JingleSessionRequest request, String initiator, String responder, + List jingleMediaManagers) { + this(conn, initiator, responder, generateSessionId(), jingleMediaManagers); + sessionRequest = request; } /** * Get the session initiator - * + * * @return the initiator */ public String getInitiator() { return initiator; } + public XMPPConnection getConnection() { + return connection; + } + /** * Set the session initiator - * - * @param initiator the initiator to set + * + * @param initiator + * the initiator to set */ public void setInitiator(String initiator) { this.initiator = initiator; @@ -184,34 +197,25 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Get the Media Manager of this Jingle Session - * + * * @return */ - public JingleMediaManager getMediaManager() { - return jingleMediaManager; + public List getMediaManagers() { + return jingleMediaManagers; } /** * Set the Media Manager of this Jingle Session - * + * * @param jingleMediaManager */ - public void setMediaManager(JingleMediaManager jingleMediaManager) { - this.jingleMediaManager = jingleMediaManager; - } - - /** - * Get the JingleMediaSession of this Jingle Session - * - * @return the JingleMediaSession - */ - public JingleMediaSession getJingleMediaSession() { - return jingleMediaSession; + public void setMediaManagers(List jingleMediaManagers) { + this.jingleMediaManagers = jingleMediaManagers; } /** * Get the session responder - * + * * @return the responder */ public String getResponder() { @@ -220,8 +224,9 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Set the session responder. - * - * @param responder the receptor to set + * + * @param responder + * the receptor to set */ public void setResponder(String responder) { this.responder = responder; @@ -229,7 +234,7 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Get the session ID - * + * * @return the sid */ public String getSid() { @@ -238,8 +243,9 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Set the session ID - * - * @param sessionId the sid to set + * + * @param sessionId + * the sid to set */ protected void setSid(String sessionId) { sid = sessionId; @@ -253,333 +259,217 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec } /** - * Obtain the description negotiator for this session - * - * @return the description negotiator + * Validate the state changes. */ - protected MediaNegotiator getMediaNeg() { - return mediaNeg; + + public void setSessionState(JingleSessionState stateIs) { + + System.out.println("Session state change: " + sessionState + "->" + stateIs); + stateIs.enter(); + sessionState = stateIs; + } + + public JingleSessionState getSessionState() { + return sessionState; } /** - * Set the jmf negotiator. - * - * @param mediaNeg the description negotiator to set - */ - protected void setMediaNeg(MediaNegotiator mediaNeg) { - destroyMediaNeg(); - this.mediaNeg = mediaNeg; - } - - /** - * Destroy the jmf negotiator. - */ - protected void destroyMediaNeg() { - if (mediaNeg != null) { - mediaNeg.close(); - mediaNeg = null; - } - } - - /** - * Adds a State Listener for the Session. It will be called twice every time the Session State changed. One before State change and other after. - * - * @param listener listener to be added - */ - public void addStateListener(JingleSessionStateListener listener) { - stateListeners.add(listener); - } - - /** - * Removes a JingleStateListener - * - * @param listener listener to be removed - */ - public void removedStateListener(JingleSessionStateListener listener) { - stateListeners.remove(listener); - } - - /** - * Removes all JingleSessionStateListeners. - */ - public void removeAllStateListeners() { - stateListeners.clear(); - } - - /** - * Overides JingleNegiociator Method to add listener capabilities - * - * @param newState new State - */ - protected void setState(State newState) { - boolean proceed = true; - State old = getState(); - - for (JingleSessionStateListener listener : stateListeners) - try { - listener.beforeChange(old, newState); - } - catch (JingleException e) { - proceed = false; - } - - if (proceed) - super.setState(newState); - - for (JingleSessionStateListener listener : stateListeners) - listener.afterChanged(old, getState()); - } - - /** - * Obtain the transport negotiator for this session. - * - * @return the transport negotiator instance - */ - protected TransportNegotiator getTransportNeg() { - return transNeg; - } - - /** - * Set TransportNegociator - * - * @param transNeg the transNeg to set - */ - protected void setTransportNeg(TransportNegotiator transNeg) { - destroyTransportNeg(); - this.transNeg = transNeg; - } - - /** - * Destroy the transport negotiator. - */ - protected void destroyTransportNeg() { - if (transNeg != null) { - transNeg.close(); - transNeg = null; - } - } - - /** - * Return true if the transport and content negotiators have finished + * Return true if all of the media managers have finished */ public boolean isFullyEstablished() { - if (!isValid()) { - return false; + boolean result = true; + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (!contentNegotiator.isFullyEstablished()) + result = false; } - if (!getTransportNeg().isFullyEstablished() - || !getMediaNeg().isFullyEstablished()) { - return false; - } - return true; + return result; } + // ---------------------------------------------------------------------------------------------------------- + // Receive section + // ---------------------------------------------------------------------------------------------------------- + /** - * Return true if the session is valid (ie, it has all the required - * elements initialized). - * - * @return true if the session is valid. + * Process and respond to an incoming packet.

This method is called + * from the packet listener dispatcher when a new packet has arrived. The + * method is responsible for recognizing the packet type and, depending on + * the current state, delivering it to the right event handler and wait for + * a response. The response will be another Jingle packet that will be sent + * to the other end point. + * + * @param iq + * the packet received + * @return the new Jingle packet to send. + * @throws XMPPException */ - public boolean isValid() { - return mediaNeg != null && transNeg != null && sid != null && initiator != null; + public synchronized void receivePacketAndRespond(IQ iq) throws XMPPException { + List responses = new ArrayList(); + + String responseId = null; + + System.out.println("Packet: " + iq.toXML()); + + try { + + // Dispatch the packet to the JingleNegotiators and get back a list of the results. + responses.addAll(dispatchIncomingPacket(iq, null)); + + if (iq != null) { + responseId = iq.getPacketID(); + + // Send the IQ to each of the content negotiators for further processing. + // Each content negotiator may pass back a list of JingleContent for addition to the response packet. + + for (ContentNegotiator contentNegotiator : contentNegotiators) { + responses.addAll(contentNegotiator.dispatchIncomingPacket(iq, responseId)); + } + + } + // Acknowledge the IQ reception + // Not anymore. The state machine generates an appropriate response IQ that + // gets sent back at the end of this routine. + //sendAck(iq); + + } catch (JingleException e) { + // Send an error message, if present + JingleError error = e.getError(); + if (error != null) { + responses.add(createJingleError(iq, error)); + } + + // Notify the session end and close everything... + triggerSessionClosedOnError(e); + } + + // // If the response is anything other than a RESULT then send it now. + // if ((response != null) && (!response.getType().equals(IQ.Type.RESULT))) { + // getConnection().sendPacket(response); + // } + + // Loop through all of the responses and send them. + for (IQ response : responses) { + sendPacket(response); + } } /** - * Dispatch an incoming packet. The medthod is responsible for recognizing - * the packet type and, depending on the current state, deliverying the + * Dispatch an incoming packet. The method is responsible for recognizing + * the packet type and, depending on the current state, delivering the * packet to the right event handler and wait for a response. - * - * @param iq the packet received + * + * @param iq + * the packet received * @return the new Jingle packet to send. * @throws XMPPException */ - public IQ dispatchIncomingPacket(IQ iq, String id) throws XMPPException { - IQ jout = null; - - if (invalidState()) { - throw new IllegalStateException( - "Illegal state in dispatch packet in Session manager."); - } - else { - if (iq == null) { - // If there is no input packet, then we must be inviting... - jout = getState().eventInvite(); - } - else { - if (iq.getType().equals(IQ.Type.ERROR)) { - // Process errors - getState().eventError(iq); - } - else if (iq.getType().equals(IQ.Type.RESULT)) { - // Process ACKs - if (isExpectedId(iq.getPacketID())) { - jout = getState().eventAck(iq); - removeExpectedId(iq.getPacketID()); - } - } - else if (iq instanceof Jingle) { - // It is not an error: it is a Jingle packet... - Jingle jin = (Jingle) iq; - Jingle.Action action = jin.getAction(); - - if (action != null) { - if (action.equals(Jingle.Action.SESSIONACCEPT)) { - jout = getState().eventAccept(jin); - } - else if (action.equals(Jingle.Action.SESSIONINFO)) { - jout = getState().eventInfo(jin); - } - else if (action.equals(Jingle.Action.SESSIONINITIATE)) { - - - jout = getState().eventInitiate(jin); - - } - else if (action.equals(Jingle.Action.SESSIONREDIRECT)) { - jout = getState().eventRedirect(jin); - } - else if (action.equals(Jingle.Action.SESSIONTERMINATE)) { - jout = getState().eventTerminate(jin); - } - } - else { - jout = errorMalformedStanza(iq); - } - } - } - - if (jout != null) { - // Save the packet id, for recognizing ACKs... - addExpectedId(jout.getPacketID()); - } - } - - return jout; - } - - /** - * Process and respond to an incomming packet. - *

- * This method is called from the packet listener dispatcher when a new - * packet has arrived. The medthod is responsible for recognizing the packet - * type and, depending on the current state, deliverying it to the right - * event handler and wait for a response. The response will be another - * Jingle packet that will be sent to the other endpoint. - * - * @param iq the packet received - * @return the new Jingle packet to send. - * @throws XMPPException - */ - public synchronized IQ respond(IQ iq) throws XMPPException { + public List dispatchIncomingPacket(IQ iq, String id) throws XMPPException { + List responses = new ArrayList(); IQ response = null; - if (isValid()) { - String responseId = null; - IQ sessionResponse = null; - IQ descriptionResponse = null; - IQ transportResponse = null; + if (iq != null) { + if (iq.getType().equals(IQ.Type.ERROR)) { + // Process errors + // TODO getState().eventError(iq); + } else if (iq.getType().equals(IQ.Type.RESULT)) { + // Process ACKs + if (isExpectedId(iq.getPacketID())) { - // Send the packet to the right event handler for the session... - try { - - sessionResponse = dispatchIncomingPacket(iq, null); - if (sessionResponse != null) { - responseId = sessionResponse.getPacketID(); + // The other side provisionally accepted our session-initiate. + // Kick off some negotiators. + if (iq.getPacketID().equals(sessionInitPacketID)) { + startNegotiators(); + } + removeExpectedId(iq.getPacketID()); } + } else if (iq instanceof Jingle) { + // It is not an error: it is a Jingle packet... + Jingle jin = (Jingle) iq; + JingleActionEnum action = jin.getAction(); - // ... and do the same for the Description and Transport - // parts... - if (mediaNeg != null) { - descriptionResponse = mediaNeg.dispatchIncomingPacket(iq, responseId); - } - - if (transNeg != null) { - transportResponse = transNeg.dispatchIncomingPacket(iq, responseId); - } - - // Acknowledge the IQ reception - sendAck(iq); - - // ... and send all these parts in a Jingle response. - response = sendJingleParts(iq, (Jingle) sessionResponse, - (Jingle) descriptionResponse, (Jingle) transportResponse); - } - catch (JingleException e) { - // Send an error message, if present - JingleError error = e.getError(); - if (error != null) { - sendFormattedError(iq, error); - } - - // Notify the session end and close everything... - triggerSessionClosedOnError(e); + // Depending on the state we're in we'll get different processing actions. + // (See Design Patterns AKA GoF State behavioral pattern.) + getSessionState().processJingle(this, jin, action); } } - return response; - } - - // Packet formatting and delivery - - /** - * Put together all the parts ina Jingle packet. - * - * @return the new Jingle packet - */ - private Jingle sendJingleParts(IQ iq, Jingle jSes, Jingle jDesc, - Jingle jTrans) { - Jingle response = null; - - if (jSes != null) { - jSes.addDescriptions(jDesc.getDescriptionsList()); - jSes.addTransports(jTrans.getTransportsList()); - - response = sendFormattedJingle(iq, jSes); - } - else { - // If we don't have a valid session message, then we must send - // separated messages for transport and jmf... - if (jDesc != null) { - response = sendFormattedJingle(iq, jDesc); - } - - if (jTrans != null) { - response = sendFormattedJingle(iq, jTrans); - } + if (response != null) { + // Save the packet id, for recognizing ACKs... + addExpectedId(response.getPacketID()); + responses.add(response); } - return response; + return responses; } /** - * Complete and send an error. Complete all the null fields in an IQ error - * reponse, using the sesssion information we have or some info from the - * incoming packet. - * - * @param iq The Jingle packet we are responing to - * @param error the IQ packet we want to complete and send + * Add a new content negotiator on behalf of a section received. */ - public IQ sendFormattedError(IQ iq, JingleError error) { - IQ perror = null; - if (error != null) { - perror = createIQ(getSid(), iq.getFrom(), iq.getTo(), IQ.Type.ERROR); + public void addContentNegotiator(ContentNegotiator inContentNegotiator) { + contentNegotiators.add(inContentNegotiator); + } - // Fill in the fields with the info from the Jingle packet - perror.setPacketID(iq.getPacketID()); - perror.addExtension(error); + - getConnection().sendPacket(perror); - System.err.println(error.toXML()); + // ---------------------------------------------------------------------------------------------------------- + // Send section + // ---------------------------------------------------------------------------------------------------------- + + public void sendPacket(IQ iq) { + + if (iq instanceof Jingle) { + // Jingle jingle = (Jingle) iq; + // + // JingleActionEnum action = jingle.getAction(); + // + // switch (getSessionState()) { + // case UNKNOWN: + // sendUnknownStateAction(jingle, action); + // break; + // + // case PENDING: + // sendPendingStateAction(jingle, action); + // break; + // + // case ACTIVE: + // sendActiveStateAction(jingle, action); + // break; + // + // case ENDED: + // sendEndedStateAction(jingle, action); + // break; + // + // default: + // break; + // } + + sendFormattedJingle((Jingle) iq); + + } else { + + getConnection().sendPacket(iq); } - return perror; + } + + /** + * Complete and send a packet. Complete all the null fields in a Jingle + * reponse, using the session information we have. + * + * @param jout + * the Jingle packet we want to complete and send + */ + public Jingle sendFormattedJingle(Jingle jout) { + return sendFormattedJingle(null, jout); } /** * Complete and send a packet. Complete all the null fields in a Jingle * reponse, using the session information we have or some info from the * incoming packet. - * - * @param iq The Jingle packet we are responing to - * @param jout the Jingle packet we want to complete and send + * + * @param iq + * The Jingle packet we are responing to + * @param jout + * the Jingle packet we want to complete and send */ public Jingle sendFormattedJingle(IQ iq, Jingle jout) { if (jout != null) { @@ -601,8 +491,7 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec if (jout.getTo() == null) { if (iq != null) { jout.setTo(iq.getFrom()); - } - else { + } else { jout.setTo(other); } } @@ -610,68 +499,76 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec if (jout.getFrom() == null) { if (iq != null) { jout.setFrom(iq.getTo()); - } - else { + } else { jout.setFrom(me); } } + + // The the packet. getConnection().sendPacket(jout); } return jout; } /** - * Complete and send a packet. Complete all the null fields in a Jingle - * reponse, using the session information we have. - * - * @param jout the Jingle packet we want to complete and send + * @param inJingle + * @param inAction */ - public Jingle sendFormattedJingle(Jingle jout) { - return sendFormattedJingle(null, jout); + // private void sendUnknownStateAction(Jingle inJingle, JingleActionEnum inAction) { + // + // if (inAction == JingleActionEnum.SESSION_INITIATE) { + // // Prepare to receive and act on response packets. + // updatePacketListener(); + // + // // Send the actual packet. + // sendPacket(inJingle); + // + // // Change to the PENDING state. + // setSessionState(JingleSessionStateEnum.PENDING); + // } else { + // throw new IllegalStateException("Only session-initiate allowed in the UNKNOWN state."); + // } + // } + /** + * @param inJingle + * @param inAction + */ + private void sendPendingStateAction(Jingle inJingle, JingleActionEnum inAction) { + } /** - * Send an error indicating that the stanza is malformed. - * - * @param iq + * @param inJingle + * @param inAction */ - protected IQ errorMalformedStanza(IQ iq) { - // FIXME: implement with the right message... - return createError(iq.getPacketID(), iq.getFrom(), getConnection().getUser(), - 400, "Bad Request"); + private void sendActiveStateAction(Jingle inJingle, JingleActionEnum inAction) { + } /** - * Check if we have an established session and, in that case, send an Accept - * packet. + * @param inJingle + * @param inAction */ - protected Jingle sendAcceptIfFullyEstablished() { - Jingle result = null; - if (isFullyEstablished()) { - // Ok, send a packet saying that we accept this session - Jingle jout = new Jingle(Jingle.Action.SESSIONACCEPT); - jout.setType(IQ.Type.SET); + private void sendEndedStateAction(Jingle inJingle, JingleActionEnum inAction) { - result = sendFormattedJingle(jout); - } - return result; } /** * Acknowledge a IQ packet. - * - * @param iq The IQ to acknowledge + * + * @param iq + * The IQ to acknowledge */ - public IQ sendAck(IQ iq) { + public IQ createAck(IQ iq) { IQ result = null; if (iq != null) { // Don't acknowledge ACKs, errors... if (iq.getType().equals(IQ.Type.SET)) { - IQ ack = createIQ(iq.getPacketID(), iq.getFrom(), iq.getTo(), - IQ.Type.RESULT); + IQ ack = createIQ(iq.getPacketID(), iq.getFrom(), iq.getTo(), IQ.Type.RESULT); - getConnection().sendPacket(ack); + // No! Don't send it. Let it flow to the normal way IQ results get processed and sent. + // getConnection().sendPacket(ack); result = ack; } } @@ -681,95 +578,23 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Send a content info message. */ - public synchronized void sendContentInfo(ContentInfo ci) { - if (isValid()) { - sendFormattedJingle(new Jingle(new JingleContentInfo(ci))); - } - } - - /** - * Get the content description the other part has accepted. - * - * @param jin The Jingle packet where they have accepted the session. - * @return The audio PayloadType they have accepted. - * @throws XMPPException - */ - protected PayloadType.Audio getAcceptedAudioPayloadType(Jingle jin) - throws XMPPException { - PayloadType.Audio acceptedPayloadType = null; - ArrayList jda = jin.getDescriptionsList(); - - if (jin.getAction().equals(Jingle.Action.SESSIONACCEPT)) { - - if (jda.size() > 1) { - throw new XMPPException( - "Unsupported feature: the number of accepted content descriptions is greater than 1."); - } - else if (jda.size() == 1) { - JingleContentDescription jd = (JingleContentDescription) jda.get(0); - if (jd.getJinglePayloadTypesCount() > 1) { - throw new XMPPException( - "Unsupported feature: the number of accepted payload types is greater than 1."); - } - if (jd.getJinglePayloadTypesCount() == 1) { - JinglePayloadType jpt = (JinglePayloadType) jd - .getJinglePayloadTypesList().get(0); - acceptedPayloadType = (PayloadType.Audio) jpt.getPayloadType(); - } - } - } - return acceptedPayloadType; - } - - /** - * Get the accepted local candidate we have previously offered. - * - * @param jin The jingle packet where they accept the session - * @return The transport candidate they have accepted. - * @throws XMPPException - */ - protected TransportCandidate getAcceptedLocalCandidate(Jingle jin) - throws XMPPException { - ArrayList jta = jin.getTransportsList(); - TransportCandidate acceptedLocalCandidate = null; - - if (jin.getAction().equals(Jingle.Action.SESSIONACCEPT)) { - if (jta.size() > 1) { - throw new XMPPException( - "Unsupported feature: the number of accepted transports is greater than 1."); - } - else if (jta.size() == 1) { - org.jivesoftware.smackx.packet.JingleTransport jt = (org.jivesoftware.smackx.packet.JingleTransport) jta.get(0); - - if (jt.getCandidatesCount() > 1) { - throw new XMPPException( - "Unsupported feature: the number of accepted transport candidates is greater than 1."); - } - else if (jt.getCandidatesCount() == 1) { - JingleTransportCandidate jtc = (JingleTransportCandidate) jt - .getCandidatesList().get(0); - acceptedLocalCandidate = jtc.getMediaTransport(); - } - } - } - - return acceptedLocalCandidate; - } - + // public synchronized void sendContentInfo(ContentInfo ci) { + // sendPacket(new Jingle(new JingleContentInfo(ci))); + // } /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ public int hashCode() { return Jingle.getSessionHash(getSid(), getInitiator()); } /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ public boolean equals(Object obj) { if (this == obj) { return true; @@ -787,18 +612,16 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec if (other.initiator != null) { return false; } - } - else if (!initiator.equals(other.initiator)) { - //Todo check behavior - // return false; + } else if (!initiator.equals(other.initiator)) { + // Todo check behavior + // return false; } if (responder == null) { if (other.responder != null) { return false; } - } - else if (!responder.equals(other.responder)) { + } else if (!responder.equals(other.responder)) { return false; } @@ -806,8 +629,7 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec if (other.sid != null) { return false; } - } - else if (!sid.equals(other.sid)) { + } else if (!sid.equals(other.sid)) { return false; } @@ -818,8 +640,9 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Clean a session from the list. - * - * @param connection The connection to clean up + * + * @param connection + * The connection to clean up */ private void unregisterInstanceFor(XMPPConnection connection) { synchronized (sessions) { @@ -838,8 +661,9 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Returns the JingleSession related to a particular connection. - * - * @param con A XMPP connection + * + * @param con + * A XMPP connection * @return a Jingle session */ public static JingleSession getInstanceFor(XMPPConnection con) { @@ -857,11 +681,11 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec return result; } - /** * Configure a session, setting some action listeners... - * - * @param connection The connection to set up + * + * @param connection + * The connection to set up */ private void installConnectionListeners(final XMPPConnection connection) { if (connection != null) { @@ -909,9 +733,8 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec packetListener = new PacketListener() { public void processPacket(Packet packet) { try { - respond((IQ) packet); - } - catch (XMPPException e) { + receivePacketAndRespond((IQ) packet); + } catch (XMPPException e) { e.printStackTrace(); } } @@ -929,8 +752,7 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec return false; } - String other = getResponder().equals(me) ? getInitiator() - : getResponder(); + String other = getResponder().equals(me) ? getInitiator() : getResponder(); if (iq.getFrom() == null || !iq.getFrom().equals(other == null ? "" : other)) { return false; @@ -939,8 +761,6 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec if (iq instanceof Jingle) { Jingle jin = (Jingle) iq; - System.out.println("Jingle: " + iq.toXML()); - String sid = jin.getSid(); if (sid == null || !sid.equals(getSid())) { System.out.println("Ignored Jingle(SID) " + sid + "|" + getSid() + " :" + iq.toXML()); @@ -951,14 +771,12 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec System.out.println("Ignored Jingle(INI): " + iq.toXML()); return false; } - } - else { + } else { // We accept some non-Jingle IQ packets: ERRORs and ACKs if (iq.getType().equals(IQ.Type.SET)) { System.out.println("Ignored Jingle(TYPE): " + iq.toXML()); return false; - } - else if (iq.getType().equals(IQ.Type.GET)) { + } else if (iq.getType().equals(IQ.Type.GET)) { System.out.println("Ignored Jingle(TYPE): " + iq.toXML()); return false; } @@ -976,136 +794,188 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Add a listener for jmf negotiation events - * - * @param li The listener + * + * @param li + * The listener */ public void addMediaListener(JingleMediaListener li) { - if (getMediaNeg() != null) { - getMediaNeg().addListener(li); + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getMediaNegotiator() != null) { + contentNegotiator.getMediaNegotiator().addListener(li); + } } + } /** * Remove a listener for jmf negotiation events - * - * @param li The listener + * + * @param li + * The listener */ public void removeMediaListener(JingleMediaListener li) { - if (getMediaNeg() != null) { - getMediaNeg().removeListener(li); + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getMediaNegotiator() != null) { + contentNegotiator.getMediaNegotiator().removeListener(li); + } } } /** * Add a listener for transport negotiation events - * - * @param li The listener + * + * @param li + * The listener */ public void addTransportListener(JingleTransportListener li) { - if (getTransportNeg() != null) { - getTransportNeg().addListener(li); + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getTransportNegotiator() != null) { + contentNegotiator.getTransportNegotiator().addListener(li); + } } } /** * Remove a listener for transport negotiation events - * - * @param li The listener + * + * @param li + * The listener */ public void removeTransportListener(JingleTransportListener li) { - if (getTransportNeg() != null) { - getTransportNeg().removeListener(li); + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getTransportNegotiator() != null) { + contentNegotiator.getTransportNegotiator().removeListener(li); + } } } + /** + * Setup the listeners that act on events coming from the lower level negotiators. + */ + + public void setupListeners() { + + JingleMediaListener jingleMediaListener = new JingleMediaListener() { + public void mediaClosed(PayloadType cand) { + } + + public void mediaEstablished(PayloadType pt) { + if (isFullyEstablished()) { + Jingle jout = new Jingle(JingleActionEnum.SESSION_ACCEPT); + + // Build up a response packet from each media manager. + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getNegotiatorState() == JingleNegotiatorState.SUCCEEDED) + jout.addContent(contentNegotiator.getJingleContent()); + } + // Send the "accept" and wait for the ACK + addExpectedId(jout.getPacketID()); + sendPacket(jout); + + //triggerSessionEstablished(); + + } + } + }; + + JingleTransportListener jingleTransportListener = new JingleTransportListener() { + + public void transportEstablished(TransportCandidate local, TransportCandidate remote) { + if (isFullyEstablished()) { + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getNegotiatorState() == JingleNegotiatorState.SUCCEEDED) + contentNegotiator.triggerContentEstablished(); + } + + if (getSessionState().equals(JingleSessionStatePending.getInstance())) { + Jingle jout = new Jingle(JingleActionEnum.SESSION_ACCEPT); + + // Build up a response packet from each media manager. + for (ContentNegotiator contentNegotiator : contentNegotiators) { + if (contentNegotiator.getNegotiatorState() == JingleNegotiatorState.SUCCEEDED) + jout.addContent(contentNegotiator.getJingleContent()); + } + // Send the "accept" and wait for the ACK + addExpectedId(jout.getPacketID()); + sendPacket(jout); + } + } + } + + public void transportClosed(TransportCandidate cand) { + } + + public void transportClosedOnError(XMPPException e) { + } + }; + + addMediaListener(jingleMediaListener); + addTransportListener(jingleTransportListener); + } + // Triggers /** * Trigger a session closed event. */ protected void triggerSessionClosed(String reason) { - for (TransportCandidate candidate : this.getTransportNeg().getOfferedCandidates()) - candidate.removeCandidateEcho(); + // for (ContentNegotiator contentNegotiator : contentNegotiators) { + // + // contentNegotiator.stopJingleMediaSession(); + // + // for (TransportCandidate candidate : contentNegotiator.getTransportNegotiator().getOfferedCandidates()) + // candidate.removeCandidateEcho(); + // } - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleSessionListener) { JingleSessionListener sli = (JingleSessionListener) li; sli.sessionClosed(reason, this); } } close(); - if (jingleMediaSession != null) { - jingleMediaSession.stopTrasmit(); - jingleMediaSession.stopReceive(); - } } /** * Trigger a session closed event due to an error. */ protected void triggerSessionClosedOnError(XMPPException exc) { - for (TransportCandidate candidate : this.getTransportNeg().getOfferedCandidates()) - candidate.removeCandidateEcho(); - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); + for (ContentNegotiator contentNegotiator : contentNegotiators) { + + contentNegotiator.stopJingleMediaSession(); + + for (TransportCandidate candidate : contentNegotiator.getTransportNegotiator().getOfferedCandidates()) + candidate.removeCandidateEcho(); + } + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleSessionListener) { JingleSessionListener sli = (JingleSessionListener) li; sli.sessionClosedOnError(exc, this); } } close(); - if (jingleMediaSession != null) { - jingleMediaSession.stopTrasmit(); - jingleMediaSession.stopReceive(); - } } /** * Trigger a session established event. */ - protected void triggerSessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc) { - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); - if (li instanceof JingleSessionListener) { - JingleSessionListener sli = (JingleSessionListener) li; - sli.sessionEstablished(pt, rc, lc, this); - } - } - if (jingleMediaManager != null) { - rc.removeCandidateEcho(); - lc.removeCandidateEcho(); - - jingleMediaSession = jingleMediaManager.createMediaSession(pt, rc, lc, this); - jingleMediaSession.addMediaReceivedListener(this); - if (jingleMediaSession != null) { - - jingleMediaSession.startTrasmit(); - jingleMediaSession.startReceive(); - - for (TransportCandidate candidate : this.getTransportNeg().getOfferedCandidates()) - candidate.removeCandidateEcho(); - - } - } - - } - + // protected void triggerSessionEstablished() { + // List listeners = getListenersList(); + // for (JingleListener li : listeners) { + // if (li instanceof JingleSessionListener) { + // JingleSessionListener sli = (JingleSessionListener) li; + // sli.sessionEstablished(this); + // } + // } + // } /** - * Trigger a session closed event due to an error. + * Trigger a media received event. */ protected void triggerMediaReceived(String participant) { - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleSessionListener) { JingleSessionListener sli = (JingleSessionListener) li; sli.sessionMediaReceived(this, participant); @@ -1116,46 +986,34 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Trigger a session redirect event. */ - protected void triggerSessionRedirect(String arg) { - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); - if (li instanceof JingleSessionListener) { - JingleSessionListener sli = (JingleSessionListener) li; - sli.sessionRedirected(arg, this); - } - } - } - + // protected void triggerSessionRedirect(String arg) { + // List listeners = getListenersList(); + // for (JingleListener li : listeners) { + // if (li instanceof JingleSessionListener) { + // JingleSessionListener sli = (JingleSessionListener) li; + // sli.sessionRedirected(arg, this); + // } + // } + // } /** - * Trigger a session redirect event. + * Trigger a session decline event. */ - protected void triggerSessionDeclined(String reason) { - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); - if (li instanceof JingleSessionListener) { - JingleSessionListener sli = (JingleSessionListener) li; - sli.sessionDeclined(reason, this); - } - } - for (TransportCandidate candidate : this.getTransportNeg().getOfferedCandidates()) - candidate.removeCandidateEcho(); - } - - /** - * Start the negotiation. - * - * @throws JingleException - * @throws XMPPException - */ - public abstract void start(JingleSessionRequest jin) throws XMPPException; - + // protected void triggerSessionDeclined(String reason) { + // List listeners = getListenersList(); + // for (JingleListener li : listeners) { + // if (li instanceof JingleSessionListener) { + // JingleSessionListener sli = (JingleSessionListener) li; + // sli.sessionDeclined(reason, this); + // } + // } + // for (ContentNegotiator contentNegotiator : contentNegotiators) { + // for (TransportCandidate candidate : contentNegotiator.getTransportNegotiator().getOfferedCandidates()) + // candidate.removeCandidateEcho(); + // } + // } /** * Terminates the session with default reason. - * + * * @throws XMPPException */ public void terminate() throws XMPPException { @@ -1164,15 +1022,16 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * Terminates the session with a custom reason. - * + * * @throws XMPPException */ public void terminate(String reason) throws XMPPException { - if (isClosed()) return; - System.out.println("State: " + this.getState()); - Jingle jout = new Jingle(Jingle.Action.SESSIONTERMINATE); + if (isClosed()) + return; + System.out.println("Terminate " + reason); + Jingle jout = new Jingle(JingleActionEnum.SESSION_TERMINATE); jout.setType(IQ.Type.SET); - sendFormattedJingle(jout); + sendPacket(jout); triggerSessionClosed(reason); } @@ -1180,32 +1039,47 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec * Terminate negotiations. */ public void close() { - if (isClosed()) return; - destroyMediaNeg(); - destroyTransportNeg(); + if (isClosed()) + return; + + // Set the session state to ENDED. + setSessionState(JingleSessionStateEnded.getInstance()); + + for (ContentNegotiator contentNegotiator : contentNegotiators) { + + contentNegotiator.stopJingleMediaSession(); + + for (TransportCandidate candidate : contentNegotiator.getTransportNegotiator().getOfferedCandidates()) + candidate.removeCandidateEcho(); + + contentNegotiator.close(); + } removePacketListener(); System.out.println("Negotiation Closed: " + getConnection().getUser() + " " + sid); - closed = true; super.close(); + } public boolean isClosed() { - return closed; + return getSessionState().equals(JingleSessionStateEnded.getInstance()); } // Packet and error creation /** * A convience method to create an IQ packet. - * - * @param ID The packet ID of the - * @param to To whom the packet is addressed. - * @param from From whom the packet is sent. - * @param type The iq type of the packet. + * + * @param ID + * The packet ID of the + * @param to + * To whom the packet is addressed. + * @param from + * From whom the packet is sent. + * @param type + * The iq type of the packet. * @return The created IQ packet. */ - public static IQ createIQ(String ID, String to, String from, - IQ.Type type) { + public static IQ createIQ(String ID, String to, String from, IQ.Type type) { IQ iqPacket = new IQ() { public String getChildElementXML() { return null; @@ -1222,19 +1096,22 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec /** * A convience method to create an error packet. - * - * @param ID The packet ID of the - * @param to To whom the packet is addressed. - * @param from From whom the packet is sent. - * @param errCode The error code. - * @param errStr The error string. + * + * @param ID + * The packet ID of the + * @param to + * To whom the packet is addressed. + * @param from + * From whom the packet is sent. + * @param errCode + * The error code. + * @param errStr + * The error string. * @return The created IQ packet. */ - public static IQ createError(String ID, String to, String from, - int errCode, String errStr) { + public static IQ createError(String ID, String to, String from, int errCode, XMPPError error) { IQ iqError = createIQ(ID, to, from, IQ.Type.ERROR); - XMPPError error = new XMPPError(new XMPPError.Condition(errStr)); iqError.setError(error); System.out.println("Created Error Packet:" + iqError.toXML()); @@ -1242,10 +1119,138 @@ public abstract class JingleSession extends JingleNegotiator implements MediaRec return iqError; } + /** + * Complete and send an error. Complete all the null fields in an IQ error + * reponse, using the sesssion information we have or some info from the + * incoming packet. + * + * @param iq + * The Jingle packet we are responing to + * @param error + * the IQ packet we want to complete and send + */ + public IQ createJingleError(IQ iq, JingleError jingleError) { + IQ errorPacket = null; + if (jingleError != null) { + errorPacket = createIQ(getSid(), iq.getFrom(), iq.getTo(), IQ.Type.ERROR); + + List extList = new ArrayList(); + extList.add(jingleError); + XMPPError error = new XMPPError(0, XMPPError.Type.CANCEL, jingleError.toString(), "", extList); + + // Fill in the fields with the info from the Jingle packet + errorPacket.setPacketID(iq.getPacketID()); + errorPacket.setError(error); + // errorPacket.addExtension(jingleError); + + // NO! Let the normal state machinery do all of the sending. + // getConnection().sendPacket(perror); + System.err.println("Error sent: " + errorPacket.toXML()); + } + return errorPacket; + } + /** * Called when new Media is received. */ public void mediaReceived(String participant) { triggerMediaReceived(participant); } + + /** + * This is the starting point for intitiating a new session. + * + * @throws IllegalStateException + */ + public void startOutgoing() throws IllegalStateException { + + updatePacketListener(); + setSessionState(JingleSessionStatePending.getInstance()); + + Jingle jingle = new Jingle(JingleActionEnum.SESSION_INITIATE); + + // Create a content negotiator for each media manager on the session. + for (JingleMediaManager mediaManager : getMediaManagers()) { + ContentNegotiator contentNeg = new ContentNegotiator(this, ContentNegotiator.INITIATOR, mediaManager.getName()); + + // Create the media negotiator for this content description. + contentNeg.setMediaNegotiator(new MediaNegotiator(this, mediaManager, mediaManager.getPayloads(), contentNeg)); + + JingleTransportManager transportManager = mediaManager.getTransportManager(); + TransportResolver resolver = null; + try { + resolver = transportManager.getResolver(this); + } catch (XMPPException e) { + e.printStackTrace(); + } + + if (resolver.getType().equals(TransportResolver.Type.rawupd)) { + contentNeg.setTransportNegotiator(new TransportNegotiator.RawUdp(this, resolver, contentNeg)); + } + if (resolver.getType().equals(TransportResolver.Type.ice)) { + contentNeg.setTransportNegotiator(new TransportNegotiator.Ice(this, resolver, contentNeg)); + } + + addContentNegotiator(contentNeg); + } + + // Give each of the content negotiators a chance to return a portion of the structure to make the Jingle packet. + for (ContentNegotiator contentNegotiator : contentNegotiators) { + jingle.addContent(contentNegotiator.getJingleContent()); + } + + // Save the session-initiate packet ID, so that we can respond to it. + sessionInitPacketID = jingle.getPacketID(); + + sendPacket(jingle); + + // Now setup to track the media negotiators, so that we know when (if) to send a session-accept. + setupListeners(); + + // Give each of the content negotiators a chance to start + // and return a portion of the structure to make the Jingle packet. + for (ContentNegotiator contentNegotiator : contentNegotiators) { + contentNegotiator.start(); + } + } + + /** + * This is the starting point for responding to a new session. + */ + public void startIncoming() { + + //updatePacketListener(); + } + + /** + * When we initiate a session we need to start a bunch of negotiators right after we receive the result + * packet for our session-initiate. This is where we start them. + * + */ + private void startNegotiators() { + + for (ContentNegotiator contentNegotiator : contentNegotiators) { + TransportNegotiator transNeg = contentNegotiator.getTransportNegotiator(); + transNeg.start(); + } + } + + /** + * The jingle session may have one or more media managers that are trying to establish media sessions. + * When the media manager succeeds in creating a media session is registers it with the session by the + * media manager's static name. This routine is where the media manager does the registering. + */ + public void addJingleMediaSession(String mediaManagerName, JingleMediaSession mediaSession) { + mediaSessionMap.put(mediaManagerName, mediaSession); + } + + /** + * The jingle session may have one or more media managers that are trying to establish media sessions. + * When the media manager succeeds in creating a media session is registers it with the session by the + * media manager's static name. This routine is where other objects can access the registered media sessions. + * NB: If the media manager has not succeeded in establishing a media session then this could return null. + */ + public JingleMediaSession getMediaSession(String mediaManagerName) { + return mediaSessionMap.get(mediaManagerName); + } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSessionRequest.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSessionRequest.java index c692f33f2..d88217e99 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSessionRequest.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSessionRequest.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: JingleSessionRequest.java,v $ + * $Revision: 1.2 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. @@ -20,11 +20,8 @@ package org.jivesoftware.smackx.jingle; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smackx.jingle.media.PayloadType; import org.jivesoftware.smackx.packet.Jingle; -import java.util.List; - /** * A Jingle session request. *

@@ -75,7 +72,7 @@ public class JingleSessionRequest { } /** - * Returns the Jingle packet that was sent by the requestor which contains + * Returns the Jingle packet that was sent by the requester which contains * the parameters of the session. */ public Jingle getJingle() { @@ -89,19 +86,17 @@ public class JingleSessionRequest { * @return Returns the IncomingJingleSession on which the * negotiation can be carried out. */ - public synchronized IncomingJingleSession accept(List pts) throws XMPPException { - IncomingJingleSession session = null; - synchronized (manager) { - session = manager.createIncomingJingleSession(this, - pts); - session.setInitialSessionRequest(this); - // Acknowledge the IQ reception - session.setSid(this.getSessionID()); - //session.sendAck(this.getJingle()); - //session.respond(this.getJingle()); - } - return session; - } +// public synchronized JingleSession accept(List pts) throws XMPPException { +// JingleSession session = null; +// synchronized (manager) { +// session = manager.createIncomingJingleSession(this, pts); +// // Acknowledge the IQ reception +// session.setSid(this.getSessionID()); +// //session.sendAck(this.getJingle()); +// //session.respond(this.getJingle()); +// } +// return session; +// } /** * Accepts this request and creates the incoming Jingle session. @@ -109,16 +104,15 @@ public class JingleSessionRequest { * @return Returns the IncomingJingleSession on which the * negotiation can be carried out. */ - public synchronized IncomingJingleSession accept() throws XMPPException { - IncomingJingleSession session = null; + public synchronized JingleSession accept() throws XMPPException { + JingleSession session = null; synchronized (manager) { session = manager.createIncomingJingleSession(this); - session.setInitialSessionRequest(this); // Acknowledge the IQ reception session.setSid(this.getSessionID()); //session.sendAck(this.getJingle()); - //session.updatePacketListener(); - //session.respond(this.getJingle()); + session.updatePacketListener(); + session.receivePacketAndRespond(this.getJingle()); } return session; } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/OutgoingJingleSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/OutgoingJingleSession.java deleted file mode 100644 index 3813fc6cd..000000000 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/OutgoingJingleSession.java +++ /dev/null @@ -1,478 +0,0 @@ -/** - * $RCSfile$ - * $Revision$ - * $Date$ - * - * Copyright (C) 2002-2006 Jive Software. All rights reserved. - * ==================================================================== - * The Jive Software License (based on Apache Software License, Version 1.1) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by - * Jive Software (http://www.jivesoftware.com)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Smack" and "Jive Software" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please - * contact webmaster@jivesoftware.com. - * - * 5. Products derived from this software may not be called "Smack", - * nor may "Smack" appear in their name, without prior written - * permission of Jive Software. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - */ - -package org.jivesoftware.smackx.jingle; - -import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smackx.jingle.listeners.JingleMediaListener; -import org.jivesoftware.smackx.jingle.listeners.JingleTransportListener; -import org.jivesoftware.smackx.jingle.media.JingleMediaManager; -import org.jivesoftware.smackx.jingle.media.MediaNegotiator; -import org.jivesoftware.smackx.jingle.media.PayloadType; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.nat.TransportNegotiator; -import org.jivesoftware.smackx.jingle.nat.TransportResolver; -import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; -import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleContentDescription; -import org.jivesoftware.smackx.packet.JingleContentDescription.JinglePayloadType; -import org.jivesoftware.smackx.packet.JingleError; - -import java.util.List; - -/** - * An outgoing Jingle session implementation. - * This class has especific bahavior to Request and establish a new Jingle Session. - *

- * This class is not directly used by users. Instead, users should refer to the - * JingleManager class, that will create the appropiate instance... - * - * @author Alvaro Saurin - * @author Thiago Camargo - */ -public class OutgoingJingleSession extends JingleSession { - - // states - - private final Inviting inviting; - - private final Pending pending; - - private final Active active; - - /** - * Constructor for a Jingle outgoing session. - * - * @param conn the XMPP connection - * @param responder the other endpoint - * @param payloadTypes A list of payload types, in order of preference. - * @param transportManager The transport manager. - */ - protected OutgoingJingleSession(XMPPConnection conn, String responder, - List payloadTypes, JingleTransportManager transportManager) { - - super(conn, conn.getUser(), responder); - - setSid(generateSessionId()); - - // Initialize the states. - inviting = new Inviting(this); - pending = new Pending(this); - active = new Active(this); - - TransportResolver resolver = null; - try { - resolver = transportManager.getResolver(this); - } - catch (XMPPException e) { - e.printStackTrace(); - } - - // Create description and transport negotiatiors... - setMediaNeg(new MediaNegotiator(this, payloadTypes)); - if (resolver.getType().equals(TransportResolver.Type.rawupd)) { - setTransportNeg(new TransportNegotiator.RawUdp(this, resolver)); - } - if (resolver.getType().equals(TransportResolver.Type.ice)) { - setTransportNeg(new TransportNegotiator.Ice(this, resolver)); - } - } - - /** - * Constructor for a Jingle outgoing session with a defined Media Manager - * - * @param conn the XMPP connection - * @param responder the other endpoint - * @param payloadTypes A list of payload types, in order of preference. - * @param transportManager The transport manager. - * @param jingleMediaManager The Media Manager for this Session - */ - protected OutgoingJingleSession(XMPPConnection conn, String responder, - List payloadTypes, JingleTransportManager transportManager, JingleMediaManager jingleMediaManager) { - this(conn, responder, payloadTypes, transportManager); - this.jingleMediaManager = jingleMediaManager; - } - - /** - * Initiate the negotiation with an invitation. This method must be invoked - * for starting all negotiations. It is the initial starting point and, - * afterwards, any other packet processing is done with the packet listener - * callback... - * - * @throws IllegalStateException - */ - public void start(JingleSessionRequest req) throws IllegalStateException { - if (invalidState()) { - setState(inviting); - - // Use the standard behavior, using a null Jingle packet - try { - updatePacketListener(); - respond((Jingle) null); - } - catch (XMPPException e) { - e.printStackTrace(); - close(); - } - } - else { - throw new IllegalStateException("Starting session without null state."); - } - } - - /** - * Initiate the negotiation with an invitation. This method must be invoked - * for starting all negotiations. It is the initial starting point and, - * afterwards, any other packet processing is done with the packet listener - * callback... - * - * @throws IllegalStateException - */ - public void start() throws IllegalStateException { - start(null); - } - - // States - - /** - * Current state when we want to invite the other endpoint. - */ - public class Inviting extends JingleNegotiator.State { - - public Inviting(JingleNegotiator neg) { - super(neg); - } - - /** - * Create an invitation packet. - */ - public Jingle eventInvite() { - // Create an invitation packet, saving the Packet ID, for any ACK - return new Jingle(Jingle.Action.SESSIONINITIATE); - } - - /** - * The receiver has partially accepted our invitation. We go to the - * pending state while the content and transport negotiators work... - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ) - */ - public Jingle eventAck(IQ iq) { - setState(pending); - return null; - } - - /** - * The other endpoint has declined the invitation with an error. - * - * @throws XMPPException - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventError(org.jivesoftware.smack.packet.IQ) - */ - public void eventError(IQ iq) throws XMPPException { - triggerSessionDeclined(null); - super.eventError(iq); - } - - /** - * The other endpoint wants to redirect this connection. - */ - public Jingle eventRedirect(Jingle jin) { - String redirArg = null; - - // TODO: parse the redirection parameters... - - triggerSessionRedirect(redirArg); - return null; - } - - /** - * Terminate the connection. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventTerminate(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventTerminate(Jingle jin) throws XMPPException { - triggerSessionClosed("Closed Remotely"); - return super.eventTerminate(jin); - } - } - - /** - * "Pending" state: we are waiting for the transport and content - * negotiators. - *

- * Note: the transition from/to this state is done with listeners... - */ - public class Pending extends JingleNegotiator.State { - - JingleMediaListener jingleMediaListener; - - JingleTransportListener jingleTransportListener; - - public Pending(JingleNegotiator neg) { - super(neg); - - // Create the listeners that will send a "session-accept" when - // the sub-negotiators are done. - jingleMediaListener = new JingleMediaListener() { - public void mediaClosed(PayloadType cand) { - } - - public void mediaEstablished(PayloadType pt) { - checkFullyEstablished(); - } - }; - - jingleTransportListener = new JingleTransportListener() { - public void transportEstablished(TransportCandidate local, - TransportCandidate remote) { - checkFullyEstablished(); - } - - public void transportClosed(TransportCandidate cand) { - } - - public void transportClosedOnError(XMPPException e) { - } - }; - } - - /** - * Enter in the pending state: install the listeners. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventEnter() { - // Add the listeners to the sub-negotiators... - addMediaListener(jingleMediaListener); - addTransportListener(jingleTransportListener); - } - - /** - * Exit of the state: remove the listeners. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventExit() - */ - public void eventExit() { - removeMediaListener(jingleMediaListener); - removeTransportListener(jingleTransportListener); - } - - /** - * Check if the session has been fully accepted by all the - * sub-negotiators and, in that case, send an "accept" message... - */ - private void checkFullyEstablished() { - - if (isFullyEstablished()) { - - PayloadType.Audio bestCommonAudioPt = getMediaNeg() - .getBestCommonAudioPt(); - TransportCandidate bestRemoteCandidate = getTransportNeg() - .getBestRemoteCandidate(); - - // Ok, send a packet saying that we accept this session - // with the audio payload type and the transport - // candidate - Jingle jout = new Jingle(Jingle.Action.SESSIONACCEPT); - jout.addDescription(new JingleContentDescription.Audio( - new JinglePayloadType(bestCommonAudioPt))); - jout.addTransport(getTransportNeg().getJingleTransport( - bestRemoteCandidate)); - - // Send the "accept" and wait for the ACK - addExpectedId(jout.getPacketID()); - sendFormattedJingle(jout); - } - } - - /** - * The other endpoint has finally accepted our invitation. - * - * @throws XMPPException - */ - public Jingle eventAccept(Jingle jin) throws XMPPException { - - PayloadType acceptedPayloadType = null; - TransportCandidate acceptedLocalCandidate = null; - - // We process the "accepted" if we have finished the - // sub-negotiators. Maybe this is not needed (ie, the other endpoint - // can take the first valid transport candidate), but otherwise we - // must cancel the negotiators... - // - if (isFullyEstablished()) { - acceptedPayloadType = getAcceptedAudioPayloadType(jin); - acceptedLocalCandidate = getAcceptedLocalCandidate(jin); - - if (acceptedPayloadType != null && acceptedLocalCandidate != null) { - if (acceptedPayloadType.equals(getMediaNeg().getBestCommonAudioPt()) - && acceptedLocalCandidate.equals(getTransportNeg() - .getAcceptedLocalCandidate())) { - setState(active); - } - } - else { - throw new JingleException(JingleError.NEGOTIATION_ERROR); - } - } - - return null; - } - - /** - * We have received the Ack of our "accept" - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ) - */ - public Jingle eventAck(IQ iq) { - setState(active); - return null; - } - - /** - * The other endpoint wants to redirect this connection. - */ - public Jingle eventRedirect(Jingle jin) { - String redirArg = null; - - // TODO: parse the redirection parameters... - - triggerSessionRedirect(redirArg); - return null; - } - - /** - * The other endpoint has rejected our invitation. - * - * @throws XMPPException - */ - public Jingle eventTerminate(Jingle jin) throws XMPPException { - triggerSessionClosed("Closed Remotely"); - return super.eventTerminate(jin); - } - - /** - * An error has occurred. - * - * @throws XMPPException - */ - public void eventError(IQ iq) throws XMPPException { - triggerSessionClosedOnError(new XMPPException(iq.getError().getMessage())); - super.eventError(iq); - } - } - - /** - * State when we have an established session. - */ - public class Active extends JingleNegotiator.State { - - public Active(JingleNegotiator neg) { - super(neg); - } - - /** - * We have a established session: notify the listeners - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventEnter() { - PayloadType.Audio bestCommonAudioPt = getMediaNeg().getBestCommonAudioPt(); - TransportCandidate bestRemoteCandidate = getTransportNeg() - .getBestRemoteCandidate(); - TransportCandidate acceptedLocalCandidate = getTransportNeg() - .getAcceptedLocalCandidate(); - - // Trigger the session established flag - triggerSessionEstablished(bestCommonAudioPt, bestRemoteCandidate, - acceptedLocalCandidate); - - super.eventEnter(); - } - - /** - * Terminate the connection. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventTerminate(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventTerminate(Jingle jin) throws XMPPException { - triggerSessionClosed("Closed Remotely"); - return super.eventTerminate(jin); - } - - /** - * An error has occurred. - * - * @throws XMPPException - */ - public void eventError(IQ iq) throws XMPPException { - triggerSessionClosedOnError(new XMPPException(iq.getError().getMessage())); - super.eventError(iq); - } - } - - public IQ sendFormattedError(JingleError error) { - IQ perror = null; - if (error != null) { - perror = createIQ(getSid(), getResponder(), getInitiator(), IQ.Type.ERROR); - - // Fill in the fields with the info from the Jingle packet - perror.addExtension(error); - - getConnection().sendPacket(perror); - System.err.println(perror.toXML()); - } - return perror; - } -} diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/CreatedJingleSessionListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/CreatedJingleSessionListener.java index 8748dc776..b19f6fe38 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/CreatedJingleSessionListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/CreatedJingleSessionListener.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: CreatedJingleSessionListener.java,v $ + * $Revision: 1.1 $ * $Date: 17/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleListener.java index 975e1dff7..1c3137a90 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:12 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaInfoListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaInfoListener.java index edbd562ad..e47b4ac79 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaInfoListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaInfoListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleMediaInfoListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:12 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaListener.java index 36a15da60..8d488c6b9 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleMediaListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleMediaListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:12 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java index 97d2c7eda..d584225b5 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleSessionListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:12 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionRequestListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionRequestListener.java index 6fb64a470..894a756e0 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionRequestListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionRequestListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleSessionRequestListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:12 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionStateListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionStateListener.java deleted file mode 100644 index 693726b28..000000000 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleSessionStateListener.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-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.smackx.jingle.listeners; - -import org.jivesoftware.smackx.jingle.JingleNegotiator; - -/** - * Used to Listen for Jingle Session State Changes - * - * @author Thiago Camargo - */ -public interface JingleSessionStateListener { - - /** - * Called before the State changing. If you want to cancel the State change, you MAY throw a JingleException. - * - * @param old old State - * @param newOne new State - * @throws JingleNegotiator.JingleException - * Exception. If you want to cancel the State change, you MAY throw a JingleException. - */ - public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException; - - /** - * Called after State Changing. - * @param old old State - * @param newOne new State - */ - public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne); - -} diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleTransportListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleTransportListener.java index 673fd1beb..b334482df 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleTransportListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/listeners/JingleTransportListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleTransportListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:12 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/ContentInfo.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/ContentInfo.java index 3ecbc315f..b192e1c5b 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/ContentInfo.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/ContentInfo.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: ContentInfo.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:14 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaManager.java index 24bb505a5..470ee608a 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaManager.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleMediaManager.java,v $ + * $Revision: 1.3 $ + * $Date: 2007/07/18 19:48:23 $11-07-2006 * * Copyright 2003-2006 Jive Software. * @@ -20,10 +20,10 @@ package org.jivesoftware.smackx.jingle.media; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import java.util.ArrayList; import java.util.List; /** @@ -36,6 +36,22 @@ import java.util.List; * @author Thiago Camargo */ public abstract class JingleMediaManager { + + public static final String MEDIA_NAME = "JingleMediaManager"; + + // Each media manager must keep track of the transport manager that it uses. + private JingleTransportManager transportManager; + + public JingleMediaManager(JingleTransportManager transportManager) { + this.transportManager = transportManager; + } + + /** + * Return The transport manager that goes with this media manager. + */ + public JingleTransportManager getTransportManager() { + return transportManager; + } /** * Return all supported Payloads for this Manager @@ -61,6 +77,12 @@ public abstract class JingleMediaManager { * @param local * @return */ - public abstract JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, JingleSession jingleSession); + public abstract JingleMediaSession createMediaSession(PayloadType payloadType, final TransportCandidate remote, + final TransportCandidate local, JingleSession jingleSession); + + // This is to set the attributes of the element of the Jingle packet. + public String getName() { + return MEDIA_NAME; + } - } \ No newline at end of file +} \ No newline at end of file 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 1438b27fb..298cf3c7f 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/JingleMediaSession.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: JingleMediaSession.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:14 $11-07-2006 * * Copyright 2003-2006 Jive Software. * @@ -19,11 +19,11 @@ */ package org.jivesoftware.smackx.jingle.media; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import java.util.List; import java.util.ArrayList; +import java.util.List; /** * Public Abstract Class provides a clear interface between Media Session and Jingle API. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaNegotiator.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaNegotiator.java index 4c1a44012..e4bed6e98 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaNegotiator.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaNegotiator.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: MediaNegotiator.java,v $ + * $Revision: 1.10 $ + * $Date: 2007/07/04 00:12:39 $ * * Copyright 2003-2005 Jive Software. * @@ -21,32 +21,30 @@ package org.jivesoftware.smackx.jingle.media; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smackx.jingle.JingleNegotiator; -import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.*; import org.jivesoftware.smackx.jingle.listeners.JingleListener; import org.jivesoftware.smackx.jingle.listeners.JingleMediaListener; import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleContentDescription; -import org.jivesoftware.smackx.packet.JingleContentDescription.JinglePayloadType; +import org.jivesoftware.smackx.packet.JingleContent; +import org.jivesoftware.smackx.packet.JingleDescription; import org.jivesoftware.smackx.packet.JingleError; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; /** - * Manager for jmf descriptor negotiation. - *

- *

- * This class is responsible for managing the descriptor negotiation process, - * handling all the xmpp packets interchange and the stage control. - * handling all the xmpp packets interchange and the stage control. - * + * Manager for jmf descriptor negotiation.

This class is responsible + * for managing the descriptor negotiation process, handling all the xmpp + * packets interchange and the stage control. handling all the xmpp packets + * interchange and the stage control. + * * @author Thiago Camargo */ public class MediaNegotiator extends JingleNegotiator { - private final JingleSession session; // The session this negotiation + //private JingleSession session; // The session this negotiation + + private final JingleMediaManager mediaManager; // Local and remote payload types... @@ -54,29 +52,24 @@ public class MediaNegotiator extends JingleNegotiator { private final List remoteAudioPts = new ArrayList(); - private PayloadType.Audio bestCommonAudioPt; + private PayloadType bestCommonAudioPt; - // states - - private final Inviting inviting; - - private final Accepting accepting; - - private final Pending pending; - - private final Active active; + private ContentNegotiator parentNegotiator; /** * Default constructor. The constructor establishes some basic parameters, * but it does not start the negotiation. For starting the negotiation, call * startNegotiation. - * - * @param js The jingle session. + * + * @param js + * The jingle session. */ - public MediaNegotiator(JingleSession js, List pts) { - super(js.getConnection()); + public MediaNegotiator(JingleSession session, JingleMediaManager mediaManager, List pts, + ContentNegotiator parentNegotiator) { + super(session); - session = js; + this.mediaManager = mediaManager; + this.parentNegotiator = parentNegotiator; bestCommonAudioPt = null; @@ -85,123 +78,282 @@ public class MediaNegotiator extends JingleNegotiator { localAudioPts.addAll(pts); } } - - // Create the states... - inviting = new Inviting(this); - accepting = new Accepting(this); - pending = new Pending(this); - active = new Active(this); } /** - * Dispatch an incomming packet. The medthod is responsible for recognizing - * the packet type and, depending on the current state, deliverying the + * Return The media manager for this negotiator. + */ + public JingleMediaManager getMediaManager() { + return mediaManager; + } + + /** + * Dispatch an incoming packet. The method is responsible for recognizing + * the packet type and, depending on the current state, delivering the * packet to the right event handler and wait for a response. - * - * @param iq the packet received + * + * @param iq + * the packet received * @return the new Jingle packet to send. * @throws XMPPException */ - public IQ dispatchIncomingPacket(IQ iq, String id) throws XMPPException { - IQ jout = null; + public List dispatchIncomingPacket(IQ iq, String id) throws XMPPException { + List responses = new ArrayList(); + IQ response = null; - if (invalidState()) { - if (iq == null) { - // With a null packet, we are just inviting the other end... - setState(inviting); - jout = getState().eventInvite(); + if (iq.getType().equals(IQ.Type.ERROR)) { + // Process errors + setNegotiatorState(JingleNegotiatorState.FAILED); + triggerMediaClosed(getBestCommonAudioPt()); + // This next line seems wrong, and may subvert the normal closing process. + throw new JingleException(iq.getError().getMessage()); + } else if (iq.getType().equals(IQ.Type.RESULT)) { + // Process ACKs + if (isExpectedId(iq.getPacketID())) { + receiveResult(iq); + removeExpectedId(iq.getPacketID()); } - else { - if (iq instanceof Jingle) { - // If there is no specific jmf action associated, then we - // are being invited to a new session... - setState(accepting); - jout = getState().eventInitiate((Jingle) iq); - } - else { - throw new IllegalStateException( - "Invitation IQ received is not a Jingle packet in Media negotiator."); - } - } - } - else { - if (iq == null) { - return null; - } - else { - if (iq.getType().equals(IQ.Type.ERROR)) { - // Process errors - getState().eventError(iq); - } - else if (iq.getType().equals(IQ.Type.RESULT)) { - // Process ACKs - if (isExpectedId(iq.getPacketID())) { - jout = getState().eventAck(iq); - removeExpectedId(iq.getPacketID()); - } - } - else if (iq instanceof Jingle) { - // Get the action from the Jingle packet - Jingle jin = (Jingle) iq; - Jingle.Action action = jin.getAction(); + } else if (iq instanceof Jingle) { + Jingle jingle = (Jingle) iq; + JingleActionEnum action = jingle.getAction(); - if (action != null) { - if (action.equals(Jingle.Action.CONTENTACCEPT)) { - jout = getState().eventAccept(jin); + // Only act on the JingleContent sections that belong to this media negotiator. + for (JingleContent jingleContent : jingle.getContentsList()) { + if (jingleContent.getName().equals(parentNegotiator.getName())) { + + JingleDescription description = jingleContent.getDescription(); + + if (description != null) { + + switch (action) { + case CONTENT_ACCEPT: + response = receiveContentAcceptAction(jingle, description); + break; + + case CONTENT_MODIFY: + break; + + case CONTENT_REMOVE: + break; + + case SESSION_INFO: + response = receiveSessionInfoAction(jingle, description); + break; + + case SESSION_INITIATE: + response = receiveSessionInitiateAction(jingle, description); + break; + + case SESSION_ACCEPT: + response = receiveSessionAcceptAction(jingle, description); + break; + + default: + break; } - else if (action.equals(Jingle.Action.CONTENTDECLINE)) { - jout = getState().eventDecline(jin); - } - else if (action.equals(Jingle.Action.DESCRIPTIONINFO)) { - jout = getState().eventInfo(jin); - } - else if (action.equals(Jingle.Action.CONTENTMODIFY)) { - jout = getState().eventModify(jin); - } - // Any unknown action will be ignored: it is not a msg - // to us... } } } + } - // Save the Id for any ACK - if (id != null) { - addExpectedId(id); - } - else { - if (jout != null) { - addExpectedId(jout.getPacketID()); - } + if (response != null) { + addExpectedId(response.getPacketID()); + responses.add(response); } - return jout; + return responses; } /** - * Return true if the content is negotiated. - * - * @return true if the content is negotiated. + * Process the ACK of our list of codecs (our offer). */ + private Jingle receiveResult(IQ iq) throws XMPPException { + Jingle response = null; + +// if (!remoteAudioPts.isEmpty()) { +// // Calculate the best common codec +// bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); +// +// // and send an accept if we havee an agreement... +// if (bestCommonAudioPt != null) { +// response = createAcceptMessage(); +// } else { +// throw new JingleException(JingleError.NO_COMMON_PAYLOAD); +// } +// } + return response; + } + + /** + * The other side has sent us a content-accept. The payload types in that message may not match with what + * we sent, but XEP-167 says that the other side should retain the order of the payload types we first sent. + * + * This means we can walk through our list, in order, until we find one from their list that matches. This + * will be the best payload type to use. + * + * @param jingle + * @return + */ + private IQ receiveContentAcceptAction(Jingle jingle, JingleDescription description) throws XMPPException { + IQ response = null; + List offeredPayloads = new ArrayList(); + + offeredPayloads = description.getAudioPayloadTypesList(); + bestCommonAudioPt = calculateBestCommonAudioPt(offeredPayloads); + + if (bestCommonAudioPt == null) { + + setNegotiatorState(JingleNegotiatorState.FAILED); + response = session.createJingleError(jingle, JingleError.NEGOTIATION_ERROR); + + } else { + + setNegotiatorState(JingleNegotiatorState.SUCCEEDED); + triggerMediaEstablished(getBestCommonAudioPt()); + System.err.println("Media choice:" + getBestCommonAudioPt().getName()); + + response = session.createAck(jingle); + } + + return response; + } + + /** + * Receive a session-initiate packet. + * @param jingle + * @param description + * @return + */ + private IQ receiveSessionInitiateAction(Jingle jingle, JingleDescription description) { + IQ response = null; + + List offeredPayloads = new ArrayList(); + + offeredPayloads = description.getAudioPayloadTypesList(); + bestCommonAudioPt = calculateBestCommonAudioPt(offeredPayloads); + + synchronized (remoteAudioPts) { + remoteAudioPts.addAll(offeredPayloads); + } + + // If there are suitable/matching payload types then accept this content. + if (bestCommonAudioPt != null) { + // Let thre transport negotiators sort-out connectivity and content-accept instead. + //response = createAudioPayloadTypesOffer(); + setNegotiatorState(JingleNegotiatorState.PENDING); + } else { + // Don't really know what to send here. XEP-166 is not clear. + setNegotiatorState(JingleNegotiatorState.FAILED); + } + + return response; + } + + /** + * A content info has been received. This is done for publishing the + * list of payload types... + * + * @param jin + * The input packet + * @return a Jingle packet + * @throws JingleException + */ + private IQ receiveSessionInfoAction(Jingle jingle, JingleDescription description) throws JingleException { + IQ response = null; + PayloadType oldBestCommonAudioPt = bestCommonAudioPt; + List offeredPayloads; + boolean ptChange = false; + + offeredPayloads = description.getAudioPayloadTypesList(); + if (!offeredPayloads.isEmpty()) { + + synchronized (remoteAudioPts) { + remoteAudioPts.clear(); + remoteAudioPts.addAll(offeredPayloads); + } + + // Calculate the best common codec + bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); + if (bestCommonAudioPt != null) { + // and send an accept if we have an agreement... + ptChange = !bestCommonAudioPt.equals(oldBestCommonAudioPt); + if (oldBestCommonAudioPt == null || ptChange) { + //response = createAcceptMessage(); + } + } else { + throw new JingleException(JingleError.NO_COMMON_PAYLOAD); + } + } + + // Parse the Jingle and get the payload accepted + return response; + } + + /** + * A jmf description has been accepted. In this case, we must save the + * accepted payload type and notify any listener... + * + * @param jin + * The input packet + * @return a Jingle packet + * @throws JingleException + */ + private IQ receiveSessionAcceptAction(Jingle jingle, JingleDescription description) throws JingleException { + IQ response = null; + PayloadType.Audio agreedCommonAudioPt; + List offeredPayloads = new ArrayList(); + + if (bestCommonAudioPt == null) { + // Update the best common audio PT + bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); + //response = createAcceptMessage(); + } + + offeredPayloads = description.getAudioPayloadTypesList(); + if (!offeredPayloads.isEmpty()) { + if (offeredPayloads.size() == 1) { + agreedCommonAudioPt = (PayloadType.Audio) offeredPayloads.get(0); + if (bestCommonAudioPt != null) { + // If the accepted PT matches the best payload + // everything is fine + if (!agreedCommonAudioPt.equals(bestCommonAudioPt)) { + throw new JingleException(JingleError.NEGOTIATION_ERROR); + } + } + + } else if (offeredPayloads.size() > 1) { + throw new JingleException(JingleError.MALFORMED_STANZA); + } + } + + return response; + } + + /** + * Return true if the content is negotiated. + * + * @return true if the content is negotiated. + */ public boolean isEstablished() { return getBestCommonAudioPt() != null; } /** * Return true if the content is fully negotiated. - * + * * @return true if the content is fully negotiated. */ public boolean isFullyEstablished() { - return isEstablished() && getState() == active; + return (isEstablished() && ((getNegotiatorState() == JingleNegotiatorState.SUCCEEDED) || (getNegotiatorState() == JingleNegotiatorState.FAILED))); } // Payload types - private PayloadType.Audio calculateBestCommonAudioPt(List remoteAudioPts) { + private PayloadType calculateBestCommonAudioPt(List remoteAudioPts) { final ArrayList commonAudioPtsHere = new ArrayList(); final ArrayList commonAudioPtsThere = new ArrayList(); - PayloadType.Audio result = null; + PayloadType result = null; if (!remoteAudioPts.isEmpty()) { commonAudioPtsHere.addAll(localAudioPts); @@ -215,7 +367,7 @@ public class MediaNegotiator extends JingleNegotiator { if (session.getInitiator().equals(session.getConnection().getUser())) { PayloadType.Audio bestPtHere = null; - PayloadType payload = this.session.getMediaManager().getPreferredPayloadType(); + PayloadType payload = mediaManager.getPreferredPayloadType(); if (payload != null && payload instanceof PayloadType.Audio) if (commonAudioPtsHere.contains(payload)) @@ -229,8 +381,7 @@ public class MediaNegotiator extends JingleNegotiator { } result = bestPtHere; - } - else { + } else { PayloadType.Audio bestPtThere = null; for (PayloadType payloadType : commonAudioPtsThere) if (payloadType instanceof PayloadType.Audio) { @@ -246,30 +397,11 @@ public class MediaNegotiator extends JingleNegotiator { return result; } - private List obtainPayloads(Jingle jin) { - List result = new ArrayList(); - Iterator iDescr = jin.getDescriptions(); - - // Add the list of payloads: iterate over the descriptions... - while (iDescr.hasNext()) { - JingleContentDescription.Audio descr = (JingleContentDescription.Audio) iDescr - .next(); - - if (descr != null) { - // ...and, then, over the payloads. - // Note: we use the last "description" in the packet... - result.clear(); - result.addAll(descr.getAudioPayloadTypesList()); - } - } - - return result; - } - /** * Adds a payload type to the list of remote payloads. - * - * @param pt the remote payload type + * + * @param pt + * the remote payload type */ public void addRemoteAudioPayloadType(PayloadType.Audio pt) { if (pt != null) { @@ -280,19 +412,25 @@ public class MediaNegotiator extends JingleNegotiator { } /** - * Create an offer for the list of audio payload types. - * - * @return a new Jingle packet with the list of audio Payload Types - */ - private Jingle getAudioPayloadTypesOffer() { - JingleContentDescription.Audio audioDescr = new JingleContentDescription.Audio(); + * Create an offer for the list of audio payload types. + * + * @return a new Jingle packet with the list of audio Payload Types + */ + private Jingle createAudioPayloadTypesOffer() { + + JingleContent jingleContent = new JingleContent(parentNegotiator.getCreator(), parentNegotiator.getName()); + JingleDescription audioDescr = new JingleDescription.Audio(); // Add the list of payloads for audio and create a - // JingleContentDescription + // JingleDescription // where we announce our payloads... audioDescr.addAudioPayloadTypes(localAudioPts); + jingleContent.setDescription(audioDescr); - return new Jingle(audioDescr); + Jingle jingle = new Jingle(JingleActionEnum.CONTENT_ACCEPT); + jingle.addContent(jingleContent); + + return jingle; } // Predefined messages and Errors @@ -300,25 +438,26 @@ public class MediaNegotiator extends JingleNegotiator { /** * Create an IQ "accept" message. */ - private Jingle createAcceptMessage() { - Jingle jout = null; - - // If we hava a common best codec, send an accept right now... - jout = new Jingle(Jingle.Action.CONTENTACCEPT); - jout.addDescription(new JingleContentDescription.Audio( - new JinglePayloadType.Audio(bestCommonAudioPt))); - - return jout; - } +// private Jingle createAcceptMessage() { +// Jingle jout = null; +// +// // If we have a common best codec, send an accept right now... +// jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT); +// JingleContent content = new JingleContent(parentNegotiator.getCreator(), parentNegotiator.getName()); +// content.setDescription(new JingleDescription.Audio(bestCommonAudioPt)); +// jout.addContent(content); +// +// return jout; +// } // Payloads /** * Get the best common codec between both parts. - * + * * @return The best common PayloadType codec. */ - public PayloadType.Audio getBestCommonAudioPt() { + public PayloadType getBestCommonAudioPt() { return bestCommonAudioPt; } @@ -326,14 +465,13 @@ public class MediaNegotiator extends JingleNegotiator { /** * Trigger a session established event. - * - * @param bestPt payload type that has been agreed. + * + * @param bestPt + * payload type that has been agreed. */ protected void triggerMediaEstablished(PayloadType bestPt) { - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleMediaListener) { JingleMediaListener mli = (JingleMediaListener) li; mli.mediaEstablished(bestPt); @@ -343,14 +481,13 @@ public class MediaNegotiator extends JingleNegotiator { /** * Trigger a jmf closed event. - * - * @param currPt current payload type that is cancelled. + * + * @param currPt + * current payload type that is cancelled. */ protected void triggerMediaClosed(PayloadType currPt) { - ArrayList listeners = getListenersList(); - Iterator iter = listeners.iterator(); - while (iter.hasNext()) { - JingleListener li = (JingleListener) iter.next(); + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleMediaListener) { JingleMediaListener mli = (JingleMediaListener) li; mli.mediaClosed(currPt); @@ -358,244 +495,38 @@ public class MediaNegotiator extends JingleNegotiator { } } + /** + * Called from above when starting a new session. + * @return + */ + public void start() { + //JingleDescription result = new JingleDescription.Audio(); + // result.addAudioPayloadTypes(localAudioPts); + + // return result; + } + /** * Terminate the jmf negotiator */ public void close() { super.close(); - } - - // States - - /** - * First stage when we send a session request. - */ - public class Inviting extends JingleNegotiator.State { - - public Inviting(MediaNegotiator neg) { - super(neg); - } - - /** - * Create an initial Jingle packet, with the list of payload types that - * we support. The list is in order of preference. - */ - public Jingle eventInvite() { - return getAudioPayloadTypesOffer(); - } - - /** - * We have received the ACK for our invitation. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ) - */ - public Jingle eventAck(IQ iq) { - setState(pending); - return null; - } + triggerMediaClosed(getBestCommonAudioPt()); } /** - * We are accepting connections. + * Create a JingleDescription that matches this negotiator. */ - public class Accepting extends JingleNegotiator.State { - - public Accepting(MediaNegotiator neg) { - super(neg); - } - - /** - * We have received an invitation! Respond with a list of our payload - * types... - */ - public Jingle eventInitiate(Jingle jin) { - synchronized (remoteAudioPts) { - remoteAudioPts.addAll(obtainPayloads(jin)); - } - - return getAudioPayloadTypesOffer(); - } - - /** - * Process the ACK of our list of codecs (our offer). - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ) - */ - public Jingle eventAck(IQ iq) throws XMPPException { - Jingle response = null; - - if (!remoteAudioPts.isEmpty()) { - // Calculate the best common codec - bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); - - // and send an accept if we havee an agreement... - if (bestCommonAudioPt != null) { - response = createAcceptMessage(); - } - else { - throw new JingleException(JingleError.NO_COMMON_PAYLOAD); - } - - setState(pending); - } - - return response; - } - } - - /** - * Pending class: we are waiting for the other enpoint, that must say if it - * accepts or not... - */ - public class Pending extends JingleNegotiator.State { - - public Pending(MediaNegotiator neg) { - super(neg); - } - - /** - * A content info has been received. This is done for publishing the - * list of payload types... - * - * @param jin The input packet - * @return a Jingle packet - * @throws JingleException - */ - public Jingle eventInfo(Jingle jin) throws JingleException { - PayloadType.Audio oldBestCommonAudioPt = bestCommonAudioPt; - List offeredPayloads; - Jingle response = null; - boolean ptChange = false; - - offeredPayloads = obtainPayloads(jin); - if (!offeredPayloads.isEmpty()) { - - synchronized (remoteAudioPts) { - remoteAudioPts.clear(); - remoteAudioPts.addAll(offeredPayloads); - } - - // Calculate the best common codec - bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); - if (bestCommonAudioPt != null) { - // and send an accept if we have an agreement... - ptChange = !bestCommonAudioPt.equals(oldBestCommonAudioPt); - if (oldBestCommonAudioPt == null || ptChange) { - response = createAcceptMessage(); - } - } - else { - throw new JingleException(JingleError.NO_COMMON_PAYLOAD); - } - } - - // Parse the Jingle and get the payload accepted - return response; - } - - /** - * A jmf description has been accepted. In this case, we must save the - * accepted payload type and notify any listener... - * - * @param jin The input packet - * @return a Jingle packet - * @throws JingleException - */ - public Jingle eventAccept(Jingle jin) throws JingleException { - PayloadType.Audio agreedCommonAudioPt; - List offeredPayloads = new ArrayList(); - Jingle response = null; - - if (bestCommonAudioPt == null) { - // Update the best common audio PT - bestCommonAudioPt = calculateBestCommonAudioPt(remoteAudioPts); - response = createAcceptMessage(); - } - - offeredPayloads = obtainPayloads(jin); - if (!offeredPayloads.isEmpty()) { - if (offeredPayloads.size() == 1) { - agreedCommonAudioPt = (PayloadType.Audio) offeredPayloads.get(0); - if (bestCommonAudioPt != null) { - // If the accepted PT matches the best payload - // everything is fine - if (!agreedCommonAudioPt.equals(bestCommonAudioPt)) { - throw new JingleException(JingleError.NEGOTIATION_ERROR); - } - } - - } - else if (offeredPayloads.size() > 1) { - throw new JingleException(JingleError.MALFORMED_STANZA); - } - } - - return response; - } - - /** - * The other part has declined the our codec... - * - * @throws JingleException - */ - public Jingle eventDecline(Jingle inJingle) throws JingleException { - triggerMediaClosed(getBestCommonAudioPt()); - throw new JingleException(); - } - - /* - * (non-Javadoc) - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventError(org.jivesoftware.smack.packet.IQ) - */ - public void eventError(IQ iq) throws XMPPException { - triggerMediaClosed(getBestCommonAudioPt()); - super.eventError(iq); - } - - /** - * ACK received. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ) - */ - public Jingle eventAck(IQ iq) { - - if (isEstablished()) { - setState(active); - return null; - } - return null; - } - } - - /** - * "Active" state: we have an agreement about the codec... - */ - public class Active extends JingleNegotiator.State { - - public Active(MediaNegotiator neg) { - super(neg); - } - - /** - * We have an agreement. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventEnter() { - triggerMediaEstablished(getBestCommonAudioPt()); - System.err.println("BS:"+getBestCommonAudioPt().getName()); - super.eventEnter(); - } - - /** - * We are breaking the contract... - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventExit() - */ - public void eventExit() { - triggerMediaClosed(getBestCommonAudioPt()); - super.eventExit(); + public JingleDescription getJingleDescription() { + JingleDescription result = null; + PayloadType payloadType = getBestCommonAudioPt(); + if (payloadType != null) { + result = new JingleDescription.Audio(payloadType); + } else { + // If we haven't settled on a best payload type yet then just use the first one in our local list. + result = new JingleDescription.Audio(); + result.addAudioPayloadTypes(localAudioPts); } + return result; } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java index 9268f63d3..b0b2a4119 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/MediaReceivedListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: $ - * $Date: $11-07-2006 + * $RCSfile: MediaReceivedListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:14 $11-07-2006 * * Copyright 2003-2006 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/PayloadType.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/PayloadType.java index 2e34e4829..294cd99c1 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/media/PayloadType.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/media/PayloadType.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: PayloadType.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:14 $ * * Copyright 2003-2005 Jive Software. * @@ -26,6 +26,8 @@ package org.jivesoftware.smackx.jingle.media; */ public class PayloadType { + public static final String NODENAME = "payload-type"; + public static int MAX_FIXED_PT = 95; public static int INVALID_PT = 65535; @@ -196,6 +198,49 @@ public class PayloadType { return true; } + + /** + * Returns the XML element name of the element. + * + * @return the XML element name of the element. + */ + public static String getElementName() { + return NODENAME; + } + + public String toXML() { + StringBuilder buf = new StringBuilder(); + + buf.append("<").append(getElementName()).append(" "); + + // We covert here the payload type to XML + if (this.getId() != PayloadType.INVALID_PT) { + buf.append(" id=\"").append(this.getId()).append("\""); + } + if (this.getName() != null) { + buf.append(" name=\"").append(this.getName()).append("\""); + } + if (this.getChannels() != 0) { + buf.append(" channels=\"").append(this.getChannels()).append("\""); + } + if (getChildAttributes() != null) { + buf.append(getChildAttributes()); + } + buf.append("/>"); + + return buf.toString(); + } + + protected String getChildAttributes() { + StringBuilder buf = new StringBuilder(); + if (this instanceof PayloadType.Audio) { + PayloadType.Audio pta = (PayloadType.Audio) this; + + buf.append(" clockrate=\"").append(pta.getClockRate()).append("\" "); + } + + return buf.toString(); + } /** * Audio payload type. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java index 12ad7727c..266a7c8df 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/demo/Demo.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: Demo.java,v $ + * $Revision: 1.3 $ * $Date: 28/12/2006 *

* Copyright 2003-2006 Jive Software. @@ -17,19 +17,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jivesoftware.smackx.jingle.mediaimpl.jmf; +package org.jivesoftware.smackx.jingle.mediaimpl.demo; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smackx.jingle.IncomingJingleSession; import org.jivesoftware.smackx.jingle.JingleManager; +import org.jivesoftware.smackx.jingle.JingleSession; import org.jivesoftware.smackx.jingle.JingleSessionRequest; -import org.jivesoftware.smackx.jingle.OutgoingJingleSession; import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; -import org.jivesoftware.smackx.jingle.nat.*; +import org.jivesoftware.smackx.jingle.media.JingleMediaManager; +import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager; +import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager; +import org.jivesoftware.smackx.jingle.nat.ICETransportManager; +import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; import javax.swing.*; import java.awt.event.ActionEvent; +import java.util.ArrayList; +import java.util.List; /** * Jingle Demo Application. It register in a XMPP Server and let users place calls using a full JID and auto-receive calls. @@ -45,16 +50,22 @@ public class Demo extends JFrame { private String pass = null; private JingleManager jm = null; - private IncomingJingleSession incoming = null; - private OutgoingJingleSession outgoing = null; + private JingleSession incoming = null; + private JingleSession outgoing = null; - private JTextField jid = new JTextField(30); + private JTextField jid; public Demo(String server, String user, String pass) { this.server = server; this.user = user; this.pass = pass; + + if (user.equals("jeffw")) { + jid = new JTextField("eowyn" + "@" + server + "/Smack"); + } else { + jid = new JTextField("jeffw" + "@" + server + "/Smack"); + } xmppConnection = new XMPPConnection(server); try { @@ -68,22 +79,26 @@ public class Demo extends JFrame { } public void initialize() { - ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "jivesoftware.com", 3478); - jm = new JingleManager(xmppConnection, icetm0, new JmfMediaManager()); + ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "10.47.47.53", 3478); + List mediaManagers = new ArrayList(); + //mediaManagers.add(new JmfMediaManager(icetm0)); + mediaManagers.add(new SpeexMediaManager(icetm0)); + mediaManagers.add(new ScreenShareMediaManager(icetm0)); + jm = new JingleManager(xmppConnection, mediaManagers); jm.addCreationListener(icetm0); jm.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(JingleSessionRequest request) { - if (incoming != null) - return; +// if (incoming != null) +// return; try { // Accept the call incoming = request.accept(); // Start the call - incoming.start(); + incoming.startIncoming(); } catch (XMPPException e) { e.printStackTrace(); @@ -105,7 +120,7 @@ public class Demo extends JFrame { if (outgoing != null) return; try { outgoing = jm.createOutgoingJingleSession(jid.getText()); - outgoing.start(); + outgoing.startOutgoing(); } catch (XMPPException e1) { e1.printStackTrace(); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java index b309d7d75..963e39ddb 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: AudioChannel.java,v $ + * $Revision: 1.1 $ * $Date: 08/11/2006 *

* Copyright 2003-2006 Jive Software. @@ -22,26 +22,24 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf; import org.jivesoftware.smackx.jingle.media.JingleMediaSession; import javax.media.*; -import javax.media.control.TrackControl; -import javax.media.control.PacketSizeControl; import javax.media.control.BufferControl; +import javax.media.control.PacketSizeControl; +import javax.media.control.TrackControl; import javax.media.format.AudioFormat; import javax.media.protocol.ContentDescriptor; import javax.media.protocol.DataSource; import javax.media.protocol.PushBufferDataSource; import javax.media.protocol.PushBufferStream; +import javax.media.rtp.InvalidSessionAddressException; import javax.media.rtp.RTPManager; import javax.media.rtp.SendStream; import javax.media.rtp.SessionAddress; -import javax.media.rtp.InvalidSessionAddressException; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; -import com.sun.media.rtp.RTPSessionMgr; - /** * An Easy to use Audio Channel implemented using JMF. * It sends and receives jmf for and from desired IPs and ports. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java index ae5e3541d..ded015fc2 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioFormatUtils.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: AudioFormatUtils.java,v $ + * $Revision: 1.1 $ * $Date: 08/11/2006 *

* Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java index cc5bacc62..5238f51ec 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: AudioMediaSession.java,v $ + * $Revision: 1.1 $ * $Date: 08/11/2006 *

* Copyright 2003-2006 Jive Software. @@ -20,10 +20,10 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf; +import org.jivesoftware.smackx.jingle.JingleSession; import org.jivesoftware.smackx.jingle.media.JingleMediaSession; import org.jivesoftware.smackx.jingle.media.PayloadType; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.JingleSession; import javax.media.MediaLocator; import java.io.IOException; diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java index 22a301db4..b8b7c0618 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioReceiver.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: AudioReceiver.java,v $ + * $Revision: 1.1 $ * $Date: 08/11/2006 *

* Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java index 944c27c42..762c17ea5 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/JmfMediaManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: JmfMediaManager.java,v $ + * $Revision: 1.3 $ * $Date: 08/11/2006 *

* Copyright 2003-2006 Jive Software. @@ -20,17 +20,18 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf; +import org.jivesoftware.smackx.jingle.JingleSession; 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.smackx.jingle.mediaimpl.JMFInit; -import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import java.io.File; import java.io.IOException; -import java.util.List; import java.util.ArrayList; +import java.util.List; /** * Implements a jingleMediaManager using JMF based API. @@ -41,13 +42,17 @@ import java.util.ArrayList; */ public class JmfMediaManager extends JingleMediaManager { + public static final String MEDIA_NAME = "JMF"; + + private List payloads = new ArrayList(); private String mediaLocator = null; /** * Creates a Media Manager instance */ - public JmfMediaManager() { + public JmfMediaManager(JingleTransportManager transportManager) { + super(transportManager); setupPayloads(); } @@ -56,7 +61,8 @@ public class JmfMediaManager extends JingleMediaManager { * * @param mediaLocator Media Locator */ - public JmfMediaManager(String mediaLocator) { + public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) { + super(transportManager); this.mediaLocator = mediaLocator; setupPayloads(); } @@ -154,4 +160,8 @@ public class JmfMediaManager extends JingleMediaManager { private static void runLinuxPreInstall() { // @TODO Implement Linux Pre-Install } + + public String getName() { + return MEDIA_NAME; + } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java index c49b1e7eb..28e43ca9c 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/AudioMediaSession.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: AudioMediaSession.java,v $ + * $Revision: 1.1 $ * $Date: 25/12/2006 *

* Copyright 2003-2006 Jive Software. @@ -24,10 +24,10 @@ import mil.jfcom.cie.media.session.MediaSession; import mil.jfcom.cie.media.session.MediaSessionListener; import mil.jfcom.cie.media.session.StreamPlayer; import mil.jfcom.cie.media.srtp.packetizer.SpeexFormat; +import org.jivesoftware.smackx.jingle.JingleSession; import org.jivesoftware.smackx.jingle.media.JingleMediaSession; import org.jivesoftware.smackx.jingle.media.PayloadType; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.JingleSession; import javax.media.NoProcessorException; import javax.media.format.UnsupportedFormatException; diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java index e01758960..527cbf750 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jspeex/SpeexMediaManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: SpeexMediaManager.java,v $ + * $Revision: 1.3 $ * $Date: 25/12/2006 *

* Copyright 2003-2006 Jive Software. @@ -19,17 +19,18 @@ */ package org.jivesoftware.smackx.jingle.mediaimpl.jspeex; +import org.jivesoftware.smackx.jingle.JingleSession; 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.smackx.jingle.mediaimpl.JMFInit; -import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import java.io.File; import java.io.IOException; -import java.util.List; import java.util.ArrayList; +import java.util.List; /** * Implements a jingleMediaManager using JMF based API and JSpeex. @@ -40,9 +41,12 @@ import java.util.ArrayList; */ public class SpeexMediaManager extends JingleMediaManager { + public static final String MEDIA_NAME = "Speex"; + private List payloads = new ArrayList(); - public SpeexMediaManager() { + public SpeexMediaManager(JingleTransportManager transportManager) { + super(transportManager); setupPayloads(); setupJMF(); } @@ -120,4 +124,8 @@ public class SpeexMediaManager extends JingleMediaManager { private static void runLinuxPreInstall() { // @TODO Implement Linux Pre-Install } + + public String getName() { + return MEDIA_NAME; + } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java index d2a9b5fa2..34c7ae5ae 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/multi/MultiMediaManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: MultiMediaManager.java,v $ + * $Revision: 1.3 $ * $Date: 25/12/2006 *

* Copyright 2003-2006 Jive Software. @@ -20,13 +20,15 @@ package org.jivesoftware.smackx.jingle.mediaimpl.multi; +import org.jivesoftware.smackx.jingle.JingleSession; 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.JingleTransportManager; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.JingleSession; -import java.util.*; +import java.util.ArrayList; +import java.util.List; /** * Implements a MultiMediaManager using other JingleMediaManager implementations. @@ -37,11 +39,14 @@ import java.util.*; public class MultiMediaManager extends JingleMediaManager { + public static final String MEDIA_NAME = "Multi"; + private List managers = new ArrayList(); private PayloadType preferredPayloadType = null; - public MultiMediaManager() { + public MultiMediaManager(JingleTransportManager transportManager) { + super(transportManager); } public void addMediaManager(JingleMediaManager manager) { @@ -94,5 +99,8 @@ public class MultiMediaManager extends JingleMediaManager { public void setPreferredPayloadType(PayloadType preferredPayloadType) { this.preferredPayloadType = preferredPayloadType; } - + + public String getName() { + return MEDIA_NAME; + } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java index 2fddbf938..c3067341b 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareMediaManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: ScreenShareMediaManager.java,v $ + * $Revision: 1.3 $ * $Date: 25/12/2006 *

* Copyright 2003-2006 Jive Software. @@ -20,13 +20,14 @@ package org.jivesoftware.smackx.jingle.mediaimpl.sshare; +import org.jivesoftware.smackx.jingle.JingleSession; 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.mediaimpl.sshare.api.ImageEncoder; import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder; +import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder; +import org.jivesoftware.smackx.jingle.nat.JingleTransportManager; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.JingleSession; import java.util.ArrayList; import java.util.List; @@ -40,12 +41,15 @@ import java.util.List; public class ScreenShareMediaManager extends JingleMediaManager { + public static final String MEDIA_NAME = "ScreenShare"; + private List payloads = new ArrayList(); private ImageDecoder decoder = null; private ImageEncoder encoder = null; - public ScreenShareMediaManager() { + public ScreenShareMediaManager(JingleTransportManager transportManager) { + super(transportManager); setupPayloads(); } @@ -104,4 +108,8 @@ public class ScreenShareMediaManager extends JingleMediaManager { public void setEncoder(ImageEncoder encoder) { this.encoder = encoder; } + + public String getName() { + return MEDIA_NAME; + } } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java index 6e369e16b..7fadac11c 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: ScreenShareSession.java,v $ + * $Revision: 1.2 $ * $Date: 08/11/2006 *

* Copyright 2003-2006 Jive Software. @@ -19,6 +19,7 @@ */ package org.jivesoftware.smackx.jingle.mediaimpl.sshare; +import org.jivesoftware.smackx.jingle.JingleSession; import org.jivesoftware.smackx.jingle.media.JingleMediaSession; import org.jivesoftware.smackx.jingle.media.PayloadType; import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder; @@ -26,19 +27,16 @@ import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder; import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageReceiver; import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter; import org.jivesoftware.smackx.jingle.nat.TransportCandidate; -import org.jivesoftware.smackx.jingle.JingleSession; -import org.jivesoftware.smackx.jingle.IncomingJingleSession; import javax.swing.*; import java.awt.*; -import java.awt.event.WindowListener; -import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.io.IOException; +import java.net.DatagramSocket; import java.net.InetAddress; import java.net.ServerSocket; import java.net.UnknownHostException; -import java.net.DatagramSocket; /** * This Class implements a complete JingleMediaSession. @@ -64,19 +62,30 @@ public class ScreenShareSession extends JingleMediaSession { * @param local the local information. The candidate that will receive the jmf * @param locator media locator */ - public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, - final TransportCandidate local, final String locator, JingleSession jingleSession) { + public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, + final String locator, JingleSession jingleSession) { super(payloadType, remote, local, "Screen", jingleSession); initialize(); } /** - * Initialize the Audio Channel to make it able to send and receive audio + * Initialize the screen share channels. */ public void initialize() { - if (this.getJingleSession() instanceof IncomingJingleSession) { + JingleSession session = getJingleSession(); + if ((session != null) && (session.getInitiator().equals(session.getConnection().getUser()))) { + // If the initiator of the jingle session is us then we transmit a screen share. + try { + InetAddress remote = InetAddress.getByName(getRemote().getIp()); + transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(), + new Rectangle(0, 0, width, height)); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + // Otherwise we receive a screen share. JFrame window = new JFrame(); JPanel jp = new JPanel(); window.add(jp); @@ -84,17 +93,17 @@ public class ScreenShareSession extends JingleMediaSession { window.setLocation(0, 0); window.setSize(600, 600); - window.addWindowListener(new WindowAdapter(){ + window.addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { receiver.stop(); } }); try { - receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width, height); + receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width, + height); System.out.println("Receiving on:" + receiver.getLocalPort()); - } - catch (UnknownHostException e) { + } catch (UnknownHostException e) { e.printStackTrace(); } @@ -103,15 +112,6 @@ public class ScreenShareSession extends JingleMediaSession { window.setAlwaysOnTop(true); window.setVisible(true); } - else { - try { - InetAddress remote = InetAddress.getByName(getRemote().getIp()); - transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(), new Rectangle(0, 0, width, height)); - } - catch (Exception e) { - e.printStackTrace(); - } - } } /** @@ -142,7 +142,7 @@ public class ScreenShareSession extends JingleMediaSession { * Stops transmission and for NAT Traversal reasons stop receiving also. */ public void stopTrasmit() { - if(transmitter!=null){ + if (transmitter != null) { transmitter.stop(); } } @@ -151,7 +151,7 @@ public class ScreenShareSession extends JingleMediaSession { * For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf */ public void stopReceive() { - if(receiver!=null){ + if (receiver != null) { receiver.stop(); } } @@ -173,8 +173,7 @@ public class ScreenShareSession extends JingleMediaSession { freePort = ss.getLocalPort(); ss.close(); return freePort; - } - catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); } } @@ -182,8 +181,7 @@ public class ScreenShareSession extends JingleMediaSession { ss = new ServerSocket(0); freePort = ss.getLocalPort(); ss.close(); - } - catch (IOException e) { + } catch (IOException e) { e.printStackTrace(); } return freePort; diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicResolver.java index 26db955f3..7fad63435 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicResolver.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: BasicResolver.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright 2003-2005 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicTransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicTransportManager.java index 35f7a3d9d..0732b883c 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicTransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BasicTransportManager.java @@ -3,8 +3,8 @@ package org.jivesoftware.smackx.jingle.nat; import org.jivesoftware.smackx.jingle.JingleSession; /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: BasicTransportManager.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java index dd3d2d9fa..f0538fad5 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedResolver.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: BridgedResolver.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright 2003-2005 Jive Software. * @@ -23,9 +23,12 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.JingleSession; -import java.util.Random; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; import java.util.Enumeration; -import java.net.*; +import java.util.Random; /** * Bridged Resolver use a RTPBridge Service to add a relayed candidate. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java index 59af7d403..085456cb2 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: BridgedTransportManager.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/DatagramListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/DatagramListener.java index e5711ceea..9dcac3df8 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/DatagramListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/DatagramListener.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: DatagramListener.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/FixedResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/FixedResolver.java index b417e72d4..911ab63f4 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/FixedResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/FixedResolver.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: FixedResolver.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java index a1bf61d2f..24b1f785c 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: HttpServer.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -52,10 +52,10 @@ package org.jivesoftware.smackx.jingle.nat; -import java.net.*; import java.io.*; -import java.util.*; -import java.lang.*; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.StringTokenizer; /** * A very Simple HTTP Server diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICECandidate.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICECandidate.java index 122dc9cd5..d916f58b4 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICECandidate.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICECandidate.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: ICECandidate.java,v $ + * $Revision: 1.2 $ + * $Date: 2007/07/03 16:36:31 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -51,8 +51,6 @@ */ package org.jivesoftware.smackx.jingle.nat; -import de.javawi.jstun.test.demo.ice.Candidate; - import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; @@ -301,7 +299,7 @@ public class ICECandidate extends TransportCandidate implements Comparable { for (int i = 0; i < 10 && !result.isReachable(); i++) try { - System.err.println(i); + System.err.println("ICE Candidate retry #" + i); Thread.sleep(400); } catch (InterruptedException e) { 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 593969dc1..a08fcbca6 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: ICEResolver.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright 2003-2005 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java index 5efc35a8b..10e461eb6 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICETransportManager.java @@ -1,15 +1,15 @@ package org.jivesoftware.smackx.jingle.nat; -import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smackx.jingle.media.PayloadType; +import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.jingle.JingleSession; -import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener; import org.jivesoftware.smackx.jingle.listeners.CreatedJingleSessionListener; +import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener; +import org.jivesoftware.smackx.jingle.media.PayloadType; /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: ICETransportManager.java,v $ + * $Revision: 1.1 $ * $Date: 02/01/2007 *

* Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java index 386aa3884..7d3e7afee 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/JingleTransportManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: JingleTransportManager.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java index 8261639e9..144a54551 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: RTPBridge.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright 2003-2005 Jive Software. * @@ -32,11 +32,11 @@ import org.jivesoftware.smackx.ServiceDiscoveryManager; import org.jivesoftware.smackx.packet.DiscoverItems; import org.xmlpull.v1.XmlPullParser; -import java.util.Iterator; -import java.util.Enumeration; +import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; -import java.net.InetAddress; +import java.util.Enumeration; +import java.util.Iterator; /** * RTPBridge IQ Packet used to request and retrieve a RTPBridge Candidates that can be used for a Jingle Media Transmission between two parties that are behind NAT. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ResultListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ResultListener.java index 5cf059f3a..1f9bfb949 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ResultListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ResultListener.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: ResultListener.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright 2003-2005 Jive Software. * diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUN.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUN.java index 23806668b..caab19c1a 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUN.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUN.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: STUN.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. @@ -32,13 +32,9 @@ import org.jivesoftware.smackx.packet.DiscoverInfo; import org.jivesoftware.smackx.packet.DiscoverItems; import org.xmlpull.v1.XmlPullParser; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.ArrayList; -import java.util.Enumeration; -import java.net.NetworkInterface; -import java.net.SocketException; -import java.net.InetAddress; /** * STUN IQ Packet used to request and retrieve a STUN server and port to make p2p connections easier. STUN is usually used by Jingle Media Transmission between two parties that are behind NAT. @@ -58,7 +54,7 @@ public class STUN extends IQ { /** * Element name of the packet extension. */ - public static final String NAME = "stun"; + public static final String DOMAIN = "stun"; /** * Element name of the packet extension. @@ -71,7 +67,7 @@ public class STUN extends IQ { public static final String NAMESPACE = "google:jingleinfo"; static { - ProviderManager.getInstance().addIQProvider(NAME, NAMESPACE, new STUN.Provider()); + ProviderManager.getInstance().addIQProvider(ELEMENT_NAME, NAMESPACE, new STUN.Provider()); } /** @@ -196,7 +192,7 @@ public class STUN extends IQ { } STUN stunPacket = new STUN(); - stunPacket.setTo(NAME + "." + xmppConnection.getServiceName()); + stunPacket.setTo(DOMAIN + "." + xmppConnection.getServiceName()); PacketCollector collector = xmppConnection .createPacketCollector(new PacketIDFilter(stunPacket.getPacketID())); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNResolver.java index 261735d6b..f4e4d90a2 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNResolver.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: STUNResolver.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java index 259b661ce..64670b7c6 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/STUNTransportManager.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: STUNTransportManager.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java index 87ab2de24..0ede283c2 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: TcpUdpBridgeClient.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -51,13 +51,13 @@ */ package org.jivesoftware.smackx.jingle.nat; -import java.net.DatagramSocket; -import java.net.Socket; -import java.net.DatagramPacket; -import java.net.InetAddress; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.Socket; /** * A Simple and Experimental Bridge. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TestResult.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TestResult.java index 072d09183..4d1ac77fe 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TestResult.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TestResult.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: TestResult.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportCandidate.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportCandidate.java index 032fb7caf..352da084e 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportCandidate.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportCandidate.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: TransportCandidate.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -58,12 +58,9 @@ import org.jivesoftware.smackx.jingle.JingleSession; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.*; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.Random; -import java.util.Arrays; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; /** * Transport candidate. diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java index 1cd131dc0..03cf90b2c 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportNegotiator.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: TransportNegotiator.java,v $ + * $Revision: 1.9 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. @@ -22,18 +22,14 @@ package org.jivesoftware.smackx.jingle.nat; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smackx.jingle.JingleNegotiator; -import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.*; import org.jivesoftware.smackx.jingle.listeners.JingleListener; import org.jivesoftware.smackx.jingle.listeners.JingleTransportListener; import org.jivesoftware.smackx.packet.Jingle; +import org.jivesoftware.smackx.packet.JingleContent; +import org.jivesoftware.smackx.packet.JingleTransport; import org.jivesoftware.smackx.packet.JingleTransport.JingleTransportCandidate; -import java.io.IOException; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -55,7 +51,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { public final static int CANDIDATES_ACCEPT_PERIOD = 4000; // The session this nenotiator belongs to - private final JingleSession session; + //private final JingleSession session; // The transport manager private final TransportResolver resolver; @@ -81,35 +77,21 @@ public abstract class TransportNegotiator extends JingleNegotiator { // Listener for the resolver private TransportResolverListener.Resolver resolverListener; - // states - private final Inviting inviting; - - private final Accepting accepting; - - private final Pending pending; - - private final Active active; + private ContentNegotiator parentNegotiator; /** - * Default constructor. - * - * @param js The Jingle session - * @param transResolver The JingleTransportManager to use - */ - public TransportNegotiator(JingleSession js, - TransportResolver transResolver) { - super(js.getConnection()); + * Default constructor. + * + * @param js The Jingle session + * @param transResolver The JingleTransportManager to use + */ + public TransportNegotiator(JingleSession session, TransportResolver transResolver, ContentNegotiator parentNegotiator) { + super(session); - session = js; resolver = transResolver; + this.parentNegotiator = parentNegotiator; resultThread = null; - - // Create the states... - inviting = new Inviting(this); - accepting = new Accepting(this); - pending = new Pending(this); - active = new Active(this); } /** @@ -118,7 +100,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @return A TransportNegotiator instance */ - public abstract org.jivesoftware.smackx.packet.JingleTransport getJingleTransport(TransportCandidate cand); + public abstract JingleTransport getJingleTransport(TransportCandidate cand); /** * Return true if the transport candidate is acceptable for the current @@ -143,8 +125,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @param bestLocalCandidate the acceptedLocalCandidate to set */ - private void setAcceptedLocalCandidate(TransportCandidate bestLocalCandidate) - throws XMPPException { + private void setAcceptedLocalCandidate(TransportCandidate bestLocalCandidate) throws XMPPException { for (int i = 0; i < resolver.getCandidateCount(); i++) { //TODO FIX The EQUAL Sentence if (resolver.getCandidate(i).getIp().equals(bestLocalCandidate.getIp()) @@ -166,11 +147,40 @@ public abstract class TransportNegotiator extends JingleNegotiator { return acceptedLocalCandidate; } + /** + * Called from above to start the negotiator during a session-initiate. + */ + public void start() { + + //JingleTransport result = new JingleTransport(getJingleTransport()); + + try { + sendTransportCandidatesOffer(); + setNegotiatorState(JingleNegotiatorState.PENDING); + } catch (XMPPException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + //return result; + + } + + /** + * Called from above to session-terminate. + */ public void close() { super.close(); } + /** + * Return a JingleTransport that best reflects this transport negotiator. + */ + public JingleTransport getJingleTransport() { + return getJingleTransport(getBestRemoteCandidate()); + } + public List getOfferedCandidates() { return offeredCandidates; } @@ -187,7 +197,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @return the remoteCandidates */ - private List getRemoteCandidates() { + private List getRemoteCandidates() { return remoteCandidates; } @@ -232,10 +242,9 @@ public abstract class TransportNegotiator extends JingleNegotiator { */ private void checkRemoteCandidate(final TransportCandidate offeredCandidate) { offeredCandidate.addListener(new TransportResolverListener.Checker() { - public void candidateChecked(TransportCandidate cand, - final boolean validCandidate) { + public void candidateChecked(TransportCandidate cand, final boolean validCandidate) { if (validCandidate) { - if (!(getState() instanceof Active)) + if (getNegotiatorState() == JingleNegotiatorState.PENDING) addValidRemoteCandidate(offeredCandidate); } } @@ -262,7 +271,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @return true if the transport is fully established. */ public final boolean isFullyEstablished() { - return isEstablished() && getState() == active; + return (isEstablished() && ((getNegotiatorState() == JingleNegotiatorState.SUCCEEDED) || (getNegotiatorState() == JingleNegotiatorState.FAILED))); } /** @@ -289,28 +298,31 @@ public abstract class TransportNegotiator extends JingleNegotiator { for (int i = 0; i < tries - 1; i++) { try { Thread.sleep(1000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } // Once we are in pending state, look for any valid remote // candidate, and send an "accept" if we have one... TransportCandidate bestRemote = getBestRemoteCandidate(); - State state = getState(); + //State state = getState(); - if (bestRemote != null && (state == pending || state == active)) { + if ((bestRemote != null) + && ((getNegotiatorState() == JingleNegotiatorState.PENDING))) { // Accepting the remote candidate if (!acceptedRemoteCandidates.contains(bestRemote)) { - Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT); - jout.addTransport(getJingleTransport(bestRemote)); + Jingle jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT); + JingleContent content = parentNegotiator.getJingleContent(); + content.addJingleTransport(getJingleTransport(bestRemote)); + jout.addContent(content); // Send the packet js.sendFormattedJingle(jin, jout); acceptedRemoteCandidates.add(bestRemote); } - if (isEstablished()) { - setState(active); + if ((isEstablished()) && (getNegotiatorState() == JingleNegotiatorState.PENDING)) { + setNegotiatorState(JingleNegotiatorState.SUCCEEDED); + triggerTransportEstablished(getAcceptedLocalCandidate(), bestRemote); break; } } @@ -371,34 +383,36 @@ public abstract class TransportNegotiator extends JingleNegotiator { for (int i = 0; i < 6; i++) { try { Thread.sleep(500); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } bestRemote = getBestRemoteCandidate(); - State state = getState(); - if (bestRemote != null && (state == pending || state == active)) { + //State state = getState(); + if ((bestRemote != null) + && ((getNegotiatorState() == JingleNegotiatorState.PENDING))) { if (!acceptedRemoteCandidates.contains(bestRemote)) { - Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT); - jout.addTransport(getJingleTransport(bestRemote)); + Jingle jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT); + JingleContent content = parentNegotiator.getJingleContent(); + content.addJingleTransport(getJingleTransport(bestRemote)); + jout.addContent(content); // Send the packet js.sendFormattedJingle(jin, jout); acceptedRemoteCandidates.add(bestRemote); } if (isEstablished()) { - setState(active); + setNegotiatorState(JingleNegotiatorState.SUCCEEDED); break; } } } - if (getState() == null || !getState().equals(active)) { + if (getNegotiatorState() != JingleNegotiatorState.SUCCEEDED) { try { - session.terminate("Unable to negotiate session. This may be caused by firewall configuration problems."); - } - catch (XMPPException e) { + session + .terminate("Unable to negotiate session. This may be caused by firewall configuration problems."); + } catch (XMPPException e) { e.printStackTrace(); } } @@ -468,21 +482,19 @@ public abstract class TransportNegotiator extends JingleNegotiator { * * @param jin The input jingle packet */ - private static ArrayList obtainCandidatesList(Jingle jin) { - ArrayList result = new ArrayList(); + private List obtainCandidatesList(Jingle jingle) { + List result = new ArrayList(); - if (jin != null) { + if (jingle != null) { // Get the list of candidates from the packet - Iterator iTrans = jin.getTransports(); - while (iTrans.hasNext()) { - org.jivesoftware.smackx.packet.JingleTransport trans = (org.jivesoftware.smackx.packet.JingleTransport) iTrans.next(); - - Iterator iCand = trans.getCandidates(); - while (iCand.hasNext()) { - JingleTransportCandidate cand = (JingleTransportCandidate) iCand - .next(); - TransportCandidate transCand = cand.getMediaTransport(); - result.add(transCand); + for (JingleContent jingleContent : jingle.getContentsList()) { + if (jingleContent.getName().equals(parentNegotiator.getName())) { + for (JingleTransport jingleTransport : jingleContent.getJingleTransportsList()) { + for (JingleTransportCandidate jingleTransportCandidate : jingleTransport.getCandidatesList()) { + TransportCandidate transCand = jingleTransportCandidate.getMediaTransport(); + result.add(transCand); + } + } } } } @@ -503,7 +515,15 @@ public abstract class TransportNegotiator extends JingleNegotiator { if (!cand.isNull()) { // Offer our new candidate... addOfferedCandidate(cand); - session.sendFormattedJingle(new Jingle(getJingleTransport(cand))); + JingleContent content = parentNegotiator.getJingleContent(); + content.addJingleTransport(getJingleTransport(cand)); + Jingle jingle = new Jingle(JingleActionEnum.TRANSPORT_INFO); + jingle.addContent(content); + + // We SHOULD NOT be sending packets directly. + // This circumvents the state machinery. + // TODO - work this into the state machinery. + session.sendFormattedJingle(jingle); } } @@ -513,7 +533,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @throws XMPPException */ private void sendTransportCandidatesOffer() throws XMPPException { - List notOffered = resolver.getCandidatesList(); + List notOffered = resolver.getCandidatesList(); notOffered.removeAll(offeredCandidates); @@ -556,79 +576,184 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @return the new Jingle packet to send. * @throws XMPPException */ - public final IQ dispatchIncomingPacket(IQ iq, String id) throws XMPPException { - IQ jout = null; + public final List dispatchIncomingPacket(IQ iq, String id) throws XMPPException { + List responses = new ArrayList(); + IQ response = null; - if (invalidState()) { - if (iq == null) { - // With a null packet, we are just inviting the other end... - setState(inviting); - jout = getState().eventInvite(); + if (iq != null) { + if (iq.getType().equals(IQ.Type.ERROR)) { + // Process errors + setNegotiatorState(JingleNegotiatorState.FAILED); + triggerTransportClosed(null); + // This next line seems wrong, and may subvert the normal closing process. + throw new JingleException(iq.getError().getMessage()); + } else if (iq.getType().equals(IQ.Type.RESULT)) { + // Process ACKs + if (isExpectedId(iq.getPacketID())) { + response = receiveResult(iq); + removeExpectedId(iq.getPacketID()); + } + } else if (iq instanceof Jingle) { + // Get the action from the Jingle packet + Jingle jingle = (Jingle) iq; + JingleActionEnum action = jingle.getAction(); - } - else { - if (iq instanceof Jingle) { - // If there is no specific jmf action associated, then we - // are being invited to a new session... - setState(accepting); - jout = getState().eventInitiate((Jingle) iq); - } - else { - throw new IllegalStateException( - "Invitation IQ received is not a Jingle packet in Transport negotiator."); - } - } - } - else { - if (iq == null) { - return null; - } - else { - if (iq.getType().equals(IQ.Type.ERROR)) { - // Process errors - getState().eventError(iq); - } - else if (iq.getType().equals(IQ.Type.RESULT)) { - // Process ACKs - if (isExpectedId(iq.getPacketID())) { - jout = getState().eventAck(iq); - removeExpectedId(iq.getPacketID()); - } - } - else if (iq instanceof Jingle) { - // Get the action from the Jingle packet - Jingle jin = (Jingle) iq; - Jingle.Action action = jin.getAction(); + switch (action) { + case CONTENT_ACCEPT: + response = receiveContentAcceptAction(jingle); + break; - if (action != null) { - if (action.equals(Jingle.Action.TRANSPORTACCEPT)) { - jout = getState().eventAccept(jin); - } - else if (action.equals(Jingle.Action.TRANSPORTDECLINE)) { - jout = getState().eventDecline(jin); - } - else if (action.equals(Jingle.Action.TRANSPORTINFO)) { - jout = getState().eventInfo(jin); - } - else if (action.equals(Jingle.Action.TRANSPORTMODIFY)) { - jout = getState().eventModify(jin); - } - } + case CONTENT_MODIFY: + break; + + case CONTENT_REMOVE: + break; + + case SESSION_INFO: + break; + + case SESSION_INITIATE: + response = receiveSessionInitiateAction(jingle); + break; + + case SESSION_ACCEPT: + response = receiveSessionAcceptAction(jingle); + break; + + case TRANSPORT_INFO: + response = receiveTransportInfoAction(jingle); + break; + + default: + break; } } } - // Save the Id for any ACK - if (id != null) { - addExpectedId(id); - } - else { - if (jout != null) { - addExpectedId(jout.getPacketID()); - } + if (response != null) { + addExpectedId(response.getPacketID()); + responses.add(response); } - return jout; + return responses; + } + + /** + * The other endpoint has partially accepted our invitation: start + * offering a list of candidates. + * + * @return an IQ packet + * @throws XMPPException + */ + private Jingle receiveResult(IQ iq) throws XMPPException { + Jingle response = null; + + sendTransportCandidatesOffer(); + setNegotiatorState(JingleNegotiatorState.PENDING); + + return response; + } + + /** + * @param jingle + * @param jingleTransport + * @return + */ + private IQ receiveSessionInitiateAction(Jingle jingle) throws XMPPException { + IQ response = null; + + // Parse the Jingle and get any proposed transport candidates + //addRemoteCandidates(obtainCandidatesList(jin)); + + // Start offering candidates + sendTransportCandidatesOffer(); + + // All these candidates will be checked asyncronously. Wait for some + // time and check if we have a valid candidate to use... + delayedCheckBestCandidate(session, jingle); + + // Set the next state + setNegotiatorState(JingleNegotiatorState.PENDING); + + return response; + } + + /** + * @param jingle + * @param jingleTransport + * @return + */ + private IQ receiveTransportInfoAction(Jingle jingle) throws XMPPException { + IQ response = null; + + // Parse the Jingle and get any proposed transport candidates + //addRemoteCandidates(obtainCandidatesList(jin)); + + // // Start offering candidates + // sendTransportCandidatesOffer(); + // + // // All these candidates will be checked asyncronously. Wait for some + // // time and check if we have a valid candidate to use... + // delayedCheckBestCandidate(session, jingle); + // + // // Set the next state + // setNegotiatorState(JingleNegotiatorState.PENDING); + + // Parse the Jingle and get any proposed transport candidates + addRemoteCandidates(obtainCandidatesList(jingle)); + + // Wait for some time and check if we have a valid candidate to + // use... + delayedCheckBestCandidate(session, jingle); + + response = session.createAck(jingle); + + return response; + } + + /** + * One of our transport candidates has been accepted. + * + * @param jin The input packet + * @return a Jingle packet + * @throws XMPPException an exception + * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAccept(org.jivesoftware.smackx.packet.Jingle) + */ + private IQ receiveContentAcceptAction(Jingle jingle) throws XMPPException { + IQ response = null; + + // Parse the Jingle and get the accepted candidate + List accepted = obtainCandidatesList(jingle); + if (!accepted.isEmpty()) { + + for (TransportCandidate cand : accepted) { + System.out.println("Cand: " + cand.getIp()); + } + + TransportCandidate cand = (TransportCandidate) accepted.get(0); + setAcceptedLocalCandidate(cand); + + if (isEstablished()) { + System.out.println("SET ACTIVE"); + //setNegotiatorState(JingleNegotiatorState.SUCCEEDED); + } + } + return response; + } + + /** + * @param jingle + * @return + */ + private IQ receiveSessionAcceptAction(Jingle jingle) { + IQ response = null; + + System.out.println("Transport stabilished"); + //triggerTransportEstablished(getAcceptedLocalCandidate(), getBestRemoteCandidate()); + + //setNegotiatorState(JingleNegotiatorState.SUCCEEDED); + + return response; } /** @@ -637,14 +762,13 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @param local TransportCandidate that has been agreed. * @param remote TransportCandidate that has been agreed. */ - private void triggerTransportEstablished(TransportCandidate local, - TransportCandidate remote) { - ArrayList listeners = getListenersList(); - for (Object listener : listeners) { - JingleListener li = (JingleListener) listener; + private void triggerTransportEstablished(TransportCandidate local, TransportCandidate remote) { + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleTransportListener) { JingleTransportListener mli = (JingleTransportListener) li; - System.out.println("triggerTransportEstablished " + local.getLocalIp() + ":" + local.getPort() + "|" + remote.getIp() + ":" + remote.getPort()); + System.out.println("triggerTransportEstablished " + local.getLocalIp() + ":" + local.getPort() + "|" + + remote.getIp() + ":" + remote.getPort()); mli.transportEstablished(local, remote); } } @@ -656,9 +780,8 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @param cand current TransportCandidate that is cancelled. */ private void triggerTransportClosed(TransportCandidate cand) { - ArrayList listeners = getListenersList(); - for (Object listener : listeners) { - JingleListener li = (JingleListener) listener; + List listeners = getListenersList(); + for (JingleListener li : listeners) { if (li instanceof JingleTransportListener) { JingleTransportListener mli = (JingleTransportListener) li; mli.transportClosed(cand); @@ -666,187 +789,6 @@ public abstract class TransportNegotiator extends JingleNegotiator { } } - // States - - /** - * First stage when we send a session request. - */ - public final class Inviting extends JingleNegotiator.State { - - public Inviting(TransportNegotiator neg) { - super(neg); - } - - /** - * Create an initial Jingle packet with an empty transport. - */ - public Jingle eventInvite() { - return new Jingle(getJingleTransport(null)); - } - - /** - * We have received some candidates. This can happen _before_ the ACK - * has been recieved... - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventInfo(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventInfo(Jingle jin) throws XMPPException { - // Parse the Jingle and get any proposed transport candidates - addRemoteCandidates(obtainCandidatesList(jin)); - - // Wait for some time and check if we have a valid candidate to - // use... - delayedCheckBestCandidate(session, jin); - - return null;// super.eventInfo(jin); - } - - /** - * The other endpoint has partially accepted our invitation: start - * offering a list of candidates. - * - * @return an IQ packet - * @throws XMPPException - */ - public Jingle eventAck(IQ iq) throws XMPPException { - sendTransportCandidatesOffer(); - setState(pending); - return super.eventAck(iq); - } - } - - /** - * We are accepting connections. This is the starting state when we accept a - * connection... - */ - public final class Accepting extends JingleNegotiator.State { - - public Accepting(TransportNegotiator neg) { - super(neg); - } - - /** - * We have received an invitation. The packet will be ACKed by lower - * levels... - */ - public Jingle eventInitiate(Jingle jin) throws XMPPException { - // Parse the Jingle and get any proposed transport candidates - //addRemoteCandidates(obtainCandidatesList(jin)); - - // Start offering candidates - sendTransportCandidatesOffer(); - - // All these candidates will be checked asyncronously. Wait for some - // time and check if we have a valid candidate to use... - delayedCheckBestCandidate(session, jin); - - // Set the next state - setState(pending); - - return super.eventInitiate(jin); - } - } - - /** - * We are still receiving candidates - */ - public final class Pending extends JingleNegotiator.State { - - public Pending(TransportNegotiator neg) { - super(neg); - } - - /** - * One of our transport candidates has been accepted. - * - * @param jin The input packet - * @return a Jingle packet - * @throws XMPPException an exception - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAccept(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventAccept(Jingle jin) throws XMPPException { - Jingle response = null; - - // Parse the Jingle and get the accepted candidate - ArrayList accepted = obtainCandidatesList(jin); - if (!accepted.isEmpty()) { - - for (TransportCandidate cand : (List) accepted) { - System.out.println("Cand: " + cand.getIp()); - } - - TransportCandidate cand = (TransportCandidate) accepted.get(0); - setAcceptedLocalCandidate(cand); - - if (isEstablished()) { - System.out.println("SET ACTIVE"); - setState(active); - } - } - return response; - } - - /** - * We have received another remote transport candidates. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventInfo(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventInfo(Jingle jin) throws XMPPException { - - sendTransportCandidatesOffer(); - - // Parse the Jingle and get any proposed transport candidates - addRemoteCandidates(obtainCandidatesList(jin)); - - // Wait for some time and check if we have a valid candidate to - // use... - delayedCheckBestCandidate(session, jin); - - return null;//super.eventInfo(jin); - } - - /** - * None of our transport candidates has been accepted... - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventDecline(org.jivesoftware.smackx.packet.Jingle) - */ - public Jingle eventDecline(Jingle inJingle) throws JingleException { - throw new JingleException("No common payload found."); - } - } - - /** - * "Active" state: we have an agreement about the codec... - */ - public final class Active extends JingleNegotiator.State { - - public Active(TransportNegotiator neg) { - super(neg); - } - - /** - * We have an agreement. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventEnter() { - System.out.println("Transport stabilished"); - triggerTransportEstablished(getAcceptedLocalCandidate(), - getBestRemoteCandidate()); - super.eventEnter(); - } - - /** - * We have finished the transport. - * - * @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventEnter() - */ - public void eventExit() { - triggerTransportClosed(null); - super.eventExit(); - } - } - // Subclasses /** @@ -862,8 +804,8 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @param js The Jingle session this negotiation belongs to. * @param res The transport resolver to use. */ - public RawUdp(JingleSession js, final TransportResolver res) { - super(js, res); + public RawUdp(JingleSession js, final TransportResolver res, ContentNegotiator parentNegotiator) { + super(js, res, parentNegotiator); } /** @@ -887,8 +829,7 @@ public abstract class TransportNegotiator extends JingleNegotiator { if (!cands.isEmpty()) { System.out.println("RAW CAND"); return (TransportCandidate) cands.get(0); - } - else { + } else { System.out.println("No Remote Candidate"); return null; } @@ -915,8 +856,8 @@ public abstract class TransportNegotiator extends JingleNegotiator { * @param js The Jingle session this negotiation belongs to. * @param res The transport manager to use. */ - public Ice(JingleSession js, final TransportResolver res) { - super(js, res); + public Ice(JingleSession js, final TransportResolver res, ContentNegotiator parentNegotiator) { + super(js, res, parentNegotiator); } /** 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 7b720ed50..6937bcb6f 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolver.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: TransportResolver.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:07 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -354,10 +354,10 @@ public abstract class TransportResolver { * @return the list of transport candidates */ public List getCandidatesList() { - ArrayList result = null; + List result = null; synchronized (candidates) { - result = new ArrayList(candidates); + result = new ArrayList(candidates); } return result; diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolverListener.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolverListener.java index 263d7d07e..f9066a7fc 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolverListener.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TransportResolverListener.java @@ -1,6 +1,6 @@ /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: TransportResolverListener.java,v $ + * $Revision: 1.1 $ * $Date: 15/11/2006 * * Copyright 2003-2006 Jive Software. diff --git a/jingle/extension/source/org/jivesoftware/smackx/packet/Jingle.java b/jingle/extension/source/org/jivesoftware/smackx/packet/Jingle.java index e567a9a77..d731847ca 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/packet/Jingle.java +++ b/jingle/extension/source/org/jivesoftware/smackx/packet/Jingle.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 2407 $ - * $Date: 2004-11-02 23:37:00 +0000 (Tue, 02 Nov 2004) $ + * $RCSfile: Jingle.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:08 $ * * Copyright 2003-2007 Jive Software. * @@ -21,6 +21,7 @@ package org.jivesoftware.smackx.packet; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smackx.jingle.JingleActionEnum; import java.util.ArrayList; import java.util.Collections; @@ -43,7 +44,7 @@ public class Jingle extends IQ { // static - public static final String NAMESPACE = "http://jabber.org/protocol/jingle"; + public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0166.html#ns"; public static final String NODENAME = "jingle"; @@ -51,33 +52,27 @@ public class Jingle extends IQ { private String sid; // The session id - private Action action; // The action associated to the Jingle + private JingleActionEnum action; // The action associated to the Jingle private String initiator; // The initiator as a "user@host/resource" private String responder; // The responder // Sub-elements of a Jingle object. - - private final List descriptions = new ArrayList(); - - private final List transports = new ArrayList(); + + private final List contents = new ArrayList(); private JingleContentInfo contentInfo; /** * A constructor where the main components can be initialized. */ - public Jingle(final List descs, final List trans, final JingleContentInfo mi, + public Jingle(final List contents, final JingleContentInfo mi, final String sid) { super(); - if (descs != null) { - descriptions.addAll(descs); - } - - if (trans != null) { - transports.addAll(trans); + if (contents != null) { + contents.addAll(contents); } setContentInfo(mi); @@ -90,44 +85,25 @@ public class Jingle extends IQ { } /** - * Constructor with a description. + * Constructor with a contents. * - * @param descr a description + * @param content a content */ - public Jingle(final JingleContentDescription descr) { + public Jingle(final JingleContent content) { super(); - addDescription(descr); + addContent(content); // Set null all other fields in the packet initiator = null; responder = null; // Some default values for the most common situation... - action = Jingle.Action.DESCRIPTIONINFO; + action = JingleActionEnum.UNKNOWN; this.setType(IQ.Type.SET); } - /** - * Constructor with a transport. - * - * @param trans a transport - */ - public Jingle(final JingleTransport trans) { - super(); - - addTransport(trans); - - // Set null all other fields in the packet - initiator = null; - responder = null; - - // Some default values for the most common situation... - action = Jingle.Action.TRANSPORTINFO; - this.setType(IQ.Type.SET); - } - - /** + /** * Constructor with a content info. * * @param info The content info @@ -142,7 +118,7 @@ public class Jingle extends IQ { responder = null; // Some default values for the most common situation... - action = Jingle.Action.DESCRIPTIONINFO; + action = JingleActionEnum.UNKNOWN; this.setType(IQ.Type.SET); } @@ -151,8 +127,8 @@ public class Jingle extends IQ { * * @param action The action. */ - public Jingle(final Jingle.Action action) { - this(null, null, null, null); + public Jingle(final JingleActionEnum action) { + this(null, null, null); this.action = action; // In general, a Jingle with an action is used in a SET packet... @@ -166,7 +142,7 @@ public class Jingle extends IQ { * @see #setSid(String) */ public Jingle(final String sid) { - this(null, null, null, sid); + this(null, null, sid); } /** @@ -215,7 +191,7 @@ public class Jingle extends IQ { /** * Returns the XML namespace of the extension sub-packet root element. * According the specification the namespace is always - * "http://jabber.org/protocol/jingle" + * "http://www.xmpp.org/extensions/xep-0166.html#ns" * * @return the XML namespace of the packet extension. */ @@ -238,107 +214,59 @@ public class Jingle extends IQ { } /** - * Get an iterator for the content descriptions + * Get an iterator for the contents * - * @return the descriptions + * @return the contents */ - public Iterator getDescriptions() { - synchronized (descriptions) { - return Collections.unmodifiableList(new ArrayList(descriptions)).iterator(); + public Iterator getContents() { + synchronized (contents) { + return Collections.unmodifiableList(new ArrayList(contents)).iterator(); } } /** - * Get an iterator for the content descriptions + * Get an iterator for the content * - * @return the descriptions + * @return the contents */ - public ArrayList getDescriptionsList() { - synchronized (descriptions) { - return new ArrayList(descriptions); + public List getContentsList() { + synchronized (contents) { + return new ArrayList(contents); } } /** - * Add a new content description. + * Add a new content. * - * @param desc the descriptions to add + * @param content the content to add */ - public void addDescription(final JingleContentDescription desc) { - if (desc != null) { - synchronized (descriptions) { - descriptions.add(desc); + public void addContent(final JingleContent content) { + if (content != null) { + synchronized (contents) { + contents.add(content); } } } /** - * Add a list of JingleContentDescription elements + * Add a list of JingleContent elements * - * @param descsList the list of transports to add + * @param contentList the list of contents to add */ - public void addDescriptions(final List descsList) { - if (descsList != null) { - synchronized (descriptions) { - descriptions.addAll(descsList); + public void addContents(final List contentList) { + if (contentList != null) { + synchronized (contents) { + contents.addAll(contentList); } } } - /** - * Get an iterator for the transport. - * - * @return the transports - */ - public Iterator getTransports() { - synchronized (transports) { - return Collections.unmodifiableList(new ArrayList(transports)).iterator(); - } - } - - /** - * Get the list of transports. - * - * @return the transports list. - */ - public ArrayList getTransportsList() { - synchronized (transports) { - return new ArrayList(transports); - } - } - - /** - * Add a new TransportNegotiator element - * - * @param trans the transports to add - */ - public void addTransport(final JingleTransport trans) { - if (trans != null) { - synchronized (transports) { - transports.add(trans); - } - } - } - - /** - * Add a list of TransportNegotiator elements - * - * @param transList the list of transports to add - */ - public void addTransports(final List transList) { - if (transList != null) { - synchronized (transports) { - transports.addAll(transList); - } - } - } - - /** + /** * Get the action specified in the packet * * @return the action */ - public Action getAction() { + public JingleActionEnum getAction() { return action; } @@ -347,7 +275,7 @@ public class Jingle extends IQ { * * @param action the action to set */ - public void setAction(final Action action) { + public void setAction(final JingleActionEnum action) { this.action = action; } @@ -433,26 +361,12 @@ public class Jingle extends IQ { buf.append(" sid=\"").append(getSid()).append("\""); } buf.append(">"); - //TODO Update to accept more than one content per session (XEP-0166) - - buf.append(""); - // Look for possible payload types, and dump them. - synchronized (descriptions) { - for (int i = 0; i < descriptions.size(); i++) { - JingleContentDescription desc = (JingleContentDescription) descriptions - .get(i); - buf.append(desc.toXML()); + + synchronized (contents) { + for (JingleContent content : contents) { + buf.append(content.toXML()); } - } - - // If the packet has transports, dump them. - synchronized (transports) { - for (int i = 0; i < transports.size(); i++) { - JingleTransport trans = (JingleTransport) transports.get(i); - buf.append(trans.toXML()); - } - } - buf.append(""); + } // and the same for audio jmf info if (contentInfo != null) { @@ -462,43 +376,4 @@ public class Jingle extends IQ { buf.append(""); return buf.toString(); } - - /** - * The "action" in the jingle packet, as an enum. - */ - public static enum Action { - - CONTENTACCEPT, CONTENTADD, CONTENTDECLINE, CONTENTMODIFY, - CONTENTREMOVE, DESCRIPTIONADD, DESCRIPTIONDECLINE, - DESCRIPTIONINFO, DESCRIPTIONMODIFY, SESSIONACCEPT, - SESSIONINFO, SESSIONINITIATE, SESSIONREDIRECT, - SESSIONTERMINATE, TRANSPORTACCEPT, TRANSPORTDECLINE, - TRANSPORTINFO, TRANSPORTMODIFY; - - private static String names[] = {"content-accept", "content-add", "content-decline", "content-modify", - "content-remove", "description-accept", "description-decline", "description-info", - "description-modify", "session-accept", "session-info", "session-initiate", - "session-redirect", "session-terminate", "transport-accept", "transport-decline", - "transport-info", "transport-modify"}; - - /** - * Returns the String value for an Action. - */ - - public String toString() { - return names[this.ordinal()]; - } - - /** - * Returns the Action for a String value. - */ - public static Action getAction(String str) { - for (int i = 0; i < names.length; i++) { - if (names[i].equals(str)) return Action.values()[i]; - } - return null; - } - - } - } diff --git a/jingle/extension/source/org/jivesoftware/smackx/packet/JingleContentInfo.java b/jingle/extension/source/org/jivesoftware/smackx/packet/JingleContentInfo.java index 6002a89f5..60ca87660 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/packet/JingleContentInfo.java +++ b/jingle/extension/source/org/jivesoftware/smackx/packet/JingleContentInfo.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: JingleContentInfo.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:08 $ * * Copyright 2003-2005 Jive Software. * @@ -96,7 +96,7 @@ public class JingleContentInfo implements PacketExtension { */ public static class Audio extends JingleContentInfo { - public static final String NAMESPACE = "http://jabber.org/protocol/jingle/info/audio"; + public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0167.html#ns-info"; public Audio(final ContentInfo mi) { super(mi); diff --git a/jingle/extension/source/org/jivesoftware/smackx/packet/JingleError.java b/jingle/extension/source/org/jivesoftware/smackx/packet/JingleError.java index 0d9ed282e..9067a7ea5 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/packet/JingleError.java +++ b/jingle/extension/source/org/jivesoftware/smackx/packet/JingleError.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: JingleError.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:08 $ * * Copyright 2003-2005 Jive Software. * @@ -27,7 +27,7 @@ import org.xmlpull.v1.XmlPullParser; public class JingleError implements PacketExtension { - public static String NAMESPACE = "http://jabber.org/protocol/jingle#error"; + public static String NAMESPACE = "http://www.xmpp.org/extensions/xep-0166.html#ns-errors"; public static final JingleError OUT_OF_ORDER = new JingleError("out-of-order"); @@ -134,7 +134,7 @@ public class JingleError implements PacketExtension { } /** - * Parse a JingleContentDescription.Audio extension. + * Parse a JingleDescription.Audio extension. */ public PacketExtension parseExtension(final XmlPullParser parser) throws Exception { diff --git a/jingle/extension/source/org/jivesoftware/smackx/packet/JingleTransport.java b/jingle/extension/source/org/jivesoftware/smackx/packet/JingleTransport.java index ce99ed332..f80d1f83f 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/packet/JingleTransport.java +++ b/jingle/extension/source/org/jivesoftware/smackx/packet/JingleTransport.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: JingleTransport.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:08 $ * * Copyright 2003-2005 Jive Software. * @@ -20,8 +20,8 @@ package org.jivesoftware.smackx.packet; import org.jivesoftware.smack.packet.PacketExtension; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.nat.ICECandidate; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import java.util.ArrayList; import java.util.Collections; @@ -43,7 +43,7 @@ public class JingleTransport implements PacketExtension { protected String namespace; - protected final List candidates = new ArrayList(); + protected final List candidates = new ArrayList(); /** * Default constructor. @@ -104,10 +104,10 @@ public class JingleTransport implements PacketExtension { * * @return The candidates list. */ - public ArrayList getCandidatesList() { - ArrayList res = null; + public List getCandidatesList() { + ArrayList res = null; synchronized (candidates) { - res = new ArrayList(candidates); + res = new ArrayList(candidates); } return res; } @@ -270,7 +270,7 @@ public class JingleTransport implements PacketExtension { * RTP-ICE profile */ public static class Ice extends JingleTransport { - public static final String NAMESPACE = "http://jabber.org/protocol/jingle/transport/ice"; + public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0176.html#ns-udp"; public Ice() { super(); @@ -292,9 +292,9 @@ public class JingleTransport implements PacketExtension { * * @see org.jivesoftware.smackx.packet.JingleTransport#getCandidates() */ - public ArrayList getCandidatesList() { - ArrayList copy = new ArrayList(); - ArrayList superCandidatesList = super.getCandidatesList(); + public List getCandidatesList() { + List copy = new ArrayList(); + List superCandidatesList = super.getCandidatesList(); for (int i = 0; i < superCandidatesList.size(); i++) { copy.add(superCandidatesList.get(i)); } @@ -352,7 +352,7 @@ public class JingleTransport implements PacketExtension { * Raw UDP profile. */ public static class RawUdp extends JingleTransport { - public static final String NAMESPACE = "http://jabber.org/protocol/jingle/transport/raw-udp"; + public static final String NAMESPACE = "http://www.xmpp.org/extensions/xep-0177.html#ns"; public RawUdp() { super(); @@ -375,9 +375,9 @@ public class JingleTransport implements PacketExtension { * * @see org.jivesoftware.smackx.packet.JingleTransport#getCandidates() */ - public ArrayList getCandidatesList() { - ArrayList copy = new ArrayList(); - ArrayList superCandidatesList = super.getCandidatesList(); + public List getCandidatesList() { + List copy = new ArrayList(); + List superCandidatesList = super.getCandidatesList(); if (superCandidatesList.size() > 0) { copy.add(superCandidatesList.get(0)); } diff --git a/jingle/extension/source/org/jivesoftware/smackx/provider/JingleContentInfoProvider.java b/jingle/extension/source/org/jivesoftware/smackx/provider/JingleContentInfoProvider.java index ab2512bf9..68c60aa18 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/provider/JingleContentInfoProvider.java +++ b/jingle/extension/source/org/jivesoftware/smackx/provider/JingleContentInfoProvider.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: JingleContentInfoProvider.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:11 $ * * Copyright 2003-2005 Jive Software. * @@ -46,7 +46,7 @@ public class JingleContentInfoProvider implements PacketExtensionProvider { } /** - * JingleContentDescription.Audio info provider + * JingleDescription.Audio info provider */ public static class Audio extends JingleContentInfoProvider { @@ -70,7 +70,7 @@ public class JingleContentInfoProvider implements PacketExtensionProvider { } /** - * Parse a JingleContentDescription.Audio extension. + * Parse a JingleDescription.Audio extension. */ public PacketExtension parseExtension(final XmlPullParser parser) throws Exception { diff --git a/jingle/extension/source/org/jivesoftware/smackx/provider/JingleProvider.java b/jingle/extension/source/org/jivesoftware/smackx/provider/JingleProvider.java index 9abdca003..cdb17dda0 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/provider/JingleProvider.java +++ b/jingle/extension/source/org/jivesoftware/smackx/provider/JingleProvider.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: JingleProvider.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:11 $ * * Copyright 2003-2005 Jive Software. * @@ -23,15 +23,13 @@ package org.jivesoftware.smackx.provider; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; -import org.jivesoftware.smackx.packet.Jingle; -import org.jivesoftware.smackx.packet.JingleContentDescription; -import org.jivesoftware.smackx.packet.JingleContentInfo; -import org.jivesoftware.smackx.packet.JingleTransport; +import org.jivesoftware.smackx.jingle.JingleActionEnum; +import org.jivesoftware.smackx.packet.*; import org.xmlpull.v1.XmlPullParser; /** * The JingleProvider parses Jingle packets. - * + * * @author Alvaro Saurin */ public class JingleProvider implements IQProvider { @@ -51,13 +49,15 @@ public class JingleProvider implements IQProvider { Jingle jingle = new Jingle(); String sid = ""; - Jingle.Action action; + JingleActionEnum action; String initiator = ""; String responder = ""; boolean done = false; + JingleContent currentContent = null; // Sub-elements providers - JingleContentDescriptionProvider jdpAudio = new JingleContentDescriptionProvider.Audio(); + JingleContentProvider jcp = new JingleContentProvider(); + JingleDescriptionProvider jdpAudio = new JingleDescriptionProvider.Audio(); JingleTransportProvider jtpRawUdp = new JingleTransportProvider.RawUdp(); JingleTransportProvider jtpIce = new JingleTransportProvider.Ice(); JingleContentInfoProvider jmipAudio = new JingleContentInfoProvider.Audio(); @@ -68,7 +68,7 @@ public class JingleProvider implements IQProvider { // Get some attributes for the element sid = parser.getAttributeValue("", "sid"); - action = Jingle.Action.getAction(parser.getAttributeValue("", "action")); + action = JingleActionEnum.getAction(parser.getAttributeValue("", "action")); initiator = parser.getAttributeValue("", "initiator"); responder = parser.getAttributeValue("", "responder"); @@ -88,32 +88,29 @@ public class JingleProvider implements IQProvider { // Parse some well know subelements, depending on the namespaces // and element names... - if (elementName.equals(JingleContentDescription.NODENAME) - && namespace.equals(JingleContentDescription.Audio.NAMESPACE)) { - jingle.addDescription((JingleContentDescription) jdpAudio - .parseExtension(parser)); + if (elementName.equals(JingleContent.NODENAME)) { + // Add a new element to the jingle + currentContent = (JingleContent) jcp.parseExtension(parser); + jingle.addContent(currentContent); + } else if (elementName.equals(JingleDescription.NODENAME) && namespace.equals(JingleDescription.Audio.NAMESPACE)) { + // Set the element of the + currentContent.setDescription((JingleDescription) jdpAudio.parseExtension(parser)); } else if (elementName.equals(JingleTransport.NODENAME)) { + // Add all of the elements to the of the jingle // Parse the possible transport namespaces if (namespace.equals(JingleTransport.RawUdp.NAMESPACE)) { - jingle.addTransport((JingleTransport) jtpRawUdp - .parseExtension(parser)); + currentContent.addJingleTransport((JingleTransport) jtpRawUdp.parseExtension(parser)); } else if (namespace.equals(JingleTransport.Ice.NAMESPACE)) { - jingle.addTransport((JingleTransport) jtpIce - .parseExtension(parser)); + currentContent.addJingleTransport((JingleTransport) jtpIce.parseExtension(parser)); } else { - throw new XMPPException("Unknown transport namespace \"" - + namespace + "\" in Jingle packet."); + throw new XMPPException("Unknown transport namespace \"" + namespace + "\" in Jingle packet."); } } else if (namespace.equals(JingleContentInfo.Audio.NAMESPACE)) { - jingle.setContentInfo((JingleContentInfo) jmipAudio - .parseExtension(parser)); - } else if (elementName.equals("content")) { - //TODO Separate Contents (XEP-0166) + jingle.setContentInfo((JingleContentInfo) jmipAudio.parseExtension(parser)); } else { - throw new XMPPException("Unknown combination of namespace \"" - + namespace + "\" and element name \"" + elementName - + "\" in Jingle packet."); + throw new XMPPException("Unknown combination of namespace \"" + namespace + "\" and element name \"" + + elementName + "\" in Jingle packet."); } } else if (eventType == XmlPullParser.END_TAG) { diff --git a/jingle/extension/source/org/jivesoftware/smackx/provider/JingleTransportProvider.java b/jingle/extension/source/org/jivesoftware/smackx/provider/JingleTransportProvider.java index 5ceda5fb5..52029eda9 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/provider/JingleTransportProvider.java +++ b/jingle/extension/source/org/jivesoftware/smackx/provider/JingleTransportProvider.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision: 7329 $ - * $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $ + * $RCSfile: JingleTransportProvider.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:11 $ * * Copyright 2003-2005 Jive Software. * @@ -21,8 +21,8 @@ package org.jivesoftware.smackx.provider; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.PacketExtensionProvider; -import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.jingle.nat.ICECandidate; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.packet.JingleTransport; import org.jivesoftware.smackx.packet.JingleTransport.JingleTransportCandidate; import org.xmlpull.v1.XmlPullParser; diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java index 479313e8a..ac30ffb5a 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleManagerTest.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: JingleManagerTest.java,v $ + * $Revision: 1.3 $ + * $Date: 2007/07/18 18:29:21 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== @@ -65,8 +65,12 @@ import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; 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.*; import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager; +import org.jivesoftware.smackx.jingle.mediaimpl.test.TestMediaManager; +import org.jivesoftware.smackx.jingle.nat.FixedResolver; +import org.jivesoftware.smackx.jingle.nat.FixedTransportManager; +import org.jivesoftware.smackx.jingle.nat.RTPBridge; +import org.jivesoftware.smackx.jingle.nat.TransportCandidate; import org.jivesoftware.smackx.packet.Jingle; import org.jivesoftware.smackx.provider.JingleProvider; @@ -127,8 +131,8 @@ public class JingleManagerTest extends SmackTestCase { * * @return A testing list */ - private ArrayList getTestPayloads1() { - ArrayList result = new ArrayList(); + private List getTestPayloads1() { + List result = new ArrayList(); result.add(new PayloadType.Audio(34, "supercodec-1", 2, 14000)); result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000)); @@ -138,8 +142,8 @@ public class JingleManagerTest extends SmackTestCase { return result; } - private ArrayList getTestPayloads2() { - ArrayList result = new ArrayList(); + private List getTestPayloads2() { + List result = new ArrayList(); result.add(new PayloadType.Audio(27, "supercodec-3", 2, 28000)); result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000)); @@ -149,8 +153,8 @@ public class JingleManagerTest extends SmackTestCase { return result; } - private ArrayList getTestPayloads3() { - ArrayList result = new ArrayList(); + private List getTestPayloads3() { + List result = new ArrayList(); result.add(new PayloadType.Audio(91, "badcodec-1", 2, 28000)); result.add(new PayloadType.Audio(92, "badcodec-2", 1, 44000)); @@ -168,9 +172,7 @@ public class JingleManagerTest extends SmackTestCase { resetCounter(); - ProviderManager.getInstance().addIQProvider("jingle", - "http://jabber.org/protocol/jingle", - new JingleProvider()); + ProviderManager.getInstance().addIQProvider("jingle", "http://jabber.org/protocol/jingle", new JingleProvider()); PacketFilter initRequestFilter = new PacketFilter() { // Return true if we accept this packet @@ -182,9 +184,8 @@ public class JingleManagerTest extends SmackTestCase { System.out.println("packet"); if (iq instanceof Jingle) { Jingle jin = (Jingle) pin; - if (jin.getAction().equals(Jingle.Action.SESSIONINITIATE)) { - System.out - .println("Session initiation packet accepted... "); + if (jin.getAction().equals(JingleActionEnum.SESSION_INITIATE)) { + System.out.println("Session initiation packet accepted... "); return true; } } @@ -203,12 +204,8 @@ public class JingleManagerTest extends SmackTestCase { }, initRequestFilter); // Create a dummy packet for testing... - IQfake iqSent = new IQfake( - " " - + ""); + IQfake iqSent = new IQfake(" " + ""); iqSent.setTo(getFullJID(0)); iqSent.setFrom(getFullJID(0)); @@ -218,8 +215,7 @@ public class JingleManagerTest extends SmackTestCase { getConnection(1).sendPacket(iqSent); try { Thread.sleep(10000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { } System.out.println("Awake... " + valCounter()); @@ -236,11 +232,22 @@ public class JingleManagerTest extends SmackTestCase { resetCounter(); try { - TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222); - TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567); + FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + TestMediaManager tmm0 = new TestMediaManager(ftm0); + tmm0.setPayloads(getTestPayloads1()); + List trl0 = new ArrayList(); + trl0.add(tmm0); - JingleManager man0 = new JingleManager(getConnection(0), tr1); - JingleManager man1 = new JingleManager(getConnection(1), tr2); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + tmm1.setPayloads(getTestPayloads1()); + List trl1 = new ArrayList(); + trl1.add(tmm1); + + JingleManager man0 = new JingleManager(getConnection(0), trl0); + JingleManager man1 = new JingleManager(getConnection(1), trl1); // Session 1 waits for connections man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { @@ -249,23 +256,20 @@ public class JingleManagerTest extends SmackTestCase { */ public void sessionRequested(final JingleSessionRequest request) { incCounter(); - System.out.println("Session request detected, from " - + request.getFrom()); + System.out.println("Session request detected, from " + request.getFrom()); } }); // Session 0 starts a request System.out.println("Starting session request, to " + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); - session0.start(null); + JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); + session0.startOutgoing(); Thread.sleep(5000); assertTrue(valCounter() > 0); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); fail("An error occured with Jingle"); } @@ -281,27 +285,36 @@ public class JingleManagerTest extends SmackTestCase { resetCounter(); try { - TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222); - TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567); + FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + TestMediaManager tmm0 = new TestMediaManager(ftm0); + tmm0.setPayloads(getTestPayloads1()); + List trl0 = new ArrayList(); + trl0.add(tmm0); - final JingleManager man0 = new JingleManager(getConnection(0), tr1); - final JingleManager man1 = new JingleManager(getConnection(1), tr2); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + tmm1.setPayloads(getTestPayloads2()); + List trl1 = new ArrayList(); + trl1.add(tmm1); + JingleManager man0 = new JingleManager(getConnection(0), trl0); + JingleManager man1 = new JingleManager(getConnection(1), trl1); + man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { /** * Called when a new session request is detected */ public void sessionRequested(final JingleSessionRequest request) { incCounter(); - System.out.println("Session request detected, from " - + request.getFrom() + ": accepting."); + System.out.println("Session request detected, from " + request.getFrom() + ": accepting."); // We accept the request try { - IncomingJingleSession session1 = request.accept(getTestPayloads2()); - session1.start(request); - } - catch (Exception e) { + JingleSession session1 = request.accept(); + session1.startIncoming(); + } catch (Exception e) { e.printStackTrace(); } } @@ -309,16 +322,14 @@ public class JingleManagerTest extends SmackTestCase { // Session 0 starts a request System.out.println("Starting session request, to " + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); - session0.start(null); + JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); + session0.startOutgoing(); Thread.sleep(20000); assertTrue(valCounter() > 0); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); fail("An error occured with Jingle"); } @@ -333,22 +344,35 @@ public class JingleManagerTest extends SmackTestCase { resetCounter(); try { - TransportResolver tr1 = new FixedResolver("127.0.0.1", 54213); - TransportResolver tr2 = new FixedResolver("127.0.0.1", 54531); + FixedResolver tr0 = new FixedResolver("127.0.0.1", 54213); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + TestMediaManager tmm0 = new TestMediaManager(ftm0); + tmm0.setPayloads(getTestPayloads1()); + List trl0 = new ArrayList(); + trl0.add(tmm0); - final JingleManager man0 = new JingleManager(getConnection(0), tr1); - final JingleManager man1 = new JingleManager(getConnection(1), tr2); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 54531); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + tmm1.setPayloads(getTestPayloads1()); + List trl1 = new ArrayList(); + trl1.add(tmm1); + JingleManager man0 = new JingleManager(getConnection(0), trl0); + JingleManager man1 = new JingleManager(getConnection(1), trl1); + + man0.addCreationListener(ftm0); + man1.addCreationListener(ftm1); + man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { /** * Called when a new session request is detected */ public void sessionRequested(final JingleSessionRequest request) { - System.out.println("Session request detected, from " - + request.getFrom() + ": accepting."); + System.out.println("Session request detected, from " + request.getFrom() + ": accepting."); try { // We accept the request - IncomingJingleSession session1 = request.accept(getTestPayloads1()); + JingleSession session1 = request.accept(); session1.addListener(new JingleSessionListener() { public void sessionClosed(String reason, JingleSession jingleSession) { @@ -363,16 +387,13 @@ public class JingleManagerTest extends SmackTestCase { System.out.println("sessionDeclined()."); } - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { incCounter(); - System.out - .println("Responder: the session is fully established."); + System.out.println("Responder: the session is fully established."); System.out.println("+ Payload Type: " + pt.getId()); - System.out.println("+ Local IP/port: " + lc.getIp() + ":" - + lc.getPort()); - System.out.println("+ Remote IP/port: " + rc.getIp() + ":" - + rc.getPort()); + System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort()); + System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort()); } public void sessionMediaReceived(JingleSession jingleSession, String participant) { @@ -383,27 +404,23 @@ public class JingleManagerTest extends SmackTestCase { } }); - session1.start(request); - } - catch (Exception e) { + session1.startIncoming(); + } catch (Exception e) { e.printStackTrace(); } } }); // Session 0 starts a request - System.out.println("Starting session request with equal payloads, to " - + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); - session0.start(null); + System.out.println("Starting session request with equal payloads, to " + getFullJID(1) + "..."); + JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); + session0.startOutgoing(); Thread.sleep(20000); assertTrue(valCounter() == 1); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); fail("An error occured with Jingle"); } @@ -417,22 +434,32 @@ public class JingleManagerTest extends SmackTestCase { resetCounter(); try { - TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222); - TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567); + FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + TestMediaManager tmm0 = new TestMediaManager(ftm0); + tmm0.setPayloads(getTestPayloads1()); + List trl0 = new ArrayList(); + trl0.add(tmm0); - final JingleManager man0 = new JingleManager(getConnection(0), tr1); - final JingleManager man1 = new JingleManager(getConnection(1), tr2); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + tmm1.setPayloads(getTestPayloads2()); + List trl1 = new ArrayList(); + trl1.add(tmm1); + + JingleManager man0 = new JingleManager(getConnection(0), trl0); + JingleManager man1 = new JingleManager(getConnection(1), trl1); man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { /** * Called when a new session request is detected */ public void sessionRequested(final JingleSessionRequest request) { - System.out.println("Session request detected, from " - + request.getFrom() + ": accepting."); + System.out.println("Session request detected, from " + request.getFrom() + ": accepting."); try { // We accept the request - IncomingJingleSession session1 = request.accept(getTestPayloads2()); + JingleSession session1 = request.accept(); session1.addListener(new JingleSessionListener() { public void sessionClosed(String reason, JingleSession jingleSession) { @@ -447,16 +474,13 @@ public class JingleManagerTest extends SmackTestCase { System.out.println("sessionDeclined()."); } - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, final TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, final TransportCandidate lc, + JingleSession jingleSession) { incCounter(); - System.out - .println("Responder: the session is fully established."); + System.out.println("Responder: the session is fully established."); System.out.println("+ Payload Type: " + pt.getId()); - System.out.println("+ Local IP/port: " + lc.getIp() + ":" - + lc.getPort()); - System.out.println("+ Remote IP/port: " + rc.getIp() + ":" - + rc.getPort()); + System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort()); + System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort()); } public void sessionMediaReceived(JingleSession jingleSession, String participant) { @@ -467,10 +491,8 @@ public class JingleManagerTest extends SmackTestCase { } }); - - session1.start(request); - } - catch (Exception e) { + session1.startIncoming(); + } catch (Exception e) { e.printStackTrace(); } } @@ -478,8 +500,7 @@ public class JingleManagerTest extends SmackTestCase { // Session 0 starts a request System.out.println("Starting session request, to " + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); + JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); session0.addListener(new JingleSessionListener() { public void sessionClosed(String reason, JingleSession jingleSession) { @@ -491,15 +512,13 @@ public class JingleManagerTest extends SmackTestCase { public void sessionDeclined(String reason, JingleSession jingleSession) { } - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { incCounter(); System.out.println("Initiator: the session is fully established."); System.out.println("+ Payload Type: " + pt.getId()); - System.out.println("+ Local IP/port: " + lc.getIp() + ":" - + lc.getPort()); - System.out.println("+ Remote IP/port: " + rc.getIp() + ":" - + rc.getPort()); + System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort()); + System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort()); } public void sessionRedirected(String redirection, JingleSession jingleSession) { @@ -509,14 +528,13 @@ public class JingleManagerTest extends SmackTestCase { // Do Nothing } }); - session0.start(null); + session0.startOutgoing(); Thread.sleep(20000); assertTrue(valCounter() == 2); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); fail("An error occured with Jingle"); } @@ -530,28 +548,37 @@ public class JingleManagerTest extends SmackTestCase { resetCounter(); try { - TransportResolver tr1 = new FixedResolver("127.0.0.1", 22222); - TransportResolver tr2 = new FixedResolver("127.0.0.1", 22444); + FixedResolver tr0 = new FixedResolver("127.0.0.1", 22222); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + TestMediaManager tmm0 = new TestMediaManager(ftm0); + tmm0.setPayloads(getTestPayloads1()); + List trl0 = new ArrayList(); + trl0.add(tmm0); - final JingleManager man0 = new JingleManager(getConnection(0), tr1); - final JingleManager man1 = new JingleManager(getConnection(1), tr2); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 22444); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + tmm1.setPayloads(getTestPayloads1()); + List trl1 = new ArrayList(); + trl1.add(tmm1); + JingleManager man0 = new JingleManager(getConnection(0), trl0); + JingleManager man1 = new JingleManager(getConnection(1), trl1); + man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { /** * Called when a new session request is detected */ public void sessionRequested(final JingleSessionRequest request) { - System.out.println("Session request detected, from " - + request.getFrom()); + System.out.println("Session request detected, from " + request.getFrom()); // We reject the request try { - IncomingJingleSession session = request.accept(getTestPayloads1()); - session.setInitialSessionRequest(request); - session.start(); + JingleSession session = request.accept(); + //session.setInitialSessionRequest(request); + session.startIncoming(); session.terminate(); - } - catch (XMPPException e) { + } catch (XMPPException e) { e.printStackTrace(); } @@ -560,11 +587,11 @@ public class JingleManagerTest extends SmackTestCase { // Session 0 starts a request System.out.println("Starting session request, to " + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); + JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); session0.addListener(new JingleSessionListener() { public void sessionClosed(String reason, JingleSession jingleSession) { + incCounter(); System.out.println("The session has been closed"); } @@ -572,14 +599,11 @@ public class JingleManagerTest extends SmackTestCase { } public void sessionDeclined(String reason, JingleSession jingleSession) { - incCounter(); - System.out - .println("The session has been detected as rejected with reason: " - + reason); + System.out.println("The session has been detected as rejected with reason: " + reason); } - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { } public void sessionMediaReceived(JingleSession jingleSession, String participant) { @@ -590,7 +614,7 @@ public class JingleManagerTest extends SmackTestCase { } }); - session0.start(); + session0.startOutgoing(); Thread.sleep(50000); @@ -600,8 +624,7 @@ public class JingleManagerTest extends SmackTestCase { assertTrue(valCounter() > 0); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); fail("An error occured with Jingle"); } @@ -616,8 +639,7 @@ public class JingleManagerTest extends SmackTestCase { try { - ProviderManager.getInstance().addIQProvider(RTPBridge.NAME, - RTPBridge.NAMESPACE, new RTPBridge.Provider()); + ProviderManager.getInstance().addIQProvider(RTPBridge.NAME, RTPBridge.NAMESPACE, new RTPBridge.Provider()); RTPBridge response = RTPBridge.getRTPBridge(getConnection(0), "102"); @@ -639,21 +661,18 @@ public class JingleManagerTest extends SmackTestCase { dataSocket.receive(packet); incCounter(); } - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } } try { - byte packet[] = {0, 0, 1, 1, 1, 1, 1}; + byte packet[] = { 0, 0, 1, 1, 1, 1, 1 }; DatagramSocket ds0 = new DatagramSocket(14004, InetAddress.getByName("0.0.0.0")); DatagramSocket ds1 = new DatagramSocket(14050, InetAddress.getByName("0.0.0.0")); - DatagramPacket echo0 = new DatagramPacket(packet, packet.length, - InetAddress.getLocalHost(), response.getPortA()); - DatagramPacket echo1 = new DatagramPacket(packet, packet.length, - InetAddress.getLocalHost(), response.getPortB()); + DatagramPacket echo0 = new DatagramPacket(packet, packet.length, InetAddress.getLocalHost(), response.getPortA()); + DatagramPacket echo1 = new DatagramPacket(packet, packet.length, InetAddress.getLocalHost(), response.getPortB()); ds1.send(echo1); ds0.send(echo0); @@ -683,13 +702,11 @@ public class JingleManagerTest extends SmackTestCase { ds0.close(); ds1.close(); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -701,37 +718,37 @@ public class JingleManagerTest extends SmackTestCase { public void testFullTest() { resetCounter(); - - XMPPConnection.DEBUG_ENABLED = true; - + XMPPConnection x0 = getConnection(0); XMPPConnection x1 = getConnection(1); - final JingleManager jm0 = new JingleManager( - x0, new FixedResolver("127.0.0.1", 20080)); + XMPPConnection.DEBUG_ENABLED = true; - final JingleManager jm1 = new JingleManager( - x1, new FixedResolver("127.0.0.1", 20040)); + FixedResolver tr0 = new FixedResolver("127.0.0.1", 20080); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + JmfMediaManager jmf0 = new JmfMediaManager(ftm0); + List trl0 = new ArrayList(); + trl0.add(jmf0); -// JingleManager jm0 = new JingleSessionManager( -// x0, new ICEResolver()); -// JingleManager jm1 = new JingleSessionManager( -// x1, new ICEResolver()); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 20040); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + JmfMediaManager jmf1 = new JmfMediaManager(ftm1); + List trl1 = new ArrayList(); + trl1.add(jmf1); - JingleMediaManager jingleMediaManager = new JmfMediaManager(); - - jm0.setMediaManager(jingleMediaManager); - jm1.setMediaManager(jingleMediaManager); - - jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { + JingleManager man0 = new JingleManager(x0, trl0); + JingleManager man1 = new JingleManager(x1, trl1); + + man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); + JingleSession session = request.accept(); session.addListener(new JingleSessionListener() { - public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { incCounter(); System.out.println("Establish In"); } @@ -755,9 +772,8 @@ public class JingleManagerTest extends SmackTestCase { } }); - session.start(); - } - catch (XMPPException e) { + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } @@ -767,11 +783,12 @@ public class JingleManagerTest extends SmackTestCase { for (int i = 0; i < 3; i++) try { - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = man0.createOutgoingJingleSession(x1.getUser()); js0.addListener(new JingleSessionListener() { - public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { incCounter(); System.out.println("Establish Out"); } @@ -795,15 +812,14 @@ public class JingleManagerTest extends SmackTestCase { } }); - js0.start(); + js0.startOutgoing(); Thread.sleep(8000); js0.terminate(); Thread.sleep(3000); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -817,26 +833,23 @@ public class JingleManagerTest extends SmackTestCase { public void testMediaManager() { resetCounter(); + + XMPPConnection x0 = getConnection(0); + XMPPConnection x1 = getConnection(1); + + FixedResolver tr0 = new FixedResolver("127.0.0.1", 20004); + FixedTransportManager ftm0 = new FixedTransportManager(tr0); + + FixedResolver tr1 = new FixedResolver("127.0.0.1", 20040); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); try { - - //XMPPConnection.DEBUG_ENABLED = true; - - XMPPConnection x0 = getConnection(0); - XMPPConnection x1 = getConnection(1); - - final JingleManager jm0 = new JingleManager( - x0, new FixedResolver("127.0.0.1", 20004)); - final JingleManager jm1 = new JingleManager( - x1, new FixedResolver("127.0.0.1", 20040)); - - //JingleManager jm0 = new ICETransportManager(x0, "stun.xten.net", 3478); - //JingleManager jm1 = new ICETransportManager(x1, "stun.xten.net", 3478); - - JingleMediaManager jingleMediaManager = new JingleMediaManager() { + + JingleMediaManager jingleMediaManager = new JingleMediaManager(ftm0) { // Media Session Implementation - public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) { - return new JingleMediaSession(payloadType, remote, local, null,null) { + public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, + final TransportCandidate local, final JingleSession jingleSession) { + return new JingleMediaSession(payloadType, remote, local, null, null) { public void initialize() { @@ -868,38 +881,42 @@ public class JingleManagerTest extends SmackTestCase { } public List getPayloads() { - return new ArrayList(); + return getTestPayloads1(); } public PayloadType.Audio getPreferredAudioPayloadType() { - return null; + return (PayloadType.Audio) getTestPayloads1().get(0); } - }; + + List trl0 = new ArrayList(); + trl0.add(jingleMediaManager); - jm0.setMediaManager(jingleMediaManager); - jm1.setMediaManager(jingleMediaManager); + List trl1 = new ArrayList(); + trl1.add(jingleMediaManager); + + JingleManager jm0 = new JingleManager(x0, trl0); + JingleManager jm1 = new JingleManager(x1, trl1); jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); + JingleSession session = request.accept(); - session.start(request); - } - catch (XMPPException e) { + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } } }); - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(10000); js0.terminate(); @@ -909,11 +926,10 @@ public class JingleManagerTest extends SmackTestCase { System.out.println(valCounter()); assertTrue(valCounter() == 8); - + Thread.sleep(15000); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -922,86 +938,93 @@ public class JingleManagerTest extends SmackTestCase { /** * This is a simple test where the user_2 rejects the Jingle session. */ - public void testIncompatibleCodecs() { - - resetCounter(); - - try { - TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222); - TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567); - - final JingleManager man0 = new JingleManager(getConnection(0), tr1); - final JingleManager man1 = new JingleManager(getConnection(1), tr2); - - man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { - /** - * Called when a new session request is detected - */ - public void sessionRequested - ( - final JingleSessionRequest request) { - System.out.println("Session request detected, from " - + request.getFrom() + ": accepting."); - - try { - // We reject the request - IncomingJingleSession ses = request.accept(getTestPayloads3()); - - ses.start(request); - } - catch (Exception e) { - e.printStackTrace(); - } - } - }); - - // Session 0 starts a request - System.out.println("Starting session request, to " + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); - - session0.addListener(new JingleSessionListener() { - public void sessionClosed(String reason, JingleSession jingleSession) { - } - - public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) { - incCounter(); - System.out - .println("The session has been close on error with reason: " - + e.getMessage()); - } - - public void sessionDeclined(String reason, JingleSession jingleSession) { - incCounter(); - System.out - .println("The session has been detected as rejected with reason: " - + reason); - } - - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { - } - - public void sessionMediaReceived(JingleSession jingleSession, String participant) { - // Do Nothing - } - - public void sessionRedirected(String redirection, JingleSession jingleSession) { - } - }); - - session0.start(null); - - Thread.sleep(20000); - - assertTrue(valCounter() > 0); - - } - catch (Exception e) { - e.printStackTrace(); - fail("An error occured with Jingle"); - } - } + +// This test doesn't make sense in light of multiple sections allowed in XEp-166. +// What we really need is a test for actions: content-add and content-remove. + + +// public void testIncompatibleCodecs() { +// +// resetCounter(); +// +// try { +// FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222); +// FixedTransportManager ftm0 = new FixedTransportManager(tr0); +// TestMediaManager tmm0 = new TestMediaManager(ftm0); +// tmm0.setPayloads(getTestPayloads1()); +// List trl0 = new ArrayList(); +// trl0.add(tmm0); +// +// FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567); +// FixedTransportManager ftm1 = new FixedTransportManager(tr1); +// TestMediaManager tmm1 = new TestMediaManager(ftm1); +// tmm1.setPayloads(getTestPayloads3()); +// List trl1 = new ArrayList(); +// trl1.add(tmm1); +// +// JingleManager man0 = new JingleManager(getConnection(0), trl0); +// JingleManager man1 = new JingleManager(getConnection(1), trl1); +// +// man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { +// /** +// * Called when a new session request is detected +// */ +// public void sessionRequested(final JingleSessionRequest request) { +// System.out.println("Session request detected, from " + request.getFrom() + ": accepting."); +// +// try { +// // We reject the request +// JingleSession ses = request.accept(); +// +// ses.startIncoming(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// }); +// +// // Session 0 starts a request +// System.out.println("Starting session request, to " + getFullJID(1) + "..."); +// JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); +// +// session0.addListener(new JingleSessionListener() { +// public void sessionClosed(String reason, JingleSession jingleSession) { +// incCounter(); +// } +// +// public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) { +// incCounter(); +// System.out.println("The session has been close on error with reason: " + e.getMessage()); +// } +// +// public void sessionDeclined(String reason, JingleSession jingleSession) { +// incCounter(); +// System.out.println("The session has been detected as rejected with reason: " + reason); +// } +// +// public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, +// JingleSession jingleSession) { +// } +// +// public void sessionMediaReceived(JingleSession jingleSession, String participant) { +// // Do Nothing +// } +// +// public void sessionRedirected(String redirection, JingleSession jingleSession) { +// } +// }); +// +// session0.startOutgoing(); +// +// Thread.sleep(20000); +// +// assertTrue(valCounter() > 0); +// +// } catch (Exception e) { +// e.printStackTrace(); +// fail("An error occured with Jingle"); +// } +// } protected int getMaxConnections() { return 2; diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java index 3ccd90614..5a288cb18 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java @@ -1,8 +1,8 @@ package org.jivesoftware.smackx.jingle; /** - * $RCSfile$ - * $Revision: $ + * $RCSfile: JingleMediaTest.java,v $ + * $Revision: 1.2 $ * $Date: 09/11/2006 *

* Copyright 2003-2006 Jive Software. @@ -23,15 +23,13 @@ package org.jivesoftware.smackx.jingle; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.test.SmackTestCase; -import org.jivesoftware.smackx.jingle.*; -import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager; +import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; +import org.jivesoftware.smackx.jingle.media.JingleMediaManager; import org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioChannel; +import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager; import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager; import org.jivesoftware.smackx.jingle.mediaimpl.multi.MultiMediaManager; import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager; -import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; -import org.jivesoftware.smackx.jingle.listeners.JingleSessionStateListener; -import org.jivesoftware.smackx.jingle.media.JingleMediaManager; import org.jivesoftware.smackx.jingle.nat.BridgedTransportManager; import org.jivesoftware.smackx.jingle.nat.ICETransportManager; import org.jivesoftware.smackx.jingle.nat.STUNTransportManager; @@ -40,6 +38,8 @@ import org.jivesoftware.smackx.packet.JingleError; import javax.media.MediaLocator; import javax.media.format.AudioFormat; import java.net.InetAddress; +import java.util.ArrayList; +import java.util.List; /** * Test the Jingle Media using the high level API @@ -64,40 +64,41 @@ public class JingleMediaTest extends SmackTestCase { ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478); ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478); - final JingleManager jm0 = new JingleManager( - x0, icetm0); - final JingleManager jm1 = new JingleManager( - x1, icetm1); + JingleMediaManager jingleMediaManager0 = new JmfMediaManager(icetm0); + JingleMediaManager jingleMediaManager1 = new JmfMediaManager(icetm1); + + List jml0 = new ArrayList(); + List jml1 = new ArrayList(); + + jml0.add(jingleMediaManager0); + jml1.add(jingleMediaManager1); + + final JingleManager jm0 = new JingleManager(x0, jml0); + final JingleManager jm1 = new JingleManager(x1, jml1); jm0.addCreationListener(icetm0); jm1.addCreationListener(icetm1); - JingleMediaManager jingleMediaManager0 = new JmfMediaManager(); - JingleMediaManager jingleMediaManager1 = new JmfMediaManager(); - - jm0.setMediaManager(jingleMediaManager0); - jm1.setMediaManager(jingleMediaManager1); - JingleSessionRequestListener jingleSessionRequestListener = new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); - session.start(request); + JingleSession session = request.accept(); + session.startIncoming(); - session.addStateListener(new JingleSessionStateListener() { - public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException { - if (newOne instanceof IncomingJingleSession.Active) { - throw new JingleNegotiator.JingleException(); - } - } + // session.addStateListener(new JingleSessionStateListener() { + // public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) + // throws JingleNegotiator.JingleException { + // if (newOne instanceof IncomingJingleSession.Active) { + // throw new JingleNegotiator.JingleException(); + // } + // } + // + // public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) { + // + // } + // }); - public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) { - - } - }); - - } - catch (XMPPException e) { + } catch (XMPPException e) { e.printStackTrace(); } @@ -106,14 +107,14 @@ public class JingleMediaTest extends SmackTestCase { jm1.addJingleSessionRequestListener(jingleSessionRequestListener); - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(20000); - IncomingJingleSession incomingJingleSession = (IncomingJingleSession) jm1.getSession(js0.getConnection().getUser()); - incomingJingleSession.removeAllStateListeners(); + JingleSession incomingJingleSession = jm1.getSession(js0.getConnection().getUser()); + //JingleSession.removeAllStateListeners(); Thread.sleep(15000); @@ -123,8 +124,7 @@ public class JingleMediaTest extends SmackTestCase { Thread.sleep(60000); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -140,47 +140,38 @@ public class JingleMediaTest extends SmackTestCase { ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478); ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478); - final JingleManager jm0 = new JingleManager( - x0, icetm0); - final JingleManager jm1 = new JingleManager( - x1, icetm1); + MultiMediaManager jingleMediaManager0 = new MultiMediaManager(icetm0); + jingleMediaManager0.addMediaManager(new JmfMediaManager(icetm0)); + jingleMediaManager0.addMediaManager(new SpeexMediaManager(icetm0)); + jingleMediaManager0.setPreferredPayloadType(jingleMediaManager0.getPayloads().get(1)); + List jml0 = new ArrayList(); + jml0.add(jingleMediaManager0); + + MultiMediaManager jingleMediaManager1 = new MultiMediaManager(icetm1); + jingleMediaManager1.addMediaManager(new JmfMediaManager(icetm1)); + jingleMediaManager1.addMediaManager(new SpeexMediaManager(icetm1)); + jingleMediaManager1.setPreferredPayloadType(jingleMediaManager1.getPayloads().get(2)); + List jml1 = new ArrayList(); + jml1.add(jingleMediaManager1); + + final JingleManager jm0 = new JingleManager(x0, jml0); + final JingleManager jm1 = new JingleManager(x1, jml1); jm0.addCreationListener(icetm0); jm1.addCreationListener(icetm1); -/* - final JingleManager jm0 = new JingleManager( - x0, new BasicTransportManager()); - final JingleManager jm1 = new JingleManager( - x1, new BasicTransportManager()); -*/ - - MultiMediaManager jingleMediaManager0 = new MultiMediaManager(); - jingleMediaManager0.addMediaManager(new JmfMediaManager()); - jingleMediaManager0.addMediaManager(new SpeexMediaManager()); - jingleMediaManager0.setPreferredPayloadType(jingleMediaManager0.getPayloads().get(1)); - MultiMediaManager jingleMediaManager1 = new MultiMediaManager(); - jingleMediaManager1.addMediaManager(new JmfMediaManager()); - jingleMediaManager1.addMediaManager(new SpeexMediaManager()); - jingleMediaManager1.setPreferredPayloadType(jingleMediaManager1.getPayloads().get(2)); - - jm0.setMediaManager(new JmfMediaManager()); - jm1.setMediaManager(new JmfMediaManager()); - jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); + JingleSession session = request.accept(); try { Thread.sleep(12000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } - session.start(request); - } - catch (XMPPException e) { + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } @@ -189,22 +180,23 @@ public class JingleMediaTest extends SmackTestCase { for (int i = 0; i < 10; i++) { - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.addStateListener(new JingleSessionStateListener() { + // js0.addStateListener(new JingleSessionStateListener() { + // + // public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) + // throws JingleNegotiator.JingleException { + // } + // + // public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) { + // if (newOne != null) { + // if ((newOne instanceof OutgoingJingleSession.Active)) + // System.err.println("|||" + newOne.getClass().getCanonicalName() + "|||"); + // } + // } + // }); - public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException { - } - - public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) { - if (newOne != null) { - if ((newOne instanceof OutgoingJingleSession.Active)) - System.err.println("|||" + newOne.getClass().getCanonicalName() + "|||"); - } - } - }); - - js0.start(); + js0.startOutgoing(); Thread.sleep(45000); js0.terminate(); @@ -213,8 +205,7 @@ public class JingleMediaTest extends SmackTestCase { } - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -229,36 +220,36 @@ public class JingleMediaTest extends SmackTestCase { XMPPConnection x0 = getConnection(0); XMPPConnection x1 = getConnection(1); - final JingleManager jm0 = new JingleManager( - x0, new STUNTransportManager()); - final JingleManager jm1 = new JingleManager( - x1, new STUNTransportManager()); + JingleMediaManager jingleMediaManager0 = new SpeexMediaManager(new STUNTransportManager()); + JingleMediaManager jingleMediaManager1 = new SpeexMediaManager(new STUNTransportManager()); - JingleMediaManager jingleMediaManager0 = new SpeexMediaManager(); - JingleMediaManager jingleMediaManager1 = new SpeexMediaManager(); + List jml0 = new ArrayList(); + List jml1 = new ArrayList(); - jm0.setMediaManager(jingleMediaManager0); - jm1.setMediaManager(jingleMediaManager1); + jml0.add(jingleMediaManager0); + jml1.add(jingleMediaManager1); + + final JingleManager jm0 = new JingleManager(x0, jml0); + final JingleManager jm1 = new JingleManager(x1, jml1); jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); + JingleSession session = request.accept(); - session.start(request); - } - catch (XMPPException e) { + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } } }); - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(150000); js0.terminate(); @@ -268,50 +259,52 @@ public class JingleMediaTest extends SmackTestCase { x0.disconnect(); x1.disconnect(); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - public void testCompleteScreenShare() { + public void testCompleteScreenShare() { try { XMPPConnection x0 = getConnection(0); XMPPConnection x1 = getConnection(1); - final JingleManager jm0 = new JingleManager( - x0, new ICETransportManager(x0,"stun.xten.net",3478)); - final JingleManager jm1 = new JingleManager( - x1, new ICETransportManager(x1,"stun.xten.net",3478)); + ICETransportManager icetm0 = new ICETransportManager(x0, "stun.xten.net", 3478); + ICETransportManager icetm1 = new ICETransportManager(x1, "stun.xten.net", 3478); - JingleMediaManager jingleMediaManager0 = new ScreenShareMediaManager(); - JingleMediaManager jingleMediaManager1 = new ScreenShareMediaManager(); + JingleMediaManager jingleMediaManager0 = new ScreenShareMediaManager(icetm0); + JingleMediaManager jingleMediaManager1 = new ScreenShareMediaManager(icetm1); - jm0.setMediaManager(jingleMediaManager0); - jm1.setMediaManager(jingleMediaManager1); + List jml0 = new ArrayList(); + List jml1 = new ArrayList(); + jml0.add(jingleMediaManager0); + jml1.add(jingleMediaManager1); + + final JingleManager jm0 = new JingleManager(x0, jml0); + final JingleManager jm1 = new JingleManager(x1, jml1); + jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); - session.start(request); - } - catch (XMPPException e) { + JingleSession session = request.accept(); + + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } } }); - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(150000); js0.terminate(); @@ -321,8 +314,7 @@ public class JingleMediaTest extends SmackTestCase { x0.disconnect(); x1.disconnect(); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -338,44 +330,49 @@ public class JingleMediaTest extends SmackTestCase { XMPPConnection x0 = getConnection(n); XMPPConnection x1 = getConnection(n + 1); - + BridgedTransportManager btm0 = new BridgedTransportManager(x0); BridgedTransportManager btm1 = new BridgedTransportManager(x1); - final JingleManager jm0 = new JingleManager(x0, btm0); - final JingleManager jm1 = new JingleManager(x1, btm1); + + JingleMediaManager jingleMediaManager0 = new JmfMediaManager(btm0); + JingleMediaManager jingleMediaManager1 = new JmfMediaManager(btm1); + + List jml0 = new ArrayList(); + List jml1 = new ArrayList(); + + jml0.add(jingleMediaManager0); + jml1.add(jingleMediaManager1); + + final JingleManager jm0 = new JingleManager(x0, jml0); + final JingleManager jm1 = new JingleManager(x1, jml1); jm0.addCreationListener(btm0); jm1.addCreationListener(btm1); - - JingleMediaManager jingleMediaManager = new JmfMediaManager(); - JingleMediaManager jingleMediaManager2 = new JmfMediaManager(); - - jm0.setMediaManager(jingleMediaManager); - jm1.setMediaManager(jingleMediaManager2); - + jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); + JingleSession session = request.accept(); - session.start(request); - } - catch (XMPPException e) { + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } } }); - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(20000); - js0.sendFormattedError(JingleError.UNSUPPORTED_TRANSPORTS); + //js0.sendFormattedError(JingleError.UNSUPPORTED_TRANSPORTS); + js0.sendPacket(js0.createJingleError(null, JingleError.UNSUPPORTED_TRANSPORTS)); + Thread.sleep(20000); @@ -386,8 +383,7 @@ public class JingleMediaTest extends SmackTestCase { x0.disconnect(); x1.disconnect(); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -398,8 +394,7 @@ public class JingleMediaTest extends SmackTestCase { try { Thread.sleep(250000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } } @@ -415,36 +410,37 @@ public class JingleMediaTest extends SmackTestCase { BridgedTransportManager btm0 = new BridgedTransportManager(x0); BridgedTransportManager btm1 = new BridgedTransportManager(x1); - final JingleManager jm0 = new JingleManager(x0, btm0); - final JingleManager jm1 = new JingleManager(x1, btm1); - jm0.addCreationListener(btm0); - jm1.addCreationListener(btm1); + JingleMediaManager jingleMediaManager0 = new JmfMediaManager(btm0); + JingleMediaManager jingleMediaManager1 = new JmfMediaManager(btm1); - JingleMediaManager jingleMediaManager = new JmfMediaManager(); + List jml0 = new ArrayList(); + List jml1 = new ArrayList(); - jm0.setMediaManager(jingleMediaManager); - jm1.setMediaManager(jingleMediaManager); + jml0.add(jingleMediaManager0); + jml1.add(jingleMediaManager1); + + final JingleManager jm0 = new JingleManager(x0, jml0); + final JingleManager jm1 = new JingleManager(x1, jml1); jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { try { - IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); - - session.start(request); - } - catch (XMPPException e) { + JingleSession session = request.accept(); + + session.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } } }); - OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); + JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(20000); @@ -454,7 +450,7 @@ public class JingleMediaTest extends SmackTestCase { js0 = jm0.createOutgoingJingleSession(x1.getUser()); - js0.start(); + js0.startOutgoing(); Thread.sleep(20000); @@ -465,8 +461,7 @@ public class JingleMediaTest extends SmackTestCase { x0.disconnect(); x1.disconnect(); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } @@ -475,16 +470,19 @@ public class JingleMediaTest extends SmackTestCase { public void testAudioChannelOpenClose() { for (int i = 0; i < 5; i++) { try { - AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null); - AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null); + AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost() + .getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat( + AudioFormat.GSM_RTP), null); + AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost() + .getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat( + AudioFormat.GSM_RTP), null); audioChannel0.start(); audioChannel1.start(); try { Thread.sleep(10000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } @@ -493,12 +491,10 @@ public class JingleMediaTest extends SmackTestCase { try { Thread.sleep(3000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } @@ -507,8 +503,12 @@ public class JingleMediaTest extends SmackTestCase { public void testAudioChannelStartStop() { try { - AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null); - AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null); + AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost() + .getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, + new AudioFormat(AudioFormat.GSM_RTP), null); + AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost() + .getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, + new AudioFormat(AudioFormat.GSM_RTP), null); for (int i = 0; i < 5; i++) { @@ -517,8 +517,7 @@ public class JingleMediaTest extends SmackTestCase { try { Thread.sleep(10000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } @@ -527,13 +526,11 @@ public class JingleMediaTest extends SmackTestCase { try { Thread.sleep(3000); - } - catch (InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } } - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSessionTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSessionTest.java index b4830ed25..1a1d9b7f0 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSessionTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSessionTest.java @@ -1,8 +1,13 @@ package org.jivesoftware.smackx.jingle; import org.jivesoftware.smack.test.SmackTestCase; -import org.jivesoftware.smackx.jingle.nat.BasicResolver; -import org.jivesoftware.smackx.jingle.nat.BasicTransportManager; +import org.jivesoftware.smackx.jingle.media.JingleMediaManager; +import org.jivesoftware.smackx.jingle.mediaimpl.test.TestMediaManager; +import org.jivesoftware.smackx.jingle.nat.FixedResolver; +import org.jivesoftware.smackx.jingle.nat.FixedTransportManager; + +import java.util.ArrayList; +import java.util.List; public class JingleSessionTest extends SmackTestCase { @@ -11,9 +16,16 @@ public class JingleSessionTest extends SmackTestCase { } public void testEqualsObject() { - JingleSession js1 = new OutgoingJingleSession(getConnection(0), "res1", null, new BasicTransportManager()); - JingleSession js2 = new OutgoingJingleSession(getConnection(1), "res1", null, new BasicTransportManager()); - JingleSession js3 = new OutgoingJingleSession(getConnection(2), "res2", null, new BasicTransportManager()); + + FixedResolver tr1 = new FixedResolver("127.0.0.1", 54222); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + List trl1 = new ArrayList(); + trl1.add(tmm1); + + JingleSession js1 = new JingleSession(getConnection(0), "res1", null, "10", trl1); + JingleSession js2 = new JingleSession(getConnection(1), "res1", null, "10", trl1); + JingleSession js3 = new JingleSession(getConnection(2), "res2", null, "11", trl1); System.out.println(js1.getSid()); System.out.println(js2.getSid()); @@ -35,8 +47,14 @@ public class JingleSessionTest extends SmackTestCase { String ini2 = "initiator2"; String sid2 = "sid2"; - JingleSession js1 = new OutgoingJingleSession(getConnection(0), sid1, null, new BasicTransportManager()); - JingleSession js2 = new OutgoingJingleSession(getConnection(1), sid2, null, new BasicTransportManager()); + FixedResolver tr1 = new FixedResolver("127.0.0.1", 54222); + FixedTransportManager ftm1 = new FixedTransportManager(tr1); + TestMediaManager tmm1 = new TestMediaManager(ftm1); + List trl1 = new ArrayList(); + trl1.add(tmm1); + + JingleSession js1 = new JingleSession(getConnection(0), ini1, null, sid1, trl1); + JingleSession js2 = new JingleSession(getConnection(1), ini2, null, sid2, trl1); // For a packet, we should be able to get a session that handles that... assertNotNull(JingleSession.getInstanceFor(getConnection(0))); diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSupportTests.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSupportTests.java index 03f8e68af..c7fed6c05 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSupportTests.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleSupportTests.java @@ -1,7 +1,7 @@ /** - * $RCSfile$ - * $Revision$ - * $Date$ + * $RCSfile: JingleSupportTests.java,v $ + * $Revision: 1.1 $ + * $Date: 2007/07/02 17:41:06 $ * * Copyright (C) 2002-2006 Jive Software. All rights reserved. * ==================================================================== diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/BridgedResolverTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/BridgedResolverTest.java index 89e5d810e..b81f17c17 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/BridgedResolverTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/BridgedResolverTest.java @@ -1,16 +1,6 @@ package org.jivesoftware.smackx.jingle.nat; -import org.jivesoftware.smack.XMPPConnection; -import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.test.SmackTestCase; -import org.jivesoftware.smackx.jingle.IncomingJingleSession; -import org.jivesoftware.smackx.jingle.JingleManager; -import org.jivesoftware.smackx.jingle.JingleSessionRequest; -import org.jivesoftware.smackx.jingle.OutgoingJingleSession; -import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; -import org.jivesoftware.smackx.jingle.media.JingleMediaManager; -import org.jivesoftware.smackx.jingle.media.JingleMediaSession; -import org.jivesoftware.smackx.jingle.media.PayloadType; import java.net.InetAddress; import java.net.UnknownHostException; diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java index 4588921e9..72f95b03c 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java @@ -5,15 +5,18 @@ import de.javawi.jstun.test.demo.ice.ICENegociator; import de.javawi.jstun.util.UtilityException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.test.SmackTestCase; -import org.jivesoftware.smackx.jingle.*; +import org.jivesoftware.smackx.jingle.JingleManager; +import org.jivesoftware.smackx.jingle.JingleSession; +import org.jivesoftware.smackx.jingle.JingleSessionRequest; import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener; import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; +import org.jivesoftware.smackx.jingle.media.JingleMediaManager; import org.jivesoftware.smackx.jingle.media.PayloadType; +import org.jivesoftware.smackx.jingle.mediaimpl.test.TestMediaManager; import java.net.UnknownHostException; -import java.net.SocketException; -import java.net.InetAddress; import java.util.ArrayList; +import java.util.List; /** * Test the STUN IP resolver. @@ -60,16 +63,14 @@ public class STUNResolverTest extends SmackTestCase { public void testGetPreferredCandidate() throws Exception { int highestPref = 100; - TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, - "password", 3468, "username1", 1, ICECandidate.Type.prflx); - TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, - "password", 3469, "username2", 15, ICECandidate.Type.prflx); - TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, - "password", 3468, "usernameH", highestPref, ICECandidate.Type.prflx); - TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, - "password", 3469, "username3", 2, ICECandidate.Type.prflx); - TransportCandidate cand4 = new ICECandidate("192.168.4.1", 3, 2, - "password", 3468, "username4", 78, ICECandidate.Type.prflx); + TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, "password", 3468, "username1", 1, ICECandidate.Type.prflx); + TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, "password", 3469, "username2", 15, + ICECandidate.Type.prflx); + TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, "password", 3468, "usernameH", highestPref, + ICECandidate.Type.prflx); + TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, "password", 3469, "username3", 2, + ICECandidate.Type.prflx); + TransportCandidate cand4 = new ICECandidate("192.168.4.1", 3, 2, "password", 3468, "username4", 78, ICECandidate.Type.prflx); STUNResolver stunResolver = new STUNResolver() { }; @@ -90,16 +91,14 @@ public class STUNResolverTest extends SmackTestCase { public void testGetPreferredCandidateICE() throws Exception { int highestPref = 100; - TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, - "password", 3468, "username1", 1, ICECandidate.Type.prflx); - TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, - "password", 3469, "username2", 15, ICECandidate.Type.prflx); - TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, - "password", 3468, "usernameH", highestPref, ICECandidate.Type.prflx); - TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, - "password", 3469, "username3", 2, ICECandidate.Type.prflx); - TransportCandidate cand4 = new ICECandidate("192.168.4.1", 3, 2, - "password", 3468, "username4", 78, ICECandidate.Type.prflx); + TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, "password", 3468, "username1", 1, ICECandidate.Type.prflx); + TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, "password", 3469, "username2", 15, + ICECandidate.Type.prflx); + TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, "password", 3468, "usernameH", highestPref, + ICECandidate.Type.prflx); + TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, "password", 3469, "username3", 2, + ICECandidate.Type.prflx); + TransportCandidate cand4 = new ICECandidate("192.168.4.1", 3, 2, "password", 3468, "username4", 78, ICECandidate.Type.prflx); ICEResolver iceResolver = new ICEResolver(getConnection(0), "stun.xten.net", 3478) { }; @@ -132,18 +131,20 @@ public class STUNResolverTest extends SmackTestCase { for (Candidate candidate : cc.getSortedCandidates()) try { - TransportCandidate transportCandidate = new ICECandidate(candidate.getAddress().getInetAddress().getHostAddress(), 1, candidate.getNetwork(), "1", candidate.getPort(), "1", candidate.getPriority(), ICECandidate.Type.prflx); + TransportCandidate transportCandidate = new ICECandidate(candidate.getAddress().getInetAddress() + .getHostAddress(), 1, candidate.getNetwork(), "1", candidate.getPort(), "1", candidate.getPriority(), + ICECandidate.Type.prflx); transportCandidate.setLocalIp(candidate.getBase().getAddress().getInetAddress().getHostAddress()); - System.out.println("C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority()); - } - catch (UtilityException e) { + System.out.println("C: " + candidate.getAddress().getInetAddress() + "|" + + candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority()); + } catch (UtilityException e) { e.printStackTrace(); - } - catch (UnknownHostException e) { + } catch (UnknownHostException e) { e.printStackTrace(); } Candidate candidate = cc.getSortedCandidates().get(0); - String temp = "C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority(); + String temp = "C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress() + + " p:" + candidate.getPriority(); if (first.equals("")) first = temp; assertEquals(first, temp); @@ -211,13 +212,11 @@ public class STUNResolverTest extends SmackTestCase { stunResolver.initializeAndWait(); Thread.sleep(55000); assertTrue(valCounter() > 0); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); } } - /** * Generate a list of payload types * @@ -262,21 +261,32 @@ public class STUNResolverTest extends SmackTestCase { tr1.resolve(null); tr2.resolve(null); - final JingleManager man0 = new JingleManager(getConnection(0), tr1); - final JingleManager man1 = new JingleManager(getConnection(1), tr2); + STUNTransportManager stm0 = new STUNTransportManager(); + TestMediaManager tmm0 = new TestMediaManager(stm0); + tmm0.setPayloads(getTestPayloads1()); + List trl0 = new ArrayList(); + trl0.add(tmm0); + + STUNTransportManager stm1 = new STUNTransportManager(); + TestMediaManager tmm1 = new TestMediaManager(stm1); + tmm1.setPayloads(getTestPayloads2()); + List trl1 = new ArrayList(); + trl1.add(tmm1); + + final JingleManager man0 = new JingleManager(getConnection(0), trl0); + final JingleManager man1 = new JingleManager(getConnection(1), trl1); man1.addJingleSessionRequestListener(new JingleSessionRequestListener() { /** * Called when a new session request is detected */ public void sessionRequested(final JingleSessionRequest request) { - System.out.println("Session request detected, from " - + request.getFrom() + ": accepting."); + System.out.println("Session request detected, from " + request.getFrom() + ": accepting."); // We accept the request - IncomingJingleSession session1; + JingleSession session1; try { - session1 = request.accept(getTestPayloads2()); + session1 = request.accept(); session1.addListener(new JingleSessionListener() { public void sessionClosed(String reason, JingleSession jingleSession) { } @@ -287,16 +297,13 @@ public class STUNResolverTest extends SmackTestCase { public void sessionDeclined(String reason, JingleSession jingleSession) { } - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { incCounter(); - System.out - .println("Responder: the session is fully established."); + System.out.println("Responder: the session is fully established."); System.out.println("+ Payload Type: " + pt.getId()); - System.out.println("+ Local IP/port: " + lc.getIp() + ":" - + lc.getPort()); - System.out.println("+ Remote IP/port: " + rc.getIp() + ":" - + rc.getPort()); + System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort()); + System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort()); } public void sessionRedirected(String redirection, JingleSession jingleSession) { @@ -306,9 +313,8 @@ public class STUNResolverTest extends SmackTestCase { // Do Nothing } }); - session1.start(request); - } - catch (XMPPException e) { + session1.startIncoming(); + } catch (XMPPException e) { e.printStackTrace(); } } @@ -316,8 +322,7 @@ public class STUNResolverTest extends SmackTestCase { // Session 0 starts a request System.out.println("Starting session request, to " + getFullJID(1) + "..."); - OutgoingJingleSession session0 = man0.createOutgoingJingleSession( - getFullJID(1), getTestPayloads1()); + JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1)); session0.addListener(new JingleSessionListener() { public void sessionClosed(String reason, JingleSession jingleSession) { @@ -329,15 +334,13 @@ public class STUNResolverTest extends SmackTestCase { public void sessionDeclined(String reason, JingleSession jingleSession) { } - public void sessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) { + public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc, + JingleSession jingleSession) { incCounter(); System.out.println("Initiator: the session is fully established."); System.out.println("+ Payload Type: " + pt.getId()); - System.out.println("+ Local IP/port: " + lc.getIp() + ":" - + lc.getPort()); - System.out.println("+ Remote IP/port: " + rc.getIp() + ":" - + rc.getPort()); + System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort()); + System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort()); } public void sessionMediaReceived(JingleSession jingleSession, String participant) { @@ -347,14 +350,13 @@ public class STUNResolverTest extends SmackTestCase { public void sessionRedirected(String redirection, JingleSession jingleSession) { } }); - session0.start(null); + session0.startOutgoing(); Thread.sleep(60000); assertTrue(valCounter() == 2); - } - catch (Exception e) { + } catch (Exception e) { e.printStackTrace(); fail("An error occured with Jingle"); }