/** * 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 HlaJson { HlaDispatcher::HlaDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp, const std::shared_ptr &recvFromTabCb, NGL::Settings *settings) : m_recvFromTabCb(recvFromTabCb) , m_recvFromHla(std::make_shared(recvFromTabCb, this)) , m_sendToHla(std::make_shared(pdp)) , 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::onHlaConnected); connect(m_webSocket, &QWebSocket::disconnected, this, &HlaDispatcher::onHlaDisconnected); connect(m_webSocket, &QWebSocket::textMessageReceived, this, &HlaDispatcher::onTextMessageReceived); connect(m_webSocketReconnectTimer, &QTimer::timeout, this, &HlaDispatcher::init); connect(m_recvFromHla.get(), &HlaHandlerRx::participantConnectionState, m_sendToHla.get(), &HlaHandlerTx::onParticipantConnectionState); } bool HlaDispatcher::init() { // TODO const QUrl url(webSocketUrl()); if (!m_bWarnedOnce) NOTICE_LOG(m_logger) << "Using WebSocket url: " << url.toString(); m_webSocket->open(url); return true; } 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::onHlaConnected() { QWebSocket *ws = qobject_cast(sender()); m_sendToHla->onHlaConnected(ws); m_webSocketReconnectTimer->stop(); m_bWarnedOnce = false; } void HlaDispatcher::onHlaDisconnected() { INFO_LOG(m_logger) << "Hla socket disconnected"; m_webSocketReconnectTimer->start(5000); m_sendToHla->onHlaDisconnected(); emit connectionState(QString::fromUtf8(name()), false); } 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 QString &message) { // convert from json to internal representation, send to TAB m_recvFromHla->handleTelegram(message.toUtf8()); } QUrl HlaDispatcher::webSocketUrl() const { const quint16 port = m_settings->settings()->value(QStringLiteral("hla/webSocketListenPort"), 12347).toInt(); const QString addr = m_settings->settings()->value(QStringLiteral("hla/webSocketHostname"), QStringLiteral("localhost")).toString(); return QUrl(QStringLiteral("ws://%1:%2/").arg(addr).arg(port)); } } // namespace HlaJson