Files
qt5-legatus-legacy/Lts/Proxies/TrainingAreaBase/Plugins/AdlerJson/json_handler_rx.cpp
T
torstenandCopilot 3028302f7b Qt6 Migration: Merge latest Qt5 devel content and apply migration fixes
- Merged 292 changed files from dlbo snapshot
- Fixed IDL enum collisions (PortType, PdmEventType)
- Fixed Grantlee template for C++11 scoped enums
- Fixed CMake VERSION_GREATER syntax
- Added missing directories (THP, LtsRestClient, etc.)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-15 18:20:51 +00:00

350 lines
13 KiB
C++
Executable File

/**
* @RDE_HEADER@
* JsonHandlerRx for AdlerJson Plugin
* $Id: hla_handler_rx.cpp 62899 2024-05-29 11:08:50Z ewert_j $
* $HeadURL: svn://slssvn/TDS/branches/product/features/ufom/Lts/Proxies/TrainingAreaBase/Plugins/AdlerJson/hla_handler_rx.cpp $
* $Author: ewert_j $
* Created by Julius Ewert, ESIM, 2024-03-20
*/
#include "json_handler_rx.h"
#include "aes_handler.h"
#include "json_dispatcher.h"
#include "ppm_handler.h"
#include "telegrams.h"
#include <QJsonDocument>
namespace AdlerJson
{
JsonHandlerRx::JsonHandlerRx(const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
JsonDispatcher *dispatcher,
AesHandler *aesHandler,
PpmHandler *ppmHandler)
: m_rxHandler(recvFromTabCb)
, m_txHandler(sendToTabCb) // std::static_pointer_cast<TrainingAreaBase::SendToTab>(sendToTabCb))
, m_dispatcher(dispatcher)
, m_bWarnedOnce(false)
, m_bWarnedOnceTx(false)
, m_aesHandler(aesHandler)
, m_ppmHandler(ppmHandler)
, m_logger(getLogger("JsonHandlerRx"))
{
}
bool JsonHandlerRx::handleTelegram(int wsId, const QJsonObject &telegram, int &errorcode)
{
errorcode = 0;
using namespace TrainingAreaBase::TetraIcd;
if (!telegram.contains(JsonKeys::TYPE_ID()))
{
ERROR_LOG(m_logger) << "telegram not contains typeId";
}
const int typeId = telegram[JsonKeys::TYPE_ID()].toInt();
const QString typeName = telegram[JsonKeys::TYPE()].toString();
const QString uuid = telegram[JsonKeys::UUID_()].toString();
const QString referenceUuid = telegram[JsonKeys::REFERENCE_UUID()].toString();
INFO_LOG(m_logger) << "[handleTelegram] typeId=" << typeId << " typeName=" << typeName << " uuid=" << uuid << " referenceUuid=" << referenceUuid;
try
{
switch (typeId)
{
case AdlerJson::TelegramIds::EX_REGISTRATION_REQUEST(): // EX-Anmeldung
{
QJsonObject dataObj = telegram[JsonKeys::DATA()].toObject();
int partyId = dataObj.value(JsonKeys::PARTY_ID()).toInt(0);
QString saaName = telegram[JsonKeys::SENDER()].toString();
QString szenarName = dataObj.value(JsonKeys::SZENAR()).toString();
bool isVerbund = dataObj.value(JsonKeys::ADLER_VERBUND()).toBool();
m_dispatcher->onSAARegistration(wsId, partyId, saaName, szenarName, isVerbund, uuid);
WARNING_LOG(m_logger) << "On Register ------------------- partyId= " << partyId << ", saaName= " << saaName << ", szenarName= " << szenarName
<< ", isVerbund= " << isVerbund << ", wsId= " << wsId;
break;
}
case TelegramIds::EX_DEREGISTRATION_REQUEST(): // EX-Abmeldung
{
const int partyId = telegram[JsonKeys::DATA()].toObject().value(JsonKeys::PARTY_ID()).toInt(0);
m_dispatcher->onSAADeregistration(wsId, partyId);
WARNING_LOG(m_logger) << "[EX_DEREGISTRATION_REQUEST] EX-Abmeldung -------------------------------------";
break;
}
case TelegramIds::EX_CONNECTION_TEST_REQUEST(): // EX-Verbindungsanfrage
{
DEBUG_LOG(m_logger) << "[EX_CONNECTION_TEST_REQUEST] EX-Verbindungsanfrage -------------------------------------";
m_dispatcher->onSAAConnectionTest(wsId, uuid);
break;
}
case TelegramIds::EX_STATUS(): // EX-Status
{
WARNING_LOG(m_logger) << "[EX_STATUS] EX-Status -------------------------------------";
auto data = telegram[JsonKeys::DATA()];
const QString status = data.toObject().value(JsonKeys::STATUS()).toString(QStringLiteral(""));
EXStatus exStatus;
exStatus.status = strToSzenarstatus(status);
m_dispatcher->onSAAStatus(wsId, exStatus);
break;
}
case TelegramIds::EX_TQ(): // Technische Quittierung
{
WARNING_LOG(m_logger) << "[EX_TQ] Technische Quittierung -------------------------------------";
const auto data = telegram[JsonKeys::DATA()].toObject();
bool bOk = true;
TechnischeDaten technischeDaten;
AdlerJson::technischeDatenFromJson(data, technischeDaten, bOk);
m_dispatcher->onSAAExceptionStatus(wsId, technischeDaten);
break;
}
case TelegramIds::EX_FIRE(): // EX-FQ(FN) Feuern
{
WARNING_LOG(m_logger) << "[EX-FQ(FN)] EX-Feuern -------------------------------------";
auto data = telegram[JsonKeys::DATA()].toObject();
bool bOk = true;
Feuerkampfdaten exFire;
feuerkampfdatenFromJson(data, exFire, bOk);
// send to AES
m_aesHandler->handleEXFire(exFire, wsId);
break;
}
case TelegramIds::EX_AWES_PLANNING(): // EX-FQ(BA-BB-FK) Wirkfeldplanung
{
WARNING_LOG(m_logger) << "[EX_AWES_PLANNING] EX-FQ(BA-BB-FK) Wirkfeldplanung";
auto data = telegram[JsonKeys::DATA()].toObject();
WirkfeldplanungData wirkfeldplanungData;
bool bOk = true;
wirkfeldplanungDataFromJson(data, wirkfeldplanungData, bOk);
DEBUG_LOG(m_logger) << "\n-------------------"
<< "\nwirkfeldplanungData"
<< "\n dauer: " << wirkfeldplanungData.dauer << "\n abfeuerungsArt: " << static_cast<int>(wirkfeldplanungData.abfeuerungsArt)
<< "\n feuerkampfReferenz: '" << wirkfeldplanungData.feuerkampfReferenz << "'"
<< "\n verein: '" << wirkfeldplanungData.feuerkommando.verein << "'"
<< "\n bOk: " << bOk << "\n-------------------";
m_aesHandler->handleEffectCluster(wirkfeldplanungData, wsId);
break;
}
case TelegramIds::EX_POSITION_REPORT_WEAPON(): // Only sent by SAA ( Ex-SQ(WS) Stellungsmeldung Waffensystem)
{
DEBUG_LOG(m_logger) << "[EX_POSITION_REPORT_WEAPON] Ex-SQ(WS) Stellungsmeldung Waffensystem";
auto data = telegram[JsonKeys::DATA()].toObject();
Waffensystemdaten exSQWS;
bool bOk = true;
waffensystemdatenFromJson(data, exSQWS, bOk);
if (!bOk)
{
ERROR_LOG(m_logger) << "Received Ex-SQ(WS) but couldn't parse the jsondata ";
break;
}
m_dispatcher->onSAASQWS(wsId, exSQWS);
break;
}
case TelegramIds::EX_POSITION_REPORT_FIRE(): // Only sent by SAA ( Ex-SQ(FS) Stellungsmeldung Feuerstellung)
{
DEBUG_LOG(m_logger) << "[EX_POSITION_REPORT_FIRE] Ex-SQ(FS) Stellungsmeldung Feuerstellung";
auto data = telegram[JsonKeys::DATA()].toObject();
Feuerstellungsdaten exSQFS;
bool bOk = true;
feuerstellungsdatenFromJson(data, exSQFS, bOk);
if (!bOk)
{
ERROR_LOG(m_logger) << "Received Ex-SQ(FS) but couldn't parse the jsondata ";
break;
}
m_dispatcher->onSAASQFS(wsId, exSQFS);
break;
}
case TelegramIds::EX_POSITION_REPORT_LOADING_PLACE(): // sent by SAA+EXCON ( EX-SQ(LP)Stellungsmeldung Ladeplatz)
{
DEBUG_LOG(m_logger) << "[EX_POSITION_REPORT_LOADING_PLACE] EX-SQ(LP)Stellungsmeldung Ladeplatz";
auto data = telegram[JsonKeys::DATA()].toObject();
Ladeplatzdaten exSQLP;
bool bOk = true;
ladeplatzdatenFromJson(data, exSQLP, bOk);
if (!bOk)
{
ERROR_LOG(m_logger) << "Received Ex-SQ(LP) but couldn't parse the jsondata ";
break;
}
m_dispatcher->onSAASQLP(wsId, exSQLP);
break;
}
case TelegramIds::EX_FLUGBAHNDATEN(): // sent by SAA (EX-Flugbahndaten)
{
DEBUG_LOG(m_logger) << "[EX_FLUGBAHNDATEN] EX-Flugbahndaten";
auto data = telegram[JsonKeys::DATA()].toObject();
Flugbahndaten flugbahndaten;
bool bOk = true;
flugbahndatenFromJson(data, flugbahndaten, bOk);
if (!bOk)
{
ERROR_LOG(m_logger) << "Received EX-Flugbahndaten but couldn't parse the jsondata ";
break;
}
DEBUG_LOG(m_logger) << "Vor onSAATrajectoryData wsId=" << wsId;
if (static_cast<int>(flugbahndaten.fehlercode) == 0)
m_dispatcher->onSAATrajectoryData(wsId, flugbahndaten, referenceUuid);
else
errorcode = static_cast<int>(flugbahndaten.fehlercode);
break;
}
case TelegramIds::EX_GUIDING_LINES(): // sent by SAA ( EX-HQ(K) Koordinierungsmassnahmen)
{
DEBUG_LOG(m_logger) << "[EX_GUIDING_LINES] EX-HQ Koordinierungsmassnahmen";
auto data = telegram[JsonKeys::DATA()].toObject();
const QString artStr = data.value(JsonKeys::ART()).toString(QStringLiteral("Koordinierungsmassnahmen"));
Koordinierungsdaten koordinierungsdaten;
bool bOk = true;
koordinierungsdatenFromJson(data, koordinierungsdaten, bOk);
if (koordinierungsdaten.name.isEmpty())
koordinierungsdaten.name = QString(QStringLiteral("%1 - %2")).arg(typeName).arg(artStr);
else
koordinierungsdaten.name = QString(QStringLiteral("%1 - %2")).arg(typeName).arg(koordinierungsdaten.name);
m_dispatcher->onSAAHXGuidingLines(wsId, koordinierungsdaten);
break;
}
case TelegramIds::EX_GUIDING_LINES_AND_BOUNDARIES(): // sent by SAA ( EX-HQ(G)Fuehrungslinien und Grenzen)
{
DEBUG_LOG(m_logger) << "[EX_GUIDING_LINES_AND_BOUNDARIES] EX-HQ(G)Fuehrungslinien und Grenzen ";
auto data = telegram[JsonKeys::DATA()].toObject();
const QString artStr = data.value(JsonKeys::ART()).toString(QStringLiteral("Fuehrungslinien und Grenzen"));
Fuehrungsdaten fuehrungsdaten;
bool bOk = true;
fuehrungsdatenFromJson(data, fuehrungsdaten, bOk);
if (fuehrungsdaten.name.isEmpty())
fuehrungsdaten.name = QString(QStringLiteral("%1 - %2")).arg(typeName).arg(artStr);
else
fuehrungsdaten.name = QString(QStringLiteral("%1 - %2")).arg(typeName).arg(fuehrungsdaten.name);
m_dispatcher->onSAAHXGuidingLinesAndBoundaries(wsId, fuehrungsdaten);
break;
}
case TelegramIds::EX_FIRE_HALT(): // sent by SAA (EX-FH Feuerhalt)
{
WARNING_LOG(m_logger) << "[EX_FIRE_HALT] Feuerhalt";
auto data = telegram[QStringLiteral("data")].toObject();
bool bOk = true;
FeuerHaltDaten feuerhaltdaten;
feuerHaltDatenFromJson(data, feuerhaltdaten, bOk);
m_dispatcher->onSSAEXFIREHALT(wsId, feuerhaltdaten);
break;
}
case TelegramIds::EX_DONT_FIRE(): // send by SAA EX-FQ(nFN)
{
WARNING_LOG(m_logger) << "[EX_DONT_FIRE] Dont Fire";
auto data = telegram[QStringLiteral("data")].toObject();
bool bOk = true;
Feuerkampfdaten feuerkampfdaten;
exNichtFeuernFromJson(data, feuerkampfdaten, bOk);
m_aesHandler->handleEXDontFire(feuerkampfdaten, wsId);
break;
}
default:
{
WARNING_LOG(m_logger) << "Cant handle Telegram typeId=" << typeId;
}
}
}
catch (const std::exception &e)
{
WARNING_LOG(m_logger) << "Could not parse json: " << e.what() << " (" << ")";
return false;
}
return true;
}
bool JsonHandlerRx::handleTelegram(const QByteArray &baJson)
{
DEBUG_LOG(m_logger) << "JsonHandlerRx::handleTelegram";
if (baJson.isEmpty())
return false;
const QJsonObject obj = QJsonDocument::fromJson(baJson).object();
const QJsonValue typeId = obj.value(QStringLiteral("typeId"));
if (!typeId.isDouble())
{
ERROR_LOG(m_logger) << "Can not read type id: " << baJson;
return false;
}
const QJsonObject data = obj.value(QStringLiteral("data")).toObject();
if (typeId.toInt() != 21)
ERROR_LOG(m_logger) << "Telegram before filter: " << baJson;
try
{
QJsonValue header = data[QStringLiteral("header")];
QJsonObject obj = header.toObject();
ERROR_LOG(m_logger) << "Telegram header: " << obj.count();
if (!obj.isEmpty())
{
int eqNo = obj[QStringLiteral("equipmentNumber")].toInt(0);
if (eqNo <= 0)
return false;
if (!checkExercise(eqNo))
return false;
}
if (typeId.toInt() != 21)
ERROR_LOG(m_logger) << "Telegram after filter: " << baJson;
}
catch (const std::exception &e)
{
WARNING_LOG(m_logger) << "Could not parse json: " << e.what() << " (" << baJson << ")";
return false;
}
return true;
}
bool JsonHandlerRx::checkExercise(int equipmentNumber) const { return m_ppmHandler->isEqNumberInExercise(equipmentNumber); }
template <typename T> void JsonHandlerRx::rxData(const T &data)
{
if (!m_rxHandler)
{
if (!m_bWarnedOnce)
{
ERROR_LOG(m_logger) << "No RecvFromTab available";
m_bWarnedOnce = true;
}
return;
}
emit m_dispatcher->jsonTelegramReceived(&data);
return m_rxHandler->rxData(data);
}
template <typename T> void JsonHandlerRx::txData(const T &data)
{
if (!m_txHandler)
{
if (!m_bWarnedOnceTx)
{
ERROR_LOG(m_logger) << "No RecvFromTab available";
m_bWarnedOnceTx = true;
}
return;
}
emit m_dispatcher->jsonTelegramReceived(&data);
m_txHandler->txData(data);
}
} // namespace AdlerJson