27 #include <ns3/boolean.h>
28 #include <ns3/double.h>
36 NS_LOG_COMPONENT_DEFINE(
"SatDefaultSuperframeAllocator");
41 NS_OBJECT_ENSURE_REGISTERED(SatDefaultSuperframeAllocator);
47 TypeId(
"ns3::SatDefaultSuperframeAllocator")
49 .AddAttribute(
"TargetLoad",
50 "Target load limits upper bound of the symbols in a frame.",
53 MakeDoubleChecker<double>())
54 .AddAttribute(
"FcaEnabled",
55 "Free capacity allocation (FCA) enable status.",
60 "RcBasedAllocationEnabled",
61 "Time slot generated per RC symbols instead of sum of UT symbols.",
64 MakeBooleanChecker());
71 NS_LOG_FUNCTION(
this);
80 m_minCarrierPayloadInBytes(0),
81 m_minimumRateBasedBytesLeft(0),
82 m_rcBasedAllocationEnabled(false),
85 NS_LOG_FUNCTION(
this);
87 uint32_t currentMinCarrierPayloadInBytes = std::numeric_limits<uint32_t>::max();
88 uint32_t currentMostRobustSlotPayloadInBytes = std::numeric_limits<uint32_t>::max();
90 Ptr<SatFrameConf> parentFrameConf =
nullptr;
91 Ptr<SatFrameAllocator> parentFrameAllocator =
nullptr;
92 for (uint8_t i = 0; i < superFrameConf->GetFrameCount(); i++)
94 Ptr<SatFrameConf> frameConf = superFrameConf->GetFrameConf(i);
95 if (!frameConf->IsRandomAccess())
97 Ptr<SatFrameConf> parentConf = frameConf->GetParent();
98 if (parentConf != parentFrameConf)
100 NS_ASSERT_MSG(parentConf ==
nullptr,
101 "Wrong ordering of frame confs. Need to have subdivided ones right "
102 "after their parents.");
103 parentFrameAllocator =
nullptr;
105 parentFrameConf = frameConf;
107 Ptr<SatFrameAllocator> frameAllocator =
108 Create<SatFrameAllocator>(frameConf,
110 superFrameConf->GetConfigType(),
111 parentFrameAllocator);
113 parentFrameAllocator = frameAllocator;
115 uint32_t minCarrierPayloadInBytes = frameAllocator->GetCarrierMinPayloadInBytes();
117 if (minCarrierPayloadInBytes < currentMinCarrierPayloadInBytes)
119 currentMinCarrierPayloadInBytes = minCarrierPayloadInBytes;
123 uint32_t mostRobustSlotPayloadInBytes =
124 frameAllocator->GetMostRobustWaveform()->GetPayloadInBytes();
126 if (mostRobustSlotPayloadInBytes < currentMostRobustSlotPayloadInBytes)
128 currentMostRobustSlotPayloadInBytes = mostRobustSlotPayloadInBytes;
133 frameAllocator->GetCarrierCount() * minCarrierPayloadInBytes;
141 NS_LOG_FUNCTION(
this);
148 NS_LOG_FUNCTION(
this << &allocReqs);
150 std::map<Ptr<SatFrameAllocator>, uint32_t> wsrDemand;
152 NS_LOG_LOGIC(
"Select best carrier for each terminal request");
153 for (
auto& allocRequest : allocReqs)
155 uint32_t bestWaveFormId = 0;
156 Ptr<SatFrameAllocator> selectedFrameAllocator =
158 if (selectedFrameAllocator !=
nullptr)
160 for (
auto& request : allocRequest->m_reqPerRc)
162 wsrDemand[selectedFrameAllocator] +=
163 request.m_craBytes + std::max(request.m_minRbdcBytes, request.m_rbdcBytes) +
169 NS_LOG_WARN(
"SatDefaultSuperframeAllocator::SelectCarriers: No suitable frame and "
170 "waveform found for "
172 << allocRequest->m_address <<
" with C/N0 of " << allocRequest->m_cno
174 "Ignoring this terminal in carrier selection.");
178 NS_LOG_LOGIC(
"Calculate Load Coefficient");
179 double requestedBandwidth = 0.0;
180 for (
auto& demand : wsrDemand)
182 requestedBandwidth +=
183 demand.first->GetCarrierBandwidthHz() * demand.second / demand.first->GetVolumeBytes();
185 double loadCoefficient = std::min(std::max(0.1,
m_totalBandwidth / requestedBandwidth), 10.0);
186 NS_LOG_INFO(
"" << allocReqs.size() <<
" requested " << requestedBandwidth <<
"Hz through "
187 << wsrDemand.size() <<
" subdivision levels; giving a load coefficient of "
191 for (
auto& demand : wsrDemand)
193 scaledDemand[demand.first] =
194 loadCoefficient * demand.second / demand.first->GetVolumeBytes() + 1;
197 NS_LOG_LOGIC(
"Zero-out old carrier selection");
200 uint16_t zeroReference = 0;
201 frameAllocator->SelectCarriers(zeroReference, 0);
204 NS_LOG_LOGIC(
"Allocate carriers in subdivision levels");
205 while (!scaledDemand.empty())
207 NS_LOG_LOGIC(
"Find bandwidth of the original frame");
208 Ptr<SatFrameAllocator> frameAllocator = scaledDemand.begin()->first;
209 while (frameAllocator->GetParent() !=
nullptr)
211 frameAllocator = frameAllocator->GetParent();
213 double remainingBandwidth = frameAllocator->GetCarrierBandwidthHz(
true);
214 NS_ASSERT_MSG(remainingBandwidth != 0.0,
"Could not find bandwidth of original frame");
217 frameAllocator = scaledDemand.begin()->first;
219 while (frameAllocator !=
nullptr)
221 auto frameDemand = scaledDemand.find(frameAllocator);
223 if (frameDemand != scaledDemand.end())
225 demand = frameDemand->second;
226 scaledDemand.erase(frameDemand);
228 NS_LOG_LOGIC(demand <<
" carriers requested on (subdivided) frame "
229 << frameAllocator->GetCarrierBandwidthHz());
230 uint16_t carriersCount = 0;
231 double carrierBandwidth = frameAllocator->GetCarrierBandwidthHz();
232 if (frameAllocator->GetParent() !=
nullptr)
235 uint16_t remainingCarriers = remainingBandwidth / carrierBandwidth;
236 carriersCount = std::max(uint16_t(0), std::min(demand, remainingCarriers));
239 frameAllocator->SelectCarriers(carriersCount, offset);
240 remainingBandwidth -= carriersCount * carrierBandwidth;
241 NS_LOG_INFO(
"Remaining bandwidth on non-subdivided frame: " << remainingBandwidth);
242 offset = (carriersCount + offset) / 2;
243 frameAllocator = frameAllocator->GetParent();
246 if (remainingBandwidth < 0.0)
249 "SatDefaultSuperframeAllocator::SelectCarriers: remaining bandwidth is negative");
254 Ptr<SatFrameAllocator>
257 NS_LOG_FUNCTION(
this << cno);
259 double cnoDiff = std::numeric_limits<double>::infinity();
260 Ptr<SatFrameAllocator> selectedFrameAllocator =
nullptr;
266 if (frameAllocator->GetBestWaveform(cno, waveFormId, waveformCNo))
268 double diff = cno - waveformCNo;
272 bestWaveFormId = waveFormId;
273 selectedFrameAllocator = frameAllocator;
278 return selectedFrameAllocator;
284 NS_LOG_FUNCTION(
this);
297 uint32_t maxSizeInBytes,
299 TracedCallback<uint32_t> waveformTrace,
300 TracedCallback<uint32_t, uint32_t> utLoadTrace,
301 TracedCallback<uint32_t, double> loadTrace)
303 NS_LOG_FUNCTION(
this);
305 if (tbtpContainer.empty())
307 NS_FATAL_ERROR(
"TBTP container must contain at least one message.");
314 (*it)->GenerateTimeSlots(tbtpContainer,
328 NS_LOG_FUNCTION(
this);
337 for (SatFrameAllocator::SatFrameAllocContainer_t::iterator itReq = allocReqs.begin();
338 itReq != allocReqs.end();
354 bool controlSlotsEnabled)
356 NS_LOG_FUNCTION(
this << minimumRateBytes);
358 uint32_t rateBasedByteToCheck = minimumRateBytes;
360 if (controlSlotsEnabled)
367 NS_FATAL_ERROR(
"Minimum requested bytes ("
368 << minimumRateBytes <<
") for UT is greater than bytes in minimum carrier ("
373 NS_FATAL_ERROR(
"Minimum requested bytes ("
374 << minimumRateBytes <<
") for UT is greater than minimum bytes left ("
385 bool controlSlotsEnabled)
387 NS_LOG_FUNCTION(
this << minimumRateBytes);
389 uint32_t rateBasedByteToCheck = minimumRateBytes;
391 if (controlSlotsEnabled)
398 NS_FATAL_ERROR(
"Minimum released bytes ("
399 << minimumRateBytes <<
") for UT is greater than bytes in minimum carrier ("
411 NS_LOG_FUNCTION(
this);
413 bool allocated =
false;
420 uint32_t waveformId = 0;
421 double cnoThreshold = std::numeric_limits<double>::quiet_NaN();
422 if (frameAllocator->GetCarrierCount() &&
423 frameAllocator->GetBestWaveform(allocReq->
m_cno, waveformId, cnoThreshold))
425 supportedFrames.insert(std::make_pair(frameAllocator, waveformId));
429 NS_LOG_INFO(
"Terminal with C/N0 of " << allocReq->
m_cno <<
" found " << supportedFrames.size()
430 <<
" supported frames.");
432 if (!supportedFrames.empty())
470 NS_LOG_FUNCTION(
this << ccLevel);
472 double loadInSymbols = 0;
473 SupportedFramesMap_t::const_iterator selectedFrame = frames.begin();
477 NS_FATAL_ERROR(
"Tried to allocate without frames!!!");
481 for (SupportedFramesMap_t::const_iterator it = frames.begin(); it != frames.end(); it++)
483 if (it == frames.begin())
485 loadInSymbols = it->first->GetCcLoad(ccLevel);
487 else if (it->first->GetCcLoad(ccLevel) < loadInSymbols)
490 loadInSymbols = it->first->GetCcLoad(ccLevel);
494 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.