/** * Telegrams between NASAT and GUEZ * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, NLE, 2019-09-18 */ #include "guez_nasat_telegrams.h" #include #include namespace GuezNasat { // // Helpers // JsonException::JsonException(const QJsonObject &obj, const QString &key) : m_obj(obj) , m_key(key) , m_what("Could not find key '" + key.toUtf8() + "' in json ('" + QJsonDocument(obj).toJson(QJsonDocument::Compact) + "')") {} template QJsonValue enumToJson(E e) { static_assert (std::is_enum::value, "Only useable with enumerations"); return static_cast(e); } template bool get(const QJsonObject &obj, const QString &key, T &val, bool bOptional = false) { if (bOptional) { try { val = T::fromJson(obj[key].toObject()); } catch (const JsonException &e) { Q_UNUSED(e); return false; } } else val = T::fromJson(obj[key].toObject()); return true; } // POD getter template <> bool get(const QJsonObject &obj, const QString &key, bool &val, bool bOptional) { const auto jVal = obj[key]; if (!jVal.isBool()) { if (bOptional) return false; throw JsonException(obj, key); } val = jVal.toBool(); return true; } template <> bool get(const QJsonObject &obj, const QString &key, int &val, bool bOptional) { const auto jVal = obj[key]; if (!jVal.isDouble()) { if (bOptional) return false; throw JsonException(obj, key); } val = jVal.toInt(); return true; } template <> bool get(const QJsonObject &obj, const QString &key, double &val, bool bOptional) { const auto jVal = obj[key]; if (!jVal.isDouble()) { if (bOptional) return false; throw JsonException(obj, key); } val = jVal.toDouble(); return true; } // // enum getter // // FinalAttackHeadingMode template <> bool get(const QJsonObject &obj, const QString &key, FinalAttackHeadingMode &val, bool bOptional) { int iVal; get(obj, key, iVal, bOptional); switch (static_cast(iVal)) { case FinalAttackHeadingMode::None: case FinalAttackHeadingMode::HeadingOnly: case FinalAttackHeadingMode::HeadingWithSector: val = static_cast(iVal); return true; } throw JsonException(obj, key); } // FuseType template <> bool get(const QJsonObject &obj, const QString &key, FuseType &val, bool bOptional) { int iVal; get(obj, key, iVal, bOptional); switch (static_cast(iVal)) { case FuseType::Undefined: case FuseType::Instant: case FuseType::Delay: case FuseType::AirBurst: val = static_cast(iVal); return true; } throw JsonException(obj, key); } // Heading2InitialPointMode template <> bool get(const QJsonObject &obj, const QString &key, Heading2InitialPointMode &val, bool bOptional) { int iVal; get(obj, key, iVal, bOptional); switch (static_cast(iVal)) { case Heading2InitialPointMode::Undefined: case Heading2InitialPointMode::UseHdgIP2Target_1: case Heading2InitialPointMode::UseHdgIP2Target_2: case Heading2InitialPointMode::KeyholeA: case Heading2InitialPointMode::KeyholeB: case Heading2InitialPointMode::KeyholeC: case Heading2InitialPointMode::KeyholeD: val = static_cast(iVal); return true; } throw JsonException(obj, key); } // Heading2InitialPointMode template <> bool get(const QJsonObject &obj, const QString &key, Munition &val, bool bOptional) { int iVal; get(obj, key, iVal, bOptional); switch (static_cast(iVal)) { case Munition::Undefined: case Munition::Gun: case Munition::Missile_AGM114: case Munition::Missile_AGM65: case Munition::Missile_MK151: case Munition::Missile_MK24: case Munition::Bomb_MK82LD: case Munition::Bomb_MK83LD: case Munition::Bomb_MK84LD: case Munition::Bomb_MK82HD: case Munition::Bomb_MK83HD: case Munition::Bomb_MK84HD: case Munition::PGM_500lb: case Munition::PGM_1000lb: case Munition::PGM_2000lb: case Munition::Bomb_MK82_Unguided: case Munition::Bomb_MK83_Unguided: case Munition::Bomb_MK84_Unguided: case Munition::PGM_GBU12: case Munition::PGM_GBU24: case Munition::PGM_GBU31: case Munition::PGM_GBU32: case Munition::PGM_GBU35: case Munition::PGM_GBU38: case Munition::PGM_GBU49: case Munition::PGM_GBU54: case Munition::PGM_BLU109: case Munition::MSL_AGM_114K: case Munition::MSL_AGM_114M: case Munition::MSL_AGM_114N: case Munition::MSL_AGM_114FA: case Munition::MSL_AGM_65: case Munition::GUN_FW20: case Munition::GUN_FW25: case Munition::GUN_20mm: case Munition::Missile_MK_151: case Munition::Missile_MK229: case Munition::Missile_MK261: case Munition::Missile_MK151LowALT: case Munition::Missile_MK229LowALT: case Munition::Missile_MK261LowALT: case Munition::Missile_MK_24: val = static_cast(iVal); return true; } throw JsonException(obj, key); } // Heading2InitialPointMode template <> bool get(const QJsonObject &obj, const QString &key, ReleaseMode &val, bool bOptional) { int iVal; get(obj, key, iVal, bOptional); switch (static_cast(iVal)) { case ReleaseMode::Undefined: case ReleaseMode::Manual: case ReleaseMode::Automatic: val = static_cast(iVal); return true; } throw JsonException(obj, key); } // Heading2InitialPointMode template <> bool get(const QJsonObject &obj, const QString &key, TimeForTargetMode &val, bool bOptional) { int iVal; get(obj, key, iVal, bOptional); switch (static_cast(iVal)) { case TimeForTargetMode::None: case TimeForTargetMode::TimeToTarget: case TimeForTargetMode::TimeOverTarget: val = static_cast(iVal); return true; } throw JsonException(obj, key); } // // GeoPosition2D // QJsonObject GeoPosition2D::toJson() const { return QJsonObject({{QStringLiteral("lat"), lat}, {QStringLiteral("lon"), lon}, }); } GeoPosition2D GeoPosition2D::fromJson(const QJsonObject &obj) { GeoPosition2D ret; get(obj, QStringLiteral("lat"), ret.lat); get(obj, QStringLiteral("lon"), ret.lon); return ret; } // // GeoPosition3D // QJsonObject GeoPosition3D::toJson() const { return QJsonObject({{QStringLiteral("lat"), lat}, {QStringLiteral("lon"), lon}, {QStringLiteral("height"), height}, }); } GeoPosition3D GeoPosition3D::fromJson(const QJsonObject &obj) { GeoPosition3D ret; get(obj, QStringLiteral("lat"), ret.lat); get(obj, QStringLiteral("lon"), ret.lon); get(obj, QStringLiteral("height"), ret.height); return ret; } // // NasatSimulationRequest // QJsonObject NasatSimulationRequest::toJson() const { return QJsonObject({{QStringLiteral("aircraftId"), aircraftId}, {QStringLiteral("timestamp"), timestamp}, {QStringLiteral("position"), position.toJson()}, {QStringLiteral("enableSimulation"), enableSimulation}, }); } NasatSimulationRequest NasatSimulationRequest::fromJson(const QJsonObject &obj) { NasatSimulationRequest ret; get(obj, QStringLiteral("aircraftId"), ret.aircraftId); get(obj, QStringLiteral("timestamp"), ret.timestamp); get(obj, QStringLiteral("position"), ret.position); get(obj, QStringLiteral("enableSimulation"), ret.enableSimulation); return ret; } // // NasatSimulationStatus // QJsonObject NasatSimulationStatus::toJson() const { return QJsonObject({{QStringLiteral("aircraftId"), aircraftId}, {QStringLiteral("timestamp"), timestamp}, {QStringLiteral("simulationEnabled"), simulationEnabled}, }); } NasatSimulationStatus NasatSimulationStatus::fromJson(const QJsonObject &obj) { NasatSimulationStatus ret; get(obj, QStringLiteral("aircraftId"), ret.aircraftId); get(obj, QStringLiteral("timestamp"), ret.timestamp); get(obj, QStringLiteral("simulationEnabled"), ret.simulationEnabled); return ret; } // // NasatPosition // QJsonObject NasatPosition::toJson() const { return QJsonObject({{QStringLiteral("aircraftId"), aircraftId}, {QStringLiteral("timestamp"), timestamp}, {QStringLiteral("position"), position.toJson()}, }); } NasatPosition NasatPosition::fromJson(const QJsonObject &obj) { NasatPosition ret; get(obj, QStringLiteral("aircraftId"), ret.aircraftId); get(obj, QStringLiteral("timestamp"), ret.timestamp); get(obj, QStringLiteral("position"), ret.position); return ret; } // // NasatWeaponRelease // QJsonObject NasatWeaponRelease::toJson() const { return QJsonObject({{QStringLiteral("aircraftId"), aircraftId}, {QStringLiteral("timestamp"), timestamp}, {QStringLiteral("impactPosition"), impactPosition.toJson()}, {QStringLiteral("flightTime"), flightTime}, {QStringLiteral("munition"), enumToJson(munition)}, {QStringLiteral("fuseType"), enumToJson(fuseType)}, {QStringLiteral("releaseMode"), enumToJson(releaseMode)}, }); } NasatWeaponRelease NasatWeaponRelease::fromJson(const QJsonObject &obj) { NasatWeaponRelease ret; get(obj, QStringLiteral("aircraftId"), ret.aircraftId); get(obj, QStringLiteral("timestamp"), ret.timestamp); get(obj, QStringLiteral("impactPosition"), ret.impactPosition); get(obj, QStringLiteral("flightTime"), ret.flightTime); get(obj, QStringLiteral("munition"), ret.munition); get(obj, QStringLiteral("fuseType"), ret.fuseType); get(obj, QStringLiteral("releaseMode"), ret.releaseMode); return ret; } // // NasatNineLiner // QJsonObject NasatNineLiner::Friendlies::toJson() const { return QJsonObject({{QStringLiteral("bearing"), bearing}, {QStringLiteral("distance"), distance}, }); } NasatNineLiner::Friendlies NasatNineLiner::Friendlies::fromJson(const QJsonObject &obj) { Friendlies ret; get(obj, QStringLiteral("bearing"), ret.bearing); get(obj, QStringLiteral("distance"), ret.distance); return ret; } QJsonObject NasatNineLiner::FinalAttackHeading::toJson() const { return QJsonObject({{QStringLiteral("heading"), heading}, {QStringLiteral("headingLow"), headingLow}, {QStringLiteral("headingHigh"), headingHigh}, }); } NasatNineLiner::FinalAttackHeading NasatNineLiner::FinalAttackHeading::fromJson(const QJsonObject &obj) { FinalAttackHeading ret; get(obj, QStringLiteral("heading"), ret.heading); get(obj, QStringLiteral("headingLow"), ret.headingLow); get(obj, QStringLiteral("headingHigh"), ret.headingHigh); return ret; } QJsonObject NasatNineLiner::toJson() const { return QJsonObject({{QStringLiteral("aircraftId"), aircraftId}, {QStringLiteral("timestamp"), timestamp}, {QStringLiteral("initialPoint"), initialPoint.toJson()}, {QStringLiteral("initialPointMode"), initialPointMode}, {QStringLiteral("headingInitialPoint2Target"), headingInitialPoint2Target}, {QStringLiteral("heading2InitialPointMode"), enumToJson(heading2InitialPointMode)}, {QStringLiteral("distanceInitialPoint2Target"), distanceInitialPoint2Target}, {QStringLiteral("distance2InitialPointMode"), distance2InitialPointMode}, {QStringLiteral("targetPosition"), targetPosition.toJson()}, {QStringLiteral("targetPositionMode"), targetPositionMode}, {QStringLiteral("altitudeTarget"), altitudeTarget}, {QStringLiteral("altitudeTargetMode"), altitudeTargetMode}, {QStringLiteral("friendlies"), friendlies.toJson()}, {QStringLiteral("modeFriendlies"), modeFriendlies}, {QStringLiteral("finalAttackHeading"), finalAttackHeading.toJson()}, {QStringLiteral("finalAttackHeadingMode"), enumToJson(finalAttackHeadingMode)}, {QStringLiteral("timeForTarget"), timeForTarget}, {QStringLiteral("timeForTargetMode"), enumToJson(timeForTargetMode)}, }); } NasatNineLiner NasatNineLiner::fromJson(const QJsonObject &obj) { NasatNineLiner ret; get(obj, QStringLiteral("aircraftId"), ret.aircraftId); get(obj, QStringLiteral("timestamp"), ret.timestamp); get(obj, QStringLiteral("initialPoint"), ret.initialPoint, true); get(obj, QStringLiteral("initialPointMode"), ret.initialPointMode, true); get(obj, QStringLiteral("headingInitialPoint2Target"), ret.headingInitialPoint2Target); get(obj, QStringLiteral("heading2InitialPointMode"), ret.heading2InitialPointMode); get(obj, QStringLiteral("distanceInitialPoint2Target"), ret.distanceInitialPoint2Target, true); get(obj, QStringLiteral("distance2InitialPointMode"), ret.distance2InitialPointMode, true); get(obj, QStringLiteral("targetPosition"), ret.targetPosition, true); get(obj, QStringLiteral("targetPositionMode"), ret.targetPositionMode, true); get(obj, QStringLiteral("altitudeTarget"), ret.altitudeTarget, true); get(obj, QStringLiteral("altitudeTargetMode"), ret.altitudeTargetMode, true); get(obj, QStringLiteral("friendlies"), ret.friendlies, true); get(obj, QStringLiteral("modeFriendlies"), ret.modeFriendlies, true); get(obj, QStringLiteral("finalAttackHeading"), ret.finalAttackHeading); get(obj, QStringLiteral("finalAttackHeadingMode"), ret.finalAttackHeadingMode); get(obj, QStringLiteral("timeForTarget"), ret.timeForTarget); get(obj, QStringLiteral("timeForTargetMode"), ret.timeForTargetMode); return ret; } } // namespace GuezNasat