satellite-phy-rx-carrier-per-frame.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: Jani Puttonen <jani.puttonen@magister.fi>
20  * Author: Mathias Ettinger <mettinger@toulouse.viveris.fr>
21  */
22 
24 
26 
27 #include <ns3/boolean.h>
28 #include <ns3/log.h>
29 #include <ns3/simulator.h>
30 
31 #include <algorithm>
32 #include <limits>
33 #include <list>
34 #include <map>
35 #include <ostream>
36 #include <set>
37 #include <utility>
38 #include <vector>
39 
40 NS_LOG_COMPONENT_DEFINE("SatPhyRxCarrierPerFrame");
41 
42 namespace ns3
43 {
44 
45 NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerFrame);
46 
48  Ptr<SatPhyRxCarrierConf> carrierConf,
49  Ptr<SatWaveformConf> waveformConf,
50  bool randomAccessEnabled)
51  : SatPhyRxCarrierPerSlot(carrierId, carrierConf, waveformConf, randomAccessEnabled),
52  m_frameEndSchedulingInitialized(false)
53 {
54  NS_LOG_FUNCTION(this);
55  NS_LOG_INFO("Constructor called with arguments " << carrierId << ", " << carrierConf << ", and "
56  << randomAccessEnabled);
57 
58  NS_ASSERT(m_randomAccessEnabled == true);
59 }
60 
61 void
63 {
64  NS_LOG_FUNCTION(this);
66  {
67  Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
69 
70  if (Now() >= nextSuperFrameRxTime)
71  {
72  NS_FATAL_ERROR("Scheduling next superframe start time to the past!");
73  }
74 
75  Time schedulingDelay = nextSuperFrameRxTime - Now();
76 
77  if (GetNodeInfo() == nullptr)
78  {
79  NS_FATAL_ERROR("m_nodeInfo not set");
80  }
81 
83 
84  Simulator::ScheduleWithContext(GetNodeInfo()->GetNodeId(),
85  schedulingDelay,
87  this);
88  }
89 }
90 
92 {
93  NS_LOG_FUNCTION(this);
94 }
95 
96 TypeId
98 {
99  static TypeId tid =
100  TypeId("ns3::SatPhyRxCarrierPerFrame")
101  .SetParent<SatPhyRxCarrierPerSlot>()
102  .AddTraceSource(
103  "CrdsaReplicaRx",
104  "Received a CRDSA packet replica through Random Access",
105  MakeTraceSourceAccessor(&SatPhyRxCarrierPerFrame::m_crdsaReplicaRxTrace),
106  "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
107  .AddTraceSource(
108  "CrdsaUniquePayloadRx",
109  "Received a unique CRDSA payload (after frame processing) "
110  "through Random Access CRDSA",
112  "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback");
113  return tid;
114 }
115 
116 void
118 {
120  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
121 
122  for (iter = m_crdsaPacketContainer.begin(); iter != m_crdsaPacketContainer.end(); iter++)
123  {
124  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
125  for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
126  {
127  iterList->rxParams = nullptr;
128  }
129  iter->second.clear();
130  }
131  m_crdsaPacketContainer.clear();
132 }
133 
134 void
136  const uint32_t nPackets)
137 {
138  NS_ASSERT(packetRxParams.rxParams->m_txInfo.packetType !=
140 
141  // If the received random access packet is of type slotted aloha, we
142  // receive the packet with the base class ReceiveSlot method.
143  if (packetRxParams.rxParams->m_txInfo.packetType == SatEnums::PACKET_TYPE_SLOTTED_ALOHA ||
144  packetRxParams.rxParams->m_txInfo.packetType == SatEnums::PACKET_TYPE_LOGON)
145  {
146  SatPhyRxCarrierPerSlot::ReceiveSlot(packetRxParams, nPackets);
147  return;
148  }
149 
150  NS_LOG_INFO("CRDSA packet received");
152 
153  params.destAddress = packetRxParams.destAddress;
154  params.sourceAddress = packetRxParams.sourceAddress;
155  params.rxParams = packetRxParams.rxParams;
156 
158  params.hasCollision = GetInterferenceModel()->HasCollision(packetRxParams.interferenceEvent);
159  params.packetHasBeenProcessed = false;
160 
161  if (nPackets > 0)
162  {
163  m_crdsaReplicaRxTrace(nPackets, // number of packets
164  params.sourceAddress, // sender address
165  params.hasCollision // collision flag
166  );
167  }
168 
169  AddCrdsaPacket(params);
170 }
171 
172 void
174 {
175  NS_LOG_FUNCTION(this);
176 
177  if (!m_crdsaPacketContainer.empty())
178  {
179  // Update the CRDSA random access load for unique payloads!
181 
182  NS_LOG_INFO("Packets in container, will process the frame");
183 
184  std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> results = ProcessFrame();
185 
186  if (!m_crdsaPacketContainer.empty())
187  {
188  NS_FATAL_ERROR("All CRDSA packets in the frame were not processed");
189  }
190 
193  std::sort(results.begin(), results.end(), CompareCrdsaPacketId);
194 
195  for (crdsaPacketRxParams_s& crdsaPacket : results)
196  {
197  NS_LOG_INFO("Sending a packet to the next layer, slot: "
198  << crdsaPacket.ownSlotId << ", UT: " << crdsaPacket.sourceAddress
199  << ", unique CRDSA packet ID: "
200  << crdsaPacket.rxParams->m_txInfo.crdsaUniquePacketId
201  << ", destination address: " << crdsaPacket.destAddress
202  << ", error: " << crdsaPacket.phyError << ", SINR: " << crdsaPacket.cSinr);
203 
204  for (Ptr<Packet>& packetInBurst : crdsaPacket.rxParams->m_packetsInBurst)
205  {
206  NS_LOG_INFO("Fragment (HL packet) UID: " << packetInBurst->GetUid());
207  }
208 
210  m_linkBudgetTrace(crdsaPacket.rxParams,
211  GetOwnAddress(),
212  crdsaPacket.destAddress,
213  crdsaPacket.ifPower,
214  crdsaPacket.cSinr);
217  crdsaPacket.rxParams->m_packetsInBurst.size(), // number of packets
218  crdsaPacket.sourceAddress, // sender address
219  crdsaPacket.phyError // error flag
220  );
221 
222  // Update composite SINR trace for CRDSA packet after combination
223  m_sinrTrace(SatUtils::LinearToDb(crdsaPacket.cSinr), crdsaPacket.sourceAddress);
224 
226  m_rxCallback(crdsaPacket.rxParams, crdsaPacket.phyError);
227 
228  crdsaPacket.rxParams = nullptr;
229  }
230 
231  results.clear();
232  }
233 
235  {
237  }
238  else
239  {
240  if (!m_crdsaPacketContainer.empty())
241  {
242  NS_FATAL_ERROR("CRDSA packets received by carrier which has random access disabled");
243  }
244  }
245 
246  Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
248 
249  if (Now() >= nextSuperFrameRxTime)
250  {
251  NS_FATAL_ERROR("Scheduling next superframe start time to the past!");
252  }
253 
254  Time schedulingDelay = nextSuperFrameRxTime - Now();
255 
256  Simulator::Schedule(schedulingDelay, &SatPhyRxCarrierPerFrame::DoFrameEnd, this);
257 }
258 
259 void
261 {
262  NS_LOG_FUNCTION(this);
263 
264  std::vector<uint64_t> uniquePacketIds;
265  uint32_t uniqueCrdsaBytes(0);
266 
267  // Go through all the received CRDSA packets
268  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
269  for (iter = m_crdsaPacketContainer.begin(); iter != m_crdsaPacketContainer.end(); iter++)
270  {
271  // Go through all the packets received in the same slot id
272  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
273  for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
274  {
275  // It is sufficient to check the first packet Uid
276  uint64_t uid = iterList->rxParams->m_packetsInBurst.front()->GetUid();
277 
278  // Check if we have already counted the bytes of this transmission
279  std::vector<uint64_t>::iterator it =
280  std::find(uniquePacketIds.begin(), uniquePacketIds.end(), uid);
281  // Not found -> is unique
282  if (it == uniquePacketIds.end())
283  {
284  // Push this to accounted unique transmissions vector
285  uniquePacketIds.push_back(uid);
286 
287  // Update the load with FEC block size!
288  uniqueCrdsaBytes += iterList->rxParams->m_txInfo.fecBlockSizeInBytes;
289  }
290  // else, do nothing, i.e. this is a replica
291  }
292  }
293 
294  // Update with the unique FEC block sum of CRDSA frame
296 }
297 
298 void
300 {
301  NS_LOG_FUNCTION(this);
302 
304  double normalizedOfferedLoad = CalculateNormalizedOfferedRandomAccessLoad();
305 
307  SaveMeasuredRandomAccessLoad(normalizedOfferedLoad);
308 
310  double averageNormalizedOfferedLoad = CalculateAverageNormalizedOfferedRandomAccessLoad();
311 
312  NS_LOG_INFO("Average normalized offered load: " << averageNormalizedOfferedLoad);
313 
315  GetBeamId(),
316  GetCarrierId(),
318  averageNormalizedOfferedLoad);
319 }
320 
321 double
323 {
324  NS_LOG_FUNCTION(this);
325 
326  Time superFrameDuration = Singleton<SatRtnLinkTime>::Get()->GetSuperFrameDuration(
328 
329  double normalizedOfferedLoad =
330  (m_randomAccessBitsInFrame / superFrameDuration.GetSeconds()) / m_rxBandwidthHz;
331 
332  NS_LOG_INFO("Bits: " << m_randomAccessBitsInFrame
333  << ", frame length in seconds: " << superFrameDuration.GetSeconds()
334  << ", bandwidth in Hz: " << m_rxBandwidthHz
335  << ", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
336 
339 
340  return normalizedOfferedLoad;
341 }
342 
343 void
346 {
347  NS_LOG_FUNCTION(this);
348 
349  if (crdsaPacketParams.rxParams->m_packetsInBurst.size() > 0)
350  {
351  SatCrdsaReplicaTag replicaTag;
352 
354  bool result = crdsaPacketParams.rxParams->m_packetsInBurst[0]->PeekPacketTag(replicaTag);
355 
356  if (!result)
357  {
358  NS_FATAL_ERROR("First packet did not contain a CRDSA replica tag");
359  }
360 
361  std::vector<uint16_t> slotIds = replicaTag.GetSlotIds();
362 
363  if (slotIds.size() < 1)
364  {
365  NS_FATAL_ERROR("The tag did not contain any slot IDs");
366  }
367 
369  crdsaPacketParams.ownSlotId = slotIds[0];
370 
371  if (crdsaPacketParams.slotIdsForOtherReplicas.size() > 0)
372  {
373  NS_FATAL_ERROR("Vector for packet replicas should be empty at this point");
374  }
375 
377  for (uint32_t i = 1; i < slotIds.size(); i++)
378  {
379  crdsaPacketParams.slotIdsForOtherReplicas.push_back(slotIds[i]);
380  }
381 
383  for (uint32_t i = 0; i < crdsaPacketParams.rxParams->m_packetsInBurst.size(); i++)
384  {
385  crdsaPacketParams.rxParams->m_packetsInBurst[i]->RemovePacketTag(replicaTag);
386  }
387  }
388  else
389  {
390  NS_FATAL_ERROR("CRDSA reception with 0 packets");
391  }
392 
393  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator result;
394 
395  result = m_crdsaPacketContainer.find(crdsaPacketParams.ownSlotId);
396 
397  if (result == m_crdsaPacketContainer.end())
398  {
399  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> tempList;
400  tempList.push_back(crdsaPacketParams);
401  m_crdsaPacketContainer.insert(std::make_pair(crdsaPacketParams.ownSlotId, tempList));
402  }
403  else
404  {
405  result->second.push_back(crdsaPacketParams);
406  }
407 
408  NS_LOG_INFO("Packet in slot " << crdsaPacketParams.ownSlotId
409  << " was added to the CRDSA packet container");
410 
411  for (uint32_t i = 0; i < crdsaPacketParams.slotIdsForOtherReplicas.size(); i++)
412  {
413  NS_LOG_INFO("A replica of the packet is in slot "
414  << crdsaPacketParams.slotIdsForOtherReplicas[i]);
415  }
416 }
417 
418 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>
420 {
421  NS_LOG_FUNCTION(this);
422 
423  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
424  std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> combinedPacketsForFrame;
425 
426  // Perform SIC in its entirety, until no more packets can be decoded
427  PerformSicCycles(combinedPacketsForFrame);
428 
429  NS_LOG_INFO("All successfully received packets processed, packets left in container: "
430  << m_crdsaPacketContainer.size());
431 
432  // Cleanup: remove remaining packets from the receive container
433  // and add them to the resulting vector by ensuring that their
434  // phyError is set to true.
435  do
436  {
438  iter = m_crdsaPacketContainer.begin();
439 
440  if (iter != m_crdsaPacketContainer.end())
441  {
442  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList =
443  iter->second.begin();
444 
445  if (iterList != iter->second.end())
446  {
447  NS_LOG_INFO("Processing unsuccessfully received packet in slot: "
448  << iterList->ownSlotId << " packet phy error: " << iterList->phyError
449  << " packet has been processed: " << iterList->packetHasBeenProcessed);
450 
451  if (!iterList->packetHasBeenProcessed || !iterList->phyError)
452  {
453  NS_FATAL_ERROR(
454  "All successfully received packets should have been processed by now");
455  }
456 
458  FindAndRemoveReplicas(*iterList);
459 
461  combinedPacketsForFrame.push_back(*iterList);
462 
464  iter->second.erase(iterList);
465 
467  if (iter->second.empty())
468  {
469  m_crdsaPacketContainer.erase(iter);
470  }
471  }
472  else
473  {
475  m_crdsaPacketContainer.erase(iter);
476  }
477  }
478  } while (!m_crdsaPacketContainer.empty());
479 
480  NS_LOG_INFO("Container processed, packets left: " << m_crdsaPacketContainer.size());
481 
482  return combinedPacketsForFrame;
483 }
484 
485 void
487  std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& combinedPacketsForFrame)
488 {
489  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
491  bool nothingToProcess = true;
492 
493  NS_LOG_INFO("Packets to process: " << m_crdsaPacketContainer.size());
494 
495  do
496  {
497  NS_LOG_INFO("Searching for the next successfully received packet");
498 
500  nothingToProcess = true;
501 
503  for (iter = m_crdsaPacketContainer.begin(); iter != m_crdsaPacketContainer.end(); ++iter)
504  {
505  NS_LOG_INFO("Iterating slot: " << iter->first);
506  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& slotContent = iter->second;
507 
508  if (slotContent.size() < 1)
509  {
510  NS_FATAL_ERROR("No packet in slot! This should not happen");
511  }
512 
513  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator currentPacket;
514 
515  for (currentPacket = slotContent.begin(); currentPacket != slotContent.end();
516  currentPacket++)
517  {
518  NS_LOG_INFO("Iterating packet in slot: " << currentPacket->ownSlotId);
519 
520  if (!currentPacket->packetHasBeenProcessed)
521  {
522  NS_LOG_INFO("Found a packet ready for processing");
523 
525  *currentPacket = ProcessReceivedCrdsaPacket(*currentPacket, slotContent.size());
526 
527  NS_LOG_INFO("Packet error: " << currentPacket->phyError);
528 
530  if (!currentPacket->phyError)
531  {
532  NS_LOG_INFO("Packet successfully received, breaking the slot iteration");
533 
534  nothingToProcess = false;
535 
537  processedPacket = *currentPacket;
538 
540  slotContent.erase(currentPacket);
541 
544  EliminateInterference(iter, processedPacket);
545 
547  break;
548  }
549  }
550  else
551  {
552  NS_LOG_INFO("This packet has already been processed");
553  }
554  }
555 
557  if (!nothingToProcess)
558  {
559  NS_LOG_INFO("Packet successfully received, breaking the container iteration");
560  break;
561  }
562  }
563 
564  if (!nothingToProcess)
565  {
566  NS_LOG_INFO("Packet successfully received, processing the replicas");
567 
569  FindAndRemoveReplicas(processedPacket);
570 
572  combinedPacketsForFrame.push_back(processedPacket);
573  }
574  } while (!nothingToProcess);
575 }
576 
580  uint32_t numOfPacketsForThisSlot)
581 {
582  NS_LOG_FUNCTION(this);
583 
584  NS_LOG_INFO("Processing a packet in slot: " << packet.ownSlotId
585  << " number of packets in this slot: "
586  << numOfPacketsForThisSlot);
587 
588  for (uint32_t i = 0; i < packet.slotIdsForOtherReplicas.size(); i++)
589  {
590  NS_LOG_INFO("Replica in slot: " << packet.slotIdsForOtherReplicas[i]);
591  }
592 
593  NS_LOG_INFO("SINR CALCULATION, RX sat: "
594  << packet.rxParams->GetRxPowerInSatellite()
595  << " IF sat: " << packet.rxParams->GetInterferencePowerInSatellite()
596  << " RX gnd: " << packet.rxParams->m_rxPower_W
597  << " IF gnd: " << packet.rxParams->GetInterferencePower());
598 
599  double sinr = CalculatePacketCompositeSinr(packet);
600 
601  SatSignalParameters::PacketsInBurst_t packets = packet.rxParams->m_packetsInBurst;
602  SatSignalParameters::PacketsInBurst_t::const_iterator i;
603  for (i = packets.begin(); i != packets.end(); i++)
604  {
605  SatUplinkInfoTag satUplinkInfoTag;
606  (*i)->RemovePacketTag(satUplinkInfoTag);
607  satUplinkInfoTag.SetSinr(sinr, m_additionalInterferenceCallback());
608  (*i)->AddPacketTag(satUplinkInfoTag);
609  }
610 
611  /*
612  * Update link specific SINR trace for the RETURN_FEEDER link. The RETURN_USER
613  * link SINR is already updated at the SatPhyRxCarrierUplink::EndRxData ()
614  * method!
615  */
617 
620  {
621  NS_LOG_INFO("Strict collision detection is ENABLED");
622 
624  if (numOfPacketsForThisSlot > 1)
625  {
626  NS_LOG_INFO("Multiple packets in this slot, successful reception is not possible");
628  packet.phyError = true;
629  }
630  else
631  {
632  NS_LOG_INFO("Only packet in this slot, checking against link results");
634  packet.phyError = CheckAgainstLinkResults(packet.cSinr, packet.rxParams);
635  }
636  NS_LOG_INFO("Strict collision detection, phy error: " << packet.phyError);
637  }
638  else if (GetRandomAccessCollisionModel() ==
640  {
642  packet.phyError = CheckAgainstLinkResults(packet.cSinr, packet.rxParams);
643  NS_LOG_INFO("Check against link results, phy error: " << packet.phyError);
644  }
645  else
646  {
647  NS_FATAL_ERROR("Random access collision model not defined");
648  }
649 
651  packet.packetHasBeenProcessed = true;
652 
653  return packet;
654 }
655 
656 double
659 {
660  NS_LOG_FUNCTION(this);
661 
662  double sinr = CalculateSinr(packet.rxParams->m_rxPower_W,
663  packet.rxParams->GetInterferencePower(),
668 
669  double cSinr;
671  {
672  double sinrSatellite = CalculateSinr(packet.rxParams->GetRxPowerInSatellite(),
673  packet.rxParams->GetInterferencePowerInSatellite(),
674  packet.rxParams->GetRxNoisePowerInSatellite(),
675  packet.rxParams->GetRxAciIfPowerInSatellite(),
676  packet.rxParams->GetRxExtNoisePowerInSatellite(),
677  packet.rxParams->GetAdditionalInterference());
678  cSinr = CalculateCompositeSinr(sinr, sinrSatellite);
679  }
680  else
681  {
682  cSinr = sinr;
683  }
684 
685  NS_LOG_INFO("Computed cSINR for packet: " << cSinr);
686 
687  packet.cSinr = cSinr;
688  packet.ifPower = packet.rxParams->GetInterferencePower();
689 
690  return sinr;
691 }
692 
693 void
696 {
697  NS_LOG_FUNCTION(this);
698 
699  for (uint32_t i = 0; i < packet.slotIdsForOtherReplicas.size(); i++)
700  {
701  NS_LOG_INFO("Processing replica in slot: " << packet.slotIdsForOtherReplicas[i]);
702 
704  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator
705  iter;
706  iter = m_crdsaPacketContainer.find(packet.slotIdsForOtherReplicas[i]);
707 
708  if (iter == m_crdsaPacketContainer.end())
709  {
710  NS_FATAL_ERROR("This should not happen");
711  }
712 
713  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
715 
716  bool replicaFound = false;
717 
718  for (iterList = iter->second.begin(); iterList != iter->second.end();)
719  {
721  if (IsReplica(packet, *iterList))
722  {
723  if (replicaFound)
724  {
725  NS_FATAL_ERROR("Found two replica of the same packet in the same slot");
726  }
728  replicaFound = true;
729  removedPacket = *iterList;
730  iter->second.erase(iterList++);
731  }
732  else
733  {
734  ++iterList;
735  }
736  }
737 
738  if (!replicaFound)
739  {
740  NS_FATAL_ERROR("Replica not found");
741  }
742 
743  if (!packet.phyError)
744  {
745  CalculatePacketCompositeSinr(removedPacket);
746  EliminateInterference(iter, removedPacket);
747  }
748  }
749 }
750 
751 void
753  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter,
755 {
756  NS_LOG_FUNCTION(this);
757 
758  if (iter->second.empty())
759  {
760  NS_LOG_INFO("No other packets in this slot, erasing the slot container");
761  m_crdsaPacketContainer.erase(iter);
762  }
763  else
764  {
765  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
766 
767  for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
768  {
770  iterList->packetHasBeenProcessed = false;
771 
772  NS_LOG_INFO("BEFORE INTERFERENCE ELIMINATION, RX sat: "
773  << iterList->rxParams->GetRxPowerInSatellite()
774  << " IF sat: " << iterList->rxParams->GetInterferencePowerInSatellite()
775  << " RX gnd: " << iterList->rxParams->m_rxPower_W
776  << " IF gnd: " << iterList->rxParams->GetInterferencePower());
777 
785 
786  if (iterList->rxParams->GetInterferencePower() < 0)
787  {
788  NS_FATAL_ERROR("Negative interference");
789  }
790 
791  GetInterferenceEliminationModel()->EliminateInterferences(iterList->rxParams,
792  processedPacket.rxParams,
793  processedPacket.cSinr,
796 
797  NS_LOG_INFO("AFTER INTERFERENCE ELIMINATION, RX sat: "
798  << iterList->rxParams->GetRxPowerInSatellite()
799  << " IF sat: " << iterList->rxParams->GetInterferencePowerInSatellite()
800  << " RX gnd: " << iterList->rxParams->m_rxPower_W
801  << " IF gnd: " << iterList->rxParams->GetInterferencePower());
802  }
803  }
804 }
805 
806 bool
809  const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s& otherPacket) const
810 {
811  NS_LOG_FUNCTION(this);
812 
813  NS_LOG_INFO("Checking the source addresses");
814 
815  bool isReplica = false;
816 
817  if (otherPacket.sourceAddress == packet.sourceAddress)
818  {
819  NS_LOG_INFO("Same source addresses, checking slot IDs");
820 
821  if (HaveSameSlotIds(packet, otherPacket))
822  {
823  NS_LOG_INFO("Same slot IDs, replica found");
824  isReplica = true;
825  }
826  }
827  return isReplica;
828 }
829 
830 bool
833  const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s& otherPacket) const
834 {
835  NS_LOG_FUNCTION(this);
836 
837  std::set<uint16_t> firstSet;
838  std::set<uint16_t> secondSet;
839  std::set<uint16_t>::iterator firstSetIterator;
840  std::set<uint16_t>::iterator secondSetIterator;
841  bool haveSameSlotIds = true;
842 
843  firstSet.insert(packet.ownSlotId);
844  secondSet.insert(otherPacket.ownSlotId);
845 
847  if (otherPacket.slotIdsForOtherReplicas.size() != packet.slotIdsForOtherReplicas.size())
848  {
849  NS_FATAL_ERROR(
850  "SatPhyRxCarrierUt::HaveSameSlotIds - The amount of replicas does not match");
851  }
852 
853  NS_LOG_INFO("Comparing slot IDs");
854 
856  for (uint32_t i = 0; i < otherPacket.slotIdsForOtherReplicas.size(); i++)
857  {
858  firstSet.insert(packet.slotIdsForOtherReplicas[i]);
859  secondSet.insert(otherPacket.slotIdsForOtherReplicas[i]);
860  }
861 
862  uint32_t numOfMatchingSlots = 0;
863 
865  for (firstSetIterator = firstSet.begin(); firstSetIterator != firstSet.end();
866  firstSetIterator++)
867  {
868  secondSetIterator = secondSet.find(*firstSetIterator);
869 
870  if (secondSetIterator == secondSet.end())
871  {
872  haveSameSlotIds = false;
873  }
874  else
875  {
876  numOfMatchingSlots++;
877  }
878  }
879 
880  NS_LOG_INFO("Are slot IDs identical: " << haveSameSlotIds
881  << ", number of matching slots: " << numOfMatchingSlots);
882 
884  if (!haveSameSlotIds && numOfMatchingSlots > 0)
885  {
886  NS_FATAL_ERROR("Partially overlapping CRDSA slots");
887  }
888 
889  return haveSameSlotIds;
890 }
891 
892 bool
895 {
896  return (bool)(obj1.rxParams->m_txInfo.crdsaUniquePacketId <
897  obj2.rxParams->m_txInfo.crdsaUniquePacketId);
898 }
899 
900 } // namespace ns3
This class implements a tag that carries information about the slot IDs of CRDSA packet replicas.
std::vector< uint16_t > GetSlotIds(void)
SatPhy::AverageNormalizedOfferedLoadCallback m_avgNormalizedOfferedLoadCallback
Average normalized offered load callback.
Ptr< SatInterference > GetInterferenceModel()
Get pointer to the current interference model.
double m_rxExtNoisePowerW
External noise power system RX noise.
TracedCallback< double, const Address & > m_linkSinrTrace
A callback for link specific SINR in dB.
TracedCallback< Ptr< SatSignalParameters >, Mac48Address, Mac48Address, double, double > m_linkBudgetTrace
The trace source on packet receptiong.
Ptr< SatNodeInfo > GetNodeInfo()
Get the satellite node info.
SatPhyRxCarrierConf::AdditionalInterferenceCallback m_additionalInterferenceCallback
Callback to get additional interference.
uint32_t GetCarrierId() const
Get the ID of the carrier.
virtual SatEnums::RegenerationMode_t GetLinkRegenerationMode()
Get the link regeneration mode.
uint32_t GetBeamId()
Get ID the ID of the beam this carrier is attached to.
double CalculateSinr(double rxPowerW, double ifPowerW, double rxNoisePowerW, double rxAciIfPowerW, double rxExtNoisePowerW, double otherInterference)
Function for calculating the SINR.
SatPhyRx::ReceiveCallback m_rxCallback
The upper layer package receive callback.
double m_rxAciIfPowerW
RX Adjacent channel interference.
TracedCallback< double, const Address & > m_sinrTrace
A callback for transmission composite SINR at UT (BBFrame) or GW (time slot).
bool CheckAgainstLinkResults(double cSinr, Ptr< SatSignalParameters > rxParams)
Function for checking the SINR against the link results.
double CalculateCompositeSinr(double sinr1, double sinr2)
Function for calculating the composite SINR.
const bool m_randomAccessEnabled
Is random access enabled for this carrier.
Ptr< SatInterferenceElimination > GetInterferenceEliminationModel()
Get pointer to the current interference elimination model.
SatEnums::RegenerationMode_t m_linkRegenerationMode
Link regeneration mode.
uint32_t GetSatId()
Get ID the ID of the satellite this carrier is attached to.
double m_rxBandwidthHz
RX Bandwidth in Hz.
Mac48Address GetOwnAddress()
Get the MAC address of the carrier.
void EliminateInterference(std::map< uint32_t, std::list< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s >>::iterator iter, SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s processedPacket)
Function for eliminating the interference to other packets in the slot from the correctly received pa...
void BeginEndScheduling()
Function for initializing the frame end scheduling.
void AddCrdsaPacket(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s crdsaPacketParams)
Function for storing the received CRDSA packets.
virtual void ReceiveSlot(SatPhyRxCarrier::rxParams_s packetRxParams, const uint32_t nPackets)
Receive a slot.
virtual void DoDispose()
Dispose implementation.
bool IsReplica(const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &packet, const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &otherPacket) const
Function for identifying whether the packet is a replica of another packet.
TracedCallback< uint32_t, const Address &, bool > m_crdsaUniquePayloadRxTrace
CrdsaUniquePayloadRx trace source.
virtual void PerformSicCycles(std::vector< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s > &combinedPacketsForFrame)
Function for receiving decodable packets and removing their interference from the other packets in th...
double CalculateNormalizedOfferedRandomAccessLoad()
Function for calculating the normalized offered random access load.
TracedCallback< uint32_t, const Address &, bool > m_crdsaReplicaRxTrace
CrdsaReplicaRx trace source.
bool m_frameEndSchedulingInitialized
Has the frame end scheduling been initialized.
std::vector< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s > ProcessFrame()
Function for processing the CRDSA frame.
bool HaveSameSlotIds(const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &packet, const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &otherPacket) const
Function for checking do the packets have identical slots.
void UpdateRandomAccessLoad()
Update the random access load for CRDSA.
double CalculatePacketCompositeSinr(crdsaPacketRxParams_s &packet)
Function for computing the composite SINR of the given packet.
void FindAndRemoveReplicas(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s packet)
Function for finding and removing the replicas of the CRDSA packet.
void MeasureRandomAccessLoad()
Function for measuring the random access load.
SatPhyRxCarrierPerFrame(uint32_t carrierId, Ptr< SatPhyRxCarrierConf > carrierConf, Ptr< SatWaveformConf > waveformConf, bool randomAccessEnabled)
Constructor.
SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s ProcessReceivedCrdsaPacket(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s packet, uint32_t numOfPacketsForThisSlot)
Process received CRDSA packet.
void DoFrameEnd()
Function for processing the frame interval operations.
static bool CompareCrdsaPacketId(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s obj1, SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s obj2)
Function for comparing the CRDSA unique packet IDs.
static TypeId GetTypeId(void)
Get the TypeId of the class.
std::map< uint32_t, std::list< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s > > m_crdsaPacketContainer
CRDSA packet container.
Inherited the base functionality of SatPhyRxCarriers for ground station nodes.
uint8_t GetRandomAccessAllocationChannelId() const
Function for getting the random access allocation channel ID.
virtual void ReceiveSlot(SatPhyRxCarrier::rxParams_s packetRxParams, const uint32_t nPackets)
Receive a slot.
virtual void DoDispose()
Dispose implementation.
void SaveMeasuredRandomAccessLoad(double measuredRandomAccessLoad)
Function for saving the measured random access load.
SatPhyRxCarrierConf::RandomAccessCollisionModel GetRandomAccessCollisionModel() const
Get the random access collision model of the carrier.
bool IsRandomAccessDynamicLoadControlEnabled() const
Check if random access dynamic load control is enabled.
uint32_t m_randomAccessBitsInFrame
The number of random access bits in current frame.
double CalculateAverageNormalizedOfferedRandomAccessLoad()
Function for calculating the average normalized offered random access load.
std::vector< Ptr< Packet > > PacketsInBurst_t
Buffer for transmissions.
static T LinearToDb(T linear)
Converts linear to decibels.
constexpr uint8_t SUPERFRAME_SEQUENCE
Used superframe sequence in the RTN link.
constexpr uint32_t BITS_PER_BYTE
Number of bits in a byte.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.
Struct for storing the packet specific Rx parameters.
Ptr< SatInterference::InterferenceChangeEvent > interferenceEvent
Struct for storing the CRDSA packet specific Rx parameters.