• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

DNSSD

mdnsd-servicebrowser.cpp

Go to the documentation of this file.
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 "mdnsd-servicebrowser_p.h"
00022 #include "domainbrowser.h"
00023 #include "servicebrowser.h"
00024 #include "mdnsd-responder.h"
00025 #include "remoteservice.h"
00026 #include "mdnsd-sdevent.h"
00027 #include <dns_sd.h>
00028 #include <QtCore/QStringList>
00029 #include <QtCore/QHash>
00030 #include <QtCore/QCoreApplication>
00031 #include <QtCore/QTimer>
00032 
00033 #define TIMEOUT_WAN 2000
00034 #define TIMEOUT_LAN 200
00035 
00036 namespace DNSSD
00037 {
00038 void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
00039              const char *serviceName, const char *regtype, const char *replyDomain, void *context);
00040 
00041 ServiceBrowser::ServiceBrowser(const QString& type,bool autoResolve,const QString& domain, const QString& subtype)
00042     :d(new ServiceBrowserPrivate(this))
00043 {
00044     d->m_type=type;
00045     d->m_autoResolve=autoResolve;
00046     d->m_domain=domain;
00047     d->m_subtype=subtype;
00048         d->timeout.setSingleShot(true);
00049     connect(&d->timeout,SIGNAL(timeout()),d,SLOT(onTimeout()));
00050 }
00051 
00052 
00053 ServiceBrowser::State ServiceBrowser::isAvailable()
00054 {
00055 //  DNSServiceRef ref;
00056 //  bool ok (DNSServiceCreateConnection(&ref)==kDNSServiceErr_NoError);
00057 //  if (ok) DNSServiceRefDeallocate(ref);
00058 //  return (ok) ? Working : Stopped;
00059     return Working;
00060 }
00061 ServiceBrowser::~ ServiceBrowser()
00062 {
00063     delete d;
00064 }
00065 
00066 bool ServiceBrowser::isAutoResolving() const
00067 {
00068     return d->m_autoResolve;
00069 }
00070 
00071 
00072 void ServiceBrowserPrivate::serviceResolved(bool success)
00073 {
00074     QObject* sender_obj = const_cast<QObject*>(sender());
00075     RemoteService* svr = static_cast<RemoteService*>(sender_obj);
00076     disconnect(svr,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
00077     QList<RemoteService::Ptr>::Iterator it = m_duringResolve.begin();
00078     QList<RemoteService::Ptr>::Iterator itEnd = m_duringResolve.end();
00079     while ( it!= itEnd && svr!= (*it).data()) ++it;
00080     if (it != itEnd) {
00081         if (success) {
00082             m_services+=(*it);
00083             emit m_parent->serviceAdded(RemoteService::Ptr(svr));
00084         }
00085         m_duringResolve.erase(it);
00086         queryFinished();
00087     }
00088 }
00089 
00090 void ServiceBrowser::startBrowse()
00091 {
00092     if (d->isRunning()) return;
00093     d->m_finished = false;
00094     DNSServiceRef ref;
00095     QString fullType=d->m_type;
00096     if (!d->m_subtype.isEmpty()) fullType=d->m_subtype+"._sub."+d->m_type;
00097     if (DNSServiceBrowse(&ref,0,0, fullType.toAscii().constData(),
00098         domainToDNS(d->m_domain),query_callback,reinterpret_cast<void*>(d))
00099            == kDNSServiceErr_NoError) d->setRef(ref);
00100     if (!d->isRunning()) emit finished();
00101     else d->timeout.start(domainIsLocal(d->m_domain) ? TIMEOUT_LAN : TIMEOUT_WAN);
00102 }
00103 
00104 
00105 void ServiceBrowserPrivate::queryFinished()
00106 {
00107     if (!m_duringResolve.count() && m_finished) emit m_parent->finished();
00108 }
00109 
00110 
00111 QList<RemoteService::Ptr> ServiceBrowser::services() const
00112 {
00113     return d->m_services;
00114 }
00115 
00116 void ServiceBrowser::virtual_hook(int, void*)
00117 {}
00118 
00119 RemoteService::Ptr ServiceBrowserPrivate::find(RemoteService::Ptr s) const
00120 {
00121     Q_FOREACH (const RemoteService::Ptr& i, m_services) if (*s==*i) return i;
00122     Q_FOREACH (const RemoteService::Ptr& i, m_duringResolve) if (*s==*i) return i;
00123     return s;
00124 }
00125 
00126 
00127 void ServiceBrowserPrivate::customEvent(QEvent* event)
00128 {
00129     if (event->type()==QEvent::User+SD_ERROR) {
00130         stop();
00131         m_finished=false;
00132         queryFinished();
00133     }
00134     if (event->type()==QEvent::User+SD_ADDREMOVE) {
00135         AddRemoveEvent *aev = static_cast<AddRemoveEvent*>(event);
00136         // m_type has useless trailing dot
00137         RemoteService::Ptr svr(new RemoteService(aev->m_name,aev->m_type.left(aev->m_type.length()-1),aev->m_domain));
00138         if (aev->m_op==AddRemoveEvent::Add) {
00139             if (m_autoResolve) {
00140             connect(svr.data(),SIGNAL(resolved(bool )),this,SLOT(serviceResolved(bool )));
00141             m_duringResolve+=svr;
00142             svr->resolveAsync();
00143             } else {
00144             m_services+=svr;
00145             emit m_parent->serviceAdded(svr);
00146             }
00147         }
00148         else {
00149             svr=find(svr);
00150             emit m_parent->serviceRemoved(svr);
00151             m_services.removeAll(svr);
00152         }
00153         m_finished = aev->m_last;
00154         if (m_finished) queryFinished();
00155     }
00156 }
00157 
00158 void ServiceBrowserPrivate::onTimeout()
00159 {
00160     m_finished=true;
00161     queryFinished();
00162 }
00163 
00164 void query_callback (DNSServiceRef, DNSServiceFlags flags, uint32_t, DNSServiceErrorType errorCode,
00165              const char *serviceName, const char *regtype, const char *replyDomain,
00166              void *context)
00167 {
00168     QObject *obj = reinterpret_cast<QObject*>(context);
00169     if (errorCode != kDNSServiceErr_NoError) {
00170         ErrorEvent err;
00171         QCoreApplication::sendEvent(obj, &err);
00172     } else {
00173         AddRemoveEvent arev((flags & kDNSServiceFlagsAdd) ? AddRemoveEvent::Add :
00174             AddRemoveEvent::Remove, QString::fromUtf8(serviceName), regtype,
00175             DNSToDomain(replyDomain), !(flags & kDNSServiceFlagsMoreComing));
00176         QCoreApplication::sendEvent(obj, &arev);
00177     }
00178 }
00179 
00180 
00181 }
00182 
00183 #include "servicebrowser.moc"
00184 #include "mdnsd-servicebrowser_p.moc"

DNSSD

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal