satellite-wave-form-conf.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sami Rantanen <sami.rantanen@magister.fi>
19  */
20 
22 
24 #include "satellite-link-results.h"
25 #include "satellite-utils.h"
26 
27 #include <ns3/boolean.h>
28 #include <ns3/double.h>
29 #include <ns3/enum.h>
30 #include <ns3/log.h>
31 #include <ns3/satellite-env-variables.h>
32 #include <ns3/singleton.h>
33 #include <ns3/uinteger.h>
34 
35 #include <algorithm>
36 #include <cmath>
37 #include <fstream>
38 #include <iostream>
39 #include <limits>
40 #include <map>
41 #include <sstream>
42 #include <string>
43 #include <utility>
44 #include <vector>
45 
46 NS_LOG_COMPONENT_DEFINE("SatWaveformConf");
47 
48 namespace ns3
49 {
50 
52  : m_waveformId(0),
53  m_modulatedBits(0),
54  m_codingRate(0.0),
55  m_modCod(SatEnums::SAT_NONVALID_MODCOD),
56  m_payloadBytes(0),
57  m_lengthInSymbols(0),
58  m_preambleLengthInSymbols(0),
59  m_ebnoRequirement(0.0)
60 {
61  NS_ASSERT(false);
62 }
63 
65  uint32_t modulatedBits,
66  double codingRate,
67  SatEnums::SatModcod_t modcod,
68  uint32_t payloadBytes,
69  uint32_t lengthInSymbols,
70  uint32_t preambleLengthInSymbols)
71  : m_waveformId(wfId),
72  m_modulatedBits(modulatedBits),
73  m_codingRate(codingRate),
74  m_modCod(modcod),
75  m_payloadBytes(payloadBytes),
76  m_lengthInSymbols(lengthInSymbols),
77  m_preambleLengthInSymbols(preambleLengthInSymbols),
78  m_ebnoRequirement(0.0)
79 {
80 }
81 
82 uint32_t
84 {
85  NS_LOG_FUNCTION(this);
86  return m_waveformId;
87 }
88 
91 {
92  NS_LOG_FUNCTION(this);
93  return m_modCod;
94 }
95 
96 uint32_t
98 {
99  NS_LOG_FUNCTION(this);
100  return m_payloadBytes;
101 }
102 
103 uint32_t
105 {
106  NS_LOG_FUNCTION(this);
107  return m_lengthInSymbols;
108 }
109 
110 uint32_t
112 {
113  NS_LOG_FUNCTION(this);
115 }
116 
117 Time
118 SatWaveform::GetBurstDuration(double symbolRateInBaud) const
119 {
120  NS_LOG_FUNCTION(this << symbolRateInBaud);
121  return Seconds(m_lengthInSymbols / symbolRateInBaud);
122 }
123 
124 Time
125 SatWaveform::GetPreambleDuration(double symbolRateInBaud) const
126 {
127  NS_LOG_FUNCTION(this << symbolRateInBaud);
128  return Seconds(m_preambleLengthInSymbols / symbolRateInBaud);
129 }
130 
131 double
132 SatWaveform::GetSpectralEfficiency(double carrierBandwidthInHz, double symbolRateInBaud) const
133 {
134  NS_LOG_FUNCTION(this << carrierBandwidthInHz << symbolRateInBaud);
136  (m_lengthInSymbols / symbolRateInBaud) / carrierBandwidthInHz;
137 }
138 
139 double
140 SatWaveform::GetThroughputInBitsPerSecond(double symbolRateInBaud) const
141 {
142  NS_LOG_FUNCTION(this << symbolRateInBaud);
144  (m_lengthInSymbols / symbolRateInBaud);
145 }
146 
147 double
148 SatWaveform::GetCNoThreshold(double symbolRateInBaud) const
149 {
150  NS_LOG_FUNCTION(this << symbolRateInBaud);
151 
157  double cnoRequirement = m_ebnoRequirement * symbolRateInBaud * m_codingRate * m_modulatedBits;
158 
159  return cnoRequirement;
160 }
161 
162 void
163 SatWaveform::SetEbNoRequirement(double ebnoRequirement)
164 {
165  NS_LOG_FUNCTION(this << ebnoRequirement);
166  m_ebnoRequirement = ebnoRequirement;
167 }
168 
169 void
170 SatWaveform::Dump(double carrierBandwidthInHz, double symbolRateInBaud) const
171 {
172  NS_LOG_FUNCTION(this << carrierBandwidthInHz << symbolRateInBaud);
173 
174  std::cout << "ModulatedBits: " << m_modulatedBits << ", CodingRate: " << m_codingRate
175  << ", Payload: " << m_payloadBytes << ", BurstLength: " << m_lengthInSymbols
176  << ", EbNoRequirement: " << SatUtils::LinearToDb(m_ebnoRequirement)
177  << ", BurstDuration: " << GetBurstDuration(symbolRateInBaud)
178  << ", Throughput: " << GetThroughputInBitsPerSecond(symbolRateInBaud)
179  << ", SpectralEfficiency: "
180  << GetSpectralEfficiency(carrierBandwidthInHz, symbolRateInBaud)
181  << ", C/No threshold: " << SatUtils::LinearToDb(GetCNoThreshold(symbolRateInBaud))
182  << std::endl;
183 }
184 
185 NS_OBJECT_ENSURE_REGISTERED(SatWaveformConf);
186 
188  : m_waveforms(),
189  m_targetBLER(0.00001),
190  m_acmEnabled(false),
191  m_defaultWfId(3),
192  m_minWfId(0),
193  m_maxWfId(23),
194  m_burstLength(SatEnums::UNKNOWN_BURST)
195 {
196  // default constructor should not be used
197  NS_ASSERT(false);
198 }
199 
200 SatWaveformConf::SatWaveformConf(std::string directoryPathName)
201  : m_waveforms(),
202  m_targetBLER(0.00001),
203  m_acmEnabled(false),
204  m_defaultWfId(3),
205  m_minWfId(0),
206  m_maxWfId(23),
207  m_burstLength(SatEnums::UNKNOWN_BURST)
208 {
209  NS_LOG_FUNCTION(this);
210 
211  ObjectBase::ConstructSelf(AttributeConstructionList());
212 
213  if (!Singleton<SatEnvVariables>::Get()->IsValidDirectory(directoryPathName))
214  {
215  NS_FATAL_ERROR("No such directory: " << directoryPathName);
216  }
217 
218  std::string waveformsFilePathName = directoryPathName + "/waveforms.txt";
219  std::string defaultWaveform = directoryPathName + "/default_waveform.txt";
220 
221  ReadFromFile(waveformsFilePathName);
222  ReadFromFileDefaultWaveform(defaultWaveform);
223 
224  switch (m_burstLength)
225  {
228  break;
231  break;
235  break;
236  default:
237  NS_FATAL_ERROR("Incorrect choice of burst length.");
238  }
239 }
240 
241 TypeId
243 {
244  static TypeId tid = TypeId("ns3::SatWaveformConf")
245  .SetParent<Object>()
246  .AddAttribute("TargetBLER",
247  "Block error rate target",
248  DoubleValue(0.00001),
249  MakeDoubleAccessor(&SatWaveformConf::m_targetBLER),
250  MakeDoubleChecker<double>())
251  .AddAttribute("AcmEnabled",
252  "Enable ACM",
253  BooleanValue(false),
254  MakeBooleanAccessor(&SatWaveformConf::m_acmEnabled),
255  MakeBooleanChecker())
256  .AddAttribute("BurstLength",
257  "Default burst length",
259  MakeEnumAccessor<SatEnums::SatWaveFormBurstLength_t>(
261  MakeEnumChecker(SatEnums::SHORT_BURST,
262  "ShortBurst",
264  "LongBurst",
266  "ShortAndLongBurst"))
267  .AddConstructor<SatWaveformConf>();
268  return tid;
269 }
270 
271 TypeId
273 {
274  NS_LOG_FUNCTION(this);
275 
276  return GetTypeId();
277 }
278 
280 {
281  NS_LOG_FUNCTION(this);
282 }
283 
284 void
286 {
287  NS_LOG_FUNCTION(this << filePathName);
288 
289  // READ FROM THE SPECIFIED INPUT FILE
290  std::ifstream* ifs = new std::ifstream(filePathName.c_str(), std::ifstream::in);
291 
292  if (!ifs->is_open())
293  {
294  // script might be launched by test.py, try a different base path
295  delete ifs;
296  filePathName = "../../" + filePathName;
297  ifs = new std::ifstream(filePathName.c_str(), std::ifstream::in);
298 
299  if (!ifs->is_open())
300  {
301  NS_FATAL_ERROR("The file " << filePathName << " is not found.");
302  }
303  }
304 
305  // Read line by line
306  std::string line;
307  std::getline(*ifs, line);
308  std::istringstream line_ss(line);
309  if (!(line_ss >> m_defaultWfId))
310  {
311  NS_FATAL_ERROR("SatWaveformConf::ReadFromFileDefaultWaveform - Waveform conf vector has "
312  "unexpected amount of elements!");
313  }
314 }
315 
316 void
317 SatWaveformConf::ReadFromFile(std::string filePathName)
318 {
319  NS_LOG_FUNCTION(this << filePathName);
320 
321  std::vector<uint32_t> wfIds;
322 
323  // READ FROM THE SPECIFIED INPUT FILE
324  std::ifstream* ifs = new std::ifstream(filePathName.c_str(), std::ifstream::in);
325 
326  if (!ifs->is_open())
327  {
328  // script might be launched by test.py, try a different base path
329  delete ifs;
330  filePathName = "../../" + filePathName;
331  ifs = new std::ifstream(filePathName.c_str(), std::ifstream::in);
332 
333  if (!ifs->is_open())
334  {
335  NS_FATAL_ERROR("The file " << filePathName << " is not found.");
336  }
337  }
338 
339  // Row vector containing the waveform information for a certain waveform index
340  std::vector<double> rowVector;
341 
342  // Start conditions
343  int32_t wfIndex, modulatedBits, payloadBytes, durationInSymbols, preambleDurationInSymbols;
344  std::string sCodingRate;
345 
346  // Read line by line
347  std::string line;
348 
349  while (std::getline(*ifs, line))
350  {
351  std::istringstream line_ss(line);
352 
353  // Unpack values
354  if (!(line_ss >> wfIndex >> modulatedBits >> sCodingRate >> payloadBytes >>
355  durationInSymbols))
356  {
357  NS_FATAL_ERROR("SatWaveformConf::ReadFromFile - Waveform conf vector has unexpected "
358  "amount of elements!");
359  }
360  // Try to unpack preambule duration
361  if (!(line_ss >> preambleDurationInSymbols))
362  {
363  preambleDurationInSymbols = 0;
364  }
365 
366  // Store temporarily all wfIds
367  wfIds.push_back(wfIndex);
368 
369  // Convert the coding rate fraction into double
370  std::istringstream ss(sCodingRate);
371  std::string token;
372  std::vector<uint32_t> output;
373 
374  while (std::getline(ss, token, '/'))
375  {
376  uint32_t i;
377  std::stringstream s;
378  s.str(token);
379  s >> i;
380  output.push_back(i);
381  }
382 
383  if (output.size() != 2)
384  {
385  NS_FATAL_ERROR("SatWaveformConf::ReadFromFile - Temp fraction vector has unexpected "
386  "amount of elements!");
387  }
388 
389  double dCodingRate = double(output[0]) / output[1];
390 
391  // Convert modulated bits and coding rate to MODCOD enum
392  SatEnums::SatModcod_t modcod = ConvertToModCod(modulatedBits, output[0], output[1]);
393 
394  // Create new waveform and insert it to the waveform map
395  Ptr<SatWaveform> wf = Create<SatWaveform>(wfIndex,
396  modulatedBits,
397  dCodingRate,
398  modcod,
399  payloadBytes,
400  durationInSymbols,
401  preambleDurationInSymbols);
402  m_waveforms.insert(std::make_pair(wfIndex, wf));
403  }
404 
405  ifs->close();
406  delete ifs;
407 
408  // Note, currently we assume that the waveform ids are consecutive!
409  m_minWfId = *std::min_element(wfIds.begin(), wfIds.end());
410  m_maxWfId = *std::max_element(wfIds.begin(), wfIds.end());
411 }
412 
413 void
414 SatWaveformConf::InitializeEbNoRequirements(Ptr<SatLinkResultsRtn> linkResults)
415 {
416  NS_LOG_FUNCTION(this);
417 
418  for (std::map<uint32_t, Ptr<SatWaveform>>::iterator it = m_waveforms.begin();
419  it != m_waveforms.end();
420  ++it)
421  {
427  double ebnoRequirementDb = linkResults->GetEbNoDb(it->first, m_targetBLER);
428  it->second->SetEbNoRequirement(SatUtils::DbToLinear(ebnoRequirementDb));
429  }
430 }
431 
432 Ptr<SatWaveform>
433 SatWaveformConf::GetWaveform(uint32_t wfId) const
434 {
435  NS_LOG_FUNCTION(this << wfId);
436 
437  if (m_minWfId > wfId || wfId > m_maxWfId)
438  {
439  NS_FATAL_ERROR("SatWaveformConf::GetWaveform - unsupported waveform id: " << wfId);
440  }
441 
442  return m_waveforms.at(wfId);
443 }
444 
445 uint32_t
447 {
448  NS_LOG_FUNCTION(this << m_defaultWfId);
449 
451  {
452  NS_FATAL_ERROR(
453  "SatWaveformConf::GetDefaultWaveformId - unsupported waveform id: " << m_defaultWfId);
454  }
455 
456  return m_defaultWfId;
457 }
458 
459 bool
461  double symbolRateInBaud,
462  uint32_t& wfId,
463  double& cnoThreshold,
464  uint32_t burstLength) const
465 {
466  NS_LOG_FUNCTION(this << cno << symbolRateInBaud << wfId << cnoThreshold << burstLength);
467 
468  bool success = false;
469 
470  // If ACM is disabled, return the default waveform
471  if (!m_acmEnabled || std::isnan(cno))
472  {
473  wfId = m_defaultWfId;
474  success = true;
475  return success;
476  }
477 
478  // Return the waveform with best spectral efficiency
479  for (std::map<uint32_t, Ptr<SatWaveform>>::const_reverse_iterator rit = m_waveforms.rbegin();
480  rit != m_waveforms.rend();
481  ++rit)
482  {
483  if (rit->second->GetBurstLengthInSymbols() == burstLength)
484  {
485  double cnoThr = rit->second->GetCNoThreshold(symbolRateInBaud);
486  // The first waveform over the threshold
487  if (cnoThr <= cno)
488  {
489  wfId = rit->first;
490  cnoThreshold = cnoThr;
491  success = true;
492  break;
493  }
494  }
495  }
496 
497  NS_LOG_INFO("Get best waveform in RTN link (ACM)! CNo: "
498  << SatUtils::LinearToDb(cno) << ", Symbol rate: " << symbolRateInBaud
499  << ", burst length: " << burstLength << ", WF: " << wfId
500  << ", CNo threshold: " << SatUtils::LinearToDb(cnoThreshold));
501 
502  return success;
503 }
504 
505 bool
506 SatWaveformConf::GetMostRobustWaveformId(uint32_t& wfId, uint32_t burstLength) const
507 {
508  NS_LOG_FUNCTION(this << burstLength);
509 
510  bool found = false;
511 
512  uint32_t payloadInBytes = std::numeric_limits<uint32_t>::max();
513 
514  // find the waveform with the more robust waveform than previous one
515  for (std::map<uint32_t, Ptr<SatWaveform>>::const_reverse_iterator rit = m_waveforms.rbegin();
516  rit != m_waveforms.rend();
517  ++rit)
518  {
519  if (rit->second->GetBurstLengthInSymbols() == burstLength)
520  {
521  // The waveform more robust than previous one
522  if (rit->second->GetPayloadInBytes() < payloadInBytes)
523  {
524  payloadInBytes = rit->second->GetPayloadInBytes();
525  wfId = rit->first;
526  found = true;
527  }
528  }
529  }
530 
531  return found;
532 }
533 
534 void
535 SatWaveformConf::Dump(double carrierBandwidthInHz, double symbolRateInBaud) const
536 {
537  NS_LOG_FUNCTION(this << carrierBandwidthInHz << symbolRateInBaud);
538 
539  for (std::map<uint32_t, Ptr<SatWaveform>>::const_iterator it = m_waveforms.begin();
540  it != m_waveforms.end();
541  ++it)
542  {
543  std::cout << "WaveformId: " << it->first << " ";
544  it->second->Dump(carrierBandwidthInHz, symbolRateInBaud);
545  }
546 }
547 
549 SatWaveformConf::GetModCod(uint32_t wfId) const
550 {
551  NS_LOG_FUNCTION(this << wfId);
552 
553  if (m_minWfId > wfId || wfId > m_maxWfId)
554  {
555  NS_FATAL_ERROR("SatWaveformConf::GetModCod - unsupported waveform id: " << wfId);
556  }
557 
558  std::map<uint32_t, Ptr<SatWaveform>>::const_iterator it = m_waveforms.find(wfId);
559 
560  if (it != m_waveforms.end())
561  {
562  return m_waveforms.at(wfId)->GetModCod();
563  }
564  else
565  {
566  NS_FATAL_ERROR("Waveform id: " << wfId << " not found in the waveform container!");
567  }
568 
570 }
571 
573 SatWaveformConf::ConvertToModCod(uint32_t modulatedBits,
574  uint32_t codingRateNumerator,
575  uint32_t codingRateDenominator) const
576 {
577  NS_LOG_FUNCTION(this << modulatedBits << codingRateNumerator << codingRateDenominator);
578 
579  switch (modulatedBits)
580  {
581  // BPSK
582  case 1: {
583  if (codingRateNumerator == 1 && codingRateDenominator == 3)
584  {
586  }
587  else
588  {
589  NS_FATAL_ERROR("Unsupported coding rate numerator: "
590  << codingRateNumerator << ", denominator: " << codingRateDenominator);
591  }
592  break;
593  }
594  // QPSK
595  case 2: {
596  if (codingRateNumerator == 1 && codingRateDenominator == 3)
597  {
599  }
600  else if (codingRateNumerator == 1 && codingRateDenominator == 2)
601  {
603  }
604  else if (codingRateNumerator == 2 && codingRateDenominator == 3)
605  {
607  }
608  else if (codingRateNumerator == 3 && codingRateDenominator == 4)
609  {
611  }
612  else if (codingRateNumerator == 5 && codingRateDenominator == 6)
613  {
615  }
616  else
617  {
618  NS_FATAL_ERROR("Unsupported coding rate numerator: "
619  << codingRateNumerator << ", denominator: " << codingRateDenominator);
620  }
621  break;
622  }
623  // 8PSK
624  case 3: {
625  if (codingRateNumerator == 2 && codingRateDenominator == 3)
626  {
628  }
629  else if (codingRateNumerator == 3 && codingRateDenominator == 4)
630  {
632  }
633  else if (codingRateNumerator == 5 && codingRateDenominator == 6)
634  {
636  }
637  else
638  {
639  NS_FATAL_ERROR("Unsupported coding rate numerator: "
640  << codingRateNumerator << ", denominator: " << codingRateDenominator);
641  }
642  break;
643  }
644  // 16 QAM
645  case 4: {
646  if (codingRateNumerator == 3 && codingRateDenominator == 4)
647  {
649  }
650  else if (codingRateNumerator == 5 && codingRateDenominator == 6)
651  {
653  }
654  else
655  {
656  NS_FATAL_ERROR("Unsupported coding rate numerator: "
657  << codingRateNumerator << ", denominator: " << codingRateDenominator);
658  }
659 
660  break;
661  }
662  default: {
663  NS_FATAL_ERROR("Unsupported modulated bits:" << modulatedBits);
664  break;
665  }
666  }
668 }
669 
670 } // namespace ns3
SatEnums class is for simplifying the use of enumerators in the satellite module.
SatModcod_t
Modulation scheme and coding rate for DVB-S2.
static T DbToLinear(T db)
Converts decibels to linear.
static T LinearToDb(T linear)
Converts linear to decibels.
This class implements the available waveform configurations of DVB-RCS2 return link.
virtual ~SatWaveformConf()
Destructor for SatWaveformConf.
bool GetMostRobustWaveformId(uint32_t &wfId, uint32_t burstLength=SHORT_BURST_LENGTH) const
Get the most robust waveform id based payload of the waveform in bytes.
uint32_t m_defaultWfId
Default waveform id.
Ptr< SatWaveform > GetWaveform(uint32_t wfId) const
Get the details of a certain waveform.
void Dump(double carrierBandwidthInHz, double symbolRateInBaud) const
Dump the contents of the waveform.
void ReadFromFile(std::string filePathName)
Read the waveform table from a file.
SatEnums::SatWaveFormBurstLength_t m_burstLength
Burst length used.
bool GetBestWaveformId(double cno, double symbolRateInBaud, uint32_t &wfId, double &cnoThreshold, uint32_t burstLength=SHORT_BURST_LENGTH) const
Get the best waveform id based on UT's C/No and C/No thresholds.
std::map< uint32_t, Ptr< SatWaveform > > m_waveforms
Container of the waveforms.
static const uint32_t LONG_BURST_LENGTH
Static variable defining long burst length.
virtual TypeId GetInstanceTypeId(void) const
Get the type ID of instance.
BurstLengthContainer_t m_supportedBurstLengthsInSymbols
Container to store supported burst lengths.
SatEnums::SatModcod_t GetModCod(uint32_t wfId) const
Get MODCOD enum corresponding to a waveform id.
void InitializeEbNoRequirements(Ptr< SatLinkResultsRtn > linkResults)
Initialize the Eb/No requirements of the waveforms based on the used return link results.
double m_targetBLER
Block error rate target for the waveforms.
bool m_acmEnabled
Flag to indicate whether ACM is enabled or disabled.
void ReadFromFileDefaultWaveform(std::string filePathName)
Read the default waveform ID from a file.
static const uint32_t SHORT_BURST_LENGTH
Static variable defining short burst length.
uint32_t GetDefaultWaveformId() const
Get default waveform id.
static TypeId GetTypeId(void)
Derived from Object.
SatWaveformConf()
Default constructor, which is not to be used.
SatEnums::SatModcod_t ConvertToModCod(uint32_t modulatedBits, uint32_t codingRateNumerator, uint32_t codingRateDenominator) const
Convert modulated bits and coding rate to a MODCOD enum.
uint32_t m_minWfId
Minimum and maximum waveform ids.
void SetEbNoRequirement(double ebnoRequirement)
Set the Eb/No requirement of the waveform in linear domain based on the used link results.
SatWaveform()
Default constructor for SatWaveform.
uint32_t m_payloadBytes
Payload in bytes.
uint32_t m_lengthInSymbols
Length of the burst in symbols.
double m_codingRate
Coding rate.
double m_ebnoRequirement
Eb/No threshold calculated with a certain BLER target from the link results.
uint32_t GetWaveformId() const
Get waveform id.
double GetCNoThreshold(double symbolRateInBaud) const
Get the C/No threshold of the waveform in linear domain.
SatEnums::SatModcod_t m_modCod
MODCOD enum.
uint32_t GetBurstLengthInSymbols() const
Get burst length of the waveform in symbols.
SatEnums::SatModcod_t GetModCod() const
Get MODCOD enum.
Time GetBurstDuration(double symbolRateInBaud) const
Get/calculate the burst duration of a waveform based on symbol rate.
Time GetPreambleDuration(double symbolRateInBaud) const
Get/calculate the preamble duration of a waveform based on symbol rate.
double GetSpectralEfficiency(double carrierBandwidthInHz, double symbolRateInBaud) const
Get/calculate the spectral efficiency of a waveform.
uint32_t GetPreambleLengthInSymbols() const
Get preamble length of the waveform in symbols.
uint32_t GetPayloadInBytes() const
Get payload of a waveform in bytes.
double GetThroughputInBitsPerSecond(double symbolRateInBaud) const
Get/calculate the throughput of a waveform based on symbol rate.
void Dump(double carrierBandwidthInHz, double symbolRateInBaud) const
Dump the contents of the waveform.
uint32_t m_waveformId
Id of this waveform.
uint32_t m_modulatedBits
Modulated bits QPSK = 2 8PSK = 3 16QAM = 4.
uint32_t m_preambleLengthInSymbols
Length of the preamble in symbols.
constexpr uint32_t BITS_PER_BYTE
Number of bits in a byte.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.