From ea02e04f2d6315f78684a13e6e0dbbfe15917ce0 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 25 Dec 2018 10:38:31 +0100 Subject: [PATCH] Reverse API: airspy changes --- plugins/samplesource/airspy/airspygui.cpp | 24 ++ plugins/samplesource/airspy/airspygui.h | 1 + plugins/samplesource/airspy/airspyinput.cpp | 284 +++++++++++++----- plugins/samplesource/airspy/airspyinput.h | 27 +- .../samplesource/airspy/airspysettings.cpp | 21 ++ plugins/samplesource/airspy/airspysettings.h | 4 + 6 files changed, 273 insertions(+), 88 deletions(-) diff --git a/plugins/samplesource/airspy/airspygui.cpp b/plugins/samplesource/airspy/airspygui.cpp index ae59a6ca7..5b8ce1313 100644 --- a/plugins/samplesource/airspy/airspygui.cpp +++ b/plugins/samplesource/airspy/airspygui.cpp @@ -28,6 +28,8 @@ #include "ui_airspygui.h" #include "gui/colormapper.h" #include "gui/glspectrum.h" +#include "gui/crightclickenabler.h" +#include "gui/basicdevicesettingsdialog.h" #include "dsp/dspengine.h" #include "dsp/dspcommands.h" @@ -51,6 +53,9 @@ AirspyGui::AirspyGui(DeviceUISet *deviceUISet, QWidget* parent) : connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus())); m_statusTimer.start(500); + CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop); + connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &))); + displaySettings(); m_rates = ((AirspyInput*) m_sampleSource)->getSampleRates(); @@ -454,3 +459,22 @@ int AirspyGui::getDevSampleRateIndex(uint32_t sampeRate) return -1; } + +void AirspyGui::openDeviceSettingsDialog(const QPoint& p) +{ + 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); + 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(); + + sendSettings(); +} diff --git a/plugins/samplesource/airspy/airspygui.h b/plugins/samplesource/airspy/airspygui.h index aca2de1e0..af27c46c0 100644 --- a/plugins/samplesource/airspy/airspygui.h +++ b/plugins/samplesource/airspy/airspygui.h @@ -95,6 +95,7 @@ private slots: void updateHardware(); void updateStatus(); void handleInputMessages(); + void openDeviceSettingsDialog(const QPoint& p); }; #endif // INCLUDE_AIRSPYGUI_H diff --git a/plugins/samplesource/airspy/airspyinput.cpp b/plugins/samplesource/airspy/airspyinput.cpp index 111ea4dcc..9a19628b7 100644 --- a/plugins/samplesource/airspy/airspyinput.cpp +++ b/plugins/samplesource/airspy/airspyinput.cpp @@ -16,8 +16,11 @@ #include #include + #include #include +#include +#include #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" @@ -52,11 +55,20 @@ AirspyInput::AirspyInput(DeviceSourceAPI *deviceAPI) : openDevice(); m_fileSink = new FileRecord(QString("test_%1.sdriq").arg(m_deviceAPI->getDeviceUID())); m_deviceAPI->addSink(m_fileSink); + + m_networkManager = new QNetworkAccessManager(); + connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); } AirspyInput::~AirspyInput() { - if (m_running) stop(); + disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); + delete m_networkManager; + + if (m_running) { + stop(); + } + m_deviceAPI->removeSink(m_fileSink); delete m_fileSink; closeDevice(); @@ -298,6 +310,10 @@ bool AirspyInput::handleMessage(const Message& message) m_deviceAPI->stopAcquisition(); } + if (m_settings.m_useReverseAPI) { + webapiReverseSendStartStop(cmd.getStartStop()); + } + return true; } else if (MsgFileRecord::match(message)) @@ -351,48 +367,47 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force) bool forwardChange = false; airspy_error rc = AIRSPY_ERROR_OTHER; + QList reverseAPIKeys; qDebug() << "AirspyInput::applySettings"; + if ((m_settings.m_dcBlock != settings.m_dcBlock) || force) { + reverseAPIKeys.append("dcBlock"); + } + if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force) { + reverseAPIKeys.append("iqCorrection"); + } + if ((m_settings.m_dcBlock != settings.m_dcBlock) || (m_settings.m_iqCorrection != settings.m_iqCorrection) || force) { - m_settings.m_dcBlock = settings.m_dcBlock; - m_settings.m_iqCorrection = settings.m_iqCorrection; - m_deviceAPI->configureCorrections(m_settings.m_dcBlock, m_settings.m_iqCorrection); + m_deviceAPI->configureCorrections(settings.m_dcBlock, settings.m_iqCorrection); } if ((m_settings.m_devSampleRateIndex != settings.m_devSampleRateIndex) || force) { + reverseAPIKeys.append("devSampleRateIndex"); forwardChange = true; - if (settings.m_devSampleRateIndex < m_sampleRates.size()) - { - m_settings.m_devSampleRateIndex = settings.m_devSampleRateIndex; - } - else - { - m_settings.m_devSampleRateIndex = m_sampleRates.size() - 1; - } - if (m_dev != 0) { - rc = (airspy_error) airspy_set_samplerate(m_dev, static_cast(m_settings.m_devSampleRateIndex)); + rc = (airspy_error) airspy_set_samplerate(m_dev, static_cast(settings.m_devSampleRateIndex)); if (rc != AIRSPY_SUCCESS) { - qCritical("AirspyInput::applySettings: could not set sample rate index %u (%d S/s): %s", m_settings.m_devSampleRateIndex, m_sampleRates[m_settings.m_devSampleRateIndex], airspy_error_name(rc)); + qCritical("AirspyInput::applySettings: could not set sample rate index %u (%d S/s): %s", settings.m_devSampleRateIndex, m_sampleRates[settings.m_devSampleRateIndex], airspy_error_name(rc)); } else if (m_airspyThread != 0) { - qDebug("AirspyInput::applySettings: sample rate set to index: %u (%d S/s)", m_settings.m_devSampleRateIndex, m_sampleRates[m_settings.m_devSampleRateIndex]); - m_airspyThread->setSamplerate(m_sampleRates[m_settings.m_devSampleRateIndex]); + qDebug("AirspyInput::applySettings: sample rate set to index: %u (%d S/s)", settings.m_devSampleRateIndex, m_sampleRates[settings.m_devSampleRateIndex]); + m_airspyThread->setSamplerate(m_sampleRates[settings.m_devSampleRateIndex]); } } } if ((m_settings.m_log2Decim != settings.m_log2Decim) || force) { + reverseAPIKeys.append("log2Decim"); forwardChange = true; if (m_airspyThread != 0) @@ -402,6 +417,22 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force) } } + if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) { + reverseAPIKeys.append("centerFrequency"); + } + if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) { + reverseAPIKeys.append("LOppmTenths"); + } + if ((m_settings.m_fcPos != settings.m_fcPos) || force) { + reverseAPIKeys.append("fcPos"); + } + if ((m_settings.m_transverterMode != settings.m_transverterMode) || force) { + reverseAPIKeys.append("transverterMode"); + } + if ((m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency) || force) { + reverseAPIKeys.append("transverterDeltaFrequency"); + } + if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || (m_settings.m_LOppmTenths != settings.m_LOppmTenths) || (m_settings.m_fcPos != settings.m_fcPos) @@ -414,15 +445,9 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force) settings.m_transverterDeltaFrequency, settings.m_log2Decim, (DeviceSampleSource::fcPos_t) settings.m_fcPos, - m_sampleRates[m_settings.m_devSampleRateIndex], + m_sampleRates[settings.m_devSampleRateIndex], settings.m_transverterMode); - m_settings.m_centerFrequency = settings.m_centerFrequency; - m_settings.m_log2Decim = settings.m_log2Decim; - m_settings.m_transverterMode = settings.m_transverterMode; - m_settings.m_transverterDeltaFrequency = settings.m_transverterDeltaFrequency; - m_settings.m_LOppmTenths = settings.m_LOppmTenths; - if (m_dev != 0) { setDeviceCenterFrequency(deviceCenterFrequency); } @@ -432,129 +457,118 @@ bool AirspyInput::applySettings(const AirspySettings& settings, bool force) if ((m_settings.m_fcPos != settings.m_fcPos) || force) { - m_settings.m_fcPos = settings.m_fcPos; - if (m_airspyThread != 0) { - m_airspyThread->setFcPos((int) m_settings.m_fcPos); - qDebug() << "AirspyInput: set fc pos (enum) to " << (int) m_settings.m_fcPos; + m_airspyThread->setFcPos((int) settings.m_fcPos); + qDebug() << "AirspyInput: set fc pos (enum) to " << (int) settings.m_fcPos; } } if ((m_settings.m_lnaGain != settings.m_lnaGain) || force) { - m_settings.m_lnaGain = settings.m_lnaGain; + reverseAPIKeys.append("lnaGain"); if (m_dev != 0) { - rc = (airspy_error) airspy_set_lna_gain(m_dev, m_settings.m_lnaGain); + rc = (airspy_error) airspy_set_lna_gain(m_dev, settings.m_lnaGain); - if(rc != AIRSPY_SUCCESS) - { + if (rc != AIRSPY_SUCCESS) { qDebug("AirspyInput::applySettings: airspy_set_lna_gain failed: %s", airspy_error_name(rc)); - } - else - { - qDebug() << "AirspyInput:applySettings: LNA gain set to " << m_settings.m_lnaGain; + } else { + qDebug() << "AirspyInput:applySettings: LNA gain set to " << settings.m_lnaGain; } } } if ((m_settings.m_lnaAGC != settings.m_lnaAGC) || force) { - m_settings.m_lnaAGC = settings.m_lnaAGC; + reverseAPIKeys.append("lnaAGC"); - if (m_dev != 0) - { - rc = (airspy_error) airspy_set_lna_agc(m_dev, (m_settings.m_lnaAGC ? 1 : 0)); + if (m_dev != 0) { + rc = (airspy_error) airspy_set_lna_agc(m_dev, (settings.m_lnaAGC ? 1 : 0)); } - if(rc != AIRSPY_SUCCESS) - { + if (rc != AIRSPY_SUCCESS) { qDebug("AirspyInput::applySettings: airspy_set_lna_agc failed: %s", airspy_error_name(rc)); - } - else - { - qDebug() << "AirspyInput:applySettings: LNA AGC set to " << m_settings.m_lnaAGC; + } else { + qDebug() << "AirspyInput:applySettings: LNA AGC set to " << settings.m_lnaAGC; } } if ((m_settings.m_mixerGain != settings.m_mixerGain) || force) { - m_settings.m_mixerGain = settings.m_mixerGain; + reverseAPIKeys.append("mixerGain"); if (m_dev != 0) { - rc = (airspy_error) airspy_set_mixer_gain(m_dev, m_settings.m_mixerGain); + rc = (airspy_error) airspy_set_mixer_gain(m_dev, settings.m_mixerGain); - if(rc != AIRSPY_SUCCESS) - { + if (rc != AIRSPY_SUCCESS) { qDebug("AirspyInput::applySettings: airspy_set_mixer_gain failed: %s", airspy_error_name(rc)); - } - else - { - qDebug() << "AirspyInput:applySettings: mixer gain set to " << m_settings.m_mixerGain; + } else { + qDebug() << "AirspyInput:applySettings: mixer gain set to " << settings.m_mixerGain; } } } if ((m_settings.m_mixerAGC != settings.m_mixerAGC) || force) { - m_settings.m_mixerAGC = settings.m_mixerAGC; + reverseAPIKeys.append("mixerAGC"); - if (m_dev != 0) - { - rc = (airspy_error) airspy_set_mixer_agc(m_dev, (m_settings.m_mixerAGC ? 1 : 0)); + if (m_dev != 0) { + rc = (airspy_error) airspy_set_mixer_agc(m_dev, (settings.m_mixerAGC ? 1 : 0)); } - if(rc != AIRSPY_SUCCESS) - { + if (rc != AIRSPY_SUCCESS) { qDebug("AirspyInput::applySettings: airspy_set_mixer_agc failed: %s", airspy_error_name(rc)); - } - else - { - qDebug() << "AirspyInput:applySettings: Mixer AGC set to " << m_settings.m_mixerAGC; + } else { + qDebug() << "AirspyInput:applySettings: Mixer AGC set to " << settings.m_mixerAGC; } } if ((m_settings.m_vgaGain != settings.m_vgaGain) || force) { - m_settings.m_vgaGain = settings.m_vgaGain; + reverseAPIKeys.append("vgaGain"); if (m_dev != 0) { - rc = (airspy_error) airspy_set_vga_gain(m_dev, m_settings.m_vgaGain); + rc = (airspy_error) airspy_set_vga_gain(m_dev, settings.m_vgaGain); - if(rc != AIRSPY_SUCCESS) - { + if (rc != AIRSPY_SUCCESS) { qDebug("AirspyInput::applySettings: airspy_set_vga_gain failed: %s", airspy_error_name(rc)); - } - else - { - qDebug() << "AirspyInput:applySettings: VGA gain set to " << m_settings.m_vgaGain; + } else { + qDebug() << "AirspyInput:applySettings: VGA gain set to " << settings.m_vgaGain; } } } if ((m_settings.m_biasT != settings.m_biasT) || force) { - m_settings.m_biasT = settings.m_biasT; + reverseAPIKeys.append("biasT"); if (m_dev != 0) { - rc = (airspy_error) airspy_set_rf_bias(m_dev, (m_settings.m_biasT ? 1 : 0)); + rc = (airspy_error) airspy_set_rf_bias(m_dev, (settings.m_biasT ? 1 : 0)); - if(rc != AIRSPY_SUCCESS) - { + if (rc != AIRSPY_SUCCESS) { qDebug("AirspyInput::applySettings: airspy_set_rf_bias failed: %s", airspy_error_name(rc)); - } - else - { - qDebug() << "AirspyInput:applySettings: bias tee set to " << m_settings.m_biasT; + } else { + qDebug() << "AirspyInput:applySettings: bias tee set to " << settings.m_biasT; } } } + if (settings.m_useReverseAPI) + { + bool fullUpdate = ((m_settings.m_useReverseAPI != settings.m_useReverseAPI) && settings.m_useReverseAPI) || + (m_settings.m_reverseAPIAddress != settings.m_reverseAPIAddress) || + (m_settings.m_reverseAPIPort != settings.m_reverseAPIPort) || + (m_settings.m_reverseAPIDeviceIndex != settings.m_reverseAPIDeviceIndex); + webapiReverseSendSettings(reverseAPIKeys, settings, fullUpdate || force); + } + + m_settings = settings; + if (forwardChange) { int sampleRate = m_sampleRates[m_settings.m_devSampleRateIndex]/(1<getSampleRates()->back()->setRate(*it); } } + +void AirspyInput::webapiReverseSendSettings(QList& deviceSettingsKeys, const AirspySettings& settings, bool force) +{ + SWGSDRangel::SWGDeviceSettings *swgDeviceSettings = new SWGSDRangel::SWGDeviceSettings(); + swgDeviceSettings->setTx(0); + swgDeviceSettings->setDeviceHwType(new QString("Airspy")); + swgDeviceSettings->setAirspySettings(new SWGSDRangel::SWGAirspySettings()); + SWGSDRangel::SWGAirspySettings *swgAirspySettings = swgDeviceSettings->getAirspySettings(); + + // transfer data that has been modified. When force is on transfer all data except reverse API data + + if (deviceSettingsKeys.contains("centerFrequency") || force) { + swgAirspySettings->setCenterFrequency(settings.m_centerFrequency); + } + if (deviceSettingsKeys.contains("LOppmTenths") || force) { + swgAirspySettings->setLOppmTenths(settings.m_LOppmTenths); + } + if (deviceSettingsKeys.contains("devSampleRateIndex") || force) { + swgAirspySettings->setDevSampleRateIndex(settings.m_devSampleRateIndex); + } + if (deviceSettingsKeys.contains("lnaGain") || force) { + swgAirspySettings->setLnaGain(settings.m_lnaGain); + } + if (deviceSettingsKeys.contains("mixerGain") || force) { + swgAirspySettings->setMixerGain(settings.m_mixerGain); + } + if (deviceSettingsKeys.contains("vgaGain") || force) { + swgAirspySettings->setVgaGain(settings.m_vgaGain); + } + if (deviceSettingsKeys.contains("lnaAGC") || force) { + swgAirspySettings->setLnaAgc(settings.m_lnaAGC ? 1 : 0); + } + if (deviceSettingsKeys.contains("mixerAGC") || force) { + swgAirspySettings->setMixerAgc(settings.m_mixerAGC ? 1 : 0); + } + if (deviceSettingsKeys.contains("log2Decim") || force) { + swgAirspySettings->setLog2Decim(settings.m_log2Decim); + } + if (deviceSettingsKeys.contains("fcPos") || force) { + swgAirspySettings->setFcPos((int) settings.m_fcPos); + } + if (deviceSettingsKeys.contains("biasT") || force) { + swgAirspySettings->setBiasT(settings.m_biasT ? 1 : 0); + } + if (deviceSettingsKeys.contains("dcBlock") || force) { + swgAirspySettings->setDcBlock(settings.m_dcBlock ? 1 : 0); + } + if (deviceSettingsKeys.contains("iqCorrection") || force) { + swgAirspySettings->setIqCorrection(settings.m_iqCorrection ? 1 : 0); + } + if (deviceSettingsKeys.contains("transverterDeltaFrequency") || force) { + swgAirspySettings->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); + } + if (deviceSettingsKeys.contains("transverterMode") || force) { + swgAirspySettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); + } + if (deviceSettingsKeys.contains("fileRecordName") || force) { + swgAirspySettings->setFileRecordName(new QString(settings.m_fileRecordName)); + } + + 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 + m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer); + + delete swgDeviceSettings; +} + +void AirspyInput::webapiReverseSendStartStop(bool start) +{ + 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)); + + if (start) { + m_networkManager->sendCustomRequest(m_networkRequest, "POST"); + } else { + m_networkManager->sendCustomRequest(m_networkRequest, "DELETE"); + } +} + +void AirspyInput::networkManagerFinished(QNetworkReply *reply) +{ + QNetworkReply::NetworkError replyError = reply->error(); + + if (replyError) + { + qWarning() << "AirspyInput::networkManagerFinished:" + << " error(" << (int) replyError + << "): " << replyError + << ": " << reply->errorString(); + return; + } + + QString answer = reply->readAll(); + answer.chop(1); // remove last \n + qDebug("AirspyInput::networkManagerFinished: reply:\n%s", answer.toStdString().c_str()); +} diff --git a/plugins/samplesource/airspy/airspyinput.h b/plugins/samplesource/airspy/airspyinput.h index f6d4788f2..dadc21088 100644 --- a/plugins/samplesource/airspy/airspyinput.h +++ b/plugins/samplesource/airspy/airspyinput.h @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -27,8 +28,11 @@ class DeviceSourceAPI; class AirspyThread; class FileRecord; +class QNetworkAccessManager; +class QNetworkReply; class AirspyInput : public DeviceSampleSource { + Q_OBJECT public: class MsgConfigureAirspy : public Message { MESSAGE_CLASS_DECLARATION @@ -138,14 +142,6 @@ public: static const qint64 loHighLimitFreq; private: - bool openDevice(); - void closeDevice(); - bool applySettings(const AirspySettings& settings, bool force); - struct airspy_device *open_airspy_from_sequence(int sequence); - void setDeviceCenterFrequency(quint64 freq); - void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const AirspySettings& settings); - void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response); - DeviceSourceAPI *m_deviceAPI; QMutex m_mutex; AirspySettings m_settings; @@ -155,6 +151,21 @@ private: std::vector m_sampleRates; bool m_running; FileRecord *m_fileSink; //!< File sink to record device I/Q output + QNetworkAccessManager *m_networkManager; + QNetworkRequest m_networkRequest; + + bool openDevice(); + void closeDevice(); + bool applySettings(const AirspySettings& settings, bool force); + struct airspy_device *open_airspy_from_sequence(int sequence); + void setDeviceCenterFrequency(quint64 freq); + void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const AirspySettings& settings); + void webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response); + void webapiReverseSendSettings(QList& deviceSettingsKeys, const AirspySettings& settings, bool force); + void webapiReverseSendStartStop(bool start); + +private slots: + void networkManagerFinished(QNetworkReply *reply); }; #endif // INCLUDE_AIRSPYINPUT_H diff --git a/plugins/samplesource/airspy/airspysettings.cpp b/plugins/samplesource/airspy/airspysettings.cpp index d1c7d786b..2de6b46cf 100644 --- a/plugins/samplesource/airspy/airspysettings.cpp +++ b/plugins/samplesource/airspy/airspysettings.cpp @@ -41,6 +41,10 @@ void AirspySettings::resetToDefaults() m_transverterMode = false; m_transverterDeltaFrequency = 0; m_fileRecordName = ""; + m_useReverseAPI = false; + m_reverseAPIAddress = "127.0.0.1"; + m_reverseAPIPort = 8888; + m_reverseAPIDeviceIndex = 0; } QByteArray AirspySettings::serialize() const @@ -61,6 +65,10 @@ QByteArray AirspySettings::serialize() const s.writeBool(12, m_mixerAGC); s.writeBool(13, m_transverterMode); s.writeS64(14, m_transverterDeltaFrequency); + s.writeBool(15, m_useReverseAPI); + s.writeString(16, m_reverseAPIAddress); + s.writeU32(17, m_reverseAPIPort); + s.writeU32(18, m_reverseAPIDeviceIndex); return s.final(); } @@ -78,6 +86,7 @@ bool AirspySettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { int intval; + uint32_t uintval; d.readS32(1, &m_LOppmTenths, 0); d.readU32(2, &m_devSampleRateIndex, 0); @@ -94,6 +103,18 @@ bool AirspySettings::deserialize(const QByteArray& data) d.readBool(12, &m_mixerAGC, false); d.readBool(13, &m_transverterMode, false); d.readS64(14, &m_transverterDeltaFrequency, 0); + d.readBool(15, &m_useReverseAPI, false); + d.readString(16, &m_reverseAPIAddress, "127.0.0.1"); + d.readU32(17, &uintval, 0); + + if ((uintval > 1023) && (uintval < 65535)) { + m_reverseAPIPort = uintval; + } else { + m_reverseAPIPort = 8888; + } + + d.readU32(18, &uintval, 0); + m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval; return true; } diff --git a/plugins/samplesource/airspy/airspysettings.h b/plugins/samplesource/airspy/airspysettings.h index b8daf0ea0..b5c619ce4 100644 --- a/plugins/samplesource/airspy/airspysettings.h +++ b/plugins/samplesource/airspy/airspysettings.h @@ -42,6 +42,10 @@ struct AirspySettings { bool m_transverterMode; qint64 m_transverterDeltaFrequency; QString m_fileRecordName; + bool m_useReverseAPI; + QString m_reverseAPIAddress; + uint16_t m_reverseAPIPort; + uint16_t m_reverseAPIDeviceIndex; AirspySettings(); void resetToDefaults();