2020-04-05 14:11:52 +02:00
|
|
|
#ifndef SCSTWCLIENT_H
|
|
|
|
#define SCSTWCLIENT_H
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
#include <QTcpSocket>
|
|
|
|
#include <QDataStream>
|
|
|
|
#include <QDateTime>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QEventLoop>
|
|
|
|
#include <QSemaphore>
|
|
|
|
#include <QThread>
|
|
|
|
#include <QFuture>
|
|
|
|
#include <QtConcurrent/QtConcurrent>
|
|
|
|
#include <string.h>
|
|
|
|
#include <QByteArray>
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
#include <ScStw.hpp>
|
|
|
|
|
2020-04-05 14:11:52 +02:00
|
|
|
/**
|
|
|
|
* This class is used to connect and talk to the ScStw basestation.
|
|
|
|
*
|
2020-04-08 18:56:37 +02:00
|
|
|
* @code{.cpp}
|
|
|
|
* ScStwClient * client = new ScStwClient();
|
|
|
|
* client->setIp("192.168.4.1");
|
|
|
|
* client->connectToHost();
|
|
|
|
* @endcode
|
|
|
|
*
|
2020-04-05 14:11:52 +02:00
|
|
|
* @brief The ScStwClient class
|
|
|
|
* @author Dorian Zedler
|
|
|
|
*/
|
|
|
|
class ScStwClient : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* The constructor
|
|
|
|
*
|
|
|
|
* @brief ScStwClient
|
|
|
|
*/
|
|
|
|
explicit ScStwClient();
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
enum State {DISCONNECTED, CONNECTING, INITIALISING, CONNECTED};
|
|
|
|
|
2020-04-05 14:11:52 +02:00
|
|
|
private:
|
|
|
|
// values for the socket connection
|
|
|
|
QString ip;
|
|
|
|
ushort port = 3563;
|
|
|
|
int errors;
|
2020-04-06 17:51:20 +02:00
|
|
|
const static int ERRORS_UNTIL_DISCONNECT = 4;
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
QVariantList connections;
|
2020-04-05 14:11:52 +02:00
|
|
|
|
|
|
|
//---general status values---//
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
// some meta data of the base station
|
2020-04-05 14:11:52 +02:00
|
|
|
QString firmwareVersion;
|
|
|
|
double timeOffset;
|
|
|
|
|
|
|
|
// the current state
|
2020-04-06 17:51:20 +02:00
|
|
|
ScStwClient::State state;
|
2020-04-05 14:11:52 +02:00
|
|
|
|
|
|
|
QDateTime *date;
|
|
|
|
//to get the current time
|
|
|
|
|
|
|
|
QTcpSocket *socket;
|
|
|
|
//socket for communication with the extention
|
|
|
|
|
|
|
|
QTimer *timeoutTimer;
|
|
|
|
|
|
|
|
QString readBuffer;
|
|
|
|
|
|
|
|
int nextConnectionId;
|
|
|
|
|
|
|
|
struct waitingRequest {
|
|
|
|
int id;
|
|
|
|
QEventLoop * loop;
|
|
|
|
QJsonObject reply;
|
|
|
|
};
|
|
|
|
|
|
|
|
QList<waitingRequest> waitingRequests;
|
|
|
|
|
|
|
|
signals:
|
|
|
|
/**
|
2020-04-06 17:51:20 +02:00
|
|
|
* @brief Is emitted, when the connection state changes
|
2020-04-05 14:11:52 +02:00
|
|
|
*/
|
|
|
|
void stateChanged();
|
|
|
|
|
|
|
|
/**
|
2020-04-06 17:51:20 +02:00
|
|
|
* @brief Is emitted, whenever a reply is recieved which does not match any requests
|
2020-04-05 14:11:52 +02:00
|
|
|
*
|
|
|
|
* @param reply contains the reply
|
|
|
|
*/
|
2020-04-06 17:51:20 +02:00
|
|
|
void gotUnexpectedMessage(QString message);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
|
|
|
/**
|
2020-04-06 17:51:20 +02:00
|
|
|
* @brief Is emitted, when an update signal from the basestation is recieved
|
2020-04-05 14:11:52 +02:00
|
|
|
*
|
|
|
|
* @param data
|
|
|
|
*/
|
2020-04-06 17:51:20 +02:00
|
|
|
void gotSignal(ScStw::SignalKey key, QVariant data);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Is emitted, when there is any network error
|
|
|
|
* @param error
|
|
|
|
*/
|
|
|
|
void gotError(QAbstractSocket::SocketError error);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Function to connect to the base station
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
void connectToHost();
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Function to disconnect from the basestation
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
void closeConnection();
|
|
|
|
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/** socket communication handling */
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/** updater functions */
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Function to set the timestamp of the base station to match the client
|
|
|
|
* @see getTimeOffset()
|
|
|
|
* @return true or false
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
bool updateTime();
|
2020-04-06 17:51:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
bool updateFirmware();
|
2020-04-06 17:51:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Function to check wether the firmware of the base station is up-to-date
|
|
|
|
* @see getFirmwareVersion()
|
|
|
|
* @see updateFirmware()
|
|
|
|
* @return true or false
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
bool isFirmwareUpToDate();
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/** helper functions */
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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);
|
|
|
|
|
|
|
|
/** Getter fuctions */
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Function to get the ip the client will try to connect to.
|
|
|
|
* @see setIP()
|
|
|
|
* @return the ip
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
QString getIP();
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Function to get the current state of the client
|
|
|
|
* @return the current state
|
|
|
|
*/
|
|
|
|
ScStwClient::State getState();
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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();
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
|
|
|
private slots:
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief called when timeout timer times out
|
|
|
|
*/
|
|
|
|
void connectionTimeout();
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
bool init();
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @brief Function to end a session on the base station
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
void deInit();
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
void processSocketMessage(QString message);
|
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/** Helper Functions */
|
2020-04-05 14:11:52 +02:00
|
|
|
|
2020-04-06 17:51:20 +02:00
|
|
|
/**
|
|
|
|
* @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
|
|
|
|
*/
|
2020-04-05 14:11:52 +02:00
|
|
|
void setConnections(QVariantList connections);
|
2020-04-06 17:51:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @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);
|
2020-04-05 14:11:52 +02:00
|
|
|
};
|
2020-04-06 17:51:20 +02:00
|
|
|
|
2020-04-05 14:11:52 +02:00
|
|
|
extern ScStwClient * pGlobalScStwClient;
|
|
|
|
|
|
|
|
#endif // SCSTWCLIENT_H
|