satellite-frame-allocator.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 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 
23 #include "satellite-utils.h"
24 
25 #include <ns3/boolean.h>
26 #include <ns3/double.h>
27 #include <ns3/log.h>
28 
29 #include <algorithm>
30 #include <limits>
31 
32 NS_LOG_COMPONENT_DEFINE("SatFrameAllocator");
33 
34 namespace ns3
35 {
36 
37 // helper classes defined inside SatFrameAllocator
38 
40  : m_ctrlSlotPresent(false),
41  m_craSymbols(0.0),
42  m_minRbdcSymbols(0.0),
43  m_rbdcSymbols(0.0),
44  m_vbdcSymbols(0.0)
45 {
46  NS_LOG_FUNCTION(this);
47 }
48 
50  : m_ctrlSlotPresent(false),
51  m_craSymbols(0.0),
52  m_minRbdcSymbols(0.0),
53  m_rbdcSymbols(0.0),
54  m_vbdcSymbols(0.0)
55 {
56  NS_LOG_FUNCTION(this << (uint32_t)countOfRcs);
57 
59 }
60 
62  Ptr<SatWaveform> trcWaveForm,
63  bool ctrlSlotPresent,
64  double ctrlSlotLength)
65  : m_ctrlSlotPresent(ctrlSlotPresent),
66  m_craSymbols(0.0),
67  m_minRbdcSymbols(0.0),
68  m_rbdcSymbols(0.0),
69  m_vbdcSymbols(0.0)
70 {
71  NS_LOG_FUNCTION(this << ctrlSlotPresent << ctrlSlotLength);
72 
73  for (SatFrameAllocReqItemContainer_t::const_iterator it = req.begin(); it != req.end(); it++)
74  {
75  SatFrameAllocInfoItem reqInSymbols;
76 
77  reqInSymbols.m_craSymbols = trcWaveForm->GetBurstLengthInSymbols() * it->m_craBytes /
78  trcWaveForm->GetPayloadInBytes();
79  reqInSymbols.m_minRbdcSymbols = trcWaveForm->GetBurstLengthInSymbols() *
80  it->m_minRbdcBytes / trcWaveForm->GetPayloadInBytes();
81  reqInSymbols.m_rbdcSymbols = trcWaveForm->GetBurstLengthInSymbols() * it->m_rbdcBytes /
82  trcWaveForm->GetPayloadInBytes();
83  reqInSymbols.m_vbdcSymbols = trcWaveForm->GetBurstLengthInSymbols() * it->m_vbdcBytes /
84  trcWaveForm->GetPayloadInBytes();
85 
86  // if control slot should be allocated and RC index is 0
87  // add symbols needed for control slot to CRA symbols
88  if (m_ctrlSlotPresent && (it == req.begin()))
89  {
90  reqInSymbols.m_craSymbols += ctrlSlotLength;
91  }
92 
93  m_craSymbols += reqInSymbols.m_craSymbols;
94  m_minRbdcSymbols += reqInSymbols.m_minRbdcSymbols;
95  m_rbdcSymbols += reqInSymbols.m_rbdcSymbols;
96  m_vbdcSymbols += reqInSymbols.m_vbdcSymbols;
97 
98  m_allocInfoPerRc.push_back(reqInSymbols);
99  }
100 }
101 
104 {
105  NS_LOG_FUNCTION(this);
106 
107  m_craSymbols = 0.0;
108  m_minRbdcSymbols = 0.0;
109  m_rbdcSymbols = 0.0;
110  m_vbdcSymbols = 0.0;
111 
112  SatFrameAllocInfoItem totalReqs;
113 
114  for (SatFrameAllocInfoItemContainer_t::const_iterator it = m_allocInfoPerRc.begin();
115  it != m_allocInfoPerRc.end();
116  it++)
117  {
118  SatFrameAllocInfoItem reqInSymbols;
119 
120  m_craSymbols += it->m_craSymbols;
121  m_minRbdcSymbols += it->m_minRbdcSymbols;
122  m_rbdcSymbols += it->m_rbdcSymbols;
123  m_vbdcSymbols += it->m_vbdcSymbols;
124  }
125 
126  totalReqs.m_craSymbols = m_craSymbols;
127  totalReqs.m_minRbdcSymbols = m_minRbdcSymbols;
128  totalReqs.m_rbdcSymbols = m_rbdcSymbols;
129  totalReqs.m_vbdcSymbols = m_vbdcSymbols;
130 
131  return totalReqs;
132 }
133 
134 double
136 {
137  return (m_craSymbols + m_rbdcSymbols + m_vbdcSymbols);
138 }
139 
141  CcReqCompare::CcReqType_t ccReqType)
142  : m_utAllocContainer(utAllocContainer),
143  m_ccReqType(ccReqType)
144 {
145 }
146 
147 bool
149 {
150  bool result = false;
151 
152  switch (m_ccReqType)
153  {
154  case CC_TYPE_MIN_RBDC:
155  result = (m_utAllocContainer.at(rcAlloc1.first)
156  .m_request.m_allocInfoPerRc[rcAlloc1.second]
157  .m_minRbdcSymbols < m_utAllocContainer.at(rcAlloc2.first)
158  .m_request.m_allocInfoPerRc[rcAlloc2.second]
159  .m_minRbdcSymbols);
160  break;
161 
162  case CC_TYPE_RBDC:
163  result = (m_utAllocContainer.at(rcAlloc1.first)
164  .m_request.m_allocInfoPerRc[rcAlloc1.second]
165  .m_rbdcSymbols < m_utAllocContainer.at(rcAlloc2.first)
166  .m_request.m_allocInfoPerRc[rcAlloc2.second]
167  .m_rbdcSymbols);
168  break;
169 
170  case CC_TYPE_VBDC:
171  result = (m_utAllocContainer.at(rcAlloc1.first)
172  .m_request.m_allocInfoPerRc[rcAlloc1.second]
173  .m_vbdcSymbols < m_utAllocContainer.at(rcAlloc2.first)
174  .m_request.m_allocInfoPerRc[rcAlloc2.second]
175  .m_vbdcSymbols);
176  break;
177 
178  default:
179  NS_FATAL_ERROR("Invalid CC type!!!");
180  break;
181  }
182 
183  return result;
184 }
185 
186 bool
188  const Ptr<SatFrameAllocator>& b) const
189 {
190  double bandwidthA = a->m_frameConf->GetBandwidthHz();
191  double bandwidthB = b->m_frameConf->GetBandwidthHz();
192 
193  if (bandwidthA == bandwidthB)
194  return a > b;
195  return bandwidthA > bandwidthB;
196 }
197 
198 // SatFrameAllocator
199 
201  : m_allocationDenied(true),
210  m_carriersOffset(0),
211  m_configType(SatSuperframeConf::CONFIG_TYPE_0),
212  m_frameId(0),
213  m_frameConf(nullptr),
214  m_parent(nullptr)
215 {
216  NS_LOG_FUNCTION(this);
217  NS_FATAL_ERROR("Default constructor not supported!!!");
218 }
219 
220 SatFrameAllocator::SatFrameAllocator(Ptr<SatFrameConf> frameConf,
221  uint8_t frameId,
223  Ptr<SatFrameAllocator> parent)
224  : m_allocationDenied(true),
225  m_maxCarrierCount(0),
226  m_carriersOffset(0),
227  m_configType(configType),
228  m_frameId(frameId),
229  m_frameConf(frameConf),
230  m_parent(parent)
231 {
232  NS_LOG_FUNCTION(this << (uint32_t)frameId);
233 
234  if (!m_frameConf->IsSubdivided())
235  {
236  m_maxCarrierCount = m_frameConf->GetCarrierCount();
237  }
238 
239  m_waveformConf = m_frameConf->GetWaveformConf();
240  m_maxSymbolsPerCarrier = frameConf->GetCarrierMaxSymbols();
242  m_guardTimeSymbols = m_frameConf->GetGuardTimeSymbols();
243 
244  switch (m_configType)
245  {
247  m_burstLenghts.push_back(m_waveformConf->GetDefaultBurstLength());
248  m_mostRobustWaveform = m_waveformConf->GetWaveform(m_waveformConf->GetDefaultWaveformId());
249  break;
250  }
251 
253  m_burstLenghts.push_back(m_waveformConf->GetDefaultBurstLength());
254 
255  uint32_t mostRobustWaveformId = 0;
256 
257  if (m_waveformConf->GetMostRobustWaveformId(mostRobustWaveformId,
258  m_waveformConf->GetDefaultBurstLength()))
259  {
260  m_mostRobustWaveform = m_waveformConf->GetWaveform(mostRobustWaveformId);
261  }
262  else
263  {
264  NS_FATAL_ERROR("Most robust waveform not found, error in waveform configuration ???");
265  }
266  break;
267  }
268 
271  if (frameConf->GetWaveformConf()->IsAcmEnabled())
272  {
273  m_burstLenghts = frameConf->GetWaveformConf()->GetSupportedBurstLengths();
274  }
275  else
276  {
277  m_burstLenghts.push_back(m_waveformConf->GetDefaultBurstLength());
278  }
279 
280  uint32_t mostRobustWaveformId = 0;
281 
282  if (m_waveformConf->GetMostRobustWaveformId(mostRobustWaveformId,
284  {
285  m_mostRobustWaveform = m_waveformConf->GetWaveform(mostRobustWaveformId);
286  }
287  else
288  {
289  NS_FATAL_ERROR("Most robust waveform not found, error in waveform configuration ???");
290  }
291  break;
292  }
293 
294  default:
295  NS_FATAL_ERROR("Not supported configuration type");
296  break;
297  }
298 
299  Reset();
300 }
301 
302 void
304 {
305  NS_LOG_FUNCTION(this);
306 
313 
314  m_utAllocs.clear();
315  m_rcAllocs.clear();
316 
317  m_allocationDenied = false;
318 }
319 
320 void
321 SatFrameAllocator::SelectCarriers(uint16_t& count, uint16_t offset)
322 {
323  NS_LOG_FUNCTION(this << count << offset);
324 
325  uint16_t total = count + offset;
326  if (total > m_frameConf->GetCarrierCount())
327  {
328  NS_FATAL_ERROR("SatFrameAllocator::SetCarrierCount: Amount of carriers in use is greater "
329  "than the amount of carriers in frame.");
330  }
331 
332  if (m_frameConf->IsSubdivided())
333  {
334  // Ensure that we get an even number of carriers on subdivided frames
335  if (total % 2)
336  ++count;
337  }
338  else
339  {
340  // Ensure that original frames uses their whole bandwidth
341  count = m_frameConf->GetCarrierCount() - offset;
342  }
343 
344  m_maxCarrierCount = count;
345  m_carriersOffset = offset;
346 
347  NS_LOG_INFO("Frame " << (uint32_t)m_frameId << " selected " << count
348  << " carriers from carrier ID " << offset);
349 }
350 
351 double
353 {
354  NS_LOG_FUNCTION(this << ccLevel);
355 
356  double load = NAN;
357 
358  switch (ccLevel)
359  {
360  case CC_LEVEL_CRA:
362  break;
363 
366  break;
367 
368  case CC_LEVEL_CRA_RBDC:
370  break;
371 
375  break;
376 
377  default:
378  NS_FATAL_ERROR("Not supported CC level!!!");
379  break;
380  }
381 
382  return load;
383 }
384 
385 bool
386 SatFrameAllocator::GetBestWaveform(double cno, uint32_t& waveFormId, double& cnoThreshold) const
387 {
388  NS_LOG_FUNCTION(this << cno << waveFormId);
389 
390  bool cnoSupported = false;
391 
392  switch (m_configType)
393  {
395  cnoSupported = true;
396  waveFormId = m_waveformConf->GetDefaultWaveformId();
397  break;
398 
400  cnoSupported =
401  m_waveformConf->GetBestWaveformId(cno,
402  m_frameConf->GetBtuConf()->GetSymbolRateInBauds(),
403  waveFormId,
404  cnoThreshold,
405  m_waveformConf->GetDefaultBurstLength());
406  break;
407 
410  cnoSupported =
411  m_waveformConf->GetBestWaveformId(cno,
412  m_frameConf->GetBtuConf()->GetSymbolRateInBauds(),
413  waveFormId,
414  cnoThreshold,
416  break;
417 
418  default:
419  NS_FATAL_ERROR("Not supported configuration type");
420  break;
421  }
422 
423  return cnoSupported;
424 }
425 
426 bool
427 SatFrameAllocator::Allocate(CcLevel_t ccLevel, SatFrameAllocReq* allocReq, uint32_t waveFormId)
428 {
429  NS_LOG_FUNCTION(this << ccLevel << waveFormId);
430 
431  bool allocated = false;
432 
433  if (!m_allocationDenied)
434  {
435  // convert request in bytes to symbols based on given waveform
437  SatFrameAllocInfo(allocReq->m_reqPerRc,
438  m_waveformConf->GetWaveform(waveFormId),
439  allocReq->m_generateCtrlSlot,
440  m_mostRobustWaveform->GetBurstLengthInSymbols());
441  if (reqInSymbols.m_minRbdcSymbols > reqInSymbols.m_rbdcSymbols)
442  {
443  NS_FATAL_ERROR("Min RBDC bytes is greater than RBDC bytes!!!");
444  }
445 
446  switch (ccLevel)
447  {
448  case CC_LEVEL_CRA: {
449  m_preAllocatedCraSymbols += reqInSymbols.m_craSymbols;
450 
451  if ((reqInSymbols.m_craSymbols) <= m_maxSymbolsPerCarrier)
452  {
453  double symbolsLeftInCarrier = m_maxSymbolsPerCarrier - reqInSymbols.m_craSymbols;
454 
456  std::min<double>(reqInSymbols.m_minRbdcSymbols, symbolsLeftInCarrier);
458  std::min<double>(reqInSymbols.m_rbdcSymbols, symbolsLeftInCarrier);
459 
461  (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols))
462  {
463  double vbdcSymbolsInCarrier = m_maxSymbolsPerCarrier -
464  reqInSymbols.m_craSymbols -
465  reqInSymbols.m_rbdcSymbols;
467  std::min<double>(reqInSymbols.m_vbdcSymbols, vbdcSymbolsInCarrier);
468  }
469 
470  allocated = true;
471  }
472  else
473  {
474  NS_FATAL_ERROR("CRA symbols exceeds carrier limit!!!");
475  }
476 
477  allocated = true;
478  }
479  break;
480 
481  case CC_LEVEL_CRA_MIN_RBDC: {
482  double symbolsLeftInFrame =
484  double symbolsToUse = std::min<double>(symbolsLeftInFrame, m_maxSymbolsPerCarrier);
485 
486  if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_minRbdcSymbols))
487  {
488  m_preAllocatedCraSymbols += reqInSymbols.m_craSymbols;
490 
491  double symbolsLeftInCarrier = m_maxSymbolsPerCarrier - reqInSymbols.m_craSymbols -
492  reqInSymbols.m_minRbdcSymbols;
493 
495  std::min<double>(reqInSymbols.m_rbdcSymbols,
496  symbolsLeftInCarrier + reqInSymbols.m_minRbdcSymbols);
497 
498  if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols))
499  {
500  double vbdcSymbolsInCarrier = m_maxSymbolsPerCarrier -
501  reqInSymbols.m_craSymbols -
502  reqInSymbols.m_rbdcSymbols;
504  std::min<double>(reqInSymbols.m_vbdcSymbols, vbdcSymbolsInCarrier);
505  }
506 
507  allocated = true;
508  }
509  }
510  break;
511 
512  case CC_LEVEL_CRA_RBDC: {
513  double symbolsLeftInFrame =
515  double symbolsToUse = std::min<double>(symbolsLeftInFrame, m_maxSymbolsPerCarrier);
516 
517  if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols))
518  {
519  double symbolsLeftInCarrier =
520  m_maxSymbolsPerCarrier - reqInSymbols.m_craSymbols - reqInSymbols.m_rbdcSymbols;
521 
522  m_preAllocatedCraSymbols += reqInSymbols.m_craSymbols;
526  std::min<double>(reqInSymbols.m_vbdcSymbols, symbolsLeftInCarrier);
527 
528  allocated = true;
529  }
530  }
531  break;
532 
533  case CC_LEVEL_CRA_RBDC_VBDC: {
534  double symbolsLeftInFrame = m_totalSymbolsInFrame - m_preAllocatedCraSymbols -
536  double symbolsToUse = std::min<double>(symbolsLeftInFrame, m_maxSymbolsPerCarrier);
537 
538  if (symbolsToUse >= (reqInSymbols.m_craSymbols + reqInSymbols.m_rbdcSymbols +
539  reqInSymbols.m_vbdcSymbols))
540  {
541  m_preAllocatedCraSymbols += reqInSymbols.m_craSymbols;
545 
546  allocated = true;
547  }
548  }
549  break;
550 
551  default:
552  NS_FATAL_ERROR("Not supported CC level!!!");
553  break;
554  }
555 
556  if (allocated)
557  {
558  // update request according to carrier limit and store allocation request
559  UpdateAndStoreAllocReq(allocReq->m_address, allocReq->m_cno, reqInSymbols);
560  }
561  }
562 
563  return allocated;
564 }
565 
566 void
567 SatFrameAllocator::PreAllocateSymbols(double targetLoad, bool fcaEnabled)
568 {
569  NS_LOG_FUNCTION(this << targetLoad << fcaEnabled);
570 
571  if (!m_allocationDenied)
572  {
573  if ((targetLoad >= 0) && (targetLoad <= 1))
574  {
576  ShareSymbols(fcaEnabled);
577  }
578  else
579  {
580  NS_FATAL_ERROR("target load must be between 0 and 1.");
581  }
582 
583  m_allocationDenied = true;
584  }
585 }
586 
587 void
589  uint32_t maxSizeInBytes,
590  UtAllocInfoContainer_t& utAllocContainer,
591  bool rcBasedAllocationEnabled,
592  TracedCallback<uint32_t> waveformTrace,
593  TracedCallback<uint32_t, uint32_t> utLoadTrace,
594  TracedCallback<uint32_t, double> loadTrace)
595 {
596  NS_LOG_FUNCTION(this);
597 
598  // variable to watch limit for maximum allowed time slot
599  uint32_t timeslotCount = 0;
600 
601  if (tbtpContainer.empty())
602  {
603  NS_FATAL_ERROR("TBTP container must contain at least one message.");
604  }
605 
606  Ptr<SatTbtpMessage> tbtpToFill = tbtpContainer.back();
607 
608  // sort UTs
609  std::vector<Address> uts = SortUts();
610 
611  // sort available carriers in the frame
612  std::vector<uint16_t> carriers = SortCarriers();
613 
614  // go through all allocated UT until there is available carriers
615 
616  std::vector<uint16_t>::const_iterator currentCarrier = carriers.begin();
617  int64_t carrierSymbolsToUse = m_maxSymbolsPerCarrier;
618  uint32_t utCount = 0;
619  uint32_t symbolsAllocated = 0;
620 
621  for (std::vector<Address>::iterator it = uts.begin();
622  (it != uts.end()) && (currentCarrier != carriers.end());
623  it++)
624  {
625  // check before the first slot addition that frame info fit in TBTP in addition to time slot
626  if ((tbtpToFill->GetSizeInBytes() + tbtpToFill->GetTimeSlotInfoSizeInBytes() +
627  tbtpToFill->GetFrameInfoSize()) > maxSizeInBytes)
628  {
629  tbtpToFill = CreateNewTbtp(tbtpContainer);
630  }
631 
632  // sort RCs in UT using random method.
633  std::vector<uint32_t> rcIndices = SortUtRcs(*it);
634  std::vector<uint32_t>::const_iterator currentRcIndex = rcIndices.begin();
635 
636  int64_t rcSymbolsLeft =
637  m_utAllocs[*it].m_allocation.m_allocInfoPerRc[*currentRcIndex].GetTotalSymbols();
638 
639  // generate slots here
640 
641  int64_t utSymbolsLeft = m_utAllocs[*it].m_allocation.GetTotalSymbols();
642  int64_t utSymbolsToUse = m_maxSymbolsPerCarrier;
643 
644  bool waveformIdTraced = false;
645 
646  while (utSymbolsLeft > 0)
647  {
648  Ptr<SatTimeSlotConf> timeSlot = NULL;
649 
650  // try to first create Control slot if present in request and is not already created
651  // otherwise create TRC slot
652  if ((currentRcIndex == rcIndices.begin()) &&
653  m_utAllocs[*it].m_request.m_ctrlSlotPresent &&
654  (m_utAllocs[*it].m_allocation.m_ctrlSlotPresent == false))
655  {
656  timeSlot = CreateCtrlTimeSlot(*currentCarrier,
657  utSymbolsToUse,
658  carrierSymbolsToUse,
659  utSymbolsLeft,
660  rcSymbolsLeft,
661  rcBasedAllocationEnabled);
662 
663  // if control slot creation fails try to allocate TRC slot,
664  // this i because control and TRC slot may use different waveforms (different amount
665  // of symbols)
666  if (timeSlot)
667  {
668  m_utAllocs[*it].m_allocation.m_ctrlSlotPresent = true;
669  }
670  else
671  {
672  timeSlot = CreateTimeSlot(*currentCarrier,
673  utSymbolsToUse,
674  carrierSymbolsToUse,
675  utSymbolsLeft,
676  rcSymbolsLeft,
677  m_utAllocs[*it].m_cno,
678  rcBasedAllocationEnabled);
679  }
680  }
681  else
682  {
683  timeSlot = CreateTimeSlot(*currentCarrier,
684  utSymbolsToUse,
685  carrierSymbolsToUse,
686  utSymbolsLeft,
687  rcSymbolsLeft,
688  m_utAllocs[*it].m_cno,
689  rcBasedAllocationEnabled);
690  }
691 
692  // if creation succeeded, add slot to TBTP and update allocation info container
693  if (timeSlot)
694  {
695  // trace first used wave form per UT
696  if (!waveformIdTraced)
697  {
698  waveformIdTraced = true;
699  waveformTrace(timeSlot->GetWaveFormId());
700  utCount++;
701  }
702 
703  if ((tbtpToFill->GetSizeInBytes() + tbtpToFill->GetTimeSlotInfoSizeInBytes()) >
704  maxSizeInBytes)
705  {
706  tbtpToFill = CreateNewTbtp(tbtpContainer);
707  }
708 
709  timeSlot->SetRcIndex(*currentRcIndex);
710 
711  if (timeslotCount > SatFrameConf::m_maxTimeSlotCount)
712  {
713  // NS_FATAL_ERROR ("Maximum limit for time slots in a frame reached. Check frame
714  // configuration!!!");
715  }
716 
717  tbtpToFill->SetDaTimeslot(Mac48Address::ConvertFrom(*it), m_frameId, timeSlot);
718  timeslotCount++;
719 
720  // store needed information to UT allocation container
721  Ptr<SatWaveform> waveform = m_waveformConf->GetWaveform(timeSlot->GetWaveFormId());
722 
723  UtAllocInfoContainer_t::iterator utAlloc = GetUtAllocItem(utAllocContainer, *it);
724  utAlloc->second.first.at(*currentRcIndex) += waveform->GetPayloadInBytes();
725  utAlloc->second.second |= m_utAllocs[*it].m_allocation.m_ctrlSlotPresent;
726 
727  symbolsAllocated += waveform->GetBurstLengthInSymbols();
728  }
729 
730  // select new carrier to use
731  if (carrierSymbolsToUse <= 0)
732  {
733  carrierSymbolsToUse = m_maxSymbolsPerCarrier;
734  currentCarrier++;
735 
736  if (currentCarrier == carriers.end())
737  {
738  // stop if no more carriers left
739  utSymbolsLeft = 0;
740  }
741  }
742 
743  // select new RC to use
744  if (rcSymbolsLeft <= 0)
745  {
746  currentRcIndex++;
747 
748  if (currentRcIndex == rcIndices.end())
749  {
750  // stop if last RC handled
751  utSymbolsLeft = 0;
752  }
753  else
754  {
755  rcSymbolsLeft = m_utAllocs[*it]
756  .m_allocation.m_allocInfoPerRc[*currentRcIndex]
757  .GetTotalSymbols();
758  }
759  }
760 
761  // carrier limit for UT reached, so we need to stop because time slot cannot generated
762  // anymore
763  if ((utSymbolsToUse <= 0) || (currentCarrier == carriers.end()))
764  {
765  utSymbolsLeft = 0;
766  }
767  }
768 
769  m_utAllocs[*it].m_allocation.m_ctrlSlotPresent = false;
770  }
771 
772  // trace out frame UT load
773  utLoadTrace((uint32_t)m_frameId, utCount);
774 
775  // trace out frame load
776  loadTrace((uint32_t)m_frameId, symbolsAllocated / m_totalSymbolsInFrame);
777 }
778 
779 void
781 {
782  NS_LOG_FUNCTION(this);
783 
786  {
788 
789  if (fcaEnabled)
790  {
791  // share additional VBDC resources
792 
793  // calculate how many symbols left over
794  double vbdcSymbolsLeft = m_availableSymbolsInFrame - m_preAllocatedCraSymbols -
796 
797  m_preAllocatedVdbcSymbols += vbdcSymbolsLeft;
798 
799  // sort RCs according to VBDC requests
801  m_rcAllocs.sort(vbdcCompare);
802 
803  uint32_t rcAllocsLeft = m_rcAllocs.size();
804 
805  // do share by adding a share to all RC/VBDC allocations
806  for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
807  it != m_rcAllocs.end() && (vbdcSymbolsLeft > 0);
808  it++)
809  {
810  double freeUtSymbols =
811  std::max<double>(0.0,
813  m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
814  double symbolsToAdd =
815  std::min<double>(freeUtSymbols, (vbdcSymbolsLeft / rcAllocsLeft));
816 
817  // only share symbols to RCs requested RBDC or VBDC
818  if ((m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_rbdcSymbols >
819  0) ||
820  (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_vbdcSymbols >
821  0))
822  {
823  m_utAllocs.at(it->first)
824  .m_allocation.m_allocInfoPerRc[it->second]
825  .m_vbdcSymbols += symbolsToAdd;
826  m_utAllocs.at(it->first).m_allocation.m_vbdcSymbols += symbolsToAdd;
827  vbdcSymbolsLeft -= symbolsToAdd;
828  }
829 
830  rcAllocsLeft--;
831  }
832  }
833  }
835  {
836  // share VBDC resources
837 
838  // calculate how many symbols left over
839  double vbdcSymbolsLeft =
841  m_preAllocatedVdbcSymbols = vbdcSymbolsLeft;
842 
843  // sort RCs according to VBDC requests
845  m_rcAllocs.sort(vbdcCompare);
846 
848 
849  uint32_t rcAllocsLeft = m_rcAllocs.size();
850 
851  // do share by setting a share to all RC/VBDC allocations
852  for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
853  it != m_rcAllocs.end() && (vbdcSymbolsLeft > 0);
854  it++)
855  {
856  double freeUtSymbols = std::max<double>(
857  0.0,
858  m_maxSymbolsPerCarrier - m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
859  double symbolsToAdd = std::min<double>(freeUtSymbols, (vbdcSymbolsLeft / rcAllocsLeft));
860 
861  // only share symbols to RCs requested VBDC
862  if (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_vbdcSymbols > 0)
863  {
864  m_utAllocs.at(it->first).m_allocation.m_allocInfoPerRc[it->second].m_vbdcSymbols =
865  symbolsToAdd;
866  m_utAllocs.at(it->first).m_allocation.m_vbdcSymbols += symbolsToAdd;
867  vbdcSymbolsLeft -= symbolsToAdd;
868  }
869 
870  rcAllocsLeft--;
871  }
872  }
874  {
875  // share RBDC resources
876 
877  // calculate how many symbols left over
878  double rbdcSymbolsLeft =
880 
882  m_preAllocatedRdbcSymbols = rbdcSymbolsLeft;
883 
884  // sort RCs according to RBDC requests
886  m_rcAllocs.sort(rbdcCompare);
887 
889 
890  uint32_t rcAllocsLeft = m_rcAllocs.size();
891 
892  // do share by setting a share to all RC/RBDC allocations
893  for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
894  it != m_rcAllocs.end() && (rbdcSymbolsLeft > 0);
895  it++)
896  {
897  double freeUtSymbols = std::max<double>(
898  0.0,
899  m_maxSymbolsPerCarrier - m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
900  double symbolsToAdd = std::min<double>(freeUtSymbols, (rbdcSymbolsLeft / rcAllocsLeft));
901 
902  // only share symbols to RCs requested RBDC
903  if (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_rbdcSymbols > 0)
904  {
905  m_utAllocs.at(it->first).m_allocation.m_allocInfoPerRc[it->second].m_rbdcSymbols =
906  symbolsToAdd + m_utAllocs.at(it->first)
907  .m_allocation.m_allocInfoPerRc[it->second]
908  .m_minRbdcSymbols;
909  m_utAllocs.at(it->first).m_allocation.m_rbdcSymbols +=
910  symbolsToAdd + m_utAllocs.at(it->first)
911  .m_allocation.m_allocInfoPerRc[it->second]
912  .m_minRbdcSymbols;
913  rbdcSymbolsLeft -= symbolsToAdd;
914  }
915 
916  rcAllocsLeft--;
917  }
918  }
920  {
921  // share minimum RBDC resources
922 
923  // calculate how many symbols left over
924  double minRbdcSymbolsLeft = m_availableSymbolsInFrame - m_preAllocatedCraSymbols;
925 
927  m_preAllocatedRdbcSymbols = minRbdcSymbolsLeft;
928  m_preAllocatedMinRdbcSymbols = minRbdcSymbolsLeft;
929 
930  // sort RCs according to RBDC requests
932  m_rcAllocs.sort(minRbdcCompare);
933 
935 
936  uint32_t rcAllocsLeft = m_rcAllocs.size();
937 
938  // do share by setting a share to all RC/Minimum RBDC and RC/RBDC allocations
939  for (RcAllocContainer_t::iterator it = m_rcAllocs.begin();
940  it != m_rcAllocs.end() && (minRbdcSymbolsLeft > 0);
941  it++)
942  {
943  double freeUtSymbols = std::max<double>(
944  0.0,
945  m_maxSymbolsPerCarrier - m_utAllocs.at(it->first).m_allocation.GetTotalSymbols());
946  double symbolsToAdd =
947  std::min<double>(freeUtSymbols, (minRbdcSymbolsLeft / rcAllocsLeft));
948 
949  // only share symbols to RCs requested RBDC
950  if (m_utAllocs.at(it->first).m_request.m_allocInfoPerRc[it->second].m_rbdcSymbols > 0)
951  {
952  m_utAllocs.at(it->first)
953  .m_allocation.m_allocInfoPerRc[it->second]
954  .m_minRbdcSymbols = symbolsToAdd;
955  m_utAllocs.at(it->first).m_allocation.m_minRbdcSymbols += symbolsToAdd;
956 
957  m_utAllocs.at(it->first).m_allocation.m_allocInfoPerRc[it->second].m_rbdcSymbols =
958  symbolsToAdd;
959  m_utAllocs.at(it->first).m_allocation.m_rbdcSymbols += symbolsToAdd;
960 
961  minRbdcSymbolsLeft -= symbolsToAdd;
962  }
963 
964  rcAllocsLeft--;
965  }
966  }
967  else
968  {
969  NS_FATAL_ERROR("CRAs don't fit to frame CAC or configuration error???");
970  }
971 }
972 
973 Ptr<SatTimeSlotConf>
975  int64_t& utSymbolsToUse,
976  int64_t& carrierSymbolsToUse,
977  int64_t& utSymbolsLeft,
978  int64_t& rcSymbolsLeft,
979  double cno,
980  bool rcBasedAllocationEnabled)
981 {
982  NS_LOG_FUNCTION(this << carrierId << cno << rcBasedAllocationEnabled);
983 
984  Ptr<SatTimeSlotConf> timeSlotConf = NULL;
985  int64_t symbolsToUse = std::min<int64_t>(carrierSymbolsToUse, utSymbolsToUse);
986  uint32_t waveformId = 0;
987  int64_t timeSlotSymbols = 0;
988 
989  if (rcBasedAllocationEnabled || (symbolsToUse + m_guardTimeSymbols < utSymbolsLeft))
990  {
991  timeSlotSymbols =
992  GetOptimalBurtsLengthInSymbols(symbolsToUse, rcSymbolsLeft, cno, waveformId);
993  }
994  else
995  {
996  timeSlotSymbols =
997  GetOptimalBurtsLengthInSymbols(symbolsToUse, utSymbolsLeft, cno, waveformId);
998  }
999 
1000  if (timeSlotSymbols == 0)
1001  {
1002  if (rcSymbolsLeft > 0)
1003  {
1004  if (carrierSymbolsToUse + m_guardTimeSymbols <= utSymbolsToUse)
1005  {
1006  carrierSymbolsToUse -= symbolsToUse;
1007  carrierSymbolsToUse -= m_guardTimeSymbols;
1008  }
1009 
1010  utSymbolsToUse -= symbolsToUse;
1011  utSymbolsToUse -= m_guardTimeSymbols;
1012  }
1013  }
1014  else if (rcSymbolsLeft > 0)
1015  {
1016  switch (m_configType)
1017  {
1019  uint16_t index = (m_maxSymbolsPerCarrier - carrierSymbolsToUse) / timeSlotSymbols;
1020  timeSlotConf = m_frameConf->GetTimeSlotConf(carrierId, index);
1021  }
1022  break;
1023 
1027  Time startTime =
1028  Seconds((m_maxSymbolsPerCarrier - carrierSymbolsToUse + m_guardTimeSymbols / 2) /
1029  m_frameConf->GetBtuConf()->GetSymbolRateInBauds());
1030  timeSlotConf = Create<SatTimeSlotConf>(startTime,
1031  waveformId,
1032  carrierId,
1034  }
1035  break;
1036 
1037  default:
1038  NS_FATAL_ERROR("Not supported configuration type!!!");
1039  break;
1040  }
1041 
1042  if (timeSlotConf)
1043  {
1044  carrierSymbolsToUse -= timeSlotSymbols;
1045  utSymbolsToUse -= timeSlotSymbols;
1046 
1047  carrierSymbolsToUse -= m_guardTimeSymbols;
1048  utSymbolsToUse -= m_guardTimeSymbols;
1049 
1050  if (rcBasedAllocationEnabled)
1051  {
1052  utSymbolsLeft -= std::min(rcSymbolsLeft, timeSlotSymbols);
1053  }
1054  else
1055  {
1056  utSymbolsLeft -= timeSlotSymbols;
1057  }
1058 
1059  rcSymbolsLeft -= timeSlotSymbols;
1060  }
1061  }
1062 
1063  return timeSlotConf;
1064 }
1065 
1066 Ptr<SatTimeSlotConf>
1068  int64_t& utSymbolsToUse,
1069  int64_t& carrierSymbolsToUse,
1070  int64_t& utSymbolsLeft,
1071  int64_t& rcSymbolsLeft,
1072  bool rcBasedAllocationEnabled)
1073 {
1074  NS_LOG_FUNCTION(this);
1075 
1076  Ptr<SatTimeSlotConf> timeSlotConf = NULL;
1077  int64_t symbolsToUse = std::min<int64_t>(carrierSymbolsToUse, utSymbolsToUse);
1078 
1079  int64_t timeSlotSymbols = m_mostRobustWaveform->GetBurstLengthInSymbols();
1080 
1081  if (timeSlotSymbols + m_guardTimeSymbols <= symbolsToUse)
1082  {
1083  Time startTime =
1084  Seconds((m_maxSymbolsPerCarrier - carrierSymbolsToUse + m_guardTimeSymbols / 2) /
1085  m_frameConf->GetBtuConf()->GetSymbolRateInBauds());
1086  timeSlotConf = Create<SatTimeSlotConf>(startTime,
1087  m_mostRobustWaveform->GetWaveformId(),
1088  carrierId,
1090 
1091  carrierSymbolsToUse -= timeSlotSymbols;
1092  utSymbolsToUse -= timeSlotSymbols;
1093 
1094  carrierSymbolsToUse -= m_guardTimeSymbols;
1095  utSymbolsToUse -= m_guardTimeSymbols;
1096 
1097  if (rcBasedAllocationEnabled)
1098  {
1099  utSymbolsLeft -= std::min(rcSymbolsLeft, timeSlotSymbols);
1100  }
1101  else
1102  {
1103  utSymbolsLeft -= timeSlotSymbols;
1104  }
1105 
1106  rcSymbolsLeft -= timeSlotSymbols;
1107  }
1108 
1109  return timeSlotConf;
1110 }
1111 
1112 uint32_t
1114  int64_t symbolsLeft,
1115  double cno,
1116  uint32_t& waveformId)
1117 {
1118  NS_LOG_FUNCTION(this);
1119 
1120  uint32_t burstLength = 0;
1121 
1122  for (SatWaveformConf::BurstLengthContainer_t::const_iterator it = m_burstLenghts.begin();
1123  it != m_burstLenghts.end();
1124  it++)
1125  {
1126  uint32_t newLength = *it;
1127  uint32_t selectedWaveformId = 0;
1128 
1130  {
1131  waveformId = m_waveformConf->GetDefaultWaveformId();
1132  }
1133  else
1134  {
1135  double cnoThreshold = std::numeric_limits<double>::quiet_NaN();
1136  bool waveformFound =
1137  m_waveformConf->GetBestWaveformId(cno,
1138  m_frameConf->GetBtuConf()->GetSymbolRateInBauds(),
1139  selectedWaveformId,
1140  cnoThreshold,
1141  *it);
1142 
1143  if (waveformFound)
1144  {
1145  newLength =
1146  m_waveformConf->GetWaveform(selectedWaveformId)->GetBurstLengthInSymbols();
1147  }
1148  }
1149 
1150  if (symbolsToUse >= newLength)
1151  {
1152  if (burstLength < symbolsLeft)
1153  {
1154  if (burstLength < newLength)
1155  {
1156  burstLength = newLength;
1157  waveformId = selectedWaveformId;
1158  }
1159  }
1160  else if ((newLength - symbolsLeft) < (burstLength - symbolsLeft))
1161  {
1162  burstLength = newLength;
1163  waveformId = selectedWaveformId;
1164  }
1165  }
1166  }
1167 
1168  return burstLength;
1169 }
1170 
1171 void
1173 {
1174  NS_LOG_FUNCTION(this);
1175 
1176  for (UtAllocContainer_t::iterator it = m_utAllocs.begin(); it != m_utAllocs.end(); it++)
1177  {
1178  // accept first UT level total requests by updating allocation counters
1179  switch (ccLevel)
1180  {
1181  case CC_LEVEL_CRA:
1182  it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1183  it->second.m_allocation.m_minRbdcSymbols = 0.0;
1184  it->second.m_allocation.m_rbdcSymbols = 0.0;
1185  it->second.m_allocation.m_vbdcSymbols = 0.0;
1186  break;
1187 
1188  case CC_LEVEL_CRA_MIN_RBDC:
1189  it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1190  it->second.m_allocation.m_minRbdcSymbols = it->second.m_request.m_minRbdcSymbols;
1191  it->second.m_allocation.m_rbdcSymbols = 0.0;
1192  it->second.m_allocation.m_vbdcSymbols = 0.0;
1193  break;
1194 
1195  case CC_LEVEL_CRA_RBDC:
1196  it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1197  it->second.m_allocation.m_minRbdcSymbols = it->second.m_request.m_minRbdcSymbols;
1198  it->second.m_allocation.m_rbdcSymbols = it->second.m_request.m_rbdcSymbols;
1199  it->second.m_allocation.m_vbdcSymbols = 0.0;
1200  break;
1201 
1203  it->second.m_allocation.m_craSymbols = it->second.m_request.m_craSymbols;
1204  it->second.m_allocation.m_minRbdcSymbols = it->second.m_request.m_minRbdcSymbols;
1205  it->second.m_allocation.m_rbdcSymbols = it->second.m_request.m_rbdcSymbols;
1206  it->second.m_allocation.m_vbdcSymbols = it->second.m_request.m_vbdcSymbols;
1207  break;
1208 
1209  default:
1210  NS_FATAL_ERROR("Not supported CC level!!!");
1211  break;
1212  }
1213 
1214  // accept first RC specific requests by updating allocation counters
1215  for (uint32_t i = 0; i < it->second.m_request.m_allocInfoPerRc.size(); i++)
1216  {
1217  switch (ccLevel)
1218  {
1219  case CC_LEVEL_CRA:
1220  it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1221  it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1222  it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols = 0.0;
1223  it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols = 0.0;
1224  it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols = 0.0;
1225  break;
1226 
1227  case CC_LEVEL_CRA_MIN_RBDC:
1228  it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1229  it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1230  it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols =
1231  it->second.m_request.m_allocInfoPerRc[i].m_minRbdcSymbols;
1232  it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols = 0.0;
1233  it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols = 0.0;
1234  break;
1235 
1236  case CC_LEVEL_CRA_RBDC:
1237  it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1238  it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1239  it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols =
1240  it->second.m_request.m_allocInfoPerRc[i].m_minRbdcSymbols;
1241  it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols =
1242  it->second.m_request.m_allocInfoPerRc[i].m_rbdcSymbols;
1243  it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols = 0.0;
1244  break;
1245 
1247  it->second.m_allocation.m_allocInfoPerRc[i].m_craSymbols =
1248  it->second.m_request.m_allocInfoPerRc[i].m_craSymbols;
1249  it->second.m_allocation.m_allocInfoPerRc[i].m_minRbdcSymbols =
1250  it->second.m_request.m_allocInfoPerRc[i].m_minRbdcSymbols;
1251  it->second.m_allocation.m_allocInfoPerRc[i].m_rbdcSymbols =
1252  it->second.m_request.m_allocInfoPerRc[i].m_rbdcSymbols;
1253  it->second.m_allocation.m_allocInfoPerRc[i].m_vbdcSymbols =
1254  it->second.m_request.m_allocInfoPerRc[i].m_vbdcSymbols;
1255  break;
1256 
1257  default:
1258  NS_FATAL_ERROR("Not supported CC level!!!");
1259  break;
1260  }
1261  }
1262  }
1263 }
1264 
1265 void
1267 {
1268  NS_LOG_FUNCTION(this);
1269 
1270  if ((m_maxSymbolsPerCarrier - req.m_craSymbols) < 0)
1271  {
1272  NS_FATAL_ERROR("CRA does not fit in to carrier. Error in configuration or CAC?");
1273  }
1274  else if ((m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_minRbdcSymbols) < 0)
1275  {
1276  double minRbdcSymbolsLeft = m_maxSymbolsPerCarrier - req.m_craSymbols;
1277 
1278  // share symbols left between minimum RBDC requests in RCs in relation of the request
1279  for (SatFrameAllocInfoItemContainer_t::iterator it = req.m_allocInfoPerRc.begin();
1280  it != req.m_allocInfoPerRc.end();
1281  it++)
1282  {
1283  it->m_vbdcSymbols = 0.0;
1284  it->m_minRbdcSymbols =
1285  (it->m_minRbdcSymbols / req.m_minRbdcSymbols) * minRbdcSymbolsLeft;
1286  it->m_rbdcSymbols = it->m_minRbdcSymbols;
1287  }
1288 
1289  // update UT total request
1290  req.m_minRbdcSymbols = minRbdcSymbolsLeft;
1291  req.m_rbdcSymbols = minRbdcSymbolsLeft;
1292  req.m_vbdcSymbols = 0;
1293  }
1294  else if ((m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_rbdcSymbols) < 0)
1295  {
1296  double rbdcSymbolsLeft = m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_minRbdcSymbols;
1297  double rbdcReqOverMinRbdc = req.m_rbdcSymbols - req.m_minRbdcSymbols;
1298 
1299  if (rbdcReqOverMinRbdc > 0)
1300  {
1301  // share symbols left over minimum RBDC between RBDC requests in RCs in relation of the
1302  // request
1303  for (SatFrameAllocInfoItemContainer_t::iterator it = req.m_allocInfoPerRc.begin();
1304  it != req.m_allocInfoPerRc.end();
1305  it++)
1306  {
1307  it->m_vbdcSymbols = 0.0;
1308  double rcRbdcReqOverMinRbdc =
1309  std::max(0.0, (it->m_rbdcSymbols - it->m_minRbdcSymbols));
1310 
1311  it->m_rbdcSymbols =
1312  ((rcRbdcReqOverMinRbdc / rbdcReqOverMinRbdc) * rbdcSymbolsLeft) +
1313  it->m_minRbdcSymbols;
1314  }
1315  }
1316 
1317  // update UT total request
1318  req.m_rbdcSymbols = rbdcSymbolsLeft + req.m_minRbdcSymbols;
1319  req.m_vbdcSymbols = 0;
1320  }
1321  else if ((m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_rbdcSymbols - req.m_vbdcSymbols) <
1322  0)
1323  {
1324  double vbdcSymbolsLeft = m_maxSymbolsPerCarrier - req.m_craSymbols - req.m_rbdcSymbols;
1325 
1326  // share symbols left over RBDC between VBDC requests in RCs in relation of the request
1327  for (SatFrameAllocInfoItemContainer_t::iterator it = req.m_allocInfoPerRc.begin();
1328  it != req.m_allocInfoPerRc.end();
1329  it++)
1330  {
1331  it->m_vbdcSymbols = (it->m_vbdcSymbols / req.m_vbdcSymbols) * vbdcSymbolsLeft;
1332  }
1333 
1334  req.m_vbdcSymbols = vbdcSymbolsLeft;
1335  }
1336 
1337  // add request and empty allocation info container
1338  UtAllocItem_t utAlloc;
1339  utAlloc.m_request = req;
1340  utAlloc.m_allocation = SatFrameAllocInfo(req.m_allocInfoPerRc.size());
1341  utAlloc.m_cno = cno;
1342 
1343  for (uint8_t i = 0; i < req.m_allocInfoPerRc.size(); i++)
1344  {
1345  RcAllocItem_t rcAlloc = std::make_pair(address, i);
1346  m_rcAllocs.push_back(rcAlloc);
1347  }
1348 
1349  m_utAllocs.insert(std::make_pair(address, utAlloc));
1350 }
1351 
1352 std::vector<Address>
1354 {
1355  NS_LOG_FUNCTION(this);
1356 
1357  std::vector<Address> uts;
1358 
1359  for (UtAllocContainer_t::const_iterator it = m_utAllocs.begin(); it != m_utAllocs.end(); it++)
1360  {
1361  uts.push_back(it->first);
1362  }
1363 
1364  // sort UTs using random method.
1365  std::random_shuffle(uts.begin(), uts.end());
1366 
1367  return uts;
1368 }
1369 
1370 std::vector<uint16_t>
1372 {
1373  NS_LOG_FUNCTION(this);
1374 
1375  std::vector<uint16_t> carriers;
1376 
1377  for (uint16_t i = 0; i < m_maxCarrierCount; ++i)
1378  {
1379  carriers.push_back(i + m_carriersOffset);
1380  }
1381 
1382  // sort available carriers using random methods.
1383  std::random_shuffle(carriers.begin(), carriers.end());
1384 
1385  return carriers;
1386 }
1387 
1388 std::vector<uint32_t>
1390 {
1391  NS_LOG_FUNCTION(this);
1392  std::vector<uint32_t> rcIndices;
1393 
1394  for (uint32_t i = 0; i < m_utAllocs[ut].m_allocation.m_allocInfoPerRc.size(); i++)
1395  {
1396  rcIndices.push_back(i);
1397  }
1398 
1399  // we need to sort (or shuffle) only when there are at least two RCs in addition to RC 0,
1400  // because RC 0 is always first in the list
1401  if (rcIndices.size() > 2)
1402  {
1403  // sort RCs in UT using random method.
1404  std::random_shuffle(rcIndices.begin() + 1, rcIndices.end());
1405  }
1406 
1407  return rcIndices;
1408 }
1409 
1410 SatFrameAllocator::UtAllocInfoContainer_t::iterator
1412 {
1413  NS_LOG_FUNCTION(this);
1414  UtAllocInfoContainer_t::iterator utAlloc = allocContainer.find(ut);
1415 
1416  if (utAlloc == allocContainer.end())
1417  {
1418  UtAllocInfoItem_t rcAllocs;
1419 
1420  rcAllocs.second = false;
1421  rcAllocs.first =
1422  std::vector<uint32_t>(m_utAllocs[ut].m_allocation.m_allocInfoPerRc.size(), 0);
1423 
1424  std::pair<UtAllocInfoContainer_t::iterator, bool> result =
1425  allocContainer.insert(std::make_pair(ut, rcAllocs));
1426 
1427  if (result.second)
1428  {
1429  utAlloc = result.first;
1430  }
1431  else
1432  {
1433  NS_FATAL_ERROR("UT cannot be added to map!!!");
1434  }
1435  }
1436 
1437  return utAlloc;
1438 }
1439 
1440 Ptr<SatTbtpMessage>
1442 {
1443  NS_LOG_FUNCTION(this);
1444 
1445  if (tbtpContainer.empty())
1446  {
1447  NS_FATAL_ERROR("TBTP container is empty");
1448  }
1449 
1450  Ptr<SatTbtpMessage> newTbtp =
1451  CreateObject<SatTbtpMessage>(tbtpContainer.back()->GetSuperframeSeqId());
1452  newTbtp->SetSuperframeCounter(tbtpContainer.back()->GetSuperframeCounter());
1453 
1454  tbtpContainer.push_back(newTbtp);
1455 
1456  return newTbtp;
1457 }
1458 
1459 } // namespace ns3
CcReqCompare class for CC type comparisons.
CcReqType_t
Definition for different comparison types.
CcReqCompare(const UtAllocContainer_t &utAllocContainer, CcReqCompare::CcReqType_t ccReqType)
Construct CcReqCompare.
bool operator()(RcAllocItem_t rcAlloc1, RcAllocItem_t rcAlloc2)
Comparison operator to compare two RC allocations.
SatFrameAllocInfo is used to hold a frame's allocation info in symbols.
SatFrameAllocInfoItemContainer_t m_allocInfoPerRc
Information for the RCs.
SatFrameAllocInfo()
Construct empty SatFrameAllocInfo.
double GetTotalSymbols()
Get total symbols of the item.
SatFrameAllocInfoItem UpdateTotalCounts()
Update total count of SatFrameAllocInfo from RCs.
Allocation information item for requests and allocations [symbols] used internally by SatFrameAllocat...
SatFrameAllocReq is used to define frame allocation parameters when requesting allocation from SatFra...
void ShareSymbols(bool fcaEnabled)
Share symbols between all UTs and RCs allocated to the frame.
std::vector< uint16_t > SortCarriers()
Sort carriers belonging to this frame.
Ptr< SatWaveform > m_mostRobustWaveform
double GetCcLoad(CcLevel_t ccLevel)
Get frame load by requested CC.
SatSuperframeConf::ConfigType_t m_configType
void SelectCarriers(uint16_t &amount, uint16_t offset)
Set the amount of carriers used in this frame.
std::map< Address, UtAllocItem_t > UtAllocContainer_t
Map container for UT allocation items.
SatFrameAllocator::UtAllocInfoContainer_t::iterator GetUtAllocItem(UtAllocInfoContainer_t &allocContainer, Address ut)
Get UT allocation item from given container.
bool Allocate(CcLevel_t ccLevel, SatFrameAllocReq *allocReq, uint32_t waveformId)
Allocate symbols to this frame, if criteria are fulfilled.
bool GetBestWaveform(double cno, uint32_t &waveFormId, double &cnoThreshold) const
Get the best waveform supported by this allocator based on given C/N0.
SatWaveformConf::BurstLengthContainer_t m_burstLenghts
Ptr< SatWaveformConf > m_waveformConf
void Reset()
Reset frame allocator.
SatFrameAllocator()
Default constructor (not in used)
std::vector< Address > SortUts()
Sort UTs allocated to this frame.
std::pair< std::vector< uint32_t >, bool > UtAllocInfoItem_t
Pair used to store UT allocation information.
Ptr< SatTimeSlotConf > CreateTimeSlot(uint16_t carrierId, int64_t &utSymbolsToUse, int64_t &carrierSymbolsToUse, int64_t &utSymbolsLeft, int64_t &rcSymbolsLeft, double cno, bool rcBasedAllocationEnabled)
Create time slot according to configuration type.
void UpdateAndStoreAllocReq(Address address, double cno, SatFrameAllocInfo &req)
Update RC/CC requested according to carrier limit.
void AcceptRequests(CcLevel_t ccLevel)
Accept UT/RC requests of the frame according to given CC level.
std::vector< SatFrameAllocInfoItem > SatFrameAllocInfoItemContainer_t
Container to store SatFrameAllocInfoItem items.
std::vector< Ptr< SatTbtpMessage > > TbtpMsgContainer_t
Container to store generated TBTP messages.
uint32_t GetOptimalBurtsLengthInSymbols(int64_t symbolsToUse, int64_t symbolsLeft, double cno, uint32_t &waveformId)
Get optimal burst length in symbols.
Ptr< SatFrameAllocator > m_parent
Ptr< SatTimeSlotConf > CreateCtrlTimeSlot(uint16_t carrierId, int64_t &utSymbolsToUse, int64_t &carrierSymbolsToUse, int64_t &utSymbolsLeft, int64_t &rcSymbolsLeft, bool rcBasedAllocationEnabled)
Create control time slot.
Ptr< SatTbtpMessage > CreateNewTbtp(TbtpMsgContainer_t &tbtpContainer)
Creates new TBTP to given container with information of the last TBTP in container.
void GenerateTimeSlots(SatFrameAllocator::TbtpMsgContainer_t &tbtpContainer, uint32_t maxSizeInBytes, UtAllocInfoContainer_t &utAllocContainer, bool rcBasedAllocationEnabled, TracedCallback< uint32_t > waveformTrace, TracedCallback< uint32_t, uint32_t > utLoadTrace, TracedCallback< uint32_t, double > loadTrace)
Generate time slots for UT/RCs i.e.
@ CC_LEVEL_CRA_RBDC
CC level CRA + RBDC.
@ 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.
std::pair< Address, uint8_t > RcAllocItem_t
Pair used as RC allocation item.
void PreAllocateSymbols(double targetLoad, bool fcaEnabled)
Preallocate symbols for all UTs with RCs allocated to the frame.
std::vector< SatFrameAllocReqItem > SatFrameAllocReqItemContainer_t
Container to store SatFrameAllocReqItem items.
std::vector< uint32_t > SortUtRcs(Address ut)
Sort RCs in given UT.
static const uint16_t m_maxTimeSlotCount
This abstract class defines and implements interface of configuration for super frames.
ConfigType_t
Enum for configuration types.
@ CONFIG_TYPE_2
Configuration type 2.
@ CONFIG_TYPE_1
Configuration type 1.
@ CONFIG_TYPE_0
Configuration type 0.
@ CONFIG_TYPE_3
Configuration type 3.
@ SLOT_TYPE_TRC
Control or traffic slot.
static const uint32_t SHORT_BURST_LENGTH
Static variable defining short burst length.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
bool operator()(const Ptr< SatFrameAllocator > &a, const Ptr< SatFrameAllocator > &b) const