diff --git a/sdrdaemon/CMakeLists.txt b/sdrdaemon/CMakeLists.txt index 36f116f7a..aa834977d 100644 --- a/sdrdaemon/CMakeLists.txt +++ b/sdrdaemon/CMakeLists.txt @@ -11,6 +11,7 @@ set(sdrdaemon_SOURCES channel/sdrdaemonchannelsinkthread.cpp channel/sdrdaemonchannelsinksettings.cpp channel/sdrdaemonchannelsourcesettings.cpp + channel/sdrdaemonchannelsourcethread.cpp webapi/webapiadapterdaemon.cpp webapi/webapirequestmapper.cpp webapi/webapiserver.cpp @@ -28,6 +29,7 @@ set(sdrdaemon_HEADERS channel/sdrdaemonchannelsinkthread.h channel/sdrdaemonchannelsinksettings.h channel/sdrdaemonchannelsourcesettings.h + channel/sdrdaemonchannelsourcethread.h webapi/webapiadapterdaemon.h webapi/webapirequestmapper.h webapi/webapiserver.h diff --git a/sdrdaemon/channel/sdrdaemonchannelsourcethread.cpp b/sdrdaemon/channel/sdrdaemonchannelsourcethread.cpp new file mode 100644 index 000000000..5498b9a84 --- /dev/null +++ b/sdrdaemon/channel/sdrdaemonchannelsourcethread.cpp @@ -0,0 +1,112 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// SDRdaemon source channel (Tx) UDP receiver thread // +// // +// 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 "channel/sdrdaemondataqueue.h" +#include "channel/sdrdaemondatablock.h" +#include "channel/sdrdaemonchannelsourcethread.h" + +#include "cm256.h" + +MESSAGE_CLASS_DEFINITION(SDRDaemonChannelSourceThread::MsgStartStop, Message) + +SDRDaemonChannelSourceThread::SDRDaemonChannelSourceThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent) : + QThread(parent), + m_running(false), + m_dataQueue(dataQueue), + m_cm256(cm256), + m_address(QHostAddress::LocalHost), + m_socket(0) +{ + connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); + connect(m_dataQueue, SIGNAL(dataBlockEnqueued()), this, SLOT(handleData()), Qt::QueuedConnection); +} + +SDRDaemonChannelSourceThread::~SDRDaemonChannelSourceThread() +{ + qDebug("SDRDaemonChannelSourceThread::~SDRDaemonChannelSourceThread"); +} + +void SDRDaemonChannelSourceThread::startStop(bool start) +{ + MsgStartStop *msg = MsgStartStop::create(start); + m_inputMessageQueue.push(msg); +} + +void SDRDaemonChannelSourceThread::startWork() +{ + qDebug("SDRDaemonChannelSourceThread::startWork"); + m_startWaitMutex.lock(); + m_socket = new QUdpSocket(this); + start(); + while(!m_running) + m_startWaiter.wait(&m_startWaitMutex, 100); + m_startWaitMutex.unlock(); +} + +void SDRDaemonChannelSourceThread::stopWork() +{ + qDebug("SDRDaemonChannelSourceThread::stopWork"); + delete m_socket; + m_socket = 0; + m_running = false; + wait(); +} + +void SDRDaemonChannelSourceThread::run() +{ + qDebug("SDRDaemonChannelSourceThread::run: begin"); + m_running = true; + m_startWaiter.wakeAll(); + + while (m_running) + { + sleep(1); // Do nothing as everything is in the data handler (dequeuer) + } + + m_running = false; + qDebug("SDRDaemonChannelSourceThread::run: end"); +} + + +void SDRDaemonChannelSourceThread::handleInputMessages() +{ + Message* message; + + while ((message = m_inputMessageQueue.pop()) != 0) + { + if (MsgStartStop::match(*message)) + { + MsgStartStop* notif = (MsgStartStop*) message; + qDebug("SDRDaemonChannelSourceThread::handleInputMessages: MsgStartStop: %s", notif->getStartStop() ? "start" : "stop"); + + if (notif->getStartStop()) { + startWork(); + } else { + stopWork(); + } + + delete message; + } + } +} diff --git a/sdrdaemon/channel/sdrdaemonchannelsourcethread.h b/sdrdaemon/channel/sdrdaemonchannelsourcethread.h new file mode 100644 index 000000000..e7f89e8ce --- /dev/null +++ b/sdrdaemon/channel/sdrdaemonchannelsourcethread.h @@ -0,0 +1,90 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// SDRdaemon source channel (Tx) UDP receiver thread // +// // +// 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_SDRDAEMONCHANNELSOURCETHREAD_H_ +#define SDRDAEMON_CHANNEL_SDRDAEMONCHANNELSOURCETHREAD_H_ + +#include +#include +#include +#include + +#include "util/message.h" +#include "util/messagequeue.h" + +class SDRDaemonDataQueue; +class SDRDaemonDataBlock; +class CM256; +class QUdpSocket; + +class SDRDaemonChannelSourceThread : public QThread { + Q_OBJECT +public: + class MsgStartStop : public Message { + MESSAGE_CLASS_DECLARATION + + public: + bool getStartStop() const { return m_startStop; } + + static MsgStartStop* create(bool startStop) { + return new MsgStartStop(startStop); + } + + protected: + bool m_startStop; + + MsgStartStop(bool startStop) : + Message(), + m_startStop(startStop) + { } + }; + + SDRDaemonChannelSourceThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent = 0); + ~SDRDaemonChannelSourceThread(); + + void startStop(bool start); + +private: + QMutex m_startWaitMutex; + QWaitCondition m_startWaiter; + bool m_running; + + SDRDaemonDataQueue *m_dataQueue; + CM256 *m_cm256; //!< CM256 library object + + QHostAddress m_address; + QUdpSocket *m_socket; + + MessageQueue m_inputMessageQueue; + + void startWork(); + void stopWork(); + + void run(); + +private slots: + void handleInputMessages(); +}; + + + +#endif /* SDRDAEMON_CHANNEL_SDRDAEMONCHANNELSOURCETHREAD_H_ */