mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-05-02 12:13:59 -04:00
FT8 Demodulator: added option to send reports to PSK reporter. Fixes #2561
This commit is contained in:
parent
c334ffeeec
commit
89a15d4d6a
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 137 KiB |
Binary file not shown.
@ -9,6 +9,7 @@ set(demodft8_SOURCES
|
||||
ft8plugin.cpp
|
||||
ft8buffer.cpp
|
||||
ft8demodworker.cpp
|
||||
pskreporterworker.cpp
|
||||
)
|
||||
|
||||
set(demodft8_HEADERS
|
||||
@ -19,7 +20,8 @@ set(demodft8_HEADERS
|
||||
ft8demodwebapiadapter.h
|
||||
ft8plugin.h
|
||||
ft8buffer.h
|
||||
ft8demodworker.h;
|
||||
ft8demodworker.h
|
||||
pskreporterworker.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
||||
@ -329,6 +329,18 @@ void FT8Demod::applySettings(const FT8DemodSettings& settings, bool force)
|
||||
if ((m_settings.m_verifyOSD != settings.m_verifyOSD) || force) {
|
||||
reverseAPIKeys.append("verifyOSD");
|
||||
}
|
||||
if ((m_settings.m_enablePSKReporter != settings.m_enablePSKReporter) || force) {
|
||||
reverseAPIKeys.append("enablePSKReporter");
|
||||
}
|
||||
if ((m_settings.m_pskReporterCallsign != settings.m_pskReporterCallsign) || force) {
|
||||
reverseAPIKeys.append("pskReporterCallsign");
|
||||
}
|
||||
if ((m_settings.m_pskReporterLocator != settings.m_pskReporterLocator) || force) {
|
||||
reverseAPIKeys.append("pskReporterLocator");
|
||||
}
|
||||
if ((m_settings.m_pskReporterSoftware != settings.m_pskReporterSoftware) || force) {
|
||||
reverseAPIKeys.append("pskReporterSoftware");
|
||||
}
|
||||
|
||||
if (m_settings.m_streamIndex != settings.m_streamIndex)
|
||||
{
|
||||
@ -525,6 +537,18 @@ void FT8Demod::webapiUpdateChannelSettings(
|
||||
if (channelSettingsKeys.contains("verifyOSD")) {
|
||||
settings.m_verifyOSD = response.getFt8DemodSettings()->getVerifyOsd() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("enablePSKReporter")) {
|
||||
settings.m_enablePSKReporter = response.getFt8DemodSettings()->getEnablePskReporter() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("pskReporterCallsign")) {
|
||||
settings.m_pskReporterCallsign = *response.getFt8DemodSettings()->getPskReporterCallsign();
|
||||
}
|
||||
if (channelSettingsKeys.contains("pskReporterLocator")) {
|
||||
settings.m_pskReporterLocator = *response.getFt8DemodSettings()->getPskReporterLocator();
|
||||
}
|
||||
if (channelSettingsKeys.contains("pskReporterSoftware")) {
|
||||
settings.m_pskReporterSoftware = *response.getFt8DemodSettings()->getPskReporterSoftware();
|
||||
}
|
||||
if (channelSettingsKeys.contains("rgbColor")) {
|
||||
settings.m_rgbColor = response.getFt8DemodSettings()->getRgbColor();
|
||||
}
|
||||
@ -589,6 +613,10 @@ void FT8Demod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& resp
|
||||
response.getFt8DemodSettings()->setOsdDepth(settings.m_osdDepth);
|
||||
response.getFt8DemodSettings()->setOsdLdpcThreshold(settings.m_osdLDPCThreshold);
|
||||
response.getFt8DemodSettings()->setUseOsd(settings.m_verifyOSD ? 1 : 0);
|
||||
response.getFt8DemodSettings()->setEnablePskReporter(settings.m_enablePSKReporter ? 1 : 0);
|
||||
response.getFt8DemodSettings()->setPskReporterCallsign(new QString(settings.m_pskReporterCallsign));
|
||||
response.getFt8DemodSettings()->setPskReporterLocator(new QString(settings.m_pskReporterLocator));
|
||||
response.getFt8DemodSettings()->setPskReporterSoftware(new QString(settings.m_pskReporterSoftware));
|
||||
response.getFt8DemodSettings()->setRgbColor(settings.m_rgbColor);
|
||||
|
||||
if (response.getFt8DemodSettings()->getTitle()) {
|
||||
@ -784,6 +812,18 @@ void FT8Demod::webapiFormatChannelSettings(
|
||||
if (channelSettingsKeys.contains("verifyOSD") || force) {
|
||||
swgFT8DemodSettings->setVerifyOsd(settings.m_verifyOSD ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("enablePSKReporter") || force) {
|
||||
swgFT8DemodSettings->setEnablePskReporter(settings.m_enablePSKReporter ? 1 : 0);
|
||||
}
|
||||
if (channelSettingsKeys.contains("pskReporterCallsign") || force) {
|
||||
swgFT8DemodSettings->setPskReporterCallsign(new QString(settings.m_pskReporterCallsign));
|
||||
}
|
||||
if (channelSettingsKeys.contains("pskReporterLocator") || force) {
|
||||
swgFT8DemodSettings->setPskReporterLocator(new QString(settings.m_pskReporterLocator));
|
||||
}
|
||||
if (channelSettingsKeys.contains("pskReporterSoftware") || force) {
|
||||
swgFT8DemodSettings->setPskReporterSoftware(new QString(settings.m_pskReporterSoftware));
|
||||
}
|
||||
if (channelSettingsKeys.contains("rgbColor") || force) {
|
||||
swgFT8DemodSettings->setRgbColor(settings.m_rgbColor);
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "maincore.h"
|
||||
|
||||
#include "ft8demodworker.h"
|
||||
#include "pskreporterworker.h"
|
||||
#include "ft8demodbaseband.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(FT8DemodBaseband::MsgConfigureFT8DemodBaseband, Message)
|
||||
@ -48,12 +49,7 @@ FT8DemodBaseband::FT8DemodBaseband() :
|
||||
m_ft8DemodWorker,
|
||||
&QObject::deleteLater
|
||||
);
|
||||
QObject::connect(
|
||||
m_workerThread,
|
||||
&QThread::finished,
|
||||
m_ft8DemodWorker,
|
||||
&QThread::deleteLater
|
||||
);
|
||||
|
||||
QObject::connect(
|
||||
this,
|
||||
&FT8DemodBaseband::bufferReady,
|
||||
@ -64,6 +60,20 @@ FT8DemodBaseband::FT8DemodBaseband() :
|
||||
|
||||
m_workerThread->start();
|
||||
|
||||
m_pskReporterThread = new QThread();
|
||||
m_pskReporterWorker = new PskReporterWorker();
|
||||
m_ft8DemodWorker->setPSKReportingMessageQueue(m_pskReporterWorker->getInputMessageQueue());
|
||||
m_pskReporterWorker->moveToThread(m_pskReporterThread);
|
||||
|
||||
QObject::connect(
|
||||
m_pskReporterThread,
|
||||
&QThread::finished,
|
||||
m_pskReporterWorker,
|
||||
&QObject::deleteLater
|
||||
);
|
||||
|
||||
m_pskReporterThread->start();
|
||||
|
||||
QObject::connect(
|
||||
&m_sampleFifo,
|
||||
&SampleSinkFifo::dataReady,
|
||||
@ -84,6 +94,8 @@ FT8DemodBaseband::~FT8DemodBaseband()
|
||||
m_workerThread->exit();
|
||||
m_workerThread->wait();
|
||||
delete[] m_ft8WorkerBuffer;
|
||||
m_pskReporterThread->exit();
|
||||
m_pskReporterThread->wait();
|
||||
}
|
||||
|
||||
void FT8DemodBaseband::reset()
|
||||
@ -96,7 +108,7 @@ void FT8DemodBaseband::reset()
|
||||
void FT8DemodBaseband::setMessageQueueToGUI(MessageQueue *messageQueue)
|
||||
{
|
||||
m_messageQueueToGUI = messageQueue;
|
||||
m_ft8DemodWorker->setReportingMessageQueue(m_messageQueueToGUI);
|
||||
m_ft8DemodWorker->setGUIReportingMessageQueue(m_messageQueueToGUI);
|
||||
}
|
||||
|
||||
void FT8DemodBaseband::setChannel(ChannelAPI *channel)
|
||||
@ -237,6 +249,22 @@ void FT8DemodBaseband::applySettings(const FT8DemodSettings& settings, bool forc
|
||||
m_ft8DemodWorker->setLogMessages(settings.m_logMessages);
|
||||
}
|
||||
|
||||
if ((settings.m_enablePSKReporter != m_settings.m_enablePSKReporter) || force) {
|
||||
m_ft8DemodWorker->setEnablePskReporter(settings.m_enablePSKReporter);
|
||||
}
|
||||
|
||||
if ((settings.m_pskReporterCallsign != m_settings.m_pskReporterCallsign) || force) {
|
||||
m_pskReporterWorker->setMyCallsign(settings.m_pskReporterCallsign);
|
||||
}
|
||||
|
||||
if ((settings.m_pskReporterLocator != m_settings.m_pskReporterLocator) || force) {
|
||||
m_pskReporterWorker->setMyLocator(settings.m_pskReporterLocator);
|
||||
}
|
||||
|
||||
if ((settings.m_pskReporterSoftware != m_settings.m_pskReporterSoftware) || force) {
|
||||
m_pskReporterWorker->setDecoderInfo(settings.m_pskReporterSoftware);
|
||||
}
|
||||
|
||||
if ((settings.m_nbDecoderThreads != m_settings.m_nbDecoderThreads) || force) {
|
||||
m_ft8DemodWorker->setNbDecoderThreads(settings.m_nbDecoderThreads);
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ class ChannelAPI;
|
||||
class SpectrumVis;
|
||||
class QThread;
|
||||
class FT8DemodWorker;
|
||||
class PskReporterWorker;
|
||||
|
||||
class FT8DemodBaseband : public QObject
|
||||
{
|
||||
@ -102,6 +103,8 @@ private:
|
||||
int m_tickCount;
|
||||
QThread *m_workerThread;
|
||||
FT8DemodWorker *m_ft8DemodWorker;
|
||||
QThread *m_pskReporterThread;
|
||||
PskReporterWorker *m_pskReporterWorker;
|
||||
int16_t *m_ft8WorkerBuffer;
|
||||
qint64 m_deviceCenterFrequency;
|
||||
QRecursiveMutex m_mutex;
|
||||
|
||||
@ -528,6 +528,30 @@ void FT8DemodGUI::on_settings_clicked()
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (settingsKeys.contains("enablePSKReporter"))
|
||||
{
|
||||
m_settings.m_enablePSKReporter = settings.m_enablePSKReporter;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (settingsKeys.contains("pskReporterCallsign"))
|
||||
{
|
||||
m_settings.m_pskReporterCallsign = settings.m_pskReporterCallsign;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (settingsKeys.contains("pskReporterLocator"))
|
||||
{
|
||||
m_settings.m_pskReporterLocator = settings.m_pskReporterLocator;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (settingsKeys.contains("pskReporterSoftware"))
|
||||
{
|
||||
m_settings.m_pskReporterSoftware = settings.m_pskReporterSoftware;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (settingsKeys.contains("bandPresets"))
|
||||
{
|
||||
m_settings.m_bandPresets = settings.m_bandPresets;
|
||||
|
||||
@ -19,9 +19,12 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QColor>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "util/simpleserializer.h"
|
||||
#include "settings/serializable.h"
|
||||
#include "maincore.h"
|
||||
#include "util/maidenhead.h"
|
||||
#include "ft8demodsettings.h"
|
||||
|
||||
const int FT8DemodSettings::m_ft8SampleRate = 12000;
|
||||
@ -66,6 +69,10 @@ void FT8DemodSettings::resetToDefaults()
|
||||
m_workspaceIndex = 0;
|
||||
m_hidden = false;
|
||||
m_filterIndex = 0;
|
||||
m_enablePSKReporter = false;
|
||||
m_pskReporterCallsign = getDefaultReporterCallsign();
|
||||
m_pskReporterLocator = getDefaultReporterLocator();
|
||||
m_pskReporterSoftware = "SDRangel FT8 Demod";
|
||||
resetBandPresets();
|
||||
}
|
||||
|
||||
@ -133,6 +140,10 @@ QByteArray FT8DemodSettings::serialize() const
|
||||
s.writeBlob(26, m_geometryBytes);
|
||||
s.writeBool(27, m_hidden);
|
||||
s.writeU32(29, m_filterIndex);
|
||||
s.writeBool(30, m_enablePSKReporter);
|
||||
s.writeString(31, m_pskReporterCallsign);
|
||||
s.writeString(32, m_pskReporterLocator);
|
||||
s.writeString(33, m_pskReporterSoftware);
|
||||
|
||||
for (unsigned int i = 0; i < 10; i++)
|
||||
{
|
||||
@ -214,6 +225,10 @@ bool FT8DemodSettings::deserialize(const QByteArray& data)
|
||||
d.readBool(27, &m_hidden, false);
|
||||
d.readU32(29, &utmp, 0);
|
||||
m_filterIndex = utmp < 10 ? utmp : 0;
|
||||
d.readBool(30, &m_enablePSKReporter, false);
|
||||
d.readString(31, &m_pskReporterCallsign, getDefaultReporterCallsign());
|
||||
d.readString(32, &m_pskReporterLocator, getDefaultReporterLocator());
|
||||
d.readString(33, &m_pskReporterSoftware, getDefaultReporterSoftware());
|
||||
|
||||
for (unsigned int i = 0; (i < 10); i++)
|
||||
{
|
||||
@ -252,3 +267,20 @@ QDataStream& operator>>(QDataStream& in, FT8DemodBandPreset& bandPreset)
|
||||
in >> bandPreset.m_channelOffset;
|
||||
return in;
|
||||
}
|
||||
|
||||
QString FT8DemodSettings::getDefaultReporterCallsign() const
|
||||
{
|
||||
return MainCore::instance()->getSettings().getStationName();
|
||||
}
|
||||
|
||||
QString FT8DemodSettings::getDefaultReporterLocator() const
|
||||
{
|
||||
float lat = MainCore::instance()->getSettings().getLatitude();
|
||||
float lon = MainCore::instance()->getSettings().getLongitude();
|
||||
return Maidenhead::toMaidenhead(lat, lon);
|
||||
}
|
||||
|
||||
QString FT8DemodSettings::getDefaultReporterSoftware() const
|
||||
{
|
||||
return QCoreApplication::applicationName() + " " + QCoreApplication::applicationVersion();
|
||||
}
|
||||
|
||||
@ -97,6 +97,10 @@ public:
|
||||
std::vector<FT8DemodFilterSettings> m_filterBank;
|
||||
unsigned int m_filterIndex;
|
||||
QList<FT8DemodBandPreset> m_bandPresets;
|
||||
bool m_enablePSKReporter;
|
||||
QString m_pskReporterCallsign;
|
||||
QString m_pskReporterLocator;
|
||||
QString m_pskReporterSoftware;
|
||||
|
||||
Serializable *m_channelMarker;
|
||||
Serializable *m_spectrumGUI;
|
||||
@ -110,6 +114,9 @@ public:
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
void resetBandPresets();
|
||||
QString getDefaultReporterCallsign() const;
|
||||
QString getDefaultReporterLocator() const;
|
||||
QString getDefaultReporterSoftware() const;
|
||||
|
||||
static const int m_ft8SampleRate;
|
||||
static const int m_minPowerThresholdDB;
|
||||
|
||||
@ -35,6 +35,10 @@ FT8DemodSettingsDialog::FT8DemodSettingsDialog(FT8DemodSettings& settings, QStri
|
||||
ui->osdLDPCThreshold->setValue(m_settings.m_osdLDPCThreshold);
|
||||
ui->osdLDPCThresholdText->setText(tr("%1").arg(m_settings.m_osdLDPCThreshold));
|
||||
ui->verifyOSD->setChecked(m_settings.m_verifyOSD);
|
||||
ui->enablePSKReporter->setChecked(m_settings.m_enablePSKReporter);
|
||||
ui->reportingStation->setText(m_settings.m_pskReporterCallsign);
|
||||
ui->reportingLocator->setText(m_settings.m_pskReporterLocator);
|
||||
ui->reportingSoftware->setText(m_settings.m_pskReporterSoftware);
|
||||
resizeBandsTable();
|
||||
populateBandsTable();
|
||||
connect(ui->bands, &QTableWidget::cellChanged, this, &FT8DemodSettingsDialog::textCellChanged);
|
||||
@ -162,6 +166,65 @@ void FT8DemodSettingsDialog::on_verifyOSD_stateChanged(int state)
|
||||
}
|
||||
}
|
||||
|
||||
void FT8DemodSettingsDialog::on_enablePSKReporter_toggled(bool checked)
|
||||
{
|
||||
m_settings.m_enablePSKReporter = checked;
|
||||
|
||||
if (!m_settingsKeys.contains("enablePSKReporter")) {
|
||||
m_settingsKeys.append("enablePSKReporter");
|
||||
}
|
||||
}
|
||||
|
||||
void FT8DemodSettingsDialog::on_pskReporterCallsign_editingFinished()
|
||||
{
|
||||
m_settings.m_pskReporterCallsign = ui->reportingStation->text();
|
||||
|
||||
if (!m_settingsKeys.contains("pskReporterCallsign")) {
|
||||
m_settingsKeys.append("pskReporterCallsign");
|
||||
}
|
||||
}
|
||||
|
||||
void FT8DemodSettingsDialog::on_pskReporterLocator_editingFinished()
|
||||
{
|
||||
m_settings.m_pskReporterLocator = ui->reportingLocator->text();
|
||||
|
||||
if (!m_settingsKeys.contains("pskReporterLocator")) {
|
||||
m_settingsKeys.append("pskReporterLocator");
|
||||
}
|
||||
}
|
||||
|
||||
void FT8DemodSettingsDialog::on_pskReporterSoftware_editingFinished()
|
||||
{
|
||||
m_settings.m_pskReporterSoftware = ui->reportingSoftware->text();
|
||||
|
||||
if (!m_settingsKeys.contains("pskReporterSoftware")) {
|
||||
m_settingsKeys.append("pskReporterSoftware");
|
||||
}
|
||||
}
|
||||
|
||||
void FT8DemodSettingsDialog::on_reportingDefaults_clicked()
|
||||
{
|
||||
ui->reportingStation->setText(m_settings.getDefaultReporterCallsign());
|
||||
ui->reportingLocator->setText(m_settings.getDefaultReporterLocator());
|
||||
ui->reportingSoftware->setText(m_settings.getDefaultReporterSoftware());
|
||||
|
||||
m_settings.m_pskReporterCallsign = ui->reportingStation->text();
|
||||
m_settings.m_pskReporterLocator = ui->reportingLocator->text();
|
||||
m_settings.m_pskReporterSoftware = ui->reportingSoftware->text();
|
||||
|
||||
if (!m_settingsKeys.contains("pskReporterCallsign")) {
|
||||
m_settingsKeys.append("pskReporterCallsign");
|
||||
}
|
||||
|
||||
if (!m_settingsKeys.contains("pskReporterLocator")) {
|
||||
m_settingsKeys.append("pskReporterLocator");
|
||||
}
|
||||
|
||||
if (!m_settingsKeys.contains("pskReporterSoftware")) {
|
||||
m_settingsKeys.append("pskReporterSoftware");
|
||||
}
|
||||
}
|
||||
|
||||
void FT8DemodSettingsDialog::on_addBand_clicked()
|
||||
{
|
||||
int currentRow = ui->bands->currentRow();
|
||||
|
||||
@ -62,6 +62,11 @@ private slots:
|
||||
void on_osdDepth_valueChanged(int value);
|
||||
void on_osdLDPCThreshold_valueChanged(int value);
|
||||
void on_verifyOSD_stateChanged(int state);
|
||||
void on_enablePSKReporter_toggled(bool checked);
|
||||
void on_pskReporterCallsign_editingFinished();
|
||||
void on_pskReporterLocator_editingFinished();
|
||||
void on_pskReporterSoftware_editingFinished();
|
||||
void on_reportingDefaults_clicked();
|
||||
void on_addBand_clicked();
|
||||
void on_deleteBand_clicked();
|
||||
void on_moveBandUp_clicked();
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>349</width>
|
||||
<height>333</height>
|
||||
<width>343</width>
|
||||
<height>423</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
@ -229,6 +229,104 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="reporterGroup">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>PSK reporter</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enablePSKReporter">
|
||||
<property name="toolTip">
|
||||
<string>Enable sending reception reports to PSK reporter</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="reportingStationLabel">
|
||||
<property name="text">
|
||||
<string>Sta</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="reportingStation">
|
||||
<property name="toolTip">
|
||||
<string>Reporting (your) station</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="reportingLocatorLabel">
|
||||
<property name="text">
|
||||
<string>Loc</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="reportingLocator">
|
||||
<property name="toolTip">
|
||||
<string>Reporting (your) locator</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="reportingSoftwareLabel">
|
||||
<property name="text">
|
||||
<string>Soft</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="reportingSoftware">
|
||||
<property name="toolTip">
|
||||
<string>Reporting (your) software</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="reportingDefaults">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Reset reporter values to defaults</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="bandsGroup">
|
||||
<property name="title">
|
||||
|
||||
@ -141,6 +141,8 @@ QString FT8DemodWorker::FT8Callback::get_name()
|
||||
|
||||
FT8DemodWorker::FT8DemodWorker() :
|
||||
m_recordSamples(false),
|
||||
m_logMessages(false),
|
||||
m_enablePskReporter(false),
|
||||
m_nbDecoderThreads(6),
|
||||
m_decoderTimeBudget(0.5),
|
||||
m_useOSD(false),
|
||||
@ -151,7 +153,8 @@ FT8DemodWorker::FT8DemodWorker() :
|
||||
m_highFreq(3000),
|
||||
m_invalidSequence(true),
|
||||
m_baseFrequency(0),
|
||||
m_reportingMessageQueue(nullptr),
|
||||
m_guiReportingMessageQueue(nullptr),
|
||||
m_pskReportingMessageQueue(nullptr),
|
||||
m_channel(nullptr)
|
||||
{
|
||||
QString relPath = "ft8/save";
|
||||
@ -237,8 +240,12 @@ void FT8DemodWorker::processBuffer(int16_t *buffer, QDateTime periodTS)
|
||||
qDebug("FT8DemodWorker::processBuffer: done: at %6.3f %d messages",
|
||||
m_baseFrequency / 1000000.0, (int)ft8Callback.getReportMessage()->getFT8Messages().size());
|
||||
|
||||
if (m_reportingMessageQueue) {
|
||||
m_reportingMessageQueue->push(new MsgReportFT8Messages(*ft8Callback.getReportMessage()));
|
||||
if (m_guiReportingMessageQueue) {
|
||||
m_guiReportingMessageQueue->push(new MsgReportFT8Messages(*ft8Callback.getReportMessage()));
|
||||
}
|
||||
|
||||
if (m_enablePskReporter && m_pskReportingMessageQueue) {
|
||||
m_pskReportingMessageQueue->push(new MsgReportFT8Messages(*ft8Callback.getReportMessage()));
|
||||
}
|
||||
|
||||
QList<ObjectPipe*> mapPipes;
|
||||
|
||||
@ -41,6 +41,7 @@ public:
|
||||
void processBuffer(int16_t *buffer, QDateTime periodTS);
|
||||
void setRecordSamples(bool recordSamples) { m_recordSamples = recordSamples; }
|
||||
void setLogMessages(bool logMessages) { m_logMessages = logMessages; }
|
||||
void setEnablePskReporter(bool enablePskReporter) { m_enablePskReporter = enablePskReporter; }
|
||||
void setNbDecoderThreads(int nbDecoderThreads) { m_nbDecoderThreads = nbDecoderThreads; }
|
||||
void setDecoderTimeBudget(float decoderTimeBudget) { m_decoderTimeBudget = decoderTimeBudget; }
|
||||
void setUseOSD(bool useOSD) { m_useOSD = useOSD; }
|
||||
@ -49,7 +50,8 @@ public:
|
||||
void setVerifyOSD(bool verifyOSD) { m_verifyOSD = verifyOSD; }
|
||||
void setLowFrequency(int lowFreq) { m_lowFreq = lowFreq; }
|
||||
void setHighFrequency(int highFreq) { m_highFreq = highFreq; }
|
||||
void setReportingMessageQueue(MessageQueue *messageQueue) { m_reportingMessageQueue = messageQueue; }
|
||||
void setGUIReportingMessageQueue(MessageQueue *messageQueue) { m_guiReportingMessageQueue = messageQueue; }
|
||||
void setPSKReportingMessageQueue(MessageQueue *messageQueue) { m_pskReportingMessageQueue = messageQueue; }
|
||||
void invalidateSequence() { m_invalidSequence = true; }
|
||||
void setBaseFrequency(qint64 baseFrequency) { m_baseFrequency = baseFrequency; }
|
||||
void setChannel(ChannelAPI *channel) { m_channel = channel; }
|
||||
@ -92,6 +94,7 @@ private:
|
||||
QString m_logsPath;
|
||||
bool m_recordSamples;
|
||||
bool m_logMessages;
|
||||
bool m_enablePskReporter;
|
||||
int m_nbDecoderThreads;
|
||||
float m_decoderTimeBudget;
|
||||
bool m_useOSD;
|
||||
@ -104,7 +107,8 @@ private:
|
||||
qint64 m_baseFrequency;
|
||||
FT8::FT8Decoder m_ft8Decoder;
|
||||
FT8::Packing m_packing;
|
||||
MessageQueue *m_reportingMessageQueue;
|
||||
MessageQueue *m_guiReportingMessageQueue;
|
||||
MessageQueue *m_pskReportingMessageQueue;
|
||||
ChannelAPI *m_channel;
|
||||
QSet<QString> m_validCallsigns;
|
||||
};
|
||||
|
||||
286
plugins/channelrx/demodft8/pskreporterworker.cpp
Normal file
286
plugins/channelrx/demodft8/pskreporterworker.cpp
Normal file
@ -0,0 +1,286 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QHostInfo>
|
||||
#include <QRandomGenerator>
|
||||
#include "util/ft8message.h"
|
||||
#include "pskreporterworker.h"
|
||||
|
||||
const char PskReporterWorker::hostname[] = "report.pskreporter.info";
|
||||
const char PskReporterWorker::service[] = "4739";
|
||||
const char PskReporterWorker::test_service[] = "14739";
|
||||
const char PskReporterWorker::txMode[] = "FT8";
|
||||
const unsigned char PskReporterWorker::rxDescriptor[] = {
|
||||
0x00, 0x03, // Template Set ID
|
||||
0x00, 0x24, // Length
|
||||
0x99, 0x92, // Link ID
|
||||
0x00, 0x03, // Field Count
|
||||
0x00, 0x00, // Scope Field Count
|
||||
0x80, 0x02, // Receiver Callsign ID
|
||||
0xFF, 0xFF, // Variable field length
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x04, // Receiver Locator ID
|
||||
0xFF, 0xFF, // Variable field length
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x08, // Receiver Decoder Software ID
|
||||
0xFF, 0xFF, // Variable field length
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x00, 0x00 // Padding
|
||||
}; // "PSKREPORTER_RX"
|
||||
const unsigned char PskReporterWorker::txDescriptor[] = {
|
||||
0x00, 0x02, // Template Set ID
|
||||
0x00, 0x3C, // Length
|
||||
0x99, 0x93, // Link ID
|
||||
0x00, 0x07, // Field Count
|
||||
0x80, 0x01, // Sender Callsign ID
|
||||
0xFF, 0xFF, // Variable field length
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x05, // Sender Frequency ID
|
||||
0x00, 0x04, // Fixed length (4)
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x06, // Sender SNR ID
|
||||
0x00, 0x01, // Fixed length (1)
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x0A, // Sender Mode ID
|
||||
0xFF, 0xFF, // Variable field length
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x03, // Sender Locator ID
|
||||
0xFF, 0xFF, // Variable field length
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x80, 0x0B, // Information Source ID
|
||||
0x00, 0x01, // Fixed length (1)
|
||||
0x00, 0x00, 0x76, 0x8F, // Enterprise number
|
||||
0x00, 0x96, // DateTimeSeconds ID
|
||||
0x00, 0x04 // Field Length
|
||||
}; // "PSKREPORTER_TX"
|
||||
|
||||
PskReporterWorker::PskReporterWorker() :
|
||||
m_udpSocket(new QUdpSocket(this))
|
||||
{
|
||||
connect(&m_reportQueue, &MessageQueue::messageEnqueued,
|
||||
this, &PskReporterWorker::handleInputMessages);
|
||||
m_lastReportTime = QDateTime::currentDateTimeUtc();
|
||||
m_identifier = QRandomGenerator::global()->generate(); // random number for the identifier for this session
|
||||
}
|
||||
|
||||
void PskReporterWorker::processFT8Messages(const QList<FT8Message>& ft8Messages, qint64 baseFrequency)
|
||||
{
|
||||
m_ft8MessageQueue.append(ft8Messages); // Queue messages for processing
|
||||
qDebug("PskReporterWorker::processFT8Messages: queued %d messages", ft8Messages.size());
|
||||
|
||||
// Avoid reporting too frequently - 5 minutes interval is the recommended value
|
||||
if (m_lastReportTime.secsTo(QDateTime::currentDateTimeUtc()) < 5*60) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_lastReportTime = QDateTime::currentDateTimeUtc();
|
||||
uint32_t txPtr = 4;
|
||||
std::fill(std::begin(txInfoData), std::end(txInfoData), 0);
|
||||
|
||||
while (!m_ft8MessageQueue.isEmpty())
|
||||
{
|
||||
FT8Message msg = m_ft8MessageQueue.dequeue();
|
||||
|
||||
if (m_reportedCalls.contains(msg.call2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_reportedCalls.insert(msg.call2);
|
||||
|
||||
if (txPtr > 1200)
|
||||
{
|
||||
sendMessageToPskReporter(txPtr);
|
||||
txPtr = 4;
|
||||
std::fill(std::begin(txInfoData), std::end(txInfoData), 0);
|
||||
}
|
||||
|
||||
// Station callsign
|
||||
*(uint8_t *)&txInfoData[txPtr] = (uint8_t) msg.call2.size();
|
||||
txPtr += 1;
|
||||
memcpy(&txInfoData[txPtr], msg.call2.toStdString().c_str(), msg.call2.size());
|
||||
txPtr += msg.call2.size();
|
||||
|
||||
// Station frequency
|
||||
uint32_t freq = static_cast<uint32_t>(baseFrequency + msg.df);
|
||||
freq = SwapEndian32(freq);
|
||||
memcpy(&txInfoData[txPtr], &freq, 4);
|
||||
txPtr +=4;
|
||||
|
||||
// Station SNR
|
||||
int8_t snr = static_cast<int8_t>(msg.snr);
|
||||
memcpy(&txInfoData[txPtr], &snr, 1);
|
||||
txPtr +=1;
|
||||
|
||||
// Station Mode
|
||||
*(uint8_t *)&txInfoData[txPtr] = (uint8_t)strlen(txMode);
|
||||
txPtr += 1;
|
||||
strncpy((char *)&txInfoData[txPtr], txMode, strlen(txMode));
|
||||
txPtr += strlen(txMode);
|
||||
|
||||
// Station locator
|
||||
*(uint8_t *)&txInfoData[txPtr] = (uint8_t) msg.loc.size();
|
||||
txPtr += 1;
|
||||
memcpy(&txInfoData[txPtr], msg.loc.toStdString().c_str(), msg.loc.size());
|
||||
txPtr += msg.loc.size();
|
||||
|
||||
/* Station Info -- Static length (1) */
|
||||
*(uint8_t *)&txInfoData[txPtr] = (uint8_t)1;
|
||||
txPtr += 1;
|
||||
|
||||
// Message timestamp -- Static length (4)
|
||||
uint32_t timestamp = static_cast<uint32_t>(msg.ts.toSecsSinceEpoch());
|
||||
timestamp = SwapEndian32(timestamp);
|
||||
memcpy(&txInfoData[txPtr], ×tamp, 4);
|
||||
txPtr +=4;
|
||||
}
|
||||
|
||||
sendMessageToPskReporter(txPtr);
|
||||
m_reportedCalls.clear();
|
||||
m_reportSequenceNumber++;
|
||||
}
|
||||
|
||||
void PskReporterWorker::sendMessageToPskReporter(uint32_t txPtr)
|
||||
{
|
||||
// Implement PSK Reporter message sending here
|
||||
if (txInfoData[4] == 0) {
|
||||
return; // No data to send
|
||||
}
|
||||
|
||||
// Prepare and send the UDP message to PSK Reporter server
|
||||
const uint32_t headerSize = 16;
|
||||
char headerData[headerSize] = {0};
|
||||
uint32_t hPtr = 0;
|
||||
|
||||
*(uint16_t *)&headerData[hPtr] = SwapEndian16(0x000A);
|
||||
hPtr += 2;
|
||||
hPtr += 2; // Skip the size block, adjust later
|
||||
|
||||
uint32_t timestamp = QDateTime::currentDateTimeUtc().toSecsSinceEpoch();
|
||||
*(uint32_t *)&headerData[hPtr] = SwapEndian32(timestamp);
|
||||
hPtr += 4;
|
||||
|
||||
*(uint32_t *)&headerData[hPtr] = SwapEndian32(m_reportSequenceNumber);
|
||||
hPtr += 4;
|
||||
|
||||
*(uint32_t *)&headerData[hPtr] = SwapEndian32(m_identifier);
|
||||
hPtr += 4;
|
||||
|
||||
char rxInfoData[256] = {0};
|
||||
uint32_t rxPtr = 0;
|
||||
|
||||
*(uint16_t *)&rxInfoData[rxPtr] = SwapEndian16(0x9992);
|
||||
rxPtr += 2;
|
||||
rxPtr += 2; // Skip the size block, adjust later
|
||||
|
||||
// Receiver callsign
|
||||
*(uint8_t *)&rxInfoData[rxPtr] = (uint8_t) m_myCallsign.size();
|
||||
rxPtr += 1;
|
||||
memcpy(&rxInfoData[rxPtr], m_myCallsign.toStdString().c_str(), m_myCallsign.size());
|
||||
rxPtr += m_myCallsign.size();
|
||||
|
||||
// Receiver locator
|
||||
*(uint8_t *)&rxInfoData[rxPtr] = (uint8_t) m_myLocator.size();
|
||||
rxPtr += 1;
|
||||
memcpy(&rxInfoData[rxPtr], m_myLocator.toStdString().c_str(), m_myLocator.size());
|
||||
rxPtr += m_myLocator.size();
|
||||
|
||||
// Receiver decoder software
|
||||
*(uint8_t *)&rxInfoData[rxPtr] = (uint8_t) m_decoderInfo.size();
|
||||
rxPtr += 1;
|
||||
memcpy(&rxInfoData[rxPtr], m_decoderInfo.toStdString().c_str(), m_decoderInfo.size());
|
||||
rxPtr += m_decoderInfo.size();
|
||||
|
||||
// Padding to 4-byte boundary
|
||||
if ((rxPtr % 4) > 0)
|
||||
rxPtr += (4 - (rxPtr % 4));
|
||||
|
||||
// Padding to 4-byte boundary
|
||||
if ((txPtr % 4) > 0)
|
||||
txPtr += (4 - (txPtr % 4));
|
||||
|
||||
*(uint16_t *)&txInfoData[0] = SwapEndian16(0x9993);
|
||||
|
||||
/* Adjust the block sizes */
|
||||
uint32_t fullBlockSize = headerSize + sizeof(rxDescriptor) + sizeof(txDescriptor) + rxPtr + txPtr;
|
||||
*(uint16_t *)&rxInfoData[2] = SwapEndian16(rxPtr);
|
||||
*(uint16_t *)&txInfoData[2] = SwapEndian16(txPtr);
|
||||
*(uint16_t *)&headerData[2] = SwapEndian16(fullBlockSize);
|
||||
|
||||
/* Assemble the block to send over UDP */
|
||||
char *fullBlockData = new char[fullBlockSize];
|
||||
uint32_t ptrBlock = 0;
|
||||
memcpy(&fullBlockData[ptrBlock], headerData, headerSize); ptrBlock += headerSize;
|
||||
memcpy(&fullBlockData[ptrBlock], rxDescriptor, sizeof(rxDescriptor)); ptrBlock += sizeof(rxDescriptor);
|
||||
memcpy(&fullBlockData[ptrBlock], txDescriptor, sizeof(txDescriptor)); ptrBlock += sizeof(txDescriptor);
|
||||
memcpy(&fullBlockData[ptrBlock], rxInfoData, rxPtr); ptrBlock += rxPtr;
|
||||
memcpy(&fullBlockData[ptrBlock], txInfoData, txPtr); ptrBlock += txPtr;
|
||||
|
||||
/* Send via UDP */
|
||||
const char* servicePort = m_isTestMode ? test_service : service;
|
||||
QHostAddress hostAddress;
|
||||
|
||||
// Resolve hostname
|
||||
QHostInfo hostInfo = QHostInfo::fromName(hostname);
|
||||
|
||||
if (!hostInfo.addresses().isEmpty()) {
|
||||
hostAddress = hostInfo.addresses().first();
|
||||
|
||||
// Send the datagram
|
||||
qint64 bytesSent = m_udpSocket->writeDatagram(fullBlockData, fullBlockSize, hostAddress, QString(servicePort).toUInt());
|
||||
|
||||
if (bytesSent == -1) {
|
||||
qWarning("PskReporterWorker::sendMessageToPskReporter: Failed to send UDP datagram: %s",
|
||||
qPrintable(m_udpSocket->errorString()));
|
||||
} else {
|
||||
qDebug("PskReporterWorker::sendMessageToPskReporter: Sent %lld bytes to %s:%s",
|
||||
bytesSent, hostname, servicePort);
|
||||
}
|
||||
} else {
|
||||
qWarning("PskReporterWorker::sendMessageToPskReporter: Failed to resolve hostname: %s", hostname);
|
||||
}
|
||||
|
||||
delete[] fullBlockData;
|
||||
}
|
||||
|
||||
bool PskReporterWorker::handleMessage(const Message& message)
|
||||
{
|
||||
if (MsgReportFT8Messages::match(message))
|
||||
{
|
||||
const MsgReportFT8Messages& ft8Msg = static_cast<const MsgReportFT8Messages&>(message);
|
||||
const QList<FT8Message>& ft8Messages = ft8Msg.getFT8Messages();
|
||||
qint64 baseFrequency = ft8Msg.getBaseFrequency();
|
||||
// Process FT8 messages for PSK Reporter here
|
||||
processFT8Messages(ft8Messages, baseFrequency);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PskReporterWorker::handleInputMessages()
|
||||
{
|
||||
Message* message = m_reportQueue.pop();
|
||||
|
||||
if (message == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!handleMessage(*message)) {
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
92
plugins/channelrx/demodft8/pskreporterworker.h
Normal file
92
plugins/channelrx/demodft8/pskreporterworker.h
Normal file
@ -0,0 +1,92 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2026 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
// it under the terms of the GNU General Public License as published by //
|
||||
// the Free Software Foundation as version 3 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||
// GNU General Public License V3 for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License //
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef INCLUDE_PSKREPORTERWORKER_H
|
||||
#define INCLUDE_PSKREPORTERWORKER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <QQueue>
|
||||
#include <QUdpSocket>
|
||||
|
||||
#include "util/ft8message.h"
|
||||
#include "util/message.h"
|
||||
#include "util/messagequeue.h"
|
||||
|
||||
|
||||
class PskReporterWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PskReporterWorker();
|
||||
~PskReporterWorker() = default;
|
||||
MessageQueue* getInputMessageQueue() { return &m_reportQueue; }
|
||||
void setMyCallsign(const QString& callsign) { m_myCallsign = callsign; }
|
||||
void setMyLocator(const QString& locator) { m_myLocator = locator; }
|
||||
void setDecoderInfo(const QString& decoderInfo) { m_decoderInfo = decoderInfo; }
|
||||
void setTestMode(bool isTestMode) { m_isTestMode = isTestMode; }
|
||||
|
||||
private:
|
||||
struct decoder_results {
|
||||
char call[13];
|
||||
char loc[7];
|
||||
int32_t freq;
|
||||
int32_t snr;
|
||||
};
|
||||
|
||||
QString m_myCallsign;
|
||||
QString m_myLocator;
|
||||
QString m_decoderInfo;
|
||||
bool m_isTestMode = false;
|
||||
MessageQueue m_reportQueue;
|
||||
QQueue<FT8Message> m_ft8MessageQueue;
|
||||
QSet<QString> m_reportedCalls;
|
||||
uint32_t m_reportSequenceNumber = 1;
|
||||
QDateTime m_lastReportTime;
|
||||
QUdpSocket* m_udpSocket;
|
||||
uint32_t m_identifier;
|
||||
|
||||
char txInfoData[1500];
|
||||
|
||||
static const char hostname[];
|
||||
static const char service[];
|
||||
static const char test_service[];
|
||||
static const char txMode[];
|
||||
static const unsigned char rxDescriptor[];
|
||||
static const unsigned char txDescriptor[];
|
||||
|
||||
void processFT8Messages(const QList<FT8Message>& ft8Messages, qint64 baseFrequency);
|
||||
void sendMessageToPskReporter(uint32_t txPtr);
|
||||
bool handleMessage(const Message& message);
|
||||
|
||||
inline uint16_t SwapEndian16(uint16_t val) {
|
||||
return (val<<8) | (val>>8);
|
||||
}
|
||||
|
||||
|
||||
inline uint32_t SwapEndian32(uint32_t val) {
|
||||
return (val<<24) | ((val<<8) & 0x00ff0000) | ((val>>8) & 0x0000ff00) | (val>>24);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDE_PSKREPORTERWORKER_H
|
||||
@ -235,7 +235,27 @@ Sets the minimum number of correct LDPC bits (out of 83) necessary to trigger OS
|
||||
|
||||
OSD search may find invalid solutions as mentioned above. When checking this option the callsigns in messages not passed through OSD (thus very certainly valid) are stored for the life of the plugin. When OSD is engaged the second callsign field which is always a callsign is checked against this list and if the callsign is not found the message is rejected. This is quite efficient in removing false messages when OSD is engaged although some valid messages may be removed.
|
||||
|
||||
<h4>C.1.7: Band presets table</h4>
|
||||
<h4>C.1.7: Report to PSK reporter</h4>
|
||||
|
||||
Sends received calls details to the PSK reporter (report.pskreporter.info port 4739) via UDP packets. Reports are sent every 5 minutes.
|
||||
|
||||
<h4>C.1.8: Reporting station callsign</h4>
|
||||
|
||||
This is the callsign of your station as it will be reported (may be an Amateur Radio callsign or something else). By default it takes the value for "Sation name" in the "Preferences > My Position..." in the main window.
|
||||
|
||||
<h4>C.1.9: Reporting station Maindenhead locator</h4>
|
||||
|
||||
This is the Maidenhead locator as it will be reported. By default it is calculated from the "Latitude" and "Longitude" values in the "Preferences > My Position..." in the main window.
|
||||
|
||||
<h4>C.1.10: Reporting station software</h4>
|
||||
|
||||
This is the decoding Software name and version as it will be reported in the "Using" field. By default it takes the value shown at the bottom right of the main SDRangel window.
|
||||
|
||||
<h4>C.1.11: Revert to default values</h4>
|
||||
|
||||
Use this push button to revert to default values for the reporting station details.
|
||||
|
||||
<h4>C.1.12: Band presets table</h4>
|
||||
|
||||
This table shows the band presets values that will appear in (C.5)
|
||||
|
||||
@ -245,23 +265,23 @@ This table shows the band presets values that will appear in (C.5)
|
||||
|
||||
You can edit these values by clicking on the cell in the table.
|
||||
|
||||
<h4>C.1.8: Add preset</h4>
|
||||
<h4>C.1.13: Add preset</h4>
|
||||
|
||||
Use this button to create a new preset. It will take the values from the row of the selected cell in the table (if selected) and put the new preset at the bottom of the table
|
||||
|
||||
<h4>C.1.9: Delete preset</h4>
|
||||
<h4>C.1.14: Delete preset</h4>
|
||||
|
||||
Delete the preset designated by the selected cell in the table.
|
||||
|
||||
<h4>C.1.10: Move up preset</h4>
|
||||
<h4>C.1.15: Move up preset</h4>
|
||||
|
||||
Move up the preset designated by the selected cell in the table.
|
||||
|
||||
<h4>C.1.11: Move down preset</h4>
|
||||
<h4>C.1.16: Move down preset</h4>
|
||||
|
||||
Move down the preset designated by the selected cell in the table.
|
||||
|
||||
<h4>C.1.12: Restore defaults</h4>
|
||||
<h4>C.1.17: Restore defaults</h4>
|
||||
|
||||
This restores the default band preset values:
|
||||
|
||||
@ -283,10 +303,10 @@ This restores the default band preset values:
|
||||
|
||||
Channel offsets are all set to 0 kHz.
|
||||
|
||||
<h4>C.1.13 Commit changes</h4>
|
||||
<h4>C.1.18 Commit changes</h4>
|
||||
|
||||
Click on the "OK" button to commit changes and close dialog.
|
||||
|
||||
<h4>C.1.14 Cancel changes</h4>
|
||||
<h4>C.1.19 Cancel changes</h4>
|
||||
|
||||
Click on the "Cancel" button to close dialog without making changes.
|
||||
|
||||
@ -6380,6 +6380,19 @@ margin-bottom: 20px;
|
||||
"type" : "integer",
|
||||
"description" : "Verify OSD decoded message against a list of validated callsigns\n * 0 - Disable\n * 1 - Enable\n"
|
||||
},
|
||||
"enablePSKReporter" : {
|
||||
"type" : "integer",
|
||||
"description" : "Enable reporting of decoded messages to PSK Reporter server\n * 0 - Disable\n * 1 - Enable\n"
|
||||
},
|
||||
"pskReporterCallsign" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"pskReporterLocator" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"pskReporterSoftware" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"rgbColor" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
@ -59634,7 +59647,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2025-12-31T21:12:50.336+01:00
|
||||
Generated 2026-01-03T10:36:00.091+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -70,6 +70,18 @@ FT8DemodSettings:
|
||||
Verify OSD decoded message against a list of validated callsigns
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
enablePSKReporter:
|
||||
type: integer
|
||||
description: >
|
||||
Enable reporting of decoded messages to PSK Reporter server
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
pskReporterCallsign:
|
||||
type: string
|
||||
pskReporterLocator:
|
||||
type: string
|
||||
pskReporterSoftware:
|
||||
type: string
|
||||
rgbColor:
|
||||
type: integer
|
||||
title:
|
||||
|
||||
@ -44,7 +44,9 @@ struct SDRBASE_API FT8Message
|
||||
class SDRBASE_API MsgReportFT8Messages : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
public:
|
||||
const QList<FT8Message>& getFT8Messages() const { return m_ft8Messages; }
|
||||
QList<FT8Message>& getFT8Messages() { return m_ft8Messages; }
|
||||
qint64 getBaseFrequency() const { return m_baseFrequency; }
|
||||
void setBaseFrequency(qint64 baseFrequency) { m_baseFrequency = baseFrequency; }
|
||||
|
||||
static MsgReportFT8Messages* create() {
|
||||
|
||||
@ -70,6 +70,18 @@ FT8DemodSettings:
|
||||
Verify OSD decoded message against a list of validated callsigns
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
enablePSKReporter:
|
||||
type: integer
|
||||
description: >
|
||||
Enable reporting of decoded messages to PSK Reporter server
|
||||
* 0 - Disable
|
||||
* 1 - Enable
|
||||
pskReporterCallsign:
|
||||
type: string
|
||||
pskReporterLocator:
|
||||
type: string
|
||||
pskReporterSoftware:
|
||||
type: string
|
||||
rgbColor:
|
||||
type: integer
|
||||
title:
|
||||
|
||||
@ -6380,6 +6380,19 @@ margin-bottom: 20px;
|
||||
"type" : "integer",
|
||||
"description" : "Verify OSD decoded message against a list of validated callsigns\n * 0 - Disable\n * 1 - Enable\n"
|
||||
},
|
||||
"enablePSKReporter" : {
|
||||
"type" : "integer",
|
||||
"description" : "Enable reporting of decoded messages to PSK Reporter server\n * 0 - Disable\n * 1 - Enable\n"
|
||||
},
|
||||
"pskReporterCallsign" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"pskReporterLocator" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"pskReporterSoftware" : {
|
||||
"type" : "string"
|
||||
},
|
||||
"rgbColor" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
@ -59634,7 +59647,7 @@ except ApiException as e:
|
||||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2025-12-31T21:12:50.336+01:00
|
||||
Generated 2026-01-03T10:36:00.091+01:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -60,6 +60,14 @@ SWGFT8DemodSettings::SWGFT8DemodSettings() {
|
||||
m_osd_ldpc_threshold_isSet = false;
|
||||
verify_osd = 0;
|
||||
m_verify_osd_isSet = false;
|
||||
enable_psk_reporter = 0;
|
||||
m_enable_psk_reporter_isSet = false;
|
||||
psk_reporter_callsign = nullptr;
|
||||
m_psk_reporter_callsign_isSet = false;
|
||||
psk_reporter_locator = nullptr;
|
||||
m_psk_reporter_locator_isSet = false;
|
||||
psk_reporter_software = nullptr;
|
||||
m_psk_reporter_software_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = nullptr;
|
||||
@ -122,6 +130,14 @@ SWGFT8DemodSettings::init() {
|
||||
m_osd_ldpc_threshold_isSet = false;
|
||||
verify_osd = 0;
|
||||
m_verify_osd_isSet = false;
|
||||
enable_psk_reporter = 0;
|
||||
m_enable_psk_reporter_isSet = false;
|
||||
psk_reporter_callsign = new QString("");
|
||||
m_psk_reporter_callsign_isSet = false;
|
||||
psk_reporter_locator = new QString("");
|
||||
m_psk_reporter_locator_isSet = false;
|
||||
psk_reporter_software = new QString("");
|
||||
m_psk_reporter_software_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = new QString("");
|
||||
@ -165,6 +181,16 @@ SWGFT8DemodSettings::cleanup() {
|
||||
|
||||
|
||||
|
||||
if(psk_reporter_callsign != nullptr) {
|
||||
delete psk_reporter_callsign;
|
||||
}
|
||||
if(psk_reporter_locator != nullptr) {
|
||||
delete psk_reporter_locator;
|
||||
}
|
||||
if(psk_reporter_software != nullptr) {
|
||||
delete psk_reporter_software;
|
||||
}
|
||||
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
@ -230,6 +256,14 @@ SWGFT8DemodSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&verify_osd, pJson["verifyOSD"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&enable_psk_reporter, pJson["enablePSKReporter"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&psk_reporter_callsign, pJson["pskReporterCallsign"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&psk_reporter_locator, pJson["pskReporterLocator"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&psk_reporter_software, pJson["pskReporterSoftware"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
@ -316,6 +350,18 @@ SWGFT8DemodSettings::asJsonObject() {
|
||||
if(m_verify_osd_isSet){
|
||||
obj->insert("verifyOSD", QJsonValue(verify_osd));
|
||||
}
|
||||
if(m_enable_psk_reporter_isSet){
|
||||
obj->insert("enablePSKReporter", QJsonValue(enable_psk_reporter));
|
||||
}
|
||||
if(psk_reporter_callsign != nullptr && *psk_reporter_callsign != QString("")){
|
||||
toJsonValue(QString("pskReporterCallsign"), psk_reporter_callsign, obj, QString("QString"));
|
||||
}
|
||||
if(psk_reporter_locator != nullptr && *psk_reporter_locator != QString("")){
|
||||
toJsonValue(QString("pskReporterLocator"), psk_reporter_locator, obj, QString("QString"));
|
||||
}
|
||||
if(psk_reporter_software != nullptr && *psk_reporter_software != QString("")){
|
||||
toJsonValue(QString("pskReporterSoftware"), psk_reporter_software, obj, QString("QString"));
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
obj->insert("rgbColor", QJsonValue(rgb_color));
|
||||
}
|
||||
@ -513,6 +559,46 @@ SWGFT8DemodSettings::setVerifyOsd(qint32 verify_osd) {
|
||||
this->m_verify_osd_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGFT8DemodSettings::getEnablePskReporter() {
|
||||
return enable_psk_reporter;
|
||||
}
|
||||
void
|
||||
SWGFT8DemodSettings::setEnablePskReporter(qint32 enable_psk_reporter) {
|
||||
this->enable_psk_reporter = enable_psk_reporter;
|
||||
this->m_enable_psk_reporter_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGFT8DemodSettings::getPskReporterCallsign() {
|
||||
return psk_reporter_callsign;
|
||||
}
|
||||
void
|
||||
SWGFT8DemodSettings::setPskReporterCallsign(QString* psk_reporter_callsign) {
|
||||
this->psk_reporter_callsign = psk_reporter_callsign;
|
||||
this->m_psk_reporter_callsign_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGFT8DemodSettings::getPskReporterLocator() {
|
||||
return psk_reporter_locator;
|
||||
}
|
||||
void
|
||||
SWGFT8DemodSettings::setPskReporterLocator(QString* psk_reporter_locator) {
|
||||
this->psk_reporter_locator = psk_reporter_locator;
|
||||
this->m_psk_reporter_locator_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGFT8DemodSettings::getPskReporterSoftware() {
|
||||
return psk_reporter_software;
|
||||
}
|
||||
void
|
||||
SWGFT8DemodSettings::setPskReporterSoftware(QString* psk_reporter_software) {
|
||||
this->psk_reporter_software = psk_reporter_software;
|
||||
this->m_psk_reporter_software_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGFT8DemodSettings::getRgbColor() {
|
||||
return rgb_color;
|
||||
@ -676,6 +762,18 @@ SWGFT8DemodSettings::isSet(){
|
||||
if(m_verify_osd_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_enable_psk_reporter_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(psk_reporter_callsign && *psk_reporter_callsign != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(psk_reporter_locator && *psk_reporter_locator != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(psk_reporter_software && *psk_reporter_software != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
||||
@ -93,6 +93,18 @@ public:
|
||||
qint32 getVerifyOsd();
|
||||
void setVerifyOsd(qint32 verify_osd);
|
||||
|
||||
qint32 getEnablePskReporter();
|
||||
void setEnablePskReporter(qint32 enable_psk_reporter);
|
||||
|
||||
QString* getPskReporterCallsign();
|
||||
void setPskReporterCallsign(QString* psk_reporter_callsign);
|
||||
|
||||
QString* getPskReporterLocator();
|
||||
void setPskReporterLocator(QString* psk_reporter_locator);
|
||||
|
||||
QString* getPskReporterSoftware();
|
||||
void setPskReporterSoftware(QString* psk_reporter_software);
|
||||
|
||||
qint32 getRgbColor();
|
||||
void setRgbColor(qint32 rgb_color);
|
||||
|
||||
@ -178,6 +190,18 @@ private:
|
||||
qint32 verify_osd;
|
||||
bool m_verify_osd_isSet;
|
||||
|
||||
qint32 enable_psk_reporter;
|
||||
bool m_enable_psk_reporter_isSet;
|
||||
|
||||
QString* psk_reporter_callsign;
|
||||
bool m_psk_reporter_callsign_isSet;
|
||||
|
||||
QString* psk_reporter_locator;
|
||||
bool m_psk_reporter_locator_isSet;
|
||||
|
||||
QString* psk_reporter_software;
|
||||
bool m_psk_reporter_software_isSet;
|
||||
|
||||
qint32 rgb_color;
|
||||
bool m_rgb_color_isSet;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user