25 #include "../stats/satellite-frame-symbol-load-probe.h"
26 #include "../stats/satellite-frame-user-load-probe.h"
37 #include <ns3/address.h>
38 #include <ns3/boolean.h>
39 #include <ns3/double.h>
41 #include <ns3/ipv4-address.h>
43 #include <ns3/mac48-address.h>
44 #include <ns3/singleton.h>
50 NS_LOG_COMPONENT_DEFINE(
"SatBeamScheduler");
57 Ptr<SatCnoEstimator> cnoEstimator,
58 Time controlSlotOffset,
59 bool controlSlotsEnabled)
60 : m_damaEntry(damaEntry),
61 m_cnoEstimator(cnoEstimator),
62 m_controlSlotsEnabled(controlSlotsEnabled)
64 NS_LOG_FUNCTION(
this);
72 NS_LOG_FUNCTION(
this);
80 NS_LOG_FUNCTION(
this);
83 std::map<uint8_t, uint16_t> rbdcReqs;
85 for (CrMsgContainer_t::const_iterator crIt = m_crContainer.begin(); crIt != m_crContainer.end();
90 for (SatCrMessage::RequestContainer_t::const_iterator descriptorIt = crContent.begin();
91 descriptorIt != crContent.end();
94 switch (descriptorIt->first.second)
97 rbdcReqs[descriptorIt->first.first] += descriptorIt->second;
102 m_damaEntry->ResetVolumeBacklogPersistence();
103 m_damaEntry->UpdateVbdcInBytes(descriptorIt->first.first, descriptorIt->second);
108 m_damaEntry->ResetVolumeBacklogPersistence();
109 m_damaEntry->SetVbdcInBytes(descriptorIt->first.first, descriptorIt->second);
120 for (std::map<uint8_t, uint16_t>::iterator it = rbdcReqs.begin(); it != rbdcReqs.end(); it++)
122 m_damaEntry->ResetDynamicRatePersistence();
123 m_damaEntry->UpdateRbdcInKbps(it->first, it->second);
127 m_crContainer.clear();
133 NS_LOG_FUNCTION(
this);
135 return m_cnoEstimator->GetCnoEstimation();
141 NS_LOG_FUNCTION(
this << sample);
143 m_cnoEstimator->AddSample(sample);
149 NS_LOG_FUNCTION(
this << crMsg);
151 m_crContainer.push_back(crMsg);
157 NS_LOG_FUNCTION(
this);
159 m_crContainer.clear();
165 NS_LOG_FUNCTION(
this);
167 bool isGenerationTime =
false;
171 isGenerationTime =
true;
174 return isGenerationTime;
180 NS_LOG_FUNCTION(
this);
182 m_controlSlotGenerationTime = Simulator::Now() + offset;
193 TypeId(
"ns3::SatBeamScheduler")
195 .AddConstructor<SatBeamScheduler>()
196 .AddAttribute(
"CnoEstimationMode",
197 "Mode of the C/N0 estimator",
203 "MinimumValueInWindow",
205 "AverageValueInWindow"))
206 .AddAttribute(
"CnoEstimationWindow",
207 "Time window for C/N0 estimation.",
208 TimeValue(MilliSeconds(1000)),
211 .AddAttribute(
"MaxTwoWayPropagationDelay",
212 "Maximum two way propagation delay between GW and UT.",
213 TimeValue(MilliSeconds(560)),
216 .AddAttribute(
"MaxTBTPTxAndProcessingDelay",
217 "Maximum TBTP transmission and processing delay at the GW.",
218 TimeValue(MilliSeconds(100)),
222 "ControlSlotsEnabled",
223 "Control slots generation enabled according to ControlSlotInterval attribute.",
226 MakeBooleanChecker())
227 .AddAttribute(
"ControlSlotInterval",
228 "Time interval to generate time slots for the UT(s).",
229 TimeValue(MilliSeconds(1000)),
232 .AddAttribute(
"HandoverStrategy",
233 "Strategy used when performing handover to transfer capacity requests "
234 "and C/No informations",
241 .AddAttribute(
"SuperFrameAllocatorType",
242 "Type of SuperFrameAllocator",
246 .AddTraceSource(
"BacklogRequestsTrace",
247 "Trace for backlog requests done to beam scheduler.",
249 "ns3::SatBeamScheduler::BacklogRequestsTraceCallback")
250 .AddTraceSource(
"WaveformTrace",
251 "Trace scheduled wave forms (called once per UT per round).",
253 "ns3::SatBeamScheduler::WaveformTrace")
254 .AddTraceSource(
"FrameUtLoadTrace",
255 "Trace UT load per the frame.",
257 "ns3::SatFrameUserLoadProbe::FrameUserLoadCallback")
258 .AddTraceSource(
"FrameLoadTrace",
259 "Trace load per the frame allocated symbols / total symbols.",
261 "ns3::SatFrameSymbolLoadProbe::FrameSymbolLoadCallback")
262 .AddTraceSource(
"UsableCapacityTrace",
263 "Trace usable capacity per beam in kbps.",
265 "ns3::SatBeamScheduler::UsableCapacityTraceCallback")
266 .AddTraceSource(
"UnmetCapacityTrace",
267 "Trace unmet capacity per beam in kbps.",
269 "ns3::SatBeamScheduler::UnmetCapacityTrace")
270 .AddTraceSource(
"ExceedingCapacityTrace",
271 "Trace exceeding capacity per beam in kbps.",
273 "ns3::SatBeamScheduler::ExceedingCapacityTrace");
289 NS_LOG_FUNCTION(
this);
294 NS_LOG_FUNCTION(
this);
300 NS_LOG_FUNCTION(
this);
308 NS_LOG_FUNCTION(
this << msg);
317 NS_LOG_FUNCTION(
this << msg << utId);
331 NS_LOG_FUNCTION(
this << msg << satelliteMac);
346 Ptr<SatSuperframeSeq> seq,
347 uint32_t maxFrameSizeInBytes,
350 NS_LOG_FUNCTION(
this << beamId << &cb);
367 uint32_t sfCountOffset =
368 (uint32_t)(totalDelay.GetInteger() / seq->GetDuration(0).GetInteger() + 1);
384 uint32_t maxIndex = 0;
387 ->GetRaChannelCount() > 0)
390 ->GetRaChannelCount() -
401 Ptr<SatDefaultSuperframeAllocator> superframeAllocator =
402 CreateObject<SatDefaultSuperframeAllocator>(
408 NS_FATAL_ERROR(
"Invalid SuperframeAllocatorType");
412 NS_LOG_INFO(
"Initialized SatBeamScheduler");
415 Time txTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
420 delay = txTime - Now();
424 NS_FATAL_ERROR(
"Trying to schedule a super frame in the past!");
433 NS_LOG_FUNCTION(
this << utId);
435 Ptr<SatDamaEntry> damaEntry = Create<SatDamaEntry>(llsConf);
442 Ptr<UniformRandomVariable> m_randomInterval = CreateObject<UniformRandomVariable>();
443 uint32_t randomOffset = m_randomInterval->GetInteger(
447 firstCtrlSlotInterval = Time(randomOffset);
451 Ptr<SatUtInfo> utInfo =
470 NS_LOG_FUNCTION(
this << utId << utInfo);
472 Ptr<SatDamaEntry> damaEntry = utInfo->GetDamaEntry();
479 std::pair<UtInfoMap_t::iterator, bool> result =
m_utInfos.insert(std::make_pair(utId, utInfo));
484 damaEntry->GetRcCount(),
487 allocReq.
m_cno = NAN;
494 NS_FATAL_ERROR(
"UT (Address: " << utId <<
") already added to Beam scheduler.");
501 Address utId = iterator->first;
502 Ptr<SatUtInfo> utInfo = iterator->second;
508 if (it->first == utId)
515 Ptr<SatDamaEntry> damaEntry = utInfo->GetDamaEntry();
524 NS_LOG_FUNCTION(
this << utId);
526 UtInfoMap_t::iterator result =
m_utInfos.find(utId);
533 NS_LOG_FUNCTION(
this << utId << cno);
544 NS_LOG_FUNCTION(
this << satelliteMac << cno);
555 NS_LOG_FUNCTION(
this << utId << crMsg);
566 NS_LOG_FUNCTION(
this);
568 Ptr<SatCnoEstimator> estimator = NULL;
579 NS_FATAL_ERROR(
"Not supported C/N0 estimation mode!!!");
593 Ptr<SatCnoReportMessage> cnoReportMessage = CreateObject<SatCnoReportMessage>();
594 cnoReportMessage->SetCnoEstimate(cno);
605 NS_LOG_FUNCTION(
this);
607 uint32_t requestedKbpsSum(0);
608 uint32_t offeredKbpsSum(0);
618 Ptr<SatTbtpMessage> firstTbtp =
622 std::vector<Ptr<SatTbtpMessage>> tbtps;
623 tbtps.push_back(firstTbtp);
643 for (std::vector<Ptr<SatTbtpMessage>>::const_iterator it = tbtps.begin(); it != tbtps.end();
662 NS_FATAL_ERROR(
"Too big for " << error <<
" TBTP messages");
665 NS_LOG_INFO(
"TBTP sent");
668 uint32_t usableCapacity = std::min(offeredKbpsSum, requestedKbpsSum);
669 uint32_t unmetCapacity = requestedKbpsSum - usableCapacity;
670 uint32_t exceedingCapacity =
671 (uint32_t)(std::max(((
double)(offeredKbpsSum)-requestedKbpsSum), 0.0) + 0.5);
688 NS_LOG_FUNCTION(
this);
690 if (tbtpContainer.empty())
692 NS_FATAL_ERROR(
"TBTP container must contain at least one message.");
695 Ptr<SatTbtpMessage> tbtpToFill = tbtpContainer.back();
697 Ptr<SatSuperframeConf> superFrameConf =
700 int32_t prevFrameId = -1;
702 for (uint32_t i = 0; i < superFrameConf->GetRaChannelCount(); i++)
704 uint8_t frameId = superFrameConf->GetRaChannelFrameId(i);
705 Ptr<SatFrameConf> frameConf = superFrameConf->GetFrameConf(frameId);
706 uint16_t timeSlotCount = frameConf->GetTimeSlotCount() / frameConf->GetCarrierCount();
710 uint32_t frameInfoSize = 0;
712 if (prevFrameId != (int32_t)frameId)
715 frameInfoSize = tbtpToFill->GetFrameInfoSize();
718 while (timeSlotCount > 0)
721 uint32_t timeSlotCountMaxFrame =
723 tbtpToFill->GetTimeSlotInfoSizeInBytes();
724 if (timeSlotCountMaxFrame > timeSlotCount)
726 timeSlotCountMaxFrame = timeSlotCount;
729 tbtpToFill->SetRaChannel(i,
730 superFrameConf->GetRaChannelFrameId(i),
731 timeSlotCountMaxFrame);
732 timeSlotCount -= timeSlotCountMaxFrame;
735 if (timeSlotCount > 0)
737 Ptr<SatTbtpMessage> newTbtp =
738 CreateObject<SatTbtpMessage>(tbtpToFill->GetSuperframeSeqId());
739 newTbtp->SetSuperframeCounter(tbtpToFill->GetSuperframeCounter());
740 tbtpContainer.push_back(newTbtp);
741 tbtpToFill = newTbtp;
750 NS_LOG_FUNCTION(
this);
752 uint32_t requestedCraRbdcKbps(0);
758 Ptr<SatDamaEntry> damaEntry =
m_utInfos.at(it->first)->GetDamaEntry();
761 m_utInfos.at(it->first)->UpdateDamaEntryFromCrs();
765 it->second.m_cno =
m_utInfos.at(it->first)->GetCnoEstimation();
768 it->second.m_generateCtrlSlot =
m_utInfos.at(it->first)->IsControlSlotGenerationTime();
770 for (uint8_t i = 0; i < damaEntry->GetRcCount(); i++)
772 double superFrameDurationInSeconds =
777 it->second.m_reqPerRc[i].m_craBytes =
779 superFrameDurationInSeconds) /
781 it->second.m_reqPerRc[i].m_rbdcBytes =
783 superFrameDurationInSeconds) /
785 it->second.m_reqPerRc[i].m_vbdcBytes = damaEntry->GetVbdcInBytes(i);
788 requestedCraRbdcKbps += damaEntry->GetCraInKbps(i);
789 requestedCraRbdcKbps += damaEntry->GetRbdcInKbps(i);
791 uint16_t minRbdcCraDeltaRateInKbps =
792 std::max(0, damaEntry->GetMinRbdcInKbps(i) - damaEntry->GetCraInKbps(i));
793 it->second.m_reqPerRc[i].m_minRbdcBytes =
795 superFrameDurationInSeconds) /
800 if (it->second.m_reqPerRc[i].m_rbdcBytes == 0)
802 it->second.m_reqPerRc[i].m_minRbdcBytes = 0;
806 (it->second.m_reqPerRc[i].m_minRbdcBytes <= it->second.m_reqPerRc[i].m_rbdcBytes));
813 std::stringstream head;
814 head << Now().GetSeconds() <<
", ";
816 head << Singleton<SatIdMapper>::Get()->GetUtIdWithMac(it->first) <<
", ";
818 std::stringstream rbdcTail;
820 rbdcTail << damaEntry->GetRbdcInKbps(i);
824 std::stringstream vbdcTail;
826 vbdcTail << damaEntry->GetVbdcInBytes(i);
833 return requestedCraRbdcKbps;
839 NS_LOG_FUNCTION(
this);
852 allocReqs.push_back(&(it->second));
864 NS_LOG_FUNCTION(
this);
866 uint32_t offeredCraRbdcKbps(0);
871 Ptr<SatDamaEntry> damaEntry =
m_utInfos.at(it->first)->GetDamaEntry();
872 SatFrameAllocator::UtAllocInfoContainer_t::const_iterator allocInfo =
873 utAllocContainer.find(it->first);
875 if (allocInfo != utAllocContainer.end())
878 if (allocInfo->second.second)
883 double superFrameDurationInSeconds =
888 for (uint32_t i = 0; i < allocInfo->second.first.size(); i++)
890 uint32_t rateBasedBytes =
892 superFrameDurationInSeconds) /
895 superFrameDurationInSeconds) /
898 offeredCraRbdcKbps += (uint32_t)((allocInfo->second.first[i] *
900 superFrameDurationInSeconds /
904 NS_LOG_INFO(
"UT: " << allocInfo->first <<
" RC index: " << i
905 <<
" rate based bytes: " << rateBasedBytes
906 <<
" allocated bytes: " << allocInfo->second.first[i]);
909 if (rateBasedBytes < allocInfo->second.first[i])
912 uint32_t vbdcBytes = damaEntry->GetVbdcInBytes(i);
914 NS_LOG_INFO(
"UT: " << allocInfo->first <<
" RC index: " << i
915 <<
" requested VBDC bytes: " << vbdcBytes);
918 uint32_t allocVbdcBytes = allocInfo->second.first[i] - rateBasedBytes;
921 if (vbdcBytes > allocVbdcBytes)
923 uint32_t remainingVbdcBytes = vbdcBytes - allocVbdcBytes;
925 NS_LOG_INFO(
"UT: " << allocInfo->first <<
" RC index: " << i
926 <<
" VBDC allocation: " << allocVbdcBytes
927 <<
" remaining VBDC bytes: " << remainingVbdcBytes);
929 damaEntry->SetVbdcInBytes(i, remainingVbdcBytes);
934 NS_LOG_INFO(
"UT: " << allocInfo->first <<
" RC index: " << i
935 <<
" VBDC allocation: " << allocVbdcBytes
936 <<
" remaining VBDC bytes: " << 0);
938 damaEntry->SetVbdcInBytes(i, 0);
944 damaEntry->DecrementDynamicRatePersistence();
945 damaEntry->DecrementVolumeBacklogPersistence();
947 return offeredCraRbdcKbps;
953 NS_LOG_FUNCTION(
this << utId << destination->m_beamId);
955 UtInfoMap_t::iterator utIterator =
m_utInfos.find(utId);
959 NS_ASSERT_MSG(destination->HasUt(utId),
"UT is not part of the source beam");
964 Ptr<SatUtInfo> utInfo = utIterator->second;
965 destination->AddUtInfo(utId, utInfo);
972 utInfo->ClearCrMsgs();
978 utInfo->ClearCrMsgs();
983 NS_FATAL_ERROR(
"Unknown handover strategy");
991 NS_LOG_FUNCTION(
this << utId);
993 UtInfoMap_t::iterator utIterator =
m_utInfos.find(utId);
996 NS_FATAL_ERROR(
"Trying to remove a UT not connected to a beam: " << utId);
1000 Ptr<SatUtInfo> utInfo = utIterator->second;
1007 NS_LOG_FUNCTION(
this);
1009 Ptr<SatTimuMessage> timuMsg = CreateObject<SatTimuMessage>();
1010 timuMsg->SetAllocatedBeamId(
m_beamId);
1018 NS_LOG_FUNCTION(
this << logonChannelId);
1022 uint32_t maxIndex = maxId.Get();
1024 if (logonChannelId > maxIndex)
1026 NS_FATAL_ERROR(
"Cannot use channel ID " << logonChannelId
1027 <<
" for logon as it doesn't exist");
CnoCompare class to sort UT request according to C/N0 information.
void ClearCrMsgs()
Remove all CR messages from UT info to reset capacity requests in case of handover.
void UpdateDamaEntryFromCrs()
Update DamaEntry with information of the received CR messages.
void AddCrMsg(Ptr< SatCrMessage > crMsg)
Add CR message to UT info to be used when capacity request is calculated next time (method UpdateDama...
double GetCnoEstimation()
Get estimated C/N0 value based on added samples.
Ptr< SatDamaEntry > GetDamaEntry()
Get damaEntry of the UT info.
bool IsControlSlotGenerationTime() const
Check if time is expired to send control slot.
SatUtInfo(Ptr< SatDamaEntry > damaEntry, Ptr< SatCnoEstimator > cnoEstimator, Time controlSlotOffset, bool controlSlotsEnabled)
Construct SatUtInfo.
void SetControlSlotGenerationTime(Time offset)
Set time for next time slot generation for this UT.
void AddCnoSample(double sample)
Add C/N0 sample to UT info's estimator.
class for module Beam Scheduler.
bool SendToSatellite(Ptr< SatControlMessage > msg, Address satelliteMac)
Send control message to the satellite.
HandoverInformationForward_t m_handoverStrategy
void UtCrReceived(Address utId, Ptr< SatCrMessage > crMsg)
Receive capacity requests from UTs.
uint32_t UpdateDamaEntriesWithAllocs(SatFrameAllocator::UtAllocInfoContainer_t &utAllocContainer)
Update dama entries with given allocations at end of the scheduling.
uint32_t m_maxBbFrameSize
Maximum size of the BB frame.
Ptr< SatCnoEstimator > m_satelliteCnoEstimator
Estimator for the C/N0 from satellite.
Time m_cnoEstimationWindow
Time window for C/N0 estimation.
bool m_receivedSatelliteCnoSample
Indicates if Cno sample have been received since last C/N0 control message sent.
Callback< bool, Ptr< SatControlMessage >, const Address & > SendCtrlMsgCallback
SatBeamScheduler::SendTbtpCallback m_txTbtpCallback
The TBTP send callback to inform GW Mac.
void AddRaChannels(std::vector< Ptr< SatTbtpMessage >> &tbtpContainer)
Add RA channel information to TBTP(s).
void DoPreResourceAllocation()
Do pre-allocation of the symbols per UT/RC, before time slot generation.
Time m_maxTwoWayPropagationDelay
Maximum two-way propagation delay estimate between GW-SAT-UT-SAT-GW.
void RemoveUtInfo(UtInfoMap_t::iterator iterator)
TracedCallback< uint32_t > m_exceedingCapacityTrace
Trace exceeding capacity.
Callback< void, Ptr< SatTbtpMessage > > SendTbtpCallback
void AddUtInfo(Address utId, Ptr< SatUtInfo > utInfo)
TracedCallback< uint32_t > m_usableCapacityTrace
Trace usable capacity.
TracedCallback< uint32_t, double > m_frameLoadTrace
Trace frame load ratio.
void DoDispose(void)
Dispose actions for SatBeamScheduler.
SatBeamScheduler::SendCtrlMsgCallback m_txCallback
The control message send callback.
uint32_t m_logonChannelIndex
Logon channel ID to exclude it from the RA channel selection.
SatEnums::SuperframeAllocatorType_t m_superframeAllocatorType
Type of SatSuperframeAllocator class to use.
void SetSendTbtpCallback(SendTbtpCallback cb)
Set the callback to inform NCC a TBTP has been sent.
Time m_controlSlotInterval
Interval to generate control time slots.
bool Send(Ptr< SatControlMessage > message)
Send control messages to the beam.
bool SendTo(Ptr< SatControlMessage > message, Address utId)
Send control message to an UT into the beam.
Ptr< SatSuperframeSeq > m_superframeSeq
Pointer to super frame sequence.
Ptr< SatCnoEstimator > CreateCnoEstimator()
Create estimator for the UT according to set attributes.
Ptr< SatSuperframeAllocator > m_superframeAllocator
Superframe allocator to maintain load information of the frames and their configurations.
TracedCallback< std::string > m_backlogRequestsTrace
Trace for backlog requests done to beam scheduler.
TracedCallback< uint32_t, uint32_t > m_frameUtLoadTrace
Trace count of UTs scheduled per Frame.
TracedCallback< uint32_t > m_waveformTrace
Trace first wave form scheduled for the UT.
Ptr< RandomVariableStream > m_raChRandomIndex
Random variable stream to select RA channel for a UT.
static TypeId GetTypeId(void)
Get the type ID.
Time m_maxTbtpTxAndProcessingDelay
Maximum TBTP tx and processing delay estimate at the GW (scheduler).
void SendCnoToSatellite()
Send an estimation of cno to satellite, if samples have been received.
void TransferUtToBeam(Address utId, Ptr< SatBeamScheduler > destination)
Transfer ownership of a terminal to the given SatBeamScheduler.
void ReserveLogonChannel(uint32_t logonChannelId)
~SatBeamScheduler()
Destroy a SatBeamScheduler.
bool HasUt(Address utId)
Check whether an UT is handled by this scheduler.
uint32_t m_superFrameCounter
Counter for super frame sequence.
Ptr< SatTimuMessage > CreateTimu() const
Create a TIM unicast message containing enough data for a terminal to connect to the beam handled by ...
void RemoveUt(Address utId)
Remove a UT from its SatBeamScheduler.
void Initialize(uint32_t beamId, SatBeamScheduler::SendCtrlMsgCallback cb, Ptr< SatSuperframeSeq > seq, uint32_t maxFrameSizeInBytes, Address gwAddress)
UtReqInfoContainer_t m_utRequestInfos
Container including every UT's allocation requests.
Address m_satelliteMac
MAC address of the satellite (used when regenerative)
SatCnoEstimator::EstimationMode_t m_cnoEstimatorMode
Mode used for C/N0 estimator.
void Schedule()
Schedule UTs added (registered) to scheduler.
bool m_controlSlotsEnabled
Flag to indicated if control time slots generation is enabled.
uint32_t m_beamId
ID of the beam.
uint32_t UpdateDamaEntriesWithReqs()
Update dama entries with received requests at beginning of the scheduling.
void UpdateUtCno(Address utId, double cno)
Update UT C/N0 info with the latest value.
SatBeamScheduler()
Construct a SatBeamScheduler.
uint32_t AddUt(Address utId, Ptr< SatLowerLayerServiceConf > llsConf)
Add UT to scheduler.
UtInfoMap_t m_utInfos
Map to store UT information in beam for updating purposes.
void UpdateSatelliteCno(Address satelliteMac, double cno)
Update satellite C/N0 info with the latest value.
TracedCallback< uint32_t > m_unmetCapacityTrace
Trace unmet capacity.
SatCnoEstimator class defines interface for C/N0 estimators.
@ MINIMUM
Minimum value in the given window returned.
@ LAST
Last value in the given window returned.
@ AVERAGE
Average value in the given window returned.
std::map< RequestDescriptor_t, uint16_t > RequestContainer_t
Define type RequestContainer_t.
SatEnums class is for simplifying the use of enumerators in the satellite module.
@ DEFAULT_SUPERFRAME_ALLOCATOR
SatFrameAllocReq is used to define frame allocation parameters when requesting allocation from SatFra...
Allocation information item for the UT/RC requests [bytes].
std::vector< SatFrameAllocReq * > SatFrameAllocContainer_t
Container to store SatFrameAllocReq item pointers.
std::map< Address, UtAllocInfoItem_t > UtAllocInfoContainer_t
Map container to store UT allocation information.
std::vector< SatFrameAllocReqItem > SatFrameAllocReqItemContainer_t
Container to store SatFrameAllocReqItem items.
constexpr uint8_t SUPERFRAME_SEQUENCE
Used superframe sequence in the RTN link.
constexpr uint32_t BITS_IN_KBIT
Number of bits consisting a kilobit.
constexpr uint32_t BITS_PER_BYTE
Number of bits in a byte.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.