From 195e740ceb8f073f05a68ecefef72d4cee77c0a4 Mon Sep 17 00:00:00 2001 From: Jonathan Bagg Date: Wed, 15 Mar 2017 20:32:28 -0400 Subject: [PATCH] Add txt records to discovered services --- README.md | 6 ++++++ avahiclient.cpp | 13 +++++++++++-- avahicore.cpp | 13 +++++++++++-- bonjour.cpp | 19 ++++++++++++++++--- example/window.cpp | 1 + qzeroconf.h | 1 + 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ce7d404..6e6f801 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,12 @@ If you are browsing for services published using both ipv4 and ipv6 ( QAbstractS Only one browser can be in use per instance of QzeroConf. +**Txt records** are placed into a QMap called txt within the discovered service. For example, the txt record value of "Qt=The Best!" can be retrieved with the code... + +```c++ +qDebug() << zcs->txt["Qt"] +``` + ### Build Dependencies Qt5 diff --git a/avahiclient.cpp b/avahiclient.cpp index 79d154e..9410a28 100644 --- a/avahiclient.cpp +++ b/avahiclient.cpp @@ -140,7 +140,7 @@ public: const char *host_name, const AvahiAddress *address, uint16_t port, - AvahiStringList *, + AvahiStringList *txt, AvahiLookupResultFlags, AVAHI_GCC_UNUSED void* userdata) { @@ -161,12 +161,21 @@ public: zcs->host = host_name; zcs->interfaceIndex = interface; zcs->port = port; + while (txt) // get txt records + { + QByteArray avahiText((const char *)txt->text, txt->size); + QList pair = avahiText.split('='); + if (pair.size() == 2) + zcs->txt[pair.at(0)] = pair.at(1); + else + zcs->txt[pair.at(0)] = ""; + txt = txt->next; + } ref->pub->services.insert(key, zcs); } char a[AVAHI_ADDRESS_STR_MAX]; avahi_address_snprint(a, sizeof(a), address); - // fixme maybe add type, and txt records if (protocol == AVAHI_PROTO_INET6) zcs->ipv6 = QHostAddress(a); else if (protocol == AVAHI_PROTO_INET) diff --git a/avahicore.cpp b/avahicore.cpp index 2787c8c..e1d3ddb 100644 --- a/avahicore.cpp +++ b/avahicore.cpp @@ -152,7 +152,7 @@ public: const char *host_name, const AvahiAddress *address, uint16_t port, - AvahiStringList *, + AvahiStringList *txt, AvahiLookupResultFlags, AVAHI_GCC_UNUSED void* userdata) { @@ -173,12 +173,21 @@ public: zcs->host = host_name; zcs->interfaceIndex = interface; zcs->port = port; + while (txt) // get txt records + { + QByteArray avahiText((const char *)txt->text, txt->size); + QList pair = avahiText.split('='); + if (pair.size() == 2) + zcs->txt[pair.at(0)] = pair.at(1); + else + zcs->txt[pair.at(0)] = ""; + txt = txt->next; + } ref->pub->services.insert(key, zcs); } char a[AVAHI_ADDRESS_STR_MAX]; avahi_address_snprint(a, sizeof(a), address); - // fixme maybe add type, and txt records if (protocol == AVAHI_PROTO_INET6) zcs->ipv6 = QHostAddress(a); else if (protocol == AVAHI_PROTO_INET) diff --git a/bonjour.cpp b/bonjour.cpp index 5639f5b..208bd06 100644 --- a/bonjour.cpp +++ b/bonjour.cpp @@ -142,9 +142,6 @@ void DNSSD_API QZeroConfPrivate::resolverCallback(DNSServiceRef, DNSServiceFlags const char *hostName, quint16 port, quint16 txtLen, const char * txtRecord, void *userdata) { - Q_UNUSED(txtLen); - Q_UNUSED(txtRecord); - QZeroConfPrivate *ref = static_cast(userdata); if (err != kDNSServiceErr_NoError) { @@ -152,6 +149,22 @@ void DNSSD_API QZeroConfPrivate::resolverCallback(DNSServiceRef, DNSServiceFlags return; } + qint16 recLen; + while (txtLen > 0) // add txt records + { + recLen = txtRecord[0]; + txtRecord++; + QByteArray avahiText((const char *)txtRecord, recLen); + QList pair = avahiText.split('='); + if (pair.size() == 2) + ref->newService->txt[pair.at(0)] = pair.at(1); + else + ref->newService->txt[pair.at(0)] = ""; + + txtLen-= recLen + 1; + txtRecord+= recLen; + } + ref->newService->port = qFromBigEndian(port); err = DNSServiceGetAddrInfo(&ref->resolver, kDNSServiceFlagsForceMulticast, interfaceIndex, ref->protocol, hostName, (DNSServiceGetAddrInfoReply) addressReply, ref); if (err == kDNSServiceErr_NoError) { diff --git a/example/window.cpp b/example/window.cpp index 6b1dc9a..399041b 100644 --- a/example/window.cpp +++ b/example/window.cpp @@ -106,6 +106,7 @@ void mainWindow::startPublish() return; publishEnabled = 1; + zeroConf.clearServiceTxtRecords(); zeroConf.addServiceTxtRecord("Qt", "the best!"); zeroConf.addServiceTxtRecord("ZeroConf is nice too"); zeroConf.startServicePublish(buildName().toUtf8(), "_qtzeroconf_test._tcp", "local", 11437); diff --git a/qzeroconf.h b/qzeroconf.h index 863aada..16c35b7 100644 --- a/qzeroconf.h +++ b/qzeroconf.h @@ -52,6 +52,7 @@ struct QZeroConfService QHostAddress ipv6; quint32 interfaceIndex; quint16 port; + QMap txt; }; class QZeroConfPrivate;