mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-24 10:50:29 -05:00
Created SDRdaemon library
This commit is contained in:
parent
e073af634c
commit
411cb36a6f
@ -222,6 +222,7 @@ endif()
|
|||||||
add_subdirectory(sdrbase)
|
add_subdirectory(sdrbase)
|
||||||
add_subdirectory(sdrgui)
|
add_subdirectory(sdrgui)
|
||||||
add_subdirectory(sdrsrv)
|
add_subdirectory(sdrsrv)
|
||||||
|
add_subdirectory(sdrdaemon)
|
||||||
add_subdirectory(sdrbench)
|
add_subdirectory(sdrbench)
|
||||||
add_subdirectory(httpserver)
|
add_subdirectory(httpserver)
|
||||||
add_subdirectory(logging)
|
add_subdirectory(logging)
|
||||||
|
55
sdrdaemon/CMakeLists.txt
Normal file
55
sdrdaemon/CMakeLists.txt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
project (sdrdaemon)
|
||||||
|
|
||||||
|
set(sdrdaemon_SOURCES
|
||||||
|
sdrdaemonmain.cpp
|
||||||
|
sdrdaemonpreferences.cpp
|
||||||
|
sdrdaemonsettings.cpp
|
||||||
|
webapi/webapiadapterdaemon.cpp
|
||||||
|
webapi/webapirequestmapper.cpp
|
||||||
|
webapi/webapiserver.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(sdrdaemon_HEADERS
|
||||||
|
sdrdaemonmain.h
|
||||||
|
sdrdaemonpreferences.h
|
||||||
|
sdrdaemonsettings.h
|
||||||
|
webapi/webapiadapterdaemon.h
|
||||||
|
webapi/webapirequestmapper.h
|
||||||
|
webapi/webapiserver.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(sdrdaemon_SOURCES
|
||||||
|
${sdrdaemon_SOURCES}
|
||||||
|
${sdrdaemon_HEADERS}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(${QT_DEFINITIONS})
|
||||||
|
add_definitions(-DQT_SHARED)
|
||||||
|
|
||||||
|
add_library(sdrdaemon SHARED
|
||||||
|
${sdrdaemon_SOURCES}
|
||||||
|
${sdrdaemon_HEADERS_MOC}
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
.
|
||||||
|
${CMAKE_SOURCE_DIR}/exports
|
||||||
|
${CMAKE_SOURCE_DIR}/sdrbase
|
||||||
|
${CMAKE_SOURCE_DIR}/logging
|
||||||
|
${CMAKE_SOURCE_DIR}/httpserver
|
||||||
|
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(sdrdaemon
|
||||||
|
${QT_LIBRARIES}
|
||||||
|
sdrbase
|
||||||
|
logging
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_features(sdrdaemon PRIVATE cxx_generalized_initializers) # cmake >= 3.1.0
|
||||||
|
|
||||||
|
target_link_libraries(sdrdaemon Qt5::Core Qt5::Multimedia)
|
||||||
|
|
||||||
|
install(TARGETS sdrdaemon DESTINATION lib)
|
||||||
|
|
162
sdrdaemon/sdrdaemonmain.cpp
Normal file
162
sdrdaemon/sdrdaemonmain.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon instance //
|
||||||
|
// //
|
||||||
|
// SDRdaemon is a detached SDR front end that handles the interface with a //
|
||||||
|
// physical device and sends or receives the I/Q samples stream to or from a //
|
||||||
|
// SDRangel instance via UDP. It is controlled via a Web REST API. //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <QSysInfo>
|
||||||
|
#include <QResource>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dsp/dspengine.h"
|
||||||
|
#include "dsp/dspdevicesourceengine.h"
|
||||||
|
#include "plugin/pluginmanager.h"
|
||||||
|
#include "util/message.h"
|
||||||
|
#include "loggerwithfile.h"
|
||||||
|
#include "sdrdaemonmain.h"
|
||||||
|
|
||||||
|
#include "webapi/webapiadapterdaemon.h"
|
||||||
|
#include "webapi/webapirequestmapper.h"
|
||||||
|
#include "webapi/webapiserver.h"
|
||||||
|
|
||||||
|
SDRDaemonMain *SDRDaemonMain::m_instance = 0;
|
||||||
|
|
||||||
|
SDRDaemonMain::SDRDaemonMain(qtwebapp::LoggerWithFile *logger, const MainParser& parser, QObject *parent) :
|
||||||
|
QObject(parent),
|
||||||
|
m_logger(logger),
|
||||||
|
m_settings(),
|
||||||
|
m_dspEngine(DSPEngine::instance()),
|
||||||
|
m_lastEngineState(DSPDeviceSourceEngine::StNotStarted)
|
||||||
|
{
|
||||||
|
qDebug() << "SDRdaemon::SDRdaemon: start";
|
||||||
|
|
||||||
|
m_instance = this;
|
||||||
|
|
||||||
|
m_pluginManager = new PluginManager(this);
|
||||||
|
m_pluginManager->loadPlugins(QString("pluginssrv"));
|
||||||
|
|
||||||
|
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection);
|
||||||
|
m_masterTimer.start(50);
|
||||||
|
|
||||||
|
loadSettings();
|
||||||
|
|
||||||
|
QString applicationDirPath = QCoreApplication::instance()->applicationDirPath();
|
||||||
|
|
||||||
|
if (QResource::registerResource(applicationDirPath + "/sdrbase.rcc")) {
|
||||||
|
qDebug("MainCore::MainCore: registered resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
|
||||||
|
} else {
|
||||||
|
qWarning("MainCore::MainCore: could not register resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_apiAdapter = new WebAPIAdapterDaemon(*this);
|
||||||
|
m_requestMapper = new SDRDaemon::WebAPIRequestMapper(this);
|
||||||
|
m_requestMapper->setAdapter(m_apiAdapter);
|
||||||
|
m_apiServer = new SDRDaemon::WebAPIServer(parser.getServerAddress(), parser.getServerPort(), m_requestMapper);
|
||||||
|
m_apiServer->start();
|
||||||
|
|
||||||
|
qDebug() << "SDRdaemon::SDRdaemon: end";
|
||||||
|
}
|
||||||
|
|
||||||
|
SDRDaemonMain::~SDRDaemonMain()
|
||||||
|
{
|
||||||
|
m_apiServer->stop();
|
||||||
|
m_settings.save();
|
||||||
|
delete m_apiServer;
|
||||||
|
delete m_requestMapper;
|
||||||
|
delete m_apiAdapter;
|
||||||
|
|
||||||
|
delete m_pluginManager;
|
||||||
|
|
||||||
|
qDebug() << "SDRdaemon::~SDRdaemon: end";
|
||||||
|
delete m_logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDaemonMain::loadSettings()
|
||||||
|
{
|
||||||
|
qDebug() << "SDRdaemon::loadSettings";
|
||||||
|
|
||||||
|
m_settings.load();
|
||||||
|
setLoggingOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDaemonMain::setLoggingOptions()
|
||||||
|
{
|
||||||
|
m_logger->setConsoleMinMessageLevel(m_settings.getConsoleMinLogLevel());
|
||||||
|
|
||||||
|
if (m_settings.getUseLogFile())
|
||||||
|
{
|
||||||
|
qtwebapp::FileLoggerSettings fileLoggerSettings; // default values
|
||||||
|
|
||||||
|
if (m_logger->hasFileLogger()) {
|
||||||
|
fileLoggerSettings = m_logger->getFileLoggerSettings(); // values from file logger if it exists
|
||||||
|
}
|
||||||
|
|
||||||
|
fileLoggerSettings.fileName = m_settings.getLogFileName(); // put new values
|
||||||
|
m_logger->createOrSetFileLogger(fileLoggerSettings, 2000); // create file logger if it does not exist and apply settings in any case
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_logger->hasFileLogger()) {
|
||||||
|
m_logger->setFileMinMessageLevel(m_settings.getFileMinLogLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_logger->setUseFileLogger(m_settings.getUseLogFile());
|
||||||
|
|
||||||
|
if (m_settings.getUseLogFile())
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= 0x050400
|
||||||
|
QString appInfoStr(tr("%1 %2 Qt %3 %4b %5 %6 DSP Rx:%7b Tx:%8b PID %9")
|
||||||
|
.arg(QCoreApplication::applicationName())
|
||||||
|
.arg(QCoreApplication::applicationVersion())
|
||||||
|
.arg(QT_VERSION_STR)
|
||||||
|
.arg(QT_POINTER_SIZE*8)
|
||||||
|
.arg(QSysInfo::currentCpuArchitecture())
|
||||||
|
.arg(QSysInfo::prettyProductName())
|
||||||
|
.arg(SDR_RX_SAMP_SZ)
|
||||||
|
.arg(SDR_TX_SAMP_SZ)
|
||||||
|
.arg(QCoreApplication::applicationPid()));
|
||||||
|
#else
|
||||||
|
QString appInfoStr(tr("%1 %2 Qt %3 %4b DSP Rx:%5b Tx:%6b PID %7")
|
||||||
|
.arg(QCoreApplication::applicationName())
|
||||||
|
.arg(QCoreApplication::applicationVersion())
|
||||||
|
.arg(QT_VERSION_STR)
|
||||||
|
.arg(QT_POINTER_SIZE*8)
|
||||||
|
.arg(SDR_RX_SAMP_SZ)
|
||||||
|
.arg(SDR_RX_SAMP_SZ)
|
||||||
|
.arg(QCoreApplication::applicationPid());
|
||||||
|
#endif
|
||||||
|
m_logger->logToFile(QtInfoMsg, appInfoStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDRDaemonMain::handleMessage(const Message& cmd __attribute__((unused)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDaemonMain::handleMessages()
|
||||||
|
{
|
||||||
|
Message* message;
|
||||||
|
|
||||||
|
while ((message = m_inputMessageQueue.pop()) != 0)
|
||||||
|
{
|
||||||
|
qDebug("SDRdaemon::handleMessages: message: %s", message->getIdentifier());
|
||||||
|
handleMessage(*message);
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
}
|
76
sdrdaemon/sdrdaemonmain.h
Normal file
76
sdrdaemon/sdrdaemonmain.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon instance //
|
||||||
|
// //
|
||||||
|
// SDRdaemon is a detached SDR front end that handles the interface with a //
|
||||||
|
// physical device and sends or receives the I/Q samples stream to or from a //
|
||||||
|
// SDRangel instance via UDP. It is controlled via a Web REST API. //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRDAEMON_SDRDAEMONMAIN_H_
|
||||||
|
#define SDRDAEMON_SDRDAEMONMAIN_H_
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "mainparser.h"
|
||||||
|
#include "sdrdaemonsettings.h"
|
||||||
|
#include "util/messagequeue.h"
|
||||||
|
|
||||||
|
namespace SDRDaemon {
|
||||||
|
class WebAPIRequestMapper;
|
||||||
|
class WebAPIServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace qtwebapp {
|
||||||
|
class LoggerWithFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DSPEngine;
|
||||||
|
class PluginManager;
|
||||||
|
class Message;
|
||||||
|
class WebAPIAdapterDaemon;
|
||||||
|
|
||||||
|
class SDRDaemonMain : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit SDRDaemonMain(qtwebapp::LoggerWithFile *logger, const MainParser& parser, QObject *parent = 0);
|
||||||
|
~SDRDaemonMain();
|
||||||
|
static SDRDaemonMain *getInstance() { return m_instance; } // Main Core is de facto a singleton so this just returns its reference
|
||||||
|
|
||||||
|
private:
|
||||||
|
static SDRDaemonMain *m_instance;
|
||||||
|
qtwebapp::LoggerWithFile *m_logger;
|
||||||
|
SDRDaemonSettings m_settings;
|
||||||
|
DSPEngine* m_dspEngine;
|
||||||
|
int m_lastEngineState;
|
||||||
|
PluginManager* m_pluginManager;
|
||||||
|
MessageQueue m_inputMessageQueue;
|
||||||
|
QTimer m_masterTimer;
|
||||||
|
|
||||||
|
SDRDaemon::WebAPIRequestMapper *m_requestMapper;
|
||||||
|
SDRDaemon::WebAPIServer *m_apiServer;
|
||||||
|
WebAPIAdapterDaemon *m_apiAdapter;
|
||||||
|
|
||||||
|
void loadSettings();
|
||||||
|
void setLoggingOptions();
|
||||||
|
bool handleMessage(const Message& cmd);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleMessages();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SDRDAEMON_SDRDAEMONMAIN_H_ */
|
95
sdrdaemon/sdrdaemonpreferences.cpp
Normal file
95
sdrdaemon/sdrdaemonpreferences.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon instance //
|
||||||
|
// //
|
||||||
|
// SDRdaemon is a detached SDR front end that handles the interface with a //
|
||||||
|
// physical device and sends or receives the I/Q samples stream to or from a //
|
||||||
|
// SDRangel instance via UDP. It is controlled via a Web REST API. //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "util/simpleserializer.h"
|
||||||
|
#include "sdrdaemonpreferences.h"
|
||||||
|
|
||||||
|
SDRDaemonPreferences::SDRDaemonPreferences()
|
||||||
|
{
|
||||||
|
resetToDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDaemonPreferences::resetToDefaults()
|
||||||
|
{
|
||||||
|
m_useLogFile = false;
|
||||||
|
m_logFileName = "sdrangel.log";
|
||||||
|
m_consoleMinLogLevel = QtDebugMsg;
|
||||||
|
m_fileMinLogLevel = QtDebugMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray SDRDaemonPreferences::serialize() const
|
||||||
|
{
|
||||||
|
SimpleSerializer s(1);
|
||||||
|
s.writeS32(1, (int) m_consoleMinLogLevel);
|
||||||
|
s.writeBool(2, m_useLogFile);
|
||||||
|
s.writeString(3, m_logFileName);
|
||||||
|
s.writeS32(4, (int) m_fileMinLogLevel);
|
||||||
|
return s.final();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDRDaemonPreferences::deserialize(const QByteArray& data)
|
||||||
|
{
|
||||||
|
int tmpInt;
|
||||||
|
|
||||||
|
SimpleDeserializer d(data);
|
||||||
|
|
||||||
|
if(!d.isValid()) {
|
||||||
|
resetToDefaults();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(d.getVersion() == 1)
|
||||||
|
{
|
||||||
|
d.readS32(1, &tmpInt, (int) QtDebugMsg);
|
||||||
|
|
||||||
|
if ((tmpInt == (int) QtDebugMsg) ||
|
||||||
|
(tmpInt == (int) QtInfoMsg) ||
|
||||||
|
(tmpInt == (int) QtWarningMsg) ||
|
||||||
|
(tmpInt == (int) QtCriticalMsg) ||
|
||||||
|
(tmpInt == (int) QtFatalMsg)) {
|
||||||
|
m_consoleMinLogLevel = (QtMsgType) tmpInt;
|
||||||
|
} else {
|
||||||
|
m_consoleMinLogLevel = QtDebugMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
d.readBool(2, &m_useLogFile, false);
|
||||||
|
d.readString(3, &m_logFileName, "sdrangel.log");
|
||||||
|
|
||||||
|
d.readS32(4, &tmpInt, (int) QtDebugMsg);
|
||||||
|
|
||||||
|
if ((tmpInt == (int) QtDebugMsg) ||
|
||||||
|
(tmpInt == (int) QtInfoMsg) ||
|
||||||
|
(tmpInt == (int) QtWarningMsg) ||
|
||||||
|
(tmpInt == (int) QtCriticalMsg) ||
|
||||||
|
(tmpInt == (int) QtFatalMsg)) {
|
||||||
|
m_fileMinLogLevel = (QtMsgType) tmpInt;
|
||||||
|
} else {
|
||||||
|
m_fileMinLogLevel = QtDebugMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
resetToDefaults();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
53
sdrdaemon/sdrdaemonpreferences.h
Normal file
53
sdrdaemon/sdrdaemonpreferences.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon instance //
|
||||||
|
// //
|
||||||
|
// SDRdaemon is a detached SDR front end that handles the interface with a //
|
||||||
|
// physical device and sends or receives the I/Q samples stream to or from a //
|
||||||
|
// SDRangel instance via UDP. It is controlled via a Web REST API. //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRDAEMON_SDRDAEMONPREFERENCES_H_
|
||||||
|
#define SDRDAEMON_SDRDAEMONPREFERENCES_H_
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class SDRDaemonPreferences
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SDRDaemonPreferences();
|
||||||
|
|
||||||
|
void resetToDefaults();
|
||||||
|
QByteArray serialize() const;
|
||||||
|
bool deserialize(const QByteArray& data);
|
||||||
|
|
||||||
|
void setConsoleMinLogLevel(const QtMsgType& minLogLevel) { m_consoleMinLogLevel = minLogLevel; }
|
||||||
|
void setFileMinLogLevel(const QtMsgType& minLogLevel) { m_fileMinLogLevel = minLogLevel; }
|
||||||
|
void setUseLogFile(bool useLogFile) { m_useLogFile = useLogFile; }
|
||||||
|
void setLogFileName(const QString& value) { m_logFileName = value; }
|
||||||
|
QtMsgType getConsoleMinLogLevel() const { return m_consoleMinLogLevel; }
|
||||||
|
QtMsgType getFileMinLogLevel() const { return m_fileMinLogLevel; }
|
||||||
|
bool getUseLogFile() const { return m_useLogFile; }
|
||||||
|
const QString& getLogFileName() const { return m_logFileName; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QtMsgType m_consoleMinLogLevel;
|
||||||
|
QtMsgType m_fileMinLogLevel;
|
||||||
|
bool m_useLogFile;
|
||||||
|
QString m_logFileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SDRDAEMON_SDRDAEMONPREFERENCES_H_ */
|
51
sdrdaemon/sdrdaemonsettings.cpp
Normal file
51
sdrdaemon/sdrdaemonsettings.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon instance //
|
||||||
|
// //
|
||||||
|
// SDRdaemon is a detached SDR front end that handles the interface with a //
|
||||||
|
// physical device and sends or receives the I/Q samples stream to or from a //
|
||||||
|
// SDRangel instance via UDP. It is controlled via a Web REST API. //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include "sdrdaemonpreferences.h"
|
||||||
|
#include "sdrdaemonsettings.h"
|
||||||
|
|
||||||
|
SDRDaemonSettings::SDRDaemonSettings()
|
||||||
|
{
|
||||||
|
resetToDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDRDaemonSettings::~SDRDaemonSettings()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void SDRDaemonSettings::load()
|
||||||
|
{
|
||||||
|
QSettings s;
|
||||||
|
m_preferences.deserialize(qUncompress(QByteArray::fromBase64(s.value("preferences").toByteArray())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDaemonSettings::save() const
|
||||||
|
{
|
||||||
|
QSettings s;
|
||||||
|
s.setValue("preferences", qCompress(m_preferences.serialize()).toBase64());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDRDaemonSettings::resetToDefaults()
|
||||||
|
{
|
||||||
|
m_preferences.resetToDefaults();
|
||||||
|
}
|
54
sdrdaemon/sdrdaemonsettings.h
Normal file
54
sdrdaemon/sdrdaemonsettings.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon instance //
|
||||||
|
// //
|
||||||
|
// SDRdaemon is a detached SDR front end that handles the interface with a //
|
||||||
|
// physical device and sends or receives the I/Q samples stream to or from a //
|
||||||
|
// SDRangel instance via UDP. It is controlled via a Web REST API. //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRDAEMON_SDRDAEMONSETTINGS_H_
|
||||||
|
#define SDRDAEMON_SDRDAEMONSETTINGS_H_
|
||||||
|
|
||||||
|
#include "sdrdaemonpreferences.h"
|
||||||
|
|
||||||
|
class SDRDaemonSettings
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SDRDaemonSettings();
|
||||||
|
~SDRDaemonSettings();
|
||||||
|
|
||||||
|
void load();
|
||||||
|
void save() const;
|
||||||
|
|
||||||
|
void resetToDefaults();
|
||||||
|
|
||||||
|
void setConsoleMinLogLevel(const QtMsgType& minLogLevel) { m_preferences.setConsoleMinLogLevel(minLogLevel); }
|
||||||
|
void setFileMinLogLevel(const QtMsgType& minLogLevel) { m_preferences.setFileMinLogLevel(minLogLevel); }
|
||||||
|
void setUseLogFile(bool useLogFile) { m_preferences.setUseLogFile(useLogFile); }
|
||||||
|
void setLogFileName(const QString& value) { m_preferences.setLogFileName(value); }
|
||||||
|
QtMsgType getConsoleMinLogLevel() const { return m_preferences.getConsoleMinLogLevel(); }
|
||||||
|
QtMsgType getFileMinLogLevel() const { return m_preferences.getFileMinLogLevel(); }
|
||||||
|
bool getUseLogFile() const { return m_preferences.getUseLogFile(); }
|
||||||
|
const QString& getLogFileName() const { return m_preferences.getLogFileName(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDRDaemonPreferences m_preferences;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SDRDAEMON_SDRDAEMONSETTINGS_H_ */
|
164
sdrdaemon/webapi/webapiadapterdaemon.cpp
Normal file
164
sdrdaemon/webapi/webapiadapterdaemon.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRDaemon Swagger server adapter interface //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "SWGDaemonSummaryResponse.h"
|
||||||
|
#include "SWGDeviceSettings.h"
|
||||||
|
#include "SWGDeviceState.h"
|
||||||
|
#include "SWGDeviceReport.h"
|
||||||
|
#include "SWGErrorResponse.h"
|
||||||
|
|
||||||
|
#include "webapiadapterdaemon.h"
|
||||||
|
|
||||||
|
QString WebAPIAdapterDaemon::daemonInstanceSummaryURL = "/sdrdaemon";
|
||||||
|
QString WebAPIAdapterDaemon::daemonInstanceLoggingURL = "/sdrdaemon/logging";
|
||||||
|
QString WebAPIAdapterDaemon::daemonSettingsURL = "/sdrdaemon/settings";
|
||||||
|
QString WebAPIAdapterDaemon::daemonReportURL = "/sdrdaemon/report";
|
||||||
|
QString WebAPIAdapterDaemon::daemonRunURL = "/sdrdaemon/run";
|
||||||
|
|
||||||
|
WebAPIAdapterDaemon::WebAPIAdapterDaemon(SDRDaemonMain& sdrDaemonMain) :
|
||||||
|
m_sdrDaemonMain(sdrDaemonMain)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WebAPIAdapterDaemon::~WebAPIAdapterDaemon()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonInstanceSummary(
|
||||||
|
SWGSDRangel::SWGDaemonSummaryResponse& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonInstanceLoggingGet(
|
||||||
|
SWGSDRangel::SWGLoggingInfo& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonInstanceLoggingPut(
|
||||||
|
SWGSDRangel::SWGLoggingInfo& query __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGLoggingInfo& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonSettingsGet(
|
||||||
|
SWGSDRangel::SWGDeviceSettings& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonSettingsPutPatch(
|
||||||
|
bool force __attribute__((unused)),
|
||||||
|
const QStringList& deviceSettingsKeys __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGDeviceSettings& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonRunGet(
|
||||||
|
SWGSDRangel::SWGDeviceState& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonRunPost(
|
||||||
|
SWGSDRangel::SWGDeviceState& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonRunDelete(
|
||||||
|
SWGSDRangel::SWGDeviceState& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WebAPIAdapterDaemon::daemonReportGet(
|
||||||
|
SWGSDRangel::SWGDeviceReport& response __attribute__((unused)),
|
||||||
|
SWGSDRangel::SWGErrorResponse& error)
|
||||||
|
{
|
||||||
|
error.init();
|
||||||
|
*error.getMessage() = "Not implemented";
|
||||||
|
return 501;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
QtMsgType WebAPIAdapterDaemon::getMsgTypeFromString(const QString& msgTypeString)
|
||||||
|
{
|
||||||
|
if (msgTypeString == "debug") {
|
||||||
|
return QtDebugMsg;
|
||||||
|
} else if (msgTypeString == "info") {
|
||||||
|
return QtInfoMsg;
|
||||||
|
} else if (msgTypeString == "warning") {
|
||||||
|
return QtWarningMsg;
|
||||||
|
} else if (msgTypeString == "error") {
|
||||||
|
return QtCriticalMsg;
|
||||||
|
} else {
|
||||||
|
return QtDebugMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
void WebAPIAdapterDaemon::getMsgTypeString(const QtMsgType& msgType, QString& levelStr)
|
||||||
|
{
|
||||||
|
switch (msgType)
|
||||||
|
{
|
||||||
|
case QtDebugMsg:
|
||||||
|
levelStr = "debug";
|
||||||
|
break;
|
||||||
|
case QtInfoMsg:
|
||||||
|
levelStr = "info";
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
levelStr = "warning";
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
case QtFatalMsg:
|
||||||
|
levelStr = "error";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
levelStr = "debug";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
98
sdrdaemon/webapi/webapiadapterdaemon.h
Normal file
98
sdrdaemon/webapi/webapiadapterdaemon.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRDaemon Swagger server adapter interface //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRDAEMON_WEBAPI_WEBAPIADAPTERDAEMON_H_
|
||||||
|
#define SDRDAEMON_WEBAPI_WEBAPIADAPTERDAEMON_H_
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace SWGSDRangel
|
||||||
|
{
|
||||||
|
class SWGDaemonSummaryResponse;
|
||||||
|
class SWGDeviceSet;
|
||||||
|
class SWGDeviceListItem;
|
||||||
|
class SWGDeviceSettings;
|
||||||
|
class SWGDeviceState;
|
||||||
|
class SWGDeviceReport;
|
||||||
|
class SWGSuccessResponse;
|
||||||
|
class SWGErrorResponse;
|
||||||
|
class SWGLoggingInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SDRDaemonMain;
|
||||||
|
|
||||||
|
class WebAPIAdapterDaemon
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebAPIAdapterDaemon(SDRDaemonMain& sdrDaemonMain);
|
||||||
|
~WebAPIAdapterDaemon();
|
||||||
|
|
||||||
|
int daemonInstanceSummary(
|
||||||
|
SWGSDRangel::SWGDaemonSummaryResponse& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonInstanceLoggingGet(
|
||||||
|
SWGSDRangel::SWGLoggingInfo& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonInstanceLoggingPut(
|
||||||
|
SWGSDRangel::SWGLoggingInfo& query,
|
||||||
|
SWGSDRangel::SWGLoggingInfo& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonSettingsGet(
|
||||||
|
SWGSDRangel::SWGDeviceSettings& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonSettingsPutPatch(
|
||||||
|
bool force,
|
||||||
|
const QStringList& deviceSettingsKeys,
|
||||||
|
SWGSDRangel::SWGDeviceSettings& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonRunGet(
|
||||||
|
SWGSDRangel::SWGDeviceState& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonRunPost(
|
||||||
|
SWGSDRangel::SWGDeviceState& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonRunDelete(
|
||||||
|
SWGSDRangel::SWGDeviceState& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
int daemonReportGet(
|
||||||
|
SWGSDRangel::SWGDeviceReport& response,
|
||||||
|
SWGSDRangel::SWGErrorResponse& error);
|
||||||
|
|
||||||
|
static QString daemonInstanceSummaryURL;
|
||||||
|
static QString daemonInstanceLoggingURL;
|
||||||
|
static QString daemonSettingsURL;
|
||||||
|
static QString daemonReportURL;
|
||||||
|
static QString daemonRunURL;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDRDaemonMain& m_sdrDaemonMain;
|
||||||
|
|
||||||
|
static QtMsgType getMsgTypeFromString(const QString& msgTypeString);
|
||||||
|
static void getMsgTypeString(const QtMsgType& msgType, QString& level);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SDRDAEMON_WEBAPI_WEBAPIADAPTERDAEMON_H_ */
|
706
sdrdaemon/webapi/webapirequestmapper.cpp
Normal file
706
sdrdaemon/webapi/webapirequestmapper.cpp
Normal file
@ -0,0 +1,706 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRDaemon Swagger server adapter interface //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include "httpdocrootsettings.h"
|
||||||
|
#include "webapirequestmapper.h"
|
||||||
|
#include "SWGDaemonSummaryResponse.h"
|
||||||
|
#include "SWGInstanceDevicesResponse.h"
|
||||||
|
#include "SWGDeviceSettings.h"
|
||||||
|
#include "SWGDeviceState.h"
|
||||||
|
#include "SWGDeviceReport.h"
|
||||||
|
#include "SWGSuccessResponse.h"
|
||||||
|
#include "SWGErrorResponse.h"
|
||||||
|
#include "SWGLoggingInfo.h"
|
||||||
|
|
||||||
|
#include "webapirequestmapper.h"
|
||||||
|
#include "webapiadapterdaemon.h"
|
||||||
|
|
||||||
|
namespace SDRDaemon
|
||||||
|
{
|
||||||
|
|
||||||
|
WebAPIRequestMapper::WebAPIRequestMapper(QObject* parent) :
|
||||||
|
HttpRequestHandler(parent),
|
||||||
|
m_adapter(0)
|
||||||
|
{
|
||||||
|
qtwebapp::HttpDocrootSettings docrootSettings;
|
||||||
|
docrootSettings.path = ":/webapi";
|
||||||
|
m_staticFileController = new qtwebapp::StaticFileController(docrootSettings, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebAPIRequestMapper::~WebAPIRequestMapper()
|
||||||
|
{
|
||||||
|
delete m_staticFileController;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
if (m_adapter == 0) // format service unavailable if adapter is null
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
response.setStatus(500,"Service not available");
|
||||||
|
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Service not available";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
else // normal processing
|
||||||
|
{
|
||||||
|
QByteArray path=request.getPath();
|
||||||
|
|
||||||
|
// Handle pre-flight requests
|
||||||
|
if (request.getMethod() == "OPTIONS")
|
||||||
|
{
|
||||||
|
qDebug("WebAPIRequestMapper::service: method OPTIONS: assume pre-flight");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
response.setHeader("Access-Control-Allow-Headers", "*");
|
||||||
|
response.setHeader("Access-Control-Allow-Methods", "*");
|
||||||
|
response.setStatus(200, "OK");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.startsWith("/sdrangel"))
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setStatus(501,"Not implemented");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Not implemented";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path == WebAPIAdapterDaemon::daemonInstanceSummaryURL) {
|
||||||
|
daemonInstanceSummaryService(request, response);
|
||||||
|
} else if (path == WebAPIAdapterDaemon::daemonInstanceLoggingURL) {
|
||||||
|
daemonInstanceLoggingService(request, response);
|
||||||
|
} else if (path == WebAPIAdapterDaemon::daemonSettingsURL) {
|
||||||
|
daemonSettingsService(request, response);
|
||||||
|
} else if (path == WebAPIAdapterDaemon::daemonReportURL) {
|
||||||
|
daemonReportService(request, response);
|
||||||
|
} else if (path == WebAPIAdapterDaemon::daemonRunURL) {
|
||||||
|
daemonRunService(request, response);
|
||||||
|
} else {
|
||||||
|
m_staticFileController->service(request, response); // serve static pages
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIRequestMapper::daemonInstanceSummaryService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
if (request.getMethod() == "GET")
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDaemonSummaryResponse normalResponse;
|
||||||
|
|
||||||
|
int status = m_adapter->daemonInstanceSummary(normalResponse, errorResponse);
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(405,"Invalid HTTP method");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid HTTP method";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIRequestMapper::daemonInstanceLoggingService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGLoggingInfo query;
|
||||||
|
SWGSDRangel::SWGLoggingInfo normalResponse;
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
if (request.getMethod() == "GET")
|
||||||
|
{
|
||||||
|
int status = m_adapter->daemonInstanceLoggingGet(normalResponse, errorResponse);
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.getMethod() == "PUT")
|
||||||
|
{
|
||||||
|
QString jsonStr = request.getBody();
|
||||||
|
QJsonObject jsonObject;
|
||||||
|
|
||||||
|
if (parseJsonBody(jsonStr, jsonObject, response))
|
||||||
|
{
|
||||||
|
query.fromJson(jsonStr);
|
||||||
|
int status = m_adapter->daemonInstanceLoggingPut(query, normalResponse, errorResponse);
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(400,"Invalid JSON format");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid JSON format";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(405,"Invalid HTTP method");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid HTTP method";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIRequestMapper::daemonSettingsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
if ((request.getMethod() == "PUT") || (request.getMethod() == "PATCH"))
|
||||||
|
{
|
||||||
|
QString jsonStr = request.getBody();
|
||||||
|
QJsonObject jsonObject;
|
||||||
|
|
||||||
|
if (parseJsonBody(jsonStr, jsonObject, response))
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDeviceSettings normalResponse;
|
||||||
|
resetDeviceSettings(normalResponse);
|
||||||
|
QStringList deviceSettingsKeys;
|
||||||
|
|
||||||
|
if (validateDeviceSettings(normalResponse, jsonObject, deviceSettingsKeys))
|
||||||
|
{
|
||||||
|
int status = m_adapter->daemonSettingsPutPatch(
|
||||||
|
(request.getMethod() == "PUT"), // force settings on PUT
|
||||||
|
deviceSettingsKeys,
|
||||||
|
normalResponse,
|
||||||
|
errorResponse);
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(400,"Invalid JSON request");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid JSON request";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(400,"Invalid JSON format");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid JSON format";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.getMethod() == "GET")
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDeviceSettings normalResponse;
|
||||||
|
resetDeviceSettings(normalResponse);
|
||||||
|
int status = m_adapter->daemonSettingsGet(normalResponse, errorResponse);
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(405,"Invalid HTTP method");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid HTTP method";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIRequestMapper::daemonReportService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
if (request.getMethod() == "GET")
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDeviceReport normalResponse;
|
||||||
|
resetDeviceReport(normalResponse);
|
||||||
|
int status = m_adapter->daemonReportGet(normalResponse, errorResponse);
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(405,"Invalid HTTP method");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid HTTP method";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIRequestMapper::daemonRunService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
response.setHeader("Access-Control-Allow-Origin", "*");
|
||||||
|
|
||||||
|
if (request.getMethod() == "GET")
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDeviceState normalResponse;
|
||||||
|
int status = m_adapter->daemonRunGet(normalResponse, errorResponse);
|
||||||
|
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.getMethod() == "POST")
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDeviceState normalResponse;
|
||||||
|
int status = m_adapter->daemonRunPost(normalResponse, errorResponse);
|
||||||
|
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (request.getMethod() == "DELETE")
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGDeviceState normalResponse;
|
||||||
|
int status = m_adapter->daemonRunDelete(normalResponse, errorResponse);
|
||||||
|
|
||||||
|
response.setStatus(status);
|
||||||
|
|
||||||
|
if (status/100 == 2) {
|
||||||
|
response.write(normalResponse.asJson().toUtf8());
|
||||||
|
} else {
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.setStatus(405,"Invalid HTTP method");
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = "Invalid HTTP method";
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
bool WebAPIRequestMapper::validateDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings, QJsonObject& jsonObject, QStringList& deviceSettingsKeys)
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("tx")) {
|
||||||
|
deviceSettings.setTx(jsonObject["tx"].toInt());
|
||||||
|
} else {
|
||||||
|
deviceSettings.setTx(0); // assume Rx
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonObject.contains("deviceHwType") && jsonObject["deviceHwType"].isString()) {
|
||||||
|
deviceSettings.setDeviceHwType(new QString(jsonObject["deviceHwType"].toString()));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString *deviceHwType = deviceSettings.getDeviceHwType();
|
||||||
|
|
||||||
|
if ((*deviceHwType == "Airspy") && (deviceSettings.getTx() == 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("airspySettings") && jsonObject["airspySettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject airspySettingsJsonObject = jsonObject["airspySettings"].toObject();
|
||||||
|
deviceSettingsKeys = airspySettingsJsonObject.keys();
|
||||||
|
deviceSettings.setAirspySettings(new SWGSDRangel::SWGAirspySettings());
|
||||||
|
deviceSettings.getAirspySettings()->fromJsonObject(airspySettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "AirspyHF") && (deviceSettings.getTx() == 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("airspyHFSettings") && jsonObject["airspyHFSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject airspyHFSettingsJsonObject = jsonObject["airspyHFSettings"].toObject();
|
||||||
|
deviceSettingsKeys = airspyHFSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setAirspyHfSettings(new SWGSDRangel::SWGAirspyHFSettings());
|
||||||
|
deviceSettings.getAirspyHfSettings()->fromJsonObject(airspyHFSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "BladeRF") && (deviceSettings.getTx() == 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("bladeRFInputSettings") && jsonObject["bladeRFInputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject bladeRFInputSettingsJsonObject = jsonObject["bladeRFInputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = bladeRFInputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setBladeRfInputSettings(new SWGSDRangel::SWGBladeRFInputSettings());
|
||||||
|
deviceSettings.getBladeRfInputSettings()->fromJsonObject(bladeRFInputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "BladeRF") && (deviceSettings.getTx() != 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("bladeRFOutputSettings") && jsonObject["bladeRFOutputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject bladeRFOutputSettingsJsonObject = jsonObject["bladeRFOutputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = bladeRFOutputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setBladeRfOutputSettings(new SWGSDRangel::SWGBladeRFOutputSettings());
|
||||||
|
deviceSettings.getBladeRfOutputSettings()->fromJsonObject(bladeRFOutputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*deviceHwType == "FCDPro")
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("fcdProSettings") && jsonObject["fcdProSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject fcdProSettingsJsonObject = jsonObject["fcdProSettings"].toObject();
|
||||||
|
deviceSettingsKeys = fcdProSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setFcdProSettings(new SWGSDRangel::SWGFCDProSettings());
|
||||||
|
deviceSettings.getFcdProSettings()->fromJsonObject(fcdProSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*deviceHwType == "FCDProPlus")
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("fcdProPlusSettings") && jsonObject["fcdProPlusSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject fcdProPlusSettingsJsonObject = jsonObject["fcdProPlusSettings"].toObject();
|
||||||
|
deviceSettingsKeys = fcdProPlusSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setFcdProPlusSettings(new SWGSDRangel::SWGFCDProPlusSettings());
|
||||||
|
deviceSettings.getFcdProPlusSettings()->fromJsonObject(fcdProPlusSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*deviceHwType == "FileSource")
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("fileSourceSettings") && jsonObject["fileSourceSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject fileSourceSettingsJsonObject = jsonObject["fileSourceSettings"].toObject();
|
||||||
|
deviceSettingsKeys = fileSourceSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setFileSourceSettings(new SWGSDRangel::SWGFileSourceSettings());
|
||||||
|
deviceSettings.getFileSourceSettings()->fromJsonObject(fileSourceSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "HackRF") && (deviceSettings.getTx() == 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("hackRFInputSettings") && jsonObject["hackRFInputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject hackRFInputSettingsJsonObject = jsonObject["hackRFInputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = hackRFInputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setHackRfInputSettings(new SWGSDRangel::SWGHackRFInputSettings());
|
||||||
|
deviceSettings.getHackRfInputSettings()->fromJsonObject(hackRFInputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "HackRF") && (deviceSettings.getTx() != 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("hackRFOutputSettings") && jsonObject["hackRFOutputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject hackRFOutputSettingsJsonObject = jsonObject["hackRFOutputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = hackRFOutputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setHackRfOutputSettings(new SWGSDRangel::SWGHackRFOutputSettings());
|
||||||
|
deviceSettings.getHackRfOutputSettings()->fromJsonObject(hackRFOutputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "LimeSDR") && (deviceSettings.getTx() == 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("limeSdrInputSettings") && jsonObject["limeSdrInputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject limeSdrInputSettingsJsonObject = jsonObject["limeSdrInputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = limeSdrInputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setLimeSdrInputSettings(new SWGSDRangel::SWGLimeSdrInputSettings());
|
||||||
|
deviceSettings.getLimeSdrInputSettings()->fromJsonObject(limeSdrInputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "LimeSDR") && (deviceSettings.getTx() != 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("limeSdrOutputSettings") && jsonObject["limeSdrOutputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject limeSdrOutputSettingsJsonObject = jsonObject["limeSdrOutputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = limeSdrOutputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setLimeSdrOutputSettings(new SWGSDRangel::SWGLimeSdrOutputSettings());
|
||||||
|
deviceSettings.getLimeSdrOutputSettings()->fromJsonObject(limeSdrOutputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*deviceHwType == "Perseus")
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("perseusSettings") && jsonObject["perseusSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject perseusSettingsJsonObject = jsonObject["perseusSettings"].toObject();
|
||||||
|
deviceSettingsKeys = perseusSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setPerseusSettings(new SWGSDRangel::SWGPerseusSettings());
|
||||||
|
deviceSettings.getPerseusSettings()->fromJsonObject(perseusSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "PlutoSDR") && (deviceSettings.getTx() == 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("plutoSdrInputSettings") && jsonObject["plutoSdrInputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject plutoSdrInputSettingsJsonObject = jsonObject["plutoSdrInputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = plutoSdrInputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setPlutoSdrInputSettings(new SWGSDRangel::SWGPlutoSdrInputSettings());
|
||||||
|
deviceSettings.getPlutoSdrInputSettings()->fromJsonObject(plutoSdrInputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((*deviceHwType == "PlutoSDR") && (deviceSettings.getTx() != 0))
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("plutoSdrOutputSettings") && jsonObject["plutoSdrOutputSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject plutoSdrOutputSettingsJsonObject = jsonObject["plutoSdrOutputSettings"].toObject();
|
||||||
|
deviceSettingsKeys = plutoSdrOutputSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setPlutoSdrOutputSettings(new SWGSDRangel::SWGPlutoSdrOutputSettings());
|
||||||
|
deviceSettings.getPlutoSdrOutputSettings()->fromJsonObject(plutoSdrOutputSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*deviceHwType == "RTLSDR")
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("rtlSdrSettings") && jsonObject["rtlSdrSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject rtlSdrSettingsJsonObject = jsonObject["rtlSdrSettings"].toObject();
|
||||||
|
deviceSettingsKeys = rtlSdrSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setRtlSdrSettings(new SWGSDRangel::SWGRtlSdrSettings());
|
||||||
|
deviceSettings.getRtlSdrSettings()->fromJsonObject(rtlSdrSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*deviceHwType == "TestSource")
|
||||||
|
{
|
||||||
|
if (jsonObject.contains("testSourceSettings") && jsonObject["testSourceSettings"].isObject())
|
||||||
|
{
|
||||||
|
QJsonObject testSourceSettingsJsonObject = jsonObject["testSourceSettings"].toObject();
|
||||||
|
deviceSettingsKeys = testSourceSettingsJsonObject.keys();
|
||||||
|
deviceSettings.setTestSourceSettings(new SWGSDRangel::SWGTestSourceSettings());
|
||||||
|
deviceSettings.getTestSourceSettings()->fromJsonObject(testSourceSettingsJsonObject);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
void WebAPIRequestMapper::appendSettingsSubKeys(
|
||||||
|
const QJsonObject& parentSettingsJsonObject,
|
||||||
|
QJsonObject& childSettingsJsonObject,
|
||||||
|
const QString& parentKey,
|
||||||
|
QStringList& keyList)
|
||||||
|
{
|
||||||
|
childSettingsJsonObject = parentSettingsJsonObject[parentKey].toObject();
|
||||||
|
QStringList childSettingsKeys = childSettingsJsonObject.keys();
|
||||||
|
|
||||||
|
for (int i = 0; i < childSettingsKeys.size(); i++) {
|
||||||
|
keyList.append(parentKey + QString(".") + childSettingsKeys.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
bool WebAPIRequestMapper::parseJsonBody(QString& jsonStr, QJsonObject& jsonObject, qtwebapp::HttpResponse& response)
|
||||||
|
{
|
||||||
|
SWGSDRangel::SWGErrorResponse errorResponse;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
QByteArray jsonBytes(jsonStr.toStdString().c_str());
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(jsonBytes, &error);
|
||||||
|
|
||||||
|
if (error.error == QJsonParseError::NoError)
|
||||||
|
{
|
||||||
|
jsonObject = doc.object();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString errorMsg = QString("Input JSON error: ") + error.errorString() + QString(" at offset ") + QString::number(error.offset);
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = errorMsg;
|
||||||
|
response.setStatus(400, errorMsg.toUtf8());
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
return (error.error == QJsonParseError::NoError);
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
QString errorMsg = QString("Error parsing request: ") + ex.what();
|
||||||
|
errorResponse.init();
|
||||||
|
*errorResponse.getMessage() = errorMsg;
|
||||||
|
response.setStatus(500, errorMsg.toUtf8());
|
||||||
|
response.write(errorResponse.asJson().toUtf8());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
void WebAPIRequestMapper::resetDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings)
|
||||||
|
{
|
||||||
|
deviceSettings.cleanup();
|
||||||
|
deviceSettings.setDeviceHwType(0);
|
||||||
|
deviceSettings.setAirspySettings(0);
|
||||||
|
deviceSettings.setAirspyHfSettings(0);
|
||||||
|
deviceSettings.setBladeRfInputSettings(0);
|
||||||
|
deviceSettings.setBladeRfOutputSettings(0);
|
||||||
|
deviceSettings.setFcdProPlusSettings(0);
|
||||||
|
deviceSettings.setFcdProSettings(0);
|
||||||
|
deviceSettings.setFileSourceSettings(0);
|
||||||
|
deviceSettings.setHackRfInputSettings(0);
|
||||||
|
deviceSettings.setHackRfOutputSettings(0);
|
||||||
|
deviceSettings.setLimeSdrInputSettings(0);
|
||||||
|
deviceSettings.setLimeSdrOutputSettings(0);
|
||||||
|
deviceSettings.setPerseusSettings(0);
|
||||||
|
deviceSettings.setPlutoSdrInputSettings(0);
|
||||||
|
deviceSettings.setPlutoSdrOutputSettings(0);
|
||||||
|
deviceSettings.setRtlSdrSettings(0);
|
||||||
|
deviceSettings.setSdrDaemonSinkSettings(0);
|
||||||
|
deviceSettings.setSdrDaemonSourceSettings(0);
|
||||||
|
deviceSettings.setSdrPlaySettings(0);
|
||||||
|
deviceSettings.setTestSourceSettings(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: put in library in common with SDRangel. Can be static.
|
||||||
|
void WebAPIRequestMapper::resetDeviceReport(SWGSDRangel::SWGDeviceReport& deviceReport)
|
||||||
|
{
|
||||||
|
deviceReport.cleanup();
|
||||||
|
deviceReport.setDeviceHwType(0);
|
||||||
|
deviceReport.setAirspyHfReport(0);
|
||||||
|
deviceReport.setAirspyReport(0);
|
||||||
|
deviceReport.setFileSourceReport(0);
|
||||||
|
deviceReport.setLimeSdrInputReport(0);
|
||||||
|
deviceReport.setLimeSdrOutputReport(0);
|
||||||
|
deviceReport.setPerseusReport(0);
|
||||||
|
deviceReport.setPlutoSdrInputReport(0);
|
||||||
|
deviceReport.setPlutoSdrOutputReport(0);
|
||||||
|
deviceReport.setRtlSdrReport(0);
|
||||||
|
deviceReport.setSdrDaemonSinkReport(0);
|
||||||
|
deviceReport.setSdrDaemonSourceReport(0);
|
||||||
|
deviceReport.setSdrPlayReport(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SDRDaemon
|
||||||
|
|
||||||
|
|
76
sdrdaemon/webapi/webapirequestmapper.h
Normal file
76
sdrdaemon/webapi/webapirequestmapper.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2017 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRDaemon Swagger server adapter interface //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRDAEMON_WEBAPI_WEBAPIREQUESTMAPPER_H_
|
||||||
|
#define SDRDAEMON_WEBAPI_WEBAPIREQUESTMAPPER_H_
|
||||||
|
|
||||||
|
#include <QJsonParseError>
|
||||||
|
|
||||||
|
#include "httprequesthandler.h"
|
||||||
|
#include "httprequest.h"
|
||||||
|
#include "httpresponse.h"
|
||||||
|
#include "staticfilecontroller.h"
|
||||||
|
|
||||||
|
#include "export.h"
|
||||||
|
|
||||||
|
namespace SWGSDRangel
|
||||||
|
{
|
||||||
|
class SWGDeviceSettings;
|
||||||
|
class SWGDeviceReport;
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebAPIAdapterDaemon;
|
||||||
|
|
||||||
|
namespace SDRDaemon
|
||||||
|
{
|
||||||
|
|
||||||
|
class SDRBASE_API WebAPIRequestMapper : public qtwebapp::HttpRequestHandler {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WebAPIRequestMapper(QObject* parent=0);
|
||||||
|
~WebAPIRequestMapper();
|
||||||
|
void service(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
|
||||||
|
void setAdapter(WebAPIAdapterDaemon *adapter) { m_adapter = adapter; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
WebAPIAdapterDaemon *m_adapter;
|
||||||
|
qtwebapp::StaticFileController *m_staticFileController;
|
||||||
|
|
||||||
|
void daemonInstanceSummaryService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
|
||||||
|
void daemonInstanceLoggingService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
|
||||||
|
void daemonSettingsService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
|
||||||
|
void daemonRunService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
|
||||||
|
void daemonReportService(qtwebapp::HttpRequest& request, qtwebapp::HttpResponse& response);
|
||||||
|
|
||||||
|
bool validateDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings, QJsonObject& jsonObject, QStringList& deviceSettingsKeys);
|
||||||
|
|
||||||
|
void appendSettingsSubKeys(
|
||||||
|
const QJsonObject& parentSettingsJsonObject,
|
||||||
|
QJsonObject& childSettingsJsonObject,
|
||||||
|
const QString& parentKey,
|
||||||
|
QStringList& keyList);
|
||||||
|
|
||||||
|
bool parseJsonBody(QString& jsonStr, QJsonObject& jsonObject, qtwebapp::HttpResponse& response);
|
||||||
|
|
||||||
|
void resetDeviceSettings(SWGSDRangel::SWGDeviceSettings& deviceSettings);
|
||||||
|
void resetDeviceReport(SWGSDRangel::SWGDeviceReport& deviceReport);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SDRdaemon
|
||||||
|
|
||||||
|
#endif /* SDRDAEMON_WEBAPI_WEBAPIREQUESTMAPPER_H_ */
|
67
sdrdaemon/webapi/webapiserver.cpp
Normal file
67
sdrdaemon/webapi/webapiserver.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon Swagger server adapter interface //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
#include "httplistener.h"
|
||||||
|
#include "webapirequestmapper.h"
|
||||||
|
#include "webapiserver.h"
|
||||||
|
|
||||||
|
namespace SDRDaemon {
|
||||||
|
|
||||||
|
WebAPIServer::WebAPIServer(const QString& host, uint16_t port, WebAPIRequestMapper *requestMapper) :
|
||||||
|
m_requestMapper(requestMapper),
|
||||||
|
m_listener(0)
|
||||||
|
{
|
||||||
|
m_settings.host = host;
|
||||||
|
m_settings.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebAPIServer::~WebAPIServer()
|
||||||
|
{
|
||||||
|
if (m_listener) { delete m_listener; }
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIServer::start()
|
||||||
|
{
|
||||||
|
if (!m_listener)
|
||||||
|
{
|
||||||
|
m_listener = new qtwebapp::HttpListener(m_settings, m_requestMapper, qApp);
|
||||||
|
qInfo("WebAPIServer::start: starting web API server at http://%s:%d", qPrintable(m_settings.host), m_settings.port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIServer::stop()
|
||||||
|
{
|
||||||
|
if (m_listener)
|
||||||
|
{
|
||||||
|
delete m_listener;
|
||||||
|
m_listener = 0;
|
||||||
|
qInfo("WebAPIServer::stop: stopped web API server at http://%s:%d", qPrintable(m_settings.host), m_settings.port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebAPIServer::setHostAndPort(const QString& host, uint16_t port)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
m_settings.host = host;
|
||||||
|
m_settings.port = port;
|
||||||
|
m_listener = new qtwebapp::HttpListener(m_settings, m_requestMapper, qApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SDRdaemon
|
56
sdrdaemon/webapi/webapiserver.h
Normal file
56
sdrdaemon/webapi/webapiserver.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
|
||||||
|
// //
|
||||||
|
// SDRdaemon Swagger server adapter interface //
|
||||||
|
// //
|
||||||
|
// This program is free software; you can redistribute it and/or modify //
|
||||||
|
// it under the terms of the GNU General Public License as published by //
|
||||||
|
// the Free Software Foundation as version 3 of the License, or //
|
||||||
|
// //
|
||||||
|
// This program is distributed in the hope that it will be useful, //
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
||||||
|
// GNU General Public License V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SDRDAEMON_WEBAPI_WEBAPISERVER_H_
|
||||||
|
#define SDRDAEMON_WEBAPI_WEBAPISERVER_H_
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include "export.h"
|
||||||
|
|
||||||
|
namespace qtwebapp
|
||||||
|
{
|
||||||
|
class HttpListener;
|
||||||
|
class HttpListenerSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SDRDaemon {
|
||||||
|
|
||||||
|
class WebAPIRequestMapper;
|
||||||
|
|
||||||
|
class SDRBASE_API WebAPIServer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebAPIServer(const QString& host, uint16_t port, WebAPIRequestMapper *requestMapper);
|
||||||
|
~WebAPIServer();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
void setHostAndPort(const QString& host, uint16_t port);
|
||||||
|
const QString& getHost() const { return m_settings.host; }
|
||||||
|
int getPort() const { return m_settings.port; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
WebAPIRequestMapper *m_requestMapper;
|
||||||
|
qtwebapp::HttpListener *m_listener;
|
||||||
|
qtwebapp::HttpListenerSettings m_settings;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SDRdaemon
|
||||||
|
|
||||||
|
#endif /* SDRDAEMON_WEBAPI_WEBAPISERVER_H_ */
|
Loading…
Reference in New Issue
Block a user