diff options
Diffstat (limited to 'Swiften/LinkLocal')
-rw-r--r-- | Swiften/LinkLocal/AppleDNSSDService.cpp | 2 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalService.h | 50 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceBrowser.cpp | 38 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceBrowser.h | 32 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceID.cpp | 7 | ||||
-rw-r--r-- | Swiften/LinkLocal/LinkLocalServiceID.h | 4 | ||||
-rw-r--r-- | Swiften/LinkLocal/Makefile.inc | 2 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp | 95 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/Makefile.inc | 1 | ||||
-rw-r--r-- | Swiften/LinkLocal/UnitTest/MockDNSSDService.h | 74 |
10 files changed, 302 insertions, 3 deletions
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; + }; + + +} |