/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2017 Edouard Griffiths, F4EXB. // // // // Swagger server adapter interface // // // // This program is free software; you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation as version 3 of the License, or // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// //#include #include #include #include #include "httpdocrootsettings.h" #include "webapirequestmapper.h" #include "SWGInstanceSummaryResponse.h" #include "SWGInstanceDevicesResponse.h" #include "SWGInstanceChannelsResponse.h" #include "SWGAudioDevices.h" #include "SWGAudioDevicesSelect.h" #include "SWGLocationInformation.h" #include "SWGDVSeralDevices.h" #include "SWGPresets.h" #include "SWGPresetTransfer.h" #include "SWGPresetIdentifier.h" #include "SWGPresetImport.h" #include "SWGPresetExport.h" #include "SWGDeviceSettings.h" #include "SWGDeviceState.h" #include "SWGChannelSettings.h" #include "SWGSuccessResponse.h" #include "SWGErrorResponse.h" WebAPIRequestMapper::WebAPIRequestMapper(QObject* parent) : HttpRequestHandler(parent), m_adapter(0) { qtwebapp::HttpDocrootSettings docrootSettings; docrootSettings.path = ":/"; m_staticFileController = new qtwebapp::StaticFileController(docrootSettings, parent); } WebAPIRequestMapper::~WebAPIRequestMapper() { delete m_staticFileController; } void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { if (m_adapter == 0) // format service unavailable if adapter is null { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); response.setStatus(500,"Service not available"); errorResponse.init(); *errorResponse.getMessage() = "Service not available"; response.write(errorResponse.asJson().toUtf8()); } else // normal processing { QByteArray path=request.getPath(); if (path == WebAPIAdapterInterface::instanceSummaryURL) { instanceSummaryService(request, response); } else if (path == WebAPIAdapterInterface::instanceDevicesURL) { instanceDevicesService(request, response); } else if (path == WebAPIAdapterInterface::instanceChannelsURL) { instanceChannelsService(request, response); } else if (path == WebAPIAdapterInterface::instanceLoggingURL) { instanceLoggingService(request, response); } else if (path == WebAPIAdapterInterface::instanceAudioURL) { instanceAudioService(request, response); } else if (path == WebAPIAdapterInterface::instanceLocationURL) { instanceLocationService(request, response); } else if (path == WebAPIAdapterInterface::instanceDVSerialURL) { instanceDVSerialService(request, response); } else if (path == WebAPIAdapterInterface::instancePresetsURL) { instancePresetsService(request, response); } else if (path == WebAPIAdapterInterface::instancePresetURL) { instancePresetService(request, response); } else if (path == WebAPIAdapterInterface::instancePresetFileURL) { instancePresetFileService(request, response); } else if (path == WebAPIAdapterInterface::instanceDeviceSetsURL) { instanceDeviceSetsService(request, response); } else if (path == WebAPIAdapterInterface::instanceDeviceSetURL) { instanceDeviceSetService(request, response); } else { std::smatch desc_match; std::string pathStr(path.constData(), path.length()); if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetURLRe)) { devicesetService(std::string(desc_match[1]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetDeviceURLRe)) { devicesetDeviceService(std::string(desc_match[1]), request, response); } else if (std::regex_match(pathStr, desc_match, WebAPIAdapterInterface::devicesetDeviceSettingsURLRe)) { 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); } else { QByteArray path = "/index.html"; response.setStatus(400, "API URL does not exist"); m_staticFileController->service(path, response); } // QDirIterator it(":", QDirIterator::Subdirectories); // while (it.hasNext()) { // qDebug() << "WebAPIRequestMapper::service: " << it.next(); // } } } } void WebAPIRequestMapper::instanceSummaryService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { SWGSDRangel::SWGInstanceSummaryResponse normalResponse; int status = m_adapter->instanceSummary(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::SWGSuccessResponse normalResponse; int status = m_adapter->instanceDelete(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()); } } void WebAPIRequestMapper::instanceDevicesService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGInstanceDevicesResponse normalResponse; SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { QByteArray txStr = request.getParameter("tx"); bool tx = false; if (txStr.length() != 0) { tx = !(txStr == "0"); } int status = m_adapter->instanceDevices(tx, 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()); } } void WebAPIRequestMapper::instanceChannelsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGInstanceChannelsResponse normalResponse; SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { QByteArray txStr = request.getParameter("tx"); bool tx = false; if (txStr.length() != 0) { tx = !(txStr == "0"); } int status = m_adapter->instanceChannels(tx, 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()); } } void WebAPIRequestMapper::instanceLoggingService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGLoggingInfo normalResponse; SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { int status = m_adapter->instanceLoggingGet(normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { response.write(normalResponse.asJson().toUtf8()); } else { response.write(errorResponse.asJson().toUtf8()); } } else if (request.getMethod() == "PUT") { QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { normalResponse.fromJson(jsonStr); int status = m_adapter->instanceLoggingPut(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 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()); } } void WebAPIRequestMapper::instanceAudioService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { SWGSDRangel::SWGAudioDevices normalResponse; int status = m_adapter->instanceAudioGet(normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { response.write(normalResponse.asJson().toUtf8()); } else { response.write(errorResponse.asJson().toUtf8()); } } else if (request.getMethod() == "PATCH") { SWGSDRangel::SWGAudioDevicesSelect normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { normalResponse.fromJson(jsonStr); int status = m_adapter->instanceAudioPatch(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 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()); } } void WebAPIRequestMapper::instanceLocationService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { SWGSDRangel::SWGLocationInformation normalResponse; int status = m_adapter->instanceLocationGet(normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { response.write(normalResponse.asJson().toUtf8()); } else { response.write(errorResponse.asJson().toUtf8()); } } else if (request.getMethod() == "PUT") { SWGSDRangel::SWGLocationInformation normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { normalResponse.fromJson(jsonStr); int status = m_adapter->instanceLocationPut(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 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()); } } void WebAPIRequestMapper::instanceDVSerialService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "PATCH") { QByteArray dvserialStr = request.getParameter("dvserial"); bool dvserial = false; if (dvserialStr.length() != 0) { dvserial = !(dvserialStr == "0"); } SWGSDRangel::SWGDVSeralDevices normalResponse; int status = m_adapter->instanceDVSerialPatch(dvserial, 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()); } } void WebAPIRequestMapper::instancePresetsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { SWGSDRangel::SWGPresets normalResponse; int status = m_adapter->instancePresetsGet(normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { response.write(normalResponse.asJson().toUtf8()); } else { response.write(errorResponse.asJson().toUtf8()); } } } void WebAPIRequestMapper::instancePresetService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "PATCH") { SWGSDRangel::SWGPresetTransfer query; SWGSDRangel::SWGPresetIdentifier normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { query.fromJson(jsonStr); if (validatePresetTransfer(query)) { int status = m_adapter->instancePresetPatch(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 if (request.getMethod() == "PUT") { SWGSDRangel::SWGPresetTransfer query; SWGSDRangel::SWGPresetIdentifier normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { query.fromJson(jsonStr); if (validatePresetTransfer(query)) { int status = m_adapter->instancePresetPut(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 if (request.getMethod() == "POST") { SWGSDRangel::SWGPresetTransfer query; SWGSDRangel::SWGPresetIdentifier normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { query.fromJson(jsonStr); if (validatePresetTransfer(query)) { int status = m_adapter->instancePresetPost(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 if (request.getMethod() == "DELETE") { SWGSDRangel::SWGPresetIdentifier normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { normalResponse.fromJson(jsonStr); if (validatePresetIdentifer(normalResponse)) { int status = m_adapter->instancePresetDelete(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()); } } void WebAPIRequestMapper::instancePresetFileService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "PUT") { SWGSDRangel::SWGPresetImport query; SWGSDRangel::SWGPresetIdentifier normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { query.fromJson(jsonStr); if (query.getFilePath()) { int status = m_adapter->instancePresetFilePut(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 query"); 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 request"; response.write(errorResponse.asJson().toUtf8()); } } else if (request.getMethod() == "POST") { SWGSDRangel::SWGPresetExport query; SWGSDRangel::SWGPresetIdentifier normalResponse; QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { query.fromJson(jsonStr); if (validatePresetExport(query)) { int status = m_adapter->instancePresetFilePost(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 query"); 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 request"; 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::instanceDeviceSetsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { SWGSDRangel::SWGDeviceSetList normalResponse; int status = m_adapter->instanceDeviceSetsGet(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()); } } void WebAPIRequestMapper::instanceDeviceSetService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "POST") { SWGSDRangel::SWGSuccessResponse normalResponse; QByteArray txStr = request.getParameter("tx"); bool tx = false; if (txStr.length() != 0) { tx = !(txStr == "0"); } int status = m_adapter->instanceDeviceSetPost(tx, 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::SWGSuccessResponse normalResponse; int status = m_adapter->instanceDeviceSetDelete(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()); } } void WebAPIRequestMapper::devicesetService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); if (request.getMethod() == "GET") { try { SWGSDRangel::SWGDeviceSet normalResponse; int deviceSetIndex = boost::lexical_cast(indexStr); int status = m_adapter->devicesetGet(deviceSetIndex, normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { 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 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::devicesetDeviceService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); try { int deviceSetIndex = boost::lexical_cast(indexStr); if (request.getMethod() == "PUT") { QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { SWGSDRangel::SWGDeviceListItem normalResponse; if (validateDeviceListItem(normalResponse, jsonObject)) { int status = m_adapter->devicesetDevicePut(deviceSetIndex, normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { response.write(normalResponse.asJson().toUtf8()); } else { response.write(errorResponse.asJson().toUtf8()); } } else { response.setStatus(400,"Missing device identification"); errorResponse.init(); *errorResponse.getMessage() = "Missing device identification"; 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 device set index"; response.setStatus(400,"Invalid data"); response.write(errorResponse.asJson().toUtf8()); } } void WebAPIRequestMapper::devicesetDeviceSettingsService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); try { int deviceSetIndex = boost::lexical_cast(indexStr); if ((request.getMethod() == "PUT") || (request.getMethod() == "PATCH")) { QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { SWGSDRangel::SWGDeviceSettings normalResponse; resetDeviceSettings(normalResponse); if (validateDeviceSettings(normalResponse, jsonObject)) { int status = m_adapter->devicesetDeviceSettingsPutPatch( deviceSetIndex, (request.getMethod() == "PUT"), // force settings on PUT 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 if (request.getMethod() == "GET") { SWGSDRangel::SWGDeviceSettings normalResponse; resetDeviceSettings(normalResponse); int status = m_adapter->devicesetDeviceSettingsGet(deviceSetIndex, 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::devicesetDeviceRunService(const std::string& indexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); try { int deviceSetIndex = boost::lexical_cast(indexStr); if (request.getMethod() == "GET") { SWGSDRangel::SWGDeviceState normalResponse; int status = m_adapter->devicesetDeviceRunGet(deviceSetIndex, 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->devicesetDeviceRunPost(deviceSetIndex, 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->devicesetDeviceRunDelete(deviceSetIndex, 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::devicesetChannelService( const std::string& deviceSetIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); try { int deviceSetIndex = boost::lexical_cast(deviceSetIndexStr); if (request.getMethod() == "POST") { QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { SWGSDRangel::SWGChannelSettings query; SWGSDRangel::SWGSuccessResponse normalResponse; resetChannelSettings(query); if (jsonObject.contains("tx")) { query.setTx(jsonObject["tx"].toInt()); } else { query.setTx(0); // assume Rx } if (jsonObject.contains("channelType") && jsonObject["channelType"].isString()) { query.setChannelType(new QString(jsonObject["channelType"].toString())); int status = m_adapter->devicesetChannelPost(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()); } } 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()); } } void WebAPIRequestMapper::devicesetChannelIndexService( const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); try { int deviceSetIndex = boost::lexical_cast(deviceSetIndexStr); int channelIndex = boost::lexical_cast(channelIndexStr); if (request.getMethod() == "DELETE") { SWGSDRangel::SWGSuccessResponse normalResponse; int status = m_adapter->devicesetChannelDelete(deviceSetIndex, channelIndex, 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 index"; response.setStatus(400,"Invalid data"); response.write(errorResponse.asJson().toUtf8()); } } void WebAPIRequestMapper::devicesetChannelSettingsService( const std::string& deviceSetIndexStr, const std::string& channelIndexStr, qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response) { SWGSDRangel::SWGErrorResponse errorResponse; response.setHeader("Content-Type", "application/json"); try { int deviceSetIndex = boost::lexical_cast(deviceSetIndexStr); int channelIndex = boost::lexical_cast(channelIndexStr); if (request.getMethod() == "GET") { SWGSDRangel::SWGChannelSettings normalResponse; resetChannelSettings(normalResponse); int status = m_adapter->devicesetChannelSettingsGet(deviceSetIndex, channelIndex, normalResponse, errorResponse); response.setStatus(status); if (status/100 == 2) { response.write(normalResponse.asJson().toUtf8()); } else { response.write(errorResponse.asJson().toUtf8()); } } else if ((request.getMethod() == "PUT") || (request.getMethod() == "PATCH")) { QString jsonStr = request.getBody(); QJsonObject jsonObject; if (parseJsonBody(jsonStr, jsonObject, response)) { SWGSDRangel::SWGChannelSettings normalResponse; resetChannelSettings(normalResponse); QStringList channelSettingsKeys; if (validateChannelSettings(normalResponse, jsonObject, channelSettingsKeys)) { int status = m_adapter->devicesetChannelSettingsPutPatch( deviceSetIndex, channelIndex, (request.getMethod() == "PUT"), // force settings on PUT channelSettingsKeys, 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; try { QByteArray jsonBytes(jsonStr.toStdString().c_str()); QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(jsonBytes, &error); if (error.error == QJsonParseError::NoError) { jsonObject = doc.object(); } else { QString errorMsg = QString("Input JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset); errorResponse.init(); *errorResponse.getMessage() = errorMsg; response.setStatus(400, errorMsg.toUtf8()); response.write(errorResponse.asJson().toUtf8()); } return (error.error == QJsonParseError::NoError); } catch (const std::exception& ex) { QString errorMsg = QString("Error parsing request: ") + ex.what(); errorResponse.init(); *errorResponse.getMessage() = errorMsg; response.setStatus(500, errorMsg.toUtf8()); response.write(errorResponse.asJson().toUtf8()); return false; } } bool WebAPIRequestMapper::validatePresetTransfer(SWGSDRangel::SWGPresetTransfer& presetTransfer) { SWGSDRangel::SWGPresetIdentifier *presetIdentifier = presetTransfer.getPreset(); if (presetIdentifier == 0) { return false; } return validatePresetIdentifer(*presetIdentifier); } bool WebAPIRequestMapper::validatePresetIdentifer(SWGSDRangel::SWGPresetIdentifier& presetIdentifier) { return (presetIdentifier.getGroupName() && presetIdentifier.getName() && presetIdentifier.getType()); } bool WebAPIRequestMapper::validatePresetExport(SWGSDRangel::SWGPresetExport& presetExport) { if (presetExport.getFilePath() == 0) { return false; } SWGSDRangel::SWGPresetIdentifier *presetIdentifier = presetExport.getPreset(); if (presetIdentifier == 0) { return false; } return validatePresetIdentifer(*presetIdentifier); } bool WebAPIRequestMapper::validateDeviceListItem(SWGSDRangel::SWGDeviceListItem& deviceListItem, QJsonObject& jsonObject) { if (jsonObject.contains("tx")) { deviceListItem.setTx(jsonObject["tx"].toInt()); } else { deviceListItem.setTx(0); // assume Rx } bool identified = false; if (jsonObject.contains("displayedName") && jsonObject["displayedName"].isString()) { deviceListItem.setDisplayedName(new QString(jsonObject["displayedName"].toString())); identified = true; } else { deviceListItem.setDisplayedName(0); } if (jsonObject.contains("hwType") && jsonObject["hwType"].isString()) { deviceListItem.setHwType(new QString(jsonObject["hwType"].toString())); identified = true; } else { deviceListItem.setHwType(0); } if (jsonObject.contains("serial") && jsonObject["serial"].isString()) { deviceListItem.setSerial(new QString(jsonObject["serial"].toString())); identified = true; } else { deviceListItem.setSerial(0); } if (jsonObject.contains("index")) { deviceListItem.setIndex(jsonObject["index"].toInt(-1)); } else { deviceListItem.setIndex(-1); } if (jsonObject.contains("sequence")){ deviceListItem.setSequence(jsonObject["sequence"].toInt(-1)); } else { deviceListItem.setSequence(-1); } if (jsonObject.contains("streamIndex")) { deviceListItem.setStreamIndex(jsonObject["streamIndex"].toInt(-1)); } else { deviceListItem.setStreamIndex(-1); } return identified; } bool WebAPIRequestMapper::validateDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings, QJsonObject& jsonObject) { if (jsonObject.contains("tx")) { deviceSettings.setTx(jsonObject["tx"].toInt()); } else { deviceSettings.setTx(0); // assume Rx } if (jsonObject.contains("deviceHwType") && jsonObject["deviceHwType"].isString()) { deviceSettings.setDeviceHwType(new QString(jsonObject["deviceHwType"].toString())); } else { return false; } QString *deviceHwType = deviceSettings.getDeviceHwType(); if (*deviceHwType == "FileSource") { if (jsonObject.contains("fileSourceSettings") && jsonObject["fileSourceSettings"].isObject()) { QJsonObject fileSourceSettingsJsonObject = jsonObject["fileSourceSettings"].toObject(); deviceSettings.setFileSourceSettings(new SWGSDRangel::SWGFileSourceSettings()); deviceSettings.getFileSourceSettings()->fromJsonObject(fileSourceSettingsJsonObject); return true; } else { return false; } } else if (*deviceHwType == "RTLSDR") { if (jsonObject.contains("rtlSdrSettings") && jsonObject["rtlSdrSettings"].isObject()) { QJsonObject rtlSdrSettingsJsonObject = jsonObject["rtlSdrSettings"].toObject(); deviceSettings.setRtlSdrSettings(new SWGSDRangel::SWGRtlSdrSettings()); deviceSettings.getRtlSdrSettings()->fromJsonObject(rtlSdrSettingsJsonObject); return true; } else { return false; } } else if ((*deviceHwType == "LimeSDR") && (deviceSettings.getTx() == 0)) { if (jsonObject.contains("limeSdrInputSettings") && jsonObject["limeSdrInputSettings"].isObject()) { QJsonObject limeSdrInputSettingsJsonObject = jsonObject["limeSdrInputSettings"].toObject(); deviceSettings.setLimeSdrInputSettings(new SWGSDRangel::SWGLimeSdrInputSettings()); deviceSettings.getLimeSdrInputSettings()->fromJsonObject(limeSdrInputSettingsJsonObject); return true; } else { return false; } } else if ((*deviceHwType == "LimeSDR") && (deviceSettings.getTx() != 0)) { if (jsonObject.contains("limeSdrOutputSettings") && jsonObject["limeSdrOutputSettings"].isObject()) { QJsonObject limeSdrOutputSettingsJsonObject = jsonObject["limeSdrOutputSettings"].toObject(); deviceSettings.setLimeSdrOutputSettings(new SWGSDRangel::SWGLimeSdrOutputSettings()); deviceSettings.getLimeSdrOutputSettings()->fromJsonObject(limeSdrOutputSettingsJsonObject); return true; } else { return false; } } else { return false; } } bool WebAPIRequestMapper::validateChannelSettings( SWGSDRangel::SWGChannelSettings& channelSettings, QJsonObject& jsonObject, QStringList& channelSettingsKeys) { if (jsonObject.contains("tx")) { channelSettings.setTx(jsonObject["tx"].toInt()); } else { channelSettings.setTx(0); // assume Rx } if (jsonObject.contains("channelType") && jsonObject["channelType"].isString()) { channelSettings.setChannelType(new QString(jsonObject["channelType"].toString())); } else { return false; } QString *channelType = channelSettings.getChannelType(); if (*channelType == "NFMDemod") { if (channelSettings.getTx() == 0) { QJsonObject nfmDemodSettingsJsonObject = jsonObject["NFMDemodSettings"].toObject(); channelSettingsKeys = nfmDemodSettingsJsonObject.keys(); channelSettings.setNfmDemodSettings(new SWGSDRangel::SWGNFMDemodSettings()); channelSettings.getNfmDemodSettings()->fromJsonObject(nfmDemodSettingsJsonObject); return true; } else { return false; } } else if (*channelType == "NFMMod") { if (channelSettings.getTx() != 0) { QJsonObject nfmModSettingsJsonObject = jsonObject["NFMModSettings"].toObject(); channelSettingsKeys = nfmModSettingsJsonObject.keys(); channelSettings.setNfmModSettings(new SWGSDRangel::SWGNFMModSettings()); channelSettings.getNfmModSettings()->fromJsonObject(nfmModSettingsJsonObject); return true; } else { return false; } } else { return false; } } void WebAPIRequestMapper::resetDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings) { deviceSettings.cleanup(); deviceSettings.setFileSourceSettings(0); deviceSettings.setRtlSdrSettings(0); deviceSettings.setLimeSdrInputSettings(0); deviceSettings.setLimeSdrOutputSettings(0); } void WebAPIRequestMapper::resetChannelSettings(SWGSDRangel::SWGChannelSettings& channelSettings) { channelSettings.cleanup(); channelSettings.setNfmDemodSettings(0); channelSettings.setNfmModSettings(0); }