Added the SDRdaemon server executable

This commit is contained in:
f4exb 2018-08-18 21:30:51 +02:00
parent 411cb36a6f
commit a1fbc790bf
7 changed files with 178 additions and 20 deletions

View File

@ -327,6 +327,31 @@ target_link_libraries(sdrangelbench
target_compile_features(sdrangelbench PRIVATE cxx_generalized_initializers) # cmake >= 3.1.0
target_link_libraries(sdrangelbench Qt5::Multimedia)
##############################################################################
# SDRdaemon application
set(sdrdaemonsrv_SOURCES
appdaemon/main.cpp
)
add_executable(sdrdaemonsrv
${sdrdaemonsrv_SOURCES}
)
target_include_directories(sdrdaemonsrv
PUBLIC ${CMAKE_SOURCE_DIR}/sdrdaemon
)
target_link_libraries(sdrdaemonsrv
sdrdaemon
sdrbase
logging
${QT_LIBRARIES}
)
target_compile_features(sdrdaemonsrv PRIVATE cxx_generalized_initializers) # cmake >= 3.1.0
target_link_libraries(sdrdaemonsrv Qt5::Multimedia)
##############################################################################
if (BUILD_DEBIAN)
@ -360,6 +385,7 @@ endif(LIBUSB_FOUND AND UNIX)
install(TARGETS sdrangel DESTINATION bin)
install(TARGETS sdrangelsrv DESTINATION bin)
install(TARGETS sdrangelbench DESTINATION bin)
install(TARGETS sdrdaemonsrv DESTINATION bin)
#install(TARGETS sdrbase DESTINATION lib)
#install files and directories

115
appdaemon/main.cpp Normal file
View File

@ -0,0 +1,115 @@
///////////////////////////////////////////////////////////////////////////////////
// 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 <QCoreApplication>
#include <QSysInfo>
#include <signal.h>
#include <unistd.h>
#include <vector>
#include "mainparser.h"
#include "loggerwithfile.h"
#include "sdrdaemonmain.h"
#include "dsp/dsptypes.h"
void handler(int sig) {
fprintf(stderr, "quit the application by signal(%d).\n", sig);
QCoreApplication::quit();
}
void catchUnixSignals(const std::vector<int>& quitSignals) {
sigset_t blocking_mask;
sigemptyset(&blocking_mask);
for (std::vector<int>::const_iterator it = quitSignals.begin(); it != quitSignals.end(); ++it) {
sigaddset(&blocking_mask, *it);
}
struct sigaction sa;
sa.sa_handler = handler;
sa.sa_mask = blocking_mask;
sa.sa_flags = 0;
for (std::vector<int>::const_iterator it = quitSignals.begin(); it != quitSignals.end(); ++it) {
sigaction(*it, &sa, 0);
}
}
static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *logger)
{
QCoreApplication a(argc, argv);
QCoreApplication::setOrganizationName("f4exb");
QCoreApplication::setApplicationName("SDRdaemonSrv");
QCoreApplication::setApplicationVersion("4.1.0");
int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
std::vector<int> vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int));
catchUnixSignals(vsig);
MainParser parser;
parser.parse(a);
#if QT_VERSION >= 0x050400
qInfo("%s %s Qt %s %db %s %s DSP Rx:%db Tx:%db PID %lld",
qPrintable(QCoreApplication::applicationName()),
qPrintable(QCoreApplication::applicationVersion()),
qPrintable(QString(QT_VERSION_STR)),
QT_POINTER_SIZE*8,
qPrintable(QSysInfo::currentCpuArchitecture()),
qPrintable(QSysInfo::prettyProductName()),
SDR_RX_SAMP_SZ,
SDR_TX_SAMP_SZ,
QCoreApplication::applicationPid());
#else
qInfo("%s %s Qt %s %db DSP Rx:%db Tx:%db PID %lld",
qPrintable(QCoreApplication::applicationName()),
qPrintable((QCoreApplication::>applicationVersion()),
qPrintable(QString(QT_VERSION_STR)),
QT_POINTER_SIZE*8,
SDR_RX_SAMP_SZ,
SDR_TX_SAMP_SZ,
QCoreApplication::applicationPid());
#endif
SDRDaemonMain m(logger, parser, &a);
// This will cause the application to exit when SDRdaemon is finished
QObject::connect(&m, SIGNAL(finished()), &a, SLOT(quit()));
return a.exec();
}
int main(int argc, char* argv[])
{
qtwebapp::LoggerWithFile *logger = new qtwebapp::LoggerWithFile(qApp);
logger->installMsgHandler();
int res = runQtApplication(argc, argv, logger);
qWarning("SDRdaemon quit.");
return res;
}

View File

@ -55,9 +55,15 @@ PluginManager::~PluginManager()
void PluginManager::loadPlugins(const QString& pluginsSubDir)
{
QString applicationDirPath = QCoreApplication::instance()->applicationDirPath();
QString applicationLibPath = applicationDirPath + "/../lib/" + pluginsSubDir;
QString applicationBuildPath = applicationDirPath + "/" + pluginsSubDir;
loadPluginsPart(pluginsSubDir);
loadPluginsFinal();
}
void PluginManager::loadPluginsPart(const QString& pluginsSubDir)
{
QString applicationDirPath = QCoreApplication::instance()->applicationDirPath();
QString applicationLibPath = applicationDirPath + "/../lib/" + pluginsSubDir;
QString applicationBuildPath = applicationDirPath + "/" + pluginsSubDir;
qDebug() << "PluginManager::loadPlugins: " << qPrintable(applicationLibPath) << "," << qPrintable(applicationBuildPath);
QDir pluginsLibDir = QDir(applicationLibPath);
@ -65,16 +71,19 @@ void PluginManager::loadPlugins(const QString& pluginsSubDir)
loadPluginsDir(pluginsLibDir);
loadPluginsDir(pluginsBuildDir);
}
qSort(m_plugins);
void PluginManager::loadPluginsFinal()
{
qSort(m_plugins);
for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
{
it->pluginInterface->initPlugin(&m_pluginAPI);
}
for (Plugins::const_iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
{
it->pluginInterface->initPlugin(&m_pluginAPI);
}
DeviceEnumerator::instance()->enumerateRxDevices(this);
DeviceEnumerator::instance()->enumerateTxDevices(this);
DeviceEnumerator::instance()->enumerateRxDevices(this);
DeviceEnumerator::instance()->enumerateTxDevices(this);
}
void PluginManager::registerRxChannel(const QString& channelIdURI, const QString& channelId, PluginInterface* plugin)

View File

@ -43,6 +43,8 @@ public:
PluginAPI *getPluginAPI() { return &m_pluginAPI; }
void loadPlugins(const QString& pluginsSubDir);
void loadPluginsPart(const QString& pluginsSubDir);
void loadPluginsFinal();
const Plugins& getPlugins() const { return m_plugins; }
// Callbacks from the plugins

View File

@ -24,6 +24,7 @@
#include <QResource>
#include <unistd.h>
#include "mainparser.h"
#include "dsp/dspengine.h"
#include "dsp/dspdevicesourceengine.h"
#include "plugin/pluginmanager.h"
@ -44,12 +45,14 @@ SDRDaemonMain::SDRDaemonMain(qtwebapp::LoggerWithFile *logger, const MainParser&
m_dspEngine(DSPEngine::instance()),
m_lastEngineState(DSPDeviceSourceEngine::StNotStarted)
{
qDebug() << "SDRdaemon::SDRdaemon: start";
qDebug() << "SDRDaemonMain::SDRDaemonMain: start";
m_instance = this;
m_pluginManager = new PluginManager(this);
m_pluginManager->loadPlugins(QString("pluginssrv"));
m_pluginManager->loadPluginsPart(QString("pluginssrv/samplesink"));
m_pluginManager->loadPluginsPart(QString("pluginssrv/samplesource"));
m_pluginManager->loadPluginsFinal();
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleMessages()), Qt::QueuedConnection);
m_masterTimer.start(50);
@ -59,9 +62,9 @@ SDRDaemonMain::SDRDaemonMain(qtwebapp::LoggerWithFile *logger, const MainParser&
QString applicationDirPath = QCoreApplication::instance()->applicationDirPath();
if (QResource::registerResource(applicationDirPath + "/sdrbase.rcc")) {
qDebug("MainCore::MainCore: registered resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
qDebug("SDRDaemonMain::SDRDaemonMain: registered resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
} else {
qWarning("MainCore::MainCore: could not register resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
qWarning("SDRDaemonMain::SDRDaemonMain: could not register resource file %s/%s", qPrintable(applicationDirPath), "sdrbase.rcc");
}
m_apiAdapter = new WebAPIAdapterDaemon(*this);
@ -70,7 +73,7 @@ SDRDaemonMain::SDRDaemonMain(qtwebapp::LoggerWithFile *logger, const MainParser&
m_apiServer = new SDRDaemon::WebAPIServer(parser.getServerAddress(), parser.getServerPort(), m_requestMapper);
m_apiServer->start();
qDebug() << "SDRdaemon::SDRdaemon: end";
qDebug() << "SDRDaemonMain::SDRDaemonMain: end";
}
SDRDaemonMain::~SDRDaemonMain()
@ -83,13 +86,13 @@ SDRDaemonMain::~SDRDaemonMain()
delete m_pluginManager;
qDebug() << "SDRdaemon::~SDRdaemon: end";
qDebug() << "SDRDaemonMain::~SDRdaemon: end";
delete m_logger;
}
void SDRDaemonMain::loadSettings()
{
qDebug() << "SDRdaemon::loadSettings";
qDebug() << "SDRDaemonMain::loadSettings";
m_settings.load();
setLoggingOptions();
@ -155,7 +158,7 @@ void SDRDaemonMain::handleMessages()
while ((message = m_inputMessageQueue.pop()) != 0)
{
qDebug("SDRdaemon::handleMessages: message: %s", message->getIdentifier());
qDebug("SDRDaemonMain::handleMessages: message: %s", message->getIdentifier());
handleMessage(*message);
delete message;
}

View File

@ -26,7 +26,6 @@
#include <QObject>
#include <QTimer>
#include "mainparser.h"
#include "sdrdaemonsettings.h"
#include "util/messagequeue.h"
@ -39,6 +38,7 @@ namespace qtwebapp {
class LoggerWithFile;
}
class MainParser;
class DSPEngine;
class PluginManager;
class Message;
@ -51,6 +51,9 @@ public:
~SDRDaemonMain();
static SDRDaemonMain *getInstance() { return m_instance; } // Main Core is de facto a singleton so this just returns its reference
signals:
void finished();
private:
static SDRDaemonMain *m_instance;
qtwebapp::LoggerWithFile *m_logger;

View File

@ -81,7 +81,7 @@ void WebAPIRequestMapper::service(qtwebapp::HttpRequest& request, qtwebapp::Http
return;
}
if (path.startsWith("/sdrangel"))
if (path.startsWith("/sdrangel") && (path != "/sdrangel_logo.png"))
{
SWGSDRangel::SWGErrorResponse errorResponse;
response.setStatus(501,"Not implemented");