mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-27 14:47:59 +01:00
STUN fix and Media Tunning
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7610 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
cb2df91084
commit
9627fef139
9 changed files with 239 additions and 126 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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://");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue