summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordknn <yoann.blein@free.fr>2012-07-08 20:27:27 (GMT)
committerdknn <yoann.blein@free.fr>2012-09-22 09:00:01 (GMT)
commit1b2d23c160b4c120a364ff9e86b54e2d8caeaaa4 (patch)
tree94c9884d7746786568d0da2d6e122dd0f0b5ca9c
parent4e0236b08d3914d24af32f45bc99663a73c6d83a (diff)
downloadswift-contrib-1b2d23c160b4c120a364ff9e86b54e2d8caeaaa4.zip
swift-contrib-1b2d23c160b4c120a364ff9e86b54e2d8caeaaa4.tar.bz2
Screen sharing managing
-rw-r--r--Swiften/Client/Client.cpp11
-rw-r--r--Swiften/Client/Client.h10
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharing.cpp57
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharing.h35
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharingManager.cpp44
-rw-r--r--Swiften/ScreenSharing/IncomingScreenSharingManager.h33
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharing.cpp105
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharing.h46
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp29
-rw-r--r--Swiften/ScreenSharing/OutgoingScreenSharingManager.h35
-rw-r--r--Swiften/ScreenSharing/SConscript8
-rw-r--r--Swiften/ScreenSharing/ScreenSharing.cpp68
-rw-r--r--Swiften/ScreenSharing/ScreenSharing.h59
-rw-r--r--Swiften/ScreenSharing/ScreenSharingManager.h26
-rw-r--r--Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp44
-rw-r--r--Swiften/ScreenSharing/ScreenSharingManagerImpl.h39
16 files changed, 647 insertions, 2 deletions
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 1a6c64b..c16d3b1 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -30,6 +30,7 @@
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/FileTransfer/FileTransferManagerImpl.h>
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+#include <Swiften/ScreenSharing/ScreenSharingManagerImpl.h>
#ifndef SWIFT_EXPERIMENTAL_FT
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#endif
@@ -69,6 +70,7 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
jingleSessionManager = new JingleSessionManager(getIQRouter());
fileTransferManager = NULL;
+ screenSharingManager = NULL;
whiteboardSessionManager = NULL;
#ifdef SWIFT_EXPERIMENTAL_WB
@@ -120,7 +122,9 @@ void Client::setSoftwareVersion(const std::string& name, const std::string& vers
void Client::handleConnected() {
#ifdef SWIFT_EXPERIMENTAL_FT
- fileTransferManager = new FileTransferManagerImpl(getJID(), jingleSessionManager, getIQRouter(), getEntityCapsProvider(), presenceOracle, getNetworkFactories()->getConnectionFactory(), getNetworkFactories()->getConnectionServerFactory(), getNetworkFactories()->getTimerFactory(), getNetworkFactories()->getNATTraverser());
+ 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());
#else
fileTransferManager = new DummyFileTransferManager();
#endif
@@ -164,6 +168,11 @@ void Client::setAlwaysTrustCertificates() {
setCertificateTrustChecker(blindCertificateTrustChecker);
}
+ScreenSharingManager *Client::getScreenSharingManager() const
+{
+ return screenSharingManager;
+}
+
NickManager* Client::getNickManager() const {
return nickManager;
}
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 126572a..fde994e 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -37,6 +37,7 @@ namespace Swift {
class JingleSessionManager;
class FileTransferManager;
class WhiteboardSessionManager;
+ class ScreenSharingManager;
/**
* Provides the core functionality for writing XMPP client software.
@@ -153,6 +154,14 @@ namespace Swift {
void setAlwaysTrustCertificates();
WhiteboardSessionManager* getWhiteboardSessionManager() const;
+
+ /**
+ * Returns a ScreenSharingManager for the client. This is only available after the onConnected
+ * signal has been fired.
+ *
+ * WARNING: Screen sharing will only work if Swiften is built in 'experimental' mode.
+ */
+ ScreenSharingManager* getScreenSharingManager() const;
public:
/**
@@ -188,6 +197,7 @@ namespace Swift {
JingleSessionManager* jingleSessionManager;
FileTransferManager* fileTransferManager;
BlindCertificateTrustChecker* blindCertificateTrustChecker;
+ ScreenSharingManager *screenSharingManager;
WhiteboardSessionManager* whiteboardSessionManager;
};
}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.cpp b/Swiften/ScreenSharing/IncomingScreenSharing.cpp
new file mode 100644
index 0000000..d5ee56e
--- /dev/null
+++ b/Swiften/ScreenSharing/IncomingScreenSharing.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/IncomingScreenSharing.h>
+
+#include <Swiften/Jingle/JingleSession.h>
+#include <Swiften/Elements/JingleRawUDPTransportPayload.h>
+#include <Swiften/Network/UDPSocketFactory.h>
+#include <Swiften/Network/UDPSocket.h>
+
+namespace Swift {
+
+IncomingScreenSharing::IncomingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory,
+ boost::shared_ptr<JingleContentPayload> content)
+ : ScreenSharing(session, udpSocketFactory),
+ initialContent(content)
+{
+ onStateChange(ScreenSharing::WaitingForAccept);
+}
+
+IncomingScreenSharing::~IncomingScreenSharing()
+{
+}
+
+void IncomingScreenSharing::cancel()
+{
+ session->sendTerminate(JinglePayload::Reason::Cancel);
+ clientSocket->close();
+ onStateChange(ScreenSharing::Canceled);
+}
+
+void IncomingScreenSharing::accept()
+{
+ JingleRawUDPTransportPayload::ref transport = boost::make_shared<JingleRawUDPTransportPayload>();
+ addBestCandidate(transport);
+ // TODO: create a valid description instead of copying the initator's one
+ session->sendAccept(getContentID(), initialContent->getDescriptions().front(), transport);
+
+ JingleRawUDPTransportPayload::ref initialTransport = initialContent->getTransport<JingleRawUDPTransportPayload>();
+ clientSocket = udpSocketFactory->createUDPSocket();
+ clientSocket->connect(initialTransport->getCandidates().front().hostAddressPort);
+ // Send a empty packet to let the server know about us
+ SafeByteArray data(1, 0);
+ clientSocket->send(data);
+
+ onStateChange(ScreenSharing::Connecting);
+}
+
+JingleContentID IncomingScreenSharing::getContentID() const
+{
+ return JingleContentID(initialContent->getName(), initialContent->getCreator());
+}
+
+}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.h b/Swiften/ScreenSharing/IncomingScreenSharing.h
new file mode 100644
index 0000000..a9850fd
--- /dev/null
+++ b/Swiften/ScreenSharing/IncomingScreenSharing.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/ScreenSharing/ScreenSharing.h>
+#include <Swiften/Jingle/JingleContentID.h>
+
+namespace Swift {
+ class JingleContentPayload;
+
+ class IncomingScreenSharing : public ScreenSharing
+ {
+ public:
+ typedef boost::shared_ptr<IncomingScreenSharing> ref;
+
+ public:
+ IncomingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory,
+ boost::shared_ptr<JingleContentPayload> content);
+ virtual ~IncomingScreenSharing();
+
+ virtual void cancel();
+
+ void accept();
+
+ private:
+ JingleContentID getContentID() const;
+
+ private:
+ boost::shared_ptr<JingleContentPayload> initialContent;
+ };
+}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp b/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
new file mode 100644
index 0000000..7706c0a
--- /dev/null
+++ b/Swiften/ScreenSharing/IncomingScreenSharingManager.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/IncomingScreenSharingManager.h>
+
+#include <Swiften/Elements/JingleRTPDescription.h>
+#include <Swiften/ScreenSharing/IncomingScreenSharing.h>
+#include <Swiften/Jingle/Jingle.h>
+#include <Swiften/Jingle/JingleSessionManager.h>
+
+#include <boost/make_shared.hpp>
+
+namespace Swift {
+
+IncomingScreenSharingManager::IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router, UDPSocketFactory* udpSocketFactory)
+ : jingleSessionManager(jingleSessionManager), router(router), udpSocketFactory(udpSocketFactory)
+{
+ jingleSessionManager->addIncomingSessionHandler(this);
+}
+
+IncomingScreenSharingManager::~IncomingScreenSharingManager()
+{
+ jingleSessionManager->removeIncomingSessionHandler(this);
+}
+
+bool IncomingScreenSharingManager::handleIncomingJingleSession(Swift::JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents, const Swift::JID& /*recipient*/)
+{
+ JingleContentPayload::ref content = Jingle::getContentWithDescription<JingleRTPDescription>(contents);
+ if (!content)
+ return false;
+
+ // Check transport
+ // Check description
+ // Create IncomingScreenSharing
+
+ onIncomingScreenSharing(boost::make_shared<IncomingScreenSharing>(session, udpSocketFactory, content));
+
+ return true;
+}
+
+}
diff --git a/Swiften/ScreenSharing/IncomingScreenSharingManager.h b/Swiften/ScreenSharing/IncomingScreenSharingManager.h
new file mode 100644
index 0000000..3563a87
--- /dev/null
+++ b/Swiften/ScreenSharing/IncomingScreenSharingManager.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Jingle/IncomingJingleSessionHandler.h>
+
+namespace Swift {
+ class IncomingScreenSharing;
+ class IQRouter;
+ class JingleSessionManager;
+ class UDPSocketFactory;
+
+ class IncomingScreenSharingManager : public IncomingJingleSessionHandler {
+ public:
+ IncomingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router, UDPSocketFactory* udpSocketFactory);
+ virtual ~IncomingScreenSharingManager();
+
+ public:
+ boost::signal<void (boost::shared_ptr<IncomingScreenSharing>)> onIncomingScreenSharing;
+
+ private:
+ bool handleIncomingJingleSession(JingleSession::ref session, const std::vector<JingleContentPayload::ref>& contents, const JID& /*recipient*/);
+
+ private:
+ JingleSessionManager* jingleSessionManager;
+ IQRouter* router;
+ UDPSocketFactory *udpSocketFactory;
+ };
+}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
new file mode 100644
index 0000000..3aa460c
--- /dev/null
+++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/OutgoingScreenSharing.h>
+
+#include <Swiften/Elements/JinglePayload.h>
+#include <Swiften/Elements/JingleRawUDPTransportPayload.h>
+#include <Swiften/Elements/JingleRTPDescription.h>
+#include <Swiften/Jingle/JingleSession.h>
+#include <Swiften/Network/UDPSocket.h>
+#include <Swiften/Network/TimerFactory.h>
+#include <Swiften/Network/Timer.h>
+
+#include <boost/bind.hpp>
+
+namespace Swift {
+
+OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory)
+ : ScreenSharing(session, udpSocketFactory),
+ contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)), canceled(false),
+ sessionAccepted(false), socketConnected(false), timerFactory(timerFactory)
+{
+}
+
+OutgoingScreenSharing::~OutgoingScreenSharing()
+{
+}
+
+void OutgoingScreenSharing::cancel()
+{
+ canceled = true;
+ session->sendTerminate(JinglePayload::Reason::Cancel);
+
+ onStateChange(ScreenSharing::Canceled);
+}
+
+void OutgoingScreenSharing::start()
+{
+ //onStateChange(ScreenSharing::WaitingForStart);
+ SWIFT_LOG(debug) << "Screen sharing: start" << std::endl;
+
+ JingleRTPDescription::ref desc = boost::make_shared<JingleRTPDescription>(JingleRTPDescription::Video);
+ desc->addPayloadType(RTPPayloadType(98, "VP8", 90000));
+
+ JingleRawUDPTransportPayload::ref transport = boost::make_shared<JingleRawUDPTransportPayload>();
+ addBestCandidate(transport);
+
+ session->sendInitiate(contentID, desc, transport);
+ onStateChange(ScreenSharing::WaitingForAccept);
+
+ serverSocket->onConnected.connect(boost::bind(&OutgoingScreenSharing::handleSocketConnected, this));
+ serverSocket->connectToFirstIncoming();
+}
+
+void OutgoingScreenSharing::handleSocketConnected()
+{
+ SWIFT_LOG(debug) << "Screen sharing: UDP socket connected" << std::endl;
+
+ if (canceled)
+ return;
+
+ socketConnected = true;
+ if (sessionAccepted)
+ startRTPSession();
+}
+
+void OutgoingScreenSharing::handleSessionAcceptReceived(const JingleContentID& /*id*/, boost::shared_ptr<JingleDescription> /*desc*/, boost::shared_ptr<JingleTransportPayload> /*transport*/)
+{
+ SWIFT_LOG(debug) << "Screen sharing: accepted" << std::endl;
+
+ if (canceled)
+ return;
+
+ sessionAccepted = true;
+ if (socketConnected) {
+ startRTPSession();
+ } else {
+ connectionTimer = timerFactory->createTimer(1000);
+ connectionTimer->onTick.connect(boost::bind(&OutgoingScreenSharing::handleConnectionFailed, this));
+ connectionTimer->start();
+ onStateChange(ScreenSharing::Connecting);
+ }
+}
+
+void OutgoingScreenSharing::handleConnectionFailed()
+{
+ SWIFT_LOG(debug) << "Screen sharing: unable to connect" << std::endl;
+
+ session->sendTerminate(JinglePayload::Reason::ConnectivityError);
+ canceled = true;
+
+ onStateChange(ScreenSharing::Failed);
+}
+
+void OutgoingScreenSharing::startRTPSession()
+{
+ SWIFT_LOG(debug) << "Screen sharing: accepted and connect, start screen sharing" << std::endl;
+
+ // Session accepted and socket connected, we can start the rtp session
+}
+
+}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.h b/Swiften/ScreenSharing/OutgoingScreenSharing.h
new file mode 100644
index 0000000..d93b476
--- /dev/null
+++ b/Swiften/ScreenSharing/OutgoingScreenSharing.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/ScreenSharing/ScreenSharing.h>
+#include <Swiften/Jingle/JingleContentID.h>
+
+namespace Swift {
+ class ConnectivityManager;
+ class JingleDescription;
+ class JingleTransportPayload;
+ class TimerFactory;
+ class Timer;
+
+ class OutgoingScreenSharing : public ScreenSharing {
+ public:
+ typedef boost::shared_ptr<OutgoingScreenSharing> ref;
+
+ public:
+ OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
+ virtual ~OutgoingScreenSharing();
+
+ virtual void cancel();
+
+ void start();
+
+ private:
+ void handleSocketConnected();
+ void handleSessionAcceptReceived(const JingleContentID& /*id*/, boost::shared_ptr<JingleDescription> /*desc*/, boost::shared_ptr<JingleTransportPayload> /*transport*/);
+ void handleConnectionFailed();
+ void startRTPSession();
+
+ private:
+ JingleContentID contentID;
+ bool canceled;
+ bool sessionAccepted;
+ bool socketConnected;
+
+ TimerFactory* timerFactory;
+ boost::shared_ptr<Timer> connectionTimer;
+ };
+}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp b/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
new file mode 100644
index 0000000..43096ae
--- /dev/null
+++ b/Swiften/ScreenSharing/OutgoingScreenSharingManager.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/OutgoingScreenSharingManager.h>
+#include <Swiften/ScreenSharing/OutgoingScreenSharing.h>
+#include <Swiften/Jingle/JingleSessionImpl.h>
+#include <Swiften/Jingle/JingleSessionManager.h>
+
+namespace Swift {
+
+OutgoingScreenSharingManager::OutgoingScreenSharingManager(JingleSessionManager* jingleSessionManager,IQRouter* router,
+ UDPSocketFactory *udpSocketFactory, TimerFactory* timerFactory)
+ : jsManager(jingleSessionManager), iqRouter(router), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)
+{
+}
+
+boost::shared_ptr<OutgoingScreenSharing> OutgoingScreenSharingManager::createOutgoingScreenSharing(const JID& from, const JID& to)
+{
+ JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, to, idGenerator.generateID(), iqRouter);
+ assert(jingleSession);
+ jsManager->registerOutgoingSession(from, jingleSession);
+
+ return boost::make_shared<OutgoingScreenSharing>(jingleSession, udpSocketFactory, timerFactory);
+}
+
+}
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharingManager.h b/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
new file mode 100644
index 0000000..de21d5a
--- /dev/null
+++ b/Swiften/ScreenSharing/OutgoingScreenSharingManager.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+#include <boost/shared_ptr.hpp>
+#include <Swiften/Base/IDGenerator.h>
+
+namespace Swift {
+ class OutgoingScreenSharing;
+ class JingleSessionManager;
+ class IQRouter;
+ class UDPSocketFactory;
+ class TimerFactory;
+
+ class OutgoingScreenSharingManager {
+ public:
+ OutgoingScreenSharingManager(JingleSessionManager* jingleSessionManager, IQRouter* router,
+ UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
+
+ boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& from, const JID& to);
+
+ private:
+ IDGenerator idGenerator;
+
+ JingleSessionManager* jsManager;
+ IQRouter* iqRouter;
+ UDPSocketFactory *udpSocketFactory;
+ TimerFactory* timerFactory;
+ };
+}
diff --git a/Swiften/ScreenSharing/SConscript b/Swiften/ScreenSharing/SConscript
index cc757a5..6504541 100644
--- a/Swiften/ScreenSharing/SConscript
+++ b/Swiften/ScreenSharing/SConscript
@@ -6,7 +6,13 @@ sources = [
"VP8RTPPacketizer.cpp",
"VP8Decoder.cpp",
"VP8RTPParser.cpp",
- ]
+ "ScreenSharing.cpp",
+ "OutgoingScreenSharing.cpp",
+ "OutgoingScreenSharingManager.cpp",
+ "IncomingScreenSharing.cpp",
+ "IncomingScreenSharingManager.cpp",
+ "ScreenSharingManagerImpl.cpp",
+ ]
objects = swiften_env.SwiftenObject(sources)
diff --git a/Swiften/ScreenSharing/ScreenSharing.cpp b/Swiften/ScreenSharing/ScreenSharing.cpp
new file mode 100644
index 0000000..fc7f672
--- /dev/null
+++ b/Swiften/ScreenSharing/ScreenSharing.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/ScreenSharing.h>
+
+#include <Swiften/Network/PlatformNetworkEnvironment.h>
+#include <Swiften/Elements/JingleRawUDPTransportPayload.h>
+#include <Swiften/Base/foreach.h>
+
+#include <Swiften/Network/UDPSocketFactory.h>
+#include <Swiften/Network/UDPSocket.h>
+
+namespace Swift {
+
+ScreenSharing::ScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory)
+ : session(session), udpSocketFactory(udpSocketFactory)
+{
+}
+
+ScreenSharing::~ScreenSharing()
+{
+}
+
+bool ScreenSharing::addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayload> transport)
+{
+ // TODO: NAT traversal
+
+ JingleRawUDPTransportPayload::Candidate candidate;
+ candidate.cid = idGenerator.generateID();
+ candidate.component = 1;
+ candidate.generation = 0;
+
+ PlatformNetworkEnvironment env;
+ std::vector<NetworkInterface> interfaces = env.getNetworkInterfaces();
+
+ // Find the first ip which is not loopback
+ foreach (const NetworkInterface& interface, interfaces) {
+ if (!interface.isLoopback()) { // exclude loopback
+ candidate.hostAddressPort = HostAddressPort(interface.getAddresses().front(), listeningPort);
+ candidate.type = JingleRawUDPTransportPayload::Candidate::Host;
+ transport->addCandidate(candidate);
+
+ serverSocket = udpSocketFactory->createUDPSocket();
+ serverSocket->bind(listeningPort);
+
+ return true;
+ }
+ }
+
+ // else loopback for self sharing
+ if (!interfaces.empty()) {
+ candidate.hostAddressPort = HostAddressPort(interfaces.front().getAddresses().front(), listeningPort);
+ candidate.type = JingleRawUDPTransportPayload::Candidate::Host;
+ transport->addCandidate(candidate);
+
+ serverSocket = udpSocketFactory->createUDPSocket();
+ serverSocket->bind(listeningPort);
+
+ return true;
+ }
+
+ return false;
+}
+
+}
diff --git a/Swiften/ScreenSharing/ScreenSharing.h b/Swiften/ScreenSharing/ScreenSharing.h
new file mode 100644
index 0000000..1f6f753
--- /dev/null
+++ b/Swiften/ScreenSharing/ScreenSharing.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swiften/Base/IDGenerator.h>
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+ class JingleSession;
+ class JingleRawUDPTransportPayload;
+ class UDPSocketFactory;
+ class UDPSocket;
+
+ class ScreenSharing {
+ public:
+ typedef boost::shared_ptr<ScreenSharing> ref;
+
+ enum SCState {
+ Canceled,
+ Failed,
+ Finished,
+ Negotiating,
+ Connecting,
+ BroadCasting,
+ Receiving,
+ WaitingForStart,
+ WaitingForAccept,
+ };
+
+ public:
+ ScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory);
+ virtual ~ScreenSharing();
+
+ virtual void cancel() = 0;
+
+ public:
+ boost::signal<void (SCState)> onStateChange;
+
+ protected:
+ bool addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayload> transport);
+
+ protected:
+ static const int listeningPort = 28888;
+
+ IDGenerator idGenerator;
+ boost::shared_ptr<UDPSocket> serverSocket;
+ boost::shared_ptr<UDPSocket> clientSocket;
+
+ boost::shared_ptr<JingleSession> session;
+ UDPSocketFactory* udpSocketFactory;
+
+ };
+}
diff --git a/Swiften/ScreenSharing/ScreenSharingManager.h b/Swiften/ScreenSharing/ScreenSharingManager.h
new file mode 100644
index 0000000..a527402
--- /dev/null
+++ b/Swiften/ScreenSharing/ScreenSharingManager.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+//#include <Swiften/JID/JID.h>
+#include <boost/shared_ptr.hpp>
+#include <Swiften/Base/boost_bsignals.h>
+
+namespace Swift {
+ class IncomingScreenSharing;
+ class OutgoingScreenSharing;
+ class JID;
+
+ class ScreenSharingManager {
+ public:
+ virtual ~ScreenSharingManager() {}
+
+ virtual boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& to) = 0;
+
+ boost::signal<void (boost::shared_ptr<IncomingScreenSharing>)> onIncomingScreenSharing;
+ };
+}
diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
new file mode 100644
index 0000000..4b88581
--- /dev/null
+++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/ScreenSharingManagerImpl.h>
+
+#include <Swiften/ScreenSharing/IncomingScreenSharingManager.h>
+#include <Swiften/ScreenSharing/OutgoingScreenSharingManager.h>
+
+namespace Swift {
+
+ScreenSharingManagerImpl::ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager *jingleSessionManager, IQRouter *iqRouter,
+ UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory)
+ : ownJID(ownFullJID)/*, jingleSM(jingleSessionManager), iqRouter(iqRouter), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)*/
+{
+ incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory);
+ outgoingSSManager = new OutgoingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);
+
+ incomingSSManager->onIncomingScreenSharing.connect(onIncomingScreenSharing);
+}
+
+ScreenSharingManagerImpl::~ScreenSharingManagerImpl()
+{
+}
+
+boost::shared_ptr<OutgoingScreenSharing> ScreenSharingManagerImpl::createOutgoingScreenSharing(const JID &to)
+{
+ JID receipient = to;
+
+ if (receipient.isBare()) {
+ //boost::optional<JID> fullJID = highestPriorityJIDSupportingFileTransfer(receipient);
+ //if (fullJID.is_initialized()) {
+ // receipient = fullJID.get();
+ //} else {
+ return boost::shared_ptr<OutgoingScreenSharing>();
+ //}
+ }
+
+ return outgoingSSManager->createOutgoingScreenSharing(ownJID, receipient);
+}
+
+}
diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
new file mode 100644
index 0000000..0075630
--- /dev/null
+++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/ScreenSharing/ScreenSharingManager.h>
+#include <Swiften/JID/JID.h>
+
+namespace Swift {
+ class IncomingScreenSharingManager;
+ class OutgoingScreenSharingManager;
+ class JingleSessionManager;
+ class IQRouter;
+ class UDPSocketFactory;
+ class TimerFactory;
+
+ class ScreenSharingManagerImpl : public ScreenSharingManager {
+ public:
+ ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter *iqRouter,
+ UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory);
+ virtual ~ScreenSharingManagerImpl();
+
+ virtual boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& to);
+
+ private:
+ IncomingScreenSharingManager* incomingSSManager;
+ OutgoingScreenSharingManager* outgoingSSManager;
+
+ JID ownJID;
+
+// JingleSessionManager* jingleSM;
+// IQRouter* iqRouter;
+// BoostUDPSocketFactory* udpSocketFactory;
+// TimerFactory* timerFactory;
+ };
+}