diff --git a/debian/man/guhd.1 b/debian/man/guhd.1 index d51b94c4..c88fed91 100644 --- a/debian/man/guhd.1 +++ b/debian/man/guhd.1 @@ -7,11 +7,10 @@ guhd \- An open source IoT (Internet of Things) server .B guhd [\fIOPTION\fR] .SH DESCRIPTION -guh (/[guːh]/) is an open source IoT (Internet of Things) server, -which allows to control a lot of different devices from many different -manufacturers. With the powerful rule engine you are able to connect any -device available in the system and create individual scenes and behaviors -for your environment. +The guh (/[guːh]/) daemon is a plugin based IoT (Internet of Things) server. The +server works like a translator for devices, things and services and +allows them to interact. With the powerful rule engine you are able to connect any device available +in the system and create individual scenes and behaviors for your environment. .SH OPTIONS .TP \fB\-h\fR, \fB\-\-help\fR @@ -67,16 +66,15 @@ Print the debug messages from the websocket server. .TP \fBDebug\ categories\ for\ plugins:\fR Since guh loads the plugins dynamically, the list of supported -plugin debug categories depends on your plugin installation. Please use +plugin debug categories depends on your plugin installation. Please use the \fB-h\fR command to see which categories are available for your system. .SH EXAMPLES .TP To start guhd in the foreground and read the debug messages from the Hardware: -.IP +.IP $ guhd -n -d Hardware .TP -To start guhd in the foreground, disable debug messages from the DeviceManager -and enable debug messages for JsonRpc and LogEngine: +To start guhd in the foreground, disable debug messages from the DeviceManager and enable debug messages for JsonRpc and LogEngine: .IP $ guhd -n -d NoDeviceManager -d JsonRpc -d LogEngine .SH FILES diff --git a/debian/rules b/debian/rules index 3fc29224..27f8b76a 100755 --- a/debian/rules +++ b/debian/rules @@ -16,6 +16,9 @@ include /usr/share/dpkg/buildflags.mk %: dh $@ --parallel +override_dh_auto_configure: + qmake . CONFIG+=debian + override_dh_auto_build: make make doc diff --git a/guh.pri b/guh.pri index d98a267f..4b63850d 100644 --- a/guh.pri +++ b/guh.pri @@ -11,13 +11,8 @@ DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" \ QT+= network websockets bluetooth -QMAKE_CXXFLAGS += -Werror -std=c++11 -g -QMAKE_LFLAGS += -std=c++11 - -QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS) -QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS) -QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS) -QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS) +QMAKE_CXXFLAGS *= -Werror -std=c++11 -g +QMAKE_LFLAGS *= -std=c++11 top_srcdir=$$PWD top_builddir=$$shadowed($$PWD) @@ -27,6 +22,13 @@ ccache { QMAKE_CXX = ccache g++ } +debian { + QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS) + QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS) + QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS) + QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS) +} + # Check for Bluetoot LE support (Qt >= 5.4) equals(QT_MAJOR_VERSION, 5):greaterThan(QT_MINOR_VERSION, 3) { DEFINES += BLUETOOTH_LE diff --git a/server/cloud/cloudconnection.cpp b/server/cloud/cloudconnection.cpp index d812a9d5..061a1cb4 100644 --- a/server/cloud/cloudconnection.cpp +++ b/server/cloud/cloudconnection.cpp @@ -39,11 +39,18 @@ CloudConnection::CloudConnection(QObject *parent) : m_reconnectionTimer->setSingleShot(false); connect(m_reconnectionTimer, &QTimer::timeout, this, &CloudConnection::reconnectionTimeout); + m_pingTimer = new QTimer(this); + m_pingTimer->setSingleShot(false); + m_pingTimer->setInterval(30000); + connect(m_pingTimer, &QTimer::timeout, this, &CloudConnection::onPingTimeout); + m_connection = new QWebSocket("guhd", QWebSocketProtocol::Version13, this); connect(m_connection, SIGNAL(connected()), this, SLOT(onConnected())); connect(m_connection, SIGNAL(disconnected()), this, SLOT(onDisconnected())); connect(m_connection, SIGNAL(textMessageReceived(QString)), this, SLOT(onTextMessageReceived(QString))); connect(m_connection, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); + connect(m_connection, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(onStateChanged(QAbstractSocket::SocketState))); + connect(m_connection, SIGNAL(pong(quint64,QByteArray)), this, SLOT(onPong(quint64,QByteArray))); m_authenticator = new CloudAuthenticator("6ac82de6a2ba454394f9022b6a733885", "d63eece1b725419f80961a9b1c49f8d4", this); m_authenticator->setUrl(m_authenticationServerUrl); @@ -120,6 +127,7 @@ void CloudConnection::onConnected() { qCDebug(dcCloud()) << "Connected to cloud proxy server" << m_proxyUrl.toString(); setConnected(true); + m_pingTimer->start(); m_reconnectionTimer->stop(); } @@ -129,6 +137,7 @@ void CloudConnection::onDisconnected() qCDebug(dcCloud()) << "Disconnected from cloud:" << m_connection->closeReason(); setConnected(false); + m_pingTimer->stop(); m_reconnectionTimer->start(10000); } @@ -156,9 +165,30 @@ void CloudConnection::onError(const QAbstractSocket::SocketError &error) if (!m_reconnectionTimer->isActive()) qCWarning(dcCloud()) << "Websocket error:" << error << m_connection->errorString(); + m_connection->close(); m_error = Cloud::CloudErrorProxyServerNotReachable; + m_pingTimer->start(); m_reconnectionTimer->start(10000); - setConnected(false); +} + +void CloudConnection::onPingTimeout() +{ + if (!connected()) + return; + + m_connection->ping("Ping"); +} + +void CloudConnection::onPong(const quint64 elapsedTime, const QByteArray &payload) +{ + Q_UNUSED(elapsedTime); + Q_UNUSED(payload); + //qCDebug(dcCloud()) << payload << elapsedTime; +} + +void CloudConnection::onStateChanged(const QAbstractSocket::SocketState &state) +{ + qCDebug(dcCloud()) << "Socket:" << state; } void CloudConnection::reconnectionTimeout() diff --git a/server/cloud/cloudconnection.h b/server/cloud/cloudconnection.h index a641393d..b6b7d64e 100644 --- a/server/cloud/cloudconnection.h +++ b/server/cloud/cloudconnection.h @@ -66,6 +66,7 @@ private: CloudConnectionError m_error; QTimer *m_reconnectionTimer; + QTimer *m_pingTimer; QUrl m_proxyUrl; QUrl m_keystoneUrl; @@ -88,7 +89,9 @@ private slots: void onConnected(); void onDisconnected(); void onError(const QAbstractSocket::SocketError &error); - void onTextMessageReceived(const QString &message); + void onStateChanged(const QAbstractSocket::SocketState &state); + void onPingTimeout(); + void onPong(const quint64 elapsedTime, const QByteArray &payload); void reconnectionTimeout(); diff --git a/server/cloud/cloudmanager.cpp b/server/cloud/cloudmanager.cpp index ad95effa..b22f33ce 100644 --- a/server/cloud/cloudmanager.cpp +++ b/server/cloud/cloudmanager.cpp @@ -137,6 +137,10 @@ void CloudManager::onTunnelRemoved(const QUuid &tunnelId) QUuid clientId = m_tunnelClients.key(tunnelId); m_tunnelClients.remove(clientId); emit clientDisconnected(clientId); + if (m_tunnelClients.isEmpty()) { + qCDebug(dcCloud()) << "Remote connection inactive."; + setActive(false); + } } } @@ -181,7 +185,27 @@ void CloudManager::onConnectedChanged() // Start authentication if connected if (m_cloudConnection->connected()) { m_interface->authenticateConnection(m_cloudConnection->authenticator()->token()); - emit connectedChanged(); + } else { + qCDebug(dcCloud()) << "Disconnected"; + // Reset information + setAuthenticated(false); + setActive(false); + m_connectionId = QUuid(); + + if (m_runningAuthentication) { + m_runningAuthentication = false; + emit authenticationFinished(m_cloudConnection->error()); + } + + // Clean up all tunnels + foreach (const QUuid &clientId, m_tunnelClients.keys()) { + emit clientDisconnected(clientId); + } + m_tunnelClients.clear(); + + // Delete all replies + qDeleteAll(m_replies.values()); + m_replies.clear(); } }