Change mDNS to Qt SmartPointers

This commit is contained in:
LordGrey
2023-12-30 19:27:53 +01:00
parent ccacad9b3f
commit e8f19e21c4
4 changed files with 67 additions and 74 deletions

View File

@@ -2,7 +2,6 @@
#define MDNS_BROWSER_H #define MDNS_BROWSER_H
#include <chrono> #include <chrono>
#include <type_traits>
#include <qmdnsengine/server.h> #include <qmdnsengine/server.h>
#include <qmdnsengine/service.h> #include <qmdnsengine/service.h>
@@ -16,6 +15,9 @@
// Qt includes // Qt includes
#include <QObject> #include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QMap>
#include <QJsonArray>
#include <QSharedPointer>
// Utility includes // Utility includes
#include <utils/Logger.h> #include <utils/Logger.h>
@@ -24,15 +26,12 @@
namespace { namespace {
constexpr std::chrono::milliseconds DEFAULT_DISCOVER_TIMEOUT{ 500 }; constexpr std::chrono::milliseconds DEFAULT_DISCOVER_TIMEOUT{ 500 };
constexpr std::chrono::milliseconds DEFAULT_ADDRESS_RESOLVE_TIMEOUT{ 1000 }; constexpr std::chrono::milliseconds DEFAULT_ADDRESS_RESOLVE_TIMEOUT{ 1000 };
} // End of constants
} //End of constants
class MdnsBrowser : public QObject class MdnsBrowser : public QObject
{ {
Q_OBJECT Q_OBJECT
// Run MdnsBrowser as singleton
private: private:
/// ///
/// @brief Browse for hyperion services in bonjour, constructed from HyperionDaemon /// @brief Browse for hyperion services in bonjour, constructed from HyperionDaemon
@@ -58,7 +57,6 @@ public:
QMdnsEngine::Service getFirstService(const QByteArray& serviceType, const QString& filter = ".*", const std::chrono::milliseconds waitTime = DEFAULT_DISCOVER_TIMEOUT) const; QMdnsEngine::Service getFirstService(const QByteArray& serviceType, const QString& filter = ".*", const std::chrono::milliseconds waitTime = DEFAULT_DISCOVER_TIMEOUT) const;
QJsonArray getServicesDiscoveredJson(const QByteArray& serviceType, const QString& filter = ".*", const std::chrono::milliseconds waitTime = std::chrono::milliseconds{ 0 }) const; QJsonArray getServicesDiscoveredJson(const QByteArray& serviceType, const QString& filter = ".*", const std::chrono::milliseconds waitTime = std::chrono::milliseconds{ 0 }) const;
void printCache(const QByteArray& name = QByteArray(), quint16 type = QMdnsEngine::ANY) const; void printCache(const QByteArray& name = QByteArray(), quint16 type = QMdnsEngine::ANY) const;
public slots: public slots:
@@ -109,9 +107,9 @@ private:
QMdnsEngine::Server _server; QMdnsEngine::Server _server;
QMdnsEngine::Cache _cache; QMdnsEngine::Cache _cache;
QMdnsEngine::Resolver* _resolver; QSharedPointer<QMdnsEngine::Resolver> _resolver;
QMap<QByteArray, QMdnsEngine::Browser*> _browsedServiceTypes; QMap<QByteArray, QSharedPointer<QMdnsEngine::Browser>> _browsedServiceTypes;
}; };
#endif // MDNSBROWSER_H #endif // MDNSBROWSER_H

View File

@@ -9,6 +9,7 @@
// Qt includes // Qt includes
#include <QObject> #include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QScopedPointer>
// Utility includes // Utility includes
#include <utils/Logger.h> #include <utils/Logger.h>
@@ -41,11 +42,11 @@ private:
/// The logger instance for mDNS-Service /// The logger instance for mDNS-Service
Logger* _log; Logger* _log;
QMdnsEngine::Server* _server; QScopedPointer<QMdnsEngine::Server> _server;
QMdnsEngine::Hostname* _hostname; QScopedPointer<QMdnsEngine::Hostname> _hostname;
/// map of services provided /// map of services provided
QMap<QByteArray, QMdnsEngine::Provider*> _providedServiceTypes; QMap<QByteArray, QSharedPointer<QMdnsEngine::Provider>> _providedServiceTypes;
}; };
#endif // MDNSPROVIDER_H #endif // MDNSPROVIDER_H

View File

@@ -2,9 +2,8 @@
#include <qmdnsengine/message.h> #include <qmdnsengine/message.h>
#include <qmdnsengine/service.h> #include <qmdnsengine/service.h>
//Qt includes // Qt includes
#include <QThread> #include <QThread>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonDocument> #include <QJsonDocument>
@@ -19,7 +18,8 @@
namespace { namespace {
const bool verboseBrowser = false; const bool verboseBrowser = false;
} //End of constants const int SERVICE_LOOKUP_RETRIES = 5;
} // End of constants
MdnsBrowser::MdnsBrowser(QObject* parent) MdnsBrowser::MdnsBrowser(QObject* parent)
: QObject(parent) : QObject(parent)
@@ -30,11 +30,7 @@ MdnsBrowser::MdnsBrowser(QObject* parent)
MdnsBrowser::~MdnsBrowser() MdnsBrowser::~MdnsBrowser()
{ {
qDeleteAll(_browsedServiceTypes);
_browsedServiceTypes.clear(); _browsedServiceTypes.clear();
disconnect(_resolver, &QMdnsEngine::Resolver::resolved, this, &MdnsBrowser::onHostNameResolved);
delete _resolver;
} }
void MdnsBrowser::browseForServiceType(const QByteArray& serviceType) void MdnsBrowser::browseForServiceType(const QByteArray& serviceType)
@@ -42,11 +38,11 @@ void MdnsBrowser::browseForServiceType(const QByteArray& serviceType)
if (!_browsedServiceTypes.contains(serviceType)) if (!_browsedServiceTypes.contains(serviceType))
{ {
DebugIf(verboseBrowser, _log, "Start new mDNS browser for serviceType [%s], Thread: %s", serviceType.constData(), QSTRING_CSTR(QThread::currentThread()->objectName())); DebugIf(verboseBrowser, _log, "Start new mDNS browser for serviceType [%s], Thread: %s", serviceType.constData(), QSTRING_CSTR(QThread::currentThread()->objectName()));
QMdnsEngine::Browser* newBrowser = new QMdnsEngine::Browser(&_server, serviceType, &_cache); QSharedPointer<QMdnsEngine::Browser> newBrowser = QSharedPointer<QMdnsEngine::Browser>::create(&_server, serviceType, &_cache);
QObject::connect(newBrowser, &QMdnsEngine::Browser::serviceAdded, this, &MdnsBrowser::onServiceAdded); QObject::connect(newBrowser.get(), &QMdnsEngine::Browser::serviceAdded, this, &MdnsBrowser::onServiceAdded);
QObject::connect(newBrowser, &QMdnsEngine::Browser::serviceUpdated, this, &MdnsBrowser::onServiceUpdated); QObject::connect(newBrowser.get(), &QMdnsEngine::Browser::serviceUpdated, this, &MdnsBrowser::onServiceUpdated);
QObject::connect(newBrowser, &QMdnsEngine::Browser::serviceRemoved, this, &MdnsBrowser::onServiceRemoved); QObject::connect(newBrowser.get(), &QMdnsEngine::Browser::serviceRemoved, this, &MdnsBrowser::onServiceRemoved);
_browsedServiceTypes.insert(serviceType, newBrowser); _browsedServiceTypes.insert(serviceType, newBrowser);
} }
@@ -128,8 +124,8 @@ QHostAddress MdnsBrowser::getHostFirstAddress(const QByteArray& hostname)
{ {
DebugIf(verboseBrowser, _log, "IP-address for hostname [%s] not yet in cache, start resolver.", toBeResolvedHostName.constData()); DebugIf(verboseBrowser, _log, "IP-address for hostname [%s] not yet in cache, start resolver.", toBeResolvedHostName.constData());
qRegisterMetaType<QMdnsEngine::Message>("Message"); qRegisterMetaType<QMdnsEngine::Message>("Message");
_resolver = new QMdnsEngine::Resolver(&_server, toBeResolvedHostName, &_cache); _resolver.reset(new QMdnsEngine::Resolver(&_server, toBeResolvedHostName, &_cache));
connect(_resolver, &QMdnsEngine::Resolver::resolved, this, &MdnsBrowser::onHostNameResolved); connect(_resolver.get(), &QMdnsEngine::Resolver::resolved, this, &MdnsBrowser::onHostNameResolved);
} }
} }
} }
@@ -153,7 +149,7 @@ void MdnsBrowser::onHostNameResolved(const QHostAddress& address)
bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddress& hostAddress, std::chrono::milliseconds timeout) bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddress& hostAddress, std::chrono::milliseconds timeout)
{ {
DebugIf(verboseBrowser, _log, "Get address for hostname [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(QThread::currentThread()->objectName())); DebugIf(verboseBrowser, log, "Get address for hostname [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(QThread::currentThread()->objectName()));
bool isHostAddressOK{ false }; bool isHostAddressOK{ false };
if (hostname.endsWith(".local") || hostname.endsWith(".local.")) if (hostname.endsWith(".local") || hostname.endsWith(".local."))
@@ -162,20 +158,20 @@ bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddr
if (hostAddress.isNull()) if (hostAddress.isNull())
{ {
DebugIf(verboseBrowser, _log, "Wait for resolver on hostname [%s]", QSTRING_CSTR(hostname)); DebugIf(verboseBrowser, log, "Wait for resolver on hostname [%s]", QSTRING_CSTR(hostname));
QEventLoop loop; QEventLoop loop;
QTimer t; QTimer timer;
QObject::connect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, &loop, &QEventLoop::quit);
QObject::connect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, &loop, &QEventLoop::quit);
weakConnect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, weakConnect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved,
[&hostAddress, hostname](const QHostAddress& resolvedAddress) { [&hostAddress, hostname, log](const QHostAddress& resolvedAddress) {
DebugIf(verboseBrowser, Logger::getInstance("MDNS"), "Resolver resolved hostname [%s] to address [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(resolvedAddress.toString()), QSTRING_CSTR(QThread::currentThread()->objectName())); DebugIf(verboseBrowser, log, "Resolver resolved hostname [%s] to address [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(resolvedAddress.toString()), QSTRING_CSTR(QThread::currentThread()->objectName()));
hostAddress = resolvedAddress; hostAddress = resolvedAddress;
}); });
QTimer::connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit); QTimer::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
t.start(static_cast<int>(timeout.count())); timer.start(static_cast<int>(timeout.count()));
loop.exec(); loop.exec();
} }
@@ -210,8 +206,8 @@ QMdnsEngine::Record MdnsBrowser::getServiceInstanceRecord(const QByteArray& serv
} }
QMdnsEngine::Record srvRecord; QMdnsEngine::Record srvRecord;
bool found{ false }; bool found { false };
int retries = 5; int retries { SERVICE_LOOKUP_RETRIES };
do do
{ {
if (_cache.lookupRecord(service, QMdnsEngine::SRV, srvRecord)) if (_cache.lookupRecord(service, QMdnsEngine::SRV, srvRecord))
@@ -323,7 +319,7 @@ QJsonArray MdnsBrowser::getServicesDiscoveredJson(const QByteArray& serviceType,
QJsonArray result; QJsonArray result;
QRegularExpression regEx(filter); static QRegularExpression regEx(filter);
if (!regEx.isValid()) { if (!regEx.isValid()) {
QString errorString = regEx.errorString(); QString errorString = regEx.errorString();
int errorOffset = regEx.patternErrorOffset(); int errorOffset = regEx.patternErrorOffset();
@@ -397,10 +393,10 @@ QJsonArray MdnsBrowser::getServicesDiscoveredJson(const QByteArray& serviceType,
QMap<QByteArray, QByteArray> txtAttributes = txtRecord.attributes(); QMap<QByteArray, QByteArray> txtAttributes = txtRecord.attributes();
QVariantMap txtMap; QVariantMap txtMap;
QMapIterator<QByteArray, QByteArray> i(txtAttributes); QMapIterator<QByteArray, QByteArray> iterator(txtAttributes);
while (i.hasNext()) { while (iterator.hasNext()) {
i.next(); iterator.next();
txtMap.insert(i.key(), i.value()); txtMap.insert(iterator.key(), iterator.value());
} }
obj.insert("txt", QJsonObject::fromVariantMap(txtMap)); obj.insert("txt", QJsonObject::fromVariantMap(txtMap));
} }

View File

@@ -1,7 +1,7 @@
#include <mdns/MdnsProvider.h> #include <mdns/MdnsProvider.h>
#include <mdns/MdnsServiceRegister.h> #include <mdns/MdnsServiceRegister.h>
//Qt includes // Qt includes
#include <QHostInfo> #include <QHostInfo>
#include <QThread> #include <QThread>
@@ -12,7 +12,7 @@
namespace { namespace {
const bool verboseProvider = false; const bool verboseProvider = false;
} //End of constants } // End of constants
MdnsProvider::MdnsProvider(QObject* parent) MdnsProvider::MdnsProvider(QObject* parent)
: QObject(parent) : QObject(parent)
@@ -24,43 +24,36 @@ MdnsProvider::MdnsProvider(QObject* parent)
void MdnsProvider::init() void MdnsProvider::init()
{ {
_server = new QMdnsEngine::Server(); _server.reset(new QMdnsEngine::Server());
_hostname = new QMdnsEngine::Hostname(_server); _hostname.reset(new QMdnsEngine::Hostname(_server.data()));
connect(_hostname, &QMdnsEngine::Hostname::hostnameChanged, this, &MdnsProvider::onHostnameChanged); connect(_hostname.data(), &QMdnsEngine::Hostname::hostnameChanged, this, &MdnsProvider::onHostnameChanged);
DebugIf(verboseProvider, _log, "Hostname [%s], isRegistered [%d]", _hostname->hostname().constData(), _hostname->isRegistered()); DebugIf(verboseProvider, _log, "Hostname [%s], isRegistered [%d]", _hostname->hostname().constData(), _hostname->isRegistered());
} }
MdnsProvider::~MdnsProvider() MdnsProvider::~MdnsProvider()
{ {
disconnect(_hostname, &QMdnsEngine::Hostname::hostnameChanged, this, &MdnsProvider::onHostnameChanged);
qDeleteAll(_providedServiceTypes);
_providedServiceTypes.clear(); _providedServiceTypes.clear();
delete _hostname;
delete _server;
} }
void MdnsProvider::publishService(const QString& serviceType, quint16 servicePort, const QByteArray& serviceName) void MdnsProvider::publishService(const QString& serviceType, quint16 servicePort, const QByteArray& serviceName)
{ {
QMdnsEngine::Provider* provider(nullptr);
QByteArray type = MdnsServiceRegister::getServiceType(serviceType); QByteArray type = MdnsServiceRegister::getServiceType(serviceType);
if (!type.isEmpty()) if (!type.isEmpty())
{ {
DebugIf(verboseProvider, _log, "Publish new mDNS serviceType [%s], Thread: %s", type.constData(), QSTRING_CSTR(QThread::currentThread()->objectName())); DebugIf(verboseProvider, _log, "Publish new mDNS serviceType [%s], Thread: %s", type.constData(), QSTRING_CSTR(QThread::currentThread()->objectName()));
if (!_providedServiceTypes.contains(type)) if (!_providedServiceTypes.contains(type))
{ {
provider = new QMdnsEngine::Provider(_server, _hostname); QSharedPointer<QMdnsEngine::Provider> newProvider = QSharedPointer<QMdnsEngine::Provider>::create(_server.data(), _hostname.data());
_providedServiceTypes.insert(type, provider); _providedServiceTypes.insert(type, newProvider);
}
else
{
provider = _providedServiceTypes[type];
} }
QSharedPointer<QMdnsEngine::Provider> provider = _providedServiceTypes.value(type);
if (!provider.isNull())
{
QMdnsEngine::Service service; QMdnsEngine::Service service;
service.setType(type); service.setType(type);
service.setPort(servicePort); service.setPort(servicePort);
@@ -72,14 +65,19 @@ void MdnsProvider::publishService(const QString& serviceType, quint16 servicePor
} }
service.setName(name); service.setName(name);
QByteArray id = AuthManager::getInstance()->getID().toUtf8(); QByteArray uuid = AuthManager::getInstance()->getID().toUtf8();
const QMap<QByteArray, QByteArray> attributes = { {"id", id}, {"version", HYPERION_VERSION} }; const QMap<QByteArray, QByteArray> attributes = {{"id", uuid}, {"version", HYPERION_VERSION}};
service.setAttributes(attributes); service.setAttributes(attributes);
DebugIf(verboseProvider, _log, "[%s], Name: [%s], Port: [%u] ", service.type().constData(), service.name().constData(), service.port()); DebugIf(verboseProvider, _log, "[%s], Name: [%s], Port: [%u] ", service.type().constData(), service.name().constData(), service.port());
provider->update(service); provider->update(service);
} }
else
{
Error(_log, "Not able to get hold of mDNS serviceType [%s]", type.constData());
}
}
} }
void MdnsProvider::onHostnameChanged(const QByteArray& hostname) void MdnsProvider::onHostnameChanged(const QByteArray& hostname)