diff --git a/plugins/samplemimo/testmi/testmi.cpp b/plugins/samplemimo/testmi/testmi.cpp index d15da58a5..d47fb6167 100644 --- a/plugins/samplemimo/testmi/testmi.cpp +++ b/plugins/samplemimo/testmi/testmi.cpp @@ -531,31 +531,48 @@ bool TestMI::applySettings(const TestMISettings& settings, bool force) } int TestMI::webapiRunGet( + int subsystemIndex, SWGSDRangel::SWGDeviceState& response, QString& errorMessage) { - (void) errorMessage; - m_deviceAPI->getDeviceEngineStateStr(*response.getState()); - return 200; + if (subsystemIndex == 0) + { + m_deviceAPI->getDeviceEngineStateStr(*response.getState()); // Rx only + return 200; + } + else + { + errorMessage = QString("Subsystem index invalid: expect 0 (Rx) only"); + return 404; + } } int TestMI::webapiRun( bool run, + int subsystemIndex, SWGSDRangel::SWGDeviceState& response, QString& errorMessage) { - (void) errorMessage; - m_deviceAPI->getDeviceEngineStateStr(*response.getState()); - MsgStartStop *message = MsgStartStop::create(run); - m_inputMessageQueue.push(message); - - if (m_guiMessageQueue) // forward to GUI if any + if (subsystemIndex == 0) { - MsgStartStop *msgToGUI = MsgStartStop::create(run); - m_guiMessageQueue->push(msgToGUI); + m_deviceAPI->getDeviceEngineStateStr(*response.getState()); // Rx only + MsgStartStop *message = MsgStartStop::create(run); + m_inputMessageQueue.push(message); + + if (m_guiMessageQueue) // forward to GUI if any + { + MsgStartStop *msgToGUI = MsgStartStop::create(run); + m_guiMessageQueue->push(msgToGUI); + } + + return 200; + } + else + { + errorMessage = QString("Subsystem index invalid: expect 0 (Rx) only"); + return 404; } - return 200; } int TestMI::webapiSettingsGet( diff --git a/plugins/samplemimo/testmi/testmi.h b/plugins/samplemimo/testmi/testmi.h index 18df632a5..ca1888b19 100644 --- a/plugins/samplemimo/testmi/testmi.h +++ b/plugins/samplemimo/testmi/testmi.h @@ -141,11 +141,13 @@ public: QString& errorMessage); virtual int webapiRunGet( + int subsystemIndex, SWGSDRangel::SWGDeviceState& response, QString& errorMessage); virtual int webapiRun( bool run, + int subsystemIndex, SWGSDRangel::SWGDeviceState& response, QString& errorMessage); diff --git a/sdrbase/device/deviceapi.cpp b/sdrbase/device/deviceapi.cpp index 226659acd..82de5b155 100644 --- a/sdrbase/device/deviceapi.cpp +++ b/sdrbase/device/deviceapi.cpp @@ -170,6 +170,7 @@ void DeviceAPI::removeChannelSourceAPI(ChannelAPI* channelAPI) void DeviceAPI::addMIMOChannelAPI(ChannelAPI* channelAPI) { m_mimoChannelAPIs.append(channelAPI); + renumerateChannels(); } void DeviceAPI::removeMIMOChannelAPI(ChannelAPI *channelAPI) @@ -177,6 +178,8 @@ void DeviceAPI::removeMIMOChannelAPI(ChannelAPI *channelAPI) if (m_mimoChannelAPIs.removeOne(channelAPI)) { renumerateChannels(); } + + channelAPI->setIndexInDeviceSet(-1); } void DeviceAPI::setSampleSource(DeviceSampleSource* source) diff --git a/sdrbase/dsp/devicesamplemimo.h b/sdrbase/dsp/devicesamplemimo.h index ea0c4f980..5dc56e085 100644 --- a/sdrbase/dsp/devicesamplemimo.h +++ b/sdrbase/dsp/devicesamplemimo.h @@ -104,19 +104,23 @@ public: } virtual int webapiRunGet( + int subsystemIndex, SWGSDRangel::SWGDeviceState& response, QString& errorMessage) { (void) response; + (void) subsystemIndex; errorMessage = "Not implemented"; return 501; } virtual int webapiRun(bool run, + int subsystemIndex, SWGSDRangel::SWGDeviceState& response, QString& errorMessage) { (void) run; + (void) subsystemIndex; (void) response; errorMessage = "Not implemented"; return 501; diff --git a/sdrbase/resources/webapi/doc/swagger/swagger.yaml b/sdrbase/resources/webapi/doc/swagger/swagger.yaml index 68c2e1fac..1d23129d2 100644 --- a/sdrbase/resources/webapi/doc/swagger/swagger.yaml +++ b/sdrbase/resources/webapi/doc/swagger/swagger.yaml @@ -987,7 +987,7 @@ paths: /sdrangel/deviceset/{deviceSetIndex}/device/run: x-swagger-router-controller: deviceset get: - description: get device rune status + description: get device run status for a single subsystem device (Rx or Tx) operationId: devicesetDeviceRunGet tags: - DeviceSet @@ -1015,7 +1015,7 @@ paths: "501": $ref: "#/responses/Response_501" post: - description: start device + description: start device for a single subsystem device (Rx or Tx) operationId: devicesetDeviceRunPost tags: - DeviceSet @@ -1049,7 +1049,7 @@ paths: "501": $ref: "#/responses/Response_501" delete: - description: stop device + description: stop device for a single subsystem device (Rx or Tx) operationId: devicesetDeviceRunDelete tags: - DeviceSet @@ -1083,6 +1083,120 @@ paths: "501": $ref: "#/responses/Response_501" + /sdrangel/deviceset/{deviceSetIndex}/subdevice/{subsystemIndex}/run: + x-swagger-router-controller: deviceset + get: + description: get device run status for a multi-subsystem device (Rx/Tx combination i.e. MIMO) + operationId: devicesetDeviceSubsystemRunGet + tags: + - DeviceSet + parameters: + - in: path + name: deviceSetIndex + type: integer + required: true + description: Index of device set in the device set list + - in: path + name: subsystemIndex + type: integer + required: true + description: Index of subsystem (0 for Rx, 1 for Tx) + responses: + "200": + description: On success return current state + schema: + $ref: "#/definitions/DeviceState" + "400": + description: Invalid device set index + schema: + $ref: "#/definitions/ErrorResponse" + "404": + description: Device or subsystem not found + schema: + $ref: "#/definitions/ErrorResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + post: + description: start device for a multi-subsystem device (Rx/Tx combination i.e. MIMO) + operationId: devicesetDeviceSubsystemRunPost + tags: + - DeviceSet + parameters: + - in: path + name: deviceSetIndex + type: integer + required: true + description: Index of device set in the device set list + - in: path + name: subsystemIndex + type: integer + required: true + description: Index of subsystem (0 for Rx, 1 for Tx) + - name: body + in: body + description: Originator information in the reverse API case + required: false + schema: + $ref: "/doc/swagger/include/DeviceSettings.yaml#/DeviceSettings" + responses: + "200": + description: On success return state before change + schema: + $ref: "#/definitions/DeviceState" + "400": + description: Invalid device set index + schema: + $ref: "#/definitions/ErrorResponse" + "404": + description: Device or subsystem not found + schema: + $ref: "#/definitions/ErrorResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + delete: + description: stop device for a multi-subsystem device (Rx/Tx combination i.e. MIMO) + operationId: devicesetDeviceSubsystemRunDelete + tags: + - DeviceSet + parameters: + - in: path + name: deviceSetIndex + type: integer + required: true + description: Index of device set in the device set list + - in: path + name: subsystemIndex + type: integer + required: true + description: Index of subsystem (0 for Rx, 1 for Tx) + - name: body + in: body + description: Originator information in the reverse API case + required: false + schema: + $ref: "/doc/swagger/include/DeviceSettings.yaml#/DeviceSettings" + responses: + "200": + description: On success return state before change + schema: + $ref: "#/definitions/DeviceState" + "400": + description: Invalid device set index + schema: + $ref: "#/definitions/ErrorResponse" + "404": + description: Device or subsystem not found + schema: + $ref: "#/definitions/ErrorResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + /sdrangel/deviceset/{deviceSetIndex}/device/report: x-swagger-router-controller: deviceset get: @@ -1579,11 +1693,9 @@ definitions: DeviceState: description: "Device running state" - required: - - state properties: state: - description: "State: notStarted, idle, ready, running, error" + description: "Unique state: notStarted, idle, ready, running, error" type: string SamplingDevice: diff --git a/sdrbase/webapi/webapiadapterinterface.cpp b/sdrbase/webapi/webapiadapterinterface.cpp index 30db1f828..f7e7e3ba2 100644 --- a/sdrbase/webapi/webapiadapterinterface.cpp +++ b/sdrbase/webapi/webapiadapterinterface.cpp @@ -42,7 +42,8 @@ std::regex WebAPIAdapterInterface::devicesetURLRe("^/sdrangel/deviceset/([0-9]{1 std::regex WebAPIAdapterInterface::devicesetFocusURLRe("^/sdrangel/deviceset/([0-9]{1,2})/focus$"); 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::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::devicesetChannelsReportURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channels/report$"); std::regex WebAPIAdapterInterface::devicesetChannelURLRe("^/sdrangel/deviceset/([0-9]{1,2})/channel$"); diff --git a/sdrbase/webapi/webapiadapterinterface.h b/sdrbase/webapi/webapiadapterinterface.h index a44a37f20..03e06f15a 100644 --- a/sdrbase/webapi/webapiadapterinterface.h +++ b/sdrbase/webapi/webapiadapterinterface.h @@ -677,6 +677,24 @@ public: return 501; } + /** + * Handler of /sdrangel/deviceset/{devicesetIndex}/subdevice/{subsystemIndex}/run (GET) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) + { + (void) deviceSetIndex; + (void) subsystemIndex; + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + /** * Handler of /sdrangel/deviceset/{devicesetIndex}/device/run (POST) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels * returns the Http status code (default 501: not implemented) @@ -693,6 +711,24 @@ public: return 501; } + /** + * Handler of /sdrangel/deviceset/{devicesetIndex}/subdevice/{subsystemIndex}/run (POST) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) + { + (void) deviceSetIndex; + (void) subsystemIndex; + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + /** * Handler of /sdrangel/deviceset/{devicesetIndex}/device/run (DELETE) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels * returns the Http status code (default 501: not implemented) @@ -709,6 +745,24 @@ public: return 501; } + /** + * Handler of /sdrangel/deviceset/{devicesetIndex}/subdevice/{subsystemIndex}/run (DELETE) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels + * returns the Http status code (default 501: not implemented) + */ + virtual int devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error) + { + (void) deviceSetIndex; + (void) subsystemIndex; + (void) response; + error.init(); + *error.getMessage() = QString("Function not implemented"); + return 501; + } + /** * Handler of /sdrangel/deviceset/{devicesetIndex}/device/report (GET) swagger/sdrangel/code/html2/index.html#api-Default-instanceChannels * returns the Http status code (default 501: not implemented) @@ -860,6 +914,7 @@ public: static std::regex devicesetDeviceURLRe; static std::regex devicesetDeviceSettingsURLRe; static std::regex devicesetDeviceRunURLRe; + static std::regex devicesetDeviceSubsystemRunURLRe; static std::regex devicesetDeviceReportURLRe; static std::regex devicesetChannelURLRe; static std::regex devicesetChannelIndexURLRe; diff --git a/sdrbase/webapi/webapirequestmapper.cpp b/sdrbase/webapi/webapirequestmapper.cpp index 085b80dea..f7952bf45 100644 --- a/sdrbase/webapi/webapirequestmapper.cpp +++ b/sdrbase/webapi/webapirequestmapper.cpp @@ -287,6 +287,8 @@ 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::devicesetDeviceSubsystemRunURLRe)) { + 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::devicesetChannelsReportURLRe)) { @@ -1601,6 +1603,73 @@ void WebAPIRequestMapper::devicesetDeviceRunService(const std::string& indexStr, } } +void WebAPIRequestMapper::devicesetDeviceSubsystemRunService(const std::string& indexStr, const std::string& subsystemIndexStr, 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(indexStr); + int subsystemIndex = boost::lexical_cast(subsystemIndexStr); + + if (request.getMethod() == "GET") + { + SWGSDRangel::SWGDeviceState normalResponse; + int status = m_adapter->devicesetDeviceSubsystemRunGet(deviceSetIndex, subsystemIndex, normalResponse, errorResponse); + + response.setStatus(status); + + if (status/100 == 2) { + response.write(normalResponse.asJson().toUtf8()); + } else { + response.write(errorResponse.asJson().toUtf8()); + } + } + else if (request.getMethod() == "POST") + { + SWGSDRangel::SWGDeviceState normalResponse; + int status = m_adapter->devicesetDeviceSubsystemRunPost(deviceSetIndex, subsystemIndex, normalResponse, errorResponse); + + response.setStatus(status); + + if (status/100 == 2) { + response.write(normalResponse.asJson().toUtf8()); + } else { + response.write(errorResponse.asJson().toUtf8()); + } + } + else if (request.getMethod() == "DELETE") + { + SWGSDRangel::SWGDeviceState normalResponse; + int status = m_adapter->devicesetDeviceSubsystemRunDelete(deviceSetIndex, subsystemIndex, normalResponse, errorResponse); + + response.setStatus(status); + + if (status/100 == 2) { + response.write(normalResponse.asJson().toUtf8()); + } else { + 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 device set index"; + response.setStatus(400,"Invalid data"); + response.write(errorResponse.asJson().toUtf8()); + } +} + void WebAPIRequestMapper::devicesetDeviceReportService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; diff --git a/sdrbase/webapi/webapirequestmapper.h b/sdrbase/webapi/webapirequestmapper.h index e075eed09..a72dadb71 100644 --- a/sdrbase/webapi/webapirequestmapper.h +++ b/sdrbase/webapi/webapirequestmapper.h @@ -76,6 +76,7 @@ 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 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 devicesetChannelsReportService(const std::string& deviceSetIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); void devicesetChannelService(const std::string& deviceSetIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response); diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index 91bdf0077..1583629d7 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -214,6 +214,8 @@ int WebAPIAdapterGUI::instanceDevices( nbSamplingDevices = DeviceEnumerator::instance()->getNbRxSamplingDevices(); } else if (direction == 1) { // Single Tx stream device nbSamplingDevices = DeviceEnumerator::instance()->getNbTxSamplingDevices(); + } else if (direction == 2) { // MIMO device + nbSamplingDevices = DeviceEnumerator::instance()->getNbMIMOSamplingDevices(); } else { // not supported nbSamplingDevices = 0; } @@ -229,6 +231,8 @@ int WebAPIAdapterGUI::instanceDevices( samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(i); } else if (direction == 1) { samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(i); + } else if (direction == 2) { + samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(i); } else { continue; } @@ -1458,11 +1462,36 @@ int WebAPIAdapterGUI::devicesetDeviceRunGet( response.init(); return sink->webapiRunGet(response, *error.getMessage()); } - else if (deviceSet->m_deviceMIMOEngine) // MIMO + 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::devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& 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_deviceMIMOEngine) // MIMO { DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); response.init(); - return mimo->webapiRunGet(response, *error.getMessage()); + return mimo->webapiRunGet(subsystemIndex, response, *error.getMessage()); } else { @@ -1500,11 +1529,36 @@ int WebAPIAdapterGUI::devicesetDeviceRunPost( response.init(); return sink->webapiRun(true, response, *error.getMessage()); } - else if (deviceSet->m_deviceMIMOEngine) // MIMO + 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::devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& 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_deviceMIMOEngine) // MIMO { DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); response.init(); - return mimo->webapiRun(true, response, *error.getMessage()); + return mimo->webapiRun(true, subsystemIndex, response, *error.getMessage()); } else { @@ -1542,12 +1596,6 @@ int WebAPIAdapterGUI::devicesetDeviceRunDelete( response.init(); return sink->webapiRun(false, response, *error.getMessage()); } - else if (deviceSet->m_deviceMIMOEngine) // MIMO - { - DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); - response.init(); - return mimo->webapiRun(false, response, *error.getMessage()); - } else { *error.getMessage() = QString("DeviceSet error"); @@ -1561,6 +1609,36 @@ int WebAPIAdapterGUI::devicesetDeviceRunDelete( } } +int WebAPIAdapterGUI::devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& 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_deviceMIMOEngine) // MIMO + { + DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); + response.init(); + return mimo->webapiRun(false, subsystemIndex, response, *error.getMessage()); + } + 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::devicesetDeviceReportGet( int deviceSetIndex, diff --git a/sdrgui/webapi/webapiadaptergui.h b/sdrgui/webapi/webapiadaptergui.h index 9a0b3798b..33603f5a2 100644 --- a/sdrgui/webapi/webapiadaptergui.h +++ b/sdrgui/webapi/webapiadaptergui.h @@ -219,6 +219,24 @@ public: SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceReportGet( int deviceSetIndex, SWGSDRangel::SWGDeviceReport& response, diff --git a/sdrsrv/webapi/webapiadaptersrv.cpp b/sdrsrv/webapi/webapiadaptersrv.cpp index 2bca2a6d2..97f8a5434 100644 --- a/sdrsrv/webapi/webapiadaptersrv.cpp +++ b/sdrsrv/webapi/webapiadaptersrv.cpp @@ -212,6 +212,8 @@ int WebAPIAdapterSrv::instanceDevices( nbSamplingDevices = DeviceEnumerator::instance()->getNbRxSamplingDevices(); } else if (direction == 1) { // Single Tx stream device nbSamplingDevices = DeviceEnumerator::instance()->getNbTxSamplingDevices(); + } else if (direction == 2) { // MIMO device + nbSamplingDevices = DeviceEnumerator::instance()->getNbMIMOSamplingDevices(); } else { // not supported nbSamplingDevices = 0; } @@ -228,6 +230,8 @@ int WebAPIAdapterSrv::instanceDevices( samplingDevice = DeviceEnumerator::instance()->getRxSamplingDevice(i); } else if (direction == 1) { samplingDevice = DeviceEnumerator::instance()->getTxSamplingDevice(i); + } else if (direction == 2) { + samplingDevice = DeviceEnumerator::instance()->getMIMOSamplingDevice(i); } else { continue; } @@ -1545,11 +1549,36 @@ int WebAPIAdapterSrv::devicesetDeviceRunGet( response.init(); return sink->webapiRunGet(response, *error.getMessage()); } - else if (deviceSet->m_deviceMIMOEngine) // MIMO + 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::devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& 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_deviceMIMOEngine) // MIMO { DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); response.init(); - return mimo->webapiRunGet(response, *error.getMessage()); + return mimo->webapiRunGet(subsystemIndex, response, *error.getMessage()); } else { @@ -1587,11 +1616,36 @@ int WebAPIAdapterSrv::devicesetDeviceRunPost( response.init(); return sink->webapiRun(true, response, *error.getMessage()); } - else if (deviceSet->m_deviceMIMOEngine) // MIMO + 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::devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& 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_deviceMIMOEngine) // MIMO { DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); response.init(); - return mimo->webapiRun(true, response, *error.getMessage()); + return mimo->webapiRun(true, subsystemIndex, response, *error.getMessage()); } else { @@ -1629,11 +1683,36 @@ int WebAPIAdapterSrv::devicesetDeviceRunDelete( response.init(); return sink->webapiRun(false, response, *error.getMessage()); } - else if (deviceSet->m_deviceMIMOEngine) // MIMO + 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::devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& 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_deviceMIMOEngine) // MIMO { DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO(); response.init(); - return mimo->webapiRun(false, response, *error.getMessage()); + return mimo->webapiRun(false, subsystemIndex, response, *error.getMessage()); } else { diff --git a/sdrsrv/webapi/webapiadaptersrv.h b/sdrsrv/webapi/webapiadaptersrv.h index fc5accdc0..18d864944 100644 --- a/sdrsrv/webapi/webapiadaptersrv.h +++ b/sdrsrv/webapi/webapiadaptersrv.h @@ -229,6 +229,24 @@ public: SWGSDRangel::SWGDeviceState& response, SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceSubsystemRunGet( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunPost( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + + virtual int devicesetDeviceSubsystemRunDelete( + int deviceSetIndex, + int subsystemIndex, + SWGSDRangel::SWGDeviceState& response, + SWGSDRangel::SWGErrorResponse& error); + virtual int devicesetDeviceReportGet( int deviceSetIndex, SWGSDRangel::SWGDeviceReport& response, diff --git a/swagger/sdrangel/api/swagger/swagger.yaml b/swagger/sdrangel/api/swagger/swagger.yaml index 255dd27e4..a78157619 100644 --- a/swagger/sdrangel/api/swagger/swagger.yaml +++ b/swagger/sdrangel/api/swagger/swagger.yaml @@ -987,7 +987,7 @@ paths: /sdrangel/deviceset/{deviceSetIndex}/device/run: x-swagger-router-controller: deviceset get: - description: get device rune status + description: get device run status for a single subsystem device (Rx or Tx) operationId: devicesetDeviceRunGet tags: - DeviceSet @@ -1015,7 +1015,7 @@ paths: "501": $ref: "#/responses/Response_501" post: - description: start device + description: start device for a single subsystem device (Rx or Tx) operationId: devicesetDeviceRunPost tags: - DeviceSet @@ -1049,7 +1049,7 @@ paths: "501": $ref: "#/responses/Response_501" delete: - description: stop device + description: stop device for a single subsystem device (Rx or Tx) operationId: devicesetDeviceRunDelete tags: - DeviceSet @@ -1083,6 +1083,120 @@ paths: "501": $ref: "#/responses/Response_501" + /sdrangel/deviceset/{deviceSetIndex}/subdevice/{subsystemIndex}/run: + x-swagger-router-controller: deviceset + get: + description: get device run status for a multi-subsystem device (Rx/Tx combination i.e. MIMO) + operationId: devicesetDeviceSubsystemRunGet + tags: + - DeviceSet + parameters: + - in: path + name: deviceSetIndex + type: integer + required: true + description: Index of device set in the device set list + - in: path + name: subsystemIndex + type: integer + required: true + description: Index of subsystem (0 for Rx, 1 for Tx) + responses: + "200": + description: On success return current state + schema: + $ref: "#/definitions/DeviceState" + "400": + description: Invalid device set index + schema: + $ref: "#/definitions/ErrorResponse" + "404": + description: Device or subsystem not found + schema: + $ref: "#/definitions/ErrorResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + post: + description: start device for a multi-subsystem device (Rx/Tx combination i.e. MIMO) + operationId: devicesetDeviceSubsystemRunPost + tags: + - DeviceSet + parameters: + - in: path + name: deviceSetIndex + type: integer + required: true + description: Index of device set in the device set list + - in: path + name: subsystemIndex + type: integer + required: true + description: Index of subsystem (0 for Rx, 1 for Tx) + - name: body + in: body + description: Originator information in the reverse API case + required: false + schema: + $ref: "http://localhost:8081/api/swagger/include/DeviceSettings.yaml#/DeviceSettings" + responses: + "200": + description: On success return state before change + schema: + $ref: "#/definitions/DeviceState" + "400": + description: Invalid device set index + schema: + $ref: "#/definitions/ErrorResponse" + "404": + description: Device or subsystem not found + schema: + $ref: "#/definitions/ErrorResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + delete: + description: stop device for a multi-subsystem device (Rx/Tx combination i.e. MIMO) + operationId: devicesetDeviceSubsystemRunDelete + tags: + - DeviceSet + parameters: + - in: path + name: deviceSetIndex + type: integer + required: true + description: Index of device set in the device set list + - in: path + name: subsystemIndex + type: integer + required: true + description: Index of subsystem (0 for Rx, 1 for Tx) + - name: body + in: body + description: Originator information in the reverse API case + required: false + schema: + $ref: "http://localhost:8081/api/swagger/include/DeviceSettings.yaml#/DeviceSettings" + responses: + "200": + description: On success return state before change + schema: + $ref: "#/definitions/DeviceState" + "400": + description: Invalid device set index + schema: + $ref: "#/definitions/ErrorResponse" + "404": + description: Device or subsystem not found + schema: + $ref: "#/definitions/ErrorResponse" + "500": + $ref: "#/responses/Response_500" + "501": + $ref: "#/responses/Response_501" + /sdrangel/deviceset/{deviceSetIndex}/device/report: x-swagger-router-controller: deviceset get: @@ -1579,11 +1693,9 @@ definitions: DeviceState: description: "Device running state" - required: - - state properties: state: - description: "State: notStarted, idle, ready, running, error" + description: "Unique state: notStarted, idle, ready, running, error" type: string SamplingDevice: diff --git a/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.cpp b/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.cpp index baf5f7191..511b4a054 100644 --- a/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.cpp @@ -872,6 +872,180 @@ SWGDeviceSetApi::devicesetDeviceSettingsPutCallback(SWGHttpRequestWorker * worke } } +void +SWGDeviceSetApi::devicesetDeviceSubsystemRunDelete(qint32 device_set_index, qint32 subsystem_index, SWGDeviceSettings& body) { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("/sdrangel/deviceset/{deviceSetIndex}/subdevice/{subsystemIndex}/run"); + + QString device_set_indexPathParam("{"); device_set_indexPathParam.append("deviceSetIndex").append("}"); + fullPath.replace(device_set_indexPathParam, stringValue(device_set_index)); + QString subsystem_indexPathParam("{"); subsystem_indexPathParam.append("subsystemIndex").append("}"); + fullPath.replace(subsystem_indexPathParam, stringValue(subsystem_index)); + + + SWGHttpRequestWorker *worker = new SWGHttpRequestWorker(); + SWGHttpRequestInput input(fullPath, "DELETE"); + + + + QString output = body.asJson(); + input.request_body.append(output); + + + + foreach(QString key, this->defaultHeaders.keys()) { + input.headers.insert(key, this->defaultHeaders.value(key)); + } + + connect(worker, + &SWGHttpRequestWorker::on_execution_finished, + this, + &SWGDeviceSetApi::devicesetDeviceSubsystemRunDeleteCallback); + + worker->execute(&input); +} + +void +SWGDeviceSetApi::devicesetDeviceSubsystemRunDeleteCallback(SWGHttpRequestWorker * worker) { + QString msg; + QString error_str = worker->error_str; + QNetworkReply::NetworkError error_type = worker->error_type; + + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + + + QString json(worker->response); + SWGDeviceState* output = static_cast(create(json, QString("SWGDeviceState"))); + worker->deleteLater(); + + if (worker->error_type == QNetworkReply::NoError) { + emit devicesetDeviceSubsystemRunDeleteSignal(output); + } else { + emit devicesetDeviceSubsystemRunDeleteSignalE(output, error_type, error_str); + emit devicesetDeviceSubsystemRunDeleteSignalEFull(worker, error_type, error_str); + } +} + +void +SWGDeviceSetApi::devicesetDeviceSubsystemRunGet(qint32 device_set_index, qint32 subsystem_index) { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("/sdrangel/deviceset/{deviceSetIndex}/subdevice/{subsystemIndex}/run"); + + QString device_set_indexPathParam("{"); device_set_indexPathParam.append("deviceSetIndex").append("}"); + fullPath.replace(device_set_indexPathParam, stringValue(device_set_index)); + QString subsystem_indexPathParam("{"); subsystem_indexPathParam.append("subsystemIndex").append("}"); + fullPath.replace(subsystem_indexPathParam, stringValue(subsystem_index)); + + + SWGHttpRequestWorker *worker = new SWGHttpRequestWorker(); + SWGHttpRequestInput input(fullPath, "GET"); + + + + + + foreach(QString key, this->defaultHeaders.keys()) { + input.headers.insert(key, this->defaultHeaders.value(key)); + } + + connect(worker, + &SWGHttpRequestWorker::on_execution_finished, + this, + &SWGDeviceSetApi::devicesetDeviceSubsystemRunGetCallback); + + worker->execute(&input); +} + +void +SWGDeviceSetApi::devicesetDeviceSubsystemRunGetCallback(SWGHttpRequestWorker * worker) { + QString msg; + QString error_str = worker->error_str; + QNetworkReply::NetworkError error_type = worker->error_type; + + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + + + QString json(worker->response); + SWGDeviceState* output = static_cast(create(json, QString("SWGDeviceState"))); + worker->deleteLater(); + + if (worker->error_type == QNetworkReply::NoError) { + emit devicesetDeviceSubsystemRunGetSignal(output); + } else { + emit devicesetDeviceSubsystemRunGetSignalE(output, error_type, error_str); + emit devicesetDeviceSubsystemRunGetSignalEFull(worker, error_type, error_str); + } +} + +void +SWGDeviceSetApi::devicesetDeviceSubsystemRunPost(qint32 device_set_index, qint32 subsystem_index, SWGDeviceSettings& body) { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("/sdrangel/deviceset/{deviceSetIndex}/subdevice/{subsystemIndex}/run"); + + QString device_set_indexPathParam("{"); device_set_indexPathParam.append("deviceSetIndex").append("}"); + fullPath.replace(device_set_indexPathParam, stringValue(device_set_index)); + QString subsystem_indexPathParam("{"); subsystem_indexPathParam.append("subsystemIndex").append("}"); + fullPath.replace(subsystem_indexPathParam, stringValue(subsystem_index)); + + + SWGHttpRequestWorker *worker = new SWGHttpRequestWorker(); + SWGHttpRequestInput input(fullPath, "POST"); + + + + QString output = body.asJson(); + input.request_body.append(output); + + + + foreach(QString key, this->defaultHeaders.keys()) { + input.headers.insert(key, this->defaultHeaders.value(key)); + } + + connect(worker, + &SWGHttpRequestWorker::on_execution_finished, + this, + &SWGDeviceSetApi::devicesetDeviceSubsystemRunPostCallback); + + worker->execute(&input); +} + +void +SWGDeviceSetApi::devicesetDeviceSubsystemRunPostCallback(SWGHttpRequestWorker * worker) { + QString msg; + QString error_str = worker->error_str; + QNetworkReply::NetworkError error_type = worker->error_type; + + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + + + QString json(worker->response); + SWGDeviceState* output = static_cast(create(json, QString("SWGDeviceState"))); + worker->deleteLater(); + + if (worker->error_type == QNetworkReply::NoError) { + emit devicesetDeviceSubsystemRunPostSignal(output); + } else { + emit devicesetDeviceSubsystemRunPostSignalE(output, error_type, error_str); + emit devicesetDeviceSubsystemRunPostSignalEFull(worker, error_type, error_str); + } +} + void SWGDeviceSetApi::devicesetFocusPatch(qint32 device_set_index) { QString fullPath; diff --git a/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.h b/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.h index e71fbc3ab..5f7bc2159 100644 --- a/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.h +++ b/swagger/sdrangel/code/qt5/client/SWGDeviceSetApi.h @@ -57,6 +57,9 @@ public: void devicesetDeviceSettingsGet(qint32 device_set_index); void devicesetDeviceSettingsPatch(qint32 device_set_index, SWGDeviceSettings& body); void devicesetDeviceSettingsPut(qint32 device_set_index, SWGDeviceSettings& body); + void devicesetDeviceSubsystemRunDelete(qint32 device_set_index, qint32 subsystem_index, SWGDeviceSettings& body); + void devicesetDeviceSubsystemRunGet(qint32 device_set_index, qint32 subsystem_index); + void devicesetDeviceSubsystemRunPost(qint32 device_set_index, qint32 subsystem_index, SWGDeviceSettings& body); void devicesetFocusPatch(qint32 device_set_index); void devicesetGet(qint32 device_set_index); void instanceDeviceSetDelete(); @@ -78,6 +81,9 @@ private: void devicesetDeviceSettingsGetCallback (SWGHttpRequestWorker * worker); void devicesetDeviceSettingsPatchCallback (SWGHttpRequestWorker * worker); void devicesetDeviceSettingsPutCallback (SWGHttpRequestWorker * worker); + void devicesetDeviceSubsystemRunDeleteCallback (SWGHttpRequestWorker * worker); + void devicesetDeviceSubsystemRunGetCallback (SWGHttpRequestWorker * worker); + void devicesetDeviceSubsystemRunPostCallback (SWGHttpRequestWorker * worker); void devicesetFocusPatchCallback (SWGHttpRequestWorker * worker); void devicesetGetCallback (SWGHttpRequestWorker * worker); void instanceDeviceSetDeleteCallback (SWGHttpRequestWorker * worker); @@ -99,6 +105,9 @@ signals: void devicesetDeviceSettingsGetSignal(SWGDeviceSettings* summary); void devicesetDeviceSettingsPatchSignal(SWGDeviceSettings* summary); void devicesetDeviceSettingsPutSignal(SWGDeviceSettings* summary); + void devicesetDeviceSubsystemRunDeleteSignal(SWGDeviceState* summary); + void devicesetDeviceSubsystemRunGetSignal(SWGDeviceState* summary); + void devicesetDeviceSubsystemRunPostSignal(SWGDeviceState* summary); void devicesetFocusPatchSignal(SWGSuccessResponse* summary); void devicesetGetSignal(SWGDeviceSet* summary); void instanceDeviceSetDeleteSignal(SWGSuccessResponse* summary); @@ -119,6 +128,9 @@ signals: void devicesetDeviceSettingsGetSignalE(SWGDeviceSettings* summary, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetDeviceSettingsPatchSignalE(SWGDeviceSettings* summary, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetDeviceSettingsPutSignalE(SWGDeviceSettings* summary, QNetworkReply::NetworkError error_type, QString& error_str); + void devicesetDeviceSubsystemRunDeleteSignalE(SWGDeviceState* summary, QNetworkReply::NetworkError error_type, QString& error_str); + void devicesetDeviceSubsystemRunGetSignalE(SWGDeviceState* summary, QNetworkReply::NetworkError error_type, QString& error_str); + void devicesetDeviceSubsystemRunPostSignalE(SWGDeviceState* summary, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetFocusPatchSignalE(SWGSuccessResponse* summary, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetGetSignalE(SWGDeviceSet* summary, QNetworkReply::NetworkError error_type, QString& error_str); void instanceDeviceSetDeleteSignalE(SWGSuccessResponse* summary, QNetworkReply::NetworkError error_type, QString& error_str); @@ -139,6 +151,9 @@ signals: void devicesetDeviceSettingsGetSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetDeviceSettingsPatchSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetDeviceSettingsPutSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); + void devicesetDeviceSubsystemRunDeleteSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); + void devicesetDeviceSubsystemRunGetSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); + void devicesetDeviceSubsystemRunPostSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetFocusPatchSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); void devicesetGetSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str); void instanceDeviceSetDeleteSignalEFull(SWGHttpRequestWorker* worker, QNetworkReply::NetworkError error_type, QString& error_str);