29 #include <ns3/boolean.h>
30 #include <ns3/double.h>
32 #include <ns3/simulator.h>
41 NS_LOG_COMPONENT_DEFINE(
"SatPhyRxCarrierPerWindow");
46 NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerWindow);
49 Ptr<SatPhyRxCarrierConf> carrierConf,
50 Ptr<SatWaveformConf> waveformConf,
51 bool randomAccessEnabled)
53 m_windowDuration(MilliSeconds(60)),
54 m_windowStep(MilliSeconds(20)),
55 m_windowDelay(Seconds(0)),
56 m_firstWindow(Seconds(0)),
57 m_windowSicIterations(10),
59 m_windowEndSchedulingInitialized(false),
60 m_detectionThreshold(0.0),
63 NS_LOG_FUNCTION(
this);
64 NS_LOG_INFO(
"Constructor called with arguments " << carrierId <<
", " << carrierConf <<
", and "
65 << randomAccessEnabled);
73 NS_LOG_FUNCTION(
this);
78 NS_FATAL_ERROR(
"SatPhyRxWindow::BeginWindowEndScheduling - m_nodeInfo not set");
85 Simulator::ScheduleWithContext(
GetNodeInfo()->GetNodeId(),
94 NS_LOG_FUNCTION(
this);
101 TypeId(
"ns3::SatPhyRxCarrierPerWindow")
103 .AddAttribute(
"WindowDuration",
104 "The duration of the sliding window",
105 TimeValue(MilliSeconds(60)),
108 .AddAttribute(
"WindowStep",
109 "The length of the step between two window iterations",
110 TimeValue(MilliSeconds(20)),
115 "The delay before processing a sliding window, waiting for incomplete packets",
116 TimeValue(Seconds(0)),
119 .AddAttribute(
"FirstWindow",
120 "The time at which the first window is processed",
121 TimeValue(Seconds(0)),
124 .AddAttribute(
"WindowSICIterations",
125 "The number of SIC iterations performed on each window",
128 MakeUintegerChecker<uint32_t>())
131 .AddAttribute(
"SpreadingFactor",
132 "The spreading factor of the packets",
135 MakeUintegerChecker<uint32_t>())
136 .AddAttribute(
"DetectionThreshold",
137 "The SNIR Detection Threshold (in magnitude) for a packet",
140 MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
141 .AddAttribute(
"EnableSIC",
142 "Use SIC when decoding a packet",
145 MakeBooleanChecker())
148 "Received a packet through Random Access ESSA",
150 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
151 .AddTraceSource(
"EssaRxError",
152 "Received a packet through Random Access ESSA",
154 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
155 .AddTraceSource(
"WindowLoad",
156 "Performed a window load measurement",
158 "ns3::SatPhyRxCarrierPerWindow::WindowLoadTraceCallback");
170 const uint32_t nPackets)
172 NS_ASSERT(packetRxParams.
rxParams->m_txInfo.packetType !=
177 NS_LOG_ERROR(
"SatPhyRxCarrierPerWindow::ReceiveSlot - Time: "
178 << Now().GetSeconds() <<
" - Non ESSA packet received");
182 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::ReceiveSlot - Time: " << Now().GetSeconds()
183 <<
" - ESSA packet received");
205 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::ReceiveSlot - Packet "
206 << params.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
207 << params.
sourceAddress <<
" cannot be detected. Ignore it.");
230 NS_LOG_FUNCTION(
this);
237 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::EliminatePreviousInterferences - Eliminate "
238 "interferences from packet "
239 << packet.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
243 packetList_t::iterator packet_it;
248 if ((packet_it->arrivalTime + packet_it->duration) <= packet.
arrivalTime)
253 if (!(packet_it->hasBeenDecoded))
258 std::pair<double, double> normalizedTimes =
261 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::EliminatePreviousInterferences - eliminate "
262 "interference with packet "
263 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
264 << packet_it->sourceAddress);
271 normalizedTimes.first,
272 normalizedTimes.second);
280 NS_LOG_FUNCTION(
this);
281 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CalculatePacketInterferenceVectors - Packet "
282 << packet.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
302 packet.
rxParams->GetRxNoisePowerInSatellite(),
303 packet.
rxParams->GetRxAciIfPowerInSatellite(),
304 packet.
rxParams->GetRxExtNoisePowerInSatellite(),
305 packet.
rxParams->GetAdditionalInterference());
318 SatSignalParameters::PacketsInBurst_t::const_iterator i;
319 for (i = packets.begin(); i != packets.end(); i++)
322 (*i)->RemovePacketTag(satUplinkInfoTag);
324 (*i)->AddPacketTag(satUplinkInfoTag);
342 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CalculatePacketInterferenceVectors - Received "
348 packet.
gamma.clear();
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;
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++)
369 normalizedTimeInSatellite += interferencePowerInSatellite->first;
372 if (normalizedTimeInSatellite > normalizedTime)
375 normalizedTime += interferencePower->first;
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());
387 double gamma = 1 / (1 / cI + 1 / cSnr);
388 packet.
gamma.emplace_back(interferencePowerInSatellite->first, gamma);
397 double cI = (packet.
rxParams->m_rxPower_W) /
398 (packet.
rxParams->m_rxPower_W + interferencePower->second);
401 double gamma = 1 / (1 / cI + 1 / cSnr);
402 packet.
gamma.emplace_back(1, gamma);
406 std::vector<std::pair<double, double>> gammaPreamble;
408 normalizedTime = 0.0;
409 double normalizedPreambleTime =
410 wf->GetPreambleLengthInSymbols() /
411 wf->GetBurstLengthInSymbols();
413 for (std::vector<std::pair<double, double>>::iterator it = packet.
gamma.begin();
414 it != packet.
gamma.end();
417 if (normalizedTime + it->first > normalizedPreambleTime)
419 gammaPreamble.emplace_back(1.0 - normalizedTime, it->second);
422 gammaPreamble.emplace_back(it->first / normalizedPreambleTime, it->second);
423 normalizedTime += it->first;
436 NS_LOG_FUNCTION(
this);
437 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd");
453 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoProcessWindow - Process window between "
454 << startTime.GetSeconds() <<
" and " << endTime.GetSeconds());
460 std::pair<packetList_t::iterator, packetList_t::iterator> windowBounds =
470 if (packet_it == windowBounds.second)
472 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd - No more packets to decode");
475 packet_it->hasBeenTreatedInWindow =
true;
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;
489 packet_it->sourceAddress,
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]));
503 NS_LOG_INFO(
"Failed to decode packet "
504 << packet_it->sourceAddress <<
"-"
505 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId);
506 packet_it->failedSic =
true;
514 for (packetList_t::iterator packet_it = windowBounds.first; packet_it != windowBounds.second;
518 if (!packet_it->isInsideWindow || !packet_it->hasBeenTreatedInWindow)
522 m_rxCallback(packet_it->rxParams, !packet_it->hasBeenDecoded);
531 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd - Window processing finished");
536 packetList_t::iterator processedPacket,
537 std::pair<packetList_t::iterator, packetList_t::iterator> windowBounds)
539 NS_LOG_FUNCTION(
this);
546 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoSic - eliminate interference from packet "
547 << processedPacket->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
548 << processedPacket->sourceAddress);
551 for (packetList_t::iterator packet_it = windowBounds.first; packet_it != windowBounds.second;
555 if (packet_it->arrivalTime >= processedPacket->arrivalTime + processedPacket->duration)
560 if (packet_it->arrivalTime + packet_it->duration <= processedPacket->arrivalTime)
565 if (packet_it == processedPacket || packet_it->hasBeenDecoded)
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 =
578 processedPacket->rxParams,
581 normalizedTimes.first,
582 normalizedTimes.second);
588 std::pair<double, double>
593 NS_LOG_FUNCTION(
this);
603 double endTimeA = std::min(
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)
625 normalizedTime += ifPower.first;
626 if ((exactStartTime < 0) && (normalizedTime == startTimeA || normalizedTime == startTimeB))
628 exactStartTime = normalizedTime;
630 if ((exactEndTime < 0) && (normalizedTime == endTimeA || normalizedTime == endTimeB))
632 exactEndTime = normalizedTime;
636 if ((exactStartTime < 0) || (exactEndTime < 0))
638 NS_FATAL_ERROR(
"Cannot find exact interference time between two packets");
641 return std::make_pair(exactStartTime, exactEndTime);
648 NS_LOG_FUNCTION(
this);
651 Ptr<SatMutualInformationTable> mutualInformationTable;
652 if (satLinkResults !=
nullptr)
654 mutualInformationTable =
659 mutualInformationTable =
662 double beta = mutualInformationTable->GetBeta();
664 double meanMutualInformation = 0.0;
665 for (std::vector<std::pair<double, double>>::const_iterator it = packet.
gamma.begin();
666 it != packet.
gamma.end();
669 meanMutualInformation += it->first * mutualInformationTable->GetNormalizedSymbolInformation(
673 double effectiveSnir =
676 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetEffectiveSnir - Packet "
680 return effectiveSnir;
686 NS_LOG_FUNCTION(
this);
687 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CleanOldPackets");
693 Time offset = it->arrivalTime - windowStartTime;
694 if (offset.IsStrictlyPositive())
699 offset = it->arrivalTime + it->duration - windowStartTime;
700 if (!offset.IsStrictlyPositive())
705 if (!(it->hasBeenDecoded))
718 !(it->hasBeenDecoded));
721 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CleanOldPackets - Remove packet "
722 << it->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
723 << it->sourceAddress);
724 it->rxParams =
nullptr;
734 std::pair<SatPhyRxCarrierPerWindow::packetList_t::iterator,
735 SatPhyRxCarrierPerWindow::packetList_t::iterator>
738 NS_LOG_FUNCTION(
this);
739 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetWindowBounds");
741 packetList_t::iterator last;
747 last->isInsideWindow =
false;
749 if (last->arrivalTime > endTime)
754 if ((last->arrivalTime >= startTime) && (last->arrivalTime + last->duration <= endTime))
756 last->isInsideWindow =
true;
757 last->hasBeenTreatedInWindow =
false;
760 ->GetWaveform(last->rxParams->m_txInfo.waveformId)
761 ->GetPayloadInBytes();
764 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetWindowBounds - Packet "
765 << last->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
766 << last->sourceAddress <<
" is inside the window");
774 SatPhyRxCarrierPerWindow::packetList_t::iterator
776 const std::pair<SatPhyRxCarrierPerWindow::packetList_t::iterator,
777 SatPhyRxCarrierPerWindow::packetList_t::iterator> windowBounds)
779 NS_LOG_FUNCTION(
this);
780 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetHighestSnirPacket");
782 SatPhyRxCarrierPerWindow::packetList_t::iterator it, max = windowBounds.second;
783 for (it = windowBounds.first; it != windowBounds.second; it++)
785 if (it->hasBeenDecoded || !(it->hasBeenUpdated) || !(it->isInsideWindow))
790 if ((max == windowBounds.second) || (it->meanSinr > max->meanSinr))
802 NS_LOG_FUNCTION(
this);
811 NS_LOG_FUNCTION(
this);
813 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::AddEssaPacket - Add packet "
814 << essaPacketParams.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
816 <<
" Arrival Time: " << essaPacketParams.
arrivalTime.GetSeconds()
817 <<
" Duration: " << essaPacketParams.
duration.GetSeconds());
826 NS_LOG_FUNCTION(
this);
837 NS_LOG_INFO(
"Average normalized offered load: " << averageNormalizedOfferedLoad);
848 averageNormalizedOfferedLoad);
855 NS_LOG_FUNCTION(
this);
860 NS_LOG_INFO(
"Payload Bytes in Window: "
863 <<
", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
865 return normalizedOfferedLoad;
@ PACKET_TYPE_DEDICATED_ACCESS
Ptr< SatMutualInformationTable > GetMutualInformationTable() const
Get the Mutual Information Table.
SatPhy::AverageNormalizedOfferedLoadCallback m_avgNormalizedOfferedLoadCallback
Average normalized offered load callback.
void DoCompositeSinrOutputTrace(double cSinr)
Function for composite SINR output tracing.
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.
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.
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).
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.
double m_rxNoisePowerW
RX noise.
SatEnums::RegenerationMode_t m_linkRegenerationMode
Link regeneration mode.
Ptr< SatWaveformConf > GetWaveformConf()
Get pointer to the waveform configuration.
Ptr< SatLinkResults > GetLinkResults()
Get pointer to the link results given by the carrier creation configuration.
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 base functionality of SatPhyRxCarriers for ground station nodes.
uint8_t GetRandomAccessAllocationChannelId() const
Function for getting the random access allocation channel ID.
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.
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.
uint32_t m_sicEnabled
Enable Sic.
double CalculateNormalizedOfferedRandomAccessLoad()
Function for calculating the normalized offered random access load.
static TypeId GetTypeId(void)
Get the TypeId of the class.
virtual ~SatPhyRxCarrierPerWindow()
Destructor.
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.
Tag to store uplink phy info that need to be forwarded to the downlink.
void SetSinr(double sinr, double additionalInterference)
Set uplink SINR.
static double ScalarProduct(const std::vector< std::pair< double, double >> &vector)
Scalar product.
static T DbToLinear(T db)
Converts decibels to linear.
static T LinearToDb(T linear)
Converts linear to decibels.
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< SatSignalParameters > rxParams
Mac48Address sourceAddress
Struct for storing the E-SSA packet specific Rx parameters.
std::vector< std::pair< double, double > > gamma
Mac48Address sourceAddress
Ptr< SatSignalParameters > rxParams