2023-07-10 15:56:20 +02:00
|
|
|
#include "apism_tcp_client.h"
|
|
|
|
|
|
|
|
#include <QHostAddress>
|
|
|
|
#include <QTimer>
|
2023-07-14 13:27:14 +02:00
|
|
|
#include <QCoreApplication>
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
ApismTcpClient::ApismTcpClient(const QString & hostname,
|
|
|
|
const QString & port,
|
|
|
|
QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, hostname(hostname)
|
|
|
|
, port(port)
|
|
|
|
, responseTimerTimeoutCounter(0)
|
|
|
|
{
|
|
|
|
this->responseTimeoutTimer = new QTimer(this);
|
|
|
|
this->responseTimeoutTimer->setInterval(10000);
|
|
|
|
this->responseTimeoutTimer->setSingleShot(true);
|
|
|
|
|
|
|
|
connect(this->responseTimeoutTimer, SIGNAL(timeout()), this, SLOT(onResponseTimeoutTimerTimeout()));
|
|
|
|
|
|
|
|
socket = new QTcpSocket(this);
|
|
|
|
connect(socket, SIGNAL(connected()), this, SLOT(onSocketConnected()));
|
|
|
|
connect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected()));
|
|
|
|
connect(socket, SIGNAL(readyRead()), this, SLOT(onSocketReadyRead()));
|
|
|
|
connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(onSocketBytesWritten(qint64)));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-07-14 13:27:14 +02:00
|
|
|
void ApismTcpClient::connectToHost() {
|
|
|
|
qCritical() << "ApismTcpClient::connectToHost(this->" << hostname << ", " << port << ")";
|
2023-07-10 15:56:20 +02:00
|
|
|
int portNumber = this->port.toInt();
|
|
|
|
this->socket->connectToHost(QHostAddress(this->hostname), portNumber);
|
2023-07-14 13:27:14 +02:00
|
|
|
if (!socket->waitForConnected(10000)) {
|
|
|
|
qCritical() << "ERROR IN WAIT FOR CONNECTED" << socket->errorString();
|
|
|
|
} else {
|
|
|
|
qDebug() << "connected to" << hostname << ", " << port << ")";
|
|
|
|
}
|
2023-07-10 15:56:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ApismTcpClient::connectToHost(const QString & hostname, const QString & port)
|
|
|
|
{
|
|
|
|
qCritical() << "ApismTcpClient::connectToHost(" << hostname << ", " << port << ")";
|
|
|
|
|
|
|
|
int portNumber = port.toInt();
|
|
|
|
socket->connectToHost(hostname, portNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApismTcpClient::closeConnection()
|
|
|
|
{
|
|
|
|
socket->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ApismTcpClient::isConnected()
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
QAbstractSocket::SocketState socketState = socket->state();
|
|
|
|
|
|
|
|
switch (socketState) {
|
|
|
|
case QAbstractSocket::UnconnectedState:
|
|
|
|
/* FALLTHRU */
|
|
|
|
case QAbstractSocket::HostLookupState:
|
|
|
|
/* FALLTHRU */
|
|
|
|
case QAbstractSocket::ConnectingState:
|
|
|
|
result = false;
|
|
|
|
break;
|
|
|
|
case QAbstractSocket::ConnectedState:
|
|
|
|
/* FALLTHRU */
|
|
|
|
case QAbstractSocket::BoundState:
|
|
|
|
result = true;
|
|
|
|
break;
|
|
|
|
case QAbstractSocket::ClosingState:
|
|
|
|
/* FALLTHRU */
|
|
|
|
case QAbstractSocket::ListeningState:
|
|
|
|
result = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-07-14 13:27:14 +02:00
|
|
|
void ApismTcpClient::sendData(const QByteArray & message) {
|
|
|
|
qDebug() << "ApismTcpClient::send: " << message;
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
this->sendQueue.enqueue(message);
|
|
|
|
|
|
|
|
if (this->isConnected()) {
|
2023-07-14 13:27:14 +02:00
|
|
|
qCritical() << "ApismTcpClient::send: connected, send" << message;
|
2023-07-10 15:56:20 +02:00
|
|
|
this->private_sendData();
|
2023-07-14 13:27:14 +02:00
|
|
|
} else {
|
|
|
|
qCritical() << "ApismTcpClient::send: not connected, connect";
|
2023-07-10 15:56:20 +02:00
|
|
|
this->connectToHost();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief ApismTcpClient::private_sendData
|
|
|
|
*
|
|
|
|
* Precondition is that queue is not empty.
|
|
|
|
*/
|
|
|
|
void ApismTcpClient::private_sendData()
|
|
|
|
{
|
|
|
|
// take message from queue
|
|
|
|
QByteArray ba = this->sendQueue.dequeue();
|
|
|
|
|
2023-07-14 13:27:14 +02:00
|
|
|
qDebug() << "ApismTcpClient::send: " << QString(ba);
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
socket->write(ba);
|
|
|
|
socket->flush();
|
|
|
|
|
|
|
|
// start timeoutTimer
|
|
|
|
this->responseTimeoutTimer->start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApismTcpClient::onSocketConnected()
|
|
|
|
{
|
2023-07-14 13:27:14 +02:00
|
|
|
qInfo() << "ApismTcpClient: Connected!";
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
if (this->sendQueue.size() > 0) {
|
|
|
|
this->private_sendData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApismTcpClient::onSocketDisconnected()
|
|
|
|
{
|
2023-07-14 13:27:14 +02:00
|
|
|
qDebug() << "ApismTcpClient: Disconnected!";
|
|
|
|
qDebug() << " -> SocketErrorString: " << socket->errorString();
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
if (this->sendQueue.size() > 0) {
|
|
|
|
this->connectToHost();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApismTcpClient::onSocketBytesWritten(qint64 bytes)
|
|
|
|
{
|
|
|
|
Q_UNUSED(bytes)
|
|
|
|
}
|
|
|
|
|
|
|
|
void ApismTcpClient::onSocketReadyRead()
|
|
|
|
{
|
|
|
|
QByteArray readData;
|
|
|
|
|
|
|
|
// stop timeoutTimer
|
|
|
|
this->responseTimeoutTimer->stop();
|
|
|
|
|
|
|
|
readData = socket->readAll();
|
|
|
|
|
2023-07-14 13:27:14 +02:00
|
|
|
qDebug() << "ISMAS received: " << QString(readData);
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
emit this->receivedData(readData);
|
2023-07-14 13:27:14 +02:00
|
|
|
//QCoreApplication::processEvents();
|
2023-07-10 15:56:20 +02:00
|
|
|
|
|
|
|
this->socket->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ApismTcpClient::onResponseTimeoutTimerTimeout()
|
|
|
|
{
|
|
|
|
if (this->sendQueue.size() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
emit this->responseTimeout();
|
|
|
|
|
|
|
|
qCritical() << "ApismTcpClient::onResponseTimeoutTimerTimeout() --> skip this message, send next command, if available.";
|
|
|
|
|
|
|
|
// Try next command
|
|
|
|
this->sendQueue.removeFirst();
|
|
|
|
if (this->sendQueue.size() > 0) this->private_sendData();
|
|
|
|
}
|