summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--basicsuite/basicsuite.pro6
-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
-rw-r--r--basicsuite/demos.xml2
-rw-r--r--basicsuite/ebike-ui/datamodelplugin/plugin.cpp3
17 files changed, 1479 insertions, 2 deletions
diff --git a/basicsuite/basicsuite.pro b/basicsuite/basicsuite.pro
index b943f4c..e64894b 100644
--- a/basicsuite/basicsuite.pro
+++ b/basicsuite/basicsuite.pro
@@ -9,3 +9,9 @@ qtHaveModule(multimedia) {
SUBDIRS += \
camera
}
+
+qtHaveModule(charts) {
+ SUBDIRS += \
+ ebike-ui \
+ datacollector
+}
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
diff --git a/basicsuite/demos.xml b/basicsuite/demos.xml
index 2c79f1a..91b7ad9 100644
--- a/basicsuite/demos.xml
+++ b/basicsuite/demos.xml
@@ -93,7 +93,6 @@ Qt for Device Creation comes with Qt Virtual Keyboard - a framework that consist
</description>
</application>
-<!--
<application title="E-Bike" location="/data/user/qt/ebike-ui" main="main.qml" icon="/data/user/qt/ebike-ui/preview_l.jpg">
<description>
An E-bike instrument cluster concept designed and implemented by Qt.
@@ -101,7 +100,6 @@ An E-bike instrument cluster concept designed and implemented by Qt.
The entire concept is a testament that Qt brings the HMI designers and Software engineers together by using the same tools, allowing them to fast prototyping through collaborative workflow. In addition to that, Qt is optimized for running on low end SoC even the ones that don't have GPU acceleration for graphics.
</description>
</application>
--->
<application title="Quick Controls 2" location="/data/user/qt/qtquickcontrols2" main="main.qml" icon="/data/user/qt/qtquickcontrols2/preview_l.jpg">
<description>
diff --git a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp
index a07e4e6..098a6a8 100644
--- a/basicsuite/ebike-ui/datamodelplugin/plugin.cpp
+++ b/basicsuite/ebike-ui/datamodelplugin/plugin.cpp
@@ -72,11 +72,14 @@ public:
void registerTypes(const char *uri)
{
+ Q_UNUSED(uri);
qmlRegisterType<DataStore>("DataStore", 1, 0, "DataStore");
}
void initializeEngine(QQmlEngine *engine, const char *uri)
{
+ Q_UNUSED(uri);
+
// Setup data store for connection to backend server
DataStore *datastore = new DataStore(engine);
datastore->connectToServer("datasocket");