fix parameter inversion,
[kdelibs.git] / dnssd / avahi-publicservice.cpp
blobc2133f5a9c2760c7ed51c00949411a7ef23bb07c
1 /* This file is part of the KDE project
3 * Copyright (C) 2004, 2005 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-publicservice_p.h"
23 #include <QtCore/QCoreApplication>
24 #include <QtCore/QStringList>
26 #include "publicservice.h"
27 #ifdef HAVE_SYS_TYPES_H
28 #include <sys/types.h>
29 #endif
30 #include "servicebrowser.h"
31 #include "settings.h"
32 #include "avahi_server_interface.h"
33 #include "avahi_entrygroup_interface.h"
34 #ifndef KDE_USE_FINAL
35 Q_DECLARE_METATYPE(QList<QByteArray>)
36 #endif
38 namespace DNSSD
41 PublicService::PublicService(const QString& name, const QString& type, unsigned int port,
42 const QString& domain, const QStringList& subtypes)
43 : QObject(), ServiceBase(new PublicServicePrivate(this, name, type, domain, port))
45 K_D;
46 if (domain.isNull()) d->m_domain="local.";
47 d->m_subtypes=subtypes;
51 PublicService::~PublicService()
53 stop();
56 void PublicServicePrivate::tryApply()
58 if (fillEntryGroup()) commit();
59 else {
60 m_parent->stop();
61 emit m_parent->published(false);
65 void PublicService::setServiceName(const QString& serviceName)
67 K_D;
68 d->m_serviceName = serviceName;
69 if (d->m_running) {
70 d->m_group->Reset();
71 d->tryApply();
75 void PublicService::setDomain(const QString& domain)
77 K_D;
78 d->m_domain = domain;
79 if (d->m_running) {
80 d->m_group->Reset();
81 d->tryApply();
86 void PublicService::setType(const QString& type)
88 K_D;
89 d->m_type = type;
90 if (d->m_running) {
91 d->m_group->Reset();
92 d->tryApply();
96 void PublicService::setSubTypes(const QStringList& subtypes)
98 K_D;
99 d->m_subtypes = subtypes;
100 if (d->m_running) {
101 d->m_group->Reset();
102 d->tryApply();
106 QStringList PublicService::subtypes() const
108 K_D;
109 return d->m_subtypes;
112 void PublicService::setPort(unsigned short port)
114 K_D;
115 d->m_port = port;
116 if (d->m_running) {
117 d->m_group->Reset();
118 d->tryApply();
122 void PublicService::setTextData(const QMap<QString,QByteArray>& textData)
124 K_D;
125 d->m_textData = textData;
126 if (d->m_running) {
127 d->m_group->Reset();
128 d->tryApply();
132 bool PublicService::isPublished() const
134 K_D;
135 return d->m_published;
138 bool PublicService::publish()
140 K_D;
141 publishAsync();
142 while (d->m_running && !d->m_published) QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
143 return d->m_published;
146 void PublicService::stop()
148 K_D;
149 if (d->m_group) d->m_group->Reset();
150 d->m_published = false;
152 bool PublicServicePrivate::fillEntryGroup()
154 registerTypes();
155 if (!m_group) {
156 QDBusReply<QDBusObjectPath> rep=m_server->EntryGroupNew();
157 if (!rep.isValid()) return false;
158 m_group=new org::freedesktop::Avahi::EntryGroup("org.freedesktop.Avahi",rep.value().path(), QDBusConnection::systemBus());
159 connect(m_group,SIGNAL(StateChanged(int,const QString&)), this, SLOT(groupStateChanged(int,const QString&)));
161 if (m_serviceName.isNull()) {
162 QDBusReply<QString> rep=m_server->GetHostName();
163 if (!rep.isValid()) return false;
164 m_serviceName=rep.value();
167 QList<QByteArray> txt;
168 QMap<QString,QByteArray>::ConstIterator itEnd = m_textData.end();
169 for (QMap<QString,QByteArray>::ConstIterator it = m_textData.begin(); it!=itEnd ; ++it)
170 if (it.value().isNull()) txt.append(it.key().toAscii());
171 else txt.append(it.key().toAscii()+'='+it.value());
172 m_group->AddService(-1,-1, 0, m_serviceName, m_type , domainToDNS(m_domain) ,
173 m_hostName, m_port,txt);
174 Q_FOREACH(const QString &subtype, m_subtypes)
175 m_group->AddServiceSubtype(-1,-1, 0, m_serviceName, m_type, domainToDNS(m_domain) , subtype);
176 return true;
179 void PublicServicePrivate::serverStateChanged(int s,const QString&)
181 if (!m_running) return;
182 switch (s) {
183 case AVAHI_SERVER_INVALID:
184 m_parent->stop();
185 emit m_parent->published(false);
186 break;
187 case AVAHI_SERVER_REGISTERING:
188 case AVAHI_SERVER_COLLISION:
189 m_group->Reset();
190 m_collision=true;
191 break;
192 case AVAHI_SERVER_RUNNING:
193 if (m_collision) {
194 m_collision=false;
195 tryApply();
200 void PublicService::publishAsync()
202 K_D;
203 if (d->m_running) stop();
205 if (!d->m_server) {
206 d->m_server = new org::freedesktop::Avahi::Server("org.freedesktop.Avahi","/",QDBusConnection::systemBus());
207 connect(d->m_server,SIGNAL(StateChanged(int,const QString&)),d,SLOT(serverStateChanged(int,const QString&)));
210 int state=AVAHI_SERVER_INVALID;
211 QDBusReply<int> rep=d->m_server->GetState();
213 if (rep.isValid()) state=rep.value();
215 d->m_running=true;
216 d->m_collision=true; // make it look like server is getting out of collision to force registering
217 d->serverStateChanged(state, QString());
221 void PublicServicePrivate::groupStateChanged(int s, const QString& reason)
223 switch (s) {
224 case AVAHI_ENTRY_GROUP_COLLISION: {
225 QDBusReply<QString> rep=m_server->GetAlternativeServiceName(m_serviceName);
226 if (rep.isValid()) m_parent->setServiceName(rep.value());
227 else serverStateChanged(AVAHI_SERVER_INVALID, reason);
228 break;
230 case AVAHI_ENTRY_GROUP_ESTABLISHED:
231 m_published=true;
232 emit m_parent->published(true);
233 break;
234 case AVAHI_ENTRY_GROUP_FAILURE:
235 serverStateChanged(AVAHI_SERVER_INVALID, reason);
236 default:
237 break;
241 void PublicService::virtual_hook(int, void*)
248 #include "publicservice.moc"
249 #include "avahi-publicservice_p.moc"