diff options
author | Kevin Smith <git@kismith.co.uk> | 2009-07-31 18:38:11 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2009-07-31 18:38:11 (GMT) |
commit | 99b65c4dd72105755a7cf95297c9cf69dcbc6446 (patch) | |
tree | c6c862f6ef33b2260c44c0229b29f65351223e7c /Swiften/LinkLocal/DNSSD | |
parent | fed11bbc3bffd383e097ea63bb92442ce2daf6ed (diff) | |
parent | aa60aa80d2d170a536c246ef6c221f92de7dd8ed (diff) | |
download | swift-contrib-99b65c4dd72105755a7cf95297c9cf69dcbc6446.zip swift-contrib-99b65c4dd72105755a7cf95297c9cf69dcbc6446.tar.bz2 |
Merge commit 'origin/master' into roster
Diffstat (limited to 'Swiften/LinkLocal/DNSSD')
34 files changed, 1141 insertions, 0 deletions
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/Bonjour/BonjourBrowseQuery.h b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h new file mode 100644 index 0000000..c605175 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourBrowseQuery.h @@ -0,0 +1,55 @@ +#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) { + sdRef = NULL; + } + } + + void startBrowsing() { + if (!sdRef) { + MainEventLoop::postEvent(boost::bind(boost::ref(onError)), shared_from_this()); + } + else { + 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) { + 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()); + } + 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..9c9e64e --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuerier.cpp @@ -0,0 +1,129 @@ +#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() { + assert(!thread); +} + +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 ByteArray& info) { + return boost::shared_ptr<DNSSDRegisterQuery>(new BonjourRegisterQuery(name, port, info, shared_from_this())); +} + +boost::shared_ptr<DNSSDResolveServiceQuery> BonjourQuerier::createResolveServiceQuery(const DNSSDServiceID& 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() { + assert(!thread); + thread = new boost::thread(boost::bind(&BonjourQuerier::run, shared_from_this())); +} + +void BonjourQuerier::stop() { + if (thread) { + stopRequested = true; + assert(runningQueries.empty()); + runningQueriesAvailableEvent.notify_one(); + interruptSelect(); + thread->join(); + delete thread; + thread = NULL; + 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..d12f94f --- /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 ByteArray; + + 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 ByteArray& info); + boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const DNSSDServiceID&); + 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..ddc2788 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourRegisterQuery.h @@ -0,0 +1,55 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Bonjour/BonjourQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.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 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(), + &BonjourRegisterQuery::handleServiceRegisteredStatic, this); + if (result != kDNSServiceErr_NoError) { + sdRef = NULL; + } + } + + void registerService() { + if (sdRef) { + run(); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>()), shared_from_this()); + } + } + + void unregisterService() { + finish(); + } + + void updateServiceInfo(const ByteArray& txtRecord) { + boost::lock_guard<boost::mutex> lock(sdRefMutex); + 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<DNSSDServiceID>()), shared_from_this()); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onRegisterFinished), boost::optional<DNSSDServiceID>(DNSSDServiceID(name, domain, regtype, 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..7b5f19a --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveHostnameQuery.h @@ -0,0 +1,63 @@ +#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) { + sdRef = NULL; + } + } + + //void DNSSDResolveHostnameQuery::run() { + void run() { + if (sdRef) { + BonjourQuery::run(); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onHostnameResolved), boost::optional<HostAddress>()), shared_from_this()); + } + } + + 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); + } + + 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..886b87b --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Bonjour/BonjourResolveServiceQuery.h @@ -0,0 +1,58 @@ +#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 DNSSDServiceID& 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) { + sdRef = NULL; + } + } + + void start() { + if (sdRef) { + run(); + } + else { + MainEventLoop::postEvent(boost::bind(boost::ref(onServiceResolved), boost::optional<Result>()), shared_from_this()); + } + } + + 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 { + std::cout << "Service resolved: name:" << fullName << " host:" << host << " port:" << port << std::endl; + MainEventLoop::postEvent( + boost::bind( + boost::ref(onServiceResolved), + Result(String(fullName), String(host), port, + 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..9b30858 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDBrowseQuery.h @@ -0,0 +1,19 @@ +#pragma once + +#include <boost/signal.hpp> + +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" + +namespace Swift { + class DNSSDBrowseQuery { + public: + virtual ~DNSSDBrowseQuery(); + + virtual void startBrowsing() = 0; + virtual void stopBrowsing() = 0; + + boost::signal<void (const DNSSDServiceID&)> onServiceAdded; + boost::signal<void (const DNSSDServiceID&)> onServiceRemoved; + boost::signal<void ()> onError; + }; +} 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..799bc0c --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDQuerier.h @@ -0,0 +1,26 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +namespace Swift { + class String; + class ByteArray; + class DNSSDServiceID; + 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 ByteArray& info) = 0; + virtual boost::shared_ptr<DNSSDResolveServiceQuery> createResolveServiceQuery( + const DNSSDServiceID&) = 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..4a04fa9 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h @@ -0,0 +1,21 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" + +namespace Swift { + class ByteArray; + + class DNSSDRegisterQuery { + public: + virtual ~DNSSDRegisterQuery(); + + virtual void registerService() = 0; + virtual void unregisterService() = 0; + virtual void updateServiceInfo(const ByteArray& info) = 0; + + boost::signal<void (boost::optional<DNSSDServiceID>)> 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..1b9f291 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveHostnameQuery.h @@ -0,0 +1,18 @@ +#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; + virtual void finish() = 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..217e396 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDResolveServiceQuery.h @@ -0,0 +1,28 @@ +#pragma once + +#include <boost/signal.hpp> +#include <boost/optional.hpp> + +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" +#include "Swiften/Base/ByteArray.h" + +namespace Swift { + class DNSSDResolveServiceQuery { + public: + struct Result { + 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; + ByteArray 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/DNSSDServiceID.cpp b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp new file mode 100644 index 0000000..b360ee5 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp @@ -0,0 +1,7 @@ +#include "Swiften/LinkLocal/DNSSD/DNSSDServiceID.h" + +namespace Swift { + +const char* DNSSDServiceID::PresenceServiceType = "_presence._tcp"; + +} diff --git a/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h b/Swiften/LinkLocal/DNSSD/DNSSDServiceID.h new file mode 100644 index 0000000..ba7828b --- /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 char* PresenceServiceType; + + DNSSDServiceID( + const String& name, + const String& domain, + const String& type = PresenceServiceType, + int networkInterface = 0) : + name(name), + domain(domain), + type(type), + networkInterface(networkInterface) { + } + + bool operator==(const DNSSDServiceID& o) const { + 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.domain == domain) { + if (o.type == type) { + return networkInterface < o.networkInterface; + } + else { + return type < o.type; + } + } + else { + return domain < o.domain; + } + } + else { + return o.name < name; + } + } + + const String& getName() const { + return name; + } + + const String& getDomain() const { + return domain; + } + + const String& getType() const { + return type; + } + + int getNetworkInterfaceID() const { + return networkInterface; + } + + private: + String name; + String domain; + String type; + int networkInterface; + }; +} 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..5079192 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.cpp @@ -0,0 +1,105 @@ +#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(const String& domain) : domain(domain) { +} + +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 ByteArray& 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()); + } + } + } + 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) { + 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()); + } + } +} + +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()); + } +} + +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..f2ec17b --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuerier.h @@ -0,0 +1,63 @@ +#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 ByteArray; + class FakeDNSSDQuery; + class FakeDNSSDBrowseQuery; + + class FakeDNSSDQuerier : + public DNSSDQuerier, + public EventOwner, + public boost::enable_shared_from_this<FakeDNSSDQuerier> { + public: + FakeDNSSDQuerier(const String& domain); + + 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 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); + bool isServiceRegistered(const String& name, int port, const ByteArray& 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: + String domain; + 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..82ec623 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDRegisterQuery.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDQuery.h" +#include "Swiften/LinkLocal/DNSSD/DNSSDRegisterQuery.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/Base/String.h" + +namespace Swift { + class FakeDNSSDQuerier; + + class FakeDNSSDRegisterQuery : public DNSSDRegisterQuery, public FakeDNSSDQuery { + public: + 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 ByteArray& i) { + info = i; + } + + void unregisterService() { + finish(); + } + + String name; + int port; + ByteArray info; + }; +} diff --git a/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h new file mode 100644 index 0000000..1f9d7f1 --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Fake/FakeDNSSDResolveHostnameQuery.h @@ -0,0 +1,29 @@ +#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(); + } + + void finish() { + FakeDNSSDQuery::finish(); + } + + 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 new file mode 100644 index 0000000..f6997ef --- /dev/null +++ b/Swiften/LinkLocal/DNSSD/Makefile.inc @@ -0,0 +1,16 @@ +SWIFTEN_SOURCES += \ + Swiften/LinkLocal/DNSSD/DNSSDServiceID.cpp \ + 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) +include Swiften/LinkLocal/DNSSD/Avahi/Makefile.inc +endif + +include Swiften/LinkLocal/DNSSD/Fake/Makefile.inc |