Initial commit
This commit is contained in:
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
|
||||
Reference in new issue
Block a user