diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index d9a5b5ec56..fbdb49e1a7 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -17,10 +17,18 @@ if (NOT SERVER_MODE)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
+ if(WIN32 AND Qt6_FOUND)
+ # https://bugreports.qt.io/browse/QTBUG-124589
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_RUNTIME_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_RUNTIME_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_RUNTIME_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_RUNTIME_DIR}")
+ else()
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINS_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINS_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINS_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINS_DIR}")
+ endif()
else()
if(WIN32)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
@@ -32,10 +40,17 @@ else()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
- set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
+ if(WIN32 AND Qt6_FOUND)
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_RUNTIME_DIR}")
+ else()
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${BUILD_PLUGINSSRV_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${BUILD_PLUGINSSRV_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${BUILD_PLUGINSSRV_DIR}")
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO "${BUILD_PLUGINSSRV_DIR}")
+ endif()
endif()
if (ENABLE_CHANNELMIMO)
diff --git a/plugins/channelrx/demodadsb/adsbdemodgui.cpp b/plugins/channelrx/demodadsb/adsbdemodgui.cpp
index 9f54f4116a..462124b475 100644
--- a/plugins/channelrx/demodadsb/adsbdemodgui.cpp
+++ b/plugins/channelrx/demodadsb/adsbdemodgui.cpp
@@ -5935,9 +5935,6 @@ void ADSBDemodGUI::applyImportSettings()
void ADSBDemodGUI::import()
{
QString urlString = "https://";
- if (!m_settings.m_importUsername.isEmpty() && !m_settings.m_importPassword.isEmpty()) {
- urlString = urlString + m_settings.m_importUsername + ":" + m_settings.m_importPassword + "@";
- }
urlString = urlString + m_settings.m_importHost + "/api/states/all";
QChar join = '?';
if (!m_settings.m_importParameters.isEmpty())
@@ -5965,7 +5962,13 @@ void ADSBDemodGUI::import()
urlString = urlString + join + "lomax=" + m_settings.m_importMaxLongitude;
join = '&';
}
- m_networkManager->get(QNetworkRequest(QUrl(urlString)));
+ QNetworkRequest request = QNetworkRequest(QUrl(urlString));
+ if (!m_settings.m_importUsername.isEmpty() && !m_settings.m_importPassword.isEmpty())
+ {
+ QByteArray encoded = (m_settings.m_importUsername + ":" + m_settings.m_importPassword).toLocal8Bit().toBase64();
+ request.setRawHeader("Authorization", "Basic " + encoded);
+ }
+ m_networkManager->get(request);
}
// Handle opensky-network API call reply
diff --git a/plugins/channelrx/demodadsb/flags.qrc b/plugins/channelrx/demodadsb/flags.qrc
index 3c9d5dab4f..0dcf50d6f9 100644
--- a/plugins/channelrx/demodadsb/flags.qrc
+++ b/plugins/channelrx/demodadsb/flags.qrc
@@ -205,7 +205,7 @@
getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "CTRL", ~settings.m_gpioDir, 0xff); // 0 for GPIO, 1 for ATR + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "DDR", settings.m_gpioDir, 0xff); // 0 for input, 1 for output + qDebug() << "USRPOutput::applySettings: set GPIO dir to " << settings.m_gpioDir; + } + } + + if (settingsKeys.contains("gpioPins") || force) + { + if (m_deviceShared.m_deviceParams->getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "OUT", settings.m_gpioPins, 0xff); + qDebug() << "USRPOutput::applySettings: set GPIO pins to " << settings.m_gpioPins; + } + } + if (settingsKeys.contains("useReverseAPI")) { bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || @@ -1036,6 +1055,12 @@ void USRPOutput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getUsrpOutputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getUsrpOutputSettings()->getGpioDir(); + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getUsrpOutputSettings()->getGpioPins(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getUsrpOutputSettings()->getUseReverseApi() != 0; } @@ -1072,6 +1097,8 @@ void USRPOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& resp response.getUsrpOutputSettings()->setLpfBw(settings.m_lpfBW); response.getUsrpOutputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getUsrpOutputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getUsrpOutputSettings()->setGpioDir(settings.m_gpioDir); + response.getUsrpOutputSettings()->setGpioPins(settings.m_gpioPins); response.getUsrpOutputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getUsrpOutputSettings()->getReverseApiAddress()) { @@ -1172,6 +1199,12 @@ void USRPOutput::webapiReverseSendSettings(const QList& deviceSettingsK if (deviceSettingsKeys.contains("transverterMode") || force) { swgUsrpOutputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); } + if (deviceSettingsKeys.contains("gpioDir") || force) { + swgUsrpOutputSettings->setGpioDir(settings.m_gpioDir); + } + if (deviceSettingsKeys.contains("gpioPins") || force) { + swgUsrpOutputSettings->setGpioPins(settings.m_gpioPins); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp b/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp index c762072670..a726884fae 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp @@ -40,6 +40,8 @@ void USRPOutputSettings::resetToDefaults() m_clockSource = "internal"; m_transverterMode = false; m_transverterDeltaFrequency = 0; + m_gpioDir = 0; + m_gpioPins = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -63,6 +65,8 @@ QByteArray USRPOutputSettings::serialize() const s.writeU32(11, m_reverseAPIPort); s.writeU32(12, m_reverseAPIDeviceIndex); s.writeS32(13, m_loOffset); + s.writeU32(14, m_gpioDir); + s.writeU32(15, m_gpioPins); return s.final(); } @@ -102,6 +106,10 @@ bool USRPOutputSettings::deserialize(const QByteArray& data) d.readU32(12, &uintval, 0); m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval; d.readS32(13, &m_loOffset, 0); + d.readU32(14, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(15, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } @@ -148,6 +156,12 @@ void USRPOutputSettings::applySettings(const QStringList& settingsKeys, const US if (settingsKeys.contains("transverterDeltaFrequency")) { m_transverterDeltaFrequency = settings.m_transverterDeltaFrequency; } + if (settingsKeys.contains("gpioDir")) { + m_gpioDir = settings.m_gpioDir; + } + if (settingsKeys.contains("gpioPins")) { + m_gpioPins = settings.m_gpioPins; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -199,6 +213,12 @@ QString USRPOutputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("transverterDeltaFrequency") || force) { ostr << " m_transverterDeltaFrequency: " << m_transverterDeltaFrequency; } + if (settingsKeys.contains("gpioDir") || force) { + ostr << " m_gpioDir: " << (int) m_gpioDir; + } + if (settingsKeys.contains("gpioPins") || force) { + ostr << " m_gpioPins: " << (int) m_gpioPins; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesink/usrpoutput/usrpoutputsettings.h b/plugins/samplesink/usrpoutput/usrpoutputsettings.h index ec07c179e5..3b11fcafff 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputsettings.h +++ b/plugins/samplesink/usrpoutput/usrpoutputsettings.h @@ -45,6 +45,8 @@ struct USRPOutputSettings QString m_clockSource; bool m_transverterMode; qint64 m_transverterDeltaFrequency; + uint8_t m_gpioDir; //!< GPIO pin direction; 0 ATR (automatic transmit/receive), 1 output + uint8_t m_gpioPins; //!< GPIO pins levels for outputs bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort; diff --git a/plugins/samplesource/usrpinput/readme.md b/plugins/samplesource/usrpinput/readme.md index 572268f50e..39feeb1d6d 100644 --- a/plugins/samplesource/usrpinput/readme.md +++ b/plugins/samplesource/usrpinput/readme.md @@ -143,3 +143,10 @@ On Ubuntu 20, the libuhd-dev package should be installed. The FPGA images then n ```shell sudo /usr/lib/uhd/utils/uhd_images_downloader.py ``` + + GPIOs
+ +The USRP device settings supports 8-bit `gpioDir` and `gpioPins` settings. These can be set via the Web API or Simple PTT feature. +`gpioDir` can be set to 0 for default ATR (automatic transmit/receive) functionality or 1 for GPIO output. +On the b210, the GPIOs are on J504 header. Bit 0 corresponds to pin 1. +On other USRP devices, that may have multiple GPIO banks, these settings correspond to bank `FP0` (Front panel). diff --git a/plugins/samplesource/usrpinput/usrpinput.cpp b/plugins/samplesource/usrpinput/usrpinput.cpp index b6d8eb1c7c..acc408d82d 100644 --- a/plugins/samplesource/usrpinput/usrpinput.cpp +++ b/plugins/samplesource/usrpinput/usrpinput.cpp @@ -895,6 +895,25 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, const QListgetDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "CTRL", ~settings.m_gpioDir, 0xff); // 0 for GPIO, 1 for ATR + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "DDR", settings.m_gpioDir, 0xff); // 0 for input, 1 for output + qDebug() << "USRPInput::applySettings: set GPIO dir to " << settings.m_gpioDir; + } + } + + if (settingsKeys.contains("gpioPins") || force) + { + if (m_deviceShared.m_deviceParams->getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "OUT", settings.m_gpioPins, 0xff); + qDebug() << "USRPInput::applySettings: set GPIO pins to " << settings.m_gpioPins; + } + } + if (settingsKeys.contains("useReverseAPI")) { bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || @@ -1162,6 +1181,12 @@ void USRPInput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getUsrpInputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getUsrpInputSettings()->getGpioDir(); + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getUsrpInputSettings()->getGpioPins(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getUsrpInputSettings()->getUseReverseApi() != 0; } @@ -1191,6 +1216,8 @@ void USRPInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& respo response.getUsrpInputSettings()->setLpfBw(settings.m_lpfBW); response.getUsrpInputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getUsrpInputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getUsrpInputSettings()->setGpioDir(settings.m_gpioDir); + response.getUsrpInputSettings()->setGpioPins(settings.m_gpioPins); response.getUsrpInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getUsrpInputSettings()->getReverseApiAddress()) { @@ -1311,6 +1338,12 @@ void USRPInput::webapiReverseSendSettings(const QList & deviceSettingsKe if (deviceSettingsKeys.contains("transverterMode") || force) { swgUsrpInputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); } + if (deviceSettingsKeys.contains("gpioDir") || force) { + swgUsrpInputSettings->setGpioDir(settings.m_gpioDir); + } + if (deviceSettingsKeys.contains("gpioPins") || force) { + swgUsrpInputSettings->setGpioPins(settings.m_gpioPins); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesource/usrpinput/usrpinputsettings.cpp b/plugins/samplesource/usrpinput/usrpinputsettings.cpp index e1b1381a26..82fec7e17e 100644 --- a/plugins/samplesource/usrpinput/usrpinputsettings.cpp +++ b/plugins/samplesource/usrpinput/usrpinputsettings.cpp @@ -46,6 +46,8 @@ void USRPInputSettings::resetToDefaults() m_replayLength = 20.0f; m_replayStep = 5.0f; m_replayLoop = false; + m_gpioDir = 0; + m_gpioPins = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -76,6 +78,8 @@ QByteArray USRPInputSettings::serialize() const s.writeFloat(18, m_replayLength); s.writeFloat(19, m_replayStep); s.writeBool(20, m_replayLoop); + s.writeU32(21, m_gpioDir); + s.writeU32(22, m_gpioPins); return s.final(); } @@ -124,6 +128,10 @@ bool USRPInputSettings::deserialize(const QByteArray& data) d.readFloat(18, &m_replayLength, 20.0f); d.readFloat(19, &m_replayStep, 5.0f); d.readBool(20, &m_replayLoop, false); + d.readU32(21, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(22, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } @@ -191,6 +199,12 @@ void USRPInputSettings::applySettings(const QStringList& settingsKeys, const USR if (settingsKeys.contains("replayLoop")) { m_replayLoop = settings.m_replayLoop; } + if (settingsKeys.contains("gpioDir")) { + m_gpioDir = settings.m_gpioDir; + } + if (settingsKeys.contains("gpioPins")) { + m_gpioPins = settings.m_gpioPins; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -263,6 +277,12 @@ QString USRPInputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("replayLoop") || force) { ostr << " m_replayLoop: " << m_replayLoop; } + if (settingsKeys.contains("gpioDir") || force) { + ostr << " m_gpioDir: " << (int) m_gpioDir; + } + if (settingsKeys.contains("gpioPins") || force) { + ostr << " m_gpioPins: " << (int) m_gpioPins; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesource/usrpinput/usrpinputsettings.h b/plugins/samplesource/usrpinput/usrpinputsettings.h index ae2f6e15df..774e62bde6 100644 --- a/plugins/samplesource/usrpinput/usrpinputsettings.h +++ b/plugins/samplesource/usrpinput/usrpinputsettings.h @@ -52,10 +52,12 @@ struct USRPInputSettings QString m_clockSource; bool m_transverterMode; qint64 m_transverterDeltaFrequency; - float m_replayOffset; //!< Replay offset in seconds + float m_replayOffset; //!< Replay offset in seconds float m_replayLength; //!< Replay buffer size in seconds float m_replayStep; //!< Replay forward/back step size in seconds bool m_replayLoop; //!< Replay buffer repeatedly without recording new data + uint8_t m_gpioDir; //!< GPIO pin direction; 0 ATR (automatic transmit/receive), 1 output + uint8_t m_gpioPins; //!< GPIO pins levels for outputs bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort; diff --git a/sdrbase/channel/channelwebapiutils.cpp b/sdrbase/channel/channelwebapiutils.cpp index 6a26b90188..e5e09ee0a5 100644 --- a/sdrbase/channel/channelwebapiutils.cpp +++ b/sdrbase/channel/channelwebapiutils.cpp @@ -1319,9 +1319,15 @@ bool ChannelWebAPIUtils::patchDeviceSetting(unsigned int deviceIndex, const QStr SWGSDRangel::SWGErrorResponse errorResponse2; delete jsonObj; - DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource(); - - httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + if (DeviceSampleSource *source = deviceSet->m_deviceAPI->getSampleSource()) { + httpRC = source->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + } else if (DeviceSampleSink *sink = deviceSet->m_deviceAPI->getSampleSink()) { + httpRC = sink->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + } else if (DeviceSampleMIMO *mimo = deviceSet->m_deviceAPI->getSampleMIMO()) { + httpRC = mimo->webapiSettingsPutPatch(false, deviceSettingsKeys, deviceSettingsResponse, *errorResponse2.getMessage()); + } else { + httpRC = 404; + } if (httpRC/100 == 2) { diff --git a/sdrbase/feature/featurewebapiutils.cpp b/sdrbase/feature/featurewebapiutils.cpp index 45832bb96a..84303acda5 100644 --- a/sdrbase/feature/featurewebapiutils.cpp +++ b/sdrbase/feature/featurewebapiutils.cpp @@ -20,12 +20,42 @@ #include "SWGFeatureActions.h" #include "SWGMapActions.h" #include "SWGPERTesterActions.h" +#include "SWGDeviceState.h" #include "maincore.h" #include "feature/featureset.h" #include "feature/feature.h" #include "featurewebapiutils.h" +// Start feature +bool FeatureWebAPIUtils::run(int featureSetIndex, int featureIndex) +{ + Feature *feature = FeatureWebAPIUtils::getFeature(featureSetIndex, featureIndex, ""); + if (feature != nullptr) + { + SWGSDRangel::SWGDeviceState runResponse; + QString errorResponse; + int httpRC; + + runResponse.setState(new QString()); + httpRC = feature->webapiRun(true, runResponse, errorResponse); + + if (httpRC/100 != 2) + { + qWarning("FeatureWebAPIUtils::run: run error %d: %s", + httpRC, qPrintable(errorResponse)); + return false; + } + + return true; + } + else + { + qWarning("FeatureWebAPIUtils::run: no feature F%d:%d", featureSetIndex, featureIndex); + return false; + } +} + // Find the specified target on the map bool FeatureWebAPIUtils::mapFind(const QString& target, int featureSetIndex, int featureIndex) { diff --git a/sdrbase/feature/featurewebapiutils.h b/sdrbase/feature/featurewebapiutils.h index d0448892cf..ddad1ae821 100644 --- a/sdrbase/feature/featurewebapiutils.h +++ b/sdrbase/feature/featurewebapiutils.h @@ -47,6 +47,7 @@ private slots: class SDRBASE_API FeatureWebAPIUtils { public: + static bool run(int featureSetIndex, int featureIndex); static bool mapFind(const QString& target, int featureSetIndex=-1, int featureIndex=-1); static bool mapSetDateTime(const QDateTime& dateTime, int featureSetIndex=-1, int featureIndex=-1); static bool skyMapFind(const QString& target, int featureSetIndex=-1, int featureIndex=-1); diff --git a/sdrbase/mainparser.cpp b/sdrbase/mainparser.cpp index 3735a5103d..1456b8f259 100644 --- a/sdrbase/mainparser.cpp +++ b/sdrbase/mainparser.cpp @@ -42,7 +42,8 @@ MainParser::MainParser() : m_remoteTCPSinkPortOption("remote-tcp-port", "Remote TCP Sink port (Default 1234).", "port", "1234"), m_remoteTCPSinkHWTypeOption("remote-tcp-hwtype", "Remote TCP Sink device hardware type (Optional. E.g. RTLSDR/SDRplayV3/AirspyHF).", "hwtype"), m_remoteTCPSinkSerialOption("remote-tcp-serial", "Remote TCP Sink device serial (Optional).", "serial"), - m_listDevicesOption("list-devices", "List available physical devices.") + m_listDevicesOption("list-devices", "List available physical devices."), + m_startOption("start", "Start all devices and features") { m_serverAddress = ""; // Bind to any address @@ -56,6 +57,7 @@ MainParser::MainParser() : m_remoteTCPSinkHWType = ""; m_remoteTCPSinkSerial = ""; m_listDevices = false; + m_start = false; m_parser.setApplicationDescription("Software Defined Radio application"); m_parser.addHelpOption(); @@ -72,6 +74,7 @@ MainParser::MainParser() : m_parser.addOption(m_remoteTCPSinkHWTypeOption); m_parser.addOption(m_remoteTCPSinkSerialOption); m_parser.addOption(m_listDevicesOption); + m_parser.addOption(m_startOption); } MainParser::~MainParser() @@ -154,4 +157,8 @@ void MainParser::parse(const QCoreApplication& app) qCritical() << "You must specify a device with either --remote-tcp-hwtype or --remote-tcp-serial"; exit (EXIT_FAILURE); } + + // Start devices and features + m_start = m_parser.isSet(m_startOption); + } diff --git a/sdrbase/mainparser.h b/sdrbase/mainparser.h index d38be74ba7..220db95bb7 100644 --- a/sdrbase/mainparser.h +++ b/sdrbase/mainparser.h @@ -45,6 +45,7 @@ class SDRBASE_API MainParser const QString& getRemoteTCPSinkHWType() const { return m_remoteTCPSinkHWType; } const QString& getRemoteTCPSinkSerial() const { return m_remoteTCPSinkSerial; } bool getListDevices() const { return m_listDevices; } + bool getStart() const { return m_start; } private: QString m_serverAddress; @@ -58,6 +59,7 @@ class SDRBASE_API MainParser QString m_remoteTCPSinkHWType; QString m_remoteTCPSinkSerial; bool m_listDevices; + bool m_start; QCommandLineParser m_parser; QCommandLineOption m_serverAddressOption; @@ -71,6 +73,7 @@ class SDRBASE_API MainParser QCommandLineOption m_remoteTCPSinkHWTypeOption; QCommandLineOption m_remoteTCPSinkSerialOption; QCommandLineOption m_listDevicesOption; + QCommandLineOption m_startOption; }; diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index cb1da788d6..ff653dee97 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -13451,6 +13451,18 @@ "properties" : { "sampleRate" : { "type" : "integer" + }, + "latitude" : { + "type" : "number", + "format" : "float" + }, + "longitude" : { + "type" : "number", + "format" : "float" + }, + "altitude" : { + "type" : "number", + "format" : "float" } }, "description" : "RemoteTCPInput" @@ -16824,6 +16836,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -16893,6 +16913,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -59441,7 +59469,7 @@ Status: 501 - Function not implemented
diff --git a/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml b/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml index 09cc073e60..c27b4e712e 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/RemoteTCPInput.yaml @@ -61,3 +61,12 @@ RemoteTCPInputReport: properties: sampleRate: type: integer + latitude: + type: number + format: float + longitude: + type: number + format: float + altitude: + type: number + format: float diff --git a/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml b/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml index e388f288fc..169094c7b5 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/USRP.yaml @@ -30,6 +30,12 @@ USRPInputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer @@ -65,6 +71,12 @@ USRPOutputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/sdrbase/util/colormap.cpp b/sdrbase/util/colormap.cpp index e2678c648a..4f7065415e 100644 --- a/sdrbase/util/colormap.cpp +++ b/sdrbase/util/colormap.cpp @@ -72,6 +72,7 @@ QHash- Generated 2024-07-16T23:20:27.082+02:00 + Generated 2024-12-24T11:56:24.260+01:00ColorMap::m_colorMaps{ {"Cubehlx2", &m_cubehlx2[0]}, {"Icy", &m_icy[0]}, {"Mint", &m_mint[0]}, + {"A.C.A.B.", &m_acab[0]}, }; const float ColorMap::m_angel[m_size] = @@ -7102,3 +7103,263 @@ const float ColorMap::m_mint[m_size] = 0.999, 0.997, 0.995, 1.000, 1.000, 1.000, }; + +const float ColorMap::m_acab[m_size] = +{ + 0.00000, 0.00000, 0.00000, + 0.01042, 0.01042, 0.01042, + 0.02083, 0.02083, 0.02083, + 0.03125, 0.03125, 0.03125, + 0.04167, 0.04167, 0.04167, + 0.05208, 0.05208, 0.05208, + 0.06250, 0.06250, 0.06250, + 0.07292, 0.07292, 0.07292, + 0.08333, 0.08333, 0.08333, + 0.09375, 0.09375, 0.09375, + 0.10417, 0.10417, 0.10417, + 0.11458, 0.11458, 0.11458, + 0.12500, 0.12500, 0.12500, + 0.13542, 0.13542, 0.13542, + 0.14583, 0.14583, 0.14583, + 0.15625, 0.15625, 0.15625, + 0.16667, 0.16667, 0.16667, + 0.17708, 0.17708, 0.17708, + 0.18750, 0.18750, 0.18750, + 0.19792, 0.19792, 0.19792, + 0.20833, 0.20833, 0.20833, + 0.21875, 0.21875, 0.21875, + 0.22917, 0.22917, 0.22917, + 0.23958, 0.23958, 0.23958, + 0.25000, 0.25000, 0.25000, + 0.26042, 0.26042, 0.26042, + 0.27083, 0.27083, 0.27083, + 0.28125, 0.28125, 0.28125, + 0.29167, 0.29167, 0.29167, + 0.30208, 0.30208, 0.30208, + 0.31250, 0.31250, 0.31250, + 0.32292, 0.32292, 0.32292, + 0.33333, 0.33333, 0.33333, + 0.32292, 0.32292, 0.35417, + 0.31250, 0.31250, 0.37500, + 0.30208, 0.30208, 0.39583, + 0.29167, 0.29167, 0.41667, + 0.28125, 0.28125, 0.43750, + 0.27083, 0.27083, 0.45833, + 0.26042, 0.26042, 0.47917, + 0.25000, 0.25000, 0.50000, + 0.23958, 0.23958, 0.52083, + 0.22917, 0.22917, 0.54167, + 0.21875, 0.21875, 0.56250, + 0.20833, 0.20833, 0.58333, + 0.19792, 0.19792, 0.60417, + 0.18750, 0.18750, 0.62500, + 0.17708, 0.17708, 0.64583, + 0.16667, 0.16667, 0.66667, + 0.15625, 0.15625, 0.68750, + 0.14583, 0.14583, 0.70833, + 0.13542, 0.13542, 0.72917, + 0.12500, 0.12500, 0.75000, + 0.11458, 0.11458, 0.77083, + 0.10417, 0.10417, 0.79167, + 0.09375, 0.09375, 0.81250, + 0.08333, 0.08333, 0.83333, + 0.07292, 0.07292, 0.85417, + 0.06250, 0.06250, 0.87500, + 0.05208, 0.05208, 0.89583, + 0.04167, 0.04167, 0.91667, + 0.03125, 0.03125, 0.93750, + 0.02083, 0.02083, 0.95833, + 0.01042, 0.01042, 0.97917, + 0.00000, 0.00000, 1.00000, + 0.00000, 0.03125, 1.00000, + 0.00000, 0.06250, 1.00000, + 0.00000, 0.09375, 1.00000, + 0.00000, 0.12500, 1.00000, + 0.00000, 0.15625, 1.00000, + 0.00000, 0.18750, 1.00000, + 0.00000, 0.21875, 1.00000, + 0.00000, 0.25000, 1.00000, + 0.00000, 0.28125, 1.00000, + 0.00000, 0.31250, 1.00000, + 0.00000, 0.34375, 1.00000, + 0.00000, 0.37500, 1.00000, + 0.00000, 0.40625, 1.00000, + 0.00000, 0.43750, 1.00000, + 0.00000, 0.46875, 1.00000, + 0.00000, 0.50000, 1.00000, + 0.00000, 0.53125, 1.00000, + 0.00000, 0.56250, 1.00000, + 0.00000, 0.59375, 1.00000, + 0.00000, 0.62500, 1.00000, + 0.00000, 0.65625, 1.00000, + 0.00000, 0.68750, 1.00000, + 0.00000, 0.71875, 1.00000, + 0.00000, 0.75000, 1.00000, + 0.00000, 0.78125, 1.00000, + 0.00000, 0.81250, 1.00000, + 0.00000, 0.84375, 1.00000, + 0.00000, 0.87500, 1.00000, + 0.00000, 0.90625, 1.00000, + 0.00000, 0.93750, 1.00000, + 0.00000, 0.96875, 1.00000, + 0.00000, 1.00000, 1.00000, + 0.00000, 1.00000, 0.96875, + 0.00000, 1.00000, 0.93750, + 0.00000, 1.00000, 0.90625, + 0.00000, 1.00000, 0.87500, + 0.00000, 1.00000, 0.84375, + 0.00000, 1.00000, 0.81250, + 0.00000, 1.00000, 0.78125, + 0.00000, 1.00000, 0.75000, + 0.00000, 1.00000, 0.71875, + 0.00000, 1.00000, 0.68750, + 0.00000, 1.00000, 0.65625, + 0.00000, 1.00000, 0.62500, + 0.00000, 1.00000, 0.59375, + 0.00000, 1.00000, 0.56250, + 0.00000, 1.00000, 0.53125, + 0.00000, 1.00000, 0.50000, + 0.00000, 1.00000, 0.46875, + 0.00000, 1.00000, 0.43750, + 0.00000, 1.00000, 0.40625, + 0.00000, 1.00000, 0.37500, + 0.00000, 1.00000, 0.34375, + 0.00000, 1.00000, 0.31250, + 0.00000, 1.00000, 0.28125, + 0.00000, 1.00000, 0.25000, + 0.00000, 1.00000, 0.21875, + 0.00000, 1.00000, 0.18750, + 0.00000, 1.00000, 0.15625, + 0.00000, 1.00000, 0.12500, + 0.00000, 1.00000, 0.09375, + 0.00000, 1.00000, 0.06250, + 0.00000, 1.00000, 0.03125, + 0.00000, 1.00000, 0.00000, + 0.03125, 1.00000, 0.00000, + 0.06250, 1.00000, 0.00000, + 0.09375, 1.00000, 0.00000, + 0.12500, 1.00000, 0.00000, + 0.15625, 1.00000, 0.00000, + 0.18750, 1.00000, 0.00000, + 0.21875, 1.00000, 0.00000, + 0.25000, 1.00000, 0.00000, + 0.28125, 1.00000, 0.00000, + 0.31250, 1.00000, 0.00000, + 0.34375, 1.00000, 0.00000, + 0.37500, 1.00000, 0.00000, + 0.40625, 1.00000, 0.00000, + 0.43750, 1.00000, 0.00000, + 0.46875, 1.00000, 0.00000, + 0.50000, 1.00000, 0.00000, + 0.53125, 1.00000, 0.00000, + 0.56250, 1.00000, 0.00000, + 0.59375, 1.00000, 0.00000, + 0.62500, 1.00000, 0.00000, + 0.65625, 1.00000, 0.00000, + 0.68750, 1.00000, 0.00000, + 0.71875, 1.00000, 0.00000, + 0.75000, 1.00000, 0.00000, + 0.78125, 1.00000, 0.00000, + 0.81250, 1.00000, 0.00000, + 0.84375, 1.00000, 0.00000, + 0.87500, 1.00000, 0.00000, + 0.90625, 1.00000, 0.00000, + 0.93750, 1.00000, 0.00000, + 0.96875, 1.00000, 0.00000, + 1.00000, 1.00000, 0.00000, + 1.00000, 0.96875, 0.00000, + 1.00000, 0.93750, 0.00000, + 1.00000, 0.90625, 0.00000, + 1.00000, 0.87500, 0.00000, + 1.00000, 0.84375, 0.00000, + 1.00000, 0.81250, 0.00000, + 1.00000, 0.78125, 0.00000, + 1.00000, 0.75000, 0.00000, + 1.00000, 0.71875, 0.00000, + 1.00000, 0.68750, 0.00000, + 1.00000, 0.65625, 0.00000, + 1.00000, 0.62500, 0.00000, + 1.00000, 0.59375, 0.00000, + 1.00000, 0.56250, 0.00000, + 1.00000, 0.53125, 0.00000, + 1.00000, 0.50000, 0.00000, + 1.00000, 0.46875, 0.00000, + 1.00000, 0.43750, 0.00000, + 1.00000, 0.40625, 0.00000, + 1.00000, 0.37500, 0.00000, + 1.00000, 0.34375, 0.00000, + 1.00000, 0.31250, 0.00000, + 1.00000, 0.28125, 0.00000, + 1.00000, 0.25000, 0.00000, + 1.00000, 0.21875, 0.00000, + 1.00000, 0.18750, 0.00000, + 1.00000, 0.15625, 0.00000, + 1.00000, 0.12500, 0.00000, + 1.00000, 0.09375, 0.00000, + 1.00000, 0.06250, 0.00000, + 1.00000, 0.03125, 0.00000, + 1.00000, 0.00000, 0.00000, + 1.00000, 0.00000, 0.03125, + 1.00000, 0.00000, 0.06250, + 1.00000, 0.00000, 0.09375, + 1.00000, 0.00000, 0.12500, + 1.00000, 0.00000, 0.15625, + 1.00000, 0.00000, 0.18750, + 1.00000, 0.00000, 0.21875, + 1.00000, 0.00000, 0.25000, + 1.00000, 0.00000, 0.28125, + 1.00000, 0.00000, 0.31250, + 1.00000, 0.00000, 0.34375, + 1.00000, 0.00000, 0.37500, + 1.00000, 0.00000, 0.40625, + 1.00000, 0.00000, 0.43750, + 1.00000, 0.00000, 0.46875, + 1.00000, 0.00000, 0.50000, + 1.00000, 0.00000, 0.53125, + 1.00000, 0.00000, 0.56250, + 1.00000, 0.00000, 0.59375, + 1.00000, 0.00000, 0.62500, + 1.00000, 0.00000, 0.65625, + 1.00000, 0.00000, 0.68750, + 1.00000, 0.00000, 0.71875, + 1.00000, 0.00000, 0.75000, + 1.00000, 0.00000, 0.78125, + 1.00000, 0.00000, 0.81250, + 1.00000, 0.00000, 0.84375, + 1.00000, 0.00000, 0.87500, + 1.00000, 0.00000, 0.90625, + 1.00000, 0.00000, 0.93750, + 1.00000, 0.00000, 0.96875, + 1.00000, 0.00000, 1.00000, + 1.00000, 0.03125, 1.00000, + 1.00000, 0.06250, 1.00000, + 1.00000, 0.09375, 1.00000, + 1.00000, 0.12500, 1.00000, + 1.00000, 0.15625, 1.00000, + 1.00000, 0.18750, 1.00000, + 1.00000, 0.21875, 1.00000, + 1.00000, 0.25000, 1.00000, + 1.00000, 0.28125, 1.00000, + 1.00000, 0.31250, 1.00000, + 1.00000, 0.34375, 1.00000, + 1.00000, 0.37500, 1.00000, + 1.00000, 0.40625, 1.00000, + 1.00000, 0.43750, 1.00000, + 1.00000, 0.46875, 1.00000, + 1.00000, 0.50000, 1.00000, + 1.00000, 0.53125, 1.00000, + 1.00000, 0.56250, 1.00000, + 1.00000, 0.59375, 1.00000, + 1.00000, 0.62500, 1.00000, + 1.00000, 0.65625, 1.00000, + 1.00000, 0.68750, 1.00000, + 1.00000, 0.71875, 1.00000, + 1.00000, 0.75000, 1.00000, + 1.00000, 0.78125, 1.00000, + 1.00000, 0.81250, 1.00000, + 1.00000, 0.84375, 1.00000, + 1.00000, 0.87500, 1.00000, + 1.00000, 0.90625, 1.00000, + 1.00000, 0.93750, 1.00000, + 1.00000, 0.96875, 1.00000, +}; diff --git a/sdrbase/util/colormap.h b/sdrbase/util/colormap.h index 110b1a04f1..ae7399b27a 100644 --- a/sdrbase/util/colormap.h +++ b/sdrbase/util/colormap.h @@ -69,6 +69,7 @@ class SDRBASE_API ColorMap static const float m_cubehlx2[m_size]; static const float m_icy[m_size]; static const float m_mint[m_size]; + static const float m_acab[m_size]; }; #endif diff --git a/sdrbase/util/sondehub.cpp b/sdrbase/util/sondehub.cpp index 75c00c76fe..9cb76158c0 100644 --- a/sdrbase/util/sondehub.cpp +++ b/sdrbase/util/sondehub.cpp @@ -126,6 +126,7 @@ void SondeHub::upload( obj.insert("subtype", subframe->getType()); } + //obj.insert("dev", true); //qDebug() << obj; QJsonArray payloads { obj @@ -189,7 +190,43 @@ void SondeHub::handleReply(QNetworkReply* reply) if (!reply->error()) { QByteArray bytes = reply->readAll(); - //qDebug() << bytes; + QJsonDocument document = QJsonDocument::fromJson(bytes); + if (document.isObject()) + { + QJsonObject obj = document.object(); + if (obj.contains(QStringLiteral("message"))) + { + QString message = obj.value(QStringLiteral("message")).toString(); + qWarning() << "SondeHub message:" << message; + } + if (obj.contains(QStringLiteral("errors"))) + { + QJsonArray errors = obj.value(QStringLiteral("errors")).toArray(); + for (auto errorObjRef : errors) + { + QJsonObject errorObj = errorObjRef.toObject(); + if (errorObj.contains(QStringLiteral("error_message"))) + { + QString errorMessage = errorObj.value(QStringLiteral("error_message")).toString(); + qWarning() << "SondeHub error:" << errorMessage; + if (errorObj.contains(QStringLiteral("payload"))) + { + QJsonObject payload = errorObj.value(QStringLiteral("payload")).toObject(); + qWarning() << "SondeHub error:" << QJsonDocument(payload); + } + } + else + { + qWarning() << "SondeHub error:" << QJsonDocument(errorObj); + } + } + } + //qDebug() << "SondeHub::handleReply: obj" << QJsonDocument(obj); + } + else + { + qDebug() << "SondeHub::handleReply:" << bytes; + } } else { diff --git a/sdrgui/gui/crightclickenabler.cpp b/sdrgui/gui/crightclickenabler.cpp index d7624c3832..3dc3c1415b 100644 --- a/sdrgui/gui/crightclickenabler.cpp +++ b/sdrgui/gui/crightclickenabler.cpp @@ -81,6 +81,17 @@ bool CRightClickEnabler::eventFilter(QObject *obj, QEvent *event) } } } + else if (event->type() == QEvent::KeyPress) + { + auto keyEvent = (QKeyEvent*) event; + + if ((keyEvent->key() == Qt::Key_Menu && keyEvent->modifiers() == 0) || (keyEvent->modifiers() & Qt::ShiftModifier && keyEvent->key() == Qt::Key_F10)) + { + emit rightClick(QCursor::pos()); + keyEvent->setAccepted(true); + return true; + } + } else if (event->type() == QEvent::ContextMenu) { // Filter ContextMenu events, so we don't get popup menus as well diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index a3c5e9fe9e..0fad8ba788 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -61,6 +61,7 @@ #include "feature/featureset.h" #include "feature/feature.h" #include "feature/featuregui.h" +#include "feature/featurewebapiutils.h" #include "mainspectrum/mainspectrumgui.h" #include "commands/commandkeyreceiver.h" #include "gui/presetitem.h" @@ -275,6 +276,9 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse InitFSM *fsm = new InitFSM(this, splash, !parser.getScratch()); connect(fsm, &InitFSM::finished, fsm, &InitFSM::deleteLater); connect(fsm, &InitFSM::finished, splash, &SDRangelSplash::deleteLater); + if (parser.getStart()) { + connect(fsm, &InitFSM::finished, this, &MainWindow::startAllAfterDelay); + } fsm->start(); qDebug() << "MainWindow::MainWindow: end"; @@ -3382,6 +3386,30 @@ void MainWindow::showAllChannels(int deviceSetIndex) } } +void MainWindow::startAllAfterDelay() +{ + // Wait a little bit before starting all devices and features, + // as some devices, such as FileSinks, can fail to start if run before initialised + // Is there a better way than this arbitrary time? + QTimer::singleShot(1000, this, &MainWindow::startAll); +} + +// Start all devices and features in all workspaces +void MainWindow::startAll() +{ + // Start all devices + for (const auto& workspace : m_workspaces) { + startAllDevices(workspace); + } + // Start all features + for (int featureSetIndex = 0; featureSetIndex < m_featureUIs.size(); featureSetIndex++) + { + for (int featureIndex = 0; featureIndex < m_featureUIs[featureSetIndex]->getNumberOfFeatures(); featureIndex++) { + FeatureWebAPIUtils::run(featureSetIndex, featureIndex); + } + } +} + // Start all devices in the workspace void MainWindow::startAllDevices(const Workspace *workspace) const { diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 6b7baf77bf..d14228fad7 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -458,6 +458,8 @@ private slots: void featureMove(FeatureGUI *gui, int wsIndexDestnation); void deviceStateChanged(DeviceAPI *deviceAPI); void openFeaturePresetsDialog(QPoint p, Workspace *workspace); + void startAllAfterDelay(); + void startAll(); void startAllDevices(const Workspace *workspace) const; void stopAllDevices(const Workspace *workspace) const; void deviceMove(DeviceGUI *gui, int wsIndexDestnation); diff --git a/swagger/sdrangel/api/swagger/include/USRP.yaml b/swagger/sdrangel/api/swagger/include/USRP.yaml index e388f288fc..169094c7b5 100644 --- a/swagger/sdrangel/api/swagger/include/USRP.yaml +++ b/swagger/sdrangel/api/swagger/include/USRP.yaml @@ -30,6 +30,12 @@ USRPInputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer @@ -65,6 +71,12 @@ USRPOutputSettings: transverterDeltaFrequency: type: integer format: int64 + gpioDir: + type: integer + format: int8 + gpioPins: + type: integer + format: int8 useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index cb1da788d6..ff653dee97 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -13451,6 +13451,18 @@ "properties" : { "sampleRate" : { "type" : "integer" + }, + "latitude" : { + "type" : "number", + "format" : "float" + }, + "longitude" : { + "type" : "number", + "format" : "float" + }, + "altitude" : { + "type" : "number", + "format" : "float" } }, "description" : "RemoteTCPInput" @@ -16824,6 +16836,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -16893,6 +16913,14 @@ "type" : "integer", "format" : "int64" }, + "gpioDir" : { + "type" : "integer", + "format" : "int8" + }, + "gpioPins" : { + "type" : "integer", + "format" : "int8" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -59441,7 +59469,7 @@ Status: 501 - Function not implemented
diff --git a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp index eb50dd12a4..5fa22b16ac 100644 --- a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.cpp @@ -1,6 +1,6 @@ /** * SDRangel - * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- + * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- * * OpenAPI spec version: 7.0.0 * Contact: f4exb06@gmail.com @@ -30,6 +30,12 @@ SWGRemoteTCPInputReport::SWGRemoteTCPInputReport(QString* json) { SWGRemoteTCPInputReport::SWGRemoteTCPInputReport() { sample_rate = 0; m_sample_rate_isSet = false; + latitude = 0.0f; + m_latitude_isSet = false; + longitude = 0.0f; + m_longitude_isSet = false; + altitude = 0.0f; + m_altitude_isSet = false; } SWGRemoteTCPInputReport::~SWGRemoteTCPInputReport() { @@ -40,11 +46,20 @@ void SWGRemoteTCPInputReport::init() { sample_rate = 0; m_sample_rate_isSet = false; + latitude = 0.0f; + m_latitude_isSet = false; + longitude = 0.0f; + m_longitude_isSet = false; + altitude = 0.0f; + m_altitude_isSet = false; } void SWGRemoteTCPInputReport::cleanup() { + + + } SWGRemoteTCPInputReport* @@ -59,7 +74,13 @@ SWGRemoteTCPInputReport::fromJson(QString &json) { void SWGRemoteTCPInputReport::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&sample_rate, pJson["sampleRate"], "qint32", ""); - + + ::SWGSDRangel::setValue(&latitude, pJson["latitude"], "float", ""); + + ::SWGSDRangel::setValue(&longitude, pJson["longitude"], "float", ""); + + ::SWGSDRangel::setValue(&altitude, pJson["altitude"], "float", ""); + } QString @@ -79,9 +100,15 @@ SWGRemoteTCPInputReport::asJsonObject() { if(m_sample_rate_isSet){ obj->insert("sampleRate", QJsonValue(sample_rate)); } - obj->insert("latitude", QJsonValue(latitude)); - obj->insert("longitude", QJsonValue(longitude)); - obj->insert("altitude", QJsonValue(altitude)); + if(m_latitude_isSet){ + obj->insert("latitude", QJsonValue(latitude)); + } + if(m_longitude_isSet){ + obj->insert("longitude", QJsonValue(longitude)); + } + if(m_altitude_isSet){ + obj->insert("altitude", QJsonValue(altitude)); + } return obj; } @@ -96,6 +123,36 @@ SWGRemoteTCPInputReport::setSampleRate(qint32 sample_rate) { this->m_sample_rate_isSet = true; } +float +SWGRemoteTCPInputReport::getLatitude() { + return latitude; +} +void +SWGRemoteTCPInputReport::setLatitude(float latitude) { + this->latitude = latitude; + this->m_latitude_isSet = true; +} + +float +SWGRemoteTCPInputReport::getLongitude() { + return longitude; +} +void +SWGRemoteTCPInputReport::setLongitude(float longitude) { + this->longitude = longitude; + this->m_longitude_isSet = true; +} + +float +SWGRemoteTCPInputReport::getAltitude() { + return altitude; +} +void +SWGRemoteTCPInputReport::setAltitude(float altitude) { + this->altitude = altitude; + this->m_altitude_isSet = true; +} + bool SWGRemoteTCPInputReport::isSet(){ @@ -104,6 +161,15 @@ SWGRemoteTCPInputReport::isSet(){ if(m_sample_rate_isSet){ isObjectUpdated = true; break; } + if(m_latitude_isSet){ + isObjectUpdated = true; break; + } + if(m_longitude_isSet){ + isObjectUpdated = true; break; + } + if(m_altitude_isSet){ + isObjectUpdated = true; break; + } }while(false); return isObjectUpdated; } diff --git a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h index 92ea400e01..661be25556 100644 --- a/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h +++ b/swagger/sdrangel/code/qt5/client/SWGRemoteTCPInputReport.h @@ -1,6 +1,6 @@ /** * SDRangel - * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- + * This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube --- Limitations and specifcities: * In SDRangel GUI the first Rx device set cannot be deleted. Conversely the server starts with no device sets and its number of device sets can be reduced to zero by as many calls as necessary to /sdrangel/deviceset with DELETE method. * Preset import and export from/to file is a server only feature. * Device set focus is a GUI only feature. * The following channels are not implemented (status 501 is returned): ATV and DATV demodulators, Channel Analyzer NG, LoRa demodulator * The device settings and report structures contains only the sub-structure corresponding to the device type. The DeviceSettings and DeviceReport structures documented here shows all of them but only one will be or should be present at a time * The channel settings and report structures contains only the sub-structure corresponding to the channel type. The ChannelSettings and ChannelReport structures documented here shows all of them but only one will be or should be present at a time --- * * OpenAPI spec version: 7.0.0 * Contact: f4exb06@gmail.com @@ -43,21 +43,31 @@ class SWG_API SWGRemoteTCPInputReport: public SWGObject { qint32 getSampleRate(); void setSampleRate(qint32 sample_rate); - float getLatitude() { return latitude; } - float getLongitude() { return longitude; } - float getAltitude() { return altitude; } - void setLatitude(float latitude) { this->latitude = latitude; } - void setLongitude(float longitude) { this->longitude = longitude; } - void setAltitude(float altitude) { this->altitude = altitude; } + + float getLatitude(); + void setLatitude(float latitude); + + float getLongitude(); + void setLongitude(float longitude); + + float getAltitude(); + void setAltitude(float altitude); + virtual bool isSet() override; private: qint32 sample_rate; bool m_sample_rate_isSet; + float latitude; + bool m_latitude_isSet; + float longitude; + bool m_longitude_isSet; + float altitude; + bool m_altitude_isSet; }; diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp index 80400dd762..9ed57c6362 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.cpp @@ -54,6 +54,10 @@ SWGUSRPInputSettings::SWGUSRPInputSettings() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = nullptr; @@ -96,6 +100,10 @@ SWGUSRPInputSettings::init() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = new QString(""); @@ -126,6 +134,8 @@ SWGUSRPInputSettings::cleanup() { + + if(reverse_api_address != nullptr) { delete reverse_api_address; } @@ -170,6 +180,10 @@ SWGUSRPInputSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&transverter_delta_frequency, pJson["transverterDeltaFrequency"], "qint64", ""); + ::SWGSDRangel::setValue(&gpio_dir, pJson["gpioDir"], "qint32", ""); + + ::SWGSDRangel::setValue(&gpio_pins, pJson["gpioPins"], "qint32", ""); + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); @@ -233,6 +247,12 @@ SWGUSRPInputSettings::asJsonObject() { if(m_transverter_delta_frequency_isSet){ obj->insert("transverterDeltaFrequency", QJsonValue(transverter_delta_frequency)); } + if(m_gpio_dir_isSet){ + obj->insert("gpioDir", QJsonValue(gpio_dir)); + } + if(m_gpio_pins_isSet){ + obj->insert("gpioPins", QJsonValue(gpio_pins)); + } if(m_use_reverse_api_isSet){ obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); } @@ -379,6 +399,26 @@ SWGUSRPInputSettings::setTransverterDeltaFrequency(qint64 transverter_delta_freq this->m_transverter_delta_frequency_isSet = true; } +qint32 +SWGUSRPInputSettings::getGpioDir() { + return gpio_dir; +} +void +SWGUSRPInputSettings::setGpioDir(qint32 gpio_dir) { + this->gpio_dir = gpio_dir; + this->m_gpio_dir_isSet = true; +} + +qint32 +SWGUSRPInputSettings::getGpioPins() { + return gpio_pins; +} +void +SWGUSRPInputSettings::setGpioPins(qint32 gpio_pins) { + this->gpio_pins = gpio_pins; + this->m_gpio_pins_isSet = true; +} + qint32 SWGUSRPInputSettings::getUseReverseApi() { return use_reverse_api; @@ -463,6 +503,12 @@ SWGUSRPInputSettings::isSet(){ if(m_transverter_delta_frequency_isSet){ isObjectUpdated = true; break; } + if(m_gpio_dir_isSet){ + isObjectUpdated = true; break; + } + if(m_gpio_pins_isSet){ + isObjectUpdated = true; break; + } if(m_use_reverse_api_isSet){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h index 7d6697cf11..3ddfc02eae 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPInputSettings.h @@ -81,6 +81,12 @@ class SWG_API SWGUSRPInputSettings: public SWGObject { qint64 getTransverterDeltaFrequency(); void setTransverterDeltaFrequency(qint64 transverter_delta_frequency); + qint32 getGpioDir(); + void setGpioDir(qint32 gpio_dir); + + qint32 getGpioPins(); + void setGpioPins(qint32 gpio_pins); + qint32 getUseReverseApi(); void setUseReverseApi(qint32 use_reverse_api); @@ -136,6 +142,12 @@ class SWG_API SWGUSRPInputSettings: public SWGObject { qint64 transverter_delta_frequency; bool m_transverter_delta_frequency_isSet; + qint32 gpio_dir; + bool m_gpio_dir_isSet; + + qint32 gpio_pins; + bool m_gpio_pins_isSet; + qint32 use_reverse_api; bool m_use_reverse_api_isSet; diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp index 57c00be9e6..dcbde1bb5f 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.cpp @@ -48,6 +48,10 @@ SWGUSRPOutputSettings::SWGUSRPOutputSettings() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = nullptr; @@ -84,6 +88,10 @@ SWGUSRPOutputSettings::init() { m_transverter_mode_isSet = false; transverter_delta_frequency = 0L; m_transverter_delta_frequency_isSet = false; + gpio_dir = 0; + m_gpio_dir_isSet = false; + gpio_pins = 0; + m_gpio_pins_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = new QString(""); @@ -111,6 +119,8 @@ SWGUSRPOutputSettings::cleanup() { + + if(reverse_api_address != nullptr) { delete reverse_api_address; } @@ -149,6 +159,10 @@ SWGUSRPOutputSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&transverter_delta_frequency, pJson["transverterDeltaFrequency"], "qint64", ""); + ::SWGSDRangel::setValue(&gpio_dir, pJson["gpioDir"], "qint32", ""); + + ::SWGSDRangel::setValue(&gpio_pins, pJson["gpioPins"], "qint32", ""); + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); @@ -203,6 +217,12 @@ SWGUSRPOutputSettings::asJsonObject() { if(m_transverter_delta_frequency_isSet){ obj->insert("transverterDeltaFrequency", QJsonValue(transverter_delta_frequency)); } + if(m_gpio_dir_isSet){ + obj->insert("gpioDir", QJsonValue(gpio_dir)); + } + if(m_gpio_pins_isSet){ + obj->insert("gpioPins", QJsonValue(gpio_pins)); + } if(m_use_reverse_api_isSet){ obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); } @@ -319,6 +339,26 @@ SWGUSRPOutputSettings::setTransverterDeltaFrequency(qint64 transverter_delta_fre this->m_transverter_delta_frequency_isSet = true; } +qint32 +SWGUSRPOutputSettings::getGpioDir() { + return gpio_dir; +} +void +SWGUSRPOutputSettings::setGpioDir(qint32 gpio_dir) { + this->gpio_dir = gpio_dir; + this->m_gpio_dir_isSet = true; +} + +qint32 +SWGUSRPOutputSettings::getGpioPins() { + return gpio_pins; +} +void +SWGUSRPOutputSettings::setGpioPins(qint32 gpio_pins) { + this->gpio_pins = gpio_pins; + this->m_gpio_pins_isSet = true; +} + qint32 SWGUSRPOutputSettings::getUseReverseApi() { return use_reverse_api; @@ -394,6 +434,12 @@ SWGUSRPOutputSettings::isSet(){ if(m_transverter_delta_frequency_isSet){ isObjectUpdated = true; break; } + if(m_gpio_dir_isSet){ + isObjectUpdated = true; break; + } + if(m_gpio_pins_isSet){ + isObjectUpdated = true; break; + } if(m_use_reverse_api_isSet){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h index ea59c25ebb..13157d962e 100644 --- a/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGUSRPOutputSettings.h @@ -72,6 +72,12 @@ class SWG_API SWGUSRPOutputSettings: public SWGObject { qint64 getTransverterDeltaFrequency(); void setTransverterDeltaFrequency(qint64 transverter_delta_frequency); + qint32 getGpioDir(); + void setGpioDir(qint32 gpio_dir); + + qint32 getGpioPins(); + void setGpioPins(qint32 gpio_pins); + qint32 getUseReverseApi(); void setUseReverseApi(qint32 use_reverse_api); @@ -118,6 +124,12 @@ class SWG_API SWGUSRPOutputSettings: public SWGObject { qint64 transverter_delta_frequency; bool m_transverter_delta_frequency_isSet; + qint32 gpio_dir; + bool m_gpio_dir_isSet; + + qint32 gpio_pins; + bool m_gpio_pins_isSet; + qint32 use_reverse_api; bool m_use_reverse_api_isSet;- Generated 2024-07-16T23:20:27.082+02:00 + Generated 2024-12-24T11:56:24.260+01:00