satellite-random-access-container.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  * Copyright (c) 2018 CNES
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Frans Laakso <frans.laakso@magister.fi>
20  * Author: Mathias Ettinger <mettinger@toulouse.viveris.fr>
21  */
22 
24 
25 #include <ns3/log.h>
26 
27 #include <map>
28 #include <set>
29 #include <utility>
30 
31 NS_LOG_COMPONENT_DEFINE("SatRandomAccess");
32 
33 namespace ns3
34 {
35 
36 NS_OBJECT_ENSURE_REGISTERED(SatRandomAccess);
37 
38 TypeId
40 {
41  static TypeId tid =
42  TypeId("ns3::SatRandomAccess").SetParent<Object>().AddConstructor<SatRandomAccess>();
43  return tid;
44 }
45 
47  : m_uniformRandomVariable(),
48  m_randomAccessModel(SatEnums::RA_MODEL_OFF),
49  m_randomAccessConf(),
50  m_numOfAllocationChannels(),
51 
53  m_crdsaNewData(true)
54 {
55  NS_LOG_FUNCTION(this);
56 
57  NS_FATAL_ERROR("SatRandomAccess::SatRandomAccess - Constructor not in use");
58 }
59 
60 SatRandomAccess::SatRandomAccess(Ptr<SatRandomAccessConf> randomAccessConf,
61  SatEnums::RandomAccessModel_t randomAccessModel)
62  : m_uniformRandomVariable(),
63  m_randomAccessModel(randomAccessModel),
64  m_randomAccessConf(randomAccessConf),
65  m_numOfAllocationChannels(randomAccessConf->GetNumOfAllocationChannelsConfigurations()),
66 
68  m_crdsaNewData(true)
69 {
70  NS_LOG_FUNCTION(this);
71 
72  m_uniformRandomVariable = CreateObject<UniformRandomVariable>();
73 
74  if (m_randomAccessConf == nullptr)
75  {
76  NS_FATAL_ERROR("SatRandomAccess::SatRandomAccess - Configuration object is NULL");
77  }
78 
79  SetRandomAccessModel(randomAccessModel);
80 }
81 
83 {
84  NS_LOG_FUNCTION(this);
85 
86  m_uniformRandomVariable = nullptr;
87  m_randomAccessConf = nullptr;
88 
89  if (!m_isDamaAvailableCb.IsNull())
90  {
91  m_isDamaAvailableCb.Nullify();
92  }
93 
94  if (!m_areBuffersEmptyCb.IsNull())
95  {
96  m_areBuffersEmptyCb.Nullify();
97  }
98 }
99 
100 void
102 {
103  NS_LOG_FUNCTION(this);
104 
106  m_randomAccessConf = NULL;
107 
108  if (!m_isDamaAvailableCb.IsNull())
109  {
110  m_isDamaAvailableCb.Nullify();
111  }
112 
113  if (!m_areBuffersEmptyCb.IsNull())
114  {
115  m_areBuffersEmptyCb.Nullify();
116  }
117 }
118 
122 
123 void
125 {
126  NS_LOG_FUNCTION(this << SatEnums::GetRandomAccessModelName(randomAccessModel));
127 
128  m_randomAccessModel = randomAccessModel;
129 }
130 
131 bool
132 SatRandomAccess::IsCrdsaAllocationChannel(uint32_t allocationChannel)
133 {
134  NS_LOG_FUNCTION(this << allocationChannel);
135 
136  return m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
137  ->GetCrdsaAllowed();
138 }
139 
140 bool
142 {
143  NS_LOG_FUNCTION(this << allocationChannel);
144 
145  return m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
146  ->GetSlottedAlohaAllowed();
147 }
148 
149 bool
150 SatRandomAccess::IsEssaAllocationChannel(uint32_t allocationChannel)
151 {
152  NS_LOG_FUNCTION(this << allocationChannel);
153 
154  return m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
155  ->GetEssaAllowed();
156 }
157 
159 SatRandomAccess::DoRandomAccess(uint32_t allocationChannelId,
161 {
162  NS_LOG_FUNCTION(this << allocationChannelId
164 
166  RandomAccessTxOpportunities_s txOpportunities;
167 
169  txOpportunities.allocationChannel = allocationChannelId;
170  uint32_t allocationChannel = GetConfigurationIdForAllocationChannel(allocationChannelId);
171 
172  NS_LOG_INFO("------------------------------------");
173  NS_LOG_INFO("------ Starting Random Access ------");
174  NS_LOG_INFO("------------------------------------");
175 
177  if (triggerType == SatEnums::RA_TRIGGER_TYPE_CRDSA &&
180  {
181  NS_LOG_INFO("Only CRDSA enabled && CRDSA trigger, checking allocation channel");
182 
183  if (IsCrdsaAllocationChannel(allocationChannel))
184  {
185  NS_LOG_INFO("Valid CRDSA allocation channel, checking backoff status");
186 
187  if (CrdsaHasBackoffTimePassed(allocationChannel))
188  {
189  NS_LOG_INFO("CRDSA backoff period over, evaluating CRDSA");
190  txOpportunities = DoCrdsa(allocationChannel);
191  }
192  else
193  {
194  NS_LOG_INFO("CRDSA backoff period in effect, aborting");
197  }
198  }
199  else
200  {
201  NS_FATAL_ERROR(
202  "SatRandomAccess::DoRandomAccess - Invalid allocation channel for CRDSA");
203  }
204  }
207  triggerType == SatEnums::RA_TRIGGER_TYPE_ESSA)
208  {
209  NS_LOG_INFO(
210  "SatRandomAccess::DoRandomAccess - Only ESSA enabled, checking allocation channel");
211 
212  if (IsEssaAllocationChannel(allocationChannel))
213  {
214  NS_LOG_INFO(
215  "SatRandomAccess::DoRandomAccess - Valid allocation channel, evaluating ESSA");
216 
217  txOpportunities = DoEssa(allocationChannel);
218  }
219  else
220  {
221  NS_FATAL_ERROR("SatRandomAccess::DoRandomAccess - Invalid allocation channel for ESSA");
222  }
223  }
225  else if (triggerType == SatEnums::RA_TRIGGER_TYPE_SLOTTED_ALOHA &&
227  {
228  NS_LOG_INFO("Only SA enabled, checking allocation channel");
229 
230  if (IsSlottedAlohaAllocationChannel(allocationChannel))
231  {
232  NS_LOG_INFO("Valid allocation channel, evaluating Slotted ALOHA");
233 
234  txOpportunities = DoSlottedAloha();
235  }
236  else
237  {
238  NS_FATAL_ERROR(
239  "SatRandomAccess::DoRandomAccess - Invalid allocation channel for Slotted ALOHA");
240  }
241  }
245  {
246  NS_LOG_INFO("RA based on RCS2 specification enabled");
247 
248  if (m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
249  ->GetCrdsaNumOfInstances() < 2)
250  {
251  if (triggerType == SatEnums::RA_TRIGGER_TYPE_SLOTTED_ALOHA)
252  {
253  if (IsSlottedAlohaAllocationChannel(allocationChannel))
254  {
255  NS_LOG_INFO("Valid Slotted ALOHA allocation channel, evaluating Slotted ALOHA");
256  txOpportunities = DoSlottedAloha();
257  }
258  else
259  {
260  NS_FATAL_ERROR("SatRandomAccess::DoRandomAccess - Invalid allocation channel "
261  "for Slotted ALOHA");
262  }
263  }
264  else
265  {
266  NS_LOG_INFO("Number of instances is < 2, only Slotted ALOHA is in use");
267  }
268  }
269  else
270  {
271  if (triggerType == SatEnums::RA_TRIGGER_TYPE_CRDSA)
272  {
273  if (IsCrdsaAllocationChannel(allocationChannel))
274  {
275  NS_LOG_INFO("Valid CRDSA allocation channel, checking backoff status");
276 
277  if (CrdsaHasBackoffTimePassed(allocationChannel))
278  {
279  NS_LOG_INFO("CRDSA backoff period over, evaluating CRDSA");
280  txOpportunities = DoCrdsa(allocationChannel);
281  }
282  else
283  {
284  NS_LOG_INFO("CRDSA backoff period in effect, aborting");
287  }
288  }
289  else
290  {
291  NS_FATAL_ERROR(
292  "SatRandomAccess::DoRandomAccess - Invalid allocation channel for CRDSA");
293  }
294  }
295  else
296  {
297  NS_LOG_INFO("Number of instances is > 1, only CRDSA is in use");
298  }
299  }
300  }
301  else if (triggerType == SatEnums::RA_TRIGGER_TYPE_SLOTTED_ALOHA &&
303  {
304  NS_LOG_INFO("Slotted ALOHA is disabled");
305  }
306  else if (triggerType == SatEnums::RA_TRIGGER_TYPE_CRDSA &&
309  {
310  NS_LOG_INFO("CRDSA is disabled");
311  }
312 
317  {
318  std::map<uint32_t, std::set<uint32_t>>::iterator iter;
319  uint32_t uniquePacketId = 1;
320 
321  for (iter = txOpportunities.crdsaTxOpportunities.begin();
322  iter != txOpportunities.crdsaTxOpportunities.end();
323  iter++)
324  {
325  std::set<uint32_t>::iterator iterSet;
326  for (iterSet = iter->second.begin(); iterSet != iter->second.end(); iterSet++)
327  {
328  NS_LOG_INFO("CRDSA transmission opportunity for unique packet: "
329  << uniquePacketId << " at slot: " << (*iterSet));
330  }
331  uniquePacketId++;
332  }
333  }
335  {
336  NS_LOG_INFO("SA minimum time to wait: " << txOpportunities.slottedAlohaTxOpportunity
337  << " milliseconds");
338  }
339  else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_ESSA)
340  {
341  NS_LOG_INFO("SatRandomAccess::DoRandomAccess - ESSA minimum time to wait: "
342  << txOpportunities.slottedAlohaTxOpportunity << " milliseconds");
343  }
344  else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_DO_NOTHING)
345  {
346  NS_LOG_INFO("No Tx opportunity");
347  }
348  else
349  {
350  NS_FATAL_ERROR("SatRandomAccess::DoRandomAccess - Invalid result type");
351  }
352 
353  NS_LOG_INFO("------------------------------------");
354  NS_LOG_INFO("------ Random Access FINISHED ------");
355  NS_LOG_INFO("------------------------------------");
356 
357  return txOpportunities;
358 }
359 
360 void
362 {
363  NS_LOG_FUNCTION(this);
364 
365  NS_LOG_INFO("Simulation time: " << Now().GetSeconds() << " seconds");
366  NS_LOG_INFO("Num of allocation channels: " << m_numOfAllocationChannels);
367  NS_LOG_INFO("New data status: " << m_crdsaNewData);
368 
369  NS_LOG_INFO("---------------");
370 
371  for (uint32_t index = 0; index < m_numOfAllocationChannels; index++)
372  {
373  Ptr<SatRandomAccessAllocationChannel> allocationChannel =
374  m_randomAccessConf->GetAllocationChannelConfiguration(index);
375  NS_LOG_INFO("ALLOCATION CHANNEL: " << index);
376  NS_LOG_INFO("Backoff release at: "
377  << allocationChannel->GetCrdsaBackoffReleaseTime().GetSeconds() << " seconds");
378  NS_LOG_INFO("Backoff time: " << allocationChannel->GetCrdsaBackoffTimeInMilliSeconds()
379  << " milliseconds");
380  NS_LOG_INFO("Backoff probability: " << allocationChannel->GetCrdsaBackoffProbability() * 100
381  << " %");
382  NS_LOG_INFO("Slot randomization: "
383  << allocationChannel->GetCrdsaNumOfInstances() *
384  allocationChannel->GetCrdsaMaxUniquePayloadPerBlock()
385  << " Tx opportunities with range from "
386  << allocationChannel->GetCrdsaMinRandomizationValue() << " to "
387  << allocationChannel->GetCrdsaMaxRandomizationValue());
388  NS_LOG_INFO("Number of unique payloads per block: "
389  << allocationChannel->GetCrdsaMaxUniquePayloadPerBlock());
390  NS_LOG_INFO("Number of instances: " << allocationChannel->GetCrdsaNumOfInstances());
391  NS_LOG_INFO("Number of consecutive blocks accessed: "
392  << allocationChannel->GetCrdsaNumOfConsecutiveBlocksUsed() << "/"
393  << allocationChannel->GetCrdsaMaxConsecutiveBlocksAccessed());
394  NS_LOG_INFO("Number of idle blocks left: " << allocationChannel->GetCrdsaIdleBlocksLeft()
395  << "/"
396  << allocationChannel->GetCrdsaMinIdleBlocks());
397  }
398 }
399 
400 uint32_t
402 {
403  return m_randomAccessConf->GetAllocationChannelConfigurationId(allocationChannelId);
404 }
405 
406 void
407 SatRandomAccess::SetBackoffTime(uint32_t allocationChannel, uint32_t backoffTime)
408 {
409  NS_LOG_FUNCTION(this);
410 
411  switch (m_randomAccessModel)
412  {
414  SetFSimBackoffTimeInFrames(allocationChannel, backoffTime);
415  break;
416  }
419  SetCrdsaBackoffTimeInMilliSeconds(allocationChannel, backoffTime);
420  break;
421  }
422  default: {
423  NS_FATAL_ERROR("SatRandomAccess::SetBackoffTime - Wrong random access model in use");
424  break;
425  }
426  }
427 }
428 
429 void
430 SatRandomAccess::SetBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
431 {
432  NS_LOG_FUNCTION(this);
433 
434  switch (m_randomAccessModel)
435  {
437  SetFSimBackoffProbability(allocationChannel, backoffProbability);
438  break;
439  }
442  SetCrdsaBackoffProbability(allocationChannel, backoffProbability);
443  break;
444  }
445  default: {
446  NS_FATAL_ERROR("SatRandomAccess::SetBackoffProbability - Wrong random access model in use");
447  break;
448  }
449  }
450 }
451 
455 
456 uint32_t
458 {
459  return m_randomAccessConf->GetSlottedAlohaSignalingOverheadInBytes();
460 }
461 
462 void
464  uint32_t controlRandomizationIntervalInMilliSeconds)
465 {
466  NS_LOG_FUNCTION(this << controlRandomizationIntervalInMilliSeconds);
467 
470  {
471  m_randomAccessConf->SetSlottedAlohaControlRandomizationIntervalInMilliSeconds(
472  controlRandomizationIntervalInMilliSeconds);
473 
474  m_randomAccessConf->DoSlottedAlohaVariableSanityCheck();
475  }
476  else
477  {
478  NS_FATAL_ERROR("SatRandomAccess::SetSlottedAlohaControlRandomizationIntervalInMilliSeconds "
479  "- Wrong random access model in use");
480  }
481 
482  NS_LOG_INFO(
483  "New control randomization interval : " << controlRandomizationIntervalInMilliSeconds);
484 }
485 
488 {
489  NS_LOG_FUNCTION(this);
490 
491  RandomAccessTxOpportunities_s txOpportunity;
493 
494  NS_LOG_INFO("---------------------------------------------");
495  NS_LOG_INFO("------ Running Slotted ALOHA algorithm ------");
496  NS_LOG_INFO("---------------------------------------------");
497  NS_LOG_INFO("Slotted ALOHA control randomization interval: "
498  << m_randomAccessConf->GetSlottedAlohaControlRandomizationIntervalInMilliSeconds()
499  << " milliseconds");
500  NS_LOG_INFO("---------------------------------------------");
501 
502  NS_LOG_INFO("Checking if we have DAMA allocations");
503 
505  if (!m_isDamaAvailableCb())
506  {
507  NS_LOG_INFO("No DAMA -> Running Slotted ALOHA");
508 
512  }
513 
514  NS_LOG_INFO("----------------------------------------------");
515  NS_LOG_INFO("------ Slotted ALOHA algorithm FINISHED ------");
516  NS_LOG_INFO("----------------------------------------------");
517 
518  return txOpportunity;
519 }
520 
521 uint32_t
523 {
524  NS_LOG_FUNCTION(this);
525 
526  NS_LOG_INFO("Randomizing the release time...");
527 
528  uint32_t releaseTime = m_uniformRandomVariable->GetInteger(
529  0,
530  m_randomAccessConf->GetSlottedAlohaControlRandomizationIntervalInMilliSeconds());
531 
532  NS_LOG_INFO("TX opportunity in the next slot after " << releaseTime << " milliseconds");
533 
534  return releaseTime;
535 }
536 
540 void
542  uint32_t backoffTimeInFrames)
543 {
547  NS_LOG_FUNCTION(this);
548 
550  {
551  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
552  ->SetFSimBackoffTimeInFrames(backoffTimeInFrames);
553  }
554  else
555  {
556  NS_FATAL_ERROR(
557  "SatRandomAccess::SetFSimBackoffTimeInFrames - Wrong random access model in use");
558  }
559 }
560 
561 void
562 SatRandomAccess::SetFSimBackoffProbability(uint32_t allocationChannel, uint16_t backoffPersistence)
563 {
567  NS_LOG_FUNCTION(this);
568 
570  {
571  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
572  ->SetFSimBackoffProbability(backoffPersistence);
573  }
574  else
575  {
576  NS_FATAL_ERROR(
577  "SatRandomAccess::SetFSimBackoffProbability - Wrong random access model in use");
578  }
579 }
580 
582 SatRandomAccess::DoEssa(uint32_t allocationChannel)
583 {
584  NS_LOG_FUNCTION(this);
585 
586  RandomAccessTxOpportunities_s txOpportunity;
587 
588  NS_LOG_INFO("------------------------------------");
589  NS_LOG_INFO("------ Running ESSA algorithm ------");
590  NS_LOG_INFO("------------------------------------");
591 
593 
599  uint32_t numberOfBackoff = 0;
600  while (m_uniformRandomVariable->GetValue(0.0, 1.0) >
601  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
602  ->GetFSimBackoffProbability())
603  {
604  numberOfBackoff++;
605  }
607  txOpportunity.slottedAlohaTxOpportunity =
608  numberOfBackoff * m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
609  ->GetFSimBackoffTimeInMilliSeconds(); // NOTE: could rename variable
610 
611  NS_LOG_INFO("-------------------------------------");
612  NS_LOG_INFO("------ ESSA algorithm FINISHED ------");
613  NS_LOG_INFO("-------------------------------------");
614 
615  return txOpportunity;
616 }
617 
621 
622 void
624  uint32_t backoffTimeInMilliSeconds)
625 {
626  NS_LOG_FUNCTION(this);
627 
631  {
632  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
633  ->SetCrdsaBackoffTimeInMilliSeconds(backoffTimeInMilliSeconds);
634 
635  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
636  ->DoCrdsaVariableSanityCheck();
637  }
638  else
639  {
640  NS_FATAL_ERROR("SatRandomAccess::SetCrdsaBackoffTimeInMilliSeconds - Wrong random access "
641  "model in use");
642  }
643 }
644 
645 void
646 SatRandomAccess::SetCrdsaBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
647 {
648  NS_LOG_FUNCTION(this);
649 
653  {
654  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
655  ->SetCrdsaBackoffProbability(backoffProbability);
656 
657  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
658  ->DoCrdsaVariableSanityCheck();
659  }
660  else
661  {
662  NS_FATAL_ERROR(
663  "SatRandomAccess::SetCrdsaBackoffProbability - Wrong random access model in use");
664  }
665 }
666 
667 void
669  uint32_t minRandomizationValue,
670  uint32_t maxRandomizationValue,
671  uint32_t numOfInstances)
672 {
673  NS_LOG_FUNCTION(this);
674 
678  {
679  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
680  ->SetCrdsaMinRandomizationValue(minRandomizationValue);
681  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
682  ->SetCrdsaMaxRandomizationValue(maxRandomizationValue);
683  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
684  ->SetCrdsaNumOfInstances(numOfInstances);
685 
686  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
687  ->DoCrdsaVariableSanityCheck();
688  }
689  else
690  {
691  NS_FATAL_ERROR(
692  "SatRandomAccess::SetCrdsaRandomizationParameters - Wrong random access model in use");
693  }
694 }
695 
696 void
698  uint32_t maxUniquePayloadPerBlock,
699  uint32_t maxConsecutiveBlocksAccessed,
700  uint32_t minIdleBlocks)
701 {
702  NS_LOG_FUNCTION(this);
703 
707  {
708  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
709  ->SetCrdsaMaxUniquePayloadPerBlock(maxUniquePayloadPerBlock);
710  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
711  ->SetCrdsaMaxConsecutiveBlocksAccessed(maxConsecutiveBlocksAccessed);
712  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
713  ->SetCrdsaMinIdleBlocks(minIdleBlocks);
714 
715  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
716  ->DoCrdsaVariableSanityCheck();
717  }
718  else
719  {
720  NS_FATAL_ERROR("SatRandomAccess::SetCrdsaMaximumDataRateLimitationParameters - Wrong "
721  "random access model in use");
722  }
723 }
724 
725 uint32_t
727 {
728  NS_LOG_FUNCTION(this);
729 
730  return m_randomAccessConf->GetCrdsaSignalingOverheadInBytes();
731 }
732 
733 bool
734 SatRandomAccess::CrdsaHasBackoffTimePassed(uint32_t allocationChannel) const
735 {
736  NS_LOG_FUNCTION(this);
737 
738  bool hasCrdsaBackoffTimePassed = false;
739 
740  if ((Now() >= m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
741  ->GetCrdsaBackoffReleaseTime()))
742  {
743  hasCrdsaBackoffTimePassed = true;
744  }
745 
746  NS_LOG_INFO("For allocation channel " << allocationChannel << ": "
747  << hasCrdsaBackoffTimePassed);
748 
749  return hasCrdsaBackoffTimePassed;
750 }
751 
752 void
753 SatRandomAccess::CrdsaReduceIdleBlocks(uint32_t allocationChannel)
754 {
755  NS_LOG_FUNCTION(this);
756 
757  uint32_t idleBlocksLeft =
758  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
759  ->GetCrdsaIdleBlocksLeft();
760 
761  if (idleBlocksLeft > 0)
762  {
763  NS_LOG_INFO("Reducing allocation channel: " << allocationChannel << " idle blocks by one");
764  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
765  ->SetCrdsaIdleBlocksLeft(idleBlocksLeft - 1);
766  }
767 }
768 
769 void
771 {
772  NS_LOG_FUNCTION(this);
773 
774  for (uint32_t i = 0; i < m_numOfAllocationChannels; i++)
775  {
777  }
778 }
779 
780 void
782 {
783  NS_LOG_FUNCTION(this << allocationChannel);
784 
785  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
786  ->SetCrdsaNumOfConsecutiveBlocksUsed(0);
787 }
788 
789 void
791 {
792  NS_LOG_FUNCTION(this);
793 
794  for (uint32_t i = 0; i < m_numOfAllocationChannels; i++)
795  {
797  }
798 }
799 
800 bool
802 {
803  NS_LOG_FUNCTION(this);
804 
805  if (m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
806  ->GetCrdsaIdleBlocksLeft() > 0)
807  {
808  NS_LOG_INFO("Allocation channel: " << allocationChannel << " idle in effect");
809  return false;
810  }
811  NS_LOG_INFO("Allocation channel: " << allocationChannel << " free");
812  return true;
813 }
814 
815 bool
816 SatRandomAccess::CrdsaDoBackoff(uint32_t allocationChannel)
817 {
818  NS_LOG_FUNCTION(this);
819 
820  bool doCrdsaBackoff = false;
821 
822  if (m_uniformRandomVariable->GetValue(0.0, 1.0) <
823  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
824  ->GetCrdsaBackoffProbability())
825  {
826  doCrdsaBackoff = true;
827  }
828 
829  NS_LOG_INFO("For allocation channel " << allocationChannel << ": " << doCrdsaBackoff);
830 
831  return doCrdsaBackoff;
832 }
833 
834 void
835 SatRandomAccess::CrdsaSetBackoffTimer(uint32_t allocationChannel)
836 {
837  NS_LOG_FUNCTION(this << allocationChannel);
838 
839  uint32_t backoff = m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
840  ->GetCrdsaBackoffTimeInMilliSeconds();
841  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
842  ->SetCrdsaBackoffReleaseTime(Now() + MilliSeconds(backoff));
843 }
844 
846 SatRandomAccess::CrdsaPrepareToTransmit(uint32_t allocationChannel)
847 {
848  NS_LOG_FUNCTION(this);
849 
850  RandomAccessTxOpportunities_s txOpportunities;
852 
853  uint32_t maxUniquePackets =
854  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
855  ->GetCrdsaMaxUniquePayloadPerBlock();
856 
861 
865  std::pair<std::set<uint32_t>, std::set<uint32_t>> slots;
866 
867  for (uint32_t i = 0; i < maxUniquePackets; i++)
868  {
869  if (CrdsaDoBackoff(allocationChannel))
870  {
871  CrdsaSetBackoffTimer(allocationChannel);
872  break;
873  }
874  else
875  {
876  NS_LOG_INFO("New Tx candidate for allocation channel: " << allocationChannel);
877 
878  if (CrdsaIsAllocationChannelFree(allocationChannel))
879  {
880  NS_LOG_INFO(
881  "Preparing for transmission with allocation channel: " << allocationChannel);
882 
884  slots = CrdsaRandomizeTxOpportunities(allocationChannel, slots);
885 
887  txOpportunities.crdsaTxOpportunities.insert(
888  std::make_pair(*slots.second.begin(), slots.second));
889 
890  if (m_areBuffersEmptyCb())
891  {
892  m_crdsaNewData = true;
893  }
894 
897  }
898  }
899  }
900 
901  return txOpportunities;
902 }
903 
904 void
906 {
907  NS_LOG_FUNCTION(this << allocationChannel);
908 
909  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
910  ->SetCrdsaNumOfConsecutiveBlocksUsed(
911  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
912  ->GetCrdsaNumOfConsecutiveBlocksUsed() +
913  1);
914 
915  if (m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
916  ->GetCrdsaNumOfConsecutiveBlocksUsed() >=
917  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
918  ->GetCrdsaMaxConsecutiveBlocksAccessed())
919  {
920  NS_LOG_INFO("Maximum number of consecutive blocks reached, forcing idle blocks for "
921  "allocation channel: "
922  << allocationChannel);
923 
924  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
925  ->SetCrdsaIdleBlocksLeft(
926  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
927  ->GetCrdsaMinIdleBlocks());
928 
930  }
931 }
932 
933 void
935 {
936  NS_LOG_FUNCTION(this);
937 
938  for (uint32_t i = 0; i < m_numOfAllocationChannels; i++)
939  {
941  }
942 }
943 
945 SatRandomAccess::DoCrdsa(uint32_t allocationChannel)
946 {
947  NS_LOG_FUNCTION(this);
948 
949  RandomAccessTxOpportunities_s txOpportunities;
951 
952  NS_LOG_INFO("-------------------------------------");
953  NS_LOG_INFO("------ Running CRDSA algorithm ------");
954  NS_LOG_INFO("-------------------------------------");
955 
956  PrintVariables();
957 
958  NS_LOG_INFO("-------------------------------------");
959 
960  NS_LOG_INFO("Backoff period over, checking DAMA status...");
961 
962  if (!m_isDamaAvailableCb())
963  {
964  NS_LOG_INFO("No DAMA, checking buffer status...");
965 
966  if (!m_areBuffersEmptyCb())
967  {
968  NS_LOG_INFO("Data in buffer, continuing CRDSA");
969 
970  if (m_crdsaNewData)
971  {
972  m_crdsaNewData = false;
973 
974  NS_LOG_INFO("Evaluating back off...");
975 
976  if (CrdsaDoBackoff(allocationChannel))
977  {
978  NS_LOG_INFO("Initial new data backoff triggered");
979  CrdsaSetBackoffTimer(allocationChannel);
980  }
981  else
982  {
983  txOpportunities = CrdsaPrepareToTransmit(allocationChannel);
984  }
985  }
986  else
987  {
988  txOpportunities = CrdsaPrepareToTransmit(allocationChannel);
989  }
990 
992  {
993  NS_LOG_INFO("Tx opportunity, increasing consecutive blocks used");
994 
996  }
997  else if (txOpportunities.txOpportunityType == SatEnums::RA_TX_OPPORTUNITY_DO_NOTHING)
998  {
999  NS_LOG_INFO(
1000  "No Tx opportunity, reducing idle blocks & resetting consecutive blocks");
1001 
1004  }
1005  }
1006  else
1007  {
1008  NS_LOG_INFO("Empty buffer, reducing idle blocks & resetting consecutive blocks, "
1009  "aborting CRDSA...");
1010 
1013  }
1014  }
1015  else
1016  {
1017  NS_LOG_INFO("DAMA allocation found, aborting CRDSA...");
1018 
1021  }
1022 
1023  NS_LOG_INFO("--------------------------------------");
1024  NS_LOG_INFO("------ CRDSA algorithm FINISHED ------");
1025  NS_LOG_INFO("------ Result: " << SatEnums::GetRandomAccessOpportunityTypeName(
1026  txOpportunities.txOpportunityType)
1027  << " ---------------------");
1028  NS_LOG_INFO("--------------------------------------");
1029 
1030  return txOpportunities;
1031 }
1032 
1033 std::pair<std::set<uint32_t>, std::set<uint32_t>>
1035  uint32_t allocationChannel,
1036  std::pair<std::set<uint32_t>, std::set<uint32_t>> slots)
1037 {
1038  NS_LOG_FUNCTION(this);
1039 
1040  std::pair<std::set<uint32_t>::iterator, bool> resultAllSlotsInFrame;
1041  std::pair<std::set<uint32_t>::iterator, bool> resultThisUniquePacket;
1042 
1043  std::set<uint32_t> emptySet;
1044  slots.second = emptySet;
1045 
1046  NS_LOG_INFO("Randomizing TX opportunities for allocation channel: " << allocationChannel);
1047 
1048  uint32_t successfulInserts = 0;
1049  uint32_t instances = m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
1050  ->GetCrdsaNumOfInstances();
1051  while (successfulInserts < instances)
1052  {
1053  uint32_t slot = m_uniformRandomVariable->GetInteger(
1054  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
1055  ->GetCrdsaMinRandomizationValue(),
1056  m_randomAccessConf->GetAllocationChannelConfiguration(allocationChannel)
1057  ->GetCrdsaMaxRandomizationValue());
1058 
1059  resultAllSlotsInFrame = slots.first.insert(slot);
1060 
1061  if (resultAllSlotsInFrame.second)
1062  {
1063  successfulInserts++;
1064 
1065  resultThisUniquePacket = slots.second.insert(slot);
1066 
1067  if (!resultAllSlotsInFrame.second)
1068  {
1069  NS_FATAL_ERROR("SatRandomAccess::CrdsaRandomizeTxOpportunities - Slots out of "
1070  "sync, this should never happen");
1071  }
1072  }
1073 
1074  NS_LOG_INFO("Allocation channel: "
1075  << allocationChannel << " insert successful " << resultAllSlotsInFrame.second
1076  << " for TX opportunity slot: " << (*resultAllSlotsInFrame.first));
1077  }
1078 
1079  NS_LOG_INFO("Randomizing done");
1080 
1081  return slots;
1082 }
1083 
1084 void
1086 {
1087  NS_LOG_FUNCTION(this << &callback);
1088 
1089  m_isDamaAvailableCb = callback;
1090 }
1091 
1092 void
1094 {
1095  NS_LOG_FUNCTION(this << &callback);
1096 
1097  m_areBuffersEmptyCb = callback;
1098 }
1099 
1100 } // namespace ns3
SatEnums class is for simplifying the use of enumerators in the satellite module.
static std::string GetRandomAccessModelName(RandomAccessModel_t model)
static std::string GetRandomAccessTriggerTypeName(RandomAccessTriggerType_t triggerType)
static std::string GetRandomAccessOpportunityTypeName(RandomAccessTxOpportunityType_t opportunityType)
RandomAccessModel_t
The defined random access models.
RandomAccessTriggerType_t
The defined random access trigger types.
SatEnums::RandomAccessModel_t m_randomAccessModel
The used random access model.
void CrdsaResetConsecutiveBlocksUsedForAllAllocationChannels()
Function for resetting the number of consecutive blocks to zero for all allocation channels.
bool IsEssaAllocationChannel(uint32_t allocationChannel)
Function for checking if the allocation channel is ESSA allocation channel.
void PrintVariables()
Function for printing out various module variables to console.
void SetCrdsaMaximumDataRateLimitationParameters(uint32_t allocationChannel, uint32_t maxUniquePayloadPerBlock, uint32_t maxConsecutiveBlocksAccessed, uint32_t minIdleBlocks)
Function for setting the maximum rate limitation parameters.
SatRandomAccess::RandomAccessTxOpportunities_s DoEssa(uint32_t allocationChannel)
Main function for ESSA.
void SetCrdsaBackoffTimeInMilliSeconds(uint32_t allocationChannel, uint32_t backoffTimeInMilliSeconds)
Function for setting the backoff time in milliseconds.
IsDamaAvailableCallback m_isDamaAvailableCb
Callback for known DAMA status.
std::pair< std::set< uint32_t >, std::set< uint32_t > > CrdsaRandomizeTxOpportunities(uint32_t allocationChannel, std::pair< std::set< uint32_t >, std::set< uint32_t >> slots)
Function for randomizing the CRDSA Tx opportunities (slots) for each unique packet.
bool IsSlottedAlohaAllocationChannel(uint32_t allocationChannel)
Function for checking if the allocation channel is Slotted ALOHA allocation channel.
SatRandomAccess::RandomAccessTxOpportunities_s DoRandomAccess(uint32_t allocationChannel, SatEnums::RandomAccessTriggerType_t triggerType)
Main function of this module.
uint32_t m_numOfAllocationChannels
Number of allocation channels available.
void CrdsaIncreaseConsecutiveBlocksUsed(uint32_t allocationChannel)
Function for increasing the allocation channel specific count of consecutive used blocks.
uint32_t GetConfigurationIdForAllocationChannel(uint32_t allocationChannelId)
Function to convert a carrier allocation channel ID into its allocation channel configuration ID.
void CrdsaResetConsecutiveBlocksUsed(uint32_t allocationChannel)
Function for resetting the number of consecutive blocks to zero for a specific allocation channel.
SatRandomAccess::RandomAccessTxOpportunities_s CrdsaPrepareToTransmit(uint32_t allocationChannel)
Function for evaluating backoff for each unique CRDSA packet and calling the randomization of Tx oppo...
bool CrdsaIsAllocationChannelFree(uint32_t allocationChannel)
Function for checking if the allocation channel is free.
void CrdsaIncreaseConsecutiveBlocksUsedForAllAllocationChannels()
Function for increasing the count of consecutive used blocks for all allocation channels.
void SetSlottedAlohaControlRandomizationIntervalInMilliSeconds(uint32_t controlRandomizationIntervalInMilliSeconds)
Function for setting the Slotted ALOHA control randomization interval.
AreBuffersEmptyCallback m_areBuffersEmptyCb
Callback for buffer status.
static TypeId GetTypeId(void)
NS-3 type id function.
Callback< bool > AreBuffersEmptyCallback
Typedef of callback for buffer status.
void CrdsaSetBackoffTimer(uint32_t allocationChannel)
Function for setting the allocation channel specific backoff timer.
void SetFSimBackoffTimeInFrames(uint32_t allocationChannel, uint32_t backoffTimeInFrames)
Function for setting the backoff time in frames.
SatRandomAccess::RandomAccessTxOpportunities_s DoCrdsa(uint32_t allocationChannel)
Main function for CRDSA algorithm.
void SetFSimBackoffProbability(uint32_t allocationChannel, uint16_t backoffPersistence)
Function for setting the backoff probability.
void SetCrdsaRandomizationParameters(uint32_t allocationChannel, uint32_t minRandomizationValue, uint32_t maxRandomizationValue, uint32_t numOfInstances)
Function for setting the parameters related to CRDSA randomization.
Ptr< SatRandomAccessConf > m_randomAccessConf
A pointer to random access configuration.
bool CrdsaHasBackoffTimePassed(uint32_t allocationChannel) const
Function for checking whether the backoff time has passed for this allocation channel.
Ptr< UniformRandomVariable > m_uniformRandomVariable
Uniform random variable object.
void SetAreBuffersEmptyCallback(SatRandomAccess::AreBuffersEmptyCallback callback)
Function for setting the AreBuffersEmpty callback.
void SetRandomAccessModel(SatEnums::RandomAccessModel_t randomAccessModel)
Function for setting the used random access model.
void SetIsDamaAvailableCallback(SatRandomAccess::IsDamaAvailableCallback callback)
Function for setting the IsDamaAvailable callback.
uint32_t GetSlottedAlohaSignalingOverheadInBytes()
Function for getting the Slotted ALOHA signaling overhead in bytes.
bool CrdsaDoBackoff(uint32_t allocationChannel)
Function for evaluating the backoff for this allocation channel.
SatRandomAccess::RandomAccessTxOpportunities_s DoSlottedAloha()
Main function for Slotted ALOHA.
uint32_t SlottedAlohaRandomizeReleaseTime()
Function for performing the Slotted ALOHA release time randomization, i.e., the time after which the ...
void CrdsaReduceIdleBlocksForAllAllocationChannels()
Function for reducing the idle blocks in effect for all allocation channels.
void SetBackoffTime(uint32_t allocationChannel, uint32_t backoffTime)
Function for setting the backoff time.
uint32_t GetCrdsaSignalingOverheadInBytes()
Function for getting the CRDSA signaling overhead in bytes.
bool m_crdsaNewData
A flag defining whether the buffers were emptied the last time RA was evaluated, i....
bool IsCrdsaAllocationChannel(uint32_t allocationChannel)
Function for checking if the allocation channel is CRDSA allocation channel.
void SetCrdsaBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
Function for setting the backoff probability.
void DoDispose()
Function for disposing the module and its variables.
void SetBackoffProbability(uint32_t allocationChannel, uint16_t backoffProbability)
Function for setting the backoff probability.
void CrdsaReduceIdleBlocks(uint32_t allocationChannel)
Function for reducing the allocation channel specific number of idle blocks in effect.
Callback< bool > IsDamaAvailableCallback
Typedef of callback for known DAMA status.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
std::map< uint32_t, std::set< uint32_t > > crdsaTxOpportunities