mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-21 23:55:13 -05:00
Add Navtex demodulator
This commit is contained in:
parent
a2cfe07dee
commit
95b46937a7
BIN
doc/img/NavtexDemod_plugin.png
Normal file
BIN
doc/img/NavtexDemod_plugin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
63
plugins/channelrx/demodnavtex/CMakeLists.txt
Normal file
63
plugins/channelrx/demodnavtex/CMakeLists.txt
Normal file
@ -0,0 +1,63 @@
|
||||
project(demodnavtex)
|
||||
|
||||
set(demodnavtex_SOURCES
|
||||
navtexdemod.cpp
|
||||
navtexdemodsettings.cpp
|
||||
navtexdemodbaseband.cpp
|
||||
navtexdemodsink.cpp
|
||||
navtexdemodplugin.cpp
|
||||
navtexdemodwebapiadapter.cpp
|
||||
)
|
||||
|
||||
set(demodnavtex_HEADERS
|
||||
navtexdemod.h
|
||||
navtexdemodsettings.h
|
||||
navtexdemodbaseband.h
|
||||
navtexdemodsink.h
|
||||
navtexdemodplugin.h
|
||||
navtexdemodwebapiadapter.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||
)
|
||||
|
||||
if(NOT SERVER_MODE)
|
||||
set(demodnavtex_SOURCES
|
||||
${demodnavtex_SOURCES}
|
||||
navtexdemodgui.cpp
|
||||
navtexdemodgui.ui
|
||||
)
|
||||
set(demodnavtex_HEADERS
|
||||
${demodnavtex_HEADERS}
|
||||
navtexdemodgui.h
|
||||
)
|
||||
|
||||
set(TARGET_NAME demodnavtex)
|
||||
set(TARGET_LIB "Qt::Widgets")
|
||||
set(TARGET_LIB_GUI "sdrgui")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
|
||||
else()
|
||||
set(TARGET_NAME demodnavtexsrv)
|
||||
set(TARGET_LIB "")
|
||||
set(TARGET_LIB_GUI "")
|
||||
set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
|
||||
endif()
|
||||
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
${demodnavtex_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(${TARGET_NAME}
|
||||
Qt::Core
|
||||
${TARGET_LIB}
|
||||
sdrbase
|
||||
${TARGET_LIB_GUI}
|
||||
)
|
||||
|
||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||
|
||||
# Install debug symbols
|
||||
if (WIN32)
|
||||
install(FILES $<TARGET_PDB_FILE:${TARGET_NAME}> CONFIGURATIONS Debug RelWithDebInfo DESTINATION ${INSTALL_FOLDER} )
|
||||
endif()
|
751
plugins/channelrx/demodnavtex/navtexdemod.cpp
Normal file
751
plugins/channelrx/demodnavtex/navtexdemod.cpp
Normal file
@ -0,0 +1,751 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 "navtexdemod.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QBuffer>
|
||||
#include <QThread>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <complex.h>
|
||||
|
||||
#include "SWGChannelSettings.h"
|
||||
#include "SWGWorkspaceInfo.h"
|
||||
#include "SWGNavtexDemodSettings.h"
|
||||
#include "SWGChannelReport.h"
|
||||
#include "SWGMapItem.h"
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "device/deviceapi.h"
|
||||
#include "feature/feature.h"
|
||||
#include "settings/serializable.h"
|
||||
#include "util/db.h"
|
||||
#include "maincore.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(NavtexDemod::MsgConfigureNavtexDemod, Message)
|
||||
MESSAGE_CLASS_DEFINITION(NavtexDemod::MsgCharacter, Message)
|
||||
MESSAGE_CLASS_DEFINITION(NavtexDemod::MsgMessage, Message)
|
||||
|
||||
const char * const NavtexDemod::m_channelIdURI = "sdrangel.channel.navtexdemod";
|
||||
const char * const NavtexDemod::m_channelId = "NavtexDemod";
|
||||
|
||||
NavtexDemod::NavtexDemod(DeviceAPI *deviceAPI) :
|
||||
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSink),
|
||||
m_deviceAPI(deviceAPI),
|
||||
m_basebandSampleRate(0)
|
||||
{
|
||||
setObjectName(m_channelId);
|
||||
|
||||
m_basebandSink = new NavtexDemodBaseband(this);
|
||||
m_basebandSink->setMessageQueueToChannel(getInputMessageQueue());
|
||||
m_basebandSink->setChannel(this);
|
||||
m_basebandSink->moveToThread(&m_thread);
|
||||
|
||||
applySettings(m_settings, true);
|
||||
|
||||
m_deviceAPI->addChannelSink(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
|
||||
m_networkManager = new QNetworkAccessManager();
|
||||
QObject::connect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&NavtexDemod::networkManagerFinished
|
||||
);
|
||||
QObject::connect(
|
||||
this,
|
||||
&ChannelAPI::indexInDeviceSetChanged,
|
||||
this,
|
||||
&NavtexDemod::handleIndexInDeviceSetChanged
|
||||
);
|
||||
}
|
||||
|
||||
NavtexDemod::~NavtexDemod()
|
||||
{
|
||||
qDebug("NavtexDemod::~NavtexDemod");
|
||||
QObject::disconnect(
|
||||
m_networkManager,
|
||||
&QNetworkAccessManager::finished,
|
||||
this,
|
||||
&NavtexDemod::networkManagerFinished
|
||||
);
|
||||
delete m_networkManager;
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
|
||||
if (m_basebandSink->isRunning()) {
|
||||
stop();
|
||||
}
|
||||
|
||||
delete m_basebandSink;
|
||||
}
|
||||
|
||||
void NavtexDemod::setDeviceAPI(DeviceAPI *deviceAPI)
|
||||
{
|
||||
if (deviceAPI != m_deviceAPI)
|
||||
{
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this);
|
||||
m_deviceAPI = deviceAPI;
|
||||
m_deviceAPI->addChannelSink(this);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NavtexDemod::getNumberOfDeviceStreams() const
|
||||
{
|
||||
return m_deviceAPI->getNbSourceStreams();
|
||||
}
|
||||
|
||||
void NavtexDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool firstOfBurst)
|
||||
{
|
||||
(void) firstOfBurst;
|
||||
m_basebandSink->feed(begin, end);
|
||||
}
|
||||
|
||||
void NavtexDemod::start()
|
||||
{
|
||||
qDebug("NavtexDemod::start");
|
||||
|
||||
m_basebandSink->reset();
|
||||
m_basebandSink->startWork();
|
||||
m_thread.start();
|
||||
|
||||
DSPSignalNotification *dspMsg = new DSPSignalNotification(m_basebandSampleRate, m_centerFrequency);
|
||||
m_basebandSink->getInputMessageQueue()->push(dspMsg);
|
||||
|
||||
NavtexDemodBaseband::MsgConfigureNavtexDemodBaseband *msg = NavtexDemodBaseband::MsgConfigureNavtexDemodBaseband::create(m_settings, true);
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
}
|
||||
|
||||
void NavtexDemod::stop()
|
||||
{
|
||||
qDebug("NavtexDemod::stop");
|
||||
m_basebandSink->stopWork();
|
||||
m_thread.quit();
|
||||
m_thread.wait();
|
||||
}
|
||||
|
||||
bool NavtexDemod::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (MsgConfigureNavtexDemod::match(cmd))
|
||||
{
|
||||
MsgConfigureNavtexDemod& cfg = (MsgConfigureNavtexDemod&) cmd;
|
||||
qDebug() << "NavtexDemod::handleMessage: MsgConfigureNavtexDemod";
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
m_basebandSampleRate = notif.getSampleRate();
|
||||
m_centerFrequency = notif.getCenterFrequency();
|
||||
// Forward to the sink
|
||||
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
|
||||
qDebug() << "NavtexDemod::handleMessage: DSPSignalNotification";
|
||||
m_basebandSink->getInputMessageQueue()->push(rep);
|
||||
// Forward to GUI if any
|
||||
if (m_guiMessageQueue) {
|
||||
m_guiMessageQueue->push(new DSPSignalNotification(notif));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (NavtexDemod::MsgCharacter::match(cmd))
|
||||
{
|
||||
// Forward to GUI
|
||||
NavtexDemod::MsgCharacter& report = (NavtexDemod::MsgCharacter&)cmd;
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
NavtexDemod::MsgCharacter *msg = new NavtexDemod::MsgCharacter(report);
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (NavtexDemod::MsgMessage::match(cmd))
|
||||
{
|
||||
// Forward to GUI
|
||||
NavtexDemod::MsgMessage& report = (NavtexDemod::MsgMessage&)cmd;
|
||||
if (getMessageQueueToGUI())
|
||||
{
|
||||
NavtexDemod::MsgMessage *msg = new NavtexDemod::MsgMessage(report);
|
||||
getMessageQueueToGUI()->push(msg);
|
||||
}
|
||||
|
||||
// Forward via UDP
|
||||
if (m_settings.m_udpEnabled)
|
||||
{
|
||||
qDebug() << "Forwarding to " << m_settings.m_udpAddress << ":" << m_settings.m_udpPort;
|
||||
QByteArray bytes = report.getMessage().m_message.toUtf8();
|
||||
m_udpSocket.writeDatagram(bytes, bytes.size(),
|
||||
QHostAddress(m_settings.m_udpAddress), m_settings.m_udpPort);
|
||||
}
|
||||
|
||||
// Write to log file
|
||||
if (m_logFile.isOpen())
|
||||
{
|
||||
const NavtexMessage &navtexMsg = report.getMessage();
|
||||
|
||||
if (navtexMsg.m_valid)
|
||||
{
|
||||
m_logStream << navtexMsg.m_dateTime.date().toString() << ","
|
||||
<< navtexMsg.m_dateTime.time().toString() << ","
|
||||
<< navtexMsg.m_stationId << ","
|
||||
<< navtexMsg.m_typeId << ","
|
||||
<< navtexMsg.m_id << ","
|
||||
<< "\"" << navtexMsg.m_message << "\","
|
||||
<< report.getErrors() << ","
|
||||
<< report.getRSSI()
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (MainCore::MsgChannelDemodQuery::match(cmd))
|
||||
{
|
||||
qDebug() << "NavtexDemod::handleMessage: MsgChannelDemodQuery";
|
||||
sendSampleRateToDemodAnalyzer();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ScopeVis *NavtexDemod::getScopeSink()
|
||||
{
|
||||
return m_basebandSink->getScopeSink();
|
||||
}
|
||||
|
||||
void NavtexDemod::setCenterFrequency(qint64 frequency)
|
||||
{
|
||||
NavtexDemodSettings settings = m_settings;
|
||||
settings.m_inputFrequencyOffset = frequency;
|
||||
applySettings(settings, false);
|
||||
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureNavtexDemod *msgToGUI = MsgConfigureNavtexDemod::create(settings, false);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemod::applySettings(const NavtexDemodSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "NavtexDemod::applySettings:"
|
||||
<< " m_logEnabled: " << settings.m_logEnabled
|
||||
<< " m_logFilename: " << settings.m_logFilename
|
||||
<< " m_streamIndex: " << settings.m_streamIndex
|
||||
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||
<< " m_reverseAPIPort: " << settings.m_reverseAPIPort
|
||||
<< " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex
|
||||
<< " m_reverseAPIChannelIndex: " << settings.m_reverseAPIChannelIndex
|
||||
<< " force: " << force;
|
||||
|
||||
QList<QString> reverseAPIKeys;
|
||||
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force) {
|
||||
reverseAPIKeys.append("inputFrequencyOffset");
|
||||
}
|
||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
|
||||
reverseAPIKeys.append("rfBandwidth");
|
||||
}
|
||||
if ((settings.m_navArea != m_settings.m_navArea) || force) {
|
||||
reverseAPIKeys.append("navArea");
|
||||
}
|
||||
if ((settings.m_filterStation != m_settings.m_filterStation) || force) {
|
||||
reverseAPIKeys.append("filterStation");
|
||||
}
|
||||
if ((settings.m_filterType != m_settings.m_filterType) || force) {
|
||||
reverseAPIKeys.append("filterType");
|
||||
}
|
||||
if ((settings.m_udpEnabled != m_settings.m_udpEnabled) || force) {
|
||||
reverseAPIKeys.append("udpEnabled");
|
||||
}
|
||||
if ((settings.m_udpAddress != m_settings.m_udpAddress) || force) {
|
||||
reverseAPIKeys.append("udpAddress");
|
||||
}
|
||||
if ((settings.m_udpPort != m_settings.m_udpPort) || force) {
|
||||
reverseAPIKeys.append("udpPort");
|
||||
}
|
||||
if ((settings.m_logFilename != m_settings.m_logFilename) || force) {
|
||||
reverseAPIKeys.append("logFilename");
|
||||
}
|
||||
if ((settings.m_logEnabled != m_settings.m_logEnabled) || force) {
|
||||
reverseAPIKeys.append("logEnabled");
|
||||
}
|
||||
if (m_settings.m_streamIndex != settings.m_streamIndex)
|
||||
{
|
||||
if (m_deviceAPI->getSampleMIMO()) // change of stream is possible for MIMO devices only
|
||||
{
|
||||
m_deviceAPI->removeChannelSinkAPI(this);
|
||||
m_deviceAPI->removeChannelSink(this, m_settings.m_streamIndex);
|
||||
m_deviceAPI->addChannelSink(this, settings.m_streamIndex);
|
||||
m_deviceAPI->addChannelSinkAPI(this);
|
||||
}
|
||||
|
||||
reverseAPIKeys.append("streamIndex");
|
||||
}
|
||||
|
||||
NavtexDemodBaseband::MsgConfigureNavtexDemodBaseband *msg = NavtexDemodBaseband::MsgConfigureNavtexDemodBaseband::create(settings, force);
|
||||
m_basebandSink->getInputMessageQueue()->push(msg);
|
||||
|
||||
if (settings.m_useReverseAPI)
|
||||
{
|
||||
bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) ||
|
||||
(m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) ||
|
||||
(m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) ||
|
||||
(m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex) ||
|
||||
(m_settings.m_reverseAPIChannelIndex != settings.m_reverseAPIChannelIndex);
|
||||
webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force);
|
||||
}
|
||||
|
||||
if ((settings.m_logEnabled != m_settings.m_logEnabled)
|
||||
|| (settings.m_logFilename != m_settings.m_logFilename)
|
||||
|| force)
|
||||
{
|
||||
if (m_logFile.isOpen())
|
||||
{
|
||||
m_logStream.flush();
|
||||
m_logFile.close();
|
||||
}
|
||||
if (settings.m_logEnabled && !settings.m_logFilename.isEmpty())
|
||||
{
|
||||
m_logFile.setFileName(settings.m_logFilename);
|
||||
if (m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
|
||||
{
|
||||
qDebug() << "NavtexDemod::applySettings - Logging to: " << settings.m_logFilename;
|
||||
bool newFile = m_logFile.size() == 0;
|
||||
m_logStream.setDevice(&m_logFile);
|
||||
if (newFile)
|
||||
{
|
||||
// Write header
|
||||
m_logStream << "Date,Time,SID,TID,MID,Message,Errors,RSSI\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "NavtexDemod::applySettings - Unable to open log file: " << settings.m_logFilename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
void NavtexDemod::sendSampleRateToDemodAnalyzer()
|
||||
{
|
||||
QList<ObjectPipe*> pipes;
|
||||
MainCore::instance()->getMessagePipes().getMessagePipes(this, "reportdemod", pipes);
|
||||
|
||||
if (pipes.size() > 0)
|
||||
{
|
||||
for (const auto& pipe : pipes)
|
||||
{
|
||||
MessageQueue *messageQueue = qobject_cast<MessageQueue*>(pipe->m_element);
|
||||
MainCore::MsgChannelDemodReport *msg = MainCore::MsgChannelDemodReport::create(
|
||||
this,
|
||||
NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE
|
||||
);
|
||||
messageQueue->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray NavtexDemod::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool NavtexDemod::deserialize(const QByteArray& data)
|
||||
{
|
||||
if (m_settings.deserialize(data))
|
||||
{
|
||||
MsgConfigureNavtexDemod *msg = MsgConfigureNavtexDemod::create(m_settings, true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
MsgConfigureNavtexDemod *msg = MsgConfigureNavtexDemod::create(m_settings, true);
|
||||
m_inputMessageQueue.push(msg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int NavtexDemod::webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setNavtexDemodSettings(new SWGSDRangel::SWGNavtexDemodSettings());
|
||||
response.getNavtexDemodSettings()->init();
|
||||
webapiFormatChannelSettings(response, m_settings);
|
||||
return 200;
|
||||
}
|
||||
|
||||
int NavtexDemod::webapiWorkspaceGet(
|
||||
SWGSDRangel::SWGWorkspaceInfo& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setIndex(m_settings.m_workspaceIndex);
|
||||
return 200;
|
||||
}
|
||||
|
||||
int NavtexDemod::webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
NavtexDemodSettings settings = m_settings;
|
||||
webapiUpdateChannelSettings(settings, channelSettingsKeys, response);
|
||||
|
||||
MsgConfigureNavtexDemod *msg = MsgConfigureNavtexDemod::create(settings, force);
|
||||
m_inputMessageQueue.push(msg);
|
||||
|
||||
qDebug("NavtexDemod::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue);
|
||||
if (m_guiMessageQueue) // forward to GUI if any
|
||||
{
|
||||
MsgConfigureNavtexDemod *msgToGUI = MsgConfigureNavtexDemod::create(settings, force);
|
||||
m_guiMessageQueue->push(msgToGUI);
|
||||
}
|
||||
|
||||
webapiFormatChannelSettings(response, settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int NavtexDemod::webapiReportGet(
|
||||
SWGSDRangel::SWGChannelReport& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setNavtexDemodReport(new SWGSDRangel::SWGNavtexDemodReport());
|
||||
response.getNavtexDemodReport()->init();
|
||||
webapiFormatChannelReport(response);
|
||||
return 200;
|
||||
}
|
||||
|
||||
void NavtexDemod::webapiUpdateChannelSettings(
|
||||
NavtexDemodSettings& settings,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response)
|
||||
{
|
||||
if (channelSettingsKeys.contains("inputFrequencyOffset")) {
|
||||
settings.m_inputFrequencyOffset = response.getNavtexDemodSettings()->getInputFrequencyOffset();
|
||||
}
|
||||
if (channelSettingsKeys.contains("rfBandwidth")) {
|
||||
settings.m_rfBandwidth = response.getNavtexDemodSettings()->getRfBandwidth();
|
||||
}
|
||||
if (channelSettingsKeys.contains("navArea")) {
|
||||
settings.m_navArea = response.getNavtexDemodSettings()->getNavArea();
|
||||
}
|
||||
if (channelSettingsKeys.contains("filterStation")) {
|
||||
settings.m_filterStation = *response.getNavtexDemodSettings()->getFilterStation();
|
||||
}
|
||||
if (channelSettingsKeys.contains("filterType")) {
|
||||
settings.m_filterType = *response.getNavtexDemodSettings()->getFilterType();
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpEnabled")) {
|
||||
settings.m_udpEnabled = response.getNavtexDemodSettings()->getUdpEnabled();
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpAddress")) {
|
||||
settings.m_udpAddress = *response.getNavtexDemodSettings()->getUdpAddress();
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpPort")) {
|
||||
settings.m_udpPort = response.getNavtexDemodSettings()->getUdpPort();
|
||||
}
|
||||
if (channelSettingsKeys.contains("logFilename")) {
|
||||
settings.m_logFilename = *response.getAdsbDemodSettings()->getLogFilename();
|
||||
}
|
||||
if (channelSettingsKeys.contains("logEnabled")) {
|
||||
settings.m_logEnabled = response.getAdsbDemodSettings()->getLogEnabled();
|
||||
}
|
||||
if (channelSettingsKeys.contains("rgbColor")) {
|
||||
settings.m_rgbColor = response.getNavtexDemodSettings()->getRgbColor();
|
||||
}
|
||||
if (channelSettingsKeys.contains("title")) {
|
||||
settings.m_title = *response.getNavtexDemodSettings()->getTitle();
|
||||
}
|
||||
if (channelSettingsKeys.contains("streamIndex")) {
|
||||
settings.m_streamIndex = response.getNavtexDemodSettings()->getStreamIndex();
|
||||
}
|
||||
if (channelSettingsKeys.contains("useReverseAPI")) {
|
||||
settings.m_useReverseAPI = response.getNavtexDemodSettings()->getUseReverseApi() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIAddress")) {
|
||||
settings.m_reverseAPIAddress = *response.getNavtexDemodSettings()->getReverseApiAddress();
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIPort")) {
|
||||
settings.m_reverseAPIPort = response.getNavtexDemodSettings()->getReverseApiPort();
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) {
|
||||
settings.m_reverseAPIDeviceIndex = response.getNavtexDemodSettings()->getReverseApiDeviceIndex();
|
||||
}
|
||||
if (channelSettingsKeys.contains("reverseAPIChannelIndex")) {
|
||||
settings.m_reverseAPIChannelIndex = response.getNavtexDemodSettings()->getReverseApiChannelIndex();
|
||||
}
|
||||
if (settings.m_scopeGUI && channelSettingsKeys.contains("scopeConfig")) {
|
||||
settings.m_scopeGUI->updateFrom(channelSettingsKeys, response.getNavtexDemodSettings()->getScopeConfig());
|
||||
}
|
||||
if (settings.m_channelMarker && channelSettingsKeys.contains("channelMarker")) {
|
||||
settings.m_channelMarker->updateFrom(channelSettingsKeys, response.getNavtexDemodSettings()->getChannelMarker());
|
||||
}
|
||||
if (settings.m_rollupState && channelSettingsKeys.contains("rollupState")) {
|
||||
settings.m_rollupState->updateFrom(channelSettingsKeys, response.getNavtexDemodSettings()->getRollupState());
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const NavtexDemodSettings& settings)
|
||||
{
|
||||
response.getNavtexDemodSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||
response.getNavtexDemodSettings()->setRfBandwidth(settings.m_rfBandwidth);
|
||||
response.getNavtexDemodSettings()->setNavArea(settings.m_navArea);
|
||||
response.getNavtexDemodSettings()->setFilterStation(new QString(settings.m_filterStation));
|
||||
response.getNavtexDemodSettings()->setFilterType(new QString(settings.m_filterType));
|
||||
response.getNavtexDemodSettings()->setUdpEnabled(settings.m_udpEnabled);
|
||||
response.getNavtexDemodSettings()->setUdpAddress(new QString(settings.m_udpAddress));
|
||||
response.getNavtexDemodSettings()->setUdpPort(settings.m_udpPort);
|
||||
response.getNavtexDemodSettings()->setLogFilename(new QString(settings.m_logFilename));
|
||||
response.getNavtexDemodSettings()->setLogEnabled(settings.m_logEnabled);
|
||||
|
||||
response.getNavtexDemodSettings()->setRgbColor(settings.m_rgbColor);
|
||||
if (response.getNavtexDemodSettings()->getTitle()) {
|
||||
*response.getNavtexDemodSettings()->getTitle() = settings.m_title;
|
||||
} else {
|
||||
response.getNavtexDemodSettings()->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
|
||||
response.getNavtexDemodSettings()->setStreamIndex(settings.m_streamIndex);
|
||||
response.getNavtexDemodSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
|
||||
|
||||
if (response.getNavtexDemodSettings()->getReverseApiAddress()) {
|
||||
*response.getNavtexDemodSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
|
||||
} else {
|
||||
response.getNavtexDemodSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
|
||||
}
|
||||
|
||||
response.getNavtexDemodSettings()->setReverseApiPort(settings.m_reverseAPIPort);
|
||||
response.getNavtexDemodSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
|
||||
response.getNavtexDemodSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex);
|
||||
|
||||
if (settings.m_scopeGUI)
|
||||
{
|
||||
if (response.getNavtexDemodSettings()->getScopeConfig())
|
||||
{
|
||||
settings.m_scopeGUI->formatTo(response.getNavtexDemodSettings()->getScopeConfig());
|
||||
}
|
||||
else
|
||||
{
|
||||
SWGSDRangel::SWGGLScope *swgGLScope = new SWGSDRangel::SWGGLScope();
|
||||
settings.m_scopeGUI->formatTo(swgGLScope);
|
||||
response.getNavtexDemodSettings()->setScopeConfig(swgGLScope);
|
||||
}
|
||||
}
|
||||
if (settings.m_channelMarker)
|
||||
{
|
||||
if (response.getNavtexDemodSettings()->getChannelMarker())
|
||||
{
|
||||
settings.m_channelMarker->formatTo(response.getNavtexDemodSettings()->getChannelMarker());
|
||||
}
|
||||
else
|
||||
{
|
||||
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
|
||||
settings.m_channelMarker->formatTo(swgChannelMarker);
|
||||
response.getNavtexDemodSettings()->setChannelMarker(swgChannelMarker);
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.m_rollupState)
|
||||
{
|
||||
if (response.getNavtexDemodSettings()->getRollupState())
|
||||
{
|
||||
settings.m_rollupState->formatTo(response.getNavtexDemodSettings()->getRollupState());
|
||||
}
|
||||
else
|
||||
{
|
||||
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
|
||||
settings.m_rollupState->formatTo(swgRollupState);
|
||||
response.getNavtexDemodSettings()->setRollupState(swgRollupState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
|
||||
{
|
||||
double magsqAvg, magsqPeak;
|
||||
int nbMagsqSamples;
|
||||
getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
|
||||
|
||||
response.getNavtexDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg));
|
||||
response.getNavtexDemodReport()->setChannelSampleRate(m_basebandSink->getChannelSampleRate());
|
||||
}
|
||||
|
||||
void NavtexDemod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const NavtexDemodSettings& settings, bool force)
|
||||
{
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings();
|
||||
webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force);
|
||||
|
||||
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
|
||||
.arg(settings.m_reverseAPIAddress)
|
||||
.arg(settings.m_reverseAPIPort)
|
||||
.arg(settings.m_reverseAPIDeviceIndex)
|
||||
.arg(settings.m_reverseAPIChannelIndex);
|
||||
m_networkRequest.setUrl(QUrl(channelSettingsURL));
|
||||
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QBuffer *buffer = new QBuffer();
|
||||
buffer->open((QBuffer::ReadWrite));
|
||||
buffer->write(swgChannelSettings->asJson().toUtf8());
|
||||
buffer->seek(0);
|
||||
|
||||
// Always use PATCH to avoid passing reverse API settings
|
||||
QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer);
|
||||
buffer->setParent(reply);
|
||||
|
||||
delete swgChannelSettings;
|
||||
}
|
||||
|
||||
void NavtexDemod::webapiFormatChannelSettings(
|
||||
QList<QString>& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
|
||||
const NavtexDemodSettings& settings,
|
||||
bool force
|
||||
)
|
||||
{
|
||||
swgChannelSettings->setDirection(0); // Single sink (Rx)
|
||||
swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet());
|
||||
swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex());
|
||||
swgChannelSettings->setChannelType(new QString("NavtexDemod"));
|
||||
swgChannelSettings->setNavtexDemodSettings(new SWGSDRangel::SWGNavtexDemodSettings());
|
||||
SWGSDRangel::SWGNavtexDemodSettings *swgNavtexDemodSettings = swgChannelSettings->getNavtexDemodSettings();
|
||||
|
||||
// transfer data that has been modified. When force is on transfer all data except reverse API data
|
||||
|
||||
if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
|
||||
swgNavtexDemodSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||
}
|
||||
if (channelSettingsKeys.contains("rfBandwidth") || force) {
|
||||
swgNavtexDemodSettings->setRfBandwidth(settings.m_rfBandwidth);
|
||||
}
|
||||
if (channelSettingsKeys.contains("navArea") || force) {
|
||||
swgNavtexDemodSettings->setNavArea(settings.m_navArea);
|
||||
}
|
||||
if (channelSettingsKeys.contains("filterStation") || force) {
|
||||
swgNavtexDemodSettings->setFilterStation(new QString(settings.m_filterStation));
|
||||
}
|
||||
if (channelSettingsKeys.contains("filterType") || force) {
|
||||
swgNavtexDemodSettings->setFilterType(new QString(settings.m_filterType));
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpEnabled") || force) {
|
||||
swgNavtexDemodSettings->setUdpEnabled(settings.m_udpEnabled);
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpAddress") || force) {
|
||||
swgNavtexDemodSettings->setUdpAddress(new QString(settings.m_udpAddress));
|
||||
}
|
||||
if (channelSettingsKeys.contains("udpPort") || force) {
|
||||
swgNavtexDemodSettings->setUdpPort(settings.m_udpPort);
|
||||
}
|
||||
if (channelSettingsKeys.contains("logFilename") || force) {
|
||||
swgNavtexDemodSettings->setLogFilename(new QString(settings.m_logFilename));
|
||||
}
|
||||
if (channelSettingsKeys.contains("logEnabled") || force) {
|
||||
swgNavtexDemodSettings->setLogEnabled(settings.m_logEnabled);
|
||||
}
|
||||
if (channelSettingsKeys.contains("rgbColor") || force) {
|
||||
swgNavtexDemodSettings->setRgbColor(settings.m_rgbColor);
|
||||
}
|
||||
if (channelSettingsKeys.contains("title") || force) {
|
||||
swgNavtexDemodSettings->setTitle(new QString(settings.m_title));
|
||||
}
|
||||
if (channelSettingsKeys.contains("streamIndex") || force) {
|
||||
swgNavtexDemodSettings->setStreamIndex(settings.m_streamIndex);
|
||||
}
|
||||
|
||||
if (settings.m_scopeGUI && (channelSettingsKeys.contains("scopeConfig") || force))
|
||||
{
|
||||
SWGSDRangel::SWGGLScope *swgGLScope = new SWGSDRangel::SWGGLScope();
|
||||
settings.m_scopeGUI->formatTo(swgGLScope);
|
||||
swgNavtexDemodSettings->setScopeConfig(swgGLScope);
|
||||
}
|
||||
|
||||
if (settings.m_channelMarker && (channelSettingsKeys.contains("channelMarker") || force))
|
||||
{
|
||||
SWGSDRangel::SWGChannelMarker *swgChannelMarker = new SWGSDRangel::SWGChannelMarker();
|
||||
settings.m_channelMarker->formatTo(swgChannelMarker);
|
||||
swgNavtexDemodSettings->setChannelMarker(swgChannelMarker);
|
||||
}
|
||||
|
||||
if (settings.m_rollupState && (channelSettingsKeys.contains("rollupState") || force))
|
||||
{
|
||||
SWGSDRangel::SWGRollupState *swgRollupState = new SWGSDRangel::SWGRollupState();
|
||||
settings.m_rollupState->formatTo(swgRollupState);
|
||||
swgNavtexDemodSettings->setRollupState(swgRollupState);
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemod::networkManagerFinished(QNetworkReply *reply)
|
||||
{
|
||||
QNetworkReply::NetworkError replyError = reply->error();
|
||||
|
||||
if (replyError)
|
||||
{
|
||||
qWarning() << "NavtexDemod::networkManagerFinished:"
|
||||
<< " error(" << (int) replyError
|
||||
<< "): " << replyError
|
||||
<< ": " << reply->errorString();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString answer = reply->readAll();
|
||||
answer.chop(1); // remove last \n
|
||||
qDebug("NavtexDemod::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void NavtexDemod::handleIndexInDeviceSetChanged(int index)
|
||||
{
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fifoLabel = QString("%1 [%2:%3]")
|
||||
.arg(m_channelId)
|
||||
.arg(m_deviceAPI->getDeviceSetIndex())
|
||||
.arg(index);
|
||||
m_basebandSink->setFifoLabel(fifoLabel);
|
||||
}
|
||||
|
224
plugins/channelrx/demodnavtex/navtexdemod.h
Normal file
224
plugins/channelrx/demodnavtex/navtexdemod.h
Normal file
@ -0,0 +1,224 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015-2018 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMOD_H
|
||||
#define INCLUDE_NAVTEXDEMOD_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QNetworkRequest>
|
||||
#include <QUdpSocket>
|
||||
#include <QThread>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QRegularExpression>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "dsp/basebandsamplesink.h"
|
||||
#include "channel/channelapi.h"
|
||||
#include "util/message.h"
|
||||
#include "util/navtex.h"
|
||||
|
||||
#include "navtexdemodbaseband.h"
|
||||
#include "navtexdemodsettings.h"
|
||||
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class QThread;
|
||||
class DeviceAPI;
|
||||
class ScopeVis;
|
||||
|
||||
class NavtexDemod : public BasebandSampleSink, public ChannelAPI {
|
||||
public:
|
||||
class MsgConfigureNavtexDemod : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const NavtexDemodSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureNavtexDemod* create(const NavtexDemodSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigureNavtexDemod(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
NavtexDemodSettings m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureNavtexDemod(const NavtexDemodSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
class MsgCharacter : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
QString getCharacter() const { return m_character; }
|
||||
|
||||
static MsgCharacter* create(const QString& character)
|
||||
{
|
||||
return new MsgCharacter(character);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_character;
|
||||
|
||||
MsgCharacter(const QString& character) :
|
||||
m_character(character)
|
||||
{}
|
||||
};
|
||||
|
||||
class MsgMessage : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const NavtexMessage& getMessage() const { return m_message; }
|
||||
int getErrors() const { return m_errors; }
|
||||
float getRSSI() const { return m_rssi; }
|
||||
|
||||
static MsgMessage* create(const NavtexMessage& message, int errors, float rssi)
|
||||
{
|
||||
return new MsgMessage(message, errors, rssi);
|
||||
}
|
||||
|
||||
private:
|
||||
NavtexMessage m_message;
|
||||
int m_errors;
|
||||
float m_rssi;
|
||||
|
||||
MsgMessage(const NavtexMessage& message, int errors, float rssi) :
|
||||
m_message(message),
|
||||
m_errors(errors),
|
||||
m_rssi(rssi)
|
||||
{}
|
||||
};
|
||||
|
||||
NavtexDemod(DeviceAPI *deviceAPI);
|
||||
virtual ~NavtexDemod();
|
||||
virtual void destroy() { delete this; }
|
||||
virtual void setDeviceAPI(DeviceAPI *deviceAPI);
|
||||
virtual DeviceAPI *getDeviceAPI() { return m_deviceAPI; }
|
||||
|
||||
using BasebandSampleSink::feed;
|
||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool po);
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void pushMessage(Message *msg) { m_inputMessageQueue.push(msg); }
|
||||
virtual QString getSinkName() { return objectName(); }
|
||||
|
||||
virtual void getIdentifier(QString& id) { id = objectName(); }
|
||||
virtual QString getIdentifier() const { return objectName(); }
|
||||
virtual const QString& getURI() const { return getName(); }
|
||||
virtual void getTitle(QString& title) { title = m_settings.m_title; }
|
||||
virtual qint64 getCenterFrequency() const { return m_settings.m_inputFrequencyOffset; }
|
||||
virtual void setCenterFrequency(qint64 frequency);
|
||||
|
||||
virtual QByteArray serialize() const;
|
||||
virtual bool deserialize(const QByteArray& data);
|
||||
|
||||
virtual int getNbSinkStreams() const { return 1; }
|
||||
virtual int getNbSourceStreams() const { return 0; }
|
||||
|
||||
virtual qint64 getStreamCenterFrequency(int streamIndex, bool sinkElseSource) const
|
||||
{
|
||||
(void) streamIndex;
|
||||
(void) sinkElseSource;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiWorkspaceGet(
|
||||
SWGSDRangel::SWGWorkspaceInfo& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiReportGet(
|
||||
SWGSDRangel::SWGChannelReport& response,
|
||||
QString& errorMessage);
|
||||
|
||||
static void webapiFormatChannelSettings(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
const NavtexDemodSettings& settings);
|
||||
|
||||
static void webapiUpdateChannelSettings(
|
||||
NavtexDemodSettings& settings,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response);
|
||||
|
||||
ScopeVis *getScopeSink();
|
||||
double getMagSq() const { return m_basebandSink->getMagSq(); }
|
||||
|
||||
void getMagSqLevels(double& avg, double& peak, int& nbSamples) {
|
||||
m_basebandSink->getMagSqLevels(avg, peak, nbSamples);
|
||||
}
|
||||
/* void setMessageQueueToGUI(MessageQueue* queue) override {
|
||||
ChannelAPI::setMessageQueueToGUI(queue);
|
||||
m_basebandSink->setMessageQueueToGUI(queue);
|
||||
}*/
|
||||
|
||||
uint32_t getNumberOfDeviceStreams() const;
|
||||
|
||||
static const char * const m_channelIdURI;
|
||||
static const char * const m_channelId;
|
||||
|
||||
private:
|
||||
DeviceAPI *m_deviceAPI;
|
||||
QThread m_thread;
|
||||
NavtexDemodBaseband* m_basebandSink;
|
||||
NavtexDemodSettings m_settings;
|
||||
int m_basebandSampleRate; //!< stored from device message used when starting baseband sink
|
||||
qint64 m_centerFrequency;
|
||||
QUdpSocket m_udpSocket;
|
||||
QFile m_logFile;
|
||||
QTextStream m_logStream;
|
||||
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
|
||||
virtual bool handleMessage(const Message& cmd);
|
||||
void applySettings(const NavtexDemodSettings& settings, bool force = false);
|
||||
void sendSampleRateToDemodAnalyzer();
|
||||
void webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const NavtexDemodSettings& settings, bool force);
|
||||
void webapiFormatChannelSettings(
|
||||
QList<QString>& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings *swgChannelSettings,
|
||||
const NavtexDemodSettings& settings,
|
||||
bool force
|
||||
);
|
||||
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
||||
|
||||
private slots:
|
||||
void networkManagerFinished(QNetworkReply *reply);
|
||||
void handleIndexInDeviceSetChanged(int index);
|
||||
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NAVTEXDEMOD_H
|
||||
|
181
plugins/channelrx/demodnavtex/navtexdemodbaseband.cpp
Normal file
181
plugins/channelrx/demodnavtex/navtexdemodbaseband.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <QDebug>
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "dsp/downchannelizer.h"
|
||||
|
||||
#include "navtexdemodbaseband.h"
|
||||
|
||||
MESSAGE_CLASS_DEFINITION(NavtexDemodBaseband::MsgConfigureNavtexDemodBaseband, Message)
|
||||
|
||||
NavtexDemodBaseband::NavtexDemodBaseband(NavtexDemod *packetDemod) :
|
||||
m_sink(packetDemod),
|
||||
m_running(false)
|
||||
{
|
||||
qDebug("NavtexDemodBaseband::NavtexDemodBaseband");
|
||||
|
||||
m_sink.setScopeSink(&m_scopeSink);
|
||||
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(48000));
|
||||
m_channelizer = new DownChannelizer(&m_sink);
|
||||
}
|
||||
|
||||
NavtexDemodBaseband::~NavtexDemodBaseband()
|
||||
{
|
||||
m_inputMessageQueue.clear();
|
||||
|
||||
delete m_channelizer;
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::reset()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_inputMessageQueue.clear();
|
||||
m_sampleFifo.reset();
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::startWork()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
QObject::connect(
|
||||
&m_sampleFifo,
|
||||
&SampleSinkFifo::dataReady,
|
||||
this,
|
||||
&NavtexDemodBaseband::handleData,
|
||||
Qt::QueuedConnection
|
||||
);
|
||||
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
m_running = true;
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::stopWork()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
disconnect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
QObject::disconnect(
|
||||
&m_sampleFifo,
|
||||
&SampleSinkFifo::dataReady,
|
||||
this,
|
||||
&NavtexDemodBaseband::handleData
|
||||
);
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::setChannel(ChannelAPI *channel)
|
||||
{
|
||||
m_sink.setChannel(channel);
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
{
|
||||
m_sampleFifo.write(begin, end);
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::handleData()
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
|
||||
while ((m_sampleFifo.fill() > 0) && (m_inputMessageQueue.size() == 0))
|
||||
{
|
||||
SampleVector::iterator part1begin;
|
||||
SampleVector::iterator part1end;
|
||||
SampleVector::iterator part2begin;
|
||||
SampleVector::iterator part2end;
|
||||
|
||||
std::size_t count = m_sampleFifo.readBegin(m_sampleFifo.fill(), &part1begin, &part1end, &part2begin, &part2end);
|
||||
|
||||
// first part of FIFO data
|
||||
if (part1begin != part1end) {
|
||||
m_channelizer->feed(part1begin, part1end);
|
||||
}
|
||||
|
||||
// second part of FIFO data (used when block wraps around)
|
||||
if(part2begin != part2end) {
|
||||
m_channelizer->feed(part2begin, part2end);
|
||||
}
|
||||
|
||||
m_sampleFifo.readCommit((unsigned int) count);
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::handleInputMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = m_inputMessageQueue.pop()) != nullptr)
|
||||
{
|
||||
if (handleMessage(*message)) {
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NavtexDemodBaseband::handleMessage(const Message& cmd)
|
||||
{
|
||||
if (MsgConfigureNavtexDemodBaseband::match(cmd))
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
MsgConfigureNavtexDemodBaseband& cfg = (MsgConfigureNavtexDemodBaseband&) cmd;
|
||||
qDebug() << "NavtexDemodBaseband::handleMessage: MsgConfigureNavtexDemodBaseband";
|
||||
|
||||
applySettings(cfg.getSettings(), cfg.getForce());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(cmd))
|
||||
{
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
|
||||
qDebug() << "NavtexDemodBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " << notif.getSampleRate();
|
||||
setBasebandSampleRate(notif.getSampleRate());
|
||||
m_sampleFifo.setSize(SampleSinkFifo::getSizePolicy(notif.getSampleRate()));
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::applySettings(const NavtexDemodSettings& settings, bool force)
|
||||
{
|
||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || force)
|
||||
{
|
||||
m_channelizer->setChannelization(NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE, settings.m_inputFrequencyOffset);
|
||||
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
|
||||
}
|
||||
|
||||
m_sink.applySettings(settings, force);
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
||||
int NavtexDemodBaseband::getChannelSampleRate() const
|
||||
{
|
||||
return m_channelizer->getChannelSampleRate();
|
||||
}
|
||||
|
||||
void NavtexDemodBaseband::setBasebandSampleRate(int sampleRate)
|
||||
{
|
||||
m_channelizer->setBasebandSampleRate(sampleRate);
|
||||
m_sink.applyChannelSettings(m_channelizer->getChannelSampleRate(), m_channelizer->getChannelFrequencyOffset());
|
||||
}
|
||||
|
103
plugins/channelrx/demodnavtex/navtexdemodbaseband.h
Normal file
103
plugins/channelrx/demodnavtex/navtexdemodbaseband.h
Normal file
@ -0,0 +1,103 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMODBASEBAND_H
|
||||
#define INCLUDE_NAVTEXDEMODBASEBAND_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QRecursiveMutex>
|
||||
|
||||
#include "dsp/samplesinkfifo.h"
|
||||
#include "dsp/scopevis.h"
|
||||
#include "util/message.h"
|
||||
#include "util/messagequeue.h"
|
||||
|
||||
#include "navtexdemodsink.h"
|
||||
|
||||
class DownChannelizer;
|
||||
class ChannelAPI;
|
||||
class NavtexDemod;
|
||||
class ScopeVis;
|
||||
|
||||
class NavtexDemodBaseband : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
class MsgConfigureNavtexDemodBaseband : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
const NavtexDemodSettings& getSettings() const { return m_settings; }
|
||||
bool getForce() const { return m_force; }
|
||||
|
||||
static MsgConfigureNavtexDemodBaseband* create(const NavtexDemodSettings& settings, bool force)
|
||||
{
|
||||
return new MsgConfigureNavtexDemodBaseband(settings, force);
|
||||
}
|
||||
|
||||
private:
|
||||
NavtexDemodSettings m_settings;
|
||||
bool m_force;
|
||||
|
||||
MsgConfigureNavtexDemodBaseband(const NavtexDemodSettings& settings, bool force) :
|
||||
Message(),
|
||||
m_settings(settings),
|
||||
m_force(force)
|
||||
{ }
|
||||
};
|
||||
|
||||
NavtexDemodBaseband(NavtexDemod *packetDemod);
|
||||
~NavtexDemodBaseband();
|
||||
void reset();
|
||||
void startWork();
|
||||
void stopWork();
|
||||
void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
||||
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
|
||||
void getMagSqLevels(double& avg, double& peak, int& nbSamples) {
|
||||
m_sink.getMagSqLevels(avg, peak, nbSamples);
|
||||
}
|
||||
void setMessageQueueToChannel(MessageQueue *messageQueue) { m_sink.setMessageQueueToChannel(messageQueue); }
|
||||
void setBasebandSampleRate(int sampleRate);
|
||||
int getChannelSampleRate() const;
|
||||
ScopeVis *getScopeSink() { return &m_scopeSink; }
|
||||
void setChannel(ChannelAPI *channel);
|
||||
double getMagSq() const { return m_sink.getMagSq(); }
|
||||
bool isRunning() const { return m_running; }
|
||||
void setFifoLabel(const QString& label) { m_sampleFifo.setLabel(label); }
|
||||
|
||||
private:
|
||||
SampleSinkFifo m_sampleFifo;
|
||||
DownChannelizer *m_channelizer;
|
||||
NavtexDemodSink m_sink;
|
||||
MessageQueue m_inputMessageQueue; //!< Queue for asynchronous inbound communication
|
||||
NavtexDemodSettings m_settings;
|
||||
ScopeVis m_scopeSink;
|
||||
bool m_running;
|
||||
QRecursiveMutex m_mutex;
|
||||
|
||||
bool handleMessage(const Message& cmd);
|
||||
void calculateOffset(NavtexDemodSink *sink);
|
||||
void applySettings(const NavtexDemodSettings& settings, bool force = false);
|
||||
|
||||
private slots:
|
||||
void handleInputMessages();
|
||||
void handleData(); //!< Handle data when samples have to be processed
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NAVTEXDEMODBASEBAND_H
|
||||
|
878
plugins/channelrx/demodnavtex/navtexdemodgui.cpp
Normal file
878
plugins/channelrx/demodnavtex/navtexdemodgui.cpp
Normal file
@ -0,0 +1,878 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <QDockWidget>
|
||||
#include <QMainWindow>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QAction>
|
||||
#include <QClipboard>
|
||||
#include <QFileDialog>
|
||||
#include <QScrollBar>
|
||||
#include <QMenu>
|
||||
|
||||
#include "navtexdemodgui.h"
|
||||
|
||||
#include "device/deviceuiset.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
#include "ui_navtexdemodgui.h"
|
||||
#include "plugin/pluginapi.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/csv.h"
|
||||
#include "util/db.h"
|
||||
#include "util/morse.h"
|
||||
#include "util/units.h"
|
||||
#include "gui/basicchannelsettingsdialog.h"
|
||||
#include "gui/devicestreamselectiondialog.h"
|
||||
#include "gui/decimaldelegate.h"
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/glscopesettings.h"
|
||||
#include "gui/crightclickenabler.h"
|
||||
#include "gui/tabletapandhold.h"
|
||||
#include "gui/dialogpositioner.h"
|
||||
#include "channel/channelwebapiutils.h"
|
||||
#include "feature/featurewebapiutils.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "navtexdemod.h"
|
||||
#include "navtexdemodsink.h"
|
||||
|
||||
void NavtexDemodGUI::resizeTable()
|
||||
{
|
||||
// Fill table with a row of dummy data that will size the columns nicely
|
||||
// Trailing spaces are for sort arrow
|
||||
int row = ui->messages->rowCount();
|
||||
ui->messages->setRowCount(row + 1);
|
||||
ui->messages->setItem(row, MESSAGE_COL_DATE, new QTableWidgetItem("15/04/2016-"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_TIME, new QTableWidgetItem("10:17"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_STATION_ID, new QTableWidgetItem("A"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_STATION, new QTableWidgetItem("Netherlands"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_TYPE_ID, new QTableWidgetItem("B"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_TYPE, new QTableWidgetItem("Meteorological\nwarning"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_MESSAGE_ID, new QTableWidgetItem("12"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_MESSAGE, new QTableWidgetItem("ABCEDGHIJKLMNOPQRSTUVWXYZ\n123456789"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_ERRORS, new QTableWidgetItem("100"));
|
||||
ui->messages->setItem(row, MESSAGE_COL_ERROR_PERCENT, new QTableWidgetItem("10.0%"));
|
||||
ui->messages->resizeColumnsToContents();
|
||||
ui->messages->removeRow(row);
|
||||
}
|
||||
|
||||
// Columns in table reordered
|
||||
void NavtexDemodGUI::messages_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
|
||||
{
|
||||
(void) oldVisualIndex;
|
||||
|
||||
m_settings.m_columnIndexes[logicalIndex] = newVisualIndex;
|
||||
}
|
||||
|
||||
// Column in table resized (when hidden size is 0)
|
||||
void NavtexDemodGUI::messages_sectionResized(int logicalIndex, int oldSize, int newSize)
|
||||
{
|
||||
(void) oldSize;
|
||||
|
||||
m_settings.m_columnSizes[logicalIndex] = newSize;
|
||||
}
|
||||
|
||||
// Right click in table header - show column select menu
|
||||
void NavtexDemodGUI::columnSelectMenu(QPoint pos)
|
||||
{
|
||||
menu->popup(ui->messages->horizontalHeader()->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
// Hide/show column when menu selected
|
||||
void NavtexDemodGUI::columnSelectMenuChecked(bool checked)
|
||||
{
|
||||
(void) checked;
|
||||
|
||||
QAction* action = qobject_cast<QAction*>(sender());
|
||||
if (action != nullptr)
|
||||
{
|
||||
int idx = action->data().toInt(nullptr);
|
||||
ui->messages->setColumnHidden(idx, !action->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
// Create column select menu item
|
||||
QAction *NavtexDemodGUI::createCheckableItem(QString &text, int idx, bool checked)
|
||||
{
|
||||
QAction *action = new QAction(text, this);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(checked);
|
||||
action->setData(QVariant(idx));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(columnSelectMenuChecked()));
|
||||
return action;
|
||||
}
|
||||
|
||||
NavtexDemodGUI* NavtexDemodGUI::create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel)
|
||||
{
|
||||
NavtexDemodGUI* gui = new NavtexDemodGUI(pluginAPI, deviceUISet, rxChannel);
|
||||
return gui;
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::resetToDefaults()
|
||||
{
|
||||
m_settings.resetToDefaults();
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
}
|
||||
|
||||
QByteArray NavtexDemodGUI::serialize() const
|
||||
{
|
||||
return m_settings.serialize();
|
||||
}
|
||||
|
||||
bool NavtexDemodGUI::deserialize(const QByteArray& data)
|
||||
{
|
||||
if(m_settings.deserialize(data)) {
|
||||
displaySettings();
|
||||
applySettings(true);
|
||||
return true;
|
||||
} else {
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 NavtexDemodGUI::getFrequency()
|
||||
{
|
||||
qint64 frequency;
|
||||
|
||||
// m_deviceCenterFrequency may sometimes be 0 if using file source
|
||||
frequency = (m_deviceCenterFrequency ? m_deviceCenterFrequency : 518000) + m_settings.m_inputFrequencyOffset;
|
||||
|
||||
return ((frequency + 500) / 1000) * 1000; // Round to nearest kHz
|
||||
}
|
||||
|
||||
// Add row to table
|
||||
void NavtexDemodGUI::messageReceived(const NavtexMessage& message, int errors, float rssi)
|
||||
{
|
||||
// Is scroll bar at bottom
|
||||
QScrollBar *sb = ui->messages->verticalScrollBar();
|
||||
bool scrollToBottom = sb->value() == sb->maximum();
|
||||
|
||||
ui->messages->setSortingEnabled(false);
|
||||
int row = ui->messages->rowCount();
|
||||
ui->messages->setRowCount(row + 1);
|
||||
|
||||
QTableWidgetItem *dateItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *timeItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *stationIdItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *stationItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *typeIdItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *typeItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *messageIdItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *messageItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *errorsItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *errorPercentItem = new QTableWidgetItem();
|
||||
QTableWidgetItem *rssiItem = new QTableWidgetItem();
|
||||
ui->messages->setItem(row, MESSAGE_COL_DATE, dateItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_TIME, timeItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_STATION_ID, stationIdItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_STATION, stationItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_TYPE_ID, typeIdItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_TYPE, typeItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_MESSAGE_ID, messageIdItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_MESSAGE, messageItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_ERRORS, errorsItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_ERROR_PERCENT, errorPercentItem);
|
||||
ui->messages->setItem(row, MESSAGE_COL_RSSI, rssiItem);
|
||||
|
||||
dateItem->setData(Qt::DisplayRole, message.m_dateTime.date());
|
||||
timeItem->setData(Qt::DisplayRole, message.m_dateTime.time());
|
||||
if (message.m_valid)
|
||||
{
|
||||
QString station = message.getStation(m_settings.m_navArea, getFrequency());
|
||||
QString type = message.getType();
|
||||
stationIdItem->setText(message.m_stationId);
|
||||
stationItem->setText(station);
|
||||
typeIdItem->setText(message.m_typeId);
|
||||
typeItem->setText(type);
|
||||
messageIdItem->setText(message.m_id);
|
||||
// Add to filter comboboxes
|
||||
if (!station.isEmpty() && (ui->filterStation->findText(station) == -1)) {
|
||||
ui->filterStation->addItem(station);
|
||||
}
|
||||
if (!type.isEmpty() && (ui->filterType->findText(type) == -1)) {
|
||||
ui->filterType->addItem(type);
|
||||
}
|
||||
errorsItem->setData(Qt::DisplayRole, errors);
|
||||
float errorPC = 100.0f * errors / (message.m_message.size() * 2.0f); // SITOR-B sends each character twice
|
||||
errorPercentItem->setData(Qt::DisplayRole, errorPC);
|
||||
rssiItem->setData(Qt::DisplayRole, rssi);
|
||||
}
|
||||
messageItem->setText(message.m_message);
|
||||
ui->messages->setSortingEnabled(true);
|
||||
ui->messages->resizeRowToContents(row);
|
||||
if (scrollToBottom) {
|
||||
ui->messages->scrollToBottom();
|
||||
}
|
||||
filterRow(row);
|
||||
}
|
||||
|
||||
bool NavtexDemodGUI::handleMessage(const Message& message)
|
||||
{
|
||||
if (NavtexDemod::MsgConfigureNavtexDemod::match(message))
|
||||
{
|
||||
qDebug("NavtexDemodGUI::handleMessage: NavtexDemod::MsgConfigureNavtexDemod");
|
||||
const NavtexDemod::MsgConfigureNavtexDemod& cfg = (NavtexDemod::MsgConfigureNavtexDemod&) message;
|
||||
m_settings = cfg.getSettings();
|
||||
blockApplySettings(true);
|
||||
ui->scopeGUI->updateSettings();
|
||||
m_channelMarker.updateSettings(static_cast<const ChannelMarker*>(m_settings.m_channelMarker));
|
||||
displaySettings();
|
||||
blockApplySettings(false);
|
||||
return true;
|
||||
}
|
||||
else if (DSPSignalNotification::match(message))
|
||||
{
|
||||
DSPSignalNotification& notif = (DSPSignalNotification&) message;
|
||||
m_deviceCenterFrequency = notif.getCenterFrequency();
|
||||
m_basebandSampleRate = notif.getSampleRate();
|
||||
ui->deltaFrequency->setValueRange(false, 7, -m_basebandSampleRate/2, m_basebandSampleRate/2);
|
||||
ui->deltaFrequencyLabel->setToolTip(tr("Range %1 %L2 Hz").arg(QChar(0xB1)).arg(m_basebandSampleRate/2));
|
||||
updateAbsoluteCenterFrequency();
|
||||
return true;
|
||||
}
|
||||
else if (NavtexDemod::MsgCharacter::match(message))
|
||||
{
|
||||
NavtexDemod::MsgCharacter& report = (NavtexDemod::MsgCharacter&) message;
|
||||
QString c = report.getCharacter();
|
||||
|
||||
// Is the scroll bar at the bottom?
|
||||
int scrollPos = ui->text->verticalScrollBar()->value();
|
||||
bool atBottom = scrollPos >= ui->text->verticalScrollBar()->maximum();
|
||||
|
||||
// Move cursor to end where we want to append new text
|
||||
// (user may have moved it by clicking / highlighting text)
|
||||
ui->text->moveCursor(QTextCursor::End);
|
||||
|
||||
// Restore scroll position
|
||||
ui->text->verticalScrollBar()->setValue(scrollPos);
|
||||
|
||||
if (c == '\b') {
|
||||
ui->text->textCursor().deletePreviousChar();
|
||||
} else {
|
||||
ui->text->insertPlainText(c);
|
||||
}
|
||||
|
||||
// Scroll to bottom, if we we're previously at the bottom
|
||||
if (atBottom) {
|
||||
ui->text->verticalScrollBar()->setValue(ui->text->verticalScrollBar()->maximum());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (NavtexDemod::MsgMessage::match(message))
|
||||
{
|
||||
NavtexDemod::MsgMessage& textMsg = (NavtexDemod::MsgMessage&) message;
|
||||
messageReceived(textMsg.getMessage(), textMsg.getErrors(), textMsg.getRSSI());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::handleInputMessages()
|
||||
{
|
||||
Message* message;
|
||||
|
||||
while ((message = getInputMessageQueue()->pop()) != 0)
|
||||
{
|
||||
if (handleMessage(*message))
|
||||
{
|
||||
delete message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::channelMarkerChangedByCursor()
|
||||
{
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::channelMarkerHighlightedByCursor()
|
||||
{
|
||||
setHighlighted(m_channelMarker.getHighlighted());
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::updateTxStation()
|
||||
{
|
||||
const NavtexTransmitter *transmitter = NavtexTransmitter::getTransmitter(QDateTime::currentDateTimeUtc().time(),
|
||||
m_settings.m_navArea,
|
||||
getFrequency());
|
||||
if (transmitter)
|
||||
{
|
||||
ui->txStation->setText(transmitter->m_station);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->txStation->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_findOnMapFeature_clicked()
|
||||
{
|
||||
QString station = ui->txStation->text();
|
||||
if (!station.isEmpty()) {
|
||||
FeatureWebAPIUtils::mapFind(station);
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
m_settings.m_inputFrequencyOffset = m_channelMarker.getCenterFrequency();
|
||||
updateAbsoluteCenterFrequency();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_rfBW_valueChanged(int value)
|
||||
{
|
||||
float bw = value;
|
||||
ui->rfBWText->setText(QString("%1 Hz").arg((int)bw));
|
||||
m_channelMarker.setBandwidth(bw);
|
||||
m_settings.m_rfBandwidth = bw;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_filterStation_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_filterStation = ui->filterStation->currentText();
|
||||
filter();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_filterType_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_filterType = ui->filterType->currentText();
|
||||
filter();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_clearTable_clicked()
|
||||
{
|
||||
ui->messages->setRowCount(0);
|
||||
ui->text->clear();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_udpEnabled_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_udpEnabled = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_udpAddress_editingFinished()
|
||||
{
|
||||
m_settings.m_udpAddress = ui->udpAddress->text();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_udpPort_editingFinished()
|
||||
{
|
||||
m_settings.m_udpPort = ui->udpPort->text().toInt();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::filterRow(int row)
|
||||
{
|
||||
bool hidden = false;
|
||||
if ((m_settings.m_filterStation != "") && (m_settings.m_filterStation != "All"))
|
||||
{
|
||||
QTableWidgetItem *stationItem = ui->messages->item(row, MESSAGE_COL_STATION);
|
||||
if (m_settings.m_filterStation != stationItem->text()) {
|
||||
hidden = true;
|
||||
}
|
||||
}
|
||||
if ((m_settings.m_filterType != "") && (m_settings.m_filterType != "All"))
|
||||
{
|
||||
QTableWidgetItem *typeItem = ui->messages->item(row, MESSAGE_COL_TYPE);
|
||||
if (m_settings.m_filterType != typeItem->text()) {
|
||||
hidden = true;
|
||||
}
|
||||
}
|
||||
ui->messages->setRowHidden(row, hidden);
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::filter()
|
||||
{
|
||||
for (int i = 0; i < ui->messages->rowCount(); i++) {
|
||||
filterRow(i);
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_navArea_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_navArea = index + 1;
|
||||
updateTxStation();
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_channel1_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_scopeCh1 = index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_channel2_currentIndexChanged(int index)
|
||||
{
|
||||
m_settings.m_scopeCh2 = index;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::onWidgetRolled(QWidget* widget, bool rollDown)
|
||||
{
|
||||
(void) widget;
|
||||
(void) rollDown;
|
||||
|
||||
getRollupContents()->saveState(m_rollupState);
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::onMenuDialogCalled(const QPoint &p)
|
||||
{
|
||||
if (m_contextMenuType == ContextMenuChannelSettings)
|
||||
{
|
||||
BasicChannelSettingsDialog dialog(&m_channelMarker, this);
|
||||
dialog.setUseReverseAPI(m_settings.m_useReverseAPI);
|
||||
dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress);
|
||||
dialog.setReverseAPIPort(m_settings.m_reverseAPIPort);
|
||||
dialog.setReverseAPIDeviceIndex(m_settings.m_reverseAPIDeviceIndex);
|
||||
dialog.setReverseAPIChannelIndex(m_settings.m_reverseAPIChannelIndex);
|
||||
dialog.setDefaultTitle(m_displayedName);
|
||||
|
||||
if (m_deviceUISet->m_deviceMIMOEngine)
|
||||
{
|
||||
dialog.setNumberOfStreams(m_navtexDemod->getNumberOfDeviceStreams());
|
||||
dialog.setStreamIndex(m_settings.m_streamIndex);
|
||||
}
|
||||
|
||||
dialog.move(p);
|
||||
new DialogPositioner(&dialog, false);
|
||||
dialog.exec();
|
||||
|
||||
m_settings.m_rgbColor = m_channelMarker.getColor().rgb();
|
||||
m_settings.m_title = m_channelMarker.getTitle();
|
||||
m_settings.m_useReverseAPI = dialog.useReverseAPI();
|
||||
m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress();
|
||||
m_settings.m_reverseAPIPort = dialog.getReverseAPIPort();
|
||||
m_settings.m_reverseAPIDeviceIndex = dialog.getReverseAPIDeviceIndex();
|
||||
m_settings.m_reverseAPIChannelIndex = dialog.getReverseAPIChannelIndex();
|
||||
|
||||
setWindowTitle(m_settings.m_title);
|
||||
setTitle(m_channelMarker.getTitle());
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
|
||||
if (m_deviceUISet->m_deviceMIMOEngine)
|
||||
{
|
||||
m_settings.m_streamIndex = dialog.getSelectedStreamIndex();
|
||||
m_channelMarker.clearStreamIndexes();
|
||||
m_channelMarker.addStreamIndex(m_settings.m_streamIndex);
|
||||
updateIndexLabel();
|
||||
}
|
||||
|
||||
applySettings();
|
||||
}
|
||||
|
||||
resetContextMenuType();
|
||||
}
|
||||
|
||||
NavtexDemodGUI::NavtexDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent) :
|
||||
ChannelGUI(parent),
|
||||
ui(new Ui::NavtexDemodGUI),
|
||||
m_pluginAPI(pluginAPI),
|
||||
m_deviceUISet(deviceUISet),
|
||||
m_channelMarker(this),
|
||||
m_deviceCenterFrequency(0),
|
||||
m_doApplySettings(true),
|
||||
m_tickCount(0)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
m_helpURL = "plugins/channelrx/demodnavtex/readme.md";
|
||||
RollupContents *rollupContents = getRollupContents();
|
||||
ui->setupUi(rollupContents);
|
||||
setSizePolicy(rollupContents->sizePolicy());
|
||||
rollupContents->arrangeRollups();
|
||||
connect(rollupContents, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool)));
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
|
||||
|
||||
m_navtexDemod = reinterpret_cast<NavtexDemod*>(rxChannel);
|
||||
m_navtexDemod->setMessageQueueToGUI(getInputMessageQueue());
|
||||
|
||||
connect(&MainCore::instance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick())); // 50 ms
|
||||
|
||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
ui->channelPowerMeter->setColorTheme(LevelMeterSignalDB::ColorGreenAndBlue);
|
||||
|
||||
ui->messages->setItemDelegateForColumn(MESSAGE_COL_ERROR_PERCENT, new DecimalDelegate(1));
|
||||
ui->messages->setItemDelegateForColumn(MESSAGE_COL_RSSI, new DecimalDelegate(1));
|
||||
|
||||
m_scopeVis = m_navtexDemod->getScopeSink();
|
||||
m_scopeVis->setGLScope(ui->glScope);
|
||||
ui->glScope->connectTimer(MainCore::instance()->getMasterTimer());
|
||||
ui->scopeGUI->setBuddies(m_scopeVis->getInputMessageQueue(), m_scopeVis, ui->glScope);
|
||||
|
||||
// Scope settings to display the IQ waveforms
|
||||
ui->scopeGUI->setPreTrigger(1);
|
||||
GLScopeSettings::TraceData traceDataI, traceDataQ;
|
||||
traceDataI.m_projectionType = Projector::ProjectionReal;
|
||||
traceDataI.m_amp = 1.0; // for -1 to +1
|
||||
traceDataI.m_ofs = 0.0; // vertical offset
|
||||
traceDataQ.m_projectionType = Projector::ProjectionImag;
|
||||
traceDataQ.m_amp = 1.0;
|
||||
traceDataQ.m_ofs = 0.0;
|
||||
ui->scopeGUI->changeTrace(0, traceDataI);
|
||||
ui->scopeGUI->addTrace(traceDataQ);
|
||||
ui->scopeGUI->setDisplayMode(GLScopeSettings::DisplayXYV);
|
||||
ui->scopeGUI->focusOnTrace(0); // re-focus to take changes into account in the GUI
|
||||
|
||||
GLScopeSettings::TriggerData triggerData;
|
||||
triggerData.m_triggerLevel = 0.1;
|
||||
triggerData.m_triggerLevelCoarse = 10;
|
||||
triggerData.m_triggerPositiveEdge = true;
|
||||
ui->scopeGUI->changeTrigger(0, triggerData);
|
||||
ui->scopeGUI->focusOnTrigger(0); // re-focus to take changes into account in the GUI
|
||||
|
||||
m_scopeVis->setLiveRate(NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE);
|
||||
m_scopeVis->configure(500, 1, 0, 0, true); // not working!
|
||||
//m_scopeVis->setFreeRun(false); // FIXME: add method rather than call m_scopeVis->configure()
|
||||
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setColor(Qt::yellow);
|
||||
m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
|
||||
m_channelMarker.setTitle("Navtex Demodulator");
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setVisible(true); // activate signal on the last setting only
|
||||
|
||||
setTitleColor(m_channelMarker.getColor());
|
||||
m_settings.setChannelMarker(&m_channelMarker);
|
||||
m_settings.setScopeGUI(ui->scopeGUI);
|
||||
m_settings.setRollupState(&m_rollupState);
|
||||
|
||||
m_deviceUISet->addChannelMarker(&m_channelMarker);
|
||||
|
||||
connect(&m_channelMarker, SIGNAL(changedByCursor()), this, SLOT(channelMarkerChangedByCursor()));
|
||||
connect(&m_channelMarker, SIGNAL(highlightedByCursor()), this, SLOT(channelMarkerHighlightedByCursor()));
|
||||
connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||
|
||||
// Resize the table using dummy data
|
||||
resizeTable();
|
||||
// Allow user to reorder columns
|
||||
ui->messages->horizontalHeader()->setSectionsMovable(true);
|
||||
// Allow user to sort table by clicking on headers
|
||||
ui->messages->setSortingEnabled(true);
|
||||
// Add context menu to allow hiding/showing of columns
|
||||
menu = new QMenu(ui->messages);
|
||||
for (int i = 0; i < ui->messages->horizontalHeader()->count(); i++)
|
||||
{
|
||||
QString text = ui->messages->horizontalHeaderItem(i)->text();
|
||||
menu->addAction(createCheckableItem(text, i, true));
|
||||
}
|
||||
ui->messages->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->messages->horizontalHeader(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(columnSelectMenu(QPoint)));
|
||||
// Get signals when columns change
|
||||
connect(ui->messages->horizontalHeader(), SIGNAL(sectionMoved(int, int, int)), SLOT(messages_sectionMoved(int, int, int)));
|
||||
connect(ui->messages->horizontalHeader(), SIGNAL(sectionResized(int, int, int)), SLOT(messages_sectionResized(int, int, int)));
|
||||
|
||||
ui->messages->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->messages, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customContextMenuRequested(QPoint)));
|
||||
TableTapAndHold *tableTapAndHold = new TableTapAndHold(ui->messages);
|
||||
connect(tableTapAndHold, &TableTapAndHold::tapAndHold, this, &NavtexDemodGUI::customContextMenuRequested);
|
||||
|
||||
ui->scopeContainer->setVisible(false);
|
||||
|
||||
displaySettings();
|
||||
makeUIConnections();
|
||||
applySettings(true);
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::customContextMenuRequested(QPoint pos)
|
||||
{
|
||||
QTableWidgetItem *item = ui->messages->itemAt(pos);
|
||||
if (item)
|
||||
{
|
||||
int row = item->row();
|
||||
QString station = ui->messages->item(row, MESSAGE_COL_STATION)->text();
|
||||
|
||||
QMenu* tableContextMenu = new QMenu(ui->messages);
|
||||
connect(tableContextMenu, &QMenu::aboutToHide, tableContextMenu, &QMenu::deleteLater);
|
||||
|
||||
QAction* copyAction = new QAction("Copy", tableContextMenu);
|
||||
const QString text = item->text();
|
||||
connect(copyAction, &QAction::triggered, this, [text]()->void {
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(text);
|
||||
});
|
||||
tableContextMenu->addAction(copyAction);
|
||||
|
||||
if (!station.isEmpty())
|
||||
{
|
||||
tableContextMenu->addSeparator();
|
||||
QAction* findOnMapAction = new QAction(QString("Find %1 on map").arg(station), tableContextMenu);
|
||||
connect(findOnMapAction, &QAction::triggered, this, [station]()->void {
|
||||
FeatureWebAPIUtils::mapFind(station);
|
||||
});
|
||||
tableContextMenu->addAction(findOnMapAction);
|
||||
}
|
||||
|
||||
tableContextMenu->popup(ui->messages->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
NavtexDemodGUI::~NavtexDemodGUI()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::blockApplySettings(bool block)
|
||||
{
|
||||
m_doApplySettings = !block;
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::applySettings(bool force)
|
||||
{
|
||||
if (m_doApplySettings)
|
||||
{
|
||||
NavtexDemod::MsgConfigureNavtexDemod* message = NavtexDemod::MsgConfigureNavtexDemod::create( m_settings, force);
|
||||
m_navtexDemod->getInputMessageQueue()->push(message);
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::displaySettings()
|
||||
{
|
||||
m_channelMarker.blockSignals(true);
|
||||
m_channelMarker.setBandwidth(m_settings.m_rfBandwidth);
|
||||
m_channelMarker.setCenterFrequency(m_settings.m_inputFrequencyOffset);
|
||||
m_channelMarker.setTitle(m_settings.m_title);
|
||||
m_channelMarker.blockSignals(false);
|
||||
m_channelMarker.setColor(m_settings.m_rgbColor); // activate signal on the last setting only
|
||||
|
||||
setTitleColor(m_settings.m_rgbColor);
|
||||
setWindowTitle(m_channelMarker.getTitle());
|
||||
setTitle(m_channelMarker.getTitle());
|
||||
|
||||
blockApplySettings(true);
|
||||
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
|
||||
ui->rfBWText->setText(QString("%1 Hz").arg((int)m_settings.m_rfBandwidth));
|
||||
ui->rfBW->setValue(m_settings.m_rfBandwidth);
|
||||
|
||||
ui->navArea->setCurrentIndex(m_settings.m_navArea - 1);
|
||||
|
||||
updateIndexLabel();
|
||||
|
||||
ui->filterStation->setCurrentText(m_settings.m_filterStation);
|
||||
ui->filterType->setCurrentText(m_settings.m_filterType);
|
||||
|
||||
ui->udpEnabled->setChecked(m_settings.m_udpEnabled);
|
||||
ui->udpAddress->setText(m_settings.m_udpAddress);
|
||||
ui->udpPort->setText(QString::number(m_settings.m_udpPort));
|
||||
|
||||
ui->channel1->setCurrentIndex(m_settings.m_scopeCh1);
|
||||
ui->channel2->setCurrentIndex(m_settings.m_scopeCh2);
|
||||
|
||||
ui->logFilename->setToolTip(QString(".csv log filename: %1").arg(m_settings.m_logFilename));
|
||||
ui->logEnable->setChecked(m_settings.m_logEnabled);
|
||||
|
||||
// Order and size columns
|
||||
QHeaderView *header = ui->messages->horizontalHeader();
|
||||
for (int i = 0; i < NAVTEXDEMOD_COLUMNS; i++)
|
||||
{
|
||||
bool hidden = m_settings.m_columnSizes[i] == 0;
|
||||
header->setSectionHidden(i, hidden);
|
||||
menu->actions().at(i)->setChecked(!hidden);
|
||||
if (m_settings.m_columnSizes[i] > 0)
|
||||
ui->messages->setColumnWidth(i, m_settings.m_columnSizes[i]);
|
||||
header->moveSection(header->visualIndex(i), m_settings.m_columnIndexes[i]);
|
||||
}
|
||||
|
||||
filter();
|
||||
|
||||
getRollupContents()->restoreState(m_rollupState);
|
||||
updateAbsoluteCenterFrequency();
|
||||
blockApplySettings(false);
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::leaveEvent(QEvent* event)
|
||||
{
|
||||
m_channelMarker.setHighlighted(false);
|
||||
ChannelGUI::leaveEvent(event);
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::enterEvent(EnterEventType* event)
|
||||
{
|
||||
m_channelMarker.setHighlighted(true);
|
||||
ChannelGUI::enterEvent(event);
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::tick()
|
||||
{
|
||||
double magsqAvg, magsqPeak;
|
||||
int nbMagsqSamples;
|
||||
m_navtexDemod->getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
|
||||
double powDbAvg = CalcDb::dbPower(magsqAvg);
|
||||
double powDbPeak = CalcDb::dbPower(magsqPeak);
|
||||
ui->channelPowerMeter->levelChanged(
|
||||
(100.0f + powDbAvg) / 100.0f,
|
||||
(100.0f + powDbPeak) / 100.0f,
|
||||
nbMagsqSamples);
|
||||
|
||||
if (m_tickCount % 4 == 0) {
|
||||
ui->channelPower->setText(QString::number(powDbAvg, 'f', 1));
|
||||
}
|
||||
if (m_tickCount % (50*10) == 0) {
|
||||
updateTxStation();
|
||||
}
|
||||
|
||||
m_tickCount++;
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_logEnable_clicked(bool checked)
|
||||
{
|
||||
m_settings.m_logEnabled = checked;
|
||||
applySettings();
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::on_logFilename_clicked()
|
||||
{
|
||||
// Get filename to save to
|
||||
QFileDialog fileDialog(nullptr, "Select file to log received messages to", "", "*.csv");
|
||||
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
if (fileDialog.exec())
|
||||
{
|
||||
QStringList fileNames = fileDialog.selectedFiles();
|
||||
if (fileNames.size() > 0)
|
||||
{
|
||||
m_settings.m_logFilename = fileNames[0];
|
||||
ui->logFilename->setToolTip(QString(".csv log filename: %1").arg(m_settings.m_logFilename));
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read .csv log and process as received messages
|
||||
void NavtexDemodGUI::on_logOpen_clicked()
|
||||
{
|
||||
QFileDialog fileDialog(nullptr, "Select .csv log file to read", "", "*.csv");
|
||||
if (fileDialog.exec())
|
||||
{
|
||||
QStringList fileNames = fileDialog.selectedFiles();
|
||||
if (fileNames.size() > 0)
|
||||
{
|
||||
QFile file(fileNames[0]);
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QTextStream in(&file);
|
||||
QString error;
|
||||
QHash<QString, int> colIndexes = CSV::readHeader(in, {"Date", "Time", "SID", "TID", "MID", "Message"}, error);
|
||||
if (error.isEmpty())
|
||||
{
|
||||
int dateCol = colIndexes.value("Date");
|
||||
int timeCol = colIndexes.value("Time");
|
||||
int sidCol = colIndexes.value("SID");
|
||||
int tidCol = colIndexes.value("TID");
|
||||
int midCol = colIndexes.value("MID");
|
||||
int messageCol = colIndexes.value("Message");
|
||||
int errorsCol = colIndexes.value("Errors");
|
||||
int rssiCol = colIndexes.value("RSSI");
|
||||
int maxCol = std::max({dateCol, timeCol, sidCol, tidCol, midCol, messageCol});
|
||||
|
||||
QMessageBox dialog(this);
|
||||
dialog.setText("Reading message data");
|
||||
dialog.addButton(QMessageBox::Cancel);
|
||||
dialog.show();
|
||||
QApplication::processEvents();
|
||||
int count = 0;
|
||||
bool cancelled = false;
|
||||
QStringList cols;
|
||||
while (!cancelled && CSV::readRow(in, &cols))
|
||||
{
|
||||
if (cols.size() > maxCol)
|
||||
{
|
||||
QDate date = QDate::fromString(cols[dateCol]);
|
||||
QTime time = QTime::fromString(cols[timeCol]);
|
||||
QDateTime dateTime(date, time);
|
||||
NavtexMessage message(dateTime,
|
||||
cols[sidCol],
|
||||
cols[tidCol],
|
||||
cols[midCol],
|
||||
cols[messageCol]);
|
||||
int errors = cols[errorsCol].toInt();
|
||||
float rssi = cols[rssiCol].toFloat();
|
||||
messageReceived(message, errors, rssi);
|
||||
if (count % 1000 == 0)
|
||||
{
|
||||
QApplication::processEvents();
|
||||
if (dialog.clickedButton()) {
|
||||
cancelled = true;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
dialog.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, "Navtex Demod", error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, "Navtex Demod", QString("Failed to open file %1").arg(fileNames[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::makeUIConnections()
|
||||
{
|
||||
QObject::connect(ui->deltaFrequency, &ValueDialZ::changed, this, &NavtexDemodGUI::on_deltaFrequency_changed);
|
||||
QObject::connect(ui->rfBW, &QSlider::valueChanged, this, &NavtexDemodGUI::on_rfBW_valueChanged);
|
||||
QObject::connect(ui->navArea, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NavtexDemodGUI::on_navArea_currentIndexChanged);
|
||||
QObject::connect(ui->findOnMapFeature, &QPushButton::clicked, this, &NavtexDemodGUI::on_findOnMapFeature_clicked);
|
||||
QObject::connect(ui->filterStation, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NavtexDemodGUI::on_filterStation_currentIndexChanged);
|
||||
QObject::connect(ui->filterType, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NavtexDemodGUI::on_filterType_currentIndexChanged);
|
||||
QObject::connect(ui->clearTable, &QPushButton::clicked, this, &NavtexDemodGUI::on_clearTable_clicked);
|
||||
QObject::connect(ui->udpEnabled, &QCheckBox::clicked, this, &NavtexDemodGUI::on_udpEnabled_clicked);
|
||||
QObject::connect(ui->udpAddress, &QLineEdit::editingFinished, this, &NavtexDemodGUI::on_udpAddress_editingFinished);
|
||||
QObject::connect(ui->udpPort, &QLineEdit::editingFinished, this, &NavtexDemodGUI::on_udpPort_editingFinished);
|
||||
QObject::connect(ui->logEnable, &ButtonSwitch::clicked, this, &NavtexDemodGUI::on_logEnable_clicked);
|
||||
QObject::connect(ui->logFilename, &QToolButton::clicked, this, &NavtexDemodGUI::on_logFilename_clicked);
|
||||
QObject::connect(ui->logOpen, &QToolButton::clicked, this, &NavtexDemodGUI::on_logOpen_clicked);
|
||||
QObject::connect(ui->channel1, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NavtexDemodGUI::on_channel1_currentIndexChanged);
|
||||
QObject::connect(ui->channel2, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &NavtexDemodGUI::on_channel2_currentIndexChanged);
|
||||
}
|
||||
|
||||
void NavtexDemodGUI::updateAbsoluteCenterFrequency()
|
||||
{
|
||||
setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset);
|
||||
updateTxStation();
|
||||
}
|
||||
|
150
plugins/channelrx/demodnavtex/navtexdemodgui.h
Normal file
150
plugins/channelrx/demodnavtex/navtexdemodgui.h
Normal file
@ -0,0 +1,150 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMODGUI_H
|
||||
#define INCLUDE_NAVTEXDEMODGUI_H
|
||||
|
||||
#include "channel/channelgui.h"
|
||||
#include "dsp/channelmarker.h"
|
||||
#include "dsp/movingaverage.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "settings/rollupstate.h"
|
||||
#include "navtexdemod.h"
|
||||
#include "navtexdemodsettings.h"
|
||||
|
||||
class PluginAPI;
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
class ScopeVis;
|
||||
class NavtexDemod;
|
||||
class NavtexDemodGUI;
|
||||
|
||||
namespace Ui {
|
||||
class NavtexDemodGUI;
|
||||
}
|
||||
class NavtexDemodGUI;
|
||||
|
||||
class NavtexDemodGUI : public ChannelGUI {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static NavtexDemodGUI* create(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel);
|
||||
virtual void destroy();
|
||||
|
||||
void resetToDefaults();
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
|
||||
virtual void setWorkspaceIndex(int index) { m_settings.m_workspaceIndex = index; };
|
||||
virtual int getWorkspaceIndex() const { return m_settings.m_workspaceIndex; };
|
||||
virtual void setGeometryBytes(const QByteArray& blob) { m_settings.m_geometryBytes = blob; };
|
||||
virtual QByteArray getGeometryBytes() const { return m_settings.m_geometryBytes; };
|
||||
virtual QString getTitle() const { return m_settings.m_title; };
|
||||
virtual QColor getTitleColor() const { return m_settings.m_rgbColor; };
|
||||
virtual void zetHidden(bool hidden) { m_settings.m_hidden = hidden; }
|
||||
virtual bool getHidden() const { return m_settings.m_hidden; }
|
||||
virtual ChannelMarker& getChannelMarker() { return m_channelMarker; }
|
||||
virtual int getStreamIndex() const { return m_settings.m_streamIndex; }
|
||||
virtual void setStreamIndex(int streamIndex) { m_settings.m_streamIndex = streamIndex; }
|
||||
|
||||
public slots:
|
||||
void channelMarkerChangedByCursor();
|
||||
void channelMarkerHighlightedByCursor();
|
||||
|
||||
private:
|
||||
Ui::NavtexDemodGUI* ui;
|
||||
PluginAPI* m_pluginAPI;
|
||||
DeviceUISet* m_deviceUISet;
|
||||
ChannelMarker m_channelMarker;
|
||||
RollupState m_rollupState;
|
||||
NavtexDemodSettings m_settings;
|
||||
qint64 m_deviceCenterFrequency;
|
||||
bool m_doApplySettings;
|
||||
ScopeVis* m_scopeVis;
|
||||
|
||||
NavtexDemod* m_navtexDemod;
|
||||
int m_basebandSampleRate;
|
||||
uint32_t m_tickCount;
|
||||
MessageQueue m_inputMessageQueue;
|
||||
|
||||
QMenu *menu; // Column select context menu
|
||||
|
||||
enum MessageCol {
|
||||
MESSAGE_COL_DATE,
|
||||
MESSAGE_COL_TIME,
|
||||
MESSAGE_COL_STATION_ID,
|
||||
MESSAGE_COL_STATION,
|
||||
MESSAGE_COL_TYPE_ID,
|
||||
MESSAGE_COL_TYPE,
|
||||
MESSAGE_COL_MESSAGE_ID,
|
||||
MESSAGE_COL_MESSAGE,
|
||||
MESSAGE_COL_ERRORS,
|
||||
MESSAGE_COL_ERROR_PERCENT,
|
||||
MESSAGE_COL_RSSI
|
||||
};
|
||||
|
||||
explicit NavtexDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel, QWidget* parent = 0);
|
||||
virtual ~NavtexDemodGUI();
|
||||
|
||||
void blockApplySettings(bool block);
|
||||
void applySettings(bool force = false);
|
||||
void displaySettings();
|
||||
void messageReceived(const NavtexMessage& message, int errors, float rssi);
|
||||
bool handleMessage(const Message& message);
|
||||
void makeUIConnections();
|
||||
void updateAbsoluteCenterFrequency();
|
||||
void updateTxStation();
|
||||
qint64 getFrequency();
|
||||
|
||||
void leaveEvent(QEvent*);
|
||||
void enterEvent(EnterEventType*);
|
||||
|
||||
void resizeTable();
|
||||
QAction *createCheckableItem(QString& text, int idx, bool checked);
|
||||
|
||||
private slots:
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_rfBW_valueChanged(int index);
|
||||
void on_navArea_currentIndexChanged(int index);
|
||||
void on_findOnMapFeature_clicked();
|
||||
void on_filterStation_currentIndexChanged(int index);
|
||||
void on_filterType_currentIndexChanged(int index);
|
||||
void on_clearTable_clicked();
|
||||
void on_udpEnabled_clicked(bool checked);
|
||||
void on_udpAddress_editingFinished();
|
||||
void on_udpPort_editingFinished();
|
||||
void on_logEnable_clicked(bool checked=false);
|
||||
void on_logFilename_clicked();
|
||||
void on_logOpen_clicked();
|
||||
void on_channel1_currentIndexChanged(int index);
|
||||
void on_channel2_currentIndexChanged(int index);
|
||||
void filterRow(int row);
|
||||
void filter();
|
||||
void messages_sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex);
|
||||
void messages_sectionResized(int logicalIndex, int oldSize, int newSize);
|
||||
void columnSelectMenu(QPoint pos);
|
||||
void columnSelectMenuChecked(bool checked = false);
|
||||
void customContextMenuRequested(QPoint point);
|
||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||
void onMenuDialogCalled(const QPoint& p);
|
||||
void handleInputMessages();
|
||||
void tick();
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NAVTEXDEMODGUI_H
|
||||
|
1140
plugins/channelrx/demodnavtex/navtexdemodgui.ui
Normal file
1140
plugins/channelrx/demodnavtex/navtexdemodgui.ui
Normal file
File diff suppressed because it is too large
Load Diff
93
plugins/channelrx/demodnavtex/navtexdemodplugin.cpp
Normal file
93
plugins/channelrx/demodnavtex/navtexdemodplugin.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <QtPlugin>
|
||||
#include "plugin/pluginapi.h"
|
||||
|
||||
#ifndef SERVER_MODE
|
||||
#include "navtexdemodgui.h"
|
||||
#endif
|
||||
#include "navtexdemod.h"
|
||||
#include "navtexdemodwebapiadapter.h"
|
||||
#include "navtexdemodplugin.h"
|
||||
|
||||
const PluginDescriptor NavtexDemodPlugin::m_pluginDescriptor = {
|
||||
NavtexDemod::m_channelId,
|
||||
QStringLiteral("Navtex Demodulator"),
|
||||
QStringLiteral("7.11.0"),
|
||||
QStringLiteral("(c) Jon Beniston, M7RCE"),
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel"),
|
||||
true,
|
||||
QStringLiteral("https://github.com/f4exb/sdrangel")
|
||||
};
|
||||
|
||||
NavtexDemodPlugin::NavtexDemodPlugin(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_pluginAPI(0)
|
||||
{
|
||||
}
|
||||
|
||||
const PluginDescriptor& NavtexDemodPlugin::getPluginDescriptor() const
|
||||
{
|
||||
return m_pluginDescriptor;
|
||||
}
|
||||
|
||||
void NavtexDemodPlugin::initPlugin(PluginAPI* pluginAPI)
|
||||
{
|
||||
m_pluginAPI = pluginAPI;
|
||||
|
||||
m_pluginAPI->registerRxChannel(NavtexDemod::m_channelIdURI, NavtexDemod::m_channelId, this);
|
||||
}
|
||||
|
||||
void NavtexDemodPlugin::createRxChannel(DeviceAPI *deviceAPI, BasebandSampleSink **bs, ChannelAPI **cs) const
|
||||
{
|
||||
if (bs || cs)
|
||||
{
|
||||
NavtexDemod *instance = new NavtexDemod(deviceAPI);
|
||||
|
||||
if (bs) {
|
||||
*bs = instance;
|
||||
}
|
||||
|
||||
if (cs) {
|
||||
*cs = instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERVER_MODE
|
||||
ChannelGUI* NavtexDemodPlugin::createRxChannelGUI(
|
||||
DeviceUISet *deviceUISet,
|
||||
BasebandSampleSink *rxChannel) const
|
||||
{
|
||||
(void) deviceUISet;
|
||||
(void) rxChannel;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
ChannelGUI* NavtexDemodPlugin::createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) const
|
||||
{
|
||||
return NavtexDemodGUI::create(m_pluginAPI, deviceUISet, rxChannel);
|
||||
}
|
||||
#endif
|
||||
|
||||
ChannelWebAPIAdapter* NavtexDemodPlugin::createChannelWebAPIAdapter() const
|
||||
{
|
||||
return new NavtexDemodWebAPIAdapter();
|
||||
}
|
||||
|
50
plugins/channelrx/demodnavtex/navtexdemodplugin.h
Normal file
50
plugins/channelrx/demodnavtex/navtexdemodplugin.h
Normal file
@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMODPLUGIN_H
|
||||
#define INCLUDE_NAVTEXDEMODPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#include "plugin/plugininterface.h"
|
||||
|
||||
class DeviceUISet;
|
||||
class BasebandSampleSink;
|
||||
|
||||
class NavtexDemodPlugin : public QObject, PluginInterface {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(PluginInterface)
|
||||
Q_PLUGIN_METADATA(IID "sdrangel.channel.navtexdemod")
|
||||
|
||||
public:
|
||||
explicit NavtexDemodPlugin(QObject* parent = NULL);
|
||||
|
||||
const PluginDescriptor& getPluginDescriptor() const;
|
||||
void initPlugin(PluginAPI* pluginAPI);
|
||||
|
||||
virtual void createRxChannel(DeviceAPI *deviceAPI, BasebandSampleSink **bs, ChannelAPI **cs) const;
|
||||
virtual ChannelGUI* createRxChannelGUI(DeviceUISet *deviceUISet, BasebandSampleSink *rxChannel) const;
|
||||
virtual ChannelWebAPIAdapter* createChannelWebAPIAdapter() const;
|
||||
|
||||
private:
|
||||
static const PluginDescriptor m_pluginDescriptor;
|
||||
|
||||
PluginAPI* m_pluginAPI;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NAVTEXDEMODPLUGIN_H
|
||||
|
209
plugins/channelrx/demodnavtex/navtexdemodsettings.cpp
Normal file
209
plugins/channelrx/demodnavtex/navtexdemodsettings.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2015 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <QColor>
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "settings/serializable.h"
|
||||
#include "navtexdemodsettings.h"
|
||||
|
||||
NavtexDemodSettings::NavtexDemodSettings() :
|
||||
m_channelMarker(nullptr),
|
||||
m_scopeGUI(nullptr),
|
||||
m_rollupState(nullptr)
|
||||
{
|
||||
resetToDefaults();
|
||||
}
|
||||
|
||||
void NavtexDemodSettings::resetToDefaults()
|
||||
{
|
||||
m_inputFrequencyOffset = 0;
|
||||
m_rfBandwidth = 450.0f; // OBW for 2FSK = 2 * deviation + data rate. Then add a bit for carrier frequency offset
|
||||
m_navArea = 1;
|
||||
m_filterStation = "All";
|
||||
m_filterType = "All";
|
||||
m_udpEnabled = false;
|
||||
m_udpAddress = "127.0.0.1";
|
||||
m_udpPort = 9999;
|
||||
m_logFilename = "navtex_log.csv";
|
||||
m_logEnabled = false;
|
||||
m_scopeCh1 = 0;
|
||||
m_scopeCh2 = 1;
|
||||
|
||||
m_rgbColor = QColor(100, 25, 207).rgb();
|
||||
m_title = "Navtex Demodulator";
|
||||
m_streamIndex = 0;
|
||||
m_useReverseAPI = false;
|
||||
m_reverseAPIAddress = "127.0.0.1";
|
||||
m_reverseAPIPort = 8888;
|
||||
m_reverseAPIDeviceIndex = 0;
|
||||
m_reverseAPIChannelIndex = 0;
|
||||
m_workspaceIndex = 0;
|
||||
m_hidden = false;
|
||||
|
||||
for (int i = 0; i < NAVTEXDEMOD_COLUMNS; i++)
|
||||
{
|
||||
m_columnIndexes[i] = i;
|
||||
m_columnSizes[i] = -1; // Autosize
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray NavtexDemodSettings::serialize() const
|
||||
{
|
||||
SimpleSerializer s(1);
|
||||
s.writeS32(1, m_inputFrequencyOffset);
|
||||
s.writeS32(2, m_streamIndex);
|
||||
s.writeS32(3, m_navArea);
|
||||
s.writeString(4, m_filterStation);
|
||||
s.writeString(5, m_filterType);
|
||||
|
||||
if (m_channelMarker) {
|
||||
s.writeBlob(6, m_channelMarker->serialize());
|
||||
}
|
||||
s.writeFloat(7, m_rfBandwidth);
|
||||
|
||||
s.writeBool(9, m_udpEnabled);
|
||||
s.writeString(10, m_udpAddress);
|
||||
s.writeU32(11, m_udpPort);
|
||||
s.writeString(12, m_logFilename);
|
||||
s.writeBool(13, m_logEnabled);
|
||||
s.writeS32(14, m_scopeCh1);
|
||||
s.writeS32(15, m_scopeCh2);
|
||||
|
||||
s.writeU32(20, m_rgbColor);
|
||||
s.writeString(21, m_title);
|
||||
s.writeBool(22, m_useReverseAPI);
|
||||
s.writeString(23, m_reverseAPIAddress);
|
||||
s.writeU32(24, m_reverseAPIPort);
|
||||
s.writeU32(25, m_reverseAPIDeviceIndex);
|
||||
s.writeU32(26, m_reverseAPIChannelIndex);
|
||||
|
||||
if (m_rollupState) {
|
||||
s.writeBlob(27, m_rollupState->serialize());
|
||||
}
|
||||
|
||||
s.writeS32(28, m_workspaceIndex);
|
||||
s.writeBlob(29, m_geometryBytes);
|
||||
s.writeBool(30, m_hidden);
|
||||
s.writeBlob(31, m_scopeGUI->serialize());
|
||||
|
||||
for (int i = 0; i < NAVTEXDEMOD_COLUMNS; i++) {
|
||||
s.writeS32(100 + i, m_columnIndexes[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NAVTEXDEMOD_COLUMNS; i++) {
|
||||
s.writeS32(200 + i, m_columnSizes[i]);
|
||||
}
|
||||
|
||||
return s.final();
|
||||
}
|
||||
|
||||
bool NavtexDemodSettings::deserialize(const QByteArray& data)
|
||||
{
|
||||
SimpleDeserializer d(data);
|
||||
|
||||
if(!d.isValid())
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(d.getVersion() == 1)
|
||||
{
|
||||
QByteArray bytetmp;
|
||||
uint32_t utmp;
|
||||
QString strtmp;
|
||||
|
||||
d.readS32(1, &m_inputFrequencyOffset, 0);
|
||||
d.readS32(2, &m_streamIndex, 0);
|
||||
d.readS32(3, &m_navArea, 1);
|
||||
d.readString(4, &m_filterStation, "All");
|
||||
d.readString(5, &m_filterType, "All");
|
||||
|
||||
if (m_channelMarker)
|
||||
{
|
||||
d.readBlob(6, &bytetmp);
|
||||
m_channelMarker->deserialize(bytetmp);
|
||||
}
|
||||
d.readFloat(7, &m_rfBandwidth, 450.0f);
|
||||
|
||||
d.readBool(9, &m_udpEnabled);
|
||||
d.readString(10, &m_udpAddress);
|
||||
d.readU32(11, &utmp);
|
||||
|
||||
if ((utmp > 1023) && (utmp < 65535)) {
|
||||
m_udpPort = utmp;
|
||||
} else {
|
||||
m_udpPort = 9999;
|
||||
}
|
||||
d.readString(12, &m_logFilename, "navtex_log.csv");
|
||||
d.readBool(13, &m_logEnabled, false);
|
||||
d.readS32(14, &m_scopeCh1, 0);
|
||||
d.readS32(15, &m_scopeCh2, 0);
|
||||
|
||||
d.readU32(20, &m_rgbColor, QColor(100, 25, 207).rgb());
|
||||
d.readString(21, &m_title, "Navtex Demodulator");
|
||||
d.readBool(22, &m_useReverseAPI, false);
|
||||
d.readString(23, &m_reverseAPIAddress, "127.0.0.1");
|
||||
d.readU32(24, &utmp, 0);
|
||||
|
||||
if ((utmp > 1023) && (utmp < 65535)) {
|
||||
m_reverseAPIPort = utmp;
|
||||
} else {
|
||||
m_reverseAPIPort = 8888;
|
||||
}
|
||||
|
||||
d.readU32(25, &utmp, 0);
|
||||
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
|
||||
d.readU32(26, &utmp, 0);
|
||||
m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp;
|
||||
|
||||
if (m_rollupState)
|
||||
{
|
||||
d.readBlob(27, &bytetmp);
|
||||
m_rollupState->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
d.readS32(28, &m_workspaceIndex, 0);
|
||||
d.readBlob(29, &m_geometryBytes);
|
||||
d.readBool(30, &m_hidden, false);
|
||||
|
||||
if (m_scopeGUI)
|
||||
{
|
||||
d.readBlob(31, &bytetmp);
|
||||
m_scopeGUI->deserialize(bytetmp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NAVTEXDEMOD_COLUMNS; i++) {
|
||||
d.readS32(100 + i, &m_columnIndexes[i], i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NAVTEXDEMOD_COLUMNS; i++) {
|
||||
d.readS32(200 + i, &m_columnSizes[i], -1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resetToDefaults();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
79
plugins/channelrx/demodnavtex/navtexdemodsettings.h
Normal file
79
plugins/channelrx/demodnavtex/navtexdemodsettings.h
Normal file
@ -0,0 +1,79 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMODSETTINGS_H
|
||||
#define INCLUDE_NAVTEXDEMODSETTINGS_H
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
class Serializable;
|
||||
|
||||
// Number of columns in the table
|
||||
#define NAVTEXDEMOD_COLUMNS 11
|
||||
|
||||
struct NavtexDemodSettings
|
||||
{
|
||||
qint32 m_inputFrequencyOffset;
|
||||
Real m_rfBandwidth;
|
||||
int m_navArea;
|
||||
QString m_filterStation;
|
||||
QString m_filterType;
|
||||
bool m_udpEnabled;
|
||||
QString m_udpAddress;
|
||||
uint16_t m_udpPort;
|
||||
|
||||
quint32 m_rgbColor;
|
||||
QString m_title;
|
||||
Serializable *m_channelMarker;
|
||||
int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
bool m_useReverseAPI;
|
||||
QString m_reverseAPIAddress;
|
||||
uint16_t m_reverseAPIPort;
|
||||
uint16_t m_reverseAPIDeviceIndex;
|
||||
uint16_t m_reverseAPIChannelIndex;
|
||||
|
||||
int m_scopeCh1;
|
||||
int m_scopeCh2;
|
||||
|
||||
QString m_logFilename;
|
||||
bool m_logEnabled;
|
||||
Serializable *m_scopeGUI;
|
||||
Serializable *m_rollupState;
|
||||
int m_workspaceIndex;
|
||||
QByteArray m_geometryBytes;
|
||||
bool m_hidden;
|
||||
|
||||
int m_columnIndexes[NAVTEXDEMOD_COLUMNS];//!< How the columns are ordered in the table
|
||||
int m_columnSizes[NAVTEXDEMOD_COLUMNS]; //!< Size of the columns in the table
|
||||
|
||||
static const int NAVTEXDEMOD_CHANNEL_SAMPLE_RATE = 1000; // Must be integer multiple of baud rate (x10)
|
||||
static const int NAVTEXDEMOD_BAUD_RATE = 100;
|
||||
static const int NAVTEXDEMOD_SAMPLES_PER_BIT = NAVTEXDEMOD_CHANNEL_SAMPLE_RATE / NAVTEXDEMOD_BAUD_RATE;
|
||||
static const int NAVTEXDEMOD_FREQUENCY_SHIFT = 170;
|
||||
|
||||
NavtexDemodSettings();
|
||||
void resetToDefaults();
|
||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||
void setRollupState(Serializable *rollupState) { m_rollupState = rollupState; }
|
||||
void setScopeGUI(Serializable *scopeGUI) { m_scopeGUI = scopeGUI; }
|
||||
QByteArray serialize() const;
|
||||
bool deserialize(const QByteArray& data);
|
||||
};
|
||||
|
||||
#endif /* INCLUDE_NAVTEXDEMODSETTINGS_H */
|
||||
|
493
plugins/channelrx/demodnavtex/navtexdemodsink.cpp
Normal file
493
plugins/channelrx/demodnavtex/navtexdemodsink.cpp
Normal file
@ -0,0 +1,493 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <QDebug>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <complex.h>
|
||||
|
||||
#include "dsp/dspengine.h"
|
||||
#include "dsp/scopevis.h"
|
||||
#include "util/db.h"
|
||||
#include "maincore.h"
|
||||
|
||||
#include "navtexdemod.h"
|
||||
#include "navtexdemodsink.h"
|
||||
|
||||
NavtexDemodSink::NavtexDemodSink(NavtexDemod *packetDemod) :
|
||||
m_navtexDemod(packetDemod),
|
||||
m_channelSampleRate(NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE),
|
||||
m_channelFrequencyOffset(0),
|
||||
m_magsqSum(0.0f),
|
||||
m_magsqPeak(0.0f),
|
||||
m_magsqCount(0),
|
||||
m_messageQueueToChannel(nullptr),
|
||||
m_exp(nullptr),
|
||||
m_sampleBufferIndex(0)
|
||||
{
|
||||
m_magsq = 0.0;
|
||||
|
||||
m_sampleBuffer.resize(m_sampleBufferSize);
|
||||
|
||||
applySettings(m_settings, true);
|
||||
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
|
||||
|
||||
m_lowpassComplex1.create(301, NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE, NavtexDemodSettings::NAVTEXDEMOD_BAUD_RATE * 1.1);
|
||||
m_lowpassComplex2.create(301, NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE, NavtexDemodSettings::NAVTEXDEMOD_BAUD_RATE * 1.1);
|
||||
}
|
||||
|
||||
NavtexDemodSink::~NavtexDemodSink()
|
||||
{
|
||||
delete[] m_exp;
|
||||
}
|
||||
|
||||
void NavtexDemodSink::sampleToScope(Complex sample)
|
||||
{
|
||||
if (m_scopeSink)
|
||||
{
|
||||
Real r = std::real(sample) * SDR_RX_SCALEF;
|
||||
Real i = std::imag(sample) * SDR_RX_SCALEF;
|
||||
m_sampleBuffer[m_sampleBufferIndex++] = Sample(r, i);
|
||||
|
||||
if (m_sampleBufferIndex == m_sampleBufferSize)
|
||||
{
|
||||
std::vector<SampleVector::const_iterator> vbegin;
|
||||
vbegin.push_back(m_sampleBuffer.begin());
|
||||
m_scopeSink->feed(vbegin, m_sampleBufferSize);
|
||||
m_sampleBufferIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodSink::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end)
|
||||
{
|
||||
Complex ci;
|
||||
|
||||
for (SampleVector::const_iterator it = begin; it != end; ++it)
|
||||
{
|
||||
Complex c(it->real(), it->imag());
|
||||
c *= m_nco.nextIQ();
|
||||
|
||||
if (m_interpolatorDistance < 1.0f) // interpolate
|
||||
{
|
||||
while (!m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
|
||||
{
|
||||
processOneSample(ci);
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
}
|
||||
}
|
||||
else // decimate
|
||||
{
|
||||
if (m_interpolator.decimate(&m_interpolatorDistanceRemain, c, &ci))
|
||||
{
|
||||
processOneSample(ci);
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodSink::eraseChars(int n)
|
||||
{
|
||||
if (getMessageQueueToChannel())
|
||||
{
|
||||
QString msg = QString("%1").arg(QChar(0x8)); // Backspace
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
NavtexDemod::MsgCharacter *msg = NavtexDemod::MsgCharacter::create(QChar(0x8));
|
||||
getMessageQueueToChannel()->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodSink::processOneSample(Complex &ci)
|
||||
{
|
||||
// Calculate average and peak levels for level meter
|
||||
double magsqRaw = ci.real()*ci.real() + ci.imag()*ci.imag();;
|
||||
Real magsq = magsqRaw / (SDR_RX_SCALED*SDR_RX_SCALED);
|
||||
m_movingAverage(magsq);
|
||||
m_magsq = m_movingAverage.asDouble();
|
||||
m_magsqSum += magsq;
|
||||
if (magsq > m_magsqPeak)
|
||||
{
|
||||
m_magsqPeak = magsq;
|
||||
}
|
||||
m_magsqCount++;
|
||||
|
||||
// Sum power while data is being received
|
||||
if (m_gotSOP)
|
||||
{
|
||||
m_rssiMagSqSum += magsq;
|
||||
m_rssiMagSqCount++;
|
||||
}
|
||||
|
||||
ci /= SDR_RX_SCALEF;
|
||||
|
||||
// Correlate with expected frequencies
|
||||
Complex exp = m_exp[m_expIdx];
|
||||
m_expIdx = (m_expIdx + 1) % m_expLength;
|
||||
Complex corr1 = ci * exp;
|
||||
Complex corr2 = ci * std::conj(exp);
|
||||
|
||||
// Low pass filter
|
||||
Real abs1Filt = std::abs(m_lowpassComplex1.filter(corr1));
|
||||
Real abs2Filt = std::abs(m_lowpassComplex2.filter(corr2));
|
||||
|
||||
// Envelope calculation
|
||||
m_movMax1(abs1Filt);
|
||||
m_movMax2(abs2Filt);
|
||||
Real env1 = m_movMax1.getMaximum();
|
||||
Real env2 = m_movMax2.getMaximum();
|
||||
|
||||
// Automatic threshold correction to compensate for frequency selective fading
|
||||
// http://www.w7ay.net/site/Technical/ATC/index.html
|
||||
Real bias1 = abs1Filt - 0.5 * env1;
|
||||
Real bias2 = abs2Filt - 0.5 * env2;
|
||||
Real unbiasedData = abs1Filt - abs2Filt;
|
||||
Real biasedData = bias1 - bias2;
|
||||
|
||||
// Save current data for edge detection
|
||||
m_dataPrev = m_data;
|
||||
// Set data according to stongest correlation
|
||||
m_data = biasedData < 0;
|
||||
|
||||
// Generate sampling clock by aligning to correlator zero-crossing
|
||||
if (m_data && !m_dataPrev)
|
||||
{
|
||||
if ((m_clockCount > 2) && (m_clockCount < m_samplesPerBit*3/4) && m_gotSOP)
|
||||
{
|
||||
//qDebug() << "Clock toggle ignored at " << m_clockCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clockCount = 0;
|
||||
m_clock = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sample in middle of symbol
|
||||
if (m_clockCount == m_samplesPerBit/2)
|
||||
{
|
||||
receiveBit(m_data);
|
||||
m_clock = true;
|
||||
}
|
||||
m_clockCount = (m_clockCount + 1) % m_samplesPerBit;
|
||||
if (m_clockCount == 0) {
|
||||
m_clock = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Select signals to feed to scope
|
||||
Complex scopeSample;
|
||||
switch (m_settings.m_scopeCh1)
|
||||
{
|
||||
case 0:
|
||||
scopeSample.real(ci.real());
|
||||
break;
|
||||
case 1:
|
||||
scopeSample.real(ci.imag());
|
||||
break;
|
||||
case 2:
|
||||
scopeSample.real(real(exp));
|
||||
break;
|
||||
case 3:
|
||||
scopeSample.real(imag(exp));
|
||||
break;
|
||||
case 4:
|
||||
scopeSample.real(real(corr1));
|
||||
break;
|
||||
case 5:
|
||||
scopeSample.real(imag(corr1));
|
||||
break;
|
||||
case 6:
|
||||
scopeSample.real(real(corr2));
|
||||
break;
|
||||
case 7:
|
||||
scopeSample.real(imag(corr2));
|
||||
break;
|
||||
case 8:
|
||||
scopeSample.real(abs1Filt);
|
||||
break;
|
||||
case 9:
|
||||
scopeSample.real(abs2Filt);
|
||||
break;
|
||||
case 10:
|
||||
scopeSample.real(env1);
|
||||
break;
|
||||
case 11:
|
||||
scopeSample.real(env2);
|
||||
break;
|
||||
case 12:
|
||||
scopeSample.real(unbiasedData);
|
||||
break;
|
||||
case 13:
|
||||
scopeSample.real(biasedData);
|
||||
break;
|
||||
case 14:
|
||||
scopeSample.real(m_data);
|
||||
break;
|
||||
case 15:
|
||||
scopeSample.real(m_clock);
|
||||
break;
|
||||
case 16:
|
||||
scopeSample.real(m_bit);
|
||||
break;
|
||||
case 17:
|
||||
scopeSample.real(m_gotSOP);
|
||||
break;
|
||||
}
|
||||
switch (m_settings.m_scopeCh2)
|
||||
{
|
||||
case 0:
|
||||
scopeSample.imag(ci.real());
|
||||
break;
|
||||
case 1:
|
||||
scopeSample.imag(ci.imag());
|
||||
break;
|
||||
case 2:
|
||||
scopeSample.imag(real(exp));
|
||||
break;
|
||||
case 3:
|
||||
scopeSample.imag(imag(exp));
|
||||
break;
|
||||
case 4:
|
||||
scopeSample.imag(real(corr1));
|
||||
break;
|
||||
case 5:
|
||||
scopeSample.imag(imag(corr1));
|
||||
break;
|
||||
case 6:
|
||||
scopeSample.imag(real(corr2));
|
||||
break;
|
||||
case 7:
|
||||
scopeSample.imag(imag(corr2));
|
||||
break;
|
||||
case 8:
|
||||
scopeSample.imag(abs1Filt);
|
||||
break;
|
||||
case 9:
|
||||
scopeSample.imag(abs2Filt);
|
||||
break;
|
||||
case 10:
|
||||
scopeSample.imag(env1);
|
||||
break;
|
||||
case 11:
|
||||
scopeSample.imag(env2);
|
||||
break;
|
||||
case 12:
|
||||
scopeSample.imag(unbiasedData);
|
||||
break;
|
||||
case 13:
|
||||
scopeSample.imag(biasedData);
|
||||
break;
|
||||
case 14:
|
||||
scopeSample.imag(m_data);
|
||||
break;
|
||||
case 15:
|
||||
scopeSample.imag(m_clock);
|
||||
break;
|
||||
case 16:
|
||||
scopeSample.imag(m_bit);
|
||||
break;
|
||||
case 17:
|
||||
scopeSample.imag(m_gotSOP);
|
||||
break;
|
||||
}
|
||||
sampleToScope(scopeSample);
|
||||
}
|
||||
|
||||
void NavtexDemodSink::receiveBit(bool bit)
|
||||
{
|
||||
m_bit = bit;
|
||||
|
||||
// Store in shift reg
|
||||
m_bits = (m_bits << 1) | m_bit;
|
||||
m_bitCount++;
|
||||
|
||||
if (!m_gotSOP)
|
||||
{
|
||||
if (m_bitCount == 14)
|
||||
{
|
||||
if ((m_bits & 0x3fff) == 0x19f8) // phase 2 followed by phase 1
|
||||
{
|
||||
m_gotSOP = true;
|
||||
m_bitCount = 0;
|
||||
m_sitorBDecoder.init();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bitCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bitCount == 7)
|
||||
{
|
||||
char c = m_sitorBDecoder.decode(m_bits & 0x7f);
|
||||
if (c != -1)
|
||||
{
|
||||
//qDebug() << "Out: " << SitorBDecoder::printable(c);
|
||||
m_consecutiveErrors = 0;
|
||||
|
||||
if ((c != '<') && (c != '>') && (c != 0x2))
|
||||
{
|
||||
// 7 bytes per second, so may as well send individually to be displayed
|
||||
if (getMessageQueueToChannel())
|
||||
{
|
||||
NavtexDemod::MsgCharacter *msg = NavtexDemod::MsgCharacter::create(SitorBDecoder::printable(c));
|
||||
getMessageQueueToChannel()->push(msg);
|
||||
}
|
||||
// Add character to message buffer
|
||||
m_messageBuffer.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_messageBuffer.size() > 0)
|
||||
{
|
||||
QRegularExpression re("[Z*][C*][Z*][C*](.|\n|\r)*[N*][N*][N*][N*]");
|
||||
QRegularExpressionMatch match = re.match(m_messageBuffer);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
if (getMessageQueueToChannel())
|
||||
{
|
||||
NavtexMessage navtexMsg = NavtexMessage(match.captured(0));
|
||||
|
||||
float rssi = CalcDb::dbPower(m_rssiMagSqSum / m_rssiMagSqCount);
|
||||
NavtexDemod::MsgMessage *msg = NavtexDemod::MsgMessage::create(navtexMsg, m_sitorBDecoder.getErrors(), rssi);
|
||||
getMessageQueueToChannel()->push(msg);
|
||||
}
|
||||
// Navtex messages can span multiple blocks?
|
||||
m_messageBuffer = "";
|
||||
}
|
||||
}
|
||||
if (c == 0x2) // End of text
|
||||
{
|
||||
// Reset demod
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (c == '*')
|
||||
{
|
||||
m_errorCount++;
|
||||
m_consecutiveErrors++;
|
||||
// ITU 476-5 just says return to standby after the percentage of
|
||||
// mutilated signals received has reached a predetermined value
|
||||
// without saying what that value is
|
||||
if (m_messageBuffer.size() >= 12)
|
||||
{
|
||||
float errorPC = m_errorCount / (float)(m_messageBuffer.size() + m_errorCount);
|
||||
if (errorPC >= 0.2f)
|
||||
{
|
||||
//qDebug() << "Too many errors" << m_errorCount << m_messageBuffer.size();
|
||||
init();
|
||||
}
|
||||
}
|
||||
else if (m_errorCount >= 3)
|
||||
{
|
||||
//qDebug() << "Too many errors" << m_errorCount << m_messageBuffer.size();
|
||||
eraseChars(m_messageBuffer.size());
|
||||
init();
|
||||
}
|
||||
if (m_consecutiveErrors >= 5)
|
||||
{
|
||||
//qDebug() << "Too many consequtive errors";
|
||||
init();
|
||||
}
|
||||
}
|
||||
m_bitCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NavtexDemodSink::applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "NavtexDemodSink::applyChannelSettings:"
|
||||
<< " channelSampleRate: " << channelSampleRate
|
||||
<< " channelFrequencyOffset: " << channelFrequencyOffset;
|
||||
|
||||
if ((m_channelFrequencyOffset != channelFrequencyOffset) ||
|
||||
(m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
m_nco.setFreq(-channelFrequencyOffset, channelSampleRate);
|
||||
}
|
||||
|
||||
if ((m_channelSampleRate != channelSampleRate) || force)
|
||||
{
|
||||
m_interpolator.create(16, channelSampleRate, m_settings.m_rfBandwidth / 2.2);
|
||||
m_interpolatorDistance = (Real) channelSampleRate / (Real) NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE;
|
||||
m_interpolatorDistanceRemain = m_interpolatorDistance;
|
||||
}
|
||||
|
||||
m_channelSampleRate = channelSampleRate;
|
||||
m_channelFrequencyOffset = channelFrequencyOffset;
|
||||
}
|
||||
|
||||
void NavtexDemodSink::init()
|
||||
{
|
||||
m_expIdx = 0;
|
||||
m_bit = 0;
|
||||
m_bits = 0;
|
||||
m_bitCount = 0;
|
||||
m_gotSOP = false;
|
||||
m_errorCount = 0;
|
||||
m_clockCount = 0;
|
||||
m_clock = 0;
|
||||
m_rssiMagSqSum = 0.0;
|
||||
m_rssiMagSqCount = 0;
|
||||
m_consecutiveErrors = 0;
|
||||
m_sitorBDecoder.init();
|
||||
m_messageBuffer = "";
|
||||
}
|
||||
|
||||
void NavtexDemodSink::applySettings(const NavtexDemodSettings& settings, bool force)
|
||||
{
|
||||
qDebug() << "NavtexDemodSink::applySettings:"
|
||||
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
||||
<< " force: " << force;
|
||||
|
||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
|
||||
{
|
||||
m_interpolator.create(16, m_channelSampleRate, settings.m_rfBandwidth / 2.2);
|
||||
m_interpolatorDistance = (Real) m_channelSampleRate / (Real) NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE;
|
||||
m_interpolatorDistanceRemain = m_interpolatorDistance;
|
||||
}
|
||||
|
||||
if (force)
|
||||
{
|
||||
delete[] m_exp;
|
||||
m_exp = new Complex[m_expLength];
|
||||
Real f0 = 0.0f;
|
||||
for (int i = 0; i < m_expLength; i++)
|
||||
{
|
||||
m_exp[i] = Complex(cos(f0), sin(f0));
|
||||
f0 += 2.0f * (Real)M_PI * (NavtexDemodSettings::NAVTEXDEMOD_FREQUENCY_SHIFT/2.0f) / NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE;
|
||||
}
|
||||
init();
|
||||
// Due to start and stop bits, we should get mark and space at least every 8 bits
|
||||
// while something is being transmitted
|
||||
m_movMax1.setSize(m_samplesPerBit * 8);
|
||||
m_movMax2.setSize(m_samplesPerBit * 8);
|
||||
}
|
||||
|
||||
m_settings = settings;
|
||||
}
|
||||
|
145
plugins/channelrx/demodnavtex/navtexdemodsink.h
Normal file
145
plugins/channelrx/demodnavtex/navtexdemodsink.h
Normal file
@ -0,0 +1,145 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMODSINK_H
|
||||
#define INCLUDE_NAVTEXDEMODSINK_H
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#include "dsp/channelsamplesink.h"
|
||||
#include "dsp/nco.h"
|
||||
#include "dsp/interpolator.h"
|
||||
#include "dsp/firfilter.h"
|
||||
#include "util/movingaverage.h"
|
||||
#include "util/movingmaximum.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "util/navtex.h"
|
||||
|
||||
#include "navtexdemodsettings.h"
|
||||
|
||||
class ChannelAPI;
|
||||
class NavtexDemod;
|
||||
class ScopeVis;
|
||||
|
||||
class NavtexDemodSink : public ChannelSampleSink {
|
||||
public:
|
||||
NavtexDemodSink(NavtexDemod *packetDemod);
|
||||
~NavtexDemodSink();
|
||||
|
||||
virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end);
|
||||
|
||||
void setScopeSink(ScopeVis* scopeSink) { m_scopeSink = scopeSink; }
|
||||
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
||||
void applySettings(const NavtexDemodSettings& settings, bool force = false);
|
||||
void setMessageQueueToChannel(MessageQueue *messageQueue) { m_messageQueueToChannel = messageQueue; }
|
||||
void setChannel(ChannelAPI *channel) { m_channel = channel; }
|
||||
|
||||
double getMagSq() const { return m_magsq; }
|
||||
|
||||
void getMagSqLevels(double& avg, double& peak, int& nbSamples)
|
||||
{
|
||||
if (m_magsqCount > 0)
|
||||
{
|
||||
m_magsq = m_magsqSum / m_magsqCount;
|
||||
m_magSqLevelStore.m_magsq = m_magsq;
|
||||
m_magSqLevelStore.m_magsqPeak = m_magsqPeak;
|
||||
}
|
||||
|
||||
avg = m_magSqLevelStore.m_magsq;
|
||||
peak = m_magSqLevelStore.m_magsqPeak;
|
||||
nbSamples = m_magsqCount == 0 ? 1 : m_magsqCount;
|
||||
|
||||
m_magsqSum = 0.0f;
|
||||
m_magsqPeak = 0.0f;
|
||||
m_magsqCount = 0;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
struct MagSqLevelsStore
|
||||
{
|
||||
MagSqLevelsStore() :
|
||||
m_magsq(1e-12),
|
||||
m_magsqPeak(1e-12)
|
||||
{}
|
||||
double m_magsq;
|
||||
double m_magsqPeak;
|
||||
};
|
||||
|
||||
ScopeVis* m_scopeSink; // Scope GUI to display baseband waveform
|
||||
NavtexDemod *m_navtexDemod;
|
||||
NavtexDemodSettings m_settings;
|
||||
ChannelAPI *m_channel;
|
||||
int m_channelSampleRate;
|
||||
int m_channelFrequencyOffset;
|
||||
|
||||
NCO m_nco;
|
||||
Interpolator m_interpolator;
|
||||
Real m_interpolatorDistance;
|
||||
Real m_interpolatorDistanceRemain;
|
||||
|
||||
double m_magsq;
|
||||
double m_magsqSum;
|
||||
double m_magsqPeak;
|
||||
int m_magsqCount;
|
||||
MagSqLevelsStore m_magSqLevelStore;
|
||||
|
||||
MessageQueue *m_messageQueueToChannel;
|
||||
|
||||
MovingAverageUtil<Real, double, 16> m_movingAverage;
|
||||
|
||||
Lowpass<Complex> m_lowpassComplex1;
|
||||
Lowpass<Complex> m_lowpassComplex2;
|
||||
MovingMaximum<Real> m_movMax1;
|
||||
MovingMaximum<Real> m_movMax2;
|
||||
|
||||
static const int m_expLength = 600;
|
||||
static const int m_samplesPerBit = NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE / NavtexDemodSettings::NAVTEXDEMOD_BAUD_RATE;
|
||||
Complex *m_exp;
|
||||
int m_expIdx;
|
||||
int m_bit;
|
||||
bool m_data;
|
||||
bool m_dataPrev;
|
||||
int m_clockCount;
|
||||
bool m_clock;
|
||||
double m_rssiMagSqSum;
|
||||
int m_rssiMagSqCount;
|
||||
|
||||
unsigned short m_bits;
|
||||
int m_bitCount;
|
||||
bool m_gotSOP;
|
||||
int m_errorCount;
|
||||
int m_consecutiveErrors;
|
||||
QString m_messageBuffer;
|
||||
|
||||
SitorBDecoder m_sitorBDecoder;
|
||||
|
||||
SampleVector m_sampleBuffer;
|
||||
static const int m_sampleBufferSize = NavtexDemodSettings::NAVTEXDEMOD_CHANNEL_SAMPLE_RATE / 20;
|
||||
int m_sampleBufferIndex;
|
||||
|
||||
void processOneSample(Complex &ci);
|
||||
MessageQueue *getMessageQueueToChannel() { return m_messageQueueToChannel; }
|
||||
void sampleToScope(Complex sample);
|
||||
void eraseChars(int n);
|
||||
void init();
|
||||
void receiveBit(bool bit);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NAVTEXDEMODSINK_H
|
||||
|
52
plugins/channelrx/demodnavtex/navtexdemodwebapiadapter.cpp
Normal file
52
plugins/channelrx/demodnavtex/navtexdemodwebapiadapter.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 "SWGChannelSettings.h"
|
||||
#include "navtexdemod.h"
|
||||
#include "navtexdemodwebapiadapter.h"
|
||||
|
||||
NavtexDemodWebAPIAdapter::NavtexDemodWebAPIAdapter()
|
||||
{}
|
||||
|
||||
NavtexDemodWebAPIAdapter::~NavtexDemodWebAPIAdapter()
|
||||
{}
|
||||
|
||||
int NavtexDemodWebAPIAdapter::webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) errorMessage;
|
||||
response.setNavtexDemodSettings(new SWGSDRangel::SWGNavtexDemodSettings());
|
||||
response.getNavtexDemodSettings()->init();
|
||||
NavtexDemod::webapiFormatChannelSettings(response, m_settings);
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
int NavtexDemodWebAPIAdapter::webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage)
|
||||
{
|
||||
(void) force;
|
||||
(void) errorMessage;
|
||||
NavtexDemod::webapiUpdateChannelSettings(m_settings, channelSettingsKeys, response);
|
||||
|
||||
return 200;
|
||||
}
|
50
plugins/channelrx/demodnavtex/navtexdemodwebapiadapter.h
Normal file
50
plugins/channelrx/demodnavtex/navtexdemodwebapiadapter.h
Normal file
@ -0,0 +1,50 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2019 Edouard Griffiths, F4EXB. //
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_NAVTEXDEMOD_WEBAPIADAPTER_H
|
||||
#define INCLUDE_NAVTEXDEMOD_WEBAPIADAPTER_H
|
||||
|
||||
#include "channel/channelwebapiadapter.h"
|
||||
#include "navtexdemodsettings.h"
|
||||
|
||||
/**
|
||||
* Standalone API adapter only for the settings
|
||||
*/
|
||||
class NavtexDemodWebAPIAdapter : public ChannelWebAPIAdapter {
|
||||
public:
|
||||
NavtexDemodWebAPIAdapter();
|
||||
virtual ~NavtexDemodWebAPIAdapter();
|
||||
|
||||
virtual QByteArray serialize() const { return m_settings.serialize(); }
|
||||
virtual bool deserialize(const QByteArray& data) { return m_settings.deserialize(data); }
|
||||
|
||||
virtual int webapiSettingsGet(
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
virtual int webapiSettingsPutPatch(
|
||||
bool force,
|
||||
const QStringList& channelSettingsKeys,
|
||||
SWGSDRangel::SWGChannelSettings& response,
|
||||
QString& errorMessage);
|
||||
|
||||
private:
|
||||
NavtexDemodSettings m_settings;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NAVTEXDEMOD_WEBAPIADAPTER_H
|
101
plugins/channelrx/demodnavtex/readme.md
Normal file
101
plugins/channelrx/demodnavtex/readme.md
Normal file
@ -0,0 +1,101 @@
|
||||
<h1>Navtex demodulator plugin</h1>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
|
||||
This plugin can be used to demodulate Navtex (Navigational Telex) transmissions, which contain marine navigational and meteorological warnings and forecasts.
|
||||
These are broadcast worldwide on 518kHz (in English for international messages), 490kHz (often in the local language for national messages) and 4209.5kHz.
|
||||
Navtex messages are transmitted using FSK with 170Hz separation at 100 baud, using [SITOR-B](https://www.itu.int/dms_pubrec/itu-r/rec/m/R-REC-M.625-4-201203-I!!PDF-E.pdf]) encoding.
|
||||
The [Map](../../feature/map/readme.md) feature can display the location of Navtex transmitters, along with their transmission times and frequencies.
|
||||
|
||||
<h2>Interface</h2>
|
||||
|
||||
The top and bottom bars of the channel window are described [here](../../../sdrgui/channel/readme.md)
|
||||
|
||||
![Navtex Demodulator plugin GUI](../../../doc/img/NavtexDemod_plugin.png)
|
||||
|
||||
<h3>1: Frequency shift from center frequency of reception</h3>
|
||||
|
||||
Use the wheels to adjust the frequency shift in Hz from the center frequency of reception. Left click on a digit sets the cursor position at this digit. Right click on a digit sets all digits on the right to zero. This effectively floors value at the digit position. Wheels are moved with the mousewheel while pointing at the wheel or by selecting the wheel with the left mouse click and using the keyboard arrows. Pressing shift simultaneously moves digit by 5 and pressing control moves it by 2.
|
||||
|
||||
<h3>2: Channel power</h3>
|
||||
|
||||
Average total power in dB relative to a +/- 1.0 amplitude signal received in the pass band.
|
||||
|
||||
<h3>3: Level meter in dB</h3>
|
||||
|
||||
- top bar (green): average value
|
||||
- bottom bar (blue green): instantaneous peak value
|
||||
- tip vertical bar (bright green): peak hold value
|
||||
|
||||
<h3>4: Navarea</h3>
|
||||
|
||||
Specifies the geographical area in which the receiver is in. This enables the plugin to decode transmitter station identifiers, and display which transmitter the current transmission timeslot is assigned to.
|
||||
Note that with good propagation conditions, it is possible to receive messages from another area, so the station indicated in the message table (17) should be checked against the location given in the recevied message text.
|
||||
|
||||
<h3>5: TX</h3>
|
||||
|
||||
Displays which transmitter is assigned the current 10 minute timeslot.
|
||||
|
||||
<h3>6: Find TX On Map</h3>
|
||||
|
||||
If the [Map](../../feature/map/readme.md) feature is open, when clicked, the Map will be centered on the current transmitter (5).
|
||||
|
||||
<h3>7: RF Bandwidth</h3>
|
||||
|
||||
This specifies the bandwidth of a filter that is applied to the input signal to limit the RF bandwidth.
|
||||
|
||||
<h3>8: UDP</h3>
|
||||
|
||||
When checked, received packets are forwarded to the specified UDP address (9) and port (10).
|
||||
|
||||
<h3>9: UDP address</h3>
|
||||
|
||||
IP address of the host to forward received packets to via UDP.
|
||||
|
||||
<h3>10: UDP port</h3>
|
||||
|
||||
UDP port number to forward received packets to.
|
||||
|
||||
<h3>11: Station Filter</h3>
|
||||
|
||||
This drop down displays a list of all stations which messages have been received from. When a station other than "All" is selected, only messages from that station will be displayed in the table.
|
||||
|
||||
<h3>12: Message Type Filter</h3>
|
||||
|
||||
This drop down displays a list of all message types that have been received. When a type other than "All" is selected, only messages with that type will be displayed in the table.
|
||||
|
||||
<h3>13: Start/stop Logging Messages to .csv File</h3>
|
||||
|
||||
When checked, writes all received messages to a .csv file.
|
||||
|
||||
<h3>14: .csv Log Filename</h3>
|
||||
|
||||
Click to specify the name of the .csv file which received messasges are logged to.
|
||||
|
||||
<h3>15: Read Data from .csv File</h3>
|
||||
|
||||
Click to specify a previously written .csv log file, which is read and used to update the table.
|
||||
|
||||
<h3>16: Received Text</h3>
|
||||
|
||||
The received text area shows text as it is received.
|
||||
|
||||
<h3>17: Received Messages Table</h3>
|
||||
|
||||
The received messages table displays the contents of the messages that have been received.
|
||||
|
||||
* Date - Date the message was received.
|
||||
* Time - Time the message was received.
|
||||
* SID - Station identifer of the transmitting station.
|
||||
* Station - SID decoded according to the currently selected navarea.
|
||||
* TID - Message type identifier.
|
||||
* MID - Message identifier.
|
||||
* Message - The message text.
|
||||
* Errors - The number of characters that were received with detected errors.
|
||||
* Error % - The percentage of characters that were received with errors.
|
||||
* RSSI - Average channel power in dB, while receiving the message.
|
||||
|
||||
Right clicking on the header will open a menu allowing you to select which columns are visible, or locate the station in the selected row on the [Map](../../feature/map/readme.md).
|
||||
To reorder the columns, left click and drag left or right a column header.
|
||||
Left click on a header to sort the table by the data in that column.
|
||||
|
729
sdrbase/util/navtex.cpp
Normal file
729
sdrbase/util/navtex.cpp
Normal file
@ -0,0 +1,729 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2023 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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 <QDebug>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "navtex.h"
|
||||
|
||||
// From https://en.wikipedia.org/wiki/List_of_Navtex_stations
|
||||
const QList<NavtexTransmitter> NavtexTransmitter::m_navtexTransmitters = {
|
||||
{1, "Svalbard", 78.056944, 13.609722, {Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{1, "Bodo", 67.266667, 14.383333, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{1, "Vardo", 70.370889, 31.097389, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{1, "Torshavn", 62.014944, -6.800056, {NavtexTransmitter::Schedule('D', 518000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(12, 30), QTime(16, 30), QTime(20, 30)})}},
|
||||
{1, "Niton", 50.586297, -1.254756, {NavtexTransmitter::Schedule('E', 518000, {QTime(0, 40), QTime(4, 40), QTime(8, 40), QTime(12, 40), QTime(16, 40), QTime(20, 40)}),
|
||||
NavtexTransmitter::Schedule('K', 518000, {QTime(1, 40), QTime(5, 40), QTime(6, 40), QTime(13, 40), QTime(17, 40), QTime(21, 40)}),
|
||||
NavtexTransmitter::Schedule('I', 490000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)})}}, // Have seen this broadcast at 9:10
|
||||
{1, "Talinn", 59.4644, 24.357294, {NavtexTransmitter::Schedule('F', 518000, {QTime(3, 20), QTime(7, 20), QTime(11, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)})}},
|
||||
{1, "Cullercoats", 55.0732, -1.463233, {NavtexTransmitter::Schedule('G', 518000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(17, 0), QTime(21, 0)}),
|
||||
NavtexTransmitter::Schedule('U', 490000, {QTime(3, 20), QTime(7, 20), QTime(11, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)})}},
|
||||
{1, "Bjuroklubb", 64.461639, 21.591833, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)})}},
|
||||
{1, "Grimeton", 57.103056, 12.385556, {NavtexTransmitter::Schedule('I', 518000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)})}},
|
||||
{1, "Gislovshammer", 55.488917, 14.314222, {NavtexTransmitter::Schedule('J', 518000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(17, 30), QTime(21, 30)})}},
|
||||
{1, "Rogaland", 58.658817, 5.603778, {NavtexTransmitter::Schedule('L', 518000, {QTime(1, 50), QTime(5, 50), QTime(9, 50), QTime(13, 50), QTime(17, 50), QTime(21, 50)})}},
|
||||
{1, "Jeloy", 59.435833, 10.589444, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{1, "Orlandet", 63.661194, 9.5455, {NavtexTransmitter::Schedule('N', 518000, {QTime(2, 10), QTime(6, 10), QTime(10, 10), QTime(14, 10), QTime(18, 10), QTime(22, 10)})}},
|
||||
{1, "Portpatrick", 54.844044, -5.124478, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)}),
|
||||
NavtexTransmitter::Schedule('C', 490000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{1, "Netherlands Coastguard", 52.095128, 4.257975, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{1, "Malin Head", 55.363278, -7.33925, {NavtexTransmitter::Schedule('Q', 518000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(18, 40), QTime(22, 40)})}},
|
||||
{1, "Saudanes", 66.18625, -18.951867, {NavtexTransmitter::Schedule('R', 518000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(18, 50), QTime(22, 50)}),
|
||||
NavtexTransmitter::Schedule('E', 490000, {QTime(0, 40), QTime(4, 40), QTime(8, 40), QTime(16, 40), QTime(20, 40)})}},
|
||||
{1, "Hamburg", 53.673333, 9.808611, {NavtexTransmitter::Schedule('S', 518000, {QTime(3, 0), QTime(7, 0), QTime(12, 0), QTime(15, 0), QTime(19, 0), QTime(23, 0)}),
|
||||
NavtexTransmitter::Schedule('L', 490000, {QTime(1, 50), QTime(5, 50), QTime(9, 50), QTime(17, 50), QTime(21, 50)})}}, // Transmitter is at Pinneberg (used on wiki), but messages give location as Hamburg
|
||||
{1, "Oostende", 51.182278, 2.806539, {NavtexTransmitter::Schedule('T', 518000, {QTime(3, 10), QTime(7, 10), QTime(11, 10), QTime(15, 10), QTime(19, 10), QTime(23, 10)}),
|
||||
NavtexTransmitter::Schedule('V', 518000, {QTime(3, 30), QTime(7, 30), QTime(11, 30), QTime(15, 30), QTime(19, 30), QTime(23, 30)}),
|
||||
NavtexTransmitter::Schedule('B', 490000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{1, "Valentia", 51.929756, -10.349028, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)})}},
|
||||
{1, "Grindavik", 63.833208, -22.450786, {NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 50), QTime(12, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)}),
|
||||
NavtexTransmitter::Schedule('K', 490000, {QTime(1, 40), QTime(5, 40), QTime(9, 40), QTime(17, 40), QTime(21, 40)})}},
|
||||
|
||||
{2, "Cross Corsen", 48.476031, -5.053697, {NavtexTransmitter::Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)}),
|
||||
NavtexTransmitter::Schedule('E', 490000, {QTime(0, 40), QTime(4, 40), QTime(8, 40), QTime(12, 40), QTime(16, 40), QTime(20, 40)})}},
|
||||
{2, "Coruna", 43.367028, -8.451861, {NavtexTransmitter::Schedule('D', 518000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(12, 30), QTime(16, 30), QTime(20, 30)}),
|
||||
NavtexTransmitter::Schedule('W', 490000, {QTime(3, 40), QTime(7, 40), QTime(11, 40), QTime(15, 40), QTime(17, 40), QTime(23, 40)})}},
|
||||
{2, "Horta", 38.529872, -28.628922, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 50), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)}),
|
||||
NavtexTransmitter::Schedule('J', 490000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(15, 30), QTime(21, 30)})}},
|
||||
{2, "Tarifa", 36.042, -5.556606, {NavtexTransmitter::Schedule('G', 518000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(17, 0), QTime(21, 0)})}},
|
||||
{2, "Las Palmas", 27.758522, -15.605361, {NavtexTransmitter::Schedule('I', 518000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)}),
|
||||
NavtexTransmitter::Schedule('A', 490000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{2, "Casablanca", 33.6, -7.633333, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{2, "Porto Santo", 33.066278, -16.355417, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{2, "Monsanto", 38.731611, -9.190611, {NavtexTransmitter::Schedule('R', 518000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(18, 50), QTime(22, 50)}),
|
||||
NavtexTransmitter::Schedule('G', 490000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(15, 0), QTime(21, 0)})}},
|
||||
{2, "Ribeira de Vinha", 16.853228, -25.003197, {NavtexTransmitter::Schedule('U', 518000, {QTime(3, 20), QTime(7, 20), QTime(11, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)})}},
|
||||
{2, "Cabo La Nao", 38.723258, 0.161367, {NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 520), QTime(11, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)}),
|
||||
NavtexTransmitter::Schedule('M', 490000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(16, 0), QTime(22, 0)})}},
|
||||
{2, "Sao Vicente", 16.853228, -25.003197, {NavtexTransmitter::Schedule('P', 490000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(16, 30), QTime(22, 30)})}},
|
||||
// {2, "Niton", 50.586297, -1.254756, {NavtexTransmitter::Schedule('T', 490000, {QTime(3, 10), QTime(7, 10), QTime(11, 10), QTime(15, 10), QTime(17, 10), QTime(23, 10)})}},
|
||||
{2, "Tarifa", 36.042, -5.556606, {NavtexTransmitter::Schedule('T', 490000, {QTime(3, 10), QTime(7, 10), QTime(11, 10), QTime(15, 10), QTime(17, 10), QTime(23, 10)})}},
|
||||
|
||||
{3, "Novorossijsk", 44.599111, 37.951442, {NavtexTransmitter::Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{3, "Algier", 36.733333, 3.18, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{3, "Odessa", 46.377611, 30.748222, {NavtexTransmitter::Schedule('C', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{3, "Istanbul", 41.066667, 28.95, {NavtexTransmitter::Schedule('D', 518000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(12, 30), QTime(16, 30), QTime(20, 30)}),
|
||||
NavtexTransmitter::Schedule('B', 490000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(16, 10), QTime(20, 10)}),
|
||||
NavtexTransmitter::Schedule('M', 4209500, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(16, 0), QTime(22, 0)})}},
|
||||
{3, "Samsun", 41.386667, 36.188333, {NavtexTransmitter::Schedule('E', 518000, {QTime(0, 40), QTime(4, 40), QTime(8, 40), QTime(12, 40), QTime(16, 40), QTime(20, 40)}),
|
||||
NavtexTransmitter::Schedule('A', 490000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{3, "Antalya", 36.1525, 32.44, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 50), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)}),
|
||||
NavtexTransmitter::Schedule('D', 490000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(16, 30), QTime(20, 30)})}},
|
||||
{3, "Iraklio", 35.322861, 25.748986, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)}),
|
||||
NavtexTransmitter::Schedule('Q', 490000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(16, 40), QTime(22, 40)}),
|
||||
NavtexTransmitter::Schedule('S', 4209500, {QTime(3, 0), QTime(7, 0), QTime(11, 0), QTime(15, 0), QTime(19, 0), QTime(3, 20)})}},
|
||||
{3, "Izmir", 38.275833, 26.2675, {NavtexTransmitter::Schedule('I', 518000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)}),
|
||||
NavtexTransmitter::Schedule('C', 490000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{3, "Varna", 43.068056, 27.786111, {NavtexTransmitter::Schedule('J', 518000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(17, 30), QTime(21, 30)})}},
|
||||
{3, "Kerkyra", 39.607222, 19.890833, {NavtexTransmitter::Schedule('K', 518000, {QTime(1, 40), QTime(5, 40), QTime(9, 40), QTime(13, 40), QTime(17, 40), QTime(21, 40)}),
|
||||
NavtexTransmitter::Schedule('P', 490000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(16, 30), QTime(22, 30)})}},
|
||||
{3, "Limnos", 39.906389, 25.181389, {NavtexTransmitter::Schedule('L', 518000, {QTime(1, 50), QTime(5, 50), QTime(9, 50), QTime(13, 50), QTime(17, 50), QTime(21, 50)}),
|
||||
NavtexTransmitter::Schedule('R', 490000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(16, 50), QTime(22, 50)})}},
|
||||
{3, "Cyprus", 35.048278, 33.283628, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{3, "Alexandria", 31.198089, 29.864494, {NavtexTransmitter::Schedule('N', 518000, {QTime(2, 10), QTime(6, 10), QTime(10, 10), QTime(14, 10), QTime(18, 10), QTime(22, 10)})}},
|
||||
{3, "Malta", 35.815211, 14.526911, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)})}},
|
||||
{3, "Haifa", 32.827806, 34.969306, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{3, "Split", 43.181861, 16.422333, {NavtexTransmitter::Schedule('Q', 518000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(18, 40), QTime(22, 40)})}},
|
||||
{3, "La Maddalena", 41.222778, 9.398889, {NavtexTransmitter::Schedule('R', 518000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(18, 50), QTime(22, 50)}),
|
||||
NavtexTransmitter::Schedule('I', 490000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)})}},
|
||||
{3, "Kelibia", 36.801819, 11.037372, {NavtexTransmitter::Schedule('T', 518000, {QTime(3, 10), QTime(7, 10), QTime(12, 10), QTime(15, 10), QTime(19, 10), QTime(23, 10)})}},
|
||||
{3, "Mondolfo", 43.747778, 13.141667, {NavtexTransmitter::Schedule('U', 518000, {QTime(3, 20), QTime(7, 20), QTime(12, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)}),
|
||||
NavtexTransmitter::Schedule('E', 490000, {QTime(0, 40), QTime(4, 40), QTime(8, 40), QTime(12, 40), QTime(16, 40), QTime(20, 40)})}},
|
||||
{3, "Sellia Marina", 38.873056, 16.719722, {NavtexTransmitter::Schedule('V', 518000, {QTime(3, 30), QTime(7, 30), QTime(12, 30), QTime(15, 30), QTime(19, 30), QTime(23, 30)}),
|
||||
NavtexTransmitter::Schedule('W', 490000, {QTime(3, 40), QTime(7, 40), QTime(11, 40), QTime(15, 40), QTime(17, 40), QTime(23, 40)})}},
|
||||
{3, "Cross La Garde", 43.104306, 5.991389, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)}),
|
||||
NavtexTransmitter::Schedule('S', 490000, {QTime(3, 0), QTime(7, 0), QTime(11, 0), QTime(15, 0), QTime(19, 0), QTime(3, 20)})}},
|
||||
{3, "Cabo de la Nao", 38.723258, 0.161367, {NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 50), QTime(12, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)}),
|
||||
NavtexTransmitter::Schedule('M', 490000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(16, 0), QTime(22, 0)})}},
|
||||
|
||||
{4, "Miami", 25.626225, -80.383411, {NavtexTransmitter::Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{4, "Bermuda Harbour", 32.380389, -64.682778, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{4, "Riviere-au-Renard", 50.195, -66.109889, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)}),
|
||||
NavtexTransmitter::Schedule('D', 490000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(16, 30), QTime(20, 30)})}},
|
||||
{4, "Boston", 41.709833, -70.498353, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 20), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)})}},
|
||||
{4, "New Orleans", 29.884625, -89.945611, {NavtexTransmitter::Schedule('G', 518000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(17, 0), QTime(21, 0)}),
|
||||
NavtexTransmitter::Schedule('G', 4209500, {QTime(3, 0), QTime(7, 0), QTime(11, 0), QTime(15, 0), QTime(19, 0), QTime(23, 0)})}},
|
||||
{4, "Wiarton", 44.937111, -81.233467, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)})}},
|
||||
{4, "Curacao", 12.173197, -68.864919, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)})}}, // Duplicate Id
|
||||
{4, "Portsmouth", 36.726342, -76.007894, {NavtexTransmitter::Schedule('N', 518000, {QTime(2, 10), QTime(6, 10), QTime(10, 10), QTime(14, 10), QTime(18, 10), QTime(22, 10)})}},
|
||||
{4, "St. John's", 47.611111, -52.666944, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)})}},
|
||||
{4, "Thunder Bay", 48.563514, -88.656311, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{4, "Sydney", 46.185556, -59.893611, {NavtexTransmitter::Schedule('Q', 518000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(18, 40), QTime(22, 40)}),
|
||||
NavtexTransmitter::Schedule('J', 490000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(15, 30), QTime(21, 30)})}},
|
||||
|
||||
{4, "Isabela", 18.466683, -67.071819, {NavtexTransmitter::Schedule('R', 518000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(18, 50), QTime(22, 50)})}},
|
||||
{4, "Iqaluit", 63.731389, -68.543167, {NavtexTransmitter::Schedule('T', 518000, {QTime(3, 10), QTime(7, 10), QTime(11, 10), QTime(15, 10), QTime(19, 10), QTime(23, 10)}),
|
||||
NavtexTransmitter::Schedule('S', 490000, {QTime(3, 0), QTime(7, 0), QTime(11, 0), QTime(15, 0), QTime(19, 0), QTime(3, 20)})}},
|
||||
{4, "Saint John", 43.744256, -66.121786, {NavtexTransmitter::Schedule('U', 518000, {QTime(3, 20), QTime(7, 20), QTime(11, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)}),
|
||||
NavtexTransmitter::Schedule('V', 490000, {QTime(3, 30), QTime(7, 30), QTime(11, 30), QTime(15, 30), QTime(19, 30), QTime(23, 30)})}},
|
||||
{4, "Kook Island", 64.067017, -52.012611, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)})}},
|
||||
{4, "Labrador", 53.708611, -57.021667, {NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 50), QTime(12, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)})}},
|
||||
|
||||
{6, "La Paloma", -34.666667, -54.15, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 50), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)})}},
|
||||
{6, "Ushuaia", -54.8, -68.3, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{6, "Rio Gallegos", -51.616667, -69.216667, {NavtexTransmitter::Schedule('N', 518000, {QTime(2, 10), QTime(6, 10), QTime(10, 10), QTime(14, 10), QTime(18, 10), QTime(22, 10)})}},
|
||||
{6, "Comodoro Rivadavia", -45.85, -67.416667, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)})}},
|
||||
{6, "Bahía Blanca", -38.716667, -62.1, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{6, "Mar del Plata", -38.05, -57.533333, {NavtexTransmitter::Schedule('Q', 518000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(18, 40), QTime(22, 40)})}},
|
||||
{6, "Buenos Aires", -34.6, -58.366667, {NavtexTransmitter::Schedule('R', 518000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(18, 50), QTime(22, 50)})}},
|
||||
|
||||
{7, "Walvis Bay", -23.05665, 14.624333, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{7, "Cape Town", -33.685128, 18.712961, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{7, "Port Elizabeth", -34.036722, 25.555833, {NavtexTransmitter::Schedule('I', 518000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)})}},
|
||||
{7, "Durban", -29.804833, 30.815633, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)})}},
|
||||
|
||||
{8, "Mauritius", -20.167089, 57.478161, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{8, "Bombay", 19.083239, 72.834033, {NavtexTransmitter::Schedule('G', 518000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(17, 0), QTime(21, 0)})}},
|
||||
{8, "Madras", 13.082778, 80.287222, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
|
||||
{9, "Bushehr", 28.962225, 50.822794, {NavtexTransmitter::Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{9, "Hamala", 26.157167, 50.47665, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{9, "Bandar Abbas", 27.161022, 56.225378, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 50), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)})}},
|
||||
{9, "Jeddah", 21.342222, 39.155833, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)})}},
|
||||
{9, "Muscat", 23.6, 58.5, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{9, "Karachi", 24.851944, 67.0425, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{9, "Quseir", 26.110889, 34.280083, {NavtexTransmitter::Schedule('V', 518000, {QTime(3, 30), QTime(7, 30), QTime(11, 30), QTime(15, 30), QTime(19, 30), QTime(23, 30)})}},
|
||||
{9, "Serapeum ", 30.470311, 32.36675, {NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 50), QTime(12, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)})}},
|
||||
|
||||
{11, "Jayapura", -2.516667, 140.716667, {NavtexTransmitter::Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{11, "Ambon", -3.7, 128.2, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{11, "Singapore", 1.333333, 103.7, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{11, "Makassar", -5.1, 119.433333, {NavtexTransmitter::Schedule('D', 518000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(12, 30), QTime(16, 30), QTime(20, 30)})}},
|
||||
{11, "Jakarta", -6.116667, 106.866667, {NavtexTransmitter::Schedule('E', 518000, {QTime(0, 40), QTime(4, 40), QTime(8, 40), QTime(12, 40), QTime(16, 40), QTime(20, 40)})}},
|
||||
{11, "Bangkok", 13.024444, 100.019733, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 50), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)})}},
|
||||
{11, "Naha", 26.15, 127.766667, {NavtexTransmitter::Schedule('G', 518000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(17, 0), QTime(21, 0)})}},
|
||||
{11, "Moji", 33.95, 130.966667, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)})}},
|
||||
{11, "Puerto Princesa", 9.733333, 118.716667, {NavtexTransmitter::Schedule('I', 518000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)})}},
|
||||
{11, "Yokohama", 35.433333, 139.633333, {NavtexTransmitter::Schedule('I', 518000, {QTime(1, 20), QTime(5, 20), QTime(9, 20), QTime(13, 20), QTime(17, 20), QTime(21, 20)})}}, // Duplicate Id
|
||||
{11, "Manila", 14.583333, 121.05, {NavtexTransmitter::Schedule('J', 518000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(17, 30), QTime(21, 30)})}},
|
||||
{11, "Otaru", 43.2, 141, {NavtexTransmitter::Schedule('J', 518000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(17, 30), QTime(21, 30)})}}, // Duplicate Id
|
||||
{11, "Davao City", 7.066667, 125.6, {NavtexTransmitter::Schedule('K', 518000, {QTime(1, 40), QTime(5, 40), QTime(9, 40), QTime(13, 40), QTime(17, 40), QTime(21, 40)})}},
|
||||
{11, "Kushiro", 42.983333, 144.383333, {NavtexTransmitter::Schedule('K', 518000, {QTime(1, 40), QTime(5, 40), QTime(9, 40), QTime(13, 40), QTime(17, 40), QTime(21, 40)})}}, // Duplicate Id
|
||||
{11, "Hongkong", 22.209167, 114.256111, {NavtexTransmitter::Schedule('L', 518000, {QTime(1, 50), QTime(5, 50), QTime(9, 50), QTime(13, 50), QTime(17, 50), QTime(21, 50)})}},
|
||||
{11, "Sanya", 18.232222, 109.495833, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{11, "Guangzhou", 23.15, 113.483333, {NavtexTransmitter::Schedule('N', 518000, {QTime(2, 10), QTime(6, 10), QTime(10, 10), QTime(14, 10), QTime(18, 10), QTime(22, 10)})}},
|
||||
{11, "Fuzhou", 26.028544, 119.305444, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)})}},
|
||||
{11, "Da Nang", 16.083333, 108.233333, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}},
|
||||
{11, "Chilung", 25.15, 121.733333, {NavtexTransmitter::Schedule('P', 518000, {QTime(2, 30), QTime(6, 30), QTime(10, 30), QTime(14, 30), QTime(18, 30), QTime(22, 30)})}}, // Duplicate Id
|
||||
{11, "Shanghai", 31.108889, 121.544167, {NavtexTransmitter::Schedule('Q', 518000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(18, 40), QTime(22, 40)})}},
|
||||
{11, "Dalian", 38.845244, 121.518056, {NavtexTransmitter::Schedule('R', 518000, {QTime(2, 50), QTime(6, 50), QTime(10, 50), QTime(14, 50), QTime(18, 50), QTime(22, 50)})}},
|
||||
{11, "Sandakan", 5.895886, 118.00305, {NavtexTransmitter::Schedule('S', 518000, {QTime(3, 0), QTime(7, 0), QTime(12, 0), QTime(15, 0), QTime(19, 0), QTime(23, 0)})}},
|
||||
{11, "Miri", 4.438, 114.020889, {NavtexTransmitter::Schedule('T', 518000, {QTime(3, 10), QTime(7, 10), QTime(11, 10), QTime(15, 10), QTime(19, 10), QTime(23, 10)})}},
|
||||
{11, "Penang", 5.425, 100.403056, {NavtexTransmitter::Schedule('U', 518000, {QTime(3, 20), QTime(7, 20), QTime(11, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)})}},
|
||||
{11, "Guam", 13.47445, 144.844389, {NavtexTransmitter::Schedule('V', 518000, {QTime(3, 30), QTime(7, 30), QTime(11, 30), QTime(15, 30), QTime(19, 30), QTime(23, 30)})}},
|
||||
{11, "Jukbyeon", 37.05, 129.416667, {NavtexTransmitter::Schedule('V', 518000, {QTime(3, 30), QTime(7, 30), QTime(11, 30), QTime(15, 30), QTime(19, 30), QTime(23, 30)}), // Duplicate Id
|
||||
NavtexTransmitter::Schedule('J', 490000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(15, 30), QTime(21, 30)})}},
|
||||
|
||||
{11, "Byeonsan", 35.6, 126.483333, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)}),
|
||||
NavtexTransmitter::Schedule('K', 490000, {QTime(1, 40), QTime(5, 40), QTime(9, 40), QTime(17, 40), QTime(21, 40)})}},
|
||||
{11, "Ho-Chi-Minh City", 10.703317, 106.729139, {NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 50), QTime(12, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)})}},
|
||||
|
||||
{12, "San Francisco", 37.925739, -122.734056, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{12, "Prince Rupert", 54.298519, -130.417669, {NavtexTransmitter::Schedule('D', 518000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(12, 30), QTime(16, 30), QTime(20, 30)})}},
|
||||
{12, "Tofino", 48.925478, -125.540306, {NavtexTransmitter::Schedule('H', 518000, {QTime(1, 10), QTime(5, 10), QTime(9, 10), QTime(13, 10), QTime(17, 10), QTime(21, 10)})}},
|
||||
{12, "Kodiak", 57.781606, -152.537583, {NavtexTransmitter::Schedule('J', 518000, {QTime(1, 30), QTime(5, 30), QTime(9, 30), QTime(13, 30), QTime(17, 30), QTime(21, 30)}),
|
||||
NavtexTransmitter::Schedule('X', 518000, {QTime(3, 50), QTime(7, 50), QTime(12, 50), QTime(15, 50), QTime(19, 50), QTime(23, 50)})}},
|
||||
{12, "Ayora", -0.75, -90.316667, {NavtexTransmitter::Schedule('L', 518000, {QTime(1, 50), QTime(5, 50), QTime(9, 50), QTime(13, 50), QTime(17, 50), QTime(21, 50)}),
|
||||
NavtexTransmitter::Schedule('A', 490000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{12, "Guayaquil", -2.283333, -80.016667, {NavtexTransmitter::Schedule('M', 518000, {QTime(2, 0), QTime(6, 0), QTime(10, 0), QTime(14, 0), QTime(18, 0), QTime(22, 0)})}},
|
||||
{12, "Honolulu", 21.437019, -158.143239, {NavtexTransmitter::Schedule('O', 518000, {QTime(2, 20), QTime(6, 20), QTime(10, 20), QTime(14, 20), QTime(18, 20), QTime(22, 20)})}},
|
||||
{12, "Cambria", 35.524297, -121.061922, {NavtexTransmitter::Schedule('Q', 518000, {QTime(2, 40), QTime(6, 40), QTime(10, 40), QTime(14, 40), QTime(18, 40), QTime(22, 40)})}},
|
||||
{12, "Astoria", 46.203989, -123.955639, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)})}},
|
||||
|
||||
{13, "Vladivostok", 43.381472, 131.899861, {NavtexTransmitter::Schedule('A', 518000, {QTime(0, 0), QTime(4, 0), QTime(8, 0), QTime(12, 0), QTime(16, 0), QTime(20, 0)})}},
|
||||
{13, "Kholmsk", 47.023556, 142.045056, {NavtexTransmitter::Schedule('B', 518000, {QTime(0, 10), QTime(4, 10), QTime(8, 10), QTime(12, 10), QTime(16, 10), QTime(20, 10)})}},
|
||||
{13, "Murmansk", 68.865803, 33.070761, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}},
|
||||
{13, "Petropavlosk", 53.247778, 158.419472, {NavtexTransmitter::Schedule('C', 518000, {QTime(0, 20), QTime(4, 20), QTime(8, 20), QTime(12, 20), QTime(16, 20), QTime(20, 20)})}}, // Duplicate
|
||||
{13, "Magadan", 59.683333, 150.15, {NavtexTransmitter::Schedule('D', 518000, {QTime(0, 30), QTime(4, 30), QTime(8, 30), QTime(12, 30), QTime(16, 30), QTime(20, 30)})}},
|
||||
{13, "Archangelsk", 64.556278, 40.550028, {NavtexTransmitter::Schedule('F', 518000, {QTime(0, 50), QTime(4, 50), QTime(8, 50), QTime(12, 50), QTime(16, 50), QTime(20, 50)})}},
|
||||
{13, "Okhotsk", 59.366667, 143.2, {NavtexTransmitter::Schedule('G', 518000, {QTime(1, 0), QTime(5, 0), QTime(9, 0), QTime(13, 0), QTime(17, 0), QTime(21, 0)})}},
|
||||
{13, "Astrakhan", 46.296694, 47.997778, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)})}},
|
||||
|
||||
{15, "Antofagasta", -23.491333, -70.424778, {NavtexTransmitter::Schedule('A', 518000, {QTime(4, 0), QTime(12, 0), QTime(20, 0)})}},
|
||||
{15, "Valparaíso", -32.802222, -71.485, {NavtexTransmitter::Schedule('B', 518000, {QTime(4, 10), QTime(12, 10), QTime(20, 10)})}},
|
||||
{15, "Talcahuano", -36.715056, -73.108, {NavtexTransmitter::Schedule('C', 518000, {QTime(4, 20), QTime(12, 20), QTime(20, 20)})}},
|
||||
{15, "Puerto Montt", -41.489983, -72.957744, {NavtexTransmitter::Schedule('D', 518000, {QTime(4, 30), QTime(12, 30), QTime(20, 30)})}},
|
||||
{15, "Punta Arenas", -52.948111, -71.056944, {NavtexTransmitter::Schedule('E', 518000, {QTime(4, 40), QTime(12, 40), QTime(20, 40)})}},
|
||||
{15, "Easter Island", -27.15, -109.416667, {NavtexTransmitter::Schedule('F', 518000, {QTime(4, 50), QTime(12, 50), QTime(20, 50)})}},
|
||||
|
||||
{16, "Paita", -5.083333, -81.116667, {NavtexTransmitter::Schedule('S', 518000, {QTime(3, 0), QTime(7, 0), QTime(12, 0), QTime(15, 0), QTime(19, 0), QTime(23, 0)})}},
|
||||
{16, "Callao", -12.5, -77.15, {NavtexTransmitter::Schedule('U', 518000, {QTime(3, 20), QTime(7, 20), QTime(11, 20), QTime(15, 20), QTime(19, 20), QTime(23, 20)})}},
|
||||
{16, "Mollendo", -17.016667, -72.016667, {NavtexTransmitter::Schedule('W', 518000, {QTime(3, 40), QTime(7, 40), QTime(12, 40), QTime(15, 40), QTime(19, 40), QTime(23, 40)})}},
|
||||
|
||||
};
|
||||
|
||||
const QMap<QString,QString> NavtexMessage::m_types = {
|
||||
{"A", "Navigational warning"},
|
||||
{"B", "Meteorological warning"},
|
||||
{"C", "Ice reports"},
|
||||
{"D", "Search and rescue"},
|
||||
{"E", "Meteorological forecasts"},
|
||||
{"F", "Pilot service messages"},
|
||||
{"G", "AIS"},
|
||||
{"H", "LORAN"},
|
||||
{"J", "SATNAV"},
|
||||
{"K", "Navaid messages"},
|
||||
{"L", "Navigational warning"},
|
||||
{"T", "Test transmissions"},
|
||||
{"X", "Special services"},
|
||||
{"Y", "Special services"},
|
||||
{"Z", "No message"}
|
||||
};
|
||||
|
||||
const NavtexTransmitter* NavtexTransmitter::getTransmitter(QTime time, int area, qint64 frequency)
|
||||
{
|
||||
for (const auto& transmitter : NavtexTransmitter::m_navtexTransmitters)
|
||||
{
|
||||
if (transmitter.m_area == area)
|
||||
{
|
||||
for (const auto& schedule : transmitter.m_schedules)
|
||||
{
|
||||
if (schedule.m_frequency == frequency)
|
||||
{
|
||||
for (const auto& txStartTime : schedule.m_times)
|
||||
{
|
||||
// Transmitters have 10 minute windows for transmission
|
||||
int secs = txStartTime.secsTo(time);
|
||||
if ((secs >= 0) && (secs < 10*60)) {
|
||||
return &transmitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NavtexMessage::NavtexMessage(QDateTime dateTime, const QString& stationId, const QString& typeId, const QString& id, const QString& message) :
|
||||
m_dateTime(dateTime),
|
||||
m_stationId(stationId),
|
||||
m_typeId(typeId),
|
||||
m_id(id),
|
||||
m_message(message),
|
||||
m_valid(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NavtexMessage::NavtexMessage(const QString& text)
|
||||
{
|
||||
m_dateTime = QDateTime::currentDateTime();
|
||||
QRegularExpression re("[Z*][C*][Z*][C*][ *]([A-Z])([A-Z])(\\d\\d)((.|\n|\r)*)[N*][N*][N*][N*]");
|
||||
|
||||
QRegularExpressionMatch match = re.match(text);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
m_stationId = match.captured(1);
|
||||
m_typeId = match.captured(2);
|
||||
m_id = match.captured(3);
|
||||
m_message = match.captured(4).trimmed();
|
||||
m_valid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_message = text;
|
||||
m_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
QString NavtexMessage::getStation(int area, qint64 frequency) const
|
||||
{
|
||||
for (const auto& transmitter : NavtexTransmitter::m_navtexTransmitters)
|
||||
{
|
||||
if (transmitter.m_area == area)
|
||||
{
|
||||
for (const auto& schedule : transmitter.m_schedules)
|
||||
{
|
||||
if ((schedule.m_id == m_stationId) && (schedule.m_frequency == frequency)) {
|
||||
return transmitter.m_station;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QString NavtexMessage::getType() const
|
||||
{
|
||||
if (m_valid && m_types.contains(m_typeId)) {
|
||||
return m_types.value(m_typeId);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void SitorBDecoder::init()
|
||||
{
|
||||
m_state = PHASING;
|
||||
m_idx = 0;
|
||||
m_figureSet = false;
|
||||
m_errors = 0;
|
||||
}
|
||||
|
||||
// In:
|
||||
// Received 7-bit CCIR476 sequence
|
||||
// Returns:
|
||||
// Decoded ASCII character
|
||||
// ETX end of text
|
||||
// '*' both chars invalid
|
||||
// -1 no character available yet
|
||||
char SitorBDecoder::decode(char c)
|
||||
{
|
||||
char ret = -1;
|
||||
|
||||
//qDebug() << "In: " << printable(ccir476Decode(c));
|
||||
|
||||
switch (m_state)
|
||||
{
|
||||
case PHASING:
|
||||
// Wait until we get a valid non-phasing character
|
||||
if ((c != PHASING_1) && (c != PHASING_2) && (ccir476Decode(c) != -1))
|
||||
{
|
||||
m_buf[m_idx++] = c;
|
||||
m_state = FILL_RX;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILL_DX:
|
||||
// Fill up buffer
|
||||
m_buf[m_idx++] = c;
|
||||
if (m_idx == BUFFER_SIZE)
|
||||
{
|
||||
m_state = RX;
|
||||
m_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state = FILL_RX;
|
||||
}
|
||||
break;
|
||||
|
||||
case FILL_RX:
|
||||
// Should be phasing 1
|
||||
if (c != PHASING_1) {
|
||||
m_errors++;
|
||||
}
|
||||
m_state = FILL_DX;
|
||||
break;
|
||||
|
||||
|
||||
case RX:
|
||||
{
|
||||
// Try to decode a character
|
||||
char dx = ccir476Decode(m_buf[m_idx]);
|
||||
char rx = ccir476Decode(c);
|
||||
char a;
|
||||
|
||||
// Idle alpha (phasing 1) in both dx and rx means end of signal
|
||||
if ((dx == '<') && (rx == '<'))
|
||||
{
|
||||
a = 0x2; // ETX - End of text
|
||||
}
|
||||
else if (dx != -1)
|
||||
{
|
||||
a = dx; // First received character has no detectable error
|
||||
if ((dx != rx) && !((dx == '<') && (rx == '>')) && !((dx == '>') && (rx == '<'))) {
|
||||
m_errors++;
|
||||
}
|
||||
}
|
||||
else if (rx != -1)
|
||||
{
|
||||
a = rx; // Second received character has no detectable error
|
||||
m_errors++;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = '*'; // Both received characters have errors
|
||||
m_errors += 2;
|
||||
}
|
||||
if (a == 0xf) {
|
||||
m_figureSet = false;
|
||||
} else if (a == 0xe) {
|
||||
m_figureSet = true;
|
||||
} else {
|
||||
ret = a;
|
||||
}
|
||||
m_state = DX;
|
||||
}
|
||||
break;
|
||||
|
||||
case DX:
|
||||
// Save received character in buffer
|
||||
m_buf[m_idx] = c;
|
||||
m_idx = (m_idx + 1) % BUFFER_SIZE;
|
||||
m_state = RX;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString SitorBDecoder::printable(char c)
|
||||
{
|
||||
if (c == -1) {
|
||||
return "Unknown";
|
||||
} else if (c == 0x2) {
|
||||
return "End of transmission";
|
||||
} else if (c == 0xf) {
|
||||
return "Letter";
|
||||
} else if (c == 0xe) {
|
||||
return "Figure";
|
||||
} else if (c == 0x5) {
|
||||
return "Cross";
|
||||
} else if (c == 0x7) {
|
||||
return "Bell";
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
// https://www.itu.int/dms_pubrec/itu-r/rec/m/R-REC-M.476-5-199510-I!!PDF-E.pdf - Table 1
|
||||
|
||||
// https://www.itu.int/dms_pubrec/itu-r/rec/m/R-REC-M.625-4-201203-I!!PDF-E.pdf
|
||||
|
||||
const char SitorBDecoder::m_ccir476LetterSetDecode[128] = {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0x0d,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'T',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0x0a,
|
||||
-1,
|
||||
' ',
|
||||
'V',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'B',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0x0f,
|
||||
'X',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'>',
|
||||
-1,
|
||||
'E',
|
||||
0x0e,
|
||||
-1,
|
||||
-1,
|
||||
'U',
|
||||
'Q',
|
||||
-1,
|
||||
'K',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'O',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'H',
|
||||
-1,
|
||||
'N',
|
||||
'M',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'L',
|
||||
-1,
|
||||
'R',
|
||||
'G',
|
||||
-1,
|
||||
-1,
|
||||
'I',
|
||||
'P',
|
||||
-1,
|
||||
'C',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'Z',
|
||||
-1,
|
||||
'D',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'S',
|
||||
'Y',
|
||||
-1,
|
||||
'F',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'A',
|
||||
'W',
|
||||
-1,
|
||||
'J',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'<',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
};
|
||||
|
||||
const char SitorBDecoder::m_ccir476FigureSetDecode[128] = {
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0x0d,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'5',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0x0a,
|
||||
-1,
|
||||
' ',
|
||||
'=',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'?',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
0x0f,
|
||||
'/',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'>',
|
||||
-1,
|
||||
'3',
|
||||
0x0e,
|
||||
-1,
|
||||
-1,
|
||||
'7',
|
||||
'1',
|
||||
-1,
|
||||
'(',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'9',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-93,
|
||||
-1,
|
||||
',',
|
||||
'.',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
')',
|
||||
-1,
|
||||
'4',
|
||||
'&',
|
||||
-1,
|
||||
-1,
|
||||
'8',
|
||||
'0',
|
||||
-1,
|
||||
':',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'+',
|
||||
-1,
|
||||
0x05,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'\'',
|
||||
'6',
|
||||
-1,
|
||||
'!',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'-',
|
||||
'2',
|
||||
-1,
|
||||
0x07,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
'<',
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
};
|
||||
|
||||
char SitorBDecoder::ccir476Decode(char c)
|
||||
{
|
||||
if (m_figureSet) {
|
||||
return m_ccir476FigureSetDecode[c];
|
||||
} else {
|
||||
return m_ccir476LetterSetDecode[c];
|
||||
}
|
||||
}
|
||||
|
111
sdrbase/util/navtex.h
Normal file
111
sdrbase/util/navtex.h
Normal file
@ -0,0 +1,111 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2020 Jon Beniston, M7RCE //
|
||||
// //
|
||||
// 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_UTIL_NAVTEX_H
|
||||
#define INCLUDE_UTIL_NAVTEX_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDateTime>
|
||||
#include <QMap>
|
||||
|
||||
#include "export.h"
|
||||
|
||||
class SDRBASE_API NavtexTransmitter {
|
||||
|
||||
public:
|
||||
|
||||
struct Schedule {
|
||||
char m_id;
|
||||
qint64 m_frequency;
|
||||
QList<QTime> m_times;
|
||||
Schedule(char id, qint64 frequency) :
|
||||
m_id(id),
|
||||
m_frequency(frequency)
|
||||
{
|
||||
}
|
||||
Schedule(char id, qint64 frequency, QList<QTime> times) :
|
||||
m_id(id),
|
||||
m_frequency(frequency),
|
||||
m_times(times)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
int m_area;
|
||||
QString m_station;
|
||||
float m_latitude;
|
||||
float m_longitude;
|
||||
QList<Schedule> m_schedules;
|
||||
|
||||
static const QList<NavtexTransmitter> m_navtexTransmitters;
|
||||
static const NavtexTransmitter* getTransmitter(QTime time, int area, qint64 frequency);
|
||||
};
|
||||
|
||||
class SDRBASE_API NavtexMessage {
|
||||
|
||||
public:
|
||||
|
||||
QString m_stationId;
|
||||
QString m_typeId;
|
||||
QString m_id;
|
||||
QString m_message;
|
||||
QDateTime m_dateTime;
|
||||
bool m_valid;
|
||||
|
||||
static const QMap<QString,QString> m_types;
|
||||
|
||||
NavtexMessage(const QString& text);
|
||||
NavtexMessage(QDateTime dataTime, const QString& stationId, const QString& typeId, const QString& id, const QString& message);
|
||||
QString getStation(int area, qint64 frequency) const;
|
||||
QString getType() const;
|
||||
|
||||
};
|
||||
|
||||
class SDRBASE_API SitorBDecoder {
|
||||
|
||||
public:
|
||||
|
||||
void init();
|
||||
char decode(char c);
|
||||
int getErrors() const { return m_errors; }
|
||||
static QString printable(char c);
|
||||
|
||||
private:
|
||||
static const char PHASING_1 = 0x78;
|
||||
static const char PHASING_2 = 0x33;
|
||||
static const int BUFFER_SIZE = 3;
|
||||
char m_buf[3];
|
||||
bool m_figureSet;
|
||||
enum State {
|
||||
PHASING,
|
||||
FILL_DX,
|
||||
FILL_RX,
|
||||
DX,
|
||||
RX
|
||||
} m_state;
|
||||
int m_idx;
|
||||
int m_errors;
|
||||
|
||||
static const char m_ccir476LetterSetDecode[128];
|
||||
static const char m_ccir476FigureSetDecode[128];
|
||||
|
||||
char ccir476Decode(char c);
|
||||
|
||||
};
|
||||
|
||||
#endif // INCLUDE_UTIL_NAVTEX_H
|
||||
|
@ -51,12 +51,16 @@ ChannelReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/FreqTracker.yaml#/FreqTrackerReport"
|
||||
FT8DemodReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/FT8Demod.yaml#/FT8DemodReport"
|
||||
RTTYDemodReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RTTYDemod.yaml#/RTTYDemodReport"
|
||||
HeatMapReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/HeatMap.yaml#/HeatMapReport"
|
||||
M17DemodReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/M17Demod.yaml#/M17DemodReport"
|
||||
M17ModReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/M17Mod.yaml#/M17ModReport"
|
||||
NavtexDemodReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/NavtexDemod.yaml#/NavtexDemodReport"
|
||||
NFMDemodReport:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodReport"
|
||||
NFMModReport:
|
||||
|
@ -65,6 +65,8 @@ ChannelSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/FreqTracker.yaml#/FreqTrackerSettings"
|
||||
FT8DemodSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/FT8Demod.yaml#/FT8DemodSettings"
|
||||
RTTYDemodSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RTTYDemod.yaml#/RTTYDemodSettings"
|
||||
HeatMapSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/HeatMap.yaml#/HeatMapSettings"
|
||||
InterferometerSettings:
|
||||
@ -75,6 +77,8 @@ ChannelSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/M17Demod.yaml#/M17DemodSettings"
|
||||
M17ModSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/M17Mod.yaml#/M17ModSettings"
|
||||
NavtexDemodSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/NavtexDemod.yaml#/NavtexDemodSettings"
|
||||
NFMDemodSettings:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/NFMDemod.yaml#/NFMDemodSettings"
|
||||
NFMModSettings:
|
||||
|
62
swagger/sdrangel/api/swagger/include/NavtexDemod.yaml
Normal file
62
swagger/sdrangel/api/swagger/include/NavtexDemod.yaml
Normal file
@ -0,0 +1,62 @@
|
||||
NavtexDemodSettings:
|
||||
description: ACARSDemod
|
||||
properties:
|
||||
inputFrequencyOffset:
|
||||
type: integer
|
||||
format: int64
|
||||
rfBandwidth:
|
||||
type: number
|
||||
format: float
|
||||
navArea:
|
||||
type: integer
|
||||
filterStation:
|
||||
type: string
|
||||
filterType:
|
||||
type: string
|
||||
udpEnabled:
|
||||
description: "Whether to forward received messages to specified UDP port"
|
||||
type: integer
|
||||
udpAddress:
|
||||
description: "UDP address to forward received messages to"
|
||||
type: string
|
||||
udpPort:
|
||||
description: "UDP port to forward received messages to"
|
||||
type: integer
|
||||
logFilename:
|
||||
type: string
|
||||
logEnabled:
|
||||
type: integer
|
||||
rgbColor:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
streamIndex:
|
||||
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
type: integer
|
||||
useReverseAPI:
|
||||
description: Synchronize with reverse API (1 for yes, 0 for no)
|
||||
type: integer
|
||||
reverseAPIAddress:
|
||||
type: string
|
||||
reverseAPIPort:
|
||||
type: integer
|
||||
reverseAPIDeviceIndex:
|
||||
type: integer
|
||||
reverseAPIChannelIndex:
|
||||
type: integer
|
||||
scopeConfig:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/GLScope.yaml#/GLScope"
|
||||
channelMarker:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/ChannelMarker.yaml#/ChannelMarker"
|
||||
rollupState:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RollupState.yaml#/RollupState"
|
||||
|
||||
NavtexDemodReport:
|
||||
description: ACARSDemod
|
||||
properties:
|
||||
channelPowerDB:
|
||||
description: power received in channel (dB)
|
||||
type: number
|
||||
format: float
|
||||
channelSampleRate:
|
||||
type: integer
|
73
swagger/sdrangel/api/swagger/include/RTTYDemod.yaml
Normal file
73
swagger/sdrangel/api/swagger/include/RTTYDemod.yaml
Normal file
@ -0,0 +1,73 @@
|
||||
RTTYDemodSettings:
|
||||
description: ACARSDemod
|
||||
properties:
|
||||
inputFrequencyOffset:
|
||||
type: integer
|
||||
format: int64
|
||||
rfBandwidth:
|
||||
type: number
|
||||
format: float
|
||||
baudRate:
|
||||
type: number
|
||||
format: float
|
||||
frequencyShift:
|
||||
type: integer
|
||||
udpEnabled:
|
||||
description: "Whether to forward received messages to specified UDP port"
|
||||
type: integer
|
||||
udpAddress:
|
||||
description: "UDP address to forward received messages to"
|
||||
type: string
|
||||
udpPort:
|
||||
description: "UDP port to forward received messages to"
|
||||
type: integer
|
||||
characterSet:
|
||||
type: integer
|
||||
suppressCRLF:
|
||||
type: integer
|
||||
unshiftOnSpace:
|
||||
type: integer
|
||||
msbFirst:
|
||||
type: integer
|
||||
spaceHigh:
|
||||
type: integer
|
||||
squelch:
|
||||
type: integer
|
||||
logFilename:
|
||||
type: string
|
||||
logEnabled:
|
||||
type: integer
|
||||
rgbColor:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
streamIndex:
|
||||
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
||||
type: integer
|
||||
useReverseAPI:
|
||||
description: Synchronize with reverse API (1 for yes, 0 for no)
|
||||
type: integer
|
||||
reverseAPIAddress:
|
||||
type: string
|
||||
reverseAPIPort:
|
||||
type: integer
|
||||
reverseAPIDeviceIndex:
|
||||
type: integer
|
||||
reverseAPIChannelIndex:
|
||||
type: integer
|
||||
scopeConfig:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/GLScope.yaml#/GLScope"
|
||||
channelMarker:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/ChannelMarker.yaml#/ChannelMarker"
|
||||
rollupState:
|
||||
$ref: "http://swgserver:8081/api/swagger/include/RollupState.yaml#/RollupState"
|
||||
|
||||
RTTYDemodReport:
|
||||
description: ACARSDemod
|
||||
properties:
|
||||
channelPowerDB:
|
||||
description: power received in channel (dB)
|
||||
type: number
|
||||
format: float
|
||||
channelSampleRate:
|
||||
type: integer
|
@ -72,12 +72,16 @@ SWGChannelReport::SWGChannelReport() {
|
||||
m_freq_tracker_report_isSet = false;
|
||||
ft8_demod_report = nullptr;
|
||||
m_ft8_demod_report_isSet = false;
|
||||
rtty_demod_report = nullptr;
|
||||
m_rtty_demod_report_isSet = false;
|
||||
heat_map_report = nullptr;
|
||||
m_heat_map_report_isSet = false;
|
||||
m17_demod_report = nullptr;
|
||||
m_m17_demod_report_isSet = false;
|
||||
m17_mod_report = nullptr;
|
||||
m_m17_mod_report_isSet = false;
|
||||
navtex_demod_report = nullptr;
|
||||
m_navtex_demod_report_isSet = false;
|
||||
nfm_demod_report = nullptr;
|
||||
m_nfm_demod_report_isSet = false;
|
||||
nfm_mod_report = nullptr;
|
||||
@ -166,12 +170,16 @@ SWGChannelReport::init() {
|
||||
m_freq_tracker_report_isSet = false;
|
||||
ft8_demod_report = new SWGFT8DemodReport();
|
||||
m_ft8_demod_report_isSet = false;
|
||||
rtty_demod_report = new SWGRTTYDemodReport();
|
||||
m_rtty_demod_report_isSet = false;
|
||||
heat_map_report = new SWGHeatMapReport();
|
||||
m_heat_map_report_isSet = false;
|
||||
m17_demod_report = new SWGM17DemodReport();
|
||||
m_m17_demod_report_isSet = false;
|
||||
m17_mod_report = new SWGM17ModReport();
|
||||
m_m17_mod_report_isSet = false;
|
||||
navtex_demod_report = new SWGNavtexDemodReport();
|
||||
m_navtex_demod_report_isSet = false;
|
||||
nfm_demod_report = new SWGNFMDemodReport();
|
||||
m_nfm_demod_report_isSet = false;
|
||||
nfm_mod_report = new SWGNFMModReport();
|
||||
@ -276,6 +284,9 @@ SWGChannelReport::cleanup() {
|
||||
if(ft8_demod_report != nullptr) {
|
||||
delete ft8_demod_report;
|
||||
}
|
||||
if(rtty_demod_report != nullptr) {
|
||||
delete rtty_demod_report;
|
||||
}
|
||||
if(heat_map_report != nullptr) {
|
||||
delete heat_map_report;
|
||||
}
|
||||
@ -285,6 +296,9 @@ SWGChannelReport::cleanup() {
|
||||
if(m17_mod_report != nullptr) {
|
||||
delete m17_mod_report;
|
||||
}
|
||||
if(navtex_demod_report != nullptr) {
|
||||
delete navtex_demod_report;
|
||||
}
|
||||
if(nfm_demod_report != nullptr) {
|
||||
delete nfm_demod_report;
|
||||
}
|
||||
@ -396,12 +410,16 @@ SWGChannelReport::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&ft8_demod_report, pJson["FT8DemodReport"], "SWGFT8DemodReport", "SWGFT8DemodReport");
|
||||
|
||||
::SWGSDRangel::setValue(&rtty_demod_report, pJson["RTTYDemodReport"], "SWGRTTYDemodReport", "SWGRTTYDemodReport");
|
||||
|
||||
::SWGSDRangel::setValue(&heat_map_report, pJson["HeatMapReport"], "SWGHeatMapReport", "SWGHeatMapReport");
|
||||
|
||||
::SWGSDRangel::setValue(&m17_demod_report, pJson["M17DemodReport"], "SWGM17DemodReport", "SWGM17DemodReport");
|
||||
|
||||
::SWGSDRangel::setValue(&m17_mod_report, pJson["M17ModReport"], "SWGM17ModReport", "SWGM17ModReport");
|
||||
|
||||
::SWGSDRangel::setValue(&navtex_demod_report, pJson["NavtexDemodReport"], "SWGNavtexDemodReport", "SWGNavtexDemodReport");
|
||||
|
||||
::SWGSDRangel::setValue(&nfm_demod_report, pJson["NFMDemodReport"], "SWGNFMDemodReport", "SWGNFMDemodReport");
|
||||
|
||||
::SWGSDRangel::setValue(&nfm_mod_report, pJson["NFMModReport"], "SWGNFMModReport", "SWGNFMModReport");
|
||||
@ -520,6 +538,9 @@ SWGChannelReport::asJsonObject() {
|
||||
if((ft8_demod_report != nullptr) && (ft8_demod_report->isSet())){
|
||||
toJsonValue(QString("FT8DemodReport"), ft8_demod_report, obj, QString("SWGFT8DemodReport"));
|
||||
}
|
||||
if((rtty_demod_report != nullptr) && (rtty_demod_report->isSet())){
|
||||
toJsonValue(QString("RTTYDemodReport"), rtty_demod_report, obj, QString("SWGRTTYDemodReport"));
|
||||
}
|
||||
if((heat_map_report != nullptr) && (heat_map_report->isSet())){
|
||||
toJsonValue(QString("HeatMapReport"), heat_map_report, obj, QString("SWGHeatMapReport"));
|
||||
}
|
||||
@ -529,6 +550,9 @@ SWGChannelReport::asJsonObject() {
|
||||
if((m17_mod_report != nullptr) && (m17_mod_report->isSet())){
|
||||
toJsonValue(QString("M17ModReport"), m17_mod_report, obj, QString("SWGM17ModReport"));
|
||||
}
|
||||
if((navtex_demod_report != nullptr) && (navtex_demod_report->isSet())){
|
||||
toJsonValue(QString("NavtexDemodReport"), navtex_demod_report, obj, QString("SWGNavtexDemodReport"));
|
||||
}
|
||||
if((nfm_demod_report != nullptr) && (nfm_demod_report->isSet())){
|
||||
toJsonValue(QString("NFMDemodReport"), nfm_demod_report, obj, QString("SWGNFMDemodReport"));
|
||||
}
|
||||
@ -807,6 +831,16 @@ SWGChannelReport::setFt8DemodReport(SWGFT8DemodReport* ft8_demod_report) {
|
||||
this->m_ft8_demod_report_isSet = true;
|
||||
}
|
||||
|
||||
SWGRTTYDemodReport*
|
||||
SWGChannelReport::getRttyDemodReport() {
|
||||
return rtty_demod_report;
|
||||
}
|
||||
void
|
||||
SWGChannelReport::setRttyDemodReport(SWGRTTYDemodReport* rtty_demod_report) {
|
||||
this->rtty_demod_report = rtty_demod_report;
|
||||
this->m_rtty_demod_report_isSet = true;
|
||||
}
|
||||
|
||||
SWGHeatMapReport*
|
||||
SWGChannelReport::getHeatMapReport() {
|
||||
return heat_map_report;
|
||||
@ -837,6 +871,16 @@ SWGChannelReport::setM17ModReport(SWGM17ModReport* m17_mod_report) {
|
||||
this->m_m17_mod_report_isSet = true;
|
||||
}
|
||||
|
||||
SWGNavtexDemodReport*
|
||||
SWGChannelReport::getNavtexDemodReport() {
|
||||
return navtex_demod_report;
|
||||
}
|
||||
void
|
||||
SWGChannelReport::setNavtexDemodReport(SWGNavtexDemodReport* navtex_demod_report) {
|
||||
this->navtex_demod_report = navtex_demod_report;
|
||||
this->m_navtex_demod_report_isSet = true;
|
||||
}
|
||||
|
||||
SWGNFMDemodReport*
|
||||
SWGChannelReport::getNfmDemodReport() {
|
||||
return nfm_demod_report;
|
||||
@ -1088,6 +1132,9 @@ SWGChannelReport::isSet(){
|
||||
if(ft8_demod_report && ft8_demod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rtty_demod_report && rtty_demod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(heat_map_report && heat_map_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
@ -1097,6 +1144,9 @@ SWGChannelReport::isSet(){
|
||||
if(m17_mod_report && m17_mod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(navtex_demod_report && navtex_demod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(nfm_demod_report && nfm_demod_report->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -47,10 +47,12 @@
|
||||
#include "SWGM17ModReport.h"
|
||||
#include "SWGNFMDemodReport.h"
|
||||
#include "SWGNFMModReport.h"
|
||||
#include "SWGNavtexDemodReport.h"
|
||||
#include "SWGNoiseFigureReport.h"
|
||||
#include "SWGPacketDemodReport.h"
|
||||
#include "SWGPacketModReport.h"
|
||||
#include "SWGPagerDemodReport.h"
|
||||
#include "SWGRTTYDemodReport.h"
|
||||
#include "SWGRadioAstronomyReport.h"
|
||||
#include "SWGRadioClockReport.h"
|
||||
#include "SWGRadiosondeDemodReport.h"
|
||||
@ -149,6 +151,9 @@ public:
|
||||
SWGFT8DemodReport* getFt8DemodReport();
|
||||
void setFt8DemodReport(SWGFT8DemodReport* ft8_demod_report);
|
||||
|
||||
SWGRTTYDemodReport* getRttyDemodReport();
|
||||
void setRttyDemodReport(SWGRTTYDemodReport* rtty_demod_report);
|
||||
|
||||
SWGHeatMapReport* getHeatMapReport();
|
||||
void setHeatMapReport(SWGHeatMapReport* heat_map_report);
|
||||
|
||||
@ -158,6 +163,9 @@ public:
|
||||
SWGM17ModReport* getM17ModReport();
|
||||
void setM17ModReport(SWGM17ModReport* m17_mod_report);
|
||||
|
||||
SWGNavtexDemodReport* getNavtexDemodReport();
|
||||
void setNavtexDemodReport(SWGNavtexDemodReport* navtex_demod_report);
|
||||
|
||||
SWGNFMDemodReport* getNfmDemodReport();
|
||||
void setNfmDemodReport(SWGNFMDemodReport* nfm_demod_report);
|
||||
|
||||
@ -282,6 +290,9 @@ private:
|
||||
SWGFT8DemodReport* ft8_demod_report;
|
||||
bool m_ft8_demod_report_isSet;
|
||||
|
||||
SWGRTTYDemodReport* rtty_demod_report;
|
||||
bool m_rtty_demod_report_isSet;
|
||||
|
||||
SWGHeatMapReport* heat_map_report;
|
||||
bool m_heat_map_report_isSet;
|
||||
|
||||
@ -291,6 +302,9 @@ private:
|
||||
SWGM17ModReport* m17_mod_report;
|
||||
bool m_m17_mod_report_isSet;
|
||||
|
||||
SWGNavtexDemodReport* navtex_demod_report;
|
||||
bool m_navtex_demod_report_isSet;
|
||||
|
||||
SWGNFMDemodReport* nfm_demod_report;
|
||||
bool m_nfm_demod_report_isSet;
|
||||
|
||||
|
@ -84,6 +84,8 @@ SWGChannelSettings::SWGChannelSettings() {
|
||||
m_freq_tracker_settings_isSet = false;
|
||||
ft8_demod_settings = nullptr;
|
||||
m_ft8_demod_settings_isSet = false;
|
||||
rtty_demod_settings = nullptr;
|
||||
m_rtty_demod_settings_isSet = false;
|
||||
heat_map_settings = nullptr;
|
||||
m_heat_map_settings_isSet = false;
|
||||
interferometer_settings = nullptr;
|
||||
@ -94,6 +96,8 @@ SWGChannelSettings::SWGChannelSettings() {
|
||||
m_m17_demod_settings_isSet = false;
|
||||
m17_mod_settings = nullptr;
|
||||
m_m17_mod_settings_isSet = false;
|
||||
navtex_demod_settings = nullptr;
|
||||
m_navtex_demod_settings_isSet = false;
|
||||
nfm_demod_settings = nullptr;
|
||||
m_nfm_demod_settings_isSet = false;
|
||||
nfm_mod_settings = nullptr;
|
||||
@ -202,6 +206,8 @@ SWGChannelSettings::init() {
|
||||
m_freq_tracker_settings_isSet = false;
|
||||
ft8_demod_settings = new SWGFT8DemodSettings();
|
||||
m_ft8_demod_settings_isSet = false;
|
||||
rtty_demod_settings = new SWGRTTYDemodSettings();
|
||||
m_rtty_demod_settings_isSet = false;
|
||||
heat_map_settings = new SWGHeatMapSettings();
|
||||
m_heat_map_settings_isSet = false;
|
||||
interferometer_settings = new SWGInterferometerSettings();
|
||||
@ -212,6 +218,8 @@ SWGChannelSettings::init() {
|
||||
m_m17_demod_settings_isSet = false;
|
||||
m17_mod_settings = new SWGM17ModSettings();
|
||||
m_m17_mod_settings_isSet = false;
|
||||
navtex_demod_settings = new SWGNavtexDemodSettings();
|
||||
m_navtex_demod_settings_isSet = false;
|
||||
nfm_demod_settings = new SWGNFMDemodSettings();
|
||||
m_nfm_demod_settings_isSet = false;
|
||||
nfm_mod_settings = new SWGNFMModSettings();
|
||||
@ -338,6 +346,9 @@ SWGChannelSettings::cleanup() {
|
||||
if(ft8_demod_settings != nullptr) {
|
||||
delete ft8_demod_settings;
|
||||
}
|
||||
if(rtty_demod_settings != nullptr) {
|
||||
delete rtty_demod_settings;
|
||||
}
|
||||
if(heat_map_settings != nullptr) {
|
||||
delete heat_map_settings;
|
||||
}
|
||||
@ -353,6 +364,9 @@ SWGChannelSettings::cleanup() {
|
||||
if(m17_mod_settings != nullptr) {
|
||||
delete m17_mod_settings;
|
||||
}
|
||||
if(navtex_demod_settings != nullptr) {
|
||||
delete navtex_demod_settings;
|
||||
}
|
||||
if(nfm_demod_settings != nullptr) {
|
||||
delete nfm_demod_settings;
|
||||
}
|
||||
@ -488,6 +502,8 @@ SWGChannelSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&ft8_demod_settings, pJson["FT8DemodSettings"], "SWGFT8DemodSettings", "SWGFT8DemodSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&rtty_demod_settings, pJson["RTTYDemodSettings"], "SWGRTTYDemodSettings", "SWGRTTYDemodSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&heat_map_settings, pJson["HeatMapSettings"], "SWGHeatMapSettings", "SWGHeatMapSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&interferometer_settings, pJson["InterferometerSettings"], "SWGInterferometerSettings", "SWGInterferometerSettings");
|
||||
@ -498,6 +514,8 @@ SWGChannelSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
|
||||
::SWGSDRangel::setValue(&m17_mod_settings, pJson["M17ModSettings"], "SWGM17ModSettings", "SWGM17ModSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&navtex_demod_settings, pJson["NavtexDemodSettings"], "SWGNavtexDemodSettings", "SWGNavtexDemodSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&nfm_demod_settings, pJson["NFMDemodSettings"], "SWGNFMDemodSettings", "SWGNFMDemodSettings");
|
||||
|
||||
::SWGSDRangel::setValue(&nfm_mod_settings, pJson["NFMModSettings"], "SWGNFMModSettings", "SWGNFMModSettings");
|
||||
@ -642,6 +660,9 @@ SWGChannelSettings::asJsonObject() {
|
||||
if((ft8_demod_settings != nullptr) && (ft8_demod_settings->isSet())){
|
||||
toJsonValue(QString("FT8DemodSettings"), ft8_demod_settings, obj, QString("SWGFT8DemodSettings"));
|
||||
}
|
||||
if((rtty_demod_settings != nullptr) && (rtty_demod_settings->isSet())){
|
||||
toJsonValue(QString("RTTYDemodSettings"), rtty_demod_settings, obj, QString("SWGRTTYDemodSettings"));
|
||||
}
|
||||
if((heat_map_settings != nullptr) && (heat_map_settings->isSet())){
|
||||
toJsonValue(QString("HeatMapSettings"), heat_map_settings, obj, QString("SWGHeatMapSettings"));
|
||||
}
|
||||
@ -657,6 +678,9 @@ SWGChannelSettings::asJsonObject() {
|
||||
if((m17_mod_settings != nullptr) && (m17_mod_settings->isSet())){
|
||||
toJsonValue(QString("M17ModSettings"), m17_mod_settings, obj, QString("SWGM17ModSettings"));
|
||||
}
|
||||
if((navtex_demod_settings != nullptr) && (navtex_demod_settings->isSet())){
|
||||
toJsonValue(QString("NavtexDemodSettings"), navtex_demod_settings, obj, QString("SWGNavtexDemodSettings"));
|
||||
}
|
||||
if((nfm_demod_settings != nullptr) && (nfm_demod_settings->isSet())){
|
||||
toJsonValue(QString("NFMDemodSettings"), nfm_demod_settings, obj, QString("SWGNFMDemodSettings"));
|
||||
}
|
||||
@ -1007,6 +1031,16 @@ SWGChannelSettings::setFt8DemodSettings(SWGFT8DemodSettings* ft8_demod_settings)
|
||||
this->m_ft8_demod_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGRTTYDemodSettings*
|
||||
SWGChannelSettings::getRttyDemodSettings() {
|
||||
return rtty_demod_settings;
|
||||
}
|
||||
void
|
||||
SWGChannelSettings::setRttyDemodSettings(SWGRTTYDemodSettings* rtty_demod_settings) {
|
||||
this->rtty_demod_settings = rtty_demod_settings;
|
||||
this->m_rtty_demod_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGHeatMapSettings*
|
||||
SWGChannelSettings::getHeatMapSettings() {
|
||||
return heat_map_settings;
|
||||
@ -1057,6 +1091,16 @@ SWGChannelSettings::setM17ModSettings(SWGM17ModSettings* m17_mod_settings) {
|
||||
this->m_m17_mod_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGNavtexDemodSettings*
|
||||
SWGChannelSettings::getNavtexDemodSettings() {
|
||||
return navtex_demod_settings;
|
||||
}
|
||||
void
|
||||
SWGChannelSettings::setNavtexDemodSettings(SWGNavtexDemodSettings* navtex_demod_settings) {
|
||||
this->navtex_demod_settings = navtex_demod_settings;
|
||||
this->m_navtex_demod_settings_isSet = true;
|
||||
}
|
||||
|
||||
SWGNFMDemodSettings*
|
||||
SWGChannelSettings::getNfmDemodSettings() {
|
||||
return nfm_demod_settings;
|
||||
@ -1366,6 +1410,9 @@ SWGChannelSettings::isSet(){
|
||||
if(ft8_demod_settings && ft8_demod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rtty_demod_settings && rtty_demod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(heat_map_settings && heat_map_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
@ -1381,6 +1428,9 @@ SWGChannelSettings::isSet(){
|
||||
if(m17_mod_settings && m17_mod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(navtex_demod_settings && navtex_demod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(nfm_demod_settings && nfm_demod_settings->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
|
@ -55,10 +55,12 @@
|
||||
#include "SWGM17ModSettings.h"
|
||||
#include "SWGNFMDemodSettings.h"
|
||||
#include "SWGNFMModSettings.h"
|
||||
#include "SWGNavtexDemodSettings.h"
|
||||
#include "SWGNoiseFigureSettings.h"
|
||||
#include "SWGPacketDemodSettings.h"
|
||||
#include "SWGPacketModSettings.h"
|
||||
#include "SWGPagerDemodSettings.h"
|
||||
#include "SWGRTTYDemodSettings.h"
|
||||
#include "SWGRadioAstronomySettings.h"
|
||||
#include "SWGRadioClockSettings.h"
|
||||
#include "SWGRadiosondeDemodSettings.h"
|
||||
@ -177,6 +179,9 @@ public:
|
||||
SWGFT8DemodSettings* getFt8DemodSettings();
|
||||
void setFt8DemodSettings(SWGFT8DemodSettings* ft8_demod_settings);
|
||||
|
||||
SWGRTTYDemodSettings* getRttyDemodSettings();
|
||||
void setRttyDemodSettings(SWGRTTYDemodSettings* rtty_demod_settings);
|
||||
|
||||
SWGHeatMapSettings* getHeatMapSettings();
|
||||
void setHeatMapSettings(SWGHeatMapSettings* heat_map_settings);
|
||||
|
||||
@ -192,6 +197,9 @@ public:
|
||||
SWGM17ModSettings* getM17ModSettings();
|
||||
void setM17ModSettings(SWGM17ModSettings* m17_mod_settings);
|
||||
|
||||
SWGNavtexDemodSettings* getNavtexDemodSettings();
|
||||
void setNavtexDemodSettings(SWGNavtexDemodSettings* navtex_demod_settings);
|
||||
|
||||
SWGNFMDemodSettings* getNfmDemodSettings();
|
||||
void setNfmDemodSettings(SWGNFMDemodSettings* nfm_demod_settings);
|
||||
|
||||
@ -346,6 +354,9 @@ private:
|
||||
SWGFT8DemodSettings* ft8_demod_settings;
|
||||
bool m_ft8_demod_settings_isSet;
|
||||
|
||||
SWGRTTYDemodSettings* rtty_demod_settings;
|
||||
bool m_rtty_demod_settings_isSet;
|
||||
|
||||
SWGHeatMapSettings* heat_map_settings;
|
||||
bool m_heat_map_settings_isSet;
|
||||
|
||||
@ -361,6 +372,9 @@ private:
|
||||
SWGM17ModSettings* m17_mod_settings;
|
||||
bool m_m17_mod_settings_isSet;
|
||||
|
||||
SWGNavtexDemodSettings* navtex_demod_settings;
|
||||
bool m_navtex_demod_settings_isSet;
|
||||
|
||||
SWGNFMDemodSettings* nfm_demod_settings;
|
||||
bool m_nfm_demod_settings_isSet;
|
||||
|
||||
|
@ -205,6 +205,8 @@
|
||||
#include "SWGNFMModReport.h"
|
||||
#include "SWGNFMModSettings.h"
|
||||
#include "SWGNamedEnum.h"
|
||||
#include "SWGNavtexDemodReport.h"
|
||||
#include "SWGNavtexDemodSettings.h"
|
||||
#include "SWGNoiseFigureReport.h"
|
||||
#include "SWGNoiseFigureSettings.h"
|
||||
#include "SWGPERTesterActions.h"
|
||||
@ -238,6 +240,8 @@
|
||||
#include "SWGPresets.h"
|
||||
#include "SWGRDSReport.h"
|
||||
#include "SWGRDSReport_altFrequencies.h"
|
||||
#include "SWGRTTYDemodReport.h"
|
||||
#include "SWGRTTYDemodSettings.h"
|
||||
#include "SWGRadioAstronomyActions.h"
|
||||
#include "SWGRadioAstronomyReport.h"
|
||||
#include "SWGRadioAstronomySettings.h"
|
||||
@ -1302,6 +1306,16 @@ namespace SWGSDRangel {
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGNavtexDemodReport").compare(type) == 0) {
|
||||
SWGNavtexDemodReport *obj = new SWGNavtexDemodReport();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGNavtexDemodSettings").compare(type) == 0) {
|
||||
SWGNavtexDemodSettings *obj = new SWGNavtexDemodSettings();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGNoiseFigureReport").compare(type) == 0) {
|
||||
SWGNoiseFigureReport *obj = new SWGNoiseFigureReport();
|
||||
obj->init();
|
||||
@ -1467,6 +1481,16 @@ namespace SWGSDRangel {
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRTTYDemodReport").compare(type) == 0) {
|
||||
SWGRTTYDemodReport *obj = new SWGRTTYDemodReport();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRTTYDemodSettings").compare(type) == 0) {
|
||||
SWGRTTYDemodSettings *obj = new SWGRTTYDemodSettings();
|
||||
obj->init();
|
||||
return obj;
|
||||
}
|
||||
if(QString("SWGRadioAstronomyActions").compare(type) == 0) {
|
||||
SWGRadioAstronomyActions *obj = new SWGRadioAstronomyActions();
|
||||
obj->init();
|
||||
|
131
swagger/sdrangel/code/qt5/client/SWGNavtexDemodReport.cpp
Normal file
131
swagger/sdrangel/code/qt5/client/SWGNavtexDemodReport.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGNavtexDemodReport.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGNavtexDemodReport::SWGNavtexDemodReport(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGNavtexDemodReport::SWGNavtexDemodReport() {
|
||||
channel_power_db = 0.0f;
|
||||
m_channel_power_db_isSet = false;
|
||||
channel_sample_rate = 0;
|
||||
m_channel_sample_rate_isSet = false;
|
||||
}
|
||||
|
||||
SWGNavtexDemodReport::~SWGNavtexDemodReport() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGNavtexDemodReport::init() {
|
||||
channel_power_db = 0.0f;
|
||||
m_channel_power_db_isSet = false;
|
||||
channel_sample_rate = 0;
|
||||
m_channel_sample_rate_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGNavtexDemodReport::cleanup() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
SWGNavtexDemodReport*
|
||||
SWGNavtexDemodReport::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGNavtexDemodReport::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&channel_power_db, pJson["channelPowerDB"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_sample_rate, pJson["channelSampleRate"], "qint32", "");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGNavtexDemodReport::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGNavtexDemodReport::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_channel_power_db_isSet){
|
||||
obj->insert("channelPowerDB", QJsonValue(channel_power_db));
|
||||
}
|
||||
if(m_channel_sample_rate_isSet){
|
||||
obj->insert("channelSampleRate", QJsonValue(channel_sample_rate));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
float
|
||||
SWGNavtexDemodReport::getChannelPowerDb() {
|
||||
return channel_power_db;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodReport::setChannelPowerDb(float channel_power_db) {
|
||||
this->channel_power_db = channel_power_db;
|
||||
this->m_channel_power_db_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodReport::getChannelSampleRate() {
|
||||
return channel_sample_rate;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodReport::setChannelSampleRate(qint32 channel_sample_rate) {
|
||||
this->channel_sample_rate = channel_sample_rate;
|
||||
this->m_channel_sample_rate_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGNavtexDemodReport::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_channel_power_db_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_channel_sample_rate_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
64
swagger/sdrangel/code/qt5/client/SWGNavtexDemodReport.h
Normal file
64
swagger/sdrangel/code/qt5/client/SWGNavtexDemodReport.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGNavtexDemodReport.h
|
||||
*
|
||||
* ACARSDemod
|
||||
*/
|
||||
|
||||
#ifndef SWGNavtexDemodReport_H_
|
||||
#define SWGNavtexDemodReport_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGNavtexDemodReport: public SWGObject {
|
||||
public:
|
||||
SWGNavtexDemodReport();
|
||||
SWGNavtexDemodReport(QString* json);
|
||||
virtual ~SWGNavtexDemodReport();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGNavtexDemodReport* fromJson(QString &jsonString) override;
|
||||
|
||||
float getChannelPowerDb();
|
||||
void setChannelPowerDb(float channel_power_db);
|
||||
|
||||
qint32 getChannelSampleRate();
|
||||
void setChannelSampleRate(qint32 channel_sample_rate);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
float channel_power_db;
|
||||
bool m_channel_power_db_isSet;
|
||||
|
||||
qint32 channel_sample_rate;
|
||||
bool m_channel_sample_rate_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGNavtexDemodReport_H_ */
|
586
swagger/sdrangel/code/qt5/client/SWGNavtexDemodSettings.cpp
Normal file
586
swagger/sdrangel/code/qt5/client/SWGNavtexDemodSettings.cpp
Normal file
@ -0,0 +1,586 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGNavtexDemodSettings.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGNavtexDemodSettings::SWGNavtexDemodSettings(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGNavtexDemodSettings::SWGNavtexDemodSettings() {
|
||||
input_frequency_offset = 0L;
|
||||
m_input_frequency_offset_isSet = false;
|
||||
rf_bandwidth = 0.0f;
|
||||
m_rf_bandwidth_isSet = false;
|
||||
nav_area = 0;
|
||||
m_nav_area_isSet = false;
|
||||
filter_station = nullptr;
|
||||
m_filter_station_isSet = false;
|
||||
filter_type = nullptr;
|
||||
m_filter_type_isSet = false;
|
||||
udp_enabled = 0;
|
||||
m_udp_enabled_isSet = false;
|
||||
udp_address = nullptr;
|
||||
m_udp_address_isSet = false;
|
||||
udp_port = 0;
|
||||
m_udp_port_isSet = false;
|
||||
log_filename = nullptr;
|
||||
m_log_filename_isSet = false;
|
||||
log_enabled = 0;
|
||||
m_log_enabled_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = nullptr;
|
||||
m_title_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = nullptr;
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_device_index = 0;
|
||||
m_reverse_api_device_index_isSet = false;
|
||||
reverse_api_channel_index = 0;
|
||||
m_reverse_api_channel_index_isSet = false;
|
||||
scope_config = nullptr;
|
||||
m_scope_config_isSet = false;
|
||||
channel_marker = nullptr;
|
||||
m_channel_marker_isSet = false;
|
||||
rollup_state = nullptr;
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
SWGNavtexDemodSettings::~SWGNavtexDemodSettings() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGNavtexDemodSettings::init() {
|
||||
input_frequency_offset = 0L;
|
||||
m_input_frequency_offset_isSet = false;
|
||||
rf_bandwidth = 0.0f;
|
||||
m_rf_bandwidth_isSet = false;
|
||||
nav_area = 0;
|
||||
m_nav_area_isSet = false;
|
||||
filter_station = new QString("");
|
||||
m_filter_station_isSet = false;
|
||||
filter_type = new QString("");
|
||||
m_filter_type_isSet = false;
|
||||
udp_enabled = 0;
|
||||
m_udp_enabled_isSet = false;
|
||||
udp_address = new QString("");
|
||||
m_udp_address_isSet = false;
|
||||
udp_port = 0;
|
||||
m_udp_port_isSet = false;
|
||||
log_filename = new QString("");
|
||||
m_log_filename_isSet = false;
|
||||
log_enabled = 0;
|
||||
m_log_enabled_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = new QString("");
|
||||
m_title_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = new QString("");
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_device_index = 0;
|
||||
m_reverse_api_device_index_isSet = false;
|
||||
reverse_api_channel_index = 0;
|
||||
m_reverse_api_channel_index_isSet = false;
|
||||
scope_config = new SWGGLScope();
|
||||
m_scope_config_isSet = false;
|
||||
channel_marker = new SWGChannelMarker();
|
||||
m_channel_marker_isSet = false;
|
||||
rollup_state = new SWGRollupState();
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGNavtexDemodSettings::cleanup() {
|
||||
|
||||
|
||||
|
||||
if(filter_station != nullptr) {
|
||||
delete filter_station;
|
||||
}
|
||||
if(filter_type != nullptr) {
|
||||
delete filter_type;
|
||||
}
|
||||
|
||||
if(udp_address != nullptr) {
|
||||
delete udp_address;
|
||||
}
|
||||
|
||||
if(log_filename != nullptr) {
|
||||
delete log_filename;
|
||||
}
|
||||
|
||||
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
|
||||
|
||||
if(reverse_api_address != nullptr) {
|
||||
delete reverse_api_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(scope_config != nullptr) {
|
||||
delete scope_config;
|
||||
}
|
||||
if(channel_marker != nullptr) {
|
||||
delete channel_marker;
|
||||
}
|
||||
if(rollup_state != nullptr) {
|
||||
delete rollup_state;
|
||||
}
|
||||
}
|
||||
|
||||
SWGNavtexDemodSettings*
|
||||
SWGNavtexDemodSettings::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGNavtexDemodSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&nav_area, pJson["navArea"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&filter_station, pJson["filterStation"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&filter_type, pJson["filterType"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_enabled, pJson["udpEnabled"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_address, pJson["udpAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&log_filename, pJson["logFilename"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&log_enabled, pJson["logEnabled"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_device_index, pJson["reverseAPIDeviceIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_channel_index, pJson["reverseAPIChannelIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&scope_config, pJson["scopeConfig"], "SWGGLScope", "SWGGLScope");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_marker, pJson["channelMarker"], "SWGChannelMarker", "SWGChannelMarker");
|
||||
|
||||
::SWGSDRangel::setValue(&rollup_state, pJson["rollupState"], "SWGRollupState", "SWGRollupState");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGNavtexDemodSettings::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGNavtexDemodSettings::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_input_frequency_offset_isSet){
|
||||
obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset));
|
||||
}
|
||||
if(m_rf_bandwidth_isSet){
|
||||
obj->insert("rfBandwidth", QJsonValue(rf_bandwidth));
|
||||
}
|
||||
if(m_nav_area_isSet){
|
||||
obj->insert("navArea", QJsonValue(nav_area));
|
||||
}
|
||||
if(filter_station != nullptr && *filter_station != QString("")){
|
||||
toJsonValue(QString("filterStation"), filter_station, obj, QString("QString"));
|
||||
}
|
||||
if(filter_type != nullptr && *filter_type != QString("")){
|
||||
toJsonValue(QString("filterType"), filter_type, obj, QString("QString"));
|
||||
}
|
||||
if(m_udp_enabled_isSet){
|
||||
obj->insert("udpEnabled", QJsonValue(udp_enabled));
|
||||
}
|
||||
if(udp_address != nullptr && *udp_address != QString("")){
|
||||
toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_udp_port_isSet){
|
||||
obj->insert("udpPort", QJsonValue(udp_port));
|
||||
}
|
||||
if(log_filename != nullptr && *log_filename != QString("")){
|
||||
toJsonValue(QString("logFilename"), log_filename, obj, QString("QString"));
|
||||
}
|
||||
if(m_log_enabled_isSet){
|
||||
obj->insert("logEnabled", QJsonValue(log_enabled));
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
obj->insert("rgbColor", QJsonValue(rgb_color));
|
||||
}
|
||||
if(title != nullptr && *title != QString("")){
|
||||
toJsonValue(QString("title"), title, obj, QString("QString"));
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
obj->insert("streamIndex", QJsonValue(stream_index));
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
obj->insert("useReverseAPI", QJsonValue(use_reverse_api));
|
||||
}
|
||||
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){
|
||||
toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
obj->insert("reverseAPIPort", QJsonValue(reverse_api_port));
|
||||
}
|
||||
if(m_reverse_api_device_index_isSet){
|
||||
obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index));
|
||||
}
|
||||
if(m_reverse_api_channel_index_isSet){
|
||||
obj->insert("reverseAPIChannelIndex", QJsonValue(reverse_api_channel_index));
|
||||
}
|
||||
if((scope_config != nullptr) && (scope_config->isSet())){
|
||||
toJsonValue(QString("scopeConfig"), scope_config, obj, QString("SWGGLScope"));
|
||||
}
|
||||
if((channel_marker != nullptr) && (channel_marker->isSet())){
|
||||
toJsonValue(QString("channelMarker"), channel_marker, obj, QString("SWGChannelMarker"));
|
||||
}
|
||||
if((rollup_state != nullptr) && (rollup_state->isSet())){
|
||||
toJsonValue(QString("rollupState"), rollup_state, obj, QString("SWGRollupState"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
qint64
|
||||
SWGNavtexDemodSettings::getInputFrequencyOffset() {
|
||||
return input_frequency_offset;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setInputFrequencyOffset(qint64 input_frequency_offset) {
|
||||
this->input_frequency_offset = input_frequency_offset;
|
||||
this->m_input_frequency_offset_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGNavtexDemodSettings::getRfBandwidth() {
|
||||
return rf_bandwidth;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setRfBandwidth(float rf_bandwidth) {
|
||||
this->rf_bandwidth = rf_bandwidth;
|
||||
this->m_rf_bandwidth_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getNavArea() {
|
||||
return nav_area;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setNavArea(qint32 nav_area) {
|
||||
this->nav_area = nav_area;
|
||||
this->m_nav_area_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGNavtexDemodSettings::getFilterStation() {
|
||||
return filter_station;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setFilterStation(QString* filter_station) {
|
||||
this->filter_station = filter_station;
|
||||
this->m_filter_station_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGNavtexDemodSettings::getFilterType() {
|
||||
return filter_type;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setFilterType(QString* filter_type) {
|
||||
this->filter_type = filter_type;
|
||||
this->m_filter_type_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getUdpEnabled() {
|
||||
return udp_enabled;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setUdpEnabled(qint32 udp_enabled) {
|
||||
this->udp_enabled = udp_enabled;
|
||||
this->m_udp_enabled_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGNavtexDemodSettings::getUdpAddress() {
|
||||
return udp_address;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setUdpAddress(QString* udp_address) {
|
||||
this->udp_address = udp_address;
|
||||
this->m_udp_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getUdpPort() {
|
||||
return udp_port;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setUdpPort(qint32 udp_port) {
|
||||
this->udp_port = udp_port;
|
||||
this->m_udp_port_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGNavtexDemodSettings::getLogFilename() {
|
||||
return log_filename;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setLogFilename(QString* log_filename) {
|
||||
this->log_filename = log_filename;
|
||||
this->m_log_filename_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getLogEnabled() {
|
||||
return log_enabled;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setLogEnabled(qint32 log_enabled) {
|
||||
this->log_enabled = log_enabled;
|
||||
this->m_log_enabled_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getRgbColor() {
|
||||
return rgb_color;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setRgbColor(qint32 rgb_color) {
|
||||
this->rgb_color = rgb_color;
|
||||
this->m_rgb_color_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGNavtexDemodSettings::getTitle() {
|
||||
return title;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setTitle(QString* title) {
|
||||
this->title = title;
|
||||
this->m_title_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getStreamIndex() {
|
||||
return stream_index;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setStreamIndex(qint32 stream_index) {
|
||||
this->stream_index = stream_index;
|
||||
this->m_stream_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getUseReverseApi() {
|
||||
return use_reverse_api;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setUseReverseApi(qint32 use_reverse_api) {
|
||||
this->use_reverse_api = use_reverse_api;
|
||||
this->m_use_reverse_api_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGNavtexDemodSettings::getReverseApiAddress() {
|
||||
return reverse_api_address;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setReverseApiAddress(QString* reverse_api_address) {
|
||||
this->reverse_api_address = reverse_api_address;
|
||||
this->m_reverse_api_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getReverseApiPort() {
|
||||
return reverse_api_port;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setReverseApiPort(qint32 reverse_api_port) {
|
||||
this->reverse_api_port = reverse_api_port;
|
||||
this->m_reverse_api_port_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getReverseApiDeviceIndex() {
|
||||
return reverse_api_device_index;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
|
||||
this->reverse_api_device_index = reverse_api_device_index;
|
||||
this->m_reverse_api_device_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGNavtexDemodSettings::getReverseApiChannelIndex() {
|
||||
return reverse_api_channel_index;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) {
|
||||
this->reverse_api_channel_index = reverse_api_channel_index;
|
||||
this->m_reverse_api_channel_index_isSet = true;
|
||||
}
|
||||
|
||||
SWGGLScope*
|
||||
SWGNavtexDemodSettings::getScopeConfig() {
|
||||
return scope_config;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setScopeConfig(SWGGLScope* scope_config) {
|
||||
this->scope_config = scope_config;
|
||||
this->m_scope_config_isSet = true;
|
||||
}
|
||||
|
||||
SWGChannelMarker*
|
||||
SWGNavtexDemodSettings::getChannelMarker() {
|
||||
return channel_marker;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setChannelMarker(SWGChannelMarker* channel_marker) {
|
||||
this->channel_marker = channel_marker;
|
||||
this->m_channel_marker_isSet = true;
|
||||
}
|
||||
|
||||
SWGRollupState*
|
||||
SWGNavtexDemodSettings::getRollupState() {
|
||||
return rollup_state;
|
||||
}
|
||||
void
|
||||
SWGNavtexDemodSettings::setRollupState(SWGRollupState* rollup_state) {
|
||||
this->rollup_state = rollup_state;
|
||||
this->m_rollup_state_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGNavtexDemodSettings::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_input_frequency_offset_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rf_bandwidth_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_nav_area_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(filter_station && *filter_station != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(filter_type && *filter_type != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_udp_enabled_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(udp_address && *udp_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_udp_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(log_filename && *log_filename != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_log_enabled_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(title && *title != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(reverse_api_address && *reverse_api_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_device_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_channel_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(scope_config && scope_config->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(channel_marker && channel_marker->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rollup_state && rollup_state->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
182
swagger/sdrangel/code/qt5/client/SWGNavtexDemodSettings.h
Normal file
182
swagger/sdrangel/code/qt5/client/SWGNavtexDemodSettings.h
Normal file
@ -0,0 +1,182 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGNavtexDemodSettings.h
|
||||
*
|
||||
* ACARSDemod
|
||||
*/
|
||||
|
||||
#ifndef SWGNavtexDemodSettings_H_
|
||||
#define SWGNavtexDemodSettings_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
#include "SWGChannelMarker.h"
|
||||
#include "SWGGLScope.h"
|
||||
#include "SWGRollupState.h"
|
||||
#include <QString>
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGNavtexDemodSettings: public SWGObject {
|
||||
public:
|
||||
SWGNavtexDemodSettings();
|
||||
SWGNavtexDemodSettings(QString* json);
|
||||
virtual ~SWGNavtexDemodSettings();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGNavtexDemodSettings* fromJson(QString &jsonString) override;
|
||||
|
||||
qint64 getInputFrequencyOffset();
|
||||
void setInputFrequencyOffset(qint64 input_frequency_offset);
|
||||
|
||||
float getRfBandwidth();
|
||||
void setRfBandwidth(float rf_bandwidth);
|
||||
|
||||
qint32 getNavArea();
|
||||
void setNavArea(qint32 nav_area);
|
||||
|
||||
QString* getFilterStation();
|
||||
void setFilterStation(QString* filter_station);
|
||||
|
||||
QString* getFilterType();
|
||||
void setFilterType(QString* filter_type);
|
||||
|
||||
qint32 getUdpEnabled();
|
||||
void setUdpEnabled(qint32 udp_enabled);
|
||||
|
||||
QString* getUdpAddress();
|
||||
void setUdpAddress(QString* udp_address);
|
||||
|
||||
qint32 getUdpPort();
|
||||
void setUdpPort(qint32 udp_port);
|
||||
|
||||
QString* getLogFilename();
|
||||
void setLogFilename(QString* log_filename);
|
||||
|
||||
qint32 getLogEnabled();
|
||||
void setLogEnabled(qint32 log_enabled);
|
||||
|
||||
qint32 getRgbColor();
|
||||
void setRgbColor(qint32 rgb_color);
|
||||
|
||||
QString* getTitle();
|
||||
void setTitle(QString* title);
|
||||
|
||||
qint32 getStreamIndex();
|
||||
void setStreamIndex(qint32 stream_index);
|
||||
|
||||
qint32 getUseReverseApi();
|
||||
void setUseReverseApi(qint32 use_reverse_api);
|
||||
|
||||
QString* getReverseApiAddress();
|
||||
void setReverseApiAddress(QString* reverse_api_address);
|
||||
|
||||
qint32 getReverseApiPort();
|
||||
void setReverseApiPort(qint32 reverse_api_port);
|
||||
|
||||
qint32 getReverseApiDeviceIndex();
|
||||
void setReverseApiDeviceIndex(qint32 reverse_api_device_index);
|
||||
|
||||
qint32 getReverseApiChannelIndex();
|
||||
void setReverseApiChannelIndex(qint32 reverse_api_channel_index);
|
||||
|
||||
SWGGLScope* getScopeConfig();
|
||||
void setScopeConfig(SWGGLScope* scope_config);
|
||||
|
||||
SWGChannelMarker* getChannelMarker();
|
||||
void setChannelMarker(SWGChannelMarker* channel_marker);
|
||||
|
||||
SWGRollupState* getRollupState();
|
||||
void setRollupState(SWGRollupState* rollup_state);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
qint64 input_frequency_offset;
|
||||
bool m_input_frequency_offset_isSet;
|
||||
|
||||
float rf_bandwidth;
|
||||
bool m_rf_bandwidth_isSet;
|
||||
|
||||
qint32 nav_area;
|
||||
bool m_nav_area_isSet;
|
||||
|
||||
QString* filter_station;
|
||||
bool m_filter_station_isSet;
|
||||
|
||||
QString* filter_type;
|
||||
bool m_filter_type_isSet;
|
||||
|
||||
qint32 udp_enabled;
|
||||
bool m_udp_enabled_isSet;
|
||||
|
||||
QString* udp_address;
|
||||
bool m_udp_address_isSet;
|
||||
|
||||
qint32 udp_port;
|
||||
bool m_udp_port_isSet;
|
||||
|
||||
QString* log_filename;
|
||||
bool m_log_filename_isSet;
|
||||
|
||||
qint32 log_enabled;
|
||||
bool m_log_enabled_isSet;
|
||||
|
||||
qint32 rgb_color;
|
||||
bool m_rgb_color_isSet;
|
||||
|
||||
QString* title;
|
||||
bool m_title_isSet;
|
||||
|
||||
qint32 stream_index;
|
||||
bool m_stream_index_isSet;
|
||||
|
||||
qint32 use_reverse_api;
|
||||
bool m_use_reverse_api_isSet;
|
||||
|
||||
QString* reverse_api_address;
|
||||
bool m_reverse_api_address_isSet;
|
||||
|
||||
qint32 reverse_api_port;
|
||||
bool m_reverse_api_port_isSet;
|
||||
|
||||
qint32 reverse_api_device_index;
|
||||
bool m_reverse_api_device_index_isSet;
|
||||
|
||||
qint32 reverse_api_channel_index;
|
||||
bool m_reverse_api_channel_index_isSet;
|
||||
|
||||
SWGGLScope* scope_config;
|
||||
bool m_scope_config_isSet;
|
||||
|
||||
SWGChannelMarker* channel_marker;
|
||||
bool m_channel_marker_isSet;
|
||||
|
||||
SWGRollupState* rollup_state;
|
||||
bool m_rollup_state_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGNavtexDemodSettings_H_ */
|
64
swagger/sdrangel/code/qt5/client/SWGRTTYDemodReport.h
Normal file
64
swagger/sdrangel/code/qt5/client/SWGRTTYDemodReport.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SWGRTTYDemodReport.h
|
||||
*
|
||||
* ACARSDemod
|
||||
*/
|
||||
|
||||
#ifndef SWGRTTYDemodReport_H_
|
||||
#define SWGRTTYDemodReport_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
|
||||
|
||||
#include "SWGObject.h"
|
||||
#include "export.h"
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
class SWG_API SWGRTTYDemodReport: public SWGObject {
|
||||
public:
|
||||
SWGRTTYDemodReport();
|
||||
SWGRTTYDemodReport(QString* json);
|
||||
virtual ~SWGRTTYDemodReport();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
virtual QString asJson () override;
|
||||
virtual QJsonObject* asJsonObject() override;
|
||||
virtual void fromJsonObject(QJsonObject &json) override;
|
||||
virtual SWGRTTYDemodReport* fromJson(QString &jsonString) override;
|
||||
|
||||
float getChannelPowerDb();
|
||||
void setChannelPowerDb(float channel_power_db);
|
||||
|
||||
qint32 getChannelSampleRate();
|
||||
void setChannelSampleRate(qint32 channel_sample_rate);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
private:
|
||||
float channel_power_db;
|
||||
bool m_channel_power_db_isSet;
|
||||
|
||||
qint32 channel_sample_rate;
|
||||
bool m_channel_sample_rate_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SWGRTTYDemodReport_H_ */
|
697
swagger/sdrangel/code/qt5/client/SWGRTTYDemodSettings.cpp
Normal file
697
swagger/sdrangel/code/qt5/client/SWGRTTYDemodSettings.cpp
Normal file
@ -0,0 +1,697 @@
|
||||
/**
|
||||
* SDRangel
|
||||
* This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time ---
|
||||
*
|
||||
* OpenAPI spec version: 7.0.0
|
||||
* Contact: f4exb06@gmail.com
|
||||
*
|
||||
* NOTE: This class is auto generated by the swagger code generator program.
|
||||
* https://github.com/swagger-api/swagger-codegen.git
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
|
||||
|
||||
#include "SWGRTTYDemodSettings.h"
|
||||
|
||||
#include "SWGHelpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
namespace SWGSDRangel {
|
||||
|
||||
SWGRTTYDemodSettings::SWGRTTYDemodSettings(QString* json) {
|
||||
init();
|
||||
this->fromJson(*json);
|
||||
}
|
||||
|
||||
SWGRTTYDemodSettings::SWGRTTYDemodSettings() {
|
||||
input_frequency_offset = 0L;
|
||||
m_input_frequency_offset_isSet = false;
|
||||
rf_bandwidth = 0.0f;
|
||||
m_rf_bandwidth_isSet = false;
|
||||
baud_rate = 0.0f;
|
||||
m_baud_rate_isSet = false;
|
||||
frequency_shift = 0;
|
||||
m_frequency_shift_isSet = false;
|
||||
udp_enabled = 0;
|
||||
m_udp_enabled_isSet = false;
|
||||
udp_address = nullptr;
|
||||
m_udp_address_isSet = false;
|
||||
udp_port = 0;
|
||||
m_udp_port_isSet = false;
|
||||
character_set = 0;
|
||||
m_character_set_isSet = false;
|
||||
suppress_crlf = 0;
|
||||
m_suppress_crlf_isSet = false;
|
||||
unshift_on_space = 0;
|
||||
m_unshift_on_space_isSet = false;
|
||||
msb_first = 0;
|
||||
m_msb_first_isSet = false;
|
||||
space_high = 0;
|
||||
m_space_high_isSet = false;
|
||||
squelch = 0;
|
||||
m_squelch_isSet = false;
|
||||
log_filename = nullptr;
|
||||
m_log_filename_isSet = false;
|
||||
log_enabled = 0;
|
||||
m_log_enabled_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = nullptr;
|
||||
m_title_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = nullptr;
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_device_index = 0;
|
||||
m_reverse_api_device_index_isSet = false;
|
||||
reverse_api_channel_index = 0;
|
||||
m_reverse_api_channel_index_isSet = false;
|
||||
scope_config = nullptr;
|
||||
m_scope_config_isSet = false;
|
||||
channel_marker = nullptr;
|
||||
m_channel_marker_isSet = false;
|
||||
rollup_state = nullptr;
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
SWGRTTYDemodSettings::~SWGRTTYDemodSettings() {
|
||||
this->cleanup();
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYDemodSettings::init() {
|
||||
input_frequency_offset = 0L;
|
||||
m_input_frequency_offset_isSet = false;
|
||||
rf_bandwidth = 0.0f;
|
||||
m_rf_bandwidth_isSet = false;
|
||||
baud_rate = 0.0f;
|
||||
m_baud_rate_isSet = false;
|
||||
frequency_shift = 0;
|
||||
m_frequency_shift_isSet = false;
|
||||
udp_enabled = 0;
|
||||
m_udp_enabled_isSet = false;
|
||||
udp_address = new QString("");
|
||||
m_udp_address_isSet = false;
|
||||
udp_port = 0;
|
||||
m_udp_port_isSet = false;
|
||||
character_set = 0;
|
||||
m_character_set_isSet = false;
|
||||
suppress_crlf = 0;
|
||||
m_suppress_crlf_isSet = false;
|
||||
unshift_on_space = 0;
|
||||
m_unshift_on_space_isSet = false;
|
||||
msb_first = 0;
|
||||
m_msb_first_isSet = false;
|
||||
space_high = 0;
|
||||
m_space_high_isSet = false;
|
||||
squelch = 0;
|
||||
m_squelch_isSet = false;
|
||||
log_filename = new QString("");
|
||||
m_log_filename_isSet = false;
|
||||
log_enabled = 0;
|
||||
m_log_enabled_isSet = false;
|
||||
rgb_color = 0;
|
||||
m_rgb_color_isSet = false;
|
||||
title = new QString("");
|
||||
m_title_isSet = false;
|
||||
stream_index = 0;
|
||||
m_stream_index_isSet = false;
|
||||
use_reverse_api = 0;
|
||||
m_use_reverse_api_isSet = false;
|
||||
reverse_api_address = new QString("");
|
||||
m_reverse_api_address_isSet = false;
|
||||
reverse_api_port = 0;
|
||||
m_reverse_api_port_isSet = false;
|
||||
reverse_api_device_index = 0;
|
||||
m_reverse_api_device_index_isSet = false;
|
||||
reverse_api_channel_index = 0;
|
||||
m_reverse_api_channel_index_isSet = false;
|
||||
scope_config = new SWGGLScope();
|
||||
m_scope_config_isSet = false;
|
||||
channel_marker = new SWGChannelMarker();
|
||||
m_channel_marker_isSet = false;
|
||||
rollup_state = new SWGRollupState();
|
||||
m_rollup_state_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYDemodSettings::cleanup() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(udp_address != nullptr) {
|
||||
delete udp_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(log_filename != nullptr) {
|
||||
delete log_filename;
|
||||
}
|
||||
|
||||
|
||||
if(title != nullptr) {
|
||||
delete title;
|
||||
}
|
||||
|
||||
|
||||
if(reverse_api_address != nullptr) {
|
||||
delete reverse_api_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(scope_config != nullptr) {
|
||||
delete scope_config;
|
||||
}
|
||||
if(channel_marker != nullptr) {
|
||||
delete channel_marker;
|
||||
}
|
||||
if(rollup_state != nullptr) {
|
||||
delete rollup_state;
|
||||
}
|
||||
}
|
||||
|
||||
SWGRTTYDemodSettings*
|
||||
SWGRTTYDemodSettings::fromJson(QString &json) {
|
||||
QByteArray array (json.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
void
|
||||
SWGRTTYDemodSettings::fromJsonObject(QJsonObject &pJson) {
|
||||
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&baud_rate, pJson["baudRate"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&frequency_shift, pJson["frequencyShift"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_enabled, pJson["udpEnabled"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_address, pJson["udpAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&udp_port, pJson["udpPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&character_set, pJson["characterSet"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&suppress_crlf, pJson["suppressCRLF"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&unshift_on_space, pJson["unshiftOnSpace"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&msb_first, pJson["msbFirst"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&space_high, pJson["spaceHigh"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&squelch, pJson["squelch"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&log_filename, pJson["logFilename"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&log_enabled, pJson["logEnabled"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_device_index, pJson["reverseAPIDeviceIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&reverse_api_channel_index, pJson["reverseAPIChannelIndex"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&scope_config, pJson["scopeConfig"], "SWGGLScope", "SWGGLScope");
|
||||
|
||||
::SWGSDRangel::setValue(&channel_marker, pJson["channelMarker"], "SWGChannelMarker", "SWGChannelMarker");
|
||||
|
||||
::SWGSDRangel::setValue(&rollup_state, pJson["rollupState"], "SWGRollupState", "SWGRollupState");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
SWGRTTYDemodSettings::asJson ()
|
||||
{
|
||||
QJsonObject* obj = this->asJsonObject();
|
||||
|
||||
QJsonDocument doc(*obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
delete obj;
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject*
|
||||
SWGRTTYDemodSettings::asJsonObject() {
|
||||
QJsonObject* obj = new QJsonObject();
|
||||
if(m_input_frequency_offset_isSet){
|
||||
obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset));
|
||||
}
|
||||
if(m_rf_bandwidth_isSet){
|
||||
obj->insert("rfBandwidth", QJsonValue(rf_bandwidth));
|
||||
}
|
||||
if(m_baud_rate_isSet){
|
||||
obj->insert("baudRate", QJsonValue(baud_rate));
|
||||
}
|
||||
if(m_frequency_shift_isSet){
|
||||
obj->insert("frequencyShift", QJsonValue(frequency_shift));
|
||||
}
|
||||
if(m_udp_enabled_isSet){
|
||||
obj->insert("udpEnabled", QJsonValue(udp_enabled));
|
||||
}
|
||||
if(udp_address != nullptr && *udp_address != QString("")){
|
||||
toJsonValue(QString("udpAddress"), udp_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_udp_port_isSet){
|
||||
obj->insert("udpPort", QJsonValue(udp_port));
|
||||
}
|
||||
if(m_character_set_isSet){
|
||||
obj->insert("characterSet", QJsonValue(character_set));
|
||||
}
|
||||
if(m_suppress_crlf_isSet){
|
||||
obj->insert("suppressCRLF", QJsonValue(suppress_crlf));
|
||||
}
|
||||
if(m_unshift_on_space_isSet){
|
||||
obj->insert("unshiftOnSpace", QJsonValue(unshift_on_space));
|
||||
}
|
||||
if(m_msb_first_isSet){
|
||||
obj->insert("msbFirst", QJsonValue(msb_first));
|
||||
}
|
||||
if(m_space_high_isSet){
|
||||
obj->insert("spaceHigh", QJsonValue(space_high));
|
||||
}
|
||||
if(m_squelch_isSet){
|
||||
obj->insert("squelch", QJsonValue(squelch));
|
||||
}
|
||||
if(log_filename != nullptr && *log_filename != QString("")){
|
||||
toJsonValue(QString("logFilename"), log_filename, obj, QString("QString"));
|
||||
}
|
||||
if(m_log_enabled_isSet){
|
||||
obj->insert("logEnabled", QJsonValue(log_enabled));
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
obj->insert("rgbColor", QJsonValue(rgb_color));
|
||||
}
|
||||
if(title != nullptr && *title != QString("")){
|
||||
toJsonValue(QString("title"), title, obj, QString("QString"));
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
obj->insert("streamIndex", QJsonValue(stream_index));
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
obj->insert("useReverseAPI", QJsonValue(use_reverse_api));
|
||||
}
|
||||
if(reverse_api_address != nullptr && *reverse_api_address != QString("")){
|
||||
toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString"));
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
obj->insert("reverseAPIPort", QJsonValue(reverse_api_port));
|
||||
}
|
||||
if(m_reverse_api_device_index_isSet){
|
||||
obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index));
|
||||
}
|
||||
if(m_reverse_api_channel_index_isSet){
|
||||
obj->insert("reverseAPIChannelIndex", QJsonValue(reverse_api_channel_index));
|
||||
}
|
||||
if((scope_config != nullptr) && (scope_config->isSet())){
|
||||
toJsonValue(QString("scopeConfig"), scope_config, obj, QString("SWGGLScope"));
|
||||
}
|
||||
if((channel_marker != nullptr) && (channel_marker->isSet())){
|
||||
toJsonValue(QString("channelMarker"), channel_marker, obj, QString("SWGChannelMarker"));
|
||||
}
|
||||
if((rollup_state != nullptr) && (rollup_state->isSet())){
|
||||
toJsonValue(QString("rollupState"), rollup_state, obj, QString("SWGRollupState"));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
qint64
|
||||
SWGRTTYDemodSettings::getInputFrequencyOffset() {
|
||||
return input_frequency_offset;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setInputFrequencyOffset(qint64 input_frequency_offset) {
|
||||
this->input_frequency_offset = input_frequency_offset;
|
||||
this->m_input_frequency_offset_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGRTTYDemodSettings::getRfBandwidth() {
|
||||
return rf_bandwidth;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setRfBandwidth(float rf_bandwidth) {
|
||||
this->rf_bandwidth = rf_bandwidth;
|
||||
this->m_rf_bandwidth_isSet = true;
|
||||
}
|
||||
|
||||
float
|
||||
SWGRTTYDemodSettings::getBaudRate() {
|
||||
return baud_rate;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setBaudRate(float baud_rate) {
|
||||
this->baud_rate = baud_rate;
|
||||
this->m_baud_rate_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getFrequencyShift() {
|
||||
return frequency_shift;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setFrequencyShift(qint32 frequency_shift) {
|
||||
this->frequency_shift = frequency_shift;
|
||||
this->m_frequency_shift_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getUdpEnabled() {
|
||||
return udp_enabled;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setUdpEnabled(qint32 udp_enabled) {
|
||||
this->udp_enabled = udp_enabled;
|
||||
this->m_udp_enabled_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYDemodSettings::getUdpAddress() {
|
||||
return udp_address;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setUdpAddress(QString* udp_address) {
|
||||
this->udp_address = udp_address;
|
||||
this->m_udp_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getUdpPort() {
|
||||
return udp_port;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setUdpPort(qint32 udp_port) {
|
||||
this->udp_port = udp_port;
|
||||
this->m_udp_port_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getCharacterSet() {
|
||||
return character_set;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setCharacterSet(qint32 character_set) {
|
||||
this->character_set = character_set;
|
||||
this->m_character_set_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getSuppressCrlf() {
|
||||
return suppress_crlf;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setSuppressCrlf(qint32 suppress_crlf) {
|
||||
this->suppress_crlf = suppress_crlf;
|
||||
this->m_suppress_crlf_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getUnshiftOnSpace() {
|
||||
return unshift_on_space;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setUnshiftOnSpace(qint32 unshift_on_space) {
|
||||
this->unshift_on_space = unshift_on_space;
|
||||
this->m_unshift_on_space_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getMsbFirst() {
|
||||
return msb_first;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setMsbFirst(qint32 msb_first) {
|
||||
this->msb_first = msb_first;
|
||||
this->m_msb_first_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getSpaceHigh() {
|
||||
return space_high;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setSpaceHigh(qint32 space_high) {
|
||||
this->space_high = space_high;
|
||||
this->m_space_high_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getSquelch() {
|
||||
return squelch;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setSquelch(qint32 squelch) {
|
||||
this->squelch = squelch;
|
||||
this->m_squelch_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYDemodSettings::getLogFilename() {
|
||||
return log_filename;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setLogFilename(QString* log_filename) {
|
||||
this->log_filename = log_filename;
|
||||
this->m_log_filename_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getLogEnabled() {
|
||||
return log_enabled;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setLogEnabled(qint32 log_enabled) {
|
||||
this->log_enabled = log_enabled;
|
||||
this->m_log_enabled_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getRgbColor() {
|
||||
return rgb_color;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setRgbColor(qint32 rgb_color) {
|
||||
this->rgb_color = rgb_color;
|
||||
this->m_rgb_color_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYDemodSettings::getTitle() {
|
||||
return title;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setTitle(QString* title) {
|
||||
this->title = title;
|
||||
this->m_title_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getStreamIndex() {
|
||||
return stream_index;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setStreamIndex(qint32 stream_index) {
|
||||
this->stream_index = stream_index;
|
||||
this->m_stream_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getUseReverseApi() {
|
||||
return use_reverse_api;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setUseReverseApi(qint32 use_reverse_api) {
|
||||
this->use_reverse_api = use_reverse_api;
|
||||
this->m_use_reverse_api_isSet = true;
|
||||
}
|
||||
|
||||
QString*
|
||||
SWGRTTYDemodSettings::getReverseApiAddress() {
|
||||
return reverse_api_address;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setReverseApiAddress(QString* reverse_api_address) {
|
||||
this->reverse_api_address = reverse_api_address;
|
||||
this->m_reverse_api_address_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getReverseApiPort() {
|
||||
return reverse_api_port;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setReverseApiPort(qint32 reverse_api_port) {
|
||||
this->reverse_api_port = reverse_api_port;
|
||||
this->m_reverse_api_port_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getReverseApiDeviceIndex() {
|
||||
return reverse_api_device_index;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
|
||||
this->reverse_api_device_index = reverse_api_device_index;
|
||||
this->m_reverse_api_device_index_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGRTTYDemodSettings::getReverseApiChannelIndex() {
|
||||
return reverse_api_channel_index;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) {
|
||||
this->reverse_api_channel_index = reverse_api_channel_index;
|
||||
this->m_reverse_api_channel_index_isSet = true;
|
||||
}
|
||||
|
||||
SWGGLScope*
|
||||
SWGRTTYDemodSettings::getScopeConfig() {
|
||||
return scope_config;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setScopeConfig(SWGGLScope* scope_config) {
|
||||
this->scope_config = scope_config;
|
||||
this->m_scope_config_isSet = true;
|
||||
}
|
||||
|
||||
SWGChannelMarker*
|
||||
SWGRTTYDemodSettings::getChannelMarker() {
|
||||
return channel_marker;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setChannelMarker(SWGChannelMarker* channel_marker) {
|
||||
this->channel_marker = channel_marker;
|
||||
this->m_channel_marker_isSet = true;
|
||||
}
|
||||
|
||||
SWGRollupState*
|
||||
SWGRTTYDemodSettings::getRollupState() {
|
||||
return rollup_state;
|
||||
}
|
||||
void
|
||||
SWGRTTYDemodSettings::setRollupState(SWGRollupState* rollup_state) {
|
||||
this->rollup_state = rollup_state;
|
||||
this->m_rollup_state_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGRTTYDemodSettings::isSet(){
|
||||
bool isObjectUpdated = false;
|
||||
do{
|
||||
if(m_input_frequency_offset_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rf_bandwidth_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_baud_rate_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_frequency_shift_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_udp_enabled_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(udp_address && *udp_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_udp_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_character_set_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_suppress_crlf_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_unshift_on_space_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_msb_first_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_space_high_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_squelch_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(log_filename && *log_filename != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_log_enabled_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_rgb_color_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(title && *title != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_stream_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_use_reverse_api_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(reverse_api_address && *reverse_api_address != QString("")){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_port_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_device_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(m_reverse_api_channel_index_isSet){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(scope_config && scope_config->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(channel_marker && channel_marker->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
if(rollup_state && rollup_state->isSet()){
|
||||
isObjectUpdated = true; break;
|
||||
}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user