diff options
Diffstat (limited to 'dnssd/query.cpp')
-rw-r--r-- | dnssd/query.cpp | 132 |
1 files changed, 89 insertions, 43 deletions
diff --git a/dnssd/query.cpp b/dnssd/query.cpp index bcb9c69f5..27b297816 100644 --- a/dnssd/query.cpp +++ b/dnssd/query.cpp @@ -22,26 +22,46 @@ #include "responder.h" #include "remoteservice.h" #include "sdevent.h" -#include <kdebug.h> +#include <qdatetime.h> #include <qapplication.h> #include <qtimer.h> -#define TIMEOUT_WAN 2000 +#include <avahi-client/client.h> +#ifdef AVAHI_API_0_6 +#include <avahi-client/lookup.h> +#endif + #define TIMEOUT_LAN 200 namespace DNSSD { -#ifdef HAVE_DNSSD -void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode, - const char *serviceName, const char *regtype, const char *replyDomain, void *context); +#ifdef AVAHI_API_0_6 + +void services_callback(AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* name, + const char* regtype, const char* domain, AvahiLookupResultFlags, void* context); +void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype, + const char* replyDomain, AvahiLookupResultFlags, void* context); +#else +void services_callback(AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* name, + const char* regtype, const char* domain, void* context); +void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype, + const char* replyDomain, void* context); +void domains_callback(AvahiDomainBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain, + void* context); #endif -class QueryPrivate : public Responder + +enum BrowserType { Types, Services }; + +class QueryPrivate { public: - QueryPrivate(const QString& type, const QString& domain) : Responder(), m_finished(false), - m_domain(domain), m_type(type) - {}; + QueryPrivate(const QString& type, const QString& domain) : m_finished(false), m_browser(0), + m_running(false), m_domain(domain), m_type(type) {} + bool m_finished; + BrowserType m_browserType; + void* m_browser; + bool m_running; QString m_domain; QTimer timeout; QString m_type; @@ -56,12 +76,18 @@ Query::Query(const QString& type, const QString& domain) Query::~Query() { + if (d->m_browser) { + switch (d->m_browserType) { + case Services: avahi_service_browser_free((AvahiServiceBrowser*)d->m_browser); break; + case Types: avahi_service_type_browser_free((AvahiServiceTypeBrowser*)d->m_browser); break; + } + } delete d; } bool Query::isRunning() const { - return d->isRunning(); + return d->m_running; } bool Query::isFinished() const @@ -76,16 +102,31 @@ const QString& Query::domain() const void Query::startQuery() { - if (d->isRunning()) return; + if (d->m_running) return; d->m_finished = false; -#ifdef HAVE_DNSSD - DNSServiceRef ref; - if (DNSServiceBrowse(&ref,0,0, d->m_type.ascii(), - domainToDNS(d->m_domain),query_callback,reinterpret_cast<void*>(this)) - == kDNSServiceErr_NoError) d->setRef(ref); + if (d->m_type=="_services._dns-sd._udp") { + d->m_browserType = Types; +#ifdef AVAHI_API_0_6 + d->m_browser = avahi_service_type_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + domainToDNS(d->m_domain), (AvahiLookupFlags)0, types_callback, this); +#else + d->m_browser = avahi_service_type_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + d->m_domain.utf8(), types_callback, this); #endif - if (!d->isRunning()) emit finished(); - else d->timeout.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAN : TIMEOUT_WAN,true); + } else { + d->m_browserType = Services; +#ifdef AVAHI_API_0_6 + d->m_browser = avahi_service_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + d->m_type.ascii(),domainToDNS(d->m_domain), (AvahiLookupFlags)0, services_callback,this); +#else + d->m_browser = avahi_service_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + d->m_type.ascii(),d->m_domain.utf8(),services_callback,this); +#endif + } + if (d->m_browser) { + d->m_running=true; + d->timeout.start(TIMEOUT_LAN,true); + } else emit finished(); } void Query::virtual_hook(int, void*) { @@ -93,24 +134,15 @@ void Query::virtual_hook(int, void*) void Query::customEvent(QCustomEvent* event) { - if (event->type()==QEvent::User+SD_ERROR) { - d->stop(); - d->m_finished=false; - emit finished(); - } if (event->type()==QEvent::User+SD_ADDREMOVE) { - RemoteService* svr; + d->timeout.start(TIMEOUT_LAN,true); + d->m_finished=false; AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event); // m_type has useless trailing dot - QString type=aev->m_type.left(aev->m_type.length()-1); - // label is badly splitted here - _http _tcp.local. . - rely on decode() - if (d->m_type=="_services._dns-sd._udp") svr = new RemoteService(aev->m_name+"."+ - type+"."+aev->m_domain); - else svr = new RemoteService(aev->m_name, type, aev->m_domain); + RemoteService* svr = new RemoteService(aev->m_name, + aev->m_type,aev->m_domain); if (aev->m_op==AddRemoveEvent::Add) emit serviceAdded(svr); else emit serviceRemoved(svr); - d->m_finished = aev->m_last; - if (d->m_finished) emit finished(); } } @@ -119,22 +151,36 @@ void Query::timeout() d->m_finished=true; emit finished(); } -#ifdef HAVE_DNSSD -void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode, - const char *serviceName, const char *regtype, const char *replyDomain, - void *context) + +#ifdef AVAHI_API_0_6 +void services_callback (AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, + const char* serviceName, const char* regtype, const char* replyDomain, AvahiLookupResultFlags, void* context) +#else +void services_callback (AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, + const char* serviceName, const char* regtype, const char* replyDomain, void* context) +#endif { QObject *obj = reinterpret_cast<QObject*>(context); - if (errorCode != kDNSServiceErr_NoError) { - ErrorEvent err; - QApplication::sendEvent(obj, &err); - } else { - AddRemoveEvent arev((flags & kDNSServiceFlagsAdd) ? AddRemoveEvent::Add : + AddRemoveEvent* arev = new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add : AddRemoveEvent::Remove, QString::fromUtf8(serviceName), regtype, - DNSToDomain(replyDomain), !(flags & kDNSServiceFlagsMoreComing)); - QApplication::sendEvent(obj, &arev); - } + DNSToDomain(replyDomain)); + QApplication::postEvent(obj, arev); } + +#ifdef AVAHI_API_0_6 +void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype, + const char* replyDomain, AvahiLookupResultFlags, void* context) +#else +void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype, + const char* replyDomain, void* context) #endif +{ + QObject *obj = reinterpret_cast<QObject*>(context); + AddRemoveEvent* arev = new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add : + AddRemoveEvent::Remove, QString::null, regtype, + DNSToDomain(replyDomain)); + QApplication::postEvent(obj, arev); +} + } #include "query.moc" |