aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/impl
diff options
context:
space:
mode:
authorEmil Ivov <emcho@jitsi.org>2010-09-19 10:53:11 +0000
committerEmil Ivov <emcho@jitsi.org>2010-09-19 10:53:11 +0000
commit9384b4fbbaf0746ba6e69fb56996148a727b354d (patch)
tree629f7c70b45df25553a0fa2531dfb694ebb3d83d /src/net/java/sip/communicator/impl
parent4c7710cd641839bbf001db5818b65331f6c69bd4 (diff)
downloadjitsi-9384b4fbbaf0746ba6e69fb56996148a727b354d.zip
jitsi-9384b4fbbaf0746ba6e69fb56996148a727b354d.tar.gz
jitsi-9384b4fbbaf0746ba6e69fb56996148a727b354d.tar.bz2
ICE integration for XMPP accounts
Diffstat (limited to 'src/net/java/sip/communicator/impl')
-rw-r--r--src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java6
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java2
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java63
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java76
4 files changed, 139 insertions, 8 deletions
diff --git a/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java b/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java
index f2724ea..11cbcab 100644
--- a/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/netaddr/NetworkAddressManagerServiceImpl.java
@@ -603,9 +603,9 @@ public class NetworkAddressManagerServiceImpl
* @throws BindException if we couldn't find a free port between within the
* default number of retries.
*/
- public static IceMediaStream createStream( int rtpPort,
- String streamName,
- Agent agent)
+ public IceMediaStream createIceStream( int rtpPort,
+ String streamName,
+ Agent agent)
throws IllegalArgumentException,
IOException,
BindException
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java
index 7552f1f..b8ceab5 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/CallPeerMediaHandlerJabberImpl.java
@@ -71,7 +71,7 @@ public class CallPeerMediaHandlerJabberImpl
{
super(peer, peer);
- transportManager = new RawUdpTransportManager(peer);
+ transportManager = new IceUdpTransportManager(peer);
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java
index f635325..f77336b 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/IceUdpTransportManager.java
@@ -7,15 +7,18 @@
package net.java.sip.communicator.impl.protocol.jabber;
import java.io.*;
+import java.net.*;
import java.nio.charset.*;
import java.text.*;
import java.util.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.CandidateType;
+import net.java.sip.communicator.impl.protocol.jabber.jinglesdp.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.netaddr.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
import org.ice4j.*;
import org.ice4j.ice.*;
@@ -32,6 +35,13 @@ public class IceUdpTransportManager
extends TransportManagerJabberImpl
{
/**
+ * The <tt>Logger</tt> used by the <tt>IceUdpTransportManager</tt>
+ * class and its instances for logging output.
+ */
+ private static final Logger logger = Logger
+ .getLogger(IceUdpTransportManager.class.getName());
+
+ /**
* This is where we keep our answer between the time we get the offer and
* are ready with the answer;
*/
@@ -68,8 +78,7 @@ public class IceUdpTransportManager
{
ProtocolProviderServiceJabberImpl provider
= getCallPeer().getProtocolProvider();
- NetworkAddressManagerService namSer
- = JabberActivator.getNetworkAddressManagerService();
+ NetworkAddressManagerService namSer = getNetAddrMgr();
Agent agent = namSer.createIceAgent();
@@ -190,16 +199,49 @@ public class IceUdpTransportManager
= (RtpDescriptionPacketExtension)content
.getFirstChildOfType(RtpDescriptionPacketExtension.class);
- IceMediaStream stream = content.getName()
+ IceMediaStream stream;
+ try
+ {
+ //the following call involves STUN calls so it may take a while.
+ stream = getNetAddrMgr().createIceStream(
+ nextMediaPortToTry, rtpDesc.getMedia(), iceAgent);
+ }
+ catch (Exception exc)
+ {
+ throw new OperationFailedException(
+ "Failed to initialize stream " + rtpDesc.getMedia(),
+ OperationFailedException.INTERNAL_ERROR);
+ }
+ //let's now update the next port var as best we can: we would assume
+ //that all local candidates are bound on the same port and set it
+ //to the one just above. if the assumption is wrong the next bind
+ //would simply include one more bind retry.
+ try
+ {
+ nextMediaPortToTry = stream.getComponent(Component.RTCP)
+ .getLocalCandidates().get(0)
+ .getTransportAddress().getPort() + 1;
+ }
+ catch(Throwable t)
+ {
+ //hey, we were just trying to be nice. if that didn't work for
+ //some reason we really can't be held responsible!
+ logger.debug("Determining next port didn't work: ", t);
+ }
+ //we now generate the XMPP code containing the candidates.
+ content.addChildExtension(JingleUtils.createTransport(stream));
}
+
this.cpeList = ourOffer;
}
+
+
/**
* Simply returns the list of local candidates that we gathered during the
- * harvest. This is a raw udp transport manager so there's no real wraping
+ * harvest. This is a raw udp transport manager so there's no real wrapping
* up to do.
*
* @return the list of local candidates that we gathered during the
@@ -232,4 +274,17 @@ public class IceUdpTransportManager
return null;
}
+
+ /**
+ * Returns a reference to the {@link NetworkAddressManagerService}. The only
+ * reason this method exists is that {@link JabberActivator
+ * #getNetworkAddressManagerService()} is too long to write and makes code
+ * look clumsy.
+ *
+ * @return a reference to the {@link NetworkAddressManagerService}.
+ */
+ private static NetworkAddressManagerService getNetAddrMgr()
+ {
+ return JabberActivator.getNetworkAddressManagerService();
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java b/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java
index 2099e7f..4513cef 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/jinglesdp/JingleUtils.java
@@ -9,12 +9,17 @@ package net.java.sip.communicator.impl.protocol.jabber.jinglesdp;
import java.net.*;
import java.util.*;
+import org.ice4j.*;
+import org.ice4j.ice.*;
+
import net.java.sip.communicator.impl.protocol.jabber.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
+import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.CandidateType;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.format.*;
import net.java.sip.communicator.service.protocol.media.*;
import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.NetworkUtils; //disambiguates with ice4j's network utils.
import static net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.ContentPacketExtension.*;
/**
@@ -502,4 +507,75 @@ public class JingleUtils
return ptExt;
}
+ /**
+ * Converts the ICE media <tt>stream</tt> and its local candidates into a
+ * {@link IceUdpTransportPacketExtension}.
+ *
+ * @param stream the {@link IceMediaStream} that we'd like to describe in
+ * XML.
+ *
+ * @return the {@link IceUdpTransportPacketExtension} that we
+ */
+ public static IceUdpTransportPacketExtension createTransport(
+ IceMediaStream stream)
+ {
+ IceUdpTransportPacketExtension trans
+ = new IceUdpTransportPacketExtension();
+
+ trans.setUfrag(stream.getParentAgent().getLocalUfrag());
+ trans.setPassword(stream.getParentAgent().getLocalPassword());
+
+ for(Component component : stream.getComponents())
+ {
+ for(Candidate cand : component.getLocalCandidates())
+ {
+ trans.addCandidate(createCandidate(cand));
+ }
+ }
+
+ return trans;
+ }
+
+
+ /**
+ * Creates a {@link CandidatePacketExtension} and initializes it so that it
+ * would describe the state of <tt>candidate</tt>
+ *
+ * @param candidate the ICE4J {@link Candidate} that we'd like to convert
+ * into an XMPP packet extension.
+ *
+ * @return a new {@link CandidatePacketExtension} corresponding to the state
+ * of the <tt>candidate</tt> candidate.
+ */
+ private static CandidatePacketExtension createCandidate(Candidate candidate)
+ {
+ CandidatePacketExtension packet = new CandidatePacketExtension();
+
+ //TODO: XMPP expects int values as foundations. Luckily that's exactly
+ //what ice4j is using under the hood at this time. still, we'd need to
+ //make sure that doesn't change ... possibly by setting a property there
+ packet.setFoundation(Integer.parseInt( candidate.getFoundation()));
+
+ packet.setComponent( candidate.getParentComponent().getComponentID());
+ packet.setProtocol(candidate.getTransport().toString());
+ packet.setPriority(candidate.getPriority());
+ packet.setGeneration(candidate.getParentComponent()
+ .getParentStream().getParentAgent().getGeneration());
+
+ packet.setIP(candidate.getTransportAddress().getHostAddress());
+ packet.setPort(candidate.getTransportAddress().getPort());
+ packet.setType(CandidateType.valueOf(candidate.getType().toString()));
+
+ TransportAddress relAddr = candidate.getRelatedAddress();
+
+ if(relAddr != null)
+ {
+ packet.setRelAddr(relAddr.getHostAddress());
+ packet.setRelPort(relAddr.getPort());
+ }
+
+
+ return packet;
+ }
+
}