From f9155575d3e4d1454aa4e544cfd4378c4bc5756e Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 1 Dec 2021 08:25:32 +0100 Subject: [PATCH] ChannelAnalyzer: implemented settings API --- plugins/channelrx/chanalyzer/chanalyzer.cpp | 382 ++++++++++++++++++ plugins/channelrx/chanalyzer/chanalyzer.h | 42 ++ .../channelrx/chanalyzer/chanalyzergui.cpp | 15 + .../chanalyzer/chanalyzersettings.cpp | 28 ++ .../channelrx/chanalyzer/chanalyzersettings.h | 6 + sdrbase/resources/webapi/doc/html2/index.html | 22 +- .../doc/swagger/include/ChannelAnalyzer.yaml | 14 + sdrbase/webapi/webapirequestmapper.cpp | 106 +---- sdrbase/webapi/webapirequestmapper.h | 5 - .../api/swagger/include/ChannelAnalyzer.yaml | 14 + swagger/sdrangel/code/html2/index.html | 22 +- .../qt5/client/SWGChannelAnalyzerSettings.cpp | 140 +++++++ .../qt5/client/SWGChannelAnalyzerSettings.h | 36 ++ 13 files changed, 720 insertions(+), 112 deletions(-) diff --git a/plugins/channelrx/chanalyzer/chanalyzer.cpp b/plugins/channelrx/chanalyzer/chanalyzer.cpp index 732109e91..1b5e8a565 100644 --- a/plugins/channelrx/chanalyzer/chanalyzer.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzer.cpp @@ -18,12 +18,19 @@ #include #include #include +#include +#include +#include #include +#include "SWGChannelSettings.h" +#include "SWGChannelAnalyzerSettings.h" + #include "device/deviceapi.h" #include "dsp/dspcommands.h" #include "dsp/devicesamplesource.h" +#include "maincore.h" #include "chanalyzer.h" MESSAGE_CLASS_DEFINITION(ChannelAnalyzer::MsgConfigureChannelAnalyzer, Message) @@ -171,3 +178,378 @@ void ChannelAnalyzer::applySettings(const ChannelAnalyzerSettings& settings, boo m_settings = settings; } + +int ChannelAnalyzer::webapiSettingsGet( + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage) +{ + (void) errorMessage; + response.setChannelAnalyzerSettings(new SWGSDRangel::SWGChannelAnalyzerSettings()); + response.getChannelAnalyzerSettings()->init(); + webapiFormatChannelSettings(response, m_settings); + return 200; +} + +int ChannelAnalyzer::webapiSettingsPutPatch( + bool force, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage) +{ + (void) errorMessage; + ChannelAnalyzerSettings settings = m_settings; + webapiUpdateChannelSettings(settings, channelSettingsKeys, response); + + MsgConfigureChannelAnalyzer *msg = MsgConfigureChannelAnalyzer::create(settings, force); + m_inputMessageQueue.push(msg); + + qDebug("ChannelAnalyzer::webapiSettingsPutPatch: forward to GUI: %p", m_guiMessageQueue); + if (m_guiMessageQueue) // forward to GUI if any + { + MsgConfigureChannelAnalyzer *msgToGUI = MsgConfigureChannelAnalyzer::create(settings, force); + m_guiMessageQueue->push(msgToGUI); + } + + webapiFormatChannelSettings(response, settings); + + return 200; +} + +void ChannelAnalyzer::webapiUpdateChannelSettings( + ChannelAnalyzerSettings& settings, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response) +{ + if (channelSettingsKeys.contains("frequency")) { + settings.m_inputFrequencyOffset = response.getChannelAnalyzerSettings()->getFrequency(); + } + if (channelSettingsKeys.contains("downSample")) { + settings.m_rationalDownSample = response.getChannelAnalyzerSettings()->getDownSample() != 0; + } + if (channelSettingsKeys.contains("downSampleRate")) { + settings.m_rationalDownSamplerRate = response.getChannelAnalyzerSettings()->getDownSampleRate(); + } + if (channelSettingsKeys.contains("bandwidth")) { + settings.m_bandwidth = response.getChannelAnalyzerSettings()->getBandwidth(); + } + if (channelSettingsKeys.contains("lowCutoff")) { + settings.m_lowCutoff = response.getChannelAnalyzerSettings()->getLowCutoff(); + } + if (channelSettingsKeys.contains("spanLog2")) { + settings.m_log2Decim = response.getChannelAnalyzerSettings()->getSpanLog2(); + } + if (channelSettingsKeys.contains("ssb")) { + settings.m_ssb = response.getChannelAnalyzerSettings()->getSsb() != 0; + } + if (channelSettingsKeys.contains("pll")) { + settings.m_pll = response.getChannelAnalyzerSettings()->getPll() != 0; + } + if (channelSettingsKeys.contains("fll")) { + settings.m_fll = response.getChannelAnalyzerSettings()->getFll() != 0; + } + if (channelSettingsKeys.contains("costasLoop")) { + settings.m_costasLoop = response.getChannelAnalyzerSettings()->getCostasLoop() != 0; + } + if (channelSettingsKeys.contains("rrc")) { + settings.m_rrc = response.getChannelAnalyzerSettings()->getRrc() != 0; + } + if (channelSettingsKeys.contains("rrcRolloff")) { + settings.m_rrcRolloff = response.getChannelAnalyzerSettings()->getRrcRolloff(); + } + if (channelSettingsKeys.contains("pllPskOrder")) { + settings.m_pllPskOrder = response.getChannelAnalyzerSettings()->getPllPskOrder(); + } + if (channelSettingsKeys.contains("pllBandwidth")) { + settings.m_pllBandwidth = response.getChannelAnalyzerSettings()->getPllBandwidth(); + } + if (channelSettingsKeys.contains("pllDampingFactor")) { + settings.m_pllDampingFactor = response.getChannelAnalyzerSettings()->getPllDampingFactor(); + } + if (channelSettingsKeys.contains("pllLoopGain")) { + settings.m_pllLoopGain = response.getChannelAnalyzerSettings()->getPllLoopGain(); + } + if (channelSettingsKeys.contains("inputType")) { + settings.m_inputType = (ChannelAnalyzerSettings::InputType) response.getChannelAnalyzerSettings()->getInputType(); + } + if (channelSettingsKeys.contains("rgbColor")) { + settings.m_rgbColor = response.getChannelAnalyzerSettings()->getRgbColor(); + } + if (channelSettingsKeys.contains("title")) { + settings.m_title = *response.getChannelAnalyzerSettings()->getTitle(); + } + if (channelSettingsKeys.contains("streamIndex")) { + settings.m_streamIndex = response.getChannelAnalyzerSettings()->getStreamIndex(); + } + if (channelSettingsKeys.contains("useReverseAPI")) { + settings.m_useReverseAPI = response.getChannelAnalyzerSettings()->getUseReverseApi() != 0; + } + if (channelSettingsKeys.contains("reverseAPIAddress")) { + settings.m_reverseAPIAddress = *response.getChannelAnalyzerSettings()->getReverseApiAddress(); + } + if (channelSettingsKeys.contains("reverseAPIPort")) { + settings.m_reverseAPIPort = response.getChannelAnalyzerSettings()->getReverseApiPort(); + } + if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) { + settings.m_reverseAPIDeviceIndex = response.getChannelAnalyzerSettings()->getReverseApiDeviceIndex(); + } + if (channelSettingsKeys.contains("reverseAPIChannelIndex")) { + settings.m_reverseAPIChannelIndex = response.getChannelAnalyzerSettings()->getReverseApiChannelIndex(); + } + if (settings.m_spectrumGUI && channelSettingsKeys.contains("spectrumConfig")) { + settings.m_spectrumGUI->updateFrom(channelSettingsKeys, response.getChannelAnalyzerSettings()->getSpectrumConfig()); + } + if (settings.m_spectrumGUI && channelSettingsKeys.contains("scopeConfig")) { + settings.m_scopeGUI->updateFrom(channelSettingsKeys, response.getChannelAnalyzerSettings()->getScopeConfig()); + } +} + +void ChannelAnalyzer::webapiFormatChannelSettings( + SWGSDRangel::SWGChannelSettings& response, + const ChannelAnalyzerSettings& settings +) +{ + response.getChannelAnalyzerSettings()->setFrequency(settings.m_inputFrequencyOffset); + response.getChannelAnalyzerSettings()->setDownSample(settings.m_rationalDownSample ? 1 : 0); + response.getChannelAnalyzerSettings()->setDownSampleRate(settings.m_rationalDownSamplerRate); + response.getChannelAnalyzerSettings()->setBandwidth(settings.m_bandwidth); + response.getChannelAnalyzerSettings()->setLowCutoff(settings.m_lowCutoff); + response.getChannelAnalyzerSettings()->setSpanLog2(settings.m_log2Decim); + response.getChannelAnalyzerSettings()->setSsb(settings.m_ssb ? 1 : 0); + response.getChannelAnalyzerSettings()->setPll(settings.m_pll ? 1 : 0); + response.getChannelAnalyzerSettings()->setFll(settings.m_fll ? 1 : 0); + response.getChannelAnalyzerSettings()->setCostasLoop(settings.m_costasLoop ? 1 : 0); + response.getChannelAnalyzerSettings()->setRrc(settings.m_rrc ? 1 : 0); + response.getChannelAnalyzerSettings()->setRrcRolloff(settings.m_rrcRolloff); + response.getChannelAnalyzerSettings()->setPllPskOrder(settings.m_pllPskOrder); + response.getChannelAnalyzerSettings()->setPllBandwidth(settings.m_pllBandwidth); + response.getChannelAnalyzerSettings()->setPllDampingFactor(settings.m_pllDampingFactor); + response.getChannelAnalyzerSettings()->setPllLoopGain(settings.m_pllLoopGain); + response.getChannelAnalyzerSettings()->setInputType((int) settings.m_inputType); + response.getChannelAnalyzerSettings()->setRgbColor(settings.m_rgbColor); + + if (response.getChannelAnalyzerSettings()->getTitle()) { + *response.getChannelAnalyzerSettings()->getTitle() = settings.m_title; + } else { + response.getChannelAnalyzerSettings()->setTitle(new QString(settings.m_title)); + } + + response.getChannelAnalyzerSettings()->setStreamIndex(settings.m_streamIndex); + response.getChannelAnalyzerSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); + + if (response.getChannelAnalyzerSettings()->getReverseApiAddress()) { + *response.getChannelAnalyzerSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; + } else { + response.getChannelAnalyzerSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); + } + + response.getChannelAnalyzerSettings()->setReverseApiPort(settings.m_reverseAPIPort); + response.getChannelAnalyzerSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); + response.getChannelAnalyzerSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); + + if (settings.m_spectrumGUI) + { + if (response.getChannelAnalyzerSettings()->getSpectrumConfig()) + { + settings.m_spectrumGUI->formatTo(response.getChannelAnalyzerSettings()->getSpectrumConfig()); + } + else + { + SWGSDRangel::SWGGLSpectrum *swgGLSpectrum = new SWGSDRangel::SWGGLSpectrum(); + settings.m_spectrumGUI->formatTo(swgGLSpectrum); + response.getChannelAnalyzerSettings()->setSpectrumConfig(swgGLSpectrum); + } + } + + if (settings.m_scopeGUI) + { + if (response.getChannelAnalyzerSettings()->getScopeConfig()) + { + settings.m_scopeGUI->formatTo(response.getChannelAnalyzerSettings()->getScopeConfig()); + } + else + { + SWGSDRangel::SWGGLScope *swgGLScope = new SWGSDRangel::SWGGLScope(); + settings.m_scopeGUI->formatTo(swgGLScope); + response.getChannelAnalyzerSettings()->setScopeConfig(swgGLScope); + } + } +} + +void ChannelAnalyzer::webapiReverseSendSettings( + QList& channelSettingsKeys, + const ChannelAnalyzerSettings& settings, + bool force +) +{ + SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings(); + webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force); + + QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings") + .arg(settings.m_reverseAPIAddress) + .arg(settings.m_reverseAPIPort) + .arg(settings.m_reverseAPIDeviceIndex) + .arg(settings.m_reverseAPIChannelIndex); + m_networkRequest.setUrl(QUrl(channelSettingsURL)); + m_networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + QBuffer *buffer = new QBuffer(); + buffer->open((QBuffer::ReadWrite)); + buffer->write(swgChannelSettings->asJson().toUtf8()); + buffer->seek(0); + + // Always use PATCH to avoid passing reverse API settings + QNetworkReply *reply = m_networkManager->sendCustomRequest(m_networkRequest, "PATCH", buffer); + buffer->setParent(reply); + + delete swgChannelSettings; +} + +void ChannelAnalyzer::sendChannelSettings( + QList *messageQueues, + QList& channelSettingsKeys, + const ChannelAnalyzerSettings& settings, + bool force) +{ + QList::iterator it = messageQueues->begin(); + + for (; it != messageQueues->end(); ++it) + { + SWGSDRangel::SWGChannelSettings *swgChannelSettings = new SWGSDRangel::SWGChannelSettings(); + webapiFormatChannelSettings(channelSettingsKeys, swgChannelSettings, settings, force); + MainCore::MsgChannelSettings *msg = MainCore::MsgChannelSettings::create( + this, + channelSettingsKeys, + swgChannelSettings, + force + ); + (*it)->push(msg); + } +} + +void ChannelAnalyzer::webapiFormatChannelSettings( + QList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings *swgChannelSettings, + const ChannelAnalyzerSettings& settings, + bool force +) +{ + swgChannelSettings->setDirection(0); // Single sink (Rx) + swgChannelSettings->setOriginatorChannelIndex(getIndexInDeviceSet()); + swgChannelSettings->setOriginatorDeviceSetIndex(getDeviceSetIndex()); + swgChannelSettings->setChannelType(new QString(m_channelId)); + swgChannelSettings->setSsbDemodSettings(new SWGSDRangel::SWGSSBDemodSettings()); + SWGSDRangel::SWGChannelAnalyzerSettings *swgChannelAnalyzerSettings = swgChannelSettings->getChannelAnalyzerSettings(); + + // transfer data that has been modified. When force is on transfer all data except reverse API data + + if (channelSettingsKeys.contains("frequency") || force) { + swgChannelAnalyzerSettings->setFrequency(settings.m_inputFrequencyOffset); + } + if (channelSettingsKeys.contains("downSample")) { + swgChannelAnalyzerSettings->setDownSample(settings.m_rationalDownSample ? 1 : 0); + } + if (channelSettingsKeys.contains("downSampleRate")) { + swgChannelAnalyzerSettings->setDownSampleRate(settings.m_rationalDownSamplerRate); + } + if (channelSettingsKeys.contains("bandwidth")) { + swgChannelAnalyzerSettings->setBandwidth(settings.m_bandwidth); + } + if (channelSettingsKeys.contains("lowCutoff")) { + swgChannelAnalyzerSettings->setLowCutoff(settings.m_lowCutoff); + } + if (channelSettingsKeys.contains("spanLog2")) { + swgChannelAnalyzerSettings->setSpanLog2(settings.m_log2Decim); + } + if (channelSettingsKeys.contains("ssb")) { + swgChannelAnalyzerSettings->setSsb(settings.m_ssb ? 1 : 0); + } + if (channelSettingsKeys.contains("pll")) { + swgChannelAnalyzerSettings->setPll(settings.m_pll ? 1 : 0); + } + if (channelSettingsKeys.contains("fll")) { + swgChannelAnalyzerSettings->setFll(settings.m_fll ? 1 : 0); + } + if (channelSettingsKeys.contains("costasLoop")) { + swgChannelAnalyzerSettings->setCostasLoop(settings.m_costasLoop ? 1 : 0); + } + if (channelSettingsKeys.contains("rrc")) { + swgChannelAnalyzerSettings->setRrc(settings.m_rrc ? 1 : 0); + } + if (channelSettingsKeys.contains("rrcRolloff")) { + swgChannelAnalyzerSettings->setRrcRolloff(settings.m_rrcRolloff); + } + if (channelSettingsKeys.contains("pllPskOrder")) { + swgChannelAnalyzerSettings->setPllPskOrder(settings.m_pllPskOrder); + } + if (channelSettingsKeys.contains("pllBandwidth")) { + swgChannelAnalyzerSettings->setPllBandwidth(settings.m_pllBandwidth); + } + if (channelSettingsKeys.contains("pllDampingFactor")) { + swgChannelAnalyzerSettings->setPllDampingFactor(settings.m_pllDampingFactor); + } + if (channelSettingsKeys.contains("pllLoopGain")) { + swgChannelAnalyzerSettings->setPllLoopGain(settings.m_pllLoopGain); + } + if (channelSettingsKeys.contains("inputType")) { + swgChannelAnalyzerSettings->setInputType((int) settings.m_inputType); + } + if (channelSettingsKeys.contains("rgbColor")) { + swgChannelAnalyzerSettings->setRgbColor(settings.m_rgbColor); + } + if (channelSettingsKeys.contains("title") || force) { + swgChannelAnalyzerSettings->setTitle(new QString(settings.m_title)); + } + if (channelSettingsKeys.contains("streamIndex")) { + swgChannelAnalyzerSettings->setStreamIndex(settings.m_streamIndex); + } + if (channelSettingsKeys.contains("useReverseAPI")) { + swgChannelAnalyzerSettings->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); + } + if (channelSettingsKeys.contains("reverseAPIAddress")) { + swgChannelAnalyzerSettings->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); + } + if (channelSettingsKeys.contains("reverseAPIPort")) { + swgChannelAnalyzerSettings->setReverseApiPort(settings.m_reverseAPIPort); + } + if (channelSettingsKeys.contains("reverseAPIDeviceIndex")) { + swgChannelAnalyzerSettings->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); + } + if (channelSettingsKeys.contains("reverseAPIChannelIndex")) { + swgChannelAnalyzerSettings->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); + } + + if (settings.m_spectrumGUI && (channelSettingsKeys.contains("spectrunConfig") || force)) + { + SWGSDRangel::SWGGLSpectrum *swgGLSpectrum = new SWGSDRangel::SWGGLSpectrum(); + settings.m_spectrumGUI->formatTo(swgGLSpectrum); + swgChannelAnalyzerSettings->setSpectrumConfig(swgGLSpectrum); + } + + if (settings.m_scopeGUI && (channelSettingsKeys.contains("scopeConfig") || force)) + { + SWGSDRangel::SWGGLScope *swgGLScope = new SWGSDRangel::SWGGLScope(); + settings.m_scopeGUI->formatTo(swgGLScope); + swgChannelAnalyzerSettings->setScopeConfig(swgGLScope); + } +} + +void ChannelAnalyzer::networkManagerFinished(QNetworkReply *reply) +{ + QNetworkReply::NetworkError replyError = reply->error(); + + if (replyError) + { + qWarning() << "ChannelAnalyzer::networkManagerFinished:" + << " error(" << (int) replyError + << "): " << replyError + << ": " << reply->errorString(); + } + else + { + QString answer = reply->readAll(); + answer.chop(1); // remove last \n + qDebug("ChannelAnalyzer::networkManagerFinished: reply:\n%s", answer.toStdString().c_str()); + } + + reply->deleteLater(); +} diff --git a/plugins/channelrx/chanalyzer/chanalyzer.h b/plugins/channelrx/chanalyzer/chanalyzer.h index 9079ccfea..80515a6a4 100644 --- a/plugins/channelrx/chanalyzer/chanalyzer.h +++ b/plugins/channelrx/chanalyzer/chanalyzer.h @@ -20,6 +20,8 @@ #include #include +#include + #include #include "dsp/basebandsamplesink.h" @@ -32,6 +34,8 @@ #include "chanalyzerbaseband.h" class DownChannelizer; +class QNetworkReply; +class QNetworkAccessManager; class ChannelAnalyzer : public BasebandSampleSink, public ChannelAPI { public: @@ -95,6 +99,25 @@ public: return m_settings.m_inputFrequencyOffset; } + virtual int webapiSettingsGet( + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage); + + virtual int webapiSettingsPutPatch( + bool force, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage); + + static void webapiFormatChannelSettings( + SWGSDRangel::SWGChannelSettings& response, + const ChannelAnalyzerSettings& settings); + + static void webapiUpdateChannelSettings( + ChannelAnalyzerSettings& settings, + const QStringList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings& response); + static const char* const m_channelIdURI; static const char* const m_channelId; @@ -108,7 +131,26 @@ private: int m_basebandSampleRate; //!< stored from device message used when starting baseband sink qint64 m_centerFrequency; //!< stored from device message used when starting baseband sink + QNetworkAccessManager *m_networkManager; + QNetworkRequest m_networkRequest; + void applySettings(const ChannelAnalyzerSettings& settings, bool force = false); + void webapiReverseSendSettings(QList& channelSettingsKeys, const ChannelAnalyzerSettings& settings, bool force); + void sendChannelSettings( + QList *messageQueues, + QList& channelSettingsKeys, + const ChannelAnalyzerSettings& settings, + bool force + ); + void webapiFormatChannelSettings( + QList& channelSettingsKeys, + SWGSDRangel::SWGChannelSettings *swgChannelSettings, + const ChannelAnalyzerSettings& settings, + bool force + ); + +private slots: + void networkManagerFinished(QNetworkReply *reply); }; #endif // INCLUDE_CHANALYZER_H diff --git a/plugins/channelrx/chanalyzer/chanalyzergui.cpp b/plugins/channelrx/chanalyzer/chanalyzergui.cpp index 796c0b1c4..b3ebd0e4f 100644 --- a/plugins/channelrx/chanalyzer/chanalyzergui.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzergui.cpp @@ -234,6 +234,21 @@ bool ChannelAnalyzerGUI::handleMessage(const Message& message) m_basebandSampleRate = cmd.getSampleRate(); qDebug("ChannelAnalyzerGUI::handleMessage: DSPSignalNotification: m_basebandSampleRate: %d", m_basebandSampleRate); setSinkSampleRate(); + + return true; + } + else if (ChannelAnalyzer::MsgConfigureChannelAnalyzer::match(message)) + { + qDebug("ChannelAnalyzerGUI::handleMessage: ChannelAnalyzer::MsgConfigureChannelAnalyzer"); + const ChannelAnalyzer::MsgConfigureChannelAnalyzer& cfg = (ChannelAnalyzer::MsgConfigureChannelAnalyzer&) message; + m_settings = cfg.getSettings(); + blockApplySettings(true); + ui->spectrumGUI->updateSettings(); + ui->scopeGUI->updateSettings(); + displaySettings(); + blockApplySettings(false); + + return true; } return false; diff --git a/plugins/channelrx/chanalyzer/chanalyzersettings.cpp b/plugins/channelrx/chanalyzer/chanalyzersettings.cpp index 1cc4478b4..f9e0d72fa 100644 --- a/plugins/channelrx/chanalyzer/chanalyzersettings.cpp +++ b/plugins/channelrx/chanalyzer/chanalyzersettings.cpp @@ -52,6 +52,12 @@ void ChannelAnalyzerSettings::resetToDefaults() m_inputType = InputSignal; m_rgbColor = QColor(128, 128, 128).rgb(); m_title = "Channel Analyzer"; + m_streamIndex = 0; + m_useReverseAPI = false; + m_reverseAPIAddress = "127.0.0.1"; + m_reverseAPIPort = 8888; + m_reverseAPIDeviceIndex = 0; + m_reverseAPIChannelIndex = 0; } QByteArray ChannelAnalyzerSettings::serialize() const @@ -80,6 +86,12 @@ QByteArray ChannelAnalyzerSettings::serialize() const s.writeFloat(20, m_pllLoopGain); s.writeBool(21, m_costasLoop); s.writeBlob(22, m_rollupState); + s.writeBool(23, m_useReverseAPI); + s.writeString(24, m_reverseAPIAddress); + s.writeU32(25, m_reverseAPIPort); + s.writeU32(26, m_reverseAPIDeviceIndex); + s.writeU32(27, m_reverseAPIChannelIndex); + s.writeS32(28, m_streamIndex); return s.final(); } @@ -98,6 +110,7 @@ bool ChannelAnalyzerSettings::deserialize(const QByteArray& data) { QByteArray bytetmp; int tmp; + unsigned int utmp; d.readS32(1, &m_inputFrequencyOffset, 0); d.readS32(2, &m_bandwidth, 5000); @@ -132,6 +145,21 @@ bool ChannelAnalyzerSettings::deserialize(const QByteArray& data) d.readFloat(20, &m_pllLoopGain, 10.0f); d.readBool(21, &m_costasLoop, false); d.readBlob(22, &m_rollupState); + d.readBool(18, &m_useReverseAPI, false); + d.readString(19, &m_reverseAPIAddress, "127.0.0.1"); + d.readU32(20, &utmp, 0); + + if ((utmp > 1023) && (utmp < 65535)) { + m_reverseAPIPort = utmp; + } else { + m_reverseAPIPort = 8888; + } + + d.readU32(21, &utmp, 0); + m_reverseAPIDeviceIndex = utmp > 99 ? 99 : utmp; + d.readU32(22, &utmp, 0); + m_reverseAPIChannelIndex = utmp > 99 ? 99 : utmp; + d.readS32(23, &m_streamIndex, 0); return true; } diff --git a/plugins/channelrx/chanalyzer/chanalyzersettings.h b/plugins/channelrx/chanalyzer/chanalyzersettings.h index ee3e6b6f5..c382e3853 100644 --- a/plugins/channelrx/chanalyzer/chanalyzersettings.h +++ b/plugins/channelrx/chanalyzer/chanalyzersettings.h @@ -54,6 +54,12 @@ struct ChannelAnalyzerSettings Serializable *m_spectrumGUI; Serializable *m_scopeGUI; QByteArray m_rollupState; + int m_streamIndex; //!< MIMO channel. Not relevant when connected to SI (single Rx). + bool m_useReverseAPI; + QString m_reverseAPIAddress; + uint16_t m_reverseAPIPort; + uint16_t m_reverseAPIDeviceIndex; + uint16_t m_reverseAPIChannelIndex; ChannelAnalyzerSettings(); void resetToDefaults(); diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index d536feb69..f4abc9db3 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -3001,6 +3001,26 @@ margin-bottom: 20px; "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" + }, "spectrumConfig" : { "$ref" : "#/definitions/GLSpectrum" }, @@ -51447,7 +51467,7 @@ except ApiException as e:
- Generated 2021-11-30T22:42:47.179+01:00 + Generated 2021-12-01T01:10:25.279+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/ChannelAnalyzer.yaml b/sdrbase/resources/webapi/doc/swagger/include/ChannelAnalyzer.yaml index 7f7b720e4..fa930df85 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/ChannelAnalyzer.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/ChannelAnalyzer.yaml @@ -50,6 +50,20 @@ ChannelAnalyzerSettings: type: integer title: type: string + streamIndex: + description: MIMO channel. Not relevant when connected to SI (single Rx). + type: integer + useReverseAPI: + description: Synchronize with reverse API (1 for yes, 0 for no) + type: integer + reverseAPIAddress: + type: string + reverseAPIPort: + type: integer + reverseAPIDeviceIndex: + type: integer + reverseAPIChannelIndex: + type: integer spectrumConfig: $ref: "/doc/swagger/include/GLSpectrum.yaml#/GLSpectrum" scopeConfig: diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index 7141d964b..c7f4bc482 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -4196,7 +4196,7 @@ bool WebAPIRequestMapper::getChannelSettings( else if (channelSettingsKey == "ChannelAnalyzerSettings") { channelSettings->setChannelAnalyzerSettings(new SWGSDRangel::SWGChannelAnalyzerSettings()); - processChannelAnalyzerSettings(channelSettings, settingsJsonObject); + channelSettings->getChannelAnalyzerSettings()->fromJsonObject(settingsJsonObject); } else if (channelSettingsKey == "ChirpChatDemodSettings") { @@ -5140,110 +5140,6 @@ void WebAPIRequestMapper::resetFeatureActions(SWGSDRangel::SWGFeatureActions& fe featureActions.setSimplePttActions(nullptr); } -void WebAPIRequestMapper::processChannelAnalyzerSettings( - SWGSDRangel::SWGChannelSettings *channelSettings, - const QJsonObject& channelSettingsJson -) -{ - SWGSDRangel::SWGChannelAnalyzerSettings *channelAnalyzerSettings = new SWGSDRangel::SWGChannelAnalyzerSettings(); - channelSettings->setChannelAnalyzerSettings(channelAnalyzerSettings); - channelAnalyzerSettings->init(); - - if (channelSettingsJson.contains("bandwidth")) { - channelAnalyzerSettings->setBandwidth(channelSettingsJson["bandwidth"].toInt()); - } - if (channelSettingsJson.contains("downSample")) { - channelAnalyzerSettings->setDownSample(channelSettingsJson["downSample"].toInt()); - } - if (channelSettingsJson.contains("downSampleRate")) { - channelAnalyzerSettings->setDownSampleRate(channelSettingsJson["downSampleRate"].toInt()); - } - if (channelSettingsJson.contains("fll")) { - channelAnalyzerSettings->setFll(channelSettingsJson["fll"].toInt()); - } - if (channelSettingsJson.contains("frequency")) { - channelAnalyzerSettings->setFrequency(channelSettingsJson["frequency"].toInt()); - } - if (channelSettingsJson.contains("inputType")) { - channelAnalyzerSettings->setInputType(channelSettingsJson["inputType"].toInt()); - } - if (channelSettingsJson.contains("lowCutoff")) { - channelAnalyzerSettings->setLowCutoff(channelSettingsJson["lowCutoff"].toInt()); - } - if (channelSettingsJson.contains("pll")) { - channelAnalyzerSettings->setPll(channelSettingsJson["pll"].toInt()); - } - if (channelSettingsJson.contains("pllPskOrder")) { - channelAnalyzerSettings->setPllPskOrder(channelSettingsJson["pllPskOrder"].toInt()); - } - if (channelSettingsJson.contains("rgbColor")) { - channelAnalyzerSettings->setRgbColor(channelSettingsJson["rgbColor"].toInt()); - } - if (channelSettingsJson.contains("rrc")) { - channelAnalyzerSettings->setRrc(channelSettingsJson["rrc"].toInt()); - } - if (channelSettingsJson.contains("rrcRolloff")) { - channelAnalyzerSettings->setRrcRolloff(channelSettingsJson["rrcRolloff"].toInt()); - } - if (channelSettingsJson.contains("spanLog2")) { - channelAnalyzerSettings->setSpanLog2(channelSettingsJson["spanLog2"].toInt()); - } - if (channelSettingsJson.contains("ssb")) { - channelAnalyzerSettings->setSsb(channelSettingsJson["ssb"].toInt()); - } - if (channelSettingsJson.contains("title")) { - channelAnalyzerSettings->setTitle(new QString(channelSettingsJson["title"].toString())); - } - - if (channelSettingsJson.contains("spectrumConfig")) - { - SWGSDRangel::SWGGLSpectrum *spectrum = new SWGSDRangel::SWGGLSpectrum(); - spectrum->init(); - channelAnalyzerSettings->setSpectrumConfig(spectrum); - QJsonObject spectrumJson; - spectrum->fromJsonObject(spectrumJson); - } - - if (channelSettingsJson.contains("scopeConfig") && channelSettingsJson["scopeConfig"].isObject()) - { - SWGSDRangel::SWGGLScope *scopeConfig = new SWGSDRangel::SWGGLScope(); - scopeConfig->init(); - channelAnalyzerSettings->setScopeConfig(scopeConfig); - QJsonObject scopeConfigJson; - scopeConfig->fromJsonObject(scopeConfigJson); - - if (scopeConfigJson.contains("tracesData") && scopeConfigJson["tracesData"].isArray()) - { - QList *tracesData = new QList(); - scopeConfig->setTracesData(tracesData); - QJsonArray tracesJson = scopeConfigJson["tracesData"].toArray(); - - for (int i = 0; i < tracesJson.size(); i++) - { - SWGSDRangel::SWGTraceData *traceData = new SWGSDRangel::SWGTraceData(); - tracesData->append(traceData); - QJsonObject traceJson = tracesJson.at(i).toObject(); - traceData->fromJsonObject(traceJson); - } - } - - if (scopeConfigJson.contains("triggersData") && scopeConfigJson["triggersData"].isArray()) - { - QList *triggersData = new QList(); - scopeConfig->setTriggersData(triggersData); - QJsonArray triggersJson = scopeConfigJson["triggersData"].toArray(); - - for (int i = 0; i < triggersJson.size(); i++) - { - SWGSDRangel::SWGTriggerData *triggerData = new SWGSDRangel::SWGTriggerData(); - triggersData->append(triggerData); - QJsonObject triggerJson = triggersJson.at(i).toObject(); - triggerData->fromJsonObject(triggerJson); - } - } - } -} - void WebAPIRequestMapper::processSoapySDRSettings( SWGSDRangel::SWGDeviceSettings *deviceSettings, QJsonObject& deviceSettingsJson, diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index 03c527fc2..c073addcb 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -219,11 +219,6 @@ private: void resetFeatureReport(SWGSDRangel::SWGFeatureReport& featureReport); void resetFeatureActions(SWGSDRangel::SWGFeatureActions& featureActions); - void processChannelAnalyzerSettings( - SWGSDRangel::SWGChannelSettings *channelSettings, - const QJsonObject& channelSettingsJson - ); - void processSoapySDRSettings( SWGSDRangel::SWGDeviceSettings *deviceSettings, QJsonObject& deviceSettingsJson, diff --git a/swagger/sdrangel/api/swagger/include/ChannelAnalyzer.yaml b/swagger/sdrangel/api/swagger/include/ChannelAnalyzer.yaml index a420bdd03..faad591f3 100644 --- a/swagger/sdrangel/api/swagger/include/ChannelAnalyzer.yaml +++ b/swagger/sdrangel/api/swagger/include/ChannelAnalyzer.yaml @@ -50,6 +50,20 @@ ChannelAnalyzerSettings: type: integer title: type: string + streamIndex: + description: MIMO channel. Not relevant when connected to SI (single Rx). + type: integer + useReverseAPI: + description: Synchronize with reverse API (1 for yes, 0 for no) + type: integer + reverseAPIAddress: + type: string + reverseAPIPort: + type: integer + reverseAPIDeviceIndex: + type: integer + reverseAPIChannelIndex: + type: integer spectrumConfig: $ref: "http://swgserver:8081/api/swagger/include/GLSpectrum.yaml#/GLSpectrum" scopeConfig: diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index d536feb69..f4abc9db3 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -3001,6 +3001,26 @@ margin-bottom: 20px; "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" + }, "spectrumConfig" : { "$ref" : "#/definitions/GLSpectrum" }, @@ -51447,7 +51467,7 @@ except ApiException as e:
- Generated 2021-11-30T22:42:47.179+01:00 + Generated 2021-12-01T01:10:25.279+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.cpp index 5d97042cf..264b5cb55 100644 --- a/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.cpp @@ -66,6 +66,18 @@ SWGChannelAnalyzerSettings::SWGChannelAnalyzerSettings() { m_rgb_color_isSet = false; title = nullptr; m_title_isSet = false; + stream_index = 0; + m_stream_index_isSet = false; + use_reverse_api = 0; + m_use_reverse_api_isSet = false; + reverse_api_address = nullptr; + m_reverse_api_address_isSet = false; + reverse_api_port = 0; + m_reverse_api_port_isSet = false; + reverse_api_device_index = 0; + m_reverse_api_device_index_isSet = false; + reverse_api_channel_index = 0; + m_reverse_api_channel_index_isSet = false; spectrum_config = nullptr; m_spectrum_config_isSet = false; scope_config = nullptr; @@ -118,6 +130,18 @@ SWGChannelAnalyzerSettings::init() { m_rgb_color_isSet = false; title = new QString(""); m_title_isSet = false; + stream_index = 0; + m_stream_index_isSet = false; + use_reverse_api = 0; + m_use_reverse_api_isSet = false; + reverse_api_address = new QString(""); + m_reverse_api_address_isSet = false; + reverse_api_port = 0; + m_reverse_api_port_isSet = false; + reverse_api_device_index = 0; + m_reverse_api_device_index_isSet = false; + reverse_api_channel_index = 0; + m_reverse_api_channel_index_isSet = false; spectrum_config = new SWGGLSpectrum(); m_spectrum_config_isSet = false; scope_config = new SWGGLScope(); @@ -149,6 +173,14 @@ SWGChannelAnalyzerSettings::cleanup() { if(title != nullptr) { delete title; } + + + if(reverse_api_address != nullptr) { + delete reverse_api_address; + } + + + if(spectrum_config != nullptr) { delete spectrum_config; } @@ -209,6 +241,18 @@ SWGChannelAnalyzerSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString"); + ::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", ""); + + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); + + ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); + + ::SWGSDRangel::setValue(&reverse_api_port, pJson["reverseAPIPort"], "qint32", ""); + + ::SWGSDRangel::setValue(&reverse_api_device_index, pJson["reverseAPIDeviceIndex"], "qint32", ""); + + ::SWGSDRangel::setValue(&reverse_api_channel_index, pJson["reverseAPIChannelIndex"], "qint32", ""); + ::SWGSDRangel::setValue(&spectrum_config, pJson["spectrumConfig"], "SWGGLSpectrum", "SWGGLSpectrum"); ::SWGSDRangel::setValue(&scope_config, pJson["scopeConfig"], "SWGGLScope", "SWGGLScope"); @@ -288,6 +332,24 @@ SWGChannelAnalyzerSettings::asJsonObject() { if(title != nullptr && *title != QString("")){ toJsonValue(QString("title"), title, obj, QString("QString")); } + if(m_stream_index_isSet){ + obj->insert("streamIndex", QJsonValue(stream_index)); + } + if(m_use_reverse_api_isSet){ + obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); + } + if(reverse_api_address != nullptr && *reverse_api_address != QString("")){ + toJsonValue(QString("reverseAPIAddress"), reverse_api_address, obj, QString("QString")); + } + if(m_reverse_api_port_isSet){ + obj->insert("reverseAPIPort", QJsonValue(reverse_api_port)); + } + if(m_reverse_api_device_index_isSet){ + obj->insert("reverseAPIDeviceIndex", QJsonValue(reverse_api_device_index)); + } + if(m_reverse_api_channel_index_isSet){ + obj->insert("reverseAPIChannelIndex", QJsonValue(reverse_api_channel_index)); + } if((spectrum_config != nullptr) && (spectrum_config->isSet())){ toJsonValue(QString("spectrumConfig"), spectrum_config, obj, QString("SWGGLSpectrum")); } @@ -491,6 +553,66 @@ SWGChannelAnalyzerSettings::setTitle(QString* title) { this->m_title_isSet = true; } +qint32 +SWGChannelAnalyzerSettings::getStreamIndex() { + return stream_index; +} +void +SWGChannelAnalyzerSettings::setStreamIndex(qint32 stream_index) { + this->stream_index = stream_index; + this->m_stream_index_isSet = true; +} + +qint32 +SWGChannelAnalyzerSettings::getUseReverseApi() { + return use_reverse_api; +} +void +SWGChannelAnalyzerSettings::setUseReverseApi(qint32 use_reverse_api) { + this->use_reverse_api = use_reverse_api; + this->m_use_reverse_api_isSet = true; +} + +QString* +SWGChannelAnalyzerSettings::getReverseApiAddress() { + return reverse_api_address; +} +void +SWGChannelAnalyzerSettings::setReverseApiAddress(QString* reverse_api_address) { + this->reverse_api_address = reverse_api_address; + this->m_reverse_api_address_isSet = true; +} + +qint32 +SWGChannelAnalyzerSettings::getReverseApiPort() { + return reverse_api_port; +} +void +SWGChannelAnalyzerSettings::setReverseApiPort(qint32 reverse_api_port) { + this->reverse_api_port = reverse_api_port; + this->m_reverse_api_port_isSet = true; +} + +qint32 +SWGChannelAnalyzerSettings::getReverseApiDeviceIndex() { + return reverse_api_device_index; +} +void +SWGChannelAnalyzerSettings::setReverseApiDeviceIndex(qint32 reverse_api_device_index) { + this->reverse_api_device_index = reverse_api_device_index; + this->m_reverse_api_device_index_isSet = true; +} + +qint32 +SWGChannelAnalyzerSettings::getReverseApiChannelIndex() { + return reverse_api_channel_index; +} +void +SWGChannelAnalyzerSettings::setReverseApiChannelIndex(qint32 reverse_api_channel_index) { + this->reverse_api_channel_index = reverse_api_channel_index; + this->m_reverse_api_channel_index_isSet = true; +} + SWGGLSpectrum* SWGChannelAnalyzerSettings::getSpectrumConfig() { return spectrum_config; @@ -583,6 +705,24 @@ SWGChannelAnalyzerSettings::isSet(){ if(title && *title != QString("")){ isObjectUpdated = true; break; } + if(m_stream_index_isSet){ + isObjectUpdated = true; break; + } + if(m_use_reverse_api_isSet){ + isObjectUpdated = true; break; + } + if(reverse_api_address && *reverse_api_address != QString("")){ + isObjectUpdated = true; break; + } + if(m_reverse_api_port_isSet){ + isObjectUpdated = true; break; + } + if(m_reverse_api_device_index_isSet){ + isObjectUpdated = true; break; + } + if(m_reverse_api_channel_index_isSet){ + isObjectUpdated = true; break; + } if(spectrum_config && spectrum_config->isSet()){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.h b/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.h index c4a33e3a2..c029d6ebc 100644 --- a/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGChannelAnalyzerSettings.h @@ -102,6 +102,24 @@ public: QString* getTitle(); void setTitle(QString* title); + qint32 getStreamIndex(); + void setStreamIndex(qint32 stream_index); + + qint32 getUseReverseApi(); + void setUseReverseApi(qint32 use_reverse_api); + + QString* getReverseApiAddress(); + void setReverseApiAddress(QString* reverse_api_address); + + qint32 getReverseApiPort(); + void setReverseApiPort(qint32 reverse_api_port); + + qint32 getReverseApiDeviceIndex(); + void setReverseApiDeviceIndex(qint32 reverse_api_device_index); + + qint32 getReverseApiChannelIndex(); + void setReverseApiChannelIndex(qint32 reverse_api_channel_index); + SWGGLSpectrum* getSpectrumConfig(); void setSpectrumConfig(SWGGLSpectrum* spectrum_config); @@ -172,6 +190,24 @@ private: QString* title; bool m_title_isSet; + qint32 stream_index; + bool m_stream_index_isSet; + + qint32 use_reverse_api; + bool m_use_reverse_api_isSet; + + QString* reverse_api_address; + bool m_reverse_api_address_isSet; + + qint32 reverse_api_port; + bool m_reverse_api_port_isSet; + + qint32 reverse_api_device_index; + bool m_reverse_api_device_index_isSet; + + qint32 reverse_api_channel_index; + bool m_reverse_api_channel_index_isSet; + SWGGLSpectrum* spectrum_config; bool m_spectrum_config_isSet;