diff --git a/sdrdaemon/CMakeLists.txt b/sdrdaemon/CMakeLists.txt index 52422863e..b70416576 100644 --- a/sdrdaemon/CMakeLists.txt +++ b/sdrdaemon/CMakeLists.txt @@ -7,6 +7,7 @@ set(sdrdaemon_SOURCES sdrdaemonparser.cpp channel/sdrdaemonchannelsink.cpp channel/sdrdaemonchannelsource.cpp + channel/sdrdaemondataqueue.cpp webapi/webapiadapterdaemon.cpp webapi/webapirequestmapper.cpp webapi/webapiserver.cpp @@ -19,6 +20,8 @@ set(sdrdaemon_HEADERS sdrdaemonparser.h channel/sdrdaemonchannelsink.h channel/sdrdaemonchannelsource.h + channel/sdrdaemondataqueue.h + channel/sdrdaemondatablock.h webapi/webapiadapterdaemon.h webapi/webapirequestmapper.h webapi/webapiserver.h diff --git a/sdrdaemon/channel/sdrdaemondatablock.h b/sdrdaemon/channel/sdrdaemondatablock.h index 6d3c93de1..9a33e022a 100644 --- a/sdrdaemon/channel/sdrdaemondatablock.h +++ b/sdrdaemon/channel/sdrdaemondatablock.h @@ -29,57 +29,57 @@ #define UDPSINKFEC_UDPSIZE 512 #define UDPSINKFEC_NBORIGINALBLOCKS 128 -#define UDPSINKFEC_NBTXBLOCKS 8 - -namespace SDRDaemon { +//#define UDPSINKFEC_NBTXBLOCKS 8 #pragma pack(push, 1) -struct MetaDataFEC +struct SDRDaemonMetaDataFEC { uint32_t m_centerFrequency; //!< 4 center frequency in kHz uint32_t m_sampleRate; //!< 8 sample rate in Hz - uint8_t m_sampleBytes; //!< 9 MSB(4): indicators, LSB(4) number of bytes per sample - uint8_t m_sampleBits; //!< 10 number of effective bits per sample + uint8_t m_sampleBytes; //!< 9 MSB(4): indicators, LSB(4) number of bytes per sample (2 or 3) + uint8_t m_sampleBits; //!< 10 number of effective bits per sample (8 t0 24) uint8_t m_nbOriginalBlocks; //!< 11 number of blocks with original (protected) data uint8_t m_nbFECBlocks; //!< 12 number of blocks carrying FEC uint32_t m_tv_sec; //!< 16 seconds of timestamp at start time of super-frame processing uint32_t m_tv_usec; //!< 20 microseconds of timestamp at start time of super-frame processing uint32_t m_crc32; //!< 24 CRC32 of the above - bool operator==(const MetaDataFEC& rhs) + bool operator==(const SDRDaemonMetaDataFEC& rhs) { return (memcmp((const void *) this, (const void *) &rhs, 12) == 0); // Only the 12 first bytes are relevant } void init() { - memset((void *) this, 0, sizeof(MetaDataFEC)); + memset((void *) this, 0, sizeof(SDRDaemonMetaDataFEC)); m_nbFECBlocks = -1; } }; -struct Header +struct SDRDaemonHeader { uint16_t m_frameIndex; uint8_t m_blockIndex; uint8_t m_filler; }; -static const int samplesPerBlock = (UDPSINKFEC_UDPSIZE - sizeof(Header)) / sizeof(Sample); +static const int SDRDaemonUdpSize = UDPSINKFEC_UDPSIZE; +static const int SDRDaemonNbOrginalBlocks = UDPSINKFEC_NBORIGINALBLOCKS; +static const int SDRDaemonSamplesPerBlock = (UDPSINKFEC_UDPSIZE - sizeof(SDRDaemonHeader)) / (SDR_RX_SAMP_SZ/4); -struct ProtectedBlock +struct SDRDaemonProtectedBlock { - Sample m_samples[samplesPerBlock]; + Sample m_samples[SDRDaemonSamplesPerBlock]; }; -struct SuperBlock +struct SDRDaemonSuperBlock { - Header m_header; - ProtectedBlock m_protectedBlock; + SDRDaemonHeader m_header; + SDRDaemonProtectedBlock m_protectedBlock; }; #pragma pack(pop) -struct TxControlBlock +struct SDRDaemonTxControlBlock { bool m_processed; uint16_t m_frameIndex; @@ -87,14 +87,11 @@ struct TxControlBlock int m_txDelay; }; -class DataBlock +class SDRDaemonDataBlock { - SuperBlock m_superBlock; - TxControlBlock m_controlBlock; +public: + SDRDaemonTxControlBlock m_controlBlock; + SDRDaemonSuperBlock m_superBlock; }; -} // namespace SDRDaemon - - - #endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */ diff --git a/sdrdaemon/channel/sdrdaemondataqueue.cpp b/sdrdaemon/channel/sdrdaemondataqueue.cpp new file mode 100644 index 000000000..b2be6ea41 --- /dev/null +++ b/sdrdaemon/channel/sdrdaemondataqueue.cpp @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// SDRdaemon sink channel (Rx) data blocks queue // +// // +// 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 "channel/sdrdaemondataqueue.h" +#include "channel/sdrdaemondatablock.h" + +SDRDaemonDataQueue::SDRDaemonDataQueue(QObject* parent) : + QObject(parent), + m_lock(QMutex::Recursive), + m_queue() +{ +} + +SDRDaemonDataQueue::~SDRDaemonDataQueue() +{ + SDRDaemonDataBlock* data; + + while ((data = pop()) != 0) + { + qDebug() << "SDRDaemonDataQueue::~SDRDaemonDataQueue: data block was still in queue"; + delete data; + } +} + +void SDRDaemonDataQueue::push(SDRDaemonDataBlock* data, bool emitSignal) +{ + if (data) + { + m_lock.lock(); + m_queue.append(data); + m_lock.unlock(); + } + + if (emitSignal) + { + emit dataBlockEnqueued(); + } +} + +SDRDaemonDataBlock* SDRDaemonDataQueue::pop() +{ + QMutexLocker locker(&m_lock); + + if (m_queue.isEmpty()) + { + return 0; + } + else + { + return m_queue.takeFirst(); + } +} + +int SDRDaemonDataQueue::size() +{ + QMutexLocker locker(&m_lock); + + return m_queue.size(); +} + +void SDRDaemonDataQueue::clear() +{ + QMutexLocker locker(&m_lock); + m_queue.clear(); +} diff --git a/sdrdaemon/channel/sdrdaemondataqueue.h b/sdrdaemon/channel/sdrdaemondataqueue.h index d83346ad1..25817a21d 100644 --- a/sdrdaemon/channel/sdrdaemondataqueue.h +++ b/sdrdaemon/channel/sdrdaemondataqueue.h @@ -24,20 +24,20 @@ #define SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_ #include +#include +#include -class DataBlock; +class SDRDaemonDataBlock; -namespace SDRDaemon { - -class DataQueue : public QObject { +class SDRDaemonDataQueue : public QObject { Q_OBJECT public: - DataQueue(QObject* parent = NULL); - ~DataQueue(); + SDRDaemonDataQueue(QObject* parent = NULL); + ~SDRDaemonDataQueue(); - void push(DataBlock* message, bool emitSignal = true); //!< Push daa block onto queue - DataBlock* pop(); //!< Pop message from queue + void push(SDRDaemonDataBlock* dataBlock, bool emitSignal = true); //!< Push daa block onto queue + SDRDaemonDataBlock* pop(); //!< Pop message from queue int size(); //!< Returns queue size void clear(); //!< Empty queue @@ -47,9 +47,7 @@ signals: private: QMutex m_lock; - QQueue m_queue; + QQueue m_queue; }; -} // namespace SDRDaemon - #endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATAQUEUE_H_ */