From 4157f642974ec991913b23d70527a6898a74132f Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 6 Aug 2019 19:06:49 +0200 Subject: [PATCH] REST API: config: PUT (3): mapper work and rework --- sdrbase/webapi/webapiadapterinterface.h | 50 +++- sdrbase/webapi/webapirequestmapper.cpp | 295 +++++++++++++++++++++++- sdrbase/webapi/webapirequestmapper.h | 30 +++ sdrgui/webapi/webapiadaptergui.cpp | 16 +- sdrgui/webapi/webapiadaptergui.h | 7 +- 5 files changed, 382 insertions(+), 16 deletions(-) diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index bdb22f5e5..5d5eff6ad 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -21,6 +21,7 @@ #define SDRBASE_WEBAPI_WEBAPIADAPTERINTERFACE_H_ #include +#include #include #include "SWGErrorResponse.h" @@ -61,6 +62,35 @@ namespace SWGSDRangel class SDRBASE_API WebAPIAdapterInterface { public: + struct ChannelKeys + { + QStringList m_keys; + QStringList m_channelKeys; + }; + struct DeviceKeys + { + QStringList m_keys; + QStringList m_deviceKeys; + }; + struct PresetKeys + { + QStringList m_keys; + QStringList m_spectrumKeys; + QList m_channelsKeys; + QList m_devicesKeys; + }; + struct CommandKeys + { + QStringList m_keys; + }; + struct ConfigKeys + { + QStringList m_preferencesKeys; + PresetKeys m_workingPresetKeys; + QList m_presetKeys; + QList m_commandKeys; + }; + virtual ~WebAPIAdapterInterface() {} /** @@ -106,21 +136,21 @@ public: } /** - * Handler of /sdrangel/config (PUT) swagger/sdrangel/code/html2/index.html#api-Default-instanceSummary + * Handler of /sdrangel/config (PUT, PATCH) swagger/sdrangel/code/html2/index.html#api-Default-instanceSummary * returns the Http status code (default 501: not implemented) */ - virtual void instanceConfigInit() - { - } - - virtual int instanceConfigPutPreferences( - SWGSDRangel::SWGPreferences& preferences, - const QStringList& preferenceKeys, + virtual int instanceConfigPutPatch( + bool force, // PUT else PATCH + SWGSDRangel::SWGInstanceConfigResponse& query, + const ConfigKeys& configKeys, + SWGSDRangel::SWGSuccessResponse& response, SWGSDRangel::SWGErrorResponse& error ) { - (void) preferences; - (void) preferenceKeys; + (void) force; + (void) query; + (void) configKeys; + (void) response; error.init(); *error.getMessage() = QString("Function not implemented"); return 501; diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index 290aae920..81eae9ef1 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -47,6 +47,10 @@ #include "SWGSuccessResponse.h" #include "SWGErrorResponse.h" +const QMap WebAPIRequestMapper::m_channelURIToSettingsKey = { + {"sdrangel.channel.bfm", "BFMDemodSettings"} +}; + WebAPIRequestMapper::WebAPIRequestMapper(QObject* parent) : HttpRequestHandler(parent), m_adapter(0) @@ -242,7 +246,7 @@ void WebAPIRequestMapper::instanceConfigService(qtwebapp::HttpRequest& request, if (parseJsonBody(jsonStr, jsonObject, response)) { - m_adapter->instanceConfigInit(); + // TODO } else { @@ -2794,6 +2798,295 @@ bool WebAPIRequestMapper::validateAMBEDevices(SWGSDRangel::SWGAMBEDevices& ambeD return false; } +bool WebAPIRequestMapper::validateConfig(SWGSDRangel::SWGInstanceConfigResponse& config, QJsonObject& jsonObject, WebAPIAdapterInterface::ConfigKeys& configKeys) +{ + if (jsonObject.contains("preferences")) + { + SWGSDRangel::SWGPreferences *preferences = new SWGSDRangel::SWGPreferences(); + config.setPreferences(preferences); + QJsonObject preferencesJson = jsonObject["preferences"].toObject(); + configKeys.m_preferencesKeys = preferencesJson.keys(); + preferences->fromJsonObject(preferencesJson); + } + + if (jsonObject.contains("commands")) + { + QList *commands = new QList(); + config.setCommands(commands); + QJsonArray commandsJson = jsonObject["commands"].toArray(); + QJsonArray::const_iterator commandsIt = commandsJson.begin(); + + for (; commandsIt != commandsJson.end(); ++commandsIt) + { + QJsonObject commandJson = commandsIt->toObject(); + commands->append(new SWGSDRangel::SWGCommand()); + configKeys.m_commandKeys.append(WebAPIAdapterInterface::CommandKeys()); + configKeys.m_commandKeys.back().m_keys = commandJson.keys(); + commands->back()->fromJsonObject(commandJson); + } + } + + if (jsonObject.contains("workingPreset")) + { + SWGSDRangel::SWGPreset *workingPreset = new SWGSDRangel::SWGPreset(); + QJsonObject presetJson = jsonObject["workingPreset"].toObject(); + appendPresetKeys(workingPreset, presetJson, configKeys.m_workingPresetKeys); + } + + return true; +} + +bool WebAPIRequestMapper::appendPresetKeys( + SWGSDRangel::SWGPreset *preset, + const QJsonObject& presetJson, + WebAPIAdapterInterface::PresetKeys& presetKeys +) +{ + if (presetJson.contains("centerFrequency")) + { + preset->setCenterFrequency(presetJson["centerFrequency"].toInt()); + presetKeys.m_keys.append("centerFrequency"); + } + if (presetJson.contains("dcOffsetCorrection")) + { + preset->setDcOffsetCorrection(presetJson["dcOffsetCorrection"].toInt()); + presetKeys.m_keys.append("dcOffsetCorrection"); + } + if (presetJson.contains("iqImbalanceCorrection")) + { + preset->setIqImbalanceCorrection(presetJson["iqImbalanceCorrection"].toInt()); + presetKeys.m_keys.append("iqImbalanceCorrection"); + } + if (presetJson.contains("iqImbalanceCorrection")) + { + preset->setIqImbalanceCorrection(presetJson["sourcePreset"].toInt()); + presetKeys.m_keys.append("sourcePreset"); + } + if (presetJson.contains("description")) + { + preset->setDescription(new QString(presetJson["description"].toString())); + presetKeys.m_keys.append("description"); + } + if (presetJson.contains("group")) + { + preset->setGroup(new QString(presetJson["group"].toString())); + presetKeys.m_keys.append("group"); + } + + if (presetJson.contains("spectrumConfig")) + { + QJsonObject spectrumJson = presetJson["spectrumConfig"].toObject(); + presetKeys.m_spectrumKeys = spectrumJson.keys(); + SWGSDRangel::SWGGLSpectrum *spectrum = new SWGSDRangel::SWGGLSpectrum(); + preset->setSpectrumConfig(spectrum); + spectrum->fromJsonObject(spectrumJson); + } + + if (presetJson.contains("channelConfigs")) + { + QJsonArray channelsJson = presetJson["channelConfigs"].toArray(); + QJsonArray::const_iterator channelsIt = channelsJson.begin(); + QList *channels = new QList(); + preset->setChannelConfigs(channels); + + for (; channelsIt != channelsJson.end(); ++channelsIt) + { + QJsonObject channelJson = channelsIt->toObject(); + channels->append(new SWGSDRangel::SWGChannelConfig()); + presetKeys.m_channelsKeys.append(WebAPIAdapterInterface::ChannelKeys()); + + if (!appendPresetChannelKeys(channels->back(), channelJson, presetKeys.m_channelsKeys.back())) { + return false; + } + } + } + + if (presetJson.contains("deviceConfigs")) + { + QJsonArray devicesJson = presetJson["deviceConfigs"].toArray(); + QJsonArray::const_iterator devicesIt = devicesJson.begin(); + QList *devices = new QList(); + preset->setDeviceConfigs(devices); + + for (; devicesIt != devicesJson.end(); ++devicesIt) + { + QJsonObject deviceJson = devicesIt->toObject(); + devices->append(new SWGSDRangel::SWGDeviceConfig()); + presetKeys.m_devicesKeys.append(WebAPIAdapterInterface::DeviceKeys()); + + if (!appendPresetDeviceKeys(devices->back(), deviceJson, presetKeys.m_devicesKeys.back())) { + return false; + } + } + } + + return true; +} + +bool WebAPIRequestMapper::appendPresetChannelKeys( + SWGSDRangel::SWGChannelConfig *channel, + const QJsonObject& channelJson, + WebAPIAdapterInterface::ChannelKeys& channelKeys +) +{ + if (channelJson.contains("channelIdURI")) + { + QString *channelURI = new QString(channelJson["channelIdURI"].toString()); + channel->setChannelIdUri(channelURI); + channelKeys.m_keys.append("channelIdURI"); + + if (channelJson.contains("config") && m_channelURIToSettingsKey.contains(*channelURI)) + { + SWGSDRangel::SWGChannelSettings *channelSettings = new SWGSDRangel::SWGChannelSettings(); + return getChannel(m_channelURIToSettingsKey[*channelURI], channelSettings, channelJson["config"].toObject(), channelKeys.m_channelKeys); + } + else + { + return false; + } + } + else + { + return false; + } +} + +bool WebAPIRequestMapper::getChannel( + const QString& channelSettingsKey, + SWGSDRangel::SWGChannelSettings *channelSettings, + const QJsonObject& channelSettingsJson, + QStringList& channelSettingsKeys +) +{ + QStringList channelKeys = channelSettingsJson.keys(); + + if (channelKeys.contains(channelSettingsKey) && channelSettingsJson[channelSettingsKey].isObject()) + { + QJsonObject settingsJsonObject = channelSettingsJson[channelSettingsKey].toObject(); + channelSettingsKeys = settingsJsonObject.keys(); + + if (channelSettingsKey == "AMDemodSettings") + { + channelSettings->setAmDemodSettings(new SWGSDRangel::SWGAMDemodSettings()); + channelSettings->getAmDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "AMModSettings") + { + channelSettings->setAmModSettings(new SWGSDRangel::SWGAMModSettings()); + channelSettings->getAmModSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "ATVModSettings") + { + channelSettings->setAtvModSettings(new SWGSDRangel::SWGATVModSettings()); + channelSettings->getAtvModSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "BFMDemodSettings") + { + channelSettings->setBfmDemodSettings(new SWGSDRangel::SWGBFMDemodSettings()); + channelSettings->getBfmDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "DSDDemodSettings") + { + channelSettings->setDsdDemodSettings(new SWGSDRangel::SWGDSDDemodSettings()); + channelSettings->getDsdDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "FreeDVDemodSettings") + { + channelSettings->setFreeDvDemodSettings(new SWGSDRangel::SWGFreeDVDemodSettings()); + channelSettings->getFreeDvDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "FreeDVModSettings") + { + channelSettings->setFreeDvModSettings(new SWGSDRangel::SWGFreeDVModSettings()); + channelSettings->getFreeDvModSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "FreqTrackerSettings") + { + channelSettings->setFreqTrackerSettings(new SWGSDRangel::SWGFreqTrackerSettings()); + channelSettings->getFreqTrackerSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "NFMDemodSettings") + { + channelSettings->setNfmDemodSettings(new SWGSDRangel::SWGNFMDemodSettings()); + channelSettings->getNfmDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "NFMModSettings") + { + channelSettings->setNfmModSettings(new SWGSDRangel::SWGNFMModSettings()); + channelSettings->getNfmModSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "LocalSinkSettings") + { + channelSettings->setLocalSinkSettings(new SWGSDRangel::SWGLocalSinkSettings()); + channelSettings->getLocalSinkSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "LocalSourceSettings") + { + channelSettings->setLocalSourceSettings(new SWGSDRangel::SWGLocalSourceSettings()); + channelSettings->getLocalSourceSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "RemoteSinkSettings") + { + channelSettings->setRemoteSinkSettings(new SWGSDRangel::SWGRemoteSinkSettings()); + channelSettings->getRemoteSinkSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "RemoteSourceSettings") + { + channelSettings->setRemoteSourceSettings(new SWGSDRangel::SWGRemoteSourceSettings()); + channelSettings->getRemoteSourceSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "SSBDemodSettings") + { + channelSettings->setSsbDemodSettings(new SWGSDRangel::SWGSSBDemodSettings()); + channelSettings->getSsbDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "SSBModSettings") + { + channelSettings->setSsbModSettings(new SWGSDRangel::SWGSSBModSettings()); + channelSettings->getSsbModSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "UDPSourceSettings") + { + channelSettings->setUdpSourceSettings(new SWGSDRangel::SWGUDPSourceSettings()); + channelSettings->getUdpSourceSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "UDPSinkSettings") + { + channelSettings->setUdpSinkSettings(new SWGSDRangel::SWGUDPSinkSettings()); + channelSettings->getUdpSinkSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "WFMDemodSettings") + { + channelSettings->setWfmDemodSettings(new SWGSDRangel::SWGWFMDemodSettings()); + channelSettings->getWfmDemodSettings()->fromJsonObject(settingsJsonObject); + } + else if (channelSettingsKey == "WFMModSettings") + { + channelSettings->setWfmModSettings(new SWGSDRangel::SWGWFMModSettings()); + channelSettings->getWfmModSettings()->fromJsonObject(settingsJsonObject); + } + else + { + return false; + } + + return true; + } + else + { + return false; + } +} + +bool WebAPIRequestMapper::appendPresetDeviceKeys( + SWGSDRangel::SWGDeviceConfig *device, + const QJsonObject& deviceJson, + WebAPIAdapterInterface::DeviceKeys& deviceKeys +) +{ + return true; +} + void WebAPIRequestMapper::appendSettingsSubKeys( const QJsonObject& parentSettingsJsonObject, QJsonObject& childSettingsJsonObject, diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index 6229728ed..262ca88e7 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -34,6 +34,9 @@ namespace SWGSDRangel { class SWGPresetTransfer; class SWGPresetIdentifier; + class SWGPreset; + class SWGChannelConfig; + class SWGDeviceConfig; } class SDRBASE_API WebAPIRequestMapper : public qtwebapp::HttpRequestHandler { @@ -89,6 +92,31 @@ private: bool validateAudioInputDevice(SWGSDRangel::SWGAudioInputDevice& audioInputDevice, QJsonObject& jsonObject, QStringList& audioInputDeviceKeys); bool validateAudioOutputDevice(SWGSDRangel::SWGAudioOutputDevice& audioOutputDevice, QJsonObject& jsonObject, QStringList& audioOutputDeviceKeys); bool validateAMBEDevices(SWGSDRangel::SWGAMBEDevices& ambeDevices, QJsonObject& jsonObject); + bool validateConfig(SWGSDRangel::SWGInstanceConfigResponse& config, QJsonObject& jsonObject, WebAPIAdapterInterface::ConfigKeys& configKeys); + + bool appendPresetKeys( + SWGSDRangel::SWGPreset *preset, + const QJsonObject& presetJson, + WebAPIAdapterInterface::PresetKeys& presetKeys); + + bool appendPresetChannelKeys( + SWGSDRangel::SWGChannelConfig *channel, + const QJsonObject& channelJson, + WebAPIAdapterInterface::ChannelKeys& channelKeys + ); + + bool getChannel( + const QString& channelSettingsKey, + SWGSDRangel::SWGChannelSettings *channelSettings, + const QJsonObject& channelSettingsJson, + QStringList& channelSettingsKeys + ); + + bool appendPresetDeviceKeys( + SWGSDRangel::SWGDeviceConfig *device, + const QJsonObject& deviceJson, + WebAPIAdapterInterface::DeviceKeys& deviceKeys + ); void appendSettingsSubKeys( const QJsonObject& parentSettingsJsonObject, @@ -109,6 +137,8 @@ private: void resetChannelReport(SWGSDRangel::SWGChannelReport& deviceSettings); void resetAudioInputDevice(SWGSDRangel::SWGAudioInputDevice& audioInputDevice); void resetAudioOutputDevice(SWGSDRangel::SWGAudioOutputDevice& audioOutputDevice); + + static const QMap m_channelURIToSettingsKey; }; #endif /* SDRBASE_WEBAPI_WEBAPIREQUESTMAPPER_H_ */ diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index 82fd10142..99737f28b 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -117,8 +117,8 @@ int WebAPIAdapterGUI::instanceDelete( } int WebAPIAdapterGUI::instanceConfigGet( - SWGSDRangel::SWGInstanceConfigResponse& response, - SWGSDRangel::SWGErrorResponse& error) + SWGSDRangel::SWGInstanceConfigResponse& response, + SWGSDRangel::SWGErrorResponse& error) { response.init(); WebAPIAdapterBase webAPIAdapterBase; @@ -151,11 +151,19 @@ int WebAPIAdapterGUI::instanceConfigGet( return 200; } -void WebAPIAdapterGUI::instanceConfigInit() +int WebAPIAdapterGUI::instanceConfigPutPatch( + bool force, // PUT else PATCH + SWGSDRangel::SWGInstanceConfigResponse& query, + const ConfigKeys& configKeys, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) { WebAPIAdapterBase webAPIAdapterBase; webAPIAdapterBase.setPluginManager(m_mainWindow.getPluginManager()); - webAPIAdapterBase.webapiInitConfig(m_mainWindow.m_settings); + + if (force) { + webAPIAdapterBase.webapiInitConfig(m_mainWindow.m_settings); + } } int WebAPIAdapterGUI::instanceDevices( diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h index 4df9be61f..9a0b3798b 100644 --- a/sdrgui/webapi/webapiadaptergui.h +++ b/sdrgui/webapi/webapiadaptergui.h @@ -45,7 +45,12 @@ public: SWGSDRangel::SWGInstanceConfigResponse& response, SWGSDRangel::SWGErrorResponse& error); - virtual void instanceConfigInit(); + virtual int instanceConfigPutPatch( + bool force, // PUT else PATCH + SWGSDRangel::SWGInstanceConfigResponse& query, + const ConfigKeys& configKeys, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); virtual int instanceDevices( int direction,