From 3bfdd49b4f03bd6e304d82396ba767f691200aad Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 27 Nov 2017 08:14:07 +0100 Subject: [PATCH] Web API: /sdrangel/deviceset/{index}/device (PUT) implementation --- sdrbase/webapi/webapiadapterinterface.h | 11 ++++ sdrbase/webapi/webapirequestmapper.cpp | 44 +++++++++++++ sdrbase/webapi/webapirequestmapper.h | 1 + sdrgui/mainwindow.cpp | 16 +++++ sdrgui/mainwindow.h | 26 ++++++++ sdrgui/webapi/webapiadaptergui.cpp | 77 +++++++++++++++++++++++ sdrgui/webapi/webapiadaptergui.h | 5 ++ swagger/sdrangel/api/swagger/swagger.yaml | 15 ++++- 8 files changed, 192 insertions(+), 3 deletions(-) diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index 570e41801..8b1305e40 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -37,6 +37,7 @@ namespace Swagger class SWGPresetIdentifier; class SWGDeviceSetList; class SWGDeviceSet; + class SWGDeviceListItem; class SWGErrorResponse; } @@ -224,6 +225,16 @@ public: Swagger::SWGErrorResponse& error __attribute__((unused))) { return 501; } + /** + * Handler of /sdrangel/devicesets (DELETE) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetDevicePut( + int deviceSetIndex __attribute__((unused)), + Swagger::SWGDeviceListItem& response __attribute__((unused)), + Swagger::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 18c24a7ac..d5ef4546b 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -87,6 +87,8 @@ void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::Http if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetURLRe)) { deviceset(std::string(desc_match[1]), request, response); + } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetDeviceURLRe)) { + devicesetDevice(std::string(desc_match[1]), request, response); } else { @@ -571,6 +573,48 @@ void WebAPIRequestMapper::deviceset(const std::string& indexStr, qtwebapp::HttpR } } +void WebAPIRequestMapper::devicesetDevice(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) +{ + Swagger::SWGErrorResponse errorResponse; + + try + { + int deviceSetIndex = boost::lexical_cast(indexStr); + + if (request.getMethod() == "PUT") + { + Swagger::SWGDeviceListItem normalResponse; + QString jsonStr = request.getBody(); + + if (parseJsonBody(jsonStr, response)) + { + normalResponse.fromJson(jsonStr); + + int status = m_adapter->devicesetDevicePut(deviceSetIndex, normalResponse, errorResponse); + response.setStatus(status); + + if (status == 200) { + response.write(normalResponse.asJson().toUtf8()); + } else { + response.write(errorResponse.asJson().toUtf8()); + } + } + } + else + { + response.setStatus(405,"Invalid HTTP method"); + response.write("Invalid HTTP method"); + } + } + 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()); + } +} + bool WebAPIRequestMapper::parseJsonBody(QString& jsonStr, qtwebapp::HttpResponse& response) { Swagger::SWGErrorResponse errorResponse; diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index 097a8d3b5..1d58deea6 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -56,6 +56,7 @@ private: void instanceDeviceSetsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void deviceset(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); + void devicesetDevice(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); bool validatePresetTransfer(Swagger::SWGPresetTransfer& presetTransfer); bool validatePresetIdentifer(Swagger::SWGPresetIdentifier& presetIdentifier); diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index cd620e498..eb73f9c2f 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -67,6 +67,7 @@ MESSAGE_CLASS_DEFINITION(MainWindow::MsgSavePreset, Message) MESSAGE_CLASS_DEFINITION(MainWindow::MsgDeletePreset, Message) MESSAGE_CLASS_DEFINITION(MainWindow::MsgAddDeviceSet, Message) MESSAGE_CLASS_DEFINITION(MainWindow::MsgRemoveLastDeviceSet, Message) +MESSAGE_CLASS_DEFINITION(MainWindow::MsgSetDevice, Message) MainWindow *MainWindow::m_instance = 0; @@ -728,6 +729,21 @@ bool MainWindow::handleMessage(const Message& cmd) return true; } + else if (MsgSetDevice::match(cmd)) + { + MsgSetDevice& notif = (MsgSetDevice&) cmd; + ui->tabInputsSelect->setCurrentIndex(notif.getDeviceSetIndex()); + DeviceUISet *deviceUI = m_deviceUIs[notif.getDeviceSetIndex()]; + deviceUI->m_samplingDeviceControl->setSelectedDeviceIndex(notif.getDeviceIndex()); + + if (notif.isTx()) { + on_sampleSink_changed(); + } else { + on_sampleSource_changed(); + } + + return true; + } return false; } diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index d0095f873..3cc5c5cb3 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -188,6 +188,32 @@ private: { } }; + class MsgSetDevice : public Message { + MESSAGE_CLASS_DECLARATION + + public: + int getDeviceSetIndex() const { return m_deviceSetIndex; } + int getDeviceIndex() const { return m_deviceIndex; } + bool isTx() const { return m_tx; } + + static MsgSetDevice* create(int deviceSetIndex, int deviceIndex, bool tx) + { + return new MsgSetDevice(deviceSetIndex, deviceIndex, tx); + } + + private: + int m_deviceSetIndex; + int m_deviceIndex; + bool m_tx; + + MsgSetDevice(int deviceSetIndex, int deviceIndex, bool tx) : + Message(), + m_deviceSetIndex(deviceSetIndex), + m_deviceIndex(deviceIndex), + m_tx(tx) + { } + }; + enum { PGroup, PItem diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index 7dbbbc9b2..ad6fdbf47 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -614,6 +614,83 @@ int WebAPIAdapterGUI::devicesetGet( } } +int WebAPIAdapterGUI::devicesetDevicePut( + int deviceSetIndex, + Swagger::SWGDeviceListItem& response, + Swagger::SWGErrorResponse& error) +{ + if ((deviceSetIndex >= 0) && (deviceSetIndex < (int) m_mainWindow.m_deviceUIs.size())) + { + DeviceUISet *deviceSet = m_mainWindow.m_deviceUIs[deviceSetIndex]; + + if ((response.getTx() == 0) && (deviceSet->m_deviceSinkEngine)) + { + *error.getMessage() = QString("Device type (Rx) and device set type (Tx) mismatch"); + return 404; + } + + if ((response.getTx() != 0) && (deviceSet->m_deviceSourceEngine)) + { + *error.getMessage() = QString("Device type (Tx) and device set type (Rx) mismatch"); + return 404; + } + + int nbSamplingDevices = response.getTx() != 0 ? DeviceEnumerator::instance()->getNbTxSamplingDevices() : DeviceEnumerator::instance()->getNbRxSamplingDevices(); + int tx = response.getTx(); + + for (int i = 0; i < nbSamplingDevices; i++) + { + PluginInterface::SamplingDevice samplingDevice = response.getTx() ? DeviceEnumerator::instance()->getTxSamplingDevice(i) : DeviceEnumerator::instance()->getRxSamplingDevice(i); + + if (response.getDisplayedName() && (*response.getDisplayedName() != samplingDevice.displayedName)) { + continue; + } + + if (response.getHwType() && (*response.getHwType() != samplingDevice.hardwareId)) { + continue; + } + + if ((response.getSequence() >= 0) && (response.getSequence() != samplingDevice.sequence)) { + continue; + } + + if (response.getSerial() && (*response.getSerial() != samplingDevice.serial)) { + continue; + } + + if ((response.getStreamIndex() >= 0) && (response.getStreamIndex() != samplingDevice.deviceItemIndex)) { + continue; + } + + MainWindow::MsgSetDevice *msg = MainWindow::MsgSetDevice::create(deviceSetIndex, i, response.getTx() != 0); + m_mainWindow.m_inputMessageQueue.push(msg); + + response.init(); + *response.getDisplayedName() = samplingDevice.displayedName; + *response.getHwType() = samplingDevice.hardwareId; + *response.getSerial() = samplingDevice.serial; + response.setSequence(samplingDevice.sequence); + response.setTx(tx); + response.setNbStreams(samplingDevice.deviceNbItems); + response.setStreamIndex(samplingDevice.deviceItemIndex); + response.setDeviceSetIndex(deviceSetIndex); + response.setIndex(i); + + return 200; + } + + *error.getMessage() = QString("Device not found"); + return 404; + } + else + { + error.init(); + *error.getMessage() = QString("There is no device set with index %1").arg(deviceSetIndex); + + return 404; + } +} + void WebAPIAdapterGUI::getDeviceSetList(Swagger::SWGDeviceSetList* deviceSetList) { deviceSetList->init(); diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h index 5a8a74e96..f5fc8a040 100644 --- a/sdrgui/webapi/webapiadaptergui.h +++ b/sdrgui/webapi/webapiadaptergui.h @@ -115,6 +115,11 @@ public: Swagger::SWGDeviceSet& response, Swagger::SWGErrorResponse& error); + virtual int devicesetDevicePut( + int deviceSetIndex, + Swagger::SWGDeviceListItem& response, + Swagger::SWGErrorResponse& error); + private: MainWindow& m_mainWindow; diff --git a/swagger/sdrangel/api/swagger/swagger.yaml b/swagger/sdrangel/api/swagger/swagger.yaml index 5a6be6d13..d7eeb35d6 100644 --- a/swagger/sdrangel/api/swagger/swagger.yaml +++ b/swagger/sdrangel/api/swagger/swagger.yaml @@ -466,11 +466,21 @@ paths: type: integer required: true description: Index of device set in the device set list + - name: body + in: body + description: Device item to look for. Give values for only the fields you want to search for among displayedName, hwType, serial, sequence and deviceSetIndex. For integers except tx set to -1 to ignore the field. It will match the first device found. + required: true + schema: + $ref: "#/definitions/DeviceListItem" responses: "200": - description: On success return details on the device set + description: On success return details on the device schema: - $ref: "#/definitions/DeviceSet" + $ref: "#/definitions/DeviceListItem" + "400": + description: Device set and device type mismatch (Rx vs Tx) + schema: + $ref: "#/definitions/ErrorResponse" "404": description: Invalid device set index or device not found schema: @@ -549,7 +559,6 @@ definitions: DeviceListItem: description: "Summarized information about attached hardware device" required: - - hwType - tx properties: displayedName: