DNSSD
query.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "query.h"
00022 #include "responder.h"
00023 #include "remoteservice.h"
00024 #include "sdevent.h"
00025 #include <kdebug.h>
00026 #include <qapplication.h>
00027 #include <qtimer.h>
00028
00029 #define TIMEOUT_WAN 2000
00030 #define TIMEOUT_LAN 200
00031
00032 namespace DNSSD
00033 {
00034 #ifdef HAVE_DNSSD
00035 void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
00036 const char *serviceName, const char *regtype, const char *replyDomain, void *context);
00037 #endif
00038 class QueryPrivate : public Responder
00039 {
00040 public:
00041 QueryPrivate(const QString& type, const QString& domain) : Responder(), m_finished(false),
00042 m_domain(domain), m_type(type)
00043 {};
00044 bool m_finished;
00045 QString m_domain;
00046 QTimer timeout;
00047 QString m_type;
00048 };
00049
00050 Query::Query(const QString& type, const QString& domain)
00051 {
00052 d = new QueryPrivate(type,domain);
00053 connect(&d->timeout,SIGNAL(timeout()),this,SLOT(timeout()));
00054 }
00055
00056
00057 Query::~Query()
00058 {
00059 delete d;
00060 }
00061
00062 bool Query::isRunning() const
00063 {
00064 return d->isRunning();
00065 }
00066
00067 bool Query::isFinished() const
00068 {
00069 return d->m_finished;
00070 }
00071
00072 const QString& Query::domain() const
00073 {
00074 return d->m_domain;
00075 }
00076
00077 void Query::startQuery()
00078 {
00079 if (d->isRunning()) return;
00080 d->m_finished = false;
00081 #ifdef HAVE_DNSSD
00082 DNSServiceRef ref;
00083 if (DNSServiceBrowse(&ref,0,0, d->m_type.ascii(),
00084 domainToDNS(d->m_domain),query_callback,reinterpret_cast<void*>(this))
00085 == kDNSServiceErr_NoError) d->setRef(ref);
00086 #endif
00087 if (!d->isRunning()) emit finished();
00088 else d->timeout.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAN : TIMEOUT_WAN,true);
00089 }
00090 void Query::virtual_hook(int, void*)
00091 {
00092 }
00093
00094 void Query::customEvent(QCustomEvent* event)
00095 {
00096 if (event->type()==QEvent::User+SD_ERROR) {
00097 d->stop();
00098 d->m_finished=false;
00099 emit finished();
00100 }
00101 if (event->type()==QEvent::User+SD_ADDREMOVE) {
00102 RemoteService* svr;
00103 AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
00104
00105 QString type=aev->m_type.left(aev->m_type.length()-1);
00106
00107 if (d->m_type=="_services._dns-sd._udp") svr = new RemoteService(aev->m_name+"."+
00108 type+"."+aev->m_domain);
00109 else svr = new RemoteService(aev->m_name, type, aev->m_domain);
00110 if (aev->m_op==AddRemoveEvent::Add) emit serviceAdded(svr);
00111 else emit serviceRemoved(svr);
00112 d->m_finished = aev->m_last;
00113 if (d->m_finished) emit finished();
00114 }
00115 }
00116
00117 void Query::timeout()
00118 {
00119 d->m_finished=true;
00120 emit finished();
00121 }
00122 #ifdef HAVE_DNSSD
00123 void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
00124 const char *serviceName, const char *regtype, const char *replyDomain,
00125 void *context)
00126 {
00127 QObject *obj = reinterpret_cast<QObject*>(context);
00128 if (errorCode != kDNSServiceErr_NoError) {
00129 ErrorEvent err;
00130 QApplication::sendEvent(obj, &err);
00131 } else {
00132 AddRemoveEvent arev((flags & kDNSServiceFlagsAdd) ? AddRemoveEvent::Add :
00133 AddRemoveEvent::Remove, QString::fromUtf8(serviceName), regtype,
00134 DNSToDomain(replyDomain), !(flags & kDNSServiceFlagsMoreComing));
00135 QApplication::sendEvent(obj, &arev);
00136 }
00137 }
00138 #endif
00139 }
00140 #include "query.moc"