...
 
Commits (2)
QT -= gui
QT += network multimedia sql
QT += network multimedia sql serialport
CONFIG += c++11 console
CONFIG -= app_bundle
TARGET = ScStwBasestation
VERSION = 0.8.6
VERSION = 0.8.7
# add version to defined
DEFINES += APP_VERSION=\"\\\"$${VERSION}\\\"\"
......@@ -30,6 +30,7 @@ QT_MESSAGE_PATTERN=[%{type}] %{appname} (%{file}:%{line}) - %{message}
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
sources/serialhandler.cpp \
sources/athleteprofiles.cpp \
sources/main.cpp \
sources/mainactivity.cpp \
......@@ -46,7 +47,8 @@ HEADERS += \
headers/extensionconn.h \
headers/speedtimer.h \
headers/appsettings.h \
headers/audioplayer.h
headers/audioplayer.h \
headers/serialhandler.h
RESOURCES += \
resources/shared.qrc
......
......@@ -22,7 +22,12 @@ public:
QString qrcToNormalFile(QString file);
QVariantMap getLocalWiFiConf();
bool setLocalWiFiConf(QString ssid, QString pwd);
private:
QSettings *settingsManager;
QSettings *wifiSettingsManager;
signals:
......
......@@ -17,6 +17,7 @@
#include "appsettings.h"
#include "audioplayer.h"
#include "athleteprofiles.h"
#include "serialhandler.h"
#ifdef RASPI
#include "wiringPi.h"
......@@ -78,6 +79,8 @@ private:
QList<SpeedTimer*> timerEnableQueque;
SerialHandler * serialHandler;
// sounds
// for 'ready' and 'at your marks'
AudioPlayer * commandPlayer;
......
#ifndef SERIALHANDLER_H
#define SERIALHANDLER_H
#include <QObject>
#include <QDebug>
#include <QEventLoop>
#include <QFile>
#include <QSettings>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTimer>
#include "appsettings.h"
class SerialHandler : public QObject
{
Q_OBJECT
public:
explicit SerialHandler(QObject *parent = nullptr);
private:
QSerialPort * serialPort;
QByteArray readBuffer;
QString lastWriteReply;
signals:
void readSomeData(QString data);
public slots:
void updateESPs();
bool connectToPort(QString portName, qint32 baudRate);
void closeConnectionToPort();
void readData();
int updateWifiCreds(QString WiFiSSID, QString WiFiPWD);
};
#endif // SERIALHANDLER_H
......@@ -307,6 +307,16 @@
"desc": "long string containing the version, new binary as base64 and an official signature of Itsblue Development",
"def": "<VER>major.minor.patch</VER><BIN>###updated binary as base64###</BIN>-SIGN-###signature###-SIGN-"
}
},
"5001": {
"desc": "update time",
"requestData": {
"type": "int",
"dev": "currentSecsSinceEpoch = UNIX timestamp"
}
},
"5002": {
"desc": "pair all extensions, that are currently connected via usb"
}
},
......
......@@ -26,6 +26,7 @@ AppSettings::AppSettings(QObject* parent)
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
this->settingsManager = new QSettings(path+"/settings.ini", QSettings::IniFormat);
this->wifiSettingsManager = new QSettings("/etc/hostapd/hostapd.conf", QSettings::IniFormat);
this->setDefaultSetting("ready_en", "false");
this->setDefaultSetting("ready_delay", 0);
......@@ -113,3 +114,21 @@ QString AppSettings::qrcToNormalFile(QString file){
return s;
}
QVariantMap AppSettings::getLocalWiFiConf() {
return {{"ssid", this->wifiSettingsManager->value("ssid")}, {"pwd", this->wifiSettingsManager->value("wpa_passphrase")}};
}
bool AppSettings::setLocalWiFiConf(QString ssid, QString pwd) {
QStringList invalidSubstrings = {"<ssid>", "</ssid>", "<pwd>", "</pwd>"};
foreach(QString invalidSubstring, invalidSubstrings) {
if(ssid.contains(invalidSubstring) || pwd.contains(invalidSubstring)) {
return false;
}
}
this->wifiSettingsManager->setValue("ssid", ssid);
this->wifiSettingsManager->setValue("wpa_passphrase", pwd);
return true;
}
......@@ -17,6 +17,8 @@ MainActivity::MainActivity(QObject *parent) : QObject(parent)
this->date = new QDateTime;
this->serialHandler = new SerialHandler;
// configure athlete profile manager
this->athleteProfiles = new AthleteProfiles;
......@@ -724,6 +726,8 @@ void MainActivity::handleSocketCommand(SocketServer::socketClient *socketClient,
}
case 5000: {
// firmware update
if(this->state != IDLE){
replyHeader = 900;
break;
......@@ -797,8 +801,48 @@ void MainActivity::handleSocketCommand(SocketServer::socketClient *socketClient,
return;
}
case 5001: {
// update system time
if(requestData.toInt() < 1546300800) {
replyHeader = 406;
break;
}
QProcess timeSetProcess;
// set the system time
QString timeCommand = "sudo date +%s -s @" + QString::number(requestData.toInt());
timeSetProcess.start(timeCommand);
timeSetProcess.waitForFinished();
if(timeSetProcess.exitStatus() != QProcess::NormalExit) {
replyHeader = 500;
break;
}
// set the hardwareclock
timeCommand = "sudo hwclock -w";
timeSetProcess.start(timeCommand);
timeSetProcess.waitForFinished();
if(timeSetProcess.exitStatus() != QProcess::NormalExit) {
replyHeader = 500;
break;
}
replyHeader = 200;
break;
}
case 5002: {
// pair connected extensions
this->serialHandler->updateESPs();
replyHeader = 200;
break;
}
default:
// not found
replyHeader = 404;
break;
}
......
#include "../headers/serialhandler.h"
SerialHandler::SerialHandler(QObject *parent) : QObject(parent)
{
this->serialPort = new QSerialPort(this);
}
void SerialHandler::updateESPs()
{
QList<QSerialPortInfo> infos = QSerialPortInfo::availablePorts();
foreach (QSerialPortInfo info, infos) {
if(info.portName().startsWith("ttyUSB") && !info.isBusy()) {
// try to update a potential ESP
if(!this->connectToPort(info.portName(), QSerialPort::Baud115200))
continue;
qDebug() << "[SerialHandler][INFO] trying to update device on port: " << info.portName();
// read the local hostapd config
int res = this->updateWifiCreds(pGlobalAppSettings->getLocalWiFiConf()["ssid"].toString(), pGlobalAppSettings->getLocalWiFiConf()["pwd"].toString());
qDebug() << "[SerialHandler][INFO] finished: " << (res == 200 ? "updated successfully" : res == 302 ? "unchanged" : "error");
this->closeConnectionToPort();
}
}
}
bool SerialHandler::connectToPort(QString portName, qint32 baudRate) {
serialPort->setPortName(portName);
serialPort->setBaudRate(baudRate);
serialPort->setDataBits(QSerialPort::Data8);
serialPort->setParity(QSerialPort::NoParity);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setFlowControl(QSerialPort::NoFlowControl);
connect(serialPort, &QSerialPort::readyRead, this, &SerialHandler::readData);
if(serialPort->open(QSerialPort::ReadWrite)) {
serialPort->setDataTerminalReady(true);
serialPort->setRequestToSend(true);
return true;
}
else {
return false;
}
}
void SerialHandler::closeConnectionToPort() {
serialPort->close();
disconnect(serialPort, &QSerialPort::readyRead, this, &SerialHandler::readData);
}
void SerialHandler::readData()
{
// read all available data
QByteArray data = serialPort->readAll();
this->readBuffer.append(data);
// process recieved data (split by rows)
if(data.contains("\n")) {
QString readData = "";
foreach(const char byte, this->readBuffer) {
readData.append(byte);
}
QStringList dataLines = readData.split("\r\n");
if(readBuffer.endsWith("\r\n")) {
this->readBuffer.clear();
}
else {
this->readBuffer = dataLines[dataLines.length()-1].toLatin1();
dataLines.takeLast();
}
foreach (QString dataLine, dataLines) {
if(!dataLine.isEmpty()) {
emit this->readSomeData(dataLine);
}
}
}
}
int SerialHandler::updateWifiCreds(QString WiFiSSID, QString WiFiPWD) {
if(WiFiSSID.contains("<ssid>") || WiFiSSID.contains("</ssid>") || WiFiPWD.contains("<pwd>") || WiFiPWD.contains("</pwd>")){
// input has wrong format
return 401;
}
// write the command
QString updateCommand = "SetWifiConf=<ssid>" + WiFiSSID + "</ssid>:<pwd>" + WiFiPWD + "</pwd>\n";
qint64 written = serialPort->write(updateCommand.toLatin1());
serialPort->waitForBytesWritten();
if(written != updateCommand.size()) {
// some write error
return false;
}
// wait for a reply
QString reply = "ERR444";
QEventLoop loop;
QTimer timeoutTimer;
connect(this, &SerialHandler::readSomeData, &loop, [&loop, &reply](QString thisReply){
reply = thisReply;
loop.quit();
});
timeoutTimer.singleShot(3000, &loop, &QEventLoop::quit);
loop.exec();
// extract status code
reply = reply.right(3);
return reply.toInt();
}
This diff is collapsed.