Loading...
Searching...
No Matches
satellite-phy-rx-carrier-per-window.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2018 CNES
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Joaquin Muguerza <jmuguerza@toulouse.viveris.fr>
19 */
20
22
26#include "satellite-utils.h"
28
29#include "ns3/boolean.h"
30#include "ns3/double.h"
31#include "ns3/log.h"
32#include "ns3/simulator.h"
33
34#include <algorithm>
35#include <iomanip>
36#include <limits>
37#include <ostream>
38#include <utility>
39#include <vector>
40
41NS_LOG_COMPONENT_DEFINE("SatPhyRxCarrierPerWindow");
42
43namespace ns3
44{
45
46NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerWindow);
47
49 Ptr<SatPhyRxCarrierConf> carrierConf,
50 Ptr<SatWaveformConf> waveformConf,
51 bool randomAccessEnabled)
52 : SatPhyRxCarrierPerSlot(carrierId, carrierConf, waveformConf, randomAccessEnabled),
53 m_windowDuration(MilliSeconds(60)),
54 m_windowStep(MilliSeconds(20)),
55 m_windowDelay(Seconds(0)),
56 m_firstWindow(Seconds(0)),
61 m_sicEnabled(true)
62{
63 NS_LOG_FUNCTION(this);
64 NS_LOG_INFO("Constructor called with arguments " << carrierId << ", " << carrierConf << ", and "
65 << randomAccessEnabled);
66
67 NS_ASSERT(m_randomAccessEnabled == true);
68}
69
70void
72{
73 NS_LOG_FUNCTION(this);
75 {
76 if (GetNodeInfo() == nullptr)
77 {
78 NS_FATAL_ERROR("SatPhyRxWindow::BeginWindowEndScheduling - m_nodeInfo not set");
79 }
80
82
85 Simulator::ScheduleWithContext(GetNodeInfo()->GetNodeId(),
88 this);
89 }
90}
91
93{
94 NS_LOG_FUNCTION(this);
95}
96
97TypeId
99{
100 static TypeId tid =
101 TypeId("ns3::SatPhyRxCarrierPerWindow")
102 .SetParent<SatPhyRxCarrierPerSlot>()
103 .AddAttribute("WindowDuration",
104 "The duration of the sliding window",
105 TimeValue(MilliSeconds(60)),
107 MakeTimeChecker())
108 .AddAttribute("WindowStep",
109 "The length of the step between two window iterations",
110 TimeValue(MilliSeconds(20)),
112 MakeTimeChecker())
113 .AddAttribute(
114 "WindowDelay",
115 "The delay before processing a sliding window, waiting for incomplete packets",
116 TimeValue(Seconds(0)),
118 MakeTimeChecker())
119 .AddAttribute("FirstWindow",
120 "The time at which the first window is processed",
121 TimeValue(Seconds(0)),
123 MakeTimeChecker())
124 .AddAttribute("WindowSICIterations",
125 "The number of SIC iterations performed on each window",
126 UintegerValue(10),
128 MakeUintegerChecker<uint32_t>())
129 // TODO: this shouldn't be here!! find a way to retrieve SF from SuperFrameConf,
130 // maybe store SF in waveform.
131 .AddAttribute("SpreadingFactor",
132 "The spreading factor of the packets",
133 UintegerValue(1),
134 MakeUintegerAccessor(&SatPhyRxCarrierPerWindow::m_spreadingFactor),
135 MakeUintegerChecker<uint32_t>())
136 .AddAttribute("DetectionThreshold",
137 "The SNIR Detection Threshold (in magnitude) for a packet",
138 DoubleValue(0.0),
140 MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
141 .AddAttribute("EnableSIC",
142 "Use SIC when decoding a packet",
143 BooleanValue(true),
144 MakeBooleanAccessor(&SatPhyRxCarrierPerWindow::m_sicEnabled),
145 MakeBooleanChecker())
146 .AddTraceSource(
147 "EssaRxCollision",
148 "Received a packet through Random Access ESSA",
149 MakeTraceSourceAccessor(&SatPhyRxCarrierPerWindow::m_essaRxCollisionTrace),
150 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
151 .AddTraceSource("EssaRxError",
152 "Received a packet through Random Access ESSA",
153 MakeTraceSourceAccessor(&SatPhyRxCarrierPerWindow::m_essaRxErrorTrace),
154 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
155 .AddTraceSource("WindowLoad",
156 "Performed a window load measurement",
157 MakeTraceSourceAccessor(&SatPhyRxCarrierPerWindow::m_windowLoadTrace),
158 "ns3::SatPhyRxCarrierPerWindow::WindowLoadTraceCallback");
159 return tid;
160}
161
162void
167
168void
170 const uint32_t nPackets)
171{
172 NS_ASSERT(packetRxParams.rxParams->m_txInfo.packetType !=
174
175 if (packetRxParams.rxParams->m_txInfo.packetType != SatEnums::PACKET_TYPE_ESSA)
176 {
177 NS_LOG_ERROR("SatPhyRxCarrierPerWindow::ReceiveSlot - Time: "
178 << Now().GetSeconds() << " - Non ESSA packet received");
179 return;
180 }
181
182 NS_LOG_INFO("SatPhyRxCarrierPerWindow::ReceiveSlot - Time: " << Now().GetSeconds()
183 << " - ESSA packet received");
184
186
187 params.destAddress = packetRxParams.destAddress;
188 params.sourceAddress = packetRxParams.sourceAddress;
189 params.duration = packetRxParams.rxParams->m_duration;
190 params.arrivalTime = Now() - params.duration; // arrival time is the start of reception
191 params.rxParams = packetRxParams.rxParams;
192 params.hasBeenDecoded = false;
193 params.failedSic = false;
194 params.hasBeenUpdated = false;
195 params.isInsideWindow = false;
196 params.meanSinr = -1.0;
197 params.preambleMeanSinr = -1.0;
198
199 // Calculate SINR, gamma and ifPowerPerFragment
201
202 // Check if packet can be detected
203 if (!PacketCanBeDetected(params))
204 {
205 NS_LOG_INFO("SatPhyRxCarrierPerWindow::ReceiveSlot - Packet "
206 << params.rxParams->m_txInfo.crdsaUniquePacketId << " from "
207 << params.sourceAddress << " cannot be detected. Ignore it.");
209 m_essaRxCollisionTrace(1, // number of packets
210 params.sourceAddress, // sender address
211 1); // error flag
212 return;
213 }
214
215 // Eliminate interference from already decoded packets
216 // WARNING: with some combinations of window size and step, it may be possible that
217 // previously decoded packets have already been cleaned.
219
220 // Calculate SINR, gamma and ifPowerPerFragment
222
223 AddEssaPacket(params);
224}
225
226void
229{
230 NS_LOG_FUNCTION(this);
231
232 if (!m_sicEnabled)
233 {
234 return;
235 }
236
237 NS_LOG_INFO("SatPhyRxCarrierPerWindow::EliminatePreviousInterferences - Eliminate "
238 "interferences from packet "
239 << packet.rxParams->m_txInfo.crdsaUniquePacketId << " from "
240 << packet.sourceAddress);
241
242 // Get which packets that have been decoded interfere with this packet
243 packetList_t::iterator packet_it;
244 for (packet_it = m_essaPacketContainer.begin(); packet_it != m_essaPacketContainer.end();
245 packet_it++)
246 {
248 if ((packet_it->arrivalTime + packet_it->duration) <= packet.arrivalTime)
249 {
250 continue;
251 }
253 if (!(packet_it->hasBeenDecoded))
254 {
255 continue;
256 }
258 std::pair<double, double> normalizedTimes =
259 GetNormalizedPacketInterferenceTime(packet, *packet_it);
260
261 NS_LOG_INFO("SatPhyRxCarrierPerWindow::EliminatePreviousInterferences - eliminate "
262 "interference with packet "
263 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId << " from "
264 << packet_it->sourceAddress);
266 GetInterferenceEliminationModel()->EliminateInterferences(
267 packet.rxParams,
268 packet_it->rxParams,
269 packet_it->meanSinr * m_spreadingFactor,
271 normalizedTimes.first,
272 normalizedTimes.second);
273 }
274}
275
276void
279{
280 NS_LOG_FUNCTION(this);
281 NS_LOG_INFO("SatPhyRxCarrierPerWindow::CalculatePacketInterferenceVectors - Packet "
282 << packet.rxParams->m_txInfo.crdsaUniquePacketId << " from "
283 << packet.sourceAddress);
284
285 // TODO: should we check the interference model used ?
286 // TODO: should we check the collision model used (check against sinr, collision always drops,
287 // etc) ?
288
289 double snr = CalculateSinr(packet.rxParams->m_rxPower_W,
290 0.0,
295
296 double cSnr;
298 {
300 double snrSatellite = CalculateSinr(packet.rxParams->GetRxPowerInSatellite(),
301 0.0,
302 packet.rxParams->GetRxNoisePowerInSatellite(),
303 packet.rxParams->GetRxAciIfPowerInSatellite(),
304 packet.rxParams->GetRxExtNoisePowerInSatellite(),
305 packet.rxParams->GetAdditionalInterference());
306
307 cSnr = CalculateCompositeSinr(snr, snrSatellite);
308 }
309 else
310 {
311 cSnr = snr;
312 }
313
315 if (packet.meanSinr < 0.0)
316 {
317 SatSignalParameters::PacketsInBurst_t packets = packet.rxParams->m_packetsInBurst;
318 SatSignalParameters::PacketsInBurst_t::const_iterator i;
319 for (i = packets.begin(); i != packets.end(); i++)
320 {
321 SatUplinkInfoTag satUplinkInfoTag;
322 (*i)->RemovePacketTag(satUplinkInfoTag);
323 satUplinkInfoTag.SetSinr(snr, m_additionalInterferenceCallback());
324 (*i)->AddPacketTag(satUplinkInfoTag);
325 }
326
327 // Update link specific SINR trace
329
330 // Update composite SNR trace for DAMA and Slotted ALOHA packets
331 // m_sinrTrace (SatUtils::LinearToDb (cSnr), packet.sourceAddress); // Done with effective
332 // SINR
333
334 m_linkBudgetTrace(packet.rxParams, GetOwnAddress(), packet.destAddress, 0.0, cSnr);
335
338 {
340 }
341
342 NS_LOG_INFO("SatPhyRxCarrierPerWindow::CalculatePacketInterferenceVectors - Received "
343 "packet SNR dB = "
344 << SatUtils::LinearToDb(cSnr));
345 }
346
348 packet.gamma.clear();
349
350 std::vector<std::pair<double, double>> interferencePowerPerFragment =
351 packet.rxParams->GetInterferencePowerPerFragment();
352 std::vector<std::pair<double, double>>::iterator interferencePower =
353 interferencePowerPerFragment.begin();
354 double normalizedTime = interferencePower->first, normalizedTimeInSatellite = 0.0;
361 {
362 std::vector<std::pair<double, double>> interferencePowerPerFragmentInSatellite =
363 packet.rxParams->GetInterferencePowerInSatellitePerFragment();
364 for (std::vector<std::pair<double, double>>::iterator interferencePowerInSatellite =
365 interferencePowerPerFragmentInSatellite.begin();
366 interferencePowerInSatellite != interferencePowerPerFragmentInSatellite.end();
367 interferencePowerInSatellite++)
368 {
369 normalizedTimeInSatellite += interferencePowerInSatellite->first;
372 if (normalizedTimeInSatellite > normalizedTime)
373 {
374 interferencePower++;
375 normalizedTime += interferencePower->first;
376 }
377
380
382 double cI = (packet.rxParams->GetRxPowerInSatellite() * packet.rxParams->m_rxPower_W) /
383 (interferencePowerInSatellite->second * packet.rxParams->m_rxPower_W +
384 interferencePower->second * packet.rxParams->GetRxPowerInSatellite());
385
387 double gamma = 1 / (1 / cI + 1 / cSnr);
388 packet.gamma.emplace_back(interferencePowerInSatellite->first, gamma);
389 }
390 }
391 else
392 {
395
397 double cI = (packet.rxParams->m_rxPower_W) /
398 (packet.rxParams->m_rxPower_W + interferencePower->second);
399
401 double gamma = 1 / (1 / cI + 1 / cSnr);
402 packet.gamma.emplace_back(1, gamma);
403 }
404
406 std::vector<std::pair<double, double>> gammaPreamble;
407 Ptr<SatWaveform> wf = GetWaveformConf()->GetWaveform(packet.rxParams->m_txInfo.waveformId);
408 normalizedTime = 0.0;
409 double normalizedPreambleTime =
410 wf->GetPreambleLengthInSymbols() /
411 wf->GetBurstLengthInSymbols(); // This asumes that preamble and burst have the same symbol
412 // rate
413 for (std::vector<std::pair<double, double>>::iterator it = packet.gamma.begin();
414 it != packet.gamma.end();
415 it++)
416 {
417 if (normalizedTime + it->first > normalizedPreambleTime)
418 {
419 gammaPreamble.emplace_back(1.0 - normalizedTime, it->second);
420 break;
421 }
422 gammaPreamble.emplace_back(it->first / normalizedPreambleTime, it->second);
423 normalizedTime += it->first;
424 }
425
427 packet.meanSinr = SatUtils::ScalarProduct(packet.gamma);
428 packet.preambleMeanSinr = SatUtils::ScalarProduct(gammaPreamble);
429
430 packet.hasBeenUpdated = true;
431}
432
433void
435{
436 NS_LOG_FUNCTION(this);
437 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoWindowEnd");
438
439 // ProcessWindow (Now () - m_windowDuration, Now ());
440 Simulator::Schedule(m_windowDelay,
442 this,
443 Now() - m_windowDuration,
444 Now());
445
446 // Advance the window (schedule DoWindowEnd for m_windowStep)
447 Simulator::Schedule(m_windowStep, &SatPhyRxCarrierPerWindow::DoWindowEnd, this);
448}
449
450void
451SatPhyRxCarrierPerWindow::ProcessWindow(Time startTime, Time endTime)
452{
453 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoProcessWindow - Process window between "
454 << startTime.GetSeconds() << " and " << endTime.GetSeconds());
455
457 CleanOldPackets(startTime);
458
460 std::pair<packetList_t::iterator, packetList_t::iterator> windowBounds =
461 GetWindowBounds(startTime, endTime);
462
463 uint32_t i = 0;
464 while (i < m_windowSicIterations)
465 {
466 while (true)
467 {
469 packetList_t::iterator packet_it = GetHighestSnirPacket(windowBounds);
470 if (packet_it == windowBounds.second)
471 {
472 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoWindowEnd - No more packets to decode");
473 break;
474 }
475 packet_it->hasBeenTreatedInWindow = true;
476
477 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoWindowEnd - Process packet "
478 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId << " from "
479 << packet_it->sourceAddress);
481 packet_it->hasBeenUpdated = false;
483 double sinrEffective = GetEffectiveSnir(*packet_it);
484 m_sinrTrace(SatUtils::LinearToDb(sinrEffective), packet_it->sourceAddress);
486 bool phyError = CheckAgainstLinkResults(sinrEffective, packet_it->rxParams);
487 // Trace if the packet has been decoded or not
488 m_essaRxErrorTrace(1, // number of packets
489 packet_it->sourceAddress, // sender address
490 phyError); // error flag
491 if (!phyError)
492 {
493 packet_it->hasBeenDecoded = true;
495 DoSic(packet_it, windowBounds);
497 NS_LOG_WARN("received " << packet_it->sourceAddress << " "
498 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId << " "
499 << " INFO " << *(packet_it->rxParams->m_packetsInBurst[0]));
500 }
501 else
502 {
503 NS_LOG_INFO("Failed to decode packet "
504 << packet_it->sourceAddress << "-"
505 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId);
506 packet_it->failedSic = true;
507 }
508 }
509
510 // increase iteration number
511 i++;
512 }
514 for (packetList_t::iterator packet_it = windowBounds.first; packet_it != windowBounds.second;
515 packet_it++)
516 {
518 if (!packet_it->isInsideWindow || !packet_it->hasBeenTreatedInWindow)
519 {
520 continue;
521 }
522 m_rxCallback(packet_it->rxParams, !packet_it->hasBeenDecoded);
525 }
528 {
530 }
531 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoWindowEnd - Window processing finished");
532}
533
534void
536 packetList_t::iterator processedPacket,
537 std::pair<packetList_t::iterator, packetList_t::iterator> windowBounds)
538{
539 NS_LOG_FUNCTION(this);
540
541 if (!m_sicEnabled)
542 {
543 return;
544 }
545
546 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoSic - eliminate interference from packet "
547 << processedPacket->rxParams->m_txInfo.crdsaUniquePacketId << " from "
548 << processedPacket->sourceAddress);
549
551 for (packetList_t::iterator packet_it = windowBounds.first; packet_it != windowBounds.second;
552 packet_it++)
553 {
555 if (packet_it->arrivalTime >= processedPacket->arrivalTime + processedPacket->duration)
556 {
557 break;
558 }
560 if (packet_it->arrivalTime + packet_it->duration <= processedPacket->arrivalTime)
561 {
562 continue;
563 }
565 if (packet_it == processedPacket || packet_it->hasBeenDecoded)
566 {
567 continue;
568 }
569 NS_LOG_INFO("SatPhyRxCarrierPerWindow::DoSic - eliminate interference with packet "
570 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId << " from "
571 << packet_it->sourceAddress);
573 std::pair<double, double> normalizedTimes =
574 GetNormalizedPacketInterferenceTime(*packet_it, *processedPacket);
576 GetInterferenceEliminationModel()->EliminateInterferences(
577 packet_it->rxParams,
578 processedPacket->rxParams,
579 processedPacket->meanSinr * m_spreadingFactor,
581 normalizedTimes.first,
582 normalizedTimes.second);
583
585 }
586}
587
588std::pair<double, double>
591 const SatPhyRxCarrierPerWindow::essaPacketRxParams_s& interferingPacket)
592{
593 NS_LOG_FUNCTION(this);
594
598 double startTimeA =
599 std::max(0.0,
600 1.0 - ((packet.duration.GetDouble() + packet.arrivalTime.GetDouble() -
601 interferingPacket.arrivalTime.GetDouble()) /
602 packet.duration.GetDouble()));
603 double endTimeA = std::min(
604 1.0,
605 1.0 - (packet.arrivalTime.GetDouble() - interferingPacket.arrivalTime.GetDouble()) /
606 packet.duration.GetDouble());
607 double startTimeB =
608 std::max(0.0,
609 (interferingPacket.arrivalTime.GetDouble() - packet.arrivalTime.GetDouble()) /
610 packet.duration.GetDouble());
611 double endTimeB =
612 std::min(1.0,
613 2.0 - (packet.arrivalTime.GetDouble() - interferingPacket.arrivalTime.GetDouble() +
614 packet.duration.GetDouble()) /
615 packet.duration.GetDouble());
616
618 // some rounding errors)
619 double normalizedTime = 0.0;
620 double exactStartTime = (startTimeA == 0.0) ? 0.0 : -1.0;
621 double exactEndTime = -1.0;
622 auto ifPowerPerFragment = packet.rxParams->GetInterferencePowerInSatellitePerFragment();
623 for (std::pair<double, double>& ifPower : ifPowerPerFragment)
624 {
625 normalizedTime += ifPower.first;
626 if ((exactStartTime < 0) && (normalizedTime == startTimeA || normalizedTime == startTimeB))
627 {
628 exactStartTime = normalizedTime;
629 }
630 if ((exactEndTime < 0) && (normalizedTime == endTimeA || normalizedTime == endTimeB))
631 {
632 exactEndTime = normalizedTime;
633 }
634 }
635
636 if ((exactStartTime < 0) || (exactEndTime < 0))
637 {
638 NS_FATAL_ERROR("Cannot find exact interference time between two packets");
639 }
640
641 return std::make_pair(exactStartTime, exactEndTime);
642}
643
644double
647{
648 NS_LOG_FUNCTION(this);
649
650 Ptr<SatLinkResultsRtn> satLinkResults = GetLinkResults()->GetObject<SatLinkResultsFSim>();
651 Ptr<SatMutualInformationTable> mutualInformationTable;
652 if (satLinkResults != nullptr)
653 {
654 mutualInformationTable =
655 (GetLinkResults()->GetObject<SatLinkResultsFSim>())->GetMutualInformationTable();
656 }
657 else
658 {
659 mutualInformationTable =
660 (GetLinkResults()->GetObject<SatLinkResultsLora>())->GetMutualInformationTable();
661 }
662 double beta = mutualInformationTable->GetBeta();
663
664 double meanMutualInformation = 0.0;
665 for (std::vector<std::pair<double, double>>::const_iterator it = packet.gamma.begin();
666 it != packet.gamma.end();
667 it++)
668 {
669 meanMutualInformation += it->first * mutualInformationTable->GetNormalizedSymbolInformation(
670 SatUtils::LinearToDb(it->second / beta));
671 }
672
673 double effectiveSnir =
674 beta * SatUtils::DbToLinear(mutualInformationTable->GetSnirDb(meanMutualInformation));
675
676 NS_LOG_INFO("SatPhyRxCarrierPerWindow::GetEffectiveSnir - Packet "
677 << packet.rxParams->m_txInfo.crdsaUniquePacketId << " from " << packet.sourceAddress
678 << " - Effective SNIR dB: " << SatUtils::LinearToDb(effectiveSnir));
679
680 return effectiveSnir;
681}
682
683void
685{
686 NS_LOG_FUNCTION(this);
687 NS_LOG_INFO("SatPhyRxCarrierPerWindow::CleanOldPackets");
688
689 packetList_t::iterator it = m_essaPacketContainer.begin();
690 while (it != m_essaPacketContainer.end())
691 {
693 Time offset = it->arrivalTime - windowStartTime;
694 if (offset.IsStrictlyPositive())
695 {
696 break;
697 }
699 offset = it->arrivalTime + it->duration - windowStartTime;
700 if (!offset.IsStrictlyPositive())
701 {
702 // Only trace packets that arrived after first Window
703 if (it->arrivalTime >= m_firstWindow)
704 {
705 if (!(it->hasBeenDecoded))
706 {
707 }
708 else
709 {
710 m_daRxTrace(1, // number of packets
711 it->sourceAddress, // sender address
712 it->failedSic // error flag
713 );
714 }
715 // Trace if the packet has been decoded or not
716 m_essaRxCollisionTrace(1, // number of packets
717 it->sourceAddress, // sender address
718 !(it->hasBeenDecoded)); // error flag
719 }
720 // Delete element from list
721 NS_LOG_INFO("SatPhyRxCarrierPerWindow::CleanOldPackets - Remove packet "
722 << it->rxParams->m_txInfo.crdsaUniquePacketId << " from "
723 << it->sourceAddress);
724 it->rxParams = nullptr;
725 m_essaPacketContainer.erase(it++);
726 }
727 else
728 {
729 ++it;
730 }
731 }
732}
733
734std::pair<SatPhyRxCarrierPerWindow::packetList_t::iterator,
735 SatPhyRxCarrierPerWindow::packetList_t::iterator>
736SatPhyRxCarrierPerWindow::GetWindowBounds(Time startTime, Time endTime)
737{
738 NS_LOG_FUNCTION(this);
739 NS_LOG_INFO("SatPhyRxCarrierPerWindow::GetWindowBounds");
740
741 packetList_t::iterator last;
743
744 for (last = m_essaPacketContainer.begin(); last != m_essaPacketContainer.end(); last++)
745 {
747 last->isInsideWindow = false;
749 if (last->arrivalTime > endTime)
750 {
751 break;
752 }
754 if ((last->arrivalTime >= startTime) && (last->arrivalTime + last->duration <= endTime))
755 {
756 last->isInsideWindow = true;
757 last->hasBeenTreatedInWindow = false;
760 ->GetWaveform(last->rxParams->m_txInfo.waveformId)
761 ->GetPayloadInBytes();
762 }
763
764 NS_LOG_INFO("SatPhyRxCarrierPerWindow::GetWindowBounds - Packet "
765 << last->rxParams->m_txInfo.crdsaUniquePacketId << " from "
766 << last->sourceAddress << " is inside the window");
767 }
768
771 return std::make_pair(m_essaPacketContainer.begin(), last);
772}
773
774SatPhyRxCarrierPerWindow::packetList_t::iterator
776 const std::pair<SatPhyRxCarrierPerWindow::packetList_t::iterator,
777 SatPhyRxCarrierPerWindow::packetList_t::iterator> windowBounds)
778{
779 NS_LOG_FUNCTION(this);
780 NS_LOG_INFO("SatPhyRxCarrierPerWindow::GetHighestSnirPacket");
781
782 SatPhyRxCarrierPerWindow::packetList_t::iterator it, max = windowBounds.second;
783 for (it = windowBounds.first; it != windowBounds.second; it++)
784 {
785 if (it->hasBeenDecoded || !(it->hasBeenUpdated) || !(it->isInsideWindow))
786 {
787 continue;
788 }
790 if ((max == windowBounds.second) || (it->meanSinr > max->meanSinr))
791 {
792 max = it;
793 }
794 }
795 return max;
796}
797
798bool
801{
802 NS_LOG_FUNCTION(this);
803
804 return (packet.preambleMeanSinr >= m_detectionThreshold);
805}
806
807void
810{
811 NS_LOG_FUNCTION(this);
812
813 NS_LOG_INFO("SatPhyRxCarrierPerWindow::AddEssaPacket - Add packet "
814 << essaPacketParams.rxParams->m_txInfo.crdsaUniquePacketId << " from "
815 << essaPacketParams.sourceAddress
816 << " Arrival Time: " << essaPacketParams.arrivalTime.GetSeconds()
817 << " Duration: " << essaPacketParams.duration.GetSeconds());
818
820 m_essaPacketContainer.push_back(essaPacketParams);
821}
822
823void
825{
826 NS_LOG_FUNCTION(this);
827
829 double normalizedOfferedLoad = CalculateNormalizedOfferedRandomAccessLoad();
830
832 SaveMeasuredRandomAccessLoad(normalizedOfferedLoad);
833
835 double averageNormalizedOfferedLoad = CalculateAverageNormalizedOfferedRandomAccessLoad();
836
837 NS_LOG_INFO("Average normalized offered load: " << averageNormalizedOfferedLoad);
838
840 m_windowLoadTrace(normalizedOfferedLoad);
841
843 {
845 GetBeamId(),
846 GetCarrierId(),
848 averageNormalizedOfferedLoad);
849 }
850}
851
852double
854{
855 NS_LOG_FUNCTION(this);
856
857 double normalizedOfferedLoad = m_payloadBytesInWindow * SatConstVariables::BITS_PER_BYTE /
858 m_windowDuration.GetSeconds() / m_rxBandwidthHz;
859
860 NS_LOG_INFO("Payload Bytes in Window: "
861 << m_payloadBytesInWindow << ", Window duration in seconds: "
862 << m_windowDuration.GetSeconds() << ", Bandwidth in Hz: " << m_rxBandwidthHz
863 << ", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
864
865 return normalizedOfferedLoad;
866}
867
868} // namespace ns3
SatPhy::AverageNormalizedOfferedLoadCallback m_avgNormalizedOfferedLoadCallback
Average normalized offered load callback.
Ptr< SatLinkResults > GetLinkResults()
Get pointer to the link results given by the carrier creation configuration.
void DoCompositeSinrOutputTrace(double cSinr)
Function for composite SINR output tracing.
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.
virtual SatEnums::ChannelType_t GetChannelType()
Get the channel type.
bool IsCompositeSinrOutputTraceEnabled() const
Check if composite SINR output trace is enabled.
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.
TracedCallback< uint32_t, const Address &, bool > m_daRxTrace
DaRx trace source.
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).
Ptr< SatWaveformConf > GetWaveformConf()
Get pointer to the waveform configuration.
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.
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.
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 DoDispose()
Dispose implementation.
void SaveMeasuredRandomAccessLoad(double measuredRandomAccessLoad)
Function for saving the measured random access load.
bool IsRandomAccessDynamicLoadControlEnabled() const
Check if random access dynamic load control is enabled.
double CalculateAverageNormalizedOfferedRandomAccessLoad()
Function for calculating the average normalized offered random access load.
Inherited the functionality of ground station SatPhyRxCarriers and extended it with CRDSA functionali...
bool m_windowEndSchedulingInitialized
Has the window end scheduling been initialized.
void BeginEndScheduling()
Function for initializing the window end scheduling.
uint32_t m_payloadBytesInWindow
The number of payload bytes in the window.
void CleanOldPackets(const Time windowStartTime)
Remove old packets from packet container.
Time m_windowDuration
The duration of the sliding window.
void CalculatePacketInterferenceVectors(SatPhyRxCarrierPerWindow::essaPacketRxParams_s &packet)
Calculate gamma and Interference vectors for a single packet.
void AddEssaPacket(SatPhyRxCarrierPerWindow::essaPacketRxParams_s essaPacketParams)
Function for storing the received E-SSA packets.
double GetEffectiveSnir(const SatPhyRxCarrierPerWindow::essaPacketRxParams_s &packet)
Get the effective SNIR of the packet using the Mutual Information function.
virtual void ReceiveSlot(SatPhyRxCarrier::rxParams_s packetRxParams, const uint32_t nPackets)
Receive a slot.
double CalculateNormalizedOfferedRandomAccessLoad()
Function for calculating the normalized offered random access load.
static TypeId GetTypeId(void)
Get the TypeId of the class.
Time m_windowDelay
The delay before processing a sliding window.
void DoWindowEnd()
Function called when a window ends.
TracedCallback< uint32_t, const Address &, bool > m_essaRxErrorTrace
EssaRxError trace source.
Time m_firstWindow
The time of the first window.
void MeasureRandomAccessLoad()
Function for measuring the random access load.
std::pair< double, double > GetNormalizedPacketInterferenceTime(const SatPhyRxCarrierPerWindow::essaPacketRxParams_s &packet, const SatPhyRxCarrierPerWindow::essaPacketRxParams_s &interferingPacket)
Get the normalized start and end time between two interfering packets.
SatPhyRxCarrierPerWindow(uint32_t carrierId, Ptr< SatPhyRxCarrierConf > carrierConf, Ptr< SatWaveformConf > waveformConf, bool randomAccessEnabled)
Constructor.
bool PacketCanBeDetected(const SatPhyRxCarrierPerWindow::essaPacketRxParams_s &packet)
Function for processing a window.
double m_detectionThreshold
SNIR detection threshold for a packet (in magnitude).
virtual void DoDispose()
Dispose implementation.
void EliminatePreviousInterferences(SatPhyRxCarrierPerWindow::essaPacketRxParams_s &packet)
Calculate gamma and Interference vectors for a single packet.
std::pair< packetList_t::iterator, packetList_t::iterator > GetWindowBounds(Time startTime, Time endTime)
Get a pair of iterators, pointing to the first element in the window, and to the first after the wind...
void DoSic(packetList_t::iterator processedPacket, std::pair< packetList_t::iterator, packetList_t::iterator > windowBounds)
Perform SIC for a given decoded packet.
Time m_windowStep
The step of the sliding window.
packetList_t m_essaPacketContainer
ESSA packet container.
uint32_t m_spreadingFactor
The spreading factor of packets.
packetList_t::iterator GetHighestSnirPacket(const std::pair< packetList_t::iterator, packetList_t::iterator > windowBounds)
Get the packet with the highst SNIR on the list.
uint32_t m_windowSicIterations
The number of SIC iterations performed on each window.
TracedCallback< double > m_windowLoadTrace
WindowLoad trace source.
TracedCallback< uint32_t, const Address &, bool > m_essaRxCollisionTrace
EssaRxError trace source.
void ProcessWindow(Time startTime, Time endTime)
Function for processing a window.
std::vector< Ptr< Packet > > PacketsInBurst_t
Buffer for transmissions.
static T DbToLinear(T db)
Converts decibels to linear.
static T LinearToDb(T linear)
Converts linear to decibels.
static double ScalarProduct(const std::vector< std::pair< double, double > > &vector)
Scalar product.
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.
Struct for storing the E-SSA packet specific Rx parameters.