summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/LinkLocal')
-rw-r--r--Swiften/LinkLocal/AppleDNSSDService.cpp2
-rw-r--r--Swiften/LinkLocal/LinkLocalService.h50
-rw-r--r--Swiften/LinkLocal/LinkLocalServiceBrowser.cpp38
-rw-r--r--Swiften/LinkLocal/LinkLocalServiceBrowser.h32
-rw-r--r--Swiften/LinkLocal/LinkLocalServiceID.cpp7
-rw-r--r--Swiften/LinkLocal/LinkLocalServiceID.h4
-rw-r--r--Swiften/LinkLocal/Makefile.inc2
-rw-r--r--Swiften/LinkLocal/UnitTest/LinkLocalServiceBrowserTest.cpp95
-rw-r--r--Swiften/LinkLocal/UnitTest/Makefile.inc1
-rw-r--r--Swiften/LinkLocal/UnitTest/MockDNSSDService.h74
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;
+ };
+
+
+}