27 #include <ns3/boolean.h>
29 #include <ns3/simulator.h>
36 NS_LOG_COMPONENT_DEFINE(
"SatPhyRxCarrierPerFrame");
41 NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerFrame);
44 Ptr<SatPhyRxCarrierConf> carrierConf,
45 Ptr<SatWaveformConf> waveformConf,
46 bool randomAccessEnabled)
48 m_frameEndSchedulingInitialized(false)
50 NS_LOG_FUNCTION(
this);
51 NS_LOG_INFO(
"Constructor called with arguments " << carrierId <<
", " << carrierConf <<
", and "
52 << randomAccessEnabled);
60 NS_LOG_FUNCTION(
this);
63 Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
66 if (Now() >= nextSuperFrameRxTime)
68 NS_FATAL_ERROR(
"Scheduling next superframe start time to the past!");
71 Time schedulingDelay = nextSuperFrameRxTime - Now();
75 NS_FATAL_ERROR(
"m_nodeInfo not set");
80 Simulator::ScheduleWithContext(
GetNodeInfo()->GetNodeId(),
89 NS_LOG_FUNCTION(
this);
96 TypeId(
"ns3::SatPhyRxCarrierPerFrame")
100 "Received a CRDSA packet replica through Random Access",
102 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
104 "CrdsaUniquePayloadRx",
105 "Received a unique CRDSA payload (after frame processing) "
106 "through Random Access CRDSA",
108 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback");
116 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
120 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
121 for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
123 iterList->rxParams = NULL;
125 iter->second.clear();
132 const uint32_t nPackets)
134 NS_ASSERT(packetRxParams.
rxParams->m_txInfo.packetType !=
146 NS_LOG_INFO(
"CRDSA packet received");
171 NS_LOG_FUNCTION(
this);
178 NS_LOG_INFO(
"Packets in container, will process the frame");
180 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> results =
ProcessFrame();
184 NS_FATAL_ERROR(
"All CRDSA packets in the frame were not processed");
193 NS_LOG_INFO(
"Sending a packet to the next layer, slot: "
194 << crdsaPacket.ownSlotId <<
", UT: " << crdsaPacket.sourceAddress
195 <<
", unique CRDSA packet ID: "
196 << crdsaPacket.rxParams->m_txInfo.crdsaUniquePacketId
197 <<
", destination address: " << crdsaPacket.destAddress
198 <<
", error: " << crdsaPacket.phyError <<
", SINR: " << crdsaPacket.cSinr);
200 for (Ptr<Packet>& packetInBurst : crdsaPacket.rxParams->m_packetsInBurst)
202 NS_LOG_INFO(
"Fragment (HL packet) UID: " << packetInBurst->GetUid());
208 crdsaPacket.destAddress,
213 crdsaPacket.rxParams->m_packetsInBurst.size(),
214 crdsaPacket.sourceAddress,
222 m_rxCallback(crdsaPacket.rxParams, crdsaPacket.phyError);
224 crdsaPacket.rxParams = NULL;
238 NS_FATAL_ERROR(
"CRDSA packets received by carrier which has random access disabled");
242 Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
245 if (Now() >= nextSuperFrameRxTime)
247 NS_FATAL_ERROR(
"Scheduling next superframe start time to the past!");
250 Time schedulingDelay = nextSuperFrameRxTime - Now();
258 NS_LOG_FUNCTION(
this);
260 std::vector<uint64_t> uniquePacketIds;
261 uint32_t uniqueCrdsaBytes(0);
264 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
268 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
269 for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
272 uint64_t uid = iterList->rxParams->m_packetsInBurst.front()->GetUid();
275 std::vector<uint64_t>::iterator it =
276 std::find(uniquePacketIds.begin(), uniquePacketIds.end(), uid);
278 if (it == uniquePacketIds.end())
281 uniquePacketIds.push_back(uid);
284 uniqueCrdsaBytes += iterList->rxParams->m_txInfo.fecBlockSizeInBytes;
297 NS_LOG_FUNCTION(
this);
308 NS_LOG_INFO(
"Average normalized offered load: " << averageNormalizedOfferedLoad);
314 averageNormalizedOfferedLoad);
320 NS_LOG_FUNCTION(
this);
322 Time superFrameDuration = Singleton<SatRtnLinkTime>::Get()->GetSuperFrameDuration(
325 double normalizedOfferedLoad =
329 <<
", frame length in seconds: " << superFrameDuration.GetSeconds()
331 <<
", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
336 return normalizedOfferedLoad;
343 NS_LOG_FUNCTION(
this);
345 if (crdsaPacketParams.
rxParams->m_packetsInBurst.size() > 0)
350 bool result = crdsaPacketParams.
rxParams->m_packetsInBurst[0]->PeekPacketTag(replicaTag);
354 NS_FATAL_ERROR(
"First packet did not contain a CRDSA replica tag");
357 std::vector<uint16_t> slotIds = replicaTag.
GetSlotIds();
359 if (slotIds.size() < 1)
361 NS_FATAL_ERROR(
"The tag did not contain any slot IDs");
365 crdsaPacketParams.
ownSlotId = slotIds[0];
369 NS_FATAL_ERROR(
"Vector for packet replicas should be empty at this point");
373 for (uint32_t i = 1; i < slotIds.size(); i++)
379 for (uint32_t i = 0; i < crdsaPacketParams.
rxParams->m_packetsInBurst.size(); i++)
381 crdsaPacketParams.
rxParams->m_packetsInBurst[i]->RemovePacketTag(replicaTag);
386 NS_FATAL_ERROR(
"CRDSA reception with 0 packets");
389 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator result;
395 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> tempList;
396 tempList.push_back(crdsaPacketParams);
401 result->second.push_back(crdsaPacketParams);
404 NS_LOG_INFO(
"Packet in slot " << crdsaPacketParams.
ownSlotId
405 <<
" was added to the CRDSA packet container");
409 NS_LOG_INFO(
"A replica of the packet is in slot "
414 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>
417 NS_LOG_FUNCTION(
this);
419 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
420 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> combinedPacketsForFrame;
425 NS_LOG_INFO(
"All successfully received packets processed, packets left in container: "
438 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList =
439 iter->second.begin();
441 if (iterList != iter->second.end())
443 NS_LOG_INFO(
"Processing unsuccessfully received packet in slot: "
444 << iterList->ownSlotId <<
" packet phy error: " << iterList->phyError
445 <<
" packet has been processed: " << iterList->packetHasBeenProcessed);
447 if (!iterList->packetHasBeenProcessed || !iterList->phyError)
450 "All successfully received packets should have been processed by now");
457 combinedPacketsForFrame.push_back(*iterList);
460 iter->second.erase(iterList);
463 if (iter->second.empty())
478 return combinedPacketsForFrame;
483 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& combinedPacketsForFrame)
485 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
487 bool nothingToProcess =
true;
493 NS_LOG_INFO(
"Searching for the next successfully received packet");
496 nothingToProcess =
true;
501 NS_LOG_INFO(
"Iterating slot: " << iter->first);
502 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& slotContent = iter->second;
504 if (slotContent.size() < 1)
506 NS_FATAL_ERROR(
"No packet in slot! This should not happen");
509 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator currentPacket;
511 for (currentPacket = slotContent.begin(); currentPacket != slotContent.end();
514 NS_LOG_INFO(
"Iterating packet in slot: " << currentPacket->ownSlotId);
516 if (!currentPacket->packetHasBeenProcessed)
518 NS_LOG_INFO(
"Found a packet ready for processing");
523 NS_LOG_INFO(
"Packet error: " << currentPacket->phyError);
526 if (!currentPacket->phyError)
528 NS_LOG_INFO(
"Packet successfully received, breaking the slot iteration");
530 nothingToProcess =
false;
533 processedPacket = *currentPacket;
536 slotContent.erase(currentPacket);
548 NS_LOG_INFO(
"This packet has already been processed");
553 if (!nothingToProcess)
555 NS_LOG_INFO(
"Packet successfully received, breaking the container iteration");
560 if (!nothingToProcess)
562 NS_LOG_INFO(
"Packet successfully received, processing the replicas");
568 combinedPacketsForFrame.push_back(processedPacket);
570 }
while (!nothingToProcess);
576 uint32_t numOfPacketsForThisSlot)
578 NS_LOG_FUNCTION(
this);
580 NS_LOG_INFO(
"Processing a packet in slot: " << packet.
ownSlotId
581 <<
" number of packets in this slot: "
582 << numOfPacketsForThisSlot);
589 NS_LOG_INFO(
"SINR CALCULATION, RX sat: "
590 << packet.
rxParams->GetRxPowerInSatellite()
591 <<
" IF sat: " << packet.
rxParams->GetInterferencePowerInSatellite()
592 <<
" RX gnd: " << packet.
rxParams->m_rxPower_W
593 <<
" IF gnd: " << packet.
rxParams->GetInterferencePower());
598 SatSignalParameters::PacketsInBurst_t::const_iterator i;
599 for (i = packets.begin(); i != packets.end(); i++)
602 (*i)->RemovePacketTag(satUplinkInfoTag);
604 (*i)->AddPacketTag(satUplinkInfoTag);
617 NS_LOG_INFO(
"Strict collision detection is ENABLED");
620 if (numOfPacketsForThisSlot > 1)
622 NS_LOG_INFO(
"Multiple packets in this slot, successful reception is not possible");
628 NS_LOG_INFO(
"Only packet in this slot, checking against link results");
632 NS_LOG_INFO(
"Strict collision detection, phy error: " << packet.
phyError);
639 NS_LOG_INFO(
"Check against link results, phy error: " << packet.
phyError);
643 NS_FATAL_ERROR(
"Random access collision model not defined");
656 NS_LOG_FUNCTION(
this);
659 packet.
rxParams->GetInterferencePower(),
669 packet.
rxParams->GetInterferencePowerInSatellite(),
670 packet.
rxParams->GetRxNoisePowerInSatellite(),
671 packet.
rxParams->GetRxAciIfPowerInSatellite(),
672 packet.
rxParams->GetRxExtNoisePowerInSatellite(),
673 packet.
rxParams->GetAdditionalInterference());
681 NS_LOG_INFO(
"Computed cSINR for packet: " << cSinr);
683 packet.
cSinr = cSinr;
693 NS_LOG_FUNCTION(
this);
700 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator
706 NS_FATAL_ERROR(
"This should not happen");
709 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
712 bool replicaFound =
false;
714 for (iterList = iter->second.begin(); iterList != iter->second.end();)
721 NS_FATAL_ERROR(
"Found two replica of the same packet in the same slot");
725 removedPacket = *iterList;
726 iter->second.erase(iterList++);
736 NS_FATAL_ERROR(
"Replica not found");
749 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter,
752 NS_LOG_FUNCTION(
this);
754 if (iter->second.empty())
756 NS_LOG_INFO(
"No other packets in this slot, erasing the slot container");
761 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
763 for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
766 iterList->packetHasBeenProcessed =
false;
768 NS_LOG_INFO(
"BEFORE INTERFERENCE ELIMINATION, RX sat: "
769 << iterList->rxParams->GetRxPowerInSatellite()
770 <<
" IF sat: " << iterList->rxParams->GetInterferencePowerInSatellite()
771 <<
" RX gnd: " << iterList->rxParams->m_rxPower_W
772 <<
" IF gnd: " << iterList->rxParams->GetInterferencePower());
782 if (iterList->rxParams->GetInterferencePower() < 0)
784 NS_FATAL_ERROR(
"Negative interference");
789 processedPacket.
cSinr,
793 NS_LOG_INFO(
"AFTER INTERFERENCE ELIMINATION, RX sat: "
794 << iterList->rxParams->GetRxPowerInSatellite()
795 <<
" IF sat: " << iterList->rxParams->GetInterferencePowerInSatellite()
796 <<
" RX gnd: " << iterList->rxParams->m_rxPower_W
797 <<
" IF gnd: " << iterList->rxParams->GetInterferencePower());
807 NS_LOG_FUNCTION(
this);
809 NS_LOG_INFO(
"Checking the source addresses");
811 bool isReplica =
false;
815 NS_LOG_INFO(
"Same source addresses, checking slot IDs");
819 NS_LOG_INFO(
"Same slot IDs, replica found");
831 NS_LOG_FUNCTION(
this);
833 std::set<uint16_t> firstSet;
834 std::set<uint16_t> secondSet;
835 std::set<uint16_t>::iterator firstSetIterator;
836 std::set<uint16_t>::iterator secondSetIterator;
837 bool haveSameSlotIds =
true;
846 "SatPhyRxCarrierUt::HaveSameSlotIds - The amount of replicas does not match");
849 NS_LOG_INFO(
"Comparing slot IDs");
858 uint32_t numOfMatchingSlots = 0;
861 for (firstSetIterator = firstSet.begin(); firstSetIterator != firstSet.end();
864 secondSetIterator = secondSet.find(*firstSetIterator);
866 if (secondSetIterator == secondSet.end())
868 haveSameSlotIds =
false;
872 numOfMatchingSlots++;
876 NS_LOG_INFO(
"Are slot IDs identical: " << haveSameSlotIds
877 <<
", number of matching slots: " << numOfMatchingSlots);
880 if (!haveSameSlotIds && numOfMatchingSlots > 0)
882 NS_FATAL_ERROR(
"Partially overlapping CRDSA slots");
885 return haveSameSlotIds;
892 return (
bool)(obj1.
rxParams->m_txInfo.crdsaUniquePacketId <
893 obj2.
rxParams->m_txInfo.crdsaUniquePacketId);
This class implements a tag that carries information about the slot IDs of CRDSA packet replicas.
std::vector< uint16_t > GetSlotIds(void)
@ PACKET_TYPE_DEDICATED_ACCESS
@ PACKET_TYPE_SLOTTED_ALOHA
@ RA_COLLISION_CHECK_AGAINST_SINR
@ RA_COLLISION_ALWAYS_DROP_ALL_COLLIDING_PACKETS
SatPhy::AverageNormalizedOfferedLoadCallback m_avgNormalizedOfferedLoadCallback
Average normalized offered load callback.
Ptr< SatInterference > GetInterferenceModel()
Get pointer to the current interference model.
double m_rxExtNoisePowerW
External noise power system RX noise.
TracedCallback< double, const Address & > m_linkSinrTrace
A callback for link specific SINR in dB.
TracedCallback< Ptr< SatSignalParameters >, Mac48Address, Mac48Address, double, double > m_linkBudgetTrace
The trace source on packet receptiong.
Ptr< SatNodeInfo > GetNodeInfo()
Get the satellite node info.
SatPhyRxCarrierConf::AdditionalInterferenceCallback m_additionalInterferenceCallback
Callback to get additional interference.
uint32_t GetCarrierId() const
Get the ID of the carrier.
virtual SatEnums::RegenerationMode_t GetLinkRegenerationMode()
Get the link regeneration mode.
uint32_t GetBeamId()
Get ID the ID of the beam this carrier is attached to.
double CalculateSinr(double rxPowerW, double ifPowerW, double rxNoisePowerW, double rxAciIfPowerW, double rxExtNoisePowerW, double otherInterference)
Function for calculating the SINR.
SatPhyRx::ReceiveCallback m_rxCallback
The upper layer package receive callback.
double m_rxAciIfPowerW
RX Adjacent channel interference.
TracedCallback< double, const Address & > m_sinrTrace
A callback for transmission composite SINR at UT (BBFrame) or GW (time slot).
bool CheckAgainstLinkResults(double cSinr, Ptr< SatSignalParameters > rxParams)
Function for checking the SINR against the link results.
double CalculateCompositeSinr(double sinr1, double sinr2)
Function for calculating the composite SINR.
const bool m_randomAccessEnabled
Is random access enabled for this carrier.
Ptr< SatInterferenceElimination > GetInterferenceEliminationModel()
Get pointer to the current interference elimination model.
double m_rxNoisePowerW
RX noise.
SatEnums::RegenerationMode_t m_linkRegenerationMode
Link regeneration mode.
uint32_t GetSatId()
Get ID the ID of the satellite this carrier is attached to.
double m_rxBandwidthHz
RX Bandwidth in Hz.
Mac48Address GetOwnAddress()
Get the MAC address of the carrier.
void EliminateInterference(std::map< uint32_t, std::list< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s >>::iterator iter, SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s processedPacket)
Function for eliminating the interference to other packets in the slot from the correctly received pa...
void BeginEndScheduling()
Function for initializing the frame end scheduling.
void AddCrdsaPacket(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s crdsaPacketParams)
Function for storing the received CRDSA packets.
virtual void ReceiveSlot(SatPhyRxCarrier::rxParams_s packetRxParams, const uint32_t nPackets)
Receive a slot.
virtual void DoDispose()
Dispose implementation.
bool IsReplica(const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &packet, const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &otherPacket) const
Function for identifying whether the packet is a replica of another packet.
TracedCallback< uint32_t, const Address &, bool > m_crdsaUniquePayloadRxTrace
CrdsaUniquePayloadRx trace source.
virtual void PerformSicCycles(std::vector< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s > &combinedPacketsForFrame)
Function for receiving decodable packets and removing their interference from the other packets in th...
double CalculateNormalizedOfferedRandomAccessLoad()
Function for calculating the normalized offered random access load.
TracedCallback< uint32_t, const Address &, bool > m_crdsaReplicaRxTrace
CrdsaReplicaRx trace source.
bool m_frameEndSchedulingInitialized
Has the frame end scheduling been initialized.
std::vector< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s > ProcessFrame()
Function for processing the CRDSA frame.
bool HaveSameSlotIds(const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &packet, const SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s &otherPacket) const
Function for checking do the packets have identical slots.
void UpdateRandomAccessLoad()
Update the random access load for CRDSA.
double CalculatePacketCompositeSinr(crdsaPacketRxParams_s &packet)
Function for computing the composite SINR of the given packet.
void FindAndRemoveReplicas(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s packet)
Function for finding and removing the replicas of the CRDSA packet.
void MeasureRandomAccessLoad()
Function for measuring the random access load.
SatPhyRxCarrierPerFrame(uint32_t carrierId, Ptr< SatPhyRxCarrierConf > carrierConf, Ptr< SatWaveformConf > waveformConf, bool randomAccessEnabled)
Constructor.
SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s ProcessReceivedCrdsaPacket(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s packet, uint32_t numOfPacketsForThisSlot)
Process received CRDSA packet.
void DoFrameEnd()
Function for processing the frame interval operations.
static bool CompareCrdsaPacketId(SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s obj1, SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s obj2)
Function for comparing the CRDSA unique packet IDs.
virtual ~SatPhyRxCarrierPerFrame()
Destructor.
static TypeId GetTypeId(void)
Get the TypeId of the class.
std::map< uint32_t, std::list< SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s > > m_crdsaPacketContainer
CRDSA packet container.
Inherited the base functionality of SatPhyRxCarriers for ground station nodes.
uint8_t GetRandomAccessAllocationChannelId() const
Function for getting the random access allocation channel ID.
virtual void ReceiveSlot(SatPhyRxCarrier::rxParams_s packetRxParams, const uint32_t nPackets)
Receive a slot.
virtual void DoDispose()
Dispose implementation.
void SaveMeasuredRandomAccessLoad(double measuredRandomAccessLoad)
Function for saving the measured random access load.
SatPhyRxCarrierConf::RandomAccessCollisionModel GetRandomAccessCollisionModel() const
Get the random access collision model of the carrier.
bool IsRandomAccessDynamicLoadControlEnabled() const
Check if random access dynamic load control is enabled.
uint32_t m_randomAccessBitsInFrame
The number of random access bits in current frame.
double CalculateAverageNormalizedOfferedRandomAccessLoad()
Function for calculating the average normalized offered random access load.
std::vector< Ptr< Packet > > PacketsInBurst_t
Buffer for transmissions.
Tag to store uplink phy info that need to be forwarded to the downlink.
void SetSinr(double sinr, double additionalInterference)
Set uplink SINR.
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< SatSignalParameters > rxParams
Mac48Address sourceAddress
Ptr< SatInterference::InterferenceChangeEvent > interferenceEvent
Struct for storing the CRDSA packet specific Rx parameters.
std::vector< uint16_t > slotIdsForOtherReplicas
Ptr< SatSignalParameters > rxParams
Mac48Address sourceAddress
bool packetHasBeenProcessed