27 #include <ns3/boolean.h>
29 #include <ns3/simulator.h>
40 NS_LOG_COMPONENT_DEFINE(
"SatPhyRxCarrierPerFrame");
45 NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerFrame);
48 Ptr<SatPhyRxCarrierConf> carrierConf,
49 Ptr<SatWaveformConf> waveformConf,
50 bool randomAccessEnabled)
52 m_frameEndSchedulingInitialized(false)
54 NS_LOG_FUNCTION(
this);
55 NS_LOG_INFO(
"Constructor called with arguments " << carrierId <<
", " << carrierConf <<
", and "
56 << randomAccessEnabled);
64 NS_LOG_FUNCTION(
this);
67 Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
70 if (Now() >= nextSuperFrameRxTime)
72 NS_FATAL_ERROR(
"Scheduling next superframe start time to the past!");
75 Time schedulingDelay = nextSuperFrameRxTime - Now();
79 NS_FATAL_ERROR(
"m_nodeInfo not set");
84 Simulator::ScheduleWithContext(
GetNodeInfo()->GetNodeId(),
93 NS_LOG_FUNCTION(
this);
100 TypeId(
"ns3::SatPhyRxCarrierPerFrame")
104 "Received a CRDSA packet replica through Random Access",
106 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
108 "CrdsaUniquePayloadRx",
109 "Received a unique CRDSA payload (after frame processing) "
110 "through Random Access CRDSA",
112 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback");
120 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
124 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
125 for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
127 iterList->rxParams =
nullptr;
129 iter->second.clear();
136 const uint32_t nPackets)
138 NS_ASSERT(packetRxParams.
rxParams->m_txInfo.packetType !=
150 NS_LOG_INFO(
"CRDSA packet received");
175 NS_LOG_FUNCTION(
this);
182 NS_LOG_INFO(
"Packets in container, will process the frame");
184 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> results =
ProcessFrame();
188 NS_FATAL_ERROR(
"All CRDSA packets in the frame were not processed");
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);
204 for (Ptr<Packet>& packetInBurst : crdsaPacket.rxParams->m_packetsInBurst)
206 NS_LOG_INFO(
"Fragment (HL packet) UID: " << packetInBurst->GetUid());
212 crdsaPacket.destAddress,
217 crdsaPacket.rxParams->m_packetsInBurst.size(),
218 crdsaPacket.sourceAddress,
226 m_rxCallback(crdsaPacket.rxParams, crdsaPacket.phyError);
228 crdsaPacket.rxParams =
nullptr;
242 NS_FATAL_ERROR(
"CRDSA packets received by carrier which has random access disabled");
246 Time nextSuperFrameRxTime = Singleton<SatRtnLinkTime>::Get()->GetNextSuperFrameStartTime(
249 if (Now() >= nextSuperFrameRxTime)
251 NS_FATAL_ERROR(
"Scheduling next superframe start time to the past!");
254 Time schedulingDelay = nextSuperFrameRxTime - Now();
262 NS_LOG_FUNCTION(
this);
264 std::vector<uint64_t> uniquePacketIds;
265 uint32_t uniqueCrdsaBytes(0);
268 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
272 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
273 for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
276 uint64_t uid = iterList->rxParams->m_packetsInBurst.front()->GetUid();
279 std::vector<uint64_t>::iterator it =
280 std::find(uniquePacketIds.begin(), uniquePacketIds.end(), uid);
282 if (it == uniquePacketIds.end())
285 uniquePacketIds.push_back(uid);
288 uniqueCrdsaBytes += iterList->rxParams->m_txInfo.fecBlockSizeInBytes;
301 NS_LOG_FUNCTION(
this);
312 NS_LOG_INFO(
"Average normalized offered load: " << averageNormalizedOfferedLoad);
318 averageNormalizedOfferedLoad);
324 NS_LOG_FUNCTION(
this);
326 Time superFrameDuration = Singleton<SatRtnLinkTime>::Get()->GetSuperFrameDuration(
329 double normalizedOfferedLoad =
333 <<
", frame length in seconds: " << superFrameDuration.GetSeconds()
335 <<
", normalized offered load (bps/Hz): " << normalizedOfferedLoad);
340 return normalizedOfferedLoad;
347 NS_LOG_FUNCTION(
this);
349 if (crdsaPacketParams.
rxParams->m_packetsInBurst.size() > 0)
354 bool result = crdsaPacketParams.
rxParams->m_packetsInBurst[0]->PeekPacketTag(replicaTag);
358 NS_FATAL_ERROR(
"First packet did not contain a CRDSA replica tag");
361 std::vector<uint16_t> slotIds = replicaTag.
GetSlotIds();
363 if (slotIds.size() < 1)
365 NS_FATAL_ERROR(
"The tag did not contain any slot IDs");
369 crdsaPacketParams.
ownSlotId = slotIds[0];
373 NS_FATAL_ERROR(
"Vector for packet replicas should be empty at this point");
377 for (uint32_t i = 1; i < slotIds.size(); i++)
383 for (uint32_t i = 0; i < crdsaPacketParams.
rxParams->m_packetsInBurst.size(); i++)
385 crdsaPacketParams.
rxParams->m_packetsInBurst[i]->RemovePacketTag(replicaTag);
390 NS_FATAL_ERROR(
"CRDSA reception with 0 packets");
393 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator result;
399 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> tempList;
400 tempList.push_back(crdsaPacketParams);
405 result->second.push_back(crdsaPacketParams);
408 NS_LOG_INFO(
"Packet in slot " << crdsaPacketParams.
ownSlotId
409 <<
" was added to the CRDSA packet container");
413 NS_LOG_INFO(
"A replica of the packet is in slot "
418 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>
421 NS_LOG_FUNCTION(
this);
423 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
424 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s> combinedPacketsForFrame;
429 NS_LOG_INFO(
"All successfully received packets processed, packets left in container: "
442 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList =
443 iter->second.begin();
445 if (iterList != iter->second.end())
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);
451 if (!iterList->packetHasBeenProcessed || !iterList->phyError)
454 "All successfully received packets should have been processed by now");
461 combinedPacketsForFrame.push_back(*iterList);
464 iter->second.erase(iterList);
467 if (iter->second.empty())
482 return combinedPacketsForFrame;
487 std::vector<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& combinedPacketsForFrame)
489 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter;
491 bool nothingToProcess =
true;
497 NS_LOG_INFO(
"Searching for the next successfully received packet");
500 nothingToProcess =
true;
505 NS_LOG_INFO(
"Iterating slot: " << iter->first);
506 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>& slotContent = iter->second;
508 if (slotContent.size() < 1)
510 NS_FATAL_ERROR(
"No packet in slot! This should not happen");
513 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator currentPacket;
515 for (currentPacket = slotContent.begin(); currentPacket != slotContent.end();
518 NS_LOG_INFO(
"Iterating packet in slot: " << currentPacket->ownSlotId);
520 if (!currentPacket->packetHasBeenProcessed)
522 NS_LOG_INFO(
"Found a packet ready for processing");
527 NS_LOG_INFO(
"Packet error: " << currentPacket->phyError);
530 if (!currentPacket->phyError)
532 NS_LOG_INFO(
"Packet successfully received, breaking the slot iteration");
534 nothingToProcess =
false;
537 processedPacket = *currentPacket;
540 slotContent.erase(currentPacket);
552 NS_LOG_INFO(
"This packet has already been processed");
557 if (!nothingToProcess)
559 NS_LOG_INFO(
"Packet successfully received, breaking the container iteration");
564 if (!nothingToProcess)
566 NS_LOG_INFO(
"Packet successfully received, processing the replicas");
572 combinedPacketsForFrame.push_back(processedPacket);
574 }
while (!nothingToProcess);
580 uint32_t numOfPacketsForThisSlot)
582 NS_LOG_FUNCTION(
this);
584 NS_LOG_INFO(
"Processing a packet in slot: " << packet.
ownSlotId
585 <<
" number of packets in this slot: "
586 << numOfPacketsForThisSlot);
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());
602 SatSignalParameters::PacketsInBurst_t::const_iterator i;
603 for (i = packets.begin(); i != packets.end(); i++)
606 (*i)->RemovePacketTag(satUplinkInfoTag);
608 (*i)->AddPacketTag(satUplinkInfoTag);
621 NS_LOG_INFO(
"Strict collision detection is ENABLED");
624 if (numOfPacketsForThisSlot > 1)
626 NS_LOG_INFO(
"Multiple packets in this slot, successful reception is not possible");
632 NS_LOG_INFO(
"Only packet in this slot, checking against link results");
636 NS_LOG_INFO(
"Strict collision detection, phy error: " << packet.
phyError);
643 NS_LOG_INFO(
"Check against link results, phy error: " << packet.
phyError);
647 NS_FATAL_ERROR(
"Random access collision model not defined");
660 NS_LOG_FUNCTION(
this);
663 packet.
rxParams->GetInterferencePower(),
673 packet.
rxParams->GetInterferencePowerInSatellite(),
674 packet.
rxParams->GetRxNoisePowerInSatellite(),
675 packet.
rxParams->GetRxAciIfPowerInSatellite(),
676 packet.
rxParams->GetRxExtNoisePowerInSatellite(),
677 packet.
rxParams->GetAdditionalInterference());
685 NS_LOG_INFO(
"Computed cSINR for packet: " << cSinr);
687 packet.
cSinr = cSinr;
697 NS_LOG_FUNCTION(
this);
704 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator
710 NS_FATAL_ERROR(
"This should not happen");
713 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
716 bool replicaFound =
false;
718 for (iterList = iter->second.begin(); iterList != iter->second.end();)
725 NS_FATAL_ERROR(
"Found two replica of the same packet in the same slot");
729 removedPacket = *iterList;
730 iter->second.erase(iterList++);
740 NS_FATAL_ERROR(
"Replica not found");
753 std::map<uint32_t, std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>>::iterator iter,
756 NS_LOG_FUNCTION(
this);
758 if (iter->second.empty())
760 NS_LOG_INFO(
"No other packets in this slot, erasing the slot container");
765 std::list<SatPhyRxCarrierPerFrame::crdsaPacketRxParams_s>::iterator iterList;
767 for (iterList = iter->second.begin(); iterList != iter->second.end(); iterList++)
770 iterList->packetHasBeenProcessed =
false;
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());
786 if (iterList->rxParams->GetInterferencePower() < 0)
788 NS_FATAL_ERROR(
"Negative interference");
793 processedPacket.
cSinr,
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());
811 NS_LOG_FUNCTION(
this);
813 NS_LOG_INFO(
"Checking the source addresses");
815 bool isReplica =
false;
819 NS_LOG_INFO(
"Same source addresses, checking slot IDs");
823 NS_LOG_INFO(
"Same slot IDs, replica found");
835 NS_LOG_FUNCTION(
this);
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;
850 "SatPhyRxCarrierUt::HaveSameSlotIds - The amount of replicas does not match");
853 NS_LOG_INFO(
"Comparing slot IDs");
862 uint32_t numOfMatchingSlots = 0;
865 for (firstSetIterator = firstSet.begin(); firstSetIterator != firstSet.end();
868 secondSetIterator = secondSet.find(*firstSetIterator);
870 if (secondSetIterator == secondSet.end())
872 haveSameSlotIds =
false;
876 numOfMatchingSlots++;
880 NS_LOG_INFO(
"Are slot IDs identical: " << haveSameSlotIds
881 <<
", number of matching slots: " << numOfMatchingSlots);
884 if (!haveSameSlotIds && numOfMatchingSlots > 0)
886 NS_FATAL_ERROR(
"Partially overlapping CRDSA slots");
889 return haveSameSlotIds;
896 return (
bool)(obj1.
rxParams->m_txInfo.crdsaUniquePacketId <
897 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