Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Proxies/TrainingAreaBase/send_to_dds.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

1402 lines
49 KiB
C++
Executable File

#include "send_to_dds.h"
#include <utility>
#include "main_handler.h"
#include "settings.h"
#include <DDS/DTS/generic_dts.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QtCore/QTimer>
namespace TrainingAreaBase
{
static constexpr const int s_PartyIdOffset = 1;
SendToDds::SendToDds(MainHandler *mainHandler)
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger())
, m_mainHandler(mainHandler)
, m_dtsTab(mainHandler->ddsHandler()->dtsTab())
, m_aesStateHandler(m_mainHandler->aesHandler() ? mainHandler->aesHandler()->aesStateHandler() : nullptr)
, m_aesHandler(m_mainHandler->aesHandler())
, m_posHandler(mainHandler->posHandler())
{}
template<typename S, typename T>
static inline void assignBase(const S &src, T &dest)
{
dest.equipmentNumber = src.header.equipmentNumber;
dest.sampleTime = src.header.timeStamp;
}
void SendToDds::rxData(const TetraIcd::ManipulationReport &inData)
{
TrainingAreaBase::EquipmentOperationalState outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.isManipulation = inData.isManipulation;
outData.equipmentFunctionId = inData.equipmentFunctionId;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentOperationalState &inData)
{
TrainingAreaBase::EquipmentOperationalState outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.nbcProtectionActive = inData.nbcProtectionActive;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentConfigurationReport &inData)
{
TrainingAreaBase::EquipmentConfigurationReport outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.equipmentNumber = inData.equipmentNumber;
outData.canStartupTime = inData.canStartUpTime;
outData.equipmentType = inData.equipmentType;
outData.loginWaittimeBitweenTrys = inData.loginWaittimeBitweenTrys;
outData.loginMaxRetryCount = inData.loginMaxRetryCnt;
outData.loginMasteringFlag = inData.loginMasteringFlag;
outData.canDeviceConfiguration = inData.canDeviceConfiguration;
outData.displayDeviceVoiceOutput = inData.displayDeviceVoiceOutput;
outData.displayDeviceLanguage = static_cast<ProjectDataManagement::LanguageConfiguration>(inData.displayDeviceLanguage);
outData.pyrotechnics = inData.pyrotechnics;
outData.mineHandgrenadeSensorMode = static_cast<TrainingAreaBase::MineHandgrenadeSensorMode>(inData.mhgrsMode);
outData.mineHandgrenadeSensorEnergySaving = inData.mhgrsEnergySaving;
outData.firMode = static_cast<TrainingAreaBase::FirMode>(inData.specialSensorFir);
outData.minelayerMode = static_cast<TrainingAreaBase::MinelayerMode>(inData.specialSensorMinelayer);
outData.specialSensorStandard = static_cast<TrainingAreaBase::SpecialSensorStandardMode>(inData.specialSensorStandard);
outData.agdusHwMode = static_cast<TrainingAreaBase::AgdusHwMode>(inData.agdusHwMode);
outData.positionUpdateIntervall = static_cast<TrainingAreaBase::PositionUpdateIntervall>(inData.positionUpdateInterval);
outData.displayTextMainGroup = inData.displayTextMainGroup;
outData.displayTextSubGroup = inData.displayTextSubGroup;
outData.vulnerabilityModelAgdus = inData.vulnerabilityModelAgdus;
outData.vulnerabilityModelMineIed = inData.vulnerabilityModelMineIed;
outData.vulnerabilityModelAreaFire = inData.vulnerabilityModelAreaFire;
outData.vulnerabilityModelOperatingResource = inData.vulnerabilityModelOperatingResource;
outData.vulnerabilityModelACWeaponry = inData.vulnerabilityModelAcWeaponry;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::CtaDataError &inData)
{
TrainingAreaBase::CtaDataError outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.reason = static_cast<ProjectDataManagement::DataErrorReason>(inData.reason);
outData.originTelegramId = inData.originTelegramId;
publish(outData);
}
template <typename S, typename T>
void setOptionalBuildingRoomId(S &in, const T &out)
{
if (out > 0)
in = out;
}
void SendToDds::rxData(const TetraIcd::PositionReport &inData)
{
TrainingAreaBase::EquipmentPosition outData;
checkTimeStamp(inData);
assignBase(inData, outData);
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
{
ctasErrorPosition(inData);
return;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::PositionReportWithMountedEquipments &inData)
{
TrainingAreaBase::EquipmentPosition outData;
checkTimeStamp(inData);
assignBase(inData, outData);
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
{
ctasErrorPosition(inData);
return;
}
outData.mountedParticipants = inData.mountedEquipments;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::MineTriggered &inData)
{
TrainingAreaBase::MineTriggered outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.mineAreaId = inData.mineAreaId;
outData.mineIndex = inData.mineIndex;
if (inData.chargeTypeId != 0)
outData.chargeTypeId = inData.chargeTypeId;
if (inData.relPositionValid)
{
if (!setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
}
publish(outData);
}
template<typename S, typename T>
static inline void assignIedBaseData(const S &inData, T &outData)
{
assignBase(inData, outData);
outData.iedId = inData.iedId;
outData.tacticalState = static_cast<int>(inData.tacticalState);
outData.statePyrotechnics = inData.statePyrotechnics;
}
void SendToDds::rxData(const TetraIcd::DefinitionIed &inData)
{
TrainingAreaBase::DefinitionIed outData;
checkTimeStamp(inData);
assignIedBaseData(inData, outData);
if (!setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
outData.type = static_cast<int>(inData.iedType);
outData.remoteTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::Remote)) ? true : false;
outData.switchTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::Switch)) ? true : false;
outData.lightBarrierTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::LightBarrier)) ? true : false;
outData.tautWireTrigger = (inData.trigger & static_cast<int>(TetraIcd::DefinitionIed::TriggerTypes::TautWire)) ? true : false;
outData.explosiveForce = inData.explosiveForce;
outData.pairingState = static_cast<int>(inData.pairingState);
if (inData.pairingState != TrainingAreaBase::TetraIcd::IedPairingState::NotPaired)
outData.pairedId = inData.pairedId;
if (inData.partyId != 0)
outData.partyId = inData.partyId + s_PartyIdOffset;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::StateIed &inData)
{
TrainingAreaBase::StateIed outData;
checkTimeStamp(inData);
assignIedBaseData(inData, outData);
outData.batteryWarnings = inData.batteryWarnings;
outData.errorStateElectronics = static_cast<int>(inData.errorStateElectronics);
outData.errorStatePyrotechnics1 = static_cast<int>(inData.errorStatePyrotechnics1);
outData.errorStatePyrotechnics2 = static_cast<int>(inData.errorStatePyrotechnics2);
outData.errorStatePyrotechnics3 = static_cast<int>(inData.errorStatePyrotechnics3);
publish(outData);
}
void SendToDds::rxData(const TetraIcd::DusSingleMineState &inData)
{
TrainingAreaBase::DusSingleMineState outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.mineId = inData.mineId;
outData.effectStart = inData.effectStart;
setPosition2d(outData, inData.relPosition);
outData.chargeTypeId = inData.chargeTypeId;
outData.state = inData.state;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::StateChangeDirect &inData)
{
if (Settings::laserRangeCode() == inData.chargeTypeId)
{
DEBUG_LOG(m_logger) << "laserRangeCode chargeTypeId=" << inData.chargeTypeId
<< "vulnerabilityState=" << static_cast<int>(inData.vulnerabilityState);
return;
}
TrainingAreaBase::EquipmentState outData;
checkTimeStamp(inData);
if (!assignStateChangeBase(inData, outData))
return;
const auto ct(pdm()->chargeTypeFromId(inData.chargeTypeId));
if (!pdm()->isIndirect(inData.chargeTypeId))
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
ctasErrorPosition(inData);
const auto gearClass(pdm()->gearClassFromChargeTypeId(inData.chargeTypeId));
if (gearClass == ProjectDataManagement::GearClass::GearClass_MineSingle ||
gearClass == ProjectDataManagement::GearClass::GearClass_MineArea)
{
TetraIcd::MineTriggered mt;
mt.header.timeStamp = inData.header.timeStamp;
if (outData.position.has_value())
{
const TrainingAreaBase::TabPosition pos = outData.position.get();
mt.relPosition = m_posHandler->geographicToRelative(pos.position);
mt.relPositionValid = true;
mt.chargeTypeId = ct.id;
mt.mineIndex = inData.originatorId;
rxData(mt);
}
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_DusMine;
}
else
{
if (pdm()->isIedChargeType({ct.id,0,0,}))
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_ImprovisedExplosiveDevice;
else
{
if (m_mainHandler->ppmHandler()->getDtc()->participantIdByEquipmentNumber(inData.originatorId) <= 0)
{
if (m_mainHandler->ppmHandler()->getDtc()->party(inData.originatorId).id)
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Party;
else
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Participant;
}
else
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Participant;
}
}
outData.originatorId = inData.originatorId;
outData.originatorChargeTypeId = inData.chargeTypeId;
if (outData.originatorType == ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_DusMine)
QTimer::singleShot(10, this, [this, outData]()
{
publish(outData);
});
else
publish(outData);
}
void SendToDds::rxData(const TetraIcd::StateChangeIndirect &inData)
{
TrainingAreaBase::EquipmentState outData;
checkTimeStamp(inData);
if (!assignStateChangeBase(inData, outData))
return;
if (!setPosition(outData, inData.geoPosition, inData.relPosition, inData.opsPosition, inData.header.timeStamp))
ctasErrorPosition(inData);
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_AreaEffectSimulation;
outData.originatorId = inData.originatorId;
if (m_aesHandler)
{
int offsetIndirectHit = inData.isSecondaryEffect ? 500 : 0;
outData.originatorChargeTypeId = offsetIndirectHit + m_aesHandler->aesChargeId(outData.originatorId);
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::OperatorAction &inData)
{
TrainingAreaBase::OperatorAction outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.operatorId = inData.operatorId;
outData.action = inData.action;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::StateChange &inData)
{
TrainingAreaBase::EquipmentState outData;
checkTimeStamp(inData);
if (!assignStateChangeBase(inData, outData))
return;
switch (inData.originatorType)
{
case TrainingAreaBase::TetraIcd::OriginatorType::ObserverController:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_ObserverController;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::ExerciseControl:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_ExerciseControl;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::MedicTimeout:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_MedicalTimeout;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::Sanitation:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Sanitation;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::MedicDecontamination:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_WoundTreatmentDevice;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::MaintainanceRepair:
case TrainingAreaBase::TetraIcd::OriginatorType::MaintainanceDecontamination:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_MaintainanceDevice;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::FunctionalArea:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_FunctionalArea;
break;
case TrainingAreaBase::TetraIcd::OriginatorType::Initialisation:
outData.originatorType = ProjectDataManagement::StateChangeOriginator::StateChangeOriginator_Initialization;
break;
}
outData.originatorId = inData.originatorId;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::FunctionalAreaEntry &inData)
{
TrainingAreaBase::FunctionalAreaEntry outData;
checkTimeStamp(inData);
assignBase(inData, outData);
if (!setPosition2d(outData, inData.relPosition))
ctasErrorPosition(inData);
outData.aesItemId = inData.aesDdsId;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::SpecialSensorData &inData)
{
TrainingAreaBase::SpecialSensorData outData;
checkTimeStamp(inData);
assignBase(inData, outData);
if ((inData.relPosition.offsetX != 0 || inData.relPosition.offsetY != 0) && !setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
int operationalState = inData.operationalState & 0xFF;
if (inData.airSensor)
operationalState |= 1 << 8;
if (inData.tireSensor)
operationalState |= 1 << 9;
if (inData.pointSensor)
operationalState |= 1 << 10;
if (inData.solidMatterSampleExtractor)
operationalState |= 1 << 11;
operationalState |= (inData.type & 0x0F) << 12;
operationalState |= (inData.nbcType & 0x03) << 16;
outData.operationalState = operationalState;
publish(outData);
}
template<typename T>
static inline void assignMinelayerData(T &inData, TrainingAreaBase::MinelayerTrailerData &outData)
{
assignBase(inData, outData);
outData.barrierId = inData.barrierId;
outData.layingDensity = inData.layingDensity;
outData.effectStart = inData.effectStart;
outData.effectDuration = inData.effectDuration;
outData.mineCount = inData.mineCount;
}
void SendToDds::rxData(const TetraIcd::MinelayerTrailerData &inData)
{
TrainingAreaBase::MinelayerTrailerData outData;
checkTimeStamp(inData);
assignMinelayerData(inData, outData);
outData.chargeTypeId = m_mainHandler->pdmHandler()->chargeTypeFromId(inData.indirectChargeTasCode).id;
if (!setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::MinelayerThrowerData &inData)
{
TrainingAreaBase::MinelayerThrowerData outData;
checkTimeStamp(inData);
assignMinelayerData(inData, outData);
outData.chargeTypeId = m_mainHandler->pdmHandler()->chargeTypeFromId(inData.indirectChargeTasCode).id;
if (!setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
outData.throwingType = static_cast<TrainingAreaBase::ThrowingType>(inData.throwingType);
publish(outData);
}
void SendToDds::rxData(const TetraIcd::MinelayerTrailerPosition &inData)
{
TrainingAreaBase::MinelayerTrailerPosition outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.dusSerialNo = inData.dusSerialNo;
outData.chargeTypeId = m_mainHandler->pdmHandler()->chargeTypeFromId(inData.indirectChargeTasCode).id;
if (!setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::BiteReport &inData)
{
TrainingAreaBase::EquipmentBite outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.registerType = static_cast<int>(inData.loginType);
outData.biteState = inData.biteState;
outData.configState = inData.configState;
outData.batteryState = inData.batteryState;
outData.configError = inData.configError;
outData.biteErrors.resize(inData.biteErrors.size());
TrainingAreaBase::EquipmentBiteError ebe;
for (size_t i = 0; i < inData.biteErrors.size(); ++i)
{
const TetraIcd::BiteError &be = inData.biteErrors.at(i);
ebe.canDeviceNumber = be.canDeviceNumber;
ebe.errorNumber = be.errorNumber;
ebe.uniqueId = be.uniqueId;
ebe.subdeviceNumber = be.subdeviceNumber;
outData.biteErrors[i] = ebe;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentEvent &inData)
{
TrainingAreaBase::EquipmentEvent outData;
checkTimeStamp(inData);
assignBase(inData, outData);
if (!setPosition2d(outData, inData.relPosition))
ctasErrorPosition(inData);
TrainingAreaBase::Equipment src;
src.equipmentFunctionId = inData.equipmentFunctionId;
src.subDeviceId = inData.subDeviceId;
src.unqiueId = inData.uniqueId;
outData.source = src;
outData.code = inData.code;
outData.data = inData.payload;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentGearAssignment &inData)
{
TrainingAreaBase::EquipmentGearAssignment outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.gears.resize(inData.gears.size());
TrainingAreaBase::Gear tabGear;
for (size_t i = 0; i < inData.gears.size(); ++i)
{
const TetraIcd::Gear &gear = inData.gears.at(i);
tabGear.gearId = gear.gearSerialNumber;
tabGear.gearTypeId = pdm()->gearTypeIdFromTasGearTasCode(gear.gearTasCode);
tabGear.chargeCounting = gear.chargeCounting;
outData.gears[i] = tabGear;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentGearChargeState &inData)
{
TrainingAreaBase::EquipmentGearChargeState outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.charge.resize(inData.charges.size());
TrainingAreaBase::GearCharge tabGr;
for (size_t i = 0; i < inData.charges.size(); ++i)
{
const TetraIcd::GearCharge &gr = inData.charges.at(i);
tabGr.gearId = gr.gearSerialNumber;
tabGr.gearTypeId = pdm()->gearTypeIdFromTasGearTasCode(gr.gearTasCode);
tabGr.remain = gr.remain;
tabGr.chargeTypeId = pdm()->chargeTypeIdFromGearAndChargeTasCode(tabGr.gearTypeId, gr.chargeTypeId);
if (gr.gearSerialNumber == 0 && gr.gearTasCode == 0)
tabGr.gearId = gr.location;
outData.charge[i] = tabGr;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentGearEvent &inData)
{
TrainingAreaBase::EquipmentGearEvent outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.chargeAmount = inData.chargeAmount;
TrainingAreaBase::GearCharge tabGr;
tabGr.gearId = inData.charge.gearSerialNumber;
tabGr.gearTypeId = pdm()->gearTypeIdFromTasGearTasCode(inData.charge.gearTasCode);
tabGr.remain = inData.charge.remain;
tabGr.chargeTypeId = pdm()->chargeTypeIdFromGearAndChargeTasCode(tabGr.gearTypeId, inData.charge.chargeTypeId);
outData.charge = tabGr;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::ParticipantSwVersions &inData)
{
TrainingAreaBase::ParticipantSwVersions outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.equipments.resize(inData.equipments.size());
TrainingAreaBase::EquipmentSwVersion eqpmt;
for (size_t i = 0; i < inData.equipments.size(); ++i)
{
const TetraIcd::EquipmentSwVersion data = inData.equipments.at(i);
eqpmt.equipmentFunctionId = data.equipmentFunctionId;
eqpmt.subDeviceId = data.subDeviceId;
eqpmt.unqiueId = data.uniqueId;
eqpmt.swVersion = data.swVersion;
outData.equipments[i] = eqpmt;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EquipmentMessageOC &inData)
{
TrainingAreaBase::EquipmentMessage outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.subject = inData.subject;
outData.text = inData.message;
outData.sender = inData.senderId;
outData.receiver = inData.receiverId;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::OpaquePayloadDataIn &inData)
{
switch (inData.payloadType)
{
case TetraIcd::OpaquePayloadDataIn::Type::FireSmokeMarker:
{
TrainingAreaBase::FireSmokeMarkerData outData;
assignBase(inData, outData);
outData.payload = inData.payload;
publish(outData);
break;
}
case TetraIcd::OpaquePayloadDataIn::Type::Geopairing:
{
TrainingAreaBase::GeopairingData outData;
checkTimeStamp(inData);
assignBase(inData, outData);
if (!setPosition2d(outData, inData.relPosition))
{
ctasErrorPosition(inData);
return;
}
outData.payload = inData.payload;
publish(outData);
break;
}
case TetraIcd::OpaquePayloadDataIn::Type::Target:
{
TrainingAreaBase::TargetData outData;
assignBase(inData, outData);
outData.payload = inData.payload;
publish(outData);
break;
}
case TetraIcd::OpaquePayloadDataIn::Type::OC:
{
TrainingAreaBase::OcData outData;
assignBase(inData, outData);
outData.payload = inData.payload;
publish(outData);
}
}
}
void SendToDds::rxData(const TetraIcd::ParticipantModeReport &inData)
{
TrainingAreaBase::ParticipantModeReport outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.language = static_cast<ProjectDataManagement::LanguageConfiguration>(inData.language);
outData.operationMode = static_cast<ProjectDataManagement::OperationMode>(inData.operationMode);
outData.reactivationDetoxication = inData.reactivationDetoxication;
outData.reactivationMaintenance = inData.reactivationMaintenance;
outData.reactivationMedic = inData.reactivationMedic;
outData.protectionModeVest = static_cast<ProjectDataManagement::WphMode>(inData.modeVest);
outData.protectionModeHelmet = static_cast<ProjectDataManagement::WphMode>(inData.modeHelmet);
outData.personellProtectionMode = static_cast<ProjectDataManagement::PersonalProtection>(inData.personellProtectionMode);
outData.protectionLevel = static_cast<ProjectDataManagement::ProtectionLevel>(inData.protectionLevel);
outData.handgrenadeSearchMode = static_cast<ProjectDataManagement::HandgrenadeSearchMode>(inData.handgrenadeSearchMode);
outData.internationalMode = static_cast<ProjectDataManagement::InternationalMode>(inData.internationalMode);
outData.abcProtectionMode = static_cast<ProjectDataManagement::ABCProtectionMode>(inData.abcProtectionMode);
publish(outData);
}
void SendToDds::rxData(const TetraIcd::ParticipantConfigurationReport &inData)
{
TrainingAreaBase::ParticipantConfigurationReport outData;
checkTimeStamp(inData);
assignBase(inData, outData);
outData.positionIntervallVehicle = inData.positionIntervallVehicle;
outData.positionIntervallPersonell = inData.positionIntervallPersonell;
outData.positionIntervallAircraft = inData.positionIntervallAircraft;
outData.positionTransmissionIntervall = inData.positionTransmissionIntervall;
outData.heightbarrier = inData.heightbarrier;
outData.faultPositionHandling = static_cast<TrainingAreaBase::FaultPositionHandling>(inData.faultPositionHandling);
outData.switchingPositionIntervall = static_cast<TrainingAreaBase::SwitichingPositionIntervall>(inData.switchingPositionIntervall);
outData.waittimeAdditionalBroadcastRequest = inData.waittimeAdditionalBroadcastDemand;
outData.factorWaittimeIncreaseHighload = inData.factorWaittimeIncreaseAtHighload;
outData.waittimeAutomaticVulnerbilityIncreaseLevel1 = inData.waittimeAutomaticVulnerabilityIncreaseLevel1;
outData.waittimeAutomaticVulnerbilityIncreaseLevel2 = inData.waittimeAutomaticVulnerabilityIncreaseLevel2;
outData.waittimeAutomaticVulnerbilityIncreaseLevel3 = inData.waittimeAutomaticVulnerabilityIncreaseLevel3;
outData.opticalCode = static_cast<TrainingAreaBase::OpticalCode>(inData.opticalCode);
outData.vulnerabilityModel = inData.vulnerabilityModel;
outData.validTimeOps = inData.validTimeOps;
publish(outData);
}
void SendToDds::rxData(const TetraIcd::EmergencyCall &inData)
{
TrainingAreaBase::EmergencyCall outData;
outData.equipmentNumber = inData.issi;
outData.sampleTime = inData.timeStamp;
const Core::GeoPosition2D pos(inData.absPosition.lon, inData.absPosition.lat);
outData.position = pos;
m_mainHandler->ddsHandler()->emergencyCall()->write(outData);
QTimer *t = m_emergencyCallTimer[inData.issi];
if (!t)
{
t = new QTimer(this);
t->setInterval(30 * 1000);
const int issi = inData.issi;
connect(t, &QTimer::timeout, this, [this, issi]() { onEmergencyCallTimerTimeout(issi); });
m_emergencyCallTimer[inData.issi] = t;
}
t->start();
}
void SendToDds::rxData(const TetraIcd::SanitationRepair &inData)
{
TrainingAreaBase::ParticipantSanitationRepair sanRepair;
sanRepair.equipmentNumber = inData.header.equipmentNumber;
sanRepair.sampleTime = inData.header.timeStamp;
sanRepair.originatorType = static_cast<ProjectDataManagement::StateChangeOriginator>(inData.originatorType);
sanRepair.equipmentNumberOrigin = inData.equipmentNumberOrigin;
sanRepair.stateStart = static_cast<ProjectDataManagement::VulnerabilityState>(inData.stateStart);
sanRepair.typeOfTreatment = inData.typeOfTreatment;
sanRepair.triage = inData.triage;
sanRepair.tyeOfDamage = inData.tyeOfDamage;
sanRepair.stateResult = static_cast<ProjectDataManagement::VulnerabilityState>(inData.stateResult);
sanRepair.treatmentResult = static_cast<TrainingAreaBase::TreatmentResult>(inData.treatmentResult);
sanRepair.triagePriority = inData.triagePriority;
sanRepair.fullState = inData.fullState;
sanRepair.timeOfTreatment = inData.timeOfTreatment;
sanRepair.timeOfRecovery = inData.timeOfRecovery;
publish(sanRepair);
}
void SendToDds::rxData(const TetraIcd::SanitaryMaterialStockReport &inData)
{
TrainingAreaBase::ParticipantSanitaryMaterialStockReport sanReport;
sanReport.equipmentNumber = inData.header.equipmentNumber;
sanReport.sampleTime = inData.header.timeStamp;
sanReport.sanitaryMaterialCount = inData.sanitaryMaterialCount;
sanReport.sanitaryMaterialStock = inData.sanitaryMaterialStock;
sanReport.uniqueId = inData.uniqueId;
sanReport.originatorEquipmentNumber = inData.originatorEquipmentNumber;
sanReport.qualification = static_cast<TrainingAreaBase::Qualification>(inData.qualification);
publish(sanReport);
DEBUG_LOG(m_logger) << "SendToDds::rxData(const TetraIcd::SanitaryMaterialStockReport for " << sanReport.equipmentNumber;
if (sanReport.qualification == TrainingAreaBase::Qualification::NotDefined)
{
int oldEquipNo = m_uniqueId2EquipmentNumber.value(sanReport.uniqueId);
if (oldEquipNo > 0)
{
TrainingAreaBase::ParticipantSanitation sanitation;
sanitation.equipmentNumber = oldEquipNo;
sanitation.sampleTime = sanReport.sampleTime;
sanitation.proceduresTaken = 0;
sanitation.uniqueId = sanReport.uniqueId;
sanitation.originatorEquipmentNumber = 0;
sanitation.qualification = TrainingAreaBase::Qualification::NotDefined;
sanitation.sanitationResult = TrainingAreaBase::SanitationResult::NoEffect;
sanitation.sanitationEvaluation = TrainingAreaBase::SanitationEvaluation::NotApplicable;
publish(sanitation);
}
m_uniqueId2EquipmentNumber.remove(sanReport.uniqueId);
}
onPvSanUniqueIdMapping(sanReport.uniqueId, sanReport.equipmentNumber, sanReport.sampleTime);
}
void SendToDds::rxData(const TetraIcd::Sanitation &inData)
{
TrainingAreaBase::ParticipantSanitation sanitation;
sanitation.equipmentNumber = inData.header.equipmentNumber;
sanitation.sampleTime = inData.header.timeStamp;
sanitation.proceduresTaken = inData.proceduresTaken;
sanitation.uniqueId = inData.uniqeId;
sanitation.originatorEquipmentNumber = inData.originatorEquipmentNumber;
sanitation.qualification = static_cast<TrainingAreaBase::Qualification>(inData.qualification);
sanitation.sanitationResult = static_cast<TrainingAreaBase::SanitationResult>(inData.sanitationResult);
sanitation.sanitationEvaluation = static_cast<TrainingAreaBase::SanitationEvaluation>(inData.sanitationEvaluation);
publish(sanitation);
DEBUG_LOG(m_logger) << "SendToDds::rxData(const TetraIcd::Sanitation for " << sanitation.equipmentNumber;
if (sanitation.qualification == TrainingAreaBase::Qualification::NotDefined)
{
TrainingAreaBase::ParticipantSanitaryMaterialStockReport sanReport;
sanReport.equipmentNumber = sanitation.equipmentNumber;
sanReport.sampleTime = sanitation.sampleTime;
sanReport.sanitaryMaterialCount = 0;
sanReport.sanitaryMaterialStock = std::vector<int>();
sanReport.uniqueId = sanitation.uniqueId;
sanReport.originatorEquipmentNumber = 0;
sanReport.qualification = TrainingAreaBase::Qualification::NotDefined;
publish(sanReport);
m_uniqueId2EquipmentNumber.remove(sanitation.uniqueId);
}
else
onPvSanUniqueIdMapping(sanitation.uniqueId, sanitation.equipmentNumber, sanitation.sampleTime);
}
void SendToDds::rxData(const TetraIcd::ApacheLaserDesignation &inData)
{
TrainingAreaBase::LaserDesignation laserDesignation;
laserDesignation.equipmentNumber = inData.header.equipmentNumber;
laserDesignation.sampleTime = inData.header.timeStamp;
laserDesignation.spotLocation = Core::GeoPosition2D(inData.spotLocation.lon, inData.spotLocation.lat);
laserDesignation.outputPower = inData.outputPower;
laserDesignation.code = inData.code;
laserDesignation.gearId = inData.gearId;
publish(laserDesignation);
}
template<typename S>
void SendToDds::ctasErrorPosition(const S &data)
{
TrainingAreaBase::CtaDataError error;
error.equipmentNumber = data.header.equipmentNumber;
error.sampleTime = data.header.timeStamp;
error.reason = ProjectDataManagement::DataErrorReason::DataErrorReason_InvalidPosition;
error.originTelegramId = data.id();
publish(error);
}
void SendToDds::rxData(const TetraIcd::BatteryInfo &inData)
{
TrainingAreaBase::BatteryInfo batteryInfo;
batteryInfo.equipmentNumber = inData.header.equipmentNumber;
batteryInfo.sampleTime = inData.header.timeStamp;
std::vector<TrainingAreaBase::BatteryState> batteryStates;
batteryStates.reserve(inData.batteryStates.size());
for(const TetraIcd::BatteryState &batState : std::as_const(inData.batteryStates))
{
TrainingAreaBase::BatteryState batStateOut;
batStateOut.batteryPort = batState.batteryPort();
batStateOut.batteryPercent = batState.batteryPercent();
batStateOut.current = batState.current();
batStateOut.frequency = batState.frequency();
batStateOut.generic = batState.generic();
batStateOut.serialNumber = batState.serialNumber().toStdString();
batStateOut.switchOrValue = batState.switchOrValue();
batStateOut.temperature = batState.temperature();
batStateOut.voltage = batState.voltage();
batteryStates.push_back(batStateOut);
}
batteryInfo.batteryStates = batteryStates;
publish(batteryInfo);
}
void SendToDds::rxData(const TetraIcd::BatteryAlarm &inData)
{
TrainingAreaBase::BatteryAlarm batAlarm;
batAlarm.acknowledge = inData.acknowledge();
batAlarm.alarmTime = inData.alarmTime();
batAlarm.condition = inData.condition();
batAlarm.description = inData.description().toStdString();
batAlarm.batteryPort = inData.id();
batAlarm.uniqueAlarmNumber = inData.uniqueAlarmNumber();
batAlarm.equipmentNumber = inData.header().equipmentNumber;
batAlarm.sampleTime = inData.header().timeStamp;
publish(batAlarm);
}
void SendToDds::rxData(const TetraIcd::ServiceControl &inData)
{
TrainingAreaBase::ServiceControl serviceControl;
serviceControl.equipmentNumber = inData.header.equipmentNumber;
serviceControl.sampleTime = inData.header.timeStamp;
serviceControl.serviceControlState = static_cast<TrainingAreaBase::ServiceControlEnum>(inData.serviceControlState);
publish(serviceControl);
}
void SendToDds::rxData(const TetraIcd::RestoreRadioReadiness &inData)
{
struct PositionStruct
{
int equipmentNumber;
Core::GeoPosition2D position;
};
RestoreRadioReadiness restoreRadioReadiness;
restoreRadioReadiness.equipmentNumber = inData.header.equipmentNumber;
restoreRadioReadiness.sampleTime = inData.header.timeStamp;
restoreRadioReadiness.readinessLossPosition = m_posHandler->relativeToGeographic(inData.readinessLossPosition);
restoreRadioReadiness.readinessLossTime = inData.readinessLossTime;
restoreRadioReadiness.readinessRestorePosition = m_posHandler->relativeToGeographic(inData.readinessRestorePosition);
restoreRadioReadiness.readinessRestoreTime = inData.readinessRestoreTime;
publish(restoreRadioReadiness);
}
void SendToDds::rxData(const TetraIcd::UAVRadioLinkConnectionStatus &inData)
{
TrainingAreaBase::UASRadioLinkConnectionState outData;
assignBase(inData, outData);
switch (inData.uavConnectionState)
{
case TetraIcd::UAVRadioLinkConnectionStatusType::Connected:
outData.connectionStatus = ProjectDataManagement::UasState::UasState_On;
break;
case TetraIcd::UAVRadioLinkConnectionStatusType::Disconnected:
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Off;
break;
case TetraIcd::UAVRadioLinkConnectionStatusType::Connecting:
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Init;
break;
case TetraIcd::UAVRadioLinkConnectionStatusType::Diconnecting:
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Shutdown;
break;
case TetraIcd::UAVRadioLinkConnectionStatusType::Error:
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Undefined;
break;
case TetraIcd::UAVRadioLinkConnectionStatusType::Undefined:
outData.connectionStatus = ProjectDataManagement::UasState::UasState_Undefined;
break;
}
publish(outData);
}
void SendToDds::rxData(const TetraIcd::UAVMissionStatus &inData)
{
TrainingAreaBase::UASMissionStatus outData;
assignBase(inData, outData);
switch (inData.currentAction)
{
case TetraIcd::UAVActionTask::Undefined: outData.currentTask = ProjectDataManagement::UasActionTask::Undefined; break;
case TetraIcd::UAVActionTask::Disarm: outData.currentTask = ProjectDataManagement::UasActionTask::Disarm; break;
case TetraIcd::UAVActionTask::Arm: outData.currentTask = ProjectDataManagement::UasActionTask::Arm; break;
case TetraIcd::UAVActionTask::Takeoff: outData.currentTask = ProjectDataManagement::UasActionTask::Takeoff; break;
case TetraIcd::UAVActionTask::Connect: outData.currentTask = ProjectDataManagement::UasActionTask::Connect; break;
case TetraIcd::UAVActionTask::Loiter: outData.currentTask = ProjectDataManagement::UasActionTask::Loiter; break;
case TetraIcd::UAVActionTask::Return: outData.currentTask = ProjectDataManagement::UasActionTask::Return; break;
case TetraIcd::UAVActionTask::Observe: outData.currentTask = ProjectDataManagement::UasActionTask::Observe; break;
}
outData.currentMissionName = inData.currentMissionName.toStdString();
outData.missionEnded = inData.missionEnded.toStdString();
publish(outData);
}
void SendToDds::rxData(const TetraIcd::UAVStatus &inData)
{
TrainingAreaBase::UASStatus outData;
assignBase(inData, outData);
switch (inData.uavState)
{
case TetraIcd::UAVState::On:
outData.uasState = ProjectDataManagement::UasState::UasState_On;
break;
case TetraIcd::UAVState::Off:
outData.uasState = ProjectDataManagement::UasState::UasState_Off;
break;
case TetraIcd::UAVState::Init:
outData.uasState = ProjectDataManagement::UasState::UasState_Init;
break;
case TetraIcd::UAVState::Shutdown:
outData.uasState = ProjectDataManagement::UasState::UasState_Shutdown;
break;
case TetraIcd::UAVState::Calibrating:
outData.uasState = ProjectDataManagement::UasState::UasState_Calibrating;
break;
case TetraIcd::UAVState::Manual:
outData.uasState = ProjectDataManagement::UasState::UasState_Manual;
break;
case TetraIcd::UAVState::Maintenance:
outData.uasState = ProjectDataManagement::UasState::UasState_Maintenance;
break;
case TetraIcd::UAVState::Standby:
outData.uasState = ProjectDataManagement::UasState::UasState_Standby;
break;
case TetraIcd::UAVState::Normal:
outData.uasState = ProjectDataManagement::UasState::UasState_Normal;
break;
case TetraIcd::UAVState::Auto:
outData.uasState = ProjectDataManagement::UasState::UasState_Auto;
break;
case TetraIcd::UAVState::Undefined:
outData.uasState = ProjectDataManagement::UasState::UasState_Undefined;
break;
}
publish(outData);
}
template <typename T>
bool SendToDds::setPosition(T &data,
const TetraIcd::AbsolutePosition &geoPos,
const TetraIcd::RelativePosition &relPos,
const TetraIcd::OpsPosition &opsPos,
const qint64 timeStamp) const
{
bool bRet = true;
bool moutCheck = true;
TrainingAreaBase::TabPosition tabPos;
if (geoPos.isValid())
{
tabPos.position = Core::GeoPosition(geoPos.lon, geoPos.lat, geoPos.z);
setOptionalBuildingRoomId(tabPos.moutObjectId, opsPos.moutObjectId);
setOptionalBuildingRoomId(tabPos.moutRoomId, opsPos.moutRoomId);
const bool bWlsLocationLost = opsPos.moutObjectId == -2 &&
opsPos.moutRoomId == -2;
if (bWlsLocationLost)
{
TrainingAreaBase::TabPosition lastTabPos =
m_posHandler->lastPosition(data.equipmentNumber);
if (lastTabPos.reportingSource == Core::PositionReportingSource::Wls ||
std::isnan(lastTabPos.position.lon))
tabPos.reportingSource = Core::PositionReportingSource::Gps;
else
std::swap(tabPos, lastTabPos);
}
else
tabPos.reportingSource = Core::PositionReportingSource::Wls;
}
else if (opsPos.opsId == 0)
{
bool changeReportSource = true;
DEBUG_LOG(m_logger) << "ops == 0 so check for marked invalid to use last position!";
if (PositionHandler::isPositionMarkedInvalid(relPos))
{
tabPos = m_posHandler->lastPosition(data.equipmentNumber);
DEBUG_LOG(m_logger) << "ops == 0 got last Position its source is " << tabPos.reportingSource;
if (tabPos.reportingSource != Core::PositionReportingSource::Wls
&& tabPos.reportingSource != Core::PositionReportingSource::Ops
&& tabPos.reportingSource != Core::PositionReportingSource::OpsTunnel)
tabPos = TrainingAreaBase::TabPosition();
else if (tabPos.reportingSource == Core::PositionReportingSource::Ops
|| tabPos.reportingSource == Core::PositionReportingSource::OpsTunnel)
changeReportSource = false;
DEBUG_LOG(m_logger) << "ops == 0 changeSource is " << changeReportSource ;
}
else
{
if (!m_posHandler->isInTrainingArea(relPos))
{
DEBUG_LOG(m_logger) << "bret = false";
bRet = false;
}
tabPos.position = m_posHandler->relativeToGeographic(relPos);
setOptionalBuildingRoomId(tabPos.moutObjectId, opsPos.moutObjectId);
setOptionalBuildingRoomId(tabPos.moutRoomId, opsPos.moutRoomId);
TrainingAreaBase::TabPosition lastPosition = m_posHandler->lastPosition(data.equipmentNumber);
{
DEBUG_LOG(m_logger) << "lastPosition.reportingSource=" << lastPosition.reportingSource;
}
if (lastPosition.reportingSource == Core::PositionReportingSource::Ops &&
lastPosition.moutObjectId.has_value())
{
DEBUG_LOG(m_logger) << "Check leave Building equipmentNumber=" << data.equipmentNumber;
DEBUG_LOG(m_logger) << "relPos=" << relPos.offsetX << "/" << relPos.offsetY;
DEBUG_LOG(m_logger) << "posInExtendedBuildingFootprint";
const Core::GeoPosition &position = tabPos.position;
int moutObjectId = lastPosition.moutObjectId.get();
const int lastMountPointTypeId = m_posHandler->lastMountPointTypeId(data.equipmentNumber);
if (ism()->posInExtendedBuildingFootprint(moutObjectId, position, lastMountPointTypeId))
{
moutCheck = false;
bRet = false;
}
else
{
DEBUG_LOG(m_logger) << "lastMountPointTypeId =" << m_posHandler->lastMountPointTypeId(data.equipmentNumber);
if ( m_posHandler->lastMountPointTypeId(data.equipmentNumber) == static_cast<int>(InfrastructureManagement::MountingPointType::IndoorIPS))
{
double speed = m_posHandler->speed(relPos, data.equipmentNumber, timeStamp);
bool checkSpeed = !m_posHandler->isTimeToPerformSpeedCheckExceeded(data.equipmentNumber,
timeStamp,
Settings::maxSpeedCheckTimeout());
DEBUG_LOG(m_logger) << "Check Speed speed=" << speed
<< " MaxSoldierSpeed=" << Settings::maxSoldierSpeed()
<< " checkSpeed=" << checkSpeed;
if (checkSpeed && speed > Settings::maxSoldierSpeed())
{
DEBUG_LOG(m_logger) << "Check Speed bRet = false";
bRet = false;
moutCheck = false;
}
}
else
{
DEBUG_LOG(m_logger) << "Kein Speed check!";
}
}
}
}
if (changeReportSource)
tabPos.reportingSource = Core::PositionReportingSource::Gps;
}
else
{
INFO_LOG(m_logger) << "Valid OpsData: " << opsPos.opsId;
IsmHandler::OpsData opsData;
if (ism())
{
opsData = ism()->dataFromOpsCode(opsPos.opsId);
DEBUG_LOG(m_logger) << "equipmentNumber=" << data.equipmentNumber
<< " AssetId=" << opsData.assetId
<< " opsData.structureElementId=" << opsData.structureElementId
<< " opsData.mseId=" << opsData.mainStructureElementId
<< " opsData.mptTypeId=" << opsData.mountingPointTypeId;
if ( opsData.structureElementId != 0)
m_posHandler->setLastMountPointTypeId(data.equipmentNumber, opsData.mountingPointTypeId);
}
if (opsData.opsCode != opsPos.opsId)
{
WARNING_LOG(m_logger) << "found no position data for ops id " << opsPos.opsId;
bRet = false;
}
else if (opsData.structureElementId == 0)
{
WARNING_LOG(m_logger) << "ops id " << opsPos.opsId << " is not mounted";
bRet = false;
}
else
{
DEBUG_LOG(m_logger) << "ops id " << opsPos.opsId;
tabPos.moutObjectId = opsData.mainStructureElementId;
tabPos.moutRoomId = opsData.roomId;
tabPos.position = opsData.position;
m_posHandler->setLastBuildingId(data.equipmentNumber, opsData.mainStructureElementId);
m_posHandler->setLastRoomId(data.equipmentNumber, opsData.roomId);
}
if (opsData.opsTunnel)
tabPos.reportingSource = Core::PositionReportingSource::OpsTunnel;
else
tabPos.reportingSource = Core::PositionReportingSource::Ops;
}
if (!bRet)
{
if ( moutCheck )
{
DEBUG_LOG(m_logger) << "POS = ungueltig";
tabPos.position.lon = nan("");
tabPos.position.lat = nan("");
}
else
{
DEBUG_LOG(m_logger) << "POS = ungueltig => alte Pos mit aktueller Zeit verschicken";
TrainingAreaBase::TabPosition lastPosition = m_posHandler->lastPosition(data.equipmentNumber);
tabPos.position.lon = lastPosition.position.lon;
tabPos.position.lat = lastPosition.position.lat;
tabPos.position.z = lastPosition.position.z;
tabPos.reportingSource = Core::PositionReportingSource::OpsBuilding;
tabPos.moutObjectId = m_posHandler->lastBuildingId(data.equipmentNumber);
tabPos.moutRoomId = m_posHandler->lastRoomId(data.equipmentNumber);
bRet = true;
}
}
else
{
DEBUG_LOG(m_logger) << "set last Position";
if (tabPos.reportingSource == Core::PositionReportingSource::Ops)
DEBUG_LOG(m_logger) << "ReportingSource=OPS";
else if (tabPos.reportingSource == Core::PositionReportingSource::Gps)
DEBUG_LOG(m_logger) << "ReportingSource=GPS";
DEBUG_LOG(m_logger) << "tabPos.reportingSource=" << tabPos.reportingSource
<< " timeStamp=" << timeStamp;
m_posHandler->setLastPosition(data.equipmentNumber, tabPos);
m_posHandler->setLastTime(data.equipmentNumber, timeStamp);
}
data.position = tabPos;
return bRet;
}
template <typename T>
bool SendToDds::setPosition2d(T &data,
const TetraIcd::RelativePosition &relPos) const
{
TrainingAreaBase::TabPosition tabPos;
bool bRet = true;
if (PositionHandler::isPositionMarkedInvalid(relPos))
tabPos = m_posHandler->lastPosition(data.equipmentNumber);
else
{
if (!m_posHandler->isInTrainingArea(relPos))
bRet = false;
DEBUG_LOG(m_logger) << "tabPos.reportingSource=" << tabPos.reportingSource;
tabPos.position = m_posHandler->relativeToGeographic(relPos);
m_posHandler->setLastPosition(data.equipmentNumber, tabPos);
}
Core::GeoPosition2D pos2d;
pos2d.lat = tabPos.position.lat;
pos2d.lon = tabPos.position.lon;
data.position = pos2d;
return bRet;
}
template<typename S, typename T>
bool SendToDds::assignStateChangeBase(const S &inData, T &outData)
{
assignBase(inData, outData);
if (inData.vulnerabilityState < TrainingAreaBase::TetraIcd::VulnerabilityState::CombatReady ||
inData.vulnerabilityState > TrainingAreaBase::TetraIcd::VulnerabilityState::VulnerabilityBitsChanged)
{
TrainingAreaBase::CtaDataError error;
assignBase(inData, error);
error.reason = ProjectDataManagement::DataErrorReason::DataErrorReason_InvalidTacticalState;
error.originTelegramId = inData.id();
publish(error);
return false;
}
outData.vulnerabilityState = static_cast<ProjectDataManagement::VulnerabilityState>(inData.vulnerabilityState);
outData.vulnerabilityKindId = pdm()->vulnerabilityKindId(inData.tasVulnerabilityKindId, inData.header.equipmentNumber);
outData.vitality = inData.tasVitality;
outData.vulnerabilityBits = inData.vulnerabilityBits;
return true;
}
template <typename S>
void SendToDds::checkTimeStamp(const S &data)
{
const auto partTime = m_mainHandler->ddsHandler()->partitionTime();
if (data.header.timeStamp > (partTime + Settings::timeDelayAhead()) ||
data.header.timeStamp < (partTime - Settings::timeDelayBack()))
{
TrainingAreaBase::CtaDataError error;
error.equipmentNumber = data.header.equipmentNumber;
error.sampleTime = data.header.timeStamp;
error.reason = ProjectDataManagement::DataErrorReason::DataErrorReason_InvalidTime;
error.originTelegramId = data.id();
publish(error);
}
}
std::shared_ptr<IsmHandler> SendToDds::ism() const
{
return m_mainHandler->ismHandler();
}
std::shared_ptr<PdmHandler> SendToDds::pdm() const
{
return m_mainHandler->pdmHandler();
}
template <typename T>
void SendToDds::publish(const T &data)
{
try
{
m_dtsTab->publish(data);
}
catch (const std::exception &ex)
{
WARNING_LOG(m_logger) << "Could not send telegram: " << ex.what();
}
}
void SendToDds::onEmergencyCallTimerTimeout(int issi)
{
auto it = m_emergencyCallTimer.find(issi);
if (it == m_emergencyCallTimer.end())
return;
delete it.value();
m_emergencyCallTimer.erase(it);
if (m_mainHandler->ddsHandler()->emergencyCall())
{
TrainingAreaBase::EmergencyCall emergCallData;
emergCallData.equipmentNumber = issi;
if (!m_mainHandler->ddsHandler()->emergencyCall()->remove(emergCallData))
ERROR_LOG(m_logger) << Q_FUNC_INFO << " removing of TrainingAreaBase::EmergencyCall failed, issi = " << issi;
}
}
void SendToDds::onPvSanUniqueIdMapping(int uniqueId, int equipNo, qint64 sampleTime)
{
DEBUG_LOG(m_logger) << Q_FUNC_INFO << "start pvSan mapping " << equipNo << " uniqueId " << uniqueId;
if (m_uniqueId2EquipmentNumber.value(uniqueId) == equipNo)
return;
if (!m_uniqueId2EquipmentNumber.contains(uniqueId))
{
m_uniqueId2EquipmentNumber.insert(uniqueId, equipNo);
return;
}
int oldEquipNo = m_uniqueId2EquipmentNumber.value(uniqueId);
if (oldEquipNo > 0)
{
TrainingAreaBase::ParticipantSanitaryMaterialStockReport sanReport;
sanReport.equipmentNumber = oldEquipNo;
sanReport.sampleTime = sampleTime;
sanReport.sanitaryMaterialCount = 0;
sanReport.sanitaryMaterialStock = std::vector<int>();
sanReport.uniqueId = uniqueId;
sanReport.originatorEquipmentNumber = 0;
sanReport.qualification = TrainingAreaBase::Qualification::NotDefined;
publish(sanReport);
TrainingAreaBase::ParticipantSanitation sanitation;
sanitation.equipmentNumber = oldEquipNo;
sanitation.sampleTime = sampleTime;
sanitation.proceduresTaken = 0;
sanitation.uniqueId = uniqueId;
sanitation.originatorEquipmentNumber = 0;
sanitation.qualification = TrainingAreaBase::Qualification::NotDefined;
sanitation.sanitationResult = TrainingAreaBase::SanitationResult::NoEffect;
sanitation.sanitationEvaluation = TrainingAreaBase::SanitationEvaluation::NotApplicable;
publish(sanitation);
m_uniqueId2EquipmentNumber.insert(uniqueId, equipNo);
}
}
}