Loading...
Searching...
No Matches
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
40NS_LOG_COMPONENT_DEFINE("SatPhyRxCarrierPerFrame");
41
42namespace ns3
43{
44
45NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerFrame);
46
48 Ptr<SatPhyRxCarrierConf> carrierConf,
49 Ptr<SatWaveformConf> waveformConf,
50 bool randomAccessEnabled)
51 : SatPhyRxCarrierPerSlot(carrierId, carrierConf, waveformConf, randomAccessEnabled),
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
61void
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
96TypeId
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
116void
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 }
132}
133
134void
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
172void
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,
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
259void
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
298void
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
321double
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
343void
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
418std::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
485void
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 }
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
656double
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
693void
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
751void
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
806bool
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
830bool
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
892bool
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.
double m_rxExtNoisePowerW
External noise power system RX noise.
Ptr< SatInterferenceElimination > GetInterferenceEliminationModel()
Get pointer to the current interference elimination model.
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.
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.
Ptr< SatNodeInfo > GetNodeInfo()
Get the satellite node info.
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< SatInterference > GetInterferenceModel()
Get pointer to the current interference 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.
Inherited the functionality of ground station SatPhyRxCarriers and extended it with CRDSA functionali...
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.
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...
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.
uint8_t GetRandomAccessAllocationChannelId() const
Function for getting the random access allocation channel ID.
SatPhyRxCarrierPerSlot(uint32_t carrierId, Ptr< SatPhyRxCarrierConf > carrierConf, Ptr< SatWaveformConf > waveformConf, bool randomAccessEnabled)
Constructor.
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.