- 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>
798 lines
34 KiB
C++
Executable File
798 lines
34 KiB
C++
Executable File
/**
|
|
* Handle incoming Function Topic Requests (and send them to Tetra)
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
|
*/
|
|
|
|
#include "recv_from_dds_fts.h"
|
|
#include "main_handler.h"
|
|
#include "ism_handler.h"
|
|
#include "settings.h"
|
|
|
|
#include <LtsUtilsCore/json.h>
|
|
|
|
|
|
namespace TrainingAreaBase
|
|
{
|
|
|
|
|
|
RecvFromDdsFts::RecvFromDdsFts(MainHandler *mainHandler, const std::shared_ptr<Interface::Fts> &ftsTab,
|
|
const std::shared_ptr<SendToTab> &txCallback)
|
|
: Interface::Fts::DemandBiteRequestHandler(ftsTab)
|
|
, Interface::Fts::DemandInitRequestHandler(ftsTab)
|
|
, Interface::Fts::SendSetVulnerabilityModelRequestHandler(ftsTab)
|
|
, Interface::Fts::DemandConfigurationReportRequestHandler(ftsTab)
|
|
, Interface::Fts::DemandVulnerabilityStateChangeRequestHandler(ftsTab)
|
|
, Interface::Fts::SendLanguageSelectionRequestHandler(ftsTab)
|
|
, Interface::Fts::SendEquipmentMessageRequestHandler(ftsTab)
|
|
, Interface::Fts::SendOcDataRequestHandler(ftsTab)
|
|
, Interface::Fts::SendFireSmokeMarkerDataRequestHandler(ftsTab)
|
|
, Interface::Fts::SendGeopairingDataRequestHandler(ftsTab)
|
|
, Interface::Fts::SendTargetDataRequestHandler(ftsTab)
|
|
, Interface::Fts::SendCesHitInformationRequestHandler(ftsTab)
|
|
, Interface::Fts::SendCesHitRequestHandler(ftsTab)
|
|
, Interface::Fts::SendParticipantSwVerionsRequestHandler(ftsTab)
|
|
, Interface::Fts::SendParticipantModeRequestHandler(ftsTab)
|
|
, Interface::Fts::DemandParticipantModeRequestHandler(ftsTab)
|
|
, Interface::Fts::SendParticipantConfigurationRequestHandler(ftsTab)
|
|
, Interface::Fts::DemandParticipantConfigurationRequestHandler(ftsTab)
|
|
, Interface::Fts::SendParticipantBlockedAreaRequestHandler(ftsTab)
|
|
, Interface::Fts::SendParticipantBeStillWarningRequestHandler(ftsTab)
|
|
, Interface::Fts::SendSetSanitationRequestHandler(ftsTab)
|
|
, Interface::Fts::SendResetAllDusMinesRequestHandler(ftsTab)
|
|
, Interface::Fts::SendSelectiveReammunitionRequestHandler(ftsTab)
|
|
, Interface::Fts::SetDevicePowerRequestHandler(ftsTab)
|
|
, Interface::Fts::AdlerCalculateTrajectoryRequestHandler(ftsTab)
|
|
, Interface::Fts::SendOcCommandRequestHandler(ftsTab)
|
|
, Interface::Fts::SendUasWaypointRequestHandler(ftsTab)
|
|
, Interface::Fts::SendModifyUasStateRequestHandler(ftsTab)
|
|
, Interface::Fts::SendExFireReadinessRequestHandler(ftsTab)
|
|
, Interface::Fts::SendExFiredReportRequestHandler(ftsTab)
|
|
, Interface::Fts::SendExConfirmationReportRequestHandler(ftsTab)
|
|
, m_mainHandler(mainHandler)
|
|
, m_ftsTab(ftsTab)
|
|
, m_txCallback(txCallback)
|
|
, m_logger(getLogger("RecvFromDdsFts"))
|
|
{
|
|
m_categorieData = loadRemainEffectStructMap();
|
|
}
|
|
|
|
void RecvFromDdsFts::onDemandBiteRequest(const rti::core::SampleIdentity &cookie, const DemandBiteRequest &request)
|
|
{
|
|
TetraIcd::DemandBite data;
|
|
data.withSelfTest = request.withSelfTest();
|
|
|
|
bool bRet = true;
|
|
// TODO: fixme
|
|
for (const int equipNo : request.equipmentNumbers())
|
|
{
|
|
data.header.equipmentNumber = equipNo;
|
|
if (!m_txCallback->txData(data))
|
|
bRet = false;
|
|
}
|
|
|
|
m_ftsTab->demandBiteReply(cookie, fillFro(request.requestId(), bRet));
|
|
}
|
|
|
|
void RecvFromDdsFts::onDemandInitRequest(const rti::core::SampleIdentity &cookie, const DemandInitRequest &request)
|
|
{
|
|
TetraIcd::Init data;
|
|
data.workstationId = request.workstationId();
|
|
data.resetManipulation = request.resetManipulation();
|
|
data.resetVulnerabilityState = request.resetVulnerabilityState();
|
|
data.restockCharges = request.restockCharges();
|
|
data.restockSanitationMaterial = request.restockSanitationMaterial();
|
|
bool bRet = true;
|
|
// TODO: fixme
|
|
for (const int equipNo : request.equipmentNumbers())
|
|
{
|
|
data.header.equipmentNumber = equipNo;
|
|
if (!m_txCallback->txData(data))
|
|
bRet = false;
|
|
}
|
|
|
|
m_ftsTab->demandInitReply(cookie, fillFro(request.requestId(), bRet));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendSetVulnerabilityModelRequest(const rti::core::SampleIdentity &cookie, const SendSetVulnerabilityModelRequest &request)
|
|
{
|
|
TetraIcd::SetVulnerabilityModel data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.vulnerabilityModelMineIed = request.vulnerabilityModelMineIed();
|
|
data.vulnerabilityModelAreaFire = request.vulnerabilityModelAreaFire();
|
|
data.vulnerabilityModelOperatingResource = request.vulnerabilityModelOperationalResource();
|
|
data.vulnerabilityModelAcWeaponry = request.vulnerabilityModelACWeaponry();
|
|
|
|
m_ftsTab->sendSetVulnerabilityModelReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onDemandConfigurationReportRequest(const rti::core::SampleIdentity &cookie, const DemandConfigurationReportRequest &request)
|
|
{
|
|
TetraIcd::DemandEquipmentConfigurationReport data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
|
|
m_ftsTab->demandConfigurationReportReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onDemandVulnerabilityStateChangeRequest(const rti::core::SampleIdentity &cookie, const DemandVulnerabilityStateChangeRequest &request)
|
|
{
|
|
TetraIcd::DemandVulnerabilityStateChange data;
|
|
data.reqestedState = static_cast<TetraIcd::VulnerabilityState>(request.vulnerabilityState().underlying());
|
|
data.workstationId = request.workstationId();
|
|
data.vulnerabilityVitalityIndex = getVulnerabilityVitalityIndexFromVitalityAndVba(request.vulnerabilityKind(), request.vitality());
|
|
|
|
bool bRet = true;
|
|
// TODO: fixme
|
|
for (const int equipNo : request.equipmentNumbers())
|
|
{
|
|
data.header.equipmentNumber = equipNo;
|
|
if (!m_txCallback->txData(data))
|
|
bRet = false;
|
|
}
|
|
|
|
m_ftsTab->demandVulnerabilityStateChangeReply(cookie, fillFro(request.requestId(), bRet));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendLanguageSelectionRequest(const rti::core::SampleIdentity &cookie, const SendLanguageSelectionRequest &request)
|
|
{
|
|
TetraIcd::LanguageSelection data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.languageSelection = static_cast<TetraIcd::Language>(request.language().underlying());
|
|
|
|
m_ftsTab->sendLanguageSelectionReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendEquipmentMessageRequest(const rti::core::SampleIdentity &cookie, const SendEquipmentMessageRequest &request)
|
|
{
|
|
if (request.sender().is_set() &&
|
|
request.subject().is_set() &&
|
|
request.message().is_set())
|
|
{
|
|
// Message to O/C
|
|
TetraIcd::EquipmentMessageOC data;
|
|
data.senderId = request.sender().get();
|
|
data.subject = request.subject().get();
|
|
data.message = request.message().get();
|
|
data.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
|
|
bool bRet = true;
|
|
// TODO: fixme
|
|
for (const int equipNo : request.equipmentNumbers())
|
|
{
|
|
data.header.equipmentNumber = equipNo;
|
|
data.receiverId = equipNo;
|
|
if (!m_txCallback->txData(data))
|
|
bRet = false;
|
|
}
|
|
|
|
m_ftsTab->sendEquipmentMessageReply(cookie, fillFro(0, bRet));
|
|
}
|
|
else
|
|
{
|
|
TetraIcd::EquipmentMessage data;
|
|
if (request.messageId().is_set())
|
|
data.msgId = request.messageId().get();
|
|
else if (request.message().is_set())
|
|
data.message = request.message().get();
|
|
else
|
|
{
|
|
m_ftsTab->sendEquipmentMessageReply(cookie, fillFro(0, false));
|
|
ERROR_LOG(m_logger) << "Got SendEquipmentMessageRequest but neither message nor messageId is set!";
|
|
return;
|
|
}
|
|
bool bRet = true;
|
|
// TODO: fixme
|
|
for (const int equipNo : request.equipmentNumbers())
|
|
{
|
|
data.header.equipmentNumber = equipNo;
|
|
if (!m_txCallback->txData(data))
|
|
bRet = false;
|
|
}
|
|
|
|
m_ftsTab->sendEquipmentMessageReply(cookie, fillFro(request.requestId(), bRet));
|
|
}
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendOcDataRequest(const rti::core::SampleIdentity &cookie, const SendOcDataRequest &request)
|
|
{
|
|
TetraIcd::OpaquePayloadDataOut data;
|
|
data.payloadType = TetraIcd::OpaquePayloadDataBase::Type::OC;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.payload = request.payload();
|
|
|
|
m_ftsTab->sendOcDataReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendFireSmokeMarkerDataRequest(const rti::core::SampleIdentity &cookie, const SendFireSmokeMarkerDataRequest &request)
|
|
{
|
|
TetraIcd::OpaquePayloadDataOut data;
|
|
data.payloadType = TetraIcd::OpaquePayloadDataBase::Type::FireSmokeMarker;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.payload = request.payload();
|
|
|
|
m_ftsTab->sendFireSmokeMarkerDataReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendGeopairingDataRequest(const rti::core::SampleIdentity &cookie, const SendGeopairingDataRequest &request)
|
|
{
|
|
TetraIcd::OpaquePayloadDataOut data;
|
|
data.payloadType = TetraIcd::OpaquePayloadDataBase::Type::Geopairing;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.payload = request.payload();
|
|
|
|
m_ftsTab->sendGeopairingDataReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendTargetDataRequest(const rti::core::SampleIdentity &cookie, const SendTargetDataRequest &request)
|
|
{
|
|
TetraIcd::OpaquePayloadDataOut data;
|
|
data.payloadType = TetraIcd::OpaquePayloadDataBase::Type::Target;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.payload = request.payload();
|
|
|
|
m_ftsTab->sendTargetDataReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendCesHitInformationRequest(const rti::core::SampleIdentity &cookie, const SendCesHitInformation &request)
|
|
{
|
|
TetraIcd::CesHitInformation data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = request.effectTime();
|
|
data.originatorEquipmentNumber = request.originatorEquipmentNumber();
|
|
const auto &ct = m_mainHandler->pdmHandler()->chargeTypeFromId(request.chargeTypeId());
|
|
data.chargeTasCodeDirect = ct.id();
|
|
data.chargeTasCodeIndirect = ct.id();
|
|
data.directionDegree = request.directionDegree();
|
|
data.distance = request.distanceToOrignator();
|
|
data.effectPercent = request.effectPercent();
|
|
|
|
m_ftsTab->sendCesHitInformationReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendCesHitRequest(const rti::core::SampleIdentity &cookie, const SendCesHitRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onSendCesHitRequest: " << request.equipmentNumber() << " - " << request.effectTime()
|
|
<< " request.chargeTypeId=" << request.chargeTypeId()
|
|
<< " request.eventType()=" << request.eventType()
|
|
<< " request.aesId()=" << request.aesId()
|
|
<< " aesTypeFromId=" << m_mainHandler->aesHandler()->aesTypeFromId(request.aesId());
|
|
|
|
// NOTE: igniterType/IgniterFunciton = 0 as long as SendCesHitRequest does not contain values
|
|
if (m_mainHandler->pdmHandler()->isSmartChargeType({request.chargeTypeId(), 0,0}))
|
|
{
|
|
// special handling for smart - must be send as singleFire
|
|
m_ftsTab->sendCesHitReply(cookie,
|
|
fillFro(request.participantId(),
|
|
m_mainHandler->aesHandler()->sendSingleFireSMArt(request)));
|
|
return;
|
|
}
|
|
TetraIcd::CesHitRequest data;
|
|
//test
|
|
data.reserve2 = request.originatorEquipmentNumber();
|
|
data.reserve1 = request.chargeTypeId();
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = request.effectTime();
|
|
const auto &ct = m_mainHandler->pdmHandler()->chargeTypeFromId(request.chargeTypeId());
|
|
// GUEZE-359 Steilfeuer mit Sekundaerwirkung wird als Mun 371, ... gesendet. Fuehrt zu Treffer DUS statt WirkSim
|
|
//#ifdef GUEZ_MODE
|
|
// if ( request.chargeTypeId() > 370 && request.chargeTypeId() < 390 )
|
|
// {
|
|
// data.chargeTasCodeDirect = 201; // immer den direkten code (fuer wirkfelder: pseudo-osag code >= 201)
|
|
// data.chargeTasCodeIndirect = 201;
|
|
// }
|
|
// else
|
|
// {
|
|
// data.chargeTasCodeDirect = ct.id(); // immer den direkten code (fuer wirkfelder: pseudo-osag code >= 201)
|
|
// data.chargeTasCodeIndirect = ct.id();
|
|
// }
|
|
//#else
|
|
if ((request.eventType() == ProjectDataManagement::EventType::HitBuilding) && (ct.legacyId() > 0))
|
|
{
|
|
data.chargeTasCodeDirect = 201; // immer den direkten code (fuer wirkfelder: pseudo-osag code >= 201)
|
|
data.chargeTasCodeIndirect = 201;
|
|
}
|
|
else if (ct.legacyId() > 0)
|
|
{
|
|
data.chargeTasCodeDirect = ct.legacyId();
|
|
data.chargeTasCodeIndirect = ct.legacyId();
|
|
}
|
|
else
|
|
{
|
|
data.chargeTasCodeDirect = ct.id();
|
|
data.chargeTasCodeIndirect = ct.id();
|
|
}
|
|
//#endif
|
|
data.mineId = request.mineId();
|
|
if (request.aesId() != 0)
|
|
{
|
|
//data.aesTetraIdUnused = m_mainHandler->aesHandler()->tetraIdFromDdsId(request.aesId());
|
|
data.aesDdsId = request.aesId();
|
|
//TODO: !!!!!! Use new EventType to check which AreaEffectSimulationType will be chosen.
|
|
if (request.eventType() == ProjectDataManagement::EventType::ExplosionCluster)
|
|
data.aesType = TetraIcd::AreaEffectSimulationType::ExplosionArea;
|
|
else
|
|
data.aesType = m_mainHandler->aesHandler()->aesTypeFromId(request.aesId());
|
|
/*!
|
|
\brief Take the new event type attribute to check if its is a HazardArea(DangerZone/Gefahrenbereich)
|
|
*
|
|
* */
|
|
|
|
if ((request.eventType() == ProjectDataManagement::EventType::LeaveHazardDistance) ||
|
|
(request.eventType() == ProjectDataManagement::EventType::EnterHazardDistance))
|
|
{
|
|
INFO_LOG(m_logger) << "HarzardArea: " << request.effectTime();
|
|
data.reserve1 = request.mineId();
|
|
data.aesType = TetraIcd::AreaEffectSimulationType::DangerZoneExplosion;
|
|
}
|
|
else if (request.eventType() == ProjectDataManagement::EventType::AirSupport)
|
|
{
|
|
data.aesType = TetraIcd::AreaEffectSimulationType::AirSupport;
|
|
}
|
|
|
|
}
|
|
else
|
|
data.originatorEquipmentNumber = request.originatorEquipmentNumber();
|
|
const auto &tabPos = request.position();
|
|
data.buildingId = tabPos.moutObjectId().is_set() ? tabPos.moutObjectId().get() : 0;
|
|
data.roomId = tabPos.moutRoomId().is_set() ? tabPos.moutRoomId().get() : 0;
|
|
data.remainEffectPercent = request.remainEffectPercent();
|
|
data.relPosition = m_mainHandler->posHandler()->geographicToRelative(tabPos.position());
|
|
|
|
// NOTE: igniterType/IgniterFunciton = 0 as long as SendCesHitRequest does not contain values
|
|
if (m_mainHandler->pdmHandler()->isSmartChargeType({request.chargeTypeId(),0,0}))
|
|
data.remainEffectTasCodeDirect = calculateRemainEffectTasCode(ct.id(), request.remainEffectPercent());
|
|
else if ((request.eventType() == ProjectDataManagement::EventType::HitBuilding) ||
|
|
(request.eventType() == ProjectDataManagement::EventType::HitEffectSimulation) // GUEZE-2873 / GUEZE-2888
|
|
) //Gebäude Sekudärwirkung
|
|
{
|
|
data.remainEffectTasCodeDirect = calculateRemainEffectTasCode(ct.id(), request.remainEffectPercent());
|
|
DEBUG_LOG(m_logger) << "PDM::EventType = " << request.eventType()
|
|
<< " equipmentNumber=" << request.equipmentNumber()
|
|
<< " originatorEquipmentNumber=" << data.originatorEquipmentNumber
|
|
<< " chargeType=" << ct.id()
|
|
<< " remainEffectPercent()=" << request.remainEffectPercent()
|
|
<< " -> remainEffectTasCodeDirect=" << data.remainEffectTasCodeDirect ;
|
|
}
|
|
else
|
|
data.remainEffectTasCodeDirect = request.remainEffectPercent();//calculateRemainEffectTasCode(ct.id(), request.remainEffectPercent());
|
|
|
|
// [GUEZE-3469] Funktionsraum dekontaminiert faelschlicherweise
|
|
if (m_mainHandler->aesHandler()->aesTypeFromId(request.aesId()) == TetraIcd::AreaEffectSimulationType::FunctionalArea)
|
|
{
|
|
// GUEZSB60_ICD_52_Zentrale-TNE
|
|
// 3.3.2.5.9.6 Trefferereignis Sekundärwirkung
|
|
// 6 = Funktionsraum 0 = verlassen
|
|
// 1 = betreten Meldung wird einmalig beim Betreten des Funktionraums und beim Verlassen gesendet.
|
|
// Feld Munitionsart: Betriebsmodus (MS-Byte) / Wartezeit (LS-Byte) für Entgiftungsmaßnahmen
|
|
// Feld Verursacher: Funktionsraumkennung
|
|
// Feld Reserve1: Betriebsmodus (MS-Byte) / Wartezeit (LS-Byte) für Instandsetzungsmaßnahmen
|
|
// Feld Reserve2: Betriebsmodus (MS-Byte) / Wartezeit (LS-Byte) für San.-dienstliche Versorgung
|
|
|
|
AreaEffectSimulation::FunctionalArea fa = m_mainHandler->aesHandler()->dtcAes()->functionalArea(request.aesId());
|
|
DEBUG_LOG(m_logger) << "fa maintMode=" << fa.maintMode()
|
|
<< " maintTime=" <<fa.maintTime()
|
|
<< " deconMode=" << fa.deconMode()
|
|
<< " deconTime=" << fa.deconTime()
|
|
<< " medicMode=" << fa.medicMode()
|
|
<< " medicTime=" << fa.medicTime();
|
|
|
|
data.chargeTasCodeDirect = 0;
|
|
data.reserve1 = 0;
|
|
data.reserve2 = 0;
|
|
if (fa.deconMode() == AreaEffectSimulation::AesOperatingMode_def::OmWaitingTime)
|
|
{
|
|
qint32 msb = AreaEffectSimulation::AesOperatingMode_def::OmWaitingTime << 8;
|
|
qint32 lsb = fa.deconTime() / 1000 / 60 / 10; // dissolution in 10 minute steps
|
|
data.chargeTasCodeIndirect = msb | lsb;
|
|
DEBUG_LOG(m_logger) << "deconMode: remainEffectTasCodeDirect=" << data.chargeTasCodeIndirect
|
|
<< " msb=" << msb
|
|
<< " lsb=" << lsb;
|
|
}
|
|
if (fa.maintMode() == AreaEffectSimulation::AesOperatingMode_def::OmWaitingTime)
|
|
{
|
|
qint32 msb = AreaEffectSimulation::AesOperatingMode_def::OmWaitingTime << 8;
|
|
qint32 lsb = fa.maintTime() / 1000 / 60 / 10; // dissolution in 10 minute steps
|
|
data.reserve1 = msb | lsb;
|
|
DEBUG_LOG(m_logger) << "maintMode: reserve1=" << data.reserve1
|
|
<< " msb=" << msb
|
|
<< " lsb=" << lsb;
|
|
}
|
|
if (fa.medicMode() == AreaEffectSimulation::AesOperatingMode_def::OmWaitingTime)
|
|
{
|
|
qint32 msb = AreaEffectSimulation::AesOperatingMode_def::OmWaitingTime << 8;
|
|
qint32 lsb = fa.medicTime() / 1000 / 60 / 10; // dissolution in 10 minute steps
|
|
data.reserve2 = msb | lsb;
|
|
DEBUG_LOG(m_logger) << "medicMode: reserve2=" << data.reserve2
|
|
<< " msb=" << msb
|
|
<< " lsb=" << lsb;
|
|
}
|
|
}
|
|
|
|
m_ftsTab->sendCesHitReply(cookie, fillFro(request.participantId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendParticipantSwVerionsRequest(const rti::core::SampleIdentity &cookie, const SendParticipantSwVerionsRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onSendParticipantSwVerionsRequest: " << request.equipmentNumber() << " - " << request.equipmentFunctionId();
|
|
|
|
TetraIcd::ParticipantSwVersionsRequest data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.equipmentFunctionId = request.equipmentFunctionId();
|
|
|
|
m_ftsTab->sendParticipantSwVerionsReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendParticipantModeRequest(const rti::core::SampleIdentity &cookie, const SendParticipantModeRequest &request)
|
|
{
|
|
TetraIcd::ParticipantMode data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.language = static_cast<TetraIcd::Language>(request.language().underlying());
|
|
data.operationMode = static_cast<TetraIcd::ParticipantMode::OperationMode>(request.operationMode().underlying());
|
|
data.reactivationDetoxication = request.reactivationDetoxication();
|
|
data.reactivationMaintenance = request.reactivationMaintenance();
|
|
data.reactivationMedic = request.reactivationMedic();
|
|
data.modeVest = static_cast<TetraIcd::ParticipantMode::WphMode>(request.protectionModeVest().underlying());
|
|
data.modeHelmet = static_cast<TetraIcd::ParticipantMode::WphMode>(request.protectionModeHelmet().underlying());
|
|
data.personellProtectionMode = static_cast<TetraIcd::ParticipantMode::PersonellProtection>(request.personellProtection().underlying());
|
|
data.protectionLevel = static_cast<TetraIcd::ParticipantMode::ProtectionLevel>(request.protectionLevel().underlying());
|
|
data.handgrenadeSearchMode = static_cast<TetraIcd::ParticipantMode::HandgrenadeSearchMode>(request.handgrenadeSearchMode().underlying());
|
|
data.internationalMode = static_cast<TetraIcd::ParticipantMode::InternationalMode>(request.internationalMode().underlying());
|
|
data.abcProtectionMode = static_cast<TetraIcd::ParticipantMode::ABCProtectionMode>(request.abcProtectionMode().underlying());
|
|
|
|
m_ftsTab->sendParticipantModeReply(cookie, fillFro(request.requestId(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onDemandParticipantModeRequest(const rti::core::SampleIdentity &cookie, const DemandParticipantModeRequest &request)
|
|
{
|
|
TetraIcd::DemandParticipantMode data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
|
|
m_ftsTab->demandParticipantModeReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendParticipantConfigurationRequest(const rti::core::SampleIdentity &cookie, const SendParticipantConfigurationRequest &request)
|
|
{
|
|
TetraIcd::ParticipantConfiguration data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
// positioning
|
|
data.positionIntervallVehicle = request.positionIntervallVehicle();
|
|
data.positionIntervallPersonell = request.positionIntervallPersonell();
|
|
data.positionIntervallAircraft = request.positionIntervallAircraft();
|
|
data.positionTransmissionIntervall = request.positionTransmissionIntervall();
|
|
data.heightbarrier = request.heightbarrier();
|
|
data.faultPositionHandling = static_cast<TetraIcd::ParticipantConfiguration::FaultPositionHandling>(request.faultPositionHandling().underlying());
|
|
data.switchingPositionIntervall = static_cast<TetraIcd::ParticipantConfiguration::SwitchingPositionIntervall>(request.switchingPositionIntervall().underlying());
|
|
// radio protocoll parameter
|
|
data.waittimeAdditionalBroadcastDemand = request.waittimeAdditionalBroadcastDemand();
|
|
data.factorWaittimeIncreaseAtHighload = request.factorWaittimeIncreaseHighload();
|
|
// automatic vulnerability increase
|
|
data.waittimeAutomaticVulnerabilityIncreaseLevel1 = request.waittimeAutomaticVulnerabilityIncreaseLevel1();
|
|
data.waittimeAutomaticVulnerabilityIncreaseLevel2 = request.waittimeAutomaticVulnerabilityIncreaseLevel2();
|
|
data.waittimeAutomaticVulnerabilityIncreaseLevel3 = request.waittimeAutomaticVulnerabilityIncreaseLevel3();
|
|
// optical code
|
|
data.opticalCode = static_cast<TetraIcd::ParticipantConfiguration::OpticalCode>(request.opticalCode().underlying());
|
|
// vulnerability model
|
|
data.vulnerabilityModel = request.vulnerabilityModel();
|
|
data.validTimeOps = request.validTimeOps();
|
|
|
|
m_ftsTab->sendParticipantConfigurationReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendParticipantBlockedAreaRequest(const rti::core::SampleIdentity &cookie, const SendParticipantBlockedAreaRequest &request)
|
|
{
|
|
TetraIcd::CesHitRequest data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = QDateTime::currentMSecsSinceEpoch(); // TODO
|
|
data.aesType = TetraIcd::AreaEffectSimulationType::SpecialArea;
|
|
data.remainEffectPercent = request.blockedAreaMode() == BlockedAreaMode::Enter ? 1 : 0;
|
|
|
|
m_ftsTab->sendParticipantBlockedAreaReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendParticipantBeStillWarningRequest(const rti::core::SampleIdentity &cookie, const SendParticipantBeStillWarningRequest &request)
|
|
{
|
|
TetraIcd::CesHitRequest data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = QDateTime::currentMSecsSinceEpoch(); // TODO
|
|
data.aesType = TetraIcd::AreaEffectSimulationType::BeStillWarning;
|
|
data.remainEffectPercent = 0;
|
|
|
|
WARNING_LOG(m_logger) << "sendParticipantBeStillWarningReply equipmentNumber=" << request.equipmentNumber();
|
|
m_ftsTab->sendParticipantBeStillWarningReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendSetSanitationRequest(const rti::core::SampleIdentity &cookie, const SendSetSanitationRequest &request)
|
|
{
|
|
TetraIcd::Sanitation data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
data.proceduresTaken = request.sanitationProceduresTaken();
|
|
data.sanitationResult = TetraIcd::SanitationResult::NoEffect;
|
|
data.sanitationEvaluation = TetraIcd::SanitationEvaluation::Okay; // To have a 0 for TETRA
|
|
data.uniqeId = 0;
|
|
data.originatorEquipmentNumber = request.originatorEquipmentNumber();
|
|
data.qualification = static_cast<TetraIcd::Qualification>(request.qualification().underlying());
|
|
m_ftsTab->sendSetSanitationReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendSelectiveReammunitionRequest(const rti::core::SampleIdentity &cookie, const SendSelectiveReammunitionRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onSendSelectiveReammunitionRequest for equipment number: " << request.equipmentNumber();
|
|
TetraIcd::SelectiveReammunition data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
data.gearId = request.gearId();
|
|
for(auto ra : request.reammunition())
|
|
{
|
|
TetraIcd::Reammunition tra;
|
|
tra.chargeTypeId = ra.chargeTypeId();
|
|
tra.newDefaultStock = ra.newDefaultStock();
|
|
tra.newStock = ra.newStock();
|
|
tra.tracerRatio = ra.tracerRatio();
|
|
data.reammunitions.push_back(tra);
|
|
}
|
|
m_ftsTab->sendSelectiveReammunitionReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendResetAllDusMinesRequest(const rti::core::SampleIdentity &cookie, const SendResetAllDusMinesRequest &request)
|
|
{
|
|
// We actually just need to have the call, no contents.
|
|
Q_UNUSED(request);
|
|
|
|
m_mainHandler->aesHandler()->resetAllDusMines();
|
|
m_ftsTab->sendResetAllDusMinesReply(cookie, fillFro(0, m_txCallback->txData(TetraIcd::DusMineReactivation())));
|
|
|
|
}
|
|
|
|
void RecvFromDdsFts::onDemandParticipantConfigurationRequest(const rti::core::SampleIdentity &cookie, const DemandParticipantConfigurationRequest &request)
|
|
{
|
|
TetraIcd::DemandParticipantConfiguration data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
|
|
m_ftsTab->demandParticipantConfigurationReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSetDevicePowerRequest(const rti::core::SampleIdentity &cookie, const SetDevicePowerRequest &request)
|
|
{
|
|
TetraIcd::SetDevicePowerRequest data;
|
|
data.header.equipmentNumber = request.equipmentNumber();
|
|
data.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
data.powerType = static_cast<TetraIcd::PowerMethod>(request.powerType().underlying());
|
|
data.subdeviceId = request.subdeviceId();
|
|
|
|
m_ftsTab->setDevicePowerReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(data)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onAdlerCalculateTrajectoryRequest(const rti::core::SampleIdentity &cookie, const AdlerCalculateTrajectoryRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onSendCalculateTrajectoryAdlerRequest";
|
|
}
|
|
|
|
|
|
void RecvFromDdsFts::onSendOcCommandRequest(const rti::core::SampleIdentity &cookie, const SendOcCommandRequest &request)
|
|
{
|
|
TetraIcd::OcCommand data;
|
|
data.action = request.action();
|
|
|
|
bool bRet = true;
|
|
|
|
for (const int equipNo : request.equipmentNumbers())
|
|
{
|
|
data.header.equipmentNumber = equipNo;
|
|
if (!m_txCallback->txData(data))
|
|
bRet = false;
|
|
}
|
|
|
|
m_ftsTab->sendOcCommandReply(cookie, fillFro(request.requestId(), bRet));
|
|
}
|
|
|
|
|
|
void RecvFromDdsFts::onSendUasWaypointRequest(const rti::core::SampleIdentity &cookie, const SendUasWaypointRequest &request)
|
|
{
|
|
TetraIcd::UAVPerformMission mission;
|
|
mission.header.equipmentNumber = request.equipmentNumber();
|
|
mission.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
mission.missionName = QString::fromStdString(request.name());
|
|
mission.missionId = request.planId();
|
|
|
|
ERROR_LOG(m_logger) << "####################### request.equipmentNumber(): " << request.equipmentNumber() << ", request.name(): " << request.name() << ", mission.header.equipmentNumber: " << mission.header.equipmentNumber << ", properties: " << request.properties();
|
|
|
|
TetraIcd::UAVAction action;
|
|
action.task = TetraIcd::UAVActionTask::Loiter;
|
|
|
|
|
|
auto &pos = action.absPosition;
|
|
|
|
|
|
double lat = 0, lon = 0, z = 0;
|
|
|
|
try
|
|
{
|
|
const auto props = LtsUtils::JsonObject::fromJsonSafe(request.properties());
|
|
|
|
lat = props.value<double>("location_y");
|
|
lon = props.value<double>("location_x");
|
|
z = props.valueOr<double>("location_z", 0);
|
|
}
|
|
catch (const std::exception &ex)
|
|
{
|
|
ERROR_LOG(m_logger) << "props is missing critical values: " << ex.what();
|
|
m_ftsTab->sendUasWaypointReply(cookie, fillFro(request.equipmentNumber(), false));
|
|
return;
|
|
}
|
|
|
|
pos.lat = lat;
|
|
pos.lon = lon;
|
|
pos.z = z;
|
|
|
|
mission.actions.push_back(action);
|
|
|
|
bool ret = m_txCallback->txData(mission); // send waypoint to uav via uas tab plugin
|
|
m_ftsTab->sendUasWaypointReply(cookie, fillFro(request.equipmentNumber(), ret));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendModifyUasStateRequest(const rti::core::SampleIdentity &cookie, const SendModifyUasStateRequest &request)
|
|
{
|
|
TetraIcd::UAVChangeState changeState;
|
|
changeState.header.equipmentNumber = request.equipmentNumber();
|
|
changeState.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
changeState.requestedState = static_cast<TetraIcd::UAVState>(request.uasState().underlying());
|
|
m_ftsTab->sendModifyUasStateReply(cookie, fillFro(request.equipmentNumber(), m_txCallback->txData(changeState)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendExFireReadinessRequest(const rti::core::SampleIdentity &cookie, const SendExFireReadinessRequest &request)
|
|
{
|
|
TetraIcd::ExFireReadiness fireReadiness;
|
|
fireReadiness.header.equipmentNumber = 100;
|
|
fireReadiness.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
fireReadiness.partyId = request.partyId();
|
|
fireReadiness.reference = QString::fromStdString(request.reference());
|
|
|
|
m_ftsTab->sendExFireReadinessReply(cookie, fillFro(request.participantId(), m_txCallback->txData(fireReadiness)));
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendExFiredReportRequest(const rti::core::SampleIdentity &cookie, const SendExFiredReportRequest &request)
|
|
{
|
|
TetraIcd::ExFiredReport firedReport;
|
|
firedReport.header.equipmentNumber = request.participantId();
|
|
firedReport.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
firedReport.partyId = request.partyId();
|
|
firedReport.reference = QString::fromStdString(request.reference());
|
|
firedReport.unitIdentifier = QString::fromStdString(request.unitIdentifier());
|
|
firedReport.identifier = QString::fromStdString(request.identifier());
|
|
|
|
m_ftsTab->sendExFiredReportReply(cookie, fillFro(request.participantId(), m_txCallback->txData(firedReport)));
|
|
|
|
}
|
|
|
|
void RecvFromDdsFts::onSendExConfirmationReportRequest(const rti::core::SampleIdentity &cookie, const SendExConfirmationReportRequest &request)
|
|
{
|
|
TetraIcd::ExConfirmationReport confirmationReport;
|
|
confirmationReport.header.equipmentNumber = request.participantId();
|
|
confirmationReport.header.timeStamp = QDateTime::currentMSecsSinceEpoch();
|
|
confirmationReport.partyId = request.partyId();
|
|
confirmationReport.reference = QString::fromStdString(request.reference());
|
|
confirmationReport.unitIdentifier = QString::fromStdString(request.unitIdentifier());
|
|
confirmationReport.identifier = QString::fromStdString(request.identifier());
|
|
|
|
m_ftsTab->sendExConfirmationReportReply(cookie, fillFro(request.participantId(), m_txCallback->txData(confirmationReport)));
|
|
|
|
}
|
|
|
|
Core::FunctionReplyObject RecvFromDdsFts::fillFro(int participantId, bool bSuccess)
|
|
{
|
|
if (bSuccess)
|
|
return Core::FunctionReplyObject(participantId);
|
|
return Core::FunctionReplyObject(participantId, tr_lts("dds", "Error sending telegram to tetra."));
|
|
}
|
|
|
|
// Charge Type ID is already baseChargeType
|
|
int RecvFromDdsFts::getDestructiveCategorie(const int destructiveFactor) const
|
|
{
|
|
int categorie = 0;
|
|
if (destructiveFactor > 100)
|
|
categorie = 5;
|
|
else if (destructiveFactor > 50)
|
|
categorie = 4;
|
|
else if (destructiveFactor > 10)
|
|
categorie = 3;
|
|
else if (destructiveFactor > 1)
|
|
categorie = 2;
|
|
else if (destructiveFactor > 0)
|
|
categorie = 1;
|
|
else
|
|
categorie = 0;
|
|
|
|
return categorie;
|
|
}
|
|
|
|
QMap<int, QVector<RecvFromDdsFts::RemainEffectStruct>> RecvFromDdsFts::loadRemainEffectStructMap()
|
|
{
|
|
QMap<int, QVector<RemainEffectStruct>> map;
|
|
|
|
// remainingEffects liefert ein Array, in einem QJsonObject "verkleidet".
|
|
// Dann werden alle keys ermittelt, damit man aus dem Array/QJsonObject
|
|
// per value() wieder an die eigentlichen values kommt...
|
|
// Sieht irgendwie sehr kompliziert aus. Sollte remainingEffects vielleicht besser ein array liefern???
|
|
|
|
QJsonObject obj = Settings::remainingEffects();
|
|
|
|
QVector<RemainEffectStruct> resVec;
|
|
|
|
QStringList keyList = obj.keys();
|
|
for (const auto &key : qAsConst(keyList))
|
|
{
|
|
const auto &val = obj.value(key).toObject();
|
|
|
|
resVec.clear();
|
|
resVec.resize(val.size());
|
|
|
|
QStringList x = val.keys();
|
|
int i=0;
|
|
for (const auto &resElement : qAsConst(x))
|
|
{
|
|
const auto val2 = val.value(resElement).toInt();
|
|
|
|
RemainEffectStruct res(resElement.toInt(), static_cast<RemainEffectStruct::Category>(val2));
|
|
|
|
resVec[i++] = res;
|
|
}
|
|
|
|
std::sort(resVec.begin(), resVec.end(), [](const RemainEffectStruct &a, const RemainEffectStruct &b)
|
|
{
|
|
return a.remainEffectMax < b.remainEffectMax;
|
|
});
|
|
|
|
map.insert(key.toInt(), resVec);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
int RecvFromDdsFts::calculateRemainEffectTasCode(int chargeTypeIdBase, int remainEffectPercent) const
|
|
{
|
|
if (remainEffectPercent < 0)
|
|
return 0;
|
|
if (remainEffectPercent > 100)
|
|
remainEffectPercent = 100;
|
|
|
|
const int destructiveFactor = m_mainHandler->pdmHandler()->buildingChargeEffect(chargeTypeIdBase).destructiveFactor();
|
|
const int categorie = getDestructiveCategorie(destructiveFactor);
|
|
const auto &value = m_categorieData.value(categorie);
|
|
|
|
// must be sorted, but loadRemainEffectStructMap() ensures this.
|
|
for (const auto &remainEffect : value)
|
|
{
|
|
if (remainEffectPercent <= remainEffect.remainEffectMax)
|
|
return (remainEffect.chargeTypeId()); // always return OSAG as the TNE is not capable of handling ULEIS IED charges (yet).
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint32_t RecvFromDdsFts::getVulnerabilityVitalityIndexFromVitalityAndVba(uint32_t vulnerabilityKind, uint32_t vitality)
|
|
{
|
|
uint32_t ret = vulnerabilityKind;
|
|
|
|
if (vitality == UINT16_MAX || vitality == 0)
|
|
vitality = 0;
|
|
else
|
|
{
|
|
vitality /= 10;
|
|
vitality += 1;
|
|
if (vitality > 11)
|
|
{
|
|
ERROR_LOG(m_logger) << "Cant convert Vitality!";
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
ret += vitality << 12;
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|