This repository has been archived on 2024-06-03. You can view files and clone it, but cannot push or open issues or pull requests.
app/sources/baseconn.cpp

337 lines
8.5 KiB
C++

#include "headers/baseconn.h"
BaseConn::BaseConn(QObject *parent) : QObject(parent)
{
socket = new QTcpSocket();
this->setState("disconnected");
remoteSessions.release(1);
this->nextConnectionId = 1;
this->speedTimers.append(pGlobalSpeedTimer);
this->refreshTimer = new QTimer();
refreshTimer->setInterval(1);
refreshTimer->setSingleShot(true);
refreshTimer->connect(this->refreshTimer, &QTimer::timeout, this, &BaseConn::refreshTimers);
refreshTimer->start();
}
bool BaseConn::connectToHost() {
qDebug() << "connecting";
setState("connecting");
this->connection_progress = 0;
QEventLoop loop;
QTimer timer;
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->socket, SIGNAL(connected()), &loop, SLOT(quit()));
// start the timer before starting to connect
timer.start(3000);
//connect
this->socket->connectToHost(this->ip, this->port);
//wait for the connection to finish (programm gets stuck in here)
loop.exec();
//loop finish
if(timer.remainingTime() == -1){
//the time has been triggered -> timeout
this->socket->abort();
setState("disconnected");
return(false);
}
// stop the timer as the connection has been established
timer.stop();
connect(this->socket, &QTcpSocket::readyRead, this, &BaseConn::readyRead);
this->connection_progress = 100;
setState("connected");
this->speedTimers[0]->remoteControlled = true;
return(true);
}
QString BaseConn::sendCommand(QString command){
if(this->state != "connected"){
return "ERR_NOT_CONNECTED";
}
// generate id and witing requests entry
int thisId = nextConnectionId;
nextConnectionId ++;
QEventLoop loop;
this->waitingRequests.append({thisId, &loop, ""});
command = "ID:" + QString::number(thisId) + "_"+command;
QByteArray arrBlock;
QDataStream out(&arrBlock, QIODevice::WriteOnly);
//out.setVersion(QDataStream::Qt_5_10);
out << quint16(0) << command;
out.device()->seek(0);
out << quint16(arrBlock.size() - sizeof(quint16));
QTimer timer;
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, &BaseConn::gotReply, &loop, &QEventLoop::quit);
// start the timer before starting to connect
timer.start(3000);
//write data
socket->write(arrBlock);
//wait for an answer to finish (programm gets stuck in here)
loop.exec();
//loop finished
if(timer.remainingTime() == -1){
//the time has been triggered -> timeout
return("ERR_TIMEOUT");
}
QString reply;
for(int i = 0; i<this->waitingRequests.length(); i++){
if(this->waitingRequests[i].id == thisId){
reply = this->waitingRequests[i].reply;
}
}
// stop the timer as the connection has been established
timer.stop();
timer.deleteLater();
//remoteSessions.release(1);
return(reply);
}
void BaseConn::readyRead() {
QDataStream in(socket);
//in.setVersion(QDataStream::Qt_5_10);
qint16 nextBlockSize = 0;
for (;;)
{
if (!nextBlockSize)
{
if (socket->bytesAvailable() < sizeof(quint16)) { break; }
in >> nextBlockSize;
}
if (socket->bytesAvailable() < nextBlockSize) { break; }
QString str; in >> str;
// if (str == "0")
// {
// str = "Connection closed";
// closeConnection();
// }
nextBlockSize = 0;
QString reply = str;
int id = 0;
if(reply.startsWith("ID:")){
reply.replace("ID:", "");
QStringList temp = reply.split("_");
reply.replace(temp[0]+"_", "");
id = temp[0].toInt();
for(int i = 0; i<this->waitingRequests.length(); i++){
if(this->waitingRequests[i].id == id){
this->waitingRequests[i].reply = reply;
this->waitingRequests[i].loop->quit();
return;
}
}
}
latestReadReply = str;
emit gotUnexpectedReply(str);
}
}
/*-----Functions to control the local stopwatch-----*/
void BaseConn::refreshTimers(){
if(this->state != "connected"){
this->refreshTimer->start();
return;
}
QString remoteState;
QString remoteTime;
QString tmpNextRemoteAction;
QString tmpNextRemoteActionDelayProg;
remoteState = sendCommand("GET_TIMER_STATE");
switch (speedTimers[0]->state) {
case SpeedTimer::IDLE:
break;
case SpeedTimer::STARTING:
if(remoteState == "RUNNING"){
speedTimers[0]->start();
}
else if (remoteState == "STOPPED") {
speedTimers[0]->stop("manual");
}
tmpNextRemoteAction = sendCommand("GET_NEXT_ACTION");
if(tmpNextRemoteAction.startsWith("ERR")){
//handle Error!!
}
else {
if(this->nextRemoteAction != tmpNextRemoteAction){
this->nextRemoteAction = tmpNextRemoteAction;
this->nextRemoteActionChanged();
}
}
tmpNextRemoteActionDelayProg = sendCommand("GET_NEXT_ACTION_DELAY_PROG");
if(tmpNextRemoteActionDelayProg.startsWith("ERR")){
//handle error!!
}
else {
if(this->nextRemoteActionDelayProg != tmpNextRemoteActionDelayProg.toFloat()){
this->nextRemoteActionDelayProg = tmpNextRemoteActionDelayProg.toFloat();
this->nextRemoteActionDelayProgChanged();
}
}
break;
case SpeedTimer::RUNNING:
if(remoteState == "STOPPED"){
speedTimers[0]->stop("manual");
}
remoteTime = sendCommand("GET_CURRTIME");
if(remoteTime.startsWith("ERR")){
//handle error!!
}
else {
speedTimers[0]->stoppedTime = remoteTime.toInt();
}
break;
case SpeedTimer::STOPPED:
remoteTime = sendCommand("GET_STOPPED_TIME");
if(remoteTime.startsWith("ERR")){
//handle error!!
}
else {
speedTimers[0]->stoppedTime = remoteTime.toInt();
}
break;
}
if(speedTimers[0]->state != speedTimers[0]->stateFromString(remoteState)){
// speedTimers[0]->setState(speedTimers[0]->stateFromString(remoteState));
qWarning() << "WARNING: Remote State not matching!!" << " remote state: " << remoteState << " local state: " << this->speedTimers[0]->getState();
}
this->refreshTimer->start();
}
bool BaseConn::startTimers(){
qDebug() << "starting timers";
QString ret = this->sendCommand("CMD_START_TIMER");
if(ret.startsWith("ERR")){
//handle Error!!
return false;
}
this->speedTimers[0]->setState(SpeedTimer::STARTING);
return true;
}
bool BaseConn::stopTimers(QString type){
qDebug() << "stopping timers";
QString ret = this->sendCommand("CMD_STOP_TIMER");
if(ret.startsWith("ERR")){
//handle Error!
return false;
}
this->speedTimers[0]->stop(type);
qDebug() << "stopped timers";
return true;
}
bool BaseConn::resetTimers(){
qDebug() << "resetting timers";
QString ret = this->sendCommand("CMD_RESET_TIMER");
if(ret.startsWith("ERR")){
//handle Error!
return false;
}
this->speedTimers[0]->reset();
return true;
}
void BaseConn::setIP(const QString &ipAdress){
this->ip = ipAdress;
}
QString BaseConn::getIP() const
{
return(this->ip);
}
QString BaseConn::getState() const
{
return(this->state);
}
void BaseConn::setState(QString newState){
this->state = newState;
emit stateChanged();
}
int BaseConn::getProgress() const
{
return(connection_progress);
}
bool BaseConn::refreshConnections() {
QString ret = this->sendCommand("GET_CONNECTIONS");
if(ret.startsWith("ERR")){
return false;
}
connections = ret.split("|||");
return true;
}
QStringList BaseConn::getConnections() {
return(connections);
}
QString BaseConn::getNextRemoteAction() {
return this->nextRemoteAction;
}
float BaseConn::getNextRemoteActionDelayProg(){
return this->nextRemoteActionDelayProg;
}