• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • dnssd
 

dnssd

servicebrowser.cpp

00001 /* This file is part of the KDE project
00002  *
00003  * Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 
00021 #include <signal.h>
00022 #include <errno.h>
00023 #include <tqstringlist.h>
00024 #include <tqfile.h>
00025 #include "domainbrowser.h"
00026 #include "responder.h"
00027 #include "query.h"
00028 #include "servicebrowser.h"
00029 #ifdef HAVE_DNSSD
00030 #include <avahi-client/client.h>
00031 #endif
00032 #include <config.h>
00033 
00034 namespace DNSSD
00035 {
00036 
00037 const TQString ServiceBrowser::AllServices = "_services._dns-sd._udp";
00038 
00039 class ServiceBrowserPrivate
00040 {
00041 public:
00042     ServiceBrowserPrivate() : m_running(false)
00043     {}
00044     TQValueList<RemoteService::Ptr> m_services;
00045     TQValueList<RemoteService::Ptr> m_duringResolve;
00046     TQStringList m_types;
00047     DomainBrowser* m_domains;
00048     int m_flags;
00049     bool m_running;
00050     bool m_finished;
00051     TQDict<Query> resolvers;
00052 };
00053 
00054 ServiceBrowser::ServiceBrowser(const TQString& type,DomainBrowser* domains,bool autoResolve)
00055 {
00056     if (domains) init(type,domains,autoResolve ? AutoResolve : 0);
00057         else init(type,new DomainBrowser(this),autoResolve ?  AutoResolve|AutoDelete : AutoDelete);
00058 }
00059 ServiceBrowser::ServiceBrowser(const TQStringList& types,DomainBrowser* domains,int flags)
00060 {
00061     if (domains) init(types,domains,flags);
00062         else init(types,new DomainBrowser(this),flags|AutoDelete);
00063 }
00064 
00065 void ServiceBrowser::init(const TQStringList& type,DomainBrowser* domains,int flags)
00066 {
00067     d = new ServiceBrowserPrivate();
00068     d->resolvers.setAutoDelete(true);
00069     d->m_types=type;
00070     d->m_flags=flags;
00071     d->m_domains = domains;
00072     connect(d->m_domains,TQT_SIGNAL(domainAdded(const TQString& )),this,TQT_SLOT(addDomain(const TQString& )));
00073     connect(d->m_domains,TQT_SIGNAL(domainRemoved(const TQString& )),this,
00074         TQT_SLOT(removeDomain(const TQString& )));
00075 }
00076 ServiceBrowser::ServiceBrowser(const TQString& type,const TQString& domain,bool autoResolve)
00077 {
00078     init(type,new DomainBrowser(domain,false,this),autoResolve ? AutoResolve|AutoDelete : AutoDelete);
00079 }
00080 ServiceBrowser::ServiceBrowser(const TQString& type,const TQString& domain,int flags)
00081 {
00082     init(type,new DomainBrowser(domain,false,this),flags | AutoDelete);
00083 }
00084 
00085 const ServiceBrowser::State ServiceBrowser::isAvailable()
00086 {
00087 #ifdef HAVE_DNSSD
00088     AvahiClientState s = Responder::self().state();
00089 #ifdef AVAHI_API_0_6
00090     return (s==AVAHI_CLIENT_FAILURE) ? Stopped : Working;
00091 #else
00092     return (s==AVAHI_CLIENT_S_INVALID || s==AVAHI_CLIENT_DISCONNECTED) ? Stopped : Working;
00093 #endif
00094 #else
00095     return Unsupported;
00096 #endif
00097 }
00098 ServiceBrowser::~ ServiceBrowser()
00099 {
00100     if (d->m_flags & AutoDelete) delete d->m_domains;
00101     delete d;
00102 }
00103 
00104 const DomainBrowser* ServiceBrowser::browsedDomains() const
00105 {
00106     return d->m_domains;
00107 }
00108 
00109 void ServiceBrowser::serviceResolved(bool success)
00110 {
00111     TQObject* sender_obj = const_cast<TQObject*>(TQT_TQOBJECT_CONST(sender()));
00112     RemoteService* svr = static_cast<RemoteService*>(sender_obj);
00113     disconnect(svr,TQT_SIGNAL(resolved(bool)),this,TQT_SLOT(serviceResolved(bool)));
00114     TQValueList<RemoteService::Ptr>::Iterator it = d->m_duringResolve.begin();
00115     TQValueList<RemoteService::Ptr>::Iterator itEnd = d->m_duringResolve.end();
00116     while ( it!= itEnd && svr!= (*it)) ++it;
00117     if (it != itEnd) {
00118         if (success) {
00119             d->m_services+=(*it);
00120             emit serviceAdded(svr);
00121         }
00122         d->m_duringResolve.remove(it);
00123         queryFinished();
00124     }
00125 }
00126 
00127 void ServiceBrowser::startBrowse()
00128 {
00129     if (d->m_running) return;
00130     d->m_running=true;
00131     if (isAvailable()!=Working) return;
00132     if (d->m_domains->isRunning()) {
00133         TQStringList::const_iterator itEnd  = d->m_domains->domains().end();
00134         for ( TQStringList::const_iterator it = d->m_domains->domains().begin(); it != itEnd; ++it )
00135             addDomain(*it);
00136     } else d->m_domains->startBrowse();
00137 }
00138 
00139 void ServiceBrowser::gotNewService(RemoteService::Ptr svr)
00140 {
00141     if (findDuplicate(svr)==(d->m_services.end()))  {
00142         if (d->m_flags & AutoResolve) {
00143             connect(svr,TQT_SIGNAL(resolved(bool )),this,TQT_SLOT(serviceResolved(bool )));
00144             d->m_duringResolve+=svr;
00145             svr->resolveAsync();
00146         } else  {
00147             d->m_services+=svr;
00148             emit serviceAdded(svr);
00149         }
00150     }
00151 }
00152 
00153 void ServiceBrowser::gotRemoveService(RemoteService::Ptr svr)
00154 {
00155     TQValueList<RemoteService::Ptr>::Iterator it = findDuplicate(svr);
00156     if (it!=(d->m_services.end())) {
00157         emit serviceRemoved(*it);
00158         d->m_services.remove(it);
00159     }
00160 }
00161 
00162 
00163 void ServiceBrowser::removeDomain(const TQString& domain)
00164 {
00165     while (d->resolvers[domain]) d->resolvers.remove(domain);
00166     TQValueList<RemoteService::Ptr>::Iterator it = d->m_services.begin();
00167     while (it!=d->m_services.end())
00168         // use section to skip possible trailing dot
00169         if ((*it)->domain().section('.',0) == domain.section('.',0)) {
00170             emit serviceRemoved(*it);
00171             it = d->m_services.remove(it);
00172         } else ++it;
00173 }
00174 
00175 void ServiceBrowser::addDomain(const TQString& domain)
00176 {
00177     if (!d->m_running) return;
00178     if (!(d->resolvers[domain])) {
00179         TQStringList::ConstIterator itEnd = d->m_types.end();
00180         for (TQStringList::ConstIterator it=d->m_types.begin(); it!=itEnd; ++it) {
00181             Query* b = new Query((*it),domain);
00182             connect(b,TQT_SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),this,
00183                 TQT_SLOT(gotNewService(DNSSD::RemoteService::Ptr)));
00184             connect(b,TQT_SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr )),this,
00185                 TQT_SLOT(gotRemoveService(DNSSD::RemoteService::Ptr)));
00186             connect(b,TQT_SIGNAL(finished()),this,TQT_SLOT(queryFinished()));
00187             b->startQuery();
00188             d->resolvers.insert(domain,b);
00189         }
00190     }
00191 }
00192 
00193 void ServiceBrowser::queryFinished()
00194 {
00195     if (allFinished()) emit finished();
00196 }
00197 
00198 bool ServiceBrowser::allFinished()
00199 {
00200     if  (d->m_duringResolve.count()) return false;
00201     bool all = true;
00202     TQDictIterator<Query> it(d->resolvers);
00203     for ( ; it.current(); ++it) all&=(*it)->isFinished();
00204     return all;
00205 }
00206 
00207 const TQValueList<RemoteService::Ptr>& ServiceBrowser::services() const
00208 {
00209     return d->m_services;
00210 }
00211 
00212 void ServiceBrowser::virtual_hook(int, void*)
00213 {}
00214 
00215 TQValueList<RemoteService::Ptr>::Iterator ServiceBrowser::findDuplicate(RemoteService::Ptr src)
00216 {
00217     TQValueList<RemoteService::Ptr>::Iterator itEnd = d->m_services.end();
00218     for (TQValueList<RemoteService::Ptr>::Iterator it = d->m_services.begin(); it!=itEnd; ++it)
00219         if ((src->type()==(*it)->type()) && (src->serviceName()==(*it)->serviceName()) &&
00220                    (src->domain() == (*it)->domain())) return it;
00221     return itEnd;
00222 }
00223 
00224 
00225 }
00226 
00227 #include "servicebrowser.moc"

dnssd

Skip menu "dnssd"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

dnssd

Skip menu "dnssd"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for dnssd by doxygen 1.6.3
This website is maintained by Timothy Pearson.