Loading...
Searching...
No Matches
satellite-phy-rx-carrier-per-slot.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2014 Magister Solutions Ltd.
4 * Copyright (c) 2018 CNES
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Author: Jani Puttonen <jani.puttonen@magister.fi>
20 * Author: Mathias Ettinger <mettinger@toulouse.viveris.fr>
21 */
22
24
26
27#include "ns3/address.h"
28#include "ns3/boolean.h"
29#include "ns3/log.h"
30#include "ns3/simulator.h"
31
32#include <algorithm>
33#include <deque>
34#include <limits>
35#include <ostream>
36#include <utility>
37
38NS_LOG_COMPONENT_DEFINE("SatPhyRxCarrierPerSlot");
39
40namespace ns3
41{
42
43NS_OBJECT_ENSURE_REGISTERED(SatPhyRxCarrierPerSlot);
44
46 Ptr<SatPhyRxCarrierConf> carrierConf,
47 Ptr<SatWaveformConf> waveformConf,
48 bool randomAccessEnabled)
49 : SatPhyRxCarrier(carrierId, carrierConf, waveformConf, randomAccessEnabled),
52 m_randomAccessCollisionModel(SatPhyRxCarrierConf::RA_COLLISION_NOT_DEFINED),
57{
58 if (randomAccessEnabled)
59 {
60 m_randomAccessCollisionModel = carrierConf->GetRandomAccessCollisionModel();
61 m_randomAccessConstantErrorRate = carrierConf->GetRandomAccessConstantErrorRate();
63 carrierConf->GetRandomAccessAverageNormalizedOfferedLoadMeasurementWindowSize();
65 carrierConf->IsRandomAccessDynamicLoadControlEnabled();
66
67 NS_LOG_INFO("RA interference model: "
68 << carrierConf->GetInterferenceModel(true)
69 << ", RA collision model: " << m_randomAccessCollisionModel
70 << ", RA avg. normalized offered load measurement window size: "
72 }
73}
74
76{
77 NS_LOG_FUNCTION(this);
78}
79
80void
84
85TypeId
87{
88 static TypeId tid =
89 TypeId("ns3::SatPhyRxCarrierPerSlot")
90 .SetParent<SatPhyRxCarrier>()
91 .AddAttribute(
92 "DisableErrorHighTransmissionTime",
93 "Disable fatal error when transmission time is higher than propagation time, but "
94 "computations are less precise.",
95 BooleanValue(false),
97 MakeBooleanChecker())
98 .AddTraceSource(
99 "SlottedAlohaRxCollision",
100 "Received a packet burst through Random Access Slotted ALOHA",
102 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback")
103 .AddTraceSource(
104 "SlottedAlohaRxError",
105 "Received a packet burst through Random Access Slotted ALOHA",
107 "ns3::SatPhyRxCarrierPacketProbe::RxStatusCallback");
108 return tid;
109}
110
111void
119
120Ptr<SatInterference::InterferenceChangeEvent>
121SatPhyRxCarrierPerSlot::CreateInterference(Ptr<SatSignalParameters> rxParams, Address senderAddress)
122{
123 NS_LOG_FUNCTION(this << rxParams << senderAddress);
124
125 // Case satellite regenerative
127 {
128 return GetInterferenceModel()->Add(rxParams->m_duration,
129 rxParams->m_rxPower_W,
130 GetOwnAddress());
131 }
132
135 {
136 // In feeder downlink the interference by UTs in the same
137 // beam (intra-beam interference e.g. due to random access) SHOULD NOT be tracked.
138 // Intra-beam interference is already taken into account at the satellite. Thus,
139 // here we pass intra-beam transmissions with zero interference power to the
140 // interference model.
141 // Rx power in the rxParams is the received power of only one of the interfering
142 // signals of the wanted signal. In reality, we are receiving the same signal
143 // through all the co-channel transponders of the satellite, where the rxPower
144 // is the C and all the other components are considered as interference I.
145 // This can be compensated with the following equation:
146 // rxPower = rxParams->m_rxPower_W * (1 + 1/rxParams->m_sinr);
147 // See more from satellite module documentation.
148
149 double rxPower(0.0);
150
151 if (rxParams->m_beamId != GetBeamId())
152 {
153 if (!rxParams->HasSinrComputed())
154 {
156 {
157 NS_LOG_WARN("SatPhyRx::StartRx - too long transmission time: packet started to "
158 "be received in a ground entity while not being fully received on "
159 "the satellite: interferences could not be properly computed.");
160 rxPower = rxParams->m_rxPower_W;
161 }
162 else
163 {
164 NS_FATAL_ERROR(
165 "SatPhyRx::StartRx - too long transmission time: packet started to be "
166 "received in a ground entity while not being fully received on the "
167 "satellite: interferences could not be properly computed.");
168 }
169 }
170 else
171 {
172 rxPower = rxParams->m_rxPower_W * (1 + 1 / rxParams->GetSinr());
173 }
174 }
175
176 // Add the interference even regardless.
177 return GetInterferenceModel()->Add(rxParams->m_duration, rxPower, GetOwnAddress());
178 }
179 else if (ct == SatEnums::FORWARD_USER_CH)
180 {
181 return GetInterferenceModel()->Add(rxParams->m_duration,
182 rxParams->m_rxPower_W,
183 GetOwnAddress());
184 }
185
186 NS_FATAL_ERROR("SatSatellitePhyRxCarrier::CreateInterference - Invalid channel type!");
187 return nullptr;
188}
189
190void
192{
193 NS_LOG_FUNCTION(this << key);
194
195 NS_LOG_INFO(this << " state: " << GetState());
196
197 NS_ASSERT(GetState() == RX);
198
199 rxParams_s packetRxParams = GetStoredRxParams(key);
200
201 const uint32_t nPackets = packetRxParams.rxParams->m_packetsInBurst.size();
202
203 DecreaseNumOfRxState(packetRxParams.rxParams->m_txInfo.packetType);
204
205 // Test if when receiving a packet on ground from transparent satellite, uplink SINR has been
206 // correctly set
208 {
209 NS_ASSERT(packetRxParams.rxParams->HasSinrComputed());
210 }
211
212 packetRxParams.rxParams->SetInterferencePower(
213 GetInterferenceModel()->Calculate(packetRxParams.interferenceEvent));
214
215 ReceiveSlot(packetRxParams, nPackets);
216
217 GetInterferenceModel()->NotifyRxEnd(packetRxParams.interferenceEvent);
218
220 packetRxParams.interferenceEvent = nullptr;
222}
223
224bool
226 double cSinr,
227 Ptr<SatSignalParameters> rxParams,
228 Ptr<SatInterference::InterferenceChangeEvent> interferenceEvent)
229{
230 NS_LOG_FUNCTION(this);
231
232 bool phyError = false;
233
236 {
239 phyError = GetInterferenceModel()->HasCollision(interferenceEvent);
240 NS_LOG_INFO("Strict collision mode, phyError: " << phyError);
241 }
243 {
245 phyError = CheckAgainstLinkResults(cSinr, rxParams);
246 NS_LOG_INFO("Composite SINR mode, phyError: " << phyError);
247 }
249 {
250 double r = GetUniformRandomValue(0, 1);
252 {
253 phyError = true;
254 }
255 NS_LOG_INFO("Constant collision probability mode, phyError: " << phyError);
256 }
257 else
258 {
259 NS_FATAL_ERROR("SatPhyRxCarrier::ProcessSlottedAlohaCollisions - Random access collision "
260 "model not defined");
261 }
262
263 return phyError;
264}
265
266void
268 const uint32_t nPackets)
269{
270 NS_LOG_FUNCTION(this << &packetRxParams << nPackets);
271
272 NS_ASSERT(packetRxParams.rxParams->m_txInfo.packetType != SatEnums::PACKET_TYPE_CRDSA);
274 double sinr = CalculateSinr(packetRxParams.rxParams->m_rxPower_W,
275 packetRxParams.rxParams->GetInterferencePower(),
280
281 SatAddressE2ETag addressE2ETag;
282 packetRxParams.rxParams->m_packetsInBurst[0]->PeekPacketTag(addressE2ETag);
283
284 // Update link specific SINR trace
285 switch (GetChannelType())
286 {
290 break;
294 break;
295 default:
296 NS_FATAL_ERROR("Incorrect channel for satPhyRxCarrierPerSlot: "
298 }
299
302 bool phyError(false);
303
305 double cSinr;
306 switch (GetLinkRegenerationMode())
307 {
309 cSinr = CalculateCompositeSinr(sinr, packetRxParams.rxParams->GetSinr());
310 break;
314 cSinr = sinr;
315 break;
316 default:
317 NS_FATAL_ERROR("Incorrect regeneration mode for satPhyRxCarrierPerSlot");
318 }
319
320 if (!m_cnoCallback.IsNull())
321 {
322 switch (GetLinkRegenerationMode())
323 {
326 double worstSinr = GetWorstSinr(sinr, packetRxParams.rxParams->GetSinr());
327
332 double cno = (GetLinkRegenerationMode() == SatEnums::TRANSPARENT) ? cSinr : worstSinr;
333
334 // Forward link
335 switch (GetNodeInfo()->GetNodeType())
336 {
337 case SatEnums::NT_UT:
340 break;
341 case SatEnums::NT_GW:
344 packetRxParams.rxParams->m_txInfo.waveformId));
345 break;
346 default:
347 NS_FATAL_ERROR("Unsupported node type for a NORMAL Rx model!");
348 }
349
350 cno *= m_rxBandwidthHz;
351
352 packetRxParams.rxParams->m_packetsInBurst[0]->PeekPacketTag(addressE2ETag);
353
354 m_cnoCallback(packetRxParams.rxParams->m_satId,
355 packetRxParams.rxParams->m_beamId,
356 addressE2ETag.GetE2ESourceAddress(),
358 cno,
359 false);
360 break;
361 }
365 packetRxParams.rxParams->m_packetsInBurst;
366 SatSignalParameters::PacketsInBurst_t::const_iterator i;
367 for (i = packets.begin(); i != packets.end(); i++)
368 {
369 SatUplinkInfoTag satUplinkInfoTag;
370 if (!(*i)->PeekPacketTag(satUplinkInfoTag))
371 {
372 NS_FATAL_ERROR("SatUplinkInfoTag not found !");
373 }
374
379 double worstCno = GetWorstSinr(sinr, satUplinkInfoTag.GetSinr());
380 double downlinkCno = sinr;
381
382 // Forward link and return link use same algorithms (because of SCPC)
383 switch (GetNodeInfo()->GetNodeType())
384 {
385 case SatEnums::NT_UT:
386 case SatEnums::NT_GW:
388 SatUtils::LinearToDb(worstCno)));
389 downlinkCno =
391 SatUtils::LinearToDb(downlinkCno)));
392 break;
393 default:
394 NS_FATAL_ERROR("Unsupported node type for a NORMAL Rx model!");
395 }
396
397 worstCno *= m_rxBandwidthHz;
398 downlinkCno *= m_rxBandwidthHz;
399
400 (*i)->PeekPacketTag(addressE2ETag);
401
402 SatMacTag satMacTag;
403 (*i)->PeekPacketTag(satMacTag);
404
405 m_cnoCallback(satUplinkInfoTag.GetSatId(),
406 satUplinkInfoTag.GetBeamId(),
407 addressE2ETag.GetE2ESourceAddress(),
409 worstCno,
410 false);
411
413 GetBeamId(),
414 satMacTag.GetSourceAddress(),
416 downlinkCno,
417 true);
418 }
419 break;
420 }
421 default:
422 NS_FATAL_ERROR("Incorrect regeneration mode for SatPhyRxCarrierPerSlot");
423 }
424 }
425
426 // Update composite SINR trace for DAMA and Slotted ALOHA packets
427 m_sinrTrace(SatUtils::LinearToDb(cSinr), packetRxParams.sourceAddress);
428
431 {
433 }
434
435 if (packetRxParams.rxParams->m_txInfo.packetType == SatEnums::PACKET_TYPE_SLOTTED_ALOHA)
436 {
437 NS_LOG_INFO("Slotted ALOHA packet received");
438
439 // Update the load with FEC block size!
440 m_randomAccessBitsInFrame += packetRxParams.rxParams->m_txInfo.fecBlockSizeInBytes *
442
444 phyError = ProcessSlottedAlohaCollisions(cSinr,
445 packetRxParams.rxParams,
446 packetRxParams.interferenceEvent);
447
448 if (nPackets > 0)
449 {
450 const bool hasCollision =
451 GetInterferenceModel()->HasCollision(packetRxParams.interferenceEvent);
452 m_slottedAlohaRxCollisionTrace(nPackets, // number of packets
453 packetRxParams.sourceAddress, // sender address
454 hasCollision // collision flag
455 );
456 m_slottedAlohaRxErrorTrace(nPackets, // number of packets
457 packetRxParams.sourceAddress, // sender address
458 phyError // error flag
459 );
460 }
461 }
462 else
463 {
465 phyError = CheckAgainstLinkResults(cSinr, packetRxParams.rxParams);
466
467 if (nPackets > 0)
468 {
469 switch (GetChannelType())
470 {
473 m_daRxTrace(nPackets, // number of packets
474 packetRxParams.destAddress, // destination address
475 phyError // error flag
476 );
477 break;
480 m_daRxTrace(nPackets, // number of packets
481 packetRxParams.sourceAddress, // destination address
482 phyError // error flag
483 );
484 break;
485 default:
486 NS_FATAL_ERROR("Channel unknown !");
487 }
488 }
489
491 }
492
493 switch (GetLinkRegenerationMode())
494 {
497 packetRxParams.rxParams->SetSinr(sinr, m_additionalInterferenceCallback());
498 break;
501 SatSignalParameters::PacketsInBurst_t packets = packetRxParams.rxParams->m_packetsInBurst;
502 SatSignalParameters::PacketsInBurst_t::const_iterator i;
503 for (i = packets.begin(); i != packets.end(); i++)
504 {
505 SatUplinkInfoTag satUplinkInfoTag;
506 (*i)->RemovePacketTag(satUplinkInfoTag);
507 satUplinkInfoTag.SetSinr(sinr, m_additionalInterferenceCallback());
508 (*i)->AddPacketTag(satUplinkInfoTag);
509 }
510 break;
511 }
512 default:
513 NS_FATAL_ERROR("Incorrect regeneration mode for SatPhyRxCarrierPerSlot");
514 }
515
517 m_linkBudgetTrace(packetRxParams.rxParams,
519 packetRxParams.destAddress,
520 packetRxParams.rxParams->GetInterferencePower(),
521 cSinr);
522
524 m_rxCallback(packetRxParams.rxParams, phyError);
525
526 packetRxParams.rxParams = nullptr;
527}
528
529void
542
543double
545{
546 NS_LOG_FUNCTION(this);
547
548 double sum = 0.0;
549 double averageNormalizedOfferedLoad = 0.0;
550 std::deque<double>::iterator it;
551
554 it++)
555 {
556 sum += (*it);
557 }
558
560 {
561 averageNormalizedOfferedLoad =
563 }
564
565 NS_LOG_INFO("Average normalized offered load: " << averageNormalizedOfferedLoad);
566
567 return averageNormalizedOfferedLoad;
568}
569
570} // namespace ns3
This class implements a tag that carries the satellite MAC of GW and UT.
Mac48Address GetE2ESourceAddress(void) const
Get E2E source MAC address.
Mac48Address GetE2EDestAddress(void) const
Get E2E destination MAC address.
ChannelType_t
Types of channel.
static std::string GetChannelTypeName(ChannelType_t channelType)
This class implements a tag that carries the satellite MAC specific information, such as source and d...
Mac48Address GetSourceAddress(void) const
Get source MAC address.
Information of beam users liken UTs and their users.
void DoCompositeSinrOutputTrace(double cSinr)
Function for composite SINR output tracing.
void RemoveStoredRxParams(uint32_t key)
Remove stored rxParams under a key.
double m_rxExtNoisePowerW
External noise power system RX noise.
TracedCallback< double, const Address & > m_linkSinrTrace
A callback for link specific SINR in dB.
Ptr< SatChannelEstimationErrorContainer > GetChannelEstimationErrorContainer()
Get a pointer to the channel estimation error container of the carrier.
TracedCallback< uint32_t, const Address & > m_daRxCarrierIdTrace
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.
void DecreaseNumOfRxState(SatEnums::PacketType_t packetType)
Function for decreasing the number of ongoing transmissions.
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).
rxParams_s GetStoredRxParams(uint32_t key)
Get stored rxParams under a key.
bool CheckAgainstLinkResults(double cSinr, Ptr< SatSignalParameters > rxParams)
Function for checking the SINR against the link results.
SatPhy::CnoCallback m_cnoCallback
The upper layer C/N0 receive callback.
double CalculateCompositeSinr(double sinr1, double sinr2)
Function for calculating the composite SINR.
double GetWorstSinr(double sinr1, double sinr2)
Function for calculating the worst sinr between uplink and downlink.
virtual void DoDispose()
Dispose.
Ptr< SatInterference > GetInterferenceModel()
Get pointer to the current interference model.
double GetUniformRandomValue(double min, double max)
A helper method for getting values form a uniform random variable in child classes.
SatPhyRxCarrier(uint32_t carrierId, Ptr< SatPhyRxCarrierConf > carrierConf, Ptr< SatWaveformConf > waveformConf, bool isRandomAccessEnabled)
Constructor.
uint32_t GetSatId()
Get ID the ID of the satellite this carrier is attached to.
double m_rxBandwidthHz
RX Bandwidth in Hz.
State GetState()
Get the state of the carrier.
Mac48Address GetOwnAddress()
Get the MAC address of the carrier.
Inherited the base functionality of SatPhyRxCarriers for ground station nodes.
uint8_t m_randomAccessAllocationChannelId
PRIVATE MEMBER VARIABLES.
TracedCallback< uint32_t, const Address &, bool > m_slottedAlohaRxCollisionTrace
SlottedAlohaRxCollision trace source.
SatPhyRxCarrierPerSlot(uint32_t carrierId, Ptr< SatPhyRxCarrierConf > carrierConf, Ptr< SatWaveformConf > waveformConf, bool randomAccessEnabled)
Constructor.
static TypeId GetTypeId(void)
Get the TypeId of the class.
virtual void EndRxData(uint32_t key)
Function for ending the packet reception from the SatChannel.
bool ProcessSlottedAlohaCollisions(double cSinr, Ptr< SatSignalParameters > rxParams, Ptr< SatInterference::InterferenceChangeEvent > interferenceEvent)
Function for processing the Slotted ALOHA collisions.
TracedCallback< uint32_t, const Address &, bool > m_slottedAlohaRxErrorTrace
SlottedAlohaRxError trace source.
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 m_randomAccessCollisionModel
virtual Ptr< SatInterference::InterferenceChangeEvent > CreateInterference(Ptr< SatSignalParameters > rxParams, Address rxAddress)
Create an interference event based on Rx parameters and address.
uint32_t m_randomAccessBitsInFrame
The number of random access bits in current frame.
std::deque< double > m_randomAccessDynamicLoadControlNormalizedOfferedLoad
double CalculateAverageNormalizedOfferedRandomAccessLoad()
Function for calculating the average normalized offered random access load.
virtual void BeginEndScheduling()
Function for initializing the frame/window end scheduling.
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.
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< SatInterference::InterferenceChangeEvent > interferenceEvent