Aaronia RTSA Rx: initial commit

This commit is contained in:
f4exb 2023-03-18 12:48:21 +01:00
parent a3a62a6912
commit a814b1f2bf
38 changed files with 3402 additions and 432 deletions

View File

@ -73,3 +73,4 @@ endif()
add_subdirectory(audioinput)
add_subdirectory(kiwisdr)
add_subdirectory(remotetcpinput)
add_subdirectory(aaroniartsa)

View File

@ -0,0 +1,63 @@
project(aaroniartsa)
set(aaroniartsa_SOURCES
aaroniartsainput.cpp
aaroniartsaplugin.cpp
aaroniartsaworker.cpp
aaroniartsasettings.cpp
aaroniartsawebapiadapter.cpp
)
set(aaroniartsa_HEADERS
aaroniartsainput.h
aaroniartsaplugin.h
aaroniartsaworker.h
aaroniartsasettings.h
aaroniartsawebapiadapter.h
)
include_directories(
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
${Boost_INCLUDE_DIRS}
)
if(NOT SERVER_MODE)
set(aaroniartsa_SOURCES
${aaroniartsa_SOURCES}
aaroniartsagui.cpp
aaroniartsagui.ui
)
set(aaroniartsa_HEADERS
${aaroniartsa_HEADERS}
aaroniartsagui.h
)
set(TARGET_NAME inputaaroniartsa)
set(TARGET_LIB "Qt::Widgets")
set(TARGET_LIB_GUI "sdrgui")
set(INSTALL_FOLDER ${INSTALL_PLUGINS_DIR})
else()
set(TARGET_NAME inputaaroniartsasrv)
set(TARGET_LIB "")
set(TARGET_LIB_GUI "")
set(INSTALL_FOLDER ${INSTALL_PLUGINSSRV_DIR})
endif()
add_library(${TARGET_NAME} SHARED
${aaroniartsa_SOURCES}
)
target_link_libraries(${TARGET_NAME}
Qt::Core
Qt::WebSockets
${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()

View File

@ -0,0 +1,361 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 <QTime>
#include <QDateTime>
#include <QString>
#include <QMessageBox>
#include <QFileDialog>
#include "ui_aaroniartsagui.h"
#include "plugin/pluginapi.h"
#include "gui/colormapper.h"
#include "gui/glspectrum.h"
#include "gui/basicdevicesettingsdialog.h"
#include "gui/dialogpositioner.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "util/db.h"
#include "mainwindow.h"
#include "aaroniartsagui.h"
#include "device/deviceapi.h"
#include "device/deviceuiset.h"
AaroniaRTSAGui::AaroniaRTSAGui(DeviceUISet *deviceUISet, QWidget* parent) :
DeviceGUI(parent),
ui(new Ui::AaroniaRTSAGui),
m_settings(),
m_doApplySettings(true),
m_forceSettings(true),
m_sampleSource(0),
m_tickCount(0),
m_lastEngineState(DeviceAPI::StNotStarted)
{
qDebug("AaroniaRTSAGui::AaroniaRTSAGui");
m_deviceUISet = deviceUISet;
setAttribute(Qt::WA_DeleteOnClose, true);
m_sampleSource = m_deviceUISet->m_deviceAPI->getSampleSource();
m_statusTooltips.push_back("Idle"); // 0
m_statusTooltips.push_back("Connecting..."); // 1
m_statusTooltips.push_back("Connected"); // 2
m_statusTooltips.push_back("Error"); // 3
m_statusTooltips.push_back("Disconnected"); // 4
m_statusColors.push_back("gray"); // Idle
m_statusColors.push_back("rgb(232, 212, 35)"); // Connecting (yellow)
m_statusColors.push_back("rgb(35, 138, 35)"); // Connected (green)
m_statusColors.push_back("rgb(232, 85, 85)"); // Error (red)
m_statusColors.push_back("rgb(232, 85, 232)"); // Disconnected (magenta)
ui->setupUi(getContents());
sizeToContents();
getContents()->setStyleSheet("#AaroniaRTSAGui { background-color: rgb(64, 64, 64); }");
m_helpURL = "plugins/samplesource/aaroniartsa/readme.md";
ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
ui->centerFrequency->setValueRange(9, 0, 999999999);
displaySettings();
makeUIConnections();
connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
m_statusTimer.start(500);
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
m_sampleSource->setMessageQueueToGUI(&m_inputMessageQueue);
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
}
AaroniaRTSAGui::~AaroniaRTSAGui()
{
delete ui;
}
void AaroniaRTSAGui::destroy()
{
delete this;
}
void AaroniaRTSAGui::resetToDefaults()
{
m_settings.resetToDefaults();
displaySettings();
m_forceSettings = true;
sendSettings();
}
QByteArray AaroniaRTSAGui::serialize() const
{
return m_settings.serialize();
}
bool AaroniaRTSAGui::deserialize(const QByteArray& data)
{
if(m_settings.deserialize(data)) {
displaySettings();
m_forceSettings = true;
sendSettings();
return true;
} else {
resetToDefaults();
return false;
}
}
void AaroniaRTSAGui::on_startStop_toggled(bool checked)
{
if (m_doApplySettings)
{
AaroniaRTSAInput::MsgStartStop *message = AaroniaRTSAInput::MsgStartStop::create(checked);
m_sampleSource->getInputMessageQueue()->push(message);
}
}
void AaroniaRTSAGui::on_centerFrequency_changed(quint64 value)
{
m_settings.m_centerFrequency = value * 1000;
m_settingsKeys.append("centerFrequency");
sendSettings();
}
void AaroniaRTSAGui::on_serverAddress_returnPressed()
{
on_serverAddressApplyButton_clicked();
}
void AaroniaRTSAGui::on_serverAddressApplyButton_clicked()
{
QString serverAddress = ui->serverAddress->text();
QUrl url(serverAddress);
if (QStringList{"ws", "wss", "http", "https"}.contains(url.scheme())) {
m_settings.m_serverAddress = QString("%1:%2").arg(url.host()).arg(url.port());
} else {
m_settings.m_serverAddress = serverAddress;
}
m_settingsKeys.append("serverAddress");
sendSettings();
}
void AaroniaRTSAGui::on_dcBlock_toggled(bool checked)
{
m_settings.m_dcBlock = checked;
m_settingsKeys.append("dcBlock");
sendSettings();
}
void AaroniaRTSAGui::on_agc_toggled(bool checked)
{
m_settings.m_useAGC = checked;
m_settingsKeys.append("useAGC");
sendSettings();
}
void AaroniaRTSAGui::on_gain_valueChanged(int value)
{
m_settings.m_gain = value;
ui->gainText->setText(QString::number(m_settings.m_gain) + " dB");
m_settingsKeys.append("gain");
sendSettings();
}
void AaroniaRTSAGui::displaySettings()
{
blockApplySettings(true);
ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
ui->serverAddress->setText(m_settings.m_serverAddress);
ui->gain->setValue(m_settings.m_gain);
ui->gainText->setText(QString::number(m_settings.m_gain) + " dB");
ui->agc->setChecked(m_settings.m_useAGC);
ui->dcBlock->setChecked(m_settings.m_dcBlock);
blockApplySettings(false);
}
void AaroniaRTSAGui::sendSettings()
{
if (!m_updateTimer.isActive()) {
m_updateTimer.start(100);
}
}
void AaroniaRTSAGui::updateHardware()
{
if (m_doApplySettings)
{
AaroniaRTSAInput::MsgConfigureAaroniaRTSA* message = AaroniaRTSAInput::MsgConfigureAaroniaRTSA::create(m_settings, m_settingsKeys, m_forceSettings);
m_sampleSource->getInputMessageQueue()->push(message);
m_forceSettings = false;
m_settingsKeys.clear();
m_updateTimer.stop();
}
}
void AaroniaRTSAGui::updateStatus()
{
int state = m_deviceUISet->m_deviceAPI->state();
if (m_lastEngineState != state)
{
switch (state)
{
case DeviceAPI::StNotStarted:
ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
break;
case DeviceAPI::StIdle:
ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
break;
case DeviceAPI::StRunning:
ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
break;
case DeviceAPI::StError:
ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
break;
default:
break;
}
m_lastEngineState = state;
}
}
bool AaroniaRTSAGui::handleMessage(const Message& message)
{
if (AaroniaRTSAInput::MsgConfigureAaroniaRTSA::match(message))
{
qDebug("AaroniaRTSAGui::handleMessage: MsgConfigureAaroniaRTSA");
const AaroniaRTSAInput::MsgConfigureAaroniaRTSA& cfg = (AaroniaRTSAInput::MsgConfigureAaroniaRTSA&) message;
if (cfg.getForce()) {
m_settings = cfg.getSettings();
} else {
m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings());
}
displaySettings();
return true;
}
else if (AaroniaRTSAInput::MsgStartStop::match(message))
{
qDebug("AaroniaRTSAGui::handleMessage: MsgStartStop");
AaroniaRTSAInput::MsgStartStop& notif = (AaroniaRTSAInput::MsgStartStop&) message;
blockApplySettings(true);
ui->startStop->setChecked(notif.getStartStop());
blockApplySettings(false);
return true;
}
else if (AaroniaRTSAInput::MsgSetStatus::match(message))
{
qDebug("AaroniaRTSAGui::handleMessage: MsgSetStatus");
AaroniaRTSAInput::MsgSetStatus& notif = (AaroniaRTSAInput::MsgSetStatus&) message;
int status = notif.getStatus();
ui->statusIndicator->setToolTip(m_statusTooltips[status]);
ui->statusIndicator->setStyleSheet("QLabel { background-color: " +
m_statusColors[status] + "; border-radius: 7px; }");
return true;
}
else
{
return false;
}
}
void AaroniaRTSAGui::handleInputMessages()
{
Message* message;
while ((message = m_inputMessageQueue.pop()) != 0)
{
if (DSPSignalNotification::match(*message))
{
DSPSignalNotification* notif = (DSPSignalNotification*) message;
m_deviceSampleRate = notif->getSampleRate();
m_deviceCenterFrequency = notif->getCenterFrequency();
qDebug("AaroniaRTSAGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu",
notif->getSampleRate(),
notif->getCenterFrequency());
updateSampleRateAndFrequency();
delete message;
}
else
{
if (handleMessage(*message))
{
delete message;
}
}
}
}
void AaroniaRTSAGui::updateSampleRateAndFrequency()
{
m_deviceUISet->getSpectrum()->setSampleRate(m_deviceSampleRate);
m_deviceUISet->getSpectrum()->setCenterFrequency(m_deviceCenterFrequency);
ui->deviceRateText->setText(tr("%1M").arg((float)m_deviceSampleRate / 1000 / 1000));
}
void AaroniaRTSAGui::openDeviceSettingsDialog(const QPoint& p)
{
if (m_contextMenuType == ContextMenuDeviceSettings)
{
BasicDeviceSettingsDialog dialog(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.move(p);
new DialogPositioner(&dialog, false);
dialog.exec();
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_settingsKeys.append("useReverseAPI");
m_settingsKeys.append("reverseAPIAddress");
m_settingsKeys.append("reverseAPIPort");
m_settingsKeys.append("reverseAPIDeviceIndex");
sendSettings();
}
resetContextMenuType();
}
void AaroniaRTSAGui::makeUIConnections()
{
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &AaroniaRTSAGui::on_startStop_toggled);
QObject::connect(ui->centerFrequency, &ValueDial::changed, this, &AaroniaRTSAGui::on_centerFrequency_changed);
QObject::connect(ui->gain, &QSlider::valueChanged, this, &AaroniaRTSAGui::on_gain_valueChanged);
QObject::connect(ui->agc, &QToolButton::toggled, this, &AaroniaRTSAGui::on_agc_toggled);
QObject::connect(ui->serverAddress, &QLineEdit::returnPressed, this, &AaroniaRTSAGui::on_serverAddress_returnPressed);
QObject::connect(ui->serverAddressApplyButton, &QPushButton::clicked, this, &AaroniaRTSAGui::on_serverAddressApplyButton_clicked);
QObject::connect(ui->dcBlock, &ButtonSwitch::toggled, this, &AaroniaRTSAGui::on_dcBlock_toggled);
}

View File

@ -0,0 +1,89 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 _AARONIARTSA_AARONIARTSAGUI_H_
#define _AARONIARTSA_AARONIARTSAGUI_H_
#include <device/devicegui.h>
#include <QTimer>
#include <QWidget>
#include "util/messagequeue.h"
#include "aaroniartsasettings.h"
#include "aaroniartsainput.h"
class DeviceUISet;
namespace Ui {
class AaroniaRTSAGui;
}
class AaroniaRTSAGui : public DeviceGUI {
Q_OBJECT
public:
explicit AaroniaRTSAGui(DeviceUISet *deviceUISet, QWidget* parent = 0);
virtual ~AaroniaRTSAGui();
virtual void destroy();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
virtual MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; }
private:
Ui::AaroniaRTSAGui* ui;
AaroniaRTSASettings m_settings;
QList<QString> m_settingsKeys;
QTimer m_updateTimer;
QTimer m_statusTimer;
bool m_doApplySettings;
bool m_forceSettings;
DeviceSampleSource* m_sampleSource;
std::size_t m_tickCount;
int m_deviceSampleRate;
quint64 m_deviceCenterFrequency; //!< Center frequency in device
int m_lastEngineState;
MessageQueue m_inputMessageQueue;
std::vector<QString> m_statusColors;
std::vector<QString> m_statusTooltips;
void blockApplySettings(bool block) { m_doApplySettings = !block; }
void displaySettings();
void sendSettings();
void updateSampleRateAndFrequency();
bool handleMessage(const Message& message);
void makeUIConnections();
private slots:
void handleInputMessages();
void on_startStop_toggled(bool checked);
void on_centerFrequency_changed(quint64 value);
void on_gain_valueChanged(int value);
void on_agc_toggled(bool checked);
void on_serverAddress_returnPressed();
void on_serverAddressApplyButton_clicked();
void on_dcBlock_toggled(bool checked);
void openDeviceSettingsDialog(const QPoint& p);
void updateStatus();
void updateHardware();
};
#endif // _AARONIARTSA_AARONIARTSAGUI_H_

View File

@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AaroniaRTSAGui</class>
<widget class="QWidget" name="AaroniaRTSAGui">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>360</width>
<height>106</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>360</width>
<height>106</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>380</width>
<height>143</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="windowTitle">
<string>AaroniaRTSA</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_freq">
<item>
<layout class="QVBoxLayout" name="deviceUILayout">
<item>
<layout class="QHBoxLayout" name="deviceButtonsLayout">
<item>
<widget class="ButtonSwitch" name="startStop">
<property name="toolTip">
<string>start/stop acquisition</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/play.png</normaloff>
<normalon>:/stop.png</normalon>:/play.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="deviceRateLayout">
<item>
<widget class="QLabel" name="deviceRateText">
<property name="minimumSize">
<size>
<width>58</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>I/Q sample rate kS/s</string>
</property>
<property name="text">
<string>0000.00k</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="ValueDial" name="centerFrequency" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>16</height>
</size>
</property>
<property name="font">
<font>
<family>Liberation Mono</family>
<pointsize>16</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Tuner center frequency in kHz</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="freqUnits">
<property name="text">
<string> kHz</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="serverAddressLayout">
<item>
<widget class="QLabel" name="serverAddressLabel">
<property name="text">
<string>Addr</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="serverAddress">
<property name="toolTip">
<string>Server address</string>
</property>
<property name="text">
<string>127.0.0.1:8073</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="statusIndicator">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>14</width>
<height>14</height>
</size>
</property>
<property name="toolTip">
<string>Idle</string>
</property>
<property name="styleSheet">
<string notr="true">QLabel { background-color: gray; border-radius: 7px; }</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="serverAddressApplyButton">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Set</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="gainLayout">
<item>
<widget class="QLabel" name="gainLabel">
<property name="text">
<string>Gain</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="gain">
<property name="toolTip">
<string>Manual gain</string>
</property>
<property name="maximum">
<number>120</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="gainText">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>20 dB</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="agc">
<property name="toolTip">
<string>Automatic gain control</string>
</property>
<property name="text">
<string>AGC</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="ButtonSwitch" name="dcBlock">
<property name="toolTip">
<string>Automatic DC offset removal</string>
</property>
<property name="text">
<string>DC</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ValueDial</class>
<extends>QWidget</extends>
<header>gui/valuedial.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>ButtonSwitch</class>
<extends>QToolButton</extends>
<header>gui/buttonswitch.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,555 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 <string.h>
#include <errno.h>
#include <QDebug>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QBuffer>
#include <QThread>
#include "SWGDeviceSettings.h"
#include "SWGDeviceState.h"
#include "SWGDeviceReport.h"
#include "SWGAaroniaRTSAReport.h"
#include "aaroniartsainput.h"
#include "device/deviceapi.h"
#include "aaroniartsaworker.h"
#include "dsp/dspcommands.h"
#include "dsp/dspengine.h"
MESSAGE_CLASS_DEFINITION(AaroniaRTSAInput::MsgConfigureAaroniaRTSA, Message)
MESSAGE_CLASS_DEFINITION(AaroniaRTSAInput::MsgStartStop, Message)
MESSAGE_CLASS_DEFINITION(AaroniaRTSAInput::MsgSetStatus, Message)
AaroniaRTSAInput::AaroniaRTSAInput(DeviceAPI *deviceAPI) :
m_deviceAPI(deviceAPI),
m_sampleRate(2.0e5),
m_settings(),
m_aaroniaRTSAWorker(nullptr),
m_aaroniaRTSAWorkerThread(nullptr),
m_deviceDescription("AaroniaRTSA"),
m_running(false),
m_masterTimer(deviceAPI->getMasterTimer())
{
m_sampleFifo.setLabel(m_deviceDescription);
m_deviceAPI->setNbSourceStreams(1);
if (!m_sampleFifo.setSize(getSampleRate() * 2)) {
qCritical("AaroniaRTSAInput::AaroniaRTSAInput: Could not allocate SampleFifo");
}
m_networkManager = new QNetworkAccessManager();
QObject::connect(
m_networkManager,
&QNetworkAccessManager::finished,
this,
&AaroniaRTSAInput::networkManagerFinished
);
}
AaroniaRTSAInput::~AaroniaRTSAInput()
{
QObject::disconnect(
m_networkManager,
&QNetworkAccessManager::finished,
this,
&AaroniaRTSAInput::networkManagerFinished
);
delete m_networkManager;
if (m_running) {
stop();
}
}
void AaroniaRTSAInput::destroy()
{
delete this;
}
void AaroniaRTSAInput::init()
{
applySettings(m_settings, QList<QString>(), true);
}
bool AaroniaRTSAInput::start()
{
QMutexLocker mutexLocker(&m_mutex);
if (m_running) {
return true;
}
m_aaroniaRTSAWorkerThread = new QThread();
m_aaroniaRTSAWorker = new AaroniaRTSAWorker(&m_sampleFifo);
m_aaroniaRTSAWorker->setInputMessageQueue(getInputMessageQueue());
m_aaroniaRTSAWorker->moveToThread(m_aaroniaRTSAWorkerThread);
QObject::connect(m_aaroniaRTSAWorkerThread, &QThread::finished, m_aaroniaRTSAWorker, &QObject::deleteLater);
QObject::connect(m_aaroniaRTSAWorkerThread, &QThread::finished, m_aaroniaRTSAWorkerThread, &QThread::deleteLater);
connect(this, &AaroniaRTSAInput::setWorkerCenterFrequency, m_aaroniaRTSAWorker, &AaroniaRTSAWorker::onCenterFrequencyChanged);
connect(this, &AaroniaRTSAInput::setWorkerServerAddress, m_aaroniaRTSAWorker, &AaroniaRTSAWorker::onServerAddressChanged);
connect(this, &AaroniaRTSAInput::setWorkerGain, m_aaroniaRTSAWorker, &AaroniaRTSAWorker::onGainChanged);
connect(m_aaroniaRTSAWorker, &AaroniaRTSAWorker::updateStatus, this, &AaroniaRTSAInput::setWorkerStatus);
m_aaroniaRTSAWorkerThread->start();
m_running = true;
mutexLocker.unlock();
applySettings(m_settings, QList<QString>(), true);
return true;
}
void AaroniaRTSAInput::stop()
{
QMutexLocker mutexLocker(&m_mutex);
if (!m_running) {
return;
}
m_running = false;
setWorkerStatus(0);
if (m_aaroniaRTSAWorkerThread)
{
m_aaroniaRTSAWorkerThread->quit();
m_aaroniaRTSAWorkerThread->wait();
m_aaroniaRTSAWorker = nullptr;
m_aaroniaRTSAWorkerThread = nullptr;
}
}
QByteArray AaroniaRTSAInput::serialize() const
{
return m_settings.serialize();
}
bool AaroniaRTSAInput::deserialize(const QByteArray& data)
{
bool success = true;
if (!m_settings.deserialize(data))
{
m_settings.resetToDefaults();
success = false;
}
MsgConfigureAaroniaRTSA* message = MsgConfigureAaroniaRTSA::create(m_settings, QList<QString>(), true);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureAaroniaRTSA* messageToGUI = MsgConfigureAaroniaRTSA::create(m_settings, QList<QString>(), true);
m_guiMessageQueue->push(messageToGUI);
}
return success;
}
const QString& AaroniaRTSAInput::getDeviceDescription() const
{
return m_deviceDescription;
}
int AaroniaRTSAInput::getSampleRate() const
{
return m_sampleRate;
}
quint64 AaroniaRTSAInput::getCenterFrequency() const
{
return m_settings.m_centerFrequency;
}
void AaroniaRTSAInput::setCenterFrequency(qint64 centerFrequency)
{
AaroniaRTSASettings settings = m_settings;
settings.m_centerFrequency = centerFrequency;
MsgConfigureAaroniaRTSA* message = MsgConfigureAaroniaRTSA::create(settings, QList<QString>{"centerFrequency"}, false);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue)
{
MsgConfigureAaroniaRTSA* messageToGUI = MsgConfigureAaroniaRTSA::create(settings, QList<QString>{"centerFrequency"}, false);
m_guiMessageQueue->push(messageToGUI);
}
}
void AaroniaRTSAInput::setWorkerStatus(int status)
{
if (m_guiMessageQueue) {
m_guiMessageQueue->push(MsgSetStatus::create(status));
}
}
bool AaroniaRTSAInput::handleMessage(const Message& message)
{
if (MsgConfigureAaroniaRTSA::match(message))
{
MsgConfigureAaroniaRTSA& conf = (MsgConfigureAaroniaRTSA&) message;
qDebug() << "AaroniaRTSAInput::handleMessage: MsgConfigureAaroniaRTSA";
bool success = applySettings(conf.getSettings(), conf.getSettingsKeys(), conf.getForce());
if (!success) {
qDebug("AaroniaRTSAInput::handleMessage: config error");
}
return true;
}
else if (AaroniaRTSAWorker::MsgReportSampleRate::match(message))
{
AaroniaRTSAWorker::MsgReportSampleRate& report = (AaroniaRTSAWorker::MsgReportSampleRate&) message;
m_sampleRate = report.getSampleRate();
qDebug() << "AaroniaRTSAInput::handleMessage: AaroniaRTSAWorker::MsgReportSampleRate: m_sampleRate: " << m_sampleRate;
if (!m_sampleFifo.setSize(m_sampleRate * 2)) {
qCritical("AaroniaRTSAInput::AaroniaRTSAInput: Could not allocate SampleFifo");
}
DSPSignalNotification *notif = new DSPSignalNotification(
m_sampleRate, m_settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
return true;
}
else if (MsgStartStop::match(message))
{
MsgStartStop& cmd = (MsgStartStop&) message;
qDebug() << "AaroniaRTSAInput::handleMessage: MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop");
if (cmd.getStartStop())
{
if (m_deviceAPI->initDeviceEngine()) {
m_deviceAPI->startDeviceEngine();
}
}
else
{
m_deviceAPI->stopDeviceEngine();
}
if (m_settings.m_useReverseAPI) {
webapiReverseSendStartStop(cmd.getStartStop());
}
return true;
}
else
{
return false;
}
}
int AaroniaRTSAInput::getStatus() const
{
if (m_aaroniaRTSAWorker) {
return m_aaroniaRTSAWorker->getStatus();
} else {
return 0;
}
}
bool AaroniaRTSAInput::applySettings(const AaroniaRTSASettings& settings, const QList<QString>& settingsKeys, bool force)
{
qDebug() << "AaroniaRTSAInput::applySettings: force: "<< force << settings.getDebugString(settingsKeys, force);
if (settingsKeys.contains("serverAddress") || force)
{
emit setWorkerServerAddress(settings.m_serverAddress);
}
if (settingsKeys.contains("gain") ||
settingsKeys.contains("useAGC") || force)
{
emit setWorkerGain(settings.m_gain, settings.m_useAGC);
}
if (settingsKeys.contains("dcBlock")) {
m_deviceAPI->configureCorrections(settings.m_dcBlock, false);
}
if (settingsKeys.contains("centerFrequency") || force)
{
emit setWorkerCenterFrequency(settings.m_centerFrequency);
DSPSignalNotification *notif = new DSPSignalNotification(
getSampleRate(), settings.m_centerFrequency);
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
}
if (settingsKeys.contains("useReverseAPI"))
{
bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) ||
settingsKeys.contains("reverseAPIAddress") ||
settingsKeys.contains("reverseAPIPort") ||
settingsKeys.contains("reverseAPIDeviceIndex");
webapiReverseSendSettings(settingsKeys, settings, fullUpdate || force);
}
if (force) {
m_settings = settings;
} else {
m_settings.applySettings(settingsKeys, settings);
}
return true;
}
int AaroniaRTSAInput::webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
{
(void) errorMessage;
m_deviceAPI->getDeviceEngineStateStr(*response.getState());
return 200;
}
int AaroniaRTSAInput::webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
{
(void) errorMessage;
m_deviceAPI->getDeviceEngineStateStr(*response.getState());
MsgStartStop *message = MsgStartStop::create(run);
m_inputMessageQueue.push(message);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgStartStop *msgToGUI = MsgStartStop::create(run);
m_guiMessageQueue->push(msgToGUI);
}
return 200;
}
int AaroniaRTSAInput::webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage)
{
(void) errorMessage;
response.setAaroniaRtsaSettings(new SWGSDRangel::SWGAaroniaRTSASettings());
response.getAaroniaRtsaSettings()->init();
webapiFormatDeviceSettings(response, m_settings);
return 200;
}
int AaroniaRTSAInput::webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage)
{
(void) errorMessage;
AaroniaRTSASettings settings = m_settings;
webapiUpdateDeviceSettings(settings, deviceSettingsKeys, response);
MsgConfigureAaroniaRTSA *msg = MsgConfigureAaroniaRTSA::create(settings, deviceSettingsKeys, force);
m_inputMessageQueue.push(msg);
if (m_guiMessageQueue) // forward to GUI if any
{
MsgConfigureAaroniaRTSA *msgToGUI = MsgConfigureAaroniaRTSA::create(settings, deviceSettingsKeys, force);
m_guiMessageQueue->push(msgToGUI);
}
webapiFormatDeviceSettings(response, settings);
return 200;
}
void AaroniaRTSAInput::webapiUpdateDeviceSettings(
AaroniaRTSASettings& settings,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response)
{
if (deviceSettingsKeys.contains("gain")) {
settings.m_gain = response.getAaroniaRtsaSettings()->getGain();
}
if (deviceSettingsKeys.contains("useAGC")) {
settings.m_useAGC = response.getAaroniaRtsaSettings()->getUseAgc();
}
if (deviceSettingsKeys.contains("dcBlock")) {
settings.m_dcBlock = response.getAaroniaRtsaSettings()->getDcBlock() != 0;
}
if (deviceSettingsKeys.contains("centerFrequency")) {
settings.m_centerFrequency = response.getAaroniaRtsaSettings()->getCenterFrequency();
}
if (deviceSettingsKeys.contains("serverAddress")) {
settings.m_serverAddress = *response.getAaroniaRtsaSettings()->getServerAddress();
}
if (deviceSettingsKeys.contains("useReverseAPI")) {
settings.m_useReverseAPI = response.getAaroniaRtsaSettings()->getUseReverseApi() != 0;
}
if (deviceSettingsKeys.contains("reverseAPIAddress")) {
settings.m_reverseAPIAddress = *response.getAaroniaRtsaSettings()->getReverseApiAddress();
}
if (deviceSettingsKeys.contains("reverseAPIPort")) {
settings.m_reverseAPIPort = response.getAaroniaRtsaSettings()->getReverseApiPort();
}
if (deviceSettingsKeys.contains("reverseAPIDeviceIndex")) {
settings.m_reverseAPIDeviceIndex = response.getAaroniaRtsaSettings()->getReverseApiDeviceIndex();
}
}
int AaroniaRTSAInput::webapiReportGet(
SWGSDRangel::SWGDeviceReport& response,
QString& errorMessage)
{
(void) errorMessage;
response.setAaroniaSdrReport(new SWGSDRangel::SWGAaroniaRTSAReport());
response.getAirspyHfReport()->init();
webapiFormatDeviceReport(response);
return 200;
}
void AaroniaRTSAInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const AaroniaRTSASettings& settings)
{
response.getAaroniaRtsaSettings()->setGain(settings.m_gain);
response.getAaroniaRtsaSettings()->setUseAgc(settings.m_useAGC ? 1 : 0);
response.getAaroniaRtsaSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0);
response.getAaroniaRtsaSettings()->setCenterFrequency(settings.m_centerFrequency);
if (response.getAaroniaRtsaSettings()->getServerAddress()) {
*response.getAaroniaRtsaSettings()->getServerAddress() = settings.m_serverAddress;
} else {
response.getAaroniaRtsaSettings()->setServerAddress(new QString(settings.m_serverAddress));
}
response.getAaroniaRtsaSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0);
if (response.getAaroniaRtsaSettings()->getReverseApiAddress()) {
*response.getAaroniaRtsaSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress;
} else {
response.getAaroniaRtsaSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress));
}
response.getAaroniaRtsaSettings()->setReverseApiPort(settings.m_reverseAPIPort);
response.getAaroniaRtsaSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex);
}
void AaroniaRTSAInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response)
{
response.getAaroniaSdrReport()->setStatus(getStatus());
}
void AaroniaRTSAInput::webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AaroniaRTSASettings& settings, bool force)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("AaroniaRTSA"));
swgDeviceSettings->setAaroniaRtsaSettings(new SWGSDRangel::SWGAaroniaRTSASettings());
SWGSDRangel::SWGAaroniaRTSASettings *swgAaroniaRTSASettings = swgDeviceSettings->getAaroniaRtsaSettings();
// transfer data that has been modified. When force is on transfer all data except reverse API data
if (deviceSettingsKeys.contains("gain")) {
swgAaroniaRTSASettings->setGain(settings.m_gain);
}
if (deviceSettingsKeys.contains("useAGC")) {
swgAaroniaRTSASettings->setUseAgc(settings.m_useAGC ? 1 : 0);
}
if (deviceSettingsKeys.contains("dcBlock") || force) {
swgAaroniaRTSASettings->setDcBlock(settings.m_dcBlock ? 1 : 0);
}
if (deviceSettingsKeys.contains("centerFrequency") || force) {
swgAaroniaRTSASettings->setCenterFrequency(settings.m_centerFrequency);
}
if (deviceSettingsKeys.contains("serverAddress") || force) {
swgAaroniaRTSASettings->setServerAddress(new QString(settings.m_serverAddress));
}
QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings")
.arg(settings.m_reverseAPIAddress)
.arg(settings.m_reverseAPIPort)
.arg(settings.m_reverseAPIDeviceIndex);
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgDeviceSettings->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 swgDeviceSettings;
}
void AaroniaRTSAInput::webapiReverseSendStartStop(bool start)
{
SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings();
swgDeviceSettings->setDirection(0); // single Rx
swgDeviceSettings->setOriginatorIndex(m_deviceAPI->getDeviceSetIndex());
swgDeviceSettings->setDeviceHwType(new QString("AaroniaRTSA"));
QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/run")
.arg(m_settings.m_reverseAPIAddress)
.arg(m_settings.m_reverseAPIPort)
.arg(m_settings.m_reverseAPIDeviceIndex);
m_networkRequest.setUrl(QUrl(deviceSettingsURL));
m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QBuffer *buffer = new QBuffer();
buffer->open((QBuffer::ReadWrite));
buffer->write(swgDeviceSettings->asJson().toUtf8());
buffer->seek(0);
QNetworkReply *reply;
if (start) {
reply = m_networkManager->sendCustomRequest(m_networkRequest, "POST", buffer);
} else {
reply = m_networkManager->sendCustomRequest(m_networkRequest, "DELETE", buffer);
}
buffer->setParent(reply);
delete swgDeviceSettings;
}
void AaroniaRTSAInput::networkManagerFinished(QNetworkReply *reply)
{
QNetworkReply::NetworkError replyError = reply->error();
if (replyError)
{
qWarning() << "AaroniaRTSAInput::networkManagerFinished:"
<< " error(" << (int) replyError
<< "): " << replyError
<< ": " << reply->errorString();
}
else
{
QString answer = reply->readAll();
answer.chop(1); // remove last \n
qDebug("AaroniaRTSAInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str());
}
reply->deleteLater();
}

View File

@ -0,0 +1,186 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 _AARONIARTSA_AARONIARTSAINPUT_H_
#define _AARONIARTSA_AARONIARTSAINPUT_H_
#include <QString>
#include <QByteArray>
#include <QTimer>
#include <QNetworkRequest>
#include <dsp/devicesamplesource.h>
#include "aaroniartsasettings.h"
class DeviceAPI;
class AaroniaRTSAWorker;
class QNetworkAccessManager;
class QNetworkReply;
class QThread;
class AaroniaRTSAInput : public DeviceSampleSource {
Q_OBJECT
public:
class MsgConfigureAaroniaRTSA : public Message {
MESSAGE_CLASS_DECLARATION
public:
const AaroniaRTSASettings& getSettings() const { return m_settings; }
const QList<QString>& getSettingsKeys() const { return m_settingsKeys; }
bool getForce() const { return m_force; }
static MsgConfigureAaroniaRTSA* create(const AaroniaRTSASettings& settings, const QList<QString>& settingsKeys, bool force)
{
return new MsgConfigureAaroniaRTSA(settings, settingsKeys, force);
}
private:
AaroniaRTSASettings m_settings;
QList<QString> m_settingsKeys;
bool m_force;
MsgConfigureAaroniaRTSA(const AaroniaRTSASettings& settings, const QList<QString>& settingsKeys, bool force) :
Message(),
m_settings(settings),
m_settingsKeys(settingsKeys),
m_force(force)
{ }
};
class MsgStartStop : public Message {
MESSAGE_CLASS_DECLARATION
public:
bool getStartStop() const { return m_startStop; }
static MsgStartStop* create(bool startStop) {
return new MsgStartStop(startStop);
}
protected:
bool m_startStop;
MsgStartStop(bool startStop) :
Message(),
m_startStop(startStop)
{ }
};
class MsgSetStatus : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getStatus() const { return m_status; }
static MsgSetStatus* create(int status) {
return new MsgSetStatus(status);
}
protected:
int m_status;
MsgSetStatus(int status) :
Message(),
m_status(status)
{ }
};
AaroniaRTSAInput(DeviceAPI *deviceAPI);
virtual ~AaroniaRTSAInput();
virtual void destroy();
virtual void init();
virtual bool start();
virtual void stop();
virtual QByteArray serialize() const;
virtual bool deserialize(const QByteArray& data);
virtual void setMessageQueueToGUI(MessageQueue *queue) { m_guiMessageQueue = queue; }
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual void setSampleRate(int sampleRate) { (void) sampleRate; }
virtual quint64 getCenterFrequency() const;
virtual void setCenterFrequency(qint64 centerFrequency);
virtual bool handleMessage(const Message& message);
virtual int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
virtual int webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
virtual int webapiRun(
bool run,
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage);
virtual int webapiReportGet(
SWGSDRangel::SWGDeviceReport& response,
QString& errorMessage);
static void webapiFormatDeviceSettings(
SWGSDRangel::SWGDeviceSettings& response,
const AaroniaRTSASettings& settings);
static void webapiUpdateDeviceSettings(
AaroniaRTSASettings& settings,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response);
private:
DeviceAPI *m_deviceAPI;
QMutex m_mutex;
int m_sampleRate;
AaroniaRTSASettings m_settings;
AaroniaRTSAWorker* m_aaroniaRTSAWorker;
QThread *m_aaroniaRTSAWorkerThread;
QString m_deviceDescription;
bool m_running;
const QTimer& m_masterTimer;
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
int getStatus() const;
bool applySettings(const AaroniaRTSASettings& settings, const QList<QString>& settingsKeys, bool force);
void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response);
void webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AaroniaRTSASettings& settings, bool force);
void webapiReverseSendStartStop(bool start);
signals:
void startWorker();
void stopWorker();
void setWorkerCenterFrequency(quint64 centerFrequency);
void setWorkerServerAddress(QString serverAddress);
void setWorkerGain(quint32 gain, bool useAGC);
private slots:
void setWorkerStatus(int status);
void networkManagerFinished(QNetworkReply *reply);
};
#endif // _AARONIARTSA_AARONIARTSAINPUT_H_

View File

@ -0,0 +1,146 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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"
#include "util/simpleserializer.h"
#ifdef SERVER_MODE
#include "aaroniartsainput.h"
#else
#include "aaroniartsagui.h"
#endif
#include "aaroniartsaplugin.h"
#include "aaroniartsawebapiadapter.h"
const PluginDescriptor AaroniaRTSAPlugin::m_pluginDescriptor = {
QStringLiteral("AaroniaRTSA"),
QStringLiteral("AaroniaRTSA input"),
QStringLiteral("7.8.4"),
QStringLiteral("(c) Vort (c) Edouard Griffiths, F4EXB"),
QStringLiteral("https://github.com/f4exb/sdrangel"),
true,
QStringLiteral("https://github.com/f4exb/sdrangel")
};
static constexpr const char* const m_hardwareID = "AaroniaRTSA";
static constexpr const char* const m_deviceTypeID = AARONIARTSA_DEVICE_TYPE_ID;
AaroniaRTSAPlugin::AaroniaRTSAPlugin(QObject* parent) :
QObject(parent)
{
}
const PluginDescriptor& AaroniaRTSAPlugin::getPluginDescriptor() const
{
return m_pluginDescriptor;
}
void AaroniaRTSAPlugin::initPlugin(PluginAPI* pluginAPI)
{
pluginAPI->registerSampleSource(m_deviceTypeID, this);
}
void AaroniaRTSAPlugin::enumOriginDevices(QStringList& listedHwIds, OriginDevices& originDevices)
{
if (listedHwIds.contains(m_hardwareID)) { // check if it was done
return;
}
originDevices.append(OriginDevice(
"AaroniaRTSA",
m_hardwareID,
QString(),
0,
1, // nb Rx
0 // nb Tx
));
listedHwIds.append(m_hardwareID);
}
PluginInterface::SamplingDevices AaroniaRTSAPlugin::enumSampleSources(const OriginDevices& originDevices)
{
SamplingDevices result;
for (OriginDevices::const_iterator it = originDevices.begin(); it != originDevices.end(); ++it)
{
if (it->hardwareId == m_hardwareID)
{
result.append(SamplingDevice(
it->displayableName,
m_hardwareID,
m_deviceTypeID,
it->serial,
it->sequence,
PluginInterface::SamplingDevice::BuiltInDevice,
PluginInterface::SamplingDevice::StreamSingleRx,
1,
0
));
}
}
return result;
}
#ifdef SERVER_MODE
DeviceGUI* AaroniaRTSAPlugin::createSampleSourcePluginInstanceGUI(
const QString& sourceId,
QWidget **widget,
DeviceUISet *deviceUISet)
{
(void) sourceId;
(void) widget;
(void) deviceUISet;
return 0;
}
#else
DeviceGUI* AaroniaRTSAPlugin::createSampleSourcePluginInstanceGUI(
const QString& sourceId,
QWidget **widget,
DeviceUISet *deviceUISet)
{
if(sourceId == m_deviceTypeID) {
AaroniaRTSAGui* gui = new AaroniaRTSAGui(deviceUISet);
*widget = gui;
return gui;
} else {
return 0;
}
}
#endif
DeviceSampleSource *AaroniaRTSAPlugin::createSampleSourcePluginInstance(const QString& sourceId, DeviceAPI *deviceAPI)
{
if (sourceId == m_deviceTypeID)
{
AaroniaRTSAInput* input = new AaroniaRTSAInput(deviceAPI);
return input;
}
else
{
return 0;
}
}
DeviceWebAPIAdapter *AaroniaRTSAPlugin::createDeviceWebAPIAdapter() const
{
return new AaroniaRTSAWebAPIAdapter();
}

View File

@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 _AARONIARTSA_AARONIARTSAPLUGIN_H
#define _AARONIARTSA_AARONIARTSAPLUGIN_H
#include <QObject>
#include "plugin/plugininterface.h"
class PluginAPI;
#define AARONIARTSA_DEVICE_TYPE_ID "sdrangel.samplesource.aaroniartsasource"
class AaroniaRTSAPlugin : public QObject, public PluginInterface {
Q_OBJECT
Q_INTERFACES(PluginInterface)
Q_PLUGIN_METADATA(IID AARONIARTSA_DEVICE_TYPE_ID)
public:
explicit AaroniaRTSAPlugin(QObject* parent = NULL);
const PluginDescriptor& getPluginDescriptor() const;
void initPlugin(PluginAPI* pluginAPI);
virtual void enumOriginDevices(QStringList& listedHwIds, OriginDevices& originDevices);
virtual SamplingDevices enumSampleSources(const OriginDevices& originDevices);
virtual DeviceGUI* createSampleSourcePluginInstanceGUI(
const QString& sourceId,
QWidget **widget,
DeviceUISet *deviceUISet);
virtual DeviceSampleSource* createSampleSourcePluginInstance(const QString& sourceId, DeviceAPI *deviceAPI);
virtual DeviceWebAPIAdapter* createDeviceWebAPIAdapter() const;
private:
static const PluginDescriptor m_pluginDescriptor;
};
#endif // _AARONIARTSA_AARONIARTSAPLUGIN_H

View File

@ -0,0 +1,164 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 "util/simpleserializer.h"
#include "aaroniartsasettings.h"
AaroniaRTSASettings::AaroniaRTSASettings()
{
resetToDefaults();
}
void AaroniaRTSASettings::resetToDefaults()
{
m_centerFrequency = 1450000;
m_gain = 20;
m_useAGC = true;
m_dcBlock = false;
m_serverAddress = "127.0.0.1:8073";
m_useReverseAPI = false;
m_reverseAPIAddress = "127.0.0.1";
m_reverseAPIPort = 8888;
m_reverseAPIDeviceIndex = 0;
}
QByteArray AaroniaRTSASettings::serialize() const
{
SimpleSerializer s(2);
s.writeString(2, m_serverAddress);
s.writeU32(3, m_gain);
s.writeBool(4, m_useAGC);
s.writeBool(100, m_useReverseAPI);
s.writeString(101, m_reverseAPIAddress);
s.writeU32(102, m_reverseAPIPort);
s.writeU32(103, m_reverseAPIDeviceIndex);
return s.final();
}
bool AaroniaRTSASettings::deserialize(const QByteArray& data)
{
SimpleDeserializer d(data);
if (!d.isValid())
{
resetToDefaults();
return false;
}
if (d.getVersion() == 2)
{
uint32_t utmp;
d.readString(2, &m_serverAddress, "127.0.0.1:8073");
d.readU32(3, &m_gain, 20);
d.readBool(4, &m_useAGC, true);
d.readBool(100, &m_useReverseAPI, false);
d.readString(101, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(102, &utmp, 0);
if ((utmp > 1023) && (utmp < 65535)) {
m_reverseAPIPort = utmp;
}
else {
m_reverseAPIPort = 8888;
}
d.readU32(103, &utmp, 0);
m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp;
return true;
}
else
{
resetToDefaults();
return false;
}
}
void AaroniaRTSASettings::applySettings(const QStringList& settingsKeys, const AaroniaRTSASettings& settings)
{
if (settingsKeys.contains("centerFrequency")) {
m_centerFrequency = settings.m_centerFrequency;
}
if (settingsKeys.contains("gain")) {
m_gain = settings.m_gain;
}
if (settingsKeys.contains("useAGC")) {
m_useAGC = settings.m_useAGC;
}
if (settingsKeys.contains("dcBlock")) {
m_dcBlock = settings.m_dcBlock;
}
if (settingsKeys.contains("serverAddress")) {
m_serverAddress = settings.m_serverAddress;
}
if (settingsKeys.contains("useReverseAPI")) {
m_useReverseAPI = settings.m_useReverseAPI;
}
if (settingsKeys.contains("reverseAPIAddress")) {
m_reverseAPIAddress = settings.m_reverseAPIAddress;
}
if (settingsKeys.contains("reverseAPIPort")) {
m_reverseAPIPort = settings.m_reverseAPIPort;
}
if (settingsKeys.contains("reverseAPIDeviceIndex")) {
m_reverseAPIDeviceIndex = settings.m_reverseAPIDeviceIndex;
}
}
QString AaroniaRTSASettings::getDebugString(const QStringList& settingsKeys, bool force) const
{
std::ostringstream ostr;
if (settingsKeys.contains("centerFrequency") || force) {
ostr << " m_centerFrequency: " << m_centerFrequency;
}
if (settingsKeys.contains("gain") || force) {
ostr << " m_gain: " << m_gain;
}
if (settingsKeys.contains("useAGC") || force) {
ostr << " m_useAGC: " << m_useAGC;
}
if (settingsKeys.contains("dcBlock") || force) {
ostr << " m_dcBlock: " << m_dcBlock;
}
if (settingsKeys.contains("serverAddress") || force) {
ostr << " m_serverAddress: " << m_serverAddress.toStdString();
}
if (settingsKeys.contains("useReverseAPI") || force) {
ostr << " m_useReverseAPI: " << m_useReverseAPI;
}
if (settingsKeys.contains("reverseAPIAddress") || force) {
ostr << " m_reverseAPIAddress: " << m_reverseAPIAddress.toStdString();
}
if (settingsKeys.contains("reverseAPIPort") || force) {
ostr << " m_reverseAPIPort: " << m_reverseAPIPort;
}
if (settingsKeys.contains("reverseAPIDeviceIndex") || force) {
ostr << " m_reverseAPIDeviceIndex: " << m_reverseAPIDeviceIndex;
}
return QString(ostr.str().c_str());
}

View File

@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// 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 _AARONIARTSA_AARONIARTSASETTINGS_H_
#define _AARONIARTSA_AARONIARTSASETTINGS_H_
#include <QString>
#include <QByteArray>
struct AaroniaRTSASettings {
uint32_t m_gain;
bool m_useAGC;
bool m_dcBlock;
quint64 m_centerFrequency;
QString m_serverAddress;
bool m_useReverseAPI;
QString m_reverseAPIAddress;
uint16_t m_reverseAPIPort;
uint16_t m_reverseAPIDeviceIndex;
AaroniaRTSASettings();
void resetToDefaults();
QByteArray serialize() const;
bool deserialize(const QByteArray& data);
void applySettings(const QStringList& settingsKeys, const AaroniaRTSASettings& settings);
QString getDebugString(const QStringList& settingsKeys, bool force=false) const;
};
#endif /* _AARONIARTSA_AARONIARTSASETTINGS_H_ */

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// Implementation of static web API adapters used for preset serialization and //
// deserialization //
// //
// 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 "SWGDeviceSettings.h"
#include "aaroniartsainput.h"
#include "aaroniartsawebapiadapter.h"
AaroniaRTSAWebAPIAdapter::AaroniaRTSAWebAPIAdapter()
{}
AaroniaRTSAWebAPIAdapter::~AaroniaRTSAWebAPIAdapter()
{}
int AaroniaRTSAWebAPIAdapter::webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage)
{
(void) errorMessage;
response.setAaroniaRtsaSettings(new SWGSDRangel::SWGAaroniaRTSASettings());
response.getAaroniaRtsaSettings()->init();
AaroniaRTSAInput::webapiFormatDeviceSettings(response, m_settings);
return 200;
}
int AaroniaRTSAWebAPIAdapter::webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage)
{
(void) force; // no action
(void) errorMessage;
AaroniaRTSAInput::webapiUpdateDeviceSettings(m_settings, deviceSettingsKeys, response);
return 200;
}

View File

@ -0,0 +1,44 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// //
// Implementation of static web API adapters used for preset serialization and //
// deserialization //
// //
// 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 "device/devicewebapiadapter.h"
#include "aaroniartsasettings.h"
class AaroniaRTSAWebAPIAdapter : public DeviceWebAPIAdapter
{
public:
AaroniaRTSAWebAPIAdapter();
virtual ~AaroniaRTSAWebAPIAdapter();
virtual QByteArray serialize() { return m_settings.serialize(); }
virtual bool deserialize(const QByteArray& data) { return m_settings.deserialize(data); }
virtual int webapiSettingsGet(
SWGSDRangel::SWGDeviceSettings& response,
QString& errorMessage);
virtual int webapiSettingsPutPatch(
bool force,
const QStringList& deviceSettingsKeys,
SWGSDRangel::SWGDeviceSettings& response, // query + response
QString& errorMessage);
private:
AaroniaRTSASettings m_settings;
};

View File

@ -0,0 +1,337 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// //
// 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 <boost/endian/conversion.hpp>
#include "util/messagequeue.h"
#include "aaroniartsaworker.h"
MESSAGE_CLASS_DEFINITION(AaroniaRTSAWorker::MsgReportSampleRate, Message)
AaroniaRTSAWorker::AaroniaRTSAWorker(SampleSinkFifo* sampleFifo) :
QObject(),
m_timer(this),
m_samplesBuf(),
m_sampleFifo(sampleFifo),
m_centerFrequency(1450000),
m_sampleRate(10.0e6),
m_inputMessageQueue(nullptr),
m_gain(20),
m_useAGC(true),
m_status(0),
m_convertBuffer(64e6)
{
/*connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick()));
m_webSocket.setParent(this);
connect(&m_webSocket, &QWebSocket::connected,
this, &AaroniaRTSAWorker::onConnected);
connect(&m_webSocket, &QWebSocket::binaryMessageReceived,
this, &AaroniaRTSAWorker::onBinaryMessageReceived);
connect(&m_webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
this, &AaroniaRTSAWorker::onSocketError);
connect(&m_webSocket, &QWebSocket::disconnected,
this, &AaroniaRTSAWorker::onDisconnected);
*/
// Initialize network manager
mNetworkAccessManager = new QNetworkAccessManager(this);
// Request 16bit raw samples
QUrl url("http://localhost:55123/stream?format=float32");
QNetworkRequest req(url);
mReply = mNetworkAccessManager->get(req);
// Connect Qt slots to network events
connect(mReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onError(QNetworkReply::NetworkError)));
connect(mReply, SIGNAL(finished()), this, SLOT(onFinished()));
connect(mReply, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
mPrevTime = 0;
mPacketSamples = 0;
}
void AaroniaRTSAWorker::onConnected()
{
m_webSocket.sendTextMessage("SET auth t=rtsa p=#");
}
void AaroniaRTSAWorker::onDisconnected()
{
qDebug("AaroniaRTSAWorker::onDisconnected");
m_status = 4;
emit updateStatus(4);
}
void AaroniaRTSAWorker::onSocketError(QAbstractSocket::SocketError error)
{
(void) error;
m_status = 3;
emit updateStatus(3);
}
void AaroniaRTSAWorker::sendCenterFrequency()
{
//if (!m_webSocket.isValid())
// return;
/*QString freq = QString::number(m_centerFrequency / 1000.0, 'f', 3);
int bw = (m_sampleRate/2) - 20;
QString msg = QString("SET mod=iq low_cut=-%1 high_cut=%2 freq=%3").arg(bw).arg(bw).arg(freq);
m_webSocket.sendTextMessage(msg);*/
//mNetworkAccessManager->put()
}
void AaroniaRTSAWorker::sendGain()
{
if (!m_webSocket.isValid())
return;
QString msg("SET agc=");
msg.append(m_useAGC ? "1" : "0");
msg.append(" hang=0 thresh=-130 slope=6 decay=1000 manGain=");
msg.append(QString::number(m_gain));
m_webSocket.sendTextMessage(msg);
}
void AaroniaRTSAWorker::onBinaryMessageReceived(const QByteArray &message)
{
if (message[0] == 'M' && message[1] == 'S' && message[2] == 'G')
{
QStringList al = QString::fromUtf8(message).split(' ');
if ((al.size() > 2) && al[2].startsWith("audio_rate="))
{
QStringList rateKeyVal = al[2].split('=');
if (rateKeyVal.size() > 1)
{
bool ok;
int sampleRate = rateKeyVal[1].toInt(&ok);
if (ok) {
m_sampleRate = sampleRate;
}
qDebug("AaroniaRTSAWorker::onBinaryMessageReceived: sample rate: %d", m_sampleRate);
if (m_inputMessageQueue) {
m_inputMessageQueue->push(MsgReportSampleRate::create(m_sampleRate));
}
QString msg = QString("SET AR OK in=%1 out=48000").arg(m_sampleRate);
m_webSocket.sendTextMessage(msg);
m_webSocket.sendTextMessage("SERVER DE CLIENT RtsaAngel SND");
sendGain();
sendCenterFrequency();
m_timer.start(5000);
m_status = 2;
emit updateStatus(2);
}
}
}
else if (message[0] == 'S' && message[1] == 'N' && message[2] == 'D')
{
int dataOffset = 20;
int sampleCount = 512;
const int16_t* messageSamples = (const int16_t*)(message.constData() + dataOffset);
m_samplesBuf.clear();
for (int i = 0; i < sampleCount; i++)
{
m_samplesBuf.push_back(Sample(
boost::endian::endian_reverse(messageSamples[i * 2]) << (SDR_RX_SAMP_SZ - 16),
boost::endian::endian_reverse(messageSamples[i * 2 + 1]) << (SDR_RX_SAMP_SZ - 16)
));
}
m_sampleFifo->write(m_samplesBuf.begin(), m_samplesBuf.end());
}
}
void AaroniaRTSAWorker::onCenterFrequencyChanged(quint64 centerFrequency)
{
if (m_centerFrequency == centerFrequency)
return;
m_centerFrequency = centerFrequency;
sendCenterFrequency();
}
void AaroniaRTSAWorker::onGainChanged(quint32 gain, bool useAGC)
{
if (m_gain == gain && m_useAGC == useAGC)
return;
m_gain = gain;
m_useAGC = useAGC;
sendGain();
}
void AaroniaRTSAWorker::onServerAddressChanged(QString serverAddress)
{
/*if (m_serverAddress == serverAddress) {
return;
}
m_serverAddress = serverAddress;
m_status = 1;
emit updateStatus(1);
QString url("ws://");
url.append(m_serverAddress);
url.append("/rtsa/");
url.append(QString::number(QDateTime::currentMSecsSinceEpoch()));
url.append("/SND");
m_webSocket.open(QUrl(url));*/
}
void AaroniaRTSAWorker::tick()
{
//m_webSocket.sendTextMessage("SET keepalive");
}
/**************************CPY ********************************* */
void AaroniaRTSAWorker::onError(QNetworkReply::NetworkError code)
{
QTextStream qerr(stderr);
qerr << "Network Error: " + mReply->errorString();
}
void AaroniaRTSAWorker::onFinished()
{
QTextStream qerr(stderr);
qerr << "Finished: " + mReply->errorString();
mBuffer.append(mReply->readAll());
mReply->deleteLater();
mReply = nullptr;
}
// bytes received from the socket
void AaroniaRTSAWorker::onReadyRead()
{
QTextStream qout(stdout);
// read as many bytes as possible into input buffer
qint64 n = mReply->bytesAvailable();
qint64 bs = mBuffer.size();
mBuffer.resize(bs + n);
qint64 done = mReply->read(mBuffer.data() + bs, n);
mBuffer.resize(bs + done);
// intialize parsing
int offset = 0;
int avail = mBuffer.size();
// cosume all input data if possible
while (offset < avail)
{
// any samples so far (not looking for meta data)
if (mPacketSamples)
{
// enough samples
if (offset + mPacketSamples * 2 * sizeof(float) <= avail)
{
// do something with the IQ data
const float * sp = (const float * )(mBuffer.constData() + offset);
SampleVector::iterator it = m_convertBuffer.begin();
m_decimatorsFloatIQ.decimate1(&it, sp, 2*mPacketSamples);
/*m_samplesBuf.clear();
for (int i = 0; i < mPacketSamples*2; i+=2)
{
m_samplesBuf.push_back(Sample(
sp[i] << (SDR_RX_SAMP_SZ - 8),
sp[i+1] << (SDR_RX_SAMP_SZ - 8)
));
}*/
//m_sampleFifo->write(m_samplesBuf.begin(), m_samplesBuf.end());
m_sampleFifo->write(m_convertBuffer.begin(), it);
// qout << "IQ " << sp[0] << ", " << sp[1] << "\n";
//m_sampleFifo->write()
// consume all samples from the input buffer
offset += mPacketSamples * 2 * sizeof(float);
mPacketSamples = 0;
}
else
break;
}
else
{
// is there a complete JSON metadata object in the buffer
int split = mBuffer.indexOf('\x1e', offset);
if (split != -1)
{
// Extract it
QByteArray data = mBuffer.mid(offset, split - offset);
offset = split + 1;
// Parse the JSON data
QJsonParseError error;
QJsonDocument jdoc = QJsonDocument::fromJson(data, &error);
if (error.error == QJsonParseError::NoError)
{
// Extract fields of interest
//double startTime = jdoc["startTime"].toDouble(), endTime = jdoc["endTime"].toDouble();
int samples = jdoc["samples"].toInt();
// Dump packet loss
//if (startTime != mPrevTime)
// qout << QDateTime::fromMSecsSinceEpoch(startTime * 1000).toString() << " D " << endTime - startTime << " O " << startTime - mPrevTime << " S " << samples << " L " << QDateTime::currentMSecsSinceEpoch() / 1000.0 - startTime << "\n";
// Switch to data phase
//mPrevTime = endTime;
mPacketSamples = samples;
}
else
{
QTextStream qerr(stderr);
qerr << "Json Parse Error: " + error.errorString();
}
}
else
break;
}
}
// Remove consumed data from the buffer
mBuffer.remove(0, offset);
}

View File

@ -0,0 +1,133 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Vort //
// //
// 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 _AARONIARTSA_AARONIARTSAWORKER_H_
#define _AARONIARTSA_AARONIARTSAWORKER_H_
#include <QTimer>
#include <QtWebSockets/QtWebSockets>
#include "dsp/samplesinkfifo.h"
#include "util/message.h"
#include <QProcess>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QTimer>
#include <QJsonDocument>
#include <QObject>
#include "dsp/decimatorsfi.h"
class MessageQueue;
class AaroniaRTSAWorker : public QObject {
Q_OBJECT
public:
class MsgReportSampleRate : public Message {
MESSAGE_CLASS_DECLARATION
public:
int getSampleRate() const { return m_sampleRate; }
static MsgReportSampleRate* create(int sampleRate) {
return new MsgReportSampleRate(sampleRate);
}
private:
int m_sampleRate;
MsgReportSampleRate(int sampleRate) :
Message(),
m_sampleRate(sampleRate)
{ }
};
AaroniaRTSAWorker(SampleSinkFifo* sampleFifo);
int getStatus() const { return m_status; }
void setInputMessageQueue(MessageQueue *messageQueue) { m_inputMessageQueue = messageQueue; }
private:
QTimer m_timer;
QWebSocket m_webSocket;
SampleVector m_samplesBuf;
SampleSinkFifo* m_sampleFifo;
QString m_serverAddress;
uint64_t m_centerFrequency;
int m_sampleRate;
MessageQueue *m_inputMessageQueue;
uint32_t m_gain;
bool m_useAGC;
int m_status; //!< See GUI for status number detail
void sendCenterFrequency();
void sendGain();
// QT htttp client
QNetworkAccessManager * mNetworkAccessManager;
// Reply from the HTTP server
QNetworkReply * mReply;
// Input buffer
QByteArray mBuffer;
// Number of IQ sample pairs in the current packet
int mPacketSamples;
// Previous sample end time to check for packet loss
double mPrevTime;
//Decimators<qint32, float, SDR_RX_SAMP_SZ, 32, true> m_decimatorsIQ;
DecimatorsFI<true> m_decimatorsFloatIQ;
SampleVector m_convertBuffer;
//void workIQ(unsigned int n_items);
signals:
void updateStatus(int status);
public slots:
void onCenterFrequencyChanged(quint64 centerFrequency);
void onServerAddressChanged(QString serverAddress);
void onGainChanged(quint32 gain, bool useAGC);
private slots:
void onConnected();
void onDisconnected();
void onBinaryMessageReceived(const QByteArray &message);
void onSocketError(QAbstractSocket::SocketError error);
void onError(QNetworkReply::NetworkError code);
void onFinished(void);
void onReadyRead(void);
void tick();
};
#endif // _AARONIARTSA_AARONIARTSAWORKER_H_

View File

@ -0,0 +1,5 @@
<h1>AaroniaRTSA input plugin</h1>
<h2>Introduction</h2>
tbd

View File

@ -55,7 +55,7 @@ private:
int m_fcPos;
bool m_iqOrder;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimatorsIQ;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, true> m_decimatorsIQ;
Decimators<qint32, qint16, SDR_RX_SAMP_SZ, 12, false> m_decimatorsQI;
void run();

View File

@ -2097,6 +2097,51 @@ margin-bottom: 20px;
}
},
"description" : "ATVMod"
};
defs.AaroniaRTSAReport = {
"properties" : {
"status" : {
"type" : "integer",
"description" : "0 for Idle, 1 for Connecting, 2 for Connected, 3 for Error, 4 for Disconnected"
}
},
"description" : "AaroniaRTSA"
};
defs.AaroniaRTSASettings = {
"properties" : {
"gain" : {
"type" : "integer"
},
"useAGC" : {
"type" : "integer",
"description" : "AGC active (1 for yes, 0 for no)"
},
"dcBlock" : {
"type" : "integer"
},
"centerFrequency" : {
"type" : "integer",
"format" : "int64"
},
"serverAddress" : {
"type" : "string",
"description" : "Distant AaroniaRTSA instance URL or IPv4 address with port"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
}
},
"description" : "AaroniaRTSA"
};
defs.AirspyHFReport = {
"properties" : {
@ -3538,9 +3583,6 @@ margin-bottom: 20px;
"HeatMapReport" : {
"$ref" : "#/definitions/HeatMapReport"
},
"ILSDemodReport" : {
"$ref" : "#/definitions/ILSDemodReport"
},
"M17DemodReport" : {
"$ref" : "#/definitions/M17DemodReport"
},
@ -3705,9 +3747,6 @@ margin-bottom: 20px;
"HeatMapSettings" : {
"$ref" : "#/definitions/HeatMapSettings"
},
"ILSDemodSettings" : {
"$ref" : "#/definitions/ILSDemodSettings"
},
"InterferometerSettings" : {
"$ref" : "#/definitions/InterferometerSettings"
},
@ -5205,6 +5244,9 @@ margin-bottom: 20px;
},
"xtrxMIMOReport" : {
"$ref" : "#/definitions/XtrxMIMOReport"
},
"aaroniaSDRReport" : {
"$ref" : "#/definitions/AaroniaRTSAReport"
}
},
"description" : "Base device report. Only the device report corresponding to the device specified in the deviceHwType is or should be present."
@ -5393,6 +5435,9 @@ margin-bottom: 20px;
},
"xtrxMIMOSettings" : {
"$ref" : "#/definitions/XtrxMIMOSettings"
},
"aaroniaRTSASettings" : {
"$ref" : "#/definitions/AaroniaRTSASettings"
}
},
"description" : "Base device settings. Only the device settings corresponding to the device specified in the deviceHwType field is or should be present."
@ -7413,143 +7458,6 @@ margin-bottom: 20px;
}
},
"description" : "IEEE_802_15_4_Mod"
};
defs.ILSDemodReport = {
"properties" : {
"channelPowerDB" : {
"type" : "number",
"format" : "float",
"description" : "power received in channel (dB)"
},
"channelSampleRate" : {
"type" : "integer"
}
},
"description" : "ILSDemod"
};
defs.ILSDemodSettings = {
"properties" : {
"inputFrequencyOffset" : {
"type" : "integer",
"format" : "int64"
},
"rfBandwidth" : {
"type" : "number",
"format" : "float"
},
"mode" : {
"type" : "integer",
"description" : "(0 for LOC, 1 for G/S)"
},
"frequencyIndex" : {
"type" : "integer"
},
"squelch" : {
"type" : "integer"
},
"volume" : {
"type" : "number",
"format" : "float"
},
"audioMute" : {
"type" : "integer"
},
"average" : {
"type" : "integer"
},
"ddmUnits" : {
"type" : "integer"
},
"identThreshold" : {
"type" : "number",
"format" : "float"
},
"ident" : {
"type" : "string"
},
"runway" : {
"type" : "string"
},
"trueBearing" : {
"type" : "number",
"format" : "float"
},
"latitude" : {
"type" : "string"
},
"longitude" : {
"type" : "string"
},
"elevation" : {
"type" : "integer"
},
"glidePath" : {
"type" : "number",
"format" : "float"
},
"refHeight" : {
"type" : "number",
"format" : "float"
},
"courseWidth" : {
"type" : "number",
"format" : "float"
},
"udpEnabled" : {
"type" : "integer",
"description" : "Whether to forward DDM to specified UDP port"
},
"udpAddress" : {
"type" : "string",
"description" : "UDP address to forward DDM to"
},
"udpPort" : {
"type" : "integer",
"description" : "UDP port to forward DDM to"
},
"logFilename" : {
"type" : "string"
},
"logEnabled" : {
"type" : "integer"
},
"rgbColor" : {
"type" : "integer"
},
"title" : {
"type" : "string"
},
"streamIndex" : {
"type" : "integer",
"description" : "MIMO channel. Not relevant when connected to SI (single Rx)."
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
},
"reverseAPIChannelIndex" : {
"type" : "integer"
},
"scopeConfig" : {
"$ref" : "#/definitions/GLScope"
},
"channelMarker" : {
"$ref" : "#/definitions/ChannelMarker"
},
"rollupState" : {
"$ref" : "#/definitions/RollupState"
}
},
"description" : "ILSDemod"
};
defs.InstanceChannelsResponse = {
"required" : [ "channelcount" ],
@ -9209,7 +9117,7 @@ margin-bottom: 20px;
},
"altitudeReference" : {
"type" : "integer",
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND."
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND"
},
"animations" : {
"type" : "array",
@ -9258,14 +9166,6 @@ margin-bottom: 20px;
"availableUntil" : {
"type" : "string",
"description" : "Date and time until after which this item should no longer appear on 3D map"
},
"colorValid" : {
"type" : "integer",
"description" : "0 - Use default color, 1 - Use specified color"
},
"color" : {
"type" : "integer",
"description" : "RGBA for polygon and polyline"
}
},
"description" : "An item to draw on the map. Set image to an empty string to remove item from the map."
@ -9368,7 +9268,7 @@ margin-bottom: 20px;
},
"altitudeReference" : {
"type" : "integer",
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND."
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND"
},
"animations" : {
"type" : "array",
@ -9417,14 +9317,6 @@ margin-bottom: 20px;
"availableUntil" : {
"type" : "string",
"description" : "Date and time until after which this item should no longer appear on 3D map"
},
"colorValid" : {
"type" : "integer",
"description" : "0 - Use default color, 1 - Use specified color"
},
"color" : {
"type" : "integer",
"description" : "RGBA for polygon and polyline"
}
},
"description" : "An item to draw on the map. Set image to an empty string to remove item from the map."
@ -9444,10 +9336,6 @@ margin-bottom: 20px;
"type" : "integer",
"description" : "Display object names on the map (1 for yes, 0 for no)"
},
"terrain" : {
"type" : "string",
"description" : "Terrain used for 3D map (E.g: 'Ellipsoid' or 'Cesium World Terrain')"
},
"title" : {
"type" : "string"
},
@ -13615,54 +13503,6 @@ margin-bottom: 20px;
"audioDeviceName" : {
"type" : "string"
},
"gpioControl" : {
"type" : "integer",
"description" : "GPIO control\n * 0 - No GPIO control\n * 1 - Rx side controls GPIO\n * 2 - Tx side controls GPIO\n"
},
"rx2txGPIOEnable" : {
"type" : "integer",
"description" : "Enable Rx to Tx GPIO control\n * 0 - disable\n * 1 - enable\n"
},
"rx2txGPIOMask" : {
"type" : "integer",
"format" : "int8",
"description" : "Rx to Tx change GPIO mask"
},
"rx2txGPIOValues" : {
"type" : "integer",
"format" : "int8",
"description" : "Rx to Tx change GPIO values"
},
"rx2txCommandEnable" : {
"type" : "integer",
"description" : "Enable Rx to Tx command\n * 0 - disable\n * 1 - enable\n"
},
"rx2txCommand" : {
"type" : "string",
"description" : "Command to be executed when Rx switches to Tx"
},
"tx2rxGPIOEnable" : {
"type" : "integer",
"description" : "Enable Tx to Rx GPIO control\n * 0 - disable\n * 1 - enable\n"
},
"tx2rxGPIOMask" : {
"type" : "integer",
"format" : "int8",
"description" : "Tx to Rx change GPIO mask"
},
"tx2rxGPIOValues" : {
"type" : "integer",
"format" : "int8",
"description" : "Tx to Rx change GPIO values"
},
"tx2rxCommandEnable" : {
"type" : "integer",
"description" : "Enable Tx to Rx command\n * 0 - disable\n * 1 - enable\n"
},
"tx2rxCommand" : {
"type" : "string",
"description" : "Command to be executed when Tx switches to Rx"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
@ -57471,7 +57311,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2023-04-01T18:43:55.658+02:00
Generated 2023-03-11T14:00:49.111+01:00
</div>
</div>
</div>

View File

@ -0,0 +1,32 @@
AaroniaRTSASettings:
description: AaroniaRTSA
properties:
gain:
type: integer
useAGC:
description: AGC active (1 for yes, 0 for no)
type: integer
dcBlock:
type: integer
centerFrequency:
type: integer
format: int64
serverAddress:
description: Distant AaroniaRTSA instance URL or IPv4 address with port
type: string
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer
AaroniaRTSAReport:
description: AaroniaRTSA
properties:
status:
description: 0 for Idle, 1 for Connecting, 2 for Connected, 3 for Error, 4 for Disconnected
type: integer

View File

@ -71,3 +71,5 @@ DeviceReport:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxOutputReport"
xtrxMIMOReport:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxMIMOReport"
aaroniaSDRReport:
$ref: "/doc/swagger/include/AaroniaRTSA.yaml#/AaroniaRTSAReport"

View File

@ -100,3 +100,5 @@ DeviceSettings:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxOutputSettings"
xtrxMIMOSettings:
$ref: "/doc/swagger/include/Xtrx.yaml#/XtrxMIMOSettings"
aaroniaRTSASettings:
$ref: "/doc/swagger/include/AaroniaRTSA.yaml#/AaroniaRTSASettings"

View File

@ -18,7 +18,7 @@ EOF
branch_name="sdrangel"
clone_label=$(date)
image_tag="latest"
uid=$(id -u)
uid=1000
docker_file="."
while getopts "h?b:c:t:j:f:" opt; do

View File

@ -2,6 +2,7 @@ version: '3'
services:
swgcodegen:
image: "sdrangel/swagger/codegen:${IMAGE_CODEGEN_VERSION}"
user: "1000:1000"
container_name: "sdrangel_swgcodegen"
volumes:
- "${SDRANGEL_BASE}:/opt/build/sdrangel:rw"
@ -12,6 +13,7 @@ services:
tty: true
swgserver:
image: "sdrangel/swagger/server:${IMAGE_SERVER_VERSION}"
user: "1000:1000"
container_name: "sdrangel_swgserver"
volumes:
- "${SDRANGEL_BASE}:/opt/build/sdrangel:rw"

View File

@ -51,4 +51,4 @@ export IMAGE_CODEGEN_VERSION=${image_tag_codegen}
export IMAGE_SERVER_VERSION=${image_tag_server}
export SDRANGEL_BASE=${sdrangel_codebase}
docker-compose -f compose.yml ${stack_name} ${action}
docker compose -f compose.yml ${stack_name} ${action}

View File

@ -15,7 +15,7 @@ EOF
image_name="sdrangel/swagger/server"
image_tag="latest"
uid=$(id -u)
uid=1000
docker_file="."
while getopts "h?t:f:" opt; do

View File

@ -0,0 +1,32 @@
AaroniaRTSASettings:
description: AaroniaRTSA
properties:
gain:
type: integer
useAGC:
description: AGC active (1 for yes, 0 for no)
type: integer
dcBlock:
type: integer
centerFrequency:
type: integer
format: int64
serverAddress:
description: Distant AaroniaRTSA instance URL or IPv4 address with port
type: string
useReverseAPI:
description: Synchronize with reverse API (1 for yes, 0 for no)
type: integer
reverseAPIAddress:
type: string
reverseAPIPort:
type: integer
reverseAPIDeviceIndex:
type: integer
AaroniaRTSAReport:
description: AaroniaRTSA
properties:
status:
description: 0 for Idle, 1 for Connecting, 2 for Connected, 3 for Error, 4 for Disconnected
type: integer

View File

@ -71,3 +71,5 @@ DeviceReport:
$ref: "http://swgserver:8081/api/swagger/include/Xtrx.yaml#/XtrxOutputReport"
xtrxMIMOReport:
$ref: "http://swgserver:8081/api/swagger/include/Xtrx.yaml#/XtrxMIMOReport"
aaroniaSDRReport:
$ref: "http://swgserver:8081/api/swagger/include/AaroniaRTSA.yaml#/AaroniaRTSAReport"

View File

@ -100,3 +100,5 @@ DeviceSettings:
$ref: "http://swgserver:8081/api/swagger/include/Xtrx.yaml#/XtrxOutputSettings"
xtrxMIMOSettings:
$ref: "http://swgserver:8081/api/swagger/include/Xtrx.yaml#/XtrxMIMOSettings"
aaroniaRTSASettings:
$ref: "http://swgserver:8081/api/swagger/include/AaroniaRTSA.yaml#/AaroniaRTSASettings"

View File

@ -2097,6 +2097,51 @@ margin-bottom: 20px;
}
},
"description" : "ATVMod"
};
defs.AaroniaRTSAReport = {
"properties" : {
"status" : {
"type" : "integer",
"description" : "0 for Idle, 1 for Connecting, 2 for Connected, 3 for Error, 4 for Disconnected"
}
},
"description" : "AaroniaRTSA"
};
defs.AaroniaRTSASettings = {
"properties" : {
"gain" : {
"type" : "integer"
},
"useAGC" : {
"type" : "integer",
"description" : "AGC active (1 for yes, 0 for no)"
},
"dcBlock" : {
"type" : "integer"
},
"centerFrequency" : {
"type" : "integer",
"format" : "int64"
},
"serverAddress" : {
"type" : "string",
"description" : "Distant AaroniaRTSA instance URL or IPv4 address with port"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
}
},
"description" : "AaroniaRTSA"
};
defs.AirspyHFReport = {
"properties" : {
@ -3538,9 +3583,6 @@ margin-bottom: 20px;
"HeatMapReport" : {
"$ref" : "#/definitions/HeatMapReport"
},
"ILSDemodReport" : {
"$ref" : "#/definitions/ILSDemodReport"
},
"M17DemodReport" : {
"$ref" : "#/definitions/M17DemodReport"
},
@ -3705,9 +3747,6 @@ margin-bottom: 20px;
"HeatMapSettings" : {
"$ref" : "#/definitions/HeatMapSettings"
},
"ILSDemodSettings" : {
"$ref" : "#/definitions/ILSDemodSettings"
},
"InterferometerSettings" : {
"$ref" : "#/definitions/InterferometerSettings"
},
@ -5205,6 +5244,9 @@ margin-bottom: 20px;
},
"xtrxMIMOReport" : {
"$ref" : "#/definitions/XtrxMIMOReport"
},
"aaroniaSDRReport" : {
"$ref" : "#/definitions/AaroniaRTSAReport"
}
},
"description" : "Base device report. Only the device report corresponding to the device specified in the deviceHwType is or should be present."
@ -5393,6 +5435,9 @@ margin-bottom: 20px;
},
"xtrxMIMOSettings" : {
"$ref" : "#/definitions/XtrxMIMOSettings"
},
"aaroniaRTSASettings" : {
"$ref" : "#/definitions/AaroniaRTSASettings"
}
},
"description" : "Base device settings. Only the device settings corresponding to the device specified in the deviceHwType field is or should be present."
@ -7413,143 +7458,6 @@ margin-bottom: 20px;
}
},
"description" : "IEEE_802_15_4_Mod"
};
defs.ILSDemodReport = {
"properties" : {
"channelPowerDB" : {
"type" : "number",
"format" : "float",
"description" : "power received in channel (dB)"
},
"channelSampleRate" : {
"type" : "integer"
}
},
"description" : "ILSDemod"
};
defs.ILSDemodSettings = {
"properties" : {
"inputFrequencyOffset" : {
"type" : "integer",
"format" : "int64"
},
"rfBandwidth" : {
"type" : "number",
"format" : "float"
},
"mode" : {
"type" : "integer",
"description" : "(0 for LOC, 1 for G/S)"
},
"frequencyIndex" : {
"type" : "integer"
},
"squelch" : {
"type" : "integer"
},
"volume" : {
"type" : "number",
"format" : "float"
},
"audioMute" : {
"type" : "integer"
},
"average" : {
"type" : "integer"
},
"ddmUnits" : {
"type" : "integer"
},
"identThreshold" : {
"type" : "number",
"format" : "float"
},
"ident" : {
"type" : "string"
},
"runway" : {
"type" : "string"
},
"trueBearing" : {
"type" : "number",
"format" : "float"
},
"latitude" : {
"type" : "string"
},
"longitude" : {
"type" : "string"
},
"elevation" : {
"type" : "integer"
},
"glidePath" : {
"type" : "number",
"format" : "float"
},
"refHeight" : {
"type" : "number",
"format" : "float"
},
"courseWidth" : {
"type" : "number",
"format" : "float"
},
"udpEnabled" : {
"type" : "integer",
"description" : "Whether to forward DDM to specified UDP port"
},
"udpAddress" : {
"type" : "string",
"description" : "UDP address to forward DDM to"
},
"udpPort" : {
"type" : "integer",
"description" : "UDP port to forward DDM to"
},
"logFilename" : {
"type" : "string"
},
"logEnabled" : {
"type" : "integer"
},
"rgbColor" : {
"type" : "integer"
},
"title" : {
"type" : "string"
},
"streamIndex" : {
"type" : "integer",
"description" : "MIMO channel. Not relevant when connected to SI (single Rx)."
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
},
"reverseAPIAddress" : {
"type" : "string"
},
"reverseAPIPort" : {
"type" : "integer"
},
"reverseAPIDeviceIndex" : {
"type" : "integer"
},
"reverseAPIChannelIndex" : {
"type" : "integer"
},
"scopeConfig" : {
"$ref" : "#/definitions/GLScope"
},
"channelMarker" : {
"$ref" : "#/definitions/ChannelMarker"
},
"rollupState" : {
"$ref" : "#/definitions/RollupState"
}
},
"description" : "ILSDemod"
};
defs.InstanceChannelsResponse = {
"required" : [ "channelcount" ],
@ -9209,7 +9117,7 @@ margin-bottom: 20px;
},
"altitudeReference" : {
"type" : "integer",
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND."
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND"
},
"animations" : {
"type" : "array",
@ -9258,14 +9166,6 @@ margin-bottom: 20px;
"availableUntil" : {
"type" : "string",
"description" : "Date and time until after which this item should no longer appear on 3D map"
},
"colorValid" : {
"type" : "integer",
"description" : "0 - Use default color, 1 - Use specified color"
},
"color" : {
"type" : "integer",
"description" : "RGBA for polygon and polyline"
}
},
"description" : "An item to draw on the map. Set image to an empty string to remove item from the map."
@ -9368,7 +9268,7 @@ margin-bottom: 20px;
},
"altitudeReference" : {
"type" : "integer",
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND."
"description" : "0 - NONE (Absolute), 1 - CLAMP_TO_GROUND, 2 - RELATIVE_TO_GROUND, 3 - CLIP_TO_GROUND"
},
"animations" : {
"type" : "array",
@ -9417,14 +9317,6 @@ margin-bottom: 20px;
"availableUntil" : {
"type" : "string",
"description" : "Date and time until after which this item should no longer appear on 3D map"
},
"colorValid" : {
"type" : "integer",
"description" : "0 - Use default color, 1 - Use specified color"
},
"color" : {
"type" : "integer",
"description" : "RGBA for polygon and polyline"
}
},
"description" : "An item to draw on the map. Set image to an empty string to remove item from the map."
@ -9444,10 +9336,6 @@ margin-bottom: 20px;
"type" : "integer",
"description" : "Display object names on the map (1 for yes, 0 for no)"
},
"terrain" : {
"type" : "string",
"description" : "Terrain used for 3D map (E.g: 'Ellipsoid' or 'Cesium World Terrain')"
},
"title" : {
"type" : "string"
},
@ -13615,54 +13503,6 @@ margin-bottom: 20px;
"audioDeviceName" : {
"type" : "string"
},
"gpioControl" : {
"type" : "integer",
"description" : "GPIO control\n * 0 - No GPIO control\n * 1 - Rx side controls GPIO\n * 2 - Tx side controls GPIO\n"
},
"rx2txGPIOEnable" : {
"type" : "integer",
"description" : "Enable Rx to Tx GPIO control\n * 0 - disable\n * 1 - enable\n"
},
"rx2txGPIOMask" : {
"type" : "integer",
"format" : "int8",
"description" : "Rx to Tx change GPIO mask"
},
"rx2txGPIOValues" : {
"type" : "integer",
"format" : "int8",
"description" : "Rx to Tx change GPIO values"
},
"rx2txCommandEnable" : {
"type" : "integer",
"description" : "Enable Rx to Tx command\n * 0 - disable\n * 1 - enable\n"
},
"rx2txCommand" : {
"type" : "string",
"description" : "Command to be executed when Rx switches to Tx"
},
"tx2rxGPIOEnable" : {
"type" : "integer",
"description" : "Enable Tx to Rx GPIO control\n * 0 - disable\n * 1 - enable\n"
},
"tx2rxGPIOMask" : {
"type" : "integer",
"format" : "int8",
"description" : "Tx to Rx change GPIO mask"
},
"tx2rxGPIOValues" : {
"type" : "integer",
"format" : "int8",
"description" : "Tx to Rx change GPIO values"
},
"tx2rxCommandEnable" : {
"type" : "integer",
"description" : "Enable Tx to Rx command\n * 0 - disable\n * 1 - enable\n"
},
"tx2rxCommand" : {
"type" : "string",
"description" : "Command to be executed when Tx switches to Rx"
},
"useReverseAPI" : {
"type" : "integer",
"description" : "Synchronize with reverse API (1 for yes, 0 for no)"
@ -57471,7 +57311,7 @@ except ApiException as e:
</div>
<div id="generator">
<div class="content">
Generated 2023-04-01T18:43:55.658+02:00
Generated 2023-03-11T14:00:49.111+01:00
</div>
</div>
</div>

View File

@ -0,0 +1,108 @@
/**
* 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 "SWGAaroniaRTSAReport.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGAaroniaRTSAReport::SWGAaroniaRTSAReport(QString* json) {
init();
this->fromJson(*json);
}
SWGAaroniaRTSAReport::SWGAaroniaRTSAReport() {
status = 0;
m_status_isSet = false;
}
SWGAaroniaRTSAReport::~SWGAaroniaRTSAReport() {
this->cleanup();
}
void
SWGAaroniaRTSAReport::init() {
status = 0;
m_status_isSet = false;
}
void
SWGAaroniaRTSAReport::cleanup() {
}
SWGAaroniaRTSAReport*
SWGAaroniaRTSAReport::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGAaroniaRTSAReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&status, pJson["status"], "qint32", "");
}
QString
SWGAaroniaRTSAReport::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGAaroniaRTSAReport::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_status_isSet){
obj->insert("status", QJsonValue(status));
}
return obj;
}
qint32
SWGAaroniaRTSAReport::getStatus() {
return status;
}
void
SWGAaroniaRTSAReport::setStatus(qint32 status) {
this->status = status;
this->m_status_isSet = true;
}
bool
SWGAaroniaRTSAReport::isSet(){
bool isObjectUpdated = false;
do{
if(m_status_isSet){
isObjectUpdated = true; break;
}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,58 @@
/**
* 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.
*/
/*
* SWGAaroniaRTSAReport.h
*
* AaroniaRTSA
*/
#ifndef SWGAaroniaRTSAReport_H_
#define SWGAaroniaRTSAReport_H_
#include <QJsonObject>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGAaroniaRTSAReport: public SWGObject {
public:
SWGAaroniaRTSAReport();
SWGAaroniaRTSAReport(QString* json);
virtual ~SWGAaroniaRTSAReport();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGAaroniaRTSAReport* fromJson(QString &jsonString) override;
qint32 getStatus();
void setStatus(qint32 status);
virtual bool isSet() override;
private:
qint32 status;
bool m_status_isSet;
};
}
#endif /* SWGAaroniaRTSAReport_H_ */

View File

@ -0,0 +1,296 @@
/**
* 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 "SWGAaroniaRTSASettings.h"
#include "SWGHelpers.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QObject>
#include <QDebug>
namespace SWGSDRangel {
SWGAaroniaRTSASettings::SWGAaroniaRTSASettings(QString* json) {
init();
this->fromJson(*json);
}
SWGAaroniaRTSASettings::SWGAaroniaRTSASettings() {
gain = 0;
m_gain_isSet = false;
use_agc = 0;
m_use_agc_isSet = false;
dc_block = 0;
m_dc_block_isSet = false;
center_frequency = 0L;
m_center_frequency_isSet = false;
server_address = nullptr;
m_server_address_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;
}
SWGAaroniaRTSASettings::~SWGAaroniaRTSASettings() {
this->cleanup();
}
void
SWGAaroniaRTSASettings::init() {
gain = 0;
m_gain_isSet = false;
use_agc = 0;
m_use_agc_isSet = false;
dc_block = 0;
m_dc_block_isSet = false;
center_frequency = 0L;
m_center_frequency_isSet = false;
server_address = new QString("");
m_server_address_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;
}
void
SWGAaroniaRTSASettings::cleanup() {
if(server_address != nullptr) {
delete server_address;
}
if(reverse_api_address != nullptr) {
delete reverse_api_address;
}
}
SWGAaroniaRTSASettings*
SWGAaroniaRTSASettings::fromJson(QString &json) {
QByteArray array (json.toStdString().c_str());
QJsonDocument doc = QJsonDocument::fromJson(array);
QJsonObject jsonObject = doc.object();
this->fromJsonObject(jsonObject);
return this;
}
void
SWGAaroniaRTSASettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&gain, pJson["gain"], "qint32", "");
::SWGSDRangel::setValue(&use_agc, pJson["useAGC"], "qint32", "");
::SWGSDRangel::setValue(&dc_block, pJson["dcBlock"], "qint32", "");
::SWGSDRangel::setValue(&center_frequency, pJson["centerFrequency"], "qint64", "");
::SWGSDRangel::setValue(&server_address, pJson["serverAddress"], "QString", "QString");
::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", "");
}
QString
SWGAaroniaRTSASettings::asJson ()
{
QJsonObject* obj = this->asJsonObject();
QJsonDocument doc(*obj);
QByteArray bytes = doc.toJson();
delete obj;
return QString(bytes);
}
QJsonObject*
SWGAaroniaRTSASettings::asJsonObject() {
QJsonObject* obj = new QJsonObject();
if(m_gain_isSet){
obj->insert("gain", QJsonValue(gain));
}
if(m_use_agc_isSet){
obj->insert("useAGC", QJsonValue(use_agc));
}
if(m_dc_block_isSet){
obj->insert("dcBlock", QJsonValue(dc_block));
}
if(m_center_frequency_isSet){
obj->insert("centerFrequency", QJsonValue(center_frequency));
}
if(server_address != nullptr && *server_address != QString("")){
toJsonValue(QString("serverAddress"), server_address, obj, QString("QString"));
}
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));
}
return obj;
}
qint32
SWGAaroniaRTSASettings::getGain() {
return gain;
}
void
SWGAaroniaRTSASettings::setGain(qint32 gain) {
this->gain = gain;
this->m_gain_isSet = true;
}
qint32
SWGAaroniaRTSASettings::getUseAgc() {
return use_agc;
}
void
SWGAaroniaRTSASettings::setUseAgc(qint32 use_agc) {
this->use_agc = use_agc;
this->m_use_agc_isSet = true;
}
qint32
SWGAaroniaRTSASettings::getDcBlock() {
return dc_block;
}
void
SWGAaroniaRTSASettings::setDcBlock(qint32 dc_block) {
this->dc_block = dc_block;
this->m_dc_block_isSet = true;
}
qint64
SWGAaroniaRTSASettings::getCenterFrequency() {
return center_frequency;
}
void
SWGAaroniaRTSASettings::setCenterFrequency(qint64 center_frequency) {
this->center_frequency = center_frequency;
this->m_center_frequency_isSet = true;
}
QString*
SWGAaroniaRTSASettings::getServerAddress() {
return server_address;
}
void
SWGAaroniaRTSASettings::setServerAddress(QString* server_address) {
this->server_address = server_address;
this->m_server_address_isSet = true;
}
qint32
SWGAaroniaRTSASettings::getUseReverseApi() {
return use_reverse_api;
}
void
SWGAaroniaRTSASettings::setUseReverseApi(qint32 use_reverse_api) {
this->use_reverse_api = use_reverse_api;
this->m_use_reverse_api_isSet = true;
}
QString*
SWGAaroniaRTSASettings::getReverseApiAddress() {
return reverse_api_address;
}
void
SWGAaroniaRTSASettings::setReverseApiAddress(QString* reverse_api_address) {
this->reverse_api_address = reverse_api_address;
this->m_reverse_api_address_isSet = true;
}
qint32
SWGAaroniaRTSASettings::getReverseApiPort() {
return reverse_api_port;
}
void
SWGAaroniaRTSASettings::setReverseApiPort(qint32 reverse_api_port) {
this->reverse_api_port = reverse_api_port;
this->m_reverse_api_port_isSet = true;
}
qint32
SWGAaroniaRTSASettings::getReverseApiDeviceIndex() {
return reverse_api_device_index;
}
void
SWGAaroniaRTSASettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) {
this->reverse_api_device_index = reverse_api_device_index;
this->m_reverse_api_device_index_isSet = true;
}
bool
SWGAaroniaRTSASettings::isSet(){
bool isObjectUpdated = false;
do{
if(m_gain_isSet){
isObjectUpdated = true; break;
}
if(m_use_agc_isSet){
isObjectUpdated = true; break;
}
if(m_dc_block_isSet){
isObjectUpdated = true; break;
}
if(m_center_frequency_isSet){
isObjectUpdated = true; break;
}
if(server_address && *server_address != QString("")){
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;
}
}while(false);
return isObjectUpdated;
}
}

View File

@ -0,0 +1,107 @@
/**
* 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.
*/
/*
* SWGAaroniaRTSASettings.h
*
* AaroniaRTSA
*/
#ifndef SWGAaroniaRTSASettings_H_
#define SWGAaroniaRTSASettings_H_
#include <QJsonObject>
#include <QString>
#include "SWGObject.h"
#include "export.h"
namespace SWGSDRangel {
class SWG_API SWGAaroniaRTSASettings: public SWGObject {
public:
SWGAaroniaRTSASettings();
SWGAaroniaRTSASettings(QString* json);
virtual ~SWGAaroniaRTSASettings();
void init();
void cleanup();
virtual QString asJson () override;
virtual QJsonObject* asJsonObject() override;
virtual void fromJsonObject(QJsonObject &json) override;
virtual SWGAaroniaRTSASettings* fromJson(QString &jsonString) override;
qint32 getGain();
void setGain(qint32 gain);
qint32 getUseAgc();
void setUseAgc(qint32 use_agc);
qint32 getDcBlock();
void setDcBlock(qint32 dc_block);
qint64 getCenterFrequency();
void setCenterFrequency(qint64 center_frequency);
QString* getServerAddress();
void setServerAddress(QString* server_address);
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);
virtual bool isSet() override;
private:
qint32 gain;
bool m_gain_isSet;
qint32 use_agc;
bool m_use_agc_isSet;
qint32 dc_block;
bool m_dc_block_isSet;
qint64 center_frequency;
bool m_center_frequency_isSet;
QString* server_address;
bool m_server_address_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;
};
}
#endif /* SWGAaroniaRTSASettings_H_ */

View File

@ -92,6 +92,8 @@ SWGDeviceReport::SWGDeviceReport() {
m_xtrx_output_report_isSet = false;
xtrx_mimo_report = nullptr;
m_xtrx_mimo_report_isSet = false;
aaronia_sdr_report = nullptr;
m_aaronia_sdr_report_isSet = false;
}
SWGDeviceReport::~SWGDeviceReport() {
@ -164,6 +166,8 @@ SWGDeviceReport::init() {
m_xtrx_output_report_isSet = false;
xtrx_mimo_report = new SWGXtrxMIMOReport();
m_xtrx_mimo_report_isSet = false;
aaronia_sdr_report = new SWGAaroniaRTSAReport();
m_aaronia_sdr_report_isSet = false;
}
void
@ -262,6 +266,9 @@ SWGDeviceReport::cleanup() {
if(xtrx_mimo_report != nullptr) {
delete xtrx_mimo_report;
}
if(aaronia_sdr_report != nullptr) {
delete aaronia_sdr_report;
}
}
SWGDeviceReport*
@ -339,6 +346,8 @@ SWGDeviceReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&xtrx_mimo_report, pJson["xtrxMIMOReport"], "SWGXtrxMIMOReport", "SWGXtrxMIMOReport");
::SWGSDRangel::setValue(&aaronia_sdr_report, pJson["aaroniaSDRReport"], "SWGAaroniaRTSAReport", "SWGAaroniaRTSAReport");
}
QString
@ -451,6 +460,9 @@ SWGDeviceReport::asJsonObject() {
if((xtrx_mimo_report != nullptr) && (xtrx_mimo_report->isSet())){
toJsonValue(QString("xtrxMIMOReport"), xtrx_mimo_report, obj, QString("SWGXtrxMIMOReport"));
}
if((aaronia_sdr_report != nullptr) && (aaronia_sdr_report->isSet())){
toJsonValue(QString("aaroniaSDRReport"), aaronia_sdr_report, obj, QString("SWGAaroniaRTSAReport"));
}
return obj;
}
@ -775,6 +787,16 @@ SWGDeviceReport::setXtrxMimoReport(SWGXtrxMIMOReport* xtrx_mimo_report) {
this->m_xtrx_mimo_report_isSet = true;
}
SWGAaroniaRTSAReport*
SWGDeviceReport::getAaroniaSdrReport() {
return aaronia_sdr_report;
}
void
SWGDeviceReport::setAaroniaSdrReport(SWGAaroniaRTSAReport* aaronia_sdr_report) {
this->aaronia_sdr_report = aaronia_sdr_report;
this->m_aaronia_sdr_report_isSet = true;
}
bool
SWGDeviceReport::isSet(){
@ -876,6 +898,9 @@ SWGDeviceReport::isSet(){
if(xtrx_mimo_report && xtrx_mimo_report->isSet()){
isObjectUpdated = true; break;
}
if(aaronia_sdr_report && aaronia_sdr_report->isSet()){
isObjectUpdated = true; break;
}
}while(false);
return isObjectUpdated;
}

View File

@ -22,6 +22,7 @@
#include <QJsonObject>
#include "SWGAaroniaRTSAReport.h"
#include "SWGAirspyHFReport.h"
#include "SWGAirspyReport.h"
#include "SWGBladeRF2InputReport.h"
@ -167,6 +168,9 @@ public:
SWGXtrxMIMOReport* getXtrxMimoReport();
void setXtrxMimoReport(SWGXtrxMIMOReport* xtrx_mimo_report);
SWGAaroniaRTSAReport* getAaroniaSdrReport();
void setAaroniaSdrReport(SWGAaroniaRTSAReport* aaronia_sdr_report);
virtual bool isSet() override;
@ -267,6 +271,9 @@ private:
SWGXtrxMIMOReport* xtrx_mimo_report;
bool m_xtrx_mimo_report_isSet;
SWGAaroniaRTSAReport* aaronia_sdr_report;
bool m_aaronia_sdr_report_isSet;
};
}

View File

@ -120,6 +120,8 @@ SWGDeviceSettings::SWGDeviceSettings() {
m_xtrx_output_settings_isSet = false;
xtrx_mimo_settings = nullptr;
m_xtrx_mimo_settings_isSet = false;
aaronia_rtsa_settings = nullptr;
m_aaronia_rtsa_settings_isSet = false;
}
SWGDeviceSettings::~SWGDeviceSettings() {
@ -220,6 +222,8 @@ SWGDeviceSettings::init() {
m_xtrx_output_settings_isSet = false;
xtrx_mimo_settings = new SWGXtrxMIMOSettings();
m_xtrx_mimo_settings_isSet = false;
aaronia_rtsa_settings = new SWGAaroniaRTSASettings();
m_aaronia_rtsa_settings_isSet = false;
}
void
@ -358,6 +362,9 @@ SWGDeviceSettings::cleanup() {
if(xtrx_mimo_settings != nullptr) {
delete xtrx_mimo_settings;
}
if(aaronia_rtsa_settings != nullptr) {
delete aaronia_rtsa_settings;
}
}
SWGDeviceSettings*
@ -463,6 +470,8 @@ SWGDeviceSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&xtrx_mimo_settings, pJson["xtrxMIMOSettings"], "SWGXtrxMIMOSettings", "SWGXtrxMIMOSettings");
::SWGSDRangel::setValue(&aaronia_rtsa_settings, pJson["aaroniaRTSASettings"], "SWGAaroniaRTSASettings", "SWGAaroniaRTSASettings");
}
QString
@ -617,6 +626,9 @@ SWGDeviceSettings::asJsonObject() {
if((xtrx_mimo_settings != nullptr) && (xtrx_mimo_settings->isSet())){
toJsonValue(QString("xtrxMIMOSettings"), xtrx_mimo_settings, obj, QString("SWGXtrxMIMOSettings"));
}
if((aaronia_rtsa_settings != nullptr) && (aaronia_rtsa_settings->isSet())){
toJsonValue(QString("aaroniaRTSASettings"), aaronia_rtsa_settings, obj, QString("SWGAaroniaRTSASettings"));
}
return obj;
}
@ -1081,6 +1093,16 @@ SWGDeviceSettings::setXtrxMimoSettings(SWGXtrxMIMOSettings* xtrx_mimo_settings)
this->m_xtrx_mimo_settings_isSet = true;
}
SWGAaroniaRTSASettings*
SWGDeviceSettings::getAaroniaRtsaSettings() {
return aaronia_rtsa_settings;
}
void
SWGDeviceSettings::setAaroniaRtsaSettings(SWGAaroniaRTSASettings* aaronia_rtsa_settings) {
this->aaronia_rtsa_settings = aaronia_rtsa_settings;
this->m_aaronia_rtsa_settings_isSet = true;
}
bool
SWGDeviceSettings::isSet(){
@ -1224,6 +1246,9 @@ SWGDeviceSettings::isSet(){
if(xtrx_mimo_settings && xtrx_mimo_settings->isSet()){
isObjectUpdated = true; break;
}
if(aaronia_rtsa_settings && aaronia_rtsa_settings->isSet()){
isObjectUpdated = true; break;
}
}while(false);
return isObjectUpdated;
}

View File

@ -22,6 +22,7 @@
#include <QJsonObject>
#include "SWGAaroniaRTSASettings.h"
#include "SWGAirspyHFSettings.h"
#include "SWGAirspySettings.h"
#include "SWGAudioInputSettings.h"
@ -223,6 +224,9 @@ public:
SWGXtrxMIMOSettings* getXtrxMimoSettings();
void setXtrxMimoSettings(SWGXtrxMIMOSettings* xtrx_mimo_settings);
SWGAaroniaRTSASettings* getAaroniaRtsaSettings();
void setAaroniaRtsaSettings(SWGAaroniaRTSASettings* aaronia_rtsa_settings);
virtual bool isSet() override;
@ -365,6 +369,9 @@ private:
SWGXtrxMIMOSettings* xtrx_mimo_settings;
bool m_xtrx_mimo_settings_isSet;
SWGAaroniaRTSASettings* aaronia_rtsa_settings;
bool m_aaronia_rtsa_settings_isSet;
};
}

View File

@ -43,6 +43,8 @@
#include "SWGATVDemodSettings.h"
#include "SWGATVModReport.h"
#include "SWGATVModSettings.h"
#include "SWGAaroniaRTSAReport.h"
#include "SWGAaroniaRTSASettings.h"
#include "SWGAirspyHFReport.h"
#include "SWGAirspyHFSettings.h"
#include "SWGAirspyReport.h"
@ -498,6 +500,16 @@ namespace SWGSDRangel {
obj->init();
return obj;
}
if(QString("SWGAaroniaRTSAReport").compare(type) == 0) {
SWGAaroniaRTSAReport *obj = new SWGAaroniaRTSAReport();
obj->init();
return obj;
}
if(QString("SWGAaroniaRTSASettings").compare(type) == 0) {
SWGAaroniaRTSASettings *obj = new SWGAaroniaRTSASettings();
obj->init();
return obj;
}
if(QString("SWGAirspyHFReport").compare(type) == 0) {
SWGAirspyHFReport *obj = new SWGAirspyHFReport();
obj->init();