From ced4cbf27545620b2a9be59173fd87305cab4a8b Mon Sep 17 00:00:00 2001
From: dknn <yoann.blein@free.fr>
Date: Sat, 22 Sep 2012 10:33:47 +0200
Subject: Add use of NAT traversal


diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index d907df6..d9718dc 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -124,7 +124,7 @@ void Client::handleConnected() {
 #ifdef SWIFT_EXPERIMENTAL_FT
 	NetworkFactories *nf = getNetworkFactories();
 	fileTransferManager = new FileTransferManagerImpl(getJID(), jingleSessionManager, getIQRouter(), getEntityCapsProvider(), presenceOracle, nf->getConnectionFactory(), nf->getConnectionServerFactory(), nf->getTimerFactory(), nf->getNATTraverser());
-	screenSharingManager = new ScreenSharingManagerImpl(getJID(), jingleSessionManager, getIQRouter(), nf->getUDPSocketFactory(), nf->getTimerFactory(), presenceOracle, getEntityCapsProvider());
+	screenSharingManager = new ScreenSharingManagerImpl(getJID(), jingleSessionManager, getIQRouter(), nf->getUDPSocketFactory(), nf->getTimerFactory(), presenceOracle, getEntityCapsProvider(), nf->getNATTraverser());
 #else
 	fileTransferManager = new DummyFileTransferManager();
 #endif
diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.cpp b/Swiften/ScreenSharing/IncomingScreenSharing.cpp
index 43e3fbc..1984ab1 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharing.cpp
+++ b/Swiften/ScreenSharing/IncomingScreenSharing.cpp
@@ -24,9 +24,9 @@
 
 namespace Swift {
 
-IncomingScreenSharing::IncomingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory,
+IncomingScreenSharing::IncomingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager,
 											 TimerFactory* timerFactory, IQRouter* iqRouter, boost::shared_ptr<JingleContentPayload> content)
-	: ScreenSharing(session, udpSocketFactory),
+	: ScreenSharing(session, udpSocketFactory, connectivityManager),
 	  initialContent(content), parser(0), decoder(0), lastMouveMoveEvent(InputEventPayload::Event::MouseMove),
 	  inputEventPayload(boost::make_shared<InputEventPayload>()), eventSendingTimer(timerFactory->createTimer(500)),
 	  iqRouter(iqRouter)
@@ -82,7 +82,8 @@ void IncomingScreenSharing::accept()
 		decoder = new VP8Decoder;
 		parser = new VP8RTPParser(decoder);
 		rtpSession->onIncomingPacket.connect(boost::bind(&VP8RTPParser::newPayloadReceived, parser, _1, _2, _3));
-		decoder->onNewFrameDecoded.connect(boost::bind(&IncomingScreenSharing::handleNewFrameDecoded, this, _1, _2));
+		decoder->onNewRef.connect(boost::bind(&RTPSession::sendRPSIFeedback, rtpSession, _1));
+		decoder->onCorrupted.connect(boost::bind(&RTPSession::sendSLIFeedback, rtpSession, _1));
 		decoder->onNewImageAvailable.connect(boost::bind(&IncomingScreenSharing::handleNewImageAvailable, this, _1));
 	}
 
@@ -116,15 +117,6 @@ JingleContentID IncomingScreenSharing::getContentID() const
 	return JingleContentID(initialContent->getName(), initialContent->getCreator());
 }
 
-void IncomingScreenSharing::handleNewFrameDecoded(int pictureID, bool success)
-{
-	if (success) {
-		rtpSession->sendRPSIFeedback(pictureID);
-	} else {
-		rtpSession->sendSLIFeedback(pictureID);
-	}
-}
-
 void IncomingScreenSharing::handleNewImageAvailable(const Image& image)
 {
 	onStateChange(ScreenSharing::Receiving);
diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.h b/Swiften/ScreenSharing/IncomingScreenSharing.h
index d5dd817..e1325b5 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharing.h
+++ b/Swiften/ScreenSharing/IncomingScreenSharing.h
@@ -28,7 +28,7 @@ namespace Swift {
 			typedef boost::shared_ptr<IncomingScreenSharing> ref;
 
 		public:
-			IncomingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory,
+			IncomingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager,
 								  TimerFactory* timerFactory, IQRouter* iqRouter, boost::shared_ptr<JingleContentPayload> content);
 			virtual ~IncomingScreenSharing();
 
@@ -44,7 +44,6 @@ namespace Swift {
 
 		private:
 			JingleContentID getContentID() const;
-			void handleNewFrameDecoded(int pictureID, bool success);
 			void handleNewImageAvailable(const Image& image);
 			void handleEventSendingTimerTick();
 			void addLastMouseMoveIfDifferent();
diff --git a/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp b/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
index 8557f40..89f1bda 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
+++ b/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
@@ -15,9 +15,9 @@
 
 namespace Swift {
 
-IncomingScreenSharingManager::IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* iqRouter,
+IncomingScreenSharingManager::IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* iqRouter, ConnectivityManager* connectivityManager,
 														   UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory)
-	: jingleSessionManager(jingleSessionManager), iqRouter(iqRouter), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)
+	: jingleSessionManager(jingleSessionManager), iqRouter(iqRouter), connectivityManager(connectivityManager), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)
 {
 	jingleSessionManager->addIncomingSessionHandler(this);
 }
@@ -37,7 +37,7 @@ bool IncomingScreenSharingManager::handleIncomingJingleSession(Swift::JingleSess
 	// Check description
 	// Create IncomingScreenSharing
 
-	onIncomingScreenSharing(boost::make_shared<IncomingScreenSharing>(session, udpSocketFactory, timerFactory, iqRouter, content));
+	onIncomingScreenSharing(boost::make_shared<IncomingScreenSharing>(session, udpSocketFactory, connectivityManager, timerFactory, iqRouter, content));
 
 	return true;
 }
diff --git a/Swiften/ScreenSharing/IncomingScreenSharingManager.h b/Swiften/ScreenSharing/IncomingScreenSharingManager.h
index 586cb0b..a34fd8d 100644
--- a/Swiften/ScreenSharing/IncomingScreenSharingManager.h
+++ b/Swiften/ScreenSharing/IncomingScreenSharingManager.h
@@ -14,10 +14,11 @@ namespace Swift {
 	class JingleSessionManager;
 	class UDPSocketFactory;
 	class TimerFactory;
+	class ConnectivityManager;
 
 	class IncomingScreenSharingManager : public IncomingJingleSessionHandler {
 		public:
-			IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* iqRouter, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
+			IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* iqRouter, ConnectivityManager* connectivityManager, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
 			virtual ~IncomingScreenSharingManager();
 
 		public:
@@ -29,6 +30,7 @@ namespace Swift {
 		private:
 			JingleSessionManager* jingleSessionManager;
 			IQRouter* iqRouter;
+			ConnectivityManager* connectivityManager;
 			UDPSocketFactory *udpSocketFactory;
 			TimerFactory* timerFactory;
 	};
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
index 6700a32..1abf0ac 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
+++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
@@ -23,8 +23,8 @@
 
 namespace Swift {
 
-OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, const JID &toJID)
-	: ScreenSharing(session, udpSocketFactory),
+OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager, TimerFactory* timerFactory, const JID &toJID)
+	: ScreenSharing(session, udpSocketFactory, connectivityManager),
 	  timerFactory(timerFactory), recipient(toJID), contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)),
 	  canceled(false), sessionAccepted(false), socketConnected(false), encoder(0), packetizer(0)
 {
@@ -73,6 +73,7 @@ void OutgoingScreenSharing::start(unsigned int width, unsigned int height)
 
 void OutgoingScreenSharing::addImage(const Image &image)
 {
+	rtpSession->poll();
 	encoder->encodeImage(image);
 }
 
@@ -137,6 +138,7 @@ void OutgoingScreenSharing::startRTPSession()
 		encoder = new VP8Encoder(packetizer, width, height);
 		packetizer->onNewPayloadReady.connect(boost::bind(&OutgoingScreenSharing::handleNewPayloadReady, this, _1, _2));
 		rtpSession->onRPSIFeedback.connect(boost::bind(&VP8Encoder::handleRPSIFeedback, static_cast<VP8Encoder*>(encoder), _1));
+		rtpSession->onSLIFeedback.connect(boost::bind(&VP8Encoder::handleSLIFeedback, static_cast<VP8Encoder*>(encoder), _1));
 		onReady();
 		onStateChange(ScreenSharing::BroadCasting);
 	}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.h b/Swiften/ScreenSharing/OutgoingScreenSharing.h
index 245d038..d1f1bf1 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharing.h
+++ b/Swiften/ScreenSharing/OutgoingScreenSharing.h
@@ -29,7 +29,7 @@ namespace Swift {
 			typedef boost::shared_ptr<OutgoingScreenSharing> ref;
 
 		public:
-			OutgoingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, const JID& recipient);
+			OutgoingScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager, TimerFactory* timerFactory, const JID& recipient);
 			virtual ~OutgoingScreenSharing();
 
 			virtual void cancel();
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp b/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
index 872fd19..b9d966f 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
+++ b/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
@@ -13,9 +13,8 @@
 
 namespace Swift {
 
-OutgoingScreenSharingManager::OutgoingScreenSharingManager(JingleSessionManager* jingleSessionManager,IQRouter* router,
-														   UDPSocketFactory *udpSocketFactory, TimerFactory* timerFactory)
-	: jsManager(jingleSessionManager), iqRouter(router), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)
+OutgoingScreenSharingManager::OutgoingScreenSharingManager(JingleSessionManager* jingleSessionManager,IQRouter* router, UDPSocketFactory *udpSocketFactory, ConnectivityManager* connectivityManager, TimerFactory* timerFactory)
+	: jsManager(jingleSessionManager), iqRouter(router), connectivityManager(connectivityManager), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)
 {
 }
 
@@ -25,7 +24,7 @@ boost::shared_ptr<OutgoingScreenSharing> OutgoingScreenSharingManager::createOut
 	assert(jingleSession);
 	jsManager->registerOutgoingSession(from, jingleSession);
 
-	return boost::make_shared<OutgoingScreenSharing>(jingleSession, udpSocketFactory, timerFactory, recipient);
+	return boost::make_shared<OutgoingScreenSharing>(jingleSession, udpSocketFactory, connectivityManager, timerFactory, recipient);
 }
 
 }
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharingManager.h b/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
index 56888ba..7c16294 100644
--- a/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
+++ b/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
@@ -16,11 +16,12 @@ namespace Swift {
 	class IQRouter;
 	class UDPSocketFactory;
 	class TimerFactory;
+	class ConnectivityManager;
 
 	class OutgoingScreenSharingManager {
 		public:
 			OutgoingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router,
-										 UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
+										 UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager, TimerFactory* timerFactory);
 
 			boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& from, const JID& recipient);
 
@@ -29,6 +30,7 @@ namespace Swift {
 
 			JingleSessionManager* jsManager;
 			IQRouter* iqRouter;
+			ConnectivityManager* connectivityManager;
 			UDPSocketFactory *udpSocketFactory;
 			TimerFactory* timerFactory;
 	};
diff --git a/Swiften/ScreenSharing/ReferencePictureSelection.cpp b/Swiften/ScreenSharing/ReferencePictureSelection.cpp
index dc2a81e..dabcf12 100644
--- a/Swiften/ScreenSharing/ReferencePictureSelection.cpp
+++ b/Swiften/ScreenSharing/ReferencePictureSelection.cpp
@@ -1,11 +1,7 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
 #include <Swiften/ScreenSharing/ReferencePictureSelection.h>
@@ -25,7 +21,7 @@ ReferencePictureSelection::ReferencePictureSelection()
 	  send_refresh(false) {
 }
 
-void ReferencePictureSelection::ReceivedRPSI(int rpsi_picture_id) {
+void ReferencePictureSelection::receivedRPSI(int rpsi_picture_id) {
 	// Assume RPSI is signaled with 7 bits.
 	SWIFT_LOG(debug) << "ReceivedRPSI: " << rpsi_picture_id  << ", " << last_sent_ref_picture_id_ << std::endl;
 	if ((rpsi_picture_id & 127) == (last_sent_ref_picture_id_ & 127)) {
@@ -38,11 +34,11 @@ void ReferencePictureSelection::ReceivedRPSI(int rpsi_picture_id) {
 	}
 }
 
-void ReferencePictureSelection::ReceivedSLI() {
+void ReferencePictureSelection::receivedSLI() {
 	send_refresh = true;
 }
 
-int ReferencePictureSelection::EncodeFlags(int picture_id) {
+int ReferencePictureSelection::encodeFlags(int picture_id) {
 	int flags = 0;
 	// We can't refresh the decoder until we have established the key frame.
 	if (send_refresh/* && received_ack_*/) {
diff --git a/Swiften/ScreenSharing/ReferencePictureSelection.h b/Swiften/ScreenSharing/ReferencePictureSelection.h
index ff2f4c0..bb1da2a 100644
--- a/Swiften/ScreenSharing/ReferencePictureSelection.h
+++ b/Swiften/ScreenSharing/ReferencePictureSelection.h
@@ -1,19 +1,7 @@
 /*
- *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-/*
- * This file defines classes for doing reference picture selection, primarily
- * with VP8.
- */
-
-/* Modified by Yoann Blein, 2012 (remove time handling for simplicity)
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
  */
 
 #pragma once
@@ -25,31 +13,12 @@ namespace Swift {
 		public:
 			ReferencePictureSelection();
 
-			// Report a received reference picture selection indication. This will
-			// introduce a new established reference if the received RPSI isn't too late.
-			void ReceivedRPSI(int rpsi_picture_id);
-
-			// Report a received slice loss indication. Returns true if a refresh frame
-			// must be sent to the receiver, which is accomplished by only predicting
-			// from the established reference.
-			// |now_ts| is the RTP timestamp corresponding to the current time. Typically
-			// the capture timestamp of the frame currently being processed.
-			// Returns true if it's time to encode a decoder refresh, otherwise false.
-			void ReceivedSLI();
-
-			// Returns the recommended VP8 encode flags needed. May refresh the decoder
-			// and/or update the reference buffers.
-			// |picture_id| picture id of the frame to be encoded.
-			// |send_refresh| should be set to true if a decoder refresh should be
-			// encoded, otherwise false.
-			// |now_ts| is the RTP timestamp corresponding to the current time. Typically
-			// the capture timestamp of the frame currently being processed.
-			// Returns the flags to be given to the libvpx encoder when encoding the next
-			// frame.
-			int EncodeFlags(int picture_id);
-
-			// Notify the RPS that the frame with picture id |picture_id| was encoded as
-			// a key frame, effectively updating all reference buffers.
+			void receivedRPSI(int rpsi_picture_id);
+
+			void receivedSLI();
+
+			int encodeFlags(int picture_id);
+
 			void refFrameSent(int picture_id);
 
 		private:
diff --git a/Swiften/ScreenSharing/ScreenSharing.cpp b/Swiften/ScreenSharing/ScreenSharing.cpp
index f2977a2..de0b430 100644
--- a/Swiften/ScreenSharing/ScreenSharing.cpp
+++ b/Swiften/ScreenSharing/ScreenSharing.cpp
@@ -13,13 +13,14 @@
 #include <Swiften/Network/UDPSocketFactory.h>
 #include <Swiften/ScreenSharing/RTPSession.h>
 #include <Swiften/Jingle/JingleSession.h>
+#include <Swiften/FileTransfer/ConnectivityManager.h>
 
 #include <boost/bind.hpp>
 
 namespace Swift {
 
-ScreenSharing::ScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory)
-	: rtpSession(0), jingleSession(session), udpSocketFactory(udpSocketFactory)
+ScreenSharing::ScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager)
+	: rtpSession(0), jingleSession(session), udpSocketFactory(udpSocketFactory), connectivityManager(connectivityManager)
 {
 	jingleSession->onSessionTerminateReceived.connect(boost::bind(&ScreenSharing::handleSessionTerminateReceived, this, _1));
 }
@@ -52,19 +53,7 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayl
 
 	serverSocket = udpSocketFactory->createUDPSocket();
 
-	// Find the first ip which is not loopback
-	/*foreach (const NetworkInterface& interface, interfaces) {
-		if (!interface.isLoopback() && !interface.getAddresses().empty()) { // exclude loopback
-			serverSocket->bindOnAvailablePort(interface.getAddresses().front());
-
-			candidate.hostAddressPort = serverSocket->getLocalAddress();
-			candidate.type = JingleRawUDPTransportPayload::Candidate::Host;
-			transport->addCandidate(candidate);
-
-			return true;
-		}
-	}*/
-
+	/*
 	SWIFT_LOG(debug) << "Screen sharing: Addresses available: " << std::endl;
 	foreach (const NetworkInterface& interface, interfaces) {
 		SWIFT_LOG(debug) << "\tInterface: " << interface.getName() << std::endl;
@@ -72,6 +61,22 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayl
 			SWIFT_LOG(debug) << "\t\t" << addr.getRawAddress().to_string() << std::endl;
 		}
 	}
+	*/
+
+	std::vector<HostAddressPort> assisted = connectivityManager->getAssistedHostAddressPorts(NATPortMapping::UDP);
+	foreach (HostAddressPort hap, assisted) {
+		int port = serverSocket->bind(HostAddressPort(HostAddress("0.0.0.0"), hap.getPort()));
+		if (port != hap.getPort())
+			continue;
+
+		SWIFT_LOG(debug) << "Listening on " << port << std::endl;
+
+		candidate.hostAddressPort = hap;
+		candidate.type = JingleRawUDPTransportPayload::Candidate::Host;
+		transport->addCandidate(candidate);
+
+		return true;
+	}
 
 	std::string scopeLinkBeginning("fe80");
 	foreach (const NetworkInterface& interface, interfaces) {
@@ -99,29 +104,6 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayl
 		}
 	}
 
-	/*
-	int port = serverSocket->bind(HostAddressPort(HostAddress("0.0.0.0"), 29999));
-	if (!port)
-		return false;
-
-	candidate.hostAddressPort = HostAddressPort(HostAddress("82.225.14.174"), 29999);
-	candidate.type = JingleRawUDPTransportPayload::Candidate::Host;
-	transport->addCandidate(candidate);
-
-	return true;
-*/
-
-	// else loopback for self sharing
-	/*if (!interfaces.empty() && !interfaces.front().getAddresses().empty()) {
-		int port = serverSocket->bindOnAvailablePort(interfaces.front().getAddresses().front());
-		if (port) {
-			candidate.hostAddressPort = serverSocket->getLocalAddress();
-			candidate.type = JingleRawUDPTransportPayload::Candidate::Host;
-			transport->addCandidate(candidate);
-			return true;
-		}
-	}*/
-
 	return false;
 }
 
diff --git a/Swiften/ScreenSharing/ScreenSharing.h b/Swiften/ScreenSharing/ScreenSharing.h
index 6107ec5..9a74c16 100644
--- a/Swiften/ScreenSharing/ScreenSharing.h
+++ b/Swiften/ScreenSharing/ScreenSharing.h
@@ -18,6 +18,7 @@ namespace Swift {
 	class UDPSocketFactory;
 	class UDPSocket;
 	class RTPSession;
+	class ConnectivityManager;
 
 	class ScreenSharing {
 		public:
@@ -36,7 +37,7 @@ namespace Swift {
 			};
 
 		public:
-			ScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory);
+			ScreenSharing(boost::shared_ptr<JingleSession> jingleSession, UDPSocketFactory* udpSocketFactory, ConnectivityManager* connectivityManager);
 			virtual ~ScreenSharing();
 
 			virtual void cancel() = 0;
@@ -58,5 +59,6 @@ namespace Swift {
 
 			boost::shared_ptr<JingleSession> jingleSession;
 			UDPSocketFactory* udpSocketFactory;
+			ConnectivityManager* connectivityManager;
 	};
 }
diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
index c20d2c7..6c930f7 100644
--- a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
+++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
@@ -14,6 +14,7 @@
 #include <Swiften/ScreenSharing/OutgoingScreenSharingManager.h>
 #include <Swiften/ScreenSharing/OutgoingScreenSharing.h>
 #include <Swiften/ScreenSharing/InputEventResponder.h>
+#include <Swiften/FileTransfer/ConnectivityManager.h>
 
 #include <boost/foreach.hpp>
 
@@ -21,11 +22,14 @@ namespace Swift {
 
 ScreenSharingManagerImpl::ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager *jingleSessionManager, IQRouter *iqRouter,
 												   UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, PresenceOracle* presenceOrable,
-												   EntityCapsProvider* capsProvider)
-	: ownJID(ownFullJID), capsProvider(capsProvider),  presenceOracle(presenceOrable)
+												   EntityCapsProvider* capsProvider, NATTraverser* natTraverser)
+	: ownJID(ownFullJID), capsProvider(capsProvider),  presenceOracle(presenceOrable), natTraverser(natTraverser)
 {
-	incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);
-	outgoingSSManager = new OutgoingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);
+	incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, connectivityManager, udpSocketFactory, timerFactory);
+	outgoingSSManager = new OutgoingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, connectivityManager, timerFactory);
+
+	connectivityManager = new ConnectivityManager(natTraverser);
+	connectivityManager->addListeningPort(29999, NATPortMapping::UDP);
 
 	responder = new InputEventResponder(this, iqRouter);
 	responder->start();
@@ -39,6 +43,7 @@ ScreenSharingManagerImpl::~ScreenSharingManagerImpl()
 	delete responder;
 	delete incomingSSManager;
 	delete outgoingSSManager;
+	delete connectivityManager;
 }
 
 boost::shared_ptr<OutgoingScreenSharing> ScreenSharingManagerImpl::createOutgoingScreenSharing(const JID &to)
diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
index 8f73f87..5403eb5 100644
--- a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
+++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
@@ -20,12 +20,14 @@ namespace Swift {
 	class EntityCapsProvider;
 	class InputEventResponder;
 	class InputEventPayload;
+	class NATTraverser;
+	class ConnectivityManager;
 
 	class ScreenSharingManagerImpl : public ScreenSharingManager {
 		public:
 			ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* iqRouter,
 									 UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, PresenceOracle* presenceOrable,
-									 EntityCapsProvider *capsProvider);
+									 EntityCapsProvider *capsProvider, NATTraverser* natTraverser);
 			virtual ~ScreenSharingManagerImpl();
 
 			virtual boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& to);
@@ -41,8 +43,10 @@ namespace Swift {
 			InputEventResponder* responder;
 			JID ownJID;
 			std::vector< boost::shared_ptr<OutgoingScreenSharing> > outgoingSharings;
+			ConnectivityManager* connectivityManager;
 
 			EntityCapsProvider* capsProvider;
 			PresenceOracle* presenceOracle;
+			NATTraverser* natTraverser;
 	};
 }
-- 
cgit v0.10.2-6-g49f6