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 <qdatetime.h>
00026 #include <qapplication.h>
00027 #include <qtimer.h>
00028
00029 #include <avahi-client/client.h>
00030 #ifdef AVAHI_API_0_6
00031 #include <avahi-client/lookup.h>
00032 #endif
00033
00034 #define TIMEOUT_LAN 200
00035
00036 namespace DNSSD
00037 {
00038 #ifdef AVAHI_API_0_6
00039
00040 void services_callback(AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* name,
00041 const char* regtype, const char* domain, AvahiLookupResultFlags, void* context);
00042 void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype,
00043 const char* replyDomain, AvahiLookupResultFlags, void* context);
00044 #else
00045 void services_callback(AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* name,
00046 const char* regtype, const char* domain, void* context);
00047 void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype,
00048 const char* replyDomain, void* context);
00049 void domains_callback(AvahiDomainBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* replyDomain,
00050 void* context);
00051 #endif
00052
00053 enum BrowserType { Types, Services };
00054
00055 class QueryPrivate
00056 {
00057 public:
00058 QueryPrivate(const QString& type, const QString& domain) : m_finished(false), m_browser(0),
00059 m_running(false), m_domain(domain), m_type(type) {}
00060
00061 bool m_finished;
00062 BrowserType m_browserType;
00063 void* m_browser;
00064 bool m_running;
00065 QString m_domain;
00066 QTimer timeout;
00067 QString m_type;
00068 };
00069
00070 Query::Query(const QString& type, const QString& domain)
00071 {
00072 d = new QueryPrivate(type,domain);
00073 connect(&d->timeout,SIGNAL(timeout()),this,SLOT(timeout()));
00074 }
00075
00076
00077 Query::~Query()
00078 {
00079 if (d->m_browser) {
00080 switch (d->m_browserType) {
00081 case Services: avahi_service_browser_free((AvahiServiceBrowser*)d->m_browser); break;
00082 case Types: avahi_service_type_browser_free((AvahiServiceTypeBrowser*)d->m_browser); break;
00083 }
00084 }
00085 delete d;
00086 }
00087
00088 bool Query::isRunning() const
00089 {
00090 return d->m_running;
00091 }
00092
00093 bool Query::isFinished() const
00094 {
00095 return d->m_finished;
00096 }
00097
00098 const QString& Query::domain() const
00099 {
00100 return d->m_domain;
00101 }
00102
00103 void Query::startQuery()
00104 {
00105 if (d->m_running) return;
00106 d->m_finished = false;
00107 if (d->m_type=="_services._dns-sd._udp") {
00108 d->m_browserType = Types;
00109 #ifdef AVAHI_API_0_6
00110 d->m_browser = avahi_service_type_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00111 domainToDNS(d->m_domain), (AvahiLookupFlags)0, types_callback, this);
00112 #else
00113 d->m_browser = avahi_service_type_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00114 d->m_domain.utf8(), types_callback, this);
00115 #endif
00116 } else {
00117 d->m_browserType = Services;
00118 #ifdef AVAHI_API_0_6
00119 d->m_browser = avahi_service_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00120 d->m_type.ascii(),domainToDNS(d->m_domain), (AvahiLookupFlags)0, services_callback,this);
00121 #else
00122 d->m_browser = avahi_service_browser_new(Responder::self().client(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
00123 d->m_type.ascii(),d->m_domain.utf8(),services_callback,this);
00124 #endif
00125 }
00126 if (d->m_browser) {
00127 d->m_running=true;
00128 d->timeout.start(TIMEOUT_LAN,true);
00129 } else emit finished();
00130 }
00131 void Query::virtual_hook(int, void*)
00132 {
00133 }
00134
00135 void Query::customEvent(QCustomEvent* event)
00136 {
00137 if (event->type()==QEvent::User+SD_ADDREMOVE) {
00138 d->timeout.start(TIMEOUT_LAN,true);
00139 d->m_finished=false;
00140 AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
00141
00142 RemoteService* svr = new RemoteService(aev->m_name,
00143 aev->m_type,aev->m_domain);
00144 if (aev->m_op==AddRemoveEvent::Add) emit serviceAdded(svr);
00145 else emit serviceRemoved(svr);
00146 }
00147 }
00148
00149 void Query::timeout()
00150 {
00151 d->m_finished=true;
00152 emit finished();
00153 }
00154
00155 #ifdef AVAHI_API_0_6
00156 void services_callback (AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event,
00157 const char* serviceName, const char* regtype, const char* replyDomain, AvahiLookupResultFlags, void* context)
00158 #else
00159 void services_callback (AvahiServiceBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event,
00160 const char* serviceName, const char* regtype, const char* replyDomain, void* context)
00161 #endif
00162 {
00163 QObject *obj = reinterpret_cast<QObject*>(context);
00164 AddRemoveEvent* arev = new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add :
00165 AddRemoveEvent::Remove, QString::fromUtf8(serviceName), regtype,
00166 DNSToDomain(replyDomain));
00167 QApplication::postEvent(obj, arev);
00168 }
00169
00170 #ifdef AVAHI_API_0_6
00171 void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype,
00172 const char* replyDomain, AvahiLookupResultFlags, void* context)
00173 #else
00174 void types_callback(AvahiServiceTypeBrowser*, AvahiIfIndex, AvahiProtocol, AvahiBrowserEvent event, const char* regtype,
00175 const char* replyDomain, void* context)
00176 #endif
00177 {
00178 QObject *obj = reinterpret_cast<QObject*>(context);
00179 AddRemoveEvent* arev = new AddRemoveEvent((event==AVAHI_BROWSER_NEW) ? AddRemoveEvent::Add :
00180 AddRemoveEvent::Remove, QString::null, regtype,
00181 DNSToDomain(replyDomain));
00182 QApplication::postEvent(obj, arev);
00183 }
00184
00185 }
00186 #include "query.moc"