/** * @RDE_HEADER@ * Websocket interface for ADLER WebsocketSimulator * $Id$ * $HeadURL$ * $Author$ * Created by Patric Karwat, ESZS, 2025-03-03 */ #include "awss_websocket_interface.h" namespace AdlerWebSocketSimulator { WebSocketInterface::WebSocketInterface(QObject *parent) : QObject{parent} , m_logger(getLogger("WebSocketInterface")) { m_socket = new QWebSocket(); connect(m_socket, &QWebSocket::textMessageReceived, this, &WebSocketInterface::onTextMessageRecived); connect(m_socket, &QWebSocket::connected, this, &WebSocketInterface::onConnected); connect(m_socket, &QWebSocket::disconnected, this, &WebSocketInterface::onDisconnected); connect(m_socket, QOverload::of(&QWebSocket::error), this, &WebSocketInterface::onError); } void WebSocketInterface::reset() { m_socket->close(); m_hostname.clear(); m_partyId = 0; m_partyName.clear(); m_awss_state = AWSS_STATE::Unconnected; } void WebSocketInterface::requestServicePortInformation() { emit statusMessage(tr("Start Service Information Request")); m_socket->sendTextMessage(QStringLiteral("{\"type\": \"servicePortsInformationRequest\",\"uuid\": \"%s\"}").arg(QUuid::createUuid().toString())); m_awss_state = AWSS_STATE::RequestServicePorts; } void WebSocketInterface::requestExcerciseInformation() { emit statusMessage(tr("Start Excercise Information Request")); m_awss_state = AWSS_STATE::RequestExerciseInformation; m_socket->sendTextMessage(QStringLiteral("{\"type\": \"exerciseInformationRequest\",\"uuid\": \"%1\"}").arg(QUuid::createUuid().toString())); } void WebSocketInterface::requestPartyInformation() { emit statusMessage(tr("Start Party Information Request")); m_awss_state = AWSS_STATE::RequestPartyInformation; m_socket->sendTextMessage(QStringLiteral("{\"type\": \"partyBaseData\",\"uuid\": \"%1\"}").arg(QUuid::createUuid().toString())); } void WebSocketInterface::connectToServer(const QString servername, int port, int saaId) { emit statusMessage(tr("Connecting to ServiceManagement on %1 : %2 for SAA%3").arg(servername).arg(port, saaId)); if (m_socket->state() != QAbstractSocket::UnconnectedState) m_socket->close(); m_hostname = servername; m_port = port; m_saaId = saaId; QUrl url = QUrl(QLatin1String("ws://") + servername + QLatin1Char(':') + QString::number(port)); m_socket->open(url); m_awss_state = AWSS_STATE::ConnectToServer; } void WebSocketInterface::connectToExerciseManagement(int port) { emit statusMessage(tr("Connecting to ExcerciseManagement on %1 : %2 ").arg(m_hostname).arg(port)); m_socket->close(); m_port = port; QUrl url = QUrl(QLatin1String("ws://") + m_hostname + QLatin1Char(':') + QString::number(port)); m_awss_state = AWSS_STATE::ConnectToExerciseManagement; m_socket->open(url); } void WebSocketInterface::connectToParticipantManagement(int port) { emit statusMessage(tr("Connecting to ParticimantManagement on %1 : %2 ").arg(m_hostname).arg(port)); m_socket->close(); m_port = port; QUrl url = QUrl(QLatin1String("ws://") + m_hostname + QLatin1Char(':') + QString::number(port)); m_awss_state = AWSS_STATE::ConnectToParticipantManagement; m_socket->open(url); } void WebSocketInterface::connectToProxy(int port, int partyId, const QString &partyName) { emit statusMessage(tr("Connecting to Proxy on %1 : %2 for party: %3").arg(m_hostname).arg(port).arg(partyName)); m_socket->close(); m_port = port; m_partyId = partyId; m_partyName = partyName; QUrl url = QUrl(QLatin1String("ws://") + m_hostname + QLatin1Char(':') + QString::number(port)); m_awss_state = AWSS_STATE::ConnectToProxy; m_socket->open(url); } void WebSocketInterface::sendToProxy(const QString &message) { if (m_socket->state() != QAbstractSocket::ConnectedState) return; m_socket->sendTextMessage(message); } void WebSocketInterface::sendFlugbahndaten(QString uuid) { AdlerJson::ExFlugbahndaten req; NOTICE_LOG(m_logger) << "WebSocketInterface::sendFlugbahndaten uuid=" << uuid; GenerateTelegrams::addHeaderData(req, m_saaId); GenerateTelegrams::generateFlugbahndaten(req); req.referenceUuid = uuid; QJsonObject messageObj =req.toJson(); QString message = QString::fromUtf8(QJsonDocument(messageObj).toJson()); sendToProxy(message); } void WebSocketInterface::onTextMessageRecived(const QString &message) { switch (m_awss_state) { case AWSS_STATE::RequestServicePorts: emit statusMessage(tr("Recieved Service Ports")); emit gotServiceData(message); break; case AWSS_STATE::RequestExerciseInformation: emit statusMessage(tr("Recieved Exercise Information")); emit gotExerciseData(message); break; case AWSS_STATE::RequestPartyInformation: emit statusMessage(tr("Recieved Party Information")); emit gotPartyData(message); break; case AWSS_STATE::ConnectedToProxy: emit statusMessage(tr("Recieved Message")); emit proxyMessage(message); //emit gotPartyData(message); default: break; } QJsonDocument jsonDoc = QJsonDocument::fromJson(message.toUtf8()); const QJsonObject jsonObj = jsonDoc.object(); if ( jsonObj.contains(QStringLiteral("type"))) if ( jsonObj.value(QStringLiteral("type")) == QStringLiteral("EX-Flugbahnberechnung")) { DEBUG_LOG(m_logger) << "type=" << jsonObj.value(QStringLiteral("type")).toString(); DEBUG_LOG(m_logger) << "reciver=" << jsonObj.value(QStringLiteral("reciver")).toString(); DEBUG_LOG(m_logger) << "sender=" << jsonObj.value(QStringLiteral("sender")).toString(); DEBUG_LOG(m_logger) << "timestamp=" << jsonObj.value(QStringLiteral("timestamp")).toString(); DEBUG_LOG(m_logger) << "uuid=" << jsonObj.value(QStringLiteral("uuid")).toString(); DEBUG_LOG(m_logger) << "Sende Flugbahndaten"; if ( !jsonObj.contains(QStringLiteral("uuid"))) { DEBUG_LOG(m_logger) << "No uuid available" << ", message=" << message; return; } QString uuid = jsonObj.value(QStringLiteral("uuid")).toString(); sendFlugbahndaten(uuid); } DEBUG_LOG(m_logger) << "Received Message from WebSocket: " << ", port :" << m_port << ", message : " << message; } void WebSocketInterface::onConnected() { switch (m_awss_state) { case AWSS_STATE::ConnectToServer: { m_awss_state = AWSS_STATE::ConnectedToServer; DEBUG_LOG(m_logger) << "ConnectedToServer"; emit statusMessage(tr("Connected To ServiceManagement")); requestServicePortInformation(); break; } case AWSS_STATE::ConnectToExerciseManagement: { m_awss_state = AWSS_STATE::ConnectedToExerciseManagement; DEBUG_LOG(m_logger) << "ConnectedToExercise"; emit statusMessage(tr("Connected To ExerciseManagement for Exercise")); requestExcerciseInformation(); break; } case AWSS_STATE::ConnectToParticipantManagement: { m_awss_state = AWSS_STATE::ConnectedToParticipantManagement; DEBUG_LOG(m_logger) << "ConnectedToParticipantManagement"; emit statusMessage(tr("Connected To ParticipantManagement for Exercise")); requestPartyInformation(); break; } case AWSS_STATE::ConnectToProxy: { emit statusMessage(tr("Connected To Exercise Proxy for party: %1").arg(m_partyName)); m_awss_state = AWSS_STATE::ConnectedToProxy; DEBUG_LOG(m_logger) << "ConnectedToProxy"; //TEST emit connectedToParty(m_partyId, m_partyName, m_saaId); break; } default: emit statusMessage(tr("Connected during wrong connection State")); DEBUG_LOG(m_logger) << "connected during wrong connection State"; break; } } void WebSocketInterface::onReconnect() { DEBUG_LOG(m_logger) << "Disconnected - current state: " << m_awss_state; switch (m_awss_state) { case AWSS_STATE::RequestServicePorts: case AWSS_STATE::ConnectedToServer: { m_awss_state = AWSS_STATE::ConnectToServer; emit statusMessage(tr("Try Recconect to ServiceManagement")); connectToServer(m_hostname, m_port, m_saaId); break; } case AWSS_STATE::ConnectedToExerciseManagement: case AWSS_STATE::RequestExerciseInformation: { m_awss_state = AWSS_STATE::ConnectToExerciseManagement; emit statusMessage(tr("Try Recconect to ExceriseManagement")); connectToExerciseManagement(m_port); break; } case AWSS_STATE::ConnectToParticipantManagement: case AWSS_STATE::RequestPartyInformation: { m_awss_state = AWSS_STATE::ConnectToParticipantManagement; emit statusMessage(tr("Try Recconect to ParticipantManagement")); connectToParticipantManagement(m_port); break; } case AWSS_STATE::ConnectToProxy: case AWSS_STATE::ConnectedToProxy: { m_awss_state = AWSS_STATE::ConnectToProxy; emit statusMessage(tr("Try Recconect to TrainingAreaBase Proxy for party:").arg(m_partyName)); connectToProxy(m_port, m_partyId, m_partyName); break; } default: DEBUG_LOG(m_logger) << "Disconnected during wrong connection State"; break; } } void WebSocketInterface::onDisconnected() { DEBUG_LOG(m_logger) << "On DisConnect: " ; emit statusMessage(tr("Discconected ")); // QTimer::singleShot(10000,this, &WebSocketInterface::onReconnect); } void WebSocketInterface::onError(QAbstractSocket::SocketError error) { DEBUG_LOG(m_logger) << "On Error: " << error; emit statusMessage(tr("got Socket Error: %1").arg(error)); QTimer::singleShot(10000,this, &WebSocketInterface::onReconnect); //onReconnect(); } } //namespace AdlerWebSocketSimulator