diff options
23 files changed, 274 insertions, 1013 deletions
diff --git a/Slimber/CLI/main.cpp b/Slimber/CLI/main.cpp index 7ebdb0f..b82ffcd 100644 --- a/Slimber/CLI/main.cpp +++ b/Slimber/CLI/main.cpp @@ -2,14 +2,8 @@ #include <boost/bind.hpp> #include "Swiften/Base/Platform.h" -#if defined(SWIFTEN_PLATFORM_MACOSX) || defined(SWIFTEN_PLATFORM_WINDOWS) -#include "Swiften/LinkLocal/AppleDNSSDService.h" -#else -#include "Swiften/LinkLocal/AvahiDNSSDService.h" -#endif #include "Slimber/Server.h" #include "Slimber/FileVCardCollection.h" -#include "Swiften/LinkLocal/LinkLocalRoster.h" #include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" #include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" #include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" @@ -27,19 +21,7 @@ int main() { browser.start(); /* - boost::shared_ptr<DNSSDService> dnsSDService; -#if defined(SWIFTEN_PLATFORM_MACOSX) || defined(SWIFTEN_PLATFORM_WINDOWS) - dnsSDService = boost::shared_ptr<AppleDNSSDService>( - new AppleDNSSDService()); -#else - dnsSDService = boost::shared_ptr<AvahiDNSSDService>( - new AvahiDNSSDService()); -#endif - - boost::shared_ptr<LinkLocalRoster> linkLocalRoster = boost::shared_ptr<LinkLocalRoster>(new LinkLocalRoster(dnsSDService)); - FileVCardCollection vCardCollection(PlatformApplication("Slimber").getSettingsDir()); - Server server(5222, 5562, linkLocalRoster, dnsSDService, &vCardCollection); */ diff --git a/Slimber/Cocoa/Makefile.inc b/Slimber/Cocoa/Makefile.inc index 8068350..8cd72cd 100644 --- a/Slimber/Cocoa/Makefile.inc +++ b/Slimber/Cocoa/Makefile.inc @@ -2,9 +2,6 @@ SLIMBER_COCOA_TARGET = Slimber/Cocoa/Slimber.app SLIMBER_COCOA_BINARY = \ Slimber/Cocoa/Slimber SLIMBER_COCOA_SOURCES = \ - Slimber/Server.cpp \ - Slimber/VCardCollection.cpp \ - Slimber/FileVCardCollection.cpp \ Slimber/Cocoa/MainController.mm \ Slimber/Cocoa/Slimber.mm \ Slimber/Cocoa/main.mm \ @@ -45,5 +42,5 @@ $(SLIMBER_COCOA_TARGET): $(SLIMBER_COCOA_BINARY) $(SLIMBER_COCOA_NIBS) Slimber/C cp $(SLIMBER_COCOA_NIBS) $(SLIMBER_COCOA_TARGET)/Contents/Resources cp $(SLIMBER_COCOA_RESOURCES) $(SLIMBER_COCOA_TARGET)/Contents/Resources -$(SLIMBER_COCOA_BINARY): $(SLIMBER_COCOA_OBJECTS) $(SWIFTEN_TARGET) - $(QUIET_LINK)$(CXX) -o $@ $(SLIMBER_COCOA_OBJECTS) $(LDFLAGS) $(SWIFTEN_TARGET) $(LIBS) -framework Cocoa +$(SLIMBER_COCOA_BINARY): $(SLIMBER_COCOA_OBJECTS) $(SWIFTEN_TARGET) $(SLIMBER_TRGET) + $(QUIET_LINK)$(CXX) -o $@ $(SLIMBER_COCOA_OBJECTS) $(LDFLAGS) $(SLIMBER_TARGET) $(SWIFTEN_TARGET) $(LIBS) -framework Cocoa diff --git a/Slimber/Cocoa/Menulet.m b/Slimber/Cocoa/Menulet.m index 4fa7fed..1cc1f1f 100644 --- a/Slimber/Cocoa/Menulet.m +++ b/Slimber/Cocoa/Menulet.m @@ -49,8 +49,10 @@ [statusMenu addItem: [[NSMenuItem alloc] initWithTitle: @"Online users:" action: NULL keyEquivalent: @""]]; int i; for (i = 0; i < [userNames count]; ++i) { - NSMenuItem* userItem = [[NSMenuItem alloc] initWithTitle: [@" " stringByAppendingString: [userNames objectAtIndex: i]] action: NULL keyEquivalent: @""]; + NSString* text = [NSString stringWithFormat: @" %@", [userNames objectAtIndex: i]]; + NSMenuItem* userItem = [[NSMenuItem alloc] initWithTitle: text action: NULL keyEquivalent: @""]; [statusMenu addItem: userItem]; + [userItem release]; } } else { diff --git a/Slimber/Cocoa/Slimber.h b/Slimber/Cocoa/Slimber.h index c2c0e2d..b62f9e5 100644 --- a/Slimber/Cocoa/Slimber.h +++ b/Slimber/Cocoa/Slimber.h @@ -1,16 +1,13 @@ #pragma once -#include <string> -#include <boost/bind.hpp> #include <boost/shared_ptr.hpp> -#include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/LinkLocal/LinkLocalRoster.h" - @class Menulet; namespace Swift { class Server; class VCardCollection; + class LinkLocalServiceBrowser; + class BonjourQuerier; } class Slimber { @@ -20,11 +17,11 @@ class Slimber { private: void handleSelfConnected(bool b); - void handleRosterChanged(); + void handleServicesChanged(); private: - boost::shared_ptr<Swift::DNSSDService> dnsSDService; - boost::shared_ptr<Swift::LinkLocalRoster>linkLocalRoster; + boost::shared_ptr<Swift::BonjourQuerier> dnsSDQuerier; + Swift::LinkLocalServiceBrowser* linkLocalServiceBrowser; Swift::VCardCollection* vCardCollection; Swift::Server* server; Menulet* menulet; diff --git a/Slimber/Cocoa/Slimber.mm b/Slimber/Cocoa/Slimber.mm index ae1d9fd..d4851c8 100644 --- a/Slimber/Cocoa/Slimber.mm +++ b/Slimber/Cocoa/Slimber.mm @@ -1,9 +1,12 @@ #include "Slimber/Cocoa/Slimber.h" +#include <boost/bind.hpp> + #include "Swiften/Base/foreach.h" -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/LinkLocal/AppleDNSSDService.h" #include "Swiften/Application/Platform/PlatformApplication.h" +#include "Swiften/LinkLocal/LinkLocalService.h" +#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" #include "Slimber/Cocoa/Menulet.h" #include "Slimber/Server.h" #include "Slimber/FileVCardCollection.h" @@ -11,37 +14,46 @@ using namespace Swift; Slimber::Slimber() { - dnsSDService = boost::shared_ptr<AppleDNSSDService>(new AppleDNSSDService()); + dnsSDQuerier = boost::shared_ptr<BonjourQuerier>(new BonjourQuerier()); + dnsSDQuerier->start(); - linkLocalRoster = boost::shared_ptr<LinkLocalRoster>(new LinkLocalRoster(dnsSDService)); - linkLocalRoster->onRosterChanged.connect(boost::bind(&Slimber::handleRosterChanged, this)); + linkLocalServiceBrowser = new LinkLocalServiceBrowser(dnsSDQuerier); + linkLocalServiceBrowser->onServiceAdded.connect( + boost::bind(&Slimber::handleServicesChanged, this)); + linkLocalServiceBrowser->onServiceRemoved.connect( + boost::bind(&Slimber::handleServicesChanged, this)); + linkLocalServiceBrowser->onServiceChanged.connect( + boost::bind(&Slimber::handleServicesChanged, this)); + linkLocalServiceBrowser->start(); - vCardCollection = new FileVCardCollection(PlatformApplication("Slimber").getSettingsDir()); + vCardCollection = new FileVCardCollection( + PlatformApplication("Slimber").getSettingsDir()); - server = new Server(5222, 5562, linkLocalRoster, dnsSDService, vCardCollection); - server->onSelfConnected.connect(boost::bind(&Slimber::handleSelfConnected, this, _1)); + server = new Server(5222, 5562, linkLocalServiceBrowser, vCardCollection); + server->onSelfConnected.connect( + boost::bind(&Slimber::handleSelfConnected, this, _1)); menulet = [[Menulet alloc] init]; - handleRosterChanged(); + handleServicesChanged(); } Slimber::~Slimber() { [menulet release]; delete server; delete vCardCollection; + linkLocalServiceBrowser->stop(); + delete linkLocalServiceBrowser; + dnsSDQuerier->stop(); } void Slimber::handleSelfConnected(bool b) { [menulet setSelfConnected: b]; } -void Slimber::handleRosterChanged() { +void Slimber::handleServicesChanged() { NSMutableArray* names = [[NSMutableArray alloc] init]; - boost::shared_ptr<RosterPayload> roster = linkLocalRoster->getRoster(); - foreach(const RosterItemPayload& item, roster->getItems()) { - NSString* name = [NSString stringWithUTF8String: item.getName().getUTF8Data()]; - [names addObject: name]; - [name release]; + foreach(const LinkLocalService& service, linkLocalServiceBrowser->getServices()) { + [names addObject: [NSString stringWithUTF8String: service.getDescription().getUTF8Data()]]; } [menulet setUserNames: names]; diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp index 39f4233..a63201b 100644 --- a/Slimber/Server.cpp +++ b/Slimber/Server.cpp @@ -3,75 +3,89 @@ #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/LinkLocalRoster.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, boost::shared_ptr<LinkLocalRoster> linkLocalRoster, boost::shared_ptr<DNSSDService> dnsSDService, VCardCollection* vCardCollection) : - dnsSDServiceRegistered_(false), - rosterRequested_(false), - clientConnectionPort_(clientConnectionPort), - linkLocalConnectionPort_(linkLocalConnectionPort), - linkLocalRoster_(linkLocalRoster), - dnsSDService_(dnsSDService), - vCardCollection_(vCardCollection) { - serverFromClientConnectionServer_ = +Server::Server( + int clientConnectionPort, + int linkLocalConnectionPort, + LinkLocalServiceBrowser* linkLocalServiceBrowser, + VCardCollection* vCardCollection) : + linkLocalServiceRegistered(false), + rosterRequested(false), + clientConnectionPort(clientConnectionPort), + linkLocalConnectionPort(linkLocalConnectionPort), + linkLocalServiceBrowser(linkLocalServiceBrowser), + vCardCollection(vCardCollection) { + serverFromClientConnectionServer = boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer( - clientConnectionPort, &boostIOServiceThread_.getIOService())); - serverFromClientConnectionServer_->onNewConnection.connect( + clientConnectionPort, &boostIOServiceThread.getIOService())); + serverFromClientConnectionServer->onNewConnection.connect( boost::bind(&Server::handleNewClientConnection, this, _1)); - serverFromClientConnectionServer_->start(); - - serverFromNetworkConnectionServer_ = - boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer( - linkLocalConnectionPort, &boostIOServiceThread_.getIOService())); - serverFromNetworkConnectionServer_->onNewConnection.connect( - boost::bind(&Server::handleNewLinkLocalConnection, this, _1)); - serverFromNetworkConnectionServer_->start(); + serverFromClientConnectionServer->start(); - dnsSDService_->onServiceRegistered.connect - (boost::bind(&Server::handleServiceRegistered, this, _1)); - linkLocalRoster_->onRosterChanged.connect( + presenceManager = new LinkLocalPresenceManager(linkLocalServiceBrowser); + presenceManager->onRosterChanged.connect( boost::bind(&Server::handleRosterChanged, this, _1)); - linkLocalRoster_->onPresenceChanged.connect( + presenceManager->onPresenceChanged.connect( boost::bind(&Server::handlePresenceChanged, this, _1)); - dnsSDService_->start(); -} -void Server::handleNewClientConnection(boost::shared_ptr<Connection> c) { - if (serverFromClientSession_) { - c->disconnect(); - } - serverFromClientSession_ = boost::shared_ptr<ServerFromClientSession>(new ServerFromClientSession(idGenerator_.generateID(), c, &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(); + linkLocalServiceBrowser->onServiceRegistered.connect( + boost::bind(&Server::handleServiceRegistered, this, _1)); + + /* + serverFromNetworkConnectionServer = + boost::shared_ptr<BoostConnectionServer>(new BoostConnectionServer( + linkLocalConnectionPort, &boostIOServiceThread.getIOService())); + serverFromNetworkConnectionServer->onNewConnection.connect( + boost::bind(&Server::handleNewLinkLocalConnection, this, _1)); + serverFromNetworkConnectionServer->start(); + */ } -void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection) { - boost::shared_ptr<IncomingLinkLocalSession> session( - new IncomingLinkLocalSession( - selfJID_, connection, - &payloadParserFactories_, &payloadSerializers_)); - registerLinkLocalSession(session); +Server::~Server() { + delete presenceManager; } -void Server::handleServiceRegistered(const DNSSDServiceID& service) { - std::cout << "Service registered " << service.getName() << " " << service.getType() << " " << service.getDomain() << std::endl; - selfJID_ = JID(service.getName()); +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() { @@ -79,34 +93,18 @@ void Server::handleSessionStarted() { } void Server::handleSessionFinished(boost::shared_ptr<ServerFromClientSession>) { - serverFromClientSession_.reset(); + serverFromClientSession.reset(); unregisterService(); - selfJID_ = JID(); - rosterRequested_ = false; + selfJID = JID(); + rosterRequested = false; onSelfConnected(false); - lastPresence_.reset(); -} - -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 (!linkLocalRoster_->hasItem(fromJID)) { - return; // TODO: Queue - } - stanza->setFrom(fromJID); - serverFromClientSession_->sendElement(stanza); - } + lastPresence.reset(); } void Server::unregisterService() { - if (dnsSDServiceRegistered_) { - dnsSDServiceRegistered_ = false; - dnsSDService_->unregisterService(); + if (linkLocalServiceRegistered) { + linkLocalServiceRegistered = false; + linkLocalServiceBrowser->unregisterService(); } } @@ -123,14 +121,17 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh if (boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza)) { if (presence->getType() == Presence::Available) { - if (!dnsSDServiceRegistered_) { - dnsSDServiceRegistered_ = true; - dnsSDService_->registerService(session->getRemoteJID().toBare().toString(), linkLocalConnectionPort_, getLinkLocalServiceInfo(presence)); + if (!linkLocalServiceRegistered) { + linkLocalServiceRegistered = true; + linkLocalServiceBrowser->registerService( + session->getRemoteJID().toBare().toString(), + linkLocalConnectionPort, getLinkLocalServiceInfo(presence)); } else { - dnsSDService_->updateService(getLinkLocalServiceInfo(presence)); + linkLocalServiceBrowser->updateService( + getLinkLocalServiceInfo(presence)); } - lastPresence_ = presence; + lastPresence = presence; } else { unregisterService(); @@ -140,9 +141,9 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh 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(), linkLocalRoster_->getRoster())); - rosterRequested_ = true; - foreach(const boost::shared_ptr<Presence> presence, linkLocalRoster_->getAllPresence()) { + session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), presenceManager->getRoster())); + rosterRequested = true; + foreach(const boost::shared_ptr<Presence> presence, presenceManager->getAllPresence()) { session->sendElement(presence); } } @@ -152,13 +153,13 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh } if (boost::shared_ptr<VCard> vcard = iq->getPayload<VCard>()) { if (iq->getType() == IQ::Get) { - session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), vCardCollection_->getOwnVCard())); + session->sendElement(IQ::createResult(iq->getFrom(), iq->getID(), vCardCollection->getOwnVCard())); } else { - vCardCollection_->setOwnVCard(vcard); + vCardCollection->setOwnVCard(vcard); session->sendElement(IQ::createResult(iq->getFrom(), iq->getID())); - if (lastPresence_) { - dnsSDService_->updateService(getLinkLocalServiceInfo(lastPresence_)); + if (lastPresence) { + linkLocalServiceBrowser->updateService(getLinkLocalServiceInfo(lastPresence)); } } } @@ -167,6 +168,7 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh } } } + /* else { JID toJID = stanza->getTo(); boost::shared_ptr<Session> outgoingSession = @@ -175,17 +177,17 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh outgoingSession->sendElement(stanza); } else { - if (linkLocalRoster_->hasItem(toJID)) { + if (linkLocalServiceBrowser->hasItem(toJID)) { boost::shared_ptr<LinkLocalConnector> connector = getLinkLocalConnectorForJID(toJID); if (!connector) { connector = boost::shared_ptr<LinkLocalConnector>( new LinkLocalConnector( toJID, - linkLocalRoster_->getHostname(toJID), - linkLocalRoster_->getPort(toJID), - dnsSDService_, - boost::shared_ptr<BoostConnection>(new BoostConnection(&boostIOServiceThread_.getIOService())))); + linkLocalServiceBrowser->getHostname(toJID), + linkLocalServiceBrowser->getPort(toJID), + linkLocalServiceBrowser, + boost::shared_ptr<BoostConnection>(new BoostConnection(&boostIOServiceThread.getIOService())))); connector->onConnectFinished.connect( boost::bind(&Server::handleConnectFinished, this, connector, _1)); connectors_.push_back(connector); @@ -200,6 +202,32 @@ void Server::handleElementReceived(boost::shared_ptr<Element> element, boost::sh } } } + */ +} + +/* +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 (!linkLocalServiceBrowser->hasItem(fromJID)) { + return; // TODO: Queue + } + stanza->setFrom(fromJID); + serverFromClientSession->sendElement(stanza); + } } void Server::handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connector, bool error) { @@ -210,8 +238,8 @@ void Server::handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connect else { boost::shared_ptr<OutgoingLinkLocalSession> outgoingSession( new OutgoingLinkLocalSession( - selfJID_, connector->getRemoteJID(), connector->getConnection(), - &payloadParserFactories_, &payloadSerializers_)); + selfJID, connector->getRemoteJID(), connector->getConnection(), + &payloadParserFactories, &payloadSerializers)); foreach(const boost::shared_ptr<Element> element, connector->getQueuedElements()) { outgoingSession->queueElement(element); } @@ -225,7 +253,7 @@ 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))); + //tracers.push_back(boost::shared_ptr<SessionTracer>(new SessionTracer(session))); session->startSession(); } @@ -246,24 +274,32 @@ boost::shared_ptr<LinkLocalConnector> Server::getLinkLocalConnectorForJID(const } 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_) { - boost::shared_ptr<IQ> iq = IQ::createRequest(IQ::Set, serverFromClientSession_->getRemoteJID(), idGenerator_.generateID(), roster); - iq->setFrom(serverFromClientSession_->getRemoteJID().toBare()); - serverFromClientSession_->sendElement(iq); + 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); + if (rosterRequested) { + serverFromClientSession->sendElement(presence); } } LinkLocalServiceInfo Server::getLinkLocalServiceInfo(boost::shared_ptr<Presence> presence) { LinkLocalServiceInfo info; - boost::shared_ptr<VCard> vcard = vCardCollection_->getOwnVCard(); + boost::shared_ptr<VCard> vcard = vCardCollection->getOwnVCard(); if (!vcard->getFamilyName().isEmpty() || !vcard->getGivenName().isEmpty()) { info.setFirstName(vcard->getGivenName()); info.setLastName(vcard->getFamilyName()); @@ -294,7 +330,7 @@ LinkLocalServiceInfo Server::getLinkLocalServiceInfo(boost::shared_ptr<Presence> info.setStatus(LinkLocalServiceInfo::DND); break; } - info.setPort(linkLocalConnectionPort_); + info.setPort(linkLocalConnectionPort); return info; } diff --git a/Slimber/Server.h b/Slimber/Server.h index 9167106..3ed0a58 100644 --- a/Slimber/Server.h +++ b/Slimber/Server.h @@ -3,49 +3,56 @@ #include <boost/shared_ptr.hpp> #include <vector> -#include "Swiften/Network/BoostConnection.h" #include "Swiften/Network/BoostIOServiceThread.h" -#include "Swiften/Network/BoostConnectionServer.h" #include "Swiften/Server/UserRegistry.h" #include "Swiften/Base/IDGenerator.h" -#include "Swiften/Network/Connection.h" -#include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/LinkLocal/LinkLocalRoster.h" -#include "Swiften/Session/SessionTracer.h" #include "Swiften/Server/ServerFromClientSession.h" -#include "Swiften/Elements/Element.h" -#include "Swiften/LinkLocal/LinkLocalConnector.h" #include "Swiften/JID/JID.h" -#include "Swiften/Elements/Presence.h" -#include "Swiften/Elements/RosterPayload.h" #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" #include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { + class DNSSDServiceID; + class String; class VCardCollection; + class LinkLocalServiceBrowser; + class LinkLocalPresenceManager; + class BoostConnectionServer; + class SessionTracer; + class RosterPayload; + class Presence; class Server { public: - Server(int clientConnectionPort, int linkLocalConnectionPort, boost::shared_ptr<LinkLocalRoster>, boost::shared_ptr<DNSSDService> dnsSDService, VCardCollection* vCardCollection); + Server( + int clientConnectionPort, + int linkLocalConnectionPort, + LinkLocalServiceBrowser* browser, + VCardCollection* vCardCollection); + ~Server(); boost::signal<void (bool)> onSelfConnected; private: void handleNewClientConnection(boost::shared_ptr<Connection> c); - void handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection); - void handleServiceRegistered(const DNSSDServiceID& service); void handleSessionStarted(); void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>); + void handleElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<ServerFromClientSession> session); + void handleRosterChanged(boost::shared_ptr<RosterPayload> roster); + void handlePresenceChanged(boost::shared_ptr<Presence> presence); + void handleServiceRegistered(const DNSSDServiceID& service); +/* + void handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection); void handleLinkLocalSessionFinished(boost::shared_ptr<Session> session); void handleLinkLocalElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<Session> session); - void unregisterService(); - void handleElementReceived(boost::shared_ptr<Element> element, boost::shared_ptr<ServerFromClientSession> session); void handleConnectFinished(boost::shared_ptr<LinkLocalConnector> connector, bool error); void registerLinkLocalSession(boost::shared_ptr<Session> session); boost::shared_ptr<Session> getLinkLocalSessionForJID(const JID& jid); boost::shared_ptr<LinkLocalConnector> getLinkLocalConnectorForJID(const JID& jid); - void handleRosterChanged(boost::shared_ptr<RosterPayload> roster); - void handlePresenceChanged(boost::shared_ptr<Presence> presence); + */ + + void unregisterService(); LinkLocalServiceInfo getLinkLocalServiceInfo(boost::shared_ptr<Presence> presence); private: @@ -59,25 +66,27 @@ namespace Swift { }; private: - IDGenerator idGenerator_; - BoostIOServiceThread boostIOServiceThread_; - DummyUserRegistry userRegistry_; - bool dnsSDServiceRegistered_; - bool rosterRequested_; - int clientConnectionPort_; - int linkLocalConnectionPort_; - boost::shared_ptr<LinkLocalRoster> linkLocalRoster_; - boost::shared_ptr<DNSSDService> dnsSDService_; - VCardCollection* vCardCollection_; - boost::shared_ptr<Presence> lastPresence_; - boost::shared_ptr<BoostConnectionServer> serverFromClientConnectionServer_; - boost::shared_ptr<ServerFromClientSession> serverFromClientSession_; + IDGenerator idGenerator; + FullPayloadParserFactoryCollection payloadParserFactories; + FullPayloadSerializerCollection payloadSerializers; + BoostIOServiceThread boostIOServiceThread; + DummyUserRegistry userRegistry; + bool linkLocalServiceRegistered; + bool rosterRequested; + int clientConnectionPort; + int linkLocalConnectionPort; + LinkLocalServiceBrowser* linkLocalServiceBrowser; + VCardCollection* vCardCollection; + LinkLocalPresenceManager* presenceManager; + boost::shared_ptr<BoostConnectionServer> serverFromClientConnectionServer; + boost::shared_ptr<ServerFromClientSession> serverFromClientSession; + boost::shared_ptr<Presence> lastPresence; + JID selfJID; + /* boost::shared_ptr<BoostConnectionServer> serverFromNetworkConnectionServer_; - std::vector< boost::shared_ptr<SessionTracer> > tracers_; std::vector< boost::shared_ptr<Session> > linkLocalSessions_; std::vector< boost::shared_ptr<LinkLocalConnector> > connectors_; - FullPayloadParserFactoryCollection payloadParserFactories_; - FullPayloadSerializerCollection payloadSerializers_; - JID selfJID_; +*/ + std::vector< boost::shared_ptr<SessionTracer> > tracers; }; } diff --git a/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp b/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp index a1ecdf8..f15daf4 100644 --- a/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp +++ b/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp @@ -18,6 +18,7 @@ using namespace Swift; class LinkLocalPresenceManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(LinkLocalPresenceManagerTest); + CPPUNIT_TEST(testConstructor); CPPUNIT_TEST(testServiceAdded); CPPUNIT_TEST(testServiceRemoved); CPPUNIT_TEST(testServiceChanged); @@ -31,8 +32,6 @@ class LinkLocalPresenceManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE_END(); public: - LinkLocalPresenceManagerTest() {} - void setUp() { eventLoop = new DummyEventLoop(); querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier("wonderland.lit")); @@ -46,6 +45,15 @@ class LinkLocalPresenceManagerTest : public CppUnit::TestFixture { delete eventLoop; } + void testConstructor() { + addService("alice@wonderland"); + addService("rabbit@teaparty"); + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(testling->getRoster()->getItems().size())); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(testling->getAllPresence().size())); + } + void testServiceAdded() { std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp deleted file mode 100644 index a052eb1..0000000 --- a/Swiften/LinkLocal/AppleDNSSDService.cpp +++ /dev/null @@ -1,299 +0,0 @@ -#include "Swiften/LinkLocal/AppleDNSSDService.h" - -#include <algorithm> -#include <unistd.h> -#include <iostream> -#include <sys/socket.h> -#include <netinet/in.h> -#include <fcntl.h> - -#include "Swiften/EventLoop/MainEventLoop.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Network/HostAddress.h" - -namespace Swift { - -AppleDNSSDService::AppleDNSSDService() : thread(0), stopRequested(false), haveError(false), browseSDRef(0), registerSDRef(0) { - int fds[2]; - int result = pipe(fds); - assert(result == 0); - interruptSelectReadSocket = fds[0]; - fcntl(interruptSelectReadSocket, F_SETFL, fcntl(interruptSelectReadSocket, F_GETFL)|O_NONBLOCK); - interruptSelectWriteSocket = fds[1]; -} - -AppleDNSSDService::~AppleDNSSDService() { - stop(); -} - -void AppleDNSSDService::start() { - stop(); - thread = new boost::thread(boost::bind(&AppleDNSSDService::doStart, shared_from_this())); -} - -void AppleDNSSDService::stop() { - if (thread) { - stopRequested = true; - interruptSelect(); - thread->join(); - delete thread; - stopRequested = false; - } -} - -void AppleDNSSDService::registerService(const String& name, int port, const LinkLocalServiceInfo& info) { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - assert(!registerSDRef); - ByteArray txtRecord = info.toTXTRecord(); - DNSServiceErrorType result = DNSServiceRegister(®isterSDRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, txtRecord.getSize(), txtRecord.getData(), &AppleDNSSDService::handleServiceRegisteredGlobal, this); - if (result != kDNSServiceErr_NoError) { - std::cerr << "Error creating service registration" << std::endl; - haveError = true; - } - - interruptSelect(); -} - -void AppleDNSSDService::updateService(const LinkLocalServiceInfo& info) { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - assert(registerSDRef); - ByteArray txtRecord = info.toTXTRecord(); - DNSServiceUpdateRecord(registerSDRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); -} - -void AppleDNSSDService::unregisterService() { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - assert(registerSDRef); - DNSServiceRefDeallocate(registerSDRef); // Interrupts select() - registerSDRef = NULL; -} - -void AppleDNSSDService::startResolvingService(const DNSSDServiceID& service) { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - DNSServiceRef resolveSDRef; - DNSServiceErrorType result = DNSServiceResolve(&resolveSDRef, 0, service.getNetworkInterfaceID(), service.getName().getUTF8Data(), service.getType().getUTF8Data(), service.getDomain().getUTF8Data(), &AppleDNSSDService::handleServiceResolvedGlobal, this); - if (result != kDNSServiceErr_NoError) { - std::cerr << "Error creating service resolve query" << std::endl; - haveError = true; - } - else { - bool isNew = resolveSDRefs.insert(std::make_pair(service, resolveSDRef)).second; - assert(isNew); - } - - interruptSelect(); -} - -void AppleDNSSDService::stopResolvingService(const DNSSDServiceID& service) { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - ServiceSDRefMap::iterator i = resolveSDRefs.find(service); - assert(i != resolveSDRefs.end()); - DNSServiceRefDeallocate(i->second); // Interrupts select() - resolveSDRefs.erase(i); -} - -void AppleDNSSDService::resolveHostname(const String& hostname, int interfaceIndex) { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - DNSServiceRef hostnameResolveSDRef; - DNSServiceErrorType result = DNSServiceGetAddrInfo(&hostnameResolveSDRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, hostname.getUTF8Data(), &AppleDNSSDService::handleHostnameResolvedGlobal, this); - if (result != kDNSServiceErr_NoError) { - std::cerr << "Error creating hostname resolve query" << std::endl; - haveError = true; - } - else { - hostnameResolveSDRefs.push_back(hostnameResolveSDRef); - } - - interruptSelect(); -} - -void AppleDNSSDService::doStart() { - haveError = false; - onStarted(); - - // Listen for new services - { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - assert(!browseSDRef); - DNSServiceErrorType result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, &AppleDNSSDService::handleServiceDiscoveredGlobal , this); - if (result != kDNSServiceErr_NoError) { - std::cerr << "Error creating browse query" << std::endl; - haveError = true; - } - } - - // Run the main loop - while (!haveError && !stopRequested) { - fd_set fdSet; - FD_ZERO(&fdSet); - int maxSocket = interruptSelectReadSocket; - FD_SET(interruptSelectReadSocket, &fdSet); - - { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - // Browsing - int browseSocket = DNSServiceRefSockFD(browseSDRef); - maxSocket = std::max(maxSocket, browseSocket); - FD_SET(browseSocket, &fdSet); - - // Registration - if (registerSDRef) { - int registerSocket = DNSServiceRefSockFD(registerSDRef); - maxSocket = std::max(maxSocket, registerSocket); - FD_SET(registerSocket, &fdSet); - } - - // Service resolving - for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { - int resolveSocket = DNSServiceRefSockFD(i->second); - maxSocket = std::max(maxSocket, resolveSocket); - FD_SET(resolveSocket, &fdSet); - } - - // Hostname resolving - for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) { - int hostnameResolveSocket = DNSServiceRefSockFD(*i); - maxSocket = std::max(maxSocket, hostnameResolveSocket); - FD_SET(hostnameResolveSocket, &fdSet); - } - } - - int selectResult = select(maxSocket+1, &fdSet, NULL, NULL, 0); - - // Flush the interruptSelectReadSocket - if (FD_ISSET(interruptSelectReadSocket, &fdSet)) { - char dummy; - while (read(interruptSelectReadSocket, &dummy, 1) > 0) {} - } - - { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - if (selectResult <= 0) { - continue; - } - if (FD_ISSET(DNSServiceRefSockFD(browseSDRef), &fdSet)) { - DNSServiceProcessResult(browseSDRef); - } - if (registerSDRef && FD_ISSET(DNSServiceRefSockFD(registerSDRef), &fdSet)) { - DNSServiceProcessResult(registerSDRef); - } - for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { - if (FD_ISSET(DNSServiceRefSockFD(i->second), &fdSet)) { - DNSServiceProcessResult(i->second); - } - } - for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) { - if (FD_ISSET(DNSServiceRefSockFD(*i), &fdSet)) { - DNSServiceProcessResult(*i); - hostnameResolveSDRefs.erase(std::remove(hostnameResolveSDRefs.begin(), hostnameResolveSDRefs.end(), *i), hostnameResolveSDRefs.end()); - DNSServiceRefDeallocate(*i); - break; // Stop the loop, because we removed an element - } - } - } - } - - { - boost::lock_guard<boost::mutex> lock(sdRefsMutex); - - for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { - DNSServiceRefDeallocate(i->second); - } - resolveSDRefs.clear(); - - for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) { - DNSServiceRefDeallocate(*i); - } - hostnameResolveSDRefs.clear(); - - if (registerSDRef) { - DNSServiceRefDeallocate(registerSDRef); - registerSDRef = NULL; - } - - DNSServiceRefDeallocate(browseSDRef); - browseSDRef = NULL; - } - - MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), haveError), shared_from_this()); -} - -void AppleDNSSDService::interruptSelect() { - char c = 0; - write(interruptSelectWriteSocket, &c, 1); -} - -void AppleDNSSDService::handleServiceDiscoveredGlobal(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context ) { - static_cast<AppleDNSSDService*>(context)->handleServiceDiscovered(sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain); -} - -void AppleDNSSDService::handleServiceDiscovered(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain) { - if (errorCode != kDNSServiceErr_NoError) { - return; - } - else { - DNSSDServiceID service(serviceName, regtype, replyDomain, interfaceIndex); - if (flags & kDNSServiceFlagsAdd) { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); - } - else { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); - } - } -} - -void AppleDNSSDService::handleServiceRegisteredGlobal(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { - static_cast<AppleDNSSDService*>(context)->handleServiceRegistered(sdRef, flags, errorCode, name, regtype, domain); -} - -void AppleDNSSDService::handleServiceRegistered(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { - if (errorCode != kDNSServiceErr_NoError) { - std::cerr << "Error registering service" << std::endl; - haveError = true; - } - else { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRegistered), DNSSDServiceID(name, regtype, domain, 0)), shared_from_this()); - } -} - -void AppleDNSSDService::handleServiceResolvedGlobal(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context ) { - static_cast<AppleDNSSDService*>(context)->handleServiceResolved(sdRef, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtLen, txtRecord); -} - -void AppleDNSSDService::handleServiceResolved(DNSServiceRef sdRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord) { - if (errorCode != kDNSServiceErr_NoError) { - return; - } - for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { - if (i->second == sdRef) { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), i->first, ResolveResult(hosttarget, port, LinkLocalServiceInfo::createFromTXTRecord(ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), shared_from_this()); - return; - } - } - assert(false); -} - -void AppleDNSSDService::handleHostnameResolvedGlobal(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { - static_cast<AppleDNSSDService*>(context)->handleHostnameResolved(sdRef, flags, interfaceIndex, errorCode, hostname, address, ttl); -} - -void AppleDNSSDService::handleHostnameResolved(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *rawAddress, uint32_t) { - if (errorCode) { - std::cerr << "Error resolving hostname" << std::endl; - MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), hostname, boost::optional<HostAddress>()), shared_from_this()); - } - else { - assert(rawAddress->sa_family == AF_INET); - const sockaddr_in* sa = reinterpret_cast<const sockaddr_in*>(rawAddress); - uint32_t address = ntohl(sa->sin_addr.s_addr); - MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), String(hostname), HostAddress(reinterpret_cast<unsigned char*>(&address), 4)), shared_from_this()); - } -} - -} diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h deleted file mode 100644 index 554a154..0000000 --- a/Swiften/LinkLocal/AppleDNSSDService.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include <boost/enable_shared_from_this.hpp> -#include <boost/thread.hpp> -#include <boost/thread/mutex.hpp> -#include <dns_sd.h> - -#include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/EventLoop/EventOwner.h" - -namespace Swift { - class AppleDNSSDService : public DNSSDService, public EventOwner, public boost::enable_shared_from_this<AppleDNSSDService> { - public: - AppleDNSSDService(); - ~AppleDNSSDService(); - - virtual void start(); - virtual void stop(); - - virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&); - virtual void updateService(const LinkLocalServiceInfo&); - virtual void unregisterService(); - - virtual void startResolvingService(const DNSSDServiceID&); - virtual void stopResolvingService(const DNSSDServiceID&); - - virtual void resolveHostname(const String& hostname, int interfaceIndex = 0); - - private: - void doStart(); - void interruptSelect(); - - static void handleServiceDiscoveredGlobal(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char *, const char *, const char *, void*); - void handleServiceDiscovered(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char *, const char *, const char *); - static void handleServiceRegisteredGlobal(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType, const char *, const char *, const char *, void *); - void handleServiceRegistered(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType, const char *, const char *, const char *); - static void handleServiceResolvedGlobal(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char *, const char *, uint16_t, uint16_t, const unsigned char *, void *); - void handleServiceResolved(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char *, const char *, uint16_t, uint16_t, const unsigned char *); - static void handleHostnameResolvedGlobal(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context); - void handleHostnameResolved(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl); - - private: - boost::thread* thread; - bool stopRequested; - bool haveError; - int interruptSelectReadSocket; - int interruptSelectWriteSocket; - boost::mutex sdRefsMutex; - DNSServiceRef browseSDRef; - DNSServiceRef registerSDRef; - typedef std::map<DNSSDServiceID, DNSServiceRef> ServiceSDRefMap; - ServiceSDRefMap resolveSDRefs; - typedef std::vector<DNSServiceRef> HostnameSDRefs; - HostnameSDRefs hostnameResolveSDRefs; - }; -} diff --git a/Swiften/LinkLocal/AvahiDNSSDService.cpp b/Swiften/LinkLocal/AvahiDNSSDService.cpp deleted file mode 100644 index 5f6295f..0000000 --- a/Swiften/LinkLocal/AvahiDNSSDService.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "Swiften/LinkLocal/AvahiDNSSDService.h" - -#include <boost/bind.hpp> - -#include "Swiften/EventLoop/MainEventLoop.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Network/HostAddress.h" - -namespace Swift { - -AvahiDNSSDService::AvahiDNSSDService() : client(NULL), threadedPoll(0), serviceBrowser(0) { -} - -AvahiDNSSDService::~AvahiDNSSDService() { -} - -void AvahiDNSSDService::start() { - threadedPoll = avahi_threaded_poll_new(); - - int error; - client = avahi_client_new( - avahi_threaded_poll_get(threadedPoll), - static_cast<AvahiClientFlags>(0), NULL, this, &error); // TODO - if (!client) { - // TODO - std::cerr << "Avahi Error: " << avahi_strerror(error) << std::endl; - return; - } - - serviceBrowser = avahi_service_browser_new( - client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, - "_presence._tcp", NULL, static_cast<AvahiLookupFlags>(0), - handleServiceDiscoveredGlobal, this); - if (!serviceBrowser) { - // TODO - std::cerr << "Avahi Error: " << avahi_strerror(error) << std::endl; - return; - } - - avahi_threaded_poll_start(threadedPoll); -} - -void AvahiDNSSDService::stop() { - avahi_threaded_poll_stop(threadedPoll); - avahi_service_browser_free(serviceBrowser); - avahi_client_free(client); - avahi_threaded_poll_free(threadedPoll); -} - -void AvahiDNSSDService::registerService(const String& name, int port, const LinkLocalServiceInfo& info) { - avahi_threaded_poll_lock(threadedPoll); - avahi_threaded_poll_unlock(threadedPoll); -} - -void AvahiDNSSDService::updateService(const LinkLocalServiceInfo& info) { - avahi_threaded_poll_lock(threadedPoll); - avahi_threaded_poll_unlock(threadedPoll); -} - -void AvahiDNSSDService::unregisterService() { - avahi_threaded_poll_lock(threadedPoll); - avahi_threaded_poll_unlock(threadedPoll); -} - -void AvahiDNSSDService::startResolvingService(const DNSSDServiceID& service) { - avahi_threaded_poll_lock(threadedPoll); - - AvahiServiceResolver* resolver = avahi_service_resolver_new( - client, - service.getNetworkInterfaceID(), - AVAHI_PROTO_INET, - service.getName().getUTF8Data(), - service.getType().getUTF8Data(), - service.getDomain().getUTF8Data(), - AVAHI_PROTO_UNSPEC, - static_cast<AvahiLookupFlags>(0), - &AvahiDNSSDService::handleServiceResolvedGlobal, - this); - assert(serviceResolvers.find(service) == serviceResolvers.end()); - serviceResolvers[service] = resolver; - - avahi_threaded_poll_unlock(threadedPoll); -} - -void AvahiDNSSDService::stopResolvingService(const DNSSDServiceID& service) { - avahi_threaded_poll_lock(threadedPoll); - - ServiceResolverMap::iterator i = serviceResolvers.find(service); - assert(i != serviceResolvers.end()); - avahi_service_resolver_free(i->second); - serviceResolvers.erase(i); - - avahi_threaded_poll_unlock(threadedPoll); -} - -// TODO: Take interfaceIndex into account -void AvahiDNSSDService::resolveHostname(const String& hostname, int) { - HostnameAddressMap::const_iterator i = hostnameAddresses.find(hostname); - if (i == hostnameAddresses.end()) { - MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), hostname, boost::optional<HostAddress>()), shared_from_this()); - } - else { - MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), hostname, boost::optional<HostAddress>(i->second)), shared_from_this()); - } -} - -void AvahiDNSSDService::handleServiceDiscovered(AvahiServiceBrowser *, AvahiIfIndex interfaceIndex, AvahiProtocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags) { - switch(event) { - case AVAHI_BROWSER_FAILURE: - std::cerr << "Browse error" << std::endl; - // TODO - return; - case AVAHI_BROWSER_NEW: { - std::cerr << "Service added: " << name << " " << type << " " << domain << std::endl; - DNSSDServiceID service(name, type, domain, interfaceIndex); - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); - } - break; - case AVAHI_BROWSER_REMOVE: { - std::cerr << "Service removed: " << name << " " << type << " " << domain << std::endl; - DNSSDServiceID service(name, type, domain, interfaceIndex); - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); - } - break; - case AVAHI_BROWSER_ALL_FOR_NOW: - case AVAHI_BROWSER_CACHE_EXHAUSTED: - break; - } -} - -void AvahiDNSSDService::handleServiceResolved(AvahiServiceResolver *, AvahiIfIndex interfaceIndex, AvahiProtocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *hostname, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags) { - switch(event) { - case AVAHI_RESOLVER_FAILURE: - //TODO - std::cerr << "Resolve error" << std::endl; - break; - case AVAHI_RESOLVER_FOUND: - ByteArray data; - for(AvahiStringList* i = txt; i; i = avahi_string_list_get_next(i)) { - char size = i->size; - data += ByteArray(&size, 1); - data += ByteArray(reinterpret_cast<char*>(avahi_string_list_get_text(i)), avahi_string_list_get_size(i)); - } - - assert(address->proto == AVAHI_PROTO_INET); - HostAddress hostAddress(reinterpret_cast<const unsigned char*>(&address->data.ipv4.address), 4); - hostnameAddresses[String(hostname)] = hostAddress; - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), - DNSSDServiceID(name, type, domain, interfaceIndex), - ResolveResult(hostname, port, - LinkLocalServiceInfo::createFromTXTRecord(data))), - shared_from_this()); - break; - } -} - -} diff --git a/Swiften/LinkLocal/AvahiDNSSDService.h b/Swiften/LinkLocal/AvahiDNSSDService.h deleted file mode 100644 index 7162ade..0000000 --- a/Swiften/LinkLocal/AvahiDNSSDService.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include <map> -#include <boost/enable_shared_from_this.hpp> -#include <avahi-client/client.h> -#include <avahi-client/lookup.h> -#include <avahi-common/thread-watch.h> -#include <avahi-common/watch.h> -#include <avahi-common/malloc.h> -#include <avahi-common/error.h> - - -#include "Swiften/EventLoop/EventOwner.h" -#include "Swiften/LinkLocal/DNSSDService.h" - -namespace Swift { - class AvahiDNSSDService : public DNSSDService, public EventOwner, public boost::enable_shared_from_this<AvahiDNSSDService> { - public: - AvahiDNSSDService(); - ~AvahiDNSSDService(); - - virtual void start(); - virtual void stop(); - - virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&); - virtual void updateService(const LinkLocalServiceInfo&); - virtual void unregisterService(); - - virtual void startResolvingService(const DNSSDServiceID&); - virtual void stopResolvingService(const DNSSDServiceID&); - - virtual void resolveHostname(const String& hostname, int interfaceIndex = 0); - - private: - static void handleServiceDiscoveredGlobal(AvahiServiceBrowser *b, AvahiIfIndex networkInterface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata) { - static_cast<AvahiDNSSDService*>(userdata)->handleServiceDiscovered(b, networkInterface, protocol, event, name, type, domain, flags); - } - void handleServiceDiscovered(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags); - - static void handleServiceResolvedGlobal(AvahiServiceResolver *r, AvahiIfIndex interfaceIndex, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *hostname, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void* userdata) { - static_cast<AvahiDNSSDService*>(userdata)->handleServiceResolved(r, interfaceIndex, protocol, event, name, type, domain, hostname, address, port, txt, flags); - } - void handleServiceResolved(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *hostname, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags); - - - private: - AvahiClient* client; - AvahiThreadedPoll* threadedPoll; - AvahiServiceBrowser* serviceBrowser; - typedef std::map<DNSSDServiceID, AvahiServiceResolver*> ServiceResolverMap; - ServiceResolverMap serviceResolvers; - typedef std::map<String, HostAddress> HostnameAddressMap; - HostnameAddressMap hostnameAddresses; - }; -} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h index 34d5742..ddc2788 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -48,7 +48,7 @@ namespace Swift { MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); } else { - MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, regtype, domain, 0))), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, domain, regtype, 0))), shared_from_this()); } } }; diff --git a/Swiften/LinkLocal/DNSSDService.cpp b/Swiften/LinkLocal/DNSSDService.cpp deleted file mode 100644 index 9545981..0000000 --- a/Swiften/LinkLocal/DNSSDService.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDService.h" - -namespace Swift { - -DNSSDService::~DNSSDService() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h deleted file mode 100644 index 0ace21b..0000000 --- a/Swiften/LinkLocal/DNSSDService.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include <boost/signal.hpp> -#include <map> - -#include "Swiften/Base/String.h" -#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" - -namespace Swift { - class LinkLocalServiceInfo; - class HostAddress; - - class DNSSDService { - public: - struct ResolveResult { - ResolveResult(const String& host, int port, const LinkLocalServiceInfo& info) : host(host), port(port), info(info) {} - String host; - int port; - LinkLocalServiceInfo info; - }; - - virtual ~DNSSDService(); - - virtual void start() = 0; - virtual void stop() = 0; - - virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&) = 0; - virtual void updateService(const LinkLocalServiceInfo&) = 0; - virtual void unregisterService() = 0; - - virtual void startResolvingService(const DNSSDServiceID&) = 0; - virtual void stopResolvingService(const DNSSDServiceID&) = 0; - - virtual void resolveHostname(const String& hostname, int interfaceIndex = 0) = 0; - - boost::signal<void ()> onStarted; - boost::signal<void (bool)> onStopped; - boost::signal<void (const DNSSDServiceID&)> onServiceAdded; - boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; - boost::signal<void (const DNSSDServiceID&)> onServiceRegistered; - boost::signal<void (const DNSSDServiceID&, const ResolveResult&)> onServiceResolved; - boost::signal<void (const String&, const boost::optional<HostAddress>&)> onHostnameResolved; - }; -} diff --git a/Swiften/LinkLocal/LinkLocalConnector.cpp b/Swiften/LinkLocal/LinkLocalConnector.cpp index af521b0..28107ed 100644 --- a/Swiften/LinkLocal/LinkLocalConnector.cpp +++ b/Swiften/LinkLocal/LinkLocalConnector.cpp @@ -6,7 +6,7 @@ #include "Swiften/Network/ConnectionFactory.h" #include "Swiften/Network/HostAddress.h" #include "Swiften/Network/HostAddressPort.h" -#include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" namespace Swift { @@ -14,22 +14,23 @@ LinkLocalConnector::LinkLocalConnector( const JID& remoteJID, const String& hostname, int port, - boost::shared_ptr<DNSSDService> resolver, + boost::shared_ptr<DNSSDQuerier> querier, boost::shared_ptr<Connection> connection) : remoteJID_(remoteJID), hostname_(hostname), port_(port), - resolver_(resolver), + querier_(querier), connection_(connection), resolving_(false) { } void LinkLocalConnector::connect() { resolving_ = true; - resolver_->onHostnameResolved.connect(boost::bind(&LinkLocalConnector::handleHostnameResolved, boost::dynamic_pointer_cast<LinkLocalConnector>(shared_from_this()), _1, _2)); - resolver_->resolveHostname(hostname_); + //querier_->onHostnameResolved.connect(boost::bind(&LinkLocalConnector::handleHostnameResolved, boost::dynamic_pointer_cast<LinkLocalConnector>(shared_from_this()), _1, _2)); + //querier_->resolveHostname(hostname_); } +/* void LinkLocalConnector::handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address) { if (resolving_) { if (hostname == hostname_) { @@ -44,6 +45,7 @@ void LinkLocalConnector::handleHostnameResolved(const String& hostname, const bo } } } +*/ void LinkLocalConnector::handleConnected(bool error) { onConnectFinished(error); diff --git a/Swiften/LinkLocal/LinkLocalConnector.h b/Swiften/LinkLocal/LinkLocalConnector.h index d296804..2ddb5b8 100644 --- a/Swiften/LinkLocal/LinkLocalConnector.h +++ b/Swiften/LinkLocal/LinkLocalConnector.h @@ -15,7 +15,7 @@ namespace Swift { class Element; class PayloadParserFactoryCollection; class PayloadSerializerCollection; - class DNSSDService; + class DNSSDQuerier; class LinkLocalConnector : public boost::enable_shared_from_this<LinkLocalConnector> { public: @@ -23,7 +23,7 @@ namespace Swift { const JID& remoteJID, const String& hostname, int port, - boost::shared_ptr<DNSSDService> resolver, + boost::shared_ptr<DNSSDQuerier> querier, boost::shared_ptr<Connection> connection); const JID& getRemoteJID() const { @@ -44,14 +44,14 @@ namespace Swift { boost::signal<void (bool)> onConnectFinished; private: - void handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address); + //void handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address); void handleConnected(bool error); private: JID remoteJID_; String hostname_; int port_; - boost::shared_ptr<DNSSDService> resolver_; + boost::shared_ptr<DNSSDQuerier> querier_; boost::shared_ptr<Connection> connection_; bool resolving_; std::vector<boost::shared_ptr<Element> > queuedElements_; diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp deleted file mode 100644 index af3c1af..0000000 --- a/Swiften/LinkLocal/LinkLocalRoster.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include <boost/bind.hpp> -#include <iostream> - -#include "Swiften/LinkLocal/LinkLocalRoster.h" -#include "Swiften/Network/HostAddress.h" - -namespace Swift { - -LinkLocalRoster::LinkLocalRoster(boost::shared_ptr<DNSSDService> service) : dnsSDService(service) { - dnsSDService->onStopped.connect(boost::bind(&LinkLocalRoster::handleStopped, this, _1)); - dnsSDService->onServiceRegistered.connect(boost::bind(&LinkLocalRoster::handleServiceRegistered, this, _1)); - dnsSDService->onServiceAdded.connect(boost::bind(&LinkLocalRoster::handleServiceAdded, this, _1)); - dnsSDService->onServiceRemoved.connect(boost::bind(&LinkLocalRoster::handleServiceRemoved, this, _1)); - dnsSDService->onServiceResolved.connect(boost::bind(&LinkLocalRoster::handleServiceResolved, this, _1, _2)); -} - -boost::shared_ptr<RosterPayload> LinkLocalRoster::getRoster() const { - boost::shared_ptr<RosterPayload> roster(new RosterPayload()); - for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { - roster->addItem(getRosterItem(i->first, i->second)); - } - return roster; -} - -std::vector<boost::shared_ptr<Presence> > LinkLocalRoster::getAllPresence() const { - std::vector<boost::shared_ptr<Presence> > result; - for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { - result.push_back(getPresence(i->first, i->second)); - } - return result; -} - -RosterItemPayload LinkLocalRoster::getRosterItem(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { - return RosterItemPayload(getJIDForService(service), getRosterName(service, resolveResult), RosterItemPayload::Both); -} - -String LinkLocalRoster::getRosterName(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { - if (!resolveResult.info.getNick().isEmpty()) { - return resolveResult.info.getNick(); - } - else if (!resolveResult.info.getFirstName().isEmpty()) { - String result = resolveResult.info.getFirstName(); - if (!resolveResult.info.getLastName().isEmpty()) { - result += " " + resolveResult.info.getLastName(); - } - return result; - } - else if (!resolveResult.info.getLastName().isEmpty()) { - return resolveResult.info.getLastName(); - } - return service.getName(); -} - -JID LinkLocalRoster::getJIDForService(const DNSSDServiceID& service) const { - return JID(service.getName()); -} - -boost::shared_ptr<Presence> LinkLocalRoster::getPresence(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { - boost::shared_ptr<Presence> presence(new Presence()); - presence->setFrom(getJIDForService(service)); - switch (resolveResult.info.getStatus()) { - case LinkLocalServiceInfo::Available: - presence->setShow(StatusShow::Online); - break; - case LinkLocalServiceInfo::Away: - presence->setShow(StatusShow::Away); - break; - case LinkLocalServiceInfo::DND: - presence->setShow(StatusShow::DND); - break; - } - presence->setStatus(resolveResult.info.getMessage()); - return presence; -} - -void LinkLocalRoster::handleServiceAdded(const DNSSDServiceID& service) { - if (selfService && *selfService == service) { - return; - } - dnsSDService->startResolvingService(service); -} - -void LinkLocalRoster::handleServiceRemoved(const DNSSDServiceID& service) { - if (selfService && *selfService == service) { - return; - } - dnsSDService->stopResolvingService(service); - services.erase(service); - boost::shared_ptr<RosterPayload> roster(new RosterPayload()); - roster->addItem(RosterItemPayload(getJIDForService(service), "", RosterItemPayload::Remove)); - onRosterChanged(roster); -} - -void LinkLocalRoster::handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result) { - std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, result)); - if (r.second) { - boost::shared_ptr<RosterPayload> roster(new RosterPayload()); - roster->addItem(getRosterItem(service, result)); - onRosterChanged(roster); - } - else { - r.first->second = result; - } - onPresenceChanged(getPresence(service, result)); -} - -void LinkLocalRoster::handleServiceRegistered(const DNSSDServiceID& service) { - selfService = service; -} - -void LinkLocalRoster::handleStopped(bool error) { - std::cout << "DNSSDService stopped: " << error << std::endl; -} - -bool LinkLocalRoster::hasItem(const JID& j) const { - for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { - if (getJIDForService(i->first) == j) { - return true; - } - } - return false; -} - -String LinkLocalRoster::getHostname(const JID& j) const { - for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { - if (getJIDForService(i->first) == j) { - return i->second.host; - } - } - return ""; -} - -int LinkLocalRoster::getPort(const JID& j) const { - for(ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { - if (getJIDForService(i->first) == j) { - return i->second.port; - } - } - return 0; -} - -} diff --git a/Swiften/LinkLocal/LinkLocalRoster.h b/Swiften/LinkLocal/LinkLocalRoster.h deleted file mode 100644 index 03ed2d5..0000000 --- a/Swiften/LinkLocal/LinkLocalRoster.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include <boost/shared_ptr.hpp> -#include <boost/optional.hpp> -#include <set> - -#include "Swiften/Base/String.h" -#include "Swiften/JID/JID.h" -#include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/Elements/RosterPayload.h" -#include "Swiften/Elements/Presence.h" - -namespace Swift { - class HostAddress; - - class LinkLocalRoster { - public: - LinkLocalRoster(boost::shared_ptr<DNSSDService> service); - - boost::shared_ptr<RosterPayload> getRoster() const; - std::vector<boost::shared_ptr<Presence> > getAllPresence() const; - - boost::signal<void (boost::shared_ptr<RosterPayload>)> onRosterChanged; - boost::signal<void (boost::shared_ptr<Presence>)> onPresenceChanged; - - bool hasItem(const JID&) const; - String getHostname(const JID&) const; - int getPort(const JID&) const; - - private: - RosterItemPayload getRosterItem(const DNSSDServiceID& service, const DNSSDService::ResolveResult& info) const; - String getRosterName(const DNSSDServiceID& service, const DNSSDService::ResolveResult& info) const; - JID getJIDForService(const DNSSDServiceID& service) const; - boost::shared_ptr<Presence> getPresence(const DNSSDServiceID& service, const DNSSDService::ResolveResult& info) const; - - void handleStopped(bool); - void handleServiceRegistered(const DNSSDServiceID& service); - void handleServiceAdded(const DNSSDServiceID&); - void handleServiceRemoved(const DNSSDServiceID&); - void handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result); - - private: - boost::shared_ptr<DNSSDService> dnsSDService; - boost::optional<DNSSDServiceID> selfService; - typedef std::map<DNSSDServiceID, DNSSDService::ResolveResult> ServiceMap; - ServiceMap services; - }; -} diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index f65cd7a..b24d8f0 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -65,6 +65,11 @@ void LinkLocalServiceBrowser::registerService(const String& name, int port, cons registerQuery->registerService(); } +void LinkLocalServiceBrowser::updateService(const LinkLocalServiceInfo& info) { + assert(registerQuery); + registerQuery->updateServiceInfo(info.toTXTRecord()); +} + void LinkLocalServiceBrowser::unregisterService() { assert(registerQuery); registerQuery->unregisterService(); @@ -125,6 +130,7 @@ void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& servic void LinkLocalServiceBrowser::handleRegisterFinished(const boost::optional<DNSSDServiceID>& result) { if (result) { selfService = result; + onServiceRegistered(*result); } else { haveError = true; diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index a6623b1..7ef661c 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -25,7 +25,12 @@ namespace Swift { bool isRunning() const; bool hasError() const; - void registerService(const String& name, int port, const LinkLocalServiceInfo& info = LinkLocalServiceInfo()); + void registerService( + const String& name, + int port, + const LinkLocalServiceInfo& info = LinkLocalServiceInfo()); + void updateService( + const LinkLocalServiceInfo& info = LinkLocalServiceInfo()); void unregisterService(); bool isRegistered() const; @@ -34,6 +39,7 @@ namespace Swift { boost::signal<void (const LinkLocalService&)> onServiceAdded; boost::signal<void (const LinkLocalService&)> onServiceChanged; boost::signal<void (const LinkLocalService&)> onServiceRemoved; + boost::signal<void (const DNSSDServiceID&)> onServiceRegistered; boost::signal<void (bool)> onStopped; private: diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 3738789..715d686 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,21 +1,10 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/LinkLocalServiceBrowser.cpp \ - Swiften/LinkLocal/DNSSDService.cpp \ Swiften/LinkLocal/LinkLocalService.cpp \ - Swiften/LinkLocal/LinkLocalRoster.cpp \ Swiften/LinkLocal/LinkLocalServiceInfo.cpp \ Swiften/LinkLocal/IncomingLinkLocalSession.cpp \ Swiften/LinkLocal/OutgoingLinkLocalSession.cpp \ Swiften/LinkLocal/LinkLocalConnector.cpp -ifeq ($(HAVE_BONJOUR),yes) -SWIFTEN_SOURCES += \ - Swiften/LinkLocal/AppleDNSSDService.cpp -endif -ifeq ($(HAVE_AVAHI),yes) -SWIFTEN_SOURCES += \ - Swiften/LinkLocal/AvahiDNSSDService.cpp -endif - include Swiften/LinkLocal/DNSSD/Makefile.inc include Swiften/LinkLocal/UnitTest/Makefile.inc diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 6e4d3b4..76117c0 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -27,6 +27,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testRegisterService); CPPUNIT_TEST(testRegisterService_Error); CPPUNIT_TEST(testRegisterService_Reregister); + CPPUNIT_TEST(testUpdateService); CPPUNIT_TEST_SUITE_END(); public: @@ -239,7 +240,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop->processEvents(); CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); - + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(registeredServices.size())); + CPPUNIT_ASSERT(registeredServices[0] == DNSSDServiceID("foo@bar", "wonderland.lit")); testling->stop(); } @@ -279,6 +281,23 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { testling->stop(); } + void testUpdateService() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + + LinkLocalServiceInfo info; + info.setFirstName("Foo"); + testling->registerService("foo@bar", 1234, info); + eventLoop->processEvents(); + info.setFirstName("Bar"); + testling->updateService(info); + + CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); + + testling->stop(); + } + private: boost::shared_ptr<LinkLocalServiceBrowser> createTestling() { boost::shared_ptr<LinkLocalServiceBrowser> testling( @@ -289,6 +308,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { &LinkLocalServiceBrowserTest::handleServiceChanged, this, _1)); testling->onServiceRemoved.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceRemoved, this, _1)); + testling->onServiceRegistered.connect(boost::bind( + &LinkLocalServiceBrowserTest::handleServiceRegistered, this, _1)); testling->onStopped.connect(boost::bind( &LinkLocalServiceBrowserTest::handleStopped, this, _1)); return testling; @@ -306,6 +327,10 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { changedServices.push_back(service); } + void handleServiceRegistered(const DNSSDServiceID& service) { + registeredServices.push_back(service); + } + void handleStopped(bool error) { CPPUNIT_ASSERT(!errorStopReceived); CPPUNIT_ASSERT(!normalStopReceived); @@ -323,6 +348,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { std::vector<LinkLocalService> addedServices; std::vector<LinkLocalService> changedServices; std::vector<LinkLocalService> removedServices; + std::vector<DNSSDServiceID> registeredServices; DNSSDServiceID* aliceServiceID; DNSSDResolveServiceQuery::Result* aliceServiceInfo; DNSSDServiceID* testServiceID; |