diff --git a/Readme.md b/Readme.md index b6ad96b20..f555b19dc 100644 --- a/Readme.md +++ b/Readme.md @@ -27,23 +27,16 @@ These plugins come from the parent code base and have been maintained so that th channelrx: - demodlora - - tcpsrc (although it has evolved please use the udpsrc plugin instead) - -

Deprecated plugins

- -These plugins are still present at least in the code but have been superceded: - - - chanalyzer: the Channel Analyzer channel plugin is superceded by the "new generation" Channel Analyzer NG (chanalyzerng)

Specific features

Multiple device support

-From version 2 SDRangel can integrate more than one hardware device running concurrently. +Since version 2 SDRangel can integrate more than one hardware device running concurrently.

Transmission support

-From version 3 transmission or signal generation is supported for BladeRF, HackRF (since version 3.1), LimeSDR (since version 3.4) and PlutoSDR (since version 3.7.8) using a sample sink plugin. These plugins are: +Since version 3 transmission or signal generation is supported for BladeRF, HackRF (since version 3.1), LimeSDR (since version 3.4) and PlutoSDR (since version 3.7.8) using a sample sink plugin. These plugins are: - [BladeRF output plugin](https://github.com/f4exb/sdrangel/tree/dev/plugins/samplesink/bladerfoutput) - [HackRF output plugin](https://github.com/f4exb/sdrangel/tree/dev/plugins/samplesink/hackrfoutput) @@ -54,11 +47,15 @@ From version 3 transmission or signal generation is supported for BladeRF, HackR

REST API

-From version 4 a REST API is available to interact with the SDRangel application. More details are provided in the server instance documentation in the `sdrsrv` folder. +Since version 4 a REST API is available to interact with the SDRangel application. More details are provided in the server instance documentation in the `sdrsrv` folder.

Server instance

-From version 4 the `sdrangelsrv` binary launches a server mode SDRangel instance that runs wihout the GUI. More information is provided in the Readme file of the `sdrsrv` folder. +Since version 4 the `sdrangelsrv` binary launches a server mode SDRangel instance that runs wihout the GUI. More information is provided in the Readme file of the `sdrsrv` folder. + +

Detached RF head server (SDRdaemon)

+ +Since version 4.1 the previously separated project SDRdaemon has been modified and included in SDRangel. Another binary `sdrdaemonsrv` is provided for handling just the RF part of the SDRangel processing chain. The baseband samples are comunicated via UDP to/from a SDRangel instance. More details are provided in the server instance documentation in the `sdrdaemon` folder.

Notes on pulseaudio setup

diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index e96fb7aeb..870afebe9 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -1702,6 +1702,9 @@ margin-bottom: 20px; "type" : "string", "description" : "Descriptive text of the operating system running the instance (available with Qt >= 5.4)" }, + "logging" : { + "$ref" : "#/definitions/LoggingInfo" + }, "samplingDevice" : { "$ref" : "#/definitions/SamplingDevice" } @@ -27070,7 +27073,7 @@ except ApiException as e:
- Generated 2018-08-18T15:06:40.106+02:00 + Generated 2018-08-19T11:32:09.545+02:00
diff --git a/sdrbase/resources/webapi/doc/swagger/swagger.yaml b/sdrbase/resources/webapi/doc/swagger/swagger.yaml index ab01945d8..536e0e7f1 100644 --- a/sdrbase/resources/webapi/doc/swagger/swagger.yaml +++ b/sdrbase/resources/webapi/doc/swagger/swagger.yaml @@ -1506,6 +1506,8 @@ definitions: os: description: "Descriptive text of the operating system running the instance (available with Qt >= 5.4)" type: string + logging: + $ref: "#/definitions/LoggingInfo" samplingDevice: $ref: "#/definitions/SamplingDevice" diff --git a/sdrdaemon/sdrdaemonmain.cpp b/sdrdaemon/sdrdaemonmain.cpp index e89b4fc07..0ed1393fa 100644 --- a/sdrdaemon/sdrdaemonmain.cpp +++ b/sdrdaemon/sdrdaemonmain.cpp @@ -215,7 +215,6 @@ bool SDRDaemonMain::addSinkDevice() char uidCStr[16]; sprintf(uidCStr, "UID:%d", dspDeviceSinkEngineUID); - m_deviceSourceEngine = 0; m_deviceSinkEngine = dspDeviceSinkEngine; m_deviceSinkAPI = new DeviceSinkAPI(0, dspDeviceSinkEngine); @@ -251,6 +250,8 @@ bool SDRDaemonMain::addSourceDevice() char uidCStr[16]; sprintf(uidCStr, "UID:%d", dspDeviceSourceEngineUID); + m_deviceSourceEngine = dspDeviceSourceEngine; + m_deviceSourceAPI = new DeviceSourceAPI(0, dspDeviceSourceEngine); int deviceIndex = getDeviceIndex(); diff --git a/sdrdaemon/sdrdaemonparser.cpp b/sdrdaemon/sdrdaemonparser.cpp index a925bc15f..a314c8772 100644 --- a/sdrdaemon/sdrdaemonparser.cpp +++ b/sdrdaemon/sdrdaemonparser.cpp @@ -140,6 +140,10 @@ void SDRDaemonParser::parse(const QCoreApplication& app) qWarning() << "SDRDaemonParser::parse: data port invalid. Defaulting to " << m_dataPort; } + // tx + m_tx = m_parser.isSet(m_txOption); + qDebug() << "SDRDaemonParser::parse: tx: " << m_tx; + // device type QString deviceType = m_parser.value(m_deviceTypeOption); @@ -147,17 +151,17 @@ void SDRDaemonParser::parse(const QCoreApplication& app) QRegExp deviceTypeRegex("^[A-Z][A-Za-z0-9]+$"); QRegExpValidator deviceTypeValidator(deviceTypeRegex); - if (deviceTypeValidator.validate(deviceType, pos) == QValidator::Acceptable) { + if (deviceTypeValidator.validate(deviceType, pos) == QValidator::Acceptable) + { m_deviceType = deviceType; qDebug() << "SDRDaemonParser::parse: device type: " << m_deviceType; - } else { + } + else + { + m_deviceType = m_tx ? "FileSink" : "TestSource"; qWarning() << "SDRDaemonParser::parse: device type invalid. Defaulting to " << m_deviceType; } - // tx - m_tx = m_parser.isSet(m_txOption); - qDebug() << "SDRDaemonParser::parse: tx: " << m_tx; - // serial m_hasSerial = m_parser.isSet(m_serialOption); diff --git a/sdrdaemon/webapi/webapiadapterdaemon.cpp b/sdrdaemon/webapi/webapiadapterdaemon.cpp index 7efaba0f9..84626b7b7 100644 --- a/sdrdaemon/webapi/webapiadapterdaemon.cpp +++ b/sdrdaemon/webapi/webapiadapterdaemon.cpp @@ -16,6 +16,8 @@ // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// +#include + #include "SWGDaemonSummaryResponse.h" #include "SWGLoggingInfo.h" #include "SWGDeviceSettings.h" @@ -23,6 +25,13 @@ #include "SWGDeviceReport.h" #include "SWGErrorResponse.h" +#include "dsp/dsptypes.h" +#include "dsp/dspdevicesourceengine.h" +#include "dsp/dspdevicesinkengine.h" +#include "device/devicesourceapi.h" +#include "device/devicesinkapi.h" +#include "dsp/devicesamplesink.h" +#include "dsp/devicesamplesource.h" #include "webapiadapterdaemon.h" #include "sdrdaemonmain.h" #include "loggerwithfile.h" @@ -43,12 +52,71 @@ WebAPIAdapterDaemon::~WebAPIAdapterDaemon() } int WebAPIAdapterDaemon::daemonInstanceSummary( - SWGSDRangel::SWGDaemonSummaryResponse& response __attribute__((unused)), - SWGSDRangel::SWGErrorResponse& error) + SWGSDRangel::SWGDaemonSummaryResponse& response, + SWGSDRangel::SWGErrorResponse& error __attribute__((unused))) { - error.init(); - *error.getMessage() = "Not implemented"; - return 501; + response.init(); + *response.getAppname() = QCoreApplication::applicationName(); + *response.getVersion() = QCoreApplication::applicationVersion(); + *response.getQtVersion() = QString(QT_VERSION_STR); + response.setDspRxBits(SDR_RX_SAMP_SZ); + response.setDspTxBits(SDR_TX_SAMP_SZ); + response.setPid(QCoreApplication::applicationPid()); +#if QT_VERSION >= 0x050400 + *response.getArchitecture() = QString(QSysInfo::currentCpuArchitecture()); + *response.getOs() = QString(QSysInfo::prettyProductName()); +#endif + + SWGSDRangel::SWGLoggingInfo *logging = response.getLogging(); + logging->init(); + logging->setDumpToFile(m_sdrDaemonMain.m_logger->getUseFileLogger() ? 1 : 0); + + if (logging->getDumpToFile()) { + m_sdrDaemonMain.m_logger->getLogFileName(*logging->getFileName()); + m_sdrDaemonMain.m_logger->getFileMinMessageLevelStr(*logging->getFileLevel()); + } + + m_sdrDaemonMain.m_logger->getConsoleMinMessageLevelStr(*logging->getConsoleLevel()); + + SWGSDRangel::SWGSamplingDevice *samplingDevice = response.getSamplingDevice(); + samplingDevice->setTx(m_sdrDaemonMain.m_tx ? 1 : 0); + samplingDevice->setHwType(new QString(m_sdrDaemonMain.m_deviceType)); + samplingDevice->setIndex(0); + + if (m_sdrDaemonMain.m_tx) + { + QString state; + m_sdrDaemonMain.m_deviceSinkAPI->getDeviceEngineStateStr(state); + samplingDevice->setState(new QString(state)); + samplingDevice->setSerial(new QString(m_sdrDaemonMain.m_deviceSinkAPI->getSampleSinkSerial())); + samplingDevice->setSequence(m_sdrDaemonMain.m_deviceSinkAPI->getSampleSinkSequence()); + samplingDevice->setNbStreams(m_sdrDaemonMain.m_deviceSinkAPI->getNbItems()); + samplingDevice->setStreamIndex(m_sdrDaemonMain.m_deviceSinkAPI->getItemIndex()); + DeviceSampleSink *sampleSink = m_sdrDaemonMain.m_deviceSinkEngine->getSink(); + + if (sampleSink) { + samplingDevice->setCenterFrequency(sampleSink->getCenterFrequency()); + samplingDevice->setBandwidth(sampleSink->getSampleRate()); + } + } + else + { + QString state; + m_sdrDaemonMain.m_deviceSourceAPI->getDeviceEngineStateStr(state); + samplingDevice->setState(new QString(state)); + samplingDevice->setSerial(new QString(m_sdrDaemonMain.m_deviceSourceAPI->getSampleSourceSerial())); + samplingDevice->setSequence(m_sdrDaemonMain.m_deviceSourceAPI->getSampleSourceSequence()); + samplingDevice->setNbStreams(m_sdrDaemonMain.m_deviceSourceAPI->getNbItems()); + samplingDevice->setStreamIndex(m_sdrDaemonMain.m_deviceSourceAPI->getItemIndex()); + DeviceSampleSource *sampleSource = m_sdrDaemonMain.m_deviceSourceEngine->getSource(); + + if (sampleSource) { + samplingDevice->setCenterFrequency(sampleSource->getCenterFrequency()); + samplingDevice->setBandwidth(sampleSource->getSampleRate()); + } + } + + return 200; } int WebAPIAdapterDaemon::daemonInstanceLoggingGet( diff --git a/swagger/sdrangel/api/swagger/swagger.yaml b/swagger/sdrangel/api/swagger/swagger.yaml index 56cebd75f..2d51dbbe4 100644 --- a/swagger/sdrangel/api/swagger/swagger.yaml +++ b/swagger/sdrangel/api/swagger/swagger.yaml @@ -1506,6 +1506,8 @@ definitions: os: description: "Descriptive text of the operating system running the instance (available with Qt >= 5.4)" type: string + logging: + $ref: "#/definitions/LoggingInfo" samplingDevice: $ref: "#/definitions/SamplingDevice" diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index e96fb7aeb..870afebe9 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -1702,6 +1702,9 @@ margin-bottom: 20px; "type" : "string", "description" : "Descriptive text of the operating system running the instance (available with Qt >= 5.4)" }, + "logging" : { + "$ref" : "#/definitions/LoggingInfo" + }, "samplingDevice" : { "$ref" : "#/definitions/SamplingDevice" } @@ -27070,7 +27073,7 @@ except ApiException as e:
- Generated 2018-08-18T15:06:40.106+02:00 + Generated 2018-08-19T11:32:09.545+02:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.cpp b/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.cpp index d5427fc54..e2e81ae9d 100644 --- a/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.cpp @@ -44,6 +44,8 @@ SWGDaemonSummaryResponse::SWGDaemonSummaryResponse() { m_architecture_isSet = false; os = nullptr; m_os_isSet = false; + logging = nullptr; + m_logging_isSet = false; sampling_device = nullptr; m_sampling_device_isSet = false; } @@ -70,6 +72,8 @@ SWGDaemonSummaryResponse::init() { m_architecture_isSet = false; os = new QString(""); m_os_isSet = false; + logging = new SWGLoggingInfo(); + m_logging_isSet = false; sampling_device = new SWGSamplingDevice(); m_sampling_device_isSet = false; } @@ -94,6 +98,9 @@ SWGDaemonSummaryResponse::cleanup() { if(os != nullptr) { delete os; } + if(logging != nullptr) { + delete logging; + } if(sampling_device != nullptr) { delete sampling_device; } @@ -126,6 +133,8 @@ SWGDaemonSummaryResponse::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&os, pJson["os"], "QString", "QString"); + ::SWGSDRangel::setValue(&logging, pJson["logging"], "SWGLoggingInfo", "SWGLoggingInfo"); + ::SWGSDRangel::setValue(&sampling_device, pJson["samplingDevice"], "SWGSamplingDevice", "SWGSamplingDevice"); } @@ -168,6 +177,9 @@ SWGDaemonSummaryResponse::asJsonObject() { if(os != nullptr && *os != QString("")){ toJsonValue(QString("os"), os, obj, QString("QString")); } + if((logging != nullptr) && (logging->isSet())){ + toJsonValue(QString("logging"), logging, obj, QString("SWGLoggingInfo")); + } if((sampling_device != nullptr) && (sampling_device->isSet())){ toJsonValue(QString("samplingDevice"), sampling_device, obj, QString("SWGSamplingDevice")); } @@ -255,6 +267,16 @@ SWGDaemonSummaryResponse::setOs(QString* os) { this->m_os_isSet = true; } +SWGLoggingInfo* +SWGDaemonSummaryResponse::getLogging() { + return logging; +} +void +SWGDaemonSummaryResponse::setLogging(SWGLoggingInfo* logging) { + this->logging = logging; + this->m_logging_isSet = true; +} + SWGSamplingDevice* SWGDaemonSummaryResponse::getSamplingDevice() { return sampling_device; @@ -278,6 +300,7 @@ SWGDaemonSummaryResponse::isSet(){ if(appname != nullptr && *appname != QString("")){ isObjectUpdated = true; break;} if(architecture != nullptr && *architecture != QString("")){ isObjectUpdated = true; break;} if(os != nullptr && *os != QString("")){ isObjectUpdated = true; break;} + if(logging != nullptr && logging->isSet()){ isObjectUpdated = true; break;} if(sampling_device != nullptr && sampling_device->isSet()){ isObjectUpdated = true; break;} }while(false); return isObjectUpdated; diff --git a/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.h b/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.h index f0e15ef94..5444e7160 100644 --- a/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.h +++ b/swagger/sdrangel/code/qt5/client/SWGDaemonSummaryResponse.h @@ -22,6 +22,7 @@ #include +#include "SWGLoggingInfo.h" #include "SWGSamplingDevice.h" #include @@ -67,6 +68,9 @@ public: QString* getOs(); void setOs(QString* os); + SWGLoggingInfo* getLogging(); + void setLogging(SWGLoggingInfo* logging); + SWGSamplingDevice* getSamplingDevice(); void setSamplingDevice(SWGSamplingDevice* sampling_device); @@ -98,6 +102,9 @@ private: QString* os; bool m_os_isSet; + SWGLoggingInfo* logging; + bool m_logging_isSet; + SWGSamplingDevice* sampling_device; bool m_sampling_device_isSet;