KDNSSD

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

KDE's Doxygen guidelines are available online.