00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avahi-servicebrowser_p.h"
00022 #include <QtCore/QStringList>
00023 #include "servicebrowser.h"
00024 #include "avahi_servicebrowser_interface.h"
00025 #include "avahi_server_interface.h"
00026 #include <QtCore/QHash>
00027 #ifndef KDE_USE_FINAL
00028 Q_DECLARE_METATYPE(QList<QByteArray>)
00029 #endif
00030 namespace DNSSD
00031 {
00032
00033 ServiceBrowser::ServiceBrowser(const QString& type,bool autoResolve,const QString& domain, const QString& subtype)
00034 :d(new ServiceBrowserPrivate(this))
00035 {
00036 d->m_type=type;
00037 d->m_subtype=subtype;
00038 d->m_autoResolve=autoResolve;
00039 d->m_domain=domain;
00040 d->m_timer.setSingleShot(true);
00041 }
00042
00043 ServiceBrowser::State ServiceBrowser::isAvailable()
00044 {
00045 org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
00046 QDBusReply<int> rep= s.GetState();
00047 return (rep.isValid() && rep.value()==2) ? Working:Stopped;
00048 }
00049 ServiceBrowser::~ServiceBrowser()
00050 {
00051 delete d;
00052 }
00053
00054 bool ServiceBrowser::isAutoResolving() const
00055 {
00056 return d->m_autoResolve;
00057 }
00058
00059 void ServiceBrowser::startBrowse()
00060 {
00061 if (d->m_running) return;
00062 org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
00063 QString fullType=d->m_type;
00064 if (!d->m_subtype.isEmpty()) fullType=d->m_subtype+"._sub."+d->m_type;
00065 QDBusReply<QDBusObjectPath> rep=s.ServiceBrowserNew(-1, -1, fullType, domainToDNS(d->m_domain),0);
00066
00067 if (!rep.isValid()) {
00068 emit finished();
00069 return;
00070 }
00071 d->m_running=true;
00072 d->m_browserFinished=true;
00073 org::freedesktop::Avahi::ServiceBrowser *b=new org::freedesktop::Avahi::ServiceBrowser("org.freedesktop.Avahi",rep.value().path(),
00074 QDBusConnection::systemBus());
00075 connect(b,SIGNAL(ItemNew(int,int,const QString&,const QString&,const QString&,uint)),d,
00076 SLOT(gotNewService(int,int,const QString&,const QString&,const QString&, uint)));
00077 connect(b,SIGNAL(ItemRemove(int,int,const QString&,const QString&,const QString&,uint)),d,
00078 SLOT(gotRemoveService(int,int,const QString&,const QString&,const QString&, uint)));
00079 connect(b,SIGNAL(AllForNow()),d,SLOT(browserFinished()));
00080 d->m_browser=b;
00081 connect(&d->m_timer,SIGNAL(timeout()), d, SLOT(browserFinished()));
00082 d->m_timer.start(TIMEOUT_LAN);
00083 }
00084
00085 void ServiceBrowserPrivate::serviceResolved(bool success)
00086 {
00087 QObject* sender_obj = const_cast<QObject*>(sender());
00088 RemoteService* svr = static_cast<RemoteService*>(sender_obj);
00089 disconnect(svr,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
00090 QList<RemoteService::Ptr>::Iterator it = m_duringResolve.begin();
00091 QList<RemoteService::Ptr>::Iterator itEnd = m_duringResolve.end();
00092 while ( it!= itEnd && svr!= (*it).data()) ++it;
00093 if (it != itEnd) {
00094 if (success) {
00095 m_services+=(*it);
00096 emit m_parent->serviceAdded(RemoteService::Ptr(svr));
00097 }
00098 m_duringResolve.erase(it);
00099 queryFinished();
00100 }
00101 }
00102
00103 RemoteService::Ptr ServiceBrowserPrivate::find(RemoteService::Ptr s) const
00104 {
00105 Q_FOREACH (const RemoteService::Ptr& i, m_services) if (*s==*i) return i;
00106 Q_FOREACH (const RemoteService::Ptr& i, m_duringResolve) if (*s==*i) return i;
00107 return s;
00108 }
00109
00110 void ServiceBrowserPrivate::gotNewService(int,int,const QString& name, const QString& type, const QString& domain, uint)
00111 {
00112 m_timer.start(TIMEOUT_LAN);
00113 RemoteService::Ptr svr(new RemoteService(name, type,domain));
00114 if (m_autoResolve) {
00115 connect(svr.data(),SIGNAL(resolved(bool )),this,SLOT(serviceResolved(bool )));
00116 m_duringResolve+=svr;
00117 svr->resolveAsync();
00118 } else {
00119 m_services+=svr;
00120 emit m_parent->serviceAdded(svr);
00121 }
00122 }
00123
00124 void ServiceBrowserPrivate::gotRemoveService(int,int,const QString& name, const QString& type, const QString& domain, uint)
00125 {
00126 m_timer.start(TIMEOUT_LAN);
00127 RemoteService::Ptr svr=find(RemoteService::Ptr(new RemoteService(name, type,domain)));
00128 emit m_parent->serviceRemoved(svr);
00129 m_services.removeAll(svr);
00130 }
00131 void ServiceBrowserPrivate::browserFinished()
00132 {
00133 m_timer.stop();
00134 m_browserFinished=true;
00135 queryFinished();
00136 }
00137
00138 void ServiceBrowserPrivate::queryFinished()
00139 {
00140 if (!m_duringResolve.count() && m_browserFinished) emit m_parent->finished();
00141 }
00142
00143
00144 QList<RemoteService::Ptr> ServiceBrowser::services() const
00145 {
00146 return d->m_services;
00147 }
00148
00149 void ServiceBrowser::virtual_hook(int, void*)
00150 {}
00151
00152
00153 }
00154
00155 #include "servicebrowser.moc"
00156 #include "avahi-servicebrowser_p.moc"