| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2023-11-19 06:43:20 +01:00
										 |  |  | // Copyright (C) 2018-2019, 2021 Edouard Griffiths, F4EXB <f4exb06@gmail.com>    //
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | //                                                                               //
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | // Remote sink channel (Rx) data block                                           //
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | //                                                                               //
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | // SDRangel can serve as a remote SDR front end that handles the interface       //
 | 
					
						
							|  |  |  | // with a physical device and sends or receives the I/Q samples stream via UDP   //
 | 
					
						
							|  |  |  | // to or from another SDRangel instance or any program implementing the same     //
 | 
					
						
							|  |  |  | // protocol. The remote SDRangel is controlled via its Web REST API.             //
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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                  //
 | 
					
						
							| 
									
										
										
										
											2019-04-11 14:32:15 +02:00
										 |  |  | // (at your option) any later version.                                           //
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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 <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-03 01:52:11 +01:00
										 |  |  | #ifndef CHANNEL_REMOTEDATABLOCK_H_
 | 
					
						
							|  |  |  | #define CHANNEL_REMOTEDATABLOCK_H_
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <stdint.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2018-08-28 06:33:15 +02:00
										 |  |  | #include <QString>
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | #include "dsp/dsptypes.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define UDPSINKFEC_UDPSIZE 512
 | 
					
						
							|  |  |  | #define UDPSINKFEC_NBORIGINALBLOCKS 128
 | 
					
						
							| 
									
										
										
										
											2018-08-20 14:05:27 +02:00
										 |  |  | //#define UDPSINKFEC_NBTXBLOCKS 8
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #pragma pack(push, 1)
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | struct RemoteMetaDataFEC | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-12-23 16:27:19 +01:00
										 |  |  |     uint64_t m_centerFrequency;       //!<  8 center frequency in kHz
 | 
					
						
							|  |  |  |     uint32_t m_sampleRate;            //!< 12 sample rate in Hz
 | 
					
						
							|  |  |  |     uint8_t  m_sampleBytes;           //!< 13 4 LSB: number of bytes per sample (2 or 4)
 | 
					
						
							|  |  |  |     uint8_t  m_sampleBits;            //!< 14 number of effective bits per sample (deprecated)
 | 
					
						
							|  |  |  |     uint8_t  m_nbOriginalBlocks;      //!< 15 number of blocks with original (protected) data
 | 
					
						
							|  |  |  |     uint8_t  m_nbFECBlocks;           //!< 16 number of blocks carrying FEC
 | 
					
						
							|  |  |  |     uint8_t  m_deviceIndex;           //!< 29 index of device set in instance
 | 
					
						
							|  |  |  |     uint8_t  m_channelIndex;          //!< 30 index of channel in device set
 | 
					
						
							| 
									
										
										
										
											2018-11-18 09:39:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-23 16:27:19 +01:00
										 |  |  |     uint32_t m_tv_sec;                //!< 34 seconds of timestamp at start time of super-frame processing
 | 
					
						
							|  |  |  |     uint32_t m_tv_usec;               //!< 38 microseconds of timestamp at start time of super-frame processing
 | 
					
						
							|  |  |  |     uint32_t m_crc32;                 //!< 42 CRC32 of the above
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  |     bool operator==(const RemoteMetaDataFEC& rhs) | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-11-18 09:39:22 +01:00
										 |  |  |         // Only the first 6 fields are relevant
 | 
					
						
							|  |  |  |         return (m_centerFrequency == rhs.m_centerFrequency) | 
					
						
							|  |  |  |             && (m_sampleRate == rhs.m_sampleRate) | 
					
						
							|  |  |  |             && (m_sampleBytes == rhs.m_sampleBytes) | 
					
						
							|  |  |  |             && (m_sampleBits == rhs.m_sampleBits) | 
					
						
							|  |  |  |             && (m_nbOriginalBlocks == rhs.m_nbOriginalBlocks) | 
					
						
							|  |  |  |             && (m_nbFECBlocks == rhs.m_nbFECBlocks); | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void init() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |         m_centerFrequency = 0; | 
					
						
							|  |  |  |         m_sampleRate = 0; | 
					
						
							|  |  |  |         m_sampleBytes = 0; | 
					
						
							|  |  |  |         m_sampleBits = 0; | 
					
						
							|  |  |  |         m_nbOriginalBlocks = 0; | 
					
						
							| 
									
										
										
										
											2018-08-27 01:09:12 +02:00
										 |  |  |         m_nbFECBlocks = 0; | 
					
						
							| 
									
										
										
										
											2021-12-23 16:27:19 +01:00
										 |  |  |         m_deviceIndex = 0; | 
					
						
							|  |  |  |         m_channelIndex = 0; | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |         m_tv_sec = 0; | 
					
						
							|  |  |  |         m_tv_usec = 0; | 
					
						
							|  |  |  |         m_crc32 = 0; | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | struct RemoteHeader | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     uint16_t m_frameIndex; | 
					
						
							|  |  |  |     uint8_t  m_blockIndex; | 
					
						
							| 
									
										
										
										
											2018-09-13 00:31:49 +02:00
										 |  |  |     uint8_t  m_sampleBytes; //!<  number of bytes per sample (2 or 4) for this block
 | 
					
						
							|  |  |  |     uint8_t  m_sampleBits;  //!<  number of bits per sample
 | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  |     uint8_t  m_filler; | 
					
						
							| 
									
										
										
										
											2018-09-13 00:31:49 +02:00
										 |  |  |     uint16_t m_filler2; | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-22 23:16:08 +02:00
										 |  |  |     void init() | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         m_frameIndex = 0; | 
					
						
							|  |  |  |         m_blockIndex = 0; | 
					
						
							| 
									
										
										
										
											2018-09-13 00:31:49 +02:00
										 |  |  |         m_sampleBytes = 2; | 
					
						
							|  |  |  |         m_sampleBits = 16; | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |         m_filler = 0; | 
					
						
							| 
									
										
										
										
											2018-09-10 02:52:36 +02:00
										 |  |  |         m_filler2 = 0; | 
					
						
							| 
									
										
										
										
											2018-08-22 23:16:08 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | static const int RemoteUdpSize = UDPSINKFEC_UDPSIZE; | 
					
						
							|  |  |  | static const int RemoteNbOrginalBlocks = UDPSINKFEC_NBORIGINALBLOCKS; | 
					
						
							|  |  |  | static const int RemoteNbBytesPerBlock = UDPSINKFEC_UDPSIZE - sizeof(RemoteHeader); | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | struct RemoteProtectedBlock | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  |     uint8_t buf[RemoteNbBytesPerBlock]; | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void init() { | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  |         std::fill(buf, buf+RemoteNbBytesPerBlock, 0); | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | struct RemoteSuperBlock | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  |     RemoteHeader         m_header; | 
					
						
							|  |  |  |     RemoteProtectedBlock m_protectedBlock; | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void init() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_header.init(); | 
					
						
							|  |  |  |         m_protectedBlock.init(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | #pragma pack(pop)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | struct RemoteTxControlBlock | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-21 14:00:56 +02:00
										 |  |  |     bool m_complete; | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  |     bool m_processed; | 
					
						
							|  |  |  |     uint16_t m_frameIndex; | 
					
						
							|  |  |  |     int m_nbBlocksFEC; | 
					
						
							| 
									
										
										
										
											2018-08-22 23:16:08 +02:00
										 |  |  |     QString m_dataAddress; | 
					
						
							|  |  |  |     uint16_t m_dataPort; | 
					
						
							| 
									
										
										
										
											2018-08-21 14:00:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-07 08:17:55 +01:00
										 |  |  |     RemoteTxControlBlock() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-08-21 14:00:56 +02:00
										 |  |  |         m_complete = false; | 
					
						
							|  |  |  |         m_processed = false; | 
					
						
							|  |  |  |         m_frameIndex = 0; | 
					
						
							|  |  |  |         m_nbBlocksFEC = 0; | 
					
						
							| 
									
										
										
										
											2018-08-22 23:16:08 +02:00
										 |  |  |         m_dataAddress = "127.0.0.1"; | 
					
						
							|  |  |  |         m_dataPort = 9090; | 
					
						
							| 
									
										
										
										
											2018-08-21 14:00:56 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  | struct RemoteRxControlBlock | 
					
						
							| 
									
										
										
										
											2018-08-27 01:09:12 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     int  m_blockCount;    //!< number of blocks received for this frame
 | 
					
						
							|  |  |  |     int  m_originalCount; //!< number of original blocks received
 | 
					
						
							|  |  |  |     int  m_recoveryCount; //!< number of recovery blocks received
 | 
					
						
							|  |  |  |     bool m_metaRetrieved; //!< true if meta data (block zero) was retrieved
 | 
					
						
							|  |  |  |     int  m_frameIndex;    //!< this frame index or -1 if unset
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  |     RemoteRxControlBlock() { | 
					
						
							| 
									
										
										
										
											2018-08-27 01:09:12 +02:00
										 |  |  |         m_blockCount = 0; | 
					
						
							|  |  |  |         m_originalCount = 0; | 
					
						
							|  |  |  |         m_recoveryCount = 0; | 
					
						
							|  |  |  |         m_metaRetrieved = false; | 
					
						
							|  |  |  |         m_frameIndex = -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-12 10:44:58 +01:00
										 |  |  | class RemoteDataFrame | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-08-20 14:05:27 +02:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2021-12-12 10:44:58 +01:00
										 |  |  |     RemoteDataFrame() { | 
					
						
							|  |  |  |         m_superBlocks = new RemoteSuperBlock[256]; //!< 128 original bloks + 128 possible recovery blocks
 | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-12 10:44:58 +01:00
										 |  |  |     ~RemoteDataFrame() { | 
					
						
							| 
									
										
										
										
											2018-08-21 17:23:48 +02:00
										 |  |  |         delete[] m_superBlocks; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-02 22:58:42 +01:00
										 |  |  |     RemoteTxControlBlock m_txControlBlock; | 
					
						
							|  |  |  |     RemoteRxControlBlock m_rxControlBlock; | 
					
						
							|  |  |  |     RemoteSuperBlock     *m_superBlocks; | 
					
						
							| 
									
										
										
										
											2018-08-20 08:41:54 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-03 01:52:11 +01:00
										 |  |  | #endif /* CHANNEL_REMOTEDATABLOCK_H_ */
 |