- major cleanup
- added global static class ScStw
This commit is contained in:
parent
d32fe7733a
commit
b752bdeed2
6 changed files with 391 additions and 194 deletions
4
ScStwLibraries/ScStw.cpp
Normal file
4
ScStwLibraries/ScStw.cpp
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include <ScStw.hpp>
|
||||
|
||||
const char *ScStw::SOCKET_MESSAGE_START_KEY = "<message>";
|
||||
const char *ScStw::SOCKET_MESSAGE_END_KEY = "</message>";
|
53
ScStwLibraries/ScStw.hpp
Normal file
53
ScStwLibraries/ScStw.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef SCSTW_HPP
|
||||
#define SCSTW_HPP
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class ScStw : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Some global enums
|
||||
*/
|
||||
|
||||
enum RaceState { IDLE, STARTING, WAITING, RUNNING, STOPPED };
|
||||
Q_ENUM(RaceState)
|
||||
|
||||
enum SignalKey {
|
||||
RaceStateChanged = 9000,
|
||||
TimersChanged = 9001,
|
||||
ExtensionsChanged = 9002,
|
||||
NextStartActionChanged = 9003 /*, ProfilesChanged*/
|
||||
};
|
||||
Q_ENUM(SignalKey)
|
||||
|
||||
enum NextStartAction { AtYourMarks, Ready, Start, None };
|
||||
Q_ENUM(NextStartAction)
|
||||
|
||||
enum BaseStationSetting {
|
||||
ReadySoundEnableSetting,
|
||||
ReadySoundDelaySetting,
|
||||
AtYourMarksSoundEnableSetting,
|
||||
AtYourMarksSoundDelaySetting,
|
||||
SoundVolumeSetting
|
||||
};
|
||||
Q_ENUM(BaseStationSetting)
|
||||
|
||||
enum ErrorCode {
|
||||
Success = 200,
|
||||
|
||||
Error = 900,
|
||||
NotConnectedError = 910,
|
||||
TimeoutError = 911,
|
||||
SettingNotAccessableError = 901
|
||||
};
|
||||
Q_ENUM(ErrorCode)
|
||||
|
||||
static const char* SOCKET_MESSAGE_START_KEY;
|
||||
static const char* SOCKET_MESSAGE_END_KEY;
|
||||
|
||||
private:
|
||||
ScStw() : QObject(nullptr) {};
|
||||
};
|
||||
|
||||
#endif // SCSTW_HPP
|
|
@ -18,9 +18,11 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
ScStw.cpp \
|
||||
scstwclient.cpp
|
||||
|
||||
HEADERS += \
|
||||
ScStw.hpp \
|
||||
ScStwLibraries_global.h \
|
||||
scstwclient.h
|
||||
|
||||
|
|
|
@ -9,13 +9,4 @@
|
|||
# define SCSTWLIBRARIES_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Some global enums
|
||||
*
|
||||
*/
|
||||
|
||||
enum raceState { IDLE, STARTING, WAITING, RUNNING, STOPPED };
|
||||
enum signalKey { RaceStateChanged, TimersChanged, ExtensionsChanged, NextStartActionChanged /*, ProfilesChanged*/ };
|
||||
enum nextStartAction { AtYourMarks, Ready, Start, None };
|
||||
|
||||
#endif // SCSTWCLIENT_GLOBAL_H
|
||||
|
|
|
@ -2,31 +2,36 @@
|
|||
|
||||
ScStwClient * pGlobalScStwClient = nullptr;
|
||||
|
||||
ScStwClient::ScStwClient(QObject *parent) : QObject(parent)
|
||||
ScStwClient::ScStwClient() : QObject(nullptr)
|
||||
{
|
||||
pGlobalScStwClient = this;
|
||||
this->state = DISCONNECTED;
|
||||
this->nextConnectionId = 1;
|
||||
this->connections = QVariantList({});
|
||||
|
||||
socket = new QTcpSocket(this);
|
||||
this->socket = new QTcpSocket(this);
|
||||
|
||||
this->timeoutTimer = new QTimer(this);
|
||||
this->timeoutTimer->setSingleShot(true);
|
||||
|
||||
this->state = "disconnected";
|
||||
connect(this->timeoutTimer, &QTimer::timeout,
|
||||
[=](){this->handleError(QAbstractSocket::ProxyConnectionTimeoutError);});
|
||||
|
||||
connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
this, SLOT(gotError(QAbstractSocket::SocketError)));
|
||||
this, SLOT(handleError(QAbstractSocket::SocketError)));
|
||||
|
||||
connect(this->socket, &QAbstractSocket::stateChanged, this, &ScStwClient::socketStateChanged);
|
||||
connect(this->socket, &QAbstractSocket::stateChanged,
|
||||
this, &ScStwClient::handleSocketStateChange);
|
||||
|
||||
this->nextConnectionId = 1;
|
||||
this->connections = QVariantList({});
|
||||
connect(this->socket, &QTcpSocket::readyRead,
|
||||
this, &ScStwClient::handleReadyRead);
|
||||
|
||||
|
||||
pGlobalScStwClient = this;
|
||||
}
|
||||
|
||||
void ScStwClient::connectToHost() {
|
||||
qDebug() << "connecting";
|
||||
setState("connecting");
|
||||
|
||||
connect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));
|
||||
setState(CONNECTING);
|
||||
|
||||
//connect
|
||||
this->socket->connectToHost(this->ip, this->port);
|
||||
|
@ -35,48 +40,52 @@ void ScStwClient::connectToHost() {
|
|||
}
|
||||
|
||||
void ScStwClient::connectionTimeout() {
|
||||
if(this->state != CONNECTING)
|
||||
return;
|
||||
|
||||
this->socket->abort();
|
||||
disconnect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));
|
||||
}
|
||||
|
||||
bool ScStwClient::init() {
|
||||
disconnect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(connectionTimeout()));
|
||||
if(this->state != CONNECTING)
|
||||
return false;
|
||||
|
||||
this->setState(INITIALISING);
|
||||
this->timeoutTimer->stop();
|
||||
|
||||
connect(this->socket, &QTcpSocket::readyRead, this, &ScStwClient::readyRead);
|
||||
this->setState("connected");
|
||||
|
||||
// init remote session
|
||||
QJsonArray updateSubs = {"onRaceStateChanged", "onTimersChanged", "onExtensionConnectionsChanged", "onNextStartActionChanged"};
|
||||
QJsonArray updateSubs = {ScStw::RaceStateChanged, ScStw::TimersChanged, ScStw::ExtensionsChanged, ScStw::NextStartActionChanged};
|
||||
QJsonObject sessionParams = {{"updateSubs", updateSubs}, {"init", true}, {"usingTerminationKeys", true}};
|
||||
|
||||
QVariantMap initResponse = this->sendCommand(1, sessionParams, false);
|
||||
QVariantMap initResponse = this->sendCommand(1, sessionParams, 3000, false);
|
||||
|
||||
if(initResponse["status"] != 200) {
|
||||
this->closeConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
this->firmwareVersion = initResponse["data"].toMap()["version"].toString();
|
||||
this->timeOffset = initResponse["data"].toMap()["time"].toDouble() - this->date->currentMSecsSinceEpoch();
|
||||
this->firmwareUpToDate = this->isFirmwareUpToDate();
|
||||
|
||||
emit this->propertiesChanged();
|
||||
|
||||
qDebug() << "[INFO][BaseStation] Init done! firmware: version: " << this->firmwareVersion << " up-to-date: " << this->firmwareUpToDate << " time offset: " << this->timeOffset;
|
||||
qDebug() << "[INFO][BaseStation] Init done! firmware: version: " << this->firmwareVersion << " up-to-date: " << this->isFirmwareUpToDate() << " time offset: " << this->timeOffset;
|
||||
|
||||
this->setState(CONNECTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScStwClient::deInit() {
|
||||
this->connections.clear();
|
||||
emit this->connectionsChanged();
|
||||
this->setState("disconnected");
|
||||
if(this->state == DISCONNECTED)
|
||||
return;
|
||||
|
||||
this->setConnections(QVariantList({}));
|
||||
this->setState(DISCONNECTED);
|
||||
}
|
||||
|
||||
void ScStwClient::closeConnection()
|
||||
{
|
||||
this->connections = QVariantList({});
|
||||
emit this->connectionsChanged();
|
||||
if(this->getState() == DISCONNECTED)
|
||||
return;
|
||||
|
||||
qDebug() << "closing connection";
|
||||
switch (socket->state())
|
||||
|
@ -90,67 +99,22 @@ void ScStwClient::closeConnection()
|
|||
default:
|
||||
socket->abort();
|
||||
}
|
||||
|
||||
setState("disconnected");
|
||||
}
|
||||
|
||||
void ScStwClient::gotError(QAbstractSocket::SocketError err)
|
||||
{
|
||||
//qDebug() << "got error";
|
||||
QString strError = "unknown";
|
||||
switch (err)
|
||||
{
|
||||
case 0:
|
||||
strError = "Connection was refused";
|
||||
break;
|
||||
case 1:
|
||||
strError = "Remote host closed the connection";
|
||||
this->closeConnection();
|
||||
break;
|
||||
case 2:
|
||||
strError = "Host address was not found";
|
||||
break;
|
||||
case 5:
|
||||
strError = "Connection timed out";
|
||||
break;
|
||||
default:
|
||||
strError = "Unknown error";
|
||||
}
|
||||
|
||||
emit gotError(strError);
|
||||
qDebug() << "got socket error: " << strError;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
// --- socket communication handling ---
|
||||
// -------------------------------------
|
||||
|
||||
void ScStwClient::socketStateChanged(QAbstractSocket::SocketState socketState) {
|
||||
switch (socketState) {
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
{
|
||||
this->deInit();
|
||||
break;
|
||||
}
|
||||
case QAbstractSocket::ConnectedState:
|
||||
{
|
||||
if(!this->init()) {
|
||||
this->closeConnection();
|
||||
QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, int timeout) {
|
||||
if(this->state != CONNECTED)
|
||||
return {{"status", ScStw::NotConnectedError}, {"data", "not connected"}};
|
||||
|
||||
return this->sendCommand(header, data, timeout, false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//qDebug() << "+ --- UNKNOWN SOCKET STATE: " << socketState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, bool useTerminationKeys, int timeout) {
|
||||
if(this->state != "connected"){
|
||||
return {{"status", 910}, {"data", "not connected"}};
|
||||
QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, int timeout, bool useTerminationKeys) {
|
||||
if(this->state != CONNECTED && this->state != INITIALISING){
|
||||
return {{"status", ScStw::NotConnectedError}, {"data", "not connected"}};
|
||||
}
|
||||
|
||||
// generate id and witing requests entry
|
||||
|
@ -174,8 +138,6 @@ QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, bool useTermin
|
|||
timer->setSingleShot(true);
|
||||
// quit the loop when the timer times out
|
||||
loop->connect(timer, SIGNAL(timeout()), loop, SLOT(quit()));
|
||||
// quit the loop when the connection was established
|
||||
// loop.connect(this, &ScStwClient::gotReply, &loop, &QEventLoop::quit);
|
||||
// start the timer before starting to connect
|
||||
timer->start(timeout);
|
||||
|
||||
|
@ -215,7 +177,7 @@ QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, bool useTermin
|
|||
|
||||
if(timer->remainingTime() == -1){
|
||||
//the time has been triggered -> timeout
|
||||
return {{"status", 911}, {"data", ""}};
|
||||
return {{"status", ScStw::TimeoutError}, {"data", ""}};
|
||||
}
|
||||
|
||||
delete timer;
|
||||
|
@ -223,7 +185,47 @@ QVariantMap ScStwClient::sendCommand(int header, QJsonValue data, bool useTermin
|
|||
|
||||
}
|
||||
|
||||
void ScStwClient::readyRead() {
|
||||
void ScStwClient::handleSocketStateChange(QAbstractSocket::SocketState socketState) {
|
||||
switch (socketState) {
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case QAbstractSocket::ConnectedState:
|
||||
{
|
||||
if(!this->init()) {
|
||||
this->closeConnection();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//qDebug() << "+ --- UNKNOWN SOCKET STATE: " << socketState;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScStwClient::handleError(QAbstractSocket::SocketError err)
|
||||
{
|
||||
if(err == QAbstractSocket::ProxyConnectionClosedError)
|
||||
this->closeConnection();
|
||||
|
||||
switch (err) {
|
||||
case QAbstractSocket::ProxyConnectionTimeoutError:
|
||||
if(this->state == CONNECTING)
|
||||
this->closeConnection();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
emit gotError(err);
|
||||
qDebug() << "got socket error: " << err;
|
||||
}
|
||||
|
||||
void ScStwClient::handleReadyRead() {
|
||||
|
||||
//qDebug() << "ready to ready " << socket->bytesAvailable() << " bytes" ;
|
||||
QString reply = socket->readAll();
|
||||
|
@ -234,15 +236,15 @@ void ScStwClient::readyRead() {
|
|||
}
|
||||
|
||||
void ScStwClient::processSocketMessage(QString message) {
|
||||
QString startKey = "<message>";
|
||||
QString endKey = "</message>";
|
||||
|
||||
//qWarning() << "... processing message now ... : " << message;
|
||||
|
||||
QString startKey = ScStw::SOCKET_MESSAGE_START_KEY;
|
||||
QString endKey = ScStw::SOCKET_MESSAGE_END_KEY;
|
||||
|
||||
if(message == ""){
|
||||
return;
|
||||
}
|
||||
|
||||
if((message.startsWith(startKey) && message.endsWith(endKey)) && (message.count(startKey) == 1 && message.count(endKey) == 1)){
|
||||
// non-split message ( e.g.: <message>123456789</message>
|
||||
}
|
||||
|
@ -282,12 +284,12 @@ void ScStwClient::processSocketMessage(QString message) {
|
|||
}
|
||||
|
||||
//qWarning() << "... done processing, message: " << message;
|
||||
this->socketReplyRecieved(message);
|
||||
this->handleSocketMessage(message);
|
||||
}
|
||||
|
||||
void ScStwClient::socketReplyRecieved(QString reply) {
|
||||
reply.replace("<message>", "");
|
||||
reply.replace("</message>", "");
|
||||
void ScStwClient::handleSocketMessage(QString reply) {
|
||||
reply.replace(ScStw::SOCKET_MESSAGE_START_KEY, "");
|
||||
reply.replace(ScStw::SOCKET_MESSAGE_END_KEY, "");
|
||||
|
||||
int id = 0;
|
||||
|
||||
|
@ -299,7 +301,7 @@ void ScStwClient::socketReplyRecieved(QString reply) {
|
|||
|
||||
if(id == -1) {
|
||||
// this message is an update!!
|
||||
emit this->gotUpdate(replyObj.toVariantMap());
|
||||
emit this->handleSignal(replyObj.toVariantMap());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -315,8 +317,28 @@ void ScStwClient::socketReplyRecieved(QString reply) {
|
|||
}
|
||||
}
|
||||
|
||||
latestReadReply = reply;
|
||||
emit gotUnexpectedReply(reply);
|
||||
emit gotUnexpectedMessage(reply);
|
||||
}
|
||||
|
||||
void ScStwClient::handleSignal(QVariantMap data) {
|
||||
// get the signal type
|
||||
ScStw::SignalKey signalKey = ScStw::SignalKey(data["header"].toInt());
|
||||
switch (signalKey) {
|
||||
case ScStw::ExtensionsChanged:
|
||||
{
|
||||
// the extension connections have changed
|
||||
// -> handle locally
|
||||
this->setConnections(data["data"].toList());
|
||||
return;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// forward to external handlers
|
||||
emit this->gotSignal(signalKey, data["data"]);
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
|
@ -336,12 +358,15 @@ bool ScStwClient::updateTime() {
|
|||
}
|
||||
|
||||
bool ScStwClient::updateFirmware() {
|
||||
if(this->state != CONNECTED)
|
||||
return false;
|
||||
|
||||
QString file = ":/ScStwBasestation.sb64";
|
||||
QFile f(file);
|
||||
if (!f.open(QFile::ReadOnly)) return false;
|
||||
QString fileContents = f.readAll();
|
||||
|
||||
if(this->firmwareUpToDate) {
|
||||
if(this->isFirmwareUpToDate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -375,15 +400,23 @@ bool ScStwClient::isFirmwareUpToDate() {
|
|||
// --- helper functions ---
|
||||
// ------------------------
|
||||
|
||||
int ScStwClient::writeRemoteSetting(QString key, QString value) {
|
||||
ScStw::ErrorCode ScStwClient::writeRemoteSetting(ScStw::BaseStationSetting key, QString value) {
|
||||
QJsonArray requestData;
|
||||
requestData.append(key);
|
||||
requestData.append(value);
|
||||
return this->sendCommand(3000, requestData)["status"].toInt();
|
||||
return ScStw::ErrorCode(this->sendCommand(3000, requestData)["status"].toInt());
|
||||
}
|
||||
|
||||
void ScStwClient::setIP(QString ipAdress){
|
||||
this->ip = ipAdress;
|
||||
QString ScStwClient::readRemoteSetting(ScStw::BaseStationSetting key) {
|
||||
QVariantMap reply = this->sendCommand(3001, key);
|
||||
if(reply["status"] != 200){
|
||||
return "false";
|
||||
}
|
||||
return reply["data"].toString();
|
||||
}
|
||||
|
||||
void ScStwClient::setIP(QString newIp){
|
||||
this->ip = newIp;
|
||||
}
|
||||
|
||||
QString ScStwClient::getIP()
|
||||
|
@ -391,60 +424,37 @@ QString ScStwClient::getIP()
|
|||
return this->ip;
|
||||
}
|
||||
|
||||
QString ScStwClient::getState()
|
||||
ScStwClient::State ScStwClient::getState()
|
||||
{
|
||||
return this->state;
|
||||
}
|
||||
|
||||
void ScStwClient::setState(QString newState){
|
||||
void ScStwClient::setState(ScStwClient::State newState){
|
||||
if(this->state != newState) {
|
||||
qDebug() << "+--- ScStwClient state changed: " << newState;
|
||||
this->state = newState;
|
||||
emit stateChanged();
|
||||
if(this->state == "disconnected") {
|
||||
if(this->state == DISCONNECTED) {
|
||||
this->deInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ScStwClient::refreshConnections() {
|
||||
/*
|
||||
"id": "id of the extention (int)",
|
||||
"type": "type of the extention (can be: 'STARTPAD', 'TOPPAD')",
|
||||
"name": "name of the extention",
|
||||
"ip": "ip-adress of he extention (string)",
|
||||
"state": "state of the extention (can be: 'disconnected', 'connecting', 'connected')"
|
||||
*/
|
||||
QVariantMap reply = this->sendCommand(2006);
|
||||
|
||||
if(reply["status"] != 200){
|
||||
//handle Error!!
|
||||
if(reply["status"] == 910){
|
||||
this->connections = QVariantList({});
|
||||
return true;
|
||||
}
|
||||
qDebug() << "+ --- error refreshing connections: " << reply["status"];
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariantList tmpConnections = reply["data"].toList();
|
||||
|
||||
if(this->connections != reply["data"].toList()){
|
||||
this->connections = reply["data"].toList();
|
||||
emit this->connectionsChanged();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
QVariant ScStwClient::getConnections() {
|
||||
QVariantList ScStwClient::getConnections() {
|
||||
return connections;
|
||||
}
|
||||
|
||||
int ScStwClient::getTimeOffset() {
|
||||
return this->timeOffset;
|
||||
}
|
||||
|
||||
QString ScStwClient::getFirmwareVersion() {
|
||||
return this->firmwareVersion;
|
||||
}
|
||||
|
||||
void ScStwClient::setConnections(QVariantList connections) {
|
||||
if(this->connections != connections){
|
||||
this->connections = connections;
|
||||
emit this->connectionsChanged();
|
||||
emit this->gotSignal(ScStw::ExtensionsChanged, this->getConnections());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <string.h>
|
||||
#include <QByteArray>
|
||||
|
||||
#include <ScStw.hpp>
|
||||
|
||||
/**
|
||||
* This class is used to connect and talk to the ScStw basestation.
|
||||
*
|
||||
|
@ -32,31 +34,25 @@ public:
|
|||
*/
|
||||
explicit ScStwClient();
|
||||
|
||||
enum State {DISCONNECTED, CONNECTING, INITIALISING, CONNECTED};
|
||||
|
||||
private:
|
||||
// values for the socket connection
|
||||
QString ip;
|
||||
ushort port = 3563;
|
||||
int errors;
|
||||
int errors_until_disconnect = 4;
|
||||
const static int ERRORS_UNTIL_DISCONNECT = 4;
|
||||
|
||||
QVariant connections;
|
||||
|
||||
QString latestReadReply;
|
||||
QVariantList connections;
|
||||
|
||||
//---general status values---//
|
||||
|
||||
// some meta data of the base
|
||||
// some meta data of the base station
|
||||
QString firmwareVersion;
|
||||
bool firmwareUpToDate;
|
||||
double timeOffset;
|
||||
|
||||
|
||||
// the current state
|
||||
QString state;
|
||||
// can be:
|
||||
// - 'disconnected'
|
||||
// - 'connecting'
|
||||
// - 'connected'
|
||||
ScStwClient::State state;
|
||||
|
||||
QDateTime *date;
|
||||
//to get the current time
|
||||
|
@ -80,94 +76,235 @@ private:
|
|||
|
||||
signals:
|
||||
/**
|
||||
* Is emitted, when the connection state changes
|
||||
*
|
||||
* @brief stateChanged
|
||||
* @brief Is emitted, when the connection state changes
|
||||
*/
|
||||
void stateChanged();
|
||||
|
||||
/**
|
||||
* Is emitted, whenever a reply is recieved which does not match any requests
|
||||
* @brief Is emitted, whenever a reply is recieved which does not match any requests
|
||||
*
|
||||
* @brief gotUnexpectedReply
|
||||
* @param reply contains the reply
|
||||
*/
|
||||
void gotUnexpectedReply(QString reply);
|
||||
void gotUnexpectedMessage(QString message);
|
||||
|
||||
/**
|
||||
* Is emitted, when an update signal from the basestation is recieved
|
||||
* @brief Is emitted, when an update signal from the basestation is recieved
|
||||
*
|
||||
* @brief gotUpdate
|
||||
* @param data
|
||||
*/
|
||||
void gotUpdate(QVariant data);
|
||||
void gotSignal(ScStw::SignalKey key, QVariant data);
|
||||
|
||||
void connectionsChanged();
|
||||
|
||||
void connectionSlotReleased();
|
||||
|
||||
void nextRemoteActionChanged();
|
||||
|
||||
void nextRemoteActionDelayProgChanged();
|
||||
|
||||
void gotError(QString error);
|
||||
|
||||
void propertiesChanged();
|
||||
/**
|
||||
* @brief Is emitted, when there is any network error
|
||||
* @param error
|
||||
*/
|
||||
void gotError(QAbstractSocket::SocketError error);
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
* @brief Function to connect to the base station
|
||||
*/
|
||||
void connectToHost();
|
||||
//function to connect to the base station
|
||||
|
||||
void connectionTimeout();
|
||||
|
||||
/**
|
||||
* @brief Function to disconnect from the basestation
|
||||
*/
|
||||
void closeConnection();
|
||||
|
||||
void gotError(QAbstractSocket::SocketError err);
|
||||
|
||||
// --- socket communication handling ---
|
||||
/** socket communication handling */
|
||||
|
||||
QVariantMap sendCommand(int header, QJsonValue data = "", bool useTerminationKeys = true, int timeout = 3000);
|
||||
/**
|
||||
* @brief Funtion to send a command to the server (for internal use)
|
||||
* @param header the command to send
|
||||
* @param data the data to send
|
||||
* @param timeout the timeout
|
||||
* @param useTerminationKeys wether to use the termination keys defined in
|
||||
*
|
||||
* @return a variant map containing the Keys "status" and "data"
|
||||
*/
|
||||
QVariantMap sendCommand(int header, QJsonValue data = "", int timeout = 3000);
|
||||
|
||||
// --- updater functions ---
|
||||
/** updater functions */
|
||||
|
||||
/**
|
||||
* @brief Function to set the timestamp of the base station to match the client
|
||||
* @see getTimeOffset()
|
||||
* @return true or false
|
||||
*/
|
||||
bool updateTime();
|
||||
|
||||
/**
|
||||
* @brief Function to update the firmware of the basestation to the version stored in the client
|
||||
* @details will not do anything if the remote firmware is newer or the same as the clients one
|
||||
* @see isFirmwareUpToDate()
|
||||
* @see getFirmwareVersion()
|
||||
* @return true: firmware was updated or is already up-to-date; false: there was an error during the update
|
||||
*/
|
||||
bool updateFirmware();
|
||||
|
||||
/**
|
||||
* @brief Function to check wether the firmware of the base station is up-to-date
|
||||
* @see getFirmwareVersion()
|
||||
* @see updateFirmware()
|
||||
* @return true or false
|
||||
*/
|
||||
bool isFirmwareUpToDate();
|
||||
|
||||
// --- helper functions ---
|
||||
/** helper functions */
|
||||
|
||||
int writeRemoteSetting(QString key, QString value);
|
||||
/**
|
||||
* @brief Function to write a setting on the base station
|
||||
* @param key the key to write to
|
||||
* @param value the value to write to
|
||||
* @return the status code returned by the command
|
||||
*/
|
||||
ScStw::ErrorCode writeRemoteSetting(ScStw::BaseStationSetting key, QString value);
|
||||
|
||||
bool refreshConnections();
|
||||
/**
|
||||
* @brief Function to read a setting on the base station
|
||||
* @param key the key to read from
|
||||
* @return the value of the key or "false" if the key is not found or an error occured
|
||||
*/
|
||||
QString readRemoteSetting(ScStw::BaseStationSetting key);
|
||||
|
||||
// functions for the qml adapter
|
||||
/** Getter fuctions */
|
||||
|
||||
/**
|
||||
* @brief Function to get the ip the client will try to connect to.
|
||||
* @see setIP()
|
||||
* @return the ip
|
||||
*/
|
||||
QString getIP();
|
||||
|
||||
/**
|
||||
* @brief Function to get the current state of the client
|
||||
* @return the current state
|
||||
*/
|
||||
ScStwClient::State getState();
|
||||
|
||||
/**
|
||||
* @brief Functio to get the extensions and their state from the base station
|
||||
* @return a list with all configured extensions and their state
|
||||
*/
|
||||
QVariantList getConnections();
|
||||
|
||||
/**
|
||||
* @brief Function to get the time offset of the base station relative to the clients time
|
||||
* @see updateTime()
|
||||
* @return the time offset in milliseconds
|
||||
*/
|
||||
int getTimeOffset();
|
||||
|
||||
/**
|
||||
* @brief Function to get the current firmware version of the base station
|
||||
* @see updateFirmware()
|
||||
* @see isFirmwareUpToDate()
|
||||
* @return Firmware version as string encoded as <major>.<minor>.<patch>
|
||||
*/
|
||||
QString getFirmwareVersion();
|
||||
|
||||
/** setter functions */
|
||||
|
||||
/**
|
||||
* @brief Function to set the ip to connect to
|
||||
* @see getIP()
|
||||
* @param ipAdress
|
||||
*/
|
||||
void setIP(QString ipAdress);
|
||||
|
||||
QString getState();
|
||||
void setState(QString newState);
|
||||
|
||||
int getProgress();
|
||||
|
||||
QVariant getConnections();
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* @brief called when timeout timer times out
|
||||
*/
|
||||
void connectionTimeout();
|
||||
|
||||
/**
|
||||
* @brief Function that is connected to the QAbstractSocket::error slot and used to handle upcoming errors
|
||||
* @param err the error that occurred
|
||||
*/
|
||||
void handleError(QAbstractSocket::SocketError err);
|
||||
|
||||
/**
|
||||
* @brief Function to init a session at the base station
|
||||
* @return true or false
|
||||
*/
|
||||
bool init();
|
||||
|
||||
/**
|
||||
* @brief Function to end a session on the base station
|
||||
*/
|
||||
void deInit();
|
||||
|
||||
void readyRead();
|
||||
/**
|
||||
* @brief Funtion to send a command to the server (for internal use)
|
||||
* @param header the command to send
|
||||
* @param data the data to send
|
||||
* @param timeout the timeout
|
||||
* @param useTerminationKeys wether to use the termination keys defined in
|
||||
* ScStw::SOCKET_MESSAGE_START_KEY and ScStw::SOCKET_MESSAGE_END_KEY
|
||||
* @return a variant map containing the Keys "status" and "data"
|
||||
*/
|
||||
QVariantMap sendCommand(int header, QJsonValue data, int timeout, bool useTerminationKeys);
|
||||
|
||||
/**
|
||||
* @brief Function connected to the QAbstractSocket::readyRead signal
|
||||
*/
|
||||
void handleReadyRead();
|
||||
|
||||
/**
|
||||
* @brief Function to process an incoming string and parse the messages contained in it.
|
||||
* @param message the message sting to parse
|
||||
*/
|
||||
void processSocketMessage(QString message);
|
||||
|
||||
void socketReplyRecieved(QString reply);
|
||||
/**
|
||||
* @brief Function that handles a parsed message
|
||||
* @details This fuction looks up the id of the incoming message and tries to find the according waiting request.
|
||||
* If it is unable to find an accordin request, the signal ScStwClient::gotUnexpectedMessage(QString message) is called.
|
||||
* If the recieved message is a signal, the ScStwClient::handleSignal() function is called.
|
||||
* @see gotUnexpectedMessage()
|
||||
* @see handleSignal()
|
||||
* @param reply the massage that needs to be handles
|
||||
*/
|
||||
void handleSocketMessage(QString reply);
|
||||
|
||||
void socketStateChanged(QAbstractSocket::SocketState socketState);
|
||||
/**
|
||||
* @brief Function to handle a change of the state of the tcp socket
|
||||
* @details it is connected to the QAbstractSocket::stateChanged signal
|
||||
* @see stateChanged()
|
||||
* @param socketState
|
||||
*/
|
||||
void handleSocketStateChange(QAbstractSocket::SocketState socketState);
|
||||
|
||||
/**
|
||||
* @brief Function to handle a signal from the base station.
|
||||
* @details Called by the ScStwClient::handleSocketMessage function
|
||||
* @see handleSocketMessage()
|
||||
* @param data
|
||||
*/
|
||||
void handleSignal(QVariantMap data);
|
||||
|
||||
/** Helper Functions */
|
||||
|
||||
/**
|
||||
* @brief Function used to set the local cache of the baseStation connections.
|
||||
* @details emits ScStwClient::gotSignal() with a ScStw::ExtensionsChanged signal.
|
||||
* @see gotSignal()
|
||||
* @param connections the list to set the chache to
|
||||
*/
|
||||
void setConnections(QVariantList connections);
|
||||
|
||||
/**
|
||||
* @brief Function to set the local state.
|
||||
* @details emits ScStwClient::stateChanged() when the new state does not match the old one.
|
||||
* @see stateChanged()
|
||||
* @param newState the state to change to
|
||||
*/
|
||||
void setState(ScStwClient::State newState);
|
||||
};
|
||||
|
||||
extern ScStwClient * pGlobalScStwClient;
|
||||
|
||||
#endif // SCSTWCLIENT_H
|
||||
|
|
Reference in a new issue