- 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>
350 lines
13 KiB
C++
Executable File
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
|