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
This commit is contained in:
Gaston Dombiak 2008-05-19 22:54:19 +00:00 committed by gato
parent c795fd7423
commit 51fb81926e
66 changed files with 2440 additions and 3778 deletions

View File

@ -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.
* <p/>
* 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;
}
}

View File

@ -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<JingleMediaManager> 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<JingleMediaManager> 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.
* <p/>
@ -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<JingleMediaManager> 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<JingleMediaManager> 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<PayloadType> 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<PayloadType> 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();
}
}
}
}

View File

@ -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;
* </p>
*
* @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<JingleListener> listeners = new ArrayList<JingleListener>();
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<JingleListener> getListenersList() {
ArrayList<JingleListener> result;
synchronized (listeners) {
result = new ArrayList(listeners);
result = new ArrayList<JingleListener>(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
*
* <jingle>
* <content>
* <description>
* <transport>
* <content>
* <description>
* <transport>
*
* 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<IQ> dispatchIncomingPacket(IQ iq, String id) throws XMPPException;
/**
* Close the negotiation.
*/
public void close() {
setState(null);
}
/**
* A Jingle exception.
*
* @author Alvaro Saurin <alvaro.saurin@gmail.com>
*/
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.
* <p/>
* </p>
* <p/>
* 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);
}
}
}
}

View File

@ -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.
* <p/>
@ -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 <b><i>IncomingJingleSession</b></i> on which the
* negotiation can be carried out.
*/
public synchronized IncomingJingleSession accept(List<PayloadType> 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<PayloadType> 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 <b><i>IncomingJingleSession</b></i> 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;
}

View File

@ -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.
* <p/>
* 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 <alvaro.saurin@gmail.com>
* @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.
* <p/>
* 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;
}
}

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: CreatedJingleSessionListener.java,v $
* $Revision: 1.1 $
* $Date: 17/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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);
}

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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 <content> element of the Jingle packet.
public String getName() {
return MEDIA_NAME;
}
}
}

View File

@ -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.

View File

@ -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.
* <p/>
* <p/>
* 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. <p/> <p/> 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<PayloadType> remoteAudioPts = new ArrayList<PayloadType>();
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<PayloadType> pts) {
super(js.getConnection());
public MediaNegotiator(JingleSession session, JingleMediaManager mediaManager, List<PayloadType> 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<IQ> dispatchIncomingPacket(IQ iq, String id) throws XMPPException {
List<IQ> responses = new ArrayList<IQ>();
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<PayloadType> offeredPayloads = new ArrayList<PayloadType>();
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<PayloadType> offeredPayloads = new ArrayList<PayloadType>();
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<PayloadType> 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<PayloadType> commonAudioPtsHere = new ArrayList<PayloadType>();
final ArrayList<PayloadType> commonAudioPtsThere = new ArrayList<PayloadType>();
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<JingleListener> 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<JingleListener> 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;
}
}

View File

@ -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.
*

View File

@ -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.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: Demo.java,v $
* $Revision: 1.3 $
* $Date: 28/12/2006
* <p/>
* 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<JingleMediaManager> mediaManagers = new ArrayList<JingleMediaManager>();
//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();

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: AudioChannel.java,v $
* $Revision: 1.1 $
* $Date: 08/11/2006
* <p/>
* 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.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: AudioFormatUtils.java,v $
* $Revision: 1.1 $
* $Date: 08/11/2006
* <p/>
* Copyright 2003-2006 Jive Software.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: AudioMediaSession.java,v $
* $Revision: 1.1 $
* $Date: 08/11/2006
* <p/>
* 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;

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: AudioReceiver.java,v $
* $Revision: 1.1 $
* $Date: 08/11/2006
* <p/>
* Copyright 2003-2006 Jive Software.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: JmfMediaManager.java,v $
* $Revision: 1.3 $
* $Date: 08/11/2006
* <p/>
* 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<PayloadType> payloads = new ArrayList<PayloadType>();
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;
}
}

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: AudioMediaSession.java,v $
* $Revision: 1.1 $
* $Date: 25/12/2006
* <p/>
* 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;

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: SpeexMediaManager.java,v $
* $Revision: 1.3 $
* $Date: 25/12/2006
* <p/>
* 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<PayloadType> payloads = new ArrayList<PayloadType>();
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;
}
}

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: MultiMediaManager.java,v $
* $Revision: 1.3 $
* $Date: 25/12/2006
* <p/>
* 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<JingleMediaManager> managers = new ArrayList<JingleMediaManager>();
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;
}
}

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: ScreenShareMediaManager.java,v $
* $Revision: 1.3 $
* $Date: 25/12/2006
* <p/>
* 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<PayloadType> payloads = new ArrayList<PayloadType>();
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;
}
}

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: ScreenShareSession.java,v $
* $Revision: 1.2 $
* $Date: 08/11/2006
* <p/>
* 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;

View File

@ -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.
*

View File

@ -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.

View File

@ -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.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: BridgedTransportManager.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: DatagramListener.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: FixedResolver.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -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

View File

@ -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) {

View File

@ -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.
*

View File

@ -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
* <p/>
* Copyright 2003-2006 Jive Software.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: JingleTransportManager.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -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.

View File

@ -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.
*

View File

@ -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()));

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: STUNResolver.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: STUNTransportManager.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -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.

View File

@ -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.
* ====================================================================

View File

@ -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.

View File

@ -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<TransportCandidate> getOfferedCandidates() {
return offeredCandidates;
}
@ -187,7 +197,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
*
* @return the remoteCandidates
*/
private List getRemoteCandidates() {
private List<TransportCandidate> 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<TransportCandidate> obtainCandidatesList(Jingle jingle) {
List<TransportCandidate> result = new ArrayList<TransportCandidate>();
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<TransportCandidate> 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<IQ> dispatchIncomingPacket(IQ iq, String id) throws XMPPException {
List<IQ> responses = new ArrayList<IQ>();
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<TransportCandidate> 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<JingleListener> 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<JingleListener> 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<TransportCandidate>) 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);
}
/**

View File

@ -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<TransportCandidate> getCandidatesList() {
ArrayList result = null;
List<TransportCandidate> result = null;
synchronized (candidates) {
result = new ArrayList(candidates);
result = new ArrayList<TransportCandidate>(candidates);
}
return result;

View File

@ -1,6 +1,6 @@
/**
* $RCSfile$
* $Revision: $
* $RCSfile: TransportResolverListener.java,v $
* $Revision: 1.1 $
* $Date: 15/11/2006
*
* Copyright 2003-2006 Jive Software.

View File

@ -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<JingleContent> contents = new ArrayList<JingleContent>();
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<JingleContent> 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<JingleContent> 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<JingleContent> getContentsList() {
synchronized (contents) {
return new ArrayList<JingleContent>(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<JingleContent> 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("<content name='Audio-Content'>");
// 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("</content>");
}
// and the same for audio jmf info
if (contentInfo != null) {
@ -462,43 +376,4 @@ public class Jingle extends IQ {
buf.append("</").append(getElementName()).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;
}
}
}

View File

@ -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);

View File

@ -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 {

View File

@ -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<JingleTransportCandidate> candidates = new ArrayList<JingleTransportCandidate>();
/**
* Default constructor.
@ -104,10 +104,10 @@ public class JingleTransport implements PacketExtension {
*
* @return The candidates list.
*/
public ArrayList getCandidatesList() {
ArrayList res = null;
public List<JingleTransportCandidate> getCandidatesList() {
ArrayList<JingleTransportCandidate> res = null;
synchronized (candidates) {
res = new ArrayList(candidates);
res = new ArrayList<JingleTransportCandidate>(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<JingleTransportCandidate> getCandidatesList() {
List<JingleTransportCandidate> copy = new ArrayList<JingleTransportCandidate>();
List<JingleTransportCandidate> 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<JingleTransportCandidate> getCandidatesList() {
List<JingleTransportCandidate> copy = new ArrayList<JingleTransportCandidate>();
List<JingleTransportCandidate> superCandidatesList = super.getCandidatesList();
if (superCandidatesList.size() > 0) {
copy.add(superCandidatesList.get(0));
}

View File

@ -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 {

View File

@ -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 <jingle> 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 <content> 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 <description> element of the <content>
currentContent.setDescription((JingleDescription) jdpAudio.parseExtension(parser));
} else if (elementName.equals(JingleTransport.NODENAME)) {
// Add all of the <transport> elements to the <content> 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) {

View File

@ -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;

View File

@ -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<PayloadType> getTestPayloads1() {
List<PayloadType> result = new ArrayList<PayloadType>();
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<PayloadType> getTestPayloads2() {
List<PayloadType> result = new ArrayList<PayloadType>();
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<PayloadType> getTestPayloads3() {
List<PayloadType> result = new ArrayList<PayloadType>();
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(
" <jingle xmlns='http://jabber.org/protocol/jingle'"
+ " initiator=\"user1@thiago\""
+ " responder=\"user0@thiago\""
+ " action=\"session-initiate\" sid=\"08666555\">"
+ "</jingle>");
IQfake iqSent = new IQfake(" <jingle xmlns='http://jabber.org/protocol/jingle'" + " initiator=\"user1@thiago\""
+ " responder=\"user0@thiago\"" + " action=\"session-initiate\" sid=\"08666555\">" + "</jingle>");
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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<PayloadType> getPayloads() {
return new ArrayList();
return getTestPayloads1();
}
public PayloadType.Audio getPreferredAudioPayloadType() {
return null;
return (PayloadType.Audio) getTestPayloads1().get(0);
}
};
List<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
trl0.add(jingleMediaManager);
jm0.setMediaManager(jingleMediaManager);
jm1.setMediaManager(jingleMediaManager);
List<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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 <content> 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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
// 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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
// 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;

View File

@ -1,8 +1,8 @@
package org.jivesoftware.smackx.jingle;
/**
* $RCSfile$
* $Revision: $
* $RCSfile: JingleMediaTest.java,v $
* $Revision: 1.2 $
* $Date: 09/11/2006
* <p/>
* 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<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
List<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
List<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
List<JingleMediaManager> jml1 = new ArrayList<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(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<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
List<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
List<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
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();
}
}

View File

@ -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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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)));

View File

@ -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.
* ====================================================================

View File

@ -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;

View File

@ -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<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
trl0.add(tmm0);
STUNTransportManager stm1 = new STUNTransportManager();
TestMediaManager tmm1 = new TestMediaManager(stm1);
tmm1.setPayloads(getTestPayloads2());
List<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
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");
}