diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d39b60f0..ed0465ff0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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
diff --git a/appdaemon/main.cpp b/appdaemon/main.cpp
new file mode 100644
index 000000000..6194726cf
--- /dev/null
+++ b/appdaemon/main.cpp
@@ -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 . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include
+#include
+
+#include
+#include
+#include
+
+#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& quitSignals) {
+ sigset_t blocking_mask;
+ sigemptyset(&blocking_mask);
+
+ for (std::vector::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::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 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;
+}
+
+
+
+
+
diff --git a/sdrbase/plugin/pluginmanager.cpp b/sdrbase/plugin/pluginmanager.cpp
index f94f9b481..17574b33e 100644
--- a/sdrbase/plugin/pluginmanager.cpp
+++ b/sdrbase/plugin/pluginmanager.cpp
@@ -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)
diff --git a/sdrbase/plugin/pluginmanager.h b/sdrbase/plugin/pluginmanager.h
index fafb25c34..e313563d9 100644
--- a/sdrbase/plugin/pluginmanager.h
+++ b/sdrbase/plugin/pluginmanager.h
@@ -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
diff --git a/sdrdaemon/sdrdaemonmain.cpp b/sdrdaemon/sdrdaemonmain.cpp
index db2567772..6e26ee02e 100644
--- a/sdrdaemon/sdrdaemonmain.cpp
+++ b/sdrdaemon/sdrdaemonmain.cpp
@@ -24,6 +24,7 @@
#include
#include
+#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;
}
diff --git a/sdrdaemon/sdrdaemonmain.h b/sdrdaemon/sdrdaemonmain.h
index 1d9fe0862..3ca10d0d6 100644
--- a/sdrdaemon/sdrdaemonmain.h
+++ b/sdrdaemon/sdrdaemonmain.h
@@ -26,7 +26,6 @@
#include
#include
-#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;
diff --git a/sdrdaemon/webapi/webapirequestmapper.cpp b/sdrdaemon/webapi/webapirequestmapper.cpp
index 3b2a6eb7f..c8b2cd807 100644
--- a/sdrdaemon/webapi/webapirequestmapper.cpp
+++ b/sdrdaemon/webapi/webapirequestmapper.cpp
@@ -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");