Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Proxies/TrainingAreaBase/Plugins/AdlerJson/ppm_handler.cpp
T
berrux-dev 598fc2560e Complete Qt6 migration: full clean build green across groups G1-G12 incl. runtime plugin set
new_docker_build.sh gains Group 12 (212 GUI/Data plugins); fixes LtsUtilsGuiDds visibility (LTO-stripped exports), LtsProjectionWorkstation unity name shadow, 6 unity-off dirs (dup file-scope statics, ddsftc INTERFACE sources) and reconfigures BUILD_FILTERMANAGEMENT/BUILD_PLUGINS_SERVICEMONITOR=ON
2026-10-20 09:36:57 +02:00

1095 lines
36 KiB
C++
Executable File

#include "ppm_handler.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <utility>
#include "Core/core.hpp"
#include <QtCore/QJsonDocument>
#include "json_dispatcher.h"
#include <QRandomGenerator>
#include <LtsUtils/LtsUtilsCore/dds_vector.h>
#include <ParticipantManagement/ppm.hpp>
namespace AdlerJson
{
static const int ADLER_OPERATIONAL = 125;
static const int ADLER_NOT_OPERATIONAL = 127;
PpmHandler::PpmHandler(QObject *parent)
: QObject(parent)
, m_sendParticipantDataTimer(new QTimer(this))
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
{
}
bool PpmHandler::init(MainDispatcher *mainDispatcher)
{
m_mainDispatcher = mainDispatcher;
m_ftcPpm = ParticipantManagement::Interface::Ftc::create(m_mainDispatcher->ddsHandler()->ddsConnector());
m_ftcPpm->enableModifyParticipantData();
m_ftcPpm->enableModifyPartyData();
m_ftcPpm->enableSetSimulatedPosition();
m_dtcPpm = ParticipantManagement::Interface::Dtc::create(m_mainDispatcher->ddsHandler()->ddsConnector());
DEBUG_LOG(m_logger) << "-------------<><><>------" << m_mainDispatcher->exerciseId();
if (!m_dtcPpm->enableParticipant() || !m_dtcPpm->enableDynamicParticipantData() || !m_dtcPpm->enableParticipantPosition())
{
ERROR_LOG(m_logger) << "Can not read data from Ppm";
return false;
}
m_dtcPpm->enableType();
m_dtcPpm->waitForHistoricalDataParticipant(2000);
m_dtcPpm->waitForHistoricalDataDynamicParticipantData(1000);
m_dtcPpm->waitForHistoricalDataParticipantPosition(1000);
m_sendParticipantDataTimer->setInterval(2 * 1000);
connect(m_sendParticipantDataTimer, &QTimer::timeout, this, &PpmHandler::onSendParticipantDataTimeout);
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::partyChanged, this, &PpmHandler::onPartyChanged);
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantChanged, this, &PpmHandler::onParticipantChanged);
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged, this, &PpmHandler::onParticipantPositionChanged);
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged, this, &PpmHandler::onDynamicParticipantDataChanged);
return true;
}
void PpmHandler::modifyPartyAdlerProperties(const int wsId,
const int assetId,
const int partyId,
const QString &saaName,
const QString &szenarName,
const ParticipantManagement::ConnectState &connectState,
const bool isVerbund)
{
DEBUG_LOG(m_logger) << "modifyParty"
<< " assetId=" << assetId << " partyId=" << partyId << " saaName=" << saaName << " szenarName=" << szenarName << " connectState=" << connectState
<< " isVerbund=" << isVerbund;
ParticipantManagement::Party requestParty;
requestParty = m_dtcPpm->party(partyId);
QJsonObject origObj = QJsonDocument::fromJson(requestParty.properties.c_str()).object();
QJsonObject adlerPropertiesObj = origObj[QStringLiteral("Adler")].toObject();
adlerPropertiesObj[QStringLiteral("saaConnectedState")] = static_cast<int>(connectState);
adlerPropertiesObj[QStringLiteral("szenarName")] = szenarName;
adlerPropertiesObj[QStringLiteral("saaName")] = saaName;
adlerPropertiesObj[QStringLiteral("wsId")] = wsId;
adlerPropertiesObj[QStringLiteral("assetId")] = ((connectState == ParticipantManagement::ConnectState::Connected) ? assetId : -1);
adlerPropertiesObj[QStringLiteral("isVerbund")] = isVerbund;
const QByteArray &propertiesBa = requestParty.properties.c_str();
QJsonParseError parserError;
QJsonDocument doc(QJsonDocument::fromJson(propertiesBa, &parserError));
if (parserError.error != QJsonParseError::NoError)
{
ERROR_LOG(m_logger) << "Error parsing json document: " << parserError.errorString() << " '" << propertiesBa << "'";
doc = QJsonDocument();
}
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
QJsonObject obj(doc.object());
obj[QStringLiteral("Adler")] = adlerPropertiesObj;
const QByteArray propertiesStr = QJsonDocument(obj).toJson(QJsonDocument::Compact);
requestParty.properties = propertiesStr.data();
m_ftcPpm->modifyPartyDataRequest(requestParty);
}
void PpmHandler::parseSQFS(const Feuerstellungsdaten &exSQFS, const int wsId)
{
DEBUG_LOG(m_logger) << "Start parse SQFS";
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByWs(wsId);
if (!saa)
{
ERROR_LOG(m_logger) << "SQ WS from SAA but SAA with id " << wsId << " not found";
return;
}
const QString &verein = exSQFS.feuereinheit.verein;
const ProjectDataManagement::L26_EffectingSystemType &internalType = exSQFS.typ;
int rndNmbr = QRandomGenerator::global()->generate();
ParticipantManagement::ParticipantData pUdata = findParticipantDataByInternalName(rndNmbr, verein, saa->getIsVerbund());
auto chargeMap = m_tempChargesMap.value(rndNmbr);
chargeMap.insert(verein, QVector<Geschoss>(exSQFS.geschosse));
m_tempChargesMap.insert(rndNmbr, chargeMap);
QMap<QString, ProjectDataManagement::L28_Status> readyMap;
readyMap.insert(verein, exSQFS.status);
m_tempReadyMessage.insert(rndNmbr, readyMap);
auto posdMap = m_tempPositionMap.value(rndNmbr);
AdlerJson::KoordinateMitHoehe middle;
middle.koordinate.longitude = exSQFS.mittelpunkt.koordinate.longitude;
middle.koordinate.latitude = exSQFS.mittelpunkt.koordinate.latitude;
posdMap.insert(verein, middle);
m_tempPositionMap.insert(rndNmbr, posdMap);
int superiorModId = 1000000007;
ParticipantManagement::Participant pUnit = findParticipantByInternalName(verein, saa->getPartyId(), saa->getIsVerbund());
if (pUdata.modId > 0)
{
m_sendParticipantDataTimer->start();
return;
}
if (pUnit.id > 0)
{
sendChargesFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
sendReadyMessageFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
sendPositionFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
m_tempChargesMap.remove(rndNmbr);
m_tempPositionMap.remove(rndNmbr);
m_tempinternalNameMap.remove(rndNmbr);
m_tempReadyMessage.remove(rndNmbr);
}
else
{
std::vector<ParticipantManagement::ParticipantData> list;
const ParticipantManagement::Type unitType = m_dtcPpm->getTypeFromAdlerType(waffensystemtypMap.key(internalType), true, saa->getIsVerbund());
const auto root = findRootUnit(saa->getPartyId());
if (root.id > 0)
{
DEBUG_LOG(m_logger) << "Append FS Unit to root Unit";
list.push_back(root);
}
ParticipantManagement::ParticipantData data = findParticipantDataByInternalName(rndNmbr, verein, saa->getIsVerbund());
data.id = 0;
data.partyId = saa->getPartyId();
data.externalId = 0;
data.hierarchyNumber = 1;
data.name = verein.toStdString();
data.designator = verein.toStdString();
data.symbol = unitType.symbol;
data.tacticalIdentifier = verein.toStdString();
data.typeId = unitType.id;
data.modId = superiorModId;
data.isDeleted = false;
data.isSimulated = false;
data.superiorModId = root.modId;
list.push_back(data);
ParticipantManagement::ModifyParticipantDataRequest newRequest;
newRequest.requestId = rndNmbr;
newRequest.data = list;
m_tempPartDataList.insert(rndNmbr, list);
m_ftcPpm->modifyParticipantDataRequest(newRequest, this);
}
}
void PpmHandler::parseSQWS(const Waffensystemdaten &exSQWS, const int wsId)
{
DEBUG_LOG(m_logger) << "Start parse SQWS";
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByWs(wsId);
if (!saa)
{
ERROR_LOG(m_logger) << "SQ WS from SAA but SAA with id " << wsId << " not found";
return;
}
const ProjectDataManagement::L27_EffectorId &internalName = exSQWS.kenner;
const ProjectDataManagement::L26_EffectingSystemType &internalType = exSQWS.typ;
const auto &charges = exSQWS.geschosse;
const QString &verein = exSQWS.einheit.verein;
int currentRandomNumber = QRandomGenerator::global()->generate();
ParticipantManagement::ParticipantData pUdata = findParticipantDataByInternalName(currentRandomNumber, verein, saa->getIsVerbund());
auto nameVec = m_tempinternalNameMap.value(currentRandomNumber);
nameVec.append(waffensystemkennerMap.key(internalName));
m_tempinternalNameMap.insert(currentRandomNumber, nameVec);
QMap<QString, QVector<Geschoss>> map = m_tempChargesMap.value(currentRandomNumber);
map.insert(waffensystemkennerMap.key(internalName), charges);
m_tempChargesMap.insert(currentRandomNumber, map);
ParticipantManagement::Participant pp = findParticipantByInternalName(waffensystemkennerMap.key(internalName), saa->getPartyId(), saa->getIsVerbund());
auto posMap = m_tempPositionMap.value(currentRandomNumber);
posMap.insert(waffensystemkennerMap.key(internalName), exSQWS.koordinate);
m_tempPositionMap.insert(currentRandomNumber, posMap);
if (pp.id > 0)
{
DEBUG_LOG(m_logger) << "Found Participant only update pos";
sendPositionFromTempMap(currentRandomNumber, saa->getPartyId(), saa->getIsVerbund());
sendChargesFromTempMap(currentRandomNumber, saa->getPartyId(), saa->getIsVerbund());
m_tempChargesMap.remove(currentRandomNumber);
m_tempPositionMap.remove(currentRandomNumber);
m_tempinternalNameMap.remove(currentRandomNumber);
m_randomNumbers.removeAll(currentRandomNumber);
}
else
{
const ParticipantManagement::Type type = m_dtcPpm->getTypeFromAdlerType(waffensystemtypMap.key(internalType), false, saa->getIsVerbund());
DEBUG_LOG(m_logger) << "found type with id: " << type.id << " for name: " << waffensystemtypMap.key(internalType);
if (type.id <= 0)
{
ERROR_LOG(m_logger) << "NO Type Found";
return;
}
std::vector<ParticipantManagement::ParticipantData> list = m_tempPartDataList.value(currentRandomNumber);
uint superiorModId = QRandomGenerator::global()->generate() / 2;
ParticipantManagement::Participant pUnit = findParticipantByInternalName(verein, saa->getPartyId(), saa->getIsVerbund());
DEBUG_LOG(m_logger) << "Looking for Verein: " << verein << " found Unit: " << pUnit.id << " foundData: " << pUdata.modId;
if (pUdata.modId > 0)
{
superiorModId = pUdata.modId;
DEBUG_LOG(m_logger) << "FOUND UNIT in list use their modId " << superiorModId << " RND: " << currentRandomNumber;
}
else if (pUnit.id > 0)
{
ParticipantManagement::ParticipantData pUData = m_dtcPpm->convertParticipantToParticipantData(pUnit);
pUData.modId = superiorModId;
pUData.hierarchyNumber = 1;
list.push_back(pUData);
m_tempPartDataList.insert(currentRandomNumber, list);
DEBUG_LOG(m_logger) << "CREATE Uit from ppm " << superiorModId << " RND: " << currentRandomNumber;
ParticipantManagement::Participant tmp = pUnit;
while (tmp.superiorId > 0)
{
tmp = m_dtcPpm->participant(tmp.superiorId);
pUData = m_dtcPpm->convertParticipantToParticipantData(tmp);
list.push_back(pUData);
}
}
else
{
const auto root = findRootUnit(saa->getPartyId());
if (root.id > 0)
{
DEBUG_LOG(m_logger) << "Append to Unit" << superiorModId << " RND: " << currentRandomNumber;
list.push_back(root);
}
const ParticipantManagement::Type unitType = m_dtcPpm->getTypeFromAdlerType(waffensystemtypMap.key(internalType), true, saa->getIsVerbund());
DEBUG_LOG(m_logger) << "CREATE NEW Unit use supId" << superiorModId << " RND: " << currentRandomNumber;
ParticipantManagement::ParticipantData data;
data.id = 0;
data.partyId = saa->getPartyId();
data.externalId = 0;
data.hierarchyNumber = 1;
data.name = verein.toStdString();
data.designator = verein.toStdString();
data.symbol = unitType.symbol;
data.tacticalIdentifier = verein.toStdString();
data.typeId = unitType.id;
data.modId = superiorModId;
data.isDeleted = false;
data.isSimulated = false;
data.superiorModId = root.modId;
list.push_back(data);
}
DEBUG_LOG(m_logger) << "Create new Participant"
<< " RND: " << currentRandomNumber;
ParticipantManagement::ParticipantData data;
data.id = 0;
data.partyId = saa->getPartyId();
data.externalId = 0;
data.hierarchyNumber = list.size();
data.name = waffensystemkennerMap.key(internalName).toStdString();
data.designator = waffensystemkennerMap.key(internalName).toStdString();
data.symbol = type.symbol;
data.tacticalIdentifier = verein.toStdString();
data.typeId = type.id;
data.modId = QRandomGenerator::global()->generate() / 2;
data.isDeleted = false;
data.isSimulated = false;
data.superiorModId = superiorModId;
list.push_back(data);
m_tempPartDataList.insert(currentRandomNumber, list);
m_randomNumbers.append(currentRandomNumber);
m_sendParticipantDataTimer->start();
}
}
void PpmHandler::parseSQLP(const Ladeplatzdaten &exSQLP, const int wsId)
{
DEBUG_LOG(m_logger) << "START parse SQLP";
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByWs(wsId);
if (!saa)
{
ERROR_LOG(m_logger) << "SQ LP from SAA but SAA with id " << wsId << " not found";
return;
}
const QString &verein = exSQLP.einheit.verein;
int rndNmbr = QRandomGenerator::global()->generate();
auto posdMap = m_tempPositionMap.value(rndNmbr);
posdMap.insert(verein, exSQLP.koordinate);
m_tempPositionMap.insert(rndNmbr, posdMap);
QMap<QString, QVector<Geschoss>> map;
map.insert(verein, QVector<Geschoss>(exSQLP.geschosse));
m_tempChargesMap.insert(rndNmbr, map);
auto nameVec = m_tempinternalNameMap.value(rndNmbr);
nameVec.append(verein);
m_tempinternalNameMap.insert(rndNmbr, nameVec);
ParticipantManagement::Participant pp = findParticipantByInternalName(verein, saa->getPartyId(), saa->getIsVerbund());
const ParticipantManagement::Type type = m_dtcPpm->getTypeFromAdlerType(QStringLiteral("LP"), false, saa->getIsVerbund());
if (pp.id > 0)
{
sendPositionFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
sendChargesFromTempMap(rndNmbr, saa->getPartyId(), saa->getIsVerbund());
m_tempChargesMap.remove(rndNmbr);
m_tempPositionMap.remove(rndNmbr);
m_tempinternalNameMap.remove(rndNmbr);
}
else
{
DEBUG_LOG(m_logger) << "Create new Participant LP";
std::vector<ParticipantManagement::ParticipantData> list;
const auto root = findRootUnit(saa->getPartyId());
if (root.id > 0)
{
DEBUG_LOG(m_logger) << "Append LP to Unit";
list.push_back(root);
}
ParticipantManagement::ParticipantData data;
data.id = 0;
data.partyId = saa->getPartyId();
data.externalId = 0;
data.hierarchyNumber = 1;
data.name = verein.toStdString();
data.designator = verein.toStdString();
data.symbol = type.symbol;
data.tacticalIdentifier = verein.toStdString();
data.typeId = type.id;
data.modId = 1000000001;
data.isDeleted = false;
data.isSimulated = false;
data.superiorModId = root.modId;
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
newRequest->requestId = rndNmbr;
list.push_back(data);
newRequest->data = list;
m_tempPartDataList.insert(rndNmbr, list);
m_ftcPpm->modifyParticipantDataRequest(*newRequest, this);
}
}
void PpmHandler::removeAllSAAParticipants(const int partyId)
{
const auto &participants = findAllSAAParticipants(partyId);
if (participants.isEmpty())
return;
ParticipantManagement::ModifyParticipantDataRequest req;
std::vector<ParticipantManagement::ParticipantData> list;
for (const auto &part : std::as_const(participants))
{
const ParticipantManagement::Type &participantType = m_dtcPpm->type(part.typeId);
bool isUnitType
= (participantType.typeClass == ParticipantManagement::TypeClass::Unit) || (participantType.typeClass == ParticipantManagement::TypeClass::SupportUnit);
if (isUnitType)
continue;
ParticipantManagement::ParticipantData pToDel;
pToDel.id = part.id;
pToDel.isDeleted = true;
list.push_back(pToDel);
}
req.data = list;
DEBUG_LOG(m_logger) << "Remove all participants (without Units): " << list.size();
m_ftcPpm->modifyParticipantDataRequest(req, this);
}
void PpmHandler::onCreateParticipant()
{
ParticipantManagement::ParticipantData data;
data.id = 0;
data.partyId = 3;
data.externalId = 0;
data.hierarchyNumber = 1;
data.name = "Noah Thiering";
data.designator = "Hund";
data.symbol = "AP6D|CMPL|10011000001308000000";
data.tacticalIdentifier = "14";
data.typeId = 177;
data.modId = 1000000001;
data.isDeleted = false;
data.isSimulated = false;
data.superiorModId = 0;
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
newRequest->requestId = 2;
std::vector<ParticipantManagement::ParticipantData> liste;
liste.push_back(data);
newRequest->data = liste;
m_ftcPpm->modifyParticipantDataRequest(*newRequest);
}
void PpmHandler::getParticipants()
{
if (!m_dtcPpm)
return;
for (const auto &participant : m_dtcPpm->participants())
{
onParticipantChanged(participant, DataModification::eAdded);
}
}
bool PpmHandler::isEqNumberInExercise(const int equipmentNumber) const
{
bool result = m_dtcPpm->participantIdByEquipmentNumber(equipmentNumber) > 0;
return result;
}
void PpmHandler::onParticipantChanged(const ParticipantManagement::Participant &participant, DataModification modType)
{
if (!participant.equipmentNumber.has_value())
{
for (auto it = m_participantIdsByEqNo.begin(); it != m_participantIdsByEqNo.end(); ++it)
if (it.value() == participant.id)
{
m_participantIdsByEqNo.remove(it.key());
break;
}
return;
}
if (participant.externalId > 0)
return;
QJsonObject headerJson;
headerJson[QStringLiteral("equipmentNumber")] = participant.equipmentNumber.get();
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
if (modType == DataModification::eRemoved)
{
m_participantIdsByEqNo.remove(participant.equipmentNumber.get());
QJsonObject telegram;
QJsonObject data;
data[QStringLiteral("header")] = headerJson;
telegram[QStringLiteral("data")] = data;
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaRemoveParticipant");
emit participantChanged(telegram);
return;
}
if (m_participantIdsByEqNo.contains(participant.equipmentNumber.get()))
{
if (m_participantIdsByEqNo[participant.equipmentNumber.get()] != participant.id)
{
for (auto it = m_participantIdsByEqNo.begin(); it != m_participantIdsByEqNo.end(); ++it)
if (it.value() == participant.id)
{
m_participantIdsByEqNo.remove(it.key());
break;
}
m_participantIdsByEqNo[participant.equipmentNumber.get()] = participant.id;
}
}
else
m_participantIdsByEqNo[participant.equipmentNumber.get()] = participant.id;
ParticipantManagement::DynamicParticipantData dynamicData = m_dtcPpm->dynamicParticipantData(participant.id);
ParticipantManagement::Party party = m_dtcPpm->party(participant.partyId);
ParticipantManagement::Type type = m_dtcPpm->type(participant.typeId);
ParticipantManagement::ParticipantPosition partPos = m_dtcPpm->participantPosition(participant.id);
QJsonObject telegram;
QJsonObject geoPositionObj;
geoPositionObj[QStringLiteral("lon")] = partPos.pos.lon;
geoPositionObj[QStringLiteral("lat")] = partPos.pos.lat;
geoPositionObj[QStringLiteral("z")] = partPos.pos.z;
QJsonObject data;
data[QStringLiteral("header")] = headerJson;
data[QStringLiteral("status")] = static_cast<int>(m_dtcPpm->youngestStateInformation(dynamicData.stateHistory).vulnerabilityState);
data[QStringLiteral("forceIdentifier")] = static_cast<int>(party.hlaForceIdentifier);
data[QStringLiteral("geoPosition")] = geoPositionObj;
telegram[QStringLiteral("data")] = data;
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaAddParticipant");
emit participantChanged(telegram);
}
void PpmHandler::onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &position, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
const bool participantIsExternal = m_dtcPpm->participant(position.participantId).externalId > 0;
if (participantIsExternal)
{
handleParticipantPositionChangedExternal(position);
}
else
{
handleParticipantPositionChangedInternal(position);
}
}
void PpmHandler::onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &dynPartData, DataModification modType)
{
if (modType == DataModification::eRemoved)
return;
ParticipantManagement::Participant part = m_dtcPpm->participant(dynPartData.participantId);
if (part.externalId > 0 || !part.equipmentNumber.has_value())
return;
QJsonObject telegram;
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaVulnerabilityStateChanged");
QJsonObject headerJson;
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber.get();
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
QJsonObject data;
data[QStringLiteral("header")] = headerJson;
data[QStringLiteral("status")] = static_cast<int>(m_dtcPpm->youngestStateInformation(dynPartData.stateHistory).vulnerabilityState);
telegram[QStringLiteral("data")] = data;
emit participantChanged(telegram);
}
void PpmHandler::onSendParticipantDataTimeout()
{
m_sendParticipantDataTimer->stop();
if (m_randomNumbers.empty())
ERROR_LOG(m_logger) << "Cant Send ParticipantData RandomNumbers is empty";
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
int currentRandomNumber = m_randomNumbers.first();
newRequest->requestId = currentRandomNumber;
newRequest->data = m_tempPartDataList.value(currentRandomNumber);
m_ftcPpm->modifyParticipantDataRequest(*newRequest, this);
}
void PpmHandler::handleParticipantPositionChangedExternal(const ParticipantManagement::ParticipantPosition &position)
{
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId);
const bool participantPreviouslyMounted = m_mountedParticipants.contains(part.equipmentNumber.get());
if (!participantPreviouslyMounted)
return;
const bool mountedOnOtherParticipant = position.mountedOn.has_value();
if (!mountedOnOtherParticipant)
{
sendParticipantUnmount(part);
return;
}
const bool newMountedParticipantIsExternal = m_dtcPpm->participant(position.mountedOn.get()).externalId != 0;
if (newMountedParticipantIsExternal)
{
m_mountedParticipants.remove(part.equipmentNumber.get());
}
}
void PpmHandler::handleParticipantPositionChangedInternal(const ParticipantManagement::ParticipantPosition &position)
{
DEBUG_LOG(m_logger) << "handleParticipantPositionChangedInternal";
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId);
const bool hasMountedParticipants = position.mountedParticipants.has_value() && position.mountedParticipants.get().size() > 0;
if (hasMountedParticipants)
{
const QVector<int32_t> mountedParticipantIds(position.mountedParticipants.get().begin(), position.mountedParticipants.get().end());
for (int mountedParticipantId : std::as_const(mountedParticipantIds))
{
ParticipantManagement::Participant mountedParticipant = m_dtcPpm->participant(mountedParticipantId);
const bool isExternal = mountedParticipant.externalId > 0;
const bool wasMountedOnThisPart = m_mountedParticipants.contains(mountedParticipant.equipmentNumber.get())
&& m_mountedParticipants[mountedParticipant.equipmentNumber.get()] == part.equipmentNumber.get();
if (!isExternal || wasMountedOnThisPart)
continue;
if (!part.equipmentNumber.has_value())
continue;
sendParticipantMount(mountedParticipant, part);
}
if (part.equipmentNumber.has_value())
{
sendParticipantPositionChanged(position);
}
}
}
void PpmHandler::sendParticipantMount(const ParticipantManagement::Participant &part, const ParticipantManagement::Participant &partToBeMounted)
{
m_mountedParticipants.insert(part.equipmentNumber.get(), partToBeMounted.equipmentNumber.get());
ERROR_LOG(m_logger) << "Mount Participant";
QJsonObject telegram;
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaParticipantMount");
QJsonObject headerJson;
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber.get();
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
QJsonObject data;
data[QStringLiteral("header")] = headerJson;
data[QStringLiteral("mountedOn")] = QJsonValue(partToBeMounted.equipmentNumber.get());
telegram[QStringLiteral("data")] = data;
emit participantMount(telegram);
}
void PpmHandler::sendParticipantUnmount(const ParticipantManagement::Participant &participant)
{
m_mountedParticipants.remove(participant.equipmentNumber.get());
DEBUG_LOG(m_logger) << "Unmount Participant";
QJsonObject telegram;
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaParticipantUnmount");
QJsonObject headerJson;
headerJson[QStringLiteral("equipmentNumber")] = participant.equipmentNumber.get();
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
QJsonObject data;
data[QStringLiteral("header")] = headerJson;
telegram[QStringLiteral("data")] = data;
emit participantUnmount(telegram);
}
void PpmHandler::sendParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &position)
{
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId);
QJsonObject telegram;
telegram[QStringLiteral("type")] = QStringLiteral("UFomHlaPositionChanged");
QJsonObject headerJson;
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber.get();
headerJson[QStringLiteral("timeStamp")] = m_mainDispatcher->ddsHandler()->partitionTime();
QJsonObject data;
data[QStringLiteral("header")] = headerJson;
data[QStringLiteral("lon")] = position.pos.lon;
data[QStringLiteral("lat")] = position.pos.lat;
data[QStringLiteral("z")] = position.pos.z;
telegram[QStringLiteral("data")] = data;
emit participantChanged(telegram);
}
void PpmHandler::onModifyParticipantDataReply(const Core::FunctionReplyObject &reply)
{
DEBUG_LOG(m_logger) << "Got Function Reply " << reply.str();
if (!reply.error())
{
if (!m_tempPartDataList.contains(reply.id()))
return;
const int partyId = m_tempPartDataList.value(reply.id()).data()->partyId;
if (!m_mainDispatcher->jsonDispatcher()->getSAAByParty(partyId))
return;
const bool isVerbund = m_mainDispatcher->jsonDispatcher()->getSAAByParty(partyId)->getIsVerbund();
DEBUG_LOG(m_logger) << "Got ModifyParticipant Reply SEND from temp Maps (partyId: " << partyId << " , isVerbund: " << isVerbund << ")";
if (m_tempPositionMap.contains(reply.id()))
sendPositionFromTempMap(reply.id(), partyId, isVerbund);
if (m_tempChargesMap.contains(reply.id()))
sendChargesFromTempMap(reply.id(), partyId, isVerbund);
if (m_tempReadyMessage.contains(reply.id()))
sendReadyMessageFromTempMap(reply.id(), partyId, isVerbund);
}
else
{
ERROR_LOG(m_logger) << "GOT ModifyParticipant Replay with error " << reply.translated();
}
m_tempChargesMap.remove(reply.id());
m_tempPositionMap.remove(reply.id());
m_tempinternalNameMap.remove(reply.id());
m_tempReadyMessage.remove(reply.id());
if (m_randomNumbers.contains(reply.id()))
{
m_randomNumbers.removeAll(reply.id());
if (!m_randomNumbers.isEmpty() && !m_sendParticipantDataTimer->isActive())
m_sendParticipantDataTimer->start();
}
m_tempPartDataList.remove(reply.id());
}
void PpmHandler::onModifyPartyDataReply(const Core::FunctionReplyObject &reply) { DEBUG_LOG(m_logger) << "Got Function Reply " << reply.str(); }
QList<ParticipantManagement::Participant> PpmHandler::findAllSAAParticipants(const int partyId)
{
QList<ParticipantManagement::Participant> ret;
const auto &list = m_dtcPpm->participants();
for (const auto &part : std::as_const(list))
{
if (part.partyId != partyId || part.isDeleted)
continue;
if (!m_dtcPpm->isArtilleryType(part.typeId))
continue;
if (part.name.empty())
continue;
ret.append(part);
}
return ret;
}
ParticipantManagement::ParticipantData PpmHandler::findParticipantDataByInternalName(int &randomNumberInOut, const QString &internalName, const bool isVerbund)
{
ParticipantManagement::ParticipantData ret;
for (const auto &randomNumber : m_tempPartDataList.keys())
{
for (const auto &part : m_tempPartDataList.value(randomNumber))
{
if (part.name != internalName.toStdString())
continue;
if (m_dtcPpm->isAdlerVerbund(part.typeId) != isVerbund)
continue;
randomNumberInOut = randomNumber;
return part;
}
}
return ret;
}
ParticipantManagement::ParticipantData PpmHandler::findRootUnit(const int partyId)
{
ParticipantManagement::ParticipantData ret;
const auto &list = m_dtcPpm->participants();
for (const auto &part : std::as_const(list))
{
if (part.partyId != partyId || part.isDeleted)
continue;
if (m_dtcPpm->type(part.typeId).typeClass != ParticipantManagement::TypeClass::Unit)
continue;
if (m_dtcPpm->isArtilleryType(part.typeId))
continue;
if (part.superiorId > 0)
continue;
ret = m_dtcPpm->convertParticipantToParticipantData(part);
}
return ret;
}
ParticipantManagement::Participant PpmHandler::findParticipantByInternalName(const QString &internalName, const int partyId, const bool isVerbund)
{
ParticipantManagement::Participant pp;
DEBUG_LOG(m_logger) << "START find participant: " << internalName;
auto participantMap = m_dtcPpm->participants();
for (const auto &part : std::as_const(participantMap))
{
if (part.partyId != partyId || part.isDeleted)
continue;
if (!m_dtcPpm->isArtilleryType(part.typeId))
continue;
if (m_dtcPpm->isAdlerVerbund(part.typeId) != isVerbund)
continue;
if (part.name != internalName.toStdString())
continue;
pp = part;
}
return pp;
}
void PpmHandler::onPartyChanged(const ParticipantManagement::Party &data, DataModification modType)
{
DEBUG_LOG(m_logger) << Q_FUNC_INFO << ", modType: " << modType;
if (modType == DataModification::eRemoved)
return;
const ParticipantManagement::ConnectState connectState = m_dtcPpm->saaConnectedState(data.id);
DEBUG_LOG(m_logger) << "++++ connectState: " << connectState;
if (connectState != ParticipantManagement::ConnectState::Disconnecting)
return;
auto saa = m_mainDispatcher->jsonDispatcher()->getSAAByParty(data.id);
if (!saa)
return;
DEBUG_LOG(m_logger) << "++++ szenarName: " << saa->getSzenarName() << ", wsId: " << saa->getWsId();
EXStatus status;
status.status = Szenarstatus::Gestoppt;
m_mainDispatcher->jsonDispatcher()->onSAAStatus(saa->getWsId(), status);
m_mainDispatcher->jsonDispatcher()->onSAADeregistration(saa->getWsId(), data.id);
}
void PpmHandler::sendPositionFromTempMap(int rndNmbr, const int partyId, const bool isVerbund)
{
const QMap<QString, KoordinateMitHoehe> posMap = m_tempPositionMap.value(rndNmbr);
const QList<QString> partList;
const auto &nameVec = m_tempinternalNameMap.value(rndNmbr);
QMapIterator<QString, KoordinateMitHoehe> it(posMap);
while (it.hasNext())
{
it.next();
ParticipantManagement::Participant pp = findParticipantByInternalName(it.key(), partyId, isVerbund);
if (pp.id <= 0)
return;
TrainingAreaBase::EquipmentPosition equipPosReq;
Core::GeoPosition tlnPos;
TrainingAreaBase::TabPosition tabPos;
tlnPos.lat = it.value().koordinate.latitude * (M_PI / 180.0);
tlnPos.lon = it.value().koordinate.longitude * (M_PI / 180.0);
tabPos.position = tlnPos;
tabPos.reportingSource = Core::PositionReportingSource::SetByOperator;
equipPosReq.sampleTime = m_mainDispatcher->ddsHandler()->partitionTime();
equipPosReq.position = tabPos;
equipPosReq.equipmentNumber = -1 * pp.id;
m_mainDispatcher->ddsHandler()->dtsTab()->publish(equipPosReq);
}
}
void PpmHandler::sendChargesFromTempMap(const int rndNmbr, const int partyId, const bool isVerbund)
{
if (!isVerbund)
return;
const auto &charges = m_tempChargesMap.value(rndNmbr);
const ParticipantManagement::Type type = m_dtcPpm->getTypeFromAdlerType(QStringLiteral("LP"), false, isVerbund);
for (const auto &charge : charges.toStdMap())
{
TrainingAreaBase::EquipmentGearChargeState gearChargeState;
TrainingAreaBase::GearCharge gc;
ParticipantManagement::Participant participant = findParticipantByInternalName(charge.first, partyId, isVerbund);
const QVector<Geschoss> geschosse = sumUpAnzahlForSameGeschoss(charge.second);
for (auto c : geschosse)
{
int chargeTypeId = m_mainDispatcher->pdmHandler()->getDtc()->getChargeTypeIdFromAdlerCharges(c.geschosssorte);
if (chargeTypeId <= 0)
continue;
DEBUG_LOG(m_logger) << "---- participant.id:" << participant.id << (participant.typeId == type.id ? " (Ladeplatz)" : "");
QVector<int> gearTypesIds = m_mainDispatcher->pdmHandler()->getDtc()->gearTypeIdFromChargeTypeId(chargeTypeId);
gc.gearTypeId = !gearTypesIds.isEmpty() ? gearTypesIds.first() : 0;
gc.gearId = participant.id;
gc.chargeTypeId = chargeTypeId;
gc.remain = c.anzahl;
gearChargeState.charge.push_back(gc);
}
gearChargeState.sampleTime = m_mainDispatcher->ddsHandler()->partitionTime();
gearChargeState.equipmentNumber = -1 * participant.id;
m_mainDispatcher->ddsHandler()->dtsTab()->publish(gearChargeState);
}
m_tempChargesMap.remove(rndNmbr);
}
void PpmHandler::sendReadyMessageFromTempMap(int rndNmbr, const int partyId, const bool isVerbund)
{
const auto &readyMap = m_tempReadyMessage.value(rndNmbr);
for (const auto &readyMsg : readyMap.toStdMap())
{
ParticipantManagement::Participant participant = findParticipantByInternalName(readyMsg.first, partyId, isVerbund);
TrainingAreaBase::SpecialSensorData ssData;
ssData.sampleTime = m_mainDispatcher->ddsHandler()->partitionTime();
ssData.operationalState = convertStatus_L28(readyMsg.second);
ssData.equipmentNumber = -1 * participant.id;
m_mainDispatcher->ddsHandler()->dtsTab()->publish(ssData);
}
m_tempReadyMessage.remove(rndNmbr);
}
int PpmHandler::convertStatus_L28(const ProjectDataManagement::L28_Status &status)
{
switch (status)
{
case ProjectDataManagement::L28_Status::Einsatzbereit:
return ADLER_OPERATIONAL;
case ProjectDataManagement::L28_Status::NichtEinsatzbereit:
return ADLER_NOT_OPERATIONAL;
default:
WARNING_LOG(m_logger) << "Status " << status << " not handled in switch";
break;
}
return -1;
}
QVector<Geschoss> PpmHandler::sumUpAnzahlForSameGeschoss(const QVector<Geschoss> &geschosse) const
{
using GeschossInfo = std::tuple<QString, QString, QString>;
QMap<GeschossInfo, Geschoss> summedUpGeschosseMap;
for (const Geschoss &geschoss : geschosse)
{
const GeschossInfo geschossInfo(geschoss.geschosssorte, geschoss.ladung, geschoss.zuender);
if (summedUpGeschosseMap.contains(geschossInfo))
{
summedUpGeschosseMap[geschossInfo].anzahl += geschoss.anzahl;
continue;
}
summedUpGeschosseMap.insert(geschossInfo, geschoss);
}
return summedUpGeschosseMap.values().toVector();
}
}