1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-12-23 10:05:46 -05:00

Created SDRdaemon library

This commit is contained in:
f4exb 2018-08-18 15:51:46 +02:00
parent e073af634c
commit 411cb36a6f
14 changed files with 1714 additions and 0 deletions

View File

@ -222,6 +222,7 @@ endif()
add_subdirectory(sdrbase)
add_subdirectory(sdrgui)
add_subdirectory(sdrsrv)
add_subdirectory(sdrdaemon)
add_subdirectory(sdrbench)
add_subdirectory(httpserver)
add_subdirectory(logging)

55
sdrdaemon/CMakeLists.txt Normal file
View 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
View 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
View 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_ */

View 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;
}
}

View 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_ */

View 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();
}

View 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_ */

View 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;
}
}

View 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_ */

View 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

View 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_ */

View 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

View 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_ */