/** * Send / Receive telegrams to/from Hla * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2016-09-26 */ #include "hla_dispatcher.h" #include "hla_handler_rx.h" #include "hla_handler_tx.h" #include #include #include #include namespace ApHlaJson { HlaDispatcher::HlaDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp, const std::shared_ptr &recvFromTabCb, const std::shared_ptr &sendToTabCb, NGL::Settings *settings, std::shared_ptr ppmHandler, std::shared_ptr pdmHandler, std::shared_ptr aesHandler) : m_recvFromTabCb(recvFromTabCb) , m_recvFromHla(std::make_shared(recvFromTabCb, sendToTabCb, this, aesHandler.get(), ppmHandler.get())) , m_sendToHla(std::make_shared(pdp, ppmHandler.get(), pdmHandler.get())) , m_settings(settings) , m_webSocket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this)) , m_webSocketReconnectTimer(new QTimer(this)) , m_bWarnedOnce(false) , m_logger(getLogger("HlaDispatcher")) { connect(m_webSocket, QOverload::of(&QWebSocket::error), this, &HlaDispatcher::onWebSocketError); connect(m_webSocket, &QWebSocket::connected, this, &HlaDispatcher::onWebSocketConnected); connect(m_webSocket, &QWebSocket::disconnected, this, &HlaDispatcher::onWebsocketDisconnected); connect(m_webSocket, &QWebSocket::binaryMessageReceived, this, &HlaDispatcher::onTextMessageReceived, Qt::UniqueConnection); connect(m_webSocketReconnectTimer, &QTimer::timeout, this, &HlaDispatcher::reallyConnectWebsocket); connect(m_recvFromHla.get(), &HlaHandlerRx::participantConnectionState, m_sendToHla.get(), &HlaHandlerTx::onParticipantConnectionState); } bool HlaDispatcher::init() { return true; } void HlaDispatcher::connectWebsocket() { const QUrl url(webSocketUrl()); if (!m_bWarnedOnce) NOTICE_LOG(m_logger) << "Using WebSocket url: " << url.toString(); if (m_webSocket->state() != QAbstractSocket::ConnectedState) m_webSocket->open(url); } std::shared_ptr HlaDispatcher::sendToTab() { return std::static_pointer_cast(m_sendToHla); } bool HlaDispatcher::canSendData() const { return m_webSocket && m_webSocket->state() == QAbstractSocket::ConnectedState; } void HlaDispatcher::onWebSocketConnected() { INFO_LOG(m_logger) << "WebSocket connected"; QWebSocket *ws = qobject_cast(sender()); m_sendToHla->onWebSocketConnected(ws); m_webSocketReconnectTimer->stop(); m_bWarnedOnce = false; } void HlaDispatcher::onWebsocketDisconnected() { INFO_LOG(m_logger) << "Hla socket disconnected"; m_sendToHla->onWebSocketDisconnected(); emit connectionState(QString::fromUtf8(name()), false); m_webSocketReconnectTimer->start(5000); } void HlaDispatcher::onHlaExternalConnectionStateChanged(bool bConnected) { m_sendToHla->onHlaConnectedToExternalSystem(bConnected); emit connectionState(QString::fromUtf8(name()), bConnected); } void HlaDispatcher::onWebSocketError() { if (!m_webSocket) return; if (!m_bWarnedOnce) WARNING_LOG(m_logger) << "Error connecting to " << webSocketUrl().toString() << ": " << m_webSocket->errorString(); m_webSocket->close(); m_webSocketReconnectTimer->start(5000); m_bWarnedOnce = true; emit connectionState(QString::fromUtf8(name()), false); } void HlaDispatcher::onTextMessageReceived(const QByteArray &message) { INFO_LOG(m_logger) << "Text Message received: " << message; // convert from json to internal representation, send to TAB m_recvFromHla->handleTelegram(message); } QUrl HlaDispatcher::webSocketUrl() const { const quint16 port = m_settings->settings()->value(QStringLiteral("aphla/webSocketListenPort"), 12345).toInt(); const QString addr = m_settings->settings()->value(QStringLiteral("aphla/webSocketHostname"), QStringLiteral("172.25.160.11")).toString(); return QUrl(QStringLiteral("ws://%1:%2/").arg(addr).arg(port)); } } // namespace HlaJson