From a4269dcd78d7ce53b5b282522c729d149870390b Mon Sep 17 00:00:00 2001 From: srcejon Date: Tue, 24 Dec 2024 10:59:35 +0000 Subject: [PATCH 1/5] Add GPIO pins to USRP and regen swagger --- sdrbase/resources/webapi/doc/html2/index.html | 30 +++++++- .../doc/swagger/include/RemoteTCPInput.yaml | 9 +++ .../webapi/doc/swagger/include/USRP.yaml | 12 +++ .../sdrangel/api/swagger/include/USRP.yaml | 12 +++ swagger/sdrangel/code/html2/index.html | 30 +++++++- .../qt5/client/SWGRemoteTCPInputReport.cpp | 76 +++++++++++++++++-- .../code/qt5/client/SWGRemoteTCPInputReport.h | 24 ++++-- .../code/qt5/client/SWGUSRPInputSettings.cpp | 46 +++++++++++ .../code/qt5/client/SWGUSRPInputSettings.h | 12 +++ .../code/qt5/client/SWGUSRPOutputSettings.cpp | 46 +++++++++++ .../code/qt5/client/SWGUSRPOutputSettings.h | 12 +++ 11 files changed, 295 insertions(+), 14 deletions(-) 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

- Generated 2024-07-16T23:20:27.082+02:00 + Generated 2024-12-24T11:56:24.260+01:00
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/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

- Generated 2024-07-16T23:20:27.082+02:00 + Generated 2024-12-24T11:56:24.260+01:00
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; From 56bd20d59b6e731909c9a72f651c6e9b51db19f4 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 24 Dec 2024 12:48:43 +0000 Subject: [PATCH 2/5] USRP: Implement GPIO settings. --- plugins/samplesink/usrpoutput/usrpoutput.cpp | 33 +++++++++++++++++++ .../usrpoutput/usrpoutputsettings.cpp | 20 +++++++++++ .../usrpoutput/usrpoutputsettings.h | 2 ++ plugins/samplesource/usrpinput/usrpinput.cpp | 33 +++++++++++++++++++ .../usrpinput/usrpinputsettings.cpp | 20 +++++++++++ .../usrpinput/usrpinputsettings.h | 4 ++- 6 files changed, 111 insertions(+), 1 deletion(-) diff --git a/plugins/samplesink/usrpoutput/usrpoutput.cpp b/plugins/samplesink/usrpoutput/usrpoutput.cpp index 8f9444e8ac..9fe77db39a 100644 --- a/plugins/samplesink/usrpoutput/usrpoutput.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutput.cpp @@ -813,6 +813,25 @@ bool USRPOutput::applySettings(const USRPOutputSettings& 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() << "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/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; From 4510f40729ef5263e6d99d0946a2e1c8590a8e22 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 24 Dec 2024 12:49:10 +0000 Subject: [PATCH 3/5] ChannelWebAPIUtils::patchDeviceSetting: Add support for sinks and MIMO. --- sdrbase/channel/channelwebapiutils.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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) { From c5efd73f6bd47585b92101f2500ab5a3169b3ce5 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 24 Dec 2024 12:56:36 +0000 Subject: [PATCH 4/5] Document GPIOs. --- plugins/samplesink/usrpoutput/readme.md | 7 +++++++ plugins/samplesource/usrpinput/readme.md | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/plugins/samplesink/usrpoutput/readme.md b/plugins/samplesink/usrpoutput/readme.md index 812ddcf1ba..2fc29d9603 100644 --- a/plugins/samplesink/usrpoutput/readme.md +++ b/plugins/samplesink/usrpoutput/readme.md @@ -123,3 +123,10 @@ This label turns green when data has been transmitted to the device. - **D**: turns red if stream experiences packet drop outs The stream warning indicators are reset when the acquisition is started. + +

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/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). From d3584f6af259f2faa80260d77b1d458787861bbc Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 24 Dec 2024 13:25:14 +0000 Subject: [PATCH 5/5] RemoteTCPSink: Handle client disconnecting immediately. --- .../remotetcpsink/remotetcpsinksink.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp b/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp index 5697422fd4..d69aebc9b9 100644 --- a/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp +++ b/plugins/channelrx/remotetcpsink/remotetcpsinksink.cpp @@ -881,8 +881,8 @@ RemoteTCPProtocol::Device RemoteTCPSinkSink::getDevice() void RemoteTCPSinkSink::acceptWebConnection() { - QMutexLocker mutexLocker(&m_mutex); - QWebSocket *client = m_webSocketServer->nextPendingConnection(); + QMutexLocker mutexLocker(&m_mutex); + QWebSocket *client = m_webSocketServer->nextPendingConnection(); connect(client, &QWebSocket::binaryMessageReceived, this, &RemoteTCPSinkSink::processCommand); connect(client, &QWebSocket::disconnected, this, &RemoteTCPSinkSink::disconnected); @@ -891,8 +891,11 @@ void RemoteTCPSinkSink::acceptWebConnection() // https://bugreports.qt.io/browse/QTBUG-125874 QTimer::singleShot(200, this, [this, client] () { QMutexLocker mutexLocker(&m_mutex); - m_clients.append(new WebSocket(client)); - acceptConnection(m_clients.last()); + if (client->isValid()) + { + m_clients.append(new WebSocket(client)); + acceptConnection(m_clients.last()); + } }); } @@ -912,8 +915,11 @@ void RemoteTCPSinkSink::acceptTCPConnection() QTimer::singleShot(200, this, [this, client] () { QMutexLocker mutexLocker(&m_mutex); - m_clients.append(new TCPSocket(client)); - acceptConnection(m_clients.last()); + if (client->isValid()) + { + m_clients.append(new TCPSocket(client)); + acceptConnection(m_clients.last()); + } }); }