diff options
Diffstat (limited to 'Slimber')
-rw-r--r-- | Slimber/Server.cpp | 99 | ||||
-rw-r--r-- | Slimber/Server.h | 14 | ||||
-rw-r--r-- | Slimber/ServerError.h | 31 |
3 files changed, 133 insertions, 11 deletions
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp index 36595b1..44a5861 100644 --- a/Slimber/Server.cpp +++ b/Slimber/Server.cpp @@ -37,33 +37,82 @@ Server::Server( clientConnectionPort(clientConnectionPort), linkLocalConnectionPort(linkLocalConnectionPort), linkLocalServiceBrowser(linkLocalServiceBrowser), - vCardCollection(vCardCollection) { + vCardCollection(vCardCollection), + presenceManager(NULL), + stopping(false) { + linkLocalServiceBrowser->onServiceRegistered.connect( + boost::bind(&Server::handleServiceRegistered, this, _1)); +} + +Server::~Server() { + stop(); +} + +void Server::start() { + assert(!serverFromClientConnectionServer); serverFromClientConnectionServer = boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer( clientConnectionPort, &boostIOServiceThread.getIOService())); serverFromClientConnectionServer->onNewConnection.connect( boost::bind(&Server::handleNewClientConnection, this, _1)); + serverFromClientConnectionServer->onStopped.connect( + boost::bind(&Server::handleClientConnectionServerStopped, this, _1)); serverFromClientConnectionServer->start(); - presenceManager = new LinkLocalPresenceManager(linkLocalServiceBrowser); - presenceManager->onRosterChanged.connect( - boost::bind(&Server::handleRosterChanged, this, _1)); - presenceManager->onPresenceChanged.connect( - boost::bind(&Server::handlePresenceChanged, this, _1)); - - linkLocalServiceBrowser->onServiceRegistered.connect( - boost::bind(&Server::handleServiceRegistered, this, _1)); - + assert(!serverFromNetworkConnectionServer); serverFromNetworkConnectionServer = boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer( linkLocalConnectionPort, &boostIOServiceThread.getIOService())); serverFromNetworkConnectionServer->onNewConnection.connect( boost::bind(&Server::handleNewLinkLocalConnection, this, _1)); + serverFromClientConnectionServer->onStopped.connect( + boost::bind(&Server::handleLinkLocalConnectionServerStopped, this, _1)); serverFromNetworkConnectionServer->start(); + + assert(!presenceManager); + presenceManager = new LinkLocalPresenceManager(linkLocalServiceBrowser); + presenceManager->onRosterChanged.connect( + boost::bind(&Server::handleRosterChanged, this, _1)); + presenceManager->onPresenceChanged.connect( + boost::bind(&Server::handlePresenceChanged, this, _1)); } -Server::~Server() { +void Server::stop() { + stop(boost::optional<ServerError>()); +} + +void Server::stop(boost::optional<ServerError> e) { + if (stopping) { + return; + } + + stopping = true; + delete presenceManager; + + if (serverFromClientSession) { + serverFromClientSession->finishSession(); + } + serverFromClientSession.reset(); + foreach(boost::shared_ptr<Session> session, linkLocalSessions) { + session->finishSession(); + } + linkLocalSessions.clear(); + foreach(boost::shared_ptr<LinkLocalConnector> connector, connectors) { + connector->cancel(); + } + connectors.clear(); + tracers.clear(); + + if (serverFromNetworkConnectionServer) { + serverFromNetworkConnectionServer->stop(); + } + if (serverFromClientConnectionServer) { + serverFromClientConnectionServer->stop(); + } + + stopping = false; + onStopped(e); } void Server::handleNewClientConnection(boost::shared_ptr<Connection> connection) { @@ -294,6 +343,34 @@ void Server::handlePresenceChanged(boost::shared_ptr<Presence> presence) { } } +void Server::handleClientConnectionServerStopped(boost::optional<BoostConnectionServer::Error> e) { + if (e) { + if (*e == BoostConnectionServer::Conflict) { + stop(ServerError(ServerError::C2SPortConflict)); + } + else { + stop(ServerError(ServerError::C2SError)); + } + } + else { + stop(); + } +} + +void Server::handleLinkLocalConnectionServerStopped(boost::optional<BoostConnectionServer::Error> e) { + if (e) { + if (*e == BoostConnectionServer::Conflict) { + stop(ServerError(ServerError::LinkLocalPortConflict)); + } + else { + stop(ServerError(ServerError::LinkLocalError)); + } + } + else { + stop(); + } +} + LinkLocalServiceInfo Server::getLinkLocalServiceInfo(boost::shared_ptr<Presence> presence) { LinkLocalServiceInfo info; boost::shared_ptr<VCard> vcard = vCardCollection->getOwnVCard(); diff --git a/Slimber/Server.h b/Slimber/Server.h index 38c45de..ff3f70d 100644 --- a/Slimber/Server.h +++ b/Slimber/Server.h @@ -1,9 +1,11 @@ #pragma once #include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> #include <vector> #include "Swiften/Network/BoostIOServiceThread.h" +#include "Swiften/Network/BoostConnectionServer.h" #include "Swiften/Server/UserRegistry.h" #include "Swiften/Base/IDGenerator.h" #include "Swiften/Server/ServerFromClientSession.h" @@ -11,6 +13,7 @@ #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" #include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Slimber/ServerError.h" namespace Swift { class DNSSDServiceID; @@ -33,9 +36,15 @@ namespace Swift { VCardCollection* vCardCollection); ~Server(); + void start(); + void stop(); + boost::signal<void (bool)> onSelfConnected; + boost::signal<void (boost::optional<ServerError>)> onStopped; private: + void stop(boost::optional<ServerError>); + void handleNewClientConnection(boost::shared_ptr<Connection> c); void handleSessionStarted(); void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>); @@ -47,6 +56,10 @@ namespace Swift { void handleLinkLocalSessionFinished(boost::shared_ptr<Session> session); void handleLinkLocalElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<Session> session); void handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connector, bool error); + void handleClientConnectionServerStopped( + boost::optional<BoostConnectionServer::Error>); + void handleLinkLocalConnectionServerStopped( + boost::optional<BoostConnectionServer::Error>); boost::shared_ptr<Session> getLinkLocalSessionForJID(const JID& jid); boost::shared_ptr<LinkLocalConnector> getLinkLocalConnectorForJID(const JID& jid); void registerLinkLocalSession(boost::shared_ptr<Session> session); @@ -76,6 +89,7 @@ namespace Swift { LinkLocalServiceBrowser* linkLocalServiceBrowser; VCardCollection* vCardCollection; LinkLocalPresenceManager* presenceManager; + bool stopping; boost::shared_ptr<BoostConnectionServer> serverFromClientConnectionServer; boost::shared_ptr<ServerFromClientSession> serverFromClientSession; boost::shared_ptr<Presence> lastPresence; diff --git a/Slimber/ServerError.h b/Slimber/ServerError.h new file mode 100644 index 0000000..ce293c2 --- /dev/null +++ b/Slimber/ServerError.h @@ -0,0 +1,31 @@ +#pragma once + +#include "Swiften/Base/String.h" + +namespace Swift { + class ServerError { + public: + enum Type { + C2SPortConflict, + C2SError, + LinkLocalPortConflict, + LinkLocalError + }; + + ServerError(Type type, const String& message = String()) : + type(type), message(message) { + } + + Type getType() const { + return type; + } + + const String& getMessage() const { + return message; + } + + private: + Type type; + String message; + }; +} |