From 568e21d68a117b7bcac1397f67f5f3090982ceaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 29 Apr 2016 14:32:23 +0200 Subject: [PATCH] add avahi documantation and webserver service --- debian/control | 1 + libguh/libguh.pro | 2 ++ libguh/network/avahi/avahiserviceentry.cpp | 30 +++++++++++++--- libguh/network/avahi/avahiserviceentry.h | 1 - libguh/network/avahi/guhavahibrowser.cpp | 7 ++++ libguh/network/avahi/guhavahibrowser.h | 17 +++++++++ libguh/network/avahi/zconfservice.cpp | 37 ++++++++++++-------- libguh/network/avahi/zconfservice.h | 11 +++--- libguh/network/avahi/zconfservicebrowser.cpp | 27 ++++++++------ libguh/network/avahi/zconfservicebrowser.h | 6 ++-- server/webserver.cpp | 25 ++++++++++++- server/webserver.h | 10 ++++++ 12 files changed, 134 insertions(+), 40 deletions(-) create mode 100644 libguh/network/avahi/guhavahibrowser.cpp create mode 100644 libguh/network/avahi/guhavahibrowser.h diff --git a/debian/control b/debian/control index 3b3a2220..f10bf959 100644 --- a/debian/control +++ b/debian/control @@ -32,6 +32,7 @@ Depends: libqt5network5, libqt5sql5, libqt5xml5, logrotate, + avahi-daemon, libguh1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} diff --git a/libguh/libguh.pro b/libguh/libguh.pro index 071e7b0a..84cd4f47 100644 --- a/libguh/libguh.pro +++ b/libguh/libguh.pro @@ -74,6 +74,7 @@ HEADERS += devicemanager.h \ types/ruleaction.h \ types/ruleactionparam.h \ types/statedescriptor.h \ + network/avahi/guhavahibrowser.h SOURCES += devicemanager.cpp \ @@ -124,6 +125,7 @@ SOURCES += devicemanager.cpp \ types/ruleaction.cpp \ types/ruleactionparam.cpp \ types/statedescriptor.cpp \ + network/avahi/guhavahibrowser.cpp # install plugininfo python script for libguh-dev diff --git a/libguh/network/avahi/avahiserviceentry.cpp b/libguh/network/avahi/avahiserviceentry.cpp index f0447abd..e6885363 100644 --- a/libguh/network/avahi/avahiserviceentry.cpp +++ b/libguh/network/avahi/avahiserviceentry.cpp @@ -18,8 +18,19 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/*! + \class AvahiServiceEntry + \brief Holds information about an avahi service entry. + + \ingroup types + \inmodule libguh + +*/ + #include "avahiserviceentry.h" + +/*! Constructs an empty invalid \l{AvahiServiceEntry}*/ AvahiServiceEntry::AvahiServiceEntry() : m_port(0), m_protocol(QAbstractSocket::UnknownNetworkLayerProtocol) @@ -27,6 +38,7 @@ AvahiServiceEntry::AvahiServiceEntry() : } +/*! Constructs a new \l{AvahiServiceEntry} with the given \a name, \a hostAddress, \a domain, \a hostName, \a port, \a protocol, \a txt and \a flags.*/ AvahiServiceEntry::AvahiServiceEntry(QString name, QHostAddress hostAddress, QString domain, QString hostName, quint16 port, QAbstractSocket::NetworkLayerProtocol protocol, QStringList txt, AvahiLookupResultFlags flags) : m_name(name), m_hostAddress(hostAddress), @@ -40,72 +52,80 @@ AvahiServiceEntry::AvahiServiceEntry(QString name, QHostAddress hostAddress, QSt } +/*! Returns the name of this \l{AvahiServiceEntry}.*/ QString AvahiServiceEntry::name() const { return m_name; } +/*! Returns the host address of this \l{AvahiServiceEntry}.*/ QHostAddress AvahiServiceEntry::hostAddress() const { return m_hostAddress; } +/*! Returns the domain of this \l{AvahiServiceEntry}.*/ QString AvahiServiceEntry::domain() const { return m_domain; } +/*! Returns the host name of this \l{AvahiServiceEntry}.*/ QString AvahiServiceEntry::hostName() const { return m_hostName; } +/*! Returns the port of this \l{AvahiServiceEntry}.*/ quint16 AvahiServiceEntry::port() const { return m_port; } +/*! Returns the protocol of this \l{AvahiServiceEntry}.*/ QAbstractSocket::NetworkLayerProtocol AvahiServiceEntry::protocol() const { return m_protocol; } -AvahiLookupResultFlags AvahiServiceEntry::flags() const -{ - return m_flags; -} - +/*! Returns the txt string list of this \l{AvahiServiceEntry}.*/ QStringList AvahiServiceEntry::txt() const { return m_txt; } +/*! Returns true if this \l{AvahiServiceEntry} is valid.*/ bool AvahiServiceEntry::isValid() const { return !m_hostAddress.isNull() && !m_hostName.isEmpty() && m_port != 0 && m_protocol != QAbstractSocket::UnknownNetworkLayerProtocol; } +/*! Returns true if this \l{AvahiServiceEntry} was loaded from the cache.*/ bool AvahiServiceEntry::isChached() const { return m_flags & AVAHI_LOOKUP_RESULT_CACHED; } +/*! Returns true if this \l{AvahiServiceEntry} was found in the wide area.*/ bool AvahiServiceEntry::isWideArea() const { return m_flags & AVAHI_LOOKUP_RESULT_WIDE_AREA; } +/*! Returns true if this \l{AvahiServiceEntry} is a multicast service.*/ bool AvahiServiceEntry::isMulticast() const { return m_flags & AVAHI_LOOKUP_RESULT_MULTICAST; } +/*! Returns true if this \l{AvahiServiceEntry} was found local.*/ bool AvahiServiceEntry::isLocal() const { return m_flags & AVAHI_LOOKUP_RESULT_LOCAL; } +/*! Returns true if this \l{AvahiServiceEntry} is our own service.*/ bool AvahiServiceEntry::isOurOwn() const { return m_flags & AVAHI_LOOKUP_RESULT_OUR_OWN; diff --git a/libguh/network/avahi/avahiserviceentry.h b/libguh/network/avahi/avahiserviceentry.h index 22a9f4f5..07740fb6 100644 --- a/libguh/network/avahi/avahiserviceentry.h +++ b/libguh/network/avahi/avahiserviceentry.h @@ -38,7 +38,6 @@ public: QString hostName() const; quint16 port() const; QAbstractSocket::NetworkLayerProtocol protocol() const; - AvahiLookupResultFlags flags() const; QStringList txt() const; bool isValid() const; diff --git a/libguh/network/avahi/guhavahibrowser.cpp b/libguh/network/avahi/guhavahibrowser.cpp new file mode 100644 index 00000000..524e206d --- /dev/null +++ b/libguh/network/avahi/guhavahibrowser.cpp @@ -0,0 +1,7 @@ +#include "guhavahibrowser.h" + +GuhAvahiBrowser::GuhAvahiBrowser(QObject *parent) : QObject(parent) +{ + +} + diff --git a/libguh/network/avahi/guhavahibrowser.h b/libguh/network/avahi/guhavahibrowser.h new file mode 100644 index 00000000..f30c7f16 --- /dev/null +++ b/libguh/network/avahi/guhavahibrowser.h @@ -0,0 +1,17 @@ +#ifndef GUHAVAHIBROWSER_H +#define GUHAVAHIBROWSER_H + +#include + +class GuhAvahiBrowser : public QObject +{ + Q_OBJECT +public: + explicit GuhAvahiBrowser(QObject *parent = 0); + +signals: + +public slots: +}; + +#endif // GUHAVAHIBROWSER_H diff --git a/libguh/network/avahi/zconfservice.cpp b/libguh/network/avahi/zconfservice.cpp index 1ea4790b..5ac87541 100644 --- a/libguh/network/avahi/zconfservice.cpp +++ b/libguh/network/avahi/zconfservice.cpp @@ -73,13 +73,30 @@ public: /*! \class ZConfService + \ingroup hardware + \inmodule libguh + \brief This class provides Avahi Zeroconf service registration. It can be used by server applications to announce a service on the local area network. Typical use involves creating an instance of ZConfService and calling registerService() with a service name and port number. - */ +*/ + +/*! \fn void ZConfService::entryGroupEstablished(); + This signal will be emited when the service entry could be established successfully. +*/ + +/*! \fn void ZConfService::entryGroupNameCollision(); + This signal will be emited when the service entry name collided with an other service. +*/ + +/*! \fn void ZConfService::entryGroupFailure(); + This signal will be emited when the service entry could not be established successfully. +*/ + +/*! Constructs a \l{ZConfService} with the given \a parent.*/ ZConfService::ZConfService(QObject *parent) : QObject(parent), d_ptr(new ZConfServicePrivate) @@ -88,9 +105,7 @@ ZConfService::ZConfService(QObject *parent) d_ptr->client->run(); } -/*! - Destroys the object and releases all resources associated with it. - */ +/*! Destroys the object and releases all resources associated with it. */ ZConfService::~ZConfService() { if (d_ptr->group) @@ -98,18 +113,13 @@ ZConfService::~ZConfService() delete d_ptr; } -/*! - Returns true if the service group was added and commited without error. - */ +/*! Returns true if the service group was added and commited without error. */ bool ZConfService::isValid() const { return (d_ptr->group && !d_ptr->error); } -/*! - Returns a human readable error string with details of the last error that - occured. - */ +/*! Returns a human readable error string with details of the last error that occured. */ QString ZConfService::errorString() const { if (!d_ptr->client->client) @@ -118,9 +128,8 @@ QString ZConfService::errorString() const } /*! - Registers a Zeroconf service on the LAN. If no service type is specified, - "_http._tcp" is assumed. Needless to say, the server should be available - and listen on the specified port. + Registers a Zeroconf service with the given \a name and \a port on the LAN. If no service \a type is specified, + "_http._tcp" is assumed. */ void ZConfService::registerService(QString name, in_port_t port, QString type) { diff --git a/libguh/network/avahi/zconfservice.h b/libguh/network/avahi/zconfservice.h index bcf3a495..876674f3 100644 --- a/libguh/network/avahi/zconfservice.h +++ b/libguh/network/avahi/zconfservice.h @@ -37,11 +37,6 @@ public: bool isValid() const; QString errorString() const; -signals: - void entryGroupEstablished(); - void entryGroupNameCollision(); - void entryGroupFailure(); - public slots: void registerService(QString name, in_port_t port, QString type = "_http._tcp"); void resetService(); @@ -51,6 +46,12 @@ protected: private: Q_DECLARE_PRIVATE(ZConfService) + +signals: + void entryGroupEstablished(); + void entryGroupNameCollision(); + void entryGroupFailure(); + }; #endif // ZCONFSERVICE_H diff --git a/libguh/network/avahi/zconfservicebrowser.cpp b/libguh/network/avahi/zconfservicebrowser.cpp index 298fc0cb..2c1f8901 100644 --- a/libguh/network/avahi/zconfservicebrowser.cpp +++ b/libguh/network/avahi/zconfservicebrowser.cpp @@ -138,7 +138,6 @@ public: // } // } - AvahiServiceEntry entry = AvahiServiceEntry(name, QHostAddress(QString(a)), QString(domain), QString(host_name), (quint16)port, p, txtList, flags); serviceBrowser->d_ptr->entries.insert(name, entry); @@ -160,6 +159,9 @@ public: /*! \class ZConfServiceBrowser + \ingroup hardware + \inmodule libguh + \brief AvahiServiceBrowser wrapper that lets you browse for services available on the local network. This class can be used to handle Zeroconf service discovery in a Qt-based client application. @@ -170,12 +172,17 @@ public: ZConfServiceBrowser will emit serviceEntryAdded() when a new service is discovered and serviceEntryRemoved() when a service is removed from the network. - */ +*/ -/*! - Creates a Zeroconf service browser. Call browse() to start browsing for - services. - */ +/*! \fn void ZConfServiceBrowser::serviceEntryAdded(const QString &name); + This signal will be emited when a new service entry with the given \a name was added in the network. +*/ + +/*! \fn void ZConfServiceBrowser::serviceEntryRemoved(const QString &name); + This signal will be emited when a new service entry with the given \a name was removed from the network. +*/ + +/*! Creates a Zeroconf service browser with the given \a parent. Call browse() to start browsing for services. */ ZConfServiceBrowser::ZConfServiceBrowser(QObject *parent) : QObject(parent), d_ptr(new ZConfServiceBrowserPrivate(new ZConfServiceClient(this))) @@ -183,9 +190,7 @@ ZConfServiceBrowser::ZConfServiceBrowser(QObject *parent) connect(d_ptr->client, SIGNAL(clientRunning()), this, SLOT(createServiceBrowser())); } -/*! - Destroys the browser object and releases all resources associated with it. - */ +/*! Destroys the browser object and releases all resources associated with it. */ ZConfServiceBrowser::~ZConfServiceBrowser() { if (d_ptr->browser) @@ -194,7 +199,7 @@ ZConfServiceBrowser::~ZConfServiceBrowser() } /*! - Browses for Zeroconf services on the LAN. This is a non-blocking call. + Browses for Zeroconf services of the given \a serviceType on the LAN. This is a non-blocking call. ZConfServiceBrowser will emit serviceEntryAdded() when a new service is discovered and serviceEntryRemoved() when a service is removed from the network. @@ -208,7 +213,7 @@ void ZConfServiceBrowser::browse(QString serviceType) /*! Returns a ZConfServiceEntry struct with detailed information about the - Zeroconf service associated with the name. + Zeroconf service associated with the \a name. */ AvahiServiceEntry ZConfServiceBrowser::serviceEntry(QString name) { diff --git a/libguh/network/avahi/zconfservicebrowser.h b/libguh/network/avahi/zconfservicebrowser.h index d18fc1be..f952408b 100644 --- a/libguh/network/avahi/zconfservicebrowser.h +++ b/libguh/network/avahi/zconfservicebrowser.h @@ -41,10 +41,10 @@ public: AvahiServiceEntry serviceEntry(QString name); signals: - void serviceEntryAdded(QString); - void serviceEntryRemoved(QString); + void serviceEntryAdded(const QString &name); + void serviceEntryRemoved(const QString &name); -protected slots: +private slots: void createServiceBrowser(); protected: diff --git a/server/webserver.cpp b/server/webserver.cpp index 5008844b..21352a6e 100644 --- a/server/webserver.cpp +++ b/server/webserver.cpp @@ -126,6 +126,13 @@ WebServer::WebServer(const QSslConfiguration &sslConfiguration, QObject *parent) if (m_useSsl && m_sslConfiguration.isNull()) m_useSsl = false; + // Create avahi service + m_avahiService = new ZConfService(this); + connect(m_avahiService, SIGNAL(entryGroupEstablished()), this, SLOT(onEntryGroupEstablished())); + connect(m_avahiService, SIGNAL(entryGroupFailure()), this, SLOT(onEntryGroupEstablished())); + connect(m_avahiService, SIGNAL(entryGroupNameCollision()), this, SLOT(onEntryGroupEstablished())); + m_avahiService->registerService("guhd", m_port); + } /*! Destructor of this \l{WebServer}. */ @@ -133,6 +140,8 @@ WebServer::~WebServer() { qCDebug(dcApplication) << "Shutting down \"Webserver\""; this->close(); + qCDebug(dcApplication) << "Shutting down \"Avahi Service\""; + m_avahiService->resetService(); } /*! Send the given \a reply map to the corresponding client. @@ -155,7 +164,6 @@ void WebServer::sendHttpReply(HttpReply *reply) socket->write(reply->data()); } - /*! Returns the port on which the webserver is listening. */ int WebServer::port() const { @@ -527,6 +535,21 @@ void WebServer::onError(QAbstractSocket::SocketError error) qCWarning(dcConnection) << QString("Client socket error %1:%2 ->").arg(socket->peerAddress().toString()).arg(socket->peerPort()) << socket->errorString(); } +void WebServer::onEntryGroupEstablished() +{ + qCDebug(dcWebServer()) << "Avahi webserver service established successfully."; +} + +void WebServer::onEntryGroupFailure() +{ + qCWarning(dcWebServer()) << "Avahi webserver service establishment failed."; +} + +void WebServer::onEntryGroupNameCollision() +{ + qCWarning(dcWebServer()) << "Avahi webserver service establishment failed. Name collision."; +} + /*! Returns true if this \l{WebServer} started successfully. */ bool WebServer::startServer() { diff --git a/server/webserver.h b/server/webserver.h index 3e12c343..814d05e3 100644 --- a/server/webserver.h +++ b/server/webserver.h @@ -34,6 +34,8 @@ #include #include +#include "network/avahi/zconfservice.h" + // Note: Hypertext Transfer Protocol (HTTP/1.1) from the Internet Engineering Task Force (IETF): // https://tools.ietf.org/html/rfc7231 @@ -84,6 +86,8 @@ private: QList m_webServerClients; QHash m_incompleteRequests; + ZConfService *m_avahiService; + QSslConfiguration m_sslConfiguration; bool m_useSsl; @@ -112,6 +116,12 @@ private slots: void onEncrypted(); void onError(QAbstractSocket::SocketError error); + // avahi service + void onEntryGroupEstablished(); + void onEntryGroupFailure(); + void onEntryGroupNameCollision(); + + public slots: bool startServer(); bool stopServer();