Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* This file is part of the KDE project |
---|---|
2 | * |
3 | * Copyright (C) 2004, 2005 Jakub Stachowski <qbast@go2.pl> |
4 | * |
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. |
9 | * |
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. |
14 | * |
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. |
19 | */ |
20 | |
21 | #include <QtCore/QCoreApplication> |
22 | #include <QtCore/QStringList> |
23 | #include <netinet/in.h> |
24 | #include "publicservice.h" |
25 | #include "servicebase_p.h" |
26 | #include "mdnsd-sdevent.h" |
27 | #include "mdnsd-responder.h" |
28 | #include "settings.h" |
29 | |
30 | #define K_D PublicServicePrivate* d=static_cast<PublicServicePrivate*>(this->d) |
31 | |
32 | namespace DNSSD |
33 | { |
34 | void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, |
35 | const char*, const char*, void *context); |
36 | class PublicServicePrivate : public Responder, public ServiceBasePrivate |
37 | { |
38 | public: |
39 | PublicServicePrivate(PublicService* parent, const QString& name, const QString& type, unsigned int port, |
40 | const QString& domain) : Responder(), ServiceBasePrivate(name, type, domain, QString(), port), |
41 | m_published(false), m_parent(parent) |
42 | {} |
43 | bool m_published; |
44 | PublicService* m_parent; |
45 | QStringList m_subtypes; |
46 | virtual void customEvent(QEvent* event); |
47 | }; |
48 | |
49 | PublicService::PublicService(const QString& name, const QString& type, unsigned int port, |
50 | const QString& domain, const QStringList& subtypes) |
51 | : QObject(), ServiceBase(new PublicServicePrivate(this, name, type, port, domain)) |
52 | { |
53 | K_D; |
54 | if (domain.isNull()) d->m_domain="local."; |
55 | d->m_subtypes=subtypes; |
56 | } |
57 | |
58 | |
59 | PublicService::~PublicService() |
60 | { |
61 | stop(); |
62 | } |
63 | |
64 | void PublicService::setServiceName(const QString& serviceName) |
65 | { |
66 | K_D; |
67 | d->m_serviceName = serviceName; |
68 | if (d->isRunning()) { |
69 | stop(); |
70 | publishAsync(); |
71 | } |
72 | } |
73 | |
74 | void PublicService::setDomain(const QString& domain) |
75 | { |
76 | K_D; |
77 | d->m_domain = domain; |
78 | if (d->isRunning()) { |
79 | stop(); |
80 | publishAsync(); |
81 | } |
82 | } |
83 | |
84 | QStringList PublicService::subtypes() const |
85 | { |
86 | K_D; |
87 | return d->m_subtypes; |
88 | } |
89 | |
90 | void PublicService::setType(const QString& type) |
91 | { |
92 | K_D; |
93 | d->m_type = type; |
94 | if (d->isRunning()) { |
95 | stop(); |
96 | publishAsync(); |
97 | } |
98 | } |
99 | |
100 | void PublicService::setSubTypes(const QStringList& subtypes) |
101 | { |
102 | K_D; |
103 | d->m_subtypes = subtypes; |
104 | if (d->isRunning()) { |
105 | stop(); |
106 | publishAsync(); |
107 | } |
108 | } |
109 | |
110 | void PublicService::setPort(unsigned short port) |
111 | { |
112 | K_D; |
113 | d->m_port = port; |
114 | if (d->isRunning()) { |
115 | stop(); |
116 | publishAsync(); |
117 | } |
118 | } |
119 | |
120 | bool PublicService::isPublished() const |
121 | { |
122 | K_D; |
123 | return d->m_published; |
124 | } |
125 | |
126 | void PublicService::setTextData(const QMap<QString,QByteArray>& textData) |
127 | { |
128 | K_D; |
129 | d->m_textData = textData; |
130 | if (d->isRunning()) { |
131 | stop(); |
132 | publishAsync(); |
133 | } |
134 | } |
135 | |
136 | bool PublicService::publish() |
137 | { |
138 | K_D; |
139 | publishAsync(); |
140 | while (d->isRunning() && !d->m_published) d->process(); |
141 | return d->m_published; |
142 | } |
143 | |
144 | void PublicService::stop() |
145 | { |
146 | K_D; |
147 | d->stop(); |
148 | d->m_published = false; |
149 | } |
150 | |
151 | void PublicService::publishAsync() |
152 | { |
153 | K_D; |
154 | if (d->isRunning()) stop(); |
155 | TXTRecordRef txt; |
156 | TXTRecordCreate(&txt,0,0); |
157 | QMap<QString,QByteArray>::ConstIterator itEnd = d->m_textData.end(); |
158 | for (QMap<QString,QByteArray>::ConstIterator it = d->m_textData.begin(); it!=itEnd ; ++it) { |
159 | if (TXTRecordSetValue(&txt,it.key().toUtf8(),it.value().length(),it.value())!=kDNSServiceErr_NoError) { |
160 | TXTRecordDeallocate(&txt); |
161 | emit published(false); |
162 | return; |
163 | } |
164 | } |
165 | DNSServiceRef ref; |
166 | QString fullType=d->m_type; |
167 | Q_FOREACH(const QString &subtype, d->m_subtypes) fullType+= |
168 | if (DNSServiceRegister(&ref,0,0,d->m_serviceName.toUtf8(),fullType.toLatin1().constData(),domainToDNS(d->m_domain),NULL, |
169 | htons(d->m_port),TXTRecordGetLength(&txt),TXTRecordGetBytesPtr(&txt),publish_callback, |
170 | reinterpret_cast<void*>(d)) == kDNSServiceErr_NoError) d->setRef(ref); |
171 | TXTRecordDeallocate(&txt); |
172 | if (!d->isRunning()) emit published(false); |
173 | } |
174 | |
175 | void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name, |
176 | const char*, const char*, void *context) |
177 | { |
178 | QObject *obj = reinterpret_cast<QObject*>(context); |
179 | if (errorCode != kDNSServiceErr_NoError) { |
180 | ErrorEvent err; |
181 | QCoreApplication::sendEvent(obj, &err); |
182 | } else { |
183 | PublishEvent pev(QString::fromUtf8(name)); |
184 | QCoreApplication::sendEvent(obj, &pev); |
185 | } |
186 | } |
187 | |
188 | void PublicServicePrivate::customEvent(QEvent* event) |
189 | { |
190 | if (event->type()==QEvent::User+SD_ERROR) { |
191 | m_parent->stop(); |
192 | emit m_parent->published(false); |
193 | } |
194 | if (event->type()==QEvent::User+SD_PUBLISH) { |
195 | m_published=true; |
196 | emit m_parent->published(true); |
197 | m_serviceName = static_cast<PublishEvent*>(event)->m_name; |
198 | } |
199 | } |
200 | |
201 | void PublicService::virtual_hook(int, void*) |
202 | { |
203 | } |
204 | |
205 | } |
206 | |
207 | #include "publicservice.moc" |
208 |
Warning: That file was not part of the compilation database. It may have many parsing errors.