137 lines
3.6 KiB
C++
Executable File
137 lines
3.6 KiB
C++
Executable File
|
|
|
|
|
|
|
|
#include "bsm_socket.h"
|
|
#include "bsm_telegrams_configuration_setup.h"
|
|
#include <QtCore/QTimer>
|
|
#include <QtNetwork/QHostAddress>
|
|
#include <TrainingAreaBase/logger.h>
|
|
|
|
static const int s_aliveTimeout = 10;
|
|
namespace BuildingControlUnit
|
|
{
|
|
namespace BSM
|
|
{
|
|
Socket::Socket(const Bsm &cfg, QObject *parent)
|
|
: QObject(parent)
|
|
, m_logger(TrainingAreaBase::getLogger("BSM.Socket"))
|
|
, m_config(cfg)
|
|
, m_tcpSocket(new QTcpSocket(this))
|
|
, m_reconnectTimer(nullptr)
|
|
, m_aliveTimer(new QTimer(this))
|
|
{
|
|
m_aliveTimer->setTimerType(Qt::VeryCoarseTimer);
|
|
m_aliveTimer->setSingleShot(true);
|
|
m_aliveTimer->setInterval(s_aliveTimeout * 2 * 1000);
|
|
connect(m_aliveTimer, &QTimer::timeout, this, &Socket::onAliveTimeout);
|
|
|
|
connect(m_tcpSocket, &QTcpSocket::connected,
|
|
this, &Socket::onConnected);
|
|
connect(m_tcpSocket, &QTcpSocket::disconnected,
|
|
this, &Socket::onDisconnected);
|
|
connect(m_tcpSocket, &QTcpSocket::errorOccurred,
|
|
this, &Socket::onError);
|
|
connect(m_tcpSocket, &QTcpSocket::readyRead,
|
|
this, &Socket::onReadyRead);
|
|
onConnect();
|
|
}
|
|
|
|
bool Socket::isConnected() const
|
|
{
|
|
return m_tcpSocket && (m_tcpSocket->state() == QAbstractSocket::ConnectedState);
|
|
}
|
|
|
|
bool Socket::sendData(const QByteArray &data)
|
|
{
|
|
if (!isConnected())
|
|
{
|
|
WARNING_LOG(m_logger) << "BSM " << m_config.id << ": Trying to send data but not connected!";
|
|
return false;
|
|
}
|
|
DEBUG_LOG(m_logger) << "BSM " << m_config.id << ": sending data: 0x" << data.toHex();
|
|
m_tcpSocket->write(data);
|
|
m_tcpSocket->flush();
|
|
return true;
|
|
}
|
|
|
|
void Socket::setVersionInformation(int verMajor, int verMinor, int verRev, const QString &manufacturer)
|
|
{
|
|
m_versionInfo = QStringLiteral("%1.%2-%3 (%4)").arg(verMajor).arg(verMinor).arg(verRev).arg(manufacturer);
|
|
INFO_LOG(m_logger) << "BSM " << m_config.id
|
|
<< ": version = " << m_versionInfo;
|
|
}
|
|
|
|
void Socket::gotAlive()
|
|
{
|
|
|
|
if (m_aliveTimer)
|
|
m_aliveTimer->start();
|
|
}
|
|
|
|
|
|
void Socket::onConnected()
|
|
{
|
|
INFO_LOG(m_logger) << "BSM " << m_config.id << " is connected to "
|
|
<< m_tcpSocket->peerAddress().toString() << ":" << m_tcpSocket->peerPort();
|
|
Telegrams::PanConfigurationSetup tele;
|
|
tele.m_aliveMessage = s_aliveTimeout;
|
|
sendData(tele.toBytestream());
|
|
m_aliveTimer->start();
|
|
|
|
emit connected(m_config.id);
|
|
}
|
|
|
|
void Socket::onDisconnected()
|
|
{
|
|
INFO_LOG(m_logger) << "BSM " << m_config.id << " is disconnected";
|
|
m_versionInfo.clear();
|
|
startReconnectTimer();
|
|
emit disconnected(m_config.id);
|
|
}
|
|
|
|
void Socket::onError(QAbstractSocket::SocketError error)
|
|
{
|
|
DEBUG_LOG(m_logger) << "BSM " << m_config.id
|
|
<< " can not connect to " << m_config.hostname << ":" << m_config.port
|
|
<< ": " << m_tcpSocket->errorString()
|
|
<< " (" << error << ");";
|
|
startReconnectTimer();
|
|
}
|
|
|
|
void Socket::onConnect()
|
|
{
|
|
DEBUG_LOG(m_logger) << "BSM " << m_config.id
|
|
<< " trying to connect to " << m_config.hostname << ":" << m_config.port;
|
|
m_tcpSocket->connectToHost(m_config.hostname, m_config.port);
|
|
}
|
|
|
|
void Socket::onReadyRead()
|
|
{
|
|
emit dataAvailable(m_config.id, m_tcpSocket->readAll());
|
|
}
|
|
|
|
void Socket::onAliveTimeout()
|
|
{
|
|
WARNING_LOG(m_logger) << "BSM " << m_config.id
|
|
<< " alive timeout! Reconnecting";
|
|
|
|
}
|
|
|
|
void Socket::startReconnectTimer()
|
|
{
|
|
if (!m_reconnectTimer)
|
|
{
|
|
m_reconnectTimer = new QTimer(this);
|
|
m_reconnectTimer->setTimerType(Qt::VeryCoarseTimer);
|
|
m_reconnectTimer->setSingleShot(true);
|
|
connect(m_reconnectTimer, &QTimer::timeout, this, &Socket::onConnect);
|
|
}
|
|
m_reconnectTimer->start(2000);
|
|
if (m_aliveTimer)
|
|
m_aliveTimer->stop();
|
|
}
|
|
|
|
}
|
|
}
|