77 NS_LOG_FUNCTION(
this << superFrameConf);
79 uint32_t currentMinCarrierPayloadInBytes = std::numeric_limits<uint32_t>::max();
80 uint32_t currentMostRobustSlotPayloadInBytes = std::numeric_limits<uint32_t>::max();
82 Ptr<SatFrameConf> parentFrameConf =
nullptr;
83 Ptr<SatFrameAllocator> parentFrameAllocator =
nullptr;
84 for (uint8_t i = 0; i < superFrameConf->GetFrameCount(); i++)
86 Ptr<SatFrameConf> frameConf = superFrameConf->GetFrameConf(i);
87 if (!frameConf->IsRandomAccess())
89 Ptr<SatFrameConf> parentConf = frameConf->GetParent();
90 if (parentConf != parentFrameConf)
92 NS_ASSERT_MSG(parentConf ==
nullptr,
93 "Wrong ordering of frame confs. Need to have subdivided ones right "
94 "after their parents.");
95 parentFrameAllocator =
nullptr;
97 parentFrameConf = frameConf;
99 Ptr<SatFrameAllocator> frameAllocator =
100 Create<SatFrameAllocator>(frameConf,
102 superFrameConf->GetConfigType(),
103 parentFrameAllocator);
105 parentFrameAllocator = frameAllocator;
107 uint32_t minCarrierPayloadInBytes = frameAllocator->GetCarrierMinPayloadInBytes();
109 if (minCarrierPayloadInBytes < currentMinCarrierPayloadInBytes)
111 currentMinCarrierPayloadInBytes = minCarrierPayloadInBytes;
115 uint32_t mostRobustSlotPayloadInBytes =
116 frameAllocator->GetMostRobustWaveform()->GetPayloadInBytes();
118 if (mostRobustSlotPayloadInBytes < currentMostRobustSlotPayloadInBytes)
120 currentMostRobustSlotPayloadInBytes = mostRobustSlotPayloadInBytes;
125 frameAllocator->GetCarrierCount() * minCarrierPayloadInBytes;
140 NS_LOG_FUNCTION(
this << &allocReqs);
142 std::map<Ptr<SatFrameAllocator>, uint32_t> wsrDemand;
144 NS_LOG_LOGIC(
"Select best carrier for each terminal request");
145 for (
auto& allocRequest : allocReqs)
147 uint32_t bestWaveFormId = 0;
148 Ptr<SatFrameAllocator> selectedFrameAllocator =
150 if (selectedFrameAllocator !=
nullptr)
152 for (
auto& request : allocRequest->m_reqPerRc)
154 wsrDemand[selectedFrameAllocator] +=
155 request.m_craBytes + std::max(request.m_minRbdcBytes, request.m_rbdcBytes) +
161 NS_LOG_WARN(
"SatDefaultSuperframeAllocator::SelectCarriers: No suitable frame and "
162 "waveform found for "
164 << allocRequest->m_address <<
" with C/N0 of " << allocRequest->m_cno
166 "Ignoring this terminal in carrier selection.");
170 NS_LOG_LOGIC(
"Calculate Load Coefficient");
171 double requestedBandwidth = 0.0;
172 for (
auto& demand : wsrDemand)
174 requestedBandwidth +=
175 demand.first->GetCarrierBandwidthHz() * demand.second / demand.first->GetVolumeBytes();
177 double loadCoefficient = std::min(std::max(0.1,
m_totalBandwidth / requestedBandwidth), 10.0);
178 NS_LOG_INFO(
"" << allocReqs.size() <<
" requested " << requestedBandwidth <<
"Hz through "
179 << wsrDemand.size() <<
" subdivision levels; giving a load coefficient of "
183 for (
auto& demand : wsrDemand)
185 scaledDemand[demand.first] =
186 loadCoefficient * demand.second / demand.first->GetVolumeBytes() + 1;
189 NS_LOG_LOGIC(
"Zero-out old carrier selection");
192 uint16_t zeroReference = 0;
193 frameAllocator->SelectCarriers(zeroReference, 0);
196 NS_LOG_LOGIC(
"Allocate carriers in subdivision levels");
197 while (!scaledDemand.empty())
199 NS_LOG_LOGIC(
"Find bandwidth of the original frame");
200 Ptr<SatFrameAllocator> frameAllocator = scaledDemand.begin()->first;
201 while (frameAllocator->GetParent() !=
nullptr)
203 frameAllocator = frameAllocator->GetParent();
205 double remainingBandwidth = frameAllocator->GetCarrierBandwidthHz(
true);
206 NS_ASSERT_MSG(remainingBandwidth != 0.0,
"Could not find bandwidth of original frame");
209 frameAllocator = scaledDemand.begin()->first;
211 while (frameAllocator !=
nullptr)
213 auto frameDemand = scaledDemand.find(frameAllocator);
215 if (frameDemand != scaledDemand.end())
217 demand = frameDemand->second;
218 scaledDemand.erase(frameDemand);
220 NS_LOG_LOGIC(demand <<
" carriers requested on (subdivided) frame "
221 << frameAllocator->GetCarrierBandwidthHz());
222 uint16_t carriersCount = 0;
223 double carrierBandwidth = frameAllocator->GetCarrierBandwidthHz();
224 if (frameAllocator->GetParent() !=
nullptr)
227 uint16_t remainingCarriers = remainingBandwidth / carrierBandwidth;
228 carriersCount = std::max(uint16_t(0), std::min(demand, remainingCarriers));
231 frameAllocator->SelectCarriers(carriersCount, offset);
232 remainingBandwidth -= carriersCount * carrierBandwidth;
233 NS_LOG_INFO(
"Remaining bandwidth on non-subdivided frame: " << remainingBandwidth);
234 offset = (carriersCount + offset) / 2;
235 frameAllocator = frameAllocator->GetParent();
238 if (remainingBandwidth < 0.0)
241 "SatDefaultSuperframeAllocator::SelectCarriers: remaining bandwidth is negative");
249 NS_LOG_FUNCTION(
this << cno);
251 double cnoDiff = std::numeric_limits<double>::infinity();
252 Ptr<SatFrameAllocator> selectedFrameAllocator =
nullptr;
258 if (frameAllocator->GetBestWaveform(cno, waveFormId, waveformCNo))
260 double diff = cno - waveformCNo;
264 bestWaveFormId = waveFormId;
265 selectedFrameAllocator = frameAllocator;
270 return selectedFrameAllocator;
403 NS_LOG_FUNCTION(
this);
405 bool allocated =
false;
412 uint32_t waveformId = 0;
413 double cnoThreshold = std::numeric_limits<double>::quiet_NaN();
414 if (frameAllocator->GetCarrierCount() &&
415 frameAllocator->GetBestWaveform(allocReq->
m_cno, waveformId, cnoThreshold))
417 supportedFrames.insert(std::make_pair(frameAllocator, waveformId));
421 NS_LOG_INFO(
"Terminal with C/N0 of " << allocReq->
m_cno <<
" found " << supportedFrames.size()
422 <<
" supported frames.");
424 if (!supportedFrames.empty())
462 NS_LOG_FUNCTION(
this << ccLevel);
464 double loadInSymbols = 0;
465 SupportedFramesMap_t::const_iterator selectedFrame = frames.begin();
469 NS_FATAL_ERROR(
"Tried to allocate without frames!!!");
473 for (SupportedFramesMap_t::const_iterator it = frames.begin(); it != frames.end(); it++)
475 if (it == frames.begin())
477 loadInSymbols = it->first->GetCcLoad(ccLevel);
479 else if (it->first->GetCcLoad(ccLevel) < loadInSymbols)
482 loadInSymbols = it->first->GetCcLoad(ccLevel);
486 return selectedFrame->first->Allocate(ccLevel, allocReq, selectedFrame->second);
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.