330 lines
9.2 KiB
C++
330 lines
9.2 KiB
C++
#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>
|
|
|
|
#include "ScStw.hpp"
|
|
|
|
/*!
|
|
* This class is used to connect and talk to the ScStw basestation.
|
|
*
|
|
* \code{.cpp}
|
|
* ScStwClient * client = new ScStwClient();
|
|
* client->setIp("192.168.4.1");
|
|
* client->connectToHost();
|
|
* \endcode
|
|
*
|
|
* \brief The ScStwClient class
|
|
* \author Dorian Zedler
|
|
*/
|
|
class ScStwClient : public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(State state READ getState NOTIFY stateChanged)
|
|
Q_PROPERTY(QVariantList extensions READ getExtensions NOTIFY extensionsChanged)
|
|
|
|
public:
|
|
/*!
|
|
* The constructor
|
|
*
|
|
* \brief ScStwClient
|
|
*/
|
|
explicit ScStwClient();
|
|
|
|
enum State {DISCONNECTED, CONNECTING, INITIALISING, CONNECTED};
|
|
Q_ENUM(State);
|
|
|
|
private:
|
|
// values for the socket connection
|
|
QString ip;
|
|
ushort port = 3563;
|
|
int errors;
|
|
const static int ERRORS_UNTIL_DISCONNECT = 4;
|
|
|
|
QVariantList extensions;
|
|
|
|
//---general status values---//
|
|
|
|
// some meta data of the base station
|
|
QString firmwareVersion;
|
|
double timeOffset;
|
|
|
|
// the current state
|
|
ScStwClient::State state;
|
|
|
|
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;
|
|
|
|
public slots:
|
|
|
|
/*!
|
|
* \brief Function to connect to the base station
|
|
*/
|
|
void connectToHost();
|
|
|
|
/*!
|
|
* \brief Function to disconnect from the basestation
|
|
*/
|
|
void closeConnection();
|
|
|
|
|
|
/*! socket communication handling */
|
|
|
|
/*!
|
|
* \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 */
|
|
|
|
/*!
|
|
* \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
|
|
|
|
/*!
|
|
* \brief Function to pair all extensions that are currently connected via USB to the base station
|
|
* \return whether the pairing was successfull
|
|
*/
|
|
bool pairConnectedUsbExtensions();
|
|
|
|
/*!
|
|
* \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::StatusCode writeRemoteSetting(ScStw::BaseStationSetting key, QString value);
|
|
|
|
/*!
|
|
* \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 */
|
|
|
|
/*!
|
|
* \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 Function to get the extensions and their state from the base station
|
|
* \return a list with all configured extensions and their state
|
|
*/
|
|
QVariantList getExtensions();
|
|
|
|
/*!
|
|
* \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);
|
|
|
|
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();
|
|
|
|
/*!
|
|
* \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);
|
|
|
|
/*!
|
|
* \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);
|
|
|
|
/*! 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 setExtensions(QVariantList extensions);
|
|
|
|
/*!
|
|
* \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);
|
|
|
|
signals:
|
|
/*!
|
|
* \brief Is emitted, when the connection state changes
|
|
*/
|
|
void stateChanged();
|
|
|
|
/*!
|
|
* \brief Is emitted, whenever a reply is recieved which does not match any requests
|
|
*
|
|
* \param reply contains the reply
|
|
*/
|
|
void gotUnexpectedMessage(QString message);
|
|
|
|
/*!
|
|
* \brief Is emitted, when an update signal from the basestation is recieved
|
|
*
|
|
* \param data
|
|
*/
|
|
void gotSignal(ScStw::SignalKey key, QVariant data);
|
|
|
|
/*!
|
|
* \brief Is emitted, when there is any network error
|
|
* \param error
|
|
*/
|
|
void gotError(QAbstractSocket::SocketError error);
|
|
|
|
/*!
|
|
* \brief Is emitted, when the extensions of the base station changed
|
|
*/
|
|
void extensionsChanged();
|
|
};
|
|
|
|
extern ScStwClient * pGlobalScStwClient;
|
|
|
|
#endif // SCSTWCLIENT_H
|