diff --git a/sdrdaemon/CMakeLists.txt b/sdrdaemon/CMakeLists.txt
index b70416576..6e6966114 100644
--- a/sdrdaemon/CMakeLists.txt
+++ b/sdrdaemon/CMakeLists.txt
@@ -8,6 +8,7 @@ set(sdrdaemon_SOURCES
channel/sdrdaemonchannelsink.cpp
channel/sdrdaemonchannelsource.cpp
channel/sdrdaemondataqueue.cpp
+ channel/sdrdaemonchannelsinkthread.cpp
webapi/webapiadapterdaemon.cpp
webapi/webapirequestmapper.cpp
webapi/webapiserver.cpp
@@ -22,6 +23,7 @@ set(sdrdaemon_HEADERS
channel/sdrdaemonchannelsource.h
channel/sdrdaemondataqueue.h
channel/sdrdaemondatablock.h
+ channel/sdrdaemonchannelsinkthread.h
webapi/webapiadapterdaemon.h
webapi/webapirequestmapper.h
webapi/webapiserver.h
diff --git a/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp b/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp
new file mode 100644
index 000000000..f54628698
--- /dev/null
+++ b/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
+// //
+// SDRdaemon sink channel (Rx) UDP sender 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 "channel/sdrdaemondataqueue.h"
+#include "channel/sdrdaemondatablock.h"
+#include "channel/sdrdaemonchannelsinkthread.h"
+
+SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent) :
+ QThread(parent),
+ m_running(false),
+ m_dataQueue(dataQueue)
+{
+ connect(m_dataQueue, SIGNAL(dataBlockEnqueued()), this, SLOT(handleData()));
+}
+
+SDRDaemonChannelSinkThread::~SDRDaemonChannelSinkThread()
+{
+ stopWork();
+}
+
+void SDRDaemonChannelSinkThread::startWork()
+{
+ qDebug("SDRDaemonChannelSinkThread::startWork");
+ m_startWaitMutex.lock();
+ start();
+ while(!m_running)
+ m_startWaiter.wait(&m_startWaitMutex, 100);
+ m_startWaitMutex.unlock();
+}
+
+void SDRDaemonChannelSinkThread::stopWork()
+{
+ qDebug("SDRDaemonChannelSinkThread::stopWork");
+ m_running = false;
+ wait();
+}
+
+void SDRDaemonChannelSinkThread::run()
+{
+ qDebug("SDRDaemonChannelSinkThread::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("SDRDaemonChannelSinkThread::run: end");
+}
+
+bool SDRDaemonChannelSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock)
+{
+ return true;
+}
+
+void SDRDaemonChannelSinkThread::handleData()
+{
+ SDRDaemonDataBlock* dataBlock;
+
+ while (m_running && ((dataBlock = m_dataQueue->pop()) != 0))
+ {
+ if (handleDataBlock(*dataBlock))
+ {
+ delete dataBlock;
+ }
+ }
+}
\ No newline at end of file
diff --git a/sdrdaemon/channel/sdrdaemonchannelsinkthread.h b/sdrdaemon/channel/sdrdaemonchannelsinkthread.h
new file mode 100644
index 000000000..67c7be3dd
--- /dev/null
+++ b/sdrdaemon/channel/sdrdaemonchannelsinkthread.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2018 Edouard Griffiths, F4EXB. //
+// //
+// SDRdaemon sink channel (Rx) UDP sender 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
+#include
+
+class SDRDaemonDataQueue;
+class SDRDaemonDataBlock;
+
+class SDRDaemonChannelSinkThread : public QThread {
+ Q_OBJECT
+
+public:
+ SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent = 0);
+ ~SDRDaemonChannelSinkThread();
+
+ void startWork();
+ void stopWork();
+
+private:
+ QMutex m_startWaitMutex;
+ QWaitCondition m_startWaiter;
+ bool m_running;
+
+ SDRDaemonDataQueue *m_dataQueue;
+
+ void run();
+ bool handleDataBlock(SDRDaemonDataBlock& dataBlock);
+
+private slots:
+ void handleData();
+};
\ No newline at end of file
diff --git a/sdrdaemon/channel/sdrdaemondatablock.h b/sdrdaemon/channel/sdrdaemondatablock.h
index 9a33e022a..3355cc0db 100644
--- a/sdrdaemon/channel/sdrdaemondatablock.h
+++ b/sdrdaemon/channel/sdrdaemondatablock.h
@@ -36,17 +36,22 @@ 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 (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
+ uint8_t m_bigEndian; //!< 9 1 if encoded as big endian, 0 for little endian
+ uint8_t m_reserved1; //!< 10 reserved
+ uint8_t m_reserved2; //!< 11 reserved
+ uint8_t m_reserved3; //!< 12 reserved
+ uint8_t m_sampleBytes; //!< 13 number of bytes per sample (2 or 3)
+ uint8_t m_sampleBits; //!< 14 number of effective bits per sample (8 t0 24)
+ uint8_t m_nbOriginalBlocks; //!< 15 number of blocks with original (protected) data
+ uint8_t m_nbFECBlocks; //!< 16 number of blocks carrying FEC
+ uint32_t m_tv_sec; //!< 20 seconds of timestamp at start time of super-frame processing
+ uint32_t m_tv_usec; //!< 24 microseconds of timestamp at start time of super-frame processing
+ uint32_t m_crc32; //!< 28 CRC32 of the above
+ // 32 bytes
bool operator==(const SDRDaemonMetaDataFEC& rhs)
{
- return (memcmp((const void *) this, (const void *) &rhs, 12) == 0); // Only the 12 first bytes are relevant
+ return (memcmp((const void *) this, (const void *) &rhs, 16) == 0); // Only the 16 first bytes are relevant
}
void init()