migrate avahi broser resource

This commit is contained in:
Simon Stürz 2017-11-13 21:14:02 +01:00 committed by Michael Zanetti
parent 66b537cadc
commit 19d8f8d4d7
11 changed files with 85 additions and 36 deletions

View File

@ -166,12 +166,9 @@ private slots:
void slotDeviceStateValueChanged(const QUuid &stateTypeId, const QVariant &value); void slotDeviceStateValueChanged(const QUuid &stateTypeId, const QVariant &value);
// void radio433SignalReceived(QList<int> rawData); // void radio433SignalReceived(QList<int> rawData);
// void replyReady(const PluginId &pluginId, QNetworkReply *reply); // void replyReady(const PluginId &pluginId, QNetworkReply *reply);
// void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &deviceDescriptorList, const PluginId &pluginId); // void upnpDiscoveryFinished(const QList<UpnpDeviceDescriptor> &deviceDescriptorList, const PluginId &pluginId);
// void upnpNotifyReceived(const QByteArray &notifyData); // void upnpNotifyReceived(const QByteArray &notifyData);
// void bluetoothDiscoveryFinished(const PluginId &pluginId, const QList<QBluetoothDeviceInfo> &deviceInfos); // void bluetoothDiscoveryFinished(const PluginId &pluginId, const QList<QBluetoothDeviceInfo> &deviceInfos);
void timerEvent(); void timerEvent();

View File

@ -19,8 +19,8 @@ HardwareManager::HardwareManager(QObject *parent) : QObject(parent)
m_radio433->enable(); m_radio433->enable();
// Create network access manager for all resources, centralized // Create network access manager for all resources, centralized
m_networkAccessManager = new QNetworkAccessManager(this);
// Note: configuration and proxy settings could be implemented here // Note: configuration and proxy settings could be implemented here
m_networkAccessManager = new QNetworkAccessManager(this);
// Network manager // Network manager
m_networkManager = new NetworkAccessManager(m_networkAccessManager, this); m_networkManager = new NetworkAccessManager(m_networkAccessManager, this);
@ -29,9 +29,12 @@ HardwareManager::HardwareManager(QObject *parent) : QObject(parent)
// UPnP discovery // UPnP discovery
m_upnpDiscovery = new UpnpDiscovery(m_networkAccessManager, this); m_upnpDiscovery = new UpnpDiscovery(m_networkAccessManager, this);
m_hardwareResources.append(m_upnpDiscovery);
m_upnpDiscovery->enable();
// Avahi Browser // Avahi Browser
m_avahiBrowser = new QtAvahiServiceBrowser(this); m_avahiBrowser = new QtAvahiServiceBrowser(this);
m_hardwareResources.append(m_avahiBrowser);
m_avahiBrowser->enable(); m_avahiBrowser->enable();
// Bluetooth LE // Bluetooth LE

View File

@ -35,7 +35,8 @@ public:
TypeTimer = 2, TypeTimer = 2,
TypeNetworkManager = 4, TypeNetworkManager = 4,
TypeUpnpDisovery = 8, TypeUpnpDisovery = 8,
TypeBluetoothLE = 16 TypeBluetoothLE = 16,
TypeAvahiBrowser = 32
}; };
Q_ENUM(Type) Q_ENUM(Type)
Q_DECLARE_FLAGS(Types, Type) Q_DECLARE_FLAGS(Types, Type)

View File

@ -28,8 +28,8 @@
QtAvahiClient::QtAvahiClient(QObject *parent) : QtAvahiClient::QtAvahiClient(QObject *parent) :
QObject(parent), QObject(parent),
poll(avahi_qt_poll_get()), m_poll(avahi_qt_poll_get()),
client(0), m_client(0),
error(0), error(0),
m_state(QtAvahiClientStateNone) m_state(QtAvahiClientStateNone)
{ {
@ -38,8 +38,8 @@ QtAvahiClient::QtAvahiClient(QObject *parent) :
QtAvahiClient::~QtAvahiClient() QtAvahiClient::~QtAvahiClient()
{ {
if (client) if (m_client)
avahi_client_free(client); avahi_client_free(m_client);
} }
@ -50,10 +50,18 @@ QtAvahiClient::QtAvahiClientState QtAvahiClient::state() const
void QtAvahiClient::start() void QtAvahiClient::start()
{ {
if (client) if (m_client)
return; return;
avahi_client_new(poll, (AvahiClientFlags) 0, QtAvahiClient::callback, this, &error); avahi_client_new(m_poll, (AvahiClientFlags) 0, QtAvahiClient::callback, this, &error);
}
void QtAvahiClient::stop()
{
if (m_client)
avahi_client_free(m_client);
m_client = nullptr;
} }
QString QtAvahiClient::errorString() const QString QtAvahiClient::errorString() const
@ -67,7 +75,7 @@ void QtAvahiClient::callback(AvahiClient *client, AvahiClientState state, void *
if (!serviceClient) if (!serviceClient)
return; return;
serviceClient->client = client; serviceClient->m_client = client;
switch (state) { switch (state) {
case AVAHI_CLIENT_S_RUNNING: case AVAHI_CLIENT_S_RUNNING:

View File

@ -53,12 +53,13 @@ private:
friend class QtAvahiServiceBrowser; friend class QtAvahiServiceBrowser;
friend class QtAvahiServiceBrowserPrivate; friend class QtAvahiServiceBrowserPrivate;
const AvahiPoll *poll; const AvahiPoll *m_poll;
AvahiClient *client; AvahiClient *m_client;
int error; int error;
QtAvahiClientState m_state; QtAvahiClientState m_state;
void start(); void start();
void stop();
QString errorString() const; QString errorString() const;
static void callback(AvahiClient *client, AvahiClientState state, void *userdata); static void callback(AvahiClient *client, AvahiClientState state, void *userdata);

View File

@ -110,7 +110,7 @@ QtAvahiService::QtAvahiServiceState QtAvahiService::state() const
bool QtAvahiService::registerService(const QString &name, const quint16 &port, const QString &serviceType, const QHash<QString, QString> &txtRecords) bool QtAvahiService::registerService(const QString &name, const quint16 &port, const QString &serviceType, const QHash<QString, QString> &txtRecords)
{ {
// Check if the client is running // Check if the client is running
if (!d_ptr->client->client || AVAHI_CLIENT_S_RUNNING != avahi_client_get_state(d_ptr->client->client)) { if (!d_ptr->client->m_client || AVAHI_CLIENT_S_RUNNING != avahi_client_get_state(d_ptr->client->m_client)) {
qCWarning(dcAvahi()) << "Could not register service" << name << port << serviceType << ". The client is not available."; qCWarning(dcAvahi()) << "Could not register service" << name << port << serviceType << ". The client is not available.";
return false; return false;
} }
@ -122,7 +122,7 @@ bool QtAvahiService::registerService(const QString &name, const quint16 &port, c
// If the group is not set yet, create it // If the group is not set yet, create it
if (!d_ptr->group) if (!d_ptr->group)
d_ptr->group = avahi_entry_group_new(d_ptr->client->client, QtAvahiServicePrivate::callback, this); d_ptr->group = avahi_entry_group_new(d_ptr->client->m_client, QtAvahiServicePrivate::callback, this);
// If the group is empty // If the group is empty
if (avahi_entry_group_is_empty(d_ptr->group)) { if (avahi_entry_group_is_empty(d_ptr->group)) {
@ -219,10 +219,10 @@ bool QtAvahiService::isValid() const
/*! Returns the error string of this \l{QtAvahiService}. */ /*! Returns the error string of this \l{QtAvahiService}. */
QString QtAvahiService::errorString() const QString QtAvahiService::errorString() const
{ {
if (!d_ptr->client->client) if (!d_ptr->client->m_client)
return "Invalid client."; return "Invalid client.";
return avahi_strerror(avahi_client_errno(d_ptr->client->client)); return avahi_strerror(avahi_client_errno(d_ptr->client->m_client));
} }
bool QtAvahiService::handlCollision() bool QtAvahiService::handlCollision()

View File

@ -44,7 +44,7 @@
/*! Constructs a new \l{QtAvahiServiceBrowser} with the given \a parent. */ /*! Constructs a new \l{QtAvahiServiceBrowser} with the given \a parent. */
QtAvahiServiceBrowser::QtAvahiServiceBrowser(QObject *parent) : QtAvahiServiceBrowser::QtAvahiServiceBrowser(QObject *parent) :
QObject(parent), HardwareResource(HardwareResource::TypeAvahiBrowser, "Avahi browser", parent),
d_ptr(new QtAvahiServiceBrowserPrivate(new QtAvahiClient)) d_ptr(new QtAvahiServiceBrowserPrivate(new QtAvahiClient))
{ {
connect(d_ptr->client, &QtAvahiClient::clientStateChanged, this, &QtAvahiServiceBrowser::onClientStateChanged); connect(d_ptr->client, &QtAvahiClient::clientStateChanged, this, &QtAvahiServiceBrowser::onClientStateChanged);
@ -68,11 +68,7 @@ QtAvahiServiceBrowser::~QtAvahiServiceBrowser()
delete d_ptr; delete d_ptr;
} }
/*! Enables this \l{QtAvahiServiceBrowser} and starts the service browsing. */
void QtAvahiServiceBrowser::enable()
{
d_ptr->client->start();
}
/*! Returns the current \l{AvahiServiceEntry} list of this \l{QtAvahiServiceBrowser}. */ /*! Returns the current \l{AvahiServiceEntry} list of this \l{QtAvahiServiceBrowser}. */
QList<AvahiServiceEntry> QtAvahiServiceBrowser::serviceEntries() const QList<AvahiServiceEntry> QtAvahiServiceBrowser::serviceEntries() const
@ -88,16 +84,31 @@ void QtAvahiServiceBrowser::onClientStateChanged(const QtAvahiClient::QtAvahiCli
if (d_ptr->serviceTypeBrowser) if (d_ptr->serviceTypeBrowser)
return; return;
d_ptr->serviceTypeBrowser = avahi_service_type_browser_new(d_ptr->client->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, (AvahiLookupFlags) 0, QtAvahiServiceBrowserPrivate::callbackServiceTypeBrowser, this); d_ptr->serviceTypeBrowser = avahi_service_type_browser_new(d_ptr->client->m_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, (AvahiLookupFlags) 0, QtAvahiServiceBrowserPrivate::callbackServiceTypeBrowser, this);
} else if (state == QtAvahiClient::QtAvahiClientStateFailure) { } else if (state == QtAvahiClient::QtAvahiClientStateFailure) {
qCWarning(dcAvahi()) << "Service browser client failure:" << d_ptr->client->errorString(); qCWarning(dcAvahi()) << "Service browser client failure:" << d_ptr->client->errorString();
} }
} }
/*! Enables this \l{QtAvahiServiceBrowser} and starts the service browsing. */
bool QtAvahiServiceBrowser::enable()
{
d_ptr->client->start();
setEnabled(true);
return true;
}
bool QtAvahiServiceBrowser::disable()
{
d_ptr->client->stop();
setEnabled(false);
return true;
}
void QtAvahiServiceBrowser::createServiceBrowser(const char *serviceType) void QtAvahiServiceBrowser::createServiceBrowser(const char *serviceType)
{ {
// create a new service browser for the given serviceType // create a new service browser for the given serviceType
AvahiServiceBrowser *browser = avahi_service_browser_new(d_ptr->client->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, serviceType, NULL, (AvahiLookupFlags) 0, QtAvahiServiceBrowserPrivate::callbackServiceBrowser, this); AvahiServiceBrowser *browser = avahi_service_browser_new(d_ptr->client->m_client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, serviceType, NULL, (AvahiLookupFlags) 0, QtAvahiServiceBrowserPrivate::callbackServiceBrowser, this);
d_ptr->serviceBrowserTable.insert(serviceType, browser); d_ptr->serviceBrowserTable.insert(serviceType, browser);
} }

View File

@ -27,20 +27,19 @@
#include <avahi-client/lookup.h> #include <avahi-client/lookup.h>
#include "libguh.h" #include "libguh.h"
#include "hardwareresource.h"
#include "qtavahiclient.h" #include "qtavahiclient.h"
#include "avahiserviceentry.h" #include "avahiserviceentry.h"
class QtAvahiServiceBrowserPrivate; class QtAvahiServiceBrowserPrivate;
class LIBGUH_EXPORT QtAvahiServiceBrowser : public QObject class LIBGUH_EXPORT QtAvahiServiceBrowser : public HardwareResource
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QtAvahiServiceBrowser(QObject *parent = 0); explicit QtAvahiServiceBrowser(QObject *parent = 0);
~QtAvahiServiceBrowser(); ~QtAvahiServiceBrowser();
void enable();
QList<AvahiServiceEntry> serviceEntries() const; QList<AvahiServiceEntry> serviceEntries() const;
signals: signals:
@ -50,6 +49,10 @@ signals:
private slots: private slots:
void onClientStateChanged(const QtAvahiClient::QtAvahiClientState &state); void onClientStateChanged(const QtAvahiClient::QtAvahiClientState &state);
public slots:
bool enable();
bool disable();
private: private:
QtAvahiServiceBrowserPrivate *d_ptr; QtAvahiServiceBrowserPrivate *d_ptr;

View File

@ -71,7 +71,7 @@ void QtAvahiServiceBrowserPrivate::callbackServiceTypeBrowser(AvahiServiceTypeBr
case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_ALL_FOR_NOW:
break; break;
case AVAHI_BROWSER_FAILURE: case AVAHI_BROWSER_FAILURE:
qCWarning(dcAvahi()) << "Service type browser error:" << QString(avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->client))); qCWarning(dcAvahi()) << "Service type browser error:" << QString(avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->m_client)));
break; break;
} }
} }
@ -88,7 +88,7 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b
switch (event) { switch (event) {
case AVAHI_BROWSER_NEW: { case AVAHI_BROWSER_NEW: {
// Start resolving new service // Start resolving new service
AvahiServiceResolver *resolver = avahi_service_resolver_new(serviceBrowser->d_ptr->client->client, AvahiServiceResolver *resolver = avahi_service_resolver_new(serviceBrowser->d_ptr->client->m_client,
interface, interface,
protocol, protocol,
name, name,
@ -101,7 +101,7 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b
if (resolver) { if (resolver) {
serviceBrowser->d_ptr->m_serviceResolvers.append(resolver); serviceBrowser->d_ptr->m_serviceResolvers.append(resolver);
} else { } else {
qCWarning(dcAvahi()) << "Failed to resolve service" << QString(name) << ":" << avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->client)); qCWarning(dcAvahi()) << "Failed to resolve service" << QString(name) << ":" << avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->m_client));
} }
break; break;
} }
@ -134,7 +134,7 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b
case AVAHI_BROWSER_CACHE_EXHAUSTED: case AVAHI_BROWSER_CACHE_EXHAUSTED:
break; break;
case AVAHI_BROWSER_FAILURE: case AVAHI_BROWSER_FAILURE:
qCWarning(dcAvahi()) << "Service browser error:" << QString(avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->client))); qCWarning(dcAvahi()) << "Service browser error:" << QString(avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->m_client)));
break; break;
} }

View File

@ -83,6 +83,19 @@ UpnpDiscovery::~UpnpDiscovery()
* the given \a searchTarget, \a userAgent and \a pluginId can be discovered.*/ * the given \a searchTarget, \a userAgent and \a pluginId can be discovered.*/
bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString &userAgent, const PluginId &pluginId) bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString &userAgent, const PluginId &pluginId)
{ {
if (!available()) {
qCWarning(dcHardware()) << name() << "not available.";
return false;
}
if (!enabled()) {
qCWarning(dcHardware()) << name() << "disabled.";
return false;
}
if (!m_socket)
return false;
if(m_socket->state() != QUdpSocket::BoundState){ if(m_socket->state() != QUdpSocket::BoundState){
qCWarning(dcHardware) << "UPnP not bound to port 1900"; qCWarning(dcHardware) << "UPnP not bound to port 1900";
return false; return false;
@ -103,6 +116,7 @@ bool UpnpDiscovery::discoverDevices(const QString &searchTarget, const QString &
void UpnpDiscovery::requestDeviceInformation(const QNetworkRequest &networkRequest, const UpnpDeviceDescriptor &upnpDeviceDescriptor) void UpnpDiscovery::requestDeviceInformation(const QNetworkRequest &networkRequest, const UpnpDeviceDescriptor &upnpDeviceDescriptor)
{ {
QNetworkReply *replay = m_networkAccessManager->get(networkRequest); QNetworkReply *replay = m_networkAccessManager->get(networkRequest);
connect(replay, &QNetworkReply::finished, this, &UpnpDiscovery::replyFinished);
m_informationRequestList.insert(replay, upnpDeviceDescriptor); m_informationRequestList.insert(replay, upnpDeviceDescriptor);
} }
@ -169,6 +183,9 @@ void UpnpDiscovery::respondToSearchRequest(QHostAddress host, int port)
/*! This method will be called to send the SSDP message \a data to the UPnP multicast.*/ /*! This method will be called to send the SSDP message \a data to the UPnP multicast.*/
void UpnpDiscovery::sendToMulticast(const QByteArray &data) void UpnpDiscovery::sendToMulticast(const QByteArray &data)
{ {
if (!m_socket)
return;
m_socket->writeDatagram(data, m_host, m_port); m_socket->writeDatagram(data, m_host, m_port);
} }
@ -226,8 +243,9 @@ void UpnpDiscovery::readData()
} }
} }
void UpnpDiscovery::replyFinished(QNetworkReply *reply) void UpnpDiscovery::replyFinished()
{ {
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
switch (status) { switch (status) {
@ -451,7 +469,14 @@ bool UpnpDiscovery::enable()
bool UpnpDiscovery::disable() bool UpnpDiscovery::disable()
{ {
// TODO: sendByeByeMessage();
m_socket->waitForBytesWritten();
m_socket->close();
delete m_socket;
m_socket = nullptr;
m_notificationTimer->stop();
setEnabled(false); setEnabled(false);
return true; return true;
} }

View File

@ -77,7 +77,7 @@ signals:
private slots: private slots:
void error(QAbstractSocket::SocketError error); void error(QAbstractSocket::SocketError error);
void readData(); void readData();
void replyFinished(QNetworkReply *reply); void replyFinished();
void notificationTimeout(); void notificationTimeout();
void sendByeByeMessage(); void sendByeByeMessage();
void sendAliveMessage(); void sendAliveMessage();