Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -0,0 +1,142 @@
/**
* Send / Receive telegrams to/from PrtCnv
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-09-26
*/
#include "socket_dispatcher_json.h"
#include <QCoreApplication>
#include <QDir>
#include <QTcpServer>
namespace TetraRadio
{
//
// SocketDispatcher
//
SocketDispatcher::SocketDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp,
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb)
: QObject()
, ConvertFromJson(recvFromTabCb, "TAB.Plugin.SocketDispatcher")
, m_txHandler(std::make_shared<ConvertToJson>("TxSocketHandler"))
, m_dataProvider(pdp)
, m_prtCnvApp(nullptr)
, m_ackTimer(new QTimer(this))
, m_bInitialAck(false)
, m_receiveCounter(0)
{
m_ackTimer->setInterval(1000);
m_ackTimer->setSingleShot(false);
connect(m_ackTimer, &QTimer::timeout,
this, &SocketDispatcher::onAckTimeout);
}
SocketDispatcher::~SocketDispatcher()
{
delete m_ackTimer;
}
bool SocketDispatcher::init(PrtCnv::PrtCnvApplication *prtCnvApp)
{
if (m_prtCnvApp == prtCnvApp)
return true;
if (m_prtCnvApp)
m_prtCnvApp->disconnect(this);
m_prtCnvApp = prtCnvApp;
if (m_prtCnvApp)
{
connect(m_txHandler.get(), &ConvertToJson::outgoingMessage,
m_prtCnvApp, &PrtCnv::PrtCnvApplication::textMessageFromCentralToPrtCnv);
connect(m_prtCnvApp, &PrtCnv::PrtCnvApplication::textMessageFromPrtCnvToCentral,
this, &SocketDispatcher::onTextMessageReceived);
connect(m_prtCnvApp, &PrtCnv::PrtCnvApplication::warehouseMessageFromPtrCnv,
this, &SocketDispatcher::warehouseMessage);
m_ackTimer->start();
m_bInitialAck = true;
}
else
{
m_bInitialAck = false;
m_ackTimer->stop();
}
return true;
}
quint16 SocketDispatcher::randomListenPort() const
{
QTcpServer *s = new QTcpServer;
s->listen(QHostAddress::Any, 0);
while (!s->isListening())
QCoreApplication::processEvents();
quint16 port = s->serverPort();
delete s;
return port;
}
std::shared_ptr<TrainingAreaBase::SendToTab> SocketDispatcher::sendToTab()
{
return std::static_pointer_cast<TrainingAreaBase::SendToTab>(m_txHandler);
}
void SocketDispatcher::onTextMessageReceived(const QByteArray &message)
{
DEBUG_LOG(m_logger) << "TetraJson onTextMessageReceived: '" << message << "'";
int newRecvCounter = 0;
if (!handleTelegram(message, newRecvCounter))
return;
m_receiveCounter = newRecvCounter;
}
void SocketDispatcher::handleTetraConnectionChanged(bool bConnected)
{
emit tetraConnectionChanged(bConnected);
}
void SocketDispatcher::handleAcknowledge(qint64 timeStamp, int counter)
{
TRACE_LOG(m_logger) << "Ack from Socket for time " << timeStamp
<< " with counter " << counter
<< ", initial: " << m_bInitialAck;
if (m_bInitialAck)
{
m_txHandler->setConnected(true);
m_bInitialAck = false;
onSendInitialData();
}
// TODO: remove all now outdated telegrams !?
}
void SocketDispatcher::onAckTimeout()
{
TrainingAreaBase::TetraIcd::Acknowledge ack;
ack.timeStamp = time(nullptr) * 1000;
ack.ackCounter = m_receiveCounter;
m_txHandler->txData(ack);
}
void SocketDispatcher::onSendInitialData()
{
if (m_dataProvider)
{
NOTICE_LOG(m_logger) << "sending initial data exerciseId=" << m_dataProvider->exerciseId();
// on connect we must send:
if (m_dataProvider->exerciseId() > 0)
{
// - Umgebungsmeldung
m_txHandler->txData(m_dataProvider->exerciseEnvironmentData());
}
// - Betriebszustandsmeldung
m_txHandler->txData(m_dataProvider->exerciseStateData());
m_txHandler->txData(m_dataProvider->exerciseEquipmentAssignment());
const auto &aesTeles = m_dataProvider->aesTelegrams();
for (TrainingAreaBase::TetraIcd::TrainingAreaTelegram *aesTele : aesTeles)
m_txHandler->sendToTx(aesTele);
}
}
} // namespace TetraRadio