summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Slimber/Server.cpp')
m---------Slimber0
-rw-r--r--Slimber/Server.cpp427
2 files changed, 0 insertions, 427 deletions
diff --git a/Slimber b/Slimber
new file mode 160000
+Subproject 723115ef8542c640580ea4751fca3c359a79dec
diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp
deleted file mode 100644
index 278a572..0000000
--- a/Slimber/Server.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-#include "Slimber/Server.h"
-
-#include <string>
-#include <boost/bind.hpp>
-
-#include "Swiften/LinkLocal/LinkLocalConnector.h"
-#include "Swiften/Network/Connection.h"
-#include "Swiften/Session/SessionTracer.h"
-#include "Swiften/Elements/Element.h"
-#include "Swiften/Elements/Presence.h"
-#include "Swiften/Elements/RosterPayload.h"
-#include "Swiften/Network/BoostConnection.h"
-#include "Swiften/Network/BoostConnectionServer.h"
-#include "Swiften/Session/SessionTracer.h"
-#include "Swiften/Elements/IQ.h"
-#include "Swiften/Elements/VCard.h"
-#include "Swiften/Server/UserRegistry.h"
-#include "Swiften/Base/String.h"
-#include "Swiften/LinkLocal/LinkLocalServiceInfo.h"
-#include "Swiften/LinkLocal/OutgoingLinkLocalSession.h"
-#include "Swiften/LinkLocal/IncomingLinkLocalSession.h"
-#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h"
-#include "Swiften/Network/ConnectionServer.h"
-#include "Slimber/VCardCollection.h"
-#include "Slimber/LinkLocalPresenceManager.h"
-#include "Swiften/Server/ServerFromClientSession.h"
-
-namespace Swift {
-
-Server::Server(
- int clientConnectionPort,
- int linkLocalConnectionPort,
- LinkLocalServiceBrowser* linkLocalServiceBrowser,
- VCardCollection* vCardCollection) :
- linkLocalServiceRegistered(false),
- rosterRequested(false),
- clientConnectionPort(clientConnectionPort),
- linkLocalConnectionPort(linkLocalConnectionPort),
- linkLocalServiceBrowser(linkLocalServiceBrowser),
- 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()));
- serverFromClientConnectionServerSignalConnections.push_back(
- serverFromClientConnectionServer->onNewConnection.connect(
- boost::bind(&Server::handleNewClientConnection, this, _1)));
- serverFromClientConnectionServerSignalConnections.push_back(
- serverFromClientConnectionServer->onStopped.connect(
- boost::bind(&Server::handleClientConnectionServerStopped, this, _1)));
-
- assert(!serverFromNetworkConnectionServer);
- serverFromNetworkConnectionServer =
- boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer(
- linkLocalConnectionPort, &boostIOServiceThread.getIOService()));
- serverFromNetworkConnectionServerSignalConnections.push_back(
- serverFromNetworkConnectionServer->onNewConnection.connect(
- boost::bind(&Server::handleNewLinkLocalConnection, this, _1)));
- serverFromNetworkConnectionServerSignalConnections.push_back(
- serverFromNetworkConnectionServer->onStopped.connect(
- boost::bind(&Server::handleLinkLocalConnectionServerStopped, this, _1)));
-
- assert(!presenceManager);
- presenceManager = new LinkLocalPresenceManager(linkLocalServiceBrowser);
- presenceManager->onRosterChanged.connect(
- boost::bind(&Server::handleRosterChanged, this, _1));
- presenceManager->onPresenceChanged.connect(
- boost::bind(&Server::handlePresenceChanged, this, _1));
-
- serverFromClientConnectionServer->start();
- serverFromNetworkConnectionServer->start();
-}
-
-void Server::stop() {
- stop(boost::optional<ServerError>());
-}
-
-void Server::stop(boost::optional<ServerError> e) {
- if (stopping) {
- return;
- }
-
- stopping = true;
-
- delete presenceManager;
- presenceManager = NULL;
-
- 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();
- foreach(boost::bsignals::connection& connection, serverFromNetworkConnectionServerSignalConnections) {
- connection.disconnect();
- }
- serverFromNetworkConnectionServerSignalConnections.clear();
- serverFromNetworkConnectionServer.reset();
- }
- if (serverFromClientConnectionServer) {
- serverFromClientConnectionServer->stop();
- foreach(boost::bsignals::connection& connection, serverFromClientConnectionServerSignalConnections) {
- connection.disconnect();
- }
- serverFromClientConnectionServerSignalConnections.clear();
- serverFromClientConnectionServer.reset();
- }
-
- stopping = false;
- onStopped(e);
-}
-
-void Server::handleNewClientConnection(boost::shared_ptr<Connection> connection) {
- if (serverFromClientSession) {
- connection->disconnect();
- }
- serverFromClientSession = boost::shared_ptr<ServerFromClientSession>(
- new ServerFromClientSession(idGenerator.generateID(), connection,
- &payloadParserFactories, &payloadSerializers, &userRegistry));
- serverFromClientSession->onSessionStarted.connect(
- boost::bind(&Server::handleSessionStarted, this));
- serverFromClientSession->onElementReceived.connect(
- boost::bind(&Server::handleElementReceived, this, _1,
- serverFromClientSession));
- serverFromClientSession->onSessionFinished.connect(
- boost::bind(&Server::handleSessionFinished, this,
- serverFromClientSession));
- //tracers.push_back(boost::shared_ptr<SessionTracer>(
- // new SessionTracer(serverFromClientSession)));
- serverFromClientSession->startSession();
-}
-
-void Server::handleSessionStarted() {
- onSelfConnected(true);
-}
-
-void Server::handleSessionFinished(boost::shared_ptr<ServerFromClientSession>) {
- serverFromClientSession.reset();
- unregisterService();
- selfJID = JID();
- rosterRequested = false;
- onSelfConnected(false);
- lastPresence.reset();
-}
-
-void Server::unregisterService() {
- if (linkLocalServiceRegistered) {
- linkLocalServiceRegistered = false;
- linkLocalServiceBrowser->unregisterService();
- }
-}
-
-void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<ServerFromClientSession> session) {
- boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
- if (!stanza) {
- return;
- }
-
- stanza->setFrom(session->getRemoteJID());
- if (!stanza->getTo().isValid()) {
- stanza->setTo(session->getLocalJID());
- }
-
- if (boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza)) {
- if (presence->getType() == Presence::Available) {
- if (!linkLocalServiceRegistered) {
- linkLocalServiceRegistered = true;
- linkLocalServiceBrowser->registerService(
- session->getRemoteJID().toBare().toString(),
- linkLocalConnectionPort, getLinkLocalServiceInfo(presence));
- }
- else {
- linkLocalServiceBrowser->updateService(
- getLinkLocalServiceInfo(presence));
- }
- lastPresence = presence;
- }
- else {
- unregisterService();
- }
- }
- else if (!stanza->getTo().isValid() || stanza->getTo() == session->getLocalJID() || stanza->getTo() == session->getRemoteJID().toBare()) {
- if (boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza)) {
- if (iq->getPayload<RosterPayload>()) {
- if (iq->getType() == IQ::Get) {
- session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), presenceManager->getRoster()));
- rosterRequested = true;
- foreach(const boost::shared_ptr<Presence> presence, presenceManager->getAllPresence()) {
- session->sendElement(presence);
- }
- }
- else {
- session->sendElement(IQ::createError(iq->getFrom(), iq->getID(), ErrorPayload::Forbidden, ErrorPayload::Cancel));
- }
- }
- if (boost::shared_ptr<VCard> vcard = iq->getPayload<VCard>()) {
- if (iq->getType() == IQ::Get) {
- session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), vCardCollection->getOwnVCard()));
- }
- else {
- vCardCollection->setOwnVCard(vcard);
- session->sendElement(IQ::createResult(iq->getFrom(), iq->getID()));
- if (lastPresence) {
- linkLocalServiceBrowser->updateService(getLinkLocalServiceInfo(lastPresence));
- }
- }
- }
- else {
- session->sendElement(IQ::createError(iq->getFrom(), iq->getID(), ErrorPayload::FeatureNotImplemented, ErrorPayload::Cancel));
- }
- }
- }
- else {
- JID toJID = stanza->getTo();
- boost::shared_ptr<Session> outgoingSession =
- getLinkLocalSessionForJID(toJID);
- if (outgoingSession) {
- outgoingSession->sendElement(stanza);
- }
- else {
- boost::optional<LinkLocalService> service =
- presenceManager->getServiceForJID(toJID);
- if (service) {
- boost::shared_ptr<LinkLocalConnector> connector =
- getLinkLocalConnectorForJID(toJID);
- if (!connector) {
- connector = boost::shared_ptr<LinkLocalConnector>(
- new LinkLocalConnector(
- *service,
- linkLocalServiceBrowser->getQuerier(),
- boost::shared_ptr<BoostConnection>(new BoostConnection(&boostIOServiceThread.getIOService()))));
- connector->onConnectFinished.connect(
- boost::bind(&Server::handleConnectFinished, this, connector, _1));
- connectors.push_back(connector);
- connector->connect();
- }
- connector->queueElement(element);
- }
- else {
- session->sendElement(IQ::createError(
- stanza->getFrom(), stanza->getID(),
- ErrorPayload::RecipientUnavailable, ErrorPayload::Wait));
- }
- }
- }
-}
-
-void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection) {
- boost::shared_ptr<IncomingLinkLocalSession> session(
- new IncomingLinkLocalSession(
- selfJID, connection,
- &payloadParserFactories, &payloadSerializers));
- registerLinkLocalSession(session);
-}
-
-void Server::handleLinkLocalSessionFinished(boost::shared_ptr<Session> session) {
- //std::cout << "Link local session from " << session->getRemoteJID() << " ended" << std::endl;
- linkLocalSessions.erase(
- std::remove(linkLocalSessions.begin(), linkLocalSessions.end(), session),
- linkLocalSessions.end());
-}
-
-void Server::handleLinkLocalElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<Session> session) {
- if (boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element)) {
- JID fromJID = session->getRemoteJID();
- if (!presenceManager->getServiceForJID(fromJID.toBare())) {
- return; // TODO: Send error back
- }
- stanza->setFrom(fromJID);
- serverFromClientSession->sendElement(stanza);
- }
-}
-
-void Server::handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connector, bool error) {
- if (error) {
- std::cerr << "Error connecting" << std::endl;
- // TODO: Send back queued stanzas
- }
- else {
- boost::shared_ptr<OutgoingLinkLocalSession> outgoingSession(
- new OutgoingLinkLocalSession(
- selfJID, connector->getService().getJID(), connector->getConnection(),
- &payloadParserFactories, &payloadSerializers));
- foreach(const boost::shared_ptr<Element> element, connector->getQueuedElements()) {
- outgoingSession->queueElement(element);
- }
- registerLinkLocalSession(outgoingSession);
- }
- connectors.erase(std::remove(connectors.begin(), connectors.end(), connector), connectors.end());
-}
-
-void Server::registerLinkLocalSession(boost::shared_ptr<Session> session) {
- session->onSessionFinished.connect(
- boost::bind(&Server::handleLinkLocalSessionFinished, this, session));
- session->onElementReceived.connect(
- boost::bind(&Server::handleLinkLocalElementReceived, this, _1, session));
- linkLocalSessions.push_back(session);
- //tracers.push_back(boost::shared_ptr<SessionTracer>(new SessionTracer(session)));
- session->startSession();
-}
-
-boost::shared_ptr<Session> Server::getLinkLocalSessionForJID(const JID& jid) {
- foreach(const boost::shared_ptr<Session> session, linkLocalSessions) {
- if (session->getRemoteJID() == jid) {
- return session;
- }
- }
- return boost::shared_ptr<Session>();
-}
-
-boost::shared_ptr<LinkLocalConnector> Server::getLinkLocalConnectorForJID(const JID& jid) {
- foreach(const boost::shared_ptr<LinkLocalConnector> connector, connectors) {
- if (connector->getService().getJID() == jid) {
- return connector;
- }
- }
- return boost::shared_ptr<LinkLocalConnector>();
-}
-
-void Server::handleServiceRegistered(const DNSSDServiceID& service) {
- selfJID = JID(service.getName());
-}
-
-void Server::handleRosterChanged(boost::shared_ptr<RosterPayload> roster) {
- if (rosterRequested) {
- assert(serverFromClientSession);
- boost::shared_ptr<IQ> iq = IQ::createRequest(
- IQ::Set, serverFromClientSession->getRemoteJID(),
- idGenerator.generateID(), roster);
- iq->setFrom(serverFromClientSession->getRemoteJID().toBare());
- serverFromClientSession->sendElement(iq);
- }
-}
-
-void Server::handlePresenceChanged(boost::shared_ptr<Presence> presence) {
- if (rosterRequested) {
- serverFromClientSession->sendElement(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();
- if (!vcard->getFamilyName().isEmpty() || !vcard->getGivenName().isEmpty()) {
- info.setFirstName(vcard->getGivenName());
- info.setLastName(vcard->getFamilyName());
- }
- else if (!vcard->getFullName().isEmpty()) {
- std::pair<String,String> p = vcard->getFullName().getSplittedAtFirst(' ');
- info.setFirstName(p.first);
- info.setLastName(p.second);
- }
- if (!vcard->getNickname().isEmpty()) {
- info.setNick(vcard->getNickname());
- }
- if (!vcard->getEMail().isEmpty()) {
- info.setEMail(vcard->getEMail());
- }
- info.setMessage(presence->getStatus());
- switch (presence->getShow()) {
- case StatusShow::Online:
- case StatusShow::None:
- case StatusShow::FFC:
- info.setStatus(LinkLocalServiceInfo::Available);
- break;
- case StatusShow::Away:
- case StatusShow::XA:
- info.setStatus(LinkLocalServiceInfo::Away);
- break;
- case StatusShow::DND:
- info.setStatus(LinkLocalServiceInfo::DND);
- break;
- }
- info.setPort(linkLocalConnectionPort);
- return info;
-}
-
-}