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>
30 #include "servicebrowser.h"
32 #include "avahi_server_interface.h"
33 #include "avahi_entrygroup_interface.h"
35 Q_DECLARE_METATYPE(QList
<QByteArray
>)
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
))
46 if (domain
.isNull()) d
->m_domain
="local.";
47 d
->m_subtypes
=subtypes
;
51 PublicService::~PublicService()
56 void PublicServicePrivate::tryApply()
58 if (fillEntryGroup()) commit();
61 emit m_parent
->published(false);
65 void PublicService::setServiceName(const QString
& serviceName
)
68 d
->m_serviceName
= serviceName
;
75 void PublicService::setDomain(const QString
& domain
)
86 void PublicService::setType(const QString
& type
)
96 void PublicService::setSubTypes(const QStringList
& subtypes
)
99 d
->m_subtypes
= subtypes
;
106 QStringList
PublicService::subtypes() const
109 return d
->m_subtypes
;
112 void PublicService::setPort(unsigned short port
)
122 void PublicService::setTextData(const QMap
<QString
,QByteArray
>& textData
)
125 d
->m_textData
= textData
;
132 bool PublicService::isPublished() const
135 return d
->m_published
;
138 bool PublicService::publish()
142 while (d
->m_running
&& !d
->m_published
) QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents
);
143 return d
->m_published
;
146 void PublicService::stop()
149 if (d
->m_group
) d
->m_group
->Reset();
150 d
->m_published
= false;
152 bool PublicServicePrivate::fillEntryGroup()
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
);
179 void PublicServicePrivate::serverStateChanged(int s
,const QString
&)
181 if (!m_running
) return;
183 case AVAHI_SERVER_INVALID
:
185 emit m_parent
->published(false);
187 case AVAHI_SERVER_REGISTERING
:
188 case AVAHI_SERVER_COLLISION
:
192 case AVAHI_SERVER_RUNNING
:
200 void PublicService::publishAsync()
203 if (d
->m_running
) stop();
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();
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
)
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
);
230 case AVAHI_ENTRY_GROUP_ESTABLISHED
:
232 emit m_parent
->published(true);
234 case AVAHI_ENTRY_GROUP_FAILURE
:
235 serverStateChanged(AVAHI_SERVER_INVALID
, reason
);
241 void PublicService::virtual_hook(int, void*)
248 #include "publicservice.moc"
249 #include "avahi-publicservice_p.moc"