1 /* This file is part of the KDE project
3 * Copyright (C) 2004 Jakub Stachowski <qbast@go2.pl>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "avahi-servicebrowser_p.h"
22 #include <QtCore/QStringList>
23 #include "servicebrowser.h"
24 #include "avahi_servicebrowser_interface.h"
25 #include "avahi_server_interface.h"
26 #include <QtCore/QHash>
27 #include <QtNetwork/QHostAddress>
29 Q_DECLARE_METATYPE(QList
<QByteArray
>)
34 ServiceBrowser::ServiceBrowser(const QString
& type
,bool autoResolve
,const QString
& domain
, const QString
& subtype
)
35 :d(new ServiceBrowserPrivate(this))
39 d
->m_autoResolve
=autoResolve
;
41 d
->m_timer
.setSingleShot(true);
44 ServiceBrowser::State
ServiceBrowser::isAvailable()
46 org::freedesktop::Avahi::Server
s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
47 QDBusReply
<int> rep
= s
.GetState();
48 return (rep
.isValid() && rep
.value()==2) ? Working
:Stopped
;
50 ServiceBrowser::~ServiceBrowser()
55 bool ServiceBrowser::isAutoResolving() const
57 return d
->m_autoResolve
;
60 void ServiceBrowser::startBrowse()
62 if (d
->m_running
) return;
63 org::freedesktop::Avahi::Server
s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
64 QString fullType
=d
->m_type
;
65 if (!d
->m_subtype
.isEmpty()) fullType
=d
->m_subtype
+"._sub."+d
->m_type
;
66 QDBusReply
<QDBusObjectPath
> rep
=s
.ServiceBrowserNew(-1, -1, fullType
, domainToDNS(d
->m_domain
),0);
73 d
->m_browserFinished
=true;
74 org::freedesktop::Avahi::ServiceBrowser
*b
=new org::freedesktop::Avahi::ServiceBrowser("org.freedesktop.Avahi",rep
.value().path(),
75 QDBusConnection::systemBus());
76 connect(b
,SIGNAL(ItemNew(int,int,const QString
&,const QString
&,const QString
&,uint
)),d
,
77 SLOT(gotNewService(int,int,const QString
&,const QString
&,const QString
&, uint
)));
78 connect(b
,SIGNAL(ItemRemove(int,int,const QString
&,const QString
&,const QString
&,uint
)),d
,
79 SLOT(gotRemoveService(int,int,const QString
&,const QString
&,const QString
&, uint
)));
80 connect(b
,SIGNAL(AllForNow()),d
,SLOT(browserFinished()));
82 connect(&d
->m_timer
,SIGNAL(timeout()), d
, SLOT(browserFinished()));
83 d
->m_timer
.start(TIMEOUT_LAN
);
86 void ServiceBrowserPrivate::serviceResolved(bool success
)
88 QObject
* sender_obj
= const_cast<QObject
*>(sender());
89 RemoteService
* svr
= static_cast<RemoteService
*>(sender_obj
);
90 disconnect(svr
,SIGNAL(resolved(bool)),this,SLOT(serviceResolved(bool)));
91 QList
<RemoteService::Ptr
>::Iterator it
= m_duringResolve
.begin();
92 QList
<RemoteService::Ptr
>::Iterator itEnd
= m_duringResolve
.end();
93 while ( it
!= itEnd
&& svr
!= (*it
).data()) ++it
;
97 emit m_parent
->serviceAdded(RemoteService::Ptr(svr
));
99 m_duringResolve
.erase(it
);
104 RemoteService::Ptr
ServiceBrowserPrivate::find(RemoteService::Ptr s
) const
106 Q_FOREACH (const RemoteService::Ptr
& i
, m_services
) if (*s
==*i
) return i
;
107 Q_FOREACH (const RemoteService::Ptr
& i
, m_duringResolve
) if (*s
==*i
) return i
;
111 void ServiceBrowserPrivate::gotNewService(int,int,const QString
& name
, const QString
& type
, const QString
& domain
, uint
)
113 m_timer
.start(TIMEOUT_LAN
);
114 RemoteService::Ptr
svr(new RemoteService(name
, type
,domain
));
116 connect(svr
.data(),SIGNAL(resolved(bool )),this,SLOT(serviceResolved(bool )));
117 m_duringResolve
+=svr
;
121 emit m_parent
->serviceAdded(svr
);
125 void ServiceBrowserPrivate::gotRemoveService(int,int,const QString
& name
, const QString
& type
, const QString
& domain
, uint
)
127 m_timer
.start(TIMEOUT_LAN
);
128 RemoteService::Ptr svr
=find(RemoteService::Ptr(new RemoteService(name
, type
,domain
)));
129 emit m_parent
->serviceRemoved(svr
);
130 m_services
.removeAll(svr
);
132 void ServiceBrowserPrivate::browserFinished()
135 m_browserFinished
=true;
139 void ServiceBrowserPrivate::queryFinished()
141 if (!m_duringResolve
.count() && m_browserFinished
) emit m_parent
->finished();
145 QList
<RemoteService::Ptr
> ServiceBrowser::services() const
147 return d
->m_services
;
150 void ServiceBrowser::virtual_hook(int, void*)
153 QHostAddress
ServiceBrowser::resolveHostName(const QString
&hostname
)
155 org::freedesktop::Avahi::Server
s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
163 QDBusReply
<int> reply
= s
.ResolveHostName(-1, -1, hostname
, 0, (unsigned int ) 0, protocol
, name
, aprotocol
, address
, flags
);
166 return QHostAddress(address
);
168 return QHostAddress();
171 QString
ServiceBrowser::getLocalHostName()
173 org::freedesktop::Avahi::Server
s("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
175 QDBusReply
<QString
> reply
= s
.GetHostName();
178 return reply
.value();
185 #include "servicebrowser.moc"
186 #include "avahi-servicebrowser_p.moc"