29 #include <ns3/boolean.h>
30 #include <ns3/double.h>
32 #include <ns3/simulator.h>
40 NS_LOG_COMPONENT_DEFINE(
"SatPhyRxCarrierPerWindow");
45 NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerWindow);
48 Ptr<SatPhyRxCarrierConf> carrierConf,
49 Ptr<SatWaveformConf> waveformConf,
50 bool randomAccessEnabled)
52 m_windowDuration(MilliSeconds(60)),
53 m_windowStep(MilliSeconds(20)),
54 m_windowDelay(Seconds(0)),
55 m_firstWindow(Seconds(0)),
56 m_windowSicIterations(10),
58 m_windowEndSchedulingInitialized(false),
59 m_detectionThreshold(0.0),
62 NS_LOG_FUNCTION(
this);
63 NS_LOG_INFO(
"Constructor called with arguments " << carrierId <<
", " << carrierConf <<
", and "
64 << randomAccessEnabled);
72 NS_LOG_FUNCTION(
this);
77 NS_FATAL_ERROR(
"SatPhyRxWindow::BeginWindowEndScheduling - m_nodeInfo not set");
84 Simulator::ScheduleWithContext(
GetNodeInfo()->GetNodeId(),
93 NS_LOG_FUNCTION(
this);
100 TypeId(
"ns3::SatPhyRxCarrierPerWindow")
102 .AddAttribute(
"WindowDuration",
103 "The duration of the sliding window",
104 TimeValue(MilliSeconds(60)),
107 .AddAttribute(
"WindowStep",
108 "The length of the step between two window iterations",
109 TimeValue(MilliSeconds(20)),
114 "The delay before processing a sliding window, waiting for incomplete packets",
115 TimeValue(Seconds(0)),
118 .AddAttribute(
"FirstWindow",
119 "The time at which the first window is processed",
120 TimeValue(Seconds(0)),
123 .AddAttribute(
"WindowSICIterations",
124 "The number of SIC iterations performed on each window",
127 MakeUintegerChecker<uint32_t>())
130 .AddAttribute(
"SpreadingFactor",
131 "The spreading factor of the packets",
134 MakeUintegerChecker<uint32_t>())
135 .AddAttribute(
"DetectionThreshold",
136 "The SNIR Detection Threshold (in magnitude) for a packet",
139 MakeDoubleChecker<double>(0, std::numeric_limits<double>::max()))
140 .AddAttribute(
"EnableSIC",
141 "Use SIC when decoding a packet",
144 MakeBooleanChecker())
147 "Received a packet through Random Access ESSA",
149 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
150 .AddTraceSource(
"EssaRxError",
151 "Received a packet through Random Access ESSA",
153 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
154 .AddTraceSource(
"WindowLoad",
155 "Performed a window load measurement",
157 "ns3::SatPhyRxCarrierPerWindow::WindowLoadTraceCallback");
169 const uint32_t nPackets)
171 NS_ASSERT(packetRxParams.
rxParams->m_txInfo.packetType !=
176 NS_LOG_ERROR(
"SatPhyRxCarrierPerWindow::ReceiveSlot - Time: "
177 << Now().GetSeconds() <<
" - Non ESSA packet received");
181 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::ReceiveSlot - Time: " << Now().GetSeconds()
182 <<
" - ESSA packet received");
204 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::ReceiveSlot - Packet "
205 << params.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
206 << params.
sourceAddress <<
" cannot be detected. Ignore it.");
229 NS_LOG_FUNCTION(
this);
236 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::EliminatePreviousInterferences - Eliminate "
237 "interferences from packet "
238 << packet.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
242 packetList_t::iterator packet_it;
247 if ((packet_it->arrivalTime + packet_it->duration) <= packet.
arrivalTime)
252 if (!(packet_it->hasBeenDecoded))
257 std::pair<double, double> normalizedTimes =
260 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::EliminatePreviousInterferences - eliminate "
261 "interference with packet "
262 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
263 << packet_it->sourceAddress);
270 normalizedTimes.first,
271 normalizedTimes.second);
279 NS_LOG_FUNCTION(
this);
280 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CalculatePacketInterferenceVectors - Packet "
281 << packet.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
301 packet.
rxParams->GetRxNoisePowerInSatellite(),
302 packet.
rxParams->GetRxAciIfPowerInSatellite(),
303 packet.
rxParams->GetRxExtNoisePowerInSatellite(),
304 packet.
rxParams->GetAdditionalInterference());
317 SatSignalParameters::PacketsInBurst_t::const_iterator i;
318 for (i = packets.begin(); i != packets.end(); i++)
321 (*i)->RemovePacketTag(satUplinkInfoTag);
323 (*i)->AddPacketTag(satUplinkInfoTag);
341 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CalculatePacketInterferenceVectors - Received "
347 packet.
gamma.clear();
349 std::vector<std::pair<double, double>> interferencePowerPerFragment =
350 packet.
rxParams->GetInterferencePowerPerFragment();
351 std::vector<std::pair<double, double>>::iterator interferencePower =
352 interferencePowerPerFragment.begin();
353 double normalizedTime = interferencePower->first, normalizedTimeInSatellite = 0.0;
361 std::vector<std::pair<double, double>> interferencePowerPerFragmentInSatellite =
362 packet.
rxParams->GetInterferencePowerInSatellitePerFragment();
363 for (std::vector<std::pair<double, double>>::iterator interferencePowerInSatellite =
364 interferencePowerPerFragmentInSatellite.begin();
365 interferencePowerInSatellite != interferencePowerPerFragmentInSatellite.end();
366 interferencePowerInSatellite++)
368 normalizedTimeInSatellite += interferencePowerInSatellite->first;
371 if (normalizedTimeInSatellite > normalizedTime)
374 normalizedTime += interferencePower->first;
381 double cI = (packet.
rxParams->GetRxPowerInSatellite() * packet.
rxParams->m_rxPower_W) /
382 (interferencePowerInSatellite->second * packet.
rxParams->m_rxPower_W +
383 interferencePower->second * packet.
rxParams->GetRxPowerInSatellite());
386 double gamma = 1 / (1 / cI + 1 / cSnr);
387 packet.
gamma.emplace_back(interferencePowerInSatellite->first, gamma);
396 double cI = (packet.
rxParams->m_rxPower_W) /
397 (packet.
rxParams->m_rxPower_W + interferencePower->second);
400 double gamma = 1 / (1 / cI + 1 / cSnr);
401 packet.
gamma.emplace_back(1, gamma);
405 std::vector<std::pair<double, double>> gammaPreamble;
407 normalizedTime = 0.0;
408 double normalizedPreambleTime =
409 wf->GetPreambleLengthInSymbols() /
410 wf->GetBurstLengthInSymbols();
412 for (std::vector<std::pair<double, double>>::iterator it = packet.
gamma.begin();
413 it != packet.
gamma.end();
416 if (normalizedTime + it->first > normalizedPreambleTime)
418 gammaPreamble.emplace_back(1.0 - normalizedTime, it->second);
421 gammaPreamble.emplace_back(it->first / normalizedPreambleTime, it->second);
422 normalizedTime += it->first;
435 NS_LOG_FUNCTION(
this);
436 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd");
452 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoProcessWindow - Process window between "
453 << startTime.GetSeconds() <<
" and " << endTime.GetSeconds());
459 std::pair<packetList_t::iterator, packetList_t::iterator> windowBounds =
469 if (packet_it == windowBounds.second)
471 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd - No more packets to decode");
474 packet_it->hasBeenTreatedInWindow =
true;
476 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd - Process packet "
477 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
478 << packet_it->sourceAddress);
480 packet_it->hasBeenUpdated =
false;
488 packet_it->sourceAddress,
492 packet_it->hasBeenDecoded =
true;
494 DoSic(packet_it, windowBounds);
496 NS_LOG_WARN(
"received " << packet_it->sourceAddress <<
" "
497 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId <<
" "
498 <<
" INFO " << *(packet_it->rxParams->m_packetsInBurst[0]));
502 NS_LOG_INFO(
"Failed to decode packet "
503 << packet_it->sourceAddress <<
"-"
504 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId);
505 packet_it->failedSic =
true;
513 for (packetList_t::iterator packet_it = windowBounds.first; packet_it != windowBounds.second;
517 if (!packet_it->isInsideWindow || !packet_it->hasBeenTreatedInWindow)
521 m_rxCallback(packet_it->rxParams, !packet_it->hasBeenDecoded);
530 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoWindowEnd - Window processing finished");
535 packetList_t::iterator processedPacket,
536 std::pair<packetList_t::iterator, packetList_t::iterator> windowBounds)
538 NS_LOG_FUNCTION(
this);
545 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoSic - eliminate interference from packet "
546 << processedPacket->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
547 << processedPacket->sourceAddress);
550 for (packetList_t::iterator packet_it = windowBounds.first; packet_it != windowBounds.second;
554 if (packet_it->arrivalTime >= processedPacket->arrivalTime + processedPacket->duration)
559 if (packet_it->arrivalTime + packet_it->duration <= processedPacket->arrivalTime)
564 if (packet_it == processedPacket || packet_it->hasBeenDecoded)
568 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::DoSic - eliminate interference with packet "
569 << packet_it->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
570 << packet_it->sourceAddress);
572 std::pair<double, double> normalizedTimes =
577 processedPacket->rxParams,
580 normalizedTimes.first,
581 normalizedTimes.second);
587 std::pair<double, double>
592 NS_LOG_FUNCTION(
this);
602 double endTimeA = std::min(
618 double normalizedTime = 0.0;
619 double exactStartTime = (startTimeA == 0.0) ? 0.0 : -1.0;
620 double exactEndTime = -1.0;
621 auto ifPowerPerFragment = packet.
rxParams->GetInterferencePowerInSatellitePerFragment();
622 for (std::pair<double, double>& ifPower : ifPowerPerFragment)
624 normalizedTime += ifPower.first;
625 if ((exactStartTime < 0) && (normalizedTime == startTimeA || normalizedTime == startTimeB))
627 exactStartTime = normalizedTime;
629 if ((exactEndTime < 0) && (normalizedTime == endTimeA || normalizedTime == endTimeB))
631 exactEndTime = normalizedTime;
635 if ((exactStartTime < 0) || (exactEndTime < 0))
637 NS_FATAL_ERROR(
"Cannot find exact interference time between two packets");
640 return std::make_pair(exactStartTime, exactEndTime);
647 NS_LOG_FUNCTION(
this);
650 Ptr<SatMutualInformationTable> mutualInformationTable;
651 if (satLinkResults != NULL)
653 mutualInformationTable =
658 mutualInformationTable =
661 double beta = mutualInformationTable->GetBeta();
663 double meanMutualInformation = 0.0;
664 for (std::vector<std::pair<double, double>>::const_iterator it = packet.
gamma.begin();
665 it != packet.
gamma.end();
668 meanMutualInformation += it->first * mutualInformationTable->GetNormalizedSymbolInformation(
672 double effectiveSnir =
675 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetEffectiveSnir - Packet "
679 return effectiveSnir;
685 NS_LOG_FUNCTION(
this);
686 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CleanOldPackets");
692 Time offset = it->arrivalTime - windowStartTime;
693 if (offset.IsStrictlyPositive())
698 offset = it->arrivalTime + it->duration - windowStartTime;
699 if (!offset.IsStrictlyPositive())
704 if (!(it->hasBeenDecoded))
717 !(it->hasBeenDecoded));
720 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::CleanOldPackets - Remove packet "
721 << it->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
722 << it->sourceAddress);
733 std::pair<SatPhyRxCarrierPerWindow::packetList_t::iterator,
734 SatPhyRxCarrierPerWindow::packetList_t::iterator>
737 NS_LOG_FUNCTION(
this);
738 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetWindowBounds");
740 packetList_t::iterator last;
746 last->isInsideWindow =
false;
748 if (last->arrivalTime > endTime)
753 if ((last->arrivalTime >= startTime) && (last->arrivalTime + last->duration <= endTime))
755 last->isInsideWindow =
true;
756 last->hasBeenTreatedInWindow =
false;
759 ->GetWaveform(last->rxParams->m_txInfo.waveformId)
760 ->GetPayloadInBytes();
763 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetWindowBounds - Packet "
764 << last->rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
765 << last->sourceAddress <<
" is inside the window");
773 SatPhyRxCarrierPerWindow::packetList_t::iterator
775 const std::pair<SatPhyRxCarrierPerWindow::packetList_t::iterator,
776 SatPhyRxCarrierPerWindow::packetList_t::iterator> windowBounds)
778 NS_LOG_FUNCTION(
this);
779 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::GetHighestSnirPacket");
781 SatPhyRxCarrierPerWindow::packetList_t::iterator it, max = windowBounds.second;
782 for (it = windowBounds.first; it != windowBounds.second; it++)
784 if (it->hasBeenDecoded || !(it->hasBeenUpdated) || !(it->isInsideWindow))
789 if ((max == windowBounds.second) || (it->meanSinr > max->meanSinr))
801 NS_LOG_FUNCTION(
this);
810 NS_LOG_FUNCTION(
this);
812 NS_LOG_INFO(
"SatPhyRxCarrierPerWindow::AddEssaPacket - Add packet "
813 << essaPacketParams.
rxParams->m_txInfo.crdsaUniquePacketId <<
" from "
815 <<
" Arrival Time: " << essaPacketParams.
arrivalTime.GetSeconds()
816 <<
" Duration: " << essaPacketParams.
duration.GetSeconds());
825 NS_LOG_FUNCTION(
this);
836 NS_LOG_INFO(
"Average normalized offered load: " << averageNormalizedOfferedLoad);
847 averageNormalizedOfferedLoad);
854 NS_LOG_FUNCTION(
this);
859 NS_LOG_INFO(
"Payload Bytes in Window: "
862 <<
", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
864 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