add avahi documantation and webserver service

This commit is contained in:
Simon Stürz 2016-04-29 14:32:23 +02:00 committed by Michael Zanetti
parent 0a2f860c64
commit 568e21d68a
12 changed files with 134 additions and 40 deletions

1
debian/control vendored
View File

@ -32,6 +32,7 @@ Depends: libqt5network5,
libqt5sql5, libqt5sql5,
libqt5xml5, libqt5xml5,
logrotate, logrotate,
avahi-daemon,
libguh1 (= ${binary:Version}), libguh1 (= ${binary:Version}),
${shlibs:Depends}, ${shlibs:Depends},
${misc:Depends} ${misc:Depends}

View File

@ -74,6 +74,7 @@ HEADERS += devicemanager.h \
types/ruleaction.h \ types/ruleaction.h \
types/ruleactionparam.h \ types/ruleactionparam.h \
types/statedescriptor.h \ types/statedescriptor.h \
network/avahi/guhavahibrowser.h
SOURCES += devicemanager.cpp \ SOURCES += devicemanager.cpp \
@ -124,6 +125,7 @@ SOURCES += devicemanager.cpp \
types/ruleaction.cpp \ types/ruleaction.cpp \
types/ruleactionparam.cpp \ types/ruleactionparam.cpp \
types/statedescriptor.cpp \ types/statedescriptor.cpp \
network/avahi/guhavahibrowser.cpp
# install plugininfo python script for libguh-dev # install plugininfo python script for libguh-dev

View File

@ -18,8 +18,19 @@
* * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class AvahiServiceEntry
\brief Holds information about an avahi service entry.
\ingroup types
\inmodule libguh
*/
#include "avahiserviceentry.h" #include "avahiserviceentry.h"
/*! Constructs an empty invalid \l{AvahiServiceEntry}*/
AvahiServiceEntry::AvahiServiceEntry() : AvahiServiceEntry::AvahiServiceEntry() :
m_port(0), m_port(0),
m_protocol(QAbstractSocket::UnknownNetworkLayerProtocol) 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) : AvahiServiceEntry::AvahiServiceEntry(QString name, QHostAddress hostAddress, QString domain, QString hostName, quint16 port, QAbstractSocket::NetworkLayerProtocol protocol, QStringList txt, AvahiLookupResultFlags flags) :
m_name(name), m_name(name),
m_hostAddress(hostAddress), 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 QString AvahiServiceEntry::name() const
{ {
return m_name; return m_name;
} }
/*! Returns the host address of this \l{AvahiServiceEntry}.*/
QHostAddress AvahiServiceEntry::hostAddress() const QHostAddress AvahiServiceEntry::hostAddress() const
{ {
return m_hostAddress; return m_hostAddress;
} }
/*! Returns the domain of this \l{AvahiServiceEntry}.*/
QString AvahiServiceEntry::domain() const QString AvahiServiceEntry::domain() const
{ {
return m_domain; return m_domain;
} }
/*! Returns the host name of this \l{AvahiServiceEntry}.*/
QString AvahiServiceEntry::hostName() const QString AvahiServiceEntry::hostName() const
{ {
return m_hostName; return m_hostName;
} }
/*! Returns the port of this \l{AvahiServiceEntry}.*/
quint16 AvahiServiceEntry::port() const quint16 AvahiServiceEntry::port() const
{ {
return m_port; return m_port;
} }
/*! Returns the protocol of this \l{AvahiServiceEntry}.*/
QAbstractSocket::NetworkLayerProtocol AvahiServiceEntry::protocol() const QAbstractSocket::NetworkLayerProtocol AvahiServiceEntry::protocol() const
{ {
return m_protocol; return m_protocol;
} }
AvahiLookupResultFlags AvahiServiceEntry::flags() const /*! Returns the txt string list of this \l{AvahiServiceEntry}.*/
{
return m_flags;
}
QStringList AvahiServiceEntry::txt() const QStringList AvahiServiceEntry::txt() const
{ {
return m_txt; return m_txt;
} }
/*! Returns true if this \l{AvahiServiceEntry} is valid.*/
bool AvahiServiceEntry::isValid() const bool AvahiServiceEntry::isValid() const
{ {
return !m_hostAddress.isNull() && !m_hostName.isEmpty() && m_port != 0 && m_protocol != QAbstractSocket::UnknownNetworkLayerProtocol; 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 bool AvahiServiceEntry::isChached() const
{ {
return m_flags & AVAHI_LOOKUP_RESULT_CACHED; return m_flags & AVAHI_LOOKUP_RESULT_CACHED;
} }
/*! Returns true if this \l{AvahiServiceEntry} was found in the wide area.*/
bool AvahiServiceEntry::isWideArea() const bool AvahiServiceEntry::isWideArea() const
{ {
return m_flags & AVAHI_LOOKUP_RESULT_WIDE_AREA; return m_flags & AVAHI_LOOKUP_RESULT_WIDE_AREA;
} }
/*! Returns true if this \l{AvahiServiceEntry} is a multicast service.*/
bool AvahiServiceEntry::isMulticast() const bool AvahiServiceEntry::isMulticast() const
{ {
return m_flags & AVAHI_LOOKUP_RESULT_MULTICAST; return m_flags & AVAHI_LOOKUP_RESULT_MULTICAST;
} }
/*! Returns true if this \l{AvahiServiceEntry} was found local.*/
bool AvahiServiceEntry::isLocal() const bool AvahiServiceEntry::isLocal() const
{ {
return m_flags & AVAHI_LOOKUP_RESULT_LOCAL; return m_flags & AVAHI_LOOKUP_RESULT_LOCAL;
} }
/*! Returns true if this \l{AvahiServiceEntry} is our own service.*/
bool AvahiServiceEntry::isOurOwn() const bool AvahiServiceEntry::isOurOwn() const
{ {
return m_flags & AVAHI_LOOKUP_RESULT_OUR_OWN; return m_flags & AVAHI_LOOKUP_RESULT_OUR_OWN;

View File

@ -38,7 +38,6 @@ public:
QString hostName() const; QString hostName() const;
quint16 port() const; quint16 port() const;
QAbstractSocket::NetworkLayerProtocol protocol() const; QAbstractSocket::NetworkLayerProtocol protocol() const;
AvahiLookupResultFlags flags() const;
QStringList txt() const; QStringList txt() const;
bool isValid() const; bool isValid() const;

View File

@ -0,0 +1,7 @@
#include "guhavahibrowser.h"
GuhAvahiBrowser::GuhAvahiBrowser(QObject *parent) : QObject(parent)
{
}

View File

@ -0,0 +1,17 @@
#ifndef GUHAVAHIBROWSER_H
#define GUHAVAHIBROWSER_H
#include <QObject>
class GuhAvahiBrowser : public QObject
{
Q_OBJECT
public:
explicit GuhAvahiBrowser(QObject *parent = 0);
signals:
public slots:
};
#endif // GUHAVAHIBROWSER_H

View File

@ -73,13 +73,30 @@ public:
/*! /*!
\class ZConfService \class ZConfService
\ingroup hardware
\inmodule libguh
\brief This class provides Avahi Zeroconf service registration. It can be \brief This class provides Avahi Zeroconf service registration. It can be
used by server applications to announce a service on the local area network. used by server applications to announce a service on the local area network.
Typical use involves creating an instance of ZConfService and calling Typical use involves creating an instance of ZConfService and calling
registerService() with a service name and port number. 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) ZConfService::ZConfService(QObject *parent)
: QObject(parent), : QObject(parent),
d_ptr(new ZConfServicePrivate) d_ptr(new ZConfServicePrivate)
@ -88,9 +105,7 @@ ZConfService::ZConfService(QObject *parent)
d_ptr->client->run(); 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() ZConfService::~ZConfService()
{ {
if (d_ptr->group) if (d_ptr->group)
@ -98,18 +113,13 @@ ZConfService::~ZConfService()
delete d_ptr; 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 bool ZConfService::isValid() const
{ {
return (d_ptr->group && !d_ptr->error); 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 QString ZConfService::errorString() const
{ {
if (!d_ptr->client->client) 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, 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. Needless to say, the server should be available "_http._tcp" is assumed.
and listen on the specified port.
*/ */
void ZConfService::registerService(QString name, in_port_t port, QString type) void ZConfService::registerService(QString name, in_port_t port, QString type)
{ {

View File

@ -37,11 +37,6 @@ public:
bool isValid() const; bool isValid() const;
QString errorString() const; QString errorString() const;
signals:
void entryGroupEstablished();
void entryGroupNameCollision();
void entryGroupFailure();
public slots: public slots:
void registerService(QString name, in_port_t port, QString type = "_http._tcp"); void registerService(QString name, in_port_t port, QString type = "_http._tcp");
void resetService(); void resetService();
@ -51,6 +46,12 @@ protected:
private: private:
Q_DECLARE_PRIVATE(ZConfService) Q_DECLARE_PRIVATE(ZConfService)
signals:
void entryGroupEstablished();
void entryGroupNameCollision();
void entryGroupFailure();
}; };
#endif // ZCONFSERVICE_H #endif // ZCONFSERVICE_H

View File

@ -138,7 +138,6 @@ public:
// } // }
// } // }
AvahiServiceEntry entry = AvahiServiceEntry(name, QHostAddress(QString(a)), QString(domain), QString(host_name), (quint16)port, p, txtList, flags); AvahiServiceEntry entry = AvahiServiceEntry(name, QHostAddress(QString(a)), QString(domain), QString(host_name), (quint16)port, p, txtList, flags);
serviceBrowser->d_ptr->entries.insert(name, entry); serviceBrowser->d_ptr->entries.insert(name, entry);
@ -160,6 +159,9 @@ public:
/*! /*!
\class ZConfServiceBrowser \class ZConfServiceBrowser
\ingroup hardware
\inmodule libguh
\brief AvahiServiceBrowser wrapper that lets you browse for services \brief AvahiServiceBrowser wrapper that lets you browse for services
available on the local network. This class can be used to handle Zeroconf available on the local network. This class can be used to handle Zeroconf
service discovery in a Qt-based client application. service discovery in a Qt-based client application.
@ -170,12 +172,17 @@ public:
ZConfServiceBrowser will emit serviceEntryAdded() when a new service is ZConfServiceBrowser will emit serviceEntryAdded() when a new service is
discovered and serviceEntryRemoved() when a service is removed from the discovered and serviceEntryRemoved() when a service is removed from the
network. network.
*/ */
/*! /*! \fn void ZConfServiceBrowser::serviceEntryAdded(const QString &name);
Creates a Zeroconf service browser. Call browse() to start browsing for This signal will be emited when a new service entry with the given \a name was added in the network.
services. */
*/
/*! \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) ZConfServiceBrowser::ZConfServiceBrowser(QObject *parent)
: QObject(parent), : QObject(parent),
d_ptr(new ZConfServiceBrowserPrivate(new ZConfServiceClient(this))) d_ptr(new ZConfServiceBrowserPrivate(new ZConfServiceClient(this)))
@ -183,9 +190,7 @@ ZConfServiceBrowser::ZConfServiceBrowser(QObject *parent)
connect(d_ptr->client, SIGNAL(clientRunning()), this, SLOT(createServiceBrowser())); 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() ZConfServiceBrowser::~ZConfServiceBrowser()
{ {
if (d_ptr->browser) 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 ZConfServiceBrowser will emit serviceEntryAdded() when a new service is
discovered and serviceEntryRemoved() when a service is removed from the discovered and serviceEntryRemoved() when a service is removed from the
network. network.
@ -208,7 +213,7 @@ void ZConfServiceBrowser::browse(QString serviceType)
/*! /*!
Returns a ZConfServiceEntry struct with detailed information about the 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) AvahiServiceEntry ZConfServiceBrowser::serviceEntry(QString name)
{ {

View File

@ -41,10 +41,10 @@ public:
AvahiServiceEntry serviceEntry(QString name); AvahiServiceEntry serviceEntry(QString name);
signals: signals:
void serviceEntryAdded(QString); void serviceEntryAdded(const QString &name);
void serviceEntryRemoved(QString); void serviceEntryRemoved(const QString &name);
protected slots: private slots:
void createServiceBrowser(); void createServiceBrowser();
protected: protected:

View File

@ -126,6 +126,13 @@ WebServer::WebServer(const QSslConfiguration &sslConfiguration, QObject *parent)
if (m_useSsl && m_sslConfiguration.isNull()) if (m_useSsl && m_sslConfiguration.isNull())
m_useSsl = false; 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}. */ /*! Destructor of this \l{WebServer}. */
@ -133,6 +140,8 @@ WebServer::~WebServer()
{ {
qCDebug(dcApplication) << "Shutting down \"Webserver\""; qCDebug(dcApplication) << "Shutting down \"Webserver\"";
this->close(); this->close();
qCDebug(dcApplication) << "Shutting down \"Avahi Service\"";
m_avahiService->resetService();
} }
/*! Send the given \a reply map to the corresponding client. /*! Send the given \a reply map to the corresponding client.
@ -155,7 +164,6 @@ void WebServer::sendHttpReply(HttpReply *reply)
socket->write(reply->data()); socket->write(reply->data());
} }
/*! Returns the port on which the webserver is listening. */ /*! Returns the port on which the webserver is listening. */
int WebServer::port() const 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(); 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. */ /*! Returns true if this \l{WebServer} started successfully. */
bool WebServer::startServer() bool WebServer::startServer()
{ {

View File

@ -34,6 +34,8 @@
#include <QSslConfiguration> #include <QSslConfiguration>
#include <QSslKey> #include <QSslKey>
#include "network/avahi/zconfservice.h"
// Note: Hypertext Transfer Protocol (HTTP/1.1) from the Internet Engineering Task Force (IETF): // Note: Hypertext Transfer Protocol (HTTP/1.1) from the Internet Engineering Task Force (IETF):
// https://tools.ietf.org/html/rfc7231 // https://tools.ietf.org/html/rfc7231
@ -84,6 +86,8 @@ private:
QList<WebServerClient *> m_webServerClients; QList<WebServerClient *> m_webServerClients;
QHash<QSslSocket *, HttpRequest> m_incompleteRequests; QHash<QSslSocket *, HttpRequest> m_incompleteRequests;
ZConfService *m_avahiService;
QSslConfiguration m_sslConfiguration; QSslConfiguration m_sslConfiguration;
bool m_useSsl; bool m_useSsl;
@ -112,6 +116,12 @@ private slots:
void onEncrypted(); void onEncrypted();
void onError(QAbstractSocket::SocketError error); void onError(QAbstractSocket::SocketError error);
// avahi service
void onEntryGroupEstablished();
void onEntryGroupFailure();
void onEntryGroupNameCollision();
public slots: public slots:
bool startServer(); bool startServer();
bool stopServer(); bool stopServer();