Files
qt6-migration-pipeline/TetraIF/CoPrtCnv/CoPrtCnvTelegramConverterNewIcd.cpp
T

2132 lines
80 KiB
C++

#include "CoPrtCnvTelegramConverter.hpp"
#include <QJsonDocument>
#include <QJsonObject>
#include <QLineF>
#include <QtCore/QTextCodec>
#include "CoPrtCnvCentralTelegram.hpp"
#include "CoPrtCnvRadioTelegram.hpp"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <TrainingAreaBase/training_area_telegrams.h>
#include <math.h>
#include <vector>
using namespace TrainingAreaBase::TetraIcd;
namespace N_CoPrtCnv
{
namespace CoPrtCnvTelegramConverter
{
static QTextCodec *s_TetraTextCodec = nullptr;
static bool s_needTextCodec = false;
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;
if (s_needTextCodec && s_TetraTextCodec)
{
const QString str = QString::fromUtf8(stdString.c_str());
encodedData = s_TetraTextCodec->fromUnicode(str);
}
else
encodedData = QByteArray(stdString.c_str(), a_size);
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)
{
if (codecName)
s_TetraTextCodec = QTextCodec::codecForName(codecName);
else
s_TetraTextCodec = nullptr;
s_needTextCodec = (s_TetraTextCodec != nullptr);
}
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;
}
}
}