From 0e3b5581410285dbbf9fac9ae0f2de3afb32e90b Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 11 Dec 2017 01:18:10 +0100 Subject: [PATCH] Web API: /sdrangel/deviceset/{deviceSetIndex}/channel (POST) --- sdrbase/webapi/webapiadapterinterface.cpp | 2 + sdrbase/webapi/webapiadapterinterface.h | 23 ++++ sdrbase/webapi/webapirequestmapper.cpp | 102 ++++++++++++++++- sdrbase/webapi/webapirequestmapper.h | 2 + sdrgui/mainwindow.cpp | 11 ++ sdrgui/mainwindow.h | 26 +++++ sdrgui/webapi/webapiadaptergui.cpp | 130 ++++++++++++++++++++++ sdrgui/webapi/webapiadaptergui.h | 5 + 8 files changed, 300 insertions(+), 1 deletion(-) diff --git a/sdrbase/webapi/webapiadapterinterface.cpp b/sdrbase/webapi/webapiadapterinterface.cpp index 7d3be9406..47dd2310b 100644 --- a/sdrbase/webapi/webapiadapterinterface.cpp +++ b/sdrbase/webapi/webapiadapterinterface.cpp @@ -32,4 +32,6 @@ std::regex WebAPIAdapterInterface::devicesetURLRe("^/sdrangel/deviceset/([0-9]{1 std::regex WebAPIAdapterInterface::devicesetDeviceURLRe("^/sdrangel/deviceset/([0-9]{1,2})/device$"); std::regex WebAPIAdapterInterface::devicesetDeviceSettingsURLRe("^/sdrangel/deviceset/([0-9]{1,2})/device/settings$"); std::regex WebAPIAdapterInterface::devicesetDeviceRunURLRe("^/sdrangel/deviceset/([0-9]{1,2})/device/run"); +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$"); diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index 5f9611bc5..b22db4e09 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -289,6 +289,27 @@ public: SWGSDRangel::SWGErrorResponse& error __attribute__((unused))) { return 501; } + /** + * Handler of /sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings (GET) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetChannelPost( + int deviceSetIndex __attribute__((unused)), + SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + SWGSDRangel::SWGErrorResponse& error __attribute__((unused))) + { return 501; } + + /** + * Handler of /sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings (GET) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetChannelIndexDelete( + int deviceSetIndex __attribute__((unused)), + int channelIndex __attribute__((unused)), + SWGSDRangel::SWGChannelSettings& response __attribute__((unused)), + SWGSDRangel::SWGErrorResponse& error __attribute__((unused))) + { return 501; } + /** * Handler of /sdrangel/deviceset/{deviceSetIndex}/channel/{channelIndex}/settings (GET) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels * returns the Http status code (default 501: not implemented) @@ -313,6 +334,8 @@ public: static std::regex devicesetDeviceURLRe; static std::regex devicesetDeviceSettingsURLRe; static std::regex devicesetDeviceRunURLRe; + static std::regex devicesetChannelURLRe; + static std::regex devicesetChannelIndexURLRe; static std::regex devicesetChannelSettingsURLRe; }; diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index e2813ce1a..e511490e5 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -96,6 +96,10 @@ void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::Http devicesetDeviceSettingsService(std::string(desc_match[1]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetDeviceRunURLRe)) { devicesetDeviceRunService(std::string(desc_match[1]), request, response); + } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelURLRe)) { + devicesetChannelService(std::string(desc_match[1]), request, response); + } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelIndexURLRe)) { + devicesetChannelIndexService(std::string(desc_match[1]), std::string(desc_match[2]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetChannelSettingsURLRe)) { devicesetChannelSettingsService(std::string(desc_match[1]), std::string(desc_match[2]), request, response); } @@ -644,7 +648,6 @@ void WebAPIRequestMapper::devicesetDeviceSettingsService(const std::string& inde { QString jsonStr = request.getBody(); QJsonObject jsonObject; - qDebug("WebAPIRequestMapper::devicesetDeviceSettingsService: %s", qPrintable(jsonStr)); if (parseJsonBody(jsonStr, jsonObject, response)) { @@ -765,6 +768,103 @@ void WebAPIRequestMapper::devicesetDeviceRunService(const std::string& indexStr, } } +void WebAPIRequestMapper::devicesetChannelService( + const std::string& deviceSetIndexStr, + qtwebapp::HttpRequest& request, + qtwebapp::HttpResponse& response) +{ + SWGSDRangel::SWGErrorResponse errorResponse; + + try + { + int deviceSetIndex = boost::lexical_cast(deviceSetIndexStr); + + if (request.getMethod() == "POST") + { + QString jsonStr = request.getBody(); + QJsonObject jsonObject; + + if (parseJsonBody(jsonStr, jsonObject, response)) + { + SWGSDRangel::SWGChannelSettings normalResponse; + resetChannelSettings(normalResponse); + + if (jsonObject.contains("tx")) { + normalResponse.setTx(jsonObject["tx"].toInt()); + } else { + normalResponse.setTx(0); // assume Rx + } + + if (jsonObject.contains("channelType") && jsonObject["channelType"].isString()) + { + normalResponse.setChannelType(new QString(jsonObject["deviceHwType"].toString())); + + int status = m_adapter->devicesetChannelPost(deviceSetIndex, 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()); + } + } + } + } + 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()); + } +} + +void WebAPIRequestMapper::devicesetChannelIndexService( + const std::string& deviceSetIndexStr, + const std::string& channelIndexStr, + qtwebapp::HttpRequest& request, + qtwebapp::HttpResponse& response) +{ + SWGSDRangel::SWGErrorResponse errorResponse; + + try + { + int deviceSetIndex = boost::lexical_cast(deviceSetIndexStr); + int channelIndex = boost::lexical_cast(channelIndexStr); + + if (request.getMethod() == "DELETE") + { + SWGSDRangel::SWGChannelSettings normalResponse; + resetChannelSettings(normalResponse); + int status = m_adapter->devicesetChannelIndexDelete(deviceSetIndex, channelIndex, normalResponse, errorResponse); + + response.setStatus(status); + + if (status == 200) { + response.write(normalResponse.asJson().toUtf8()); + } else { + 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()); + } +} + void WebAPIRequestMapper::devicesetChannelSettingsService( const std::string& deviceSetIndexStr, const std::string& channelIndexStr, diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index 6f42b66f9..cfcb7822f 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -59,6 +59,8 @@ private: void devicesetDeviceService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetDeviceSettingsService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetDeviceRunService(const std::string& indexStr, 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); bool validatePresetTransfer(SWGSDRangel::SWGPresetTransfer& presetTransfer); diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index eb73f9c2f..898a6e4f5 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -68,6 +68,7 @@ MESSAGE_CLASS_DEFINITION(MainWindow::MsgDeletePreset, Message) MESSAGE_CLASS_DEFINITION(MainWindow::MsgAddDeviceSet, Message) MESSAGE_CLASS_DEFINITION(MainWindow::MsgRemoveLastDeviceSet, Message) MESSAGE_CLASS_DEFINITION(MainWindow::MsgSetDevice, Message) +MESSAGE_CLASS_DEFINITION(MainWindow::MsgAddChannel, Message) MainWindow *MainWindow::m_instance = 0; @@ -744,6 +745,16 @@ bool MainWindow::handleMessage(const Message& cmd) return true; } + else if (MsgAddChannel::match(cmd)) + { + MsgAddChannel& notif = (MsgAddChannel&) cmd; + ui->tabInputsSelect->setCurrentIndex(notif.getDeviceSetIndex()); + DeviceUISet *deviceUI = m_deviceUIs[notif.getDeviceSetIndex()]; + deviceUI->m_samplingDeviceControl->getChannelSelector()->setCurrentIndex(notif.getChannelRegistrationIndex()); + on_channel_addClicked(true); + + return true; + } return false; } diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 3cc5c5cb3..560c7beae 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -214,6 +214,32 @@ private: { } }; + class MsgAddChannel : public Message { + MESSAGE_CLASS_DECLARATION + + public: + int getDeviceSetIndex() const { return m_deviceSetIndex; } + int getChannelRegistrationIndex() const { return m_channelRegistrationIndex; } + bool isTx() const { return m_tx; } + + static MsgAddChannel* create(int deviceSetIndex, int channelRegistrationIndex, bool tx) + { + return new MsgAddChannel(deviceSetIndex, channelRegistrationIndex, tx); + } + + private: + int m_deviceSetIndex; + int m_channelRegistrationIndex; + bool m_tx; + + MsgAddChannel(int deviceSetIndex, int channelRegistrationIndex, bool tx) : + Message(), + m_deviceSetIndex(deviceSetIndex), + m_channelRegistrationIndex(channelRegistrationIndex), + m_tx(tx) + { } + }; + enum { PGroup, PItem diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index e53e9f136..81b743e92 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -887,6 +887,136 @@ int WebAPIAdapterGUI::devicesetDeviceRunDelete( } } +int WebAPIAdapterGUI::devicesetChannelPost( + int deviceSetIndex, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainWindow.m_deviceUIs.size())) + { + DeviceUISet *deviceSet = m_mainWindow.m_deviceUIs[deviceSetIndex]; + + if (response.getTx() == 0) // Rx + { + if (deviceSet->m_deviceSourceEngine == 0) + { + error.init(); + *error.getMessage() = QString("Device set at %1 is not a receive device set").arg(deviceSetIndex); + return 400; + } + + PluginAPI::ChannelRegistrations *channelRegistrations = m_mainWindow.m_pluginManager->getRxChannelRegistrations(); + int nbRegistrations = channelRegistrations->size(); + int index = 0; + for (; index < nbRegistrations; index++) + { + if (channelRegistrations->at(index).m_channelId == *response.getChannelType()) { + break; + } + } + + if (index < nbRegistrations) + { + MainWindow::MsgAddChannel *msg = MainWindow::MsgAddChannel::create(deviceSetIndex, index, false); + m_mainWindow.m_inputMessageQueue.push(msg); + + usleep(100000); + + int nbChannels = deviceSet->m_deviceSourceAPI->getNbChannels(); + + if (nbChannels > 0) + { + ChannelSinkAPI *channelAPI = deviceSet->m_deviceSourceAPI->getChanelAPIAt(nbChannels-1); + if (channelAPI == 0) + { + error.init(); + *error.getMessage() = QString("Expected channel not found"); + return 500; + } + else + { + return channelAPI->webapiSettingsGet(response, *error.getMessage()); + } + } + else + { + error.init(); + *error.getMessage() = QString("No channels for device set"); + return 500; + } + } + else + { + error.init(); + *error.getMessage() = QString("There is no receive channel with id %1").arg(*response.getChannelType()); + return 404; + } + } + else // Tx + { + if (deviceSet->m_deviceSinkEngine == 0) + { + error.init(); + *error.getMessage() = QString("Device set at %1 is not a transmit device set").arg(deviceSetIndex); + return 400; + } + + PluginAPI::ChannelRegistrations *channelRegistrations = m_mainWindow.m_pluginManager->getTxChannelRegistrations(); + int nbRegistrations = channelRegistrations->size(); + int index = 0; + for (; index < nbRegistrations; index++) + { + if (channelRegistrations->at(index).m_channelId == *response.getChannelType()) { + break; + } + } + + if (index < nbRegistrations) + { + MainWindow::MsgAddChannel *msg = MainWindow::MsgAddChannel::create(deviceSetIndex, index, true); + m_mainWindow.m_inputMessageQueue.push(msg); + + usleep(100000); + + int nbChannels = deviceSet->m_deviceSinkAPI->getNbChannels(); + + if (nbChannels > 0) + { + ChannelSourceAPI *channelAPI = deviceSet->m_deviceSinkAPI->getChanelAPIAt(nbChannels-1); + if (channelAPI == 0) + { + error.init(); + *error.getMessage() = QString("Expected channel not found"); + return 500; + } + else + { + return channelAPI->webapiSettingsGet(response, *error.getMessage()); + } + } + else + { + error.init(); + *error.getMessage() = QString("No channels for device set"); + return 500; + } + } + else + { + error.init(); + *error.getMessage() = QString("There is no transmit channel with id %1").arg(*response.getChannelType()); + return 404; + } + } + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + return 404; + } +} + int WebAPIAdapterGUI::devicesetChannelSettingsGet( int deviceSetIndex, int channelIndex, diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h index 9fa72d659..a1f82e769 100644 --- a/sdrgui/webapi/webapiadaptergui.h +++ b/sdrgui/webapi/webapiadaptergui.h @@ -146,6 +146,11 @@ public: SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelPost( + int deviceSetIndex, + SWGSDRangel::SWGChannelSettings& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetChannelSettingsGet( int deviceSetIndex, int channelIndex,