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