Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,273 @@
|
||||
#include "cnr_frequency_planning_helper.h"
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
// Todo: Better tr() ?
|
||||
#include <QCoreApplication>
|
||||
|
||||
namespace AudioVideoManagement {
|
||||
|
||||
template<typename T>
|
||||
T fromJson(const QByteArray &json)
|
||||
{
|
||||
QJsonParseError jError;
|
||||
QJsonDocument doc(QJsonDocument::fromJson(json, &jError));
|
||||
if (jError.error)
|
||||
return {};
|
||||
QJsonObject obj = doc.object();
|
||||
return T::fromJson(obj);
|
||||
}
|
||||
|
||||
// Todo:
|
||||
|
||||
//
|
||||
// FreqPlanningDataSet ist nur noch ein pro FreqPlanningData vorhanden. Also integrieren in die Relation.
|
||||
// DB und DDS Typen anpassen
|
||||
// Die Properties einer FreqPlanningData(Set) sind ein Array (REL) (VHF/UHF/HF)
|
||||
// wie in der Methode unter diesem Kommentar (bei dem die RadioSpecificaJSON schon mit rein geht!),
|
||||
// siehe avm_edit_frequency_planning_resource_dialog.cpp:120
|
||||
// Aus dieser einen Zeile müssen dann im Übersichtsdialog entweder ein Eintrag oder (mindestens) 3 Einträge (REL) gemacht werden.
|
||||
// Die RadioSpecificaHelper also um Hilfsmethoden erweitern, damit man passende Objekte bekommt.
|
||||
// Vielleicht die drei items Name, FreqBand, RadioStation ID gleich mit in die Specifica, bzw. von was ableiten, dass das beinhaltet!
|
||||
|
||||
// Method to obtain all "FrequencySetDataId" from an QJsonObject
|
||||
QJsonObject frequencyPlanningJson(QJsonObject obj, const QString &name, FrequencyBand freqBand, int radioStationId)
|
||||
{
|
||||
obj.insert(QStringLiteral("Name"), name);
|
||||
obj.insert(QStringLiteral("FrequencyBand"), freqBand.underlying());
|
||||
obj.insert(QStringLiteral("RadioStationId"), radioStationId);
|
||||
return obj;
|
||||
}
|
||||
|
||||
bool RadioCircuitHF::isValid() const
|
||||
{
|
||||
if ((modulationType != ModulationType::AM && modulationType != ModulationType::FM) ||
|
||||
(channelSpacing != ChannelSpacingHF::CS_100_Hz) ||
|
||||
frequency < FREQ_MIN || frequency > FREQ_MAX ||
|
||||
squelch < (SQUELCH_MIN-1) || squelch > SQUELCH_MAX
|
||||
)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject RadioCircuitHF::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj.insert(QStringLiteral("ModulationType"), modulationType.underlying());
|
||||
obj.insert(QStringLiteral("ChannelSpacing"), channelSpacing.underlying());
|
||||
obj.insert(QStringLiteral("Frequency"), frequency);
|
||||
obj.insert(QStringLiteral("Squelch"), squelch);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
RadioCircuitHF* RadioCircuitHF::fromJson(const QJsonObject &obj)
|
||||
{
|
||||
RadioCircuitHF *spec = new RadioCircuitHF();
|
||||
spec->modulationType = static_cast<ModulationType::inner_enum>(obj.value(QStringLiteral("ModulationType")).toInt(-1));
|
||||
spec->channelSpacing = static_cast<ChannelSpacingHF::inner_enum>(obj.value(QStringLiteral("ChannelSpacing")).toInt());
|
||||
spec->frequency = obj.value(QStringLiteral("Frequency")).toInt();
|
||||
spec->squelch = obj.value(QStringLiteral("Squelch")).toInt(-1);
|
||||
if (spec->isValid())
|
||||
return spec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool RadioCircuitUHF::isValid() const
|
||||
{
|
||||
if ((modulationType != ModulationType::AM && modulationType != ModulationType::FM) ||
|
||||
(channelSpacing != ChannelSpacing::CS_8_33_kHz && channelSpacing != ChannelSpacing::CS_12_50_kHz && channelSpacing != ChannelSpacing::CS_25_00_kHz) ||
|
||||
frequency < FREQ_MIN || frequency > FREQ_MAX ||
|
||||
((squelchDB < SQUELCH_MIN || squelchDB > SQUELCH_MAX) && squelchDB != 0) // 0 or Min <squelch < max
|
||||
)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject RadioCircuitUHF::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj.insert(QStringLiteral("ModulationType"), modulationType.underlying());
|
||||
obj.insert(QStringLiteral("ChannelSpacing"), channelSpacing.underlying());
|
||||
obj.insert(QStringLiteral("Frequency"), frequency);
|
||||
obj.insert(QStringLiteral("Squelch"), squelchDB);
|
||||
obj.insert(QStringLiteral("Clipper"), clipper);
|
||||
obj.insert(QStringLiteral("AGC"), agc);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
RadioCircuitUHF* RadioCircuitUHF::fromJson(const QJsonObject &obj)
|
||||
{
|
||||
RadioCircuitUHF *spec = new RadioCircuitUHF();
|
||||
spec->modulationType = static_cast<ModulationType::inner_enum>(obj.value(QStringLiteral("ModulationType")).toInt(-1));
|
||||
spec->channelSpacing = static_cast<ChannelSpacing::inner_enum>(obj.value(QStringLiteral("ChannelSpacing")).toInt());
|
||||
spec->frequency = obj.value(QStringLiteral("Frequency")).toInt();
|
||||
spec->squelchDB = obj.value(QStringLiteral("Squelch")).toInt(-1);
|
||||
auto clipper = obj.value(QStringLiteral("Clipper"));
|
||||
if (clipper.isUndefined() || !clipper.isBool())
|
||||
return nullptr;
|
||||
spec->clipper = clipper.toBool();
|
||||
auto agc = obj.value(QStringLiteral("AGC"));
|
||||
if (agc.isUndefined() || !agc.isBool())
|
||||
return {};
|
||||
spec->agc = agc.toBool();
|
||||
|
||||
if (spec->isValid())
|
||||
return spec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QJsonObject RadioCircuitVHF::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj.insert(QStringLiteral("OperatingMode"), operatingMode.underlying());
|
||||
obj.insert(QStringLiteral("FrequencySetDataId"), freqSetDataId);
|
||||
obj.insert(QStringLiteral("PilotTone"), pilotTone);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
RadioCircuitVHF* RadioCircuitVHF::fromJson(const QJsonObject &obj)
|
||||
{
|
||||
RadioCircuitVHF *spec = new RadioCircuitVHF();
|
||||
spec->operatingMode = static_cast<RcOperatingMode::inner_enum>(obj.value(QStringLiteral("OperatingMode")).toInt(-1));
|
||||
spec->freqSetDataId = obj.value(QStringLiteral("FrequencySetDataId")).toInt();
|
||||
auto pilotTone = obj.value(QStringLiteral("PilotTone"));
|
||||
if (pilotTone.isUndefined() || !pilotTone.isBool())
|
||||
return nullptr;
|
||||
spec->pilotTone = pilotTone.toBool();
|
||||
|
||||
if (spec->isValid())
|
||||
return spec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString RadioCircuitHF::toString() const
|
||||
{
|
||||
|
||||
return QCoreApplication::translate("AVM", "Frequency: %1, ModulationType: %2, ChannelSpacing: %3, Squelch: %4")
|
||||
.arg(frequency)
|
||||
.arg(AudioVideoManagement::toString(modulationType))
|
||||
.arg(100)
|
||||
.arg(squelch);
|
||||
}
|
||||
|
||||
QString RadioCircuitUHF::toString() const
|
||||
{
|
||||
return QCoreApplication::translate("AVM", "Frequency: %1, ModulationType: %2, ChannelSpacing: %3, Squelch: %4, Clipper: %5, AGC: %6")
|
||||
.arg(frequency)
|
||||
.arg(AudioVideoManagement::toString(modulationType))
|
||||
.arg(AudioVideoManagement::toString(channelSpacing))
|
||||
.arg(squelchDB)
|
||||
.arg(clipper)
|
||||
.arg(agc);
|
||||
}
|
||||
|
||||
QString RadioCircuitVHF::toString() const
|
||||
{
|
||||
return QCoreApplication::translate("AVM", "OperatingMode: %1, PilotTone: %2")
|
||||
.arg(AudioVideoManagement::toString(operatingMode))
|
||||
.arg(pilotTone);
|
||||
}
|
||||
|
||||
QVector<RadioCircuit*> fromJson(const std::string &json)
|
||||
{
|
||||
QVector<RadioCircuit*> vec;
|
||||
QJsonParseError err;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(json), &err);
|
||||
|
||||
if(err.error != QJsonParseError::NoError)
|
||||
return {};
|
||||
|
||||
QJsonArray arr = doc.object().value(QStringLiteral("subCircuits")).toArray();
|
||||
|
||||
// Todo? Check if values are correctly filled and values are present...
|
||||
// maybe VHF is missing a frequencysetid : show ErrorMessage?
|
||||
for(const QJsonValue &val : qAsConst(arr))
|
||||
{
|
||||
RadioCircuit *rc = nullptr;
|
||||
const QJsonObject obj = val.toObject();
|
||||
FrequencyBand ft = static_cast<FrequencyBand::inner_enum>(obj[QStringLiteral("FrequencyBand")].toInt());
|
||||
switch (ft.underlying())
|
||||
{
|
||||
case FrequencyBand_def::HF:
|
||||
rc = RadioCircuitHF::fromJson(obj);
|
||||
break;
|
||||
case FrequencyBand_def::UHF:
|
||||
rc = RadioCircuitUHF::fromJson(obj);
|
||||
break;
|
||||
case FrequencyBand_def::VHF:
|
||||
rc = RadioCircuitVHF::fromJson(obj);
|
||||
break;
|
||||
case FrequencyBand_def::REL:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(rc)
|
||||
{
|
||||
rc->freqBand = ft;
|
||||
rc->name = obj[QStringLiteral("Name")].toString();
|
||||
rc->radioStationId = obj[QStringLiteral("RadioStationId")].toInt();
|
||||
vec << rc;
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
QSet<int> frequencySetDataIds(const std::string &frequencyPlanDataProperties)
|
||||
{
|
||||
QSet<int> set;
|
||||
QJsonParseError err;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(frequencyPlanDataProperties), &err);
|
||||
|
||||
if(err.error != QJsonParseError::NoError)
|
||||
return {};
|
||||
|
||||
QJsonArray arr = doc.object().value(QStringLiteral("subCircuits")).toArray();
|
||||
|
||||
// Todo? Check if values are correctly filled and values are present...
|
||||
for(const QJsonValue &val : qAsConst(arr))
|
||||
{
|
||||
const QJsonObject obj = val.toObject();
|
||||
FrequencyBand ft = static_cast<FrequencyBand::inner_enum>(obj[QStringLiteral("FrequencyBand")].toInt());
|
||||
switch (ft.underlying())
|
||||
{
|
||||
case FrequencyBand_def::VHF:
|
||||
{
|
||||
RadioCircuitVHF *rcVhf = RadioCircuitVHF::fromJson(obj);
|
||||
if(!rcVhf)
|
||||
break;
|
||||
set << rcVhf->frequencySetDataId();
|
||||
delete rcVhf;
|
||||
break;
|
||||
}
|
||||
case FrequencyBand_def::UHF:
|
||||
case FrequencyBand_def::HF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
bool isReadOnly(const std::string &frequencyPlanDataProperties)
|
||||
{
|
||||
QJsonParseError err;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(frequencyPlanDataProperties), &err);
|
||||
|
||||
if(err.error != QJsonParseError::NoError)
|
||||
return false;
|
||||
|
||||
return doc.object().value(QStringLiteral("readOnly")).toBool();
|
||||
}
|
||||
|
||||
bool isAkwMode(RcOperatingMode mode)
|
||||
{
|
||||
return mode == RcOperatingMode::AkwEncEccm || mode == RcOperatingMode::AkwEncNone;
|
||||
}
|
||||
|
||||
} // AudioVideoManagement
|
||||
@@ -0,0 +1,100 @@
|
||||
#pragma once
|
||||
#include <QJsonDocument>
|
||||
#include <AudioVideoManagement/avm_enums.hpp>
|
||||
#include <CombatNetRadio/svccnrhelper_export.h>
|
||||
#include <CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
|
||||
namespace AudioVideoManagement {
|
||||
|
||||
struct SVCCNRHELPER_EXPORT RadioCircuit
|
||||
{
|
||||
RadioCircuit() = default;
|
||||
virtual ~RadioCircuit() = default;
|
||||
|
||||
QString name;
|
||||
FrequencyBand freqBand {FrequencyBand_def::VHF};
|
||||
int radioStationId {0};
|
||||
|
||||
|
||||
virtual bool isValid() const = 0;
|
||||
virtual QJsonObject toJson() const = 0;
|
||||
virtual QString toString() const = 0;
|
||||
virtual int frequencySetDataId() const = 0;
|
||||
};
|
||||
|
||||
struct SVCCNRHELPER_EXPORT RadioCircuitHF : public RadioCircuit
|
||||
{
|
||||
ModulationType modulationType {ModulationType::AM};
|
||||
ChannelSpacingHF channelSpacing {ChannelSpacingHF::CS_100_Hz};
|
||||
int frequency {0}; // Valid: 20.000-30.0000 [Hz]
|
||||
int squelch {0}; // Valid: 0..9
|
||||
|
||||
static const int FREQ_MIN = 2000000;
|
||||
static const int FREQ_MAX = 29975000;
|
||||
static const int SQUELCH_MIN = 1;
|
||||
static const int SQUELCH_MAX = 9;
|
||||
|
||||
RadioCircuitHF()
|
||||
: RadioCircuit()
|
||||
{}
|
||||
bool isValid() const;
|
||||
QJsonObject toJson() const;
|
||||
static RadioCircuitHF* fromJson(const QJsonObject &obj);
|
||||
QString toString() const;
|
||||
int frequencySetDataId() const { return 0; }
|
||||
};
|
||||
|
||||
struct SVCCNRHELPER_EXPORT RadioCircuitUHF: public RadioCircuit
|
||||
{
|
||||
ModulationType modulationType {ModulationType::AM};
|
||||
ChannelSpacing channelSpacing {ChannelSpacing::CS_25_00_kHz};
|
||||
int frequency {0}; // Valid: 225.000.000 - 399.975.000 [Hz]
|
||||
int squelchDB {0}; // Valid: 0 (off), 6-20 [dB]
|
||||
bool clipper {false};
|
||||
bool agc {false};
|
||||
|
||||
static const int FREQ_MIN = 225000000;
|
||||
static const int FREQ_MAX = 399975000;
|
||||
static const int SQUELCH_MIN = 6;
|
||||
static const int SQUELCH_MAX = 20;
|
||||
|
||||
RadioCircuitUHF()
|
||||
: RadioCircuit()
|
||||
{}
|
||||
|
||||
bool isValid() const;
|
||||
QJsonObject toJson() const;
|
||||
static RadioCircuitUHF* fromJson(const QJsonObject &obj);
|
||||
QString toString() const;
|
||||
int frequencySetDataId() const { return 0; }
|
||||
};
|
||||
|
||||
struct SVCCNRHELPER_EXPORT RadioCircuitVHF: public RadioCircuit
|
||||
{
|
||||
RcOperatingMode operatingMode {RcOperatingMode_def::FixedFreqEncNone};
|
||||
int freqSetDataId {0};
|
||||
bool pilotTone {false};
|
||||
|
||||
RadioCircuitVHF(RcOperatingMode _operatingMode, int _frequencySetDataId, bool _pilotTone)
|
||||
: RadioCircuit()
|
||||
, operatingMode(_operatingMode)
|
||||
, freqSetDataId(_frequencySetDataId)
|
||||
, pilotTone(_pilotTone)
|
||||
{}
|
||||
|
||||
RadioCircuitVHF() = default;
|
||||
int frequencySetDataId() const { return freqSetDataId; }
|
||||
bool isValid() const {return freqSetDataId > 0; }
|
||||
QJsonObject toJson() const;
|
||||
static RadioCircuitVHF* fromJson(const QJsonObject &obj);
|
||||
QString toString() const;
|
||||
|
||||
};
|
||||
|
||||
bool SVCCNRHELPER_EXPORT isReadOnly(const std::string& json);
|
||||
QVector<RadioCircuit*> SVCCNRHELPER_EXPORT fromJson(const std::string& json);
|
||||
QSet<int> SVCCNRHELPER_EXPORT frequencySetDataIds(const std::string &frequencyPlanDataProperties);
|
||||
QJsonObject SVCCNRHELPER_EXPORT frequencyPlanningJson(QJsonObject obj, const QString &name, FrequencyBand freqBand, int radioStationId);
|
||||
bool SVCCNRHELPER_EXPORT isAkwMode(RcOperatingMode mode);
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Reference in new issue
Block a user