#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 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()), 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(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()), shared_from_this()); } else { MainEventLoop::postEvent( boost::bind( boost::ref(onServiceResolved), Result(String(fullName), String(host), port, LinkLocalServiceInfo::createFromTXTRecord( ByteArray(reinterpret_cast(txtRecord), txtLen)))), shared_from_this()); } } }; }