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:
parent
c795fd7423
commit
51fb81926e
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleManager.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.4 $
|
||||||
* $Date$
|
* $Date: 2007/07/17 22:13:16 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* 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.IQ;
|
||||||
import org.jivesoftware.smack.packet.Packet;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
|
||||||
import org.jivesoftware.smack.provider.ProviderManager;
|
import org.jivesoftware.smack.provider.ProviderManager;
|
||||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.CreatedJingleSessionListener;
|
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.listeners.JingleSessionRequestListener;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
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.TransportCandidate;
|
||||||
import org.jivesoftware.smackx.jingle.nat.TransportResolver;
|
import org.jivesoftware.smackx.jingle.nat.TransportResolver;
|
||||||
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
import org.jivesoftware.smackx.packet.Jingle;
|
import org.jivesoftware.smackx.packet.Jingle;
|
||||||
import org.jivesoftware.smackx.packet.JingleError;
|
import org.jivesoftware.smackx.provider.JingleProvider;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -174,13 +169,13 @@ import java.util.List;
|
||||||
*
|
*
|
||||||
* @author Thiago Camargo
|
* @author Thiago Camargo
|
||||||
* @author Alvaro Saurin
|
* @author Alvaro Saurin
|
||||||
|
* @author Jeff Williams
|
||||||
* @see JingleListener
|
* @see JingleListener
|
||||||
* @see TransportResolver
|
* @see TransportResolver
|
||||||
* @see org.jivesoftware.smackx.jingle.nat.JingleTransportManager
|
* @see JingleSession
|
||||||
* @see OutgoingJingleSession
|
* @see JingleSession
|
||||||
* @see IncomingJingleSession
|
|
||||||
* @see JingleMediaManager
|
* @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 {
|
public class JingleManager implements JingleSessionListener {
|
||||||
|
|
||||||
|
@ -197,40 +192,12 @@ public class JingleManager implements JingleSessionListener {
|
||||||
// The XMPP connection
|
// The XMPP connection
|
||||||
private XMPPConnection connection;
|
private XMPPConnection connection;
|
||||||
|
|
||||||
// The Media Manager
|
// The Media Managers
|
||||||
private JingleMediaManager jingleMediaManager;
|
private List<JingleMediaManager> jingleMediaManagers;
|
||||||
|
|
||||||
// The Jingle transport manager
|
|
||||||
private final JingleTransportManager jingleTransportManager;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
||||||
ProviderManager providerManager = ProviderManager.getInstance();
|
ProviderManager providerManager = ProviderManager.getInstance();
|
||||||
|
providerManager.addIQProvider("jingle", "http://www.xmpp.org/extensions/xep-0166.html#ns", new JingleProvider());
|
||||||
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());
|
|
||||||
|
|
||||||
// Enable the Jingle support on every established connection
|
// Enable the Jingle support on every established connection
|
||||||
// The ServiceDiscoveryManager class should have been already
|
// 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
|
* If a fully implemented JingleMediaSession is entered, JingleManager manage Jingle signalling and jmf
|
||||||
*
|
*
|
||||||
* @param connection XMPP Connection to be used
|
* @param connection XMPP Connection to be used
|
||||||
* @param jingleTransportManager transport resolver to be used
|
|
||||||
* @param jingleMediaManager an implemeted JingleMediaManager 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.connection = connection;
|
||||||
this.jingleTransportManager = jingleTransportManager;
|
this.jingleMediaManagers = jingleMediaManagers;
|
||||||
this.jingleMediaManager = jingleMediaManager;
|
|
||||||
|
|
||||||
connection.getRoster().addRosterListener(new RosterListener() {
|
connection.getRoster().addRosterListener(new RosterListener() {
|
||||||
|
|
||||||
|
@ -271,16 +236,14 @@ public class JingleManager implements JingleSessionListener {
|
||||||
String xmppAddress = presence.getFrom();
|
String xmppAddress = presence.getFrom();
|
||||||
JingleSession aux = null;
|
JingleSession aux = null;
|
||||||
for (JingleSession jingleSession : jingleSessions) {
|
for (JingleSession jingleSession : jingleSessions) {
|
||||||
if (jingleSession.getInitiator().equals(xmppAddress) ||
|
if (jingleSession.getInitiator().equals(xmppAddress) || jingleSession.getResponder().equals(xmppAddress)) {
|
||||||
jingleSession.getResponder().equals(xmppAddress)) {
|
|
||||||
aux = jingleSession;
|
aux = jingleSession;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aux != null)
|
if (aux != null)
|
||||||
try {
|
try {
|
||||||
aux.terminate();
|
aux.terminate();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,44 +252,32 @@ 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.
|
* Default constructor with a defined XMPPConnection.
|
||||||
* A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport.
|
* A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport.
|
||||||
*
|
*
|
||||||
* @param connection XMPP Connection to be used
|
* @param connection XMPP Connection to be used
|
||||||
*/
|
*/
|
||||||
public JingleManager(XMPPConnection connection) {
|
// public JingleManager(XMPPConnection connection) {
|
||||||
this(connection, new JingleTransportManager() {
|
// this(connection, new JingleTransportManager() {
|
||||||
protected TransportResolver createResolver(JingleSession session) {
|
// protected TransportResolver createResolver(JingleSession session) {
|
||||||
return new BasicResolver();
|
// return new BasicResolver();
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor with a defined XMPPConnection and a defined Resolver.
|
* Default constructor with a defined XMPPConnection and a defined Resolver.
|
||||||
* A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport.
|
* A default JingleTransportmanager based on BasicResolver will be used in this JingleManager transport.
|
||||||
*
|
*
|
||||||
* @param connection XMPP Connection to be used
|
* @param connection XMPP Connection to be used
|
||||||
*/
|
*/
|
||||||
public JingleManager(XMPPConnection connection, final TransportResolver resolver) {
|
// public JingleManager(XMPPConnection connection, final TransportResolver resolver) {
|
||||||
this(connection, new JingleTransportManager() {
|
// this(connection, new JingleTransportManager() {
|
||||||
protected TransportResolver createResolver(JingleSession session) {
|
// protected TransportResolver createResolver(JingleSession session) {
|
||||||
return resolver;
|
// return resolver;
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables the Jingle support on a given connection.
|
* Enables or disables the Jingle support on a given connection.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -339,19 +290,15 @@ public class JingleManager implements JingleSessionListener {
|
||||||
* disabled
|
* disabled
|
||||||
* @param enabled indicates if the service will be enabled or disabled
|
* @param enabled indicates if the service will be enabled or disabled
|
||||||
*/
|
*/
|
||||||
public synchronized static void setServiceEnabled(XMPPConnection connection,
|
public synchronized static void setServiceEnabled(XMPPConnection connection, boolean enabled) {
|
||||||
boolean enabled) {
|
|
||||||
if (isServiceEnabled(connection) == enabled) {
|
if (isServiceEnabled(connection) == enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(
|
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(Jingle.NAMESPACE);
|
||||||
Jingle.NAMESPACE);
|
} else {
|
||||||
}
|
ServiceDiscoveryManager.getInstanceFor(connection).removeFeature(Jingle.NAMESPACE);
|
||||||
else {
|
|
||||||
ServiceDiscoveryManager.getInstanceFor(connection).removeFeature(
|
|
||||||
Jingle.NAMESPACE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,8 +310,7 @@ public class JingleManager implements JingleSessionListener {
|
||||||
* given connection
|
* given connection
|
||||||
*/
|
*/
|
||||||
public static boolean isServiceEnabled(XMPPConnection connection) {
|
public static boolean isServiceEnabled(XMPPConnection connection) {
|
||||||
return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(
|
return ServiceDiscoveryManager.getInstanceFor(connection).includesFeature(Jingle.NAMESPACE);
|
||||||
Jingle.NAMESPACE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -378,41 +324,30 @@ public class JingleManager implements JingleSessionListener {
|
||||||
*/
|
*/
|
||||||
public static boolean isServiceEnabled(XMPPConnection connection, String userID) {
|
public static boolean isServiceEnabled(XMPPConnection connection, String userID) {
|
||||||
try {
|
try {
|
||||||
DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection)
|
DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(userID);
|
||||||
.discoverInfo(userID);
|
|
||||||
return result.containsFeature(Jingle.NAMESPACE);
|
return result.containsFeature(Jingle.NAMESPACE);
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the JingleTransportManager of this JingleManager
|
* Get the Media Managers of this Jingle Manager
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public JingleTransportManager getJingleTransportManager() {
|
public List<JingleMediaManager> getMediaManagers() {
|
||||||
return jingleTransportManager;
|
return jingleMediaManagers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Media Manager of this Jingle Manager
|
* Set the Media Managers of this Jingle Manager
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public JingleMediaManager getMediaManager() {
|
|
||||||
return jingleMediaManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Media Manager of this Jingle Manager
|
|
||||||
*
|
*
|
||||||
* @param jingleMediaManager JingleMediaManager to be used for open, close, start and stop jmf streamings
|
* @param jingleMediaManager JingleMediaManager to be used for open, close, start and stop jmf streamings
|
||||||
*/
|
*/
|
||||||
public void setMediaManager(JingleMediaManager jingleMediaManager) {
|
public void setMediaManagers(List<JingleMediaManager> jingleMediaManagers) {
|
||||||
this.jingleMediaManager = jingleMediaManager;
|
this.jingleMediaManagers = jingleMediaManagers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,8 +358,7 @@ public class JingleManager implements JingleSessionListener {
|
||||||
* @see #removeJingleSessionRequestListener(JingleSessionRequestListener)
|
* @see #removeJingleSessionRequestListener(JingleSessionRequestListener)
|
||||||
* @see JingleListener
|
* @see JingleListener
|
||||||
*/
|
*/
|
||||||
public synchronized void addJingleSessionRequestListener(
|
public synchronized void addJingleSessionRequestListener(final JingleSessionRequestListener jingleSessionRequestListener) {
|
||||||
final JingleSessionRequestListener jingleSessionRequestListener) {
|
|
||||||
if (jingleSessionRequestListener != null) {
|
if (jingleSessionRequestListener != null) {
|
||||||
if (jingleSessionRequestListeners == null) {
|
if (jingleSessionRequestListeners == null) {
|
||||||
initJingleSessionRequestListeners();
|
initJingleSessionRequestListeners();
|
||||||
|
@ -482,8 +416,7 @@ public class JingleManager implements JingleSessionListener {
|
||||||
for (CreatedJingleSessionListener createdJingleSessionListener : creationListeners) {
|
for (CreatedJingleSessionListener createdJingleSessionListener : creationListeners) {
|
||||||
try {
|
try {
|
||||||
createdJingleSessionListener.sessionCreated(jingleSession);
|
createdJingleSessionListener.sessionCreated(jingleSession);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,7 +464,7 @@ public class JingleManager implements JingleSessionListener {
|
||||||
if (iq.getType().equals(IQ.Type.SET)) {
|
if (iq.getType().equals(IQ.Type.SET)) {
|
||||||
if (iq instanceof Jingle) {
|
if (iq instanceof Jingle) {
|
||||||
Jingle jin = (Jingle) pin;
|
Jingle jin = (Jingle) pin;
|
||||||
if (jin.getAction().equals(Jingle.Action.SESSIONINITIATE)) {
|
if (jin.getAction().equals(JingleActionEnum.SESSION_INITIATE)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,8 +494,7 @@ public class JingleManager implements JingleSessionListener {
|
||||||
for (JingleSession jingleSession : sessions)
|
for (JingleSession jingleSession : sessions)
|
||||||
try {
|
try {
|
||||||
jingleSession.terminate();
|
jingleSession.terminate();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,22 +533,14 @@ public class JingleManager implements JingleSessionListener {
|
||||||
* @param payloadTypes list of supported payload types
|
* @param payloadTypes list of supported payload types
|
||||||
* @return The session on which the negotiation can be run.
|
* @return The session on which the negotiation can be run.
|
||||||
*/
|
*/
|
||||||
public OutgoingJingleSession createOutgoingJingleSession(String responder,
|
public JingleSession createOutgoingJingleSession(String responder) throws XMPPException {
|
||||||
List<PayloadType> payloadTypes) throws XMPPException {
|
|
||||||
|
|
||||||
if (responder == null || StringUtils.parseName(responder).length() <= 0
|
if (responder == null || StringUtils.parseName(responder).length() <= 0 || StringUtils.parseServer(responder).length() <= 0
|
||||||
|| StringUtils.parseServer(responder).length() <= 0
|
|
||||||
|| StringUtils.parseResource(responder).length() <= 0) {
|
|| StringUtils.parseResource(responder).length() <= 0) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("The provided user id was not fully qualified");
|
||||||
"The provided user id was not fully qualified");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutgoingJingleSession session;
|
JingleSession session = new JingleSession(connection, (JingleSessionRequest) null, connection.getUser(), responder, jingleMediaManagers);
|
||||||
|
|
||||||
if (jingleMediaManager != null)
|
|
||||||
session = new OutgoingJingleSession(connection, responder, payloadTypes, jingleTransportManager, jingleMediaManager);
|
|
||||||
else
|
|
||||||
session = new OutgoingJingleSession(connection, responder, payloadTypes, jingleTransportManager);
|
|
||||||
|
|
||||||
triggerSessionCreated(session);
|
triggerSessionCreated(session);
|
||||||
|
|
||||||
|
@ -630,11 +554,10 @@ public class JingleManager implements JingleSessionListener {
|
||||||
* user.
|
* user.
|
||||||
* @return the session on which the negotiation can be run.
|
* @return the session on which the negotiation can be run.
|
||||||
*/
|
*/
|
||||||
public OutgoingJingleSession createOutgoingJingleSession(String responder) throws XMPPException {
|
// public OutgoingJingleSession createOutgoingJingleSession(String responder) throws XMPPException {
|
||||||
if (this.getMediaManager() == null) return null;
|
// if (this.getMediaManagers() == null) return null;
|
||||||
return createOutgoingJingleSession(responder, this.getMediaManager().getPayloads());
|
// return createOutgoingJingleSession(responder, this.getMediaManagers());
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the session request is acceptable, this method should be invoked. It
|
* When the session request is acceptable, this method should be invoked. It
|
||||||
* will create an JingleSession which allows the negotiation to procede.
|
* 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
|
* @param payloadTypes the list of supported Payload types that can be accepted
|
||||||
* @return the session which manages the rest of the negotiation.
|
* @return the session which manages the rest of the negotiation.
|
||||||
*/
|
*/
|
||||||
IncomingJingleSession createIncomingJingleSession(
|
public JingleSession createIncomingJingleSession(JingleSessionRequest request) throws XMPPException {
|
||||||
JingleSessionRequest request, List<PayloadType> payloadTypes) throws XMPPException {
|
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
throw new NullPointerException("Received request cannot be null");
|
throw new NullPointerException("Received request cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
IncomingJingleSession session;
|
JingleSession session = new JingleSession(connection, request, request.getFrom(), connection.getUser(), jingleMediaManagers);
|
||||||
|
|
||||||
if (jingleMediaManager != null)
|
|
||||||
session = new IncomingJingleSession(connection, request
|
|
||||||
.getFrom(), payloadTypes, jingleTransportManager, jingleMediaManager, request);
|
|
||||||
else
|
|
||||||
session = new IncomingJingleSession(connection, request
|
|
||||||
.getFrom(), payloadTypes, jingleTransportManager, request);
|
|
||||||
|
|
||||||
triggerSessionCreated(session);
|
triggerSessionCreated(session);
|
||||||
|
|
||||||
|
@ -671,16 +586,15 @@ public class JingleManager implements JingleSessionListener {
|
||||||
* @param request the remote request that is being accepted.
|
* @param request the remote request that is being accepted.
|
||||||
* @return the session which manages the rest of the negotiation.
|
* @return the session which manages the rest of the negotiation.
|
||||||
*/
|
*/
|
||||||
IncomingJingleSession createIncomingJingleSession(JingleSessionRequest request) throws XMPPException {
|
// IncomingJingleSession createIncomingJingleSession(JingleSessionRequest request) throws XMPPException {
|
||||||
if (request == null) {
|
// if (request == null) {
|
||||||
throw new NullPointerException("JingleMediaManager is not defined");
|
// throw new NullPointerException("JingleMediaManager is not defined");
|
||||||
}
|
// }
|
||||||
if (jingleMediaManager != null)
|
// if (jingleMediaManager != null)
|
||||||
return createIncomingJingleSession(request, jingleMediaManager.getPayloads());
|
// return createIncomingJingleSession(request, jingleMediaManager.getPayloads());
|
||||||
|
//
|
||||||
return createIncomingJingleSession(request, null);
|
// return createIncomingJingleSession(request, null);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a session with the informed JID. If no session is found, return 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) {
|
public JingleSession getSession(String jid) {
|
||||||
for (JingleSession jingleSession : jingleSessions) {
|
for (JingleSession jingleSession : jingleSessions) {
|
||||||
if (jingleSession instanceof OutgoingJingleSession) {
|
|
||||||
if (jingleSession.getResponder().equals(jid)) {
|
if (jingleSession.getResponder().equals(jid)) {
|
||||||
return jingleSession;
|
return jingleSession;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (jingleSession instanceof IncomingJingleSession) {
|
|
||||||
if (jingleSession.getInitiator().equals(jid)) {
|
|
||||||
return jingleSession;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reject the session. If we don't want to accept the new session, send an
|
* Reject the session. If we don't want to accept the new session then we have to
|
||||||
* appropriate error packet.
|
* result/ack the session-initiate and send a session-terminate.
|
||||||
*
|
*
|
||||||
* @param request the request to be rejected.
|
* @param request the request to be rejected.
|
||||||
*/
|
*/
|
||||||
protected void rejectIncomingJingleSession(JingleSessionRequest request) {
|
protected void rejectIncomingJingleSession(JingleSessionRequest request) {
|
||||||
Jingle initiation = request.getJingle();
|
|
||||||
|
|
||||||
IQ rejection = JingleSession.createError(initiation.getPacketID(), initiation
|
JingleSession session = getSession(request.getSessionID());
|
||||||
.getFrom(), initiation.getTo(), 403, "Declined");
|
if (session != null) {
|
||||||
connection.sendPacket(rejection);
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleNegotiator.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.6 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/17 22:13:16 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -23,10 +23,9 @@ import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleListener;
|
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.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic Jingle negotiator.
|
* Basic Jingle negotiator.
|
||||||
|
@ -40,17 +39,20 @@ import java.util.ArrayList;
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Alvaro Saurin
|
* @author Alvaro Saurin
|
||||||
|
* @author Jeff Williams
|
||||||
*/
|
*/
|
||||||
public abstract class JingleNegotiator {
|
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 String expectedAckId;
|
||||||
|
|
||||||
|
private JingleNegotiatorState state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
|
@ -63,9 +65,44 @@ public abstract class JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @param connection the connection associated
|
* @param connection the connection associated
|
||||||
*/
|
*/
|
||||||
public JingleNegotiator(XMPPConnection connection) {
|
public JingleNegotiator(JingleSession session) {
|
||||||
this.connection = connection;
|
this.session = session;
|
||||||
state = null;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,8 +110,8 @@ public abstract class JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @return the connection
|
* @return the connection
|
||||||
*/
|
*/
|
||||||
public XMPPConnection getConnection() {
|
public JingleSession getSession() {
|
||||||
return connection;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,60 +119,8 @@ public abstract class JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @param connection the connection to set
|
* @param connection the connection to set
|
||||||
*/
|
*/
|
||||||
public void setConnection(XMPPConnection connection) {
|
public void setSession(JingleSession session) {
|
||||||
this.connection = connection;
|
this.session = session;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Acks management
|
// Acks management
|
||||||
|
@ -158,8 +143,7 @@ public abstract class JingleNegotiator {
|
||||||
public boolean isExpectedId(String id) {
|
public boolean isExpectedId(String id) {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
return id.equals(expectedAckId);
|
return id.equals(expectedAckId);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,175 +188,54 @@ public abstract class JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @return a copy of the listeners
|
* @return a copy of the listeners
|
||||||
*/
|
*/
|
||||||
protected ArrayList getListenersList() {
|
protected List<JingleListener> getListenersList() {
|
||||||
ArrayList result;
|
ArrayList<JingleListener> result;
|
||||||
|
|
||||||
synchronized (listeners) {
|
synchronized (listeners) {
|
||||||
result = new ArrayList(listeners);
|
result = new ArrayList<JingleListener>(listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch an incomming packet. This method is responsible for recognizing
|
* Dispatch an incoming packet.
|
||||||
* the packet type and, depending on the current state, deliverying the
|
*
|
||||||
* packet to the right event handler and wait for a response.
|
* 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 iq the packet received
|
||||||
* @param id the ID of the response that will be sent
|
* @param id the ID of the response that will be sent
|
||||||
* @return the new packet to send (either a Jingle or an IQ error).
|
* @return the new packet to send (either a Jingle or an IQ error).
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
public abstract IQ dispatchIncomingPacket(IQ iq, String id)
|
public abstract List<IQ> dispatchIncomingPacket(IQ iq, String id) throws XMPPException;
|
||||||
throws XMPPException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the negotiation.
|
* Close the negotiation.
|
||||||
*/
|
*/
|
||||||
public void close() {
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleSessionRequest.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.2 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -20,11 +20,8 @@
|
||||||
package org.jivesoftware.smackx.jingle;
|
package org.jivesoftware.smackx.jingle;
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
|
||||||
import org.jivesoftware.smackx.packet.Jingle;
|
import org.jivesoftware.smackx.packet.Jingle;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Jingle session request.
|
* A Jingle session request.
|
||||||
* <p/>
|
* <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.
|
* the parameters of the session.
|
||||||
*/
|
*/
|
||||||
public Jingle getJingle() {
|
public Jingle getJingle() {
|
||||||
|
@ -89,19 +86,17 @@ public class JingleSessionRequest {
|
||||||
* @return Returns the <b><i>IncomingJingleSession</b></i> on which the
|
* @return Returns the <b><i>IncomingJingleSession</b></i> on which the
|
||||||
* negotiation can be carried out.
|
* negotiation can be carried out.
|
||||||
*/
|
*/
|
||||||
public synchronized IncomingJingleSession accept(List<PayloadType> pts) throws XMPPException {
|
// public synchronized JingleSession accept(List<PayloadType> pts) throws XMPPException {
|
||||||
IncomingJingleSession session = null;
|
// JingleSession session = null;
|
||||||
synchronized (manager) {
|
// synchronized (manager) {
|
||||||
session = manager.createIncomingJingleSession(this,
|
// session = manager.createIncomingJingleSession(this, pts);
|
||||||
pts);
|
// // Acknowledge the IQ reception
|
||||||
session.setInitialSessionRequest(this);
|
// session.setSid(this.getSessionID());
|
||||||
// Acknowledge the IQ reception
|
// //session.sendAck(this.getJingle());
|
||||||
session.setSid(this.getSessionID());
|
// //session.respond(this.getJingle());
|
||||||
//session.sendAck(this.getJingle());
|
// }
|
||||||
//session.respond(this.getJingle());
|
// return session;
|
||||||
}
|
// }
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts this request and creates the incoming Jingle 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
|
* @return Returns the <b><i>IncomingJingleSession</b></i> on which the
|
||||||
* negotiation can be carried out.
|
* negotiation can be carried out.
|
||||||
*/
|
*/
|
||||||
public synchronized IncomingJingleSession accept() throws XMPPException {
|
public synchronized JingleSession accept() throws XMPPException {
|
||||||
IncomingJingleSession session = null;
|
JingleSession session = null;
|
||||||
synchronized (manager) {
|
synchronized (manager) {
|
||||||
session = manager.createIncomingJingleSession(this);
|
session = manager.createIncomingJingleSession(this);
|
||||||
session.setInitialSessionRequest(this);
|
|
||||||
// Acknowledge the IQ reception
|
// Acknowledge the IQ reception
|
||||||
session.setSid(this.getSessionID());
|
session.setSid(this.getSessionID());
|
||||||
//session.sendAck(this.getJingle());
|
//session.sendAck(this.getJingle());
|
||||||
//session.updatePacketListener();
|
session.updatePacketListener();
|
||||||
//session.respond(this.getJingle());
|
session.receivePacketAndRespond(this.getJingle());
|
||||||
}
|
}
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: CreatedJingleSessionListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 17/11/2006
|
* $Date: 17/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:12 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleMediaInfoListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:12 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleMediaListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:12 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleSessionListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:12 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleSessionRequestListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:12 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleTransportListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:12 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ContentInfo.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:14 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleMediaManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.3 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/18 19:48:23 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -20,10 +20,10 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.jingle.media;
|
package org.jivesoftware.smackx.jingle.media;
|
||||||
|
|
||||||
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
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;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +37,22 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public abstract class JingleMediaManager {
|
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
|
* Return all supported Payloads for this Manager
|
||||||
*
|
*
|
||||||
|
@ -61,6 +77,12 @@ public abstract class JingleMediaManager {
|
||||||
* @param local
|
* @param local
|
||||||
* @return
|
* @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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleMediaSession.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:14 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -19,11 +19,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.media;
|
package org.jivesoftware.smackx.jingle.media;
|
||||||
|
|
||||||
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
import org.jivesoftware.smackx.jingle.JingleSession;
|
||||||
|
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public Abstract Class provides a clear interface between Media Session and Jingle API.
|
* Public Abstract Class provides a clear interface between Media Session and Jingle API.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: MediaNegotiator.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.10 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/04 00:12:39 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -21,32 +21,30 @@ package org.jivesoftware.smackx.jingle.media;
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smackx.jingle.JingleNegotiator;
|
import org.jivesoftware.smackx.jingle.*;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleListener;
|
import org.jivesoftware.smackx.jingle.listeners.JingleListener;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleMediaListener;
|
import org.jivesoftware.smackx.jingle.listeners.JingleMediaListener;
|
||||||
import org.jivesoftware.smackx.packet.Jingle;
|
import org.jivesoftware.smackx.packet.Jingle;
|
||||||
import org.jivesoftware.smackx.packet.JingleContentDescription;
|
import org.jivesoftware.smackx.packet.JingleContent;
|
||||||
import org.jivesoftware.smackx.packet.JingleContentDescription.JinglePayloadType;
|
import org.jivesoftware.smackx.packet.JingleDescription;
|
||||||
import org.jivesoftware.smackx.packet.JingleError;
|
import org.jivesoftware.smackx.packet.JingleError;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for jmf descriptor negotiation.
|
* Manager for jmf descriptor negotiation. <p/> <p/> This class is responsible
|
||||||
* <p/>
|
* for managing the descriptor negotiation process, handling all the xmpp
|
||||||
* <p/>
|
* packets interchange and the stage control. handling all the xmpp packets
|
||||||
* This class is responsible for managing the descriptor negotiation process,
|
* interchange and the stage control.
|
||||||
* handling all the xmpp packets interchange and the stage control.
|
|
||||||
* handling all the xmpp packets interchange and the stage control.
|
|
||||||
*
|
*
|
||||||
* @author Thiago Camargo
|
* @author Thiago Camargo
|
||||||
*/
|
*/
|
||||||
public class MediaNegotiator extends JingleNegotiator {
|
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...
|
// Local and remote payload types...
|
||||||
|
|
||||||
|
@ -54,29 +52,24 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
|
|
||||||
private final List<PayloadType> remoteAudioPts = new ArrayList<PayloadType>();
|
private final List<PayloadType> remoteAudioPts = new ArrayList<PayloadType>();
|
||||||
|
|
||||||
private PayloadType.Audio bestCommonAudioPt;
|
private PayloadType bestCommonAudioPt;
|
||||||
|
|
||||||
// states
|
private ContentNegotiator parentNegotiator;
|
||||||
|
|
||||||
private final Inviting inviting;
|
|
||||||
|
|
||||||
private final Accepting accepting;
|
|
||||||
|
|
||||||
private final Pending pending;
|
|
||||||
|
|
||||||
private final Active active;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor. The constructor establishes some basic parameters,
|
* Default constructor. The constructor establishes some basic parameters,
|
||||||
* but it does not start the negotiation. For starting the negotiation, call
|
* but it does not start the negotiation. For starting the negotiation, call
|
||||||
* startNegotiation.
|
* startNegotiation.
|
||||||
*
|
*
|
||||||
* @param js The jingle session.
|
* @param js
|
||||||
|
* The jingle session.
|
||||||
*/
|
*/
|
||||||
public MediaNegotiator(JingleSession js, List<PayloadType> pts) {
|
public MediaNegotiator(JingleSession session, JingleMediaManager mediaManager, List<PayloadType> pts,
|
||||||
super(js.getConnection());
|
ContentNegotiator parentNegotiator) {
|
||||||
|
super(session);
|
||||||
|
|
||||||
session = js;
|
this.mediaManager = mediaManager;
|
||||||
|
this.parentNegotiator = parentNegotiator;
|
||||||
|
|
||||||
bestCommonAudioPt = null;
|
bestCommonAudioPt = null;
|
||||||
|
|
||||||
|
@ -85,97 +78,256 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
localAudioPts.addAll(pts);
|
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
|
* Return The media manager for this negotiator.
|
||||||
* the packet type and, depending on the current state, deliverying the
|
*/
|
||||||
|
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.
|
* 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.
|
* @return the new Jingle packet to send.
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
public IQ dispatchIncomingPacket(IQ iq, String id) throws XMPPException {
|
public List<IQ> dispatchIncomingPacket(IQ iq, String id) throws XMPPException {
|
||||||
IQ jout = null;
|
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();
|
|
||||||
}
|
|
||||||
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)) {
|
if (iq.getType().equals(IQ.Type.ERROR)) {
|
||||||
// Process errors
|
// Process errors
|
||||||
getState().eventError(iq);
|
setNegotiatorState(JingleNegotiatorState.FAILED);
|
||||||
}
|
triggerMediaClosed(getBestCommonAudioPt());
|
||||||
else if (iq.getType().equals(IQ.Type.RESULT)) {
|
// 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
|
// Process ACKs
|
||||||
if (isExpectedId(iq.getPacketID())) {
|
if (isExpectedId(iq.getPacketID())) {
|
||||||
jout = getState().eventAck(iq);
|
receiveResult(iq);
|
||||||
removeExpectedId(iq.getPacketID());
|
removeExpectedId(iq.getPacketID());
|
||||||
}
|
}
|
||||||
}
|
} else if (iq instanceof Jingle) {
|
||||||
else if (iq instanceof Jingle) {
|
Jingle jingle = (Jingle) iq;
|
||||||
// Get the action from the Jingle packet
|
JingleActionEnum action = jingle.getAction();
|
||||||
Jingle jin = (Jingle) iq;
|
|
||||||
Jingle.Action action = jin.getAction();
|
|
||||||
|
|
||||||
if (action != null) {
|
// Only act on the JingleContent sections that belong to this media negotiator.
|
||||||
if (action.equals(Jingle.Action.CONTENTACCEPT)) {
|
for (JingleContent jingleContent : jingle.getContentsList()) {
|
||||||
jout = getState().eventAccept(jin);
|
if (jingleContent.getName().equals(parentNegotiator.getName())) {
|
||||||
}
|
|
||||||
else if (action.equals(Jingle.Action.CONTENTDECLINE)) {
|
JingleDescription description = jingleContent.getDescription();
|
||||||
jout = getState().eventDecline(jin);
|
|
||||||
}
|
if (description != null) {
|
||||||
else if (action.equals(Jingle.Action.DESCRIPTIONINFO)) {
|
|
||||||
jout = getState().eventInfo(jin);
|
switch (action) {
|
||||||
}
|
case CONTENT_ACCEPT:
|
||||||
else if (action.equals(Jingle.Action.CONTENTMODIFY)) {
|
response = receiveContentAcceptAction(jingle, description);
|
||||||
jout = getState().eventModify(jin);
|
break;
|
||||||
}
|
|
||||||
// Any unknown action will be ignored: it is not a msg
|
case CONTENT_MODIFY:
|
||||||
// to us...
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the Id for any ACK
|
|
||||||
if (id != null) {
|
|
||||||
addExpectedId(id);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (jout != null) {
|
if (response != null) {
|
||||||
addExpectedId(jout.getPacketID());
|
addExpectedId(response.getPacketID());
|
||||||
|
responses.add(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
return responses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return jout;
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,15 +345,15 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
* @return true if the content is fully negotiated.
|
* @return true if the content is fully negotiated.
|
||||||
*/
|
*/
|
||||||
public boolean isFullyEstablished() {
|
public boolean isFullyEstablished() {
|
||||||
return isEstablished() && getState() == active;
|
return (isEstablished() && ((getNegotiatorState() == JingleNegotiatorState.SUCCEEDED) || (getNegotiatorState() == JingleNegotiatorState.FAILED)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Payload types
|
// Payload types
|
||||||
|
|
||||||
private PayloadType.Audio calculateBestCommonAudioPt(List remoteAudioPts) {
|
private PayloadType calculateBestCommonAudioPt(List remoteAudioPts) {
|
||||||
final ArrayList<PayloadType> commonAudioPtsHere = new ArrayList<PayloadType>();
|
final ArrayList<PayloadType> commonAudioPtsHere = new ArrayList<PayloadType>();
|
||||||
final ArrayList<PayloadType> commonAudioPtsThere = new ArrayList<PayloadType>();
|
final ArrayList<PayloadType> commonAudioPtsThere = new ArrayList<PayloadType>();
|
||||||
PayloadType.Audio result = null;
|
PayloadType result = null;
|
||||||
|
|
||||||
if (!remoteAudioPts.isEmpty()) {
|
if (!remoteAudioPts.isEmpty()) {
|
||||||
commonAudioPtsHere.addAll(localAudioPts);
|
commonAudioPtsHere.addAll(localAudioPts);
|
||||||
|
@ -215,7 +367,7 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
if (session.getInitiator().equals(session.getConnection().getUser())) {
|
if (session.getInitiator().equals(session.getConnection().getUser())) {
|
||||||
PayloadType.Audio bestPtHere = null;
|
PayloadType.Audio bestPtHere = null;
|
||||||
|
|
||||||
PayloadType payload = this.session.getMediaManager().getPreferredPayloadType();
|
PayloadType payload = mediaManager.getPreferredPayloadType();
|
||||||
|
|
||||||
if (payload != null && payload instanceof PayloadType.Audio)
|
if (payload != null && payload instanceof PayloadType.Audio)
|
||||||
if (commonAudioPtsHere.contains(payload))
|
if (commonAudioPtsHere.contains(payload))
|
||||||
|
@ -229,8 +381,7 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
}
|
}
|
||||||
|
|
||||||
result = bestPtHere;
|
result = bestPtHere;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PayloadType.Audio bestPtThere = null;
|
PayloadType.Audio bestPtThere = null;
|
||||||
for (PayloadType payloadType : commonAudioPtsThere)
|
for (PayloadType payloadType : commonAudioPtsThere)
|
||||||
if (payloadType instanceof PayloadType.Audio) {
|
if (payloadType instanceof PayloadType.Audio) {
|
||||||
|
@ -246,30 +397,11 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
return result;
|
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.
|
* 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) {
|
public void addRemoteAudioPayloadType(PayloadType.Audio pt) {
|
||||||
if (pt != null) {
|
if (pt != null) {
|
||||||
|
@ -284,15 +416,21 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @return a new Jingle packet with the list of audio Payload Types
|
* @return a new Jingle packet with the list of audio Payload Types
|
||||||
*/
|
*/
|
||||||
private Jingle getAudioPayloadTypesOffer() {
|
private Jingle createAudioPayloadTypesOffer() {
|
||||||
JingleContentDescription.Audio audioDescr = new JingleContentDescription.Audio();
|
|
||||||
|
JingleContent jingleContent = new JingleContent(parentNegotiator.getCreator(), parentNegotiator.getName());
|
||||||
|
JingleDescription audioDescr = new JingleDescription.Audio();
|
||||||
|
|
||||||
// Add the list of payloads for audio and create a
|
// Add the list of payloads for audio and create a
|
||||||
// JingleContentDescription
|
// JingleDescription
|
||||||
// where we announce our payloads...
|
// where we announce our payloads...
|
||||||
audioDescr.addAudioPayloadTypes(localAudioPts);
|
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
|
// Predefined messages and Errors
|
||||||
|
@ -300,16 +438,17 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
/**
|
/**
|
||||||
* Create an IQ "accept" message.
|
* Create an IQ "accept" message.
|
||||||
*/
|
*/
|
||||||
private Jingle createAcceptMessage() {
|
// private Jingle createAcceptMessage() {
|
||||||
Jingle jout = null;
|
// Jingle jout = null;
|
||||||
|
//
|
||||||
// If we hava a common best codec, send an accept right now...
|
// // If we have a common best codec, send an accept right now...
|
||||||
jout = new Jingle(Jingle.Action.CONTENTACCEPT);
|
// jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT);
|
||||||
jout.addDescription(new JingleContentDescription.Audio(
|
// JingleContent content = new JingleContent(parentNegotiator.getCreator(), parentNegotiator.getName());
|
||||||
new JinglePayloadType.Audio(bestCommonAudioPt)));
|
// content.setDescription(new JingleDescription.Audio(bestCommonAudioPt));
|
||||||
|
// jout.addContent(content);
|
||||||
return jout;
|
//
|
||||||
}
|
// return jout;
|
||||||
|
// }
|
||||||
|
|
||||||
// Payloads
|
// Payloads
|
||||||
|
|
||||||
|
@ -318,7 +457,7 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @return The best common PayloadType codec.
|
* @return The best common PayloadType codec.
|
||||||
*/
|
*/
|
||||||
public PayloadType.Audio getBestCommonAudioPt() {
|
public PayloadType getBestCommonAudioPt() {
|
||||||
return bestCommonAudioPt;
|
return bestCommonAudioPt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,13 +466,12 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
/**
|
/**
|
||||||
* Trigger a session established event.
|
* 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) {
|
protected void triggerMediaEstablished(PayloadType bestPt) {
|
||||||
ArrayList listeners = getListenersList();
|
List<JingleListener> listeners = getListenersList();
|
||||||
Iterator iter = listeners.iterator();
|
for (JingleListener li : listeners) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
JingleListener li = (JingleListener) iter.next();
|
|
||||||
if (li instanceof JingleMediaListener) {
|
if (li instanceof JingleMediaListener) {
|
||||||
JingleMediaListener mli = (JingleMediaListener) li;
|
JingleMediaListener mli = (JingleMediaListener) li;
|
||||||
mli.mediaEstablished(bestPt);
|
mli.mediaEstablished(bestPt);
|
||||||
|
@ -344,13 +482,12 @@ public class MediaNegotiator extends JingleNegotiator {
|
||||||
/**
|
/**
|
||||||
* Trigger a jmf closed event.
|
* 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) {
|
protected void triggerMediaClosed(PayloadType currPt) {
|
||||||
ArrayList listeners = getListenersList();
|
List<JingleListener> listeners = getListenersList();
|
||||||
Iterator iter = listeners.iterator();
|
for (JingleListener li : listeners) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
JingleListener li = (JingleListener) iter.next();
|
|
||||||
if (li instanceof JingleMediaListener) {
|
if (li instanceof JingleMediaListener) {
|
||||||
JingleMediaListener mli = (JingleMediaListener) li;
|
JingleMediaListener mli = (JingleMediaListener) li;
|
||||||
mli.mediaClosed(currPt);
|
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
|
* Terminate the jmf negotiator
|
||||||
*/
|
*/
|
||||||
public void close() {
|
public void close() {
|
||||||
super.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We are accepting connections.
|
|
||||||
*/
|
|
||||||
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());
|
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.
|
* Create a JingleDescription that matches this negotiator.
|
||||||
*
|
|
||||||
* @see org.jivesoftware.smackx.jingle.JingleNegotiator.State#eventAck(org.jivesoftware.smack.packet.IQ)
|
|
||||||
*/
|
*/
|
||||||
public Jingle eventAck(IQ iq) {
|
public JingleDescription getJingleDescription() {
|
||||||
|
JingleDescription result = null;
|
||||||
if (isEstablished()) {
|
PayloadType payloadType = getBestCommonAudioPt();
|
||||||
setState(active);
|
if (payloadType != null) {
|
||||||
return null;
|
result = new JingleDescription.Audio(payloadType);
|
||||||
}
|
} else {
|
||||||
return null;
|
// 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);
|
||||||
|
|
||||||
/**
|
|
||||||
* "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();
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: MediaReceivedListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: $11-07-2006
|
* $Date: 2007/07/02 17:41:14 $11-07-2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: PayloadType.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:14 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -26,6 +26,8 @@ package org.jivesoftware.smackx.jingle.media;
|
||||||
*/
|
*/
|
||||||
public class PayloadType {
|
public class PayloadType {
|
||||||
|
|
||||||
|
public static final String NODENAME = "payload-type";
|
||||||
|
|
||||||
public static int MAX_FIXED_PT = 95;
|
public static int MAX_FIXED_PT = 95;
|
||||||
|
|
||||||
public static int INVALID_PT = 65535;
|
public static int INVALID_PT = 65535;
|
||||||
|
@ -197,6 +199,49 @@ public class PayloadType {
|
||||||
return true;
|
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.
|
* Audio payload type.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: Demo.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.3 $
|
||||||
* $Date: 28/12/2006
|
* $Date: 28/12/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -17,19 +17,24 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* 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.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smackx.jingle.IncomingJingleSession;
|
|
||||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleSession;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSessionRequest;
|
import org.jivesoftware.smackx.jingle.JingleSessionRequest;
|
||||||
import org.jivesoftware.smackx.jingle.OutgoingJingleSession;
|
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
|
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 javax.swing.*;
|
||||||
import java.awt.event.ActionEvent;
|
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.
|
* Jingle Demo Application. It register in a XMPP Server and let users place calls using a full JID and auto-receive calls.
|
||||||
|
@ -45,10 +50,10 @@ public class Demo extends JFrame {
|
||||||
private String pass = null;
|
private String pass = null;
|
||||||
|
|
||||||
private JingleManager jm = null;
|
private JingleManager jm = null;
|
||||||
private IncomingJingleSession incoming = null;
|
private JingleSession incoming = null;
|
||||||
private OutgoingJingleSession outgoing = null;
|
private JingleSession outgoing = null;
|
||||||
|
|
||||||
private JTextField jid = new JTextField(30);
|
private JTextField jid;
|
||||||
|
|
||||||
public Demo(String server, String user, String pass) {
|
public Demo(String server, String user, String pass) {
|
||||||
|
|
||||||
|
@ -56,6 +61,12 @@ public class Demo extends JFrame {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.pass = pass;
|
this.pass = pass;
|
||||||
|
|
||||||
|
if (user.equals("jeffw")) {
|
||||||
|
jid = new JTextField("eowyn" + "@" + server + "/Smack");
|
||||||
|
} else {
|
||||||
|
jid = new JTextField("jeffw" + "@" + server + "/Smack");
|
||||||
|
}
|
||||||
|
|
||||||
xmppConnection = new XMPPConnection(server);
|
xmppConnection = new XMPPConnection(server);
|
||||||
try {
|
try {
|
||||||
xmppConnection.connect();
|
xmppConnection.connect();
|
||||||
|
@ -68,22 +79,26 @@ public class Demo extends JFrame {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "jivesoftware.com", 3478);
|
ICETransportManager icetm0 = new ICETransportManager(xmppConnection, "10.47.47.53", 3478);
|
||||||
jm = new JingleManager(xmppConnection, icetm0, new JmfMediaManager());
|
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.addCreationListener(icetm0);
|
||||||
|
|
||||||
jm.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
jm.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(JingleSessionRequest request) {
|
public void sessionRequested(JingleSessionRequest request) {
|
||||||
|
|
||||||
if (incoming != null)
|
// if (incoming != null)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Accept the call
|
// Accept the call
|
||||||
incoming = request.accept();
|
incoming = request.accept();
|
||||||
|
|
||||||
// Start the call
|
// Start the call
|
||||||
incoming.start();
|
incoming.startIncoming();
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -105,7 +120,7 @@ public class Demo extends JFrame {
|
||||||
if (outgoing != null) return;
|
if (outgoing != null) return;
|
||||||
try {
|
try {
|
||||||
outgoing = jm.createOutgoingJingleSession(jid.getText());
|
outgoing = jm.createOutgoingJingleSession(jid.getText());
|
||||||
outgoing.start();
|
outgoing.startOutgoing();
|
||||||
}
|
}
|
||||||
catch (XMPPException e1) {
|
catch (XMPPException e1) {
|
||||||
e1.printStackTrace();
|
e1.printStackTrace();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: AudioChannel.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 08/11/2006
|
* $Date: 08/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -22,26 +22,24 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
||||||
|
|
||||||
import javax.media.*;
|
import javax.media.*;
|
||||||
import javax.media.control.TrackControl;
|
|
||||||
import javax.media.control.PacketSizeControl;
|
|
||||||
import javax.media.control.BufferControl;
|
import javax.media.control.BufferControl;
|
||||||
|
import javax.media.control.PacketSizeControl;
|
||||||
|
import javax.media.control.TrackControl;
|
||||||
import javax.media.format.AudioFormat;
|
import javax.media.format.AudioFormat;
|
||||||
import javax.media.protocol.ContentDescriptor;
|
import javax.media.protocol.ContentDescriptor;
|
||||||
import javax.media.protocol.DataSource;
|
import javax.media.protocol.DataSource;
|
||||||
import javax.media.protocol.PushBufferDataSource;
|
import javax.media.protocol.PushBufferDataSource;
|
||||||
import javax.media.protocol.PushBufferStream;
|
import javax.media.protocol.PushBufferStream;
|
||||||
|
import javax.media.rtp.InvalidSessionAddressException;
|
||||||
import javax.media.rtp.RTPManager;
|
import javax.media.rtp.RTPManager;
|
||||||
import javax.media.rtp.SendStream;
|
import javax.media.rtp.SendStream;
|
||||||
import javax.media.rtp.SessionAddress;
|
import javax.media.rtp.SessionAddress;
|
||||||
import javax.media.rtp.InvalidSessionAddressException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.sun.media.rtp.RTPSessionMgr;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Easy to use Audio Channel implemented using JMF.
|
* An Easy to use Audio Channel implemented using JMF.
|
||||||
* It sends and receives jmf for and from desired IPs and ports.
|
* It sends and receives jmf for and from desired IPs and ports.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: AudioFormatUtils.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 08/11/2006
|
* $Date: 08/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: AudioMediaSession.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 08/11/2006
|
* $Date: 08/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -20,10 +20,10 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
|
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.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
||||||
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
||||||
|
|
||||||
import javax.media.MediaLocator;
|
import javax.media.MediaLocator;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: AudioReceiver.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 08/11/2006
|
* $Date: 08/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JmfMediaManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.3 $
|
||||||
* $Date: 08/11/2006
|
* $Date: 08/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -20,17 +20,18 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
|
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.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
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.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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a jingleMediaManager using JMF based API.
|
* Implements a jingleMediaManager using JMF based API.
|
||||||
|
@ -41,13 +42,17 @@ import java.util.ArrayList;
|
||||||
*/
|
*/
|
||||||
public class JmfMediaManager extends JingleMediaManager {
|
public class JmfMediaManager extends JingleMediaManager {
|
||||||
|
|
||||||
|
public static final String MEDIA_NAME = "JMF";
|
||||||
|
|
||||||
|
|
||||||
private List<PayloadType> payloads = new ArrayList<PayloadType>();
|
private List<PayloadType> payloads = new ArrayList<PayloadType>();
|
||||||
private String mediaLocator = null;
|
private String mediaLocator = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Media Manager instance
|
* Creates a Media Manager instance
|
||||||
*/
|
*/
|
||||||
public JmfMediaManager() {
|
public JmfMediaManager(JingleTransportManager transportManager) {
|
||||||
|
super(transportManager);
|
||||||
setupPayloads();
|
setupPayloads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +61,8 @@ public class JmfMediaManager extends JingleMediaManager {
|
||||||
*
|
*
|
||||||
* @param mediaLocator Media Locator
|
* @param mediaLocator Media Locator
|
||||||
*/
|
*/
|
||||||
public JmfMediaManager(String mediaLocator) {
|
public JmfMediaManager(String mediaLocator, JingleTransportManager transportManager) {
|
||||||
|
super(transportManager);
|
||||||
this.mediaLocator = mediaLocator;
|
this.mediaLocator = mediaLocator;
|
||||||
setupPayloads();
|
setupPayloads();
|
||||||
}
|
}
|
||||||
|
@ -154,4 +160,8 @@ public class JmfMediaManager extends JingleMediaManager {
|
||||||
private static void runLinuxPreInstall() {
|
private static void runLinuxPreInstall() {
|
||||||
// @TODO Implement Linux Pre-Install
|
// @TODO Implement Linux Pre-Install
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return MEDIA_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: AudioMediaSession.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 25/12/2006
|
* $Date: 25/12/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* 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.MediaSessionListener;
|
||||||
import mil.jfcom.cie.media.session.StreamPlayer;
|
import mil.jfcom.cie.media.session.StreamPlayer;
|
||||||
import mil.jfcom.cie.media.srtp.packetizer.SpeexFormat;
|
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.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
||||||
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
||||||
|
|
||||||
import javax.media.NoProcessorException;
|
import javax.media.NoProcessorException;
|
||||||
import javax.media.format.UnsupportedFormatException;
|
import javax.media.format.UnsupportedFormatException;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: SpeexMediaManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.3 $
|
||||||
* $Date: 25/12/2006
|
* $Date: 25/12/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -19,17 +19,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.mediaimpl.jspeex;
|
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.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
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.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.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements a jingleMediaManager using JMF based API and JSpeex.
|
* Implements a jingleMediaManager using JMF based API and JSpeex.
|
||||||
|
@ -40,9 +41,12 @@ import java.util.ArrayList;
|
||||||
*/
|
*/
|
||||||
public class SpeexMediaManager extends JingleMediaManager {
|
public class SpeexMediaManager extends JingleMediaManager {
|
||||||
|
|
||||||
|
public static final String MEDIA_NAME = "Speex";
|
||||||
|
|
||||||
private List<PayloadType> payloads = new ArrayList<PayloadType>();
|
private List<PayloadType> payloads = new ArrayList<PayloadType>();
|
||||||
|
|
||||||
public SpeexMediaManager() {
|
public SpeexMediaManager(JingleTransportManager transportManager) {
|
||||||
|
super(transportManager);
|
||||||
setupPayloads();
|
setupPayloads();
|
||||||
setupJMF();
|
setupJMF();
|
||||||
}
|
}
|
||||||
|
@ -120,4 +124,8 @@ public class SpeexMediaManager extends JingleMediaManager {
|
||||||
private static void runLinuxPreInstall() {
|
private static void runLinuxPreInstall() {
|
||||||
// @TODO Implement Linux Pre-Install
|
// @TODO Implement Linux Pre-Install
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return MEDIA_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: MultiMediaManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.3 $
|
||||||
* $Date: 25/12/2006
|
* $Date: 25/12/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -20,13 +20,15 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.jingle.mediaimpl.multi;
|
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.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
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.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.
|
* Implements a MultiMediaManager using other JingleMediaManager implementations.
|
||||||
|
@ -37,11 +39,14 @@ import java.util.*;
|
||||||
|
|
||||||
public class MultiMediaManager extends JingleMediaManager {
|
public class MultiMediaManager extends JingleMediaManager {
|
||||||
|
|
||||||
|
public static final String MEDIA_NAME = "Multi";
|
||||||
|
|
||||||
private List<JingleMediaManager> managers = new ArrayList<JingleMediaManager>();
|
private List<JingleMediaManager> managers = new ArrayList<JingleMediaManager>();
|
||||||
|
|
||||||
private PayloadType preferredPayloadType = null;
|
private PayloadType preferredPayloadType = null;
|
||||||
|
|
||||||
public MultiMediaManager() {
|
public MultiMediaManager(JingleTransportManager transportManager) {
|
||||||
|
super(transportManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMediaManager(JingleMediaManager manager) {
|
public void addMediaManager(JingleMediaManager manager) {
|
||||||
|
@ -95,4 +100,7 @@ public class MultiMediaManager extends JingleMediaManager {
|
||||||
this.preferredPayloadType = preferredPayloadType;
|
this.preferredPayloadType = preferredPayloadType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return MEDIA_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ScreenShareMediaManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.3 $
|
||||||
* $Date: 25/12/2006
|
* $Date: 25/12/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -20,13 +20,14 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
|
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.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
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.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.nat.TransportCandidate;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -40,12 +41,15 @@ import java.util.List;
|
||||||
|
|
||||||
public class ScreenShareMediaManager extends JingleMediaManager {
|
public class ScreenShareMediaManager extends JingleMediaManager {
|
||||||
|
|
||||||
|
public static final String MEDIA_NAME = "ScreenShare";
|
||||||
|
|
||||||
private List<PayloadType> payloads = new ArrayList<PayloadType>();
|
private List<PayloadType> payloads = new ArrayList<PayloadType>();
|
||||||
|
|
||||||
private ImageDecoder decoder = null;
|
private ImageDecoder decoder = null;
|
||||||
private ImageEncoder encoder = null;
|
private ImageEncoder encoder = null;
|
||||||
|
|
||||||
public ScreenShareMediaManager() {
|
public ScreenShareMediaManager(JingleTransportManager transportManager) {
|
||||||
|
super(transportManager);
|
||||||
setupPayloads();
|
setupPayloads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,4 +108,8 @@ public class ScreenShareMediaManager extends JingleMediaManager {
|
||||||
public void setEncoder(ImageEncoder encoder) {
|
public void setEncoder(ImageEncoder encoder) {
|
||||||
this.encoder = encoder;
|
this.encoder = encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return MEDIA_NAME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ScreenShareSession.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.2 $
|
||||||
* $Date: 08/11/2006
|
* $Date: 08/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
|
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.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
|
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.ImageReceiver;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter;
|
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter;
|
||||||
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
||||||
import org.jivesoftware.smackx.jingle.IncomingJingleSession;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.WindowListener;
|
|
||||||
import java.awt.event.WindowEvent;
|
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.net.DatagramSocket;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Class implements a complete JingleMediaSession.
|
* 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 local the local information. The candidate that will receive the jmf
|
||||||
* @param locator media locator
|
* @param locator media locator
|
||||||
*/
|
*/
|
||||||
public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote,
|
public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
|
||||||
final TransportCandidate local, final String locator, JingleSession jingleSession) {
|
final String locator, JingleSession jingleSession) {
|
||||||
super(payloadType, remote, local, "Screen", jingleSession);
|
super(payloadType, remote, local, "Screen", jingleSession);
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Audio Channel to make it able to send and receive audio
|
* Initialize the screen share channels.
|
||||||
*/
|
*/
|
||||||
public void initialize() {
|
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();
|
JFrame window = new JFrame();
|
||||||
JPanel jp = new JPanel();
|
JPanel jp = new JPanel();
|
||||||
window.add(jp);
|
window.add(jp);
|
||||||
|
@ -84,17 +93,17 @@ public class ScreenShareSession extends JingleMediaSession {
|
||||||
window.setLocation(0, 0);
|
window.setLocation(0, 0);
|
||||||
window.setSize(600, 600);
|
window.setSize(600, 600);
|
||||||
|
|
||||||
window.addWindowListener(new WindowAdapter(){
|
window.addWindowListener(new WindowAdapter() {
|
||||||
public void windowClosed(WindowEvent e) {
|
public void windowClosed(WindowEvent e) {
|
||||||
receiver.stop();
|
receiver.stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
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());
|
System.out.println("Receiving on:" + receiver.getLocalPort());
|
||||||
}
|
} catch (UnknownHostException e) {
|
||||||
catch (UnknownHostException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,15 +112,6 @@ public class ScreenShareSession extends JingleMediaSession {
|
||||||
window.setAlwaysOnTop(true);
|
window.setAlwaysOnTop(true);
|
||||||
window.setVisible(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.
|
* Stops transmission and for NAT Traversal reasons stop receiving also.
|
||||||
*/
|
*/
|
||||||
public void stopTrasmit() {
|
public void stopTrasmit() {
|
||||||
if(transmitter!=null){
|
if (transmitter != null) {
|
||||||
transmitter.stop();
|
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
|
* For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
|
||||||
*/
|
*/
|
||||||
public void stopReceive() {
|
public void stopReceive() {
|
||||||
if(receiver!=null){
|
if (receiver != null) {
|
||||||
receiver.stop();
|
receiver.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,8 +173,7 @@ public class ScreenShareSession extends JingleMediaSession {
|
||||||
freePort = ss.getLocalPort();
|
freePort = ss.getLocalPort();
|
||||||
ss.close();
|
ss.close();
|
||||||
return freePort;
|
return freePort;
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,8 +181,7 @@ public class ScreenShareSession extends JingleMediaSession {
|
||||||
ss = new ServerSocket(0);
|
ss = new ServerSocket(0);
|
||||||
freePort = ss.getLocalPort();
|
freePort = ss.getLocalPort();
|
||||||
ss.close();
|
ss.close();
|
||||||
}
|
} catch (IOException e) {
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return freePort;
|
return freePort;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: BasicResolver.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -3,8 +3,8 @@ package org.jivesoftware.smackx.jingle.nat;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
import org.jivesoftware.smackx.jingle.JingleSession;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: BasicTransportManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: BridgedResolver.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -23,9 +23,12 @@ import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
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.util.Enumeration;
|
||||||
import java.net.*;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bridged Resolver use a RTPBridge Service to add a relayed candidate.
|
* Bridged Resolver use a RTPBridge Service to add a relayed candidate.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: BridgedTransportManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: DatagramListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: FixedResolver.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: HttpServer.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
|
@ -52,10 +52,10 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.jingle.nat;
|
package org.jivesoftware.smackx.jingle.nat;
|
||||||
|
|
||||||
import java.net.*;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.net.ServerSocket;
|
||||||
import java.lang.*;
|
import java.net.Socket;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A very Simple HTTP Server
|
* A very Simple HTTP Server
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ICECandidate.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.2 $
|
||||||
* $Date$
|
* $Date: 2007/07/03 16:36:31 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
|
@ -51,8 +51,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.nat;
|
package org.jivesoftware.smackx.jingle.nat;
|
||||||
|
|
||||||
import de.javawi.jstun.test.demo.ice.Candidate;
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -301,7 +299,7 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
|
|
||||||
for (int i = 0; i < 10 && !result.isReachable(); i++)
|
for (int i = 0; i < 10 && !result.isReachable(); i++)
|
||||||
try {
|
try {
|
||||||
System.err.println(i);
|
System.err.println("ICE Candidate retry #" + i);
|
||||||
Thread.sleep(400);
|
Thread.sleep(400);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ICEResolver.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package org.jivesoftware.smackx.jingle.nat;
|
package org.jivesoftware.smackx.jingle.nat;
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
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.JingleSession;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
|
|
||||||
import org.jivesoftware.smackx.jingle.listeners.CreatedJingleSessionListener;
|
import org.jivesoftware.smackx.jingle.listeners.CreatedJingleSessionListener;
|
||||||
|
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
|
||||||
|
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ICETransportManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 02/01/2007
|
* $Date: 02/01/2007
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleTransportManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: RTPBridge.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -32,11 +32,11 @@ import org.jivesoftware.smackx.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.packet.DiscoverItems;
|
import org.jivesoftware.smackx.packet.DiscoverItems;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.net.InetAddress;
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.net.SocketException;
|
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.
|
* 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.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: ResultListener.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: STUN.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -32,13 +32,9 @@ import org.jivesoftware.smackx.packet.DiscoverInfo;
|
||||||
import org.jivesoftware.smackx.packet.DiscoverItems;
|
import org.jivesoftware.smackx.packet.DiscoverItems;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
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.
|
* 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.
|
* Element name of the packet extension.
|
||||||
*/
|
*/
|
||||||
public static final String NAME = "stun";
|
public static final String DOMAIN = "stun";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Element name of the packet extension.
|
* Element name of the packet extension.
|
||||||
|
@ -71,7 +67,7 @@ public class STUN extends IQ {
|
||||||
public static final String NAMESPACE = "google:jingleinfo";
|
public static final String NAMESPACE = "google:jingleinfo";
|
||||||
|
|
||||||
static {
|
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();
|
STUN stunPacket = new STUN();
|
||||||
stunPacket.setTo(NAME + "." + xmppConnection.getServiceName());
|
stunPacket.setTo(DOMAIN + "." + xmppConnection.getServiceName());
|
||||||
|
|
||||||
PacketCollector collector = xmppConnection
|
PacketCollector collector = xmppConnection
|
||||||
.createPacketCollector(new PacketIDFilter(stunPacket.getPacketID()));
|
.createPacketCollector(new PacketIDFilter(stunPacket.getPacketID()));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: STUNResolver.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: STUNTransportManager.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: TcpUdpBridgeClient.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
|
@ -51,13 +51,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle.nat;
|
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.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
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.
|
* A Simple and Experimental Bridge.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: TestResult.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: TransportCandidate.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* 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.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.CharBuffer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transport candidate.
|
* Transport candidate.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: TransportNegotiator.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.9 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -22,18 +22,14 @@ package org.jivesoftware.smackx.jingle.nat;
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smackx.jingle.JingleNegotiator;
|
import org.jivesoftware.smackx.jingle.*;
|
||||||
import org.jivesoftware.smackx.jingle.JingleSession;
|
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleListener;
|
import org.jivesoftware.smackx.jingle.listeners.JingleListener;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleTransportListener;
|
import org.jivesoftware.smackx.jingle.listeners.JingleTransportListener;
|
||||||
import org.jivesoftware.smackx.packet.Jingle;
|
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 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.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -55,7 +51,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
public final static int CANDIDATES_ACCEPT_PERIOD = 4000;
|
public final static int CANDIDATES_ACCEPT_PERIOD = 4000;
|
||||||
|
|
||||||
// The session this nenotiator belongs to
|
// The session this nenotiator belongs to
|
||||||
private final JingleSession session;
|
//private final JingleSession session;
|
||||||
|
|
||||||
// The transport manager
|
// The transport manager
|
||||||
private final TransportResolver resolver;
|
private final TransportResolver resolver;
|
||||||
|
@ -81,14 +77,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
// Listener for the resolver
|
// Listener for the resolver
|
||||||
private TransportResolverListener.Resolver resolverListener;
|
private TransportResolverListener.Resolver resolverListener;
|
||||||
|
|
||||||
// states
|
private ContentNegotiator parentNegotiator;
|
||||||
private final Inviting inviting;
|
|
||||||
|
|
||||||
private final Accepting accepting;
|
|
||||||
|
|
||||||
private final Pending pending;
|
|
||||||
|
|
||||||
private final Active active;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
|
@ -96,20 +85,13 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
* @param js The Jingle session
|
* @param js The Jingle session
|
||||||
* @param transResolver The JingleTransportManager to use
|
* @param transResolver The JingleTransportManager to use
|
||||||
*/
|
*/
|
||||||
public TransportNegotiator(JingleSession js,
|
public TransportNegotiator(JingleSession session, TransportResolver transResolver, ContentNegotiator parentNegotiator) {
|
||||||
TransportResolver transResolver) {
|
super(session);
|
||||||
super(js.getConnection());
|
|
||||||
|
|
||||||
session = js;
|
|
||||||
resolver = transResolver;
|
resolver = transResolver;
|
||||||
|
this.parentNegotiator = parentNegotiator;
|
||||||
|
|
||||||
resultThread = null;
|
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
|
* @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
|
* 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
|
* @param bestLocalCandidate the acceptedLocalCandidate to set
|
||||||
*/
|
*/
|
||||||
private void setAcceptedLocalCandidate(TransportCandidate bestLocalCandidate)
|
private void setAcceptedLocalCandidate(TransportCandidate bestLocalCandidate) throws XMPPException {
|
||||||
throws XMPPException {
|
|
||||||
for (int i = 0; i < resolver.getCandidateCount(); i++) {
|
for (int i = 0; i < resolver.getCandidateCount(); i++) {
|
||||||
//TODO FIX The EQUAL Sentence
|
//TODO FIX The EQUAL Sentence
|
||||||
if (resolver.getCandidate(i).getIp().equals(bestLocalCandidate.getIp())
|
if (resolver.getCandidate(i).getIp().equals(bestLocalCandidate.getIp())
|
||||||
|
@ -166,11 +147,40 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
return acceptedLocalCandidate;
|
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() {
|
public void close() {
|
||||||
super.close();
|
super.close();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a JingleTransport that best reflects this transport negotiator.
|
||||||
|
*/
|
||||||
|
public JingleTransport getJingleTransport() {
|
||||||
|
return getJingleTransport(getBestRemoteCandidate());
|
||||||
|
}
|
||||||
|
|
||||||
public List<TransportCandidate> getOfferedCandidates() {
|
public List<TransportCandidate> getOfferedCandidates() {
|
||||||
return offeredCandidates;
|
return offeredCandidates;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +197,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @return the remoteCandidates
|
* @return the remoteCandidates
|
||||||
*/
|
*/
|
||||||
private List getRemoteCandidates() {
|
private List<TransportCandidate> getRemoteCandidates() {
|
||||||
return remoteCandidates;
|
return remoteCandidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,10 +242,9 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
*/
|
*/
|
||||||
private void checkRemoteCandidate(final TransportCandidate offeredCandidate) {
|
private void checkRemoteCandidate(final TransportCandidate offeredCandidate) {
|
||||||
offeredCandidate.addListener(new TransportResolverListener.Checker() {
|
offeredCandidate.addListener(new TransportResolverListener.Checker() {
|
||||||
public void candidateChecked(TransportCandidate cand,
|
public void candidateChecked(TransportCandidate cand, final boolean validCandidate) {
|
||||||
final boolean validCandidate) {
|
|
||||||
if (validCandidate) {
|
if (validCandidate) {
|
||||||
if (!(getState() instanceof Active))
|
if (getNegotiatorState() == JingleNegotiatorState.PENDING)
|
||||||
addValidRemoteCandidate(offeredCandidate);
|
addValidRemoteCandidate(offeredCandidate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,7 +271,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
* @return true if the transport is fully established.
|
* @return true if the transport is fully established.
|
||||||
*/
|
*/
|
||||||
public final boolean isFullyEstablished() {
|
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++) {
|
for (int i = 0; i < tries - 1; i++) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once we are in pending state, look for any valid remote
|
// Once we are in pending state, look for any valid remote
|
||||||
// candidate, and send an "accept" if we have one...
|
// candidate, and send an "accept" if we have one...
|
||||||
TransportCandidate bestRemote = getBestRemoteCandidate();
|
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
|
// Accepting the remote candidate
|
||||||
if (!acceptedRemoteCandidates.contains(bestRemote)) {
|
if (!acceptedRemoteCandidates.contains(bestRemote)) {
|
||||||
Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT);
|
Jingle jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT);
|
||||||
jout.addTransport(getJingleTransport(bestRemote));
|
JingleContent content = parentNegotiator.getJingleContent();
|
||||||
|
content.addJingleTransport(getJingleTransport(bestRemote));
|
||||||
|
jout.addContent(content);
|
||||||
|
|
||||||
// Send the packet
|
// Send the packet
|
||||||
js.sendFormattedJingle(jin, jout);
|
js.sendFormattedJingle(jin, jout);
|
||||||
acceptedRemoteCandidates.add(bestRemote);
|
acceptedRemoteCandidates.add(bestRemote);
|
||||||
}
|
}
|
||||||
if (isEstablished()) {
|
if ((isEstablished()) && (getNegotiatorState() == JingleNegotiatorState.PENDING)) {
|
||||||
setState(active);
|
setNegotiatorState(JingleNegotiatorState.SUCCEEDED);
|
||||||
|
triggerTransportEstablished(getAcceptedLocalCandidate(), bestRemote);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,34 +383,36 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
bestRemote = getBestRemoteCandidate();
|
bestRemote = getBestRemoteCandidate();
|
||||||
State state = getState();
|
//State state = getState();
|
||||||
if (bestRemote != null && (state == pending || state == active)) {
|
if ((bestRemote != null)
|
||||||
|
&& ((getNegotiatorState() == JingleNegotiatorState.PENDING))) {
|
||||||
if (!acceptedRemoteCandidates.contains(bestRemote)) {
|
if (!acceptedRemoteCandidates.contains(bestRemote)) {
|
||||||
Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT);
|
Jingle jout = new Jingle(JingleActionEnum.CONTENT_ACCEPT);
|
||||||
jout.addTransport(getJingleTransport(bestRemote));
|
JingleContent content = parentNegotiator.getJingleContent();
|
||||||
|
content.addJingleTransport(getJingleTransport(bestRemote));
|
||||||
|
jout.addContent(content);
|
||||||
|
|
||||||
// Send the packet
|
// Send the packet
|
||||||
js.sendFormattedJingle(jin, jout);
|
js.sendFormattedJingle(jin, jout);
|
||||||
acceptedRemoteCandidates.add(bestRemote);
|
acceptedRemoteCandidates.add(bestRemote);
|
||||||
}
|
}
|
||||||
if (isEstablished()) {
|
if (isEstablished()) {
|
||||||
setState(active);
|
setNegotiatorState(JingleNegotiatorState.SUCCEEDED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getState() == null || !getState().equals(active)) {
|
if (getNegotiatorState() != JingleNegotiatorState.SUCCEEDED) {
|
||||||
try {
|
try {
|
||||||
session.terminate("Unable to negotiate session. This may be caused by firewall configuration problems.");
|
session
|
||||||
}
|
.terminate("Unable to negotiate session. This may be caused by firewall configuration problems.");
|
||||||
catch (XMPPException e) {
|
} catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -468,24 +482,22 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
*
|
*
|
||||||
* @param jin The input jingle packet
|
* @param jin The input jingle packet
|
||||||
*/
|
*/
|
||||||
private static ArrayList obtainCandidatesList(Jingle jin) {
|
private List<TransportCandidate> obtainCandidatesList(Jingle jingle) {
|
||||||
ArrayList result = new ArrayList();
|
List<TransportCandidate> result = new ArrayList<TransportCandidate>();
|
||||||
|
|
||||||
if (jin != null) {
|
if (jingle != null) {
|
||||||
// Get the list of candidates from the packet
|
// Get the list of candidates from the packet
|
||||||
Iterator iTrans = jin.getTransports();
|
for (JingleContent jingleContent : jingle.getContentsList()) {
|
||||||
while (iTrans.hasNext()) {
|
if (jingleContent.getName().equals(parentNegotiator.getName())) {
|
||||||
org.jivesoftware.smackx.packet.JingleTransport trans = (org.jivesoftware.smackx.packet.JingleTransport) iTrans.next();
|
for (JingleTransport jingleTransport : jingleContent.getJingleTransportsList()) {
|
||||||
|
for (JingleTransportCandidate jingleTransportCandidate : jingleTransport.getCandidatesList()) {
|
||||||
Iterator iCand = trans.getCandidates();
|
TransportCandidate transCand = jingleTransportCandidate.getMediaTransport();
|
||||||
while (iCand.hasNext()) {
|
|
||||||
JingleTransportCandidate cand = (JingleTransportCandidate) iCand
|
|
||||||
.next();
|
|
||||||
TransportCandidate transCand = cand.getMediaTransport();
|
|
||||||
result.add(transCand);
|
result.add(transCand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -503,7 +515,15 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
if (!cand.isNull()) {
|
if (!cand.isNull()) {
|
||||||
// Offer our new candidate...
|
// Offer our new candidate...
|
||||||
addOfferedCandidate(cand);
|
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
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
private void sendTransportCandidatesOffer() throws XMPPException {
|
private void sendTransportCandidatesOffer() throws XMPPException {
|
||||||
List notOffered = resolver.getCandidatesList();
|
List<TransportCandidate> notOffered = resolver.getCandidatesList();
|
||||||
|
|
||||||
notOffered.removeAll(offeredCandidates);
|
notOffered.removeAll(offeredCandidates);
|
||||||
|
|
||||||
|
@ -556,79 +576,184 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
* @return the new Jingle packet to send.
|
* @return the new Jingle packet to send.
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
public final IQ dispatchIncomingPacket(IQ iq, String id) throws XMPPException {
|
public final List<IQ> dispatchIncomingPacket(IQ iq, String id) throws XMPPException {
|
||||||
IQ jout = null;
|
List<IQ> responses = new ArrayList<IQ>();
|
||||||
|
IQ response = null;
|
||||||
|
|
||||||
if (invalidState()) {
|
if (iq != null) {
|
||||||
if (iq == null) {
|
|
||||||
// With a null packet, we are just inviting the other end...
|
|
||||||
setState(inviting);
|
|
||||||
jout = getState().eventInvite();
|
|
||||||
|
|
||||||
}
|
|
||||||
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)) {
|
if (iq.getType().equals(IQ.Type.ERROR)) {
|
||||||
// Process errors
|
// Process errors
|
||||||
getState().eventError(iq);
|
setNegotiatorState(JingleNegotiatorState.FAILED);
|
||||||
}
|
triggerTransportClosed(null);
|
||||||
else if (iq.getType().equals(IQ.Type.RESULT)) {
|
// 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
|
// Process ACKs
|
||||||
if (isExpectedId(iq.getPacketID())) {
|
if (isExpectedId(iq.getPacketID())) {
|
||||||
jout = getState().eventAck(iq);
|
response = receiveResult(iq);
|
||||||
removeExpectedId(iq.getPacketID());
|
removeExpectedId(iq.getPacketID());
|
||||||
}
|
}
|
||||||
}
|
} else if (iq instanceof Jingle) {
|
||||||
else if (iq instanceof Jingle) {
|
|
||||||
// Get the action from the Jingle packet
|
// Get the action from the Jingle packet
|
||||||
Jingle jin = (Jingle) iq;
|
Jingle jingle = (Jingle) iq;
|
||||||
Jingle.Action action = jin.getAction();
|
JingleActionEnum action = jingle.getAction();
|
||||||
|
|
||||||
if (action != null) {
|
switch (action) {
|
||||||
if (action.equals(Jingle.Action.TRANSPORTACCEPT)) {
|
case CONTENT_ACCEPT:
|
||||||
jout = getState().eventAccept(jin);
|
response = receiveContentAcceptAction(jingle);
|
||||||
}
|
break;
|
||||||
else if (action.equals(Jingle.Action.TRANSPORTDECLINE)) {
|
|
||||||
jout = getState().eventDecline(jin);
|
case CONTENT_MODIFY:
|
||||||
}
|
break;
|
||||||
else if (action.equals(Jingle.Action.TRANSPORTINFO)) {
|
|
||||||
jout = getState().eventInfo(jin);
|
case CONTENT_REMOVE:
|
||||||
}
|
break;
|
||||||
else if (action.equals(Jingle.Action.TRANSPORTMODIFY)) {
|
|
||||||
jout = getState().eventModify(jin);
|
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 (response != null) {
|
||||||
if (id != null) {
|
addExpectedId(response.getPacketID());
|
||||||
addExpectedId(id);
|
responses.add(response);
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (jout != null) {
|
|
||||||
addExpectedId(jout.getPacketID());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 local TransportCandidate that has been agreed.
|
||||||
* @param remote TransportCandidate that has been agreed.
|
* @param remote TransportCandidate that has been agreed.
|
||||||
*/
|
*/
|
||||||
private void triggerTransportEstablished(TransportCandidate local,
|
private void triggerTransportEstablished(TransportCandidate local, TransportCandidate remote) {
|
||||||
TransportCandidate remote) {
|
List<JingleListener> listeners = getListenersList();
|
||||||
ArrayList listeners = getListenersList();
|
for (JingleListener li : listeners) {
|
||||||
for (Object listener : listeners) {
|
|
||||||
JingleListener li = (JingleListener) listener;
|
|
||||||
if (li instanceof JingleTransportListener) {
|
if (li instanceof JingleTransportListener) {
|
||||||
JingleTransportListener mli = (JingleTransportListener) li;
|
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);
|
mli.transportEstablished(local, remote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -656,9 +780,8 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
* @param cand current TransportCandidate that is cancelled.
|
* @param cand current TransportCandidate that is cancelled.
|
||||||
*/
|
*/
|
||||||
private void triggerTransportClosed(TransportCandidate cand) {
|
private void triggerTransportClosed(TransportCandidate cand) {
|
||||||
ArrayList listeners = getListenersList();
|
List<JingleListener> listeners = getListenersList();
|
||||||
for (Object listener : listeners) {
|
for (JingleListener li : listeners) {
|
||||||
JingleListener li = (JingleListener) listener;
|
|
||||||
if (li instanceof JingleTransportListener) {
|
if (li instanceof JingleTransportListener) {
|
||||||
JingleTransportListener mli = (JingleTransportListener) li;
|
JingleTransportListener mli = (JingleTransportListener) li;
|
||||||
mli.transportClosed(cand);
|
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
|
// Subclasses
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -862,8 +804,8 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
* @param js The Jingle session this negotiation belongs to.
|
* @param js The Jingle session this negotiation belongs to.
|
||||||
* @param res The transport resolver to use.
|
* @param res The transport resolver to use.
|
||||||
*/
|
*/
|
||||||
public RawUdp(JingleSession js, final TransportResolver res) {
|
public RawUdp(JingleSession js, final TransportResolver res, ContentNegotiator parentNegotiator) {
|
||||||
super(js, res);
|
super(js, res, parentNegotiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -887,8 +829,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
if (!cands.isEmpty()) {
|
if (!cands.isEmpty()) {
|
||||||
System.out.println("RAW CAND");
|
System.out.println("RAW CAND");
|
||||||
return (TransportCandidate) cands.get(0);
|
return (TransportCandidate) cands.get(0);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
System.out.println("No Remote Candidate");
|
System.out.println("No Remote Candidate");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -915,8 +856,8 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
* @param js The Jingle session this negotiation belongs to.
|
* @param js The Jingle session this negotiation belongs to.
|
||||||
* @param res The transport manager to use.
|
* @param res The transport manager to use.
|
||||||
*/
|
*/
|
||||||
public Ice(JingleSession js, final TransportResolver res) {
|
public Ice(JingleSession js, final TransportResolver res, ContentNegotiator parentNegotiator) {
|
||||||
super(js, res);
|
super(js, res, parentNegotiator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: TransportResolver.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:07 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
|
@ -354,10 +354,10 @@ public abstract class TransportResolver {
|
||||||
* @return the list of transport candidates
|
* @return the list of transport candidates
|
||||||
*/
|
*/
|
||||||
public List<TransportCandidate> getCandidatesList() {
|
public List<TransportCandidate> getCandidatesList() {
|
||||||
ArrayList result = null;
|
List<TransportCandidate> result = null;
|
||||||
|
|
||||||
synchronized (candidates) {
|
synchronized (candidates) {
|
||||||
result = new ArrayList(candidates);
|
result = new ArrayList<TransportCandidate>(candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: TransportResolverListener.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.1 $
|
||||||
* $Date: 15/11/2006
|
* $Date: 15/11/2006
|
||||||
*
|
*
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: Jingle.java,v $
|
||||||
* $Revision: 2407 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2004-11-02 23:37:00 +0000 (Tue, 02 Nov 2004) $
|
* $Date: 2007/07/02 17:41:08 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software.
|
* Copyright 2003-2007 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
package org.jivesoftware.smackx.packet;
|
package org.jivesoftware.smackx.packet;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleActionEnum;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -43,7 +44,7 @@ public class Jingle extends IQ {
|
||||||
|
|
||||||
// static
|
// 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";
|
public static final String NODENAME = "jingle";
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public class Jingle extends IQ {
|
||||||
|
|
||||||
private String sid; // The session id
|
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 initiator; // The initiator as a "user@host/resource"
|
||||||
|
|
||||||
|
@ -59,25 +60,19 @@ public class Jingle extends IQ {
|
||||||
|
|
||||||
// Sub-elements of a Jingle object.
|
// Sub-elements of a Jingle object.
|
||||||
|
|
||||||
private final List descriptions = new ArrayList();
|
private final List<JingleContent> contents = new ArrayList<JingleContent>();
|
||||||
|
|
||||||
private final List transports = new ArrayList();
|
|
||||||
|
|
||||||
private JingleContentInfo contentInfo;
|
private JingleContentInfo contentInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constructor where the main components can be initialized.
|
* 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) {
|
final String sid) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
if (descs != null) {
|
if (contents != null) {
|
||||||
descriptions.addAll(descs);
|
contents.addAll(contents);
|
||||||
}
|
|
||||||
|
|
||||||
if (trans != null) {
|
|
||||||
transports.addAll(trans);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentInfo(mi);
|
setContentInfo(mi);
|
||||||
|
@ -90,40 +85,21 @@ 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();
|
super();
|
||||||
|
|
||||||
addDescription(descr);
|
addContent(content);
|
||||||
|
|
||||||
// Set null all other fields in the packet
|
// Set null all other fields in the packet
|
||||||
initiator = null;
|
initiator = null;
|
||||||
responder = null;
|
responder = null;
|
||||||
|
|
||||||
// Some default values for the most common situation...
|
// 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);
|
this.setType(IQ.Type.SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +118,7 @@ public class Jingle extends IQ {
|
||||||
responder = null;
|
responder = null;
|
||||||
|
|
||||||
// Some default values for the most common situation...
|
// Some default values for the most common situation...
|
||||||
action = Jingle.Action.DESCRIPTIONINFO;
|
action = JingleActionEnum.UNKNOWN;
|
||||||
this.setType(IQ.Type.SET);
|
this.setType(IQ.Type.SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,8 +127,8 @@ public class Jingle extends IQ {
|
||||||
*
|
*
|
||||||
* @param action The action.
|
* @param action The action.
|
||||||
*/
|
*/
|
||||||
public Jingle(final Jingle.Action action) {
|
public Jingle(final JingleActionEnum action) {
|
||||||
this(null, null, null, null);
|
this(null, null, null);
|
||||||
this.action = action;
|
this.action = action;
|
||||||
|
|
||||||
// In general, a Jingle with an action is used in a SET packet...
|
// 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)
|
* @see #setSid(String)
|
||||||
*/
|
*/
|
||||||
public Jingle(final String sid) {
|
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.
|
* Returns the XML namespace of the extension sub-packet root element.
|
||||||
* According the specification the namespace is always
|
* 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.
|
* @return the XML namespace of the packet extension.
|
||||||
*/
|
*/
|
||||||
|
@ -238,97 +214,49 @@ 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() {
|
public Iterator<JingleContent> getContents() {
|
||||||
synchronized (descriptions) {
|
synchronized (contents) {
|
||||||
return Collections.unmodifiableList(new ArrayList(descriptions)).iterator();
|
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() {
|
public List<JingleContent> getContentsList() {
|
||||||
synchronized (descriptions) {
|
synchronized (contents) {
|
||||||
return new ArrayList(descriptions);
|
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) {
|
public void addContent(final JingleContent content) {
|
||||||
if (desc != null) {
|
if (content != null) {
|
||||||
synchronized (descriptions) {
|
synchronized (contents) {
|
||||||
descriptions.add(desc);
|
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) {
|
public void addContents(final List<JingleContent> contentList) {
|
||||||
if (descsList != null) {
|
if (contentList != null) {
|
||||||
synchronized (descriptions) {
|
synchronized (contents) {
|
||||||
descriptions.addAll(descsList);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,7 +266,7 @@ public class Jingle extends IQ {
|
||||||
*
|
*
|
||||||
* @return the action
|
* @return the action
|
||||||
*/
|
*/
|
||||||
public Action getAction() {
|
public JingleActionEnum getAction() {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +275,7 @@ public class Jingle extends IQ {
|
||||||
*
|
*
|
||||||
* @param action the action to set
|
* @param action the action to set
|
||||||
*/
|
*/
|
||||||
public void setAction(final Action action) {
|
public void setAction(final JingleActionEnum action) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,27 +361,13 @@ public class Jingle extends IQ {
|
||||||
buf.append(" sid=\"").append(getSid()).append("\"");
|
buf.append(" sid=\"").append(getSid()).append("\"");
|
||||||
}
|
}
|
||||||
buf.append(">");
|
buf.append(">");
|
||||||
//TODO Update to accept more than one content per session (XEP-0166)
|
|
||||||
|
|
||||||
buf.append("<content name='Audio-Content'>");
|
synchronized (contents) {
|
||||||
// Look for possible payload types, and dump them.
|
for (JingleContent content : contents) {
|
||||||
synchronized (descriptions) {
|
buf.append(content.toXML());
|
||||||
for (int i = 0; i < descriptions.size(); i++) {
|
|
||||||
JingleContentDescription desc = (JingleContentDescription) descriptions
|
|
||||||
.get(i);
|
|
||||||
buf.append(desc.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
|
// and the same for audio jmf info
|
||||||
if (contentInfo != null) {
|
if (contentInfo != null) {
|
||||||
buf.append(contentInfo.toXML());
|
buf.append(contentInfo.toXML());
|
||||||
|
@ -462,43 +376,4 @@ public class Jingle extends IQ {
|
||||||
buf.append("</").append(getElementName()).append(">");
|
buf.append("</").append(getElementName()).append(">");
|
||||||
return buf.toString();
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleContentInfo.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:08 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -96,7 +96,7 @@ public class JingleContentInfo implements PacketExtension {
|
||||||
*/
|
*/
|
||||||
public static class Audio extends JingleContentInfo {
|
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) {
|
public Audio(final ContentInfo mi) {
|
||||||
super(mi);
|
super(mi);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleError.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:08 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -27,7 +27,7 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
public class JingleError implements PacketExtension {
|
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");
|
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)
|
public PacketExtension parseExtension(final XmlPullParser parser)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleTransport.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:08 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -20,8 +20,8 @@
|
||||||
package org.jivesoftware.smackx.packet;
|
package org.jivesoftware.smackx.packet;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
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.ICECandidate;
|
||||||
|
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -43,7 +43,7 @@ public class JingleTransport implements PacketExtension {
|
||||||
|
|
||||||
protected String namespace;
|
protected String namespace;
|
||||||
|
|
||||||
protected final List candidates = new ArrayList();
|
protected final List<JingleTransportCandidate> candidates = new ArrayList<JingleTransportCandidate>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
|
@ -104,10 +104,10 @@ public class JingleTransport implements PacketExtension {
|
||||||
*
|
*
|
||||||
* @return The candidates list.
|
* @return The candidates list.
|
||||||
*/
|
*/
|
||||||
public ArrayList getCandidatesList() {
|
public List<JingleTransportCandidate> getCandidatesList() {
|
||||||
ArrayList res = null;
|
ArrayList<JingleTransportCandidate> res = null;
|
||||||
synchronized (candidates) {
|
synchronized (candidates) {
|
||||||
res = new ArrayList(candidates);
|
res = new ArrayList<JingleTransportCandidate>(candidates);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ public class JingleTransport implements PacketExtension {
|
||||||
* RTP-ICE profile
|
* RTP-ICE profile
|
||||||
*/
|
*/
|
||||||
public static class Ice extends JingleTransport {
|
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() {
|
public Ice() {
|
||||||
super();
|
super();
|
||||||
|
@ -292,9 +292,9 @@ public class JingleTransport implements PacketExtension {
|
||||||
*
|
*
|
||||||
* @see org.jivesoftware.smackx.packet.JingleTransport#getCandidates()
|
* @see org.jivesoftware.smackx.packet.JingleTransport#getCandidates()
|
||||||
*/
|
*/
|
||||||
public ArrayList getCandidatesList() {
|
public List<JingleTransportCandidate> getCandidatesList() {
|
||||||
ArrayList copy = new ArrayList();
|
List<JingleTransportCandidate> copy = new ArrayList<JingleTransportCandidate>();
|
||||||
ArrayList superCandidatesList = super.getCandidatesList();
|
List<JingleTransportCandidate> superCandidatesList = super.getCandidatesList();
|
||||||
for (int i = 0; i < superCandidatesList.size(); i++) {
|
for (int i = 0; i < superCandidatesList.size(); i++) {
|
||||||
copy.add(superCandidatesList.get(i));
|
copy.add(superCandidatesList.get(i));
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,7 @@ public class JingleTransport implements PacketExtension {
|
||||||
* Raw UDP profile.
|
* Raw UDP profile.
|
||||||
*/
|
*/
|
||||||
public static class RawUdp extends JingleTransport {
|
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() {
|
public RawUdp() {
|
||||||
super();
|
super();
|
||||||
|
@ -375,9 +375,9 @@ public class JingleTransport implements PacketExtension {
|
||||||
*
|
*
|
||||||
* @see org.jivesoftware.smackx.packet.JingleTransport#getCandidates()
|
* @see org.jivesoftware.smackx.packet.JingleTransport#getCandidates()
|
||||||
*/
|
*/
|
||||||
public ArrayList getCandidatesList() {
|
public List<JingleTransportCandidate> getCandidatesList() {
|
||||||
ArrayList copy = new ArrayList();
|
List<JingleTransportCandidate> copy = new ArrayList<JingleTransportCandidate>();
|
||||||
ArrayList superCandidatesList = super.getCandidatesList();
|
List<JingleTransportCandidate> superCandidatesList = super.getCandidatesList();
|
||||||
if (superCandidatesList.size() > 0) {
|
if (superCandidatesList.size() > 0) {
|
||||||
copy.add(superCandidatesList.get(0));
|
copy.add(superCandidatesList.get(0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleContentInfoProvider.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:11 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* 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 {
|
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)
|
public PacketExtension parseExtension(final XmlPullParser parser)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleProvider.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:11 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -23,10 +23,8 @@ package org.jivesoftware.smackx.provider;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.provider.IQProvider;
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
import org.jivesoftware.smackx.packet.Jingle;
|
import org.jivesoftware.smackx.jingle.JingleActionEnum;
|
||||||
import org.jivesoftware.smackx.packet.JingleContentDescription;
|
import org.jivesoftware.smackx.packet.*;
|
||||||
import org.jivesoftware.smackx.packet.JingleContentInfo;
|
|
||||||
import org.jivesoftware.smackx.packet.JingleTransport;
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,13 +49,15 @@ public class JingleProvider implements IQProvider {
|
||||||
|
|
||||||
Jingle jingle = new Jingle();
|
Jingle jingle = new Jingle();
|
||||||
String sid = "";
|
String sid = "";
|
||||||
Jingle.Action action;
|
JingleActionEnum action;
|
||||||
String initiator = "";
|
String initiator = "";
|
||||||
String responder = "";
|
String responder = "";
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
|
JingleContent currentContent = null;
|
||||||
|
|
||||||
// Sub-elements providers
|
// Sub-elements providers
|
||||||
JingleContentDescriptionProvider jdpAudio = new JingleContentDescriptionProvider.Audio();
|
JingleContentProvider jcp = new JingleContentProvider();
|
||||||
|
JingleDescriptionProvider jdpAudio = new JingleDescriptionProvider.Audio();
|
||||||
JingleTransportProvider jtpRawUdp = new JingleTransportProvider.RawUdp();
|
JingleTransportProvider jtpRawUdp = new JingleTransportProvider.RawUdp();
|
||||||
JingleTransportProvider jtpIce = new JingleTransportProvider.Ice();
|
JingleTransportProvider jtpIce = new JingleTransportProvider.Ice();
|
||||||
JingleContentInfoProvider jmipAudio = new JingleContentInfoProvider.Audio();
|
JingleContentInfoProvider jmipAudio = new JingleContentInfoProvider.Audio();
|
||||||
|
@ -68,7 +68,7 @@ public class JingleProvider implements IQProvider {
|
||||||
|
|
||||||
// Get some attributes for the <jingle> element
|
// Get some attributes for the <jingle> element
|
||||||
sid = parser.getAttributeValue("", "sid");
|
sid = parser.getAttributeValue("", "sid");
|
||||||
action = Jingle.Action.getAction(parser.getAttributeValue("", "action"));
|
action = JingleActionEnum.getAction(parser.getAttributeValue("", "action"));
|
||||||
initiator = parser.getAttributeValue("", "initiator");
|
initiator = parser.getAttributeValue("", "initiator");
|
||||||
responder = parser.getAttributeValue("", "responder");
|
responder = parser.getAttributeValue("", "responder");
|
||||||
|
|
||||||
|
@ -88,32 +88,29 @@ public class JingleProvider implements IQProvider {
|
||||||
// Parse some well know subelements, depending on the namespaces
|
// Parse some well know subelements, depending on the namespaces
|
||||||
// and element names...
|
// and element names...
|
||||||
|
|
||||||
if (elementName.equals(JingleContentDescription.NODENAME)
|
if (elementName.equals(JingleContent.NODENAME)) {
|
||||||
&& namespace.equals(JingleContentDescription.Audio.NAMESPACE)) {
|
// Add a new <content> element to the jingle
|
||||||
jingle.addDescription((JingleContentDescription) jdpAudio
|
currentContent = (JingleContent) jcp.parseExtension(parser);
|
||||||
.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)) {
|
} else if (elementName.equals(JingleTransport.NODENAME)) {
|
||||||
|
// Add all of the <transport> elements to the <content> of the jingle
|
||||||
|
|
||||||
// Parse the possible transport namespaces
|
// Parse the possible transport namespaces
|
||||||
if (namespace.equals(JingleTransport.RawUdp.NAMESPACE)) {
|
if (namespace.equals(JingleTransport.RawUdp.NAMESPACE)) {
|
||||||
jingle.addTransport((JingleTransport) jtpRawUdp
|
currentContent.addJingleTransport((JingleTransport) jtpRawUdp.parseExtension(parser));
|
||||||
.parseExtension(parser));
|
|
||||||
} else if (namespace.equals(JingleTransport.Ice.NAMESPACE)) {
|
} else if (namespace.equals(JingleTransport.Ice.NAMESPACE)) {
|
||||||
jingle.addTransport((JingleTransport) jtpIce
|
currentContent.addJingleTransport((JingleTransport) jtpIce.parseExtension(parser));
|
||||||
.parseExtension(parser));
|
|
||||||
} else {
|
} else {
|
||||||
throw new XMPPException("Unknown transport namespace \""
|
throw new XMPPException("Unknown transport namespace \"" + namespace + "\" in Jingle packet.");
|
||||||
+ namespace + "\" in Jingle packet.");
|
|
||||||
}
|
}
|
||||||
} else if (namespace.equals(JingleContentInfo.Audio.NAMESPACE)) {
|
} else if (namespace.equals(JingleContentInfo.Audio.NAMESPACE)) {
|
||||||
jingle.setContentInfo((JingleContentInfo) jmipAudio
|
jingle.setContentInfo((JingleContentInfo) jmipAudio.parseExtension(parser));
|
||||||
.parseExtension(parser));
|
|
||||||
} else if (elementName.equals("content")) {
|
|
||||||
//TODO Separate Contents (XEP-0166)
|
|
||||||
} else {
|
} else {
|
||||||
throw new XMPPException("Unknown combination of namespace \""
|
throw new XMPPException("Unknown combination of namespace \"" + namespace + "\" and element name \""
|
||||||
+ namespace + "\" and element name \"" + elementName
|
+ elementName + "\" in Jingle packet.");
|
||||||
+ "\" in Jingle packet.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (eventType == XmlPullParser.END_TAG) {
|
} else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleTransportProvider.java,v $
|
||||||
* $Revision: 7329 $
|
* $Revision: 1.1 $
|
||||||
* $Date: 2007-02-28 20:59:28 -0300 (qua, 28 fev 2007) $
|
* $Date: 2007/07/02 17:41:11 $
|
||||||
*
|
*
|
||||||
* Copyright 2003-2005 Jive Software.
|
* Copyright 2003-2005 Jive Software.
|
||||||
*
|
*
|
||||||
|
@ -21,8 +21,8 @@ package org.jivesoftware.smackx.provider;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
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.ICECandidate;
|
||||||
|
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
|
||||||
import org.jivesoftware.smackx.packet.JingleTransport;
|
import org.jivesoftware.smackx.packet.JingleTransport;
|
||||||
import org.jivesoftware.smackx.packet.JingleTransport.JingleTransportCandidate;
|
import org.jivesoftware.smackx.packet.JingleTransport.JingleTransportCandidate;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleManagerTest.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.3 $
|
||||||
* $Date$
|
* $Date: 2007/07/18 18:29:21 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* 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.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
|
||||||
import org.jivesoftware.smackx.jingle.media.PayloadType;
|
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.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.packet.Jingle;
|
||||||
import org.jivesoftware.smackx.provider.JingleProvider;
|
import org.jivesoftware.smackx.provider.JingleProvider;
|
||||||
|
|
||||||
|
@ -127,8 +131,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
*
|
*
|
||||||
* @return A testing list
|
* @return A testing list
|
||||||
*/
|
*/
|
||||||
private ArrayList getTestPayloads1() {
|
private List<PayloadType> getTestPayloads1() {
|
||||||
ArrayList result = new ArrayList();
|
List<PayloadType> result = new ArrayList<PayloadType>();
|
||||||
|
|
||||||
result.add(new PayloadType.Audio(34, "supercodec-1", 2, 14000));
|
result.add(new PayloadType.Audio(34, "supercodec-1", 2, 14000));
|
||||||
result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000));
|
result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000));
|
||||||
|
@ -138,8 +142,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList getTestPayloads2() {
|
private List<PayloadType> getTestPayloads2() {
|
||||||
ArrayList result = new ArrayList();
|
List<PayloadType> result = new ArrayList<PayloadType>();
|
||||||
|
|
||||||
result.add(new PayloadType.Audio(27, "supercodec-3", 2, 28000));
|
result.add(new PayloadType.Audio(27, "supercodec-3", 2, 28000));
|
||||||
result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000));
|
result.add(new PayloadType.Audio(56, "supercodec-2", 1, 44000));
|
||||||
|
@ -149,8 +153,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList getTestPayloads3() {
|
private List<PayloadType> getTestPayloads3() {
|
||||||
ArrayList result = new ArrayList();
|
List<PayloadType> result = new ArrayList<PayloadType>();
|
||||||
|
|
||||||
result.add(new PayloadType.Audio(91, "badcodec-1", 2, 28000));
|
result.add(new PayloadType.Audio(91, "badcodec-1", 2, 28000));
|
||||||
result.add(new PayloadType.Audio(92, "badcodec-2", 1, 44000));
|
result.add(new PayloadType.Audio(92, "badcodec-2", 1, 44000));
|
||||||
|
@ -168,9 +172,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
ProviderManager.getInstance().addIQProvider("jingle",
|
ProviderManager.getInstance().addIQProvider("jingle", "http://jabber.org/protocol/jingle", new JingleProvider());
|
||||||
"http://jabber.org/protocol/jingle",
|
|
||||||
new JingleProvider());
|
|
||||||
|
|
||||||
PacketFilter initRequestFilter = new PacketFilter() {
|
PacketFilter initRequestFilter = new PacketFilter() {
|
||||||
// Return true if we accept this packet
|
// Return true if we accept this packet
|
||||||
|
@ -182,9 +184,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
System.out.println("packet");
|
System.out.println("packet");
|
||||||
if (iq instanceof Jingle) {
|
if (iq instanceof Jingle) {
|
||||||
Jingle jin = (Jingle) pin;
|
Jingle jin = (Jingle) pin;
|
||||||
if (jin.getAction().equals(Jingle.Action.SESSIONINITIATE)) {
|
if (jin.getAction().equals(JingleActionEnum.SESSION_INITIATE)) {
|
||||||
System.out
|
System.out.println("Session initiation packet accepted... ");
|
||||||
.println("Session initiation packet accepted... ");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,12 +204,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}, initRequestFilter);
|
}, initRequestFilter);
|
||||||
|
|
||||||
// Create a dummy packet for testing...
|
// Create a dummy packet for testing...
|
||||||
IQfake iqSent = new IQfake(
|
IQfake iqSent = new IQfake(" <jingle xmlns='http://jabber.org/protocol/jingle'" + " initiator=\"user1@thiago\""
|
||||||
" <jingle xmlns='http://jabber.org/protocol/jingle'"
|
+ " responder=\"user0@thiago\"" + " action=\"session-initiate\" sid=\"08666555\">" + "</jingle>");
|
||||||
+ " initiator=\"user1@thiago\""
|
|
||||||
+ " responder=\"user0@thiago\""
|
|
||||||
+ " action=\"session-initiate\" sid=\"08666555\">"
|
|
||||||
+ "</jingle>");
|
|
||||||
|
|
||||||
iqSent.setTo(getFullJID(0));
|
iqSent.setTo(getFullJID(0));
|
||||||
iqSent.setFrom(getFullJID(0));
|
iqSent.setFrom(getFullJID(0));
|
||||||
|
@ -218,8 +215,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
getConnection(1).sendPacket(iqSent);
|
getConnection(1).sendPacket(iqSent);
|
||||||
try {
|
try {
|
||||||
Thread.sleep(10000);
|
Thread.sleep(10000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Awake... " + valCounter());
|
System.out.println("Awake... " + valCounter());
|
||||||
|
@ -236,11 +232,22 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222);
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222);
|
||||||
TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567);
|
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);
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567);
|
||||||
JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
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
|
// Session 1 waits for connections
|
||||||
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
|
@ -249,23 +256,20 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
*/
|
*/
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out.println("Session request detected, from "
|
System.out.println("Session request detected, from " + request.getFrom());
|
||||||
+ request.getFrom());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Session 0 starts a request
|
// Session 0 starts a request
|
||||||
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
getFullJID(1), getTestPayloads1());
|
session0.startOutgoing();
|
||||||
session0.start(null);
|
|
||||||
|
|
||||||
Thread.sleep(5000);
|
Thread.sleep(5000);
|
||||||
|
|
||||||
assertTrue(valCounter() > 0);
|
assertTrue(valCounter() > 0);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("An error occured with Jingle");
|
fail("An error occured with Jingle");
|
||||||
}
|
}
|
||||||
|
@ -281,11 +285,22 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222);
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222);
|
||||||
TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567);
|
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);
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567);
|
||||||
final JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
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() {
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
/**
|
/**
|
||||||
|
@ -293,15 +308,13 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
*/
|
*/
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out.println("Session request detected, from "
|
System.out.println("Session request detected, from " + request.getFrom() + ": accepting.");
|
||||||
+ request.getFrom() + ": accepting.");
|
|
||||||
|
|
||||||
// We accept the request
|
// We accept the request
|
||||||
try {
|
try {
|
||||||
IncomingJingleSession session1 = request.accept(getTestPayloads2());
|
JingleSession session1 = request.accept();
|
||||||
session1.start(request);
|
session1.startIncoming();
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,16 +322,14 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
// Session 0 starts a request
|
// Session 0 starts a request
|
||||||
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
getFullJID(1), getTestPayloads1());
|
session0.startOutgoing();
|
||||||
session0.start(null);
|
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
assertTrue(valCounter() > 0);
|
assertTrue(valCounter() > 0);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("An error occured with Jingle");
|
fail("An error occured with Jingle");
|
||||||
}
|
}
|
||||||
|
@ -333,22 +344,35 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TransportResolver tr1 = new FixedResolver("127.0.0.1", 54213);
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 54213);
|
||||||
TransportResolver tr2 = new FixedResolver("127.0.0.1", 54531);
|
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);
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 54531);
|
||||||
final JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
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() {
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
/**
|
/**
|
||||||
* Called when a new session request is detected
|
* Called when a new session request is detected
|
||||||
*/
|
*/
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
System.out.println("Session request detected, from "
|
System.out.println("Session request detected, from " + request.getFrom() + ": accepting.");
|
||||||
+ request.getFrom() + ": accepting.");
|
|
||||||
try {
|
try {
|
||||||
// We accept the request
|
// We accept the request
|
||||||
IncomingJingleSession session1 = request.accept(getTestPayloads1());
|
JingleSession session1 = request.accept();
|
||||||
|
|
||||||
session1.addListener(new JingleSessionListener() {
|
session1.addListener(new JingleSessionListener() {
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
public void sessionClosed(String reason, JingleSession jingleSession) {
|
||||||
|
@ -363,16 +387,13 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
System.out.println("sessionDeclined().");
|
System.out.println("sessionDeclined().");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionEstablished(PayloadType pt,
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
||||||
TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) {
|
JingleSession jingleSession) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out
|
System.out.println("Responder: the session is fully established.");
|
||||||
.println("Responder: the session is fully established.");
|
|
||||||
System.out.println("+ Payload Type: " + pt.getId());
|
System.out.println("+ Payload Type: " + pt.getId());
|
||||||
System.out.println("+ Local IP/port: " + lc.getIp() + ":"
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
||||||
+ lc.getPort());
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
||||||
System.out.println("+ Remote IP/port: " + rc.getIp() + ":"
|
|
||||||
+ rc.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
||||||
|
@ -383,27 +404,23 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
session1.start(request);
|
session1.startIncoming();
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Session 0 starts a request
|
// Session 0 starts a request
|
||||||
System.out.println("Starting session request with equal payloads, to "
|
System.out.println("Starting session request with equal payloads, to " + getFullJID(1) + "...");
|
||||||
+ getFullJID(1) + "...");
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
session0.startOutgoing();
|
||||||
getFullJID(1), getTestPayloads1());
|
|
||||||
session0.start(null);
|
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
assertTrue(valCounter() == 1);
|
assertTrue(valCounter() == 1);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("An error occured with Jingle");
|
fail("An error occured with Jingle");
|
||||||
}
|
}
|
||||||
|
@ -417,22 +434,32 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TransportResolver tr1 = new FixedResolver("127.0.0.1", 54222);
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222);
|
||||||
TransportResolver tr2 = new FixedResolver("127.0.0.1", 54567);
|
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);
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567);
|
||||||
final JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
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() {
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
/**
|
/**
|
||||||
* Called when a new session request is detected
|
* Called when a new session request is detected
|
||||||
*/
|
*/
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
System.out.println("Session request detected, from "
|
System.out.println("Session request detected, from " + request.getFrom() + ": accepting.");
|
||||||
+ request.getFrom() + ": accepting.");
|
|
||||||
try {
|
try {
|
||||||
// We accept the request
|
// We accept the request
|
||||||
IncomingJingleSession session1 = request.accept(getTestPayloads2());
|
JingleSession session1 = request.accept();
|
||||||
|
|
||||||
session1.addListener(new JingleSessionListener() {
|
session1.addListener(new JingleSessionListener() {
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
public void sessionClosed(String reason, JingleSession jingleSession) {
|
||||||
|
@ -447,16 +474,13 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
System.out.println("sessionDeclined().");
|
System.out.println("sessionDeclined().");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionEstablished(PayloadType pt,
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, final TransportCandidate lc,
|
||||||
TransportCandidate rc, final TransportCandidate lc, JingleSession jingleSession) {
|
JingleSession jingleSession) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out
|
System.out.println("Responder: the session is fully established.");
|
||||||
.println("Responder: the session is fully established.");
|
|
||||||
System.out.println("+ Payload Type: " + pt.getId());
|
System.out.println("+ Payload Type: " + pt.getId());
|
||||||
System.out.println("+ Local IP/port: " + lc.getIp() + ":"
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
||||||
+ lc.getPort());
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
||||||
System.out.println("+ Remote IP/port: " + rc.getIp() + ":"
|
|
||||||
+ rc.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
||||||
|
@ -467,10 +491,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
session1.startIncoming();
|
||||||
session1.start(request);
|
} catch (Exception e) {
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,8 +500,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
// Session 0 starts a request
|
// Session 0 starts a request
|
||||||
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
getFullJID(1), getTestPayloads1());
|
|
||||||
|
|
||||||
session0.addListener(new JingleSessionListener() {
|
session0.addListener(new JingleSessionListener() {
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
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 sessionDeclined(String reason, JingleSession jingleSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionEstablished(PayloadType pt,
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
||||||
TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) {
|
JingleSession jingleSession) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out.println("Initiator: the session is fully established.");
|
System.out.println("Initiator: the session is fully established.");
|
||||||
System.out.println("+ Payload Type: " + pt.getId());
|
System.out.println("+ Payload Type: " + pt.getId());
|
||||||
System.out.println("+ Local IP/port: " + lc.getIp() + ":"
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
||||||
+ lc.getPort());
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
||||||
System.out.println("+ Remote IP/port: " + rc.getIp() + ":"
|
|
||||||
+ rc.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
||||||
|
@ -509,14 +528,13 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
session0.start(null);
|
session0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
assertTrue(valCounter() == 2);
|
assertTrue(valCounter() == 2);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("An error occured with Jingle");
|
fail("An error occured with Jingle");
|
||||||
}
|
}
|
||||||
|
@ -530,28 +548,37 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TransportResolver tr1 = new FixedResolver("127.0.0.1", 22222);
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 22222);
|
||||||
TransportResolver tr2 = new FixedResolver("127.0.0.1", 22444);
|
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);
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 22444);
|
||||||
final JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
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() {
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
/**
|
/**
|
||||||
* Called when a new session request is detected
|
* Called when a new session request is detected
|
||||||
*/
|
*/
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
System.out.println("Session request detected, from "
|
System.out.println("Session request detected, from " + request.getFrom());
|
||||||
+ request.getFrom());
|
|
||||||
|
|
||||||
// We reject the request
|
// We reject the request
|
||||||
try {
|
try {
|
||||||
IncomingJingleSession session = request.accept(getTestPayloads1());
|
JingleSession session = request.accept();
|
||||||
session.setInitialSessionRequest(request);
|
//session.setInitialSessionRequest(request);
|
||||||
session.start();
|
session.startIncoming();
|
||||||
session.terminate();
|
session.terminate();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,11 +587,11 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
// Session 0 starts a request
|
// Session 0 starts a request
|
||||||
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
getFullJID(1), getTestPayloads1());
|
|
||||||
|
|
||||||
session0.addListener(new JingleSessionListener() {
|
session0.addListener(new JingleSessionListener() {
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
public void sessionClosed(String reason, JingleSession jingleSession) {
|
||||||
|
incCounter();
|
||||||
System.out.println("The session has been closed");
|
System.out.println("The session has been closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,14 +599,11 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionDeclined(String reason, JingleSession jingleSession) {
|
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,
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
||||||
TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) {
|
JingleSession jingleSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
||||||
|
@ -590,7 +614,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
session0.start();
|
session0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(50000);
|
Thread.sleep(50000);
|
||||||
|
|
||||||
|
@ -600,8 +624,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
assertTrue(valCounter() > 0);
|
assertTrue(valCounter() > 0);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("An error occured with Jingle");
|
fail("An error occured with Jingle");
|
||||||
}
|
}
|
||||||
|
@ -616,8 +639,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ProviderManager.getInstance().addIQProvider(RTPBridge.NAME,
|
ProviderManager.getInstance().addIQProvider(RTPBridge.NAME, RTPBridge.NAMESPACE, new RTPBridge.Provider());
|
||||||
RTPBridge.NAMESPACE, new RTPBridge.Provider());
|
|
||||||
|
|
||||||
RTPBridge response = RTPBridge.getRTPBridge(getConnection(0), "102");
|
RTPBridge response = RTPBridge.getRTPBridge(getConnection(0), "102");
|
||||||
|
|
||||||
|
@ -639,21 +661,18 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
dataSocket.receive(packet);
|
dataSocket.receive(packet);
|
||||||
incCounter();
|
incCounter();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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 ds0 = new DatagramSocket(14004, InetAddress.getByName("0.0.0.0"));
|
||||||
DatagramSocket ds1 = new DatagramSocket(14050, InetAddress.getByName("0.0.0.0"));
|
DatagramSocket ds1 = new DatagramSocket(14050, InetAddress.getByName("0.0.0.0"));
|
||||||
DatagramPacket echo0 = new DatagramPacket(packet, packet.length,
|
DatagramPacket echo0 = new DatagramPacket(packet, packet.length, InetAddress.getLocalHost(), response.getPortA());
|
||||||
InetAddress.getLocalHost(), response.getPortA());
|
DatagramPacket echo1 = new DatagramPacket(packet, packet.length, InetAddress.getLocalHost(), response.getPortB());
|
||||||
DatagramPacket echo1 = new DatagramPacket(packet, packet.length,
|
|
||||||
InetAddress.getLocalHost(), response.getPortB());
|
|
||||||
|
|
||||||
ds1.send(echo1);
|
ds1.send(echo1);
|
||||||
ds0.send(echo0);
|
ds0.send(echo0);
|
||||||
|
@ -683,13 +702,11 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
ds0.close();
|
ds0.close();
|
||||||
ds1.close();
|
ds1.close();
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,36 +719,36 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
XMPPConnection.DEBUG_ENABLED = true;
|
|
||||||
|
|
||||||
XMPPConnection x0 = getConnection(0);
|
XMPPConnection x0 = getConnection(0);
|
||||||
XMPPConnection x1 = getConnection(1);
|
XMPPConnection x1 = getConnection(1);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(
|
XMPPConnection.DEBUG_ENABLED = true;
|
||||||
x0, new FixedResolver("127.0.0.1", 20080));
|
|
||||||
|
|
||||||
final JingleManager jm1 = new JingleManager(
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 20080);
|
||||||
x1, new FixedResolver("127.0.0.1", 20040));
|
FixedTransportManager ftm0 = new FixedTransportManager(tr0);
|
||||||
|
JmfMediaManager jmf0 = new JmfMediaManager(ftm0);
|
||||||
|
List<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
|
||||||
|
trl0.add(jmf0);
|
||||||
|
|
||||||
// JingleManager jm0 = new JingleSessionManager(
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 20040);
|
||||||
// x0, new ICEResolver());
|
FixedTransportManager ftm1 = new FixedTransportManager(tr1);
|
||||||
// JingleManager jm1 = new JingleSessionManager(
|
JmfMediaManager jmf1 = new JmfMediaManager(ftm1);
|
||||||
// x1, new ICEResolver());
|
List<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
|
||||||
|
trl1.add(jmf1);
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager = new JmfMediaManager();
|
JingleManager man0 = new JingleManager(x0, trl0);
|
||||||
|
JingleManager man1 = new JingleManager(x1, trl1);
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager);
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
jm1.setMediaManager(jingleMediaManager);
|
|
||||||
|
|
||||||
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
session.addListener(new JingleSessionListener() {
|
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();
|
incCounter();
|
||||||
System.out.println("Establish In");
|
System.out.println("Establish In");
|
||||||
}
|
}
|
||||||
|
@ -755,9 +772,8 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
session.start();
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,11 +783,12 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = man0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.addListener(new JingleSessionListener() {
|
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();
|
incCounter();
|
||||||
System.out.println("Establish Out");
|
System.out.println("Establish Out");
|
||||||
}
|
}
|
||||||
|
@ -795,15 +812,14 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(8000);
|
Thread.sleep(8000);
|
||||||
js0.terminate();
|
js0.terminate();
|
||||||
|
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -818,25 +834,22 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
resetCounter();
|
resetCounter();
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
//XMPPConnection.DEBUG_ENABLED = true;
|
|
||||||
|
|
||||||
XMPPConnection x0 = getConnection(0);
|
XMPPConnection x0 = getConnection(0);
|
||||||
XMPPConnection x1 = getConnection(1);
|
XMPPConnection x1 = getConnection(1);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(
|
FixedResolver tr0 = new FixedResolver("127.0.0.1", 20004);
|
||||||
x0, new FixedResolver("127.0.0.1", 20004));
|
FixedTransportManager ftm0 = new FixedTransportManager(tr0);
|
||||||
final JingleManager jm1 = new JingleManager(
|
|
||||||
x1, new FixedResolver("127.0.0.1", 20040));
|
|
||||||
|
|
||||||
//JingleManager jm0 = new ICETransportManager(x0, "stun.xten.net", 3478);
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 20040);
|
||||||
//JingleManager jm1 = new ICETransportManager(x1, "stun.xten.net", 3478);
|
FixedTransportManager ftm1 = new FixedTransportManager(tr1);
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager = new JingleMediaManager() {
|
try {
|
||||||
|
|
||||||
|
JingleMediaManager jingleMediaManager = new JingleMediaManager(ftm0) {
|
||||||
// Media Session Implementation
|
// Media Session Implementation
|
||||||
public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local, final JingleSession jingleSession) {
|
public JingleMediaSession createMediaSession(final PayloadType payloadType, final TransportCandidate remote,
|
||||||
return new JingleMediaSession(payloadType, remote, local, null,null) {
|
final TransportCandidate local, final JingleSession jingleSession) {
|
||||||
|
return new JingleMediaSession(payloadType, remote, local, null, null) {
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
|
||||||
|
@ -868,38 +881,42 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PayloadType> getPayloads() {
|
public List<PayloadType> getPayloads() {
|
||||||
return new ArrayList();
|
return getTestPayloads1();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PayloadType.Audio getPreferredAudioPayloadType() {
|
public PayloadType.Audio getPreferredAudioPayloadType() {
|
||||||
return null;
|
return (PayloadType.Audio) getTestPayloads1().get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager);
|
List<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
|
||||||
jm1.setMediaManager(jingleMediaManager);
|
trl0.add(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() {
|
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
|
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(10000);
|
Thread.sleep(10000);
|
||||||
js0.terminate();
|
js0.terminate();
|
||||||
|
@ -912,8 +929,7 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
|
|
||||||
Thread.sleep(15000);
|
Thread.sleep(15000);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,86 +938,93 @@ public class JingleManagerTest extends SmackTestCase {
|
||||||
/**
|
/**
|
||||||
* This is a simple test where the user_2 rejects the Jingle session.
|
* This is a simple test where the user_2 rejects the Jingle session.
|
||||||
*/
|
*/
|
||||||
public void testIncompatibleCodecs() {
|
|
||||||
|
|
||||||
resetCounter();
|
// 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.
|
||||||
|
|
||||||
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);
|
// public void testIncompatibleCodecs() {
|
||||||
final JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
//
|
||||||
|
// resetCounter();
|
||||||
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
//
|
||||||
/**
|
// try {
|
||||||
* Called when a new session request is detected
|
// FixedResolver tr0 = new FixedResolver("127.0.0.1", 54222);
|
||||||
*/
|
// FixedTransportManager ftm0 = new FixedTransportManager(tr0);
|
||||||
public void sessionRequested
|
// TestMediaManager tmm0 = new TestMediaManager(ftm0);
|
||||||
(
|
// tmm0.setPayloads(getTestPayloads1());
|
||||||
final JingleSessionRequest request) {
|
// List<JingleMediaManager> trl0 = new ArrayList<JingleMediaManager>();
|
||||||
System.out.println("Session request detected, from "
|
// trl0.add(tmm0);
|
||||||
+ request.getFrom() + ": accepting.");
|
//
|
||||||
|
// FixedResolver tr1 = new FixedResolver("127.0.0.1", 54567);
|
||||||
try {
|
// FixedTransportManager ftm1 = new FixedTransportManager(tr1);
|
||||||
// We reject the request
|
// TestMediaManager tmm1 = new TestMediaManager(ftm1);
|
||||||
IncomingJingleSession ses = request.accept(getTestPayloads3());
|
// tmm1.setPayloads(getTestPayloads3());
|
||||||
|
// List<JingleMediaManager> trl1 = new ArrayList<JingleMediaManager>();
|
||||||
ses.start(request);
|
// trl1.add(tmm1);
|
||||||
}
|
//
|
||||||
catch (Exception e) {
|
// JingleManager man0 = new JingleManager(getConnection(0), trl0);
|
||||||
e.printStackTrace();
|
// JingleManager man1 = new JingleManager(getConnection(1), trl1);
|
||||||
}
|
//
|
||||||
}
|
// man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
});
|
// /**
|
||||||
|
// * Called when a new session request is detected
|
||||||
// Session 0 starts a request
|
// */
|
||||||
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
// public void sessionRequested(final JingleSessionRequest request) {
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
// System.out.println("Session request detected, from " + request.getFrom() + ": accepting.");
|
||||||
getFullJID(1), getTestPayloads1());
|
//
|
||||||
|
// try {
|
||||||
session0.addListener(new JingleSessionListener() {
|
// // We reject the request
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
// JingleSession ses = request.accept();
|
||||||
}
|
//
|
||||||
|
// ses.startIncoming();
|
||||||
public void sessionClosedOnError(XMPPException e, JingleSession jingleSession) {
|
// } catch (Exception e) {
|
||||||
incCounter();
|
// e.printStackTrace();
|
||||||
System.out
|
// }
|
||||||
.println("The session has been close on error with reason: "
|
// }
|
||||||
+ e.getMessage());
|
// });
|
||||||
}
|
//
|
||||||
|
// // Session 0 starts a request
|
||||||
public void sessionDeclined(String reason, JingleSession jingleSession) {
|
// System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
||||||
incCounter();
|
// JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
System.out
|
//
|
||||||
.println("The session has been detected as rejected with reason: "
|
// session0.addListener(new JingleSessionListener() {
|
||||||
+ reason);
|
// public void sessionClosed(String reason, JingleSession jingleSession) {
|
||||||
}
|
// incCounter();
|
||||||
|
// }
|
||||||
public void sessionEstablished(PayloadType pt,
|
//
|
||||||
TransportCandidate rc, TransportCandidate lc, 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 sessionMediaReceived(JingleSession jingleSession, String participant) {
|
// }
|
||||||
// Do Nothing
|
//
|
||||||
}
|
// public void sessionDeclined(String reason, JingleSession jingleSession) {
|
||||||
|
// incCounter();
|
||||||
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
// System.out.println("The session has been detected as rejected with reason: " + reason);
|
||||||
}
|
// }
|
||||||
});
|
//
|
||||||
|
// public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
||||||
session0.start(null);
|
// JingleSession jingleSession) {
|
||||||
|
// }
|
||||||
Thread.sleep(20000);
|
//
|
||||||
|
// public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
||||||
assertTrue(valCounter() > 0);
|
// // Do Nothing
|
||||||
|
// }
|
||||||
}
|
//
|
||||||
catch (Exception e) {
|
// public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
||||||
e.printStackTrace();
|
// }
|
||||||
fail("An error occured with Jingle");
|
// });
|
||||||
}
|
//
|
||||||
}
|
// session0.startOutgoing();
|
||||||
|
//
|
||||||
|
// Thread.sleep(20000);
|
||||||
|
//
|
||||||
|
// assertTrue(valCounter() > 0);
|
||||||
|
//
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// fail("An error occured with Jingle");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
protected int getMaxConnections() {
|
protected int getMaxConnections() {
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.jivesoftware.smackx.jingle;
|
package org.jivesoftware.smackx.jingle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleMediaTest.java,v $
|
||||||
* $Revision: $
|
* $Revision: 1.2 $
|
||||||
* $Date: 09/11/2006
|
* $Date: 09/11/2006
|
||||||
* <p/>
|
* <p/>
|
||||||
* Copyright 2003-2006 Jive Software.
|
* Copyright 2003-2006 Jive Software.
|
||||||
|
@ -23,15 +23,13 @@ package org.jivesoftware.smackx.jingle;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.test.SmackTestCase;
|
import org.jivesoftware.smack.test.SmackTestCase;
|
||||||
import org.jivesoftware.smackx.jingle.*;
|
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioChannel;
|
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.jspeex.SpeexMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.multi.MultiMediaManager;
|
import org.jivesoftware.smackx.jingle.mediaimpl.multi.MultiMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.ScreenShareMediaManager;
|
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.BridgedTransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
|
import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.STUNTransportManager;
|
import org.jivesoftware.smackx.jingle.nat.STUNTransportManager;
|
||||||
|
@ -40,6 +38,8 @@ import org.jivesoftware.smackx.packet.JingleError;
|
||||||
import javax.media.MediaLocator;
|
import javax.media.MediaLocator;
|
||||||
import javax.media.format.AudioFormat;
|
import javax.media.format.AudioFormat;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the Jingle Media using the high level API
|
* 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 icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
||||||
ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478);
|
ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(
|
JingleMediaManager jingleMediaManager0 = new JmfMediaManager(icetm0);
|
||||||
x0, icetm0);
|
JingleMediaManager jingleMediaManager1 = new JmfMediaManager(icetm1);
|
||||||
final JingleManager jm1 = new JingleManager(
|
|
||||||
x1, 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);
|
jm0.addCreationListener(icetm0);
|
||||||
jm1.addCreationListener(icetm1);
|
jm1.addCreationListener(icetm1);
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager0 = new JmfMediaManager();
|
|
||||||
JingleMediaManager jingleMediaManager1 = new JmfMediaManager();
|
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager0);
|
|
||||||
jm1.setMediaManager(jingleMediaManager1);
|
|
||||||
|
|
||||||
JingleSessionRequestListener jingleSessionRequestListener = new JingleSessionRequestListener() {
|
JingleSessionRequestListener jingleSessionRequestListener = new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
try {
|
try {
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
|
|
||||||
session.addStateListener(new JingleSessionStateListener() {
|
// session.addStateListener(new JingleSessionStateListener() {
|
||||||
public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException {
|
// public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne)
|
||||||
if (newOne instanceof IncomingJingleSession.Active) {
|
// throws JingleNegotiator.JingleException {
|
||||||
throw new 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();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,14 +107,14 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
jm1.addJingleSessionRequestListener(jingleSessionRequestListener);
|
jm1.addJingleSessionRequestListener(jingleSessionRequestListener);
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
IncomingJingleSession incomingJingleSession = (IncomingJingleSession) jm1.getSession(js0.getConnection().getUser());
|
JingleSession incomingJingleSession = jm1.getSession(js0.getConnection().getUser());
|
||||||
incomingJingleSession.removeAllStateListeners();
|
//JingleSession.removeAllStateListeners();
|
||||||
|
|
||||||
Thread.sleep(15000);
|
Thread.sleep(15000);
|
||||||
|
|
||||||
|
@ -123,8 +124,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
Thread.sleep(60000);
|
Thread.sleep(60000);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,47 +140,38 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
||||||
ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478);
|
ICETransportManager icetm1 = new ICETransportManager(x1, "jivesoftware.com", 3478);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(
|
MultiMediaManager jingleMediaManager0 = new MultiMediaManager(icetm0);
|
||||||
x0, icetm0);
|
jingleMediaManager0.addMediaManager(new JmfMediaManager(icetm0));
|
||||||
final JingleManager jm1 = new JingleManager(
|
jingleMediaManager0.addMediaManager(new SpeexMediaManager(icetm0));
|
||||||
x1, icetm1);
|
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);
|
jm0.addCreationListener(icetm0);
|
||||||
jm1.addCreationListener(icetm1);
|
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() {
|
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
try {
|
try {
|
||||||
Thread.sleep(12000);
|
Thread.sleep(12000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,22 +180,23 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
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 {
|
js0.startOutgoing();
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
Thread.sleep(45000);
|
Thread.sleep(45000);
|
||||||
js0.terminate();
|
js0.terminate();
|
||||||
|
@ -213,8 +205,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,36 +220,36 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
XMPPConnection x0 = getConnection(0);
|
XMPPConnection x0 = getConnection(0);
|
||||||
XMPPConnection x1 = getConnection(1);
|
XMPPConnection x1 = getConnection(1);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(
|
JingleMediaManager jingleMediaManager0 = new SpeexMediaManager(new STUNTransportManager());
|
||||||
x0, new STUNTransportManager());
|
JingleMediaManager jingleMediaManager1 = new SpeexMediaManager(new STUNTransportManager());
|
||||||
final JingleManager jm1 = new JingleManager(
|
|
||||||
x1, new STUNTransportManager());
|
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager0 = new SpeexMediaManager();
|
List<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
|
||||||
JingleMediaManager jingleMediaManager1 = new SpeexMediaManager();
|
List<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager0);
|
jml0.add(jingleMediaManager0);
|
||||||
jm1.setMediaManager(jingleMediaManager1);
|
jml1.add(jingleMediaManager1);
|
||||||
|
|
||||||
|
final JingleManager jm0 = new JingleManager(x0, jml0);
|
||||||
|
final JingleManager jm1 = new JingleManager(x1, jml1);
|
||||||
|
|
||||||
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
|
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(150000);
|
Thread.sleep(150000);
|
||||||
js0.terminate();
|
js0.terminate();
|
||||||
|
@ -268,8 +259,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
x0.disconnect();
|
x0.disconnect();
|
||||||
x1.disconnect();
|
x1.disconnect();
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,36 +272,39 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
XMPPConnection x0 = getConnection(0);
|
XMPPConnection x0 = getConnection(0);
|
||||||
XMPPConnection x1 = getConnection(1);
|
XMPPConnection x1 = getConnection(1);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(
|
ICETransportManager icetm0 = new ICETransportManager(x0, "stun.xten.net", 3478);
|
||||||
x0, new ICETransportManager(x0,"stun.xten.net",3478));
|
ICETransportManager icetm1 = new ICETransportManager(x1, "stun.xten.net", 3478);
|
||||||
final JingleManager jm1 = new JingleManager(
|
|
||||||
x1, new ICETransportManager(x1,"stun.xten.net",3478));
|
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager0 = new ScreenShareMediaManager();
|
JingleMediaManager jingleMediaManager0 = new ScreenShareMediaManager(icetm0);
|
||||||
JingleMediaManager jingleMediaManager1 = new ScreenShareMediaManager();
|
JingleMediaManager jingleMediaManager1 = new ScreenShareMediaManager(icetm1);
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager0);
|
List<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
|
||||||
jm1.setMediaManager(jingleMediaManager1);
|
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() {
|
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
|
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(150000);
|
Thread.sleep(150000);
|
||||||
js0.terminate();
|
js0.terminate();
|
||||||
|
@ -321,8 +314,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
x0.disconnect();
|
x0.disconnect();
|
||||||
x1.disconnect();
|
x1.disconnect();
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,40 +334,45 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
BridgedTransportManager btm0 = new BridgedTransportManager(x0);
|
BridgedTransportManager btm0 = new BridgedTransportManager(x0);
|
||||||
BridgedTransportManager btm1 = new BridgedTransportManager(x1);
|
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);
|
jm0.addCreationListener(btm0);
|
||||||
jm1.addCreationListener(btm1);
|
jm1.addCreationListener(btm1);
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager = new JmfMediaManager();
|
|
||||||
JingleMediaManager jingleMediaManager2 = new JmfMediaManager();
|
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager);
|
|
||||||
jm1.setMediaManager(jingleMediaManager2);
|
|
||||||
|
|
||||||
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
|
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
js0.sendFormattedError(JingleError.UNSUPPORTED_TRANSPORTS);
|
//js0.sendFormattedError(JingleError.UNSUPPORTED_TRANSPORTS);
|
||||||
|
js0.sendPacket(js0.createJingleError(null, JingleError.UNSUPPORTED_TRANSPORTS));
|
||||||
|
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
|
@ -386,8 +383,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
x0.disconnect();
|
x0.disconnect();
|
||||||
x1.disconnect();
|
x1.disconnect();
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,8 +394,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(250000);
|
Thread.sleep(250000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,36 +410,37 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
BridgedTransportManager btm0 = new BridgedTransportManager(x0);
|
BridgedTransportManager btm0 = new BridgedTransportManager(x0);
|
||||||
BridgedTransportManager btm1 = new BridgedTransportManager(x1);
|
BridgedTransportManager btm1 = new BridgedTransportManager(x1);
|
||||||
|
|
||||||
final JingleManager jm0 = new JingleManager(x0, btm0);
|
|
||||||
final JingleManager jm1 = new JingleManager(x1, btm1);
|
|
||||||
|
|
||||||
jm0.addCreationListener(btm0);
|
JingleMediaManager jingleMediaManager0 = new JmfMediaManager(btm0);
|
||||||
jm1.addCreationListener(btm1);
|
JingleMediaManager jingleMediaManager1 = new JmfMediaManager(btm1);
|
||||||
|
|
||||||
JingleMediaManager jingleMediaManager = new JmfMediaManager();
|
List<JingleMediaManager> jml0 = new ArrayList<JingleMediaManager>();
|
||||||
|
List<JingleMediaManager> jml1 = new ArrayList<JingleMediaManager>();
|
||||||
|
|
||||||
jm0.setMediaManager(jingleMediaManager);
|
jml0.add(jingleMediaManager0);
|
||||||
jm1.setMediaManager(jingleMediaManager);
|
jml1.add(jingleMediaManager1);
|
||||||
|
|
||||||
|
final JingleManager jm0 = new JingleManager(x0, jml0);
|
||||||
|
final JingleManager jm1 = new JingleManager(x1, jml1);
|
||||||
|
|
||||||
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
jm1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
JingleSession session = request.accept();
|
||||||
|
|
||||||
session.start(request);
|
session.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
OutgoingJingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
JingleSession js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
|
@ -454,7 +450,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
js0 = jm0.createOutgoingJingleSession(x1.getUser());
|
||||||
|
|
||||||
js0.start();
|
js0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(20000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
|
@ -465,8 +461,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
x0.disconnect();
|
x0.disconnect();
|
||||||
x1.disconnect();
|
x1.disconnect();
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,16 +470,19 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
public void testAudioChannelOpenClose() {
|
public void testAudioChannelOpenClose() {
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
try {
|
try {
|
||||||
AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null);
|
AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost()
|
||||||
AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null);
|
.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();
|
audioChannel0.start();
|
||||||
audioChannel1.start();
|
audioChannel1.start();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(10000);
|
Thread.sleep(10000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,12 +491,10 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,8 +503,12 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
public void testAudioChannelStartStop() {
|
public void testAudioChannelStartStop() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7002, 7020, new AudioFormat(AudioFormat.GSM_RTP),null);
|
AudioChannel audioChannel0 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost()
|
||||||
AudioChannel audioChannel1 = new AudioChannel(new MediaLocator("javasound://"), InetAddress.getLocalHost().getHostAddress(), InetAddress.getLocalHost().getHostAddress(), 7020, 7002, new AudioFormat(AudioFormat.GSM_RTP),null);
|
.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++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
|
|
||||||
|
@ -517,8 +517,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(10000);
|
Thread.sleep(10000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,13 +526,11 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(3000);
|
Thread.sleep(3000);
|
||||||
}
|
} catch (InterruptedException e) {
|
||||||
catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
package org.jivesoftware.smackx.jingle;
|
package org.jivesoftware.smackx.jingle;
|
||||||
|
|
||||||
import org.jivesoftware.smack.test.SmackTestCase;
|
import org.jivesoftware.smack.test.SmackTestCase;
|
||||||
import org.jivesoftware.smackx.jingle.nat.BasicResolver;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.BasicTransportManager;
|
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 {
|
public class JingleSessionTest extends SmackTestCase {
|
||||||
|
|
||||||
|
@ -11,9 +16,16 @@ public class JingleSessionTest extends SmackTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEqualsObject() {
|
public void testEqualsObject() {
|
||||||
JingleSession js1 = new OutgoingJingleSession(getConnection(0), "res1", null, new BasicTransportManager());
|
|
||||||
JingleSession js2 = new OutgoingJingleSession(getConnection(1), "res1", null, new BasicTransportManager());
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 54222);
|
||||||
JingleSession js3 = new OutgoingJingleSession(getConnection(2), "res2", null, new BasicTransportManager());
|
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(js1.getSid());
|
||||||
System.out.println(js2.getSid());
|
System.out.println(js2.getSid());
|
||||||
|
@ -35,8 +47,14 @@ public class JingleSessionTest extends SmackTestCase {
|
||||||
String ini2 = "initiator2";
|
String ini2 = "initiator2";
|
||||||
String sid2 = "sid2";
|
String sid2 = "sid2";
|
||||||
|
|
||||||
JingleSession js1 = new OutgoingJingleSession(getConnection(0), sid1, null, new BasicTransportManager());
|
FixedResolver tr1 = new FixedResolver("127.0.0.1", 54222);
|
||||||
JingleSession js2 = new OutgoingJingleSession(getConnection(1), sid2, null, new BasicTransportManager());
|
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...
|
// For a packet, we should be able to get a session that handles that...
|
||||||
assertNotNull(JingleSession.getInstanceFor(getConnection(0)));
|
assertNotNull(JingleSession.getInstanceFor(getConnection(0)));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* $RCSfile$
|
* $RCSfile: JingleSupportTests.java,v $
|
||||||
* $Revision$
|
* $Revision: 1.1 $
|
||||||
* $Date$
|
* $Date: 2007/07/02 17:41:06 $
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
package org.jivesoftware.smackx.jingle.nat;
|
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.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.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
|
@ -5,15 +5,18 @@ import de.javawi.jstun.test.demo.ice.ICENegociator;
|
||||||
import de.javawi.jstun.util.UtilityException;
|
import de.javawi.jstun.util.UtilityException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.test.SmackTestCase;
|
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.JingleSessionListener;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
|
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.media.PayloadType;
|
||||||
|
import org.jivesoftware.smackx.jingle.mediaimpl.test.TestMediaManager;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the STUN IP resolver.
|
* Test the STUN IP resolver.
|
||||||
|
@ -60,16 +63,14 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
public void testGetPreferredCandidate() throws Exception {
|
public void testGetPreferredCandidate() throws Exception {
|
||||||
int highestPref = 100;
|
int highestPref = 100;
|
||||||
|
|
||||||
TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2,
|
TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, "password", 3468, "username1", 1, ICECandidate.Type.prflx);
|
||||||
"password", 3468, "username1", 1, ICECandidate.Type.prflx);
|
TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, "password", 3469, "username2", 15,
|
||||||
TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10,
|
ICECandidate.Type.prflx);
|
||||||
"password", 3469, "username2", 15, ICECandidate.Type.prflx);
|
TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, "password", 3468, "usernameH", highestPref,
|
||||||
TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2,
|
ICECandidate.Type.prflx);
|
||||||
"password", 3468, "usernameH", highestPref, ICECandidate.Type.prflx);
|
TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, "password", 3469, "username3", 2,
|
||||||
TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10,
|
ICECandidate.Type.prflx);
|
||||||
"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 cand4 = new ICECandidate("192.168.4.1", 3, 2,
|
|
||||||
"password", 3468, "username4", 78, ICECandidate.Type.prflx);
|
|
||||||
|
|
||||||
STUNResolver stunResolver = new STUNResolver() {
|
STUNResolver stunResolver = new STUNResolver() {
|
||||||
};
|
};
|
||||||
|
@ -90,16 +91,14 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
public void testGetPreferredCandidateICE() throws Exception {
|
public void testGetPreferredCandidateICE() throws Exception {
|
||||||
int highestPref = 100;
|
int highestPref = 100;
|
||||||
|
|
||||||
TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2,
|
TransportCandidate cand1 = new ICECandidate("192.168.2.1", 3, 2, "password", 3468, "username1", 1, ICECandidate.Type.prflx);
|
||||||
"password", 3468, "username1", 1, ICECandidate.Type.prflx);
|
TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10, "password", 3469, "username2", 15,
|
||||||
TransportCandidate cand2 = new ICECandidate("192.168.5.1", 2, 10,
|
ICECandidate.Type.prflx);
|
||||||
"password", 3469, "username2", 15, ICECandidate.Type.prflx);
|
TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2, "password", 3468, "usernameH", highestPref,
|
||||||
TransportCandidate candH = new ICECandidate("192.168.2.11", 1, 2,
|
ICECandidate.Type.prflx);
|
||||||
"password", 3468, "usernameH", highestPref, ICECandidate.Type.prflx);
|
TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10, "password", 3469, "username3", 2,
|
||||||
TransportCandidate cand3 = new ICECandidate("192.168.2.10", 2, 10,
|
ICECandidate.Type.prflx);
|
||||||
"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 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) {
|
ICEResolver iceResolver = new ICEResolver(getConnection(0), "stun.xten.net", 3478) {
|
||||||
};
|
};
|
||||||
|
@ -132,18 +131,20 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
|
|
||||||
for (Candidate candidate : cc.getSortedCandidates())
|
for (Candidate candidate : cc.getSortedCandidates())
|
||||||
try {
|
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());
|
transportCandidate.setLocalIp(candidate.getBase().getAddress().getInetAddress().getHostAddress());
|
||||||
System.out.println("C: " + candidate.getAddress().getInetAddress() + "|" + candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority());
|
System.out.println("C: " + candidate.getAddress().getInetAddress() + "|"
|
||||||
}
|
+ candidate.getBase().getAddress().getInetAddress() + " p:" + candidate.getPriority());
|
||||||
catch (UtilityException e) {
|
} catch (UtilityException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
} catch (UnknownHostException e) {
|
||||||
catch (UnknownHostException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
Candidate candidate = cc.getSortedCandidates().get(0);
|
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(""))
|
if (first.equals(""))
|
||||||
first = temp;
|
first = temp;
|
||||||
assertEquals(first, temp);
|
assertEquals(first, temp);
|
||||||
|
@ -211,13 +212,11 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
stunResolver.initializeAndWait();
|
stunResolver.initializeAndWait();
|
||||||
Thread.sleep(55000);
|
Thread.sleep(55000);
|
||||||
assertTrue(valCounter() > 0);
|
assertTrue(valCounter() > 0);
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a list of payload types
|
* Generate a list of payload types
|
||||||
*
|
*
|
||||||
|
@ -262,21 +261,32 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
tr1.resolve(null);
|
tr1.resolve(null);
|
||||||
tr2.resolve(null);
|
tr2.resolve(null);
|
||||||
|
|
||||||
final JingleManager man0 = new JingleManager(getConnection(0), tr1);
|
STUNTransportManager stm0 = new STUNTransportManager();
|
||||||
final JingleManager man1 = new JingleManager(getConnection(1), tr2);
|
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() {
|
man1.addJingleSessionRequestListener(new JingleSessionRequestListener() {
|
||||||
/**
|
/**
|
||||||
* Called when a new session request is detected
|
* Called when a new session request is detected
|
||||||
*/
|
*/
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
System.out.println("Session request detected, from "
|
System.out.println("Session request detected, from " + request.getFrom() + ": accepting.");
|
||||||
+ request.getFrom() + ": accepting.");
|
|
||||||
|
|
||||||
// We accept the request
|
// We accept the request
|
||||||
IncomingJingleSession session1;
|
JingleSession session1;
|
||||||
try {
|
try {
|
||||||
session1 = request.accept(getTestPayloads2());
|
session1 = request.accept();
|
||||||
session1.addListener(new JingleSessionListener() {
|
session1.addListener(new JingleSessionListener() {
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
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 sessionDeclined(String reason, JingleSession jingleSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionEstablished(PayloadType pt,
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
||||||
TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) {
|
JingleSession jingleSession) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out
|
System.out.println("Responder: the session is fully established.");
|
||||||
.println("Responder: the session is fully established.");
|
|
||||||
System.out.println("+ Payload Type: " + pt.getId());
|
System.out.println("+ Payload Type: " + pt.getId());
|
||||||
System.out.println("+ Local IP/port: " + lc.getIp() + ":"
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
||||||
+ lc.getPort());
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
||||||
System.out.println("+ Remote IP/port: " + rc.getIp() + ":"
|
|
||||||
+ rc.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
||||||
|
@ -306,9 +313,8 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
session1.start(request);
|
session1.startIncoming();
|
||||||
}
|
} catch (XMPPException e) {
|
||||||
catch (XMPPException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,8 +322,7 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
|
|
||||||
// Session 0 starts a request
|
// Session 0 starts a request
|
||||||
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
System.out.println("Starting session request, to " + getFullJID(1) + "...");
|
||||||
OutgoingJingleSession session0 = man0.createOutgoingJingleSession(
|
JingleSession session0 = man0.createOutgoingJingleSession(getFullJID(1));
|
||||||
getFullJID(1), getTestPayloads1());
|
|
||||||
|
|
||||||
session0.addListener(new JingleSessionListener() {
|
session0.addListener(new JingleSessionListener() {
|
||||||
public void sessionClosed(String reason, JingleSession jingleSession) {
|
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 sessionDeclined(String reason, JingleSession jingleSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionEstablished(PayloadType pt,
|
public void sessionEstablished(PayloadType pt, TransportCandidate rc, TransportCandidate lc,
|
||||||
TransportCandidate rc, TransportCandidate lc, JingleSession jingleSession) {
|
JingleSession jingleSession) {
|
||||||
incCounter();
|
incCounter();
|
||||||
System.out.println("Initiator: the session is fully established.");
|
System.out.println("Initiator: the session is fully established.");
|
||||||
System.out.println("+ Payload Type: " + pt.getId());
|
System.out.println("+ Payload Type: " + pt.getId());
|
||||||
System.out.println("+ Local IP/port: " + lc.getIp() + ":"
|
System.out.println("+ Local IP/port: " + lc.getIp() + ":" + lc.getPort());
|
||||||
+ lc.getPort());
|
System.out.println("+ Remote IP/port: " + rc.getIp() + ":" + rc.getPort());
|
||||||
System.out.println("+ Remote IP/port: " + rc.getIp() + ":"
|
|
||||||
+ rc.getPort());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
public void sessionMediaReceived(JingleSession jingleSession, String participant) {
|
||||||
|
@ -347,14 +350,13 @@ public class STUNResolverTest extends SmackTestCase {
|
||||||
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
session0.start(null);
|
session0.startOutgoing();
|
||||||
|
|
||||||
Thread.sleep(60000);
|
Thread.sleep(60000);
|
||||||
|
|
||||||
assertTrue(valCounter() == 2);
|
assertTrue(valCounter() == 2);
|
||||||
|
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
fail("An error occured with Jingle");
|
fail("An error occured with Jingle");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue