KDNSSD

mdnsd-remoteservice.cpp
1/*
2 This file is part of the KDE project
3
4 SPDX-FileCopyrightText: 2004, 2005 Jakub Stachowski <qbast@go2.pl>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "mdnsd-responder.h"
10#include "mdnsd-sdevent.h"
11#include "remoteservice.h"
12#include "servicebase_p.h"
13#include <QCoreApplication>
14#include <QDebug>
15#include <QEventLoop>
16
17#ifdef _WIN32
18#include <winsock2.h>
19#else
20#include <netinet/in.h>
21#endif
22
23namespace KDNSSD
24{
25void resolve_callback(DNSServiceRef,
26 DNSServiceFlags,
27 uint32_t,
28 DNSServiceErrorType errorCode,
29 const char *,
30 const char *hosttarget,
31 uint16_t port,
32 uint16_t txtLen,
33 const unsigned char *txtRecord,
34 void *context);
35
36#define KDNSSD_D RemoteServicePrivate *d = static_cast<RemoteServicePrivate *>(this->d.operator->())
37
38class RemoteServicePrivate : public Responder, public ServiceBasePrivate
39{
40public:
41 RemoteServicePrivate(RemoteService *parent, const QString &name, const QString &type, const QString &domain)
42 : Responder()
43 , ServiceBasePrivate(name, type, domain, QString(), 0)
44 , m_resolved(false)
45 , m_parent(parent)
46 {
47 }
48 bool m_resolved;
49 RemoteService *m_parent;
50 virtual void customEvent(QEvent *event);
51};
52
53RemoteService::RemoteService(const QString &name, const QString &type, const QString &domain)
54 : ServiceBase(new RemoteServicePrivate(this, name, type, domain))
55{
56}
57
58RemoteService::~RemoteService()
59{
60}
61
62bool RemoteService::resolve()
63{
64 KDNSSD_D;
65 resolveAsync();
66 while (d->isRunning() && !d->m_resolved) {
67 d->process();
68 }
69 d->stop();
70 return d->m_resolved;
71}
72
73void RemoteService::resolveAsync()
74{
75 KDNSSD_D;
76 if (d->isRunning()) {
77 return;
78 }
79 d->m_resolved = false;
80 // qDebug() << this << ":Starting resolve of : " << d->m_serviceName << " " << d->m_type << " " << d->m_domain << "\n";
81 DNSServiceRef ref;
82 if (DNSServiceResolve(&ref,
83 0,
84 0,
85 d->m_serviceName.toUtf8().constData(),
86 d->m_type.toLatin1().constData(),
87 domainToDNS(d->m_domain).constData(),
88 (DNSServiceResolveReply)resolve_callback,
89 reinterpret_cast<void *>(d))
90 == kDNSServiceErr_NoError) {
91 d->setRef(ref);
92 }
93 if (!d->isRunning()) {
94 Q_EMIT resolved(false);
95 }
96}
97
98bool RemoteService::isResolved() const
99{
100 KDNSSD_D;
101 return d->m_resolved;
102}
103
104void RemoteServicePrivate::customEvent(QEvent *event)
105{
106 if (event->type() == QEvent::User + SD_ERROR) {
107 stop();
108 m_resolved = false;
109 Q_EMIT m_parent->resolved(false);
110 }
111 if (event->type() == QEvent::User + SD_RESOLVE) {
112 ResolveEvent *rev = static_cast<ResolveEvent *>(event);
113 m_hostName = rev->m_hostname;
114 m_port = rev->m_port;
115 m_textData = rev->m_txtdata;
116 m_resolved = true;
117 Q_EMIT m_parent->resolved(true);
118 }
119}
120
121void RemoteService::virtual_hook(int, void *)
122{
123 // BASE::virtual_hook(int, void*);
124}
125
126void resolve_callback(DNSServiceRef,
127 DNSServiceFlags,
128 uint32_t,
129 DNSServiceErrorType errorCode,
130 const char *,
131 const char *hosttarget,
132 uint16_t port,
133 uint16_t txtLen,
134 const unsigned char *txtRecord,
135 void *context)
136{
137 QObject *obj = reinterpret_cast<QObject *>(context);
138 if (errorCode != kDNSServiceErr_NoError) {
139 ErrorEvent err;
141 return;
142 }
143 char key[256];
144 int index = 0;
145 unsigned char valueLen;
146 // qDebug() << "Resolve callback\n";
148 const void *voidValue = 0;
149 while (TXTRecordGetItemAtIndex(txtLen, txtRecord, index++, 256, key, &valueLen, &voidValue) == kDNSServiceErr_NoError) {
150 if (voidValue) {
151 map[QString::fromUtf8(key)] = QByteArray((const char *)voidValue, valueLen);
152 } else {
153 map[QString::fromUtf8(key)].clear();
154 }
155 }
156 ResolveEvent rev(DNSToDomain(hosttarget), ntohs(port), map);
158}
159
160}
161
162#include "moc_remoteservice.cpp"
RemoteService(const QString &name, const QString &type, const QString &domain)
Creates an unresolved RemoteService representing the service with the given name, type and domain.
void stop(Ekos::AlignState mode)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
Type type(const QSqlDatabase &db)
QString name(StandardShortcut id)
bool sendEvent(QObject *receiver, QEvent *event)
virtual bool event(QEvent *e)
QObject * parent() const const
const QChar * constData() const const
QString fromUtf8(QByteArrayView str)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:48 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.