From 15103cc6eb3dd62c0e84c68bb08995247c653094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Wed, 22 Jul 2009 21:28:48 +0200 Subject: Introduce LinkLocalServiceID to identify Link-Local services. diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp index 969cbb2..5262357 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.cpp +++ b/Swiften/LinkLocal/AppleDNSSDService.cpp @@ -70,11 +70,11 @@ void AppleDNSSDService::unregisterService() { registerSDRef = NULL; } -void AppleDNSSDService::startResolvingService(const Service& service) { +void AppleDNSSDService::startResolvingService(const LinkLocalServiceID& service) { boost::lock_guard<boost::mutex> lock(sdRefsMutex); DNSServiceRef resolveSDRef; - DNSServiceErrorType result = DNSServiceResolve(&resolveSDRef, 0, service.networkInterface, service.name.getUTF8Data(), service.type.getUTF8Data(), service.domain.getUTF8Data(), &AppleDNSSDService::handleServiceResolvedGlobal, this); + 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; @@ -87,7 +87,7 @@ void AppleDNSSDService::startResolvingService(const Service& service) { interruptSelect(); } -void AppleDNSSDService::stopResolvingService(const Service& service) { +void AppleDNSSDService::stopResolvingService(const LinkLocalServiceID& service) { boost::lock_guard<boost::mutex> lock(sdRefsMutex); ServiceSDRefMap::iterator i = resolveSDRefs.find(service); @@ -238,7 +238,7 @@ void AppleDNSSDService::handleServiceDiscovered(DNSServiceRef, DNSServiceFlags f return; } else { - Service service(serviceName, regtype, replyDomain, interfaceIndex); + LinkLocalServiceID service(serviceName, regtype, replyDomain, interfaceIndex); if (flags & kDNSServiceFlagsAdd) { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); } @@ -258,7 +258,7 @@ void AppleDNSSDService::handleServiceRegistered(DNSServiceRef, DNSServiceFlags, haveError = true; } else { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRegistered), Service(name, regtype, domain, 0)), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRegistered), LinkLocalServiceID(name, regtype, domain, 0)), shared_from_this()); } } diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h index fe4a648..7fdfd3e 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.h +++ b/Swiften/LinkLocal/AppleDNSSDService.h @@ -6,6 +6,7 @@ #include <dns_sd.h> #include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/LinkLocalServiceID.h" #include "Swiften/EventLoop/EventOwner.h" namespace Swift { @@ -21,8 +22,8 @@ namespace Swift { virtual void updateService(const LinkLocalServiceInfo&); virtual void unregisterService(); - virtual void startResolvingService(const Service&); - virtual void stopResolvingService(const Service&); + virtual void startResolvingService(const LinkLocalServiceID&); + virtual void stopResolvingService(const LinkLocalServiceID&); virtual void resolveHostname(const String& hostname, int interfaceIndex = 0); @@ -48,7 +49,7 @@ namespace Swift { boost::mutex sdRefsMutex; DNSServiceRef browseSDRef; DNSServiceRef registerSDRef; - typedef std::map<Service, DNSServiceRef> ServiceSDRefMap; + typedef std::map<LinkLocalServiceID, DNSServiceRef> ServiceSDRefMap; ServiceSDRefMap resolveSDRefs; typedef std::vector<DNSServiceRef> HostnameSDRefs; HostnameSDRefs hostnameResolveSDRefs; diff --git a/Swiften/LinkLocal/AvahiDNSSDService.cpp b/Swiften/LinkLocal/AvahiDNSSDService.cpp index 1dd5c28..72039b7 100644 --- a/Swiften/LinkLocal/AvahiDNSSDService.cpp +++ b/Swiften/LinkLocal/AvahiDNSSDService.cpp @@ -62,16 +62,16 @@ void AvahiDNSSDService::unregisterService() { avahi_threaded_poll_unlock(threadedPoll); } -void AvahiDNSSDService::startResolvingService(const Service& service) { +void AvahiDNSSDService::startResolvingService(const LinkLocalServiceID& service) { avahi_threaded_poll_lock(threadedPoll); AvahiServiceResolver* resolver = avahi_service_resolver_new( client, - service.networkInterface, + service.getNetworkInterfaceID(), AVAHI_PROTO_INET, - service.name.getUTF8Data(), - service.type.getUTF8Data(), - service.domain.getUTF8Data(), + service.getName().getUTF8Data(), + service.getType().getUTF8Data(), + service.getDomain().getUTF8Data(), AVAHI_PROTO_UNSPEC, static_cast<AvahiLookupFlags>(0), &AvahiDNSSDService::handleServiceResolvedGlobal, @@ -112,13 +112,13 @@ void AvahiDNSSDService::handleServiceDiscovered(AvahiServiceBrowser *, AvahiIfIn return; case AVAHI_BROWSER_NEW: { std::cerr << "Service added: " << name << " " << type << " " << domain << std::endl; - Service service(name, type, domain, interfaceIndex); + LinkLocalServiceID 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; - Service service(name, type, domain, interfaceIndex); + LinkLocalServiceID service(name, type, domain, interfaceIndex); MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); } break; @@ -146,7 +146,7 @@ void AvahiDNSSDService::handleServiceResolved(AvahiServiceResolver *, AvahiIfInd HostAddress hostAddress(reinterpret_cast<const unsigned char*>(&address->data.ipv4.address), 4); hostnameAddresses[String(hostname)] = hostAddress; MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), - Service(name, type, domain, interfaceIndex), + LinkLocalServiceID(name, type, domain, interfaceIndex), ResolveResult(hostname, port, LinkLocalServiceInfo::createFromTXTRecord(data))), shared_from_this()); diff --git a/Swiften/LinkLocal/AvahiDNSSDService.h b/Swiften/LinkLocal/AvahiDNSSDService.h index 8d31e41..a5be943 100644 --- a/Swiften/LinkLocal/AvahiDNSSDService.h +++ b/Swiften/LinkLocal/AvahiDNSSDService.h @@ -26,8 +26,8 @@ namespace Swift { virtual void updateService(const LinkLocalServiceInfo&); virtual void unregisterService(); - virtual void startResolvingService(const Service&); - virtual void stopResolvingService(const Service&); + virtual void startResolvingService(const LinkLocalServiceID&); + virtual void stopResolvingService(const LinkLocalServiceID&); virtual void resolveHostname(const String& hostname, int interfaceIndex = 0); diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h index 9689352..4cf1a6e 100644 --- a/Swiften/LinkLocal/DNSSDService.h +++ b/Swiften/LinkLocal/DNSSDService.h @@ -4,6 +4,7 @@ #include <map> #include "Swiften/Base/String.h" +#include "Swiften/LinkLocal/LinkLocalServiceID.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { @@ -12,36 +13,6 @@ namespace Swift { class DNSSDService { public: - struct Service { - Service(const String& name, const String& type, const String& domain, int networkInterface) : name(name), type(type), domain(domain), networkInterface(networkInterface) {} - bool operator==(const Service& o) const { - return name == o.name && type == o.type && domain == o.domain && (networkInterface != 0 && o.networkInterface != 0 ? networkInterface == o.networkInterface : true); - } - bool operator<(const Service& o) const { - if (o.name == name) { - if (o.type == type) { - if (o.domain == domain) { - return networkInterface < o.networkInterface; - } - else { - return domain < o.domain; - } - } - else { - return type < o.type; - } - } - else { - return o.name < name; - } - } - - String name; - String type; - String domain; - int networkInterface; - }; - struct ResolveResult { ResolveResult(const String& host, int port, const LinkLocalServiceInfo& info) : host(host), port(port), info(info) {} String host; @@ -58,17 +29,17 @@ namespace Swift { virtual void updateService(const LinkLocalServiceInfo&) = 0; virtual void unregisterService() = 0; - virtual void startResolvingService(const Service&) = 0; - virtual void stopResolvingService(const Service&) = 0; + virtual void startResolvingService(const LinkLocalServiceID&) = 0; + virtual void stopResolvingService(const LinkLocalServiceID&) = 0; virtual void resolveHostname(const String& hostname, int interfaceIndex = 0) = 0; boost::signal<void ()> onStarted; boost::signal<void (bool)> onStopped; - boost::signal<void (const Service&)> onServiceAdded; - boost::signal<void (const Service&)> onServiceRemoved; - boost::signal<void (const Service&)> onServiceRegistered; - boost::signal<void (const Service&, const ResolveResult&)> onServiceResolved; + boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; + boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; + boost::signal<void (const LinkLocalServiceID&)> onServiceRegistered; + boost::signal<void (const LinkLocalServiceID&, const ResolveResult&)> onServiceResolved; boost::signal<void (const String&, const boost::optional<HostAddress>&)> onHostnameResolved; }; } diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp index 25143a6..5a6ccfd 100644 --- a/Swiften/LinkLocal/LinkLocalRoster.cpp +++ b/Swiften/LinkLocal/LinkLocalRoster.cpp @@ -30,11 +30,11 @@ std::vector<boost::shared_ptr<Presence> > LinkLocalRoster::getAllPresence() cons return result; } -RosterItemPayload LinkLocalRoster::getRosterItem(const DNSSDService::Service& service, const DNSSDService::ResolveResult& resolveResult) const { +RosterItemPayload LinkLocalRoster::getRosterItem(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { return RosterItemPayload(getJIDForService(service), getRosterName(service, resolveResult), RosterItemPayload::Both); } -String LinkLocalRoster::getRosterName(const DNSSDService::Service& service, const DNSSDService::ResolveResult& resolveResult) const { +String LinkLocalRoster::getRosterName(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { if (!resolveResult.info.getNick().isEmpty()) { return resolveResult.info.getNick(); } @@ -48,14 +48,14 @@ String LinkLocalRoster::getRosterName(const DNSSDService::Service& service, cons else if (!resolveResult.info.getLastName().isEmpty()) { return resolveResult.info.getLastName(); } - return service.name; + return service.getName(); } -JID LinkLocalRoster::getJIDForService(const DNSSDService::Service& service) const { - return JID(service.name); +JID LinkLocalRoster::getJIDForService(const LinkLocalServiceID& service) const { + return JID(service.getName()); } -boost::shared_ptr<Presence> LinkLocalRoster::getPresence(const DNSSDService::Service& service, const DNSSDService::ResolveResult& resolveResult) const { +boost::shared_ptr<Presence> LinkLocalRoster::getPresence(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { boost::shared_ptr<Presence> presence(new Presence()); presence->setFrom(getJIDForService(service)); switch (resolveResult.info.getStatus()) { @@ -73,14 +73,14 @@ boost::shared_ptr<Presence> LinkLocalRoster::getPresence(const DNSSDService::Ser return presence; } -void LinkLocalRoster::handleServiceAdded(const DNSSDService::Service& service) { +void LinkLocalRoster::handleServiceAdded(const LinkLocalServiceID& service) { if (selfService && *selfService == service) { return; } dnsSDService->startResolvingService(service); } -void LinkLocalRoster::handleServiceRemoved(const DNSSDService::Service& service) { +void LinkLocalRoster::handleServiceRemoved(const LinkLocalServiceID& service) { if (selfService && *selfService == service) { return; } @@ -91,7 +91,7 @@ void LinkLocalRoster::handleServiceRemoved(const DNSSDService::Service& service) onRosterChanged(roster); } -void LinkLocalRoster::handleServiceResolved(const DNSSDService::Service& service, const DNSSDService::ResolveResult& result) { +void LinkLocalRoster::handleServiceResolved(const LinkLocalServiceID& 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()); @@ -104,7 +104,7 @@ void LinkLocalRoster::handleServiceResolved(const DNSSDService::Service& service onPresenceChanged(getPresence(service, result)); } -void LinkLocalRoster::handleServiceRegistered(const DNSSDService::Service& service) { +void LinkLocalRoster::handleServiceRegistered(const LinkLocalServiceID& service) { selfService = service; } diff --git a/Swiften/LinkLocal/LinkLocalRoster.h b/Swiften/LinkLocal/LinkLocalRoster.h index c18d8fc..128e39d 100644 --- a/Swiften/LinkLocal/LinkLocalRoster.h +++ b/Swiften/LinkLocal/LinkLocalRoster.h @@ -28,21 +28,21 @@ namespace Swift { int getPort(const JID&) const; private: - RosterItemPayload getRosterItem(const DNSSDService::Service& service, const DNSSDService::ResolveResult& info) const; - String getRosterName(const DNSSDService::Service& service, const DNSSDService::ResolveResult& info) const; - JID getJIDForService(const DNSSDService::Service& service) const; - boost::shared_ptr<Presence> getPresence(const DNSSDService::Service& service, const DNSSDService::ResolveResult& info) const; + RosterItemPayload getRosterItem(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& info) const; + String getRosterName(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& info) const; + JID getJIDForService(const LinkLocalServiceID& service) const; + boost::shared_ptr<Presence> getPresence(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& info) const; void handleStopped(bool); - void handleServiceRegistered(const DNSSDService::Service& service); - void handleServiceAdded(const DNSSDService::Service&); - void handleServiceRemoved(const DNSSDService::Service&); - void handleServiceResolved(const DNSSDService::Service& service, const DNSSDService::ResolveResult& result); + void handleServiceRegistered(const LinkLocalServiceID& service); + void handleServiceAdded(const LinkLocalServiceID&); + void handleServiceRemoved(const LinkLocalServiceID&); + void handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result); private: boost::shared_ptr<DNSSDService> dnsSDService; - boost::optional<DNSSDService::Service> selfService; - typedef std::map<DNSSDService::Service, DNSSDService::ResolveResult> ServiceMap; + boost::optional<LinkLocalServiceID> selfService; + typedef std::map<LinkLocalServiceID, DNSSDService::ResolveResult> ServiceMap; ServiceMap services; }; } diff --git a/Swiften/LinkLocal/LinkLocalServiceID.h b/Swiften/LinkLocal/LinkLocalServiceID.h new file mode 100644 index 0000000..72615d4 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalServiceID.h @@ -0,0 +1,64 @@ +#pragma once + +#include "Swiften/Base/String.h" + +namespace Swift { + class LinkLocalServiceID { + public: + LinkLocalServiceID( + const String& name, + const String& type, + const String& domain, + int networkInterface = 0) : + name(name), + type(type), + domain(domain), + networkInterface(networkInterface) { + } + + bool operator==(const LinkLocalServiceID& o) const { + return name == o.name && type == o.type && domain == o.domain && (networkInterface != 0 && o.networkInterface != 0 ? networkInterface == o.networkInterface : true); + } + + bool operator<(const LinkLocalServiceID& o) const { + if (o.name == name) { + if (o.type == type) { + if (o.domain == domain) { + return networkInterface < o.networkInterface; + } + else { + return domain < o.domain; + } + } + else { + return type < o.type; + } + } + else { + return o.name < name; + } + } + + const String& getName() const { + return name; + } + + const String& getType() const { + return type; + } + + const String& getDomain() const { + return domain; + } + + int getNetworkInterfaceID() const { + return networkInterface; + } + + private: + String name; + String type; + String domain; + int networkInterface; + }; +} -- cgit v0.10.2-6-g49f6 From 0a7336577f9609c70bb4d846c668e7853746cb52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Wed, 22 Jul 2009 23:36:52 +0200 Subject: Started LinkLocalServiceBrowser. diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp index 5262357..bf66e50 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.cpp +++ b/Swiften/LinkLocal/AppleDNSSDService.cpp @@ -268,8 +268,6 @@ void AppleDNSSDService::handleServiceResolvedGlobal(DNSServiceRef sdRef, DNSServ 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) { - // TODO - std::cerr << "Resolve error " << hosttarget << std::endl; return; } for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) { diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h new file mode 100644 index 0000000..446feb8 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Swiften/Base/String.h" +#include "Swiften/Network/HostAddress.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" + +namespace Swift { + class LinkLocalService { + public: + LinkLocalService(); + + const String& getName() const { + return name; + } + + void setName(const String& n) { + name = n; + } + + const String& getHostname() const { + return hostname; + } + + void setHostname(const String& h) { + hostname = h; + } + + const HostAddress& getAddress() const { + return address; + } + + void setAddress(const HostAddress& a) { + address = a; + } + + const LinkLocalServiceInfo& getInfo() const { + return info; + } + + void setInfo(const LinkLocalServiceInfo& i) { + info = i; + } + + private: + String name; + String hostname; + LinkLocalServiceInfo info; + HostAddress address; + }; +} diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp new file mode 100644 index 0000000..63cf075 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -0,0 +1,38 @@ +#include <boost/bind.hpp> +#include <iostream> + +#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" +#include "Swiften/Network/HostAddress.h" + +namespace Swift { + +LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDService> service) : dnsSDService(service) { + dnsSDService->onServiceAdded.connect( + boost::bind(&LinkLocalServiceBrowser::handleServiceAdded, this, _1)); + dnsSDService->onServiceRemoved.connect( + boost::bind(&LinkLocalServiceBrowser::handleServiceRemoved, this, _1)); + dnsSDService->onServiceResolved.connect( + boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, _1, _2)); +} + +void LinkLocalServiceBrowser::handleServiceAdded(const LinkLocalServiceID& service) { + dnsSDService->startResolvingService(service); +} + +void LinkLocalServiceBrowser::handleServiceRemoved(const LinkLocalServiceID& service) { + /*dnsSDService->stopResolvingService(service); + services.erase(service);*/ +} + +void LinkLocalServiceBrowser::handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result) { + std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, result)); + if (r.second) { + onServiceAdded(service); + } + else { + onServiceChanged(service); + } +} + + +} diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h new file mode 100644 index 0000000..c0788e6 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -0,0 +1,32 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> +#include <map> +#include <vector> + +#include "Swiften/Base/String.h" +#include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/LinkLocalService.h" + +namespace Swift { + class HostAddress; + + class LinkLocalServiceBrowser { + public: + LinkLocalServiceBrowser(boost::shared_ptr<DNSSDService> service); + + boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; + boost::signal<void (const LinkLocalServiceID&)> onServiceChanged; + + private: + void handleServiceAdded(const LinkLocalServiceID&); + void handleServiceRemoved(const LinkLocalServiceID&); + void handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result); + + private: + boost::shared_ptr<DNSSDService> dnsSDService; + typedef std::map<LinkLocalServiceID, DNSSDService::ResolveResult> ServiceMap; + ServiceMap services; + }; +} diff --git a/Swiften/LinkLocal/LinkLocalServiceID.cpp b/Swiften/LinkLocal/LinkLocalServiceID.cpp new file mode 100644 index 0000000..4248d88 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalServiceID.cpp @@ -0,0 +1,7 @@ +#include "Swiften/LinkLocal/LinkLocalServiceID.h" + +namespace Swift { + +const String LinkLocalServiceID::PresenceServiceType = String("_presence._tcp"); + +} diff --git a/Swiften/LinkLocal/LinkLocalServiceID.h b/Swiften/LinkLocal/LinkLocalServiceID.h index 72615d4..ca5ba17 100644 --- a/Swiften/LinkLocal/LinkLocalServiceID.h +++ b/Swiften/LinkLocal/LinkLocalServiceID.h @@ -5,10 +5,12 @@ namespace Swift { class LinkLocalServiceID { public: + static const String PresenceServiceType; + LinkLocalServiceID( const String& name, const String& type, - const String& domain, + const String& domain = PresenceServiceType, int networkInterface = 0) : name(name), type(type), diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 788c000..a890d0a 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,7 +1,9 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/DNSSDService.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ + Swiften/LinkLocal/LinkLocalServiceID.cpp \ Swiften/LinkLocal/LinkLocalServiceInfo.cpp \ + Swiften/LinkLocal/LinkLocalServiceBrowser.cpp \ Swiften/LinkLocal/IncomingLinkLocalSession.cpp \ Swiften/LinkLocal/OutgoingLinkLocalSession.cpp \ Swiften/LinkLocal/LinkLocalConnector.cpp diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp new file mode 100644 index 0000000..449a823 --- /dev/null +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -0,0 +1,95 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <boost/bind.hpp> +#include <map> + +#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" +#include "Swiften/LinkLocal/LinkLocalService.h" +#include "Swiften/LinkLocal/UnitTest/MockDNSSDService.h" +#include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/EventLoop/DummyEventLoop.h" + +// Test IP address change + +using namespace Swift; + +class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LinkLocalServiceBrowserTest); + CPPUNIT_TEST(testServiceAdded); + CPPUNIT_TEST(testServiceAdded_NoServiceInfo); + CPPUNIT_TEST(testServiceChanged); + CPPUNIT_TEST_SUITE_END(); + + public: + LinkLocalServiceBrowserTest() {} + + void setUp() { + eventLoop = new DummyEventLoop(); + dnsSDService = boost::shared_ptr<MockDNSSDService>(new MockDNSSDService()); + testServiceID = new LinkLocalServiceID("foo", "bar.local"); + testServiceInfo = new DNSSDService::ResolveResult("xmpp.bar.local", 1234, LinkLocalServiceInfo()); + testServiceInfo2 = new DNSSDService::ResolveResult("xmpp.foo.local", 2345, LinkLocalServiceInfo()); + } + + void tearDown() { + delete testServiceInfo2; + delete testServiceInfo; + delete testServiceID; + delete eventLoop; + } + + void testServiceAdded() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + + dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo); + dnsSDService->addService(*testServiceID); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); + CPPUNIT_ASSERT(addedServices[0] == *testServiceID); + // TODO: Check getServices + } + + void testServiceAdded_NoServiceInfo() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + + dnsSDService->addService(*testServiceID); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size())); + } + + void testServiceChanged() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo); + dnsSDService->addService(*testServiceID); + eventLoop->processEvents(); + + dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo2); + eventLoop->processEvents(); + // TODO: Check getServices + } + + private: + boost::shared_ptr<LinkLocalServiceBrowser> createTestling() { + boost::shared_ptr<LinkLocalServiceBrowser> testling( + new LinkLocalServiceBrowser(dnsSDService)); + testling->onServiceAdded.connect(boost::bind( + &LinkLocalServiceBrowserTest::handleServiceAdded, this, _1)); + return testling; + } + + void handleServiceAdded(const LinkLocalServiceID& service) { + addedServices.push_back(service); + } + + private: + DummyEventLoop* eventLoop; + boost::shared_ptr<MockDNSSDService> dnsSDService; + std::vector<LinkLocalServiceID> addedServices; + LinkLocalServiceID* testServiceID; + DNSSDService::ResolveResult* testServiceInfo; + DNSSDService::ResolveResult* testServiceInfo2; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceBrowserTest); diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc index abc1180..9640fa7 100644 --- a/Swiften/LinkLocal/UnitTest/Makefile.inc +++ b/Swiften/LinkLocal/UnitTest/Makefile.inc @@ -1,2 +1,3 @@ UNITTEST_SOURCES += \ + Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp \ Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp diff --git a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h new file mode 100644 index 0000000..5d857fb --- /dev/null +++ b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h @@ -0,0 +1,74 @@ +#pragma once + +#include <vector> +#include <map> +#include <boost/bind.hpp> + +#include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/LinkLocal/DNSSDService.h" + +namespace Swift { + class MockDNSSDService : public DNSSDService { + public: + MockDNSSDService() { + } + + void start() { + } + + void stop() { + } + + virtual void registerService(const String&, int, const LinkLocalServiceInfo&) { + assert(false); + } + + virtual void updateService(const LinkLocalServiceInfo&) { + assert(false); + } + + virtual void unregisterService() { + assert(false); + } + + virtual void startResolvingService(const LinkLocalServiceID& id) { + resolvingServices.push_back(id); + broadcastServiceInfo(id); + } + + virtual void stopResolvingService(const LinkLocalServiceID& id) { + resolvingServices.erase(std::remove(resolvingServices.begin(), resolvingServices.end(), id), resolvingServices.end()); + } + + virtual void resolveHostname(const String&, int) { + assert(false); + } + + void addService(const LinkLocalServiceID& id) { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), id)); + } + + void setServiceInfo(const LinkLocalServiceID& id, const DNSSDService::ResolveResult& info) { + serviceInfo.insert(std::make_pair(id, info)); + broadcastServiceInfo(id); + } + + private: + void broadcastServiceInfo(const LinkLocalServiceID& id) { + if (std::find(resolvingServices.begin(), resolvingServices.end(), id) != resolvingServices.end()) { + ServiceInfoMap::const_iterator i = serviceInfo.find(id); + if (i != serviceInfo.end()) { + MainEventLoop::postEvent( + boost::bind(boost::ref(onServiceResolved), id, i->second)); + } + } + } + + private: + typedef std::map<LinkLocalServiceID,DNSSDService::ResolveResult> ServiceInfoMap; + ServiceInfoMap serviceInfo; + std::vector<LinkLocalServiceID> resolvingServices; + }; + + +} -- cgit v0.10.2-6-g49f6 From 1c1491cbbe9fca509ddc292dbeaedbba7b6a2b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 23 Jul 2009 08:54:10 +0200 Subject: Added more LinkLocalServiceBrowser tests. diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h index 446feb8..6616303 100644 --- a/Swiften/LinkLocal/LinkLocalService.h +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -2,49 +2,40 @@ #include "Swiften/Base/String.h" #include "Swiften/Network/HostAddress.h" +#include "Swiften/LinkLocal/LinkLocalServiceID.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { class LinkLocalService { public: - LinkLocalService(); + LinkLocalService( + const LinkLocalServiceID& id, + const DNSSDService::ResolveResult& info) : + id(id), + info(info) {} - const String& getName() const { - return name; - } - - void setName(const String& n) { - name = n; - } - - const String& getHostname() const { - return hostname; + const LinkLocalServiceID& getID() const { + return id; } - void setHostname(const String& h) { - hostname = h; + const String& getName() const { + return id.getName(); } - const HostAddress& getAddress() const { - return address; + int getPort() const { + return info.port; } - void setAddress(const HostAddress& a) { - address = a; + const String& getHostname() const { + return info.host; } const LinkLocalServiceInfo& getInfo() const { - return info; - } - - void setInfo(const LinkLocalServiceInfo& i) { - info = i; + return info.info; } private: - String name; - String hostname; - LinkLocalServiceInfo info; - HostAddress address; + LinkLocalServiceID id; + DNSSDService::ResolveResult info; }; } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index 63cf075..fbc3022 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -15,13 +15,22 @@ LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDService> boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, _1, _2)); } +std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { + std::vector<LinkLocalService> result; + for (ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { + result.push_back(LinkLocalService(i->first, i->second)); + } + return result; +} + void LinkLocalServiceBrowser::handleServiceAdded(const LinkLocalServiceID& service) { dnsSDService->startResolvingService(service); } void LinkLocalServiceBrowser::handleServiceRemoved(const LinkLocalServiceID& service) { - /*dnsSDService->stopResolvingService(service); - services.erase(service);*/ + dnsSDService->stopResolvingService(service); + services.erase(service); + onServiceRemoved(service); } void LinkLocalServiceBrowser::handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result) { @@ -30,6 +39,7 @@ void LinkLocalServiceBrowser::handleServiceResolved(const LinkLocalServiceID& se onServiceAdded(service); } else { + r.first->second = result; onServiceChanged(service); } } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index c0788e6..6107557 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -16,8 +16,11 @@ namespace Swift { public: LinkLocalServiceBrowser(boost::shared_ptr<DNSSDService> service); + std::vector<LinkLocalService> getServices() const; + boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; boost::signal<void (const LinkLocalServiceID&)> onServiceChanged; + boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; private: void handleServiceAdded(const LinkLocalServiceID&); diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 449a823..59a113d 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -18,6 +18,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testServiceAdded); CPPUNIT_TEST(testServiceAdded_NoServiceInfo); CPPUNIT_TEST(testServiceChanged); + CPPUNIT_TEST(testServiceRemoved); CPPUNIT_TEST_SUITE_END(); public: @@ -32,6 +33,10 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { } void tearDown() { + addedServices.clear(); + removedServices.clear(); + changedServices.clear(); + delete testServiceInfo2; delete testServiceInfo; delete testServiceID; @@ -47,7 +52,13 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); CPPUNIT_ASSERT(addedServices[0] == *testServiceID); - // TODO: Check getServices + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); + std::vector<LinkLocalService> services = testling->getServices(); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(services.size())); + CPPUNIT_ASSERT(*testServiceID == services[0].getID()); + CPPUNIT_ASSERT(testServiceInfo->port == services[0].getPort()); + CPPUNIT_ASSERT(testServiceInfo->host == services[0].getHostname()); } void testServiceAdded_NoServiceInfo() { @@ -57,6 +68,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size())); + std::vector<LinkLocalService> services = testling->getServices(); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size())); } void testServiceChanged() { @@ -67,7 +80,35 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); - // TODO: Check getServices + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); + CPPUNIT_ASSERT(changedServices[0] == *testServiceID); + std::vector<LinkLocalService> services = testling->getServices(); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(services.size())); + CPPUNIT_ASSERT(*testServiceID == services[0].getID()); + CPPUNIT_ASSERT(testServiceInfo2->port == services[0].getPort()); + CPPUNIT_ASSERT(testServiceInfo2->host == services[0].getHostname()); + } + + void testServiceRemoved() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo); + dnsSDService->addService(*testServiceID); + eventLoop->processEvents(); + + dnsSDService->removeService(*testServiceID); + eventLoop->processEvents(); + dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo2); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(removedServices.size())); + CPPUNIT_ASSERT(removedServices[0] == *testServiceID); + std::vector<LinkLocalService> services = testling->getServices(); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size())); } private: @@ -76,6 +117,10 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { new LinkLocalServiceBrowser(dnsSDService)); testling->onServiceAdded.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceAdded, this, _1)); + testling->onServiceChanged.connect(boost::bind( + &LinkLocalServiceBrowserTest::handleServiceChanged, this, _1)); + testling->onServiceRemoved.connect(boost::bind( + &LinkLocalServiceBrowserTest::handleServiceRemoved, this, _1)); return testling; } @@ -83,10 +128,20 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { addedServices.push_back(service); } + void handleServiceRemoved(const LinkLocalServiceID& service) { + removedServices.push_back(service); + } + + void handleServiceChanged(const LinkLocalServiceID& service) { + changedServices.push_back(service); + } + private: DummyEventLoop* eventLoop; boost::shared_ptr<MockDNSSDService> dnsSDService; std::vector<LinkLocalServiceID> addedServices; + std::vector<LinkLocalServiceID> changedServices; + std::vector<LinkLocalServiceID> removedServices; LinkLocalServiceID* testServiceID; DNSSDService::ResolveResult* testServiceInfo; DNSSDService::ResolveResult* testServiceInfo2; diff --git a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h index 5d857fb..56661ee 100644 --- a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h +++ b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h @@ -48,8 +48,16 @@ namespace Swift { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), id)); } + void removeService(const LinkLocalServiceID& id) { + serviceInfo.erase(id); + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), id)); + } + void setServiceInfo(const LinkLocalServiceID& id, const DNSSDService::ResolveResult& info) { - serviceInfo.insert(std::make_pair(id, info)); + std::pair<ServiceInfoMap::iterator, bool> r = serviceInfo.insert(std::make_pair(id, info)); + if (!r.second) { + r.first->second = info; + } broadcastServiceInfo(id); } -- cgit v0.10.2-6-g49f6 From 3a0309d2d897bf4f399610e52ad439c002e16f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 23 Jul 2009 21:03:11 +0200 Subject: Add DNS service factory. diff --git a/Makefile.config.in b/Makefile.config.in index 848f223..010075a 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -22,6 +22,7 @@ HAVE_EXPAT=@HAVE_EXPAT@ USE_BUNDLED_EXPAT=@USE_BUNDLED_EXPAT@ HAVE_LIBXML=@CONFIG_HAVE_LIBXML@ HAVE_OPENSSL=@CONFIG_HAVE_OPENSSL@ +HAVE_BONJOUR=@HAVE_BONJOUR@ HAVE_AVAHI=@HAVE_AVAHI@ WIN32=@CONFIG_WIN32@ MACOSX=@CONFIG_MACOSX@ diff --git a/Swiften/LinkLocal/AvahiDNSSDService.cpp b/Swiften/LinkLocal/AvahiDNSSDService.cpp index 72039b7..fe9ac83 100644 --- a/Swiften/LinkLocal/AvahiDNSSDService.cpp +++ b/Swiften/LinkLocal/AvahiDNSSDService.cpp @@ -82,7 +82,7 @@ void AvahiDNSSDService::startResolvingService(const LinkLocalServiceID& service) avahi_threaded_poll_unlock(threadedPoll); } -void AvahiDNSSDService::stopResolvingService(const Service& service) { +void AvahiDNSSDService::stopResolvingService(const LinkLocalServiceID& service) { avahi_threaded_poll_lock(threadedPoll); ServiceResolverMap::iterator i = serviceResolvers.find(service); diff --git a/Swiften/LinkLocal/AvahiDNSSDService.h b/Swiften/LinkLocal/AvahiDNSSDService.h index a5be943..99a1d23 100644 --- a/Swiften/LinkLocal/AvahiDNSSDService.h +++ b/Swiften/LinkLocal/AvahiDNSSDService.h @@ -47,7 +47,7 @@ namespace Swift { AvahiClient* client; AvahiThreadedPoll* threadedPoll; AvahiServiceBrowser* serviceBrowser; - typedef std::map<Service, AvahiServiceResolver*> ServiceResolverMap; + typedef std::map<LinkLocalServiceID, AvahiServiceResolver*> ServiceResolverMap; ServiceResolverMap serviceResolvers; typedef std::map<String, HostAddress> HostnameAddressMap; HostnameAddressMap hostnameAddresses; diff --git a/Swiften/LinkLocal/DNSSDServiceFactory.cpp b/Swiften/LinkLocal/DNSSDServiceFactory.cpp new file mode 100644 index 0000000..f53660a --- /dev/null +++ b/Swiften/LinkLocal/DNSSDServiceFactory.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDServiceFactory.h" + +namespace Swift { + +DNSSDServiceFactory::~DNSSDServiceFactory() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDServiceFactory.h b/Swiften/LinkLocal/DNSSDServiceFactory.h new file mode 100644 index 0000000..6296165 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDServiceFactory.h @@ -0,0 +1,15 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +namespace Swift { + class DNSSDService; + + class DNSSDServiceFactory { + public: + virtual ~DNSSDServiceFactory(); + virtual bool canCreate() const = 0; + + virtual boost::shared_ptr<DNSSDService> createDNSSDService() = 0; + }; +} diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index fbc3022..904f8f0 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -6,7 +6,8 @@ namespace Swift { -LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDService> service) : dnsSDService(service) { +LinkLocalServiceBrowser::LinkLocalServiceBrowser(DNSSDServiceFactory* factory) { + dnsSDService = factory->createDNSSDService(); dnsSDService->onServiceAdded.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceAdded, this, _1)); dnsSDService->onServiceRemoved.connect( diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 6107557..879b286 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -7,6 +7,7 @@ #include "Swiften/Base/String.h" #include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/DNSSDServiceFactory.h" #include "Swiften/LinkLocal/LinkLocalService.h" namespace Swift { @@ -14,7 +15,7 @@ namespace Swift { class LinkLocalServiceBrowser { public: - LinkLocalServiceBrowser(boost::shared_ptr<DNSSDService> service); + LinkLocalServiceBrowser(DNSSDServiceFactory*); std::vector<LinkLocalService> getServices() const; diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index a890d0a..4bd1b0e 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,4 +1,6 @@ SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSDServiceFactory.cpp \ + Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ Swiften/LinkLocal/LinkLocalServiceID.cpp \ @@ -8,7 +10,7 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/OutgoingLinkLocalSession.cpp \ Swiften/LinkLocal/LinkLocalConnector.cpp -ifeq ($(MACOSX),1) +ifeq ($(HAVE_BONJOUR),yes) SWIFTEN_SOURCES += \ Swiften/LinkLocal/AppleDNSSDService.cpp endif diff --git a/Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp b/Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp new file mode 100644 index 0000000..df70506 --- /dev/null +++ b/Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp @@ -0,0 +1,38 @@ +#include "Swiften/LinkLocal/PlatformDNSSDServiceFactory.h" + +#include <cassert> + +#ifdef HAVE_SWIFTEN_CONFIG_H +#include "Swiften/config.h" +#endif +#if defined(HAVE_AVAHI) +#include "Swiften/LinkLocal/AvahiDNSSDService.h" +#elif defined(HAVE_BONJOUR) +#include "Swiften/LinkLocal/AppleDNSSDService.h" +#endif + +namespace Swift { + +PlatformDNSSDServiceFactory::PlatformDNSSDServiceFactory() { +} + +bool PlatformDNSSDServiceFactory::canCreate() const { +#if defined(HAVE_AVAHI) || defined(HAVE_BONJOUR) + return true; +#else + return false; +#endif +} + +boost::shared_ptr<DNSSDService> PlatformDNSSDServiceFactory::createDNSSDService() { +#if defined(HAVE_AVAHI) + return boost::shared_ptr<DNSSDService>(new AvahiDNSSDService()); +#elif defined(HAVE_BONJOUR) + return boost::shared_ptr<DNSSDService>(new AppleDNSSDService()); +#else + assert(false); + return boost::shared_ptr<DNSSDService>(); +#endif +} + +} diff --git a/Swiften/LinkLocal/PlatformDNSSDServiceFactory.h b/Swiften/LinkLocal/PlatformDNSSDServiceFactory.h new file mode 100644 index 0000000..9c4e4e6 --- /dev/null +++ b/Swiften/LinkLocal/PlatformDNSSDServiceFactory.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSDServiceFactory.h" + +namespace Swift { + class PlatformDNSSDServiceFactory : public DNSSDServiceFactory { + public: + PlatformDNSSDServiceFactory(); + + bool canCreate() const; + virtual boost::shared_ptr<DNSSDService> createDNSSDService(); + }; +} diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 59a113d..34f797c 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -9,7 +9,7 @@ #include "Swiften/LinkLocal/DNSSDService.h" #include "Swiften/EventLoop/DummyEventLoop.h" -// Test IP address change +// Test canCreate() == false using namespace Swift; @@ -26,7 +26,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { void setUp() { eventLoop = new DummyEventLoop(); - dnsSDService = boost::shared_ptr<MockDNSSDService>(new MockDNSSDService()); + dnsSDServiceFactory = new MockDNSSDServiceFactory(); testServiceID = new LinkLocalServiceID("foo", "bar.local"); testServiceInfo = new DNSSDService::ResolveResult("xmpp.bar.local", 1234, LinkLocalServiceInfo()); testServiceInfo2 = new DNSSDService::ResolveResult("xmpp.foo.local", 2345, LinkLocalServiceInfo()); @@ -40,14 +40,15 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { delete testServiceInfo2; delete testServiceInfo; delete testServiceID; + delete dnsSDServiceFactory; delete eventLoop; } void testServiceAdded() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); - dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo); - dnsSDService->addService(*testServiceID); + dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo); + dnsSDService()->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); @@ -64,7 +65,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { void testServiceAdded_NoServiceInfo() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); - dnsSDService->addService(*testServiceID); + dnsSDService()->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size())); @@ -74,11 +75,11 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { void testServiceChanged() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); - dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo); - dnsSDService->addService(*testServiceID); + dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo); + dnsSDService()->addService(*testServiceID); eventLoop->processEvents(); - dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo2); + dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); @@ -94,13 +95,13 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { void testServiceRemoved() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); - dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo); - dnsSDService->addService(*testServiceID); + dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo); + dnsSDService()->addService(*testServiceID); eventLoop->processEvents(); - dnsSDService->removeService(*testServiceID); + dnsSDService()->removeService(*testServiceID); eventLoop->processEvents(); - dnsSDService->setServiceInfo(*testServiceID,*testServiceInfo2); + dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); @@ -114,7 +115,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { private: boost::shared_ptr<LinkLocalServiceBrowser> createTestling() { boost::shared_ptr<LinkLocalServiceBrowser> testling( - new LinkLocalServiceBrowser(dnsSDService)); + new LinkLocalServiceBrowser(dnsSDServiceFactory)); testling->onServiceAdded.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceAdded, this, _1)); testling->onServiceChanged.connect(boost::bind( @@ -136,9 +137,14 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { changedServices.push_back(service); } + boost::shared_ptr<MockDNSSDService> dnsSDService() const { + CPPUNIT_ASSERT(dnsSDServiceFactory->services.size() > 0); + return dnsSDServiceFactory->services[0]; + } + private: DummyEventLoop* eventLoop; - boost::shared_ptr<MockDNSSDService> dnsSDService; + MockDNSSDServiceFactory* dnsSDServiceFactory; std::vector<LinkLocalServiceID> addedServices; std::vector<LinkLocalServiceID> changedServices; std::vector<LinkLocalServiceID> removedServices; diff --git a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h index 56661ee..69ac06d 100644 --- a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h +++ b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h @@ -6,6 +6,7 @@ #include "Swiften/EventLoop/MainEventLoop.h" #include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/DNSSDServiceFactory.h" namespace Swift { class MockDNSSDService : public DNSSDService { @@ -78,5 +79,19 @@ namespace Swift { std::vector<LinkLocalServiceID> resolvingServices; }; + class MockDNSSDServiceFactory : public DNSSDServiceFactory { + public: + boost::shared_ptr<DNSSDService> createDNSSDService() { + boost::shared_ptr<MockDNSSDService> result(new MockDNSSDService()); + services.push_back(result); + return result; + } + + bool canCreate() const { + return true; + } + + std::vector<boost::shared_ptr<MockDNSSDService> > services; + }; } diff --git a/configure.in b/configure.in index 9025855..3a10e2c 100644 --- a/configure.in +++ b/configure.in @@ -13,6 +13,7 @@ AC_CANONICAL_HOST AH_TEMPLATE(HAVE_OPENSSL, [OpenSSL library available]) AH_TEMPLATE(HAVE_LIBXML, [LibXML library available]) AH_TEMPLATE(HAVE_EXPAT, [Expat library available]) +AH_TEMPLATE(HAVE_BONJOUR, [Apple Bonjour SDK available]) AH_TEMPLATE(HAVE_AVAHI, [Avahi library available]) ################################################################################ @@ -194,11 +195,13 @@ fi # Resolv AC_CHECK_LIB(resolv, inet_aton) -# Avahi +# DNSSD Service case $host in *-*-cygwin*) + AC_DEFINE(HAVE_BONJOUR) ;; *-mingw32*) + AC_DEFINE(HAVE_BONJOUR) ;; *-*-darwin*) ;; @@ -239,6 +242,7 @@ echo AC_SUBST(SET_MAKE) AC_SUBST(HAVE_EXPAT) AC_SUBST(HAVE_AVAHI) +AC_SUBST(HAVE_BONJOUR) AC_SUBST(CONFIG_CXX) AC_SUBST(CONFIG_CXXFLAGS) AC_SUBST(CONFIG_CC) -- cgit v0.10.2-6-g49f6 From 714e831bb9ea2b14cba3c2696c12e2e13b1bb9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 23 Jul 2009 21:04:08 +0200 Subject: Add beginning of new DNS-SD query framework. diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp index ba55403..c3c3d22 100644 --- a/Slimber/Server.cpp +++ b/Slimber/Server.cpp @@ -69,9 +69,9 @@ void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connecti registerLinkLocalSession(session); } -void Server::handleServiceRegistered(const DNSSDService::Service& service) { - std::cout << "Service registered " << service.name << " " << service.type << " " << service.domain << std::endl; - selfJID_ = JID(service.name); +void Server::handleServiceRegistered(const LinkLocalServiceID& service) { + std::cout << "Service registered " << service.getName() << " " << service.getType() << " " << service.getDomain() << std::endl; + selfJID_ = JID(service.getName()); } void Server::handleSessionStarted() { diff --git a/Slimber/Server.h b/Slimber/Server.h index ac80509..b40f576 100644 --- a/Slimber/Server.h +++ b/Slimber/Server.h @@ -33,7 +33,7 @@ namespace Swift { private: void handleNewClientConnection(boost::shared_ptr<Connection> c); void handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection); - void handleServiceRegistered(const DNSSDService::Service& service); + void handleServiceRegistered(const LinkLocalServiceID& service); void handleSessionStarted(); void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>); void handleLinkLocalSessionFinished(boost::shared_ptr<Session> session); diff --git a/Swiften/LinkLocal/BonjourBrowseQuery.h b/Swiften/LinkLocal/BonjourBrowseQuery.h new file mode 100644 index 0000000..5b14d30 --- /dev/null +++ b/Swiften/LinkLocal/BonjourBrowseQuery.h @@ -0,0 +1,55 @@ +#pragma once + +#include "Swiften/LinkLocal/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourBrowseQuery : public DNSSDBrowseQuery, public BonjourQuery { + public: + BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) { + DNSServiceErrorType result = DNSServiceBrowse( + &sdRef, 0, 0, "_presence._tcp", 0, + &BonjourBrowseQuery::handleServiceDiscoveredGlobal , this); + if (result != kDNSServiceErr_NoError) { + // TODO + } + } + + void startBrowsing() { + assert(sdRef); + run(); + } + + void stopBrowsing() { + finish(); + } + + private: + static void handleServiceDiscoveredGlobal(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) { + static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain); + } + + void handleServiceDiscovered( + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *serviceName, + const char *type, + const char *domain) { + if (errorCode != kDNSServiceErr_NoError) { + return; + } + else { + LinkLocalServiceID service(serviceName, type, domain, interfaceIndex); + if (flags & kDNSServiceFlagsAdd) { + onServiceAdded(service); + } + else { + onServiceRemoved(service); + } + } + } + }; +} diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp new file mode 100644 index 0000000..1ddbd9d --- /dev/null +++ b/Swiften/LinkLocal/BonjourQuerier.cpp @@ -0,0 +1,115 @@ +#include "Swiften/LinkLocal/BonjourQuerier.h" + +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <fcntl.h> + +#include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/LinkLocal/BonjourBrowseQuery.h" +#include "Swiften/Base/foreach.h" + +namespace Swift { + +BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(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]; + // TODO: Schedule thread +} + +BonjourQuerier::~BonjourQuerier() { + stop(); +} + +boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { + return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this())); +} + +void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { + { + boost::lock_guard<boost::mutex> lock(runningQueriesMutex); + runningQueries.push_back(query); + } + runningQueriesAvailableEvent.notify_one(); + interruptSelect(); +} + +void BonjourQuerier::removeRunningQuery(boost::shared_ptr<BonjourQuery> query) { + { + boost::lock_guard<boost::mutex> lock(runningQueriesMutex); + runningQueries.erase(std::remove( + runningQueries.begin(), runningQueries.end(), query), runningQueries.end()); + } +} + +void BonjourQuerier::interruptSelect() { + char c = 0; + write(interruptSelectWriteSocket, &c, 1); +} + +void BonjourQuerier::start() { + stop(); + thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this())); +} + +void BonjourQuerier::stop() { + if (thread) { + stopRequested = true; + runningQueries.clear(); // TODO: Is this the right thing to do? + runningQueriesAvailableEvent.notify_one(); + interruptSelect(); + thread->join(); + delete thread; + stopRequested = false; + } +} + +void BonjourQuerier::run() { + while (!stopRequested) { + fd_set fdSet; + int maxSocket; + { + boost::unique_lock<boost::mutex> lock(runningQueriesMutex); + runningQueriesAvailableEvent.wait(lock); + if (runningQueries.empty()) { + continue; + } + + // Run all running queries + FD_ZERO(&fdSet); + int maxSocket = interruptSelectReadSocket; + FD_SET(interruptSelectReadSocket, &fdSet); + + foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) { + int socketID = query->getSocketID(); + maxSocket = std::max(maxSocket, socketID); + FD_SET(socketID, &fdSet); + } + } + + if (select(maxSocket+1, &fdSet, NULL, NULL, 0) <= 0) { + continue; + } + + if (FD_ISSET(interruptSelectReadSocket, &fdSet)) { + char dummy; + while (read(interruptSelectReadSocket, &dummy, 1) > 0) {} + } + + { + boost::lock_guard<boost::mutex> lock(runningQueriesMutex); + foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) { + if (FD_ISSET(query->getSocketID(), &fdSet)) { + MainEventLoop::postEvent( + boost::bind(&BonjourQuery::processResult, query), shared_from_this()); + } + } + } + } +} + +} diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h new file mode 100644 index 0000000..037d9e6 --- /dev/null +++ b/Swiften/LinkLocal/BonjourQuerier.h @@ -0,0 +1,45 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <list> +#include <boost/thread.hpp> +#include <boost/thread/mutex.hpp> + +#include "Swiften/EventLoop/EventOwner.h" +#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" +#include "Swiften/LinkLocal/BonjourQuery.h" + +namespace Swift { + class BonjourQuerier : + public boost::enable_shared_from_this<BonjourQuerier>, + public EventOwner { + public: + BonjourQuerier(); + ~BonjourQuerier(); + + boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); + + void start(); + void stop(); + + private: + friend class BonjourQuery; + + void addRunningQuery(boost::shared_ptr<BonjourQuery>); + void removeRunningQuery(boost::shared_ptr<BonjourQuery>); + + private: + void interruptSelect(); + void run(); + + private: + bool stopRequested; + boost::thread* thread; + boost::mutex runningQueriesMutex; + std::list< boost::shared_ptr<BonjourQuery> > runningQueries; + int interruptSelectReadSocket; + int interruptSelectWriteSocket; + boost::condition_variable runningQueriesAvailableEvent; + }; +} diff --git a/Swiften/LinkLocal/BonjourQuery.cpp b/Swiften/LinkLocal/BonjourQuery.cpp new file mode 100644 index 0000000..a9c13fb --- /dev/null +++ b/Swiften/LinkLocal/BonjourQuery.cpp @@ -0,0 +1,31 @@ +#include "Swiften/LinkLocal/BonjourQuery.h" +#include "Swiften/LinkLocal/BonjourQuerier.h" + +namespace Swift { + +BonjourQuery::BonjourQuery(boost::shared_ptr<BonjourQuerier> q) : querier(q), sdRef(0) { +} + +BonjourQuery::~BonjourQuery() { + DNSServiceRefDeallocate(sdRef); +} + +void BonjourQuery::processResult() { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + DNSServiceProcessResult(sdRef); +} + +int BonjourQuery::getSocketID() const { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + return DNSServiceRefSockFD(sdRef); +} + +void BonjourQuery::run() { + querier->addRunningQuery(shared_from_this()); +} + +void BonjourQuery::finish() { + querier->removeRunningQuery(shared_from_this()); +} + +} diff --git a/Swiften/LinkLocal/BonjourQuery.h b/Swiften/LinkLocal/BonjourQuery.h new file mode 100644 index 0000000..2a47f73 --- /dev/null +++ b/Swiften/LinkLocal/BonjourQuery.h @@ -0,0 +1,28 @@ +#pragma once + +#include <dns_sd.h> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/thread/mutex.hpp> + +namespace Swift { + class BonjourQuerier; + + class BonjourQuery : public boost::enable_shared_from_this<BonjourQuery> { + public: + BonjourQuery(boost::shared_ptr<BonjourQuerier>); + virtual ~BonjourQuery(); + + void processResult(); + int getSocketID() const; + + protected: + void run(); + void finish(); + + protected: + boost::shared_ptr<BonjourQuerier> querier; + mutable boost::mutex sdRefMutex; + DNSServiceRef sdRef; + }; +} diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.cpp b/Swiften/LinkLocal/DNSSDBrowseQuery.cpp new file mode 100644 index 0000000..4924247 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDBrowseQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" + +namespace Swift { + +DNSSDBrowseQuery::~DNSSDBrowseQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSDBrowseQuery.h new file mode 100644 index 0000000..b46d968 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDBrowseQuery.h @@ -0,0 +1,15 @@ +#pragma once + +#include <boost/signal.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" + +namespace Swift { + class DNSSDBrowseQuery { + public: + virtual ~DNSSDBrowseQuery(); + + boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; + boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; + }; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 4bd1b0e..b43a7e4 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,5 +1,8 @@ SWIFTEN_SOURCES += \ + Swiften/LinkLocal/BonjourQuery.cpp \ + Swiften/LinkLocal/DNSSDBrowseQuery.cpp \ Swiften/LinkLocal/DNSSDServiceFactory.cpp \ + Swiften/LinkLocal/BonjourQuerier.cpp \ Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ -- cgit v0.10.2-6-g49f6 From 42e410208ca9aa8af5f27c85a6b33af488a0b6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 24 Jul 2009 08:30:33 +0200 Subject: More DNSSD framework. diff --git a/Slimber/CLI/main.cpp b/Slimber/CLI/main.cpp index 40f41c8..65af3bc 100644 --- a/Slimber/CLI/main.cpp +++ b/Slimber/CLI/main.cpp @@ -10,6 +10,7 @@ #include "Slimber/Server.h" #include "Slimber/FileVCardCollection.h" #include "Swiften/LinkLocal/LinkLocalRoster.h" +#include "Swiften/LinkLocal/BonjourQuerier.h" #include "Swiften/EventLoop/SimpleEventLoop.h" #include "Swiften/Application/Platform/PlatformApplication.h" @@ -17,7 +18,14 @@ using namespace Swift; int main() { SimpleEventLoop eventLoop; + boost::shared_ptr<BonjourQuerier> querier(new BonjourQuerier()); + querier->start(); + boost::shared_ptr<DNSSDBrowseQuery> query = querier->createBrowseQuery(); + query->startBrowsing(); + boost::shared_ptr<DNSSDPublishQuery> query2 = querier->createPublishQuery("remko", 1234, LinkLocalServiceInfo()); + query2->publish(); +/* boost::shared_ptr<DNSSDService> dnsSDService; #if defined(SWIFTEN_PLATFORM_MACOSX) || defined(SWIFTEN_PLATFORM_WINDOWS) dnsSDService = boost::shared_ptr<AppleDNSSDService>( @@ -32,6 +40,8 @@ int main() { FileVCardCollection vCardCollection(PlatformApplication("Slimber").getSettingsDir()); Server server(5222, 5562, linkLocalRoster, dnsSDService, &vCardCollection); + */ + eventLoop.run(); return 0; } diff --git a/Swiften/LinkLocal/BonjourBrowseQuery.h b/Swiften/LinkLocal/BonjourBrowseQuery.h index 5b14d30..6a50a61 100644 --- a/Swiften/LinkLocal/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/BonjourBrowseQuery.h @@ -11,8 +11,9 @@ namespace Swift { BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) { DNSServiceErrorType result = DNSServiceBrowse( &sdRef, 0, 0, "_presence._tcp", 0, - &BonjourBrowseQuery::handleServiceDiscoveredGlobal , this); + &BonjourBrowseQuery::handleServiceDiscovered, this); if (result != kDNSServiceErr_NoError) { + std::cout << "Error" << std::endl; // TODO } } @@ -27,29 +28,21 @@ namespace Swift { } private: - static void handleServiceDiscoveredGlobal(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) { - static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain); - } - - void handleServiceDiscovered( - DNSServiceFlags flags, - uint32_t interfaceIndex, - DNSServiceErrorType errorCode, - const char *serviceName, - const char *type, - const char *domain) { + static void handleServiceDiscovered(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) { if (errorCode != kDNSServiceErr_NoError) { return; } else { - LinkLocalServiceID service(serviceName, type, domain, interfaceIndex); + BonjourBrowseQuery* query = static_cast<BonjourBrowseQuery*>(context); + LinkLocalServiceID service(name, type, domain, interfaceIndex); + std::cout << "Service discovered: " << name << std::endl; if (flags & kDNSServiceFlagsAdd) { - onServiceAdded(service); + query->onServiceAdded(service); } else { - onServiceRemoved(service); + query->onServiceRemoved(service); } } - } + } }; } diff --git a/Swiften/LinkLocal/BonjourPublishQuery.h b/Swiften/LinkLocal/BonjourPublishQuery.h new file mode 100644 index 0000000..4e7fd2f --- /dev/null +++ b/Swiften/LinkLocal/BonjourPublishQuery.h @@ -0,0 +1,41 @@ +#pragma once + +#include "Swiften/LinkLocal/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSDPublishQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourPublishQuery : public DNSSDPublishQuery, public BonjourQuery { + public: + BonjourPublishQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceErrorType result = DNSServiceRegister( + &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, + txtRecord.getSize(), txtRecord.getData(), + &BonjourPublishQuery::handleServiceRegistered, this); + if (result != kDNSServiceErr_NoError) { + // TODO + std::cerr << "Error creating service registration" << std::endl; + } + } + + void publish() { + run(); + } + + private: + static void handleServiceRegistered(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { + std::cout << "Publish finished " << name << std::endl; + BonjourPublishQuery* query = static_cast<BonjourPublishQuery*>(context); + if (errorCode != kDNSServiceErr_NoError) { + query->onPublishFinished(boost::optional<LinkLocalServiceID>()); + } + else { + query->onPublishFinished(boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))); + } + } + }; +} diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp index 1ddbd9d..93259c1 100644 --- a/Swiften/LinkLocal/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/BonjourQuerier.cpp @@ -7,6 +7,7 @@ #include "Swiften/EventLoop/MainEventLoop.h" #include "Swiften/LinkLocal/BonjourBrowseQuery.h" +#include "Swiften/LinkLocal/BonjourPublishQuery.h" #include "Swiften/Base/foreach.h" namespace Swift { @@ -18,7 +19,6 @@ BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(0) { interruptSelectReadSocket = fds[0]; fcntl(interruptSelectReadSocket, F_SETFL, fcntl(interruptSelectReadSocket, F_GETFL)|O_NONBLOCK); interruptSelectWriteSocket = fds[1]; - // TODO: Schedule thread } BonjourQuerier::~BonjourQuerier() { @@ -29,6 +29,10 @@ boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this())); } +boost::shared_ptr<DNSSDPublishQuery> BonjourQuerier::createPublishQuery(const String& name, int port, const LinkLocalServiceInfo& info) { + return boost::shared_ptr<DNSSDPublishQuery>(new BonjourPublishQuery(name, port, info, shared_from_this())); +} + void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { { boost::lock_guard<boost::mutex> lock(runningQueriesMutex); @@ -74,14 +78,16 @@ void BonjourQuerier::run() { int maxSocket; { boost::unique_lock<boost::mutex> lock(runningQueriesMutex); - runningQueriesAvailableEvent.wait(lock); if (runningQueries.empty()) { - continue; + runningQueriesAvailableEvent.wait(lock); + if (runningQueries.empty()) { + continue; + } } // Run all running queries FD_ZERO(&fdSet); - int maxSocket = interruptSelectReadSocket; + maxSocket = interruptSelectReadSocket; FD_SET(interruptSelectReadSocket, &fdSet); foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) { diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h index 037d9e6..5f69ad6 100644 --- a/Swiften/LinkLocal/BonjourQuerier.h +++ b/Swiften/LinkLocal/BonjourQuerier.h @@ -8,9 +8,12 @@ #include "Swiften/EventLoop/EventOwner.h" #include "Swiften/LinkLocal/DNSSDBrowseQuery.h" +#include "Swiften/LinkLocal/DNSSDPublishQuery.h" #include "Swiften/LinkLocal/BonjourQuery.h" namespace Swift { + class LinkLocalServiceInfo; + class BonjourQuerier : public boost::enable_shared_from_this<BonjourQuerier>, public EventOwner { @@ -19,6 +22,7 @@ namespace Swift { ~BonjourQuerier(); boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); + boost::shared_ptr<DNSSDPublishQuery> createPublishQuery(const String& name, int port, const LinkLocalServiceInfo& info); void start(); void stop(); diff --git a/Swiften/LinkLocal/BonjourQuery.cpp b/Swiften/LinkLocal/BonjourQuery.cpp index a9c13fb..965a845 100644 --- a/Swiften/LinkLocal/BonjourQuery.cpp +++ b/Swiften/LinkLocal/BonjourQuery.cpp @@ -11,7 +11,9 @@ BonjourQuery::~BonjourQuery() { } void BonjourQuery::processResult() { + std::cout << "Process result" << std::endl; boost::lock_guard<boost::mutex> lock(sdRefMutex); + std::cout << "DNSSDServiceProcessResult" << std::endl; DNSServiceProcessResult(sdRef); } diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSDBrowseQuery.h index b46d968..e548ca5 100644 --- a/Swiften/LinkLocal/DNSSDBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSDBrowseQuery.h @@ -9,6 +9,9 @@ namespace Swift { public: virtual ~DNSSDBrowseQuery(); + virtual void startBrowsing() = 0; + virtual void stopBrowsing() = 0; + boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; }; diff --git a/Swiften/LinkLocal/DNSSDPublishQuery.cpp b/Swiften/LinkLocal/DNSSDPublishQuery.cpp new file mode 100644 index 0000000..cf3fd25 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDPublishQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDPublishQuery.h" + +namespace Swift { + +DNSSDPublishQuery::~DNSSDPublishQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDPublishQuery.h b/Swiften/LinkLocal/DNSSDPublishQuery.h new file mode 100644 index 0000000..48c86dc --- /dev/null +++ b/Swiften/LinkLocal/DNSSDPublishQuery.h @@ -0,0 +1,17 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" + +namespace Swift { + class DNSSDPublishQuery { + public: + virtual ~DNSSDPublishQuery(); + + virtual void publish() = 0; + + boost::signal<void (boost::optional<LinkLocalServiceID>)> onPublishFinished; + }; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index b43a7e4..093ac70 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,6 +1,7 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/BonjourQuery.cpp \ Swiften/LinkLocal/DNSSDBrowseQuery.cpp \ + Swiften/LinkLocal/DNSSDPublishQuery.cpp \ Swiften/LinkLocal/DNSSDServiceFactory.cpp \ Swiften/LinkLocal/BonjourQuerier.cpp \ Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ -- cgit v0.10.2-6-g49f6 From 0dd979a856719f16925f84d6be532bd31044fa82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 24 Jul 2009 20:09:11 +0200 Subject: Fix uninitialized streamstack. diff --git a/Swiften/Client/UnitTest/ClientSessionTest.cpp b/Swiften/Client/UnitTest/ClientSessionTest.cpp index a91216c..bb10cfd 100644 --- a/Swiften/Client/UnitTest/ClientSessionTest.cpp +++ b/Swiften/Client/UnitTest/ClientSessionTest.cpp @@ -38,7 +38,7 @@ using namespace Swift; class ClientSessionTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ClientSessionTest); - //CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testConstructor); /* CPPUNIT_TEST(testStart_Error); CPPUNIT_TEST(testStart_XMLError); diff --git a/Swiften/Session/Session.cpp b/Swiften/Session/Session.cpp index 5ee98e7..92d1fdc 100644 --- a/Swiften/Session/Session.cpp +++ b/Swiften/Session/Session.cpp @@ -14,6 +14,7 @@ Session::Session( connection(connection), payloadParserFactories(payloadParserFactories), payloadSerializers(payloadSerializers), + streamStack(0), initialized(false) { } -- cgit v0.10.2-6-g49f6 From f6e73393afbe7ce8d1a5c5fc55565582cb8906cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 24 Jul 2009 20:09:29 +0200 Subject: Update the build system. Coverage now works better. Some files are cleaned by default (without the need of CLEANFILES). diff --git a/.gitignore b/.gitignore index 8a6563e..697ca06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .DS_Store *.dep +*.gcov *.gcda *.gcno *.app diff --git a/3rdParty/Boost/Makefile.inc b/3rdParty/Boost/Makefile.inc index 27aed09..d28bbcb 100644 --- a/3rdParty/Boost/Makefile.inc +++ b/3rdParty/Boost/Makefile.inc @@ -57,6 +57,3 @@ endif BOOST_OBJECTS = \ $(BOOST_SOURCES:.cpp=.o) - -CLEANFILES += \ - $(BOOST_OBJECTS) diff --git a/3rdParty/CppUnit/Makefile.inc b/3rdParty/CppUnit/Makefile.inc index 27aadc2..3749144 100644 --- a/3rdParty/CppUnit/Makefile.inc +++ b/3rdParty/CppUnit/Makefile.inc @@ -39,9 +39,5 @@ CPPUNIT_SOURCES = \ CPPUNIT_OBJECTS = \ $(CPPUNIT_SOURCES:.cpp=.o) -CLEANFILES += \ - $(CPPUNIT_OBJECTS) \ - $(CPPUNIT_TARGET) - $(CPPUNIT_TARGET): $(CPPUNIT_OBJECTS) $(QUIET_AR)$(AR) $(ARFLAGS) $@ $(CPPUNIT_OBJECTS) diff --git a/3rdParty/Expat/Makefile.inc b/3rdParty/Expat/Makefile.inc index c143263..a241cf1 100644 --- a/3rdParty/Expat/Makefile.inc +++ b/3rdParty/Expat/Makefile.inc @@ -8,10 +8,6 @@ EXPAT_SOURCES = \ EXPAT_OBJECTS = \ $(EXPAT_SOURCES:.c=.o) -CLEANFILES += \ - $(EXPAT_OBJECTS) \ - $(EXPAT_TARGET) - $(EXPAT_TARGET): $(EXPAT_OBJECTS) $(QUIET_AR)$(AR) $(ARFLAGS) $@ $(EXPAT_OBJECTS) diff --git a/3rdParty/LibIDN/Makefile.inc b/3rdParty/LibIDN/Makefile.inc index f0f64ac..2aeb34b 100644 --- a/3rdParty/LibIDN/Makefile.inc +++ b/3rdParty/LibIDN/Makefile.inc @@ -18,8 +18,3 @@ LIBIDN_SOURCES += \ LIBIDN_OBJECTS = \ $(LIBIDN_SOURCES:.c=.o) - -CLEANFILES += \ - $(LIBIDN_OBJECTS) - - diff --git a/3rdParty/SQLite/Makefile.inc b/3rdParty/SQLite/Makefile.inc index 339e7a0..141cfca 100644 --- a/3rdParty/SQLite/Makefile.inc +++ b/3rdParty/SQLite/Makefile.inc @@ -5,7 +5,3 @@ SQLITE_SOURCES = \ SQLITE_OBJECTS = \ $(SQLITE_SOURCES:.c=.o) - -CLEANFILES += \ - $(SQLITE_OBJECTS) \ - $(SQLITE_TARGET) diff --git a/3rdParty/ZLib/Makefile.inc b/3rdParty/ZLib/Makefile.inc index dccfcf4..a30f65d 100644 --- a/3rdParty/ZLib/Makefile.inc +++ b/3rdParty/ZLib/Makefile.inc @@ -17,6 +17,3 @@ ZLIB_SOURCES += \ ZLIB_OBJECTS = \ $(ZLIB_SOURCES:.c=.o) - -CLEANFILES += \ - $(ZLIB_OBJECTS) diff --git a/Limber/Makefile.inc b/Limber/Makefile.inc index ea0d288..fe0e7d2 100644 --- a/Limber/Makefile.inc +++ b/Limber/Makefile.inc @@ -11,6 +11,5 @@ $(LIMBER_TARGET): $(SWIFTEN_TARGET) $(LIMBER_OBJECTS) $(QUIET_LINK)$(CXX) -o $(LIMBER_TARGET) $(LIMBER_OBJECTS) $(LDFLAGS) $(SWIFTEN_TARGET) $(LIBS) #TARGETS += $(LIMBER_TARGET) -CLEANFILES += $(LIMBER_OBJECTS) DEPS += \ $(LIMBER_SOURCES:.cpp=.dep) \ diff --git a/Makefile b/Makefile index 8ea2c13..b93c85f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ include Makefile.config -CXXFLAGS += -I. -CFLAGS += -I. +CXXFLAGS += -I$(PWD) +CFLAGS += -I$(PWD) ARFLAGS = rcs .DEFAULT_GOAL = all @@ -66,16 +66,9 @@ coverage: tools/coverage/GenerateCoverageResults.sh .PHONY: clean -clean: clean-deps $(CLEAN_TARGETS) - - -$(RM) $(CLEANFILES) *.gcov - -find . -name "*.gcda" -exec rm {} \; - -find . -name "*.gcno" -exec rm {} \; - -.PHONY: clean-deps -clean-deps: - -$(RM) $(DEPS) - +clean: $(CLEAN_TARGETS) + -rm -rf $(CLEANFILES) + -find . \( -name "*.dep" -or -name "*.a" -or -name "*.o" -or -name "*.obj" -or -name "*.gcda" -or -name "*.gcno" -or -name "*.gcov" \) -exec rm {} \; ################################################################################ # Automatic dependency detection diff --git a/QA/UnitTest/Makefile.inc b/QA/UnitTest/Makefile.inc index 531f616..f51828e 100644 --- a/QA/UnitTest/Makefile.inc +++ b/QA/UnitTest/Makefile.inc @@ -6,7 +6,7 @@ UNITTEST_OBJECTS = \ TEST_TARGETS += check -CLEANFILES += $(UNITTEST_OBJECTS) $(UNITTEST_TARGET) +CLEANFILES += $(UNITTEST_TARGET) DEPS += $(UNITTEST_SOURCES:.cpp=.dep) .PHONY: check diff --git a/Slimber/CLI/Makefile.inc b/Slimber/CLI/Makefile.inc index 601929c..974b835 100644 --- a/Slimber/CLI/Makefile.inc +++ b/Slimber/CLI/Makefile.inc @@ -7,10 +7,9 @@ SLIMBER_CLI_OBJECTS = \ $(SLIMBER_CLI_TARGET): $(SWIFTEN_TARGET) $(SLIMBER_TARGET) $(SLIMBER_CLI_OBJECTS) $(QUIET_LINK)$(CXX) -o $(SLIMBER_CLI_TARGET) $(SLIMBER_CLI_OBJECTS) $(LDFLAGS) $(SLIMBER_TARGET) $(SWIFTEN_TARGET) $(LIBS) -TARGETS += $(SLIMBER_CLI_TARGET) +#TARGETS += $(SLIMBER_CLI_TARGET) SLIMBER_TARGETS += $(SLIMBER_CLI_TARGET) CLEANFILES += \ - $(SLIMBER_CLI_OBJECTS) \ $(SLIMBER_CLI_TARGET) DEPS += \ $(SLIMBER_CLI_SOURCES:.cpp=.dep) \ diff --git a/Slimber/Cocoa/Makefile.inc b/Slimber/Cocoa/Makefile.inc index 73b0f5d..28495f7 100644 --- a/Slimber/Cocoa/Makefile.inc +++ b/Slimber/Cocoa/Makefile.inc @@ -25,7 +25,6 @@ SLIMBER_COCOA_OBJECTS = \ $(patsubst %.m,%.o,$(patsubst %.mm,%.o,$(patsubst %.cpp,%.o, $(SLIMBER_COCOA_SOURCES)))) CLEANFILES += \ Slimber/Cocoa/PkgInfo \ - $(SLIMBER_COCOA_OBJECTS) \ $(SLIMBER_COCOA_NIBS) \ $(SLIMBER_COCOA_TARGET) \ $(SLIMBER_COCOA_BINARY) diff --git a/Slimber/Makefile.inc b/Slimber/Makefile.inc index 539646c..fea164f 100644 --- a/Slimber/Makefile.inc +++ b/Slimber/Makefile.inc @@ -6,9 +6,6 @@ SLIMBER_SOURCES = \ SLIMBER_OBJECTS = \ $(SLIMBER_SOURCES:.cpp=.o) -CLEANFILES += \ - $(SLIMBER_OBJECTS) \ - $(SLIMBER_TARGET) DEPS += \ $(SLIMBER_SOURCES:.cpp=.dep) \ diff --git a/Swift/Controllers/Makefile.inc b/Swift/Controllers/Makefile.inc index 4c69e34..b145c54 100644 --- a/Swift/Controllers/Makefile.inc +++ b/Swift/Controllers/Makefile.inc @@ -18,7 +18,6 @@ SWIFT_CONTROLLERS_OBJECTS = \ TARGETS += $(SWIFT_CONTROLLERS_TARGET) UNITTEST_LIBS += $(SWIFT_CONTROLLERS_TARGET) -CLEANFILES += $(SWIFT_CONTROLLERS_TARGET) $(SWIFT_CONTROLLERS_OBJECTS) DEPS += $(SWIFT_CONTROLLERS_SOURCES:.cpp=.dep) $(SWIFT_CONTROLLERS_TARGET): $(SWIFT_CONTROLLERS_OBJECTS) diff --git a/Swiften/Examples/EchoBot/Makefile.inc b/Swiften/Examples/EchoBot/Makefile.inc index 09c63d5..beab023 100644 --- a/Swiften/Examples/EchoBot/Makefile.inc +++ b/Swiften/Examples/EchoBot/Makefile.inc @@ -4,7 +4,7 @@ ECHOBOT_SOURCES += \ ECHOBOT_OBJECTS = \ $(ECHOBOT_SOURCES:.cpp=.o) -CLEANFILES += $(ECHOBOT_OBJECTS) $(ECHOBOT_TARGET) +CLEANFILES += $(ECHOBOT_TARGET) DEPS += $(ECHOBOT_SOURCES:.cpp=.dep) EXAMPLES_TARGETS += $(ECHOBOT_TARGET) diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 093ac70..902fa7a 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,9 +1,7 @@ SWIFTEN_SOURCES += \ - Swiften/LinkLocal/BonjourQuery.cpp \ Swiften/LinkLocal/DNSSDBrowseQuery.cpp \ Swiften/LinkLocal/DNSSDPublishQuery.cpp \ Swiften/LinkLocal/DNSSDServiceFactory.cpp \ - Swiften/LinkLocal/BonjourQuerier.cpp \ Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ @@ -16,6 +14,8 @@ SWIFTEN_SOURCES += \ ifeq ($(HAVE_BONJOUR),yes) SWIFTEN_SOURCES += \ + Swiften/LinkLocal/BonjourQuery.cpp \ + Swiften/LinkLocal/BonjourQuerier.cpp \ Swiften/LinkLocal/AppleDNSSDService.cpp endif ifeq ($(HAVE_AVAHI),yes) diff --git a/Swiften/Makefile.inc b/Swiften/Makefile.inc index 57ff329..d7c3340 100644 --- a/Swiften/Makefile.inc +++ b/Swiften/Makefile.inc @@ -41,7 +41,6 @@ SWIFTEN_HEADERS += \ TARGETS += $(SWIFTEN_TARGET) INSTALL_TARGETS += install-swiften UNITTEST_LIBS += $(SWIFTEN_TARGET) -CLEANFILES += $(SWIFTEN_TARGET) $(SWIFTEN_OBJECTS) DEPS += \ $(SWIFTEN_SOURCES:.cpp=.dep) //TODO: Add objective stuff diff --git a/Swiften/QA/ClientTest/Makefile.inc b/Swiften/QA/ClientTest/Makefile.inc index 16a87cf..b9ab167 100644 --- a/Swiften/QA/ClientTest/Makefile.inc +++ b/Swiften/QA/ClientTest/Makefile.inc @@ -6,7 +6,7 @@ CLIENTTEST_OBJECTS = \ TEST_TARGETS += ClientTest -CLEANFILES += $(CLIENTTEST_OBJECTS) $(CLIENTTEST_TARGET) +CLEANFILES += $(CLIENTTEST_TARGET) DEPS += $(CLIENTTEST_SOURCES:.cpp=.dep) $(CLIENTTEST_TARGET): $(SWIFTEN_TARGET) $(CLIENTTEST_OBJECTS) $(BUNDLED_LIBS) diff --git a/Swiften/QA/NetworkTest/Makefile.inc b/Swiften/QA/NetworkTest/Makefile.inc index 5ac14c0..b263cdb 100644 --- a/Swiften/QA/NetworkTest/Makefile.inc +++ b/Swiften/QA/NetworkTest/Makefile.inc @@ -8,7 +8,7 @@ NETWORKTEST_OBJECTS = \ TEST_TARGETS += NetworkTest -CLEANFILES += $(NETWORKTEST_OBJECTS) $(NETWORKTEST_TARGET) +CLEANFILES += $(NETWORKTEST_TARGET) DEPS += $(NETWORKTEST_SOURCES:.cpp=.dep) $(NETWORKTEST_TARGET): $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(NETWORKTEST_OBJECTS) $(BUNDLED_LIBS) diff --git a/tools/coverage/FilterLCovData.py b/tools/coverage/FilterLCovData.py index 8b8d24e..b1dd74e 100755 --- a/tools/coverage/FilterLCovData.py +++ b/tools/coverage/FilterLCovData.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -import sys, re +import sys, re, os.path assert(len(sys.argv) == 2) @@ -15,8 +15,9 @@ for line in inputFile.readlines() : if line.startswith("SF:") and (line.find("/Swiften/") == -1 or line.find("/UnitTest/") != -1 or line.find("/QA/") != -1 or line.find("/3rdParty/") != -1): inIgnoredFile = True else : - if line.startswith("SF:") : - line = line.replace("/./Swiften/", "/Swiften/") + m = re.match("SF:(.*)", line) + if m : + line = "SF:" + os.path.realpath(m.group(1)) + "\n" output.append(line) inputFile.close() -- cgit v0.10.2-6-g49f6 From 30f99a2bcbbeb41bfd61768b98c243ebcfdf67c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 24 Jul 2009 20:07:47 +0200 Subject: Make BonjourQuerier thread-safe. diff --git a/Swiften/LinkLocal/BonjourBrowseQuery.h b/Swiften/LinkLocal/BonjourBrowseQuery.h index 6a50a61..6db108d 100644 --- a/Swiften/LinkLocal/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/BonjourBrowseQuery.h @@ -2,6 +2,7 @@ #include "Swiften/LinkLocal/BonjourQuery.h" #include "Swiften/LinkLocal/DNSSDBrowseQuery.h" +#include "Swiften/EventLoop/MainEventLoop.h" namespace Swift { class BonjourQuerier; @@ -11,7 +12,7 @@ namespace Swift { BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) { DNSServiceErrorType result = DNSServiceBrowse( &sdRef, 0, 0, "_presence._tcp", 0, - &BonjourBrowseQuery::handleServiceDiscovered, this); + &BonjourBrowseQuery::handleServiceDiscoveredStatic, this); if (result != kDNSServiceErr_NoError) { std::cout << "Error" << std::endl; // TODO @@ -28,19 +29,21 @@ namespace Swift { } private: - static void handleServiceDiscovered(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) { + static void handleServiceDiscoveredStatic(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) { + static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, name, type, domain); + } + + void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) { if (errorCode != kDNSServiceErr_NoError) { return; } else { - BonjourBrowseQuery* query = static_cast<BonjourBrowseQuery*>(context); LinkLocalServiceID service(name, type, domain, interfaceIndex); - std::cout << "Service discovered: " << name << std::endl; if (flags & kDNSServiceFlagsAdd) { - query->onServiceAdded(service); + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); } else { - query->onServiceRemoved(service); + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); } } } diff --git a/Swiften/LinkLocal/BonjourPublishQuery.h b/Swiften/LinkLocal/BonjourPublishQuery.h index 4e7fd2f..a96e25a 100644 --- a/Swiften/LinkLocal/BonjourPublishQuery.h +++ b/Swiften/LinkLocal/BonjourPublishQuery.h @@ -4,6 +4,7 @@ #include "Swiften/LinkLocal/DNSSDPublishQuery.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" #include "Swiften/Base/ByteArray.h" +#include "Swiften/EventLoop/MainEventLoop.h" namespace Swift { class BonjourQuerier; @@ -15,7 +16,7 @@ namespace Swift { DNSServiceErrorType result = DNSServiceRegister( &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, txtRecord.getSize(), txtRecord.getData(), - &BonjourPublishQuery::handleServiceRegistered, this); + &BonjourPublishQuery::handleServicePublishedStatic, this); if (result != kDNSServiceErr_NoError) { // TODO std::cerr << "Error creating service registration" << std::endl; @@ -26,15 +27,23 @@ namespace Swift { run(); } + void update(const LinkLocalService& info) { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); + } + private: - static void handleServiceRegistered(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { - std::cout << "Publish finished " << name << std::endl; - BonjourPublishQuery* query = static_cast<BonjourPublishQuery*>(context); + static void handleServicePublishedStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { + static_cast<BonjourPublishQuery*>(context)->handleServicePublished(errorCode, name, regtype, domain); + } + + void handleServicePublished(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { if (errorCode != kDNSServiceErr_NoError) { - query->onPublishFinished(boost::optional<LinkLocalServiceID>()); + MainEventLoop::postEvent(boost::bind(boost::ref(onPublishFinished), boost::optional<LinkLocalServiceID>()), shared_from_this()); } else { - query->onPublishFinished(boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))); + MainEventLoop::postEvent(boost::bind(boost::ref(onPublishFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this()); } } }; diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp index 93259c1..3080869 100644 --- a/Swiften/LinkLocal/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/BonjourQuerier.cpp @@ -5,7 +5,6 @@ #include <netinet/in.h> #include <fcntl.h> -#include "Swiften/EventLoop/MainEventLoop.h" #include "Swiften/LinkLocal/BonjourBrowseQuery.h" #include "Swiften/LinkLocal/BonjourPublishQuery.h" #include "Swiften/Base/foreach.h" @@ -108,10 +107,9 @@ void BonjourQuerier::run() { { boost::lock_guard<boost::mutex> lock(runningQueriesMutex); - foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) { + foreach(boost::shared_ptr<BonjourQuery> query, runningQueries) { if (FD_ISSET(query->getSocketID(), &fdSet)) { - MainEventLoop::postEvent( - boost::bind(&BonjourQuery::processResult, query), shared_from_this()); + query->processResult(); } } } diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h index 5f69ad6..e5ffa49 100644 --- a/Swiften/LinkLocal/BonjourQuerier.h +++ b/Swiften/LinkLocal/BonjourQuerier.h @@ -6,7 +6,6 @@ #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> -#include "Swiften/EventLoop/EventOwner.h" #include "Swiften/LinkLocal/DNSSDBrowseQuery.h" #include "Swiften/LinkLocal/DNSSDPublishQuery.h" #include "Swiften/LinkLocal/BonjourQuery.h" @@ -14,9 +13,7 @@ namespace Swift { class LinkLocalServiceInfo; - class BonjourQuerier : - public boost::enable_shared_from_this<BonjourQuerier>, - public EventOwner { + class BonjourQuerier : public boost::enable_shared_from_this<BonjourQuerier> { public: BonjourQuerier(); ~BonjourQuerier(); diff --git a/Swiften/LinkLocal/BonjourQuery.cpp b/Swiften/LinkLocal/BonjourQuery.cpp index 965a845..a9c13fb 100644 --- a/Swiften/LinkLocal/BonjourQuery.cpp +++ b/Swiften/LinkLocal/BonjourQuery.cpp @@ -11,9 +11,7 @@ BonjourQuery::~BonjourQuery() { } void BonjourQuery::processResult() { - std::cout << "Process result" << std::endl; boost::lock_guard<boost::mutex> lock(sdRefMutex); - std::cout << "DNSSDServiceProcessResult" << std::endl; DNSServiceProcessResult(sdRef); } diff --git a/Swiften/LinkLocal/BonjourQuery.h b/Swiften/LinkLocal/BonjourQuery.h index 2a47f73..bdb91a4 100644 --- a/Swiften/LinkLocal/BonjourQuery.h +++ b/Swiften/LinkLocal/BonjourQuery.h @@ -5,10 +5,14 @@ #include <boost/enable_shared_from_this.hpp> #include <boost/thread/mutex.hpp> +#include "Swiften/EventLoop/EventOwner.h" + namespace Swift { class BonjourQuerier; - class BonjourQuery : public boost::enable_shared_from_this<BonjourQuery> { + class BonjourQuery : + public EventOwner, + public boost::enable_shared_from_this<BonjourQuery> { public: BonjourQuery(boost::shared_ptr<BonjourQuerier>); virtual ~BonjourQuery(); diff --git a/configure.in b/configure.in index 3a10e2c..186bc3c 100644 --- a/configure.in +++ b/configure.in @@ -198,12 +198,11 @@ AC_CHECK_LIB(resolv, inet_aton) # DNSSD Service case $host in *-*-cygwin*) - AC_DEFINE(HAVE_BONJOUR) ;; *-mingw32*) - AC_DEFINE(HAVE_BONJOUR) ;; *-*-darwin*) + AC_DEFINE(HAVE_BONJOUR) ;; *) AX_AVAHI() -- cgit v0.10.2-6-g49f6 From 8cad7cff0462d8a48a5bc9762ce6d6b62e74d0e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 24 Jul 2009 21:04:05 +0200 Subject: Remove unnecessary Slimber Cocoa menu entries. diff --git a/Slimber/Cocoa/MainMenu.xib b/Slimber/Cocoa/MainMenu.xib index a5eb7e1..50e4ca3 100644 --- a/Slimber/Cocoa/MainMenu.xib +++ b/Slimber/Cocoa/MainMenu.xib @@ -8,7 +8,7 @@ <string key="IBDocument.HIToolboxVersion">353.00</string> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <bool key="EncodedWithXMLCoder">YES</bool> - <integer value="205"/> + <integer value="136"/> </object> <object class="NSArray" key="IBDocument.PluginDependencies"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -41,7 +41,7 @@ <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="694149608"> <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">NewApplication</string> + <string key="NSTitle">Slimber</string> <string key="NSKeyEquiv"/> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> @@ -55,12 +55,12 @@ </object> <string key="NSAction">submenuAction:</string> <object class="NSMenu" key="NSSubmenu" id="110575045"> - <string key="NSTitle">NewApplication</string> + <string key="NSTitle">Slimber</string> <object class="NSMutableArray" key="NSMenuItems"> <bool key="EncodedWithXMLCoder">YES</bool> <object class="NSMenuItem" id="238522557"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">About NewApplication</string> + <string key="NSTitle">About Slimber</string> <string key="NSKeyEquiv"/> <int key="NSMnemonicLoc">2147483647</int> <reference key="NSOnImage" ref="35465992"/> @@ -127,7 +127,7 @@ </object> <object class="NSMenuItem" id="755159360"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">Hide NewApplication</string> + <string key="NSTitle">Hide Slimber</string> <string key="NSKeyEquiv">h</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> @@ -165,7 +165,7 @@ </object> <object class="NSMenuItem" id="632727374"> <reference key="NSMenu" ref="110575045"/> - <string key="NSTitle">Quit NewApplication</string> + <string key="NSTitle">Quit Slimber</string> <string key="NSKeyEquiv">q</string> <int key="NSKeyEquivModMask">1048576</int> <int key="NSMnemonicLoc">2147483647</int> @@ -176,2364 +176,194 @@ <string key="NSName">_NSAppleMenu</string> </object> </object> - <object class="NSMenuItem" id="379814623"> - <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">File</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="720053764"> - <string key="NSTitle">File</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="705341025"> - <reference key="NSMenu" ref="720053764"/> - <string key="NSTitle">New</string> - <string key="NSKeyEquiv">n</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="722745758"> - <reference key="NSMenu" ref="720053764"/> - <string type="base64-UTF8" key="NSTitle">T3BlbuKApg</string> - <string key="NSKeyEquiv">o</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1025936716"> - <reference key="NSMenu" ref="720053764"/> - <string key="NSTitle">Open Recent</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="1065607017"> - <string key="NSTitle">Open Recent</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="759406840"> - <reference key="NSMenu" ref="1065607017"/> - <string key="NSTitle">Clear Menu</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - <string key="NSName">_NSRecentDocumentsMenu</string> - </object> - </object> - <object class="NSMenuItem" id="425164168"> - <reference key="NSMenu" ref="720053764"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="776162233"> - <reference key="NSMenu" ref="720053764"/> - <string key="NSTitle">Close</string> - <string key="NSKeyEquiv">w</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1023925487"> - <reference key="NSMenu" ref="720053764"/> - <string key="NSTitle">Save</string> - <string key="NSKeyEquiv">s</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="117038363"> - <reference key="NSMenu" ref="720053764"/> - <string type="base64-UTF8" key="NSTitle">U2F2ZSBBc+KApg</string> - <string key="NSKeyEquiv">S</string> - <int key="NSKeyEquivModMask">1179648</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="579971712"> - <reference key="NSMenu" ref="720053764"/> - <string key="NSTitle">Revert to Saved</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1010469920"> - <reference key="NSMenu" ref="720053764"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="294629803"> - <reference key="NSMenu" ref="720053764"/> - <string key="NSTitle">Page Setup...</string> - <string key="NSKeyEquiv">P</string> - <int key="NSKeyEquivModMask">1179648</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSToolTip"/> - </object> - <object class="NSMenuItem" id="49223823"> - <reference key="NSMenu" ref="720053764"/> - <string type="base64-UTF8" key="NSTitle">UHJpbnTigKY</string> - <string key="NSKeyEquiv">p</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="952259628"> - <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">Edit</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="789758025"> - <string key="NSTitle">Edit</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="1058277027"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Undo</string> - <string key="NSKeyEquiv">z</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="790794224"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Redo</string> - <string key="NSKeyEquiv">Z</string> - <int key="NSKeyEquivModMask">1179648</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1040322652"> - <reference key="NSMenu" ref="789758025"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="296257095"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Cut</string> - <string key="NSKeyEquiv">x</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="860595796"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Copy</string> - <string key="NSKeyEquiv">c</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="29853731"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Paste</string> - <string key="NSKeyEquiv">v</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="437104165"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Delete</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="583158037"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Select All</string> - <string key="NSKeyEquiv">a</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="212016141"> - <reference key="NSMenu" ref="789758025"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="892235320"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Find</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="963351320"> - <string key="NSTitle">Find</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="447796847"> - <reference key="NSMenu" ref="963351320"/> - <string type="base64-UTF8" key="NSTitle">RmluZOKApg</string> - <string key="NSKeyEquiv">f</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">1</int> - </object> - <object class="NSMenuItem" id="326711663"> - <reference key="NSMenu" ref="963351320"/> - <string key="NSTitle">Find Next</string> - <string key="NSKeyEquiv">g</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">2</int> - </object> - <object class="NSMenuItem" id="270902937"> - <reference key="NSMenu" ref="963351320"/> - <string key="NSTitle">Find Previous</string> - <string key="NSKeyEquiv">G</string> - <int key="NSKeyEquivModMask">1179648</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">3</int> - </object> - <object class="NSMenuItem" id="159080638"> - <reference key="NSMenu" ref="963351320"/> - <string key="NSTitle">Use Selection for Find</string> - <string key="NSKeyEquiv">e</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">7</int> - </object> - <object class="NSMenuItem" id="88285865"> - <reference key="NSMenu" ref="963351320"/> - <string key="NSTitle">Jump to Selection</string> - <string key="NSKeyEquiv">j</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="972420730"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Spelling and Grammar</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="769623530"> - <string key="NSTitle">Spelling and Grammar</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="679648819"> - <reference key="NSMenu" ref="769623530"/> - <string type="base64-UTF8" key="NSTitle">U2hvdyBTcGVsbGluZ+KApg</string> - <string key="NSKeyEquiv">:</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="96193923"> - <reference key="NSMenu" ref="769623530"/> - <string key="NSTitle">Check Spelling</string> - <string key="NSKeyEquiv">;</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="948374510"> - <reference key="NSMenu" ref="769623530"/> - <string key="NSTitle">Check Spelling While Typing</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="967646866"> - <reference key="NSMenu" ref="769623530"/> - <string key="NSTitle">Check Grammar With Spelling</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="507821607"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Substitutions</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="698887838"> - <string key="NSTitle">Substitutions</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="605118523"> - <reference key="NSMenu" ref="698887838"/> - <string key="NSTitle">Smart Copy/Paste</string> - <string key="NSKeyEquiv">f</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">1</int> - </object> - <object class="NSMenuItem" id="197661976"> - <reference key="NSMenu" ref="698887838"/> - <string key="NSTitle">Smart Quotes</string> - <string key="NSKeyEquiv">g</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">2</int> - </object> - <object class="NSMenuItem" id="708854459"> - <reference key="NSMenu" ref="698887838"/> - <string key="NSTitle">Smart Links</string> - <string key="NSKeyEquiv">G</string> - <int key="NSKeyEquivModMask">1179648</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">3</int> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="676164635"> - <reference key="NSMenu" ref="789758025"/> - <string key="NSTitle">Speech</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="785027613"> - <string key="NSTitle">Speech</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="731782645"> - <reference key="NSMenu" ref="785027613"/> - <string key="NSTitle">Start Speaking</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="680220178"> - <reference key="NSMenu" ref="785027613"/> - <string key="NSTitle">Stop Speaking</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="302598603"> - <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">Format</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="941447902"> - <string key="NSTitle">Format</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="792887677"> - <reference key="NSMenu" ref="941447902"/> - <string key="NSTitle">Font</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="786677654"> - <string key="NSTitle">Font</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="159677712"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Show Fonts</string> - <string key="NSKeyEquiv">t</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="305399458"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Bold</string> - <string key="NSKeyEquiv">b</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">2</int> - </object> - <object class="NSMenuItem" id="814362025"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Italic</string> - <string key="NSKeyEquiv">i</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">1</int> - </object> - <object class="NSMenuItem" id="330926929"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Underline</string> - <string key="NSKeyEquiv">u</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="533507878"> - <reference key="NSMenu" ref="786677654"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="158063935"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Bigger</string> - <string key="NSKeyEquiv">+</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">3</int> - </object> - <object class="NSMenuItem" id="885547335"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Smaller</string> - <string key="NSKeyEquiv">-</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <int key="NSTag">4</int> - </object> - <object class="NSMenuItem" id="901062459"> - <reference key="NSMenu" ref="786677654"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="767671776"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Kern</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="175441468"> - <string key="NSTitle">Kern</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="252969304"> - <reference key="NSMenu" ref="175441468"/> - <string key="NSTitle">Use Default</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="766922938"> - <reference key="NSMenu" ref="175441468"/> - <string key="NSTitle">Use None</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="677519740"> - <reference key="NSMenu" ref="175441468"/> - <string key="NSTitle">Tighten</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="238351151"> - <reference key="NSMenu" ref="175441468"/> - <string key="NSTitle">Loosen</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="691570813"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Ligature</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="1058217995"> - <string key="NSTitle">Ligature</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="706297211"> - <reference key="NSMenu" ref="1058217995"/> - <string key="NSTitle">Use Default</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="568384683"> - <reference key="NSMenu" ref="1058217995"/> - <string key="NSTitle">Use None</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="663508465"> - <reference key="NSMenu" ref="1058217995"/> - <string key="NSTitle">Use All</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="769124883"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Baseline</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="18263474"> - <string key="NSTitle">Baseline</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="257962622"> - <reference key="NSMenu" ref="18263474"/> - <string key="NSTitle">Use Default</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="644725453"> - <reference key="NSMenu" ref="18263474"/> - <string key="NSTitle">Superscript</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1037576581"> - <reference key="NSMenu" ref="18263474"/> - <string key="NSTitle">Subscript</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="941806246"> - <reference key="NSMenu" ref="18263474"/> - <string key="NSTitle">Raise</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1045724900"> - <reference key="NSMenu" ref="18263474"/> - <string key="NSTitle">Lower</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="739652853"> - <reference key="NSMenu" ref="786677654"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="1012600125"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Show Colors</string> - <string key="NSKeyEquiv">C</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="214559597"> - <reference key="NSMenu" ref="786677654"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="596732606"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Copy Style</string> - <string key="NSKeyEquiv">c</string> - <int key="NSKeyEquivModMask">1572864</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="393423671"> - <reference key="NSMenu" ref="786677654"/> - <string key="NSTitle">Paste Style</string> - <string key="NSKeyEquiv">v</string> - <int key="NSKeyEquivModMask">1572864</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - <string key="NSName">_NSFontMenu</string> - </object> - </object> - <object class="NSMenuItem" id="15516124"> - <reference key="NSMenu" ref="941447902"/> - <string key="NSTitle">Text</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="23081656"> - <string key="NSTitle">Text</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="135107054"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Align Left</string> - <string key="NSKeyEquiv">{</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="310547522"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Center</string> - <string key="NSKeyEquiv">|</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="436088763"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Justify</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="498119243"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Align Right</string> - <string key="NSKeyEquiv">}</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="607995063"> - <reference key="NSMenu" ref="23081656"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="420564933"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Show Ruler</string> - <string key="NSKeyEquiv"/> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="479856769"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Copy Ruler</string> - <string key="NSKeyEquiv">c</string> - <int key="NSKeyEquivModMask">1310720</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="333628178"> - <reference key="NSMenu" ref="23081656"/> - <string key="NSTitle">Paste Ruler</string> - <string key="NSKeyEquiv">v</string> - <int key="NSKeyEquivModMask">1310720</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="586577488"> - <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">View</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="466310130"> - <string key="NSTitle">View</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="102151532"> - <reference key="NSMenu" ref="466310130"/> - <string key="NSTitle">Show Toolbar</string> - <string key="NSKeyEquiv">t</string> - <int key="NSKeyEquivModMask">1572864</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="237841660"> - <reference key="NSMenu" ref="466310130"/> - <string type="base64-UTF8" key="NSTitle">Q3VzdG9taXplIFRvb2xiYXLigKY</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - <object class="NSMenuItem" id="713487014"> - <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">Window</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="835318025"> - <string key="NSTitle">Window</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="1011231497"> - <reference key="NSMenu" ref="835318025"/> - <string key="NSTitle">Minimize</string> - <string key="NSKeyEquiv">m</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="575023229"> - <reference key="NSMenu" ref="835318025"/> - <string key="NSTitle">Zoom</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="299356726"> - <reference key="NSMenu" ref="835318025"/> - <bool key="NSIsDisabled">YES</bool> - <bool key="NSIsSeparator">YES</bool> - <string key="NSTitle"/> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - <object class="NSMenuItem" id="625202149"> - <reference key="NSMenu" ref="835318025"/> - <string key="NSTitle">Bring All to Front</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - <string key="NSName">_NSWindowsMenu</string> - </object> - </object> - <object class="NSMenuItem" id="391199113"> - <reference key="NSMenu" ref="649796088"/> - <string key="NSTitle">Help</string> - <string key="NSKeyEquiv"/> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - <string key="NSAction">submenuAction:</string> - <object class="NSMenu" key="NSSubmenu" id="374024848"> - <string key="NSTitle">Help</string> - <object class="NSMutableArray" key="NSMenuItems"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSMenuItem" id="238773614"> - <reference key="NSMenu" ref="374024848"/> - <string key="NSTitle">NewApplication Help</string> - <string key="NSKeyEquiv">?</string> - <int key="NSKeyEquivModMask">1048576</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="35465992"/> - <reference key="NSMixedImage" ref="502551668"/> - </object> - </object> - </object> - </object> - </object> - <string key="NSName">_NSMainMenu</string> - </object> - <object class="NSCustomObject" id="755631768"> - <string key="NSClassName">NSFontManager</string> - </object> - <object class="NSCustomObject" id="16040424"> - <string key="NSClassName">MainController</string> - </object> - </object> - <object class="IBObjectContainer" key="IBDocument.Objects"> - <object class="NSMutableArray" key="connectionRecords"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">performMiniaturize:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="1011231497"/> - </object> - <int key="connectionID">37</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">arrangeInFront:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="625202149"/> - </object> - <int key="connectionID">39</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">print:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="49223823"/> - </object> - <int key="connectionID">86</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">runPageLayout:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="294629803"/> - </object> - <int key="connectionID">87</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">clearRecentDocuments:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="759406840"/> - </object> - <int key="connectionID">127</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">orderFrontStandardAboutPanel:</string> - <reference key="source" ref="1021"/> - <reference key="destination" ref="238522557"/> - </object> - <int key="connectionID">142</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">performClose:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="776162233"/> - </object> - <int key="connectionID">193</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleContinuousSpellChecking:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="948374510"/> - </object> - <int key="connectionID">222</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">undo:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="1058277027"/> - </object> - <int key="connectionID">223</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">copy:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="860595796"/> - </object> - <int key="connectionID">224</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">checkSpelling:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="96193923"/> - </object> - <int key="connectionID">225</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">paste:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="29853731"/> - </object> - <int key="connectionID">226</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">stopSpeaking:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="680220178"/> - </object> - <int key="connectionID">227</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">cut:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="296257095"/> - </object> - <int key="connectionID">228</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">showGuessPanel:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="679648819"/> - </object> - <int key="connectionID">230</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">redo:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="790794224"/> - </object> - <int key="connectionID">231</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">selectAll:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="583158037"/> - </object> - <int key="connectionID">232</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">startSpeaking:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="731782645"/> - </object> - <int key="connectionID">233</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">delete:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="437104165"/> - </object> - <int key="connectionID">235</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">performZoom:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="575023229"/> - </object> - <int key="connectionID">240</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">performFindPanelAction:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="447796847"/> - </object> - <int key="connectionID">241</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">centerSelectionInVisibleArea:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="88285865"/> - </object> - <int key="connectionID">245</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleGrammarChecking:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="967646866"/> - </object> - <int key="connectionID">347</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleSmartInsertDelete:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="605118523"/> - </object> - <int key="connectionID">355</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleAutomaticQuoteSubstitution:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="197661976"/> - </object> - <int key="connectionID">356</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleAutomaticLinkDetection:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="708854459"/> - </object> - <int key="connectionID">357</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">showHelp:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="238773614"/> - </object> - <int key="connectionID">360</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">saveDocument:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="1023925487"/> - </object> - <int key="connectionID">362</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">saveDocumentAs:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="117038363"/> - </object> - <int key="connectionID">363</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">revertDocumentToSaved:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="579971712"/> - </object> - <int key="connectionID">364</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">runToolbarCustomizationPalette:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="237841660"/> - </object> - <int key="connectionID">365</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleToolbarShown:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="102151532"/> - </object> - <int key="connectionID">366</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">hide:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="755159360"/> - </object> - <int key="connectionID">367</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">hideOtherApplications:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="342932134"/> - </object> - <int key="connectionID">368</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">unhideAllApplications:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="908899353"/> - </object> - <int key="connectionID">370</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">newDocument:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="705341025"/> - </object> - <int key="connectionID">373</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">openDocument:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="722745758"/> - </object> - <int key="connectionID">374</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">addFontTrait:</string> - <reference key="source" ref="755631768"/> - <reference key="destination" ref="305399458"/> - </object> - <int key="connectionID">421</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">addFontTrait:</string> - <reference key="source" ref="755631768"/> - <reference key="destination" ref="814362025"/> - </object> - <int key="connectionID">422</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">modifyFont:</string> - <reference key="source" ref="755631768"/> - <reference key="destination" ref="885547335"/> - </object> - <int key="connectionID">423</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">orderFrontFontPanel:</string> - <reference key="source" ref="755631768"/> - <reference key="destination" ref="159677712"/> - </object> - <int key="connectionID">424</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">modifyFont:</string> - <reference key="source" ref="755631768"/> - <reference key="destination" ref="158063935"/> - </object> - <int key="connectionID">425</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">raiseBaseline:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="941806246"/> - </object> - <int key="connectionID">426</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">lowerBaseline:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="1045724900"/> - </object> - <int key="connectionID">427</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">copyFont:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="596732606"/> - </object> - <int key="connectionID">428</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">subscript:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="1037576581"/> - </object> - <int key="connectionID">429</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">superscript:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="644725453"/> - </object> - <int key="connectionID">430</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">tightenKerning:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="677519740"/> - </object> - <int key="connectionID">431</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">underline:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="330926929"/> - </object> - <int key="connectionID">432</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">orderFrontColorPanel:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="1012600125"/> - </object> - <int key="connectionID">433</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">useAllLigatures:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="663508465"/> - </object> - <int key="connectionID">434</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">loosenKerning:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="238351151"/> - </object> - <int key="connectionID">435</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">pasteFont:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="393423671"/> - </object> - <int key="connectionID">436</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">unscript:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="257962622"/> - </object> - <int key="connectionID">437</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">useStandardKerning:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="252969304"/> - </object> - <int key="connectionID">438</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">useStandardLigatures:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="706297211"/> - </object> - <int key="connectionID">439</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">turnOffLigatures:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="568384683"/> - </object> - <int key="connectionID">440</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">turnOffKerning:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="766922938"/> - </object> - <int key="connectionID">441</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">alignLeft:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="135107054"/> - </object> - <int key="connectionID">442</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">alignJustified:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="436088763"/> - </object> - <int key="connectionID">443</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">copyRuler:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="479856769"/> - </object> - <int key="connectionID">444</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">alignCenter:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="310547522"/> - </object> - <int key="connectionID">445</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">toggleRuler:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="420564933"/> - </object> - <int key="connectionID">446</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">alignRight:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="498119243"/> - </object> - <int key="connectionID">447</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">pasteRuler:</string> - <reference key="source" ref="1014"/> - <reference key="destination" ref="333628178"/> - </object> - <int key="connectionID">448</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">terminate:</string> - <reference key="source" ref="1050"/> - <reference key="destination" ref="632727374"/> - </object> - <int key="connectionID">449</int> - </object> - </object> - <object class="IBMutableOrderedSet" key="objectRecords"> - <object class="NSArray" key="orderedObjects"> - <bool key="EncodedWithXMLCoder">YES</bool> - <object class="IBObjectRecord"> - <int key="objectID">0</int> - <object class="NSArray" key="object" id="1049"> - <bool key="EncodedWithXMLCoder">YES</bool> - </object> - <reference key="children" ref="1048"/> - <nil key="parent"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">-2</int> - <reference key="object" ref="1021"/> - <reference key="parent" ref="1049"/> - <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">-1</int> - <reference key="object" ref="1014"/> - <reference key="parent" ref="1049"/> - <string key="objectName">First Responder</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">-3</int> - <reference key="object" ref="1050"/> - <reference key="parent" ref="1049"/> - <string key="objectName">Application</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">29</int> - <reference key="object" ref="649796088"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="713487014"/> - <reference ref="694149608"/> - <reference ref="391199113"/> - <reference ref="952259628"/> - <reference ref="379814623"/> - <reference ref="586577488"/> - <reference ref="302598603"/> - </object> - <reference key="parent" ref="1049"/> - <string key="objectName">MainMenu</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">19</int> - <reference key="object" ref="713487014"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="835318025"/> - </object> - <reference key="parent" ref="649796088"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">56</int> - <reference key="object" ref="694149608"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="110575045"/> - </object> - <reference key="parent" ref="649796088"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">103</int> - <reference key="object" ref="391199113"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="374024848"/> - </object> - <reference key="parent" ref="649796088"/> - <string key="objectName">1</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">217</int> - <reference key="object" ref="952259628"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="789758025"/> - </object> - <reference key="parent" ref="649796088"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">83</int> - <reference key="object" ref="379814623"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="720053764"/> - </object> - <reference key="parent" ref="649796088"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">81</int> - <reference key="object" ref="720053764"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="1023925487"/> - <reference ref="117038363"/> - <reference ref="49223823"/> - <reference ref="722745758"/> - <reference ref="705341025"/> - <reference ref="1025936716"/> - <reference ref="294629803"/> - <reference ref="776162233"/> - <reference ref="425164168"/> - <reference ref="579971712"/> - <reference ref="1010469920"/> - </object> - <reference key="parent" ref="379814623"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">75</int> - <reference key="object" ref="1023925487"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">3</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">80</int> - <reference key="object" ref="117038363"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">8</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">78</int> - <reference key="object" ref="49223823"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">6</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">72</int> - <reference key="object" ref="722745758"/> - <reference key="parent" ref="720053764"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">82</int> - <reference key="object" ref="705341025"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">9</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">124</int> - <reference key="object" ref="1025936716"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="1065607017"/> - </object> - <reference key="parent" ref="720053764"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">77</int> - <reference key="object" ref="294629803"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">5</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">73</int> - <reference key="object" ref="776162233"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">1</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">79</int> - <reference key="object" ref="425164168"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">7</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">112</int> - <reference key="object" ref="579971712"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">10</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">74</int> - <reference key="object" ref="1010469920"/> - <reference key="parent" ref="720053764"/> - <string key="objectName">2</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">125</int> - <reference key="object" ref="1065607017"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="759406840"/> - </object> - <reference key="parent" ref="1025936716"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">126</int> - <reference key="object" ref="759406840"/> - <reference key="parent" ref="1065607017"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">205</int> - <reference key="object" ref="789758025"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="437104165"/> - <reference ref="583158037"/> - <reference ref="1058277027"/> - <reference ref="212016141"/> - <reference ref="296257095"/> - <reference ref="29853731"/> - <reference ref="860595796"/> - <reference ref="1040322652"/> - <reference ref="790794224"/> - <reference ref="892235320"/> - <reference ref="972420730"/> - <reference ref="676164635"/> - <reference ref="507821607"/> - </object> - <reference key="parent" ref="952259628"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">202</int> - <reference key="object" ref="437104165"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">198</int> - <reference key="object" ref="583158037"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">207</int> - <reference key="object" ref="1058277027"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">214</int> - <reference key="object" ref="212016141"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">199</int> - <reference key="object" ref="296257095"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">203</int> - <reference key="object" ref="29853731"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">197</int> - <reference key="object" ref="860595796"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">206</int> - <reference key="object" ref="1040322652"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">215</int> - <reference key="object" ref="790794224"/> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">218</int> - <reference key="object" ref="892235320"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="963351320"/> - </object> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">216</int> - <reference key="object" ref="972420730"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="769623530"/> - </object> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">200</int> - <reference key="object" ref="769623530"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="948374510"/> - <reference ref="96193923"/> - <reference ref="679648819"/> - <reference ref="967646866"/> - </object> - <reference key="parent" ref="972420730"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">219</int> - <reference key="object" ref="948374510"/> - <reference key="parent" ref="769623530"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">201</int> - <reference key="object" ref="96193923"/> - <reference key="parent" ref="769623530"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">204</int> - <reference key="object" ref="679648819"/> - <reference key="parent" ref="769623530"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">220</int> - <reference key="object" ref="963351320"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="270902937"/> - <reference ref="88285865"/> - <reference ref="159080638"/> - <reference ref="326711663"/> - <reference ref="447796847"/> - </object> - <reference key="parent" ref="892235320"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">213</int> - <reference key="object" ref="270902937"/> - <reference key="parent" ref="963351320"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">210</int> - <reference key="object" ref="88285865"/> - <reference key="parent" ref="963351320"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">221</int> - <reference key="object" ref="159080638"/> - <reference key="parent" ref="963351320"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">208</int> - <reference key="object" ref="326711663"/> - <reference key="parent" ref="963351320"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">209</int> - <reference key="object" ref="447796847"/> - <reference key="parent" ref="963351320"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">106</int> - <reference key="object" ref="374024848"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="238773614"/> - </object> - <reference key="parent" ref="391199113"/> - <string key="objectName">2</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">111</int> - <reference key="object" ref="238773614"/> - <reference key="parent" ref="374024848"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">57</int> - <reference key="object" ref="110575045"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="238522557"/> - <reference ref="755159360"/> - <reference ref="908899353"/> - <reference ref="632727374"/> - <reference ref="646227648"/> - <reference ref="609285721"/> - <reference ref="481834944"/> - <reference ref="304266470"/> - <reference ref="1046388886"/> - <reference ref="1056857174"/> - <reference ref="342932134"/> - </object> - <reference key="parent" ref="694149608"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">58</int> - <reference key="object" ref="238522557"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">134</int> - <reference key="object" ref="755159360"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">150</int> - <reference key="object" ref="908899353"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">136</int> - <reference key="object" ref="632727374"/> - <reference key="parent" ref="110575045"/> - <string key="objectName">1111</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">144</int> - <reference key="object" ref="646227648"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">129</int> - <reference key="object" ref="609285721"/> - <reference key="parent" ref="110575045"/> - <string key="objectName">121</string> - </object> - <object class="IBObjectRecord"> - <int key="objectID">143</int> - <reference key="object" ref="481834944"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">236</int> - <reference key="object" ref="304266470"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">131</int> - <reference key="object" ref="1046388886"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="752062318"/> - </object> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">149</int> - <reference key="object" ref="1056857174"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">145</int> - <reference key="object" ref="342932134"/> - <reference key="parent" ref="110575045"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">130</int> - <reference key="object" ref="752062318"/> - <reference key="parent" ref="1046388886"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">24</int> - <reference key="object" ref="835318025"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="299356726"/> - <reference ref="625202149"/> - <reference ref="575023229"/> - <reference ref="1011231497"/> - </object> - <reference key="parent" ref="713487014"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">92</int> - <reference key="object" ref="299356726"/> - <reference key="parent" ref="835318025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">5</int> - <reference key="object" ref="625202149"/> - <reference key="parent" ref="835318025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">239</int> - <reference key="object" ref="575023229"/> - <reference key="parent" ref="835318025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">23</int> - <reference key="object" ref="1011231497"/> - <reference key="parent" ref="835318025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">295</int> - <reference key="object" ref="586577488"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="466310130"/> - </object> - <reference key="parent" ref="649796088"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">296</int> - <reference key="object" ref="466310130"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="102151532"/> - <reference ref="237841660"/> - </object> - <reference key="parent" ref="586577488"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">297</int> - <reference key="object" ref="102151532"/> - <reference key="parent" ref="466310130"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">298</int> - <reference key="object" ref="237841660"/> - <reference key="parent" ref="466310130"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">211</int> - <reference key="object" ref="676164635"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="785027613"/> - </object> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">212</int> - <reference key="object" ref="785027613"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="680220178"/> - <reference ref="731782645"/> - </object> - <reference key="parent" ref="676164635"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">195</int> - <reference key="object" ref="680220178"/> - <reference key="parent" ref="785027613"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">196</int> - <reference key="object" ref="731782645"/> - <reference key="parent" ref="785027613"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">346</int> - <reference key="object" ref="967646866"/> - <reference key="parent" ref="769623530"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">348</int> - <reference key="object" ref="507821607"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="698887838"/> - </object> - <reference key="parent" ref="789758025"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">349</int> - <reference key="object" ref="698887838"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="605118523"/> - <reference ref="197661976"/> - <reference ref="708854459"/> - </object> - <reference key="parent" ref="507821607"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">350</int> - <reference key="object" ref="605118523"/> - <reference key="parent" ref="698887838"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">351</int> - <reference key="object" ref="197661976"/> - <reference key="parent" ref="698887838"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">354</int> - <reference key="object" ref="708854459"/> - <reference key="parent" ref="698887838"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">375</int> - <reference key="object" ref="302598603"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="941447902"/> - </object> - <reference key="parent" ref="649796088"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">376</int> - <reference key="object" ref="941447902"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="792887677"/> - <reference ref="15516124"/> - </object> - <reference key="parent" ref="302598603"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">377</int> - <reference key="object" ref="792887677"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="786677654"/> - </object> - <reference key="parent" ref="941447902"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">378</int> - <reference key="object" ref="15516124"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="23081656"/> - </object> - <reference key="parent" ref="941447902"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">379</int> - <reference key="object" ref="23081656"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="135107054"/> - <reference ref="310547522"/> - <reference ref="436088763"/> - <reference ref="498119243"/> - <reference ref="607995063"/> - <reference ref="420564933"/> - <reference ref="479856769"/> - <reference ref="333628178"/> - </object> - <reference key="parent" ref="15516124"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">380</int> - <reference key="object" ref="135107054"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">381</int> - <reference key="object" ref="310547522"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">382</int> - <reference key="object" ref="436088763"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">383</int> - <reference key="object" ref="498119243"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">384</int> - <reference key="object" ref="607995063"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">385</int> - <reference key="object" ref="420564933"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">386</int> - <reference key="object" ref="479856769"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">387</int> - <reference key="object" ref="333628178"/> - <reference key="parent" ref="23081656"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">388</int> - <reference key="object" ref="786677654"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="159677712"/> - <reference ref="305399458"/> - <reference ref="814362025"/> - <reference ref="330926929"/> - <reference ref="533507878"/> - <reference ref="158063935"/> - <reference ref="885547335"/> - <reference ref="901062459"/> - <reference ref="767671776"/> - <reference ref="691570813"/> - <reference ref="769124883"/> - <reference ref="739652853"/> - <reference ref="1012600125"/> - <reference ref="214559597"/> - <reference ref="596732606"/> - <reference ref="393423671"/> - </object> - <reference key="parent" ref="792887677"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">389</int> - <reference key="object" ref="159677712"/> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">390</int> - <reference key="object" ref="305399458"/> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">391</int> - <reference key="object" ref="814362025"/> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">392</int> - <reference key="object" ref="330926929"/> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">393</int> - <reference key="object" ref="533507878"/> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">394</int> - <reference key="object" ref="158063935"/> - <reference key="parent" ref="786677654"/> + </object> + <string key="NSName">_NSMainMenu</string> + </object> + <object class="NSCustomObject" id="16040424"> + <string key="NSClassName">MainController</string> + </object> + </object> + <object class="IBObjectContainer" key="IBDocument.Objects"> + <object class="NSMutableArray" key="connectionRecords"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">orderFrontStandardAboutPanel:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="238522557"/> </object> - <object class="IBObjectRecord"> - <int key="objectID">395</int> - <reference key="object" ref="885547335"/> - <reference key="parent" ref="786677654"/> + <int key="connectionID">142</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">hide:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="755159360"/> </object> - <object class="IBObjectRecord"> - <int key="objectID">396</int> - <reference key="object" ref="901062459"/> - <reference key="parent" ref="786677654"/> + <int key="connectionID">367</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">hideOtherApplications:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="342932134"/> </object> - <object class="IBObjectRecord"> - <int key="objectID">397</int> - <reference key="object" ref="767671776"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="175441468"/> - </object> - <reference key="parent" ref="786677654"/> + <int key="connectionID">368</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">unhideAllApplications:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="908899353"/> </object> - <object class="IBObjectRecord"> - <int key="objectID">398</int> - <reference key="object" ref="691570813"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="1058217995"/> - </object> - <reference key="parent" ref="786677654"/> + <int key="connectionID">370</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">terminate:</string> + <reference key="source" ref="1050"/> + <reference key="destination" ref="632727374"/> </object> + <int key="connectionID">449</int> + </object> + </object> + <object class="IBMutableOrderedSet" key="objectRecords"> + <object class="NSArray" key="orderedObjects"> + <bool key="EncodedWithXMLCoder">YES</bool> <object class="IBObjectRecord"> - <int key="objectID">399</int> - <reference key="object" ref="769124883"/> - <object class="NSMutableArray" key="children"> + <int key="objectID">0</int> + <object class="NSArray" key="object" id="1049"> <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="18263474"/> </object> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">400</int> - <reference key="object" ref="739652853"/> - <reference key="parent" ref="786677654"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">401</int> - <reference key="object" ref="1012600125"/> - <reference key="parent" ref="786677654"/> + <reference key="children" ref="1048"/> + <nil key="parent"/> </object> <object class="IBObjectRecord"> - <int key="objectID">402</int> - <reference key="object" ref="214559597"/> - <reference key="parent" ref="786677654"/> + <int key="objectID">-2</int> + <reference key="object" ref="1021"/> + <reference key="parent" ref="1049"/> + <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string> </object> <object class="IBObjectRecord"> - <int key="objectID">403</int> - <reference key="object" ref="596732606"/> - <reference key="parent" ref="786677654"/> + <int key="objectID">-1</int> + <reference key="object" ref="1014"/> + <reference key="parent" ref="1049"/> + <string key="objectName">First Responder</string> </object> <object class="IBObjectRecord"> - <int key="objectID">404</int> - <reference key="object" ref="393423671"/> - <reference key="parent" ref="786677654"/> + <int key="objectID">-3</int> + <reference key="object" ref="1050"/> + <reference key="parent" ref="1049"/> + <string key="objectName">Application</string> </object> <object class="IBObjectRecord"> - <int key="objectID">405</int> - <reference key="object" ref="18263474"/> + <int key="objectID">29</int> + <reference key="object" ref="649796088"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="257962622"/> - <reference ref="644725453"/> - <reference ref="1037576581"/> - <reference ref="941806246"/> - <reference ref="1045724900"/> + <reference ref="694149608"/> </object> - <reference key="parent" ref="769124883"/> + <reference key="parent" ref="1049"/> + <string key="objectName">MainMenu</string> </object> <object class="IBObjectRecord"> - <int key="objectID">406</int> - <reference key="object" ref="257962622"/> - <reference key="parent" ref="18263474"/> + <int key="objectID">458</int> + <reference key="object" ref="16040424"/> + <reference key="parent" ref="1049"/> </object> <object class="IBObjectRecord"> - <int key="objectID">407</int> - <reference key="object" ref="644725453"/> - <reference key="parent" ref="18263474"/> + <int key="objectID">56</int> + <reference key="object" ref="694149608"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="110575045"/> + </object> + <reference key="parent" ref="649796088"/> </object> <object class="IBObjectRecord"> - <int key="objectID">408</int> - <reference key="object" ref="1037576581"/> - <reference key="parent" ref="18263474"/> + <int key="objectID">57</int> + <reference key="object" ref="110575045"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="342932134"/> + <reference ref="1056857174"/> + <reference ref="1046388886"/> + <reference ref="304266470"/> + <reference ref="481834944"/> + <reference ref="609285721"/> + <reference ref="646227648"/> + <reference ref="632727374"/> + <reference ref="908899353"/> + <reference ref="755159360"/> + <reference ref="238522557"/> + </object> + <reference key="parent" ref="694149608"/> </object> <object class="IBObjectRecord"> - <int key="objectID">409</int> - <reference key="object" ref="941806246"/> - <reference key="parent" ref="18263474"/> + <int key="objectID">145</int> + <reference key="object" ref="342932134"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">410</int> - <reference key="object" ref="1045724900"/> - <reference key="parent" ref="18263474"/> + <int key="objectID">149</int> + <reference key="object" ref="1056857174"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">411</int> - <reference key="object" ref="1058217995"/> + <int key="objectID">131</int> + <reference key="object" ref="1046388886"/> <object class="NSMutableArray" key="children"> <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="706297211"/> - <reference ref="568384683"/> - <reference ref="663508465"/> + <reference ref="752062318"/> </object> - <reference key="parent" ref="691570813"/> - </object> - <object class="IBObjectRecord"> - <int key="objectID">412</int> - <reference key="object" ref="706297211"/> - <reference key="parent" ref="1058217995"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">413</int> - <reference key="object" ref="568384683"/> - <reference key="parent" ref="1058217995"/> + <int key="objectID">130</int> + <reference key="object" ref="752062318"/> + <reference key="parent" ref="1046388886"/> </object> <object class="IBObjectRecord"> - <int key="objectID">414</int> - <reference key="object" ref="663508465"/> - <reference key="parent" ref="1058217995"/> + <int key="objectID">236</int> + <reference key="object" ref="304266470"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">415</int> - <reference key="object" ref="175441468"/> - <object class="NSMutableArray" key="children"> - <bool key="EncodedWithXMLCoder">YES</bool> - <reference ref="252969304"/> - <reference ref="766922938"/> - <reference ref="677519740"/> - <reference ref="238351151"/> - </object> - <reference key="parent" ref="767671776"/> + <int key="objectID">143</int> + <reference key="object" ref="481834944"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">416</int> - <reference key="object" ref="252969304"/> - <reference key="parent" ref="175441468"/> + <int key="objectID">129</int> + <reference key="object" ref="609285721"/> + <reference key="parent" ref="110575045"/> + <string key="objectName">121</string> </object> <object class="IBObjectRecord"> - <int key="objectID">417</int> - <reference key="object" ref="766922938"/> - <reference key="parent" ref="175441468"/> + <int key="objectID">144</int> + <reference key="object" ref="646227648"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">418</int> - <reference key="object" ref="677519740"/> - <reference key="parent" ref="175441468"/> + <int key="objectID">136</int> + <reference key="object" ref="632727374"/> + <reference key="parent" ref="110575045"/> + <string key="objectName">1111</string> </object> <object class="IBObjectRecord"> - <int key="objectID">419</int> - <reference key="object" ref="238351151"/> - <reference key="parent" ref="175441468"/> + <int key="objectID">150</int> + <reference key="object" ref="908899353"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">420</int> - <reference key="object" ref="755631768"/> - <reference key="parent" ref="1049"/> + <int key="objectID">134</int> + <reference key="object" ref="755159360"/> + <reference key="parent" ref="110575045"/> </object> <object class="IBObjectRecord"> - <int key="objectID">458</int> - <reference key="object" ref="16040424"/> - <reference key="parent" ref="1049"/> + <int key="objectID">58</int> + <reference key="object" ref="238522557"/> + <reference key="parent" ref="110575045"/> </object> </object> </object> @@ -2544,22 +374,6 @@ <string>-1.IBPluginDependency</string> <string>-2.IBPluginDependency</string> <string>-3.IBPluginDependency</string> - <string>103.IBPluginDependency</string> - <string>103.ImportedFromIB2</string> - <string>106.IBPluginDependency</string> - <string>106.ImportedFromIB2</string> - <string>106.editorWindowContentRectSynchronizationRect</string> - <string>111.IBPluginDependency</string> - <string>111.ImportedFromIB2</string> - <string>112.IBPluginDependency</string> - <string>112.ImportedFromIB2</string> - <string>124.IBPluginDependency</string> - <string>124.ImportedFromIB2</string> - <string>125.IBPluginDependency</string> - <string>125.ImportedFromIB2</string> - <string>125.editorWindowContentRectSynchronizationRect</string> - <string>126.IBPluginDependency</string> - <string>126.ImportedFromIB2</string> <string>129.IBPluginDependency</string> <string>129.ImportedFromIB2</string> <string>130.IBPluginDependency</string> @@ -2581,150 +395,14 @@ <string>149.ImportedFromIB2</string> <string>150.IBPluginDependency</string> <string>150.ImportedFromIB2</string> - <string>19.IBPluginDependency</string> - <string>19.ImportedFromIB2</string> - <string>195.IBPluginDependency</string> - <string>195.ImportedFromIB2</string> - <string>196.IBPluginDependency</string> - <string>196.ImportedFromIB2</string> - <string>197.IBPluginDependency</string> - <string>197.ImportedFromIB2</string> - <string>198.IBPluginDependency</string> - <string>198.ImportedFromIB2</string> - <string>199.IBPluginDependency</string> - <string>199.ImportedFromIB2</string> - <string>200.IBPluginDependency</string> - <string>200.ImportedFromIB2</string> - <string>200.editorWindowContentRectSynchronizationRect</string> - <string>201.IBPluginDependency</string> - <string>201.ImportedFromIB2</string> - <string>202.IBPluginDependency</string> - <string>202.ImportedFromIB2</string> - <string>203.IBPluginDependency</string> - <string>203.ImportedFromIB2</string> - <string>204.IBPluginDependency</string> - <string>204.ImportedFromIB2</string> - <string>205.IBEditorWindowLastContentRect</string> - <string>205.IBPluginDependency</string> - <string>205.ImportedFromIB2</string> - <string>205.editorWindowContentRectSynchronizationRect</string> - <string>206.IBPluginDependency</string> - <string>206.ImportedFromIB2</string> - <string>207.IBPluginDependency</string> - <string>207.ImportedFromIB2</string> - <string>208.IBPluginDependency</string> - <string>208.ImportedFromIB2</string> - <string>209.IBPluginDependency</string> - <string>209.ImportedFromIB2</string> - <string>210.IBPluginDependency</string> - <string>210.ImportedFromIB2</string> - <string>211.IBPluginDependency</string> - <string>211.ImportedFromIB2</string> - <string>212.IBPluginDependency</string> - <string>212.ImportedFromIB2</string> - <string>212.editorWindowContentRectSynchronizationRect</string> - <string>213.IBPluginDependency</string> - <string>213.ImportedFromIB2</string> - <string>214.IBPluginDependency</string> - <string>214.ImportedFromIB2</string> - <string>215.IBPluginDependency</string> - <string>215.ImportedFromIB2</string> - <string>216.IBPluginDependency</string> - <string>216.ImportedFromIB2</string> - <string>217.IBPluginDependency</string> - <string>217.ImportedFromIB2</string> - <string>218.IBPluginDependency</string> - <string>218.ImportedFromIB2</string> - <string>219.IBPluginDependency</string> - <string>219.ImportedFromIB2</string> - <string>220.IBPluginDependency</string> - <string>220.ImportedFromIB2</string> - <string>220.editorWindowContentRectSynchronizationRect</string> - <string>221.IBPluginDependency</string> - <string>221.ImportedFromIB2</string> - <string>23.IBPluginDependency</string> - <string>23.ImportedFromIB2</string> <string>236.IBPluginDependency</string> <string>236.ImportedFromIB2</string> - <string>239.IBPluginDependency</string> - <string>239.ImportedFromIB2</string> - <string>24.IBPluginDependency</string> - <string>24.ImportedFromIB2</string> - <string>24.editorWindowContentRectSynchronizationRect</string> <string>29.IBEditorWindowLastContentRect</string> <string>29.IBPluginDependency</string> <string>29.ImportedFromIB2</string> <string>29.WindowOrigin</string> <string>29.editorWindowContentRectSynchronizationRect</string> - <string>295.IBPluginDependency</string> - <string>296.IBPluginDependency</string> - <string>296.editorWindowContentRectSynchronizationRect</string> - <string>297.IBPluginDependency</string> - <string>298.IBPluginDependency</string> - <string>346.IBPluginDependency</string> - <string>346.ImportedFromIB2</string> - <string>348.IBPluginDependency</string> - <string>348.ImportedFromIB2</string> - <string>349.IBPluginDependency</string> - <string>349.ImportedFromIB2</string> - <string>349.editorWindowContentRectSynchronizationRect</string> - <string>350.IBPluginDependency</string> - <string>350.ImportedFromIB2</string> - <string>351.IBPluginDependency</string> - <string>351.ImportedFromIB2</string> - <string>354.IBPluginDependency</string> - <string>354.ImportedFromIB2</string> - <string>375.IBPluginDependency</string> - <string>376.IBEditorWindowLastContentRect</string> - <string>376.IBPluginDependency</string> - <string>377.IBPluginDependency</string> - <string>378.IBPluginDependency</string> - <string>379.IBPluginDependency</string> - <string>380.IBPluginDependency</string> - <string>381.IBPluginDependency</string> - <string>382.IBPluginDependency</string> - <string>383.IBPluginDependency</string> - <string>384.IBPluginDependency</string> - <string>385.IBPluginDependency</string> - <string>386.IBPluginDependency</string> - <string>387.IBPluginDependency</string> - <string>388.IBEditorWindowLastContentRect</string> - <string>388.IBPluginDependency</string> - <string>389.IBPluginDependency</string> - <string>390.IBPluginDependency</string> - <string>391.IBPluginDependency</string> - <string>392.IBPluginDependency</string> - <string>393.IBPluginDependency</string> - <string>394.IBPluginDependency</string> - <string>395.IBPluginDependency</string> - <string>396.IBPluginDependency</string> - <string>397.IBPluginDependency</string> - <string>398.IBPluginDependency</string> - <string>399.IBPluginDependency</string> - <string>400.IBPluginDependency</string> - <string>401.IBPluginDependency</string> - <string>402.IBPluginDependency</string> - <string>403.IBPluginDependency</string> - <string>404.IBPluginDependency</string> - <string>405.IBPluginDependency</string> - <string>406.IBPluginDependency</string> - <string>407.IBPluginDependency</string> - <string>408.IBPluginDependency</string> - <string>409.IBPluginDependency</string> - <string>410.IBPluginDependency</string> - <string>411.IBPluginDependency</string> - <string>412.IBPluginDependency</string> - <string>413.IBPluginDependency</string> - <string>414.IBPluginDependency</string> - <string>415.IBPluginDependency</string> - <string>416.IBPluginDependency</string> - <string>417.IBPluginDependency</string> - <string>418.IBPluginDependency</string> - <string>419.IBPluginDependency</string> - <string>420.IBPluginDependency</string> <string>458.IBPluginDependency</string> - <string>5.IBPluginDependency</string> - <string>5.ImportedFromIB2</string> <string>56.IBPluginDependency</string> <string>56.ImportedFromIB2</string> <string>57.IBEditorWindowLastContentRect</string> @@ -2733,32 +411,6 @@ <string>57.editorWindowContentRectSynchronizationRect</string> <string>58.IBPluginDependency</string> <string>58.ImportedFromIB2</string> - <string>72.IBPluginDependency</string> - <string>72.ImportedFromIB2</string> - <string>73.IBPluginDependency</string> - <string>73.ImportedFromIB2</string> - <string>74.IBPluginDependency</string> - <string>74.ImportedFromIB2</string> - <string>75.IBPluginDependency</string> - <string>75.ImportedFromIB2</string> - <string>77.IBPluginDependency</string> - <string>77.ImportedFromIB2</string> - <string>78.IBPluginDependency</string> - <string>78.ImportedFromIB2</string> - <string>79.IBPluginDependency</string> - <string>79.ImportedFromIB2</string> - <string>80.IBPluginDependency</string> - <string>80.ImportedFromIB2</string> - <string>81.IBEditorWindowLastContentRect</string> - <string>81.IBPluginDependency</string> - <string>81.ImportedFromIB2</string> - <string>81.editorWindowContentRectSynchronizationRect</string> - <string>82.IBPluginDependency</string> - <string>82.ImportedFromIB2</string> - <string>83.IBPluginDependency</string> - <string>83.ImportedFromIB2</string> - <string>92.IBPluginDependency</string> - <string>92.ImportedFromIB2</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -2769,22 +421,6 @@ <integer value="1" id="9"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> - <string>{{596, 852}, {216, 23}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{522, 812}, {146, 23}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> <string>{{436, 809}, {64, 6}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> @@ -2804,182 +440,20 @@ <reference ref="9"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{608, 612}, {275, 83}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{492, 116}, {243, 243}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{187, 434}, {243, 243}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{608, 612}, {167, 43}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{608, 612}, {241, 103}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{525, 802}, {197, 73}}</string> - <string>{{306, 359}, {478, 20}}</string> + <string>{{306, 359}, {97, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>{74, 862}</string> <string>{{6, 978}, {478, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{475, 832}, {234, 43}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{608, 612}, {215, 63}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{437, 242}, {86, 43}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{523, 2}, {178, 283}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> - <string>{{318, 176}, {245, 183}}</string> + <string>{{318, 176}, {190, 183}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>{{23, 794}, {245, 183}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{450, 156}, {199, 203}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>{{145, 474}, {199, 203}}</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <reference ref="9"/> </object> </object> <object class="NSMutableDictionary" key="unlocalizedProperties"> -- cgit v0.10.2-6-g49f6 From ef4284acb29aca0bdf792ab40356c7955902e307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 24 Jul 2009 21:28:19 +0200 Subject: LinkLocal: Publish->Register. diff --git a/Swiften/LinkLocal/BonjourPublishQuery.h b/Swiften/LinkLocal/BonjourPublishQuery.h deleted file mode 100644 index a96e25a..0000000 --- a/Swiften/LinkLocal/BonjourPublishQuery.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "Swiften/LinkLocal/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSDPublishQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/MainEventLoop.h" - -namespace Swift { - class BonjourQuerier; - - class BonjourPublishQuery : public DNSSDPublishQuery, public BonjourQuery { - public: - BonjourPublishQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { - ByteArray txtRecord = info.toTXTRecord(); - DNSServiceErrorType result = DNSServiceRegister( - &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, - txtRecord.getSize(), txtRecord.getData(), - &BonjourPublishQuery::handleServicePublishedStatic, this); - if (result != kDNSServiceErr_NoError) { - // TODO - std::cerr << "Error creating service registration" << std::endl; - } - } - - void publish() { - run(); - } - - void update(const LinkLocalService& info) { - boost::lock_guard<boost::mutex> lock(sdRefMutex); - ByteArray txtRecord = info.toTXTRecord(); - DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); - } - - private: - static void handleServicePublishedStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { - static_cast<BonjourPublishQuery*>(context)->handleServicePublished(errorCode, name, regtype, domain); - } - - void handleServicePublished(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { - if (errorCode != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onPublishFinished), boost::optional<LinkLocalServiceID>()), shared_from_this()); - } - else { - MainEventLoop::postEvent(boost::bind(boost::ref(onPublishFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this()); - } - } - }; -} diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp index 3080869..7764f51 100644 --- a/Swiften/LinkLocal/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/BonjourQuerier.cpp @@ -6,7 +6,7 @@ #include <fcntl.h> #include "Swiften/LinkLocal/BonjourBrowseQuery.h" -#include "Swiften/LinkLocal/BonjourPublishQuery.h" +#include "Swiften/LinkLocal/BonjourRegisterQuery.h" #include "Swiften/Base/foreach.h" namespace Swift { @@ -28,8 +28,8 @@ boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this())); } -boost::shared_ptr<DNSSDPublishQuery> BonjourQuerier::createPublishQuery(const String& name, int port, const LinkLocalServiceInfo& info) { - return boost::shared_ptr<DNSSDPublishQuery>(new BonjourPublishQuery(name, port, info, shared_from_this())); +boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) { + return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); } void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h index e5ffa49..a35483c 100644 --- a/Swiften/LinkLocal/BonjourQuerier.h +++ b/Swiften/LinkLocal/BonjourQuerier.h @@ -7,7 +7,7 @@ #include <boost/thread/mutex.hpp> #include "Swiften/LinkLocal/DNSSDBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSDPublishQuery.h" +#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" #include "Swiften/LinkLocal/BonjourQuery.h" namespace Swift { @@ -19,7 +19,7 @@ namespace Swift { ~BonjourQuerier(); boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); - boost::shared_ptr<DNSSDPublishQuery> createPublishQuery(const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info); void start(); void stop(); diff --git a/Swiften/LinkLocal/BonjourRegisterQuery.h b/Swiften/LinkLocal/BonjourRegisterQuery.h new file mode 100644 index 0000000..c34ba02 --- /dev/null +++ b/Swiften/LinkLocal/BonjourRegisterQuery.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Swiften/LinkLocal/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/EventLoop/MainEventLoop.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery { + public: + BonjourRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceErrorType result = DNSServiceRegister( + &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, + txtRecord.getSize(), txtRecord.getData(), + &BonjourRegisterQuery::handleServiceRegisteredStatic, this); + if (result != kDNSServiceErr_NoError) { + // TODO + std::cerr << "Error creating service registration" << std::endl; + } + } + + void registerService() { + run(); + } + + void updateServiceInfo(const LinkLocalServiceInfo& info) { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); + } + + private: + static void handleServiceRegisteredStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { + static_cast<BonjourRegisterQuery*>(context)->handleServiceRegistered(errorCode, name, regtype, domain); + } + + void handleServiceRegistered(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { + if (errorCode != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>()), shared_from_this()); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSDPublishQuery.cpp b/Swiften/LinkLocal/DNSSDPublishQuery.cpp deleted file mode 100644 index cf3fd25..0000000 --- a/Swiften/LinkLocal/DNSSDPublishQuery.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDPublishQuery.h" - -namespace Swift { - -DNSSDPublishQuery::~DNSSDPublishQuery() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDPublishQuery.h b/Swiften/LinkLocal/DNSSDPublishQuery.h deleted file mode 100644 index 48c86dc..0000000 --- a/Swiften/LinkLocal/DNSSDPublishQuery.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include <boost/signal.hpp> -#include <boost/optional.hpp> - -#include "Swiften/LinkLocal/LinkLocalServiceID.h" - -namespace Swift { - class DNSSDPublishQuery { - public: - virtual ~DNSSDPublishQuery(); - - virtual void publish() = 0; - - boost::signal<void (boost::optional<LinkLocalServiceID>)> onPublishFinished; - }; -} diff --git a/Swiften/LinkLocal/DNSSDRegisterQuery.cpp b/Swiften/LinkLocal/DNSSDRegisterQuery.cpp new file mode 100644 index 0000000..fe00b02 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDRegisterQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" + +namespace Swift { + +DNSSDRegisterQuery::~DNSSDRegisterQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSDRegisterQuery.h new file mode 100644 index 0000000..252fbf0 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDRegisterQuery.h @@ -0,0 +1,20 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" + +namespace Swift { + class LinkLocalServiceInfo; + + class DNSSDRegisterQuery { + public: + virtual ~DNSSDRegisterQuery(); + + virtual void registerService() = 0; + virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0; + + boost::signal<void (boost::optional<LinkLocalServiceID>)> onRegisterFinished; + }; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 902fa7a..a3144ac 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,6 +1,6 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/DNSSDBrowseQuery.cpp \ - Swiften/LinkLocal/DNSSDPublishQuery.cpp \ + Swiften/LinkLocal/DNSSDRegisterQuery.cpp \ Swiften/LinkLocal/DNSSDServiceFactory.cpp \ Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ diff --git a/configure.in b/configure.in index 186bc3c..80e69c0 100644 --- a/configure.in +++ b/configure.in @@ -202,6 +202,7 @@ case $host in *-mingw32*) ;; *-*-darwin*) + HAVE_BONJOUR=yes AC_DEFINE(HAVE_BONJOUR) ;; *) -- cgit v0.10.2-6-g49f6 From b33a2937fe4a3cae0017892ad7f5c27b8a6f976d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 25 Jul 2009 10:35:33 +0200 Subject: Implement more DNSSD queries. diff --git a/Slimber/CLI/main.cpp b/Slimber/CLI/main.cpp index 65af3bc..3a72ca1 100644 --- a/Slimber/CLI/main.cpp +++ b/Slimber/CLI/main.cpp @@ -22,8 +22,8 @@ int main() { querier->start(); boost::shared_ptr<DNSSDBrowseQuery> query = querier->createBrowseQuery(); query->startBrowsing(); - boost::shared_ptr<DNSSDPublishQuery> query2 = querier->createPublishQuery("remko", 1234, LinkLocalServiceInfo()); - query2->publish(); + boost::shared_ptr<DNSSDRegisterQuery> query2 = querier->createRegisterQuery("remko", 1234, LinkLocalServiceInfo()); + query2->registerService(); /* boost::shared_ptr<DNSSDService> dnsSDService; diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp index 7764f51..42ba12a 100644 --- a/Swiften/LinkLocal/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/BonjourQuerier.cpp @@ -2,11 +2,12 @@ #include <unistd.h> #include <sys/socket.h> -#include <netinet/in.h> #include <fcntl.h> #include "Swiften/LinkLocal/BonjourBrowseQuery.h" #include "Swiften/LinkLocal/BonjourRegisterQuery.h" +#include "Swiften/LinkLocal/BonjourResolveServiceQuery.h" +#include "Swiften/LinkLocal/BonjourResolveHostnameQuery.h" #include "Swiften/Base/foreach.h" namespace Swift { @@ -32,6 +33,14 @@ boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); } +boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) { + return boost::shared_ptr<DNSSDResolveServiceQuery>(new BonjourResolveServiceQuery(service, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveHostnameQuery> BonjourQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) { + return boost::shared_ptr<DNSSDResolveHostnameQuery>(new BonjourResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); +} + void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { { boost::lock_guard<boost::mutex> lock(runningQueriesMutex); diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h index a35483c..324e79e 100644 --- a/Swiften/LinkLocal/BonjourQuerier.h +++ b/Swiften/LinkLocal/BonjourQuerier.h @@ -6,20 +6,26 @@ #include <boost/thread.hpp> #include <boost/thread/mutex.hpp> -#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" -#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/DNSSDQuerier.h" #include "Swiften/LinkLocal/BonjourQuery.h" namespace Swift { class LinkLocalServiceInfo; - class BonjourQuerier : public boost::enable_shared_from_this<BonjourQuerier> { + class BonjourQuerier : + public DNSSDQuerier, + public boost::enable_shared_from_this<BonjourQuerier> { public: BonjourQuerier(); ~BonjourQuerier(); boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); - boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const LinkLocalServiceID&); + boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( + const String& hostname, int interfaceIndex); void start(); void stop(); @@ -29,8 +35,6 @@ namespace Swift { void addRunningQuery(boost::shared_ptr<BonjourQuery>); void removeRunningQuery(boost::shared_ptr<BonjourQuery>); - - private: void interruptSelect(); void run(); diff --git a/Swiften/LinkLocal/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/BonjourResolveHostnameQuery.h new file mode 100644 index 0000000..771fc84 --- /dev/null +++ b/Swiften/LinkLocal/BonjourResolveHostnameQuery.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Swiften/Base/String.h" +#include "Swiften/LinkLocal/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h" +#include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/Network/HostAddress.h" + +#include <netinet/in.h> + +namespace Swift { + class BonjourQuerier; + + class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery { + public: + BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + DNSServiceErrorType result = DNSServiceGetAddrInfo( + &sdRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, + hostname.getUTF8Data(), + &BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this); + if (result != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this()); + } + } + + //void DNSSDResolveHostnameQuery::run() { + void run() { + BonjourQuery::run(); + } + + private: + static void handleHostnameResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char*, const struct sockaddr *address, uint32_t, void *context) { + static_cast<BonjourResolveHostnameQuery*>(context)->handleHostnameResolved(errorCode, address); + } + + void handleHostnameResolved(DNSServiceErrorType errorCode, const struct sockaddr *rawAddress) { + if (errorCode) { + MainEventLoop::postEvent( + boost::bind(boost::ref(onHostnameResolved), + 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), + HostAddress(reinterpret_cast<unsigned char*>(&address), 4)), + shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/BonjourResolveServiceQuery.h new file mode 100644 index 0000000..e4f02ee --- /dev/null +++ b/Swiften/LinkLocal/BonjourResolveServiceQuery.h @@ -0,0 +1,53 @@ +#pragma once + +#include "Swiften/LinkLocal/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/EventLoop/MainEventLoop.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery { + public: + BonjourResolveServiceQuery(const LinkLocalServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + DNSServiceErrorType result = DNSServiceResolve( + &sdRef, 0, service.getNetworkInterfaceID(), + service.getName().getUTF8Data(), service.getType().getUTF8Data(), + service.getDomain().getUTF8Data(), + &BonjourResolveServiceQuery::handleServiceResolvedStatic, this); + if (result != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } + } + + void start() { + run(); + } + + void stop() { + finish(); + } + + private: + static void handleServiceResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { + static_cast<BonjourResolveServiceQuery*>(context)->handleServiceResolved(errorCode, fullname, hosttarget, port, txtLen, txtRecord); + } + + void handleServiceResolved(DNSServiceErrorType errorCode, const char* fullName, const char* host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord) { + if (errorCode != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } + else { + MainEventLoop::postEvent( + boost::bind( + boost::ref(onServiceResolved), + Result(String(fullName), String(host), port, + LinkLocalServiceInfo::createFromTXTRecord( + ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), + shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSDQuerier.cpp new file mode 100644 index 0000000..be87a3c --- /dev/null +++ b/Swiften/LinkLocal/DNSSDQuerier.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDQuerier.h" + +namespace Swift { + +DNSSDQuerier::~DNSSDQuerier() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSDQuerier.h new file mode 100644 index 0000000..528a6ea --- /dev/null +++ b/Swiften/LinkLocal/DNSSDQuerier.h @@ -0,0 +1,26 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +namespace Swift { + class String; + class LinkLocalServiceInfo; + class LinkLocalServiceID; + class DNSSDBrowseQuery; + class DNSSDRegisterQuery; + class DNSSDResolveServiceQuery; + class DNSSDResolveHostnameQuery; + + class DNSSDQuerier { + public: + virtual ~DNSSDQuerier(); + + virtual boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery() = 0; + virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info) = 0; + virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const LinkLocalServiceID&) = 0; + virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( + const String& hostname, int interfaceIndex) = 0; + }; +} diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp new file mode 100644 index 0000000..f7c88bd --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h" + +namespace Swift { + +DNSSDResolveHostnameQuery::~DNSSDResolveHostnameQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h new file mode 100644 index 0000000..a2e218c --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h @@ -0,0 +1,17 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/Network/HostAddress.h" + +namespace Swift { + class DNSSDResolveHostnameQuery { + public: + virtual ~DNSSDResolveHostnameQuery(); + + virtual void run() = 0; + + boost::signal<void (const boost::optional<HostAddress>&)> onHostnameResolved; + }; +} diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp new file mode 100644 index 0000000..83a9ccd --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h" + +namespace Swift { + +DNSSDResolveServiceQuery::~DNSSDResolveServiceQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSDResolveServiceQuery.h new file mode 100644 index 0000000..d8b5cf1 --- /dev/null +++ b/Swiften/LinkLocal/DNSSDResolveServiceQuery.h @@ -0,0 +1,29 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" + +namespace Swift { + class DNSSDResolveServiceQuery { + public: + struct Result { + Result(const String& fullName, const String& host, int port, + const LinkLocalServiceInfo& info) : + fullName(fullName), host(host), port(port), info(info) {} + String fullName; + String host; + int port; + LinkLocalServiceInfo info; + }; + + virtual ~DNSSDResolveServiceQuery(); + + virtual void start() = 0; + virtual void stop() = 0; + + boost::signal<void (const boost::optional<Result>&)> onServiceResolved; + }; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index a3144ac..9522cbb 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,6 +1,9 @@ SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSDQuerier.cpp \ Swiften/LinkLocal/DNSSDBrowseQuery.cpp \ Swiften/LinkLocal/DNSSDRegisterQuery.cpp \ + Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp \ + Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp \ Swiften/LinkLocal/DNSSDServiceFactory.cpp \ Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ -- cgit v0.10.2-6-g49f6 From 0f77a684b42f25052eb1cfa688721e321526a90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 25 Jul 2009 11:37:42 +0200 Subject: Created DNSSD submodule for LinkLocal. diff --git a/Swiften/LinkLocal/BonjourBrowseQuery.h b/Swiften/LinkLocal/BonjourBrowseQuery.h deleted file mode 100644 index 6db108d..0000000 --- a/Swiften/LinkLocal/BonjourBrowseQuery.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "Swiften/LinkLocal/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" -#include "Swiften/EventLoop/MainEventLoop.h" - -namespace Swift { - class BonjourQuerier; - - class BonjourBrowseQuery : public DNSSDBrowseQuery, public BonjourQuery { - public: - BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) { - DNSServiceErrorType result = DNSServiceBrowse( - &sdRef, 0, 0, "_presence._tcp", 0, - &BonjourBrowseQuery::handleServiceDiscoveredStatic, this); - if (result != kDNSServiceErr_NoError) { - std::cout << "Error" << std::endl; - // TODO - } - } - - void startBrowsing() { - assert(sdRef); - run(); - } - - void stopBrowsing() { - finish(); - } - - private: - static void handleServiceDiscoveredStatic(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) { - static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, name, type, domain); - } - - void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) { - if (errorCode != kDNSServiceErr_NoError) { - return; - } - else { - LinkLocalServiceID service(name, type, domain, 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()); - } - } - } - }; -} diff --git a/Swiften/LinkLocal/BonjourQuerier.cpp b/Swiften/LinkLocal/BonjourQuerier.cpp deleted file mode 100644 index 42ba12a..0000000 --- a/Swiften/LinkLocal/BonjourQuerier.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include "Swiften/LinkLocal/BonjourQuerier.h" - -#include <unistd.h> -#include <sys/socket.h> -#include <fcntl.h> - -#include "Swiften/LinkLocal/BonjourBrowseQuery.h" -#include "Swiften/LinkLocal/BonjourRegisterQuery.h" -#include "Swiften/LinkLocal/BonjourResolveServiceQuery.h" -#include "Swiften/LinkLocal/BonjourResolveHostnameQuery.h" -#include "Swiften/Base/foreach.h" - -namespace Swift { - -BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(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]; -} - -BonjourQuerier::~BonjourQuerier() { - stop(); -} - -boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { - return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this())); -} - -boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) { - return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); -} - -boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) { - return boost::shared_ptr<DNSSDResolveServiceQuery>(new BonjourResolveServiceQuery(service, shared_from_this())); -} - -boost::shared_ptr<DNSSDResolveHostnameQuery> BonjourQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) { - return boost::shared_ptr<DNSSDResolveHostnameQuery>(new BonjourResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); -} - -void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { - { - boost::lock_guard<boost::mutex> lock(runningQueriesMutex); - runningQueries.push_back(query); - } - runningQueriesAvailableEvent.notify_one(); - interruptSelect(); -} - -void BonjourQuerier::removeRunningQuery(boost::shared_ptr<BonjourQuery> query) { - { - boost::lock_guard<boost::mutex> lock(runningQueriesMutex); - runningQueries.erase(std::remove( - runningQueries.begin(), runningQueries.end(), query), runningQueries.end()); - } -} - -void BonjourQuerier::interruptSelect() { - char c = 0; - write(interruptSelectWriteSocket, &c, 1); -} - -void BonjourQuerier::start() { - stop(); - thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this())); -} - -void BonjourQuerier::stop() { - if (thread) { - stopRequested = true; - runningQueries.clear(); // TODO: Is this the right thing to do? - runningQueriesAvailableEvent.notify_one(); - interruptSelect(); - thread->join(); - delete thread; - stopRequested = false; - } -} - -void BonjourQuerier::run() { - while (!stopRequested) { - fd_set fdSet; - int maxSocket; - { - boost::unique_lock<boost::mutex> lock(runningQueriesMutex); - if (runningQueries.empty()) { - runningQueriesAvailableEvent.wait(lock); - if (runningQueries.empty()) { - continue; - } - } - - // Run all running queries - FD_ZERO(&fdSet); - maxSocket = interruptSelectReadSocket; - FD_SET(interruptSelectReadSocket, &fdSet); - - foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) { - int socketID = query->getSocketID(); - maxSocket = std::max(maxSocket, socketID); - FD_SET(socketID, &fdSet); - } - } - - if (select(maxSocket+1, &fdSet, NULL, NULL, 0) <= 0) { - continue; - } - - if (FD_ISSET(interruptSelectReadSocket, &fdSet)) { - char dummy; - while (read(interruptSelectReadSocket, &dummy, 1) > 0) {} - } - - { - boost::lock_guard<boost::mutex> lock(runningQueriesMutex); - foreach(boost::shared_ptr<BonjourQuery> query, runningQueries) { - if (FD_ISSET(query->getSocketID(), &fdSet)) { - query->processResult(); - } - } - } - } -} - -} diff --git a/Swiften/LinkLocal/BonjourQuerier.h b/Swiften/LinkLocal/BonjourQuerier.h deleted file mode 100644 index 324e79e..0000000 --- a/Swiften/LinkLocal/BonjourQuerier.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp> -#include <list> -#include <boost/thread.hpp> -#include <boost/thread/mutex.hpp> - -#include "Swiften/LinkLocal/DNSSDQuerier.h" -#include "Swiften/LinkLocal/BonjourQuery.h" - -namespace Swift { - class LinkLocalServiceInfo; - - class BonjourQuerier : - public DNSSDQuerier, - public boost::enable_shared_from_this<BonjourQuerier> { - public: - BonjourQuerier(); - ~BonjourQuerier(); - - boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); - boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( - const String& name, int port, const LinkLocalServiceInfo& info); - boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( - const LinkLocalServiceID&); - boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( - const String& hostname, int interfaceIndex); - - void start(); - void stop(); - - private: - friend class BonjourQuery; - - void addRunningQuery(boost::shared_ptr<BonjourQuery>); - void removeRunningQuery(boost::shared_ptr<BonjourQuery>); - void interruptSelect(); - void run(); - - private: - bool stopRequested; - boost::thread* thread; - boost::mutex runningQueriesMutex; - std::list< boost::shared_ptr<BonjourQuery> > runningQueries; - int interruptSelectReadSocket; - int interruptSelectWriteSocket; - boost::condition_variable runningQueriesAvailableEvent; - }; -} diff --git a/Swiften/LinkLocal/BonjourQuery.cpp b/Swiften/LinkLocal/BonjourQuery.cpp deleted file mode 100644 index a9c13fb..0000000 --- a/Swiften/LinkLocal/BonjourQuery.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Swiften/LinkLocal/BonjourQuery.h" -#include "Swiften/LinkLocal/BonjourQuerier.h" - -namespace Swift { - -BonjourQuery::BonjourQuery(boost::shared_ptr<BonjourQuerier> q) : querier(q), sdRef(0) { -} - -BonjourQuery::~BonjourQuery() { - DNSServiceRefDeallocate(sdRef); -} - -void BonjourQuery::processResult() { - boost::lock_guard<boost::mutex> lock(sdRefMutex); - DNSServiceProcessResult(sdRef); -} - -int BonjourQuery::getSocketID() const { - boost::lock_guard<boost::mutex> lock(sdRefMutex); - return DNSServiceRefSockFD(sdRef); -} - -void BonjourQuery::run() { - querier->addRunningQuery(shared_from_this()); -} - -void BonjourQuery::finish() { - querier->removeRunningQuery(shared_from_this()); -} - -} diff --git a/Swiften/LinkLocal/BonjourQuery.h b/Swiften/LinkLocal/BonjourQuery.h deleted file mode 100644 index bdb91a4..0000000 --- a/Swiften/LinkLocal/BonjourQuery.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include <dns_sd.h> -#include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp> -#include <boost/thread/mutex.hpp> - -#include "Swiften/EventLoop/EventOwner.h" - -namespace Swift { - class BonjourQuerier; - - class BonjourQuery : - public EventOwner, - public boost::enable_shared_from_this<BonjourQuery> { - public: - BonjourQuery(boost::shared_ptr<BonjourQuerier>); - virtual ~BonjourQuery(); - - void processResult(); - int getSocketID() const; - - protected: - void run(); - void finish(); - - protected: - boost::shared_ptr<BonjourQuerier> querier; - mutable boost::mutex sdRefMutex; - DNSServiceRef sdRef; - }; -} diff --git a/Swiften/LinkLocal/BonjourRegisterQuery.h b/Swiften/LinkLocal/BonjourRegisterQuery.h deleted file mode 100644 index c34ba02..0000000 --- a/Swiften/LinkLocal/BonjourRegisterQuery.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "Swiften/LinkLocal/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/MainEventLoop.h" - -namespace Swift { - class BonjourQuerier; - - class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery { - public: - BonjourRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { - ByteArray txtRecord = info.toTXTRecord(); - DNSServiceErrorType result = DNSServiceRegister( - &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, - txtRecord.getSize(), txtRecord.getData(), - &BonjourRegisterQuery::handleServiceRegisteredStatic, this); - if (result != kDNSServiceErr_NoError) { - // TODO - std::cerr << "Error creating service registration" << std::endl; - } - } - - void registerService() { - run(); - } - - void updateServiceInfo(const LinkLocalServiceInfo& info) { - boost::lock_guard<boost::mutex> lock(sdRefMutex); - ByteArray txtRecord = info.toTXTRecord(); - DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); - } - - private: - static void handleServiceRegisteredStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { - static_cast<BonjourRegisterQuery*>(context)->handleServiceRegistered(errorCode, name, regtype, domain); - } - - void handleServiceRegistered(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { - if (errorCode != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>()), shared_from_this()); - } - else { - MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this()); - } - } - }; -} diff --git a/Swiften/LinkLocal/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/BonjourResolveHostnameQuery.h deleted file mode 100644 index 771fc84..0000000 --- a/Swiften/LinkLocal/BonjourResolveHostnameQuery.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "Swiften/Base/String.h" -#include "Swiften/LinkLocal/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h" -#include "Swiften/EventLoop/MainEventLoop.h" -#include "Swiften/Network/HostAddress.h" - -#include <netinet/in.h> - -namespace Swift { - class BonjourQuerier; - - class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery { - public: - BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { - DNSServiceErrorType result = DNSServiceGetAddrInfo( - &sdRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, - hostname.getUTF8Data(), - &BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this); - if (result != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this()); - } - } - - //void DNSSDResolveHostnameQuery::run() { - void run() { - BonjourQuery::run(); - } - - private: - static void handleHostnameResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char*, const struct sockaddr *address, uint32_t, void *context) { - static_cast<BonjourResolveHostnameQuery*>(context)->handleHostnameResolved(errorCode, address); - } - - void handleHostnameResolved(DNSServiceErrorType errorCode, const struct sockaddr *rawAddress) { - if (errorCode) { - MainEventLoop::postEvent( - boost::bind(boost::ref(onHostnameResolved), - 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), - HostAddress(reinterpret_cast<unsigned char*>(&address), 4)), - shared_from_this()); - } - } - }; -} diff --git a/Swiften/LinkLocal/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/BonjourResolveServiceQuery.h deleted file mode 100644 index e4f02ee..0000000 --- a/Swiften/LinkLocal/BonjourResolveServiceQuery.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "Swiften/LinkLocal/BonjourQuery.h" -#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" -#include "Swiften/Base/ByteArray.h" -#include "Swiften/EventLoop/MainEventLoop.h" - -namespace Swift { - class BonjourQuerier; - - class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery { - public: - BonjourResolveServiceQuery(const LinkLocalServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { - DNSServiceErrorType result = DNSServiceResolve( - &sdRef, 0, service.getNetworkInterfaceID(), - service.getName().getUTF8Data(), service.getType().getUTF8Data(), - service.getDomain().getUTF8Data(), - &BonjourResolveServiceQuery::handleServiceResolvedStatic, this); - if (result != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); - } - } - - void start() { - run(); - } - - void stop() { - finish(); - } - - private: - static void handleServiceResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { - static_cast<BonjourResolveServiceQuery*>(context)->handleServiceResolved(errorCode, fullname, hosttarget, port, txtLen, txtRecord); - } - - void handleServiceResolved(DNSServiceErrorType errorCode, const char* fullName, const char* host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord) { - if (errorCode != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); - } - else { - MainEventLoop::postEvent( - boost::bind( - boost::ref(onServiceResolved), - Result(String(fullName), String(host), port, - LinkLocalServiceInfo::createFromTXTRecord( - ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), - shared_from_this()); - } - } - }; -} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h new file mode 100644 index 0000000..edff064 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -0,0 +1,51 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" +#include "Swiften/EventLoop/MainEventLoop.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourBrowseQuery : public DNSSDBrowseQuery, public BonjourQuery { + public: + BonjourBrowseQuery(boost::shared_ptr<BonjourQuerier> q) : BonjourQuery(q) { + DNSServiceErrorType result = DNSServiceBrowse( + &sdRef, 0, 0, "_presence._tcp", 0, + &BonjourBrowseQuery::handleServiceDiscoveredStatic, this); + if (result != kDNSServiceErr_NoError) { + std::cout << "Error" << std::endl; + // TODO + } + } + + void startBrowsing() { + assert(sdRef); + run(); + } + + void stopBrowsing() { + finish(); + } + + private: + static void handleServiceDiscoveredStatic(DNSServiceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain, void *context) { + static_cast<BonjourBrowseQuery*>(context)->handleServiceDiscovered(flags, interfaceIndex, errorCode, name, type, domain); + } + + void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) { + if (errorCode != kDNSServiceErr_NoError) { + return; + } + else { + LinkLocalServiceID service(name, type, domain, 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()); + } + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp new file mode 100644 index 0000000..064e3c5 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp @@ -0,0 +1,128 @@ +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" + +#include <unistd.h> +#include <sys/socket.h> +#include <fcntl.h> + +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h" +#include "Swiften/Base/foreach.h" + +namespace Swift { + +BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(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]; +} + +BonjourQuerier::~BonjourQuerier() { + stop(); +} + +boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { + return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this())); +} + +boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) { + return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) { + return boost::shared_ptr<DNSSDResolveServiceQuery>(new BonjourResolveServiceQuery(service, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveHostnameQuery> BonjourQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) { + return boost::shared_ptr<DNSSDResolveHostnameQuery>(new BonjourResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); +} + +void BonjourQuerier::addRunningQuery(boost::shared_ptr<BonjourQuery> query) { + { + boost::lock_guard<boost::mutex> lock(runningQueriesMutex); + runningQueries.push_back(query); + } + runningQueriesAvailableEvent.notify_one(); + interruptSelect(); +} + +void BonjourQuerier::removeRunningQuery(boost::shared_ptr<BonjourQuery> query) { + { + boost::lock_guard<boost::mutex> lock(runningQueriesMutex); + runningQueries.erase(std::remove( + runningQueries.begin(), runningQueries.end(), query), runningQueries.end()); + } +} + +void BonjourQuerier::interruptSelect() { + char c = 0; + write(interruptSelectWriteSocket, &c, 1); +} + +void BonjourQuerier::start() { + stop(); + thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this())); +} + +void BonjourQuerier::stop() { + if (thread) { + stopRequested = true; + runningQueries.clear(); // TODO: Is this the right thing to do? + runningQueriesAvailableEvent.notify_one(); + interruptSelect(); + thread->join(); + delete thread; + stopRequested = false; + } +} + +void BonjourQuerier::run() { + while (!stopRequested) { + fd_set fdSet; + int maxSocket; + { + boost::unique_lock<boost::mutex> lock(runningQueriesMutex); + if (runningQueries.empty()) { + runningQueriesAvailableEvent.wait(lock); + if (runningQueries.empty()) { + continue; + } + } + + // Run all running queries + FD_ZERO(&fdSet); + maxSocket = interruptSelectReadSocket; + FD_SET(interruptSelectReadSocket, &fdSet); + + foreach(const boost::shared_ptr<BonjourQuery>& query, runningQueries) { + int socketID = query->getSocketID(); + maxSocket = std::max(maxSocket, socketID); + FD_SET(socketID, &fdSet); + } + } + + if (select(maxSocket+1, &fdSet, NULL, NULL, 0) <= 0) { + continue; + } + + if (FD_ISSET(interruptSelectReadSocket, &fdSet)) { + char dummy; + while (read(interruptSelectReadSocket, &dummy, 1) > 0) {} + } + + { + boost::lock_guard<boost::mutex> lock(runningQueriesMutex); + foreach(boost::shared_ptr<BonjourQuery> query, runningQueries) { + if (FD_ISSET(query->getSocketID(), &fdSet)) { + query->processResult(); + } + } + } + } +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h new file mode 100644 index 0000000..79f9a81 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h @@ -0,0 +1,50 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <list> +#include <boost/thread.hpp> +#include <boost/thread/mutex.hpp> + +#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" + +namespace Swift { + class LinkLocalServiceInfo; + + class BonjourQuerier : + public DNSSDQuerier, + public boost::enable_shared_from_this<BonjourQuerier> { + public: + BonjourQuerier(); + ~BonjourQuerier(); + + boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); + boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const LinkLocalServiceID&); + boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( + const String& hostname, int interfaceIndex); + + void start(); + void stop(); + + private: + friend class BonjourQuery; + + void addRunningQuery(boost::shared_ptr<BonjourQuery>); + void removeRunningQuery(boost::shared_ptr<BonjourQuery>); + void interruptSelect(); + void run(); + + private: + bool stopRequested; + boost::thread* thread; + boost::mutex runningQueriesMutex; + std::list< boost::shared_ptr<BonjourQuery> > runningQueries; + int interruptSelectReadSocket; + int interruptSelectWriteSocket; + boost::condition_variable runningQueriesAvailableEvent; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp new file mode 100644 index 0000000..c1c481b --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp @@ -0,0 +1,31 @@ +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" + +namespace Swift { + +BonjourQuery::BonjourQuery(boost::shared_ptr<BonjourQuerier> q) : querier(q), sdRef(0) { +} + +BonjourQuery::~BonjourQuery() { + DNSServiceRefDeallocate(sdRef); +} + +void BonjourQuery::processResult() { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + DNSServiceProcessResult(sdRef); +} + +int BonjourQuery::getSocketID() const { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + return DNSServiceRefSockFD(sdRef); +} + +void BonjourQuery::run() { + querier->addRunningQuery(shared_from_this()); +} + +void BonjourQuery::finish() { + querier->removeRunningQuery(shared_from_this()); +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h new file mode 100644 index 0000000..bdb91a4 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h @@ -0,0 +1,32 @@ +#pragma once + +#include <dns_sd.h> +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <boost/thread/mutex.hpp> + +#include "Swiften/EventLoop/EventOwner.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourQuery : + public EventOwner, + public boost::enable_shared_from_this<BonjourQuery> { + public: + BonjourQuery(boost::shared_ptr<BonjourQuerier>); + virtual ~BonjourQuery(); + + void processResult(); + int getSocketID() const; + + protected: + void run(); + void finish(); + + protected: + boost::shared_ptr<BonjourQuerier> querier; + mutable boost::mutex sdRefMutex; + DNSServiceRef sdRef; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h new file mode 100644 index 0000000..31e86fc --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -0,0 +1,50 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/EventLoop/MainEventLoop.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery { + public: + BonjourRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceErrorType result = DNSServiceRegister( + &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, + txtRecord.getSize(), txtRecord.getData(), + &BonjourRegisterQuery::handleServiceRegisteredStatic, this); + if (result != kDNSServiceErr_NoError) { + // TODO + std::cerr << "Error creating service registration" << std::endl; + } + } + + void registerService() { + run(); + } + + void updateServiceInfo(const LinkLocalServiceInfo& info) { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); + } + + private: + static void handleServiceRegisteredStatic(DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) { + static_cast<BonjourRegisterQuery*>(context)->handleServiceRegistered(errorCode, name, regtype, domain); + } + + void handleServiceRegistered(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { + if (errorCode != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>()), shared_from_this()); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h new file mode 100644 index 0000000..58c6588 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Swiften/Base/String.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" +#include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/Network/HostAddress.h" + +#include <netinet/in.h> + +namespace Swift { + class BonjourQuerier; + + class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery { + public: + BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + DNSServiceErrorType result = DNSServiceGetAddrInfo( + &sdRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, + hostname.getUTF8Data(), + &BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this); + if (result != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this()); + } + } + + //void DNSSDResolveHostnameQuery::run() { + void run() { + BonjourQuery::run(); + } + + private: + static void handleHostnameResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char*, const struct sockaddr *address, uint32_t, void *context) { + static_cast<BonjourResolveHostnameQuery*>(context)->handleHostnameResolved(errorCode, address); + } + + void handleHostnameResolved(DNSServiceErrorType errorCode, const struct sockaddr *rawAddress) { + if (errorCode) { + MainEventLoop::postEvent( + boost::bind(boost::ref(onHostnameResolved), + 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), + HostAddress(reinterpret_cast<unsigned char*>(&address), 4)), + shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h new file mode 100644 index 0000000..1afdf5a --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -0,0 +1,53 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/EventLoop/MainEventLoop.h" + +namespace Swift { + class BonjourQuerier; + + class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery { + public: + BonjourResolveServiceQuery(const LinkLocalServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + DNSServiceErrorType result = DNSServiceResolve( + &sdRef, 0, service.getNetworkInterfaceID(), + service.getName().getUTF8Data(), service.getType().getUTF8Data(), + service.getDomain().getUTF8Data(), + &BonjourResolveServiceQuery::handleServiceResolvedStatic, this); + if (result != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } + } + + void start() { + run(); + } + + void stop() { + finish(); + } + + private: + static void handleServiceResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { + static_cast<BonjourResolveServiceQuery*>(context)->handleServiceResolved(errorCode, fullname, hosttarget, port, txtLen, txtRecord); + } + + void handleServiceResolved(DNSServiceErrorType errorCode, const char* fullName, const char* host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord) { + if (errorCode != kDNSServiceErr_NoError) { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } + else { + MainEventLoop::postEvent( + boost::bind( + boost::ref(onServiceResolved), + Result(String(fullName), String(host), port, + LinkLocalServiceInfo::createFromTXTRecord( + ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), + shared_from_this()); + } + } + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc b/Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc new file mode 100644 index 0000000..efa329d --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc @@ -0,0 +1,3 @@ +SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.cpp \ + Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp new file mode 100644 index 0000000..1dbff2c --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" + +namespace Swift { + +DNSSDBrowseQuery::~DNSSDBrowseQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h new file mode 100644 index 0000000..e548ca5 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h @@ -0,0 +1,18 @@ +#pragma once + +#include <boost/signal.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" + +namespace Swift { + class DNSSDBrowseQuery { + public: + virtual ~DNSSDBrowseQuery(); + + virtual void startBrowsing() = 0; + virtual void stopBrowsing() = 0; + + boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; + boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp new file mode 100644 index 0000000..cc8d6ef --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" + +namespace Swift { + +DNSSDQuerier::~DNSSDQuerier() { +} + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h new file mode 100644 index 0000000..528a6ea --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h @@ -0,0 +1,26 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +namespace Swift { + class String; + class LinkLocalServiceInfo; + class LinkLocalServiceID; + class DNSSDBrowseQuery; + class DNSSDRegisterQuery; + class DNSSDResolveServiceQuery; + class DNSSDResolveHostnameQuery; + + class DNSSDQuerier { + public: + virtual ~DNSSDQuerier(); + + virtual boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery() = 0; + virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info) = 0; + virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const LinkLocalServiceID&) = 0; + virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( + const String& hostname, int interfaceIndex) = 0; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp new file mode 100644 index 0000000..bbb8692 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" + +namespace Swift { + +DNSSDRegisterQuery::~DNSSDRegisterQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h new file mode 100644 index 0000000..252fbf0 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h @@ -0,0 +1,20 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" + +namespace Swift { + class LinkLocalServiceInfo; + + class DNSSDRegisterQuery { + public: + virtual ~DNSSDRegisterQuery(); + + virtual void registerService() = 0; + virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0; + + boost::signal<void (boost::optional<LinkLocalServiceID>)> onRegisterFinished; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp new file mode 100644 index 0000000..e247e39 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" + +namespace Swift { + +DNSSDResolveHostnameQuery::~DNSSDResolveHostnameQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h new file mode 100644 index 0000000..a2e218c --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h @@ -0,0 +1,17 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/Network/HostAddress.h" + +namespace Swift { + class DNSSDResolveHostnameQuery { + public: + virtual ~DNSSDResolveHostnameQuery(); + + virtual void run() = 0; + + boost::signal<void (const boost::optional<HostAddress>&)> onHostnameResolved; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp new file mode 100644 index 0000000..67a5d66 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp @@ -0,0 +1,8 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" + +namespace Swift { + +DNSSDResolveServiceQuery::~DNSSDResolveServiceQuery() { +} + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h new file mode 100644 index 0000000..d8b5cf1 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h @@ -0,0 +1,29 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" + +namespace Swift { + class DNSSDResolveServiceQuery { + public: + struct Result { + Result(const String& fullName, const String& host, int port, + const LinkLocalServiceInfo& info) : + fullName(fullName), host(host), port(port), info(info) {} + String fullName; + String host; + int port; + LinkLocalServiceInfo info; + }; + + virtual ~DNSSDResolveServiceQuery(); + + virtual void start() = 0; + virtual void stop() = 0; + + boost::signal<void (const boost::optional<Result>&)> onServiceResolved; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Makefile.inc b/Swiften/LinkLocal/DNSSD/Makefile.inc new file mode 100644 index 0000000..81beee0 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Makefile.inc @@ -0,0 +1,12 @@ +SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp \ + Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp \ + Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp \ + Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.cpp \ + Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.cpp + +ifeq ($(HAVE_BONJOUR),yes) +include Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc +endif +ifeq ($(HAVE_AVAHI),yes) +endif diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.cpp b/Swiften/LinkLocal/DNSSDBrowseQuery.cpp deleted file mode 100644 index 4924247..0000000 --- a/Swiften/LinkLocal/DNSSDBrowseQuery.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDBrowseQuery.h" - -namespace Swift { - -DNSSDBrowseQuery::~DNSSDBrowseQuery() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSDBrowseQuery.h deleted file mode 100644 index e548ca5..0000000 --- a/Swiften/LinkLocal/DNSSDBrowseQuery.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include <boost/signal.hpp> - -#include "Swiften/LinkLocal/LinkLocalServiceID.h" - -namespace Swift { - class DNSSDBrowseQuery { - public: - virtual ~DNSSDBrowseQuery(); - - virtual void startBrowsing() = 0; - virtual void stopBrowsing() = 0; - - boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; - boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; - }; -} diff --git a/Swiften/LinkLocal/DNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSDQuerier.cpp deleted file mode 100644 index be87a3c..0000000 --- a/Swiften/LinkLocal/DNSSDQuerier.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDQuerier.h" - -namespace Swift { - -DNSSDQuerier::~DNSSDQuerier() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSDQuerier.h deleted file mode 100644 index 528a6ea..0000000 --- a/Swiften/LinkLocal/DNSSDQuerier.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include <boost/shared_ptr.hpp> - -namespace Swift { - class String; - class LinkLocalServiceInfo; - class LinkLocalServiceID; - class DNSSDBrowseQuery; - class DNSSDRegisterQuery; - class DNSSDResolveServiceQuery; - class DNSSDResolveHostnameQuery; - - class DNSSDQuerier { - public: - virtual ~DNSSDQuerier(); - - virtual boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery() = 0; - virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( - const String& name, int port, const LinkLocalServiceInfo& info) = 0; - virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( - const LinkLocalServiceID&) = 0; - virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( - const String& hostname, int interfaceIndex) = 0; - }; -} diff --git a/Swiften/LinkLocal/DNSSDRegisterQuery.cpp b/Swiften/LinkLocal/DNSSDRegisterQuery.cpp deleted file mode 100644 index fe00b02..0000000 --- a/Swiften/LinkLocal/DNSSDRegisterQuery.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDRegisterQuery.h" - -namespace Swift { - -DNSSDRegisterQuery::~DNSSDRegisterQuery() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSDRegisterQuery.h deleted file mode 100644 index 252fbf0..0000000 --- a/Swiften/LinkLocal/DNSSDRegisterQuery.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include <boost/signal.hpp> -#include <boost/optional.hpp> - -#include "Swiften/LinkLocal/LinkLocalServiceID.h" - -namespace Swift { - class LinkLocalServiceInfo; - - class DNSSDRegisterQuery { - public: - virtual ~DNSSDRegisterQuery(); - - virtual void registerService() = 0; - virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0; - - boost::signal<void (boost::optional<LinkLocalServiceID>)> onRegisterFinished; - }; -} diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp deleted file mode 100644 index f7c88bd..0000000 --- a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDResolveHostnameQuery.h" - -namespace Swift { - -DNSSDResolveHostnameQuery::~DNSSDResolveHostnameQuery() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h deleted file mode 100644 index a2e218c..0000000 --- a/Swiften/LinkLocal/DNSSDResolveHostnameQuery.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include <boost/signal.hpp> -#include <boost/optional.hpp> - -#include "Swiften/Network/HostAddress.h" - -namespace Swift { - class DNSSDResolveHostnameQuery { - public: - virtual ~DNSSDResolveHostnameQuery(); - - virtual void run() = 0; - - boost::signal<void (const boost::optional<HostAddress>&)> onHostnameResolved; - }; -} diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp b/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp deleted file mode 100644 index 83a9ccd..0000000 --- a/Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDResolveServiceQuery.h" - -namespace Swift { - -DNSSDResolveServiceQuery::~DNSSDResolveServiceQuery() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSDResolveServiceQuery.h deleted file mode 100644 index d8b5cf1..0000000 --- a/Swiften/LinkLocal/DNSSDResolveServiceQuery.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include <boost/signal.hpp> -#include <boost/optional.hpp> - -#include "Swiften/LinkLocal/LinkLocalServiceID.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" - -namespace Swift { - class DNSSDResolveServiceQuery { - public: - struct Result { - Result(const String& fullName, const String& host, int port, - const LinkLocalServiceInfo& info) : - fullName(fullName), host(host), port(port), info(info) {} - String fullName; - String host; - int port; - LinkLocalServiceInfo info; - }; - - virtual ~DNSSDResolveServiceQuery(); - - virtual void start() = 0; - virtual void stop() = 0; - - boost::signal<void (const boost::optional<Result>&)> onServiceResolved; - }; -} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 9522cbb..86a25fd 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,12 +1,7 @@ SWIFTEN_SOURCES += \ - Swiften/LinkLocal/DNSSDQuerier.cpp \ - Swiften/LinkLocal/DNSSDBrowseQuery.cpp \ - Swiften/LinkLocal/DNSSDRegisterQuery.cpp \ - Swiften/LinkLocal/DNSSDResolveServiceQuery.cpp \ - Swiften/LinkLocal/DNSSDResolveHostnameQuery.cpp \ Swiften/LinkLocal/DNSSDServiceFactory.cpp \ - Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ + Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ Swiften/LinkLocal/LinkLocalServiceID.cpp \ Swiften/LinkLocal/LinkLocalServiceInfo.cpp \ @@ -17,8 +12,6 @@ SWIFTEN_SOURCES += \ ifeq ($(HAVE_BONJOUR),yes) SWIFTEN_SOURCES += \ - Swiften/LinkLocal/BonjourQuery.cpp \ - Swiften/LinkLocal/BonjourQuerier.cpp \ Swiften/LinkLocal/AppleDNSSDService.cpp endif ifeq ($(HAVE_AVAHI),yes) @@ -26,4 +19,5 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/AvahiDNSSDService.cpp endif +include Swiften/LinkLocal/DNSSD/Makefile.inc include Swiften/LinkLocal/UnitTest/Makefile.inc -- cgit v0.10.2-6-g49f6 From c54914a3666c0687f5bba776db34263eeb8e810f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 25 Jul 2009 15:17:19 +0200 Subject: Added About menu. diff --git a/Slimber/CLI/main.cpp b/Slimber/CLI/main.cpp index 3a72ca1..8b70625 100644 --- a/Slimber/CLI/main.cpp +++ b/Slimber/CLI/main.cpp @@ -10,7 +10,9 @@ #include "Slimber/Server.h" #include "Slimber/FileVCardCollection.h" #include "Swiften/LinkLocal/LinkLocalRoster.h" -#include "Swiften/LinkLocal/BonjourQuerier.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" #include "Swiften/EventLoop/SimpleEventLoop.h" #include "Swiften/Application/Platform/PlatformApplication.h" diff --git a/Slimber/Cocoa/Info.plist b/Slimber/Cocoa/Info.plist index bcbed49..f934a10 100644 --- a/Slimber/Cocoa/Info.plist +++ b/Slimber/Cocoa/Info.plist @@ -24,5 +24,7 @@ <string>NSApplication</string> <key>LSUIElement</key> <string>1</string> + <key>NSHumanReadableCopyright</key> + <string>© 2009 Swift Development Team. All Rights Reserved.</string> </dict> </plist> diff --git a/Slimber/Cocoa/Menulet.m b/Slimber/Cocoa/Menulet.m index b2af97f..4fa7fed 100644 --- a/Slimber/Cocoa/Menulet.m +++ b/Slimber/Cocoa/Menulet.m @@ -75,6 +75,12 @@ [statusMenu addItem: loggedInItem]; [statusMenu addItem: [NSMenuItem separatorItem]]; + // About menu + NSMenuItem* aboutMenuItem = [[NSMenuItem alloc] initWithTitle: @"About Slimber" action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""]; + [aboutMenuItem setTarget: [NSApplication sharedApplication]]; + [statusMenu addItem: aboutMenuItem]; + [statusMenu addItem: [NSMenuItem separatorItem]]; + // Exit item NSMenuItem* exitMenuItem = [[NSMenuItem alloc] initWithTitle: @"Exit" action: @selector(terminate:) keyEquivalent: @""]; [exitMenuItem setTarget: [NSApplication sharedApplication]]; -- cgit v0.10.2-6-g49f6 From d2807a77d39bd1a359f5b85869113ed83e01c204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 25 Jul 2009 15:24:05 +0200 Subject: Added credts to about box. diff --git a/Slimber/Cocoa/Makefile.inc b/Slimber/Cocoa/Makefile.inc index 28495f7..8068350 100644 --- a/Slimber/Cocoa/Makefile.inc +++ b/Slimber/Cocoa/Makefile.inc @@ -12,6 +12,7 @@ SLIMBER_COCOA_SOURCES = \ SLIMBER_COCOA_XIBS = \ Slimber/Cocoa/MainMenu.xib SLIMBER_COCOA_RESOURCES = \ + Slimber/Resources/Credits.html \ Slimber/Resources/Online.png \ Slimber/Resources/Offline.png \ Slimber/Resources/UsersOnline.png \ diff --git a/Slimber/Resources/Credits.html b/Slimber/Resources/Credits.html new file mode 100644 index 0000000..66ecb13 --- /dev/null +++ b/Slimber/Resources/Credits.html @@ -0,0 +1 @@ +<a href="http://swift.im/slimber">http://swift.im/slimber</a> -- cgit v0.10.2-6-g49f6 From 9f51e6c6279ae7fb541774ac4bf9debfa61395c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 25 Jul 2009 19:32:55 +0200 Subject: Move LinkLocalServiceID->DNSSDServiceID. diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp index bf66e50..a052eb1 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.cpp +++ b/Swiften/LinkLocal/AppleDNSSDService.cpp @@ -70,7 +70,7 @@ void AppleDNSSDService::unregisterService() { registerSDRef = NULL; } -void AppleDNSSDService::startResolvingService(const LinkLocalServiceID& service) { +void AppleDNSSDService::startResolvingService(const DNSSDServiceID& service) { boost::lock_guard<boost::mutex> lock(sdRefsMutex); DNSServiceRef resolveSDRef; @@ -87,7 +87,7 @@ void AppleDNSSDService::startResolvingService(const LinkLocalServiceID& service) interruptSelect(); } -void AppleDNSSDService::stopResolvingService(const LinkLocalServiceID& service) { +void AppleDNSSDService::stopResolvingService(const DNSSDServiceID& service) { boost::lock_guard<boost::mutex> lock(sdRefsMutex); ServiceSDRefMap::iterator i = resolveSDRefs.find(service); @@ -238,7 +238,7 @@ void AppleDNSSDService::handleServiceDiscovered(DNSServiceRef, DNSServiceFlags f return; } else { - LinkLocalServiceID service(serviceName, regtype, replyDomain, interfaceIndex); + DNSSDServiceID service(serviceName, regtype, replyDomain, interfaceIndex); if (flags & kDNSServiceFlagsAdd) { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); } @@ -258,7 +258,7 @@ void AppleDNSSDService::handleServiceRegistered(DNSServiceRef, DNSServiceFlags, haveError = true; } else { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRegistered), LinkLocalServiceID(name, regtype, domain, 0)), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRegistered), DNSSDServiceID(name, regtype, domain, 0)), shared_from_this()); } } diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h index 7fdfd3e..554a154 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.h +++ b/Swiften/LinkLocal/AppleDNSSDService.h @@ -6,7 +6,7 @@ #include <dns_sd.h> #include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" #include "Swiften/EventLoop/EventOwner.h" namespace Swift { @@ -22,8 +22,8 @@ namespace Swift { virtual void updateService(const LinkLocalServiceInfo&); virtual void unregisterService(); - virtual void startResolvingService(const LinkLocalServiceID&); - virtual void stopResolvingService(const LinkLocalServiceID&); + virtual void startResolvingService(const DNSSDServiceID&); + virtual void stopResolvingService(const DNSSDServiceID&); virtual void resolveHostname(const String& hostname, int interfaceIndex = 0); @@ -49,7 +49,7 @@ namespace Swift { boost::mutex sdRefsMutex; DNSServiceRef browseSDRef; DNSServiceRef registerSDRef; - typedef std::map<LinkLocalServiceID, DNSServiceRef> ServiceSDRefMap; + 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 index fe9ac83..5f6295f 100644 --- a/Swiften/LinkLocal/AvahiDNSSDService.cpp +++ b/Swiften/LinkLocal/AvahiDNSSDService.cpp @@ -62,7 +62,7 @@ void AvahiDNSSDService::unregisterService() { avahi_threaded_poll_unlock(threadedPoll); } -void AvahiDNSSDService::startResolvingService(const LinkLocalServiceID& service) { +void AvahiDNSSDService::startResolvingService(const DNSSDServiceID& service) { avahi_threaded_poll_lock(threadedPoll); AvahiServiceResolver* resolver = avahi_service_resolver_new( @@ -82,7 +82,7 @@ void AvahiDNSSDService::startResolvingService(const LinkLocalServiceID& service) avahi_threaded_poll_unlock(threadedPoll); } -void AvahiDNSSDService::stopResolvingService(const LinkLocalServiceID& service) { +void AvahiDNSSDService::stopResolvingService(const DNSSDServiceID& service) { avahi_threaded_poll_lock(threadedPoll); ServiceResolverMap::iterator i = serviceResolvers.find(service); @@ -112,13 +112,13 @@ void AvahiDNSSDService::handleServiceDiscovered(AvahiServiceBrowser *, AvahiIfIn return; case AVAHI_BROWSER_NEW: { std::cerr << "Service added: " << name << " " << type << " " << domain << std::endl; - LinkLocalServiceID service(name, type, domain, interfaceIndex); + 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; - LinkLocalServiceID service(name, type, domain, interfaceIndex); + DNSSDServiceID service(name, type, domain, interfaceIndex); MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), service), shared_from_this()); } break; @@ -146,7 +146,7 @@ void AvahiDNSSDService::handleServiceResolved(AvahiServiceResolver *, AvahiIfInd HostAddress hostAddress(reinterpret_cast<const unsigned char*>(&address->data.ipv4.address), 4); hostnameAddresses[String(hostname)] = hostAddress; MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), - LinkLocalServiceID(name, type, domain, interfaceIndex), + DNSSDServiceID(name, type, domain, interfaceIndex), ResolveResult(hostname, port, LinkLocalServiceInfo::createFromTXTRecord(data))), shared_from_this()); diff --git a/Swiften/LinkLocal/AvahiDNSSDService.h b/Swiften/LinkLocal/AvahiDNSSDService.h index 99a1d23..7162ade 100644 --- a/Swiften/LinkLocal/AvahiDNSSDService.h +++ b/Swiften/LinkLocal/AvahiDNSSDService.h @@ -26,8 +26,8 @@ namespace Swift { virtual void updateService(const LinkLocalServiceInfo&); virtual void unregisterService(); - virtual void startResolvingService(const LinkLocalServiceID&); - virtual void stopResolvingService(const LinkLocalServiceID&); + virtual void startResolvingService(const DNSSDServiceID&); + virtual void stopResolvingService(const DNSSDServiceID&); virtual void resolveHostname(const String& hostname, int interfaceIndex = 0); @@ -47,7 +47,7 @@ namespace Swift { AvahiClient* client; AvahiThreadedPoll* threadedPoll; AvahiServiceBrowser* serviceBrowser; - typedef std::map<LinkLocalServiceID, AvahiServiceResolver*> ServiceResolverMap; + typedef std::map<DNSSDServiceID, AvahiServiceResolver*> ServiceResolverMap; ServiceResolverMap serviceResolvers; typedef std::map<String, HostAddress> HostnameAddressMap; HostnameAddressMap hostnameAddresses; diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h index edff064..62d8606 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -38,7 +38,7 @@ namespace Swift { return; } else { - LinkLocalServiceID service(name, type, domain, interfaceIndex); + DNSSDServiceID service(name, type, domain, interfaceIndex); if (flags & kDNSServiceFlagsAdd) { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp index 064e3c5..c065d4d 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp @@ -33,7 +33,7 @@ boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); } -boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const LinkLocalServiceID& service) { +boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const DNSSDServiceID& service) { return boost::shared_ptr<DNSSDResolveServiceQuery>(new BonjourResolveServiceQuery(service, shared_from_this())); } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h index 79f9a81..644a8d9 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h @@ -23,7 +23,7 @@ namespace Swift { boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( const String& name, int port, const LinkLocalServiceInfo& info); boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( - const LinkLocalServiceID&); + const DNSSDServiceID&); boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( const String& hostname, int interfaceIndex); diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h index 31e86fc..9c4db13 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -40,10 +40,10 @@ namespace Swift { void handleServiceRegistered(DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain) { if (errorCode != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>()), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); } else { - MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<LinkLocalServiceID>(LinkLocalServiceID(name, regtype, domain, 0))), shared_from_this()); + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, regtype, domain, 0))), shared_from_this()); } } }; diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h index 1afdf5a..1ebd487 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -11,7 +11,7 @@ namespace Swift { class BonjourResolveServiceQuery : public DNSSDResolveServiceQuery, public BonjourQuery { public: - BonjourResolveServiceQuery(const LinkLocalServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { + BonjourResolveServiceQuery(const DNSSDServiceID& service, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { DNSServiceErrorType result = DNSServiceResolve( &sdRef, 0, service.getNetworkInterfaceID(), service.getName().getUTF8Data(), service.getType().getUTF8Data(), diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h index e548ca5..86967ed 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h @@ -2,7 +2,7 @@ #include <boost/signal.hpp> -#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" namespace Swift { class DNSSDBrowseQuery { @@ -12,7 +12,7 @@ namespace Swift { virtual void startBrowsing() = 0; virtual void stopBrowsing() = 0; - boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; - boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; + boost::signal<void (const DNSSDServiceID&)> onServiceAdded; + boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; }; } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h index 528a6ea..6c7b576 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h @@ -5,7 +5,7 @@ namespace Swift { class String; class LinkLocalServiceInfo; - class LinkLocalServiceID; + class DNSSDServiceID; class DNSSDBrowseQuery; class DNSSDRegisterQuery; class DNSSDResolveServiceQuery; @@ -19,7 +19,7 @@ namespace Swift { virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( const String& name, int port, const LinkLocalServiceInfo& info) = 0; virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( - const LinkLocalServiceID&) = 0; + const DNSSDServiceID&) = 0; virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( const String& hostname, int interfaceIndex) = 0; }; diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h index 252fbf0..a643880 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h @@ -3,7 +3,7 @@ #include <boost/signal.hpp> #include <boost/optional.hpp> -#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" namespace Swift { class LinkLocalServiceInfo; @@ -15,6 +15,6 @@ namespace Swift { virtual void registerService() = 0; virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0; - boost::signal<void (boost::optional<LinkLocalServiceID>)> onRegisterFinished; + boost::signal<void (boost::optional<DNSSDServiceID>)> onRegisterFinished; }; } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h index d8b5cf1..f79b537 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h @@ -3,7 +3,7 @@ #include <boost/signal.hpp> #include <boost/optional.hpp> -#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp new file mode 100644 index 0000000..06a5b81 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp @@ -0,0 +1,7 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" + +namespace Swift { + +const String DNSSDServiceID::PresenceServiceType = String("_presence._tcp"); + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h new file mode 100644 index 0000000..b1986d3 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h @@ -0,0 +1,66 @@ +#pragma once + +#include "Swiften/Base/String.h" + +namespace Swift { + class DNSSDServiceID { + public: + static const String PresenceServiceType; + + DNSSDServiceID( + const String& name, + const String& type, + const String& domain = PresenceServiceType, + int networkInterface = 0) : + name(name), + type(type), + domain(domain), + networkInterface(networkInterface) { + } + + bool operator==(const DNSSDServiceID& o) const { + return name == o.name && type == o.type && domain == o.domain && (networkInterface != 0 && o.networkInterface != 0 ? networkInterface == o.networkInterface : true); + } + + bool operator<(const DNSSDServiceID& o) const { + if (o.name == name) { + if (o.type == type) { + if (o.domain == domain) { + return networkInterface < o.networkInterface; + } + else { + return domain < o.domain; + } + } + else { + return type < o.type; + } + } + else { + return o.name < name; + } + } + + const String& getName() const { + return name; + } + + const String& getType() const { + return type; + } + + const String& getDomain() const { + return domain; + } + + int getNetworkInterfaceID() const { + return networkInterface; + } + + private: + String name; + String type; + String domain; + int networkInterface; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Makefile.inc b/Swiften/LinkLocal/DNSSD/Makefile.inc index 81beee0..8612fee 100644 --- a/Swiften/LinkLocal/DNSSD/Makefile.inc +++ b/Swiften/LinkLocal/DNSSD/Makefile.inc @@ -1,4 +1,5 @@ SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp \ Swiften/LinkLocal/DNSSD/DNSSDQuerier.cpp \ Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.cpp \ Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.cpp \ diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h index 4cf1a6e..0ace21b 100644 --- a/Swiften/LinkLocal/DNSSDService.h +++ b/Swiften/LinkLocal/DNSSDService.h @@ -4,7 +4,7 @@ #include <map> #include "Swiften/Base/String.h" -#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { @@ -29,17 +29,17 @@ namespace Swift { virtual void updateService(const LinkLocalServiceInfo&) = 0; virtual void unregisterService() = 0; - virtual void startResolvingService(const LinkLocalServiceID&) = 0; - virtual void stopResolvingService(const LinkLocalServiceID&) = 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 LinkLocalServiceID&)> onServiceAdded; - boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; - boost::signal<void (const LinkLocalServiceID&)> onServiceRegistered; - boost::signal<void (const LinkLocalServiceID&, const ResolveResult&)> onServiceResolved; + 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/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp index 5a6ccfd..af3c1af 100644 --- a/Swiften/LinkLocal/LinkLocalRoster.cpp +++ b/Swiften/LinkLocal/LinkLocalRoster.cpp @@ -30,11 +30,11 @@ std::vector<boost::shared_ptr<Presence> > LinkLocalRoster::getAllPresence() cons return result; } -RosterItemPayload LinkLocalRoster::getRosterItem(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { +RosterItemPayload LinkLocalRoster::getRosterItem(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { return RosterItemPayload(getJIDForService(service), getRosterName(service, resolveResult), RosterItemPayload::Both); } -String LinkLocalRoster::getRosterName(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { +String LinkLocalRoster::getRosterName(const DNSSDServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { if (!resolveResult.info.getNick().isEmpty()) { return resolveResult.info.getNick(); } @@ -51,11 +51,11 @@ String LinkLocalRoster::getRosterName(const LinkLocalServiceID& service, const D return service.getName(); } -JID LinkLocalRoster::getJIDForService(const LinkLocalServiceID& service) const { +JID LinkLocalRoster::getJIDForService(const DNSSDServiceID& service) const { return JID(service.getName()); } -boost::shared_ptr<Presence> LinkLocalRoster::getPresence(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& resolveResult) const { +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()) { @@ -73,14 +73,14 @@ boost::shared_ptr<Presence> LinkLocalRoster::getPresence(const LinkLocalServiceI return presence; } -void LinkLocalRoster::handleServiceAdded(const LinkLocalServiceID& service) { +void LinkLocalRoster::handleServiceAdded(const DNSSDServiceID& service) { if (selfService && *selfService == service) { return; } dnsSDService->startResolvingService(service); } -void LinkLocalRoster::handleServiceRemoved(const LinkLocalServiceID& service) { +void LinkLocalRoster::handleServiceRemoved(const DNSSDServiceID& service) { if (selfService && *selfService == service) { return; } @@ -91,7 +91,7 @@ void LinkLocalRoster::handleServiceRemoved(const LinkLocalServiceID& service) { onRosterChanged(roster); } -void LinkLocalRoster::handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result) { +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()); @@ -104,7 +104,7 @@ void LinkLocalRoster::handleServiceResolved(const LinkLocalServiceID& service, c onPresenceChanged(getPresence(service, result)); } -void LinkLocalRoster::handleServiceRegistered(const LinkLocalServiceID& service) { +void LinkLocalRoster::handleServiceRegistered(const DNSSDServiceID& service) { selfService = service; } diff --git a/Swiften/LinkLocal/LinkLocalRoster.h b/Swiften/LinkLocal/LinkLocalRoster.h index 128e39d..03ed2d5 100644 --- a/Swiften/LinkLocal/LinkLocalRoster.h +++ b/Swiften/LinkLocal/LinkLocalRoster.h @@ -28,21 +28,21 @@ namespace Swift { int getPort(const JID&) const; private: - RosterItemPayload getRosterItem(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& info) const; - String getRosterName(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& info) const; - JID getJIDForService(const LinkLocalServiceID& service) const; - boost::shared_ptr<Presence> getPresence(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& info) const; + 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 LinkLocalServiceID& service); - void handleServiceAdded(const LinkLocalServiceID&); - void handleServiceRemoved(const LinkLocalServiceID&); - void handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result); + 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<LinkLocalServiceID> selfService; - typedef std::map<LinkLocalServiceID, DNSSDService::ResolveResult> ServiceMap; + boost::optional<DNSSDServiceID> selfService; + typedef std::map<DNSSDServiceID, DNSSDService::ResolveResult> ServiceMap; ServiceMap services; }; } diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h index 6616303..2c62307 100644 --- a/Swiften/LinkLocal/LinkLocalService.h +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -2,19 +2,19 @@ #include "Swiften/Base/String.h" #include "Swiften/Network/HostAddress.h" -#include "Swiften/LinkLocal/LinkLocalServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { class LinkLocalService { public: LinkLocalService( - const LinkLocalServiceID& id, + const DNSSDServiceID& id, const DNSSDService::ResolveResult& info) : id(id), info(info) {} - const LinkLocalServiceID& getID() const { + const DNSSDServiceID& getID() const { return id; } @@ -35,7 +35,7 @@ namespace Swift { } private: - LinkLocalServiceID id; + DNSSDServiceID id; DNSSDService::ResolveResult info; }; } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index 904f8f0..ab56695 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -6,35 +6,35 @@ namespace Swift { -LinkLocalServiceBrowser::LinkLocalServiceBrowser(DNSSDServiceFactory* factory) { - dnsSDService = factory->createDNSSDService(); +LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier) : querier(querier) { + /*dnsSDService = factory->createDNSSDService(); dnsSDService->onServiceAdded.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceAdded, this, _1)); dnsSDService->onServiceRemoved.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceRemoved, this, _1)); dnsSDService->onServiceResolved.connect( - boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, _1, _2)); + boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, _1, _2));*/ } std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { std::vector<LinkLocalService> result; - for (ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { + /*for (ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { result.push_back(LinkLocalService(i->first, i->second)); - } + }*/ return result; } -void LinkLocalServiceBrowser::handleServiceAdded(const LinkLocalServiceID& service) { +/*void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) { dnsSDService->startResolvingService(service); } -void LinkLocalServiceBrowser::handleServiceRemoved(const LinkLocalServiceID& service) { +void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service) { dnsSDService->stopResolvingService(service); services.erase(service); onServiceRemoved(service); } -void LinkLocalServiceBrowser::handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result) { +void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result) { std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, result)); if (r.second) { onServiceAdded(service); @@ -44,6 +44,6 @@ void LinkLocalServiceBrowser::handleServiceResolved(const LinkLocalServiceID& se onServiceChanged(service); } } - +*/ } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 879b286..10b12b7 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -6,31 +6,31 @@ #include <vector> #include "Swiften/Base/String.h" -#include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/LinkLocal/DNSSDServiceFactory.h" #include "Swiften/LinkLocal/LinkLocalService.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" namespace Swift { class HostAddress; class LinkLocalServiceBrowser { public: - LinkLocalServiceBrowser(DNSSDServiceFactory*); + LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier); std::vector<LinkLocalService> getServices() const; - boost::signal<void (const LinkLocalServiceID&)> onServiceAdded; - boost::signal<void (const LinkLocalServiceID&)> onServiceChanged; - boost::signal<void (const LinkLocalServiceID&)> onServiceRemoved; + boost::signal<void (const DNSSDServiceID&)> onServiceAdded; + boost::signal<void (const DNSSDServiceID&)> onServiceChanged; + boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; private: - void handleServiceAdded(const LinkLocalServiceID&); - void handleServiceRemoved(const LinkLocalServiceID&); - void handleServiceResolved(const LinkLocalServiceID& service, const DNSSDService::ResolveResult& result); + //void handleServiceAdded(const DNSSDServiceID&); + //void handleServiceRemoved(const DNSSDServiceID&); + //void handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result); private: - boost::shared_ptr<DNSSDService> dnsSDService; - typedef std::map<LinkLocalServiceID, DNSSDService::ResolveResult> ServiceMap; - ServiceMap services; + boost::shared_ptr<DNSSDQuerier> querier; + //typedef std::map<DNSSDServiceID, DNSSDService::ResolveResult> ServiceMap; + //ServiceMap services; }; } diff --git a/Swiften/LinkLocal/LinkLocalServiceID.cpp b/Swiften/LinkLocal/LinkLocalServiceID.cpp deleted file mode 100644 index 4248d88..0000000 --- a/Swiften/LinkLocal/LinkLocalServiceID.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "Swiften/LinkLocal/LinkLocalServiceID.h" - -namespace Swift { - -const String LinkLocalServiceID::PresenceServiceType = String("_presence._tcp"); - -} diff --git a/Swiften/LinkLocal/LinkLocalServiceID.h b/Swiften/LinkLocal/LinkLocalServiceID.h deleted file mode 100644 index ca5ba17..0000000 --- a/Swiften/LinkLocal/LinkLocalServiceID.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "Swiften/Base/String.h" - -namespace Swift { - class LinkLocalServiceID { - public: - static const String PresenceServiceType; - - LinkLocalServiceID( - const String& name, - const String& type, - const String& domain = PresenceServiceType, - int networkInterface = 0) : - name(name), - type(type), - domain(domain), - networkInterface(networkInterface) { - } - - bool operator==(const LinkLocalServiceID& o) const { - return name == o.name && type == o.type && domain == o.domain && (networkInterface != 0 && o.networkInterface != 0 ? networkInterface == o.networkInterface : true); - } - - bool operator<(const LinkLocalServiceID& o) const { - if (o.name == name) { - if (o.type == type) { - if (o.domain == domain) { - return networkInterface < o.networkInterface; - } - else { - return domain < o.domain; - } - } - else { - return type < o.type; - } - } - else { - return o.name < name; - } - } - - const String& getName() const { - return name; - } - - const String& getType() const { - return type; - } - - const String& getDomain() const { - return domain; - } - - int getNetworkInterfaceID() const { - return networkInterface; - } - - private: - String name; - String type; - String domain; - int networkInterface; - }; -} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 86a25fd..0980194 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -3,12 +3,11 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/DNSSDService.cpp \ Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ - Swiften/LinkLocal/LinkLocalServiceID.cpp \ Swiften/LinkLocal/LinkLocalServiceInfo.cpp \ - Swiften/LinkLocal/LinkLocalServiceBrowser.cpp \ Swiften/LinkLocal/IncomingLinkLocalSession.cpp \ Swiften/LinkLocal/OutgoingLinkLocalSession.cpp \ Swiften/LinkLocal/LinkLocalConnector.cpp +#Swiften/LinkLocal/LinkLocalServiceBrowser.cpp ifeq ($(HAVE_BONJOUR),yes) SWIFTEN_SOURCES += \ diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc index 9640fa7..abc1180 100644 --- a/Swiften/LinkLocal/UnitTest/Makefile.inc +++ b/Swiften/LinkLocal/UnitTest/Makefile.inc @@ -1,3 +1,2 @@ UNITTEST_SOURCES += \ - Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp \ Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp -- cgit v0.10.2-6-g49f6 From 2b749bb5665adf893188faec1c299e23dd9c6c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sat, 25 Jul 2009 19:38:11 +0200 Subject: Remove obsolete DNSSD factories. diff --git a/Swiften/LinkLocal/DNSSDServiceFactory.cpp b/Swiften/LinkLocal/DNSSDServiceFactory.cpp deleted file mode 100644 index f53660a..0000000 --- a/Swiften/LinkLocal/DNSSDServiceFactory.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "Swiften/LinkLocal/DNSSDServiceFactory.h" - -namespace Swift { - -DNSSDServiceFactory::~DNSSDServiceFactory() { -} - -} diff --git a/Swiften/LinkLocal/DNSSDServiceFactory.h b/Swiften/LinkLocal/DNSSDServiceFactory.h deleted file mode 100644 index 6296165..0000000 --- a/Swiften/LinkLocal/DNSSDServiceFactory.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include <boost/shared_ptr.hpp> - -namespace Swift { - class DNSSDService; - - class DNSSDServiceFactory { - public: - virtual ~DNSSDServiceFactory(); - virtual bool canCreate() const = 0; - - virtual boost::shared_ptr<DNSSDService> createDNSSDService() = 0; - }; -} diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index ab56695..6634a0a 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -2,48 +2,68 @@ #include <iostream> #include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" #include "Swiften/Network/HostAddress.h" namespace Swift { LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier) : querier(querier) { - /*dnsSDService = factory->createDNSSDService(); - dnsSDService->onServiceAdded.connect( + browseQuery = querier->createBrowseQuery(); + browseQuery->onServiceAdded.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceAdded, this, _1)); - dnsSDService->onServiceRemoved.connect( + browseQuery->onServiceRemoved.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceRemoved, this, _1)); - dnsSDService->onServiceResolved.connect( - boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, _1, _2));*/ + browseQuery->startBrowsing(); } +LinkLocalServiceBrowser::~LinkLocalServiceBrowser() { + browseQuery->stopBrowsing(); +} + +/* std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { std::vector<LinkLocalService> result; - /*for (ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { + for (ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { result.push_back(LinkLocalService(i->first, i->second)); - }*/ + } return result; } +*/ -/*void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) { - dnsSDService->startResolvingService(service); +void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) { + boost::shared_ptr<DNSSDResolveServiceQuery> resolveQuery = querier->createResolveServiceQuery(service); + resolveQuery->onServiceResolved.connect( + boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, service, _1)); + std::pair<ResolveQueryMap::iterator, bool> r = resolveQueries.insert(std::make_pair(service, resolveQuery)); + if (!r.second) { + r.first->second = resolveQuery; + } + resolveQuery->start(); } void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service) { - dnsSDService->stopResolvingService(service); - services.erase(service); + ResolveQueryMap::iterator i = resolveQueries.find(service); + assert(i != resolveQueries.end()); + i->second->stop(); + resolveQueries.erase(i); onServiceRemoved(service); } -void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result) { - std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, result)); - if (r.second) { - onServiceAdded(service); +void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& service, const boost::optional<DNSSDResolveServiceQuery::Result>& result) { + if (!result) { + // TODO + std::cerr << "Error resolving" << std::endl; } else { - r.first->second = result; - onServiceChanged(service); + std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, *result)); + if (r.second) { + onServiceAdded(service); + } + else { + r.first->second = *result; + onServiceChanged(service); + } } } -*/ } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 10b12b7..5bd9bf0 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -1,36 +1,41 @@ #pragma once +#include <boost/signal.hpp> #include <boost/shared_ptr.hpp> #include <boost/optional.hpp> #include <map> #include <vector> #include "Swiften/Base/String.h" -#include "Swiften/LinkLocal/LinkLocalService.h" #include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" namespace Swift { - class HostAddress; + //class HostAddress; class LinkLocalServiceBrowser { public: LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier); + ~LinkLocalServiceBrowser(); - std::vector<LinkLocalService> getServices() const; + /*std::vector<LinkLocalService> getServices() const;*/ boost::signal<void (const DNSSDServiceID&)> onServiceAdded; boost::signal<void (const DNSSDServiceID&)> onServiceChanged; boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; private: - //void handleServiceAdded(const DNSSDServiceID&); - //void handleServiceRemoved(const DNSSDServiceID&); - //void handleServiceResolved(const DNSSDServiceID& service, const DNSSDService::ResolveResult& result); + void handleServiceAdded(const DNSSDServiceID&); + void handleServiceRemoved(const DNSSDServiceID&); + void handleServiceResolved(const DNSSDServiceID& service, const boost::optional<DNSSDResolveServiceQuery::Result>& result); private: boost::shared_ptr<DNSSDQuerier> querier; - //typedef std::map<DNSSDServiceID, DNSSDService::ResolveResult> ServiceMap; - //ServiceMap services; + boost::shared_ptr<DNSSDBrowseQuery> browseQuery; + typedef std::map<DNSSDServiceID, boost::shared_ptr<DNSSDResolveServiceQuery> > ResolveQueryMap; + ResolveQueryMap resolveQueries; + typedef std::map<DNSSDServiceID, DNSSDResolveServiceQuery::Result> ServiceMap; + ServiceMap services; }; } diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 0980194..ac3d2a2 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,13 +1,11 @@ SWIFTEN_SOURCES += \ - Swiften/LinkLocal/DNSSDServiceFactory.cpp \ + Swiften/LinkLocal/LinkLocalServiceBrowser.cpp \ Swiften/LinkLocal/DNSSDService.cpp \ - Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp \ Swiften/LinkLocal/LinkLocalRoster.cpp \ Swiften/LinkLocal/LinkLocalServiceInfo.cpp \ Swiften/LinkLocal/IncomingLinkLocalSession.cpp \ Swiften/LinkLocal/OutgoingLinkLocalSession.cpp \ Swiften/LinkLocal/LinkLocalConnector.cpp -#Swiften/LinkLocal/LinkLocalServiceBrowser.cpp ifeq ($(HAVE_BONJOUR),yes) SWIFTEN_SOURCES += \ diff --git a/Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp b/Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp deleted file mode 100644 index df70506..0000000 --- a/Swiften/LinkLocal/PlatformDNSSDServiceFactory.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "Swiften/LinkLocal/PlatformDNSSDServiceFactory.h" - -#include <cassert> - -#ifdef HAVE_SWIFTEN_CONFIG_H -#include "Swiften/config.h" -#endif -#if defined(HAVE_AVAHI) -#include "Swiften/LinkLocal/AvahiDNSSDService.h" -#elif defined(HAVE_BONJOUR) -#include "Swiften/LinkLocal/AppleDNSSDService.h" -#endif - -namespace Swift { - -PlatformDNSSDServiceFactory::PlatformDNSSDServiceFactory() { -} - -bool PlatformDNSSDServiceFactory::canCreate() const { -#if defined(HAVE_AVAHI) || defined(HAVE_BONJOUR) - return true; -#else - return false; -#endif -} - -boost::shared_ptr<DNSSDService> PlatformDNSSDServiceFactory::createDNSSDService() { -#if defined(HAVE_AVAHI) - return boost::shared_ptr<DNSSDService>(new AvahiDNSSDService()); -#elif defined(HAVE_BONJOUR) - return boost::shared_ptr<DNSSDService>(new AppleDNSSDService()); -#else - assert(false); - return boost::shared_ptr<DNSSDService>(); -#endif -} - -} diff --git a/Swiften/LinkLocal/PlatformDNSSDServiceFactory.h b/Swiften/LinkLocal/PlatformDNSSDServiceFactory.h deleted file mode 100644 index 9c4e4e6..0000000 --- a/Swiften/LinkLocal/PlatformDNSSDServiceFactory.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Swiften/LinkLocal/DNSSDServiceFactory.h" - -namespace Swift { - class PlatformDNSSDServiceFactory : public DNSSDServiceFactory { - public: - PlatformDNSSDServiceFactory(); - - bool canCreate() const; - virtual boost::shared_ptr<DNSSDService> createDNSSDService(); - }; -} -- cgit v0.10.2-6-g49f6 From 2833b8f09c9aef09004662a2a89eefbaee1e4247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sun, 26 Jul 2009 00:05:30 +0200 Subject: Implement LinkLocalService. diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h index 2c62307..0c675a3 100644 --- a/Swiften/LinkLocal/LinkLocalService.h +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -1,8 +1,8 @@ #pragma once #include "Swiften/Base/String.h" -#include "Swiften/Network/HostAddress.h" #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" #include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { @@ -10,7 +10,7 @@ namespace Swift { public: LinkLocalService( const DNSSDServiceID& id, - const DNSSDService::ResolveResult& info) : + const DNSSDResolveServiceQuery::Result& info) : id(id), info(info) {} @@ -36,6 +36,6 @@ namespace Swift { private: DNSSDServiceID id; - DNSSDService::ResolveResult info; + DNSSDResolveServiceQuery::Result info; }; } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index 6634a0a..4e9c2de 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -20,7 +20,6 @@ LinkLocalServiceBrowser::~LinkLocalServiceBrowser() { browseQuery->stopBrowsing(); } -/* std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { std::vector<LinkLocalService> result; for (ServiceMap::const_iterator i = services.begin(); i != services.end(); ++i) { @@ -28,7 +27,6 @@ std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { } return result; } -*/ void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) { boost::shared_ptr<DNSSDResolveServiceQuery> resolveQuery = querier->createResolveServiceQuery(service); @@ -50,11 +48,7 @@ void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service } void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& service, const boost::optional<DNSSDResolveServiceQuery::Result>& result) { - if (!result) { - // TODO - std::cerr << "Error resolving" << std::endl; - } - else { + if (result) { std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, *result)); if (r.second) { onServiceAdded(service); diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 5bd9bf0..7ec796a 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -10,16 +10,15 @@ #include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" #include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include "Swiften/LinkLocal/LinkLocalService.h" namespace Swift { - //class HostAddress; - class LinkLocalServiceBrowser { public: LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier); ~LinkLocalServiceBrowser(); - /*std::vector<LinkLocalService> getServices() const;*/ + std::vector<LinkLocalService> getServices() const; boost::signal<void (const DNSSDServiceID&)> onServiceAdded; boost::signal<void (const DNSSDServiceID&)> onServiceChanged; -- cgit v0.10.2-6-g49f6 From 26d623d3cfd8937fb52acf76ef33d230f5010538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sun, 26 Jul 2009 10:21:20 +0200 Subject: Implement fake DNSSD querier. diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h index 62d8606..8e3181e 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -14,14 +14,17 @@ namespace Swift { &sdRef, 0, 0, "_presence._tcp", 0, &BonjourBrowseQuery::handleServiceDiscoveredStatic, this); if (result != kDNSServiceErr_NoError) { - std::cout << "Error" << std::endl; - // TODO + sdRef = NULL; } } void startBrowsing() { - assert(sdRef); - run(); + if (!sdRef) { + MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this()); + } + else { + run(); + } } void stopBrowsing() { @@ -35,7 +38,7 @@ namespace Swift { void handleServiceDiscovered(DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *name, const char *type, const char *domain) { if (errorCode != kDNSServiceErr_NoError) { - return; + MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this()); } else { DNSSDServiceID service(name, type, domain, interfaceIndex); diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp index c065d4d..70fbc7c 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp @@ -22,7 +22,7 @@ BonjourQuerier::BonjourQuerier() : stopRequested(false), thread(0) { } BonjourQuerier::~BonjourQuerier() { - stop(); + assert(!thread); } boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { @@ -64,18 +64,19 @@ void BonjourQuerier::interruptSelect() { } void BonjourQuerier::start() { - stop(); + assert(!thread); thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this())); } void BonjourQuerier::stop() { if (thread) { stopRequested = true; - runningQueries.clear(); // TODO: Is this the right thing to do? + assert(runningQueries.empty()); runningQueriesAvailableEvent.notify_one(); interruptSelect(); thread->join(); delete thread; + thread = NULL; stopRequested = false; } } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h index 9c4db13..41e5831 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -18,13 +18,21 @@ namespace Swift { txtRecord.getSize(), txtRecord.getData(), &BonjourRegisterQuery::handleServiceRegisteredStatic, this); if (result != kDNSServiceErr_NoError) { - // TODO - std::cerr << "Error creating service registration" << std::endl; + sdRef = NULL; } } void registerService() { - run(); + if (sdRef) { + run(); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); + } + } + + void unregisterService() { + stop(); } void updateServiceInfo(const LinkLocalServiceInfo& info) { diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h index 58c6588..6e2a852 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h @@ -19,13 +19,18 @@ namespace Swift { hostname.getUTF8Data(), &BonjourResolveHostnameQuery::handleHostnameResolvedStatic, this); if (result != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this()); + sdRef = NULL; } } //void DNSSDResolveHostnameQuery::run() { void run() { - BonjourQuery::run(); + if (sdRef) { + BonjourQuery::run(); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this()); + } } private: diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h index 1ebd487..8b3f7ec 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -18,12 +18,17 @@ namespace Swift { service.getDomain().getUTF8Data(), &BonjourResolveServiceQuery::handleServiceResolvedStatic, this); if (result != kDNSServiceErr_NoError) { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + sdRef = NULL; } } void start() { - run(); + if (sdRef) { + run(); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } } void stop() { diff --git a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h index 86967ed..9b30858 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h @@ -14,5 +14,6 @@ namespace Swift { boost::signal<void (const DNSSDServiceID&)> onServiceAdded; boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; + boost::signal<void ()> onError; }; } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h index a643880..627cc6b 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h @@ -13,6 +13,7 @@ namespace Swift { virtual ~DNSSDRegisterQuery(); virtual void registerService() = 0; + virtual void unregisterService() = 0; virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0; boost::signal<void (boost::optional<DNSSDServiceID>)> onRegisterFinished; diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h new file mode 100644 index 0000000..5a0b93b --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h" + +namespace Swift { + class FakeDNSSDQuerier; + + class FakeDNSSDBrowseQuery : public DNSSDBrowseQuery, public FakeDNSSDQuery { + public: + FakeDNSSDBrowseQuery(boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier) { + } + + void startBrowsing() { + run(); + } + + void stopBrowsing() { + finish(); + } + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp new file mode 100644 index 0000000..222500a --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp @@ -0,0 +1,92 @@ +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" + +#include <boost/bind.hpp> + +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDBrowseQuery.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h" +#include "Swiften/EventLoop/MainEventLoop.h" + +namespace Swift { + +FakeDNSSDQuerier::FakeDNSSDQuerier() { +} + +boost::shared_ptr<DNSSDBrowseQuery> FakeDNSSDQuerier::createBrowseQuery() { + return boost::shared_ptr<DNSSDBrowseQuery>(new FakeDNSSDBrowseQuery(shared_from_this())); +} + +boost::shared_ptr<DNSSDRegisterQuery> FakeDNSSDQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) { + return boost::shared_ptr<DNSSDRegisterQuery>(new FakeDNSSDRegisterQuery(name, port, info, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveServiceQuery> FakeDNSSDQuerier::createResolveServiceQuery(const DNSSDServiceID& service) { + return boost::shared_ptr<DNSSDResolveServiceQuery>(new FakeDNSSDResolveServiceQuery(service, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveHostnameQuery> FakeDNSSDQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) { + return boost::shared_ptr<DNSSDResolveHostnameQuery>(new FakeDNSSDResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); +} + +void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) { + runningQueries.push_back(query); + if (boost::shared_ptr<FakeDNSSDBrowseQuery> browseQuery = boost::dynamic_pointer_cast<FakeDNSSDBrowseQuery>(query)) { + foreach(const DNSSDServiceID& service, services) { + MainEventLoop::postEvent(boost::bind(boost::ref(browseQuery->onServiceAdded), service), shared_from_this()); + } + } + else if (boost::shared_ptr<FakeDNSSDResolveServiceQuery> resolveQuery = boost::dynamic_pointer_cast<FakeDNSSDResolveServiceQuery>(query)) { + for(ServiceInfoMap::const_iterator i = serviceInfo.begin(); i != serviceInfo.end(); ++i) { + if (i->first == resolveQuery->service) { + MainEventLoop::postEvent(boost::bind(boost::ref(resolveQuery->onServiceResolved), i->second), shared_from_this()); + } + } + } +} + +void FakeDNSSDQuerier::removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) { + runningQueries.erase(std::remove( + runningQueries.begin(), runningQueries.end(), query), runningQueries.end()); +} + +void FakeDNSSDQuerier::addService(const DNSSDServiceID& id) { + services.insert(id); + foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) { + MainEventLoop::postEvent(boost::bind(boost::ref(query->onServiceAdded), id), shared_from_this()); + } +} + +void FakeDNSSDQuerier::removeService(const DNSSDServiceID& id) { + services.erase(id); + serviceInfo.erase(id); + foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) { + MainEventLoop::postEvent(boost::bind(boost::ref(query->onServiceRemoved), id), shared_from_this()); + } +} + +void FakeDNSSDQuerier::setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info) { + std::pair<ServiceInfoMap::iterator, bool> r = serviceInfo.insert(std::make_pair(id, info)); + if (!r.second) { + r.first->second = info; + } + foreach(const boost::shared_ptr<FakeDNSSDResolveServiceQuery>& query, getQueries<FakeDNSSDResolveServiceQuery>()) { + if (query->service == id) { + MainEventLoop::postEvent(boost::bind(boost::ref(query->onServiceResolved), info), shared_from_this()); + } + } +} + +void FakeDNSSDQuerier::setBrowseError() { + foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) { + MainEventLoop::postEvent(boost::ref(query->onError), shared_from_this()); + } +} + +void FakeDNSSDQuerier::setRegisterError() { + foreach(const boost::shared_ptr<FakeDNSSDRegisterQuery>& query, getQueries<FakeDNSSDRegisterQuery>()) { + MainEventLoop::postEvent(boost::bind(boost::ref(query->onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); + } +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h new file mode 100644 index 0000000..6c5f343 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h @@ -0,0 +1,61 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> +#include <list> +#include <set> + +#include "Swiften/Base/foreach.h" +#include "Swiften/EventLoop/EventOwner.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" + +namespace Swift { + class LinkLocalServiceInfo; + class FakeDNSSDQuery; + class FakeDNSSDBrowseQuery; + + class FakeDNSSDQuerier : + public DNSSDQuerier, + public EventOwner, + public boost::enable_shared_from_this<FakeDNSSDQuerier> { + public: + FakeDNSSDQuerier(); + + boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); + boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( + const String& name, int port, const LinkLocalServiceInfo& info); + boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const DNSSDServiceID&); + boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( + const String& hostname, int interfaceIndex); + + void addRunningQuery(boost::shared_ptr<FakeDNSSDQuery>); + void removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery>); + + void addService(const DNSSDServiceID& id); + void removeService(const DNSSDServiceID& id); + void setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info); + + void setBrowseError(); + void setRegisterError(); + + private: + template<typename T> + std::vector< boost::shared_ptr<T> > getQueries() const { + std::vector< boost::shared_ptr<T> > result; + foreach(const boost::shared_ptr<FakeDNSSDQuery>& query, runningQueries) { + if (boost::shared_ptr<T> resultQuery = boost::dynamic_pointer_cast<T>(query)) { + result.push_back(resultQuery); + } + } + return result; + } + + private: + std::list< boost::shared_ptr<FakeDNSSDQuery> > runningQueries; + std::set<DNSSDServiceID> services; + typedef std::map<DNSSDServiceID,DNSSDResolveServiceQuery::Result> ServiceInfoMap; + ServiceInfoMap serviceInfo; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp new file mode 100644 index 0000000..ced7850 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp @@ -0,0 +1,20 @@ +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" + +namespace Swift { + +FakeDNSSDQuery::FakeDNSSDQuery(boost::shared_ptr<FakeDNSSDQuerier> querier) : querier(querier) { +} + +FakeDNSSDQuery::~FakeDNSSDQuery() { +} + +void FakeDNSSDQuery::run() { + querier->addRunningQuery(shared_from_this()); +} + +void FakeDNSSDQuery::finish() { + querier->removeRunningQuery(shared_from_this()); +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h new file mode 100644 index 0000000..9fca1d4 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h @@ -0,0 +1,25 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/enable_shared_from_this.hpp> + +#include "Swiften/EventLoop/EventOwner.h" + +namespace Swift { + class FakeDNSSDQuerier; + + class FakeDNSSDQuery : + public EventOwner, + public boost::enable_shared_from_this<FakeDNSSDQuery> { + public: + FakeDNSSDQuery(boost::shared_ptr<FakeDNSSDQuerier>); + virtual ~FakeDNSSDQuery(); + + protected: + void run(); + void finish(); + + protected: + boost::shared_ptr<FakeDNSSDQuerier> querier; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h new file mode 100644 index 0000000..b4646fd --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h @@ -0,0 +1,31 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/String.h" + +namespace Swift { + class FakeDNSSDQuerier; + + class FakeDNSSDRegisterQuery : public DNSSDRegisterQuery, public FakeDNSSDQuery { + public: + FakeDNSSDRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), name(name), port(port), info(info) { + } + + void registerService() { + run(); + } + + void updateServiceInfo(const LinkLocalServiceInfo&) { + } + + void unregisterService() { + finish(); + } + + String name; + int port; + LinkLocalServiceInfo info; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h new file mode 100644 index 0000000..2ff84d3 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Swiften/Base/String.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" +#include "Swiften/Network/HostAddress.h" + +#include <netinet/in.h> + +namespace Swift { + class FakeDNSSDQuerier; + + class FakeDNSSDResolveHostnameQuery : public DNSSDResolveHostnameQuery, public FakeDNSSDQuery { + public: + FakeDNSSDResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), hostname(hostname), interfaceIndex(interfaceIndex) { + } + + void run() { + FakeDNSSDQuery::run(); + } + + String hostname; + int interfaceIndex; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h new file mode 100644 index 0000000..60d35e5 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveServiceQuery.h @@ -0,0 +1,25 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" + +namespace Swift { + class FakeDNSSDQuerier; + + class FakeDNSSDResolveServiceQuery : public DNSSDResolveServiceQuery, public FakeDNSSDQuery { + public: + FakeDNSSDResolveServiceQuery(const DNSSDServiceID& service, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), service(service) { + } + + void start() { + run(); + } + + void stop() { + finish(); + } + + DNSSDServiceID service; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/Makefile.inc b/Swiften/LinkLocal/DNSSD/Fake/Makefile.inc new file mode 100644 index 0000000..316d061 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/Makefile.inc @@ -0,0 +1,3 @@ +SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.cpp \ + Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp diff --git a/Swiften/LinkLocal/DNSSD/Makefile.inc b/Swiften/LinkLocal/DNSSD/Makefile.inc index 8612fee..3d2c969 100644 --- a/Swiften/LinkLocal/DNSSD/Makefile.inc +++ b/Swiften/LinkLocal/DNSSD/Makefile.inc @@ -11,3 +11,5 @@ include Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc endif ifeq ($(HAVE_AVAHI),yes) endif + +include Swiften/LinkLocal/DNSSD/Fake/Makefile.inc diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index 4e9c2de..aed917a 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -7,17 +7,66 @@ namespace Swift { -LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier) : querier(querier) { +LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier) : querier(querier), haveError(false) { +} + +LinkLocalServiceBrowser::~LinkLocalServiceBrowser() { + assert(!isRunning()); +} + + +void LinkLocalServiceBrowser::start() { + assert(!isRunning()); + haveError = false; browseQuery = querier->createBrowseQuery(); browseQuery->onServiceAdded.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceAdded, this, _1)); browseQuery->onServiceRemoved.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceRemoved, this, _1)); + browseQuery->onError.connect( + boost::bind(&LinkLocalServiceBrowser::handleBrowseError, this)); browseQuery->startBrowsing(); } -LinkLocalServiceBrowser::~LinkLocalServiceBrowser() { +void LinkLocalServiceBrowser::stop() { + assert(isRunning()); + if (isRegistered()) { + unregisterService(); + } + for (ResolveQueryMap::const_iterator i = resolveQueries.begin(); i != resolveQueries.end(); ++i) { + i->second->stop(); + } + resolveQueries.clear(); + services.clear(); browseQuery->stopBrowsing(); + browseQuery.reset(); + onStopped(haveError); +} + +bool LinkLocalServiceBrowser::isRunning() const { + return browseQuery; +} + +bool LinkLocalServiceBrowser::hasError() const { + return haveError; +} + +bool LinkLocalServiceBrowser::isRegistered() const { + return registerQuery; +} + +void LinkLocalServiceBrowser::registerService(const String& name, int port, const LinkLocalServiceInfo& info) { + assert(!registerQuery); + registerQuery = querier->createRegisterQuery(name, port, info); + registerQuery->onRegisterFinished.connect( + boost::bind(&LinkLocalServiceBrowser::handleRegisterFinished, this, _1)); + registerQuery->registerService(); +} + +void LinkLocalServiceBrowser::unregisterService() { + assert(registerQuery); + registerQuery->unregisterService(); + registerQuery.reset(); } std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { @@ -44,6 +93,7 @@ void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service assert(i != resolveQueries.end()); i->second->stop(); resolveQueries.erase(i); + services.erase(service); onServiceRemoved(service); } @@ -60,4 +110,16 @@ void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& servic } } +void LinkLocalServiceBrowser::handleRegisterFinished(const boost::optional<DNSSDServiceID>& result) { + if (!result) { + haveError = true; + stop(); + } +} + +void LinkLocalServiceBrowser::handleBrowseError() { + haveError = true; + stop(); +} + } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 7ec796a..33c9858 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -9,8 +9,10 @@ #include "Swiften/Base/String.h" #include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" #include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" #include "Swiften/LinkLocal/LinkLocalService.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { class LinkLocalServiceBrowser { @@ -18,23 +20,37 @@ namespace Swift { LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> querier); ~LinkLocalServiceBrowser(); + void start(); + void stop(); + bool isRunning() const; + bool hasError() const; + + void registerService(const String& name, int port, const LinkLocalServiceInfo& info = LinkLocalServiceInfo()); + void unregisterService(); + bool isRegistered() const; + std::vector<LinkLocalService> getServices() const; boost::signal<void (const DNSSDServiceID&)> onServiceAdded; boost::signal<void (const DNSSDServiceID&)> onServiceChanged; boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; + boost::signal<void (bool)> onStopped; private: void handleServiceAdded(const DNSSDServiceID&); void handleServiceRemoved(const DNSSDServiceID&); void handleServiceResolved(const DNSSDServiceID& service, const boost::optional<DNSSDResolveServiceQuery::Result>& result); + void handleRegisterFinished(const boost::optional<DNSSDServiceID>&); + void handleBrowseError(); private: boost::shared_ptr<DNSSDQuerier> querier; boost::shared_ptr<DNSSDBrowseQuery> browseQuery; + boost::shared_ptr<DNSSDRegisterQuery> registerQuery; typedef std::map<DNSSDServiceID, boost::shared_ptr<DNSSDResolveServiceQuery> > ResolveQueryMap; ResolveQueryMap resolveQueries; typedef std::map<DNSSDServiceID, DNSSDResolveServiceQuery::Result> ServiceMap; ServiceMap services; + bool haveError; }; } diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 34f797c..7e2dd26 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -5,20 +5,26 @@ #include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" #include "Swiften/LinkLocal/LinkLocalService.h" -#include "Swiften/LinkLocal/UnitTest/MockDNSSDService.h" -#include "Swiften/LinkLocal/DNSSDService.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" #include "Swiften/EventLoop/DummyEventLoop.h" -// Test canCreate() == false - using namespace Swift; class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(LinkLocalServiceBrowserTest); + CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testStart); CPPUNIT_TEST(testServiceAdded); CPPUNIT_TEST(testServiceAdded_NoServiceInfo); CPPUNIT_TEST(testServiceChanged); CPPUNIT_TEST(testServiceRemoved); + CPPUNIT_TEST(testError_BrowseErrorAfterStart); + CPPUNIT_TEST(testError_BrowseErrorAfterResolve); + CPPUNIT_TEST(testRegisterService); + CPPUNIT_TEST(testRegisterService_Error); + CPPUNIT_TEST(testRegisterService_Reregister); CPPUNIT_TEST_SUITE_END(); public: @@ -26,10 +32,10 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { void setUp() { eventLoop = new DummyEventLoop(); - dnsSDServiceFactory = new MockDNSSDServiceFactory(); - testServiceID = new LinkLocalServiceID("foo", "bar.local"); - testServiceInfo = new DNSSDService::ResolveResult("xmpp.bar.local", 1234, LinkLocalServiceInfo()); - testServiceInfo2 = new DNSSDService::ResolveResult("xmpp.foo.local", 2345, LinkLocalServiceInfo()); + querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier()); + testServiceID = new DNSSDServiceID("foo", "bar.local"); + testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo()); + testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo()); } void tearDown() { @@ -40,15 +46,33 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { delete testServiceInfo2; delete testServiceInfo; delete testServiceID; - delete dnsSDServiceFactory; delete eventLoop; } + void testConstructor() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + + CPPUNIT_ASSERT(!testling->isRunning()); + CPPUNIT_ASSERT(!testling->hasError()); + } + + void testStart() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + + CPPUNIT_ASSERT(testling->isRunning()); + CPPUNIT_ASSERT(!testling->hasError()); + + testling->stop(); + } + void testServiceAdded() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); - dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo); - dnsSDService()->addService(*testServiceID); + querier->setServiceInfo(*testServiceID,*testServiceInfo); + querier->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); @@ -60,26 +84,33 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(*testServiceID == services[0].getID()); CPPUNIT_ASSERT(testServiceInfo->port == services[0].getPort()); CPPUNIT_ASSERT(testServiceInfo->host == services[0].getHostname()); + + testling->stop(); } void testServiceAdded_NoServiceInfo() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); - dnsSDService()->addService(*testServiceID); + querier->addService(*testServiceID); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size())); std::vector<LinkLocalService> services = testling->getServices(); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size())); + + testling->stop(); } void testServiceChanged() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); - dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo); - dnsSDService()->addService(*testServiceID); + testling->start(); + querier->setServiceInfo(*testServiceID,*testServiceInfo); + querier->addService(*testServiceID); eventLoop->processEvents(); - dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo2); + querier->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); @@ -91,31 +122,93 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(*testServiceID == services[0].getID()); CPPUNIT_ASSERT(testServiceInfo2->port == services[0].getPort()); CPPUNIT_ASSERT(testServiceInfo2->host == services[0].getHostname()); + + testling->stop(); } void testServiceRemoved() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); - dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo); - dnsSDService()->addService(*testServiceID); + testling->start(); + querier->setServiceInfo(*testServiceID,*testServiceInfo); + querier->addService(*testServiceID); eventLoop->processEvents(); - dnsSDService()->removeService(*testServiceID); + querier->removeService(*testServiceID); eventLoop->processEvents(); - dnsSDService()->setServiceInfo(*testServiceID,*testServiceInfo2); + querier->setServiceInfo(*testServiceID,*testServiceInfo2); eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(removedServices.size())); CPPUNIT_ASSERT(removedServices[0] == *testServiceID); - std::vector<LinkLocalService> services = testling->getServices(); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size())); + + testling->stop(); + } + + void testError_BrowseErrorAfterStart() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + + querier->setBrowseError(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(!testling->isRunning()); + CPPUNIT_ASSERT(testling->hasError()); + } + + void testError_BrowseErrorAfterResolve() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + querier->setServiceInfo(*testServiceID,*testServiceInfo); + querier->addService(*testServiceID); + eventLoop->processEvents(); + + querier->setBrowseError(); + eventLoop->processEvents(); + querier->setServiceInfo(*testServiceID,*testServiceInfo2); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(!testling->isRunning()); + CPPUNIT_ASSERT(testling->hasError()); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); + } + + void testRegisterService() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + + testling->stop(); + } + + void testRegisterService_Error() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + testling->registerService("", 1234); + eventLoop->processEvents(); + + querier->setRegisterError(); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(!testling->isRunning()); + CPPUNIT_ASSERT(testling->hasError()); + } + + void testRegisterService_Reregister() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + + testling->stop(); } private: boost::shared_ptr<LinkLocalServiceBrowser> createTestling() { boost::shared_ptr<LinkLocalServiceBrowser> testling( - new LinkLocalServiceBrowser(dnsSDServiceFactory)); + new LinkLocalServiceBrowser(querier)); testling->onServiceAdded.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceAdded, this, _1)); testling->onServiceChanged.connect(boost::bind( @@ -125,32 +218,27 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { return testling; } - void handleServiceAdded(const LinkLocalServiceID& service) { + void handleServiceAdded(const DNSSDServiceID& service) { addedServices.push_back(service); } - void handleServiceRemoved(const LinkLocalServiceID& service) { + void handleServiceRemoved(const DNSSDServiceID& service) { removedServices.push_back(service); } - void handleServiceChanged(const LinkLocalServiceID& service) { + void handleServiceChanged(const DNSSDServiceID& service) { changedServices.push_back(service); } - boost::shared_ptr<MockDNSSDService> dnsSDService() const { - CPPUNIT_ASSERT(dnsSDServiceFactory->services.size() > 0); - return dnsSDServiceFactory->services[0]; - } - private: DummyEventLoop* eventLoop; - MockDNSSDServiceFactory* dnsSDServiceFactory; - std::vector<LinkLocalServiceID> addedServices; - std::vector<LinkLocalServiceID> changedServices; - std::vector<LinkLocalServiceID> removedServices; - LinkLocalServiceID* testServiceID; - DNSSDService::ResolveResult* testServiceInfo; - DNSSDService::ResolveResult* testServiceInfo2; + boost::shared_ptr<FakeDNSSDQuerier> querier; + std::vector<DNSSDServiceID> addedServices; + std::vector<DNSSDServiceID> changedServices; + std::vector<DNSSDServiceID> removedServices; + DNSSDServiceID* testServiceID; + DNSSDResolveServiceQuery::Result* testServiceInfo; + DNSSDResolveServiceQuery::Result* testServiceInfo2; }; CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceBrowserTest); diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc index abc1180..9640fa7 100644 --- a/Swiften/LinkLocal/UnitTest/Makefile.inc +++ b/Swiften/LinkLocal/UnitTest/Makefile.inc @@ -1,2 +1,3 @@ UNITTEST_SOURCES += \ + Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp \ Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp diff --git a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h b/Swiften/LinkLocal/UnitTest/MockDNSSDService.h deleted file mode 100644 index 69ac06d..0000000 --- a/Swiften/LinkLocal/UnitTest/MockDNSSDService.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include <vector> -#include <map> -#include <boost/bind.hpp> - -#include "Swiften/EventLoop/MainEventLoop.h" -#include "Swiften/LinkLocal/DNSSDService.h" -#include "Swiften/LinkLocal/DNSSDServiceFactory.h" - -namespace Swift { - class MockDNSSDService : public DNSSDService { - public: - MockDNSSDService() { - } - - void start() { - } - - void stop() { - } - - virtual void registerService(const String&, int, const LinkLocalServiceInfo&) { - assert(false); - } - - virtual void updateService(const LinkLocalServiceInfo&) { - assert(false); - } - - virtual void unregisterService() { - assert(false); - } - - virtual void startResolvingService(const LinkLocalServiceID& id) { - resolvingServices.push_back(id); - broadcastServiceInfo(id); - } - - virtual void stopResolvingService(const LinkLocalServiceID& id) { - resolvingServices.erase(std::remove(resolvingServices.begin(), resolvingServices.end(), id), resolvingServices.end()); - } - - virtual void resolveHostname(const String&, int) { - assert(false); - } - - void addService(const LinkLocalServiceID& id) { - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), id)); - } - - void removeService(const LinkLocalServiceID& id) { - serviceInfo.erase(id); - MainEventLoop::postEvent(boost::bind(boost::ref(onServiceRemoved), id)); - } - - void setServiceInfo(const LinkLocalServiceID& id, const DNSSDService::ResolveResult& info) { - std::pair<ServiceInfoMap::iterator, bool> r = serviceInfo.insert(std::make_pair(id, info)); - if (!r.second) { - r.first->second = info; - } - broadcastServiceInfo(id); - } - - private: - void broadcastServiceInfo(const LinkLocalServiceID& id) { - if (std::find(resolvingServices.begin(), resolvingServices.end(), id) != resolvingServices.end()) { - ServiceInfoMap::const_iterator i = serviceInfo.find(id); - if (i != serviceInfo.end()) { - MainEventLoop::postEvent( - boost::bind(boost::ref(onServiceResolved), id, i->second)); - } - } - } - - private: - typedef std::map<LinkLocalServiceID,DNSSDService::ResolveResult> ServiceInfoMap; - ServiceInfoMap serviceInfo; - std::vector<LinkLocalServiceID> resolvingServices; - }; - - class MockDNSSDServiceFactory : public DNSSDServiceFactory { - public: - boost::shared_ptr<DNSSDService> createDNSSDService() { - boost::shared_ptr<MockDNSSDService> result(new MockDNSSDService()); - services.push_back(result); - return result; - } - - bool canCreate() const { - return true; - } - - std::vector<boost::shared_ptr<MockDNSSDService> > services; - }; - -} -- cgit v0.10.2-6-g49f6 From e7ab68e8daf120d932d9eefc9053e9e064ca29af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sun, 26 Jul 2009 17:06:11 +0200 Subject: Make DNSSD independent of LinkLocalServiceInfo. diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp index 70fbc7c..9c9e64e 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp @@ -29,7 +29,7 @@ boost::shared_ptr<DNSSDBrowseQuery> BonjourQuerier::createBrowseQuery() { return boost::shared_ptr<DNSSDBrowseQuery>(new BonjourBrowseQuery(shared_from_this())); } -boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) { +boost::shared_ptr<DNSSDRegisterQuery> BonjourQuerier::createRegisterQuery(const String& name, int port, const ByteArray& info) { return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h index 644a8d9..d12f94f 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h @@ -10,7 +10,7 @@ #include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" namespace Swift { - class LinkLocalServiceInfo; + class ByteArray; class BonjourQuerier : public DNSSDQuerier, @@ -21,7 +21,7 @@ namespace Swift { boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( - const String& name, int port, const LinkLocalServiceInfo& info); + const String& name, int port, const ByteArray& info); boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( const DNSSDServiceID&); boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h index 41e5831..c85b90f 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -2,7 +2,6 @@ #include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" #include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" #include "Swiften/Base/ByteArray.h" #include "Swiften/EventLoop/MainEventLoop.h" @@ -11,8 +10,7 @@ namespace Swift { class BonjourRegisterQuery : public DNSSDRegisterQuery, public BonjourQuery { public: - BonjourRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { - ByteArray txtRecord = info.toTXTRecord(); + BonjourRegisterQuery(const String& name, int port, const ByteArray& txtRecord, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { DNSServiceErrorType result = DNSServiceRegister( &sdRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, txtRecord.getSize(), txtRecord.getData(), @@ -35,9 +33,8 @@ namespace Swift { stop(); } - void updateServiceInfo(const LinkLocalServiceInfo& info) { + void updateServiceInfo(const ByteArray& txtRecord) { boost::lock_guard<boost::mutex> lock(sdRefMutex); - ByteArray txtRecord = info.toTXTRecord(); DNSServiceUpdateRecord(sdRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0); } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h index 6c7b576..799bc0c 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h @@ -4,7 +4,7 @@ namespace Swift { class String; - class LinkLocalServiceInfo; + class ByteArray; class DNSSDServiceID; class DNSSDBrowseQuery; class DNSSDRegisterQuery; @@ -17,7 +17,7 @@ namespace Swift { virtual boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery() = 0; virtual boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( - const String& name, int port, const LinkLocalServiceInfo& info) = 0; + const String& name, int port, const ByteArray& info) = 0; virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( const DNSSDServiceID&) = 0; virtual boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( diff --git a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h index 627cc6b..4a04fa9 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h @@ -6,7 +6,7 @@ #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" namespace Swift { - class LinkLocalServiceInfo; + class ByteArray; class DNSSDRegisterQuery { public: @@ -14,7 +14,7 @@ namespace Swift { virtual void registerService() = 0; virtual void unregisterService() = 0; - virtual void updateServiceInfo(const LinkLocalServiceInfo& info) = 0; + virtual void updateServiceInfo(const ByteArray& info) = 0; boost::signal<void (boost::optional<DNSSDServiceID>)> onRegisterFinished; }; diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h index f79b537..217e396 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h @@ -4,19 +4,18 @@ #include <boost/optional.hpp> #include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" namespace Swift { class DNSSDResolveServiceQuery { public: struct Result { - Result(const String& fullName, const String& host, int port, - const LinkLocalServiceInfo& info) : + Result(const String& fullName, const String& host, int port, const ByteArray& info) : fullName(fullName), host(host), port(port), info(info) {} String fullName; String host; int port; - LinkLocalServiceInfo info; + ByteArray info; }; virtual ~DNSSDResolveServiceQuery(); diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp index 222500a..88c7774 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp @@ -17,7 +17,7 @@ boost::shared_ptr<DNSSDBrowseQuery> FakeDNSSDQuerier::createBrowseQuery() { return boost::shared_ptr<DNSSDBrowseQuery>(new FakeDNSSDBrowseQuery(shared_from_this())); } -boost::shared_ptr<DNSSDRegisterQuery> FakeDNSSDQuerier::createRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info) { +boost::shared_ptr<DNSSDRegisterQuery> FakeDNSSDQuerier::createRegisterQuery(const String& name, int port, const ByteArray& info) { return boost::shared_ptr<DNSSDRegisterQuery>(new FakeDNSSDRegisterQuery(name, port, info, shared_from_this())); } diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h index 6c5f343..43b717e 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h @@ -11,7 +11,7 @@ #include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" namespace Swift { - class LinkLocalServiceInfo; + class ByteArray; class FakeDNSSDQuery; class FakeDNSSDBrowseQuery; @@ -24,7 +24,7 @@ namespace Swift { boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( - const String& name, int port, const LinkLocalServiceInfo& info); + const String& name, int port, const ByteArray& info); boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( const DNSSDServiceID&); boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h index b4646fd..82ec623 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h @@ -2,7 +2,7 @@ #include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" #include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" -#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/Base/ByteArray.h" #include "Swiften/Base/String.h" namespace Swift { @@ -10,14 +10,15 @@ namespace Swift { class FakeDNSSDRegisterQuery : public DNSSDRegisterQuery, public FakeDNSSDQuery { public: - FakeDNSSDRegisterQuery(const String& name, int port, const LinkLocalServiceInfo& info, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), name(name), port(port), info(info) { + FakeDNSSDRegisterQuery(const String& name, int port, const ByteArray& info, boost::shared_ptr<FakeDNSSDQuerier> querier) : FakeDNSSDQuery(querier), name(name), port(port), info(info) { } void registerService() { run(); } - void updateServiceInfo(const LinkLocalServiceInfo&) { + void updateServiceInfo(const ByteArray& i) { + info = i; } void unregisterService() { @@ -26,6 +27,6 @@ namespace Swift { String name; int port; - LinkLocalServiceInfo info; + ByteArray info; }; } diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h index 0c675a3..37f2130 100644 --- a/Swiften/LinkLocal/LinkLocalService.h +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -30,8 +30,8 @@ namespace Swift { return info.host; } - const LinkLocalServiceInfo& getInfo() const { - return info.info; + LinkLocalServiceInfo getInfo() const { + return LinkLocalServiceInfo::createFromTXTRecord(info.info); } private: diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index aed917a..265acc1 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -57,7 +57,7 @@ bool LinkLocalServiceBrowser::isRegistered() const { void LinkLocalServiceBrowser::registerService(const String& name, int port, const LinkLocalServiceInfo& info) { assert(!registerQuery); - registerQuery = querier->createRegisterQuery(name, port, info); + registerQuery = querier->createRegisterQuery(name, port, info.toTXTRecord()); registerQuery->onRegisterFinished.connect( boost::bind(&LinkLocalServiceBrowser::handleRegisterFinished, this, _1)); registerQuery->registerService(); diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 7e2dd26..ab42834 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -34,8 +34,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop = new DummyEventLoop(); querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier()); testServiceID = new DNSSDServiceID("foo", "bar.local"); - testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo()); - testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo()); + testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo().toTXTRecord()); + testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo().toTXTRecord()); } void tearDown() { -- cgit v0.10.2-6-g49f6 From 81ea0a6b0ea85c55c2f166b69da652aaab2ef79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sun, 26 Jul 2009 17:23:28 +0200 Subject: Test LinkLocal service registration. diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h index 8e3181e..be0c921 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -41,7 +41,7 @@ namespace Swift { MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this()); } else { - DNSSDServiceID service(name, type, domain, interfaceIndex); + DNSSDServiceID service(name, domain, type, interfaceIndex); if (flags & kDNSServiceFlagsAdd) { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h index b1986d3..5243662 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h @@ -9,31 +9,31 @@ namespace Swift { DNSSDServiceID( const String& name, - const String& type, - const String& domain = PresenceServiceType, + const String& domain, + const String& type = PresenceServiceType, int networkInterface = 0) : name(name), - type(type), domain(domain), + type(type), networkInterface(networkInterface) { } bool operator==(const DNSSDServiceID& o) const { - return name == o.name && type == o.type && domain == o.domain && (networkInterface != 0 && o.networkInterface != 0 ? networkInterface == o.networkInterface : true); + return name == o.name && domain == o.domain && type == o.type && (networkInterface != 0 && o.networkInterface != 0 ? networkInterface == o.networkInterface : true); } bool operator<(const DNSSDServiceID& o) const { if (o.name == name) { - if (o.type == type) { - if (o.domain == domain) { + if (o.domain == domain) { + if (o.type == type) { return networkInterface < o.networkInterface; } else { - return domain < o.domain; + return type < o.type; } } else { - return type < o.type; + return domain < o.domain; } } else { @@ -45,22 +45,22 @@ namespace Swift { return name; } - const String& getType() const { - return type; - } - const String& getDomain() const { return domain; } + const String& getType() const { + return type; + } + int getNetworkInterfaceID() const { return networkInterface; } private: String name; - String type; String domain; + String type; int networkInterface; }; } diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp index 88c7774..5079192 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp @@ -10,7 +10,7 @@ namespace Swift { -FakeDNSSDQuerier::FakeDNSSDQuerier() { +FakeDNSSDQuerier::FakeDNSSDQuerier(const String& domain) : domain(domain) { } boost::shared_ptr<DNSSDBrowseQuery> FakeDNSSDQuerier::createBrowseQuery() { @@ -43,6 +43,10 @@ void FakeDNSSDQuerier::addRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) } } } + else if (boost::shared_ptr<FakeDNSSDRegisterQuery> registerQuery = boost::dynamic_pointer_cast<FakeDNSSDRegisterQuery>(query)) { + DNSSDServiceID service(registerQuery->name, domain); + MainEventLoop::postEvent(boost::bind(boost::ref(registerQuery->onRegisterFinished), service), shared_from_this()); + } } void FakeDNSSDQuerier::removeRunningQuery(boost::shared_ptr<FakeDNSSDQuery> query) { @@ -77,6 +81,15 @@ void FakeDNSSDQuerier::setServiceInfo(const DNSSDServiceID& id, const DNSSDResol } } +bool FakeDNSSDQuerier::isServiceRegistered(const String& name, int port, const ByteArray& info) { + foreach(const boost::shared_ptr<FakeDNSSDRegisterQuery>& query, getQueries<FakeDNSSDRegisterQuery>()) { + if (query->name == name && query->port == port && query->info == info) { + return true; + } + } + return false; +} + void FakeDNSSDQuerier::setBrowseError() { foreach(const boost::shared_ptr<FakeDNSSDBrowseQuery>& query, getQueries<FakeDNSSDBrowseQuery>()) { MainEventLoop::postEvent(boost::ref(query->onError), shared_from_this()); diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h index 43b717e..f2ec17b 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h @@ -20,7 +20,7 @@ namespace Swift { public EventOwner, public boost::enable_shared_from_this<FakeDNSSDQuerier> { public: - FakeDNSSDQuerier(); + FakeDNSSDQuerier(const String& domain); boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( @@ -36,6 +36,7 @@ namespace Swift { void addService(const DNSSDServiceID& id); void removeService(const DNSSDServiceID& id); void setServiceInfo(const DNSSDServiceID& id, const DNSSDResolveServiceQuery::Result& info); + bool isServiceRegistered(const String& name, int port, const ByteArray& info); void setBrowseError(); void setRegisterError(); @@ -53,6 +54,7 @@ namespace Swift { } private: + String domain; std::list< boost::shared_ptr<FakeDNSSDQuery> > runningQueries; std::set<DNSSDServiceID> services; typedef std::map<DNSSDServiceID,DNSSDResolveServiceQuery::Result> ServiceInfoMap; diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index 265acc1..f7c5478 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -11,7 +11,9 @@ LinkLocalServiceBrowser::LinkLocalServiceBrowser(boost::shared_ptr<DNSSDQuerier> } LinkLocalServiceBrowser::~LinkLocalServiceBrowser() { - assert(!isRunning()); + if (isRunning()) { + std::cerr << "WARNING: LinkLocalServiceBrowser still running on destruction" << std::endl; + } } @@ -67,6 +69,7 @@ void LinkLocalServiceBrowser::unregisterService() { assert(registerQuery); registerQuery->unregisterService(); registerQuery.reset(); + selfService.reset(); } std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { @@ -78,6 +81,9 @@ std::vector<LinkLocalService> LinkLocalServiceBrowser::getServices() const { } void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) { + if (selfService && service == *selfService) { + return; + } boost::shared_ptr<DNSSDResolveServiceQuery> resolveQuery = querier->createResolveServiceQuery(service); resolveQuery->onServiceResolved.connect( boost::bind(&LinkLocalServiceBrowser::handleServiceResolved, this, service, _1)); @@ -89,6 +95,9 @@ void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) } void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service) { + if (selfService && service == *selfService) { + return; + } ResolveQueryMap::iterator i = resolveQueries.find(service); assert(i != resolveQueries.end()); i->second->stop(); @@ -111,7 +120,10 @@ void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& servic } void LinkLocalServiceBrowser::handleRegisterFinished(const boost::optional<DNSSDServiceID>& result) { - if (!result) { + if (result) { + selfService = result; + } + else { haveError = true; stop(); } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index 33c9858..dcdd576 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -45,6 +45,7 @@ namespace Swift { private: boost::shared_ptr<DNSSDQuerier> querier; + boost::optional<DNSSDServiceID> selfService; boost::shared_ptr<DNSSDBrowseQuery> browseQuery; boost::shared_ptr<DNSSDRegisterQuery> registerQuery; typedef std::map<DNSSDServiceID, boost::shared_ptr<DNSSDResolveServiceQuery> > ResolveQueryMap; diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index ab42834..4b66398 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -18,6 +18,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testStart); CPPUNIT_TEST(testServiceAdded); CPPUNIT_TEST(testServiceAdded_NoServiceInfo); + CPPUNIT_TEST(testServiceAdded_RegisteredService); + CPPUNIT_TEST(testServiceAdded_UnregisteredService); CPPUNIT_TEST(testServiceChanged); CPPUNIT_TEST(testServiceRemoved); CPPUNIT_TEST(testError_BrowseErrorAfterStart); @@ -32,10 +34,14 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { void setUp() { eventLoop = new DummyEventLoop(); - querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier()); + querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier("wonderland.lit")); + aliceServiceID = new DNSSDServiceID("alice", "wonderland.lit"); + aliceServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.wonderland.lit", "xmpp.wonderland.lit", 1234, LinkLocalServiceInfo().toTXTRecord()); testServiceID = new DNSSDServiceID("foo", "bar.local"); testServiceInfo = new DNSSDResolveServiceQuery::Result("_presence._tcp.bar.local", "xmpp.bar.local", 1234, LinkLocalServiceInfo().toTXTRecord()); testServiceInfo2 = new DNSSDResolveServiceQuery::Result("_presence.tcp.bar.local", "xmpp.foo.local", 2345, LinkLocalServiceInfo().toTXTRecord()); + errorStopReceived = false; + normalStopReceived = false; } void tearDown() { @@ -97,8 +103,50 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size())); + + testling->stop(); + } + + void testServiceAdded_RegisteredService() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + + testling->registerService("alice", 1234, LinkLocalServiceInfo()); + eventLoop->processEvents(); + querier->setServiceInfo(*aliceServiceID, *aliceServiceInfo); + querier->addService(*aliceServiceID); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(addedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size())); + + testling->stop(); + } + + void testServiceAdded_UnregisteredService() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + testling->registerService("alice", 1234, LinkLocalServiceInfo()); + eventLoop->processEvents(); + testling->unregisterService(); + eventLoop->processEvents(); + + querier->setServiceInfo(*aliceServiceID, *aliceServiceInfo); + querier->addService(*aliceServiceID); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); + CPPUNIT_ASSERT(addedServices[0] == *aliceServiceID); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); std::vector<LinkLocalService> services = testling->getServices(); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(services.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(services.size())); + CPPUNIT_ASSERT(*aliceServiceID == services[0].getID()); + CPPUNIT_ASSERT(aliceServiceInfo->port == services[0].getPort()); + CPPUNIT_ASSERT(aliceServiceInfo->host == services[0].getHostname()); testling->stop(); } @@ -156,6 +204,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(testling->hasError()); + CPPUNIT_ASSERT(errorStopReceived); } void testError_BrowseErrorAfterResolve() { @@ -174,6 +223,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(testling->hasError()); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size())); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); + CPPUNIT_ASSERT(errorStopReceived); } void testRegisterService() { @@ -181,13 +231,21 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { testling->start(); eventLoop->processEvents(); + LinkLocalServiceInfo info; + info.setFirstName("Foo"); + testling->registerService("foo@bar", 1234, info); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); + testling->stop(); } void testRegisterService_Error() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); testling->start(); - testling->registerService("", 1234); + LinkLocalServiceInfo info; + testling->registerService("foo@bar", 1234, info); eventLoop->processEvents(); querier->setRegisterError(); @@ -195,12 +253,26 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(!testling->isRunning()); CPPUNIT_ASSERT(testling->hasError()); + CPPUNIT_ASSERT(errorStopReceived); + CPPUNIT_ASSERT(!querier->isServiceRegistered("foo@bar", 1234, info.toTXTRecord())); } void testRegisterService_Reregister() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); testling->start(); eventLoop->processEvents(); + LinkLocalServiceInfo info; + info.setFirstName("Foo"); + testling->registerService("foo@bar", 1234, info); + eventLoop->processEvents(); + testling->unregisterService(); + eventLoop->processEvents(); + + info.setFirstName("Bar"); + testling->registerService("bar@baz", 3456, info); + eventLoop->processEvents(); + + CPPUNIT_ASSERT(querier->isServiceRegistered("bar@baz", 3456, info.toTXTRecord())); testling->stop(); } @@ -215,6 +287,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { &LinkLocalServiceBrowserTest::handleServiceChanged, this, _1)); testling->onServiceRemoved.connect(boost::bind( &LinkLocalServiceBrowserTest::handleServiceRemoved, this, _1)); + testling->onStopped.connect(boost::bind( + &LinkLocalServiceBrowserTest::handleStopped, this, _1)); return testling; } @@ -230,15 +304,30 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { changedServices.push_back(service); } + void handleStopped(bool error) { + CPPUNIT_ASSERT(!errorStopReceived); + CPPUNIT_ASSERT(!normalStopReceived); + if (error) { + errorStopReceived = true; + } + else { + normalStopReceived = true; + } + } + private: DummyEventLoop* eventLoop; boost::shared_ptr<FakeDNSSDQuerier> querier; std::vector<DNSSDServiceID> addedServices; std::vector<DNSSDServiceID> changedServices; std::vector<DNSSDServiceID> removedServices; + DNSSDServiceID* aliceServiceID; + DNSSDResolveServiceQuery::Result* aliceServiceInfo; DNSSDServiceID* testServiceID; DNSSDResolveServiceQuery::Result* testServiceInfo; DNSSDResolveServiceQuery::Result* testServiceInfo2; + bool errorStopReceived; + bool normalStopReceived; }; CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceBrowserTest); -- cgit v0.10.2-6-g49f6 From 4e2cb67ac26ca338a4bd7676683186f543903c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Sun, 26 Jul 2009 22:52:45 +0200 Subject: Fix bonjour compilation. diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h index c85b90f..34d5742 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -30,7 +30,7 @@ namespace Swift { } void unregisterService() { - stop(); + finish(); } void updateServiceInfo(const ByteArray& txtRecord) { diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h index 8b3f7ec..d16ca5b 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -49,8 +49,7 @@ namespace Swift { boost::bind( boost::ref(onServiceResolved), Result(String(fullName), String(host), port, - LinkLocalServiceInfo::createFromTXTRecord( - ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen)))), + ByteArray(reinterpret_cast<const char*>(txtRecord), txtLen))), shared_from_this()); } } -- cgit v0.10.2-6-g49f6 From 644bcda4cb795944cc5d5df53b3c0392450239df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Mon, 27 Jul 2009 20:32:51 +0200 Subject: Improve LinkLocalServiceInfo unit test. diff --git a/Slimber/Server.cpp b/Slimber/Server.cpp index c3c3d22..39f4233 100644 --- a/Slimber/Server.cpp +++ b/Slimber/Server.cpp @@ -69,7 +69,7 @@ void Server::handleNewLinkLocalConnection(boost::shared_ptr<Connection> connecti registerLinkLocalSession(session); } -void Server::handleServiceRegistered(const LinkLocalServiceID& service) { +void Server::handleServiceRegistered(const DNSSDServiceID& service) { std::cout << "Service registered " << service.getName() << " " << service.getType() << " " << service.getDomain() << std::endl; selfJID_ = JID(service.getName()); } diff --git a/Slimber/Server.h b/Slimber/Server.h index b40f576..9167106 100644 --- a/Slimber/Server.h +++ b/Slimber/Server.h @@ -33,7 +33,7 @@ namespace Swift { private: void handleNewClientConnection(boost::shared_ptr<Connection> c); void handleNewLinkLocalConnection(boost::shared_ptr<Connection> connection); - void handleServiceRegistered(const LinkLocalServiceID& service); + void handleServiceRegistered(const DNSSDServiceID& service); void handleSessionStarted(); void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>); void handleLinkLocalSessionFinished(boost::shared_ptr<Session> session); diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp index 06a5b81..b360ee5 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp @@ -2,6 +2,6 @@ namespace Swift { -const String DNSSDServiceID::PresenceServiceType = String("_presence._tcp"); +const char* DNSSDServiceID::PresenceServiceType = "_presence._tcp"; } diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h index 5243662..ba7828b 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h @@ -5,7 +5,7 @@ namespace Swift { class DNSSDServiceID { public: - static const String PresenceServiceType; + static const char* PresenceServiceType; DNSSDServiceID( const String& name, diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 4b66398..e9501cb 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -49,6 +49,8 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { removedServices.clear(); changedServices.clear(); + delete aliceServiceID; + delete aliceServiceInfo; delete testServiceInfo2; delete testServiceInfo; delete testServiceID; diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp index b850f14..68f191a 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp @@ -10,6 +10,7 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { CPPUNIT_TEST(testGetTXTRecord); CPPUNIT_TEST(testCreateFromTXTRecord); CPPUNIT_TEST(testCreateFromTXTRecord_InvalidSize); + CPPUNIT_TEST(testGetTXTRecordCreateFromTXTRecord_RoundTrip); CPPUNIT_TEST_SUITE_END(); public: @@ -37,6 +38,28 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(String("a"), info.getLastName()); } + + void testGetTXTRecordCreateFromTXTRecord_RoundTrip() { + LinkLocalServiceInfo info; + info.setFirstName("Remko"); + info.setLastName("Tron\xc3\xe7on"); + info.setEMail("remko-email@swift.im"); + info.setJID(JID("remko-jid@swift.im")); + info.setMessage("I'm busy"); + info.setNick("el-tramo"); + info.setStatus(LinkLocalServiceInfo::DND); + info.setPort(1234); + + LinkLocalServiceInfo info2 = LinkLocalServiceInfo::createFromTXTRecord(info.toTXTRecord()); + CPPUNIT_ASSERT_EQUAL(info.getFirstName(), info2.getFirstName()); + CPPUNIT_ASSERT_EQUAL(info.getLastName(), info2.getLastName()); + CPPUNIT_ASSERT_EQUAL(info.getEMail(), info2.getEMail()); + CPPUNIT_ASSERT_EQUAL(info.getJID(), info2.getJID()); + CPPUNIT_ASSERT_EQUAL(info.getMessage(), info2.getMessage()); + CPPUNIT_ASSERT_EQUAL(info.getNick(), info2.getNick()); + CPPUNIT_ASSERT(info.getStatus() == info2.getStatus()); + CPPUNIT_ASSERT(info.getPort() == info2.getPort()); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceInfoTest); -- cgit v0.10.2-6-g49f6 From 4b809245dd6a1236dda99ab780485599434a419a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Mon, 27 Jul 2009 20:33:30 +0200 Subject: Add beginnings of AvahiQuerier. diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp new file mode 100644 index 0000000..55ccede --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp @@ -0,0 +1,59 @@ +#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h" + +#include <iostream> + +//#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiBrowseQuery.h" +//#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiRegisterQuery.h" +//#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveServiceQuery.h" +//#include "Swiften/LinkLocal/DNSSD/Avahi/AvahiResolveHostnameQuery.h" +//#include "Swiften/Base/foreach.h" + +namespace Swift { + +AvahiQuerier::AvahiQuerier() : client(NULL), threadedPoll(NULL) { +} + +AvahiQuerier::~AvahiQuerier() { +} + +boost::shared_ptr<DNSSDBrowseQuery> AvahiQuerier::createBrowseQuery() { + //return boost::shared_ptr<DNSSDBrowseQuery>(new AvahiBrowseQuery(shared_from_this())); +} + +boost::shared_ptr<DNSSDRegisterQuery> AvahiQuerier::createRegisterQuery(const String& name, int port, const ByteArray& info) { + //return boost::shared_ptr<DNSSDRegisterQuery>(new AvahiRegisterQuery(name, port, info, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveServiceQuery> AvahiQuerier::createResolveServiceQuery(const DNSSDServiceID& service) { + //return boost::shared_ptr<DNSSDResolveServiceQuery>(new AvahiResolveServiceQuery(service, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveHostnameQuery> AvahiQuerier::createResolveHostnameQuery(const String& hostname, int interfaceIndex) { + //return boost::shared_ptr<DNSSDResolveHostnameQuery>(new AvahiResolveHostnameQuery(hostname, interfaceIndex, shared_from_this())); +} + +void AvahiQuerier::start() { + assert(!threadedPoll); + threadedPoll = avahi_threaded_poll_new(); + int error; + assert(!client); + 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; + } + avahi_threaded_poll_start(threadedPoll); +} + +void AvahiQuerier::stop() { + assert(threadedPoll); + avahi_threaded_poll_stop(threadedPoll); + assert(client); + avahi_client_free(client); + avahi_threaded_poll_free(threadedPoll); +} + +} diff --git a/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h new file mode 100644 index 0000000..ca45384 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.h @@ -0,0 +1,39 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#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/LinkLocal/DNSSD/DNSSDQuerier.h" + +namespace Swift { + class ByteArray; + + class AvahiQuerier : + public DNSSDQuerier, + public boost::enable_shared_from_this<AvahiQuerier> { + public: + AvahiQuerier(); + ~AvahiQuerier(); + + boost::shared_ptr<DNSSDBrowseQuery> createBrowseQuery(); + boost::shared_ptr<DNSSDRegisterQuery> createRegisterQuery( + const String& name, int port, const ByteArray& info); + boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const DNSSDServiceID&); + boost::shared_ptr<DNSSDResolveHostnameQuery> createResolveHostnameQuery( + const String& hostname, int interfaceIndex); + + void start(); + void stop(); + + private: + AvahiClient* client; + AvahiThreadedPoll* threadedPoll; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Avahi/Makefile.inc b/Swiften/LinkLocal/DNSSD/Avahi/Makefile.inc new file mode 100644 index 0000000..6150dc1 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Avahi/Makefile.inc @@ -0,0 +1,2 @@ +SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSD/Avahi/AvahiQuerier.cpp diff --git a/Swiften/LinkLocal/DNSSD/Makefile.inc b/Swiften/LinkLocal/DNSSD/Makefile.inc index 3d2c969..f6997ef 100644 --- a/Swiften/LinkLocal/DNSSD/Makefile.inc +++ b/Swiften/LinkLocal/DNSSD/Makefile.inc @@ -10,6 +10,7 @@ ifeq ($(HAVE_BONJOUR),yes) include Swiften/LinkLocal/DNSSD/Bonjour/Makefile.inc endif ifeq ($(HAVE_AVAHI),yes) +include Swiften/LinkLocal/DNSSD/Avahi/Makefile.inc endif include Swiften/LinkLocal/DNSSD/Fake/Makefile.inc -- cgit v0.10.2-6-g49f6 From b145bde2b103b0e688eef6300d34668431c5ad04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Wed, 29 Jul 2009 22:18:02 +0200 Subject: Created LinkLocalPresenceManager. diff --git a/Slimber/CLI/main.cpp b/Slimber/CLI/main.cpp index 8b70625..7ebdb0f 100644 --- a/Slimber/CLI/main.cpp +++ b/Slimber/CLI/main.cpp @@ -10,6 +10,7 @@ #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" #include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.h" @@ -22,10 +23,8 @@ int main() { SimpleEventLoop eventLoop; boost::shared_ptr<BonjourQuerier> querier(new BonjourQuerier()); querier->start(); - boost::shared_ptr<DNSSDBrowseQuery> query = querier->createBrowseQuery(); - query->startBrowsing(); - boost::shared_ptr<DNSSDRegisterQuery> query2 = querier->createRegisterQuery("remko", 1234, LinkLocalServiceInfo()); - query2->registerService(); + LinkLocalServiceBrowser browser(querier); + browser.start(); /* boost::shared_ptr<DNSSDService> dnsSDService; diff --git a/Slimber/LinkLocalPresenceManager.cpp b/Slimber/LinkLocalPresenceManager.cpp new file mode 100644 index 0000000..b964786 --- /dev/null +++ b/Slimber/LinkLocalPresenceManager.cpp @@ -0,0 +1,98 @@ +#include "Slimber/LinkLocalPresenceManager.h" + +#include <boost/bind.hpp> + +#include "Swiften/Base/foreach.h" +#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" +#include "Swiften/Elements/RosterPayload.h" +#include "Swiften/Elements/Presence.h" + +namespace Swift { + +LinkLocalPresenceManager::LinkLocalPresenceManager(LinkLocalServiceBrowser* browser) : browser(browser) { + browser->onServiceAdded.connect( + boost::bind(&LinkLocalPresenceManager::handleServiceAdded, this, _1)); + browser->onServiceChanged.connect( + boost::bind(&LinkLocalPresenceManager::handleServiceChanged, this, _1)); + browser->onServiceRemoved.connect( + boost::bind(&LinkLocalPresenceManager::handleServiceRemoved, this, _1)); +} + +void LinkLocalPresenceManager::handleServiceAdded(const LinkLocalService& service) { + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->addItem(getRosterItem(service)); + onRosterChanged(roster); + onPresenceChanged(getPresence(service)); +} + +void LinkLocalPresenceManager::handleServiceChanged(const LinkLocalService& service) { + onPresenceChanged(getPresence(service)); +} + +void LinkLocalPresenceManager::handleServiceRemoved(const LinkLocalService& service) { + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->addItem(RosterItemPayload(getJIDForService(service), "", RosterItemPayload::Remove)); + onRosterChanged(roster); +} + +boost::shared_ptr<RosterPayload> LinkLocalPresenceManager::getRoster() const { + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + foreach(const LinkLocalService& service, browser->getServices()) { + roster->addItem(getRosterItem(service)); + } + return roster; +} + +std::vector<boost::shared_ptr<Presence> > LinkLocalPresenceManager::getAllPresence() const { + std::vector<boost::shared_ptr<Presence> > result; + foreach(const LinkLocalService& service, browser->getServices()) { + result.push_back(getPresence(service)); + } + return result; +} + +RosterItemPayload LinkLocalPresenceManager::getRosterItem(const LinkLocalService& service) const { + return RosterItemPayload(getJIDForService(service), getRosterName(service), RosterItemPayload::Both); +} + +String LinkLocalPresenceManager::getRosterName(const LinkLocalService& service) const { + LinkLocalServiceInfo info = service.getInfo(); + if (!info.getNick().isEmpty()) { + return info.getNick(); + } + else if (!info.getFirstName().isEmpty()) { + String result = info.getFirstName(); + if (!info.getLastName().isEmpty()) { + result += " " + info.getLastName(); + } + return result; + } + else if (!info.getLastName().isEmpty()) { + return info.getLastName(); + } + return ""; +} + +JID LinkLocalPresenceManager::getJIDForService(const LinkLocalService& service) const { + return JID(service.getName()); +} + +boost::shared_ptr<Presence> LinkLocalPresenceManager::getPresence(const LinkLocalService& service) const { + boost::shared_ptr<Presence> presence(new Presence()); + presence->setFrom(getJIDForService(service)); + switch (service.getInfo().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(service.getInfo().getMessage()); + return presence; +} + +} diff --git a/Slimber/LinkLocalPresenceManager.h b/Slimber/LinkLocalPresenceManager.h new file mode 100644 index 0000000..2af2313 --- /dev/null +++ b/Slimber/LinkLocalPresenceManager.h @@ -0,0 +1,39 @@ +#pragma once + +#include <boost/shared_ptr.hpp> +#include <boost/signal.hpp> + +#include "Swiften/Elements/RosterItemPayload.h" +#include "Swiften/Base/String.h" +#include "Swiften/JID/JID.h" + +namespace Swift { + class LinkLocalService; + class LinkLocalServiceBrowser; + class RosterPayload; + class Presence; + + class LinkLocalPresenceManager { + public: + LinkLocalPresenceManager(LinkLocalServiceBrowser*); + + 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; + + private: + void handleServiceAdded(const LinkLocalService&); + void handleServiceChanged(const LinkLocalService&); + void handleServiceRemoved(const LinkLocalService&); + + RosterItemPayload getRosterItem(const LinkLocalService& service) const; + String getRosterName(const LinkLocalService& service) const; + JID getJIDForService(const LinkLocalService& service) const; + boost::shared_ptr<Presence> getPresence(const LinkLocalService& service) const; + + private: + LinkLocalServiceBrowser* browser; + }; +} diff --git a/Slimber/Makefile.inc b/Slimber/Makefile.inc index fea164f..16fcb8f 100644 --- a/Slimber/Makefile.inc +++ b/Slimber/Makefile.inc @@ -1,14 +1,16 @@ SLIMBER_TARGET = Slimber/Slimber.a SLIMBER_SOURCES = \ + Slimber/LinkLocalPresenceManager.cpp \ Slimber/FileVCardCollection.cpp \ Slimber/VCardCollection.cpp \ Slimber/Server.cpp SLIMBER_OBJECTS = \ $(SLIMBER_SOURCES:.cpp=.o) -DEPS += \ - $(SLIMBER_SOURCES:.cpp=.dep) \ +DEPS += $(SLIMBER_SOURCES:.cpp=.dep) +UNITTEST_LIBS += $(SLIMBER_TARGET) +include Slimber/UnitTest/Makefile.inc include Slimber/CLI/Makefile.inc ifeq ($(MACOSX),1) include Slimber/Cocoa/Makefile.inc diff --git a/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp b/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp new file mode 100644 index 0000000..a1ecdf8 --- /dev/null +++ b/Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp @@ -0,0 +1,224 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <boost/bind.hpp> +#include <map> + +#include "Swiften/Elements/Presence.h" +#include "Swiften/Elements/RosterPayload.h" +#include "Swiften/Elements/RosterItemPayload.h" +#include "Slimber/LinkLocalPresenceManager.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" +#include "Swiften/LinkLocal/LinkLocalServiceBrowser.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h" +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h" +#include "Swiften/EventLoop/DummyEventLoop.h" + +using namespace Swift; + +class LinkLocalPresenceManagerTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LinkLocalPresenceManagerTest); + CPPUNIT_TEST(testServiceAdded); + CPPUNIT_TEST(testServiceRemoved); + CPPUNIT_TEST(testServiceChanged); + CPPUNIT_TEST(testGetRoster); + CPPUNIT_TEST(testGetAllPresence); + CPPUNIT_TEST(testGetRoster_InfoWithNick); + CPPUNIT_TEST(testGetRoster_InfoWithFirstName); + CPPUNIT_TEST(testGetRoster_InfoWithLastName); + CPPUNIT_TEST(testGetRoster_InfoWithFirstAndLastName); + CPPUNIT_TEST(testGetRoster_NoInfo); + CPPUNIT_TEST_SUITE_END(); + + public: + LinkLocalPresenceManagerTest() {} + + void setUp() { + eventLoop = new DummyEventLoop(); + querier = boost::shared_ptr<FakeDNSSDQuerier>(new FakeDNSSDQuerier("wonderland.lit")); + browser = new LinkLocalServiceBrowser(querier); + browser->start(); + } + + void tearDown() { + browser->stop(); + delete browser; + delete eventLoop; + } + + void testServiceAdded() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland", "Alice"); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(rosterChanges.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(rosterChanges[0]->getItems().size())); + boost::optional<RosterItemPayload> item = rosterChanges[0]->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT(item); + CPPUNIT_ASSERT_EQUAL(String("Alice"), item->getName()); + CPPUNIT_ASSERT_EQUAL(RosterItemPayload::Both, item->getSubscription()); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(presenceChanges.size())); + CPPUNIT_ASSERT(StatusShow::Online == presenceChanges[0]->getShow()); + CPPUNIT_ASSERT(JID("alice@wonderland") == presenceChanges[0]->getFrom()); + } + + void testServiceRemoved() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland"); + removeService("alice@wonderland"); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(rosterChanges.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(rosterChanges[1]->getItems().size())); + boost::optional<RosterItemPayload> item = rosterChanges[1]->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT(item); + CPPUNIT_ASSERT_EQUAL(RosterItemPayload::Remove, item->getSubscription()); + } + + void testServiceChanged() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland"); + updateServicePresence("alice@wonderland", LinkLocalServiceInfo::Away, "I'm Away"); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(rosterChanges.size())); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(presenceChanges.size())); + CPPUNIT_ASSERT(StatusShow::Away == presenceChanges[1]->getShow()); + CPPUNIT_ASSERT(JID("alice@wonderland") == presenceChanges[1]->getFrom()); + CPPUNIT_ASSERT_EQUAL(String("I'm Away"), presenceChanges[1]->getStatus()); + } + + void testGetAllPresence() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland"); + addService("rabbit@teaparty"); + updateServicePresence("rabbit@teaparty", LinkLocalServiceInfo::Away, "Partying"); + + std::vector<boost::shared_ptr<Presence> > presences = testling->getAllPresence(); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(presences.size())); + // The order doesn't matter + CPPUNIT_ASSERT(JID("rabbit@teaparty") == presences[0]->getFrom()); + CPPUNIT_ASSERT(StatusShow::Away == presences[0]->getShow()); + CPPUNIT_ASSERT(JID("alice@wonderland") == presences[1]->getFrom()); + CPPUNIT_ASSERT(StatusShow::Online == presences[1]->getShow()); + } + + void testGetRoster() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland", "Alice"); + addService("rabbit@teaparty", "Rabbit"); + + boost::shared_ptr<RosterPayload> roster = testling->getRoster(); + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(roster->getItems().size())); + boost::optional<RosterItemPayload> item; + item = roster->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT(item); + CPPUNIT_ASSERT_EQUAL(String("Alice"), item->getName()); + CPPUNIT_ASSERT_EQUAL(RosterItemPayload::Both, item->getSubscription()); + item = roster->getItem(JID("rabbit@teaparty")); + CPPUNIT_ASSERT(item); + CPPUNIT_ASSERT_EQUAL(String("Rabbit"), item->getName()); + CPPUNIT_ASSERT_EQUAL(RosterItemPayload::Both, item->getSubscription()); + } + + void testGetRoster_InfoWithNick() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland", "Alice", "Alice In", "Wonderland"); + + boost::optional<RosterItemPayload> item = testling->getRoster()->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT_EQUAL(String("Alice"), item->getName()); + } + + void testGetRoster_InfoWithFirstName() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland", "", "Alice In", ""); + + boost::optional<RosterItemPayload> item = testling->getRoster()->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT_EQUAL(String("Alice In"), item->getName()); + } + + void testGetRoster_InfoWithLastName() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland", "", "", "Wonderland"); + + boost::optional<RosterItemPayload> item = testling->getRoster()->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT_EQUAL(String("Wonderland"), item->getName()); + } + + void testGetRoster_InfoWithFirstAndLastName() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland", "", "Alice In", "Wonderland"); + + boost::optional<RosterItemPayload> item = testling->getRoster()->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT_EQUAL(String("Alice In Wonderland"), item->getName()); + } + + void testGetRoster_NoInfo() { + std::auto_ptr<LinkLocalPresenceManager> testling(createTestling()); + + addService("alice@wonderland"); + + boost::optional<RosterItemPayload> item = testling->getRoster()->getItem(JID("alice@wonderland")); + CPPUNIT_ASSERT_EQUAL(String(""), item->getName()); + } + + private: + std::auto_ptr<LinkLocalPresenceManager> createTestling() { + std::auto_ptr<LinkLocalPresenceManager> testling( + new LinkLocalPresenceManager(browser)); + testling->onRosterChanged.connect(boost::bind( + &LinkLocalPresenceManagerTest::handleRosterChanged, this, _1)); + testling->onPresenceChanged.connect(boost::bind( + &LinkLocalPresenceManagerTest::handlePresenceChanged, this, _1)); + return testling; + } + + void addService(const String& name, const String& nickName = String(), const String& firstName = String(), const String& lastName = String()) { + DNSSDServiceID service(name, "local."); + LinkLocalServiceInfo info; + info.setFirstName(firstName); + info.setLastName(lastName); + info.setNick(nickName); + querier->setServiceInfo(service, DNSSDResolveServiceQuery::Result(name + "._presence._tcp.local", "rabbithole.local", 1234, info.toTXTRecord())); + querier->addService(service); + eventLoop->processEvents(); + } + + void removeService(const String& name) { + DNSSDServiceID service(name, "local."); + querier->removeService(DNSSDServiceID(name, "local.")); + eventLoop->processEvents(); + } + + void updateServicePresence(const String& name, LinkLocalServiceInfo::Status status, const String& message) { + DNSSDServiceID service(name, "local."); + LinkLocalServiceInfo info; + info.setStatus(status); + info.setMessage(message); + querier->setServiceInfo(service, DNSSDResolveServiceQuery::Result(name + "._presence._tcp.local", "rabbithole.local", 1234, info.toTXTRecord())); + eventLoop->processEvents(); + } + + void handleRosterChanged(boost::shared_ptr<RosterPayload> payload) { + rosterChanges.push_back(payload); + } + + void handlePresenceChanged(boost::shared_ptr<Presence> presence) { + presenceChanges.push_back(presence); + } + + private: + DummyEventLoop* eventLoop; + boost::shared_ptr<FakeDNSSDQuerier> querier; + LinkLocalServiceBrowser* browser; + std::vector< boost::shared_ptr<RosterPayload> > rosterChanges; + std::vector< boost::shared_ptr<Presence> > presenceChanges; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalPresenceManagerTest); diff --git a/Slimber/UnitTest/Makefile.inc b/Slimber/UnitTest/Makefile.inc new file mode 100644 index 0000000..f2c4db8 --- /dev/null +++ b/Slimber/UnitTest/Makefile.inc @@ -0,0 +1,2 @@ +UNITTEST_SOURCES += \ + Slimber/UnitTest/LinkLocalPresenceManagerTest.cpp diff --git a/Swiften/Elements/RosterPayload.cpp b/Swiften/Elements/RosterPayload.cpp index 6d39264..8e2fd87 100644 --- a/Swiften/Elements/RosterPayload.cpp +++ b/Swiften/Elements/RosterPayload.cpp @@ -7,7 +7,7 @@ boost::optional<RosterItemPayload> RosterPayload::getItem(const JID& jid) const foreach(const RosterItemPayload& item, items_) { // FIXME: MSVC rejects this. Find out why. //if (item.getJID() == jid) { - if (item.getJID().compare(jid, JID::WithResource)) { + if (item.getJID().equals(jid, JID::WithResource)) { return boost::optional<RosterItemPayload>(item); } } diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h index be0c921..c605175 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -41,6 +41,7 @@ namespace Swift { MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this()); } else { + std::cout << "Discovered service: name:" << name << " domain:" << domain << " type: " << type << std::endl; DNSSDServiceID service(name, domain, type, interfaceIndex); if (flags & kDNSServiceFlagsAdd) { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceAdded), service), shared_from_this()); diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h index d16ca5b..886b87b 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -45,6 +45,7 @@ namespace Swift { MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); } else { + std::cout << "Service resolved: name:" << fullName << " host:" << host << " port:" << port << std::endl; MainEventLoop::postEvent( boost::bind( boost::ref(onServiceResolved), diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index f7c5478..f65cd7a 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -102,19 +102,22 @@ void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service assert(i != resolveQueries.end()); i->second->stop(); resolveQueries.erase(i); - services.erase(service); - onServiceRemoved(service); + ServiceMap::iterator j = services.find(service); + assert(j != services.end()); + LinkLocalService linkLocalService(j->first, j->second); + services.erase(j); + onServiceRemoved(linkLocalService); } void LinkLocalServiceBrowser::handleServiceResolved(const DNSSDServiceID& service, const boost::optional<DNSSDResolveServiceQuery::Result>& result) { if (result) { std::pair<ServiceMap::iterator, bool> r = services.insert(std::make_pair(service, *result)); if (r.second) { - onServiceAdded(service); + onServiceAdded(LinkLocalService(r.first->first, r.first->second)); } else { r.first->second = *result; - onServiceChanged(service); + onServiceChanged(LinkLocalService(r.first->first, r.first->second)); } } } diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.h b/Swiften/LinkLocal/LinkLocalServiceBrowser.h index dcdd576..a6623b1 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.h +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.h @@ -31,9 +31,9 @@ namespace Swift { std::vector<LinkLocalService> getServices() const; - boost::signal<void (const DNSSDServiceID&)> onServiceAdded; - boost::signal<void (const DNSSDServiceID&)> onServiceChanged; - boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; + boost::signal<void (const LinkLocalService&)> onServiceAdded; + boost::signal<void (const LinkLocalService&)> onServiceChanged; + boost::signal<void (const LinkLocalService&)> onServiceRemoved; boost::signal<void (bool)> onStopped; private: diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index e9501cb..6e4d3b4 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -84,7 +84,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); - CPPUNIT_ASSERT(addedServices[0] == *testServiceID); + CPPUNIT_ASSERT(addedServices[0].getID() == *testServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); std::vector<LinkLocalService> services = testling->getServices(); @@ -141,7 +141,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { eventLoop->processEvents(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); - CPPUNIT_ASSERT(addedServices[0] == *aliceServiceID); + CPPUNIT_ASSERT(addedServices[0].getID() == *aliceServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); std::vector<LinkLocalService> services = testling->getServices(); @@ -166,7 +166,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); - CPPUNIT_ASSERT(changedServices[0] == *testServiceID); + CPPUNIT_ASSERT(changedServices[0].getID() == *testServiceID); std::vector<LinkLocalService> services = testling->getServices(); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(services.size())); CPPUNIT_ASSERT(*testServiceID == services[0].getID()); @@ -191,7 +191,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(addedServices.size())); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changedServices.size())); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(removedServices.size())); - CPPUNIT_ASSERT(removedServices[0] == *testServiceID); + CPPUNIT_ASSERT(removedServices[0].getID() == *testServiceID); CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(testling->getServices().size())); testling->stop(); @@ -294,15 +294,15 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { return testling; } - void handleServiceAdded(const DNSSDServiceID& service) { + void handleServiceAdded(const LinkLocalService& service) { addedServices.push_back(service); } - void handleServiceRemoved(const DNSSDServiceID& service) { + void handleServiceRemoved(const LinkLocalService& service) { removedServices.push_back(service); } - void handleServiceChanged(const DNSSDServiceID& service) { + void handleServiceChanged(const LinkLocalService& service) { changedServices.push_back(service); } @@ -320,9 +320,9 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { private: DummyEventLoop* eventLoop; boost::shared_ptr<FakeDNSSDQuerier> querier; - std::vector<DNSSDServiceID> addedServices; - std::vector<DNSSDServiceID> changedServices; - std::vector<DNSSDServiceID> removedServices; + std::vector<LinkLocalService> addedServices; + std::vector<LinkLocalService> changedServices; + std::vector<LinkLocalService> removedServices; DNSSDServiceID* aliceServiceID; DNSSDResolveServiceQuery::Result* aliceServiceInfo; DNSSDServiceID* testServiceID; -- cgit v0.10.2-6-g49f6 From be2db74cad9f1d0359741beecdef2aed63e0ad2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 30 Jul 2009 21:11:19 +0200 Subject: Proide a description for LinkLocalServices. diff --git a/Swiften/LinkLocal/LinkLocalService.cpp b/Swiften/LinkLocal/LinkLocalService.cpp new file mode 100644 index 0000000..f567a63 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalService.cpp @@ -0,0 +1,23 @@ +#include "Swiften/LinkLocal/LinkLocalService.h" + +namespace Swift { + +String LinkLocalService::getDescription() const { + LinkLocalServiceInfo info = getInfo(); + if (!info.getNick().isEmpty()) { + return info.getNick(); + } + else if (!info.getFirstName().isEmpty()) { + String result = info.getFirstName(); + if (!info.getLastName().isEmpty()) { + result += " " + info.getLastName(); + } + return result; + } + else if (!info.getLastName().isEmpty()) { + return info.getLastName(); + } + return getName(); +} + +} diff --git a/Swiften/LinkLocal/LinkLocalService.h b/Swiften/LinkLocal/LinkLocalService.h index 37f2130..f7e9e3c 100644 --- a/Swiften/LinkLocal/LinkLocalService.h +++ b/Swiften/LinkLocal/LinkLocalService.h @@ -34,6 +34,8 @@ namespace Swift { return LinkLocalServiceInfo::createFromTXTRecord(info.info); } + String getDescription() const; + private: DNSSDServiceID id; DNSSDResolveServiceQuery::Result info; diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index ac3d2a2..3738789 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,6 +1,7 @@ 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 \ diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp index 68f191a..b5d7ef5 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp @@ -14,8 +14,6 @@ class LinkLocalServiceInfoTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE_END(); public: - LinkLocalServiceInfoTest() {} - void testGetTXTRecord() { LinkLocalServiceInfo info; info.setFirstName("Remko"); diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp new file mode 100644 index 0000000..69ec718 --- /dev/null +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp @@ -0,0 +1,62 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include "Swiften/LinkLocal/LinkLocalService.h" + +using namespace Swift; + +class LinkLocalServiceTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LinkLocalServiceTest); + CPPUNIT_TEST(testGetDescription_WithNick); + CPPUNIT_TEST(testGetDescription_WithFirstName); + CPPUNIT_TEST(testGetDescription_WithLastName); + CPPUNIT_TEST(testGetDescription_WithFirstAndLastName); + CPPUNIT_TEST(testGetDescription_NoInfo); + CPPUNIT_TEST_SUITE_END(); + + public: + void testGetDescription_WithNick() { + LinkLocalService testling = createService("alice@wonderland", "Alice", "Alice In", "Wonderland"); + + CPPUNIT_ASSERT_EQUAL(String("Alice"), testling.getDescription()); + } + + void testGetDescription_WithFirstName() { + LinkLocalService testling = createService("alice@wonderland", "", "Alice In"); + + CPPUNIT_ASSERT_EQUAL(String("Alice In"), testling.getDescription()); + } + + void testGetDescription_WithLastName() { + LinkLocalService testling = createService("alice@wonderland", "", "", "Wonderland"); + + CPPUNIT_ASSERT_EQUAL(String("Wonderland"), testling.getDescription()); + } + + void testGetDescription_WithFirstAndLastName() { + LinkLocalService testling = createService("alice@wonderland", "", "Alice In", "Wonderland"); + + CPPUNIT_ASSERT_EQUAL(String("Alice In Wonderland"), testling.getDescription()); + } + + void testGetDescription_NoInfo() { + LinkLocalService testling = createService("alice@wonderland"); + + CPPUNIT_ASSERT_EQUAL(String("alice@wonderland"), testling.getDescription()); + } + + private: + LinkLocalService createService(const String& name, const String& nickName = String(), const String& firstName = String(), const String& lastName = String()) { + DNSSDServiceID service(name, "local."); + LinkLocalServiceInfo info; + info.setFirstName(firstName); + info.setLastName(lastName); + info.setNick(nickName); + return LinkLocalService(service, + DNSSDResolveServiceQuery::Result( + name + "._presence._tcp.local", "rabbithole.local", 1234, + info.toTXTRecord())); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceTest); diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc index 9640fa7..e5f1bf0 100644 --- a/Swiften/LinkLocal/UnitTest/Makefile.inc +++ b/Swiften/LinkLocal/UnitTest/Makefile.inc @@ -1,3 +1,4 @@ UNITTEST_SOURCES += \ + Swiften/LinkLocal/UnitTest/LinkLocalServiceTest.cpp \ Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp \ Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp -- cgit v0.10.2-6-g49f6 From f1938c7096f2ab77fb438d285f1eadb094010b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 30 Jul 2009 21:15:22 +0200 Subject: Remove unnecessary test constructor. diff --git a/QA/UnitTest/template/FooTest.cpp b/QA/UnitTest/template/FooTest.cpp index b6b9abf..9657360 100644 --- a/QA/UnitTest/template/FooTest.cpp +++ b/QA/UnitTest/template/FooTest.cpp @@ -9,8 +9,6 @@ class FooTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE_END(); public: - FooTest() {} - void setUp() { } -- cgit v0.10.2-6-g49f6 From c8634883470be42eaa674aab05db61c46b005608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Thu, 30 Jul 2009 21:15:34 +0200 Subject: Make Slimber use the new LinkLocal framework. XMPP Server is temporarily out of order. 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; -- cgit v0.10.2-6-g49f6 From ba113b63e5ee8e76638ae8f02f7220fb1b8fcdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 31 Jul 2009 00:14:58 +0200 Subject: Remove assertion that is triggered on unregister(). diff --git a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp index b24d8f0..061bf2c 100644 --- a/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp +++ b/Swiften/LinkLocal/LinkLocalServiceBrowser.cpp @@ -100,11 +100,12 @@ void LinkLocalServiceBrowser::handleServiceAdded(const DNSSDServiceID& service) } void LinkLocalServiceBrowser::handleServiceRemoved(const DNSSDServiceID& service) { - if (selfService && service == *selfService) { + ResolveQueryMap::iterator i = resolveQueries.find(service); + if (i == resolveQueries.end()) { + // Can happen after an unregister(), when getting the old 'self' + // service remove notification. return; } - ResolveQueryMap::iterator i = resolveQueries.find(service); - assert(i != resolveQueries.end()); i->second->stop(); resolveQueries.erase(i); ServiceMap::iterator j = services.find(service); -- cgit v0.10.2-6-g49f6 From 387a3193b648f40f499895c0c03b982c2f8d1263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 31 Jul 2009 00:25:50 +0200 Subject: Added unit test that triggers the assertion on self service removal. diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp index 76117c0..9f91269 100644 --- a/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp @@ -22,6 +22,7 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testServiceAdded_UnregisteredService); CPPUNIT_TEST(testServiceChanged); CPPUNIT_TEST(testServiceRemoved); + CPPUNIT_TEST(testServiceRemoved_UnregisteredService); CPPUNIT_TEST(testError_BrowseErrorAfterStart); CPPUNIT_TEST(testError_BrowseErrorAfterResolve); CPPUNIT_TEST(testRegisterService); @@ -154,6 +155,23 @@ class LinkLocalServiceBrowserTest : public CppUnit::TestFixture { testling->stop(); } + void testServiceRemoved_UnregisteredService() { + boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); + testling->start(); + eventLoop->processEvents(); + testling->registerService("alice", 1234, LinkLocalServiceInfo()); + eventLoop->processEvents(); + testling->unregisterService(); + eventLoop->processEvents(); + + querier->removeService(*aliceServiceID); + eventLoop->processEvents(); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(removedServices.size())); + + testling->stop(); + } + void testServiceChanged() { boost::shared_ptr<LinkLocalServiceBrowser> testling = createTestling(); testling->start(); -- cgit v0.10.2-6-g49f6 From 1dc80e3835c85a47291d91fd82c0f2f2617aa591 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 31 Jul 2009 18:34:32 +0200 Subject: Re-enable accidentally disabled XMLParser tests. diff --git a/Swiften/Parser/UnitTest/XMLParserTest.cpp b/Swiften/Parser/UnitTest/XMLParserTest.cpp index a26b31b..6a42d0d 100644 --- a/Swiften/Parser/UnitTest/XMLParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMLParserTest.cpp @@ -2,7 +2,7 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <vector> -#ifdef HAVE_CONFIG_H +#ifdef HAVE_SWIFTEN_CONFIG_H #include "Swiften/config.h" #endif #include "Swiften/Base/String.h" @@ -17,10 +17,10 @@ using namespace Swift; template <typename ParserType> -class XMLParserTest : public CppUnit::TestFixture -{ +class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(XMLParserTest); CPPUNIT_TEST(testParse_NestedElements); + CPPUNIT_TEST(testParse_ElementInNamespacedElement); CPPUNIT_TEST(testParse_CharacterData); CPPUNIT_TEST(testParse_NamespacePrefix); CPPUNIT_TEST(testParse_UnhandledXML); @@ -30,8 +30,6 @@ class XMLParserTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE_END(); public: - XMLParserTest() {} - void testParse_NestedElements() { ParserType testling(&client_); @@ -46,17 +44,51 @@ class XMLParserTest : public CppUnit::TestFixture CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.size()); CPPUNIT_ASSERT_EQUAL(String("get"), client_.events[0].attributes["type"]); + CPPUNIT_ASSERT_EQUAL(String(), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[1].data); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[1].attributes.size()); - CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[1].attributes["xmlns"]); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[1].attributes.size()); + CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[1].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[2].data); + CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[2].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[3].data); + CPPUNIT_ASSERT_EQUAL(String(), client_.events[3].ns); + } + + void testParse_ElementInNamespacedElement() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse( + "<query xmlns='jabber:iq:version'>" + "<name>Swift</name>" + "</query>")); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(5), client_.events.size()); + + CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); + CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[0].data); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), client_.events[0].attributes.size()); + CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[0].ns); + + CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); + CPPUNIT_ASSERT_EQUAL(String("name"), client_.events[1].data); + CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[1].ns); + + CPPUNIT_ASSERT_EQUAL(Client::CharacterData, client_.events[2].type); + CPPUNIT_ASSERT_EQUAL(String("Swift"), client_.events[2].data); + + CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); + CPPUNIT_ASSERT_EQUAL(String("name"), client_.events[3].data); + CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[3].ns); + + CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[4].type); + CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[4].data); + CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[4].ns); } void testParse_CharacterData() { @@ -96,16 +128,20 @@ class XMLParserTest : public CppUnit::TestFixture CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); - CPPUNIT_ASSERT_EQUAL(String("p:x"), client_.events[0].data); + CPPUNIT_ASSERT_EQUAL(String("x"), client_.events[0].data); + CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); - CPPUNIT_ASSERT_EQUAL(String("p:y"), client_.events[1].data); + CPPUNIT_ASSERT_EQUAL(String("y"), client_.events[1].data); + CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[1].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); - CPPUNIT_ASSERT_EQUAL(String("p:y"), client_.events[2].data); + CPPUNIT_ASSERT_EQUAL(String("y"), client_.events[2].data); + CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[2].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); - CPPUNIT_ASSERT_EQUAL(String("p:x"), client_.events[3].data); + CPPUNIT_ASSERT_EQUAL(String("x"), client_.events[3].data); + CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[3].ns); } void testParse_UnhandledXML() { @@ -158,24 +194,26 @@ class XMLParserTest : public CppUnit::TestFixture Event( Type type, const String& data, + const String& ns, const AttributeMap& attributes) - : type(type), data(data), attributes(attributes) {} - Event(Type type, const String& data) - : type(type), data(data) {} + : type(type), data(data), ns(ns), attributes(attributes) {} + Event(Type type, const String& data, const String& ns = String()) + : type(type), data(data), ns(ns) {} Type type; String data; + String ns; AttributeMap attributes; }; Client() {} - virtual void handleStartElement(const String& element, const AttributeMap& attributes) { - events.push_back(Event(StartElement, element, attributes)); + virtual void handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) { + events.push_back(Event(StartElement, element, ns, attributes)); } - virtual void handleEndElement(const String& element) { - events.push_back(Event(EndElement, element)); + virtual void handleEndElement(const String& element, const String& ns) { + events.push_back(Event(EndElement, element, ns)); } virtual void handleCharacterData(const String& data) { -- cgit v0.10.2-6-g49f6 From 7d03474e499e9d357c2d69e2333ba5dd0dc03fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 31 Jul 2009 18:34:49 +0200 Subject: ExpatParser: Fix invalid handleEndElement() diff --git a/Swiften/Parser/ExpatParser.cpp b/Swiften/Parser/ExpatParser.cpp index 6d23c93..6f7ff86 100644 --- a/Swiften/Parser/ExpatParser.cpp +++ b/Swiften/Parser/ExpatParser.cpp @@ -32,6 +32,10 @@ static void handleStartElement(void* client, const XML_Char* name, const XML_Cha static void handleEndElement(void* client, const XML_Char* name) { std::pair<String,String> nsTagPair = String(name).getSplittedAtFirst(NAMESPACE_SEPARATOR); + if (nsTagPair.second == "") { + nsTagPair.second = nsTagPair.first; + nsTagPair.first = ""; + } static_cast<XMLParserClient*>(client)->handleEndElement(nsTagPair.second, nsTagPair.first); } -- cgit v0.10.2-6-g49f6 From d0f250d26bd1bdb405b2232159e7f84741d13e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 31 Jul 2009 18:35:29 +0200 Subject: Add Slimber to coverage tests. diff --git a/tools/coverage/FilterLCovData.py b/tools/coverage/FilterLCovData.py index b1dd74e..8d56a7f 100755 --- a/tools/coverage/FilterLCovData.py +++ b/tools/coverage/FilterLCovData.py @@ -1,9 +1,15 @@ #!/usr/bin/env python +# TODO: Add uncovered non-ignored files + import sys, re, os.path assert(len(sys.argv) == 2) +def isIgnored(file) : + return (find.find("/Swiften/") == -1 and find.find("/Slimber/") == -1 and find.find("/Swift/") == -1) or (find.find("/UnitTest/") != -1 or find.find("/QA/") != -1) + + output = [] inputFile = open(sys.argv[1]) inIgnoredFile = False @@ -12,7 +18,7 @@ for line in inputFile.readlines() : if line == "end_of_record\n" : inIgnoredFile = False else : - if line.startswith("SF:") and (line.find("/Swiften/") == -1 or line.find("/UnitTest/") != -1 or line.find("/QA/") != -1 or line.find("/3rdParty/") != -1): + if line.startswith("SF:") and isIgnored(line) : inIgnoredFile = True else : m = re.match("SF:(.*)", line) diff --git a/tools/coverage/GenerateCoverageResults.sh b/tools/coverage/GenerateCoverageResults.sh index 75efaa9..f006e4b 100755 --- a/tools/coverage/GenerateCoverageResults.sh +++ b/tools/coverage/GenerateCoverageResults.sh @@ -31,6 +31,7 @@ $LCOVDIR/lcov --zerocounters --directory $SOURCE_DIR # All tests make -C $SOURCE_DIR test $LCOVDIR/lcov --capture --directory $SOURCE_DIR -b $SOURCE_DIR --output-file $OUTPUT_DIR/all.info --test-name all +cp $OUTPUT_DIR/all.info $OUTPUT_DIR/all.info.orig $SCRIPT_DIR/FilterLCovData.py $OUTPUT_DIR/all.info # Generate HTML -- cgit v0.10.2-6-g49f6 From aa60aa80d2d170a536c246ef6c221f92de7dd8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be> Date: Fri, 31 Jul 2009 18:38:15 +0200 Subject: Adapt LinkLocalConnector to new LinkLocal infrastructure. diff --git a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h index 6e2a852..7b5f19a 100644 --- a/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h @@ -12,7 +12,7 @@ namespace Swift { class BonjourQuerier; class BonjourResolveHostnameQuery : public DNSSDResolveHostnameQuery, public BonjourQuery { - public: + public: BonjourResolveHostnameQuery(const String& hostname, int interfaceIndex, boost::shared_ptr<BonjourQuerier> querier) : BonjourQuery(querier) { DNSServiceErrorType result = DNSServiceGetAddrInfo( &sdRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, @@ -33,6 +33,10 @@ namespace Swift { } } + void finish() { + BonjourQuery::finish(); + } + private: static void handleHostnameResolvedStatic(DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType errorCode, const char*, const struct sockaddr *address, uint32_t, void *context) { static_cast<BonjourResolveHostnameQuery*>(context)->handleHostnameResolved(errorCode, address); diff --git a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h index a2e218c..1b9f291 100644 --- a/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h @@ -11,6 +11,7 @@ namespace Swift { virtual ~DNSSDResolveHostnameQuery(); virtual void run() = 0; + virtual void finish() = 0; boost::signal<void (const boost::optional<HostAddress>&)> onHostnameResolved; }; diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h index 2ff84d3..1f9d7f1 100644 --- a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h @@ -19,6 +19,10 @@ namespace Swift { FakeDNSSDQuery::run(); } + void finish() { + FakeDNSSDQuery::finish(); + } + String hostname; int interfaceIndex; }; diff --git a/Swiften/LinkLocal/LinkLocalConnector.cpp b/Swiften/LinkLocal/LinkLocalConnector.cpp index 28107ed..18b5d6a 100644 --- a/Swiften/LinkLocal/LinkLocalConnector.cpp +++ b/Swiften/LinkLocal/LinkLocalConnector.cpp @@ -7,52 +7,53 @@ #include "Swiften/Network/HostAddress.h" #include "Swiften/Network/HostAddressPort.h" #include "Swiften/LinkLocal/DNSSD/DNSSDQuerier.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h" namespace Swift { LinkLocalConnector::LinkLocalConnector( const JID& remoteJID, const String& hostname, + int interfaceIndex, int port, boost::shared_ptr<DNSSDQuerier> querier, boost::shared_ptr<Connection> connection) : - remoteJID_(remoteJID), - hostname_(hostname), - port_(port), - querier_(querier), - connection_(connection), - resolving_(false) { + remoteJID(remoteJID), + hostname(hostname), + interfaceIndex(interfaceIndex), + port(port), + querier(querier), + connection(connection) { } void LinkLocalConnector::connect() { - resolving_ = true; - //querier_->onHostnameResolved.connect(boost::bind(&LinkLocalConnector::handleHostnameResolved, boost::dynamic_pointer_cast<LinkLocalConnector>(shared_from_this()), _1, _2)); - //querier_->resolveHostname(hostname_); + resolveQuery = querier->createResolveHostnameQuery(hostname, interfaceIndex); + resolveQuery->onHostnameResolved.connect(boost::bind( + &LinkLocalConnector::handleHostnameResolved, + boost::dynamic_pointer_cast<LinkLocalConnector>(shared_from_this()), + _1)); + resolveQuery->run(); } -/* -void LinkLocalConnector::handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address) { - if (resolving_) { - if (hostname == hostname_) { - resolving_ = false; - if (address) { - connection_->onConnectFinished.connect(boost::bind(boost::ref(onConnectFinished), _1)); - connection_->connect(HostAddressPort(*address, port_)); - } - else { - onConnectFinished(false); - } - } +void LinkLocalConnector::handleHostnameResolved(const boost::optional<HostAddress>& address) { + if (address) { + resolveQuery->finish(); + resolveQuery.reset(); + connection->onConnectFinished.connect( + boost::bind(boost::ref(onConnectFinished), _1)); + connection->connect(HostAddressPort(*address, port)); + } + else { + onConnectFinished(false); } } -*/ void LinkLocalConnector::handleConnected(bool error) { onConnectFinished(error); } void LinkLocalConnector::queueElement(boost::shared_ptr<Element> element) { - queuedElements_.push_back(element); + queuedElements.push_back(element); } diff --git a/Swiften/LinkLocal/LinkLocalConnector.h b/Swiften/LinkLocal/LinkLocalConnector.h index 2ddb5b8..134656c 100644 --- a/Swiften/LinkLocal/LinkLocalConnector.h +++ b/Swiften/LinkLocal/LinkLocalConnector.h @@ -16,44 +16,47 @@ namespace Swift { class PayloadParserFactoryCollection; class PayloadSerializerCollection; class DNSSDQuerier; + class DNSSDResolveHostnameQuery; class LinkLocalConnector : public boost::enable_shared_from_this<LinkLocalConnector> { public: LinkLocalConnector( const JID& remoteJID, const String& hostname, + int interfaceIndex, int port, boost::shared_ptr<DNSSDQuerier> querier, boost::shared_ptr<Connection> connection); const JID& getRemoteJID() const { - return remoteJID_; + return remoteJID; } void connect(); void queueElement(boost::shared_ptr<Element> element); const std::vector<boost::shared_ptr<Element> >& getQueuedElements() const { - return queuedElements_; + return queuedElements; } boost::shared_ptr<Connection> getConnection() const { - return connection_; + return connection; } boost::signal<void (bool)> onConnectFinished; private: - //void handleHostnameResolved(const String& hostname, const boost::optional<HostAddress>& address); + void handleHostnameResolved(const boost::optional<HostAddress>& address); void handleConnected(bool error); private: - JID remoteJID_; - String hostname_; - int port_; - boost::shared_ptr<DNSSDQuerier> querier_; - boost::shared_ptr<Connection> connection_; - bool resolving_; - std::vector<boost::shared_ptr<Element> > queuedElements_; + JID remoteJID; + String hostname; + int interfaceIndex; + int port; + boost::shared_ptr<DNSSDQuerier> querier; + boost::shared_ptr<DNSSDResolveHostnameQuery> resolveQuery; + boost::shared_ptr<Connection> connection; + std::vector<boost::shared_ptr<Element> > queuedElements; }; } -- cgit v0.10.2-6-g49f6