27 #include <ns3/boolean.h>
28 #include <ns3/double.h>
34 NS_LOG_COMPONENT_DEFINE(
"SatDefaultSuperframeAllocator");
39 NS_OBJECT_ENSURE_REGISTERED(SatDefaultSuperframeAllocator);
45 TypeId(
"ns3::SatDefaultSuperframeAllocator")
47 .AddAttribute(
"TargetLoad",
48 "Target load limits upper bound of the symbols in a frame.",
51 MakeDoubleChecker<double>())
52 .AddAttribute(
"FcaEnabled",
53 "Free capacity allocation (FCA) enable status.",
58 "RcBasedAllocationEnabled",
59 "Time slot generated per RC symbols instead of sum of UT symbols.",
62 MakeBooleanChecker());
69 NS_LOG_FUNCTION(
this);
78 m_minCarrierPayloadInBytes(0),
79 m_minimumRateBasedBytesLeft(0),
80 m_rcBasedAllocationEnabled(false),
83 NS_LOG_FUNCTION(
this);
85 uint32_t currentMinCarrierPayloadInBytes = std::numeric_limits<uint32_t>::max();
86 uint32_t currentMostRobustSlotPayloadInBytes = std::numeric_limits<uint32_t>::max();
88 Ptr<SatFrameConf> parentFrameConf =
nullptr;
89 Ptr<SatFrameAllocator> parentFrameAllocator =
nullptr;
90 for (uint8_t i = 0; i < superFrameConf->GetFrameCount(); i++)
92 Ptr<SatFrameConf> frameConf = superFrameConf->GetFrameConf(i);
93 if (!frameConf->IsRandomAccess())
95 Ptr<SatFrameConf> parentConf = frameConf->GetParent();
96 if (parentConf != parentFrameConf)
98 NS_ASSERT_MSG(parentConf ==
nullptr,
99 "Wrong ordering of frame confs. Need to have subdivided ones right "
100 "after their parents.");
101 parentFrameAllocator =
nullptr;
103 parentFrameConf = frameConf;
105 Ptr<SatFrameAllocator> frameAllocator =
106 Create<SatFrameAllocator>(frameConf,
108 superFrameConf->GetConfigType(),
109 parentFrameAllocator);
111 parentFrameAllocator = frameAllocator;
113 uint32_t minCarrierPayloadInBytes = frameAllocator->GetCarrierMinPayloadInBytes();
115 if (minCarrierPayloadInBytes < currentMinCarrierPayloadInBytes)
117 currentMinCarrierPayloadInBytes = minCarrierPayloadInBytes;
121 uint32_t mostRobustSlotPayloadInBytes =
122 frameAllocator->GetMostRobustWaveform()->GetPayloadInBytes();
124 if (mostRobustSlotPayloadInBytes < currentMostRobustSlotPayloadInBytes)
126 currentMostRobustSlotPayloadInBytes = mostRobustSlotPayloadInBytes;
131 frameAllocator->GetCarrierCount() * minCarrierPayloadInBytes;
139 NS_LOG_FUNCTION(
this);
146 NS_LOG_FUNCTION(
this << &allocReqs);
148 std::map<Ptr<SatFrameAllocator>, uint32_t> wsrDemand;
150 NS_LOG_LOGIC(
"Select best carrier for each terminal request");
151 for (
auto& allocRequest : allocReqs)
153 uint32_t bestWaveFormId = 0;
154 Ptr<SatFrameAllocator> selectedFrameAllocator =
156 if (selectedFrameAllocator !=
nullptr)
158 for (
auto& request : allocRequest->m_reqPerRc)
160 wsrDemand[selectedFrameAllocator] +=
161 request.m_craBytes + std::max(request.m_minRbdcBytes, request.m_rbdcBytes) +
167 NS_LOG_WARN(
"SatDefaultSuperframeAllocator::SelectCarriers: No suitable frame and "
168 "waveform found for "
170 << allocRequest->m_address <<
" with C/N0 of " << allocRequest->m_cno
172 "Ignoring this terminal in carrier selection.");
176 NS_LOG_LOGIC(
"Calculate Load Coefficient");
177 double requestedBandwidth = 0.0;
178 for (
auto& demand : wsrDemand)
180 requestedBandwidth +=
181 demand.first->GetCarrierBandwidthHz() * demand.second / demand.first->GetVolumeBytes();
183 double loadCoefficient = std::min(std::max(0.1,
m_totalBandwidth / requestedBandwidth), 10.0);
184 NS_LOG_INFO(
"" << allocReqs.size() <<
" requested " << requestedBandwidth <<
"Hz through "
185 << wsrDemand.size() <<
" subdivision levels; giving a load coefficient of "
189 for (
auto& demand : wsrDemand)
191 scaledDemand[demand.first] =
192 loadCoefficient * demand.second / demand.first->GetVolumeBytes() + 1;
195 NS_LOG_LOGIC(
"Zero-out old carrier selection");
198 uint16_t zeroReference = 0;
199 frameAllocator->SelectCarriers(zeroReference, 0);
202 NS_LOG_LOGIC(
"Allocate carriers in subdivision levels");
203 while (!scaledDemand.empty())
205 NS_LOG_LOGIC(
"Find bandwidth of the original frame");
206 Ptr<SatFrameAllocator> frameAllocator = scaledDemand.begin()->first;
207 while (frameAllocator->GetParent() !=
nullptr)
209 frameAllocator = frameAllocator->GetParent();
211 double remainingBandwidth = frameAllocator->GetCarrierBandwidthHz(
true);
212 NS_ASSERT_MSG(remainingBandwidth != 0.0,
"Could not find bandwidth of original frame");
215 frameAllocator = scaledDemand.begin()->first;
217 while (frameAllocator !=
nullptr)
219 auto frameDemand = scaledDemand.find(frameAllocator);
221 if (frameDemand != scaledDemand.end())
223 demand = frameDemand->second;
224 scaledDemand.erase(frameDemand);
226 NS_LOG_LOGIC(demand <<
" carriers requested on (subdivided) frame "
227 << frameAllocator->GetCarrierBandwidthHz());
228 uint16_t carriersCount = 0;
229 double carrierBandwidth = frameAllocator->GetCarrierBandwidthHz();
230 if (frameAllocator->GetParent() !=
nullptr)
233 uint16_t remainingCarriers = remainingBandwidth / carrierBandwidth;
234 carriersCount = std::max(uint16_t(0), std::min(demand, remainingCarriers));
237 frameAllocator->SelectCarriers(carriersCount, offset);
238 remainingBandwidth -= carriersCount * carrierBandwidth;
239 NS_LOG_INFO(
"Remaining bandwidth on non-subdivided frame: " << remainingBandwidth);
240 offset = (carriersCount + offset) / 2;
241 frameAllocator = frameAllocator->GetParent();
244 if (remainingBandwidth < 0.0)
247 "SatDefaultSuperframeAllocator::SelectCarriers: remaining bandwidth is negative");
252 Ptr<SatFrameAllocator>
255 NS_LOG_FUNCTION(
this << cno);
257 double cnoDiff = std::numeric_limits<double>::infinity();
258 Ptr<SatFrameAllocator> selectedFrameAllocator =
nullptr;
264 if (frameAllocator->GetBestWaveform(cno, waveFormId, waveformCNo))
266 double diff = cno - waveformCNo;
270 bestWaveFormId = waveFormId;
271 selectedFrameAllocator = frameAllocator;
276 return selectedFrameAllocator;
282 NS_LOG_FUNCTION(
this);
295 uint32_t maxSizeInBytes,
297 TracedCallback<uint32_t> waveformTrace,
298 TracedCallback<uint32_t, uint32_t> utLoadTrace,
299 TracedCallback<uint32_t, double> loadTrace)
301 NS_LOG_FUNCTION(
this);
303 if (tbtpContainer.empty())
305 NS_FATAL_ERROR(
"TBTP container must contain at least one message.");
312 (*it)->GenerateTimeSlots(tbtpContainer,
326 NS_LOG_FUNCTION(
this);
335 for (SatFrameAllocator::SatFrameAllocContainer_t::iterator itReq = allocReqs.begin();
336 itReq != allocReqs.end();
352 bool controlSlotsEnabled)
354 NS_LOG_FUNCTION(
this << minimumRateBytes);
356 uint32_t rateBasedByteToCheck = minimumRateBytes;
358 if (controlSlotsEnabled)
365 NS_FATAL_ERROR(
"Minimum requested bytes ("
366 << minimumRateBytes <<
") for UT is greater than bytes in minimum carrier ("
371 NS_FATAL_ERROR(
"Minimum requested bytes ("
372 << minimumRateBytes <<
") for UT is greater than minimum bytes left ("
383 bool controlSlotsEnabled)
385 NS_LOG_FUNCTION(
this << minimumRateBytes);
387 uint32_t rateBasedByteToCheck = minimumRateBytes;
389 if (controlSlotsEnabled)
396 NS_FATAL_ERROR(
"Minimum released bytes ("
397 << minimumRateBytes <<
") for UT is greater than bytes in minimum carrier ("
409 NS_LOG_FUNCTION(
this);
411 bool allocated =
false;
418 uint32_t waveformId = 0;
419 double cnoThreshold = std::numeric_limits<double>::quiet_NaN();
420 if (frameAllocator->GetCarrierCount() &&
421 frameAllocator->GetBestWaveform(allocReq->
m_cno, waveformId, cnoThreshold))
423 supportedFrames.insert(std::make_pair(frameAllocator, waveformId));
427 NS_LOG_INFO(
"Terminal with C/N0 of " << allocReq->
m_cno <<
" found " << supportedFrames.size()
428 <<
" supported frames.");
430 if (!supportedFrames.empty())
468 NS_LOG_FUNCTION(
this << ccLevel);
470 double loadInSymbols = 0;
471 SupportedFramesMap_t::const_iterator selectedFrame = frames.begin();
475 NS_FATAL_ERROR(
"Tried to allocate without frames!!!");
479 for (SupportedFramesMap_t::const_iterator it = frames.begin(); it != frames.end(); it++)
481 if (it == frames.begin())
483 loadInSymbols = it->first->GetCcLoad(ccLevel);
485 else if (it->first->GetCcLoad(ccLevel) < loadInSymbols)
488 loadInSymbols = it->first->GetCcLoad(ccLevel);
492 return selectedFrame->first->Allocate(ccLevel, allocReq, selectedFrame->second);
uint32_t m_minimumRateBasedBytesLeft
bool m_rcBasedAllocationEnabled
bool AllocateBasedOnCc(SatFrameAllocator::CcLevel_t ccLevel, SatFrameAllocator::SatFrameAllocReq *allocReq, const SupportedFramesMap_t &frames)
Allocate given request according to type.
bool AllocateToFrame(SatFrameAllocator::SatFrameAllocReq *allocReq)
Allocate a request to a frame.
void PreAllocateSymbols(SatFrameAllocator::SatFrameAllocContainer_t &allocReqs)
Preallocate symbols for given to UTs in superframe.
void ReleaseMinimumRate(uint32_t minimumRateBytes, bool controlSlotsEnabled)
Release minimum rate from the allocator.
SatDefaultSuperframeAllocator(Ptr< SatSuperframeConf > superFrameConf)
Construct SatDefaultSuperframeAllocator.
void RemoveAllocations()
Remove allocations from all frames maintained by frame allocator.
virtual TypeId GetInstanceTypeId(void) const
Get the type ID of instance.
Ptr< SatFrameAllocator > SelectBestCarrier(double cno, uint32_t &bestWaveFormId)
Select which carrier is the best suited for handling requests of a terminal communicating at the give...
FrameAllocatorContainer_t m_frameAllocators
uint32_t m_minCarrierPayloadInBytes
void SelectCarriers(SatFrameAllocator::SatFrameAllocContainer_t &allocReqs)
Select which carriers to use from the underlying frames.
void GenerateTimeSlots(SatFrameAllocator::TbtpMsgContainer_t &tbtpContainer, uint32_t maxSizeInBytes, SatFrameAllocator::UtAllocInfoContainer_t &utAllocContainer, TracedCallback< uint32_t > waveformTrace, TracedCallback< uint32_t, uint32_t > utLoadTrace, TracedCallback< uint32_t, double > loadTrace)
Generate time slots in TBTP(s) for the UT/RC.
~SatDefaultSuperframeAllocator()
Destruct SatDefaultSuperframeAllocator.
static TypeId GetTypeId(void)
derived from object
std::map< Ptr< SatFrameAllocator >, uint32_t > SupportedFramesMap_t
Container for the supported SatFrameAllocator (frames).
uint32_t m_mostRobustSlotPayloadInBytes
void ReserveMinimumRate(uint32_t minimumRateBytes, bool controlSlotsEnabled)
Reserve minimum rate from the allocator.
SatFrameAllocReq is used to define frame allocation parameters when requesting allocation from SatFra...
std::vector< SatFrameAllocReq * > SatFrameAllocContainer_t
Container to store SatFrameAllocReq item pointers.
std::vector< Ptr< SatTbtpMessage > > TbtpMsgContainer_t
Container to store generated TBTP messages.
CcLevel_t
Enum for CC levels.
@ CC_LEVEL_CRA_RBDC
CC level CRA + RBDC.
@ CC_LEVEL_CRA
CC level CRA.
@ CC_LEVEL_CRA_RBDC_VBDC
CC level CRA + RBDC + VBDC.
@ CC_LEVEL_CRA_MIN_RBDC
CC level CRA + Minimum RBDC.
std::map< Address, UtAllocInfoItem_t > UtAllocInfoContainer_t
Map container to store UT allocation information.
helper class for Satellite Beam Scheduler.
Ptr< SatSuperframeConf > m_superframeConf
@ CONFIG_TYPE_3
Configuration type 3.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
BandwidthComparator is a custom functor meant as comparison function for std::map.