From e4b65b52b4da44e235c78ee2bde443df47468a59 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 11 Dec 2017 18:18:47 +0100 Subject: [PATCH] Web API: /sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings PUT, PATCH for NFM demod and mod --- plugins/channelrx/demodnfm/nfmdemod.cpp | 37 ++++++++ plugins/channelrx/demodnfm/nfmdemod.h | 5 ++ plugins/channelrx/demodnfm/nfmdemodgui.cpp | 11 ++- plugins/channeltx/modnfm/nfmmod.cpp | 49 +++++++++++ plugins/channeltx/modnfm/nfmmod.h | 5 ++ plugins/channeltx/modnfm/nfmmodgui.cpp | 15 ++++ .../samplesink/hackrfoutput/hackrfoutput.pro | 2 + sdrbase/channel/channelsinkapi.h | 6 ++ sdrbase/channel/channelsourceapi.h | 6 ++ sdrbase/dsp/cwkeyer.cpp | 2 + sdrbase/dsp/cwkeyer.h | 30 +++++-- sdrbase/webapi/webapiadapterinterface.h | 12 +++ sdrbase/webapi/webapirequestmapper.cpp | 79 +++++++++++++++++ sdrbase/webapi/webapirequestmapper.h | 1 + sdrgui/gui/cwkeyergui.cpp | 58 +++++++++++-- sdrgui/gui/cwkeyergui.h | 5 ++ sdrgui/webapi/webapiadaptergui.cpp | 87 +++++++++++++++++++ sdrgui/webapi/webapiadaptergui.h | 7 ++ 18 files changed, 402 insertions(+), 15 deletions(-) diff --git a/plugins/channelrx/demodnfm/nfmdemod.cpp b/plugins/channelrx/demodnfm/nfmdemod.cpp index 2435eefed..4942e447d 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.cpp +++ b/plugins/channelrx/demodnfm/nfmdemod.cpp @@ -480,3 +480,40 @@ int NFMDemod::webapiSettingsGet( response.getNfmDemodSettings()->setVolume(m_settings.m_volume); return 200; } + +int NFMDemod::webapiSettingsPutPatch( + bool force, + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage __attribute__((unused))) +{ + NFMDemodSettings settings; + settings.m_afBandwidth = response.getNfmDemodSettings()->getAfBandwidth(); + settings.m_audioMute = response.getNfmDemodSettings()->getAudioMute() != 0; + settings.m_audioSampleRate = response.getNfmDemodSettings()->getAudioSampleRate(); + settings.m_copyAudioToUDP = response.getNfmDemodSettings()->getCopyAudioToUdp() != 0; + settings.m_ctcssIndex = response.getNfmDemodSettings()->getCtcssIndex(); + settings.m_ctcssOn = response.getNfmDemodSettings()->getCtcssOn() != 0; + settings.m_deltaSquelch = response.getNfmDemodSettings()->getDeltaSquelch() != 0; + settings.m_fmDeviation = response.getNfmDemodSettings()->getFmDeviation(); + settings.m_inputFrequencyOffset = response.getNfmDemodSettings()->getInputFrequencyOffset(); + settings.m_inputSampleRate = response.getNfmDemodSettings()->getInputSampleRate(); + settings.m_rfBandwidth = response.getNfmDemodSettings()->getRfBandwidth(); + settings.m_rgbColor = response.getNfmDemodSettings()->getRgbColor(); + settings.m_squelch = response.getNfmDemodSettings()->getSquelch(); + settings.m_squelchGate = response.getNfmDemodSettings()->getSquelchGate(); + settings.m_title = *response.getNfmDemodSettings()->getTitle(); + settings.m_udpAddress = *response.getNfmDemodSettings()->getUdpAddress(); + settings.m_udpPort = response.getNfmDemodSettings()->getUdpPort(); + settings.m_volume = response.getNfmDemodSettings()->getVolume(); + + MsgConfigureNFMDemod *msg = MsgConfigureNFMDemod::create(settings, force); + m_inputMessageQueue.push(msg); + + if (m_guiMessageQueue) // forward to GUI if any + { + MsgConfigureNFMDemod *msgToGUI = MsgConfigureNFMDemod::create(settings, force); + m_guiMessageQueue->push(msgToGUI); + } + + return 200; +} diff --git a/plugins/channelrx/demodnfm/nfmdemod.h b/plugins/channelrx/demodnfm/nfmdemod.h index 9db09cd8c..73b6ada11 100644 --- a/plugins/channelrx/demodnfm/nfmdemod.h +++ b/plugins/channelrx/demodnfm/nfmdemod.h @@ -125,6 +125,11 @@ public: SWGSDRangel::SWGChannelSettings& response, QString& errorMessage); + virtual int webapiSettingsPutPatch( + bool force, + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage); + const Real *getCtcssToneSet(int& nbTones) const { nbTones = m_ctcssDetector.getNTones(); return m_ctcssDetector.getToneSet(); diff --git a/plugins/channelrx/demodnfm/nfmdemodgui.cpp b/plugins/channelrx/demodnfm/nfmdemodgui.cpp index 8ba8d8e6b..d76b18b71 100644 --- a/plugins/channelrx/demodnfm/nfmdemodgui.cpp +++ b/plugins/channelrx/demodnfm/nfmdemodgui.cpp @@ -72,7 +72,7 @@ bool NFMDemodGUI::deserialize(const QByteArray& data) } } -bool NFMDemodGUI::handleMessage(const Message& message __attribute__((unused))) +bool NFMDemodGUI::handleMessage(const Message& message) { if (NFMDemod::MsgReportCTCSSFreq::match(message)) { @@ -81,6 +81,15 @@ bool NFMDemodGUI::handleMessage(const Message& message __attribute__((unused))) //qDebug("NFMDemodGUI::handleMessage: MsgReportCTCSSFreq: %f", report.getFrequency()); return true; } + else if (NFMDemod::MsgConfigureNFMDemod::match(message)) + { + const NFMDemod::MsgConfigureNFMDemod& cfg = (NFMDemod::MsgConfigureNFMDemod&) message; + m_settings = cfg.getSettings(); + blockApplySettings(true); + displaySettings(); + blockApplySettings(false); + return true; + } return false; } diff --git a/plugins/channeltx/modnfm/nfmmod.cpp b/plugins/channeltx/modnfm/nfmmod.cpp index e50b80caa..ba69de73c 100644 --- a/plugins/channeltx/modnfm/nfmmod.cpp +++ b/plugins/channeltx/modnfm/nfmmod.cpp @@ -499,3 +499,52 @@ int NFMMod::webapiSettingsGet( apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm); return 200; } + +int NFMMod::webapiSettingsPutPatch( + bool force, + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage __attribute__((unused))) +{ + NFMModSettings settings; + settings.m_afBandwidth = response.getNfmModSettings()->getAfBandwidth(); + settings.m_audioSampleRate = response.getNfmModSettings()->getAudioSampleRate(); + settings.m_basebandSampleRate = response.getNfmModSettings()->getBasebandSampleRate(); + settings.m_channelMute = response.getNfmModSettings()->getChannelMute() != 0; + settings.m_ctcssIndex = response.getNfmModSettings()->getCtcssIndex(); + settings.m_ctcssOn = response.getNfmModSettings()->getCtcssOn() != 0; + settings.m_fmDeviation = response.getNfmModSettings()->getFmDeviation(); + settings.m_inputFrequencyOffset = response.getNfmModSettings()->getInputFrequencyOffset(); + settings.m_outputSampleRate = response.getNfmModSettings()->getOutputSampleRate(); + settings.m_playLoop = response.getNfmModSettings()->getPlayLoop() != 0; + settings.m_rfBandwidth = response.getNfmModSettings()->getRfBandwidth(); + settings.m_rgbColor = response.getNfmModSettings()->getRgbColor(); + settings.m_title = *response.getNfmModSettings()->getTitle(); + settings.m_toneFrequency = response.getNfmModSettings()->getToneFrequency(); + settings.m_volumeFactor = response.getNfmModSettings()->getVolumeFactor(); + SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getNfmModSettings()->getCwKeyer(); + CWKeyerSettings cwKeyerSettings; + cwKeyerSettings.m_loop = apiCwKeyerSettings->getLoop() != 0; + cwKeyerSettings.m_mode = (CWKeyerSettings::CWMode) apiCwKeyerSettings->getMode(); + cwKeyerSettings.m_sampleRate = apiCwKeyerSettings->getSampleRate(); + cwKeyerSettings.m_text = *apiCwKeyerSettings->getText(); + cwKeyerSettings.m_wpm = apiCwKeyerSettings->getWpm(); + m_cwKeyer.setLoop(cwKeyerSettings.m_loop); + m_cwKeyer.setMode(cwKeyerSettings.m_mode); + m_cwKeyer.setSampleRate(cwKeyerSettings.m_sampleRate); + m_cwKeyer.setText(cwKeyerSettings.m_text); + m_cwKeyer.setWPM(cwKeyerSettings.m_wpm); + + MsgConfigureNFMMod *msg = MsgConfigureNFMMod::create(settings, force); + m_inputMessageQueue.push(msg); + + if (m_guiMessageQueue) // forward to GUI if any + { + CWKeyer::MsgConfigureCWKeyer *msgCwKeyer = CWKeyer::MsgConfigureCWKeyer::create(cwKeyerSettings, force); + m_guiMessageQueue->push(msgCwKeyer); + MsgConfigureNFMMod *msgToGUI = MsgConfigureNFMMod::create(settings, force); + m_guiMessageQueue->push(msgToGUI); + } + + return 200; +} + diff --git a/plugins/channeltx/modnfm/nfmmod.h b/plugins/channeltx/modnfm/nfmmod.h index fdc50566b..9d1263dbb 100644 --- a/plugins/channeltx/modnfm/nfmmod.h +++ b/plugins/channeltx/modnfm/nfmmod.h @@ -245,6 +245,11 @@ public: SWGSDRangel::SWGChannelSettings& response, QString& errorMessage); + virtual int webapiSettingsPutPatch( + bool force, + SWGSDRangel::SWGChannelSettings& response, + QString& errorMessage); + double getMagSq() const { return m_magsq; } CWKeyer *getCWKeyer() { return &m_cwKeyer; } diff --git a/plugins/channeltx/modnfm/nfmmodgui.cpp b/plugins/channeltx/modnfm/nfmmodgui.cpp index 471a36cd6..c3fe955a4 100644 --- a/plugins/channeltx/modnfm/nfmmodgui.cpp +++ b/plugins/channeltx/modnfm/nfmmodgui.cpp @@ -103,6 +103,21 @@ bool NFMModGUI::handleMessage(const Message& message) updateWithStreamTime(); return true; } + else if (NFMMod::MsgConfigureNFMMod::match(message)) + { + const NFMMod::MsgConfigureNFMMod& cfg = (NFMMod::MsgConfigureNFMMod&) message; + m_settings = cfg.getSettings(); + blockApplySettings(true); + displaySettings(); + blockApplySettings(false); + return true; + } + else if (CWKeyer::MsgConfigureCWKeyer::match(message)) + { + const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) message; + ui->cwKeyerGUI->displaySettings(cfg.getSettings()); + return true; + } else { return false; diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.pro b/plugins/samplesink/hackrfoutput/hackrfoutput.pro index e99f4a8c7..c619666ac 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.pro +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.pro @@ -22,6 +22,7 @@ CONFIG(MINGW64):LIBHACKRFSRC = "D:\softs\hackrf\host" INCLUDEPATH += $$PWD INCLUDEPATH += ../../../sdrbase INCLUDEPATH += ../../../sdrgui +INCLUDEPATH += ../../../swagger/sdrangel/code/qt5/client INCLUDEPATH += ../../../devices !macx:INCLUDEPATH += $$LIBHACKRFSRC macx:INCLUDEPATH += /opt/local/include @@ -45,6 +46,7 @@ FORMS += hackrfoutputgui.ui LIBS += -L../../../sdrbase/$${build_subdir} -lsdrbase LIBS += -L../../../sdrgui/$${build_subdir} -lsdrgui +LIBS += -L../../../swagger/$${build_subdir} -lswagger !macx:LIBS += -L../../../libhackrf/$${build_subdir} -llibhackrf macx:LIBS += -L/opt/local/lib -lhackrf LIBS += -L../../../devices/$${build_subdir} -ldevices diff --git a/sdrbase/channel/channelsinkapi.h b/sdrbase/channel/channelsinkapi.h index 6315e4b43..ef1df8454 100644 --- a/sdrbase/channel/channelsinkapi.h +++ b/sdrbase/channel/channelsinkapi.h @@ -43,6 +43,12 @@ public: QString& errorMessage) { errorMessage = "Not implemented"; return 501; } + virtual int webapiSettingsPutPatch( + bool force __attribute__((unused)), + SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + QString& errorMessage) + { errorMessage = "Not implemented"; return 501; } + int getIndexInDeviceSet() const { return m_indexInDeviceSet; } void setIndexInDeviceSet(int indexInDeviceSet) { m_indexInDeviceSet = indexInDeviceSet; } uint64_t getUID() const { return m_uid; } diff --git a/sdrbase/channel/channelsourceapi.h b/sdrbase/channel/channelsourceapi.h index f79c45d00..383e893f4 100644 --- a/sdrbase/channel/channelsourceapi.h +++ b/sdrbase/channel/channelsourceapi.h @@ -43,6 +43,12 @@ public: QString& errorMessage) { errorMessage = "Not implemented"; return 501; } + virtual int webapiSettingsPutPatch( + bool force __attribute__((unused)), + SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + QString& errorMessage) + { errorMessage = "Not implemented"; return 501; } + int getIndexInDeviceSet() const { return m_indexInDeviceSet; } void setIndexInDeviceSet(int indexInDeviceSet) { m_indexInDeviceSet = indexInDeviceSet; } uint64_t getUID() const { return m_uid; } diff --git a/sdrbase/dsp/cwkeyer.cpp b/sdrbase/dsp/cwkeyer.cpp index 572216f57..e46008f36 100644 --- a/sdrbase/dsp/cwkeyer.cpp +++ b/sdrbase/dsp/cwkeyer.cpp @@ -21,6 +21,8 @@ #include "cwkeyer.h" #include "util/stepfunctions.h" +MESSAGE_CLASS_DEFINITION(CWKeyer::MsgConfigureCWKeyer, Message) + /** * 0: dot * 1: dash diff --git a/sdrbase/dsp/cwkeyer.h b/sdrbase/dsp/cwkeyer.h index a2c3976fe..445da213b 100644 --- a/sdrbase/dsp/cwkeyer.h +++ b/sdrbase/dsp/cwkeyer.h @@ -22,6 +22,7 @@ #include #include "util/export.h" +#include "util/message.h" #include "cwkeyersettings.h" /** @@ -49,13 +50,28 @@ class SDRANGEL_API CWKeyer : public QObject { Q_OBJECT public: -// typedef enum -// { -// CWNone, -// CWText, -// CWDots, -// CWDashes -// } CWMode; + class MsgConfigureCWKeyer : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const CWKeyerSettings& getSettings() const { return m_settings; } + bool getForce() const { return m_force; } + + static MsgConfigureCWKeyer* create(const CWKeyerSettings& settings, bool force) + { + return new MsgConfigureCWKeyer(settings, force); + } + + private: + CWKeyerSettings m_settings; + bool m_force; + + MsgConfigureCWKeyer(const CWKeyerSettings& settings, bool force) : + Message(), + m_settings(settings), + m_force(force) + { } + }; typedef enum { diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index b22db4e09..658dd4bbf 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -321,6 +321,18 @@ public: SWGSDRangel::SWGErrorResponse& error __attribute__((unused))) { return 501; } + /** + * Handler of /sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings (PUT, PATCH) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetChannelSettingsPutPatch( + int deviceSetIndex __attribute__((unused)), + int channelIndex __attribute__((unused)), + bool force __attribute__((unused)), + SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + SWGSDRangel::SWGErrorResponse& error __attribute__((unused))) + { return 501; } + static QString instanceSummaryURL; static QString instanceDevicesURL; static QString instanceChannelsURL; diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index 96a325a26..ca3ea602c 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -891,6 +891,41 @@ void WebAPIRequestMapper::devicesetChannelSettingsService( response.write(errorResponse.asJson().toUtf8()); } } + else if ((request.getMethod() == "PUT") || (request.getMethod() == "PATCH")) + { + QString jsonStr = request.getBody(); + QJsonObject jsonObject; + + if (parseJsonBody(jsonStr, jsonObject, response)) + { + SWGSDRangel::SWGChannelSettings normalResponse; + resetChannelSettings(normalResponse); + + if (validateChannelSettings(normalResponse, jsonObject)) + { + int status = m_adapter->devicesetChannelSettingsPutPatch( + deviceSetIndex, + channelIndex, + (request.getMethod() == "PUT"), // force settings on PUT + normalResponse, + errorResponse); + response.setStatus(status); + + if (status == 200) { + response.write(normalResponse.asJson().toUtf8()); + } else { + response.write(errorResponse.asJson().toUtf8()); + } + } + else + { + response.setStatus(400,"Invalid JSON request"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid JSON request"; + response.write(errorResponse.asJson().toUtf8()); + } + } + } else { response.setStatus(405,"Invalid HTTP method"); @@ -1037,6 +1072,50 @@ bool WebAPIRequestMapper::validateDeviceSettings(SWGSDRangel::SWGDeviceSettings& } } +bool WebAPIRequestMapper::validateChannelSettings(SWGSDRangel::SWGChannelSettings& channelSettings, QJsonObject& jsonObject) +{ + if (jsonObject.contains("tx")) { + channelSettings.setTx(jsonObject["tx"].toInt()); + } else { + channelSettings.setTx(0); // assume Rx + } + + if (jsonObject.contains("channelType") && jsonObject["channelType"].isString()) { + channelSettings.setChannelType(new QString(jsonObject["channelType"].toString())); + } else { + return false; + } + + QString *channelType = channelSettings.getChannelType(); + + if (*channelType == "NFMDemod") + { + if (channelSettings.getTx() == 0) + { + QJsonObject nfmDemodSettingsJsonObject = jsonObject["nfmDemodSettings"].toObject(); + channelSettings.setNfmDemodSettings(new SWGSDRangel::SWGNFMDemodSettings()); + channelSettings.getNfmDemodSettings()->fromJsonObject(nfmDemodSettingsJsonObject); + return true; + } + else { + return false; + } + } + else if (*channelType == "NFMMod") + { + if (channelSettings.getTx() != 0) + { + QJsonObject nfmModSettingsJsonObject = jsonObject["nfmModSettings"].toObject(); + channelSettings.setNfmModSettings(new SWGSDRangel::SWGNFMModSettings()); + channelSettings.getNfmModSettings()->fromJsonObject(nfmModSettingsJsonObject); + return true; + } + else { + return false; + } + } +} + void WebAPIRequestMapper::resetDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings) { deviceSettings.cleanup(); diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index cfcb7822f..dc33b9636 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -66,6 +66,7 @@ private: bool validatePresetTransfer(SWGSDRangel::SWGPresetTransfer& presetTransfer); bool validatePresetIdentifer(SWGSDRangel::SWGPresetIdentifier& presetIdentifier); bool validateDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings, QJsonObject& jsonObject); + bool validateChannelSettings(SWGSDRangel::SWGChannelSettings& deviceSettings, QJsonObject& jsonObject); bool parseJsonBody(QString& jsonStr, QJsonObject& jsonObject, qtwebapp::HttpResponse& response); diff --git a/sdrgui/gui/cwkeyergui.cpp b/sdrgui/gui/cwkeyergui.cpp index 5938d537d..b8761cd0f 100644 --- a/sdrgui/gui/cwkeyergui.cpp +++ b/sdrgui/gui/cwkeyergui.cpp @@ -27,7 +27,8 @@ CWKeyerGUI::CWKeyerGUI(QWidget* parent) : QWidget(parent), ui(new Ui::CWKeyerGUI), m_messageQueue(0), - m_cwKeyer(0) + m_cwKeyer(0), + m_doApplySettings(true) { ui->setupUi(this); } @@ -100,13 +101,13 @@ void CWKeyerGUI::on_cwTextClear_clicked(bool checked __attribute__((unused))) void CWKeyerGUI::on_cwTextEdit_editingFinished() { - m_cwKeyer->setText(ui->cwTextEdit->text()); + if (m_doApplySettings) { m_cwKeyer->setText(ui->cwTextEdit->text()); } } void CWKeyerGUI::on_cwSpeed_valueChanged(int value) { ui->cwSpeedText->setText(QString("%1").arg(value)); - m_cwKeyer->setWPM(value); + if (m_doApplySettings) { m_cwKeyer->setWPM(value); } } void CWKeyerGUI::on_playDots_toggled(bool checked) @@ -115,7 +116,7 @@ void CWKeyerGUI::on_playDots_toggled(bool checked) ui->playDashes->setEnabled(!checked); ui->playText->setEnabled(!checked); - m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDots : CWKeyerSettings::CWNone); + if (m_doApplySettings) { m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDots : CWKeyerSettings::CWNone); } } void CWKeyerGUI::on_playDashes_toggled(bool checked) @@ -124,7 +125,7 @@ void CWKeyerGUI::on_playDashes_toggled(bool checked) //ui->playDashes->setEnabled(!checked); ui->playText->setEnabled(!checked); - m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDashes : CWKeyerSettings::CWNone); + if (m_doApplySettings) { m_cwKeyer->setMode(checked ? CWKeyerSettings::CWDashes : CWKeyerSettings::CWNone); } } void CWKeyerGUI::on_playText_toggled(bool checked) @@ -133,7 +134,7 @@ void CWKeyerGUI::on_playText_toggled(bool checked) ui->playDashes->setEnabled(!checked); //ui->playText->setEnabled(!checked); - m_cwKeyer->setMode(checked ? CWKeyerSettings::CWText : CWKeyerSettings::CWNone); + if (m_doApplySettings) { m_cwKeyer->setMode(checked ? CWKeyerSettings::CWText : CWKeyerSettings::CWNone); } if (checked) { ui->playStop->setChecked(true); @@ -144,7 +145,7 @@ void CWKeyerGUI::on_playText_toggled(bool checked) void CWKeyerGUI::on_playLoopCW_toggled(bool checked) { - m_cwKeyer->setLoop(checked); + if (m_doApplySettings) { m_cwKeyer->setLoop(checked); } } void CWKeyerGUI::on_playStop_toggled(bool checked) @@ -171,3 +172,46 @@ void CWKeyerGUI::applySettings() ui->cwSpeedText->setText(QString("%1").arg(value)); m_cwKeyer->setWPM(value); } + +void CWKeyerGUI::displaySettings(const CWKeyerSettings& settings) +{ + blockApplySettings(true); + + ui->playLoopCW->setChecked(settings.m_loop); + + switch (settings.m_mode) + { + case CWKeyerSettings::CWDashes: + ui->playDots->setEnabled(false); + ui->playDashes->setEnabled(true); + ui->playText->setEnabled(false); + break; + case CWKeyerSettings::CWDots: + ui->playDots->setEnabled(true); + ui->playDashes->setEnabled(false); + ui->playText->setEnabled(false); + break; + case CWKeyerSettings::CWText: + ui->playDots->setEnabled(false); + ui->playDashes->setEnabled(false); + ui->playText->setEnabled(true); + break; + case CWKeyerSettings::CWNone: + default: + ui->playDots->setEnabled(false); + ui->playDashes->setEnabled(false); + ui->playText->setEnabled(false); + break; + } + + ui->cwTextEdit->setText(settings.m_text); + ui->cwSpeed->setValue(settings.m_wpm); + ui->cwSpeedText->setText(QString("%1").arg(settings.m_wpm)); + + blockApplySettings(false); +} + +void CWKeyerGUI::blockApplySettings(bool block) +{ + m_doApplySettings = !block; +} diff --git a/sdrgui/gui/cwkeyergui.h b/sdrgui/gui/cwkeyergui.h index 917d34ce5..32fa03048 100644 --- a/sdrgui/gui/cwkeyergui.h +++ b/sdrgui/gui/cwkeyergui.h @@ -29,6 +29,7 @@ namespace Ui { class MessageQueue; class CWKeyer; +class CWKeyerSettings; class SDRANGEL_API CWKeyerGUI : public QWidget, public Serializable { Q_OBJECT @@ -43,13 +44,17 @@ public: QByteArray serialize() const; bool deserialize(const QByteArray& data); + void displaySettings(const CWKeyerSettings& settings); + private: Ui::CWKeyerGUI* ui; MessageQueue* m_messageQueue; CWKeyer* m_cwKeyer; + bool m_doApplySettings; void applySettings(); + void blockApplySettings(bool block); private slots: void on_cwTextClear_clicked(bool checked); diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index 81b743e92..44e1333a4 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -1077,6 +1077,93 @@ int WebAPIAdapterGUI::devicesetChannelSettingsGet( } } +int WebAPIAdapterGUI::devicesetChannelSettingsPutPatch( + int deviceSetIndex, + int channelIndex, + bool force, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainWindow.m_deviceUIs.size())) + { + DeviceUISet *deviceSet = m_mainWindow.m_deviceUIs[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Rx + { + ChannelSinkAPI *channelAPI = deviceSet->m_deviceSourceAPI->getChanelAPIAt(channelIndex); + + if (channelAPI == 0) + { + error.init(); + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *response.getChannelType()) + { + return channelAPI->webapiSettingsPutPatch(force, response, *error.getMessage()); + } + else + { + error.init(); + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*response.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceSinkEngine) // Tx + { + ChannelSourceAPI *channelAPI = deviceSet->m_deviceSinkAPI->getChanelAPIAt(channelIndex); + + if (channelAPI == 0) + { + error.init(); + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *response.getChannelType()) + { + return channelAPI->webapiSettingsPutPatch(force, response, *error.getMessage()); + } + else + { + error.init(); + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*response.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } + +} + void WebAPIAdapterGUI::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList) { deviceSetList->init(); diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h index a1f82e769..d23573c19 100644 --- a/sdrgui/webapi/webapiadaptergui.h +++ b/sdrgui/webapi/webapiadaptergui.h @@ -157,6 +157,13 @@ public: SWGSDRangel::SWGChannelSettings& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelSettingsPutPatch( + int deviceSetIndex, + int channelIndex, + bool force, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error); + private: MainWindow& m_mainWindow;