Merge PR #150: Workaround zeroconf breaking because of broken multicast hardware
This commit is contained in:
commit
0434ad22d2
@ -1,6 +1,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||||
|
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea. *
|
* This file is part of nymea. *
|
||||||
* *
|
* *
|
||||||
@ -53,6 +54,7 @@
|
|||||||
#include "loggingcategories.h"
|
#include "loggingcategories.h"
|
||||||
|
|
||||||
#include <QNetworkInterface>
|
#include <QNetworkInterface>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
namespace nymeaserver {
|
namespace nymeaserver {
|
||||||
|
|
||||||
@ -60,12 +62,20 @@ namespace nymeaserver {
|
|||||||
QtAvahiService::QtAvahiService(QObject *parent) :
|
QtAvahiService::QtAvahiService(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
d_ptr(new QtAvahiServicePrivate),
|
d_ptr(new QtAvahiServicePrivate),
|
||||||
m_state(QtAvahiServiceStateUncomitted)
|
m_state(QtAvahiServiceStateUncommitted)
|
||||||
{
|
{
|
||||||
connect(this, &QtAvahiService::serviceStateChanged, this, &QtAvahiService::onStateChanged);
|
connect(this, &QtAvahiService::serviceStateChanged, this, &QtAvahiService::onStateChanged);
|
||||||
|
|
||||||
d_ptr->client = new QtAvahiClient(this);
|
d_ptr->client = new QtAvahiClient(this);
|
||||||
d_ptr->client->start();
|
d_ptr->client->start();
|
||||||
|
|
||||||
|
m_reregisterTimer.setInterval(60000);
|
||||||
|
m_reregisterTimer.setSingleShot(true);
|
||||||
|
connect(&m_reregisterTimer, &QTimer::timeout, this, [this](){
|
||||||
|
qCDebug(dcAvahiDebug()) << "Re-registering service" << this;
|
||||||
|
resetService(true);
|
||||||
|
registerService(m_name, m_hostAddress, m_port, m_serviceType, m_txtRecords, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Destructs this \l{QtAvahiService}. */
|
/*! Destructs this \l{QtAvahiService}. */
|
||||||
@ -116,7 +126,7 @@ QtAvahiService::QtAvahiServiceState QtAvahiService::state() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*! Register a new \l{QtAvahiService} with the given \a name and \a port. The service type can be specified with the \a serviceType string. The \a txtRecords records inform about additional information. Returns true if the service could be registered. */
|
/*! Register a new \l{QtAvahiService} with the given \a name and \a port. The service type can be specified with the \a serviceType string. The \a txtRecords records inform about additional information. Returns true if the service could be registered. */
|
||||||
bool QtAvahiService::registerService(const QString &name, const QHostAddress &hostAddress, const quint16 &port, const QString &serviceType, const QHash<QString, QString> &txtRecords)
|
bool QtAvahiService::registerService(const QString &name, const QHostAddress &hostAddress, const quint16 &port, const QString &serviceType, const QHash<QString, QString> &txtRecords, bool silent)
|
||||||
{
|
{
|
||||||
// Check if the client is running
|
// Check if the client is running
|
||||||
if (!d_ptr->client->m_client || AVAHI_CLIENT_S_RUNNING != avahi_client_get_state(d_ptr->client->m_client)) {
|
if (!d_ptr->client->m_client || AVAHI_CLIENT_S_RUNNING != avahi_client_get_state(d_ptr->client->m_client)) {
|
||||||
@ -124,6 +134,14 @@ bool QtAvahiService::registerService(const QString &name, const QHostAddress &ho
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache all values locally at first
|
||||||
|
m_name = name;
|
||||||
|
m_hostAddress = hostAddress;
|
||||||
|
m_port = port;
|
||||||
|
m_serviceType = serviceType;
|
||||||
|
m_txtRecords = txtRecords;
|
||||||
|
|
||||||
|
// Now set up avahi
|
||||||
d_ptr->name = name;
|
d_ptr->name = name;
|
||||||
d_ptr->hostAddress = hostAddress;
|
d_ptr->hostAddress = hostAddress;
|
||||||
d_ptr->port = port;
|
d_ptr->port = port;
|
||||||
@ -149,7 +167,8 @@ bool QtAvahiService::registerService(const QString &name, const QHostAddress &ho
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qCDebug(dcAvahi()) << "Registering avahi service" << name << hostAddress.toString() << port << serviceType << "on interface" << ifIndex;
|
|
||||||
|
qCDebug((silent ? dcAvahiDebug() : dcAvahi())) << "Registering avahi service" << name << hostAddress.toString() << port << serviceType << "on interface" << ifIndex;
|
||||||
|
|
||||||
d_ptr->serviceList = QtAvahiServicePrivate::createTxtList(txtRecords);
|
d_ptr->serviceList = QtAvahiServicePrivate::createTxtList(txtRecords);
|
||||||
d_ptr->error = avahi_entry_group_add_service_strlst(d_ptr->group,
|
d_ptr->error = avahi_entry_group_add_service_strlst(d_ptr->group,
|
||||||
@ -167,7 +186,7 @@ bool QtAvahiService::registerService(const QString &name, const QHostAddress &ho
|
|||||||
if (d_ptr->error) {
|
if (d_ptr->error) {
|
||||||
|
|
||||||
if (d_ptr->error == AVAHI_ERR_COLLISION) {
|
if (d_ptr->error == AVAHI_ERR_COLLISION) {
|
||||||
if (!handlCollision()) {
|
if (!handleCollision()) {
|
||||||
qCWarning(dcAvahi()) << this << "error:" << avahi_strerror(d_ptr->error);
|
qCWarning(dcAvahi()) << this << "error:" << avahi_strerror(d_ptr->error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -190,20 +209,29 @@ bool QtAvahiService::registerService(const QString &name, const QHostAddress &ho
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reregister every minute in order to work around low quality network hardware which
|
||||||
|
// doesn't properly keep multicast sessions alive.
|
||||||
|
// https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=736641
|
||||||
|
m_reregisterTimer.start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Remove this service from the local network. This \l{QtAvahiService} can be reused to register a new avahi service. */
|
/*! Remove this service from the local network. This \l{QtAvahiService} can be reused to register a new avahi service. */
|
||||||
void QtAvahiService::resetService()
|
void QtAvahiService::resetService(bool silent)
|
||||||
{
|
{
|
||||||
if (!d_ptr->group)
|
if (!d_ptr->group) {
|
||||||
|
qCWarning(dcAvahi()) << "Cannot unregister service. Service Group not existing.";
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug((silent ? dcAvahiDebug() : dcAvahi())) << "Unregistering service" << this;
|
||||||
|
|
||||||
if (d_ptr->serviceList) {
|
if (d_ptr->serviceList) {
|
||||||
avahi_string_list_free(d_ptr->serviceList);
|
avahi_string_list_free(d_ptr->serviceList);
|
||||||
d_ptr->serviceList = nullptr;
|
d_ptr->serviceList = nullptr;
|
||||||
}
|
}
|
||||||
avahi_entry_group_reset(d_ptr->group);
|
avahi_entry_group_reset(d_ptr->group);
|
||||||
|
m_reregisterTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Update the TXT record of this service. Returns true of the record could be updated. */
|
/*! Update the TXT record of this service. Returns true of the record could be updated. */
|
||||||
@ -212,11 +240,26 @@ bool QtAvahiService::updateTxtRecord(const QHash<QString, QString> &txtRecords)
|
|||||||
if (!d_ptr->group)
|
if (!d_ptr->group)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
m_txtRecords = txtRecords;
|
||||||
|
|
||||||
// Add the service
|
// Add the service
|
||||||
|
AvahiIfIndex ifIndex = AVAHI_IF_UNSPEC;
|
||||||
|
if (d_ptr->hostAddress != QHostAddress("0.0.0.0")) {
|
||||||
|
foreach (const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
|
||||||
|
foreach (const QNetworkAddressEntry &addressEntry, interface.addressEntries()) {
|
||||||
|
QPair<QHostAddress, int> subnet = QHostAddress::parseSubnet(addressEntry.ip().toString() + "/" + addressEntry.netmask().toString());
|
||||||
|
if (d_ptr->hostAddress.isInSubnet(subnet.first, subnet.second)) {
|
||||||
|
ifIndex = interface.index();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d_ptr->serviceList = QtAvahiServicePrivate::createTxtList(txtRecords);
|
d_ptr->serviceList = QtAvahiServicePrivate::createTxtList(txtRecords);
|
||||||
d_ptr->error = avahi_entry_group_update_service_txt_strlst(d_ptr->group,
|
d_ptr->error = avahi_entry_group_update_service_txt_strlst(d_ptr->group,
|
||||||
AVAHI_IF_UNSPEC,
|
ifIndex,
|
||||||
AVAHI_PROTO_INET,
|
d_ptr->hostAddress.protocol() == QAbstractSocket::IPv6Protocol ? AVAHI_PROTO_INET6 : AVAHI_PROTO_INET,
|
||||||
(AvahiPublishFlags) 0,
|
(AvahiPublishFlags) 0,
|
||||||
d_ptr->name.toLatin1().data(),
|
d_ptr->name.toLatin1().data(),
|
||||||
d_ptr->type.toLatin1().data(),
|
d_ptr->type.toLatin1().data(),
|
||||||
@ -249,12 +292,12 @@ QString QtAvahiService::errorString() const
|
|||||||
return avahi_strerror(avahi_client_errno(d_ptr->client->m_client));
|
return avahi_strerror(avahi_client_errno(d_ptr->client->m_client));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QtAvahiService::handlCollision()
|
bool QtAvahiService::handleCollision()
|
||||||
{
|
{
|
||||||
char* alt = avahi_alternative_service_name(name().toStdString().data());
|
char* alt = avahi_alternative_service_name(name().toStdString().data());
|
||||||
QString alternativeServiceName = QLatin1String(alt);
|
QString alternativeServiceName = QLatin1String(alt);
|
||||||
free(alt);
|
free(alt);
|
||||||
qCDebug(dcAvahi()) << "Service name colision. Picking alternative service name" << alternativeServiceName;
|
qCDebug(dcAvahi()) << "Service name collision. Picking alternative service name" << alternativeServiceName;
|
||||||
|
|
||||||
resetService();
|
resetService();
|
||||||
return registerService(alternativeServiceName, hostAddress(), port(), serviceType(), txtRecords());
|
return registerService(alternativeServiceName, hostAddress(), port(), serviceType(), txtRecords());
|
||||||
@ -268,23 +311,21 @@ void QtAvahiService::onStateChanged(const QtAvahiServiceState &state)
|
|||||||
m_state = state;
|
m_state = state;
|
||||||
|
|
||||||
switch (m_state) {
|
switch (m_state) {
|
||||||
case QtAvahiServiceStateUncomitted:
|
case QtAvahiServiceStateUncommitted:
|
||||||
qCDebug(dcAvahi()) << this << "state changed: uncomitted";
|
qCDebug(dcAvahiDebug()) << "Service state changed to Uncommitted:" << this;
|
||||||
break;
|
break;
|
||||||
case QtAvahiServiceStateRegistering:
|
case QtAvahiServiceStateRegistering:
|
||||||
qCDebug(dcAvahi()) << this << "state changed: registering...";
|
qCDebug(dcAvahiDebug()) << "Service state changed to Registering:" << this;
|
||||||
break;
|
break;
|
||||||
case QtAvahiServiceStateEstablished:
|
case QtAvahiServiceStateEstablished:
|
||||||
qCDebug(dcAvahi()) << this << "state changed: established";
|
qCDebug(dcAvahiDebug()) << "Service state changed to Established:" << this;
|
||||||
break;
|
break;
|
||||||
case QtAvahiServiceStateCollision:
|
case QtAvahiServiceStateCollision:
|
||||||
qCDebug(dcAvahi()) << this << "state changed: collision";
|
qCDebug(dcAvahiDebug()) << "Service state changed to Collision:" << this;
|
||||||
handlCollision();
|
handleCollision();
|
||||||
break;
|
break;
|
||||||
case QtAvahiServiceStateFailure:
|
case QtAvahiServiceStateFailure:
|
||||||
qCWarning(dcAvahi()) << this << "failure: " << errorString();
|
qCDebug(dcAvahiDebug()) << "Service state changed to Failure:" << this;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
* Copyright (C) 2016 Simon Stürz <simon.stuerz@guh.io> *
|
||||||
|
* Copyright (C) 2019 Michael Zanetti <michael.zanetti@nymea.io> *
|
||||||
* *
|
* *
|
||||||
* This file is part of nymea. *
|
* This file is part of nymea. *
|
||||||
* *
|
* *
|
||||||
@ -27,6 +28,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace nymeaserver {
|
namespace nymeaserver {
|
||||||
|
|
||||||
@ -38,7 +40,7 @@ class QtAvahiService : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
enum QtAvahiServiceState {
|
enum QtAvahiServiceState {
|
||||||
QtAvahiServiceStateUncomitted = 0,
|
QtAvahiServiceStateUncommitted = 0,
|
||||||
QtAvahiServiceStateRegistering = 1,
|
QtAvahiServiceStateRegistering = 1,
|
||||||
QtAvahiServiceStateEstablished = 2,
|
QtAvahiServiceStateEstablished = 2,
|
||||||
QtAvahiServiceStateCollision = 3,
|
QtAvahiServiceStateCollision = 3,
|
||||||
@ -56,8 +58,8 @@ public:
|
|||||||
QHash<QString, QString> txtRecords() const;
|
QHash<QString, QString> txtRecords() const;
|
||||||
QtAvahiServiceState state() const;
|
QtAvahiServiceState state() const;
|
||||||
|
|
||||||
bool registerService(const QString &name, const QHostAddress &hostAddress, const quint16 &port, const QString &serviceType = "_http._tcp", const QHash<QString, QString> &txtRecords = QHash<QString, QString>());
|
bool registerService(const QString &name, const QHostAddress &hostAddress, const quint16 &port, const QString &serviceType = "_http._tcp", const QHash<QString, QString> &txtRecords = QHash<QString, QString>(), bool silent = false);
|
||||||
void resetService();
|
void resetService(bool silent = false);
|
||||||
|
|
||||||
bool updateTxtRecord(const QHash<QString, QString> &txtRecords);
|
bool updateTxtRecord(const QHash<QString, QString> &txtRecords);
|
||||||
|
|
||||||
@ -71,13 +73,20 @@ protected:
|
|||||||
QtAvahiServicePrivate *d_ptr;
|
QtAvahiServicePrivate *d_ptr;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
bool handlCollision();
|
bool handleCollision();
|
||||||
void onStateChanged(const QtAvahiServiceState &state);
|
void onStateChanged(const QtAvahiServiceState &state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QtAvahiServiceState m_state;
|
QtAvahiServiceState m_state;
|
||||||
Q_DECLARE_PRIVATE(QtAvahiService)
|
Q_DECLARE_PRIVATE(QtAvahiService)
|
||||||
|
|
||||||
|
QTimer m_reregisterTimer;
|
||||||
|
|
||||||
|
QString m_name;
|
||||||
|
QHostAddress m_hostAddress;
|
||||||
|
quint16 m_port;
|
||||||
|
QString m_serviceType;
|
||||||
|
QHash<QString, QString> m_txtRecords;
|
||||||
};
|
};
|
||||||
|
|
||||||
QDebug operator <<(QDebug dbg, QtAvahiService *service);
|
QDebug operator <<(QDebug dbg, QtAvahiService *service);
|
||||||
|
|||||||
@ -50,7 +50,7 @@ void QtAvahiServicePrivate::callback(AvahiEntryGroup *group, AvahiEntryGroupStat
|
|||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case AVAHI_ENTRY_GROUP_UNCOMMITED:
|
case AVAHI_ENTRY_GROUP_UNCOMMITED:
|
||||||
emit service->serviceStateChanged(QtAvahiService::QtAvahiServiceStateUncomitted);
|
emit service->serviceStateChanged(QtAvahiService::QtAvahiServiceStateUncommitted);
|
||||||
break;
|
break;
|
||||||
case AVAHI_ENTRY_GROUP_REGISTERING:
|
case AVAHI_ENTRY_GROUP_REGISTERING:
|
||||||
emit service->serviceStateChanged(QtAvahiService::QtAvahiServiceStateRegistering);
|
emit service->serviceStateChanged(QtAvahiService::QtAvahiServiceStateRegistering);
|
||||||
@ -69,7 +69,7 @@ void QtAvahiServicePrivate::callback(AvahiEntryGroup *group, AvahiEntryGroupStat
|
|||||||
|
|
||||||
AvahiStringList *QtAvahiServicePrivate::createTxtList(const QHash<QString, QString> &txt)
|
AvahiStringList *QtAvahiServicePrivate::createTxtList(const QHash<QString, QString> &txt)
|
||||||
{
|
{
|
||||||
AvahiStringList *list = NULL;
|
AvahiStringList *list = nullptr;
|
||||||
if (txt.isEmpty())
|
if (txt.isEmpty())
|
||||||
return list;
|
return list;
|
||||||
|
|
||||||
|
|||||||
@ -46,7 +46,7 @@ QtAvahiServiceBrowserImplementation::QtAvahiServiceBrowserImplementation(QObject
|
|||||||
|
|
||||||
connect(d_ptr->client, &QtAvahiClient::clientStateChanged, this, &QtAvahiServiceBrowserImplementation::onClientStateChanged);
|
connect(d_ptr->client, &QtAvahiClient::clientStateChanged, this, &QtAvahiServiceBrowserImplementation::onClientStateChanged);
|
||||||
|
|
||||||
qCDebug(dcAvahi()) << "-->" << name() << "created successfully.";
|
qCDebug(dcAvahiDebug()) << "-->" << name() << "created successfully.";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Destructs this \l{QtAvahiServiceBrowserImplementation}. */
|
/*! Destructs this \l{QtAvahiServiceBrowserImplementation}. */
|
||||||
@ -86,7 +86,7 @@ bool QtAvahiServiceBrowserImplementation::enabled() const
|
|||||||
void QtAvahiServiceBrowserImplementation::onClientStateChanged(const QtAvahiClient::QtAvahiClientState &state)
|
void QtAvahiServiceBrowserImplementation::onClientStateChanged(const QtAvahiClient::QtAvahiClientState &state)
|
||||||
{
|
{
|
||||||
if (state == QtAvahiClient::QtAvahiClientStateRunning) {
|
if (state == QtAvahiClient::QtAvahiClientStateRunning) {
|
||||||
qCDebug(dcAvahi()) << "Service browser client connected.";
|
qCDebug(dcAvahiDebug()) << "Service browser client connected.";
|
||||||
// Return if we already have a service type browser
|
// Return if we already have a service type browser
|
||||||
if (d_ptr->serviceTypeBrowser)
|
if (d_ptr->serviceTypeBrowser)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -60,7 +60,7 @@ void QtAvahiServiceBrowserImplementationPrivate::callbackServiceTypeBrowser(Avah
|
|||||||
case AVAHI_BROWSER_NEW:
|
case AVAHI_BROWSER_NEW:
|
||||||
if (!serviceBrowser->m_serviceTypes.contains(type)) {
|
if (!serviceBrowser->m_serviceTypes.contains(type)) {
|
||||||
serviceBrowser->m_serviceTypes.append(type);
|
serviceBrowser->m_serviceTypes.append(type);
|
||||||
qCDebug(dcAvahi()) << "[+] Service browser" << type;
|
qCDebug(dcAvahiDebug()) << "[+] Service browser" << type;
|
||||||
serviceBrowser->createServiceBrowser(type);
|
serviceBrowser->createServiceBrowser(type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -42,6 +42,7 @@ Q_LOGGING_CATEGORY(dcJsonRpcTraffic, "JsonRpcTraffic")
|
|||||||
Q_LOGGING_CATEGORY(dcRest, "Rest")
|
Q_LOGGING_CATEGORY(dcRest, "Rest")
|
||||||
Q_LOGGING_CATEGORY(dcOAuth2, "OAuth2")
|
Q_LOGGING_CATEGORY(dcOAuth2, "OAuth2")
|
||||||
Q_LOGGING_CATEGORY(dcAvahi, "Avahi")
|
Q_LOGGING_CATEGORY(dcAvahi, "Avahi")
|
||||||
|
Q_LOGGING_CATEGORY(dcAvahiDebug, "AvahiDebug")
|
||||||
Q_LOGGING_CATEGORY(dcUpnp, "UPnP")
|
Q_LOGGING_CATEGORY(dcUpnp, "UPnP")
|
||||||
Q_LOGGING_CATEGORY(dcBluetooth, "Bluetooth")
|
Q_LOGGING_CATEGORY(dcBluetooth, "Bluetooth")
|
||||||
Q_LOGGING_CATEGORY(dcCloud, "Cloud")
|
Q_LOGGING_CATEGORY(dcCloud, "Cloud")
|
||||||
|
|||||||
@ -50,6 +50,7 @@ Q_DECLARE_LOGGING_CATEGORY(dcJsonRpcTraffic)
|
|||||||
Q_DECLARE_LOGGING_CATEGORY(dcRest)
|
Q_DECLARE_LOGGING_CATEGORY(dcRest)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcOAuth2)
|
Q_DECLARE_LOGGING_CATEGORY(dcOAuth2)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcAvahi)
|
Q_DECLARE_LOGGING_CATEGORY(dcAvahi)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(dcAvahiDebug)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcUpnp)
|
Q_DECLARE_LOGGING_CATEGORY(dcUpnp)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcBluetooth)
|
Q_DECLARE_LOGGING_CATEGORY(dcBluetooth)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcCloud)
|
Q_DECLARE_LOGGING_CATEGORY(dcCloud)
|
||||||
|
|||||||
@ -122,6 +122,7 @@ int main(int argc, char *argv[])
|
|||||||
"TimeManager",
|
"TimeManager",
|
||||||
"Coap",
|
"Coap",
|
||||||
"Avahi",
|
"Avahi",
|
||||||
|
"AvahiDebug",
|
||||||
"UPnP",
|
"UPnP",
|
||||||
"Cloud",
|
"Cloud",
|
||||||
"CloudTraffic",
|
"CloudTraffic",
|
||||||
|
|||||||
Reference in New Issue
Block a user