diff --git a/sdrdaemon/CMakeLists.txt b/sdrdaemon/CMakeLists.txt index cf8407a3e..c7f9e82c7 100644 --- a/sdrdaemon/CMakeLists.txt +++ b/sdrdaemon/CMakeLists.txt @@ -9,6 +9,7 @@ set(sdrdaemon_SOURCES channel/sdrdaemonchannelsource.cpp channel/sdrdaemondataqueue.cpp channel/sdrdaemonchannelsinkthread.cpp + channel/sdrdaemonchannelsinksettings.cpp webapi/webapiadapterdaemon.cpp webapi/webapirequestmapper.cpp webapi/webapiserver.cpp @@ -24,6 +25,7 @@ set(sdrdaemon_HEADERS channel/sdrdaemondataqueue.h channel/sdrdaemondatablock.h channel/sdrdaemonchannelsinkthread.h + channel/sdrdaemonchannelsinksettings.h webapi/webapiadapterdaemon.h webapi/webapirequestmapper.h webapi/webapiserver.h diff --git a/sdrdaemon/channel/sdrdaemonchannelsink.cpp b/sdrdaemon/channel/sdrdaemonchannelsink.cpp index 9b4a270fc..62d6c5d8d 100644 --- a/sdrdaemon/channel/sdrdaemonchannelsink.cpp +++ b/sdrdaemon/channel/sdrdaemonchannelsink.cpp @@ -33,6 +33,8 @@ #include "channel/sdrdaemonchannelsinkthread.h" #include "sdrdaemonchannelsink.h" +MESSAGE_CLASS_DEFINITION(SDRDaemonChannelSink::MsgConfigureSDRDaemonChannelSink, Message) + const QString SDRDaemonChannelSink::m_channelIdURI = "sdrangel.channel.sdrdaemonsink"; const QString SDRDaemonChannelSink::m_channelId = "SDRDaemonChannelSink"; @@ -247,6 +249,14 @@ bool SDRDaemonChannelSink::handleMessage(const Message& cmd __attribute__((unuse return true; } + else if (MsgConfigureSDRDaemonChannelSink::match(cmd)) + { + MsgConfigureSDRDaemonChannelSink& cfg = (MsgConfigureSDRDaemonChannelSink&) cmd; + qDebug() << "SDRDaemonChannelSink::handleMessage: MsgConfigureSDRDaemonChannelSink"; + applySettings(cfg.getSettings(), cfg.getForce()); + + return true; + } else { return false; @@ -255,11 +265,50 @@ bool SDRDaemonChannelSink::handleMessage(const Message& cmd __attribute__((unuse QByteArray SDRDaemonChannelSink::serialize() const { - SimpleSerializer s(1); - return s.final(); + return m_settings.serialize(); } bool SDRDaemonChannelSink::deserialize(const QByteArray& data __attribute__((unused))) { - return false; + if (m_settings.deserialize(data)) + { + MsgConfigureSDRDaemonChannelSink *msg = MsgConfigureSDRDaemonChannelSink::create(m_settings, true); + m_inputMessageQueue.push(msg); + return true; + } + else + { + m_settings.resetToDefaults(); + MsgConfigureSDRDaemonChannelSink *msg = MsgConfigureSDRDaemonChannelSink::create(m_settings, true); + m_inputMessageQueue.push(msg); + return false; + } +} + +void SDRDaemonChannelSink::applySettings(const SDRDaemonChannelSinkSettings& settings, bool force) +{ + qDebug() << "SDRDaemonChannelSink::applySettings:" + << " m_nbFECBlocks: " << settings.m_nbFECBlocks + << " m_txDelay: " << settings.m_txDelay + << " m_dataAddress: " << settings.m_dataAddress + << " m_dataPort: " << settings.m_dataPort + << " force: " << force; + + if ((m_settings.m_nbFECBlocks != settings.m_nbFECBlocks) || force) { + m_nbBlocksFEC = settings.m_nbFECBlocks; + } + + if ((m_settings.m_txDelay != settings.m_txDelay) || force) { + m_txDelay = settings.m_txDelay; + } + + if ((m_settings.m_dataAddress != settings.m_dataAddress) || force) { + m_dataAddress = settings.m_dataAddress; + } + + if ((m_settings.m_dataPort != settings.m_dataPort) || force) { + m_dataPort = settings.m_dataPort; + } + + m_settings = settings; } diff --git a/sdrdaemon/channel/sdrdaemonchannelsink.h b/sdrdaemon/channel/sdrdaemonchannelsink.h index 11c7a7841..06b8ebbe4 100644 --- a/sdrdaemon/channel/sdrdaemonchannelsink.h +++ b/sdrdaemon/channel/sdrdaemonchannelsink.h @@ -31,6 +31,7 @@ #include "channel/channelsinkapi.h" #include "channel/sdrdaemondataqueue.h" #include "channel/sdrdaemondatablock.h" +#include "channel/sdrdaemonchannelsinksettings.h" class DeviceSourceAPI; class ThreadedBasebandSampleSink; @@ -40,6 +41,29 @@ class SDRDaemonChannelSinkThread; class SDRDaemonChannelSink : public BasebandSampleSink, public ChannelSinkAPI { Q_OBJECT public: + class MsgConfigureSDRDaemonChannelSink : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const SDRDaemonChannelSinkSettings& getSettings() const { return m_settings; } + bool getForce() const { return m_force; } + + static MsgConfigureSDRDaemonChannelSink* create(const SDRDaemonChannelSinkSettings& settings, bool force) + { + return new MsgConfigureSDRDaemonChannelSink(settings, force); + } + + private: + SDRDaemonChannelSinkSettings m_settings; + bool m_force; + + MsgConfigureSDRDaemonChannelSink(const SDRDaemonChannelSinkSettings& settings, bool force) : + Message(), + m_settings(settings), + m_force(force) + { } + }; + SDRDaemonChannelSink(DeviceSourceAPI *deviceAPI); virtual ~SDRDaemonChannelSink(); virtual void destroy() { delete this; } @@ -76,6 +100,7 @@ private: DownChannelizer* m_channelizer; bool m_running; + SDRDaemonChannelSinkSettings m_settings; SDRDaemonDataQueue m_dataQueue; SDRDaemonChannelSinkThread *m_sinkThread; CM256 m_cm256; @@ -96,6 +121,8 @@ private: int m_txDelay; QString m_dataAddress; uint16_t m_dataPort; + + void applySettings(const SDRDaemonChannelSinkSettings& settings, bool force = false); }; #endif /* SDRDAEMON_CHANNEL_SDRDAEMONCHANNELSINK_H_ */ diff --git a/sdrdaemon/channel/sdrdaemonchannelsinksettings.cpp b/sdrdaemon/channel/sdrdaemonchannelsinksettings.cpp new file mode 100644 index 000000000..7a5a2e57c --- /dev/null +++ b/sdrdaemon/channel/sdrdaemonchannelsinksettings.cpp @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// SDRdaemon sink channel (Rx) main settings // +// // +// 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 "dsp/dspengine.h" +#include "util/simpleserializer.h" +#include "settings/serializable.h" +#include "channel/sdrdaemonchannelsinksettings.h" + +SDRDaemonChannelSinkSettings::SDRDaemonChannelSinkSettings() +{ + resetToDefaults(); +} + +void SDRDaemonChannelSinkSettings::resetToDefaults() +{ + m_nbFECBlocks = 0; + m_txDelay = 100; + m_dataAddress = "127.0.0.1"; + m_dataPort = 9090; +} + +QByteArray SDRDaemonChannelSinkSettings::serialize() const +{ + SimpleSerializer s(1); + s.writeU32(1, m_nbFECBlocks); + s.writeU32(2, m_txDelay); + s.writeString(3, m_dataAddress); + s.writeU32(4, m_dataPort); + + return s.final(); +} + +bool SDRDaemonChannelSinkSettings::deserialize(const QByteArray& data) +{ + SimpleDeserializer d(data); + + if(!d.isValid()) + { + resetToDefaults(); + return false; + } + + if(d.getVersion() == 1) + { + uint32_t tmp; + QString strtmp; + + d.readU32(1, &tmp, 0); + + if (tmp < 128) { + m_nbFECBlocks = tmp; + } else { + m_nbFECBlocks = 0; + } + + d.readU32(2, &m_txDelay, 100); + d.readString(3, &m_dataAddress, "127.0.0.1"); + d.readU32(4, &tmp, 0); + + if ((tmp > 1023) && (tmp < 65535)) { + m_dataPort = tmp; + } else { + m_dataPort = 9090; + } + + return true; + } + else + { + resetToDefaults(); + return false; + } +} + + + + + diff --git a/sdrdaemon/channel/sdrdaemonchannelsinksettings.h b/sdrdaemon/channel/sdrdaemonchannelsinksettings.h new file mode 100644 index 000000000..ff9be3f25 --- /dev/null +++ b/sdrdaemon/channel/sdrdaemonchannelsinksettings.h @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// SDRdaemon sink channel (Rx) main settings // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRDAEMON_CHANNEL_SDRDAEMONCHANNELSINKSETTINGS_H_ +#define SDRDAEMON_CHANNEL_SDRDAEMONCHANNELSINKSETTINGS_H_ + +#include + +class Serializable; + +struct SDRDaemonChannelSinkSettings +{ + uint16_t m_nbFECBlocks; + uint32_t m_txDelay; + QString m_dataAddress; + uint16_t m_dataPort; + + SDRDaemonChannelSinkSettings(); + void resetToDefaults(); + QByteArray serialize() const; + bool deserialize(const QByteArray& data); +}; + +#endif /* SDRDAEMON_CHANNEL_SDRDAEMONCHANNELSINKSETTINGS_H_ */