Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/TetraIF/CoPrtCnv/CoPrtCnvTelegramConverterNewIcd.cpp
T
torstenandCopilot bafed3705f Qt6 migration: LtsWidgets API fixes, LtsWebSocket logger init, RTI Docker install
- LtsWidgets: Fixed Qt6 API compatibility issues
  - QWheelEvent::delta() → angleDelta().y()
  - QStyleOption::init() → initFrom()
  - QComboBox activated signal signature change
  - QTextCodec removal (UTF-8 default in Qt6)
  - Missing widget includes added

- LtsWebSocket: Fixed m_logger reference initialization
  - Added NGLLoggerBootstrap includes
  - Proper initialization in constructor initializer lists

- CMake: Added BUILD_LTSWEBSOCKET option for temporary exclusion

- Docker: RTI Connext permanent installation script added
  - ci/install-rti-in-docker.sh for persistent RTI setup
  - Removes need for volume mounting RTI into container

- BUILD options: FilterManagement, RTI, Codification, Grantlee, LtsWebSocket
  can be disabled for partial builds during migration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-19 14:04:26 +02:00

1816 lines
83 KiB
C++

#include "CoPrtCnvCentralTelegram.hpp"
#include "CoPrtCnvRadioTelegram.hpp"
#include "CoPrtCnvTelegramConverter.hpp"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLineF>
#include <TrainingAreaBase/training_area_telegrams.h>
#include <math.h>
#include <utility>
#include <vector>
using namespace TrainingAreaBase::TetraIcd;
namespace N_CoPrtCnv
{
namespace CoPrtCnvTelegramConverter
{
static bool s_use2BytesForSingleFireDiameter = true;
static bool s_usePvSan = false;
static inline NGL::INGLLogger& logger()
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("CoPrtCnvTelegramConverter");
}
template <typename T> static inline bool checkBitmask(const T& d, int bitmask)
{
return ((d & bitmask) == bitmask);
}
template <typename T> void getSpecialSensorData(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t offset, T* tele)
{
const uint8_t betrZust = a_radioTelegram->getPayloadDataUInt32(offset, 1);
const uint8_t spuerfunktion = a_radioTelegram->getPayloadDataUInt32(offset + 1, 1);
tele->operationalState = betrZust;
tele->airSensor = checkBitmask(spuerfunktion, 0x80);
tele->tireSensor = checkBitmask(spuerfunktion, 0x40);
tele->pointSensor = checkBitmask(spuerfunktion, 0x20);
tele->solidMatterSampleExtractor = checkBitmask(spuerfunktion, 0x10);
}
int getVitality(uint32_t index)
{
uint32_t vitalty = (index &= 0xF000);
uint32_t retVitalty = 0;
retVitalty = vitalty >> 12;
if (retVitalty > 0)
{
retVitalty -= 1;
return retVitalty * 10;
}
return UINT16_MAX;
}
void setVitality(uint16_t& index, uint16_t vitality)
{
if (vitality == UINT16_MAX)
vitality = 0;
else
{
vitality /= 10;
vitality += 1;
if (vitality > 11)
{
ERROR_LOG(logger()) << "Cant convert Vitality!";
return;
}
}
for (int i = 0; i <= 3; i++)
{
if (((vitality) & (1 << (i))))
index |= (1UL << (i + 12));
}
}
template <typename T> void getTaktZustand(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t iOffset, T* tele)
{
tele->vulnerabilityState = static_cast<TrainingAreaBase::TetraIcd::VulnerabilityState>(
a_radioTelegram->getPayloadDataUInt32(iOffset + 0, 1));
const uint32_t teilnehmertyp = a_radioTelegram->getPayloadDataUInt32(iOffset + 1, 1);
const uint32_t index = a_radioTelegram->getPayloadDataUInt32(iOffset + 2, 2);
if (index)
{
uint32_t indexForVulnerabilit = index;
indexForVulnerabilit &= 0x0FFF;
tele->tasVulnerabilityKindId = teilnehmertyp;
tele->tasVulnerabilityKindId <<= 16;
tele->tasVulnerabilityKindId |= indexForVulnerabilit;
tele->tasVitality = getVitality(index);
}
else
tele->tasVulnerabilityKindId = 0;
tele->vulnerabilityBits = 0;
int tmp = a_radioTelegram->getPayloadDataUInt32(iOffset + 4, 2);
if (tmp == 0)
tele->vulnerabilityBits |= 0x1;
else
{
for (int i = 1; i <= static_cast<int>(VulnerabilityState::CContamination); ++i)
tele->vulnerabilityBits |= ((tmp >> (16 - i)) & 0x1) << (i);
}
}
static BiteError getBiteError(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t iOffset)
{
BiteError ret;
ret.canDeviceNumber = a_radioTelegram->getPayloadDataUInt8(iOffset + 0);
ret.subdeviceNumber = a_radioTelegram->getPayloadDataUInt8(iOffset + 1);
ret.uniqueId = a_radioTelegram->getPayloadDataUInt32(iOffset + 2, 4);
ret.errorNumber = a_radioTelegram->getPayloadDataUInt8(iOffset + 6);
return ret;
}
static void convertToTetraEncoding(N_CoPrtCnv::CoPrtCnvRadioTelegram* radioTelegramm, const std::string& stdString,
const uint16_t a_size)
{
QByteArray encodedData = QByteArray::fromStdString(stdString);
encodedData = encodedData.leftJustified(a_size, '\0', true);
encodedData[a_size - 1] = '\0';
const uint8_t* data = reinterpret_cast<const uint8_t*>(encodedData.data());
radioTelegramm->setPayloadData(data, a_size);
}
void setTetraTextCodec(const char* /*codecName*/)
{
// Qt6 uses UTF-8 by default, QTextCodec is no longer available
}
void setUse2BytesForSingleFireDiameter(bool bUse)
{
s_use2BytesForSingleFireDiameter = bUse;
}
void setUsePvSan(bool bUse)
{
s_usePvSan = bUse;
}
template <typename T> T fromJson(CoPrtCnvCentralTelegram* radioTelegram)
{
return T::fromJson(radioTelegram->jsonData());
}
template <typename T> const T& fromJson(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram* tabTelegram)
{
return static_cast<const T&>(*tabTelegram);
}
TrainingAreaBase::TetraIcd::TelegramId getTelegramId(CoPrtCnvCentralTelegram* centralTelegram)
{
return TrainingAreaBase::TetraIcd::TelegramId(centralTelegram->telegramId());
}
TrainingAreaBase::TetraIcd::TelegramId
getTelegramId(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram* tabTelegram)
{
return tabTelegram->id();
}
void convertToSecAndSetTime(int64_t timeStamp, N_CoPrtCnv::CoPrtCnvRadioTelegram* radioTelegram)
{
radioTelegram->setPayloadData((uint32_t)(timeStamp / 1000), 4);
}
template <typename T> void setCommonAesParams(const T& tele, CoPrtCnvRadioTelegram* radioTelegram)
{
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
convertToTetraEncoding(radioTelegram, tele.name, 8);
radioTelegram->setPayloadData(tele.partyId, 1);
convertToSecAndSetTime(tele.effectStart, radioTelegram);
}
template <typename T> void setAesPosition(const T& tele, CoPrtCnvRadioTelegram* radioTelegram)
{
radioTelegram->setPayloadData(tele.relEffectPosition.offsetY, 3);
radioTelegram->setPayloadData(tele.relEffectPosition.offsetX, 3);
}
static inline int compassToMathAngleForSfm(double compassDegree)
{
int ret = qRound((90.0 - compassDegree) * 100.0);
while (ret < 0)
ret += 36000;
while (ret > 36000)
ret -= 36000;
return ret;
}
template <typename T> static CoPrtCnvRadioTelegram* convertToRadioInternal(T* a_telegram)
{
N_CoPrtCnv::CoPrtCnvRadioTelegram* radioTelegram = nullptr;
switch (getTelegramId(a_telegram))
{
case Constraints<Init>::id(): {
const Init& tele(fromJson<Init>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_INIT, 4, tele.header.equipmentNumber);
uint8_t initialisierungsdaten = 0;
initialisierungsdaten |= ((uint8_t(tele.resetVulnerabilityState) & 0x01) << 6);
initialisierungsdaten |= ((uint8_t(tele.restockCharges) & 0x01) << 5);
initialisierungsdaten |= ((uint8_t(tele.resetManipulation) & 0x01) << 0);
initialisierungsdaten |= ((uint8_t(tele.restockSanitationMaterial) & 0x01) << 1);
radioTelegram->setPayloadData(initialisierungsdaten);
break;
}
case Constraints<SetVulnerabilityModel>::id(): {
const SetVulnerabilityModel& tele(fromJson<SetVulnerabilityModel>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_KONFIGURATION_WIRKMODELL, 9, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData((uint8_t)tele.vulnerabilityModelMineIed);
radioTelegram->setPayloadData((uint8_t)tele.vulnerabilityModelAreaFire);
radioTelegram->setPayloadData((uint8_t)tele.vulnerabilityModelOperatingResource);
radioTelegram->setPayloadData((uint8_t)tele.vulnerabilityModelAcWeaponry);
break;
}
case Constraints<DemandEquipmentConfigurationReport>::id(): {
const DemandEquipmentConfigurationReport& tele(fromJson<DemandEquipmentConfigurationReport>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_ANFORDERUNG_KONFIGURATIONSDATEN, 3,
tele.header.equipmentNumber);
break;
}
case Constraints<StateChange>::id(): {
const StateChange& tele(fromJson<StateChange>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TAKTISCHER_STATUS, 16, tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayloadData((uint8_t)tele.vulnerabilityState);
radioTelegram->setPayloadData((uint8_t)(tele.tasVulnerabilityKindId & 0xFF));
uint16_t vulnerabilityVitalityIndex = 0;
vulnerabilityVitalityIndex = (uint16_t)((tele.tasVulnerabilityKindId >> 16) & 0xFFFF);
setVitality(vulnerabilityVitalityIndex, tele.tasVitality);
radioTelegram->setPayloadData((uint16_t)vulnerabilityVitalityIndex, 2);
radioTelegram->setPayloadData((uint16_t)tele.vulnerabilityBits, 2);
radioTelegram->setPayloadData((uint8_t)tele.originatorId);
radioTelegram->setPayloadData((uint16_t)tele.originatorType, 2);
break;
}
case Constraints<BiteReport>::id(): {
const BiteReport& tele(fromJson<BiteReport>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_BITE_MELDUNG2, 27, tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayloadData((uint8_t)tele.loginType);
radioTelegram->setPayloadData((uint32_t)tele.biteState, 3);
radioTelegram->setPayloadData((uint8_t)tele.batteryState);
if (tele.biteErrors.size() > 0)
{
radioTelegram->setPayloadData((uint8_t)tele.biteErrors[0].canDeviceNumber);
radioTelegram->setPayloadData((uint8_t)tele.biteErrors[0].subdeviceNumber);
radioTelegram->setPayloadData((uint32_t)tele.biteErrors[0].uniqueId, 4);
radioTelegram->setPayloadData((uint8_t)tele.biteErrors[0].errorNumber);
radioTelegram->setPayloadData((uint8_t)tele.biteErrors.size() - 1);
}
else
{
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint32_t)0, 4);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint8_t)0);
}
radioTelegram->setPayloadData((uint32_t)0, 3);
radioTelegram->setPayloadData((uint8_t)tele.configError);
radioTelegram->setPayloadData((uint32_t)tele.configState, 3);
for (const BiteError& be : tele.biteErrors)
{
radioTelegram->setPayloadData((uint8_t)be.canDeviceNumber);
radioTelegram->setPayloadData((uint8_t)be.subdeviceNumber);
radioTelegram->setPayloadData((uint32_t)be.uniqueId, 4);
radioTelegram->setPayloadData((uint8_t)be.errorNumber);
}
break;
}
case Constraints<ExerciseEnvironmentData>::id(): {
const ExerciseEnvironmentData& tele(fromJson<ExerciseEnvironmentData>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_UMGEBUNGS_MELDUNG2, 20, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.exerciseId, 2);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint8_t)tele.timeZone);
radioTelegram->setPayloadData((uint8_t)tele.utmZone);
radioTelegram->setPayloadData(tele.utmBand);
radioTelegram->setPayloadData((uint8_t*)tele.grid.c_str(), 2);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData((uint32_t)0, 4);
break;
}
case Constraints<DemandBite>::id(): {
const DemandBite& tele(fromJson<DemandBite>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_AUFFORDERUNG_BITE_MELDUNG, 4, tele.header.equipmentNumber);
radioTelegram->setPayloadData(tele.withSelfTest, 1);
break;
}
case Constraints<PositionReport>::id(): {
const PositionReport& tele(fromJson<PositionReport>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_POSITIONS_MELDUNG, 14, tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayloadData(tele.relPosition.offsetY, 3);
radioTelegram->setPayloadData(tele.relPosition.offsetX, 3);
radioTelegram->setPayloadData((uint8_t)(((tele.gpsQuality.moreThan4SatellitesAvailable) ? 0x80 : 0) |
((tele.gpsQuality.dgpsModeAvailable) ? 0x40 : 0) |
(tele.gpsQuality.pdopValue & 0x3f)),
1);
break;
}
case Constraints<CreateSingleExplosion>::id(): {
const CreateSingleExplosion& tele(fromJson<CreateSingleExplosion>(a_telegram));
const int teleSize = s_use2BytesForSingleFireDiameter ? 29 : 28;
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_EINZELGESCHOSS, teleSize,
tele.header.equipmentNumber);
setCommonAesParams(tele, radioTelegram);
setAesPosition(tele, radioTelegram);
if (s_use2BytesForSingleFireDiameter)
{
Q_ASSERT(tele.effectDiameter < 256 * 256 && tele.effectDiameter >= 0);
radioTelegram->setPayloadData(tele.effectDiameter, 2);
}
else
{
Q_ASSERT(tele.effectDiameter < 256 && tele.effectDiameter >= 0);
radioTelegram->setPayloadData(tele.effectDiameter, 1);
}
radioTelegram->setPayloadData(tele.chargeTypeId, 1);
break;
}
case Constraints<CreateAreaExplosion>::id(): {
const CreateAreaExplosion& tele(fromJson<CreateAreaExplosion>(a_telegram));
#ifdef GUEZ_MODE
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_WIRKFELD_FLAECHENDECKENDES_FEUER, 44 + tele.mhPoints.size() * 6, tele.header.equipmentNumber);
#else
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_FLAECHENDECKENDES_FEUER, 36,
tele.header.equipmentNumber);
#endif
setCommonAesParams(tele, radioTelegram);
radioTelegram->setPayloadData(tele.effectDuration / 1000, 2);
radioTelegram->setPayloadData(tele.relCorner.offsetY, 3);
radioTelegram->setPayloadData(tele.relCorner.offsetX, 3);
radioTelegram->setPayloadData(tele.width / 5, 1);
radioTelegram->setPayloadData(tele.height / 5, 1);
radioTelegram->setPayloadData(compassToMathAngleForSfm(tele.rotationAngle + 90.0), 2);
#ifdef GUEZ_MODE
radioTelegram->setPayloadData(tele.mhpWidth / 5, 1);
radioTelegram->setPayloadData(tele.mhpLength / 5, 1);
radioTelegram->setPayloadData(compassToMathAngleForSfm(tele.mhpRotation + 90.0), 2);
#endif
radioTelegram->setPayloadData(tele.impactCount, 2);
#ifdef GUEZ_MODE
radioTelegram->setPayloadData(tele.impactRadius, 2);
#else
radioTelegram->setPayloadData(tele.impactEdgeLength, 1);
#endif
radioTelegram->setPayloadData(tele.chargeTypeId, 1);
#ifdef GUEZ_MODE
radioTelegram->setPayloadData((tele.hazardDistance / 5), 1);
radioTelegram->setPayloadData((uint8_t)0);
radioTelegram->setPayloadData(tele.mhPoints.size(), 1);
for (auto pos : std::as_const(tele.mhPoints))
{
radioTelegram->setPayloadData(pos.offsetY, 3);
radioTelegram->setPayloadData(pos.offsetX, 3);
}
#endif
break;
}
case Constraints<PauseEffectSimulation>::id(): {
const PauseEffectSimulation& tele(fromJson<PauseEffectSimulation>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP, 7, 0);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
break;
}
case Constraints<ResumeEffectSimulation>::id(): {
const ResumeEffectSimulation& tele(fromJson<ResumeEffectSimulation>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN, 17, 0);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
radioTelegram->setPayloadData(tele.sequelNumber, 2);
radioTelegram->setPayloadData(tele.nextImpact, 2);
convertToSecAndSetTime(tele.resumeTime, radioTelegram);
radioTelegram->setPayloadData(tele.remainDuration / 1000, 2);
break;
}
case Constraints<CreateMineArea>::id(): {
const CreateMineArea& tele(fromJson<CreateMineArea>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_WIRKFELD_MINENSPERRE, 5 + 22 + tele.segments.size() * 12, tele.header.equipmentNumber);
setCommonAesParams(tele, radioTelegram);
radioTelegram->setPayloadData(tele.effectDuration / (1000 * 60 * 60), 1);
radioTelegram->setPayloadData(qRound(tele.layingDepth), 1);
radioTelegram->setPayloadData(qRound(tele.layingDensity * 100), 1);
radioTelegram->setPayloadData(tele.chargeTypeId, 1);
double length = 0;
for (const MineAreaSegment& ms : tele.segments)
{
length +=
QLineF(ms.relStart.offsetX, ms.relStart.offsetY, ms.relEnd.offsetX, ms.relEnd.offsetY).length();
}
int minecount = qRound(length * tele.layingDensity);
if (minecount > 1200)
minecount = 1200;
radioTelegram->setPayloadData((uint32_t)minecount, 2);
radioTelegram->setPayloadData(tele.segments.size(), 1);
for (const MineAreaSegment& ms : tele.segments)
{
radioTelegram->setPayloadData(ms.relStart.offsetY, 3);
radioTelegram->setPayloadData(ms.relStart.offsetX, 3);
radioTelegram->setPayloadData(ms.relEnd.offsetY, 3);
radioTelegram->setPayloadData(ms.relEnd.offsetX, 3);
}
break;
}
case Constraints<MineAreaSingleMineState>::id(): {
const MineAreaSingleMineState& tele(fromJson<MineAreaSingleMineState>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_STATUS_MINENSPERRE,
5 + 4 + tele.mineState.size(), 0);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
radioTelegram->setPayloadData(tele.mineCount, 2);
radioTelegram->setPayloadData((uint8_t*)(tele.mineState.data()), tele.mineState.size());
break;
}
case Constraints<CreateNContamination>::id(): {
const CreateNContamination& tele(fromJson<CreateNContamination>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_A_KAMPFMITTEL, 38, tele.header.equipmentNumber);
setCommonAesParams(tele, radioTelegram);
radioTelegram->setPayloadData(tele.effectDuration / (1000 * 60), 2);
setAesPosition(tele, radioTelegram);
radioTelegram->setPayloadData(tele.innerRadius, 2);
radioTelegram->setPayloadData(tele.borderLengthInner, 2);
radioTelegram->setPayloadData(tele.borderLengthOuter, 2);
radioTelegram->setPayloadData(qRound(tele.spanAngle * 100), 2);
radioTelegram->setPayloadData(compassToMathAngleForSfm(tele.rotationAngle), 2);
break;
}
case Constraints<CreateCContamination>::id(): {
const CreateCContamination& tele(fromJson<CreateCContamination>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_C_KAMPFMITTEL, 45, tele.header.equipmentNumber);
setCommonAesParams(tele, radioTelegram);
radioTelegram->setPayloadData(tele.effectDuration / (1000 * 60), 1);
setAesPosition(tele, radioTelegram);
radioTelegram->setPayloadData(tele.effectRadius, 2);
radioTelegram->setPayloadData(qRound(tele.expansionFactor * 100), 1);
radioTelegram->setPayloadData(compassToMathAngleForSfm(tele.propagationDirection), 2);
radioTelegram->setPayloadData(tele.windSpeed, 1);
convertToSecAndSetTime(tele.validityTimeWind, radioTelegram);
radioTelegram->setPayloadData(tele.relPositionValidityTimeWind.offsetY, 3);
radioTelegram->setPayloadData(tele.relPositionValidityTimeWind.offsetX, 3);
radioTelegram->setPayloadData(tele.chargeTypeId, 1);
radioTelegram->setPayloadData((uint8_t)tele.volatility, 1);
break;
}
case Constraints<DeactivateEffectSimulation>::id(): {
const DeactivateEffectSimulation& tele(fromJson<DeactivateEffectSimulation>(a_telegram));
if (tele.aesType == AreaEffectSimulationType::FunctionalArea)
{
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_DEAKTIVIEREN_FUNKTIONSRAUM, 7, 0);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
}
else
{
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_DEAKTIVIERUNG_WIRKFELD, 8, 0);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData((uint8_t)tele.aesType, 1);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
}
break;
}
case Constraints<ModifyAreaEffectSimulationName>::id(): {
const ModifyAreaEffectSimulationName& tele(fromJson<ModifyAreaEffectSimulationName>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_AENDERUNG_BEZEICHNER, 16, 0);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData((uint8_t)tele.aesType, 1);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
convertToTetraEncoding(radioTelegram, tele.name, 8);
break;
}
case Constraints<MineTriggered>::id(): {
const MineTriggered& tele(fromJson<MineTriggered>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_DEAKTIVIERUNG_EINZELMINE, 13, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayloadData(tele.mineAreaId, 2);
radioTelegram->setPayloadData(tele.mineIndex, 2);
break;
}
case Constraints<DusMineReactivation>::id(): {
const DusMineReactivation& tele(fromJson<DusMineReactivation>(a_telegram));
const size_t cnt = tele.dusSerialNumbers.size() > 500 ? 500 : tele.dusSerialNumbers.size();
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_REAKTIVIERUNG_DUS_MINE, 3 + 2 + 2 + 2 * cnt,
tele.header.equipmentNumber);
radioTelegram->setPayload2Byte(0);
radioTelegram->setPayload2Byte(cnt);
for (size_t i = 0; i < cnt; i++)
radioTelegram->setPayload2Byte(tele.dusSerialNumbers.at(i));
break;
}
case Constraints<CreateDusSingleMine>::id(): {
const CreateDusSingleMine& tele(fromJson<CreateDusSingleMine>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_WIRKFELD_EINZELMINENSIMULATOR, 21,
tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
radioTelegram->setPayloadData(tele.partyId, 1);
radioTelegram->setPayloadData(tele.mineId, 2);
convertToSecAndSetTime(tele.effectStart, radioTelegram);
radioTelegram->setPayloadData(tele.relEffectPosition.offsetY, 3);
radioTelegram->setPayloadData(tele.relEffectPosition.offsetX, 3);
radioTelegram->setPayloadData(tele.chargeTypeId, 1);
break;
}
case Constraints<DemandVulnerabilityStateChange>::id(): {
const DemandVulnerabilityStateChange& tele(fromJson<DemandVulnerabilityStateChange>(a_telegram));
#ifdef GUEZ_MODE
if (s_usePvSan)
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TREFFER_AUSLOESUNG, 10, tele.header.equipmentNumber);
else
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TREFFER_AUSLOESUNG, 8, tele.header.equipmentNumber);
#else
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TREFFER_AUSLOESUNG, 8, tele.header.equipmentNumber);
#endif
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayloadData((uint8_t)tele.reqestedState, 1);
#ifdef GUEZ_MODE
if (s_usePvSan)
radioTelegram->setPayloadData((uint16_t)tele.vulnerabilityVitalityIndex, 2);
#endif
break;
}
case Constraints<TechnicalArea>::id(): {
const TechnicalArea& tele(fromJson<TechnicalArea>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TECHNIK_FUNKTIONSRAUM, 34, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
radioTelegram->setPayloadData(tele.taType, 1);
convertToTetraEncoding(radioTelegram, tele.name, 8);
radioTelegram->setPayloadData(tele.relCorner.offsetY, 3);
radioTelegram->setPayloadData(tele.relCorner.offsetX, 3);
radioTelegram->setPayloadData(tele.width, 2);
radioTelegram->setPayloadData(tele.height, 2);
radioTelegram->setPayloadData((uint32_t)0, 4);
radioTelegram->setPayloadData((uint32_t)0, 4);
break;
}
case Constraints<CreateFunctionalArea>::id(): {
const CreateFunctionalArea& tele(fromJson<CreateFunctionalArea>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_FUNKTIONSRAUM, 30, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.aesDdsId, 2);
convertToTetraEncoding(radioTelegram, tele.name, 8);
radioTelegram->setPayloadData(tele.partyId, 1);
radioTelegram->setPayloadData(tele.relEffectPosition.offsetY, 3);
radioTelegram->setPayloadData(tele.relEffectPosition.offsetX, 3);
radioTelegram->setPayloadData(tele.width / 5, 1);
radioTelegram->setPayloadData(tele.height / 5, 1);
radioTelegram->setPayloadData((uint8_t)tele.deconMode, 1);
radioTelegram->setPayloadData(tele.deconTimeout / 1000 / 60 / 10, 1);
radioTelegram->setPayloadData((uint8_t)tele.maintenanceMode, 1);
radioTelegram->setPayloadData(tele.maintenanceTimeout / 1000 / 60 / 10, 1);
radioTelegram->setPayloadData((uint8_t)tele.medicalMode, 1);
radioTelegram->setPayloadData(tele.medicalTimeout / 1000 / 60 / 10, 1);
break;
}
case Constraints<LanguageSelection>::id(): {
const LanguageSelection& tele(fromJson<LanguageSelection>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_SPRACHAUSWAHL, 6, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData((uint8_t)tele.languageSelection, 1);
break;
}
case Constraints<EquipmentMessage>::id(): {
const EquipmentMessage& tele(fromJson<EquipmentMessage>(a_telegram));
int len = 0;
int messageLength = (tele.message.size() > 81) ? 81 : tele.message.size();
if (tele.msgId == -1)
len = messageLength + 6;
else
len = 9;
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_ALLGEMEINE_NACHRICHT, len, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
if (tele.msgId != -1)
{
radioTelegram->setPayloadData(3, 1);
radioTelegram->setPayloadData((uint32_t)0, 1);
radioTelegram->setPayloadData(tele.msgId, 2);
}
else
{
radioTelegram->setPayloadData(tele.message.size(), 1);
radioTelegram->setPayloadData((uint8_t*)(tele.message.c_str()), messageLength);
}
break;
}
case Constraints<OpaquePayloadDataOut>::id(): {
const OpaquePayloadDataOut& tele(fromJson<OpaquePayloadDataOut>(a_telegram));
switch (tele.payloadType)
{
case TrainingAreaBase::TetraIcd::OpaquePayloadDataBase::Type::FireSmokeMarker:
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_DATENVERKEHR_TDS_DMF, tele.payload.size() + 3, tele.header.equipmentNumber);
break;
case TrainingAreaBase::TetraIcd::OpaquePayloadDataBase::Type::Geopairing:
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_DATENVERKEHR_TDS_GEOP, tele.payload.size() + 4, tele.header.equipmentNumber);
radioTelegram->setPayloadData(tele.payload.size(), 1);
break;
case TrainingAreaBase::TetraIcd::OpaquePayloadDataBase::Type::Target:
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_DATENVERKEHR_TDS_TGTC, tele.payload.size() + 4, tele.header.equipmentNumber);
radioTelegram->setPayloadData(tele.payload.size(), 1);
break;
case TrainingAreaBase::TetraIcd::OpaquePayloadDataBase::Type::OC:
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_DATENVERKEHR_TDS_SRT, tele.payload.size() + 3, tele.header.equipmentNumber);
break;
}
radioTelegram->setPayloadData((uint8_t*)(tele.payload.data()), tele.payload.size());
break;
}
case Constraints<CesHitInformation>::id(): {
const CesHitInformation& tele(fromJson<CesHitInformation>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_AUSLOESUNG_DUS_TREFFER, 16, tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayloadData(tele.chargeTasCodeDirect, 2);
radioTelegram->setPayloadData(tele.directionDegree, 2);
radioTelegram->setPayloadData(tele.distance, 2);
radioTelegram->setPayloadData(tele.effectPercent, 1);
radioTelegram->setPayloadData(tele.originatorEquipmentNumber, 2);
break;
}
case Constraints<ParticipantSwVersionsRequest>::id(): {
const ParticipantSwVersionsRequest& tele(fromJson<ParticipantSwVersionsRequest>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_ANFORDERUNG_SW_VERSION, 4, tele.header.equipmentNumber);
radioTelegram->setPayloadData(tele.equipmentFunctionId, 1);
break;
}
case Constraints<ParticipantMode>::id(): {
const ParticipantMode& tele(fromJson<ParticipantMode>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TEILNEHMERMODE_SETZEN, 13, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData((uint8_t)tele.language, 1);
radioTelegram->setPayloadData((uint8_t)tele.operationMode, 1);
radioTelegram->setPayloadData(tele.reactivationDetoxication / 10, 1);
radioTelegram->setPayloadData(tele.reactivationMaintenance / 10, 1);
radioTelegram->setPayloadData(tele.reactivationMedic / 10, 1);
unsigned char wph_mode = 0;
wph_mode |= ((uint8_t)tele.modeHelmet & 0x03);
wph_mode |= ((uint8_t)tele.modeVest & 0x03) << 2;
wph_mode |= ((uint8_t)tele.personellProtectionMode & 0x07) << 4;
radioTelegram->setPayloadData(wph_mode, 1);
unsigned char protection_mode = 0;
protection_mode |= ((uint8_t)tele.protectionLevel & 0x07);
protection_mode |= ((uint8_t)tele.abcProtectionMode & 0x03) << 3;
radioTelegram->setPayloadData(protection_mode, 1);
unsigned char specialFunction = 0;
specialFunction |= ((uint8_t)tele.handgrenadeSearchMode & 0x03);
specialFunction |= ((uint8_t)tele.internationalMode & 0x03) << 2;
specialFunction |= ((uint8_t)tele.abcProtectionMode & 0x03) << 3;
radioTelegram->setPayloadData(specialFunction, 1);
break;
}
case Constraints<DemandParticipantMode>::id(): {
const DemandParticipantMode& tele(fromJson<DemandParticipantMode>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TEILNEHMERMODE_ANFORDERN, 3, tele.header.equipmentNumber);
break;
}
case Constraints<ParticipantConfiguration>::id(): {
const ParticipantConfiguration& tele(fromJson<ParticipantConfiguration>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TEILNEHMER_KONFIG_SETZEN, 25, tele.header.equipmentNumber);
radioTelegram->setPayloadData((uint32_t)0, 2);
radioTelegram->setPayloadData(tele.positionIntervallVehicle, 2);
radioTelegram->setPayloadData(tele.positionIntervallPersonell, 2);
radioTelegram->setPayloadData(tele.positionIntervallAircraft, 2);
radioTelegram->setPayloadData(tele.positionTransmissionIntervall, 2);
radioTelegram->setPayloadData(tele.heightbarrier, 2);
unsigned char tmp = ((uint8_t)tele.faultPositionHandling & 0x03) << 6;
tmp |= ((uint8_t)tele.switchingPositionIntervall & 0x03);
radioTelegram->setPayloadData(tmp, 1);
radioTelegram->setPayloadData(tele.waittimeAdditionalBroadcastDemand, 2);
radioTelegram->setPayloadData(tele.factorWaittimeIncreaseAtHighload, 1);
radioTelegram->setPayloadData(tele.waittimeAutomaticVulnerabilityIncreaseLevel1, 1);
radioTelegram->setPayloadData(tele.waittimeAutomaticVulnerabilityIncreaseLevel2, 1);
radioTelegram->setPayloadData(tele.waittimeAutomaticVulnerabilityIncreaseLevel3, 1);
radioTelegram->setPayloadData((uint8_t)tele.opticalCode, 1);
radioTelegram->setPayloadData(tele.vulnerabilityModel, 1);
radioTelegram->setPayloadData(tele.validTimeOps, 1);
break;
}
case Constraints<DemandParticipantConfiguration>::id(): {
const DemandParticipantConfiguration& tele(fromJson<DemandParticipantConfiguration>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TEILNEHMER_KONFIG_ANFORDERN, 3, tele.header.equipmentNumber);
break;
}
case Constraints<SanitationRepair>::id(): {
const SanitationRepair& tele(fromJson<SanitationRepair>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_SANITAETSDIENST_INSTANDSETZUNG, 19,
tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayload1Byte(uint8_t(tele.originatorType));
radioTelegram->setPayload2Byte(tele.equipmentNumberOrigin);
radioTelegram->setPayload1Byte(uint8_t(tele.stateStart));
unsigned int bitfield1 = 0;
if (tele.timeOfTreatment)
bitfield1 |= 0x7F;
if (tele.triage)
bitfield1 |= 0x80;
radioTelegram->setPayload1Byte(bitfield1);
radioTelegram->setPayload1Byte(tele.tyeOfDamage);
unsigned int bitfield2 = 0;
bitfield2 |= (uint8_t(tele.stateResult) | 0x0F);
bitfield2 |= ((uint8_t(tele.treatmentResult) | 0x30) << 4);
bitfield2 |= (0xC0 << 6);
radioTelegram->setPayload1Byte(bitfield2);
radioTelegram->setPayload1Byte(tele.fullState);
radioTelegram->setPayloadData(tele.timeOfTreatment, 2);
radioTelegram->setPayloadData(tele.timeOfRecovery, 2);
break;
}
case Constraints<SanitaryMaterialStockReport>::id(): {
const SanitaryMaterialStockReport& tele(fromJson<SanitaryMaterialStockReport>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_BESTANDSMELDUNG_SANITAETSMATERIAL, 15 + tele.sanitaryMaterialCount, tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
radioTelegram->setPayload4Byte(tele.uniqueId);
radioTelegram->setPayload2Byte(tele.originatorEquipmentNumber);
radioTelegram->setPayload1Byte((uint8_t)tele.qualification);
radioTelegram->setPayload1Byte(tele.sanitaryMaterialCount);
for (const auto stock : tele.sanitaryMaterialStock)
radioTelegram->setPayloadData(stock, 1);
break;
}
case Constraints<Sanitation>::id(): {
const Sanitation& tele(fromJson<Sanitation>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN, 23,
tele.header.equipmentNumber);
convertToSecAndSetTime(tele.header.timeStamp, radioTelegram);
int p1 = tele.proceduresTaken & 0xFFFFFFFF;
int p2 = tele.proceduresTaken >> 32;
radioTelegram->setPayloadData(p2, 4);
radioTelegram->setPayloadData(p1, 4);
radioTelegram->setPayloadData(tele.uniqeId, 4);
radioTelegram->setPayloadData(tele.originatorEquipmentNumber, 2);
radioTelegram->setPayloadData((uint8_t)tele.qualification, 1);
quint8 sanResultAndEvaluation =
(((uint8_t)tele.sanitationEvaluation & 0x03) << 6) + ((uint8_t)tele.sanitationResult & 0x3f);
radioTelegram->setPayloadData(sanResultAndEvaluation, 1);
break;
}
case Constraints<CesHitRequest>::id(): {
const CesHitRequest& tele(fromJson<CesHitRequest>(a_telegram));
int chargeTasCode = tele.chargeTasCodeDirect;
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG, 17,
tele.header.equipmentNumber);
const bool insideBuilding = (tele.roomId > 0 && tele.buildingId > 0);
int remainEffectOrTasCodeDirect = 0;
int reserve1 = tele.mineId;
int reserve2 = 0;
int gpsZeit = tele.header.timeStamp;
switch (tele.aesType)
{
case AreaEffectSimulationType::Unknown:
remainEffectOrTasCodeDirect = tele.remainEffectTasCodeDirect;
if (remainEffectOrTasCodeDirect == 100)
{
remainEffectOrTasCodeDirect = 49;
}
break;
case AreaEffectSimulationType::FunctionalArea:
remainEffectOrTasCodeDirect = tele.remainEffectTasCodeDirect;
chargeTasCode = tele.chargeTasCodeIndirect;
reserve1 = tele.reserve1;
reserve2 = tele.reserve2;
break;
case AreaEffectSimulationType::AirSupport:
case AreaEffectSimulationType::NContamination:
case AreaEffectSimulationType::MineArea:
case AreaEffectSimulationType::CContamination:
remainEffectOrTasCodeDirect = tele.remainEffectTasCodeDirect;
chargeTasCode = tele.chargeTasCodeIndirect;
break;
case AreaEffectSimulationType::DangerZoneExplosion:
remainEffectOrTasCodeDirect = tele.remainEffectTasCodeDirect;
chargeTasCode = tele.chargeTasCodeIndirect;
reserve1 = tele.reserve1;
break;
case AreaEffectSimulationType::ExplosionArea:
case AreaEffectSimulationType::ExplosionSingle:
if (insideBuilding)
{
remainEffectOrTasCodeDirect = tele.remainEffectTasCodeDirect;
}
else
{
remainEffectOrTasCodeDirect = 255;
chargeTasCode = tele.chargeTasCodeIndirect;
}
break;
case AreaEffectSimulationType::GasPipeDetonation:
remainEffectOrTasCodeDirect = tele.remainEffectTasCodeDirect;
break;
default:
remainEffectOrTasCodeDirect = tele.remainEffectPercent;
chargeTasCode = tele.chargeTasCodeIndirect;
break;
}
radioTelegram->setPayloadData((uint32_t)gpsZeit, 4);
radioTelegram->setPayload2Byte(chargeTasCode);
if (tele.aesDdsId != 0)
radioTelegram->setPayload2Byte(tele.aesDdsId);
else
radioTelegram->setPayload2Byte(tele.originatorEquipmentNumber);
radioTelegram->setPayload1Byte(uint8_t(tele.aesType));
radioTelegram->setPayload1Byte(remainEffectOrTasCodeDirect);
radioTelegram->setPayload2Byte(reserve1);
radioTelegram->setPayload2Byte(reserve2);
DEBUG_LOG(logger()) << "Reserve1 of CesHitRequest: " << reserve1 << " Reserve2: " << reserve2;
break;
}
case Constraints<SelectiveReammunition>::id(): {
const SelectiveReammunition& tele(fromJson<SelectiveReammunition>(a_telegram));
radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(
GEF_SELEKTIVE_AUFMUNITIONIERUNG, 8 + tele.reammunitions.size() * 8, tele.header.equipmentNumber);
radioTelegram->setPayload4Byte(tele.gearId);
radioTelegram->setPayload1Byte(tele.reammunitions.size());
for (const auto& reammunition : tele.reammunitions)
{
radioTelegram->setPayload2Byte(reammunition.chargeTypeId);
radioTelegram->setPayload1Byte(reammunition.location);
radioTelegram->setPayload2Byte(reammunition.newStock);
radioTelegram->setPayload2Byte(reammunition.newDefaultStock);
radioTelegram->setPayload1Byte(reammunition.tracerRatio);
}
break;
}
case Constraints<OcCommand>::id(): {
const OcCommand& tele(fromJson<OcCommand>(a_telegram));
radioTelegram =
new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_SCHIEDSRICHTERKOMMANDO, 4, tele.header.equipmentNumber);
radioTelegram->setPayloadData(tele.action, 1);
break;
}
default: {
ERROR_LOG(logger()) << "Conversion of Central-Telegram to Radio-Telegram with telId="
<< getTelegramId(a_telegram) << " not implemented!";
}
}
return radioTelegram;
}
CoPrtCnvRadioTelegram* convertToRadio(CoPrtCnvCentralTelegram* a_telegram)
{
return convertToRadioInternal(a_telegram);
}
CoPrtCnvRadioTelegram* convertToRadio(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram* a_telegram)
{
return convertToRadioInternal(a_telegram);
}
static inline Header getHeader(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t tsOffset)
{
Header hdr;
hdr.equipmentNumber = a_radioTelegram->getIdentity();
hdr.timeStamp = a_radioTelegram->getPayloadDataUInt32(tsOffset, 4) * 1000LL;
return hdr;
}
static inline RelativePosition getRelativePosition(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t offset)
{
RelativePosition pos;
pos.offsetY = a_radioTelegram->getPayloadDataSInt24(offset);
pos.offsetX = a_radioTelegram->getPayloadDataSInt24(offset + 3);
return pos;
}
static inline GpsQuality getGpsQuality(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t offset)
{
const uint8_t gps = a_radioTelegram->getPayloadDataUInt8(offset);
GpsQuality ret;
ret.moreThan4SatellitesAvailable = ((gps & 0x80) == 0x80);
ret.dgpsModeAvailable = ((gps & 0x40) == 0x40);
ret.pdopValue = (gps & 0x3f);
return ret;
}
static inline OpsPosition getOpsPosition(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t offset,
size_t* newOffset = nullptr)
{
const uint8_t opsLen = a_radioTelegram->getPayloadDataUInt8(offset);
offset += 1;
OpsPosition pos;
pos.opsId = -1;
if (opsLen > 0)
{
std::vector<uint32_t> opse;
opse.reserve(opsLen);
for (uint32_t i = 0; i < opsLen; i++)
{
opse.push_back(a_radioTelegram->getPayloadDataUInt32(offset, 2));
offset += 2;
}
pos.opsId = opse.at(opse.size() - 1);
}
if (newOffset)
*newOffset = offset;
return pos;
}
static inline std::vector<unsigned char> getPayload(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t offsetData)
{
int payloadLen = a_radioTelegram->getPayloadSize();
payloadLen -= offsetData;
if (payloadLen <= 0)
{
ERROR_LOG(logger()) << "Radio-Telegram Datenverkehr SRT-TDS contains too less data: " << payloadLen;
return {};
}
std::vector<unsigned char> ret;
ret.resize(payloadLen);
memcpy(ret.data(), a_radioTelegram->getPayloadDataPtr(offsetData), payloadLen);
return ret;
}
static inline std::vector<unsigned char> getPayload(const CoPrtCnvRadioTelegram* a_radioTelegram, size_t offsetLen,
size_t offsetData)
{
int payloadLen = a_radioTelegram->getPayloadDataUInt8(offsetLen);
if (payloadLen <= 0)
{
ERROR_LOG(logger()) << "Radio-Telegram Datenverkehr SRT-TDS contains too less data: " << payloadLen;
return {};
}
std::vector<unsigned char> ret;
ret.resize(payloadLen);
memcpy(ret.data(), a_radioTelegram->getPayloadDataPtr(offsetData), payloadLen);
return ret;
}
static N_CoPrtCnv::CoPrtCnvCentralTelegram* toCentral(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram* data)
{
QJsonObject obj;
obj[QStringLiteral("data")] = data->toJson();
obj[QStringLiteral("type")] = data->type();
obj[QStringLiteral("typeId")] = data->id();
const QByteArray ba = QJsonDocument(obj).toJson(QJsonDocument::Compact);
return new N_CoPrtCnv::CoPrtCnvCentralTelegram(ba, static_cast<TrainingAreaBase::TetraIcd::TelegramId>(data->id()));
}
template <typename T> void fixupEnum(T lowerBound, T upperBound, T defaultVal, T& valToFixup)
{
if (valToFixup >= lowerBound && valToFixup <= upperBound)
return;
valToFixup = defaultVal;
}
static bool isPayloadLengthOk(const CoPrtCnvRadioTelegram* tele, uint16_t a_length)
{
const uint16_t length = tele->getPayloadSize();
if (length >= a_length)
return true;
WARNING_LOG(logger()) << "The payload-length of telegram with telId: " << tele->getTelID() << " must be "
<< a_length << ", but it is " << length;
return false;
}
static bool isPayloadLengthOk(const CoPrtCnvRadioTelegram* tele, uint16_t a_minLength,
const uint16_t a_dataAmountOffset, const uint8_t a_variableDataElementSize,
bool useHalf = false)
{
if (0 == a_variableDataElementSize)
return isPayloadLengthOk(tele, a_minLength);
const uint16_t length = tele->getPayloadSize();
if (length >= a_minLength)
{
uint8_t dataAmount = tele->getPayloadDataUInt8(a_dataAmountOffset);
uint16_t dataSize = a_variableDataElementSize * dataAmount;
if (useHalf)
{
if ((dataAmount % 2) == 1)
dataSize = a_variableDataElementSize * ((dataAmount / 2.0) + 0.5);
else
dataSize = a_variableDataElementSize * (dataAmount / 2);
}
uint16_t expectedLength = dataSize + a_minLength;
if (expectedLength != length)
{
WARNING_LOG(logger()) << "The payload-length of telegram with telId: " << tele->getTelID() << " must be "
<< expectedLength << ", but it is " << length
<< " (the amount of variable data in telegram was " << dataAmount << " => "
<< dataSize << " bytes)";
return false;
}
}
else
{
WARNING_LOG(logger()) << "The payload-length of telegram with telId: " << tele->getTelID()
<< " must be at least " << a_minLength << ", but it is only " << length;
return false;
}
return true;
}
N_CoPrtCnv::CoPrtCnvCentralTelegram* convertToCentral(const CoPrtCnvRadioTelegram* a_radioTelegram)
{
auto tab = convertToTabTele(a_radioTelegram);
if (!tab)
return nullptr;
auto ret = toCentral(tab);
delete tab;
return ret;
}
TrainingAreaTelegram* convertToTabTele(const CoPrtCnvRadioTelegram* a_radioTelegram)
{
switch (a_radioTelegram->getTelID())
{
case GEF_MANIPULATIONSMELDUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 12))
return nullptr;
auto tele = new ManipulationReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->isManipulation = a_radioTelegram->getPayloadDataUInt32(7, 1);
tele->equipmentFunctionId = a_radioTelegram->getPayloadDataUInt32(8, 1);
return tele;
}
case GEF_BITE_MELDUNG2: {
if (!isPayloadLengthOk(a_radioTelegram, 27, 19, 7))
return nullptr;
auto tele = new BiteReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->loginType = static_cast<BiteReport::LoginType>(a_radioTelegram->getPayloadDataUInt8(7));
uint32_t ergebnisCAN = a_radioTelegram->getPayloadDataUInt32(8, 3);
tele->biteState = ergebnisCAN;
uint8_t ergebnisAusstattung = a_radioTelegram->getPayloadDataUInt8(11);
tele->batteryState = ergebnisAusstattung;
const auto nonDynamic = getBiteError(a_radioTelegram, 12);
if (nonDynamic.errorNumber != 0 || nonDynamic.canDeviceNumber != 0 || nonDynamic.subdeviceNumber != 0 ||
nonDynamic.uniqueId != 0)
tele->biteErrors.push_back(nonDynamic);
const uint8_t fehlerLen = a_radioTelegram->getPayloadDataUInt8(19);
tele->biteErrors.reserve(tele->biteErrors.size() + fehlerLen);
for (uint8_t i = 0; i < fehlerLen; ++i)
{
const uint8_t iPos = 27 + i * 7;
tele->biteErrors.push_back(getBiteError(a_radioTelegram, iPos));
}
a_radioTelegram->getPayloadDataUInt32(20, 3);
tele->configError = a_radioTelegram->getPayloadDataUInt8(23);
uint32_t aktuelleKonfiguration = a_radioTelegram->getPayloadDataUInt32(24, 3);
tele->configState = aktuelleKonfiguration;
return tele;
}
case GEF_FEUEREREIGNIS_MIT_WAFFENZUORDNUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 18))
return nullptr;
auto tele = new EquipmentGearEvent;
tele->header = getHeader(a_radioTelegram, 3);
tele->charge.gearSerialNumber = a_radioTelegram->getPayloadDataUInt32(7, 4);
tele->charge.gearTasCode = a_radioTelegram->getPayloadDataUInt8(11);
tele->charge.chargeTypeId = a_radioTelegram->getPayloadDataUInt32(12, 2);
tele->chargeAmount = a_radioTelegram->getPayloadDataUInt32(14, 2);
const short remain = a_radioTelegram->getPayloadDataUInt32(16, 2);
tele->charge.remain = remain;
return tele;
}
case GEF_SW_VERSIONSMELDUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 8, 7, 8))
return nullptr;
auto tele = new ParticipantSwVersions;
tele->header = getHeader(a_radioTelegram, 3);
const uint8_t versionsliste_len = a_radioTelegram->getPayloadDataUInt8(7);
tele->equipments.reserve(versionsliste_len);
for (uint32_t i = 0; i < versionsliste_len; i++)
{
const uint8_t iPos = 8 + i * 8;
EquipmentSwVersion ver;
ver.equipmentFunctionId = a_radioTelegram->getPayloadDataUInt8(iPos);
ver.subDeviceId = a_radioTelegram->getPayloadDataUInt8(iPos + 1);
ver.uniqueId = a_radioTelegram->getPayloadDataUInt32(iPos + 2, 4);
ver.swVersion = a_radioTelegram->getPayloadDataUInt32(iPos + 6, 2);
}
return tele;
}
case GEF_SANITAETSDIENST_INSTANDSETZUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 19))
return nullptr;
auto tele = new SanitationRepair;
tele->header = getHeader(a_radioTelegram, 3);
tele->originatorType =
static_cast<TrainingAreaBase::TetraIcd::OriginatorType>(a_radioTelegram->getPayloadDataUInt8(7));
tele->equipmentNumberOrigin = a_radioTelegram->getPayloadDataUInt32(8, 2);
tele->stateStart =
static_cast<TrainingAreaBase::TetraIcd::VulnerabilityState>(a_radioTelegram->getPayloadDataUInt8(10));
unsigned int bitfield1 = a_radioTelegram->getPayloadDataUInt8(11);
tele->typeOfTreatment = bitfield1 & 0x7F;
tele->triage = (bitfield1 & 0x80) >> 7;
tele->tyeOfDamage = a_radioTelegram->getPayloadDataUInt8(12);
unsigned int bitfield2 = a_radioTelegram->getPayloadDataUInt8(13);
tele->stateResult = static_cast<TrainingAreaBase::TetraIcd::VulnerabilityState>(bitfield2 & 0x0F);
tele->treatmentResult =
static_cast<TrainingAreaBase::TetraIcd::SanitationRepair::TreatmentResult>((bitfield2 & 0x30) >> 4);
tele->triagePriority = ((bitfield2 & 0xC0) >> 6);
tele->fullState = a_radioTelegram->getPayloadDataUInt8(14);
tele->timeOfTreatment = a_radioTelegram->getPayloadDataUInt32(15, 2);
tele->timeOfRecovery = a_radioTelegram->getPayloadDataUInt32(17, 2);
return tele;
}
case GEF_BESTANDSMELDUNG_SANITAETSMATERIAL: {
if (!isPayloadLengthOk(a_radioTelegram, 15, 14, 1))
return nullptr;
auto tele = new SanitaryMaterialStockReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->uniqueId = a_radioTelegram->getPayloadDataUInt32(7, 4);
tele->originatorEquipmentNumber = a_radioTelegram->getPayloadDataUInt32(11, 2);
tele->qualification = static_cast<Qualification>(a_radioTelegram->getPayloadDataUInt8(13));
const uint16_t sanitaryMaterialCount = a_radioTelegram->getPayloadDataUInt8(14);
tele->sanitaryMaterialCount = sanitaryMaterialCount;
double size = sanitaryMaterialCount;
if (tele->sanitaryMaterialCount != 0)
{
int pos = 15;
std::vector<int> stock;
stock.reserve(sanitaryMaterialCount);
for (int i = 0; i < size; i++)
{
unsigned int in = a_radioTelegram->getPayloadDataUInt8(pos++);
stock.emplace_back(in);
}
tele->sanitaryMaterialStock = stock;
}
else
tele->sanitaryMaterialStock = std::vector<int>();
return tele;
}
case GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN: {
if (!isPayloadLengthOk(a_radioTelegram, 23))
return nullptr;
auto tele = new Sanitation;
tele->header = getHeader(a_radioTelegram, 3);
qint64 proceduresP1 = a_radioTelegram->getPayloadDataUInt32(7, 4);
qint64 proceduresP2 = a_radioTelegram->getPayloadDataUInt32(11, 4);
tele->proceduresTaken = (proceduresP1 << 32) + proceduresP2;
tele->uniqeId = a_radioTelegram->getPayloadDataUInt32(15, 4);
tele->originatorEquipmentNumber = a_radioTelegram->getPayloadDataUInt32(19, 2);
tele->qualification = static_cast<Qualification>(a_radioTelegram->getPayloadDataUInt8(21));
quint8 enumByte = a_radioTelegram->getPayloadDataUInt8(22);
tele->sanitationEvaluation = static_cast<SanitationEvaluation>((enumByte & 0xc0) >> 6);
tele->sanitationResult = static_cast<SanitationResult>(enumByte & 0x3f);
return tele;
}
case GEF_BETRIEBSZUSTAND_AUSSTATTUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 9))
return nullptr;
auto tele = new EquipmentOperationalState;
tele->header = getHeader(a_radioTelegram, 3);
uint8_t abcSchutz = a_radioTelegram->getPayloadDataUInt8(8);
tele->nbcProtectionActive = checkBitmask(abcSchutz, 0x40);
return tele;
}
case GEF_FEHLERMELDUNG_GFD: {
if (!isPayloadLengthOk(a_radioTelegram, 9))
return nullptr;
auto tele = new CtaDataError;
tele->header = getHeader(a_radioTelegram, 3);
tele->reason = static_cast<CtaDataError::Reason>(a_radioTelegram->getPayloadDataUInt8(7));
tele->originTelegramId = a_radioTelegram->getPayloadDataUInt8(8);
return tele;
}
case GEF_WIEDERHERSTELLUNG_FUNKBEREITSCHAFT: {
if (!isPayloadLengthOk(a_radioTelegram, 31))
return nullptr;
auto tele = new RestoreRadioReadiness;
tele->header = getHeader(a_radioTelegram, 3);
tele->readinessLossPosition = getRelativePosition(a_radioTelegram, 7);
tele->readinessLossTime = a_radioTelegram->getPayloadDataUInt32(13, 4);
tele->readinessRestorePosition = getRelativePosition(a_radioTelegram, 17);
tele->readinessRestoreTime = a_radioTelegram->getPayloadDataUInt32(23, 4);
return tele;
}
case GEF_POSITIONS_MELDUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 14))
return nullptr;
auto tele = new PositionReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->gpsQuality = getGpsQuality(a_radioTelegram, 13);
return tele;
}
case GEF_POSITIONS_MELDUNG_MIT_TEILNEHMER: {
if (!isPayloadLengthOk(a_radioTelegram, 15, 14, 2))
return nullptr;
auto tele = new PositionReportWithMountedEquipments;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
const uint8_t gps = a_radioTelegram->getPayloadDataUInt8(13);
tele->gpsQuality.moreThan4SatellitesAvailable = ((gps & 0x80) == 0x80);
tele->gpsQuality.dgpsModeAvailable = ((gps & 0x40) == 0x40);
tele->gpsQuality.pdopValue = (gps & 0x3f);
const uint8_t aufgesessene_teilnehmer_len = a_radioTelegram->getPayloadDataUInt8(14);
tele->mountedEquipments.reserve(aufgesessene_teilnehmer_len);
for (uint8_t i = 0; i < aufgesessene_teilnehmer_len; i++)
{
int eqId = a_radioTelegram->getPayloadDataUInt32(15 + 2 * i, 2);
tele->mountedEquipments.push_back(eqId);
}
return tele;
}
case GEF_DEAKTIVIERUNG_EINZELMINE: {
if (!isPayloadLengthOk(a_radioTelegram, 13))
return nullptr;
auto tele = new MineTriggered;
tele->header = getHeader(a_radioTelegram, 5);
tele->mineAreaId = a_radioTelegram->getPayloadDataUInt32(9, 2);
tele->mineIndex = a_radioTelegram->getPayloadDataUInt32(11, 2);
return tele;
}
case GEF_DEFINITION_IED: {
if (!isPayloadLengthOk(a_radioTelegram, 24))
return nullptr;
auto tele = new DefinitionIed;
tele->header = getHeader(a_radioTelegram, 3);
tele->iedId = a_radioTelegram->getPayloadDataUInt32(7, 2);
tele->iedType = static_cast<IedType>(a_radioTelegram->getPayloadDataUInt8(9));
tele->trigger = a_radioTelegram->getPayloadDataUInt8(10);
tele->explosiveForce = a_radioTelegram->getPayloadDataUInt8(11);
tele->relPosition = getRelativePosition(a_radioTelegram, 12);
tele->partyId = a_radioTelegram->getPayloadDataUInt8(18);
tele->pairingState = static_cast<IedPairingState>(a_radioTelegram->getPayloadDataUInt8(19));
tele->pairedId = a_radioTelegram->getPayloadDataUInt32(20, 2);
tele->tacticalState = static_cast<IedTacticalState>(a_radioTelegram->getPayloadDataUInt8(22));
tele->statePyrotechnics = a_radioTelegram->getPayloadDataUInt8(23);
fixupEnum(IedType::SuicideIed, IedType::IedBigPyro, IedType::SuicideIed, tele->iedType);
fixupEnum(IedPairingState::NotPaired, IedPairingState::PairedToOps, IedPairingState::NotPaired,
tele->pairingState);
fixupEnum(IedTacticalState::NotActive, IedTacticalState::TriggeredByControlDevice,
IedTacticalState::Unknown, tele->tacticalState);
return tele;
}
case GEF_ZUSTAND_IED: {
if (!isPayloadLengthOk(a_radioTelegram, 16))
return nullptr;
auto tele = new StateIed;
tele->header = getHeader(a_radioTelegram, 3);
tele->iedId = a_radioTelegram->getPayloadDataUInt32(7, 2);
tele->tacticalState = static_cast<IedTacticalState>(a_radioTelegram->getPayloadDataUInt8(9));
tele->statePyrotechnics = a_radioTelegram->getPayloadDataUInt8(10);
tele->batteryWarnings = a_radioTelegram->getPayloadDataUInt8(11);
tele->errorStateElectronics = static_cast<IedError>(a_radioTelegram->getPayloadDataUInt8(12));
tele->errorStatePyrotechnics1 = static_cast<IedError>(a_radioTelegram->getPayloadDataUInt8(13));
tele->errorStatePyrotechnics2 = static_cast<IedError>(a_radioTelegram->getPayloadDataUInt8(14));
tele->errorStatePyrotechnics3 = static_cast<IedError>(a_radioTelegram->getPayloadDataUInt8(15));
fixupEnum(IedTacticalState::NotActive, IedTacticalState::TriggeredByControlDevice,
IedTacticalState::Unknown, tele->tacticalState);
fixupEnum(IedError::NoError, IedError::DeviceMissing, IedError::DeviceMissing, tele->errorStateElectronics);
fixupEnum(IedError::NoError, IedError::DeviceMissing, IedError::DeviceMissing,
tele->errorStatePyrotechnics1);
fixupEnum(IedError::NoError, IedError::DeviceMissing, IedError::DeviceMissing,
tele->errorStatePyrotechnics2);
fixupEnum(IedError::NoError, IedError::DeviceMissing, IedError::DeviceMissing,
tele->errorStatePyrotechnics3);
return tele;
}
case GEF_STATUS_EINZELMINENSIMULATOR: {
if (!isPayloadLengthOk(a_radioTelegram, 17))
return nullptr;
auto tele = new DusSingleMineState;
tele->header = getHeader(a_radioTelegram, 3);
tele->mineId = a_radioTelegram->getPayloadDataUInt32(7, 2);
tele->relPosition = getRelativePosition(a_radioTelegram, 9);
tele->chargeTypeId = a_radioTelegram->getPayloadDataUInt8(15);
tele->state = a_radioTelegram->getPayloadDataUInt8(16);
tele->effectStart = tele->header.timeStamp;
return tele;
}
case GEF_TREFFER_EREIGNIS_DUS: {
if (!isPayloadLengthOk(a_radioTelegram, 23))
return nullptr;
auto tele = new StateChangeDirect;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
getTaktZustand(a_radioTelegram, 13, tele);
tele->chargeTypeId = a_radioTelegram->getPayloadDataUInt32(19, 2);
tele->originatorId = a_radioTelegram->getPayloadDataUInt32(21, 2);
return tele;
}
case GEF_TREFFER_EREIGNIS_WIRKSIMULATION: {
if (!isPayloadLengthOk(a_radioTelegram, 22))
return nullptr;
auto tele = new StateChangeIndirect;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
getTaktZustand(a_radioTelegram, 13, tele);
tele->originatorId = a_radioTelegram->getPayloadDataUInt32(20, 2);
return tele;
}
case GEF_SCHIEDSRICHTEREINGRIFF: {
if (!isPayloadLengthOk(a_radioTelegram, 16))
return nullptr;
auto tele = new OperatorAction;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->action = a_radioTelegram->getPayloadDataUInt8(13);
tele->operatorId = a_radioTelegram->getPayloadDataUInt32(14, 2);
return tele;
}
case GEF_TREFFER_EREIGNIS_DUS_IPS: {
if (!isPayloadLengthOk(a_radioTelegram, 18, 17, 2))
return nullptr;
auto tele = new StateChangeDirect;
tele->header = getHeader(a_radioTelegram, 3);
getTaktZustand(a_radioTelegram, 7, tele);
tele->chargeTypeId = a_radioTelegram->getPayloadDataUInt32(13, 2);
tele->originatorId = a_radioTelegram->getPayloadDataUInt32(15, 2);
size_t iPos = 17;
tele->opsPosition = getOpsPosition(a_radioTelegram, iPos);
return tele;
}
case GEF_TREFFER_EREIGNIS_WIRKSIMULATION_IPS: {
if (!isPayloadLengthOk(a_radioTelegram, 17, 16, 2))
return nullptr;
auto tele = new StateChangeIndirect;
tele->header = getHeader(a_radioTelegram, 3);
getTaktZustand(a_radioTelegram, 7, tele);
tele->originatorId = a_radioTelegram->getPayloadDataUInt32(14, 2);
size_t iPos = 16;
tele->opsPosition = getOpsPosition(a_radioTelegram, iPos);
tele->isSecondaryEffect = true;
return tele;
}
case GEF_TAKTISCHER_STATUS: {
if (!isPayloadLengthOk(a_radioTelegram, 16))
return nullptr;
auto tele = new StateChange;
tele->header = getHeader(a_radioTelegram, 3);
getTaktZustand(a_radioTelegram, 7, tele);
tele->originatorType =
static_cast<TrainingAreaBase::TetraIcd::OriginatorType>(a_radioTelegram->getPayloadDataUInt8(13));
tele->originatorId = a_radioTelegram->getPayloadDataUInt32(14, 2);
return tele;
}
case GEF_EINTRETEN_FUNKTIONSRAUM: {
if (!isPayloadLengthOk(a_radioTelegram, 15))
return nullptr;
auto tele = new FunctionalAreaEntry;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->aesDdsId = a_radioTelegram->getPayloadDataUInt32(13, 2);
return tele;
}
case GEF_SONDERSENSORIK_BETRIEBSZUSTAND: {
if (!isPayloadLengthOk(a_radioTelegram, 9))
return nullptr;
auto tele = new SpecialSensorData;
tele->header = getHeader(a_radioTelegram, 3);
getSpecialSensorData(a_radioTelegram, 7, tele);
return tele;
}
case GEF_SONDERSENSORIK_FAHRSPUR: {
if (!isPayloadLengthOk(a_radioTelegram, 15))
return nullptr;
auto tele = new SpecialSensorData;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
getSpecialSensorData(a_radioTelegram, 13, tele);
return tele;
}
case GEF_SONDERSENSORIK_DATEN: {
if (!isPayloadLengthOk(a_radioTelegram, 16))
return nullptr;
auto tele = new SpecialSensorData;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->type = a_radioTelegram->getPayloadDataUInt32(13, 1);
getSpecialSensorData(a_radioTelegram, 14, tele);
tele->nbcType = a_radioTelegram->getPayloadDataUInt32(16, 1);
return tele;
}
case GEF_SONDERSENSORIK_MIVANH_VERLEGEDATEN: {
if (!isPayloadLengthOk(a_radioTelegram, 24))
return nullptr;
auto tele = new MinelayerTrailerData;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->barrierId = a_radioTelegram->getPayloadDataUInt32(13, 2);
tele->layingDensity = a_radioTelegram->getPayloadDataUInt32(15, 1);
tele->effectStart = a_radioTelegram->getPayloadDataUInt32(16, 4) * 1000LL;
tele->effectDuration = a_radioTelegram->getPayloadDataUInt32(20, 1);
tele->indirectChargeTasCode = a_radioTelegram->getPayloadDataUInt32(21, 1);
tele->mineCount = a_radioTelegram->getPayloadDataUInt32(22, 2);
return tele;
}
case GEF_SONDERSENSORIK_WMIV_VERLEGEDATEN: {
if (!isPayloadLengthOk(a_radioTelegram, 25))
return nullptr;
auto tele = new MinelayerThrowerData;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->barrierId = a_radioTelegram->getPayloadDataUInt32(13, 2);
tele->layingDensity = a_radioTelegram->getPayloadDataUInt32(15, 1);
tele->effectStart = a_radioTelegram->getPayloadDataUInt32(16, 4) * 1000LL;
tele->effectDuration = a_radioTelegram->getPayloadDataUInt32(20, 1);
tele->indirectChargeTasCode = a_radioTelegram->getPayloadDataUInt32(21, 1);
tele->throwingType =
static_cast<MinelayerThrowerData::ThrowingType>(a_radioTelegram->getPayloadDataUInt32(22, 2));
tele->mineCount = a_radioTelegram->getPayloadDataUInt32(23, 2);
return tele;
}
case GEF_SONDERSENSORIK_MIVANH_VERLEGEPOSITION: {
if (!isPayloadLengthOk(a_radioTelegram, 16))
return nullptr;
auto tele = new MinelayerTrailerPosition;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->dusSerialNo = a_radioTelegram->getPayloadDataUInt32(13, 2);
tele->indirectChargeTasCode = a_radioTelegram->getPayloadDataUInt32(15, 1);
return tele;
}
case GEF_DATENVERKEHR_SRT_TDS: {
if (!isPayloadLengthOk(a_radioTelegram, 7))
return nullptr;
auto tele = new OpaquePayloadDataIn;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->payloadType = OpaquePayloadDataBase::Type::OC;
tele->payload = getPayload(a_radioTelegram, 7);
return tele;
}
case GEF_DATENVERKEHR_DMF_TDS: {
if (!isPayloadLengthOk(a_radioTelegram, 7))
return nullptr;
auto tele = new OpaquePayloadDataIn;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->payloadType = OpaquePayloadDataBase::Type::FireSmokeMarker;
tele->payload = getPayload(a_radioTelegram, 7);
return tele;
}
case GEF_DATENVERKEHR_GEOP_TDS: {
if (!isPayloadLengthOk(a_radioTelegram, 14))
return nullptr;
auto tele = new OpaquePayloadDataIn;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->gpsQuality = getGpsQuality(a_radioTelegram, 13);
tele->payloadType = OpaquePayloadDataBase::Type::Geopairing;
tele->payload = getPayload(a_radioTelegram, 14, 15);
return tele;
}
case GEF_DATENVERKEHR_TGTC_TDS: {
if (!isPayloadLengthOk(a_radioTelegram, 7))
return nullptr;
auto tele = new OpaquePayloadDataIn;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->payloadType = OpaquePayloadDataBase::Type::Target;
tele->payload = getPayload(a_radioTelegram, 7, 8);
return tele;
}
case GEF_GERAETEEREIGNIS: {
if (!isPayloadLengthOk(a_radioTelegram, 24))
return nullptr;
auto tele = new EquipmentEvent;
tele->header = getHeader(a_radioTelegram, 3);
tele->relPosition = getRelativePosition(a_radioTelegram, 7);
tele->equipmentFunctionId = a_radioTelegram->getPayloadDataUInt8(13);
tele->subDeviceId = a_radioTelegram->getPayloadDataUInt8(14);
tele->uniqueId = a_radioTelegram->getPayloadDataUInt32(15, 4);
tele->code = a_radioTelegram->getPayloadDataUInt8(23);
tele->payload = getPayload(a_radioTelegram, 24, 25);
return tele;
}
case GEF_WAFFENZUORDNUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 8, 7, 6))
return nullptr;
auto tele = new EquipmentGearAssignment;
tele->header = getHeader(a_radioTelegram, 3);
const uint8_t waffen_len = a_radioTelegram->getPayloadDataUInt8(7);
tele->gears.reserve(waffen_len);
for (uint32_t i = 0; i < waffen_len && i < 10; i++)
{
const uint8_t iPos = 8 + i * 6;
Gear gear;
gear.gearSerialNumber = a_radioTelegram->getPayloadDataUInt32(iPos, 4);
gear.gearTasCode = a_radioTelegram->getPayloadDataUInt8(iPos + 4);
gear.chargeCounting = a_radioTelegram->getPayloadDataUInt8(iPos + 5) != 0;
tele->gears.push_back(std::move(gear));
}
return tele;
}
case GEF_IPS_POSITIONSDATEN: {
if (!isPayloadLengthOk(a_radioTelegram, 8, 7, 2))
return nullptr;
auto tele = new PositionReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->header.timeStamp += 1;
size_t iPos = 7;
tele->opsPosition = getOpsPosition(a_radioTelegram, iPos);
if (tele->opsPosition.opsId == -1)
{
delete tele;
tele = nullptr;
}
return tele;
}
case GEF_MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE: {
constexpr int varSize = 5;
if (!isPayloadLengthOk(a_radioTelegram, 13, 12, varSize))
return nullptr;
auto tele = new EquipmentGearChargeState;
tele->header = getHeader(a_radioTelegram, 3);
GearCharge gc;
gc.gearSerialNumber = a_radioTelegram->getPayloadDataUInt32(7, 4);
gc.gearTasCode = a_radioTelegram->getPayloadDataUInt8(11);
const uint8_t munitionsliste_len = a_radioTelegram->getPayloadDataUInt8(12);
tele->charges.reserve(munitionsliste_len);
for (uint32_t i = 0; i < munitionsliste_len; i++)
{
int iPos = 13;
const int offset = 5 * i;
gc.location = a_radioTelegram->getPayloadDataUInt8(iPos + offset);
iPos++;
short munitionsmenge = a_radioTelegram->getPayloadDataUInt32(iPos + offset, 2);
iPos += 2;
gc.remain = munitionsmenge < 0 ? -1 : munitionsmenge;
gc.chargeTypeId = a_radioTelegram->getPayloadDataUInt32(iPos + offset, 2);
tele->charges.push_back(gc);
}
return tele;
}
case GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 13))
return nullptr;
auto tele = new CesHitRequest;
tele->header = getHeader(a_radioTelegram, 3);
tele->chargeTasCodeDirect = a_radioTelegram->getPayloadDataUInt32(7, 2);
tele->aesDdsId = a_radioTelegram->getPayloadDataUInt32(9, 2);
tele->aesType = static_cast<AreaEffectSimulationType>(a_radioTelegram->getPayloadDataUInt8(11));
tele->remainEffectTasCodeDirect = a_radioTelegram->getPayloadDataUInt8(12);
return tele;
}
case GEF_TEILNEHMERMODE_MELDUNG: {
if (!isPayloadLengthOk(a_radioTelegram, 15))
return nullptr;
auto tele = new ParticipantModeReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->language = static_cast<Language>(a_radioTelegram->getPayloadDataUInt8(7));
tele->operationMode =
static_cast<ParticipantModeBase::OperationMode>(a_radioTelegram->getPayloadDataUInt8(8));
tele->reactivationDetoxication = a_radioTelegram->getPayloadDataUInt8(9) * 10;
tele->reactivationMaintenance = a_radioTelegram->getPayloadDataUInt8(10) * 10;
tele->reactivationMedic = a_radioTelegram->getPayloadDataUInt8(11) * 10;
unsigned char wph_mode = a_radioTelegram->getPayloadDataUInt8(12);
tele->modeHelmet = static_cast<ParticipantModeBase::WphMode>(wph_mode & 0x03);
tele->modeVest = static_cast<ParticipantModeBase::WphMode>((wph_mode >> 2) & 0x03);
tele->personellProtectionMode =
static_cast<ParticipantModeBase::PersonellProtection>((wph_mode >> 4) & 0x07);
unsigned char protection_mode = a_radioTelegram->getPayloadDataUInt8(13);
tele->protectionLevel = static_cast<ParticipantModeBase::ProtectionLevel>(protection_mode & 0x06);
tele->abcProtectionMode =
static_cast<ParticipantModeBase::ABCProtectionMode>((protection_mode >> 3) & 0x03);
unsigned char specialFunction = a_radioTelegram->getPayloadDataUInt8(14);
tele->handgrenadeSearchMode =
static_cast<ParticipantModeBase::HandgrenadeSearchMode>(specialFunction & 0b11);
tele->internationalMode =
static_cast<ParticipantModeBase::InternationalMode>((specialFunction >> 2) & 0b11);
return tele;
}
case GEF_TEILNEHMER_KONFIG_ANTWORT: {
if (!isPayloadLengthOk(a_radioTelegram, 27))
return nullptr;
auto tele = new ParticipantConfigurationReport;
tele->header = getHeader(a_radioTelegram, 3);
tele->positionIntervallVehicle = a_radioTelegram->getPayloadDataUInt32(7, 2);
tele->positionIntervallPersonell = a_radioTelegram->getPayloadDataUInt32(9, 2);
tele->positionIntervallAircraft = a_radioTelegram->getPayloadDataUInt32(11, 2);
tele->positionTransmissionIntervall = a_radioTelegram->getPayloadDataUInt32(13, 2);
tele->heightbarrier = a_radioTelegram->getPayloadDataUInt32(15, 2);
unsigned char tmp = a_radioTelegram->getPayloadDataUInt8(17);
tele->faultPositionHandling =
static_cast<ParticipantConfigurationBase::FaultPositionHandling>((tmp >> 6) & 0x03);
tele->switchingPositionIntervall =
static_cast<ParticipantConfigurationBase::SwitchingPositionIntervall>(tmp & 0x03);
tele->waittimeAdditionalBroadcastDemand = a_radioTelegram->getPayloadDataUInt32(18, 2);
tele->factorWaittimeIncreaseAtHighload = a_radioTelegram->getPayloadDataUInt8(20);
tele->waittimeAutomaticVulnerabilityIncreaseLevel1 = a_radioTelegram->getPayloadDataUInt8(21);
tele->waittimeAutomaticVulnerabilityIncreaseLevel2 = a_radioTelegram->getPayloadDataUInt8(22);
tele->waittimeAutomaticVulnerabilityIncreaseLevel3 = a_radioTelegram->getPayloadDataUInt8(23);
tele->opticalCode =
static_cast<ParticipantConfigurationBase::OpticalCode>(a_radioTelegram->getPayloadDataUInt8(24));
tele->vulnerabilityModel = a_radioTelegram->getPayloadDataUInt8(25);
tele->validTimeOps = a_radioTelegram->getPayloadDataUInt8(26);
return tele;
}
case GEF_ESW_MELDUNG:
return nullptr;
case GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME: {
if (!isPayloadLengthOk(a_radioTelegram, 10))
return nullptr;
auto tele = new RequestBroadcastTelegrams;
tele->header = getHeader(a_radioTelegram, 3);
tele->resetCounter = a_radioTelegram->getPayloadDataUInt8(7);
tele->broadcastIndex = a_radioTelegram->getPayloadDataUInt32(8, 2);
return tele;
}
case GEF_LASER_TARGET_DESIGNATOR_UPDATE: {
auto tele = new ApacheLaserDesignation;
tele->header = getHeader(a_radioTelegram, 3);
tele->code = a_radioTelegram->getPayloadDataUInt32(7, 2);
tele->outputPower = a_radioTelegram->getPayloadDataUInt8(9);
tele->gearId = a_radioTelegram->getPayloadDataUInt32(10, 4);
return tele;
}
default: {
ERROR_LOG(logger()) << "Conversion of Radio-Telegram to Central-Telegram with telId="
<< a_radioTelegram->getTelID() << " not implemented.";
}
}
return nullptr;
}
} // namespace CoPrtCnvTelegramConverter
} // namespace N_CoPrtCnv