summaryrefslogtreecommitdiffstats
path: root/basicsuite/datacollector
diff options
context:
space:
mode:
Diffstat (limited to 'basicsuite/datacollector')
-rw-r--r--basicsuite/datacollector/abstractdatasource.cpp42
-rw-r--r--basicsuite/datacollector/abstractdatasource.h71
-rw-r--r--basicsuite/datacollector/datacollector.pro50
-rw-r--r--basicsuite/datacollector/main.cpp63
-rw-r--r--basicsuite/datacollector/mockdatasource.cpp236
-rw-r--r--basicsuite/datacollector/mockdatasource.h90
-rw-r--r--basicsuite/datacollector/socketclient.cpp89
-rw-r--r--basicsuite/datacollector/socketclient.h72
-rw-r--r--basicsuite/datacollector/socketserver.cpp94
-rw-r--r--basicsuite/datacollector/socketserver.h69
-rw-r--r--basicsuite/datacollector/tripdata.cpp253
-rw-r--r--basicsuite/datacollector/tripdata.h115
-rw-r--r--basicsuite/datacollector/unixsignalhandler.cpp149
-rw-r--r--basicsuite/datacollector/unixsignalhandler.h77
14 files changed, 1470 insertions, 0 deletions
diff --git a/basicsuite/datacollector/abstractdatasource.cpp b/basicsuite/datacollector/abstractdatasource.cpp
new file mode 100644
index 0000000..e7e7aa3
--- /dev/null
+++ b/basicsuite/datacollector/abstractdatasource.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractdatasource.h"
+
+AbstractDataSource::AbstractDataSource(QObject *parent)
+ : QObject(parent)
+{
+}
diff --git a/basicsuite/datacollector/abstractdatasource.h b/basicsuite/datacollector/abstractdatasource.h
new file mode 100644
index 0000000..3fc0e1b
--- /dev/null
+++ b/basicsuite/datacollector/abstractdatasource.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTDATASOURCE_H
+#define ABSTRACTDATASOURCE_H
+
+#include <QObject>
+#include <QJsonObject>
+
+class AbstractDataSource : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit AbstractDataSource(QObject *parent = nullptr);
+ virtual ~AbstractDataSource() {}
+
+public:
+ virtual void setSpeed(double speed)=0;
+ virtual void setTopSpeed(double topSpeed)=0;
+ virtual void setAverageSpeed(double averageSpeed)=0;
+ virtual void setLifetime(double lifetime)=0;
+ virtual void setOdometer(double odometer)=0;
+ virtual void setCalories(double calories)=0;
+ virtual void setBatteryLevel(int batteryLevel)=0;
+ virtual void setAssistDistance(int assistdistance)=0;
+ virtual void setAssistPower(int assistpower)=0;
+ virtual void setCurrentTrip(const QJsonObject &current)=0;
+
+signals:
+ void dataUpdate(const QJsonObject &update);
+
+public slots:
+ virtual void parseMessage(const QJsonObject &message)=0;
+ virtual void shutdown()=0;
+};
+
+#endif // ABSTRACTDATASOURCE_H
diff --git a/basicsuite/datacollector/datacollector.pro b/basicsuite/datacollector/datacollector.pro
new file mode 100644
index 0000000..a01e690
--- /dev/null
+++ b/basicsuite/datacollector/datacollector.pro
@@ -0,0 +1,50 @@
+QT -= gui
+QT += network
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+QMAKE_CXXFLAGS += -Os
+
+if(linux*imx7*g++) {
+ message("Building for IMX7")
+
+ #Use FLTO for better size, other for better speed
+ #(both needs to be used with proper Qt libs)
+
+ if(linux-ffopt-imx7-g++) {
+ }
+ else {
+ DEFINES += USE_FLTO
+ }
+
+ contains(DEFINES,USE_FLTO) {
+ message("Building with FLTO")
+ QMAKE_CXXFLAGS += -flto
+ QMAKE_LFLAGS += -flto
+ } else {
+ message("Building with Sections Optimization")
+ QMAKE_CXXFLAGS += -ffunction-sections -fdata-sections
+ QMAKE_LFLAGS += -Wl,--gc-sections
+ #QMAKE_LFLAGS += -Wl,--print-gc-sections
+ }
+}
+
+SOURCES += main.cpp \
+ socketserver.cpp \
+ socketclient.cpp \
+ abstractdatasource.cpp \
+ mockdatasource.cpp \
+ tripdata.cpp \
+ unixsignalhandler.cpp
+
+HEADERS += \
+ socketserver.h \
+ socketclient.h \
+ abstractdatasource.h \
+ mockdatasource.h \
+ tripdata.h \
+ unixsignalhandler.h
+
+target.path += /data/user/qt/$$TARGET
+INSTALLS += target
diff --git a/basicsuite/datacollector/main.cpp b/basicsuite/datacollector/main.cpp
new file mode 100644
index 0000000..438abbb
--- /dev/null
+++ b/basicsuite/datacollector/main.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+
+#include "socketserver.h"
+#include "mockdatasource.h"
+#include "unixsignalhandler.h"
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ SocketServer* server = new SocketServer(&app);
+ AbstractDataSource* ds = new MockDataSource(&app);
+ UnixSignalHandler* handler = new UnixSignalHandler(&app);
+
+ QObject::connect(ds, &AbstractDataSource::dataUpdate,
+ server, static_cast<void (SocketServer::*)(const QJsonObject&)>(&SocketServer::sendToClients));
+ QObject::connect(server, &SocketServer::clientMessage,
+ ds, &AbstractDataSource::parseMessage);
+ QObject::connect(handler, &UnixSignalHandler::sigInt,
+ ds, &AbstractDataSource::shutdown);
+ QObject::connect(handler, &UnixSignalHandler::sigInt,
+ &app, &QCoreApplication::quit);
+
+ UnixSignalHandler::setupSignalHandlers();
+
+ return app.exec();
+}
diff --git a/basicsuite/datacollector/mockdatasource.cpp b/basicsuite/datacollector/mockdatasource.cpp
new file mode 100644
index 0000000..1932ce3
--- /dev/null
+++ b/basicsuite/datacollector/mockdatasource.cpp
@@ -0,0 +1,236 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QDir>
+#include <cmath>
+
+#include "mockdatasource.h"
+
+static const char currentTripFilename[] = "currenttrip.bson";
+static const char tripDataFilename[] = "tripdata.bson";
+static const char statisticsFilename[] = "stats.bson";
+
+MockDataSource::MockDataSource(QObject *parent)
+ : AbstractDataSource(parent)
+{
+ connect(&m_updateTimer, &QTimer::timeout, this, &MockDataSource::generateData);
+
+ QDir dir(QCoreApplication::applicationDirPath());
+
+ // Load current status
+ m_dataFile = dir.absoluteFilePath(statisticsFilename);
+ QFile dataFile(m_dataFile);
+ if (dataFile.open(QIODevice::ReadOnly)) {
+ QJsonDocument doc = QJsonDocument::fromBinaryData(dataFile.readAll());
+ m_data = doc.object();
+ m_lifetime = m_data.value("lifetime").toDouble();
+ } else {
+ // Set some default values in case data file did not exist
+ m_data.insert("speed", 0.0);
+ m_data.insert("topspeed", 0.0);
+ m_data.insert("odometer", 0.0);
+ m_data.insert("batterylevel", 100);
+ m_lifetime = 0.0;
+ }
+
+ // Try to load current trip data as well as recorded trip(s)
+ m_currentFile = dir.absoluteFilePath(currentTripFilename);
+ m_current.load(m_currentFile);
+ m_tripsFile = dir.absoluteFilePath(tripDataFilename);
+ m_trips.load(m_tripsFile);
+
+ m_updateTimer.start(100);
+ m_elapsedTimer.start();
+
+ // Generate the list of static trips to be shown on reset
+ m_resettrips << TripData(2100, 6800, 225, 6.944, 3.2, 1515008400.0) // 3.1.2018 11:40
+ << TripData(2700, 10700, 300, 8.333, 2.5, 1515122400.0) // 4.1.2018 19:20
+ << TripData(3900, 13700, 370, 6.944, 5, 1515197100.0) // 5.1.2018 16:05
+ << TripData(1500, 3300, 150, 6.944, 4.7, 1515260100.0) // 6.1.2018 9:35
+ << TripData(4500, 15800, 450, 5.556, 3.2, 1515359700.0); // 7.1.2018 13:15
+}
+
+void MockDataSource::shutdown()
+{
+ m_current.save(m_currentFile);
+ m_trips.save(m_tripsFile);
+}
+
+void MockDataSource::setSpeed(double speed)
+{
+ updateOne("speed", speed);
+}
+
+void MockDataSource::setTopSpeed(double topspeed)
+{
+ updateOne("topspeed", topspeed);
+}
+
+void MockDataSource::setAverageSpeed(double averagespeed)
+{
+ updateOne("averagespeed", averagespeed);
+}
+
+void MockDataSource::setLifetime(double lifetime)
+{
+ updateOne("lifetime", lifetime);
+}
+
+void MockDataSource::setOdometer(double odometer)
+{
+ updateOne("odometer", odometer);
+}
+
+void MockDataSource::setCalories(double calories)
+{
+ updateOne("calories", calories);
+}
+
+void MockDataSource::setBatteryLevel(int batterylevel)
+{
+ updateOne("batterylevel", batterylevel);
+}
+
+void MockDataSource::setAssistDistance(int assistdistance)
+{
+ updateOne("assistdistance", assistdistance);
+}
+
+void MockDataSource::setAssistPower(int assistpower)
+{
+ updateOne("assistpower", assistpower);
+}
+
+void MockDataSource::setCurrentTrip(const QJsonObject &current)
+{
+ emit dataUpdate(QJsonObject{{"method", "currenttrip"}, {"currenttrip", current}});
+}
+
+void MockDataSource::updateOne(const QString &key, const QJsonValue &value)
+{
+ m_data.insert(key, value);
+ emit dataUpdate(QJsonObject{{"method", "updateone"}, {"key", key}, {"value", value}});
+}
+
+void MockDataSource::generateData()
+{
+ static int spd = 1;
+ static int btr = 101;
+
+ double x = static_cast<double>(spd) / 500;
+ double speed = 4.5 * (1.5 + (0.75 * sin(2 * M_PI * x) + 0.5 * sin(6 * M_PI * x - M_PI_2))) - 1.5;
+ double dist = speed / 10; // 10 times per second
+ double elapsed = static_cast<double>(m_elapsedTimer.elapsed()) / 1000.0;
+
+ setAssistPower(speed * 9.5);
+ setSpeed(speed);
+ if (speed > m_data.value("topspeed").toDouble())
+ setTopSpeed(speed);
+ setAverageSpeed(m_data.value("odometer").toDouble() / (m_lifetime + elapsed));
+ setOdometer(m_data.value("odometer").toDouble() + dist);
+ setLifetime(m_lifetime + elapsed);
+
+ // Update trip data
+ if (speed > m_current.maxSpeed())
+ m_current.setMaxSpeed(speed);
+ m_current.addDistance(dist);
+ m_current.addDuration(0.1);
+ m_current.addCalories(0.01);
+
+ setCurrentTrip(m_current);
+
+ if (spd % 50 == 0) {
+ btr -= 1;
+ setBatteryLevel(btr);
+ setAssistDistance(500 * btr);
+ if (btr == 0)
+ btr = 100;
+ }
+
+ // Save the current trip and statistics files every 10 seconds
+ if (spd % 100 == 0) {
+ m_current.save(m_currentFile);
+ QFile dataFile(m_dataFile);
+ if (dataFile.open(QIODevice::WriteOnly)) {
+ QJsonDocument doc(m_data);
+ dataFile.write(doc.toBinaryData());
+ }
+ }
+
+ spd++;
+}
+
+void MockDataSource::parseMessage(const QJsonObject &message)
+{
+ QString method = message.value("method").toString();
+
+ if (method == "set") {
+ m_data.insert(message.value("key").toString(), message.value("value"));
+ } else if (method == "getall") {
+ QJsonArray values;
+ // Iterate over all data
+ QJsonObject::ConstIterator it = m_data.constBegin();
+ while (it != m_data.constEnd()) {
+ values.append(QJsonObject{{"key", it.key()}, {"value", it.value()}});
+ ++it;
+ }
+
+ emit dataUpdate(QJsonObject{{"method", "updatemany"}, {"values", values}});
+ setCurrentTrip(m_current);
+ } else if (method == "gettrips") {
+ emit dataUpdate(QJsonObject{{"method", "trips"}, {"trips", m_trips.toJsonArray()}});
+ } else if (method == "endtrip") {
+ // Append current trip to list of trips and send to frontend
+ m_trips.append(m_current);
+ emit dataUpdate(QJsonObject{{"method", "trip"}, {"trip", m_current.toJsonObject()}});
+ // Then clear it and its save file
+ m_current.clear();
+ m_current.setStartTime();
+ QFile::remove(m_currentFile);
+ // Send update of an empty trip to frontend
+ setCurrentTrip(m_current);
+ // Also save current trip list to file (in case of a crash)
+ m_trips.save(m_tripsFile);
+ } else if (method == "reset") {
+ // Demo only method, to reset trip history
+ m_trips = m_resettrips;
+ emit dataUpdate(QJsonObject{{"method", "reset"}});
+ emit dataUpdate(QJsonObject{{"method", "trips"}, {"trips", m_trips.toJsonArray()}});
+ }
+}
diff --git a/basicsuite/datacollector/mockdatasource.h b/basicsuite/datacollector/mockdatasource.h
new file mode 100644
index 0000000..fe82e19
--- /dev/null
+++ b/basicsuite/datacollector/mockdatasource.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOCKDATASOURCE_H
+#define MOCKDATASOURCE_H
+
+#include <QObject>
+#include <QTimer>
+#include <QElapsedTimer>
+#include "abstractdatasource.h"
+#include "tripdata.h"
+
+class MockDataSource: public AbstractDataSource
+{
+ Q_OBJECT
+
+public:
+ explicit MockDataSource(QObject *parent = nullptr);
+
+public:
+ void setSpeed(double speed);
+ void setTopSpeed(double topSpeed);
+ void setAverageSpeed(double averageSpeed);
+ void setLifetime(double lifetime);
+ void setOdometer(double odometer);
+ void setTrip(double trip);
+ void setCalories(double calories);
+ void setBatteryLevel(int batteryLevel);
+ void setAssistDistance(int assistdistance);
+ void setAssistPower(int assistpower);
+ void setCurrentTrip(const QJsonObject &current);
+
+public slots:
+ void parseMessage(const QJsonObject &message);
+ void shutdown();
+
+private:
+ void updateOne(const QString &key, const QJsonValue &value);
+
+private slots:
+ void generateData();
+
+private:
+ QTimer m_updateTimer;
+ QElapsedTimer m_elapsedTimer;
+ double m_lifetime;
+
+ QJsonObject m_data;
+ QString m_dataFile;
+ TripData m_current;
+ Trips m_trips;
+ Trips m_resettrips;
+ QString m_currentFile;
+ QString m_tripsFile;
+};
+
+#endif // MOCKDATASOURCE_H
diff --git a/basicsuite/datacollector/socketclient.cpp b/basicsuite/datacollector/socketclient.cpp
new file mode 100644
index 0000000..a17f3dc
--- /dev/null
+++ b/basicsuite/datacollector/socketclient.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDataStream>
+#include <QJsonDocument>
+#include <QJsonObject>
+
+#include "socketclient.h"
+
+SocketClient::SocketClient(QLocalSocket *socket, QObject *parent)
+ : QObject(parent)
+ , m_socket(socket)
+{
+ // Connect socket signals
+ connect(m_socket, &QLocalSocket::connected, this, &SocketClient::connected);
+ connect(m_socket, &QLocalSocket::disconnected, this, &SocketClient::disconnected);
+ connect(m_socket, &QLocalSocket::readyRead, this, &SocketClient::readyRead);
+}
+
+qint64 SocketClient::write(const QByteArray &data) {
+ return m_socket->write(data);
+}
+
+void SocketClient::readyRead() {
+ m_data += m_socket->readAll();
+
+ bool messagefound = true;
+ while (messagefound) {
+ messagefound = false;
+ // If we have at least some data
+ if (m_data.size() >= 4) {
+ // Extract message size
+ qint32 messagesize;
+ QDataStream stream(m_data.left(4));
+ stream >> messagesize;
+
+ // If we have enough data for at least one message
+ if (m_data.size() >= messagesize) {
+ // Extract actual message
+ QByteArray message = m_data.mid(4, messagesize - 4);
+ parseMessage(message);
+ // Drop necessary amount of bytes
+ m_data = m_data.mid(messagesize);
+ messagefound = true; // Try to parse another message
+ }
+ }
+ }
+}
+
+void SocketClient::parseMessage(const QByteArray &message) {
+ // Parse message from raw format
+ QJsonDocument doc = QJsonDocument::fromBinaryData(message);
+ QJsonObject obj = doc.object();
+
+ emit clientMessage(obj);
+}
diff --git a/basicsuite/datacollector/socketclient.h b/basicsuite/datacollector/socketclient.h
new file mode 100644
index 0000000..c489fd5
--- /dev/null
+++ b/basicsuite/datacollector/socketclient.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SOCKETCLIENT_H
+#define SOCKETCLIENT_H
+
+#include <QObject>
+#include <QLocalSocket>
+
+class SocketClient : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit SocketClient(QLocalSocket *socket, QObject *parent = nullptr);
+
+public:
+ QLocalSocket *socket(void) const { return m_socket; }
+ qint64 write(const QByteArray& data);
+
+private:
+ void parseMessage(const QByteArray& message);
+
+signals:
+ void connected();
+ void disconnected();
+ void clientMessage(const QJsonObject &message);
+
+public slots:
+
+private slots:
+ void readyRead();
+
+private:
+ QLocalSocket *m_socket;
+ QByteArray m_data;
+};
+
+#endif // SOCKETCLIENT_H
diff --git a/basicsuite/datacollector/socketserver.cpp b/basicsuite/datacollector/socketserver.cpp
new file mode 100644
index 0000000..9391316
--- /dev/null
+++ b/basicsuite/datacollector/socketserver.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QLocalServer>
+#include <QJsonDocument>
+#include <QDataStream>
+
+#include "socketserver.h"
+#include "socketclient.h"
+
+SocketServer::SocketServer(QObject *parent)
+ : QObject(parent)
+ , m_server(new QLocalServer(this))
+{
+ connect(m_server, &QLocalServer::newConnection, this, &SocketServer::processConnected);
+ QLocalServer::removeServer("datasocket");
+ m_server->listen("datasocket");
+}
+
+void SocketServer::processConnected(void) {
+ while (m_server->hasPendingConnections()) {
+ QLocalSocket* socket = m_server->nextPendingConnection();
+ qDebug() << "Client connected" << socket;
+ if (socket) {
+ SocketClient *client = new SocketClient(socket, this);
+ connect(client, &SocketClient::disconnected, this, &SocketServer::processDisconnected);
+ connect(client, &SocketClient::clientMessage, this, &SocketServer::clientMessage);
+ m_clients.append(client);
+ }
+ }
+}
+
+void SocketServer::processDisconnected(void) {
+ SocketClient *client = qobject_cast<SocketClient*>(sender());
+ qDebug() << "Client disconnected" << client->socket();
+ m_clients.removeOne(client);
+ client->deleteLater();
+}
+
+void SocketServer::sendToClients(const QByteArray &message) {
+ // Prepend the message length
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+ stream << static_cast<qint32>(message.size() + 4);
+ data.append(message);
+
+ foreach (SocketClient *client, m_clients) {
+ client->write(data);
+ }
+}
+
+/**
+ * @brief sendToClients
+ * @param message
+ *
+ * Converts a JSON object to its binary representation and sends it to all clients
+ */
+void SocketServer::sendToClients(const QJsonObject &message) {
+ QJsonDocument doc(message);
+ sendToClients(doc.toBinaryData());
+}
diff --git a/basicsuite/datacollector/socketserver.h b/basicsuite/datacollector/socketserver.h
new file mode 100644
index 0000000..e48232c
--- /dev/null
+++ b/basicsuite/datacollector/socketserver.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SOCKETSERVER_H
+#define SOCKETSERVER_H
+
+#include <QObject>
+#include <QJsonObject>
+
+class QLocalServer;
+class SocketClient;
+
+class SocketServer: public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit SocketServer(QObject *parent = nullptr);
+
+signals:
+ void clientMessage(const QJsonObject &message);
+
+public slots:
+ void sendToClients(const QByteArray &message);
+ void sendToClients(const QJsonObject &message);
+
+private slots:
+ void processConnected();
+ void processDisconnected();
+
+private:
+ QLocalServer *m_server;
+ QList<SocketClient *> m_clients;
+};
+
+#endif // SOCKETSERVER_H
diff --git a/basicsuite/datacollector/tripdata.cpp b/basicsuite/datacollector/tripdata.cpp
new file mode 100644
index 0000000..7ce5590
--- /dev/null
+++ b/basicsuite/datacollector/tripdata.cpp
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QFile>
+#include <QDateTime>
+
+#include "tripdata.h"
+
+TripData::TripData()
+ : m_duration(0.0)
+ , m_distance(0.0)
+ , m_calories(0.0)
+ , m_maxspeed(0.0)
+ , m_ascent(0.0)
+ , m_starttime(static_cast<double>(QDateTime::currentMSecsSinceEpoch()) / 1000.0)
+{
+}
+
+TripData::TripData(double duration, double distance, double calories,
+ double maxspeed, double ascent, double starttime)
+ : m_duration(duration)
+ , m_distance(distance)
+ , m_calories(calories)
+ , m_maxspeed(maxspeed)
+ , m_ascent(ascent)
+ , m_starttime(starttime)
+{
+}
+
+TripData::TripData(const QJsonObject &data)
+ : m_duration(data.value("duration").toDouble())
+ , m_distance(data.value("distance").toDouble())
+ , m_calories(data.value("calories").toDouble())
+ , m_maxspeed(data.value("maxspeed").toDouble())
+ , m_ascent(data.value("ascent").toDouble())
+ , m_starttime(data.value("starttime").toDouble())
+{
+}
+
+bool TripData::load(const QString &filename)
+{
+ QFile jsonfile(filename);
+ if (jsonfile.open(QIODevice::ReadOnly)) {
+ QJsonDocument doc = QJsonDocument::fromBinaryData(jsonfile.readAll());
+ QJsonObject data = doc.object();
+
+ m_duration = data.value("duration").toDouble();
+ m_distance = data.value("distance").toDouble();
+ m_calories = data.value("calories").toDouble();
+ m_maxspeed = data.value("maxspeed").toDouble();
+ m_ascent = data.value("ascent").toDouble();
+ m_starttime = data.value("starttime").toDouble();
+
+ return true;
+ }
+ return false;
+}
+
+void TripData::save(const QString &filename) const
+{
+ QFile jsonfile(filename);
+ if (jsonfile.open(QIODevice::WriteOnly)) {
+ QJsonDocument doc(toJsonObject());
+ jsonfile.write(doc.toBinaryData());
+ }
+}
+
+void TripData::setDuration(double duration)
+{
+ if (qFuzzyCompare(m_duration, duration))
+ return;
+
+ m_duration = duration;
+}
+
+void TripData::setDistance(double distance)
+{
+ if (qFuzzyCompare(m_distance, distance))
+ return;
+
+ m_distance = distance;
+}
+
+void TripData::setCalories(double calories)
+{
+ if (qFuzzyCompare(m_calories, calories))
+ return;
+
+ m_calories = calories;
+}
+
+void TripData::setMaxSpeed(double maxspeed)
+{
+ if (qFuzzyCompare(m_maxspeed, maxspeed))
+ return;
+
+ m_maxspeed = maxspeed;
+}
+
+void TripData::setAscent(double ascent)
+{
+ if (qFuzzyCompare(m_ascent, ascent))
+ return;
+
+ m_ascent = ascent;
+}
+
+void TripData::setStartTime(double starttime)
+{
+ // Special value means reset to current timestamp
+ if (starttime == 0.0)
+ starttime = static_cast<double>(QDateTime::currentMSecsSinceEpoch()) / 1000.0;
+
+ if (qFuzzyCompare(m_starttime, starttime))
+ return;
+
+ m_starttime = starttime;
+}
+
+void TripData::addDuration(double duration)
+{
+ m_duration += duration;
+}
+
+void TripData::addDistance(double distance)
+{
+ m_distance += distance;
+}
+
+void TripData::addCalories(double calories)
+{
+ m_calories += calories;
+}
+
+void TripData::clear()
+{
+ m_duration = 0.0;
+ m_distance = 0.0;
+ m_calories = 0.0;
+ m_maxspeed = 0.0;
+ m_ascent = 0.0;
+ m_starttime = 0.0;
+}
+
+TripData::operator QJsonObject() const
+{
+ return toJsonObject();
+}
+
+const QJsonObject TripData::toJsonObject(void) const
+{
+ QJsonObject data;
+
+ data.insert("duration", m_duration);
+ data.insert("distance", m_distance);
+ data.insert("calories", m_calories);
+ data.insert("maxspeed", m_maxspeed);
+ data.insert("avgspeed", m_distance / m_duration);
+ data.insert("ascent", m_ascent);
+ data.insert("starttime", m_starttime);
+
+ return data;
+}
+
+TripData TripData::fromJsonObject(const QJsonObject &data)
+{
+ return TripData(data);
+}
+
+TripData TripData::fromFile(const QString &filename)
+{
+ TripData trip;
+ trip.load(filename);
+ return trip;
+}
+
+bool Trips::load(const QString &filename)
+{
+ QFile jsonfile(filename);
+ if (jsonfile.open(QIODevice::ReadOnly)) {
+ QJsonDocument doc = QJsonDocument::fromBinaryData(jsonfile.readAll());
+ clear();
+ foreach (const QJsonValue &trip, doc.array())
+ append(trip.toObject());
+ return true;
+ }
+ return false;
+}
+
+void Trips::save(const QString &filename) const
+{
+ QFile jsonfile(filename);
+ if (jsonfile.open(QIODevice::WriteOnly)) {
+ QJsonDocument doc(*this);
+ jsonfile.write(doc.toBinaryData());
+ }
+}
+
+Trips::operator QJsonArray() const
+{
+ return toJsonArray();
+}
+
+const QJsonArray Trips::toJsonArray() const
+{
+ QJsonArray array;
+ foreach (const TripData &data, *this)
+ array.append(data.toJsonObject());
+
+ return array;
+}
+
+Trips Trips::fromFile(const QString &filename)
+{
+ Trips trips;
+ trips.load(filename);
+ return trips;
+}
diff --git a/basicsuite/datacollector/tripdata.h b/basicsuite/datacollector/tripdata.h
new file mode 100644
index 0000000..36fd9c8
--- /dev/null
+++ b/basicsuite/datacollector/tripdata.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRIPDATA_H
+#define TRIPDATA_H
+
+#include <QElapsedTimer>
+#include <QJsonObject>
+#include <QList>
+
+class TripData
+{
+public:
+ TripData();
+ TripData(double duration, double distance, double calories,
+ double maxspeed, double ascent, double starttime);
+ TripData(const QJsonObject &data);
+
+public:
+ double duration() const { return m_duration; }
+ double distance() const { return m_distance; }
+ double calories() const { return m_calories; }
+ double maxSpeed() const { return m_maxspeed; }
+ double avgSpeed() const { return m_distance / m_duration; }
+ double ascent() const { return m_ascent; }
+ double startTime() const { return m_starttime; }
+
+ void setDuration(double duration);
+ void setDistance(double distance);
+ void setCalories(double calories);
+ void setMaxSpeed(double maxspeed);
+ void setAscent(double ascent);
+ void setStartTime(double starttime=0);
+ void addDuration(double duration);
+ void addDistance(double distance);
+ void addCalories(double calories);
+ void clear();
+
+ // Load from file
+ bool load(const QString &filename);
+
+ // Save to file
+ void save(const QString &filename) const;
+
+ // Convert to Json Object
+ operator QJsonObject() const;
+ const QJsonObject toJsonObject(void) const;
+
+ // Create from Json
+ static TripData fromJsonObject(const QJsonObject &data);
+
+ // Load from binary Json data
+ static TripData fromFile(const QString &filename);
+
+private:
+ QElapsedTimer m_timer;
+ double m_duration; // Seconds
+ double m_distance; // Meters
+ double m_calories; // calories, not kcal
+ double m_maxspeed; // m/s
+ double m_ascent; // meters
+ double m_starttime; // Timestamp of the start of the trip
+};
+
+class Trips: public QList<TripData>
+{
+public:
+ // Load from file
+ bool load(const QString &filename);
+
+ // Save to file
+ void save(const QString &filename) const;
+
+ // Convert to Json Array
+ operator QJsonArray() const;
+ const QJsonArray toJsonArray(void) const;
+
+ // Load from binary Json data
+ static Trips fromFile(const QString &filename);
+};
+
+#endif // TRIPDATA_H
diff --git a/basicsuite/datacollector/unixsignalhandler.cpp b/basicsuite/datacollector/unixsignalhandler.cpp
new file mode 100644
index 0000000..61fd87b
--- /dev/null
+++ b/basicsuite/datacollector/unixsignalhandler.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QSocketNotifier>
+#include <signal.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include "unixsignalhandler.h"
+
+int UnixSignalHandler::sigintFd[2] = {0};
+int UnixSignalHandler::sighupFd[2] = {0};
+int UnixSignalHandler::sigtermFd[2] = {0};
+
+UnixSignalHandler::UnixSignalHandler(QObject *parent)
+ : QObject(parent)
+{
+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigintFd))
+ qFatal("Couldn't create INT socketpair");
+
+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighupFd))
+ qFatal("Couldn't create HUP socketpair");
+
+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigtermFd))
+ qFatal("Couldn't create TERM socketpair");
+
+ m_sigintNotifier = new QSocketNotifier(sigintFd[1], QSocketNotifier::Read, this);
+ connect(m_sigintNotifier, &QSocketNotifier::activated,
+ this, &UnixSignalHandler::handleSigInt);
+ m_sighupNotifier = new QSocketNotifier(sighupFd[1], QSocketNotifier::Read, this);
+ connect(m_sighupNotifier, &QSocketNotifier::activated,
+ this, &UnixSignalHandler::handleSigHup);
+ m_sigtermNotifier = new QSocketNotifier(sigtermFd[1], QSocketNotifier::Read, this);
+ connect(m_sigtermNotifier, &QSocketNotifier::activated,
+ this, &UnixSignalHandler::handleSigTerm);
+}
+
+int UnixSignalHandler::setupSignalHandlers()
+{
+ struct sigaction sig_int, sig_hup, sig_term;
+
+ sig_int.sa_handler = UnixSignalHandler::sigIntHandler;
+ sigemptyset(&sig_int.sa_mask);
+ sig_int.sa_flags = 0;
+ sig_int.sa_flags |= SA_RESTART;
+
+ if (sigaction(SIGINT, &sig_int, 0))
+ return 1;
+
+ sig_hup.sa_handler = UnixSignalHandler::sigHupHandler;
+ sigemptyset(&sig_hup.sa_mask);
+ sig_hup.sa_flags = 0;
+ sig_hup.sa_flags |= SA_RESTART;
+
+ if (sigaction(SIGHUP, &sig_hup, 0))
+ return 2;
+
+ sig_term.sa_handler = UnixSignalHandler::sigTermHandler;
+ sigemptyset(&sig_term.sa_mask);
+ sig_term.sa_flags |= SA_RESTART;
+
+ if (sigaction(SIGTERM, &sig_term, 0))
+ return 3;
+
+ return 0;
+}
+
+void UnixSignalHandler::sigIntHandler(int)
+{
+ char a = 1;
+ ::write(sigintFd[0], &a, sizeof(a));
+}
+
+void UnixSignalHandler::sigHupHandler(int)
+{
+ char a = 1;
+ ::write(sighupFd[0], &a, sizeof(a));
+}
+
+void UnixSignalHandler::sigTermHandler(int)
+{
+ char a = 1;
+ ::write(sigtermFd[0], &a, sizeof(a));
+}
+
+void UnixSignalHandler::handleSigInt()
+{
+ m_sigintNotifier->setEnabled(false);
+ char tmp;
+ ::read(sigintFd[1], &tmp, sizeof(tmp));
+
+ emit sigInt();
+
+ m_sigintNotifier->setEnabled(true);
+}
+
+void UnixSignalHandler::handleSigHup()
+{
+ m_sighupNotifier->setEnabled(false);
+ char tmp;
+ ::read(sighupFd[1], &tmp, sizeof(tmp));
+
+ emit sigHup();
+
+ m_sighupNotifier->setEnabled(true);
+}
+
+void UnixSignalHandler::handleSigTerm()
+{
+ m_sigtermNotifier->setEnabled(false);
+ char tmp;
+ ::read(sigtermFd[1], &tmp, sizeof(tmp));
+
+ emit sigTerm();
+
+ m_sigtermNotifier->setEnabled(true);
+}
diff --git a/basicsuite/datacollector/unixsignalhandler.h b/basicsuite/datacollector/unixsignalhandler.h
new file mode 100644
index 0000000..63c5d53
--- /dev/null
+++ b/basicsuite/datacollector/unixsignalhandler.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the E-Bike demo project.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef UNIXSIGNALHANDLER_H
+#define UNIXSIGNALHANDLER_H
+
+#include <QObject>
+
+class QSocketNotifier;
+
+class UnixSignalHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit UnixSignalHandler(QObject *parent = nullptr);
+
+public:
+ static int setupSignalHandlers();
+ static void sigIntHandler(int);
+ static void sigHupHandler(int);
+ static void sigTermHandler(int);
+
+signals:
+ void sigInt();
+ void sigHup();
+ void sigTerm();
+
+private slots:
+ void handleSigInt();
+ void handleSigHup();
+ void handleSigTerm();
+
+private:
+ static int sigintFd[2];
+ static int sighupFd[2];
+ static int sigtermFd[2];
+
+ QSocketNotifier *m_sigintNotifier;
+ QSocketNotifier *m_sighupNotifier;
+ QSocketNotifier *m_sigtermNotifier;
+};
+
+#endif // UNIXSIGNALHANDLER_H