From 9627fef1392e201ec8d2df9cd94ed3eaf131e0e3 Mon Sep 17 00:00:00 2001 From: Thiago Camargo Date: Tue, 20 Mar 2007 18:52:57 +0000 Subject: [PATCH] STUN fix and Media Tunning git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7610 b35dd754-fafc-0310-a699-88a17e54d16e --- .../smackx/jingle/IncomingJingleSession.java | 73 ++++++++------- .../smackx/jingle/JingleManager.java | 4 +- .../smackx/jingle/JingleSession.java | 78 +++++++++------- .../jingle/mediaimpl/jmf/AudioChannel.java | 89 ++++++++++++++++--- .../mediaimpl/jmf/AudioMediaSession.java | 4 +- .../jingle/nat/BridgedTransportManager.java | 6 +- .../smackx/jingle/nat/ICEResolver.java | 75 ++++++++-------- .../smackx/jingle/nat/RTPBridge.java | 2 + .../smackx/jingle/JingleMediaTest.java | 34 +++++-- 9 files changed, 239 insertions(+), 126 deletions(-) diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java index 6dab8a255..790e061e4 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/IncomingJingleSession.java @@ -97,16 +97,17 @@ public class IncomingJingleSession extends JingleSession { /** * Constructor for a Jingle incoming session * - * @param conn the XMPP connection - * @param responder the responder - * @param transportManager The transport manager + * @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, String sid) { + List payloadTypes, JingleTransportManager transportManager, JingleSessionRequest initialJingleSessionRequest) throws XMPPException { super(conn, responder, conn.getUser()); - setSid(sid); + setSid(initialJingleSessionRequest.getSessionID()); // Create the states... @@ -130,19 +131,38 @@ public class IncomingJingleSession extends JingleSession { setTransportNeg(new TransportNegotiator.Ice(this, resolver)); } + // 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."); + } + } /** * 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 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, String sid) { - this(conn, responder, payloadTypes, transportManager, sid); + List payloadTypes, JingleTransportManager transportManager, JingleMediaManager jingleMediaManager, JingleSessionRequest initialJingleSessionRequest) throws XMPPException { + this(conn, responder, payloadTypes, transportManager, initialJingleSessionRequest); this.jingleMediaManager = jingleMediaManager; } @@ -153,27 +173,6 @@ public class IncomingJingleSession extends JingleSession { * @throws XMPPException */ public void start(JingleSessionRequest initialJingleSessionRequest) throws XMPPException { - if (invalidState()) { - Jingle packet = initialJingleSessionRequest.getJingle(); - if (packet != null) { - - // Initialize the session information - setSid(packet.getSid()); - - // Establish the default state - setState(accepting); - - updatePacketListener(); - respond(packet); - } - else { - throw new IllegalStateException( - "Session request with null Jingle packet."); - } - } - else { - throw new IllegalStateException("Starting session without null state."); - } } /** @@ -182,7 +181,15 @@ public class IncomingJingleSession extends JingleSession { * @throws XMPPException */ public void start() throws XMPPException { - start(this.getInitialSessionRequest()); + + } + + /** + * Force a call acceptance. Used to accept a hooked call. + * @deprecated Avoid to use this method. Not compliance. + */ + public void accept(){ + setState(active); } /** diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java index ef81bef9a..516c75f48 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleManager.java @@ -649,10 +649,10 @@ public class JingleManager implements JingleSessionListener { if (jingleMediaManager != null) session = new IncomingJingleSession(connection, request - .getFrom(), payloadTypes, jingleTransportManager, jingleMediaManager, request.getSessionID()); + .getFrom(), payloadTypes, jingleTransportManager, jingleMediaManager, request); else session = new IncomingJingleSession(connection, request - .getFrom(), payloadTypes, jingleTransportManager, request.getSessionID()); + .getFrom(), payloadTypes, jingleTransportManager, request); triggerSessionCreated(session); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java index f6bceb9d7..e28f5bf79 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/JingleSession.java @@ -124,7 +124,7 @@ public abstract class JingleSession extends JingleNegotiator { * @param jingleMediaManager the jingleMediaManager */ protected JingleSession(XMPPConnection conn, String initiator, String responder, - String sessionid, JingleMediaManager jingleMediaManager) { + String sessionid, JingleMediaManager jingleMediaManager) { super(conn); this.mediaNeg = null; @@ -389,21 +389,25 @@ public abstract class JingleSession extends JingleNegotiator { if (invalidState()) { throw new IllegalStateException( "Illegal state in dispatch packet in Session manager."); - } else { + } + else { if (iq == null) { // If there is no input packet, then we must be inviting... jout = getState().eventInvite(); - } else { + } + else { if (iq.getType().equals(IQ.Type.ERROR)) { // Process errors getState().eventError(iq); - } else if (iq.getType().equals(IQ.Type.RESULT)) { + } + else if (iq.getType().equals(IQ.Type.RESULT)) { // Process ACKs if (isExpectedId(iq.getPacketID())) { jout = getState().eventAck(iq); removeExpectedId(iq.getPacketID()); } - } else if (iq instanceof Jingle) { + } + else if (iq instanceof Jingle) { // It is not an error: it is a Jingle packet... Jingle jin = (Jingle) iq; Jingle.Action action = jin.getAction(); @@ -411,17 +415,22 @@ public abstract class JingleSession extends JingleNegotiator { if (action != null) { if (action.equals(Jingle.Action.SESSIONACCEPT)) { jout = getState().eventAccept(jin); - } else if (action.equals(Jingle.Action.SESSIONINFO)) { + } + else if (action.equals(Jingle.Action.SESSIONINFO)) { jout = getState().eventInfo(jin); - } else if (action.equals(Jingle.Action.SESSIONINITIATE)) { + } + else if (action.equals(Jingle.Action.SESSIONINITIATE)) { if (getState() != null) jout = getState().eventInitiate(jin); - } else if (action.equals(Jingle.Action.SESSIONREDIRECT)) { + } + else if (action.equals(Jingle.Action.SESSIONREDIRECT)) { jout = getState().eventRedirect(jin); - } else if (action.equals(Jingle.Action.SESSIONTERMINATE)) { + } + else if (action.equals(Jingle.Action.SESSIONTERMINATE)) { jout = getState().eventTerminate(jin); } - } else { + } + else { jout = errorMalformedStanza(iq); } } @@ -506,7 +515,7 @@ public abstract class JingleSession extends JingleNegotiator { * @return the new Jingle packet */ private Jingle sendJingleParts(IQ iq, Jingle jSes, Jingle jDesc, - Jingle jTrans) { + Jingle jTrans) { Jingle response = null; if (jSes != null) { @@ -514,7 +523,8 @@ public abstract class JingleSession extends JingleNegotiator { jSes.addTransports(jTrans.getTransportsList()); response = sendFormattedJingle(iq, jSes); - } else { + } + else { // If we don't have a valid session message, then we must send // separated messages for transport and jmf... if (jDesc != null) { @@ -580,7 +590,8 @@ public abstract class JingleSession extends JingleNegotiator { if (jout.getTo() == null) { if (iq != null) { jout.setTo(iq.getFrom()); - } else { + } + else { jout.setTo(other); } } @@ -588,7 +599,8 @@ public abstract class JingleSession extends JingleNegotiator { if (jout.getFrom() == null) { if (iq != null) { jout.setFrom(iq.getTo()); - } else { + } + else { jout.setFrom(me); } } @@ -681,7 +693,8 @@ public abstract class JingleSession extends JingleNegotiator { if (jda.size() > 1) { throw new XMPPException( "Unsupported feature: the number of accepted content descriptions is greater than 1."); - } else if (jda.size() == 1) { + } + else if (jda.size() == 1) { JingleContentDescription jd = (JingleContentDescription) jda.get(0); if (jd.getJinglePayloadTypesCount() > 1) { throw new XMPPException( @@ -713,13 +726,15 @@ public abstract class JingleSession extends JingleNegotiator { if (jta.size() > 1) { throw new XMPPException( "Unsupported feature: the number of accepted transports is greater than 1."); - } else if (jta.size() == 1) { + } + else if (jta.size() == 1) { org.jivesoftware.smackx.packet.JingleTransport jt = (org.jivesoftware.smackx.packet.JingleTransport) jta.get(0); if (jt.getCandidatesCount() > 1) { throw new XMPPException( "Unsupported feature: the number of accepted transport candidates is greater than 1."); - } else if (jt.getCandidatesCount() == 1) { + } + else if (jt.getCandidatesCount() == 1) { JingleTransportCandidate jtc = (JingleTransportCandidate) jt .getCandidatesList().get(0); acceptedLocalCandidate = jtc.getMediaTransport(); @@ -761,7 +776,8 @@ public abstract class JingleSession extends JingleNegotiator { if (other.initiator != null) { return false; } - } else if (!initiator.equals(other.initiator)) { + } + else if (!initiator.equals(other.initiator)) { //Todo check behavior // return false; } @@ -770,7 +786,8 @@ public abstract class JingleSession extends JingleNegotiator { if (other.responder != null) { return false; } - } else if (!responder.equals(other.responder)) { + } + else if (!responder.equals(other.responder)) { return false; } @@ -778,7 +795,8 @@ public abstract class JingleSession extends JingleNegotiator { if (other.sid != null) { return false; } - } else if (!sid.equals(other.sid)) { + } + else if (!sid.equals(other.sid)) { return false; } @@ -922,12 +940,14 @@ public abstract class JingleSession extends JingleNegotiator { System.out.println("Ignored Jingle(INI): " + iq.toXML()); return false; } - } else { + } + else { // We accept some non-Jingle IQ packets: ERRORs and ACKs if (iq.getType().equals(IQ.Type.SET)) { System.out.println("Ignored Jingle(TYPE): " + iq.toXML()); return false; - } else if (iq.getType().equals(IQ.Type.GET)) { + } + else if (iq.getType().equals(IQ.Type.GET)) { System.out.println("Ignored Jingle(TYPE): " + iq.toXML()); return false; } @@ -1038,7 +1058,7 @@ public abstract class JingleSession extends JingleNegotiator { * Trigger a session established event. */ protected void triggerSessionEstablished(PayloadType pt, - TransportCandidate rc, TransportCandidate lc) { + TransportCandidate rc, TransportCandidate lc) { ArrayList listeners = getListenersList(); Iterator iter = listeners.iterator(); while (iter.hasNext()) { @@ -1049,12 +1069,12 @@ public abstract class JingleSession extends JingleNegotiator { } } if (jingleMediaManager != null) { + rc.removeCandidateEcho(); + lc.removeCandidateEcho(); + jingleMediaSession = jingleMediaManager.createMediaSession(pt, rc, lc); if (jingleMediaSession != null) { - rc.removeCandidateEcho(); - lc.removeCandidateEcho(); - jingleMediaSession.startTrasmit(); jingleMediaSession.startReceive(); @@ -1113,9 +1133,7 @@ public abstract class JingleSession extends JingleNegotiator { */ public void terminate() throws XMPPException { if (isClosed()) return; - //remo System.out.println("State: " + this.getState()); - Jingle result = null; Jingle jout = new Jingle(Jingle.Action.SESSIONTERMINATE); jout.setType(IQ.Type.SET); sendFormattedJingle(jout); @@ -1151,7 +1169,7 @@ public abstract class JingleSession extends JingleNegotiator { * @return The created IQ packet. */ public static IQ createIQ(String ID, String to, String from, - IQ.Type type) { + IQ.Type type) { IQ iqPacket = new IQ() { public String getChildElementXML() { return null; @@ -1177,7 +1195,7 @@ public abstract class JingleSession extends JingleNegotiator { * @return The created IQ packet. */ public static IQ createError(String ID, String to, String from, - int errCode, String errStr) { + int errCode, String errStr) { IQ iqError = createIQ(ID, to, from, IQ.Type.ERROR); XMPPError error = new XMPPError(new XMPPError.Condition(errStr)); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java index c73347645..b1b648dcc 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioChannel.java @@ -21,6 +21,8 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf; import javax.media.*; import javax.media.control.TrackControl; +import javax.media.control.PacketSizeControl; +import javax.media.control.BufferControl; import javax.media.format.AudioFormat; import javax.media.protocol.ContentDescriptor; import javax.media.protocol.DataSource; @@ -57,7 +59,7 @@ public class AudioChannel { private MediaLocator locator; private String localIpAddress; - private String ipAddress; + private String remoteIpAddress; private int localPort; private int portBase; private Format format; @@ -76,30 +78,25 @@ public class AudioChannel { * * @param locator media locator * @param localIpAddress local IP address - * @param ipAddress remote IP address + * @param remoteIpAddress remote IP address * @param localPort local port number * @param remotePort remote port number * @param format audio format */ public AudioChannel(MediaLocator locator, String localIpAddress, - String ipAddress, + String remoteIpAddress, int localPort, int remotePort, Format format) { this.locator = locator; this.localIpAddress = localIpAddress; - this.ipAddress = ipAddress; + this.remoteIpAddress = remoteIpAddress; this.localPort = localPort; this.portBase = remotePort; this.format = format; - // Create a processor for the specified jmf locator - String result = createProcessor(); - if (result != null) { - started = false; - } } /** @@ -111,8 +108,14 @@ public class AudioChannel { */ public synchronized String start() { if (started) return null; + + // Create a processor for the specified jmf locator + String result = createProcessor(); + if (result != null) { + started = false; + } + started = true; - String result; // Create an RTP session to transmit the output of the // processor to the specified IP address and port no. @@ -121,7 +124,6 @@ public class AudioChannel { processor.close(); processor = null; started = false; - return result; } // Start the transmission @@ -226,6 +228,39 @@ public class AudioChannel { tracks[i].setFormat(chosen); System.err.println("Track " + i + " is set to transmit as:"); System.err.println(" " + chosen); + + if (tracks[i].getFormat() instanceof AudioFormat) { + int packetRate = 20; + PacketSizeControl pktCtrl = (PacketSizeControl) processor.getControl(PacketSizeControl.class.getName()); + if (pktCtrl != null) { + try { + pktCtrl.setPacketSize(getPacketSize(tracks[i].getFormat(), packetRate)); + } + catch (IllegalArgumentException e) { + pktCtrl.setPacketSize(80); + // Do nothing + } + } + + if (tracks[i].getFormat().getEncoding().equals(AudioFormat.ULAW_RTP)) { + Codec codec[] = new Codec[3]; + + codec[0] = new com.ibm.media.codec.audio.rc.RCModule(); + codec[1] = new com.ibm.media.codec.audio.ulaw.JavaEncoder(); + codec[2] = new com.sun.media.codec.audio.ulaw.Packetizer(); + ((com.sun.media.codec.audio.ulaw.Packetizer) codec + [2]).setPacketSize(160); + + try { + tracks[i].setCodecChain(codec); + } + catch (UnsupportedPlugInException e) { + e.printStackTrace(); + } + } + + } + atLeastOneTrack = true; } else @@ -249,6 +284,28 @@ public class AudioChannel { return null; } + /** + * Get the best packet size for a given codec and a codec rate + * + * @param codecFormat + * @param milliseconds + * @return + * @throws IllegalArgumentException + */ + private int getPacketSize(Format codecFormat, int milliseconds) throws IllegalArgumentException { + String encoding = codecFormat.getEncoding(); + if (encoding.equalsIgnoreCase(AudioFormat.GSM) || + encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) { + return milliseconds * 4; // 1 byte per millisec + } + else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) || + encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) { + return milliseconds * 8; + } + else { + throw new IllegalArgumentException("Unknown codec type"); + } + } /** * Use the RTPManager API to create sessions for each jmf @@ -274,7 +331,7 @@ public class AudioChannel { rtpMgrs[i] = RTPManager.newInstance(); port = portBase + 2 * i; - ipAddr = InetAddress.getByName(ipAddress); + ipAddr = InetAddress.getByName(remoteIpAddress); localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress), localPort); @@ -284,11 +341,17 @@ public class AudioChannel { rtpMgrs[i].addReceiveStreamListener(audioReceiver); rtpMgrs[i].addSessionListener(audioReceiver); + BufferControl bc = (BufferControl) rtpMgrs[i].getControl("javax.media.control.BufferControl"); + if (bc != null) { + int bl = 160; + bc.setBufferLength(bl); + } + rtpMgrs[i].initialize(localAddr); rtpMgrs[i].addTarget(destAddr); - System.err.println("Created RTP session at " + localPort + " to: " + ipAddress + " " + port); + System.err.println("Created RTP session at " + localPort + " to: " + remoteIpAddress + " " + port); sendStream = rtpMgrs[i].createSendStream(dataOutput, i); diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java index 4a1abce84..1aa05db7b 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/jmf/AudioMediaSession.java @@ -41,7 +41,7 @@ import java.net.ServerSocket; public class AudioMediaSession extends JingleMediaSession { private AudioChannel audioChannel; - private String locator = "javasound://"; + private String locator = "dsound://"; /** * Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates @@ -52,7 +52,7 @@ public class AudioMediaSession extends JingleMediaSession { */ public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local) { - this(payloadType, remote, local, "javasound://"); + this(payloadType, remote, local, "dsound://"); } /** diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java index 09ff8aa2d..e49d540cd 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/BridgedTransportManager.java @@ -42,7 +42,11 @@ public class BridgedTransportManager extends JingleTransportManager implements J this.xmppConnection = xmppConnection; } - // Return the correspondent resolver + /** + * Return the correspondent resolver + * @param session correspondent Jingle Session + * @return resolver + */ protected TransportResolver createResolver(JingleSession session) { BridgedResolver bridgedResolver = new BridgedResolver(this.xmppConnection); return bridgedResolver; diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java index 13508f902..3dbf717de 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/ICEResolver.java @@ -176,64 +176,65 @@ public class ICEResolver extends TransportResolver { e.printStackTrace(); } - } + // Get Public Candidate From XMPP Server - // Get Public Candidate From XMPP Server + if (iceNegociator.getPublicCandidate() == null) { - if (iceNegociator.getPublicCandidate() == null) { + String publicIp = RTPBridge.getPublicIP(connection); - String publicIp = RTPBridge.getPublicIP(connection); + if (publicIp != null && !publicIp.equals("")) { - if (publicIp != null && !publicIp.equals("")) { + Enumeration ifaces = null; - Enumeration ifaces = null; + try { + ifaces = NetworkInterface.getNetworkInterfaces(); + } + catch (SocketException e) { + e.printStackTrace(); + } - try { - ifaces = NetworkInterface.getNetworkInterfaces(); - } - catch (SocketException e) { - e.printStackTrace(); - } + // If detect this address in local machine, don't use it. - // If detect this address in local machine, don't use it. + boolean found = false; - boolean found = false; + while (ifaces.hasMoreElements() && !false) { - while (ifaces.hasMoreElements() && !false) { + NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); + Enumeration iaddresses = iface.getInetAddresses(); - NetworkInterface iface = (NetworkInterface) ifaces.nextElement(); - Enumeration iaddresses = iface.getInetAddresses(); - - while (iaddresses.hasMoreElements()) { - InetAddress iaddress = (InetAddress) iaddresses.nextElement(); - if (iaddress.getHostAddress().indexOf(publicIp) > -1) { - found = true; - break; + while (iaddresses.hasMoreElements()) { + InetAddress iaddress = (InetAddress) iaddresses.nextElement(); + if (iaddress.getHostAddress().indexOf(publicIp) > -1) { + found = true; + break; + } } } - } - - if (!found) { - try { - TransportCandidate publicCandidate = new ICECandidate( - publicIp, 1, 0, String.valueOf(Math.abs(random.nextLong())), getFreePort(), "1", 0, "srflx"); - publicCandidate.setLocalIp(InetAddress.getLocalHost().getHostAddress()); + if (!found) { try { - publicCandidate.addCandidateEcho(session); + TransportCandidate publicCandidate = new ICECandidate( + publicIp, 1, 0, String.valueOf(Math.abs(random.nextLong())), getFreePort(), "1", 0, "srflx"); + publicCandidate.setLocalIp(InetAddress.getLocalHost().getHostAddress()); + + try { + publicCandidate.addCandidateEcho(session); + } + catch (SocketException e) { + e.printStackTrace(); + } + + addCandidate(publicCandidate); } - catch (SocketException e) { + catch (UnknownHostException e) { e.printStackTrace(); } - - addCandidate(publicCandidate); - } - catch (UnknownHostException e) { - e.printStackTrace(); } } } + } + this.setResolveEnd(); } diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java index 7adc40cf7..8261639e9 100644 --- a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/RTPBridge.java @@ -512,6 +512,8 @@ public class RTPBridge extends IQ { // Cancel the collector. collector.cancel(); + if(response == null) return null; + if (response.getIp() == null || response.getIp().equals("")) return null; Enumeration ifaces = null; diff --git a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java index 3144b6787..989d6b9d7 100644 --- a/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java +++ b/jingle/extension/test/org/jivesoftware/smackx/jingle/JingleMediaTest.java @@ -21,15 +21,13 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.test.SmackTestCase; -import org.jivesoftware.smackx.jingle.IncomingJingleSession; -import org.jivesoftware.smackx.jingle.JingleManager; -import org.jivesoftware.smackx.jingle.JingleSessionRequest; -import org.jivesoftware.smackx.jingle.OutgoingJingleSession; +import org.jivesoftware.smackx.jingle.*; import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager; import org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioChannel; import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager; import org.jivesoftware.smackx.jingle.mediaimpl.multi.MultiMediaManager; import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener; +import org.jivesoftware.smackx.jingle.listeners.JingleSessionStateListener; import org.jivesoftware.smackx.jingle.media.JingleMediaManager; import org.jivesoftware.smackx.jingle.nat.BridgedTransportManager; import org.jivesoftware.smackx.jingle.nat.ICETransportManager; @@ -56,7 +54,7 @@ public class JingleMediaTest extends SmackTestCase { XMPPConnection x0 = getConnection(0); XMPPConnection x1 = getConnection(1); - for (int i = 0; i < 3; i++) + for (int i = 0; i < 1; i++) try { ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478); @@ -78,10 +76,22 @@ public class JingleMediaTest extends SmackTestCase { JingleSessionRequestListener jingleSessionRequestListener = new JingleSessionRequestListener() { public void sessionRequested(final JingleSessionRequest request) { - try { IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads()); session.start(request); + + session.addStateListener(new JingleSessionStateListener() { + public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException { + if (newOne instanceof IncomingJingleSession.Active) { + throw new JingleNegotiator.JingleException(); + } + } + + public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) { + + } + }); + } catch (XMPPException e) { e.printStackTrace(); @@ -96,12 +106,19 @@ public class JingleMediaTest extends SmackTestCase { js0.start(); - Thread.sleep(50000); + Thread.sleep(20000); + + IncomingJingleSession incomingJingleSession = (IncomingJingleSession) jm1.getSession(js0.getConnection().getUser()); + incomingJingleSession.removeAllStateListeners(); + incomingJingleSession.accept(); + + Thread.sleep(15000); + js0.terminate(); jm1.removeJingleSessionRequestListener(jingleSessionRequestListener); - Thread.sleep(6000); + Thread.sleep(60000); } catch (Exception e) { @@ -139,6 +156,7 @@ public class JingleMediaTest extends SmackTestCase { 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());