From 07c11edb87c860500a045064c635c9b9c5d8c24a Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 9 Mar 2020 04:01:23 +0100 Subject: [PATCH] REST API device and channel actions: general implementation and RTLSDR and FileSource implementations --- plugins/channeltx/filesource/filesource.cpp | 21 ++ plugins/channeltx/filesource/filesource.h | 4 + plugins/samplesource/rtlsdr/rtlsdrinput.cpp | 21 ++ plugins/samplesource/rtlsdr/rtlsdrinput.h | 4 + sdrbase/channel/channelapi.h | 12 + sdrbase/dsp/devicesamplemimo.h | 10 + sdrbase/dsp/devicesamplesink.h | 10 + sdrbase/dsp/devicesamplesource.h | 10 + sdrbase/webapi/webapiadapterinterface.cpp | 2 + sdrbase/webapi/webapiadapterinterface.h | 43 ++++ sdrbase/webapi/webapirequestmapper.cpp | 173 +++++++++++++ sdrbase/webapi/webapirequestmapper.h | 6 +- sdrgui/webapi/webapiadaptergui.cpp | 260 +++++++++++++++++++- sdrgui/webapi/webapiadaptergui.h | 13 + sdrsrv/webapi/webapiadaptersrv.cpp | 259 +++++++++++++++++++ sdrsrv/webapi/webapiadaptersrv.h | 13 + 16 files changed, 859 insertions(+), 2 deletions(-) diff --git a/plugins/channeltx/filesource/filesource.cpp b/plugins/channeltx/filesource/filesource.cpp index 192f73b61..ef0d55c91 100644 --- a/plugins/channeltx/filesource/filesource.cpp +++ b/plugins/channeltx/filesource/filesource.cpp @@ -25,6 +25,7 @@ #include "SWGChannelSettings.h" #include "SWGChannelReport.h" +#include "SWGChannelActions.h" #include "SWGFileSourceReport.h" #include "device/deviceapi.h" @@ -377,6 +378,26 @@ int FileSource::webapiReportGet( return 200; } +int FileSource::webapiActionsPost( + SWGSDRangel::SWGChannelActions& query, + QString& errorMessage) +{ + SWGSDRangel::SWGFileSourceActions *swgFileSourceActions = query.getFileSourceActions(); + + if (swgFileSourceActions) + { + bool play = swgFileSourceActions->getPlay() != 0; + FileSourceBaseband::MsgConfigureFileSourceWork *msg = FileSourceBaseband::MsgConfigureFileSourceWork::create(play); + m_basebandSource->getInputMessageQueue()->push(msg); + return 202; + } + else + { + errorMessage = "Missing FileSourceActions key in JSON body"; + return 400; + } +} + void FileSource::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const FileSourceSettings& settings) { if (response.getFileSourceSettings()->getFileName()) { diff --git a/plugins/channeltx/filesource/filesource.h b/plugins/channeltx/filesource/filesource.h index a79e42dc5..b91eb7f55 100644 --- a/plugins/channeltx/filesource/filesource.h +++ b/plugins/channeltx/filesource/filesource.h @@ -205,6 +205,10 @@ public: SWGSDRangel::SWGChannelReport& response, QString& errorMessage); + virtual int webapiActionsPost( + SWGSDRangel::SWGChannelActions& query, + QString& errorMessage); + static void webapiFormatChannelSettings( SWGSDRangel::SWGChannelSettings& response, const FileSourceSettings& settings); diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp index b8903a07e..7a1f485ba 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp @@ -27,6 +27,7 @@ #include "SWGRtlSdrSettings.h" #include "SWGDeviceState.h" #include "SWGDeviceReport.h" +#include "SWGDeviceActions.h" #include "SWGRtlSdrReport.h" #include "rtlsdrinput.h" @@ -755,6 +756,26 @@ int RTLSDRInput::webapiReportGet( return 200; } +int RTLSDRInput::webapiActionsPost( + SWGSDRangel::SWGDeviceActions& query, + QString& errorMessage) +{ + SWGSDRangel::SWGRtlSdrActions *swgRtlSdrActions = query.getRtlSdrActions(); + + if (swgRtlSdrActions) + { + bool record = swgRtlSdrActions->getRecord() != 0; + MsgFileRecord *msg = MsgFileRecord::create(record); + getInputMessageQueue()->push(msg); + return 202; + } + else + { + errorMessage = "Missing RtlSdrActions key in JSON body"; + return 400; + } +} + void RTLSDRInput::webapiFormatDeviceReport(SWGSDRangel::SWGDeviceReport& response) { response.getRtlSdrReport()->setGains(new QList); diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.h b/plugins/samplesource/rtlsdr/rtlsdrinput.h index ca051125f..c3135c9cc 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.h +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.h @@ -131,6 +131,10 @@ public: SWGSDRangel::SWGDeviceReport& response, QString& errorMessage); + virtual int webapiActionsPost( + SWGSDRangel::SWGDeviceActions& actions, + QString& errorMessage); + virtual int webapiRunGet( SWGSDRangel::SWGDeviceState& response, QString& errorMessage); diff --git a/sdrbase/channel/channelapi.h b/sdrbase/channel/channelapi.h index 98f231c56..e2e995a38 100644 --- a/sdrbase/channel/channelapi.h +++ b/sdrbase/channel/channelapi.h @@ -32,6 +32,7 @@ namespace SWGSDRangel { class SWGChannelSettings; class SWGChannelReport; + class SWGChannelActions; } class SDRBASE_API ChannelAPI { @@ -93,6 +94,17 @@ public: errorMessage = "Not implemented"; return 501; } + /** + * API adapter for the channel actions POST requests + */ + virtual int webapiActionsPost( + SWGSDRangel::SWGChannelActions& query, + QString& errorMessage) + { + (void) query; + errorMessage = "Not implemented"; return 501; + } + int getIndexInDeviceSet() const { return m_indexInDeviceSet; } void setIndexInDeviceSet(int indexInDeviceSet) { m_indexInDeviceSet = indexInDeviceSet; } int getDeviceSetIndex() const { return m_deviceSetIndex; } diff --git a/sdrbase/dsp/devicesamplemimo.h b/sdrbase/dsp/devicesamplemimo.h index 5dc56e085..087494e89 100644 --- a/sdrbase/dsp/devicesamplemimo.h +++ b/sdrbase/dsp/devicesamplemimo.h @@ -33,6 +33,7 @@ namespace SWGSDRangel class SWGDeviceSettings; class SWGDeviceState; class SWGDeviceReport; + class SWGDeviceActions; } class SDRBASE_API DeviceSampleMIMO : public QObject { @@ -135,6 +136,15 @@ public: return 501; } + virtual int webapiActionsPost( + SWGSDRangel::SWGDeviceActions& actions, + QString& errorMessage) + { + (void) actions; + errorMessage = "Not implemented"; + return 501; + } + MIMOType getMIMOType() const { return m_mimoType; } MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } virtual void setMessageQueueToGUI(MessageQueue *queue) = 0; // pure virtual so that child classes must have to deal with this diff --git a/sdrbase/dsp/devicesamplesink.h b/sdrbase/dsp/devicesamplesink.h index 98cdb89fa..7b09a51d6 100644 --- a/sdrbase/dsp/devicesamplesink.h +++ b/sdrbase/dsp/devicesamplesink.h @@ -31,6 +31,7 @@ namespace SWGSDRangel class SWGDeviceSettings; class SWGDeviceState; class SWGDeviceReport; + class SWGDeviceActions; } class SDRBASE_API DeviceSampleSink : public QObject { @@ -111,6 +112,15 @@ public: return 501; } + virtual int webapiActionsPost( + SWGSDRangel::SWGDeviceActions& actions, + QString& errorMessage) + { + (void) actions; + errorMessage = "Not implemented"; + return 501; + } + MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } virtual void setMessageQueueToGUI(MessageQueue *queue) = 0; // pure virtual so that child classes must have to deal with this MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } diff --git a/sdrbase/dsp/devicesamplesource.h b/sdrbase/dsp/devicesamplesource.h index e468202f5..dfcc00bf0 100644 --- a/sdrbase/dsp/devicesamplesource.h +++ b/sdrbase/dsp/devicesamplesource.h @@ -32,6 +32,7 @@ namespace SWGSDRangel class SWGDeviceSettings; class SWGDeviceState; class SWGDeviceReport; + class SWGDeviceActions; } class SDRBASE_API DeviceSampleSource : public QObject { @@ -117,6 +118,15 @@ public: return 501; } + virtual int webapiActionsPost( + SWGSDRangel::SWGDeviceActions& actions, + QString& errorMessage) + { + (void) actions; + errorMessage = "Not implemented"; + return 501; + } + MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } virtual void setMessageQueueToGUI(MessageQueue *queue) = 0; // pure virtual so that child classes must have to deal with this MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; } diff --git a/sdrbase/webapi/webapiadapterinterface.cpp b/sdrbase/webapi/webapiadapterinterface.cpp index 83638b46b..83b6484e9 100644 --- a/sdrbase/webapi/webapiadapterinterface.cpp +++ b/sdrbase/webapi/webapiadapterinterface.cpp @@ -49,11 +49,13 @@ std::regex WebAPIAdapterInterface::devicesetDeviceSettingsURLRe("^/sdrangel/devi std::regex WebAPIAdapterInterface::devicesetDeviceRunURLRe("^/sdrangel/deviceset/([0-9]{1,2})/device/run$"); std::regex WebAPIAdapterInterface::devicesetDeviceSubsystemRunURLRe("^/sdrangel/deviceset/([0-9]{1,2})/subdevice/([0-9]{1,2})/run$"); std::regex WebAPIAdapterInterface::devicesetDeviceReportURLRe("^/sdrangel/deviceset/([0-9]{1,2})/device/report$"); +std::regex WebAPIAdapterInterface::devicesetDeviceActionsURLRe("^/sdrangel/deviceset/([0-9]{1,2})/device/actions$"); std::regex WebAPIAdapterInterface::devicesetChannelsReportURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channels/report$"); std::regex WebAPIAdapterInterface::devicesetChannelURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channel$"); std::regex WebAPIAdapterInterface::devicesetChannelIndexURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channel/([0-9]{1,2})$"); std::regex WebAPIAdapterInterface::devicesetChannelSettingsURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channel/([0-9]{1,2})/settings$"); std::regex WebAPIAdapterInterface::devicesetChannelReportURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channel/([0-9]{1,2})/report"); +std::regex WebAPIAdapterInterface::devicesetChannelActionsURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channel/([0-9]{1,2})/actions"); void WebAPIAdapterInterface::ConfigKeys::debug() const { diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index fe15430eb..eacb89fce 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -56,9 +56,11 @@ namespace SWGSDRangel class SWGDeviceSettings; class SWGDeviceState; class SWGDeviceReport; + class SWGDeviceActions; class SWGChannelsDetail; class SWGChannelSettings; class SWGChannelReport; + class SWGChannelActions; class SWGSuccessResponse; } @@ -876,6 +878,25 @@ public: return 501; } + /** + * Handler of /sdrangel/deviceset/{deviceSetIndex}/device/actions (POST) + * post action(s) on device + */ + virtual int devicesetDeviceActionsPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error + ) + { + (void) deviceSetIndex; + (void) query; + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + /** * Handler of /sdrangel/deviceset/{deviceSetIndex}/channel (POST) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels * returns the Http status code (default 501: not implemented) @@ -972,6 +993,26 @@ public: return 501; } + /** + * Handler of /sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/actions (POST) + * posts an action on the channel (default 501: not implemented) + */ + virtual int devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) + { + (void) deviceSetIndex; + (void) channelIndex; + (void) query; + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + static QString instanceSummaryURL; static QString instanceConfigURL; static QString instanceDevicesURL; @@ -1001,10 +1042,12 @@ public: static std::regex devicesetDeviceRunURLRe; static std::regex devicesetDeviceSubsystemRunURLRe; static std::regex devicesetDeviceReportURLRe; + static std::regex devicesetDeviceActionsURLRe; static std::regex devicesetChannelURLRe; static std::regex devicesetChannelIndexURLRe; static std::regex devicesetChannelSettingsURLRe; static std::regex devicesetChannelReportURLRe; + static std::regex devicesetChannelActionsURLRe; static std::regex devicesetChannelsReportURLRe; }; diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index a8eb05537..ff7a0b973 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -44,9 +44,11 @@ #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" #include "SWGDeviceReport.h" +#include "SWGDeviceActions.h" #include "SWGChannelsDetail.h" #include "SWGChannelSettings.h" #include "SWGChannelReport.h" +#include "SWGChannelActions.h" #include "SWGSuccessResponse.h" #include "SWGErrorResponse.h" @@ -297,6 +299,8 @@ void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::Http devicesetDeviceSubsystemRunService(std::string(desc_match[1]), std::string(desc_match[2]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetDeviceReportURLRe)) { devicesetDeviceReportService(std::string(desc_match[1]), request, response); + } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetDeviceActionsURLRe)) { + devicesetDeviceActionsService(std::string(desc_match[1]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelsReportURLRe)) { devicesetChannelsReportService(std::string(desc_match[1]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelURLRe)) { @@ -1912,6 +1916,77 @@ void WebAPIRequestMapper::devicesetDeviceReportService(const std::string& indexS } } +void WebAPIRequestMapper::devicesetDeviceActionsService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) +{ + SWGSDRangel::SWGErrorResponse errorResponse; + response.setHeader("Content-Type", "application/json"); + response.setHeader("Access-Control-Allow-Origin", "*"); + + if (request.getMethod() == "POST") + { + try + { + QString jsonStr = request.getBody(); + QJsonObject jsonObject; + + if (parseJsonBody(jsonStr, jsonObject, response)) + { + SWGSDRangel::SWGDeviceActions query; + SWGSDRangel::SWGSuccessResponse normalResponse; + int deviceSetIndex = boost::lexical_cast(indexStr); + resetDeviceActions(query); + + if (jsonObject.contains("direction")) { + query.setDirection(jsonObject["direction"].toInt()); + } else { + query.setDirection(0); // assume Rx + } + + if (jsonObject.contains("deviceHwType") && jsonObject["deviceHwType"].isString()) + { + query.setDeviceHwType(new QString(jsonObject["deviceHwType"].toString())); + int status = m_adapter->devicesetDeviceActionsPost(deviceSetIndex, query, normalResponse, errorResponse); + response.setStatus(status); + + if (status/100 == 2) { + 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(400,"Invalid JSON format"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid JSON format"; + response.write(errorResponse.asJson().toUtf8()); + } + } + catch (const boost::bad_lexical_cast &e) + { + errorResponse.init(); + *errorResponse.getMessage() = "Wrong integer conversion on device set index"; + response.setStatus(400,"Invalid data"); + response.write(errorResponse.asJson().toUtf8()); + } + } + else + { + response.setStatus(405,"Invalid HTTP method"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid HTTP method"; + response.write(errorResponse.asJson().toUtf8()); + } +} + void WebAPIRequestMapper::devicesetChannelsReportService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; @@ -2189,6 +2264,13 @@ void WebAPIRequestMapper::devicesetChannelReportService( response.write(errorResponse.asJson().toUtf8()); } } + else + { + response.setStatus(405,"Invalid HTTP method"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid HTTP method"; + response.write(errorResponse.asJson().toUtf8()); + } } catch (const boost::bad_lexical_cast &e) { @@ -2199,6 +2281,83 @@ void WebAPIRequestMapper::devicesetChannelReportService( } } +void WebAPIRequestMapper::devicesetChannelActtionsService( + const std::string& deviceSetIndexStr, + const std::string& channelIndexStr, + qtwebapp::HttpRequest& request, + qtwebapp::HttpResponse& response) +{ + SWGSDRangel::SWGErrorResponse errorResponse; + response.setHeader("Content-Type", "application/json"); + response.setHeader("Access-Control-Allow-Origin", "*"); + + try + { + int deviceSetIndex = boost::lexical_cast(deviceSetIndexStr); + int channelIndex = boost::lexical_cast(channelIndexStr); + + if (request.getMethod() == "POST") + { + QString jsonStr = request.getBody(); + QJsonObject jsonObject; + + if (parseJsonBody(jsonStr, jsonObject, response)) + { + SWGSDRangel::SWGChannelActions query; + SWGSDRangel::SWGSuccessResponse normalResponse; + resetChannelActions(query); + + if (jsonObject.contains("direction")) { + query.setDirection(jsonObject["direction"].toInt()); + } else { + query.setDirection(0); // assume Rx + } + + if (jsonObject.contains("channelType") && jsonObject["channelType"].isString()) + { + query.setChannelType(new QString(jsonObject["channelType"].toString())); + int status = m_adapter->devicesetChannelActionsPost(deviceSetIndex, channelIndex, query, normalResponse, errorResponse); + response.setStatus(status); + + if (status/100 == 2) { + 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(400,"Invalid JSON format"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid JSON format"; + response.write(errorResponse.asJson().toUtf8()); + } + } + else + { + response.setStatus(405,"Invalid HTTP method"); + errorResponse.init(); + *errorResponse.getMessage() = "Invalid HTTP method"; + response.write(errorResponse.asJson().toUtf8()); + } + } + catch(const boost::bad_lexical_cast &e) + { + errorResponse.init(); + *errorResponse.getMessage() = "Wrong integer conversion on index"; + response.setStatus(400,"Invalid data"); + response.write(errorResponse.asJson().toUtf8()); + } +} + bool WebAPIRequestMapper::parseJsonBody(QString& jsonStr, QJsonObject& jsonObject, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; @@ -3237,6 +3396,13 @@ void WebAPIRequestMapper::resetDeviceReport(SWGSDRangel::SWGDeviceReport& device deviceReport.setSdrPlayReport(nullptr); } +void WebAPIRequestMapper::resetDeviceActions(SWGSDRangel::SWGDeviceActions& deviceActions) +{ + deviceActions.cleanup(); + deviceActions.setDeviceHwType(nullptr); + deviceActions.setRtlSdrActions(nullptr); +} + void WebAPIRequestMapper::resetChannelSettings(SWGSDRangel::SWGChannelSettings& channelSettings) { channelSettings.cleanup(); @@ -3278,6 +3444,13 @@ void WebAPIRequestMapper::resetChannelReport(SWGSDRangel::SWGChannelReport& chan channelReport.setWfmModReport(nullptr); } +void WebAPIRequestMapper::resetChannelActions(SWGSDRangel::SWGChannelActions& channelActions) +{ + channelActions.cleanup(); + channelActions.setChannelType(nullptr); + channelActions.setFileSourceActions(nullptr); +} + void WebAPIRequestMapper::resetAudioInputDevice(SWGSDRangel::SWGAudioInputDevice& audioInputDevice) { audioInputDevice.cleanup(); diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index a20a89cd1..c61bfe2ba 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -82,11 +82,13 @@ private: void devicesetDeviceRunService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetDeviceSubsystemRunService(const std::string& indexStr, const std::string& subsystemIndexStr,qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetDeviceReportService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); + void devicesetDeviceActionsService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetChannelsReportService(const std::string& deviceSetIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetChannelService(const std::string& deviceSetIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetChannelIndexService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetChannelSettingsService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetChannelReportService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); + void devicesetChannelActtionsService(const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); bool validatePresetTransfer(SWGSDRangel::SWGPresetTransfer& presetTransfer); bool validatePresetIdentifer(SWGSDRangel::SWGPresetIdentifier& presetIdentifier); @@ -146,8 +148,10 @@ private: void resetDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings); void resetDeviceReport(SWGSDRangel::SWGDeviceReport& deviceReport); + void resetDeviceActions(SWGSDRangel::SWGDeviceActions& deviceActions); void resetChannelSettings(SWGSDRangel::SWGChannelSettings& deviceSettings); - void resetChannelReport(SWGSDRangel::SWGChannelReport& deviceSettings); + void resetChannelReport(SWGSDRangel::SWGChannelReport& channelReport); + void resetChannelActions(SWGSDRangel::SWGChannelActions& channelActions); void resetAudioInputDevice(SWGSDRangel::SWGAudioInputDevice& audioInputDevice); void resetAudioOutputDevice(SWGSDRangel::SWGAudioOutputDevice& audioOutputDevice); diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index 065da5590..2b3b337f8 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -58,9 +58,11 @@ #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" #include "SWGDeviceReport.h" +#include "SWGDeviceActions.h" #include "SWGChannelsDetail.h" #include "SWGChannelSettings.h" #include "SWGChannelReport.h" +#include "SWGChannelActions.h" #include "SWGSuccessResponse.h" #include "SWGErrorResponse.h" #include "SWGDeviceState.h" @@ -1565,6 +1567,109 @@ int WebAPIAdapterGUI::devicesetDeviceSettingsGet( } } +int WebAPIAdapterGUI::devicesetDeviceActionsPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainWindow.m_deviceUIs.size())) + { + DeviceUISet *deviceSet = m_mainWindow.m_deviceUIs[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + if (query.getDirection() != 0) + { + *error.getMessage() = QString("Single Rx device found but other type of device requested"); + return 400; + } + if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 input").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + int res = source->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + if (query.getDirection() != 1) + { + *error.getMessage() = QString("Single Tx device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + int res = sink->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + if (query.getDirection() != 2) + { + *error.getMessage() = QString("MIMO device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + int res = mimo->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + int WebAPIAdapterGUI::devicesetDeviceSettingsPutPatch( int deviceSetIndex, bool force, @@ -2281,6 +2386,160 @@ int WebAPIAdapterGUI::devicesetChannelReportGet( } } +int WebAPIAdapterGUI::devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainWindow.m_deviceUIs.size())) + { + DeviceUISet *deviceSet = m_mainWindow.m_deviceUIs[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + ChannelAPI *channelAPI = nullptr; + + if ((query.getDirection() == 0) && (channelIndex < nbSinkChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + } + else if ((query.getDirection() == 1) && (channelIndex < nbSinkChannels + nbSourceChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex - nbSinkChannels); + } + else if ((query.getDirection() == 2) && (channelIndex < nbSinkChannels + nbSourceChannels + nbMIMOChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(channelIndex - nbSinkChannels - nbSourceChannels); + } + else + { + *error.getMessage() = QString("here is no channel with index %1").arg(channelIndex); + return 404; + } + + if (channelAPI) + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(query, *error.getMessage()); + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + else + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + int WebAPIAdapterGUI::devicesetChannelSettingsPutPatch( int deviceSetIndex, int channelIndex, @@ -2414,7 +2673,6 @@ int WebAPIAdapterGUI::devicesetChannelSettingsPutPatch( *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); return 404; } - } void WebAPIAdapterGUI::getDeviceSetList(SWGSDRangel::SWGDeviceSetList* deviceSetList) diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h index 8679b28b3..de9f4fbc8 100644 --- a/sdrgui/webapi/webapiadaptergui.h +++ b/sdrgui/webapi/webapiadaptergui.h @@ -223,6 +223,12 @@ public: SWGSDRangel::SWGDeviceSettings& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceActionsPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceSettingsPutPatch( int deviceSetIndex, bool force, @@ -291,6 +297,13 @@ public: SWGSDRangel::SWGChannelSettings& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelSettingsPutPatch( int deviceSetIndex, int channelIndex, diff --git a/sdrsrv/webapi/webapiadaptersrv.cpp b/sdrsrv/webapi/webapiadaptersrv.cpp index 22c5da222..1953c4f58 100644 --- a/sdrsrv/webapi/webapiadaptersrv.cpp +++ b/sdrsrv/webapi/webapiadaptersrv.cpp @@ -36,9 +36,11 @@ #include "SWGPresets.h" #include "SWGPresetTransfer.h" #include "SWGDeviceSettings.h" +#include "SWGDeviceActions.h" #include "SWGChannelsDetail.h" #include "SWGChannelSettings.h" #include "SWGChannelReport.h" +#include "SWGChannelActions.h" #include "SWGSuccessResponse.h" #include "SWGErrorResponse.h" #include "SWGDeviceState.h" @@ -1662,6 +1664,109 @@ int WebAPIAdapterSrv::devicesetDeviceSettingsGet( } } +int WebAPIAdapterSrv::devicesetDeviceActionsPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + if (query.getDirection() != 0) + { + *error.getMessage() = QString("Single Rx device found but other type of device requested"); + return 400; + } + if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 input").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); + int res = source->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + if (query.getDirection() != 1) + { + *error.getMessage() = QString("Single Tx device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink(); + int res = sink->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + if (query.getDirection() != 2) + { + *error.getMessage() = QString("MIMO device found but other type of device requested"); + return 400; + } + else if (deviceSet->m_deviceAPI->getHardwareId() != *query.getDeviceHwType()) + { + *error.getMessage() = QString("Device mismatch. Found %1 output").arg(deviceSet->m_deviceAPI->getHardwareId()); + return 400; + } + else + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + int res = mimo->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + int WebAPIAdapterSrv::devicesetDeviceSettingsPutPatch( int deviceSetIndex, bool force, @@ -2377,6 +2482,160 @@ int WebAPIAdapterSrv::devicesetChannelReportGet( } } +int WebAPIAdapterSrv::devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error) +{ + error.init(); + + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainCore.m_deviceSets.size())) + { + DeviceSet *deviceSet = m_mainCore.m_deviceSets[deviceSetIndex]; + + if (deviceSet->m_deviceSourceEngine) // Single Rx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceSinkEngine) // Single Tx + { + ChannelAPI *channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex); + + if (channelAPI == 0) + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + else + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(query, *error.getMessage()); + + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + } + else if (deviceSet->m_deviceMIMOEngine) // MIMO + { + int nbSinkChannels = deviceSet->m_deviceAPI->getNbSinkChannels(); + int nbSourceChannels = deviceSet->m_deviceAPI->getNbSourceChannels(); + int nbMIMOChannels = deviceSet->m_deviceAPI->getNbMIMOChannels(); + ChannelAPI *channelAPI = nullptr; + + if ((query.getDirection() == 0) && (channelIndex < nbSinkChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSinkAPIAt(channelIndex); + } + else if ((query.getDirection() == 1) && (channelIndex < nbSinkChannels + nbSourceChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getChanelSourceAPIAt(channelIndex - nbSinkChannels); + } + else if ((query.getDirection() == 2) && (channelIndex < nbSinkChannels + nbSourceChannels + nbMIMOChannels)) + { + channelAPI = deviceSet->m_deviceAPI->getMIMOChannelAPIAt(channelIndex - nbSinkChannels - nbSourceChannels); + } + else + { + *error.getMessage() = QString("here is no channel with index %1").arg(channelIndex); + return 404; + } + + if (channelAPI) + { + QString channelType; + channelAPI->getIdentifier(channelType); + + if (channelType == *query.getChannelType()) + { + int res = channelAPI->webapiActionsPost(query, *error.getMessage()); + if (res/100 == 2) + { + response.init(); + *response.getMessage() = QString("Message to post action was submitted successfully"); + } + + return res; + } + else + { + *error.getMessage() = QString("There is no channel type %1 at index %2. Found %3.") + .arg(*query.getChannelType()) + .arg(channelIndex) + .arg(channelType); + return 404; + } + } + else + { + *error.getMessage() = QString("There is no channel with index %1").arg(channelIndex); + return 404; + } + } + else + { + *error.getMessage() = QString("DeviceSet error"); + return 500; + } + } + else + { + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + int WebAPIAdapterSrv::devicesetChannelSettingsPutPatch( int deviceSetIndex, int channelIndex, diff --git a/sdrsrv/webapi/webapiadaptersrv.h b/sdrsrv/webapi/webapiadaptersrv.h index f2688833c..cf2d743db 100644 --- a/sdrsrv/webapi/webapiadaptersrv.h +++ b/sdrsrv/webapi/webapiadaptersrv.h @@ -233,6 +233,12 @@ public: SWGSDRangel::SWGDeviceSettings& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceActionsPost( + int deviceSetIndex, + SWGSDRangel::SWGDeviceActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceSettingsPutPatch( int deviceSetIndex, bool force, @@ -301,6 +307,13 @@ public: SWGSDRangel::SWGChannelSettings& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelActionsPost( + int deviceSetIndex, + int channelIndex, + SWGSDRangel::SWGChannelActions& query, + SWGSDRangel::SWGSuccessResponse& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelSettingsPutPatch( int deviceSetIndex, int channelIndex,