diff options
Diffstat (limited to 'Slimber/Server.cpp')
m--------- | Slimber | 0 | ||||
-rw-r--r-- | Slimber/Server.cpp | 427 |
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; -} - -} |