diff --git a/sdrdaemon/CMakeLists.txt b/sdrdaemon/CMakeLists.txt index 6e6966114..cf8407a3e 100644 --- a/sdrdaemon/CMakeLists.txt +++ b/sdrdaemon/CMakeLists.txt @@ -48,12 +48,14 @@ include_directories( ${CMAKE_SOURCE_DIR}/sdrbase ${CMAKE_SOURCE_DIR}/logging ${CMAKE_SOURCE_DIR}/httpserver - ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client + ${CM256CC_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries(sdrdaemon ${QT_LIBRARIES} + ${CM256CC_LIBRARIES} sdrbase logging ) diff --git a/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp b/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp index f54628698..f8876a96d 100644 --- a/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp +++ b/sdrdaemon/channel/sdrdaemonchannelsinkthread.cpp @@ -25,10 +25,13 @@ #include "channel/sdrdaemondatablock.h" #include "channel/sdrdaemonchannelsinkthread.h" -SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent) : +#include "cm256.h" + +SDRDaemonChannelSinkThread::SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent) : QThread(parent), m_running(false), - m_dataQueue(dataQueue) + m_dataQueue(dataQueue), + m_cm256(cm256) { connect(m_dataQueue, SIGNAL(dataBlockEnqueued()), this, SLOT(handleData())); } @@ -72,6 +75,65 @@ void SDRDaemonChannelSinkThread::run() bool SDRDaemonChannelSinkThread::handleDataBlock(SDRDaemonDataBlock& dataBlock) { + CM256::cm256_encoder_params cm256Params; //!< Main interface with CM256 encoder + CM256::cm256_block descriptorBlocks[256]; //!< Pointers to data for CM256 encoder + SDRDaemonProtectedBlock fecBlocks[256]; //!< FEC data + + uint16_t frameIndex = dataBlock.m_controlBlock.m_frameIndex; + int nbBlocksFEC = dataBlock.m_controlBlock.m_nbBlocksFEC; + int txDelay = dataBlock.m_controlBlock.m_txDelay; + SDRDaemonSuperBlock *txBlockx = dataBlock.m_superBlocks; + + if ((nbBlocksFEC == 0) || !m_cm256) // Do not FEC encode + { + for (int i = 0; i < SDRDaemonNbOrginalBlocks; i++) + { + // TODO: send block via UDP here + usleep(txDelay); + } + } + else + { + cm256Params.BlockBytes = sizeof(SDRDaemonProtectedBlock); + cm256Params.OriginalCount = SDRDaemonNbOrginalBlocks; + cm256Params.RecoveryCount = nbBlocksFEC; + + // Fill pointers to data + for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; ++i) + { + if (i >= cm256Params.OriginalCount) { + memset((void *) &txBlockx[i].m_protectedBlock, 0, sizeof(SDRDaemonProtectedBlock)); + } + + txBlockx[i].m_header.m_frameIndex = frameIndex; + txBlockx[i].m_header.m_blockIndex = i; + descriptorBlocks[i].Block = (void *) &(txBlockx[i].m_protectedBlock); + descriptorBlocks[i].Index = txBlockx[i].m_header.m_blockIndex; + } + + // Encode FEC blocks + if (m_cm256->cm256_encode(cm256Params, descriptorBlocks, fecBlocks)) + { + qWarning("SDRDaemonChannelSinkThread::handleDataBlock: CM256 encode failed. No transmission."); + // TODO: send without FEC changing meta data to set indication of no FEC + return true; + } + + // Merge FEC with data to transmit + for (int i = 0; i < cm256Params.RecoveryCount; i++) + { + txBlockx[i + cm256Params.OriginalCount].m_protectedBlock = fecBlocks[i]; + } + + // Transmit all blocks + for (int i = 0; i < cm256Params.OriginalCount + cm256Params.RecoveryCount; i++) + { + // TODO: send block via UDP here + usleep(txDelay); + } + } + + dataBlock.m_controlBlock.m_processed = true; return true; } diff --git a/sdrdaemon/channel/sdrdaemonchannelsinkthread.h b/sdrdaemon/channel/sdrdaemonchannelsinkthread.h index 67c7be3dd..afa11524d 100644 --- a/sdrdaemon/channel/sdrdaemonchannelsinkthread.h +++ b/sdrdaemon/channel/sdrdaemonchannelsinkthread.h @@ -26,12 +26,13 @@ class SDRDaemonDataQueue; class SDRDaemonDataBlock; +class CM256; class SDRDaemonChannelSinkThread : public QThread { Q_OBJECT public: - SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, QObject* parent = 0); + SDRDaemonChannelSinkThread(SDRDaemonDataQueue *dataQueue, CM256 *cm256, QObject* parent = 0); ~SDRDaemonChannelSinkThread(); void startWork(); @@ -44,6 +45,8 @@ private: SDRDaemonDataQueue *m_dataQueue; + CM256 *m_cm256; //!< CM256 library object + void run(); bool handleDataBlock(SDRDaemonDataBlock& dataBlock); diff --git a/sdrdaemon/channel/sdrdaemondatablock.h b/sdrdaemon/channel/sdrdaemondatablock.h index 3355cc0db..2d76dbb54 100644 --- a/sdrdaemon/channel/sdrdaemondatablock.h +++ b/sdrdaemon/channel/sdrdaemondatablock.h @@ -96,7 +96,7 @@ class SDRDaemonDataBlock { public: SDRDaemonTxControlBlock m_controlBlock; - SDRDaemonSuperBlock m_superBlock; + SDRDaemonSuperBlock m_superBlocks[256]; }; #endif /* SDRDAEMON_CHANNEL_SDRDAEMONDATABLOCK_H_ */