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 <ostream>
34 #include <utility>
35 
36 NS_LOG_COMPONENT_DEFINE("SatPhyRxCarrierPerFrame");
37 
38 namespace ns3
39 {
40 
41 NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerFrame);
42 
44  Ptr<SatPhyRxCarrierConf> carrierConf,
45  Ptr<SatWaveformConf> waveformConf,
46  bool randomAccessEnabled)
47  : SatPhyRxCarrierPerSlot(carrierId, carrierConf, waveformConf, randomAccessEnabled),
48  m_frameEndSchedulingInitialized(false)
49 {
50  NS_LOG_FUNCTION(this);
51  NS_LOG_INFO("Constructor called with arguments " << carrierId << ", " << carrierConf << ", and "
52  << randomAccessEnabled);
53 
54  NS_ASSERT(m_randomAccessEnabled == true);
55 }
56 
57 void
59 {
60  NS_LOG_FUNCTION(this);
62  {
63  Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
65 
66  if (Now() >= nextSuperFrameRxTime)
67  {
68  NS_FATAL_ERROR("Scheduling next superframe start time to the past!");
69  }
70 
71  Time schedulingDelay = nextSuperFrameRxTime - Now();
72 
73  if (GetNodeInfo() == NULL)
74  {
75  NS_FATAL_ERROR("m_nodeInfo not set");
76  }
77 
79 
80  Simulator::ScheduleWithContext(GetNodeInfo()->GetNodeId(),
81  schedulingDelay,
83  this);
84  }
85 }
86 
88 {
89  NS_LOG_FUNCTION(this);
90 }
91 
92 TypeId
94 {
95  static TypeId tid =
96  TypeId("ns3::SatPhyRxCarrierPerFrame")
97  .SetParent<SatPhyRxCarrierPerSlot>()
98  .AddTraceSource(
99  "CrdsaReplicaRx",
100  "Received a CRDSA packet replica through Random Access",
101  MakeTraceSourceAccessor(&SatPhyRxCarrierPerFrame::m_crdsaReplicaRxTrace),
102  "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
103  .AddTraceSource(
104  "CrdsaUniquePayloadRx",
105  "Received a unique CRDSA payload (after frame processing) "
106  "through Random Access CRDSA",
108  "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback");
109  return tid;
110 }
111 
112 void
114 {
116  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
117 
118  for (iter = m_crdsaPacketContainer.begin(); iter != m_crdsaPacketContainer.end(); iter++)
119  {
120  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
121  for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
122  {
123  iterList->rxParams = NULL;
124  }
125  iter->second.clear();
126  }
127  m_crdsaPacketContainer.clear();
128 }
129 
130 void
132  const uint32_t nPackets)
133 {
134  NS_ASSERT(packetRxParams.rxParams->m_txInfo.packetType !=
136 
137  // If the received random access packet is of type slotted aloha, we
138  // receive the packet with the base class ReceiveSlot method.
139  if (packetRxParams.rxParams->m_txInfo.packetType == SatEnums::PACKET_TYPE_SLOTTED_ALOHA ||
140  packetRxParams.rxParams->m_txInfo.packetType == SatEnums::PACKET_TYPE_LOGON)
141  {
142  SatPhyRxCarrierPerSlot::ReceiveSlot(packetRxParams, nPackets);
143  return;
144  }
145 
146  NS_LOG_INFO("CRDSA packet received");
148 
149  params.destAddress = packetRxParams.destAddress;
150  params.sourceAddress = packetRxParams.sourceAddress;
151  params.rxParams = packetRxParams.rxParams;
152 
154  params.hasCollision = GetInterferenceModel()->HasCollision(packetRxParams.interferenceEvent);
155  params.packetHasBeenProcessed = false;
156 
157  if (nPackets > 0)
158  {
159  m_crdsaReplicaRxTrace(nPackets, // number of packets
160  params.sourceAddress, // sender address
161  params.hasCollision // collision flag
162  );
163  }
164 
165  AddCrdsaPacket(params);
166 }
167 
168 void
170 {
171  NS_LOG_FUNCTION(this);
172 
173  if (!m_crdsaPacketContainer.empty())
174  {
175  // Update the CRDSA random access load for unique payloads!
177 
178  NS_LOG_INFO("Packets in container, will process the frame");
179 
180  std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> results = ProcessFrame();
181 
182  if (!m_crdsaPacketContainer.empty())
183  {
184  NS_FATAL_ERROR("All CRDSA packets in the frame were not processed");
185  }
186 
189  std::sort(results.begin(), results.end(), CompareCrdsaPacketId);
190 
191  for (crdsaPacketRxParams_s& crdsaPacket : results)
192  {
193  NS_LOG_INFO("Sending a packet to the next layer, slot: "
194  << crdsaPacket.ownSlotId << ", UT: " << crdsaPacket.sourceAddress
195  << ", unique CRDSA packet ID: "
196  << crdsaPacket.rxParams->m_txInfo.crdsaUniquePacketId
197  << ", destination address: " << crdsaPacket.destAddress
198  << ", error: " << crdsaPacket.phyError << ", SINR: " << crdsaPacket.cSinr);
199 
200  for (Ptr<Packet>& packetInBurst : crdsaPacket.rxParams->m_packetsInBurst)
201  {
202  NS_LOG_INFO("Fragment (HL packet) UID: " << packetInBurst->GetUid());
203  }
204 
206  m_linkBudgetTrace(crdsaPacket.rxParams,
207  GetOwnAddress(),
208  crdsaPacket.destAddress,
209  crdsaPacket.ifPower,
210  crdsaPacket.cSinr);
213  crdsaPacket.rxParams->m_packetsInBurst.size(), // number of packets
214  crdsaPacket.sourceAddress, // sender address
215  crdsaPacket.phyError // error flag
216  );
217 
218  // Update composite SINR trace for CRDSA packet after combination
219  m_sinrTrace(SatUtils::LinearToDb(crdsaPacket.cSinr), crdsaPacket.sourceAddress);
220 
222  m_rxCallback(crdsaPacket.rxParams, crdsaPacket.phyError);
223 
224  crdsaPacket.rxParams = NULL;
225  }
226 
227  results.clear();
228  }
229 
231  {
233  }
234  else
235  {
236  if (!m_crdsaPacketContainer.empty())
237  {
238  NS_FATAL_ERROR("CRDSA packets received by carrier which has random access disabled");
239  }
240  }
241 
242  Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
244 
245  if (Now() >= nextSuperFrameRxTime)
246  {
247  NS_FATAL_ERROR("Scheduling next superframe start time to the past!");
248  }
249 
250  Time schedulingDelay = nextSuperFrameRxTime - Now();
251 
252  Simulator::Schedule(schedulingDelay, &SatPhyRxCarrierPerFrame::DoFrameEnd, this);
253 }
254 
255 void
257 {
258  NS_LOG_FUNCTION(this);
259 
260  std::vector<uint64_t> uniquePacketIds;
261  uint32_t uniqueCrdsaBytes(0);
262 
263  // Go through all the received CRDSA packets
264  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
265  for (iter = m_crdsaPacketContainer.begin(); iter != m_crdsaPacketContainer.end(); iter++)
266  {
267  // Go through all the packets received in the same slot id
268  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
269  for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
270  {
271  // It is sufficient to check the first packet Uid
272  uint64_t uid = iterList->rxParams->m_packetsInBurst.front()->GetUid();
273 
274  // Check if we have already counted the bytes of this transmission
275  std::vector<uint64_t>::iterator it =
276  std::find(uniquePacketIds.begin(), uniquePacketIds.end(), uid);
277  // Not found -> is unique
278  if (it == uniquePacketIds.end())
279  {
280  // Push this to accounted unique transmissions vector
281  uniquePacketIds.push_back(uid);
282 
283  // Update the load with FEC block size!
284  uniqueCrdsaBytes += iterList->rxParams->m_txInfo.fecBlockSizeInBytes;
285  }
286  // else, do nothing, i.e. this is a replica
287  }
288  }
289 
290  // Update with the unique FEC block sum of CRDSA frame
292 }
293 
294 void
296 {
297  NS_LOG_FUNCTION(this);
298 
300  double normalizedOfferedLoad = CalculateNormalizedOfferedRandomAccessLoad();
301 
303  SaveMeasuredRandomAccessLoad(normalizedOfferedLoad);
304 
306  double averageNormalizedOfferedLoad = CalculateAverageNormalizedOfferedRandomAccessLoad();
307 
308  NS_LOG_INFO("Average normalized offered load: " << averageNormalizedOfferedLoad);
309 
311  GetBeamId(),
312  GetCarrierId(),
314  averageNormalizedOfferedLoad);
315 }
316 
317 double
319 {
320  NS_LOG_FUNCTION(this);
321 
322  Time superFrameDuration = Singleton<SatRtnLinkTime>::Get()->GetSuperFrameDuration(
324 
325  double normalizedOfferedLoad =
326  (m_randomAccessBitsInFrame / superFrameDuration.GetSeconds()) / m_rxBandwidthHz;
327 
328  NS_LOG_INFO("Bits: " << m_randomAccessBitsInFrame
329  << ", frame length in seconds: " << superFrameDuration.GetSeconds()
330  << ", bandwidth in Hz: " << m_rxBandwidthHz
331  << ", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
332 
335 
336  return normalizedOfferedLoad;
337 }
338 
339 void
342 {
343  NS_LOG_FUNCTION(this);
344 
345  if (crdsaPacketParams.rxParams->m_packetsInBurst.size() > 0)
346  {
347  SatCrdsaReplicaTag replicaTag;
348 
350  bool result = crdsaPacketParams.rxParams->m_packetsInBurst[0]->PeekPacketTag(replicaTag);
351 
352  if (!result)
353  {
354  NS_FATAL_ERROR("First packet did not contain a CRDSA replica tag");
355  }
356 
357  std::vector<uint16_t> slotIds = replicaTag.GetSlotIds();
358 
359  if (slotIds.size() < 1)
360  {
361  NS_FATAL_ERROR("The tag did not contain any slot IDs");
362  }
363 
365  crdsaPacketParams.ownSlotId = slotIds[0];
366 
367  if (crdsaPacketParams.slotIdsForOtherReplicas.size() > 0)
368  {
369  NS_FATAL_ERROR("Vector for packet replicas should be empty at this point");
370  }
371 
373  for (uint32_t i = 1; i < slotIds.size(); i++)
374  {
375  crdsaPacketParams.slotIdsForOtherReplicas.push_back(slotIds[i]);
376  }
377 
379  for (uint32_t i = 0; i < crdsaPacketParams.rxParams->m_packetsInBurst.size(); i++)
380  {
381  crdsaPacketParams.rxParams->m_packetsInBurst[i]->RemovePacketTag(replicaTag);
382  }
383  }
384  else
385  {
386  NS_FATAL_ERROR("CRDSA reception with 0 packets");
387  }
388 
389  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator result;
390 
391  result = m_crdsaPacketContainer.find(crdsaPacketParams.ownSlotId);
392 
393  if (result == m_crdsaPacketContainer.end())
394  {
395  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> tempList;
396  tempList.push_back(crdsaPacketParams);
397  m_crdsaPacketContainer.insert(std::make_pair(crdsaPacketParams.ownSlotId, tempList));
398  }
399  else
400  {
401  result->second.push_back(crdsaPacketParams);
402  }
403 
404  NS_LOG_INFO("Packet in slot " << crdsaPacketParams.ownSlotId
405  << " was added to the CRDSA packet container");
406 
407  for (uint32_t i = 0; i < crdsaPacketParams.slotIdsForOtherReplicas.size(); i++)
408  {
409  NS_LOG_INFO("A replica of the packet is in slot "
410  << crdsaPacketParams.slotIdsForOtherReplicas[i]);
411  }
412 }
413 
414 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>
416 {
417  NS_LOG_FUNCTION(this);
418 
419  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
420  std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> combinedPacketsForFrame;
421 
422  // Perform SIC in its entirety, until no more packets can be decoded
423  PerformSicCycles(combinedPacketsForFrame);
424 
425  NS_LOG_INFO("All successfully received packets processed, packets left in container: "
426  << m_crdsaPacketContainer.size());
427 
428  // Cleanup: remove remaining packets from the receive container
429  // and add them to the resulting vector by ensuring that their
430  // phyError is set to true.
431  do
432  {
434  iter = m_crdsaPacketContainer.begin();
435 
436  if (iter != m_crdsaPacketContainer.end())
437  {
438  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList =
439  iter->second.begin();
440 
441  if (iterList != iter->second.end())
442  {
443  NS_LOG_INFO("Processing unsuccessfully received packet in slot: "
444  << iterList->ownSlotId << " packet phy error: " << iterList->phyError
445  << " packet has been processed: " << iterList->packetHasBeenProcessed);
446 
447  if (!iterList->packetHasBeenProcessed || !iterList->phyError)
448  {
449  NS_FATAL_ERROR(
450  "All successfully received packets should have been processed by now");
451  }
452 
454  FindAndRemoveReplicas(*iterList);
455 
457  combinedPacketsForFrame.push_back(*iterList);
458 
460  iter->second.erase(iterList);
461 
463  if (iter->second.empty())
464  {
465  m_crdsaPacketContainer.erase(iter);
466  }
467  }
468  else
469  {
471  m_crdsaPacketContainer.erase(iter);
472  }
473  }
474  } while (!m_crdsaPacketContainer.empty());
475 
476  NS_LOG_INFO("Container processed, packets left: " << m_crdsaPacketContainer.size());
477 
478  return combinedPacketsForFrame;
479 }
480 
481 void
483  std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& combinedPacketsForFrame)
484 {
485  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
487  bool nothingToProcess = true;
488 
489  NS_LOG_INFO("Packets to process: " << m_crdsaPacketContainer.size());
490 
491  do
492  {
493  NS_LOG_INFO("Searching for the next successfully received packet");
494 
496  nothingToProcess = true;
497 
499  for (iter = m_crdsaPacketContainer.begin(); iter != m_crdsaPacketContainer.end(); ++iter)
500  {
501  NS_LOG_INFO("Iterating slot: " << iter->first);
502  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& slotContent = iter->second;
503 
504  if (slotContent.size() < 1)
505  {
506  NS_FATAL_ERROR("No packet in slot! This should not happen");
507  }
508 
509  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator currentPacket;
510 
511  for (currentPacket = slotContent.begin(); currentPacket != slotContent.end();
512  currentPacket++)
513  {
514  NS_LOG_INFO("Iterating packet in slot: " << currentPacket->ownSlotId);
515 
516  if (!currentPacket->packetHasBeenProcessed)
517  {
518  NS_LOG_INFO("Found a packet ready for processing");
519 
521  *currentPacket = ProcessReceivedCrdsaPacket(*currentPacket, slotContent.size());
522 
523  NS_LOG_INFO("Packet error: " << currentPacket->phyError);
524 
526  if (!currentPacket->phyError)
527  {
528  NS_LOG_INFO("Packet successfully received, breaking the slot iteration");
529 
530  nothingToProcess = false;
531 
533  processedPacket = *currentPacket;
534 
536  slotContent.erase(currentPacket);
537 
540  EliminateInterference(iter, processedPacket);
541 
543  break;
544  }
545  }
546  else
547  {
548  NS_LOG_INFO("This packet has already been processed");
549  }
550  }
551 
553  if (!nothingToProcess)
554  {
555  NS_LOG_INFO("Packet successfully received, breaking the container iteration");
556  break;
557  }
558  }
559 
560  if (!nothingToProcess)
561  {
562  NS_LOG_INFO("Packet successfully received, processing the replicas");
563 
565  FindAndRemoveReplicas(processedPacket);
566 
568  combinedPacketsForFrame.push_back(processedPacket);
569  }
570  } while (!nothingToProcess);
571 }
572 
576  uint32_t numOfPacketsForThisSlot)
577 {
578  NS_LOG_FUNCTION(this);
579 
580  NS_LOG_INFO("Processing a packet in slot: " << packet.ownSlotId
581  << " number of packets in this slot: "
582  << numOfPacketsForThisSlot);
583 
584  for (uint32_t i = 0; i < packet.slotIdsForOtherReplicas.size(); i++)
585  {
586  NS_LOG_INFO("Replica in slot: " << packet.slotIdsForOtherReplicas[i]);
587  }
588 
589  NS_LOG_INFO("SINR CALCULATION, RX sat: "
590  << packet.rxParams->GetRxPowerInSatellite()
591  << " IF sat: " << packet.rxParams->GetInterferencePowerInSatellite()
592  << " RX gnd: " << packet.rxParams->m_rxPower_W
593  << " IF gnd: " << packet.rxParams->GetInterferencePower());
594 
595  double sinr = CalculatePacketCompositeSinr(packet);
596 
597  SatSignalParameters::PacketsInBurst_t packets = packet.rxParams->m_packetsInBurst;
598  SatSignalParameters::PacketsInBurst_t::const_iterator i;
599  for (i = packets.begin(); i != packets.end(); i++)
600  {
601  SatUplinkInfoTag satUplinkInfoTag;
602  (*i)->RemovePacketTag(satUplinkInfoTag);
603  satUplinkInfoTag.SetSinr(sinr, m_additionalInterferenceCallback());
604  (*i)->AddPacketTag(satUplinkInfoTag);
605  }
606 
607  /*
608  * Update link specific SINR trace for the RETURN_FEEDER link. The RETURN_USER
609  * link SINR is already updated at the SatPhyRxCarrierUplink::EndRxData ()
610  * method!
611  */
613 
616  {
617  NS_LOG_INFO("Strict collision detection is ENABLED");
618 
620  if (numOfPacketsForThisSlot > 1)
621  {
622  NS_LOG_INFO("Multiple packets in this slot, successful reception is not possible");
624  packet.phyError = true;
625  }
626  else
627  {
628  NS_LOG_INFO("Only packet in this slot, checking against link results");
630  packet.phyError = CheckAgainstLinkResults(packet.cSinr, packet.rxParams);
631  }
632  NS_LOG_INFO("Strict collision detection, phy error: " << packet.phyError);
633  }
634  else if (GetRandomAccessCollisionModel() ==
636  {
638  packet.phyError = CheckAgainstLinkResults(packet.cSinr, packet.rxParams);
639  NS_LOG_INFO("Check against link results, phy error: " << packet.phyError);
640  }
641  else
642  {
643  NS_FATAL_ERROR("Random access collision model not defined");
644  }
645 
647  packet.packetHasBeenProcessed = true;
648 
649  return packet;
650 }
651 
652 double
655 {
656  NS_LOG_FUNCTION(this);
657 
658  double sinr = CalculateSinr(packet.rxParams->m_rxPower_W,
659  packet.rxParams->GetInterferencePower(),
664 
665  double cSinr;
667  {
668  double sinrSatellite = CalculateSinr(packet.rxParams->GetRxPowerInSatellite(),
669  packet.rxParams->GetInterferencePowerInSatellite(),
670  packet.rxParams->GetRxNoisePowerInSatellite(),
671  packet.rxParams->GetRxAciIfPowerInSatellite(),
672  packet.rxParams->GetRxExtNoisePowerInSatellite(),
673  packet.rxParams->GetAdditionalInterference());
674  cSinr = CalculateCompositeSinr(sinr, sinrSatellite);
675  }
676  else
677  {
678  cSinr = sinr;
679  }
680 
681  NS_LOG_INFO("Computed cSINR for packet: " << cSinr);
682 
683  packet.cSinr = cSinr;
684  packet.ifPower = packet.rxParams->GetInterferencePower();
685 
686  return sinr;
687 }
688 
689 void
692 {
693  NS_LOG_FUNCTION(this);
694 
695  for (uint32_t i = 0; i < packet.slotIdsForOtherReplicas.size(); i++)
696  {
697  NS_LOG_INFO("Processing replica in slot: " << packet.slotIdsForOtherReplicas[i]);
698 
700  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator
701  iter;
702  iter = m_crdsaPacketContainer.find(packet.slotIdsForOtherReplicas[i]);
703 
704  if (iter == m_crdsaPacketContainer.end())
705  {
706  NS_FATAL_ERROR("This should not happen");
707  }
708 
709  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
711 
712  bool replicaFound = false;
713 
714  for (iterList = iter->second.begin(); iterList != iter->second.end();)
715  {
717  if (IsReplica(packet, *iterList))
718  {
719  if (replicaFound)
720  {
721  NS_FATAL_ERROR("Found two replica of the same packet in the same slot");
722  }
724  replicaFound = true;
725  removedPacket = *iterList;
726  iter->second.erase(iterList++);
727  }
728  else
729  {
730  ++iterList;
731  }
732  }
733 
734  if (!replicaFound)
735  {
736  NS_FATAL_ERROR("Replica not found");
737  }
738 
739  if (!packet.phyError)
740  {
741  CalculatePacketCompositeSinr(removedPacket);
742  EliminateInterference(iter, removedPacket);
743  }
744  }
745 }
746 
747 void
749  std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter,
751 {
752  NS_LOG_FUNCTION(this);
753 
754  if (iter->second.empty())
755  {
756  NS_LOG_INFO("No other packets in this slot, erasing the slot container");
757  m_crdsaPacketContainer.erase(iter);
758  }
759  else
760  {
761  std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
762 
763  for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
764  {
766  iterList->packetHasBeenProcessed = false;
767 
768  NS_LOG_INFO("BEFORE INTERFERENCE ELIMINATION, RX sat: "
769  << iterList->rxParams->GetRxPowerInSatellite()
770  << " IF sat: " << iterList->rxParams->GetInterferencePowerInSatellite()
771  << " RX gnd: " << iterList->rxParams->m_rxPower_W
772  << " IF gnd: " << iterList->rxParams->GetInterferencePower());
773 
781 
782  if (iterList->rxParams->GetInterferencePower() < 0)
783  {
784  NS_FATAL_ERROR("Negative interference");
785  }
786 
787  GetInterferenceEliminationModel()->EliminateInterferences(iterList->rxParams,
788  processedPacket.rxParams,
789  processedPacket.cSinr,
792 
793  NS_LOG_INFO("AFTER INTERFERENCE ELIMINATION, RX sat: "
794  << iterList->rxParams->GetRxPowerInSatellite()
795  << " IF sat: " << iterList->rxParams->GetInterferencePowerInSatellite()
796  << " RX gnd: " << iterList->rxParams->m_rxPower_W
797  << " IF gnd: " << iterList->rxParams->GetInterferencePower());
798  }
799  }
800 }
801 
802 bool
805  const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s& otherPacket) const
806 {
807  NS_LOG_FUNCTION(this);
808 
809  NS_LOG_INFO("Checking the source addresses");
810 
811  bool isReplica = false;
812 
813  if (otherPacket.sourceAddress == packet.sourceAddress)
814  {
815  NS_LOG_INFO("Same source addresses, checking slot IDs");
816 
817  if (HaveSameSlotIds(packet, otherPacket))
818  {
819  NS_LOG_INFO("Same slot IDs, replica found");
820  isReplica = true;
821  }
822  }
823  return isReplica;
824 }
825 
826 bool
829  const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s& otherPacket) const
830 {
831  NS_LOG_FUNCTION(this);
832 
833  std::set<uint16_t> firstSet;
834  std::set<uint16_t> secondSet;
835  std::set<uint16_t>::iterator firstSetIterator;
836  std::set<uint16_t>::iterator secondSetIterator;
837  bool haveSameSlotIds = true;
838 
839  firstSet.insert(packet.ownSlotId);
840  secondSet.insert(otherPacket.ownSlotId);
841 
843  if (otherPacket.slotIdsForOtherReplicas.size() != packet.slotIdsForOtherReplicas.size())
844  {
845  NS_FATAL_ERROR(
846  "SatPhyRxCarrierUt::HaveSameSlotIds - The amount of replicas does not match");
847  }
848 
849  NS_LOG_INFO("Comparing slot IDs");
850 
852  for (uint32_t i = 0; i < otherPacket.slotIdsForOtherReplicas.size(); i++)
853  {
854  firstSet.insert(packet.slotIdsForOtherReplicas[i]);
855  secondSet.insert(otherPacket.slotIdsForOtherReplicas[i]);
856  }
857 
858  uint32_t numOfMatchingSlots = 0;
859 
861  for (firstSetIterator = firstSet.begin(); firstSetIterator != firstSet.end();
862  firstSetIterator++)
863  {
864  secondSetIterator = secondSet.find(*firstSetIterator);
865 
866  if (secondSetIterator == secondSet.end())
867  {
868  haveSameSlotIds = false;
869  }
870  else
871  {
872  numOfMatchingSlots++;
873  }
874  }
875 
876  NS_LOG_INFO("Are slot IDs identical: " << haveSameSlotIds
877  << ", number of matching slots: " << numOfMatchingSlots);
878 
880  if (!haveSameSlotIds && numOfMatchingSlots > 0)
881  {
882  NS_FATAL_ERROR("Partially overlapping CRDSA slots");
883  }
884 
885  return haveSameSlotIds;
886 }
887 
888 bool
891 {
892  return (bool)(obj1.rxParams->m_txInfo.crdsaUniquePacketId <
893  obj2.rxParams->m_txInfo.crdsaUniquePacketId);
894 }
895 
896 } // 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.