#include "CoPrtCnvTelegramConverter.hpp" #include #include #include #include #include "CoPrtCnvCentralTelegram.hpp" #include "CoPrtCnvRadioTelegram.hpp" #include #include #include #include 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 static inline bool checkBitmask(const T &d, int bitmask) { return ((d & bitmask) == bitmask); } template 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 void getTaktZustand(const CoPrtCnvRadioTelegram *a_radioTelegram, size_t iOffset, T *tele) { tele->vulnerabilityState = static_cast( 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(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(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 T fromJson(CoPrtCnvCentralTelegram *radioTelegram) { return T::fromJson(radioTelegram->jsonData()); } template const T &fromJson(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *tabTelegram) { return static_cast(*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 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 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 static CoPrtCnvRadioTelegram *convertToRadioInternal(T *a_telegram) { N_CoPrtCnv::CoPrtCnvRadioTelegram *radioTelegram = nullptr; switch (getTelegramId(a_telegram)) { case Constraints::id(): { const Init &tele(fromJson(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::id(): { const SetVulnerabilityModel &tele(fromJson(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::id(): { const DemandEquipmentConfigurationReport &tele( fromJson(a_telegram)); radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_ANFORDERUNG_KONFIGURATIONSDATEN, 3, tele.header.equipmentNumber); break; } case Constraints::id(): { const StateChange &tele(fromJson(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::id(): { const BiteReport &tele(fromJson(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::id(): { const ExerciseEnvironmentData &tele(fromJson(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::id(): { const DemandBite &tele(fromJson(a_telegram)); radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_AUFFORDERUNG_BITE_MELDUNG, 4, tele.header.equipmentNumber); radioTelegram->setPayloadData(tele.withSelfTest, 1); break; } case Constraints::id(): { const PositionReport &tele(fromJson(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::id(): { const CreateSingleExplosion &tele(fromJson(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::id(): { const CreateAreaExplosion &tele(fromJson(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::id(): { const PauseEffectSimulation &tele(fromJson(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::id(): { const ResumeEffectSimulation &tele(fromJson(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::id(): { const CreateMineArea &tele(fromJson(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::id(): { const MineAreaSingleMineState &tele(fromJson(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::id(): { const CreateNContamination &tele(fromJson(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::id(): { const CreateCContamination &tele(fromJson(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::id(): { const DeactivateEffectSimulation &tele(fromJson(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::id(): { const ModifyAreaEffectSimulationName &tele(fromJson(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::id(): { const MineTriggered &tele(fromJson(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::id(): { const DusMineReactivation &tele(fromJson(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::id(): { const CreateDusSingleMine &tele(fromJson(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::id(): { const DemandVulnerabilityStateChange &tele(fromJson(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::id(): { const TechnicalArea &tele(fromJson(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::id(): { const CreateFunctionalArea &tele(fromJson(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::id(): { const LanguageSelection &tele(fromJson(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::id(): { const EquipmentMessage &tele(fromJson(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::id(): { const OpaquePayloadDataOut &tele(fromJson(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::id(): { const CesHitInformation &tele(fromJson(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::id(): { const ParticipantSwVersionsRequest &tele(fromJson(a_telegram)); radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_ANFORDERUNG_SW_VERSION, 4, tele.header.equipmentNumber); radioTelegram->setPayloadData(tele.equipmentFunctionId, 1); break; } case Constraints::id(): { const ParticipantMode &tele(fromJson(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::id(): { const DemandParticipantMode &tele(fromJson(a_telegram)); radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TEILNEHMERMODE_ANFORDERN, 3, tele.header.equipmentNumber); break; } case Constraints::id(): { const ParticipantConfiguration &tele(fromJson(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::id(): { const DemandParticipantConfiguration &tele(fromJson(a_telegram)); radioTelegram = new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_TEILNEHMER_KONFIG_ANFORDERN, 3, tele.header.equipmentNumber); break; } case Constraints::id(): { const SanitationRepair &tele(fromJson(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::id(): { const SanitaryMaterialStockReport &tele(fromJson(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::id(): { const Sanitation &tele(fromJson(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::id(): { const CesHitRequest &tele(fromJson(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::id(): { const SelectiveReammunition &tele(fromJson(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::id(): { const OcCommand &tele(fromJson(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 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 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 ret; ret.resize(payloadLen); memcpy(ret.data(), a_radioTelegram->getPayloadDataPtr(offsetData), payloadLen); return ret; } static inline std::vector 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 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( data->id())); } template 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(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( a_radioTelegram->getPayloadDataUInt8(7)); tele->equipmentNumberOrigin = a_radioTelegram->getPayloadDataUInt32(8, 2); tele->stateStart = static_cast( 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( bitfield2 & 0x0F); tele->treatmentResult = static_cast( (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(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 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(); 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(a_radioTelegram->getPayloadDataUInt8(21)); quint8 enumByte = a_radioTelegram->getPayloadDataUInt8(22); tele->sanitationEvaluation = static_cast((enumByte & 0xc0) >> 6); tele->sanitationResult = static_cast(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(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(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(a_radioTelegram->getPayloadDataUInt8(19)); tele->pairedId = a_radioTelegram->getPayloadDataUInt32(20, 2); tele->tacticalState = static_cast(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(a_radioTelegram->getPayloadDataUInt8(9)); tele->statePyrotechnics = a_radioTelegram->getPayloadDataUInt8(10); tele->batteryWarnings = a_radioTelegram->getPayloadDataUInt8(11); tele->errorStateElectronics = static_cast(a_radioTelegram->getPayloadDataUInt8(12)); tele->errorStatePyrotechnics1 = static_cast(a_radioTelegram->getPayloadDataUInt8(13)); tele->errorStatePyrotechnics2 = static_cast(a_radioTelegram->getPayloadDataUInt8(14)); tele->errorStatePyrotechnics3 = static_cast(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( 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( 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(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(a_radioTelegram->getPayloadDataUInt8(7)); tele->operationMode = static_cast( 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(wph_mode & 0x03); tele->modeVest = static_cast((wph_mode >> 2) & 0x03); tele->personellProtectionMode = static_cast((wph_mode >> 4) & 0x07); unsigned char protection_mode = a_radioTelegram->getPayloadDataUInt8(13); tele->protectionLevel = static_cast(protection_mode & 0x06); tele->abcProtectionMode = static_cast((protection_mode >> 3) & 0x03); unsigned char specialFunction = a_radioTelegram->getPayloadDataUInt8( 14); tele->handgrenadeSearchMode = static_cast( specialFunction & 0b11); tele->internationalMode = static_cast( (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( (tmp >> 6) & 0x03); tele->switchingPositionIntervall = static_cast( 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( 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; } } }