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
00055 void ServiceBrowser::startBrowse()
00056 {
00057 if (d->m_running) return;
00058 org::freedesktop::Avahi::Server s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
00059 QString fullType=d->m_type;
00060 if (!d->m_subtype.isEmpty()) fullType=d->m_subtype+"._sub."+d->m_type;
00061 QDBusReply<QDBusObjectPath> rep=s.ServiceBrowserNew(-1, -1, fullType, domainToDNS(d->m_domain),0);
00062
00063 if (!rep.isValid()) {
00064 emit finished();
00065 return;
00066 }
00067 d->m_running=true;
00068 d->m_browserFinished=true;
00069 org::freedesktop::Avahi::ServiceBrowser *b=new org::freedesktop::Avahi::ServiceBrowser("org.freedesktop.Avahi",rep.value().path(),
00070 QDBusConnection::systemBus());
00071 connect(b,SIGNAL(ItemNew(int,int,const QString&,const QString&,const QString&,uint)),d,
00072 SLOT(gotNewService(int,int,const QString&,const QString&,const QString&, uint)));
00073 connect(b,SIGNAL(ItemRemove(int,int,const QString&,const QString&,const QString&,uint)),d,
00074 SLOT(gotRemoveService(int,int,const QString&,const QString&,const QString&, uint)));
00075 connect(b,SIGNAL(AllForNow()),d,SLOT(browserFinished()));
00076 d->m_browser=b;
00077 connect(&d->m_timer,SIGNAL(timeout()), d, SLOT(browserFinished()));
00078 d->m_timer.start(TIMEOUT_LAN);
00079 }
00080
00081 void ServiceBrowserPrivate::serviceResolved(bool success)
00082 {
00083 QObject* sender_obj = const_cast<QObject*>(sender());
00084 RemoteService* svr = static_cast<RemoteService*>(sender_obj);
00085 disconnect(svr,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
00086 QList<RemoteService::Ptr>::Iterator it = m_duringResolve.begin();
00087 QList<RemoteService::Ptr>::Iterator itEnd = m_duringResolve.end();
00088 while ( it!= itEnd && svr!= (*it).data()) ++it;
00089 if (it != itEnd) {
00090 if (success) {
00091 m_services+=(*it);
00092 emit m_parent->serviceAdded(RemoteService::Ptr(svr));
00093 }
00094 m_duringResolve.erase(it);
00095 queryFinished();
00096 }
00097 }
00098
00099
00100 void ServiceBrowserPrivate::gotNewService(int,int,const QString& name, const QString& type, const QString& domain, uint)
00101 {
00102 m_timer.start(TIMEOUT_LAN);
00103 RemoteService::Ptr svr(new RemoteService(name, type,domain));
00104 if (m_autoResolve) {
00105 connect(svr.data(),SIGNAL(resolved(bool )),this,SLOT(serviceResolved(bool )));
00106 m_duringResolve+=svr;
00107 svr->resolveAsync();
00108 } else {
00109 m_services+=svr;
00110 emit m_parent->serviceAdded(svr);
00111 }
00112 }
00113
00114 void ServiceBrowserPrivate::gotRemoveService(int,int,const QString& name, const QString& type, const QString& domain, uint)
00115 {
00116 m_timer.start(TIMEOUT_LAN);
00117 RemoteService::Ptr svr(new RemoteService(name, type,domain));
00118 emit m_parent->serviceRemoved(svr);
00119 m_services.removeAll(svr);
00120 }
00121 void ServiceBrowserPrivate::browserFinished()
00122 {
00123 m_timer.stop();
00124 m_browserFinished=true;
00125 queryFinished();
00126 }
00127
00128 void ServiceBrowserPrivate::queryFinished()
00129 {
00130 if (!m_duringResolve.count() && m_browserFinished) emit m_parent->finished();
00131 }
00132
00133
00134 QList<RemoteService::Ptr> ServiceBrowser::services() const
00135 {
00136 return d->m_services;
00137 }
00138
00139 void ServiceBrowser::virtual_hook(int, void*)
00140 {}
00141
00142
00143 }
00144
00145 #include "servicebrowser.moc"
00146 #include "avahi-servicebrowser_p.moc"