A Discrete-Event Network Simulator
API
interference-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include <numeric>
23 #include <algorithm>
24 #include "ns3/simulator.h"
25 #include "ns3/log.h"
26 #include "ns3/packet.h"
27 #include "interference-helper.h"
28 #include "wifi-phy.h"
29 #include "error-rate-model.h"
30 #include "wifi-utils.h"
31 #include "wifi-psdu.h"
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
36 
37 /****************************************************************
38  * PHY event class
39  ****************************************************************/
40 
42  : m_ppdu (ppdu),
43  m_txVector (txVector),
44  m_startTime (Simulator::Now ()),
45  m_endTime (m_startTime + duration),
46  m_rxPowerW (rxPower)
47 {
48 }
49 
51 {
52  m_ppdu = 0;
53  m_rxPowerW.clear ();
54 }
55 
57 Event::GetPpdu (void) const
58 {
59  return m_ppdu;
60 }
61 
62 Time
63 Event::GetStartTime (void) const
64 {
65  return m_startTime;
66 }
67 
68 Time
69 Event::GetEndTime (void) const
70 {
71  return m_endTime;
72 }
73 
74 Time
75 Event::GetDuration (void) const
76 {
77  return m_endTime - m_startTime;
78 }
79 
80 double
81 Event::GetRxPowerW (void) const
82 {
83  NS_ASSERT (m_rxPowerW.size () > 0);
84  //The total RX power corresponds to the maximum over all the bands
85  auto it = std::max_element (m_rxPowerW.begin (), m_rxPowerW.end (),
86  [] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
87  return p1.second < p2.second;
88  });
89  return it->second;
90 }
91 
92 double
94 {
95  auto it = m_rxPowerW.find (band);
96  NS_ASSERT (it != m_rxPowerW.end ());
97  return it->second;
98 }
99 
102 {
103  return m_rxPowerW;
104 }
105 
106 const WifiTxVector&
107 Event::GetTxVector (void) const
108 {
109  return m_txVector;
110 }
111 
112 void
114 {
115  NS_ASSERT (rxPower.size () == m_rxPowerW.size ());
116  //Update power band per band
117  for (auto & currentRxPowerW : m_rxPowerW)
118  {
119  auto band = currentRxPowerW.first;
120  auto it = rxPower.find (band);
121  if (it != rxPower.end ())
122  {
123  currentRxPowerW.second += it->second;
124  }
125  }
126 }
127 
128 std::ostream & operator << (std::ostream &os, const Event &event)
129 {
130  os << "start=" << event.GetStartTime () << ", end=" << event.GetEndTime ()
131  << ", TXVECTOR=" << event.GetTxVector ()
132  << ", power=" << event.GetRxPowerW () << "W"
133  << ", PPDU=" << event.GetPpdu ();
134  return os;
135 }
136 
137 /****************************************************************
138  * Class which records SNIR change events for a
139  * short period of time.
140  ****************************************************************/
141 
143  : m_power (power),
144  m_event (event)
145 {
146 }
147 
149 {
150  m_event = 0;
151 }
152 
153 double
155 {
156  return m_power;
157 }
158 
159 void
161 {
162  m_power += power;
163 }
164 
167 {
168  return m_event;
169 }
170 
171 
172 /****************************************************************
173  * The actual InterferenceHelper
174  ****************************************************************/
175 
177  : m_errorRateModel (0),
178  m_numRxAntennas (1),
179  m_rxing (false)
180 {
181 }
182 
184 {
185  RemoveBands ();
186  m_errorRateModel = 0;
187 }
188 
190 InterferenceHelper::Add (Ptr<const WifiPpdu> ppdu, const WifiTxVector& txVector, Time duration, RxPowerWattPerChannelBand rxPowerW, bool isStartOfdmaRxing)
191 {
192  Ptr<Event> event = Create<Event> (ppdu, txVector, duration, rxPowerW);
193  AppendEvent (event, isStartOfdmaRxing);
194  return event;
195 }
196 
197 void
199 {
200  // Parameters other than duration and rxPowerW are unused for this type
201  // of signal, so we provide dummy versions
202  WifiMacHeader hdr;
204  hdr.SetQosTid (0);
205  Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu> (Create<WifiPsdu> (Create<Packet> (0), hdr),
206  WifiTxVector ());
207  Add (fakePpdu, WifiTxVector (), duration, rxPowerW);
208 }
209 
210 void
212 {
213  NS_LOG_FUNCTION (this);
214  for (auto it : m_niChangesPerBand)
215  {
216  it.second.clear ();
217  }
218  m_niChangesPerBand.clear();
219  m_firstPowerPerBand.clear();
220 }
221 
222 void
224 {
225  NS_LOG_FUNCTION (this << band.first << band.second);
226  NS_ASSERT (m_niChangesPerBand.find (band) == m_niChangesPerBand.end ());
227  NiChanges niChanges;
228  m_niChangesPerBand.insert ({band, niChanges});
229  // Always have a zero power noise event in the list
230  AddNiChangeEvent (Time (0), NiChange (0.0, 0), band);
231  m_firstPowerPerBand.insert ({band, 0.0});
232 }
233 
234 void
236 {
237  m_noiseFigure = value;
238 }
239 
240 void
242 {
243  m_errorRateModel = rate;
244 }
245 
248 {
249  return m_errorRateModel;
250 }
251 
252 void
254 {
255  m_numRxAntennas = rx;
256 }
257 
258 Time
260 {
261  Time now = Simulator::Now ();
262  auto i = GetPreviousPosition (now, band);
263  Time end = i->first;
264  auto ni_it = m_niChangesPerBand.find (band);
265  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
266  for (; i != ni_it->second.end (); ++i)
267  {
268  double noiseInterferenceW = i->second.GetPower ();
269  end = i->first;
270  if (noiseInterferenceW < energyW)
271  {
272  break;
273  }
274  }
275  return end > now ? end - now : MicroSeconds (0);
276 }
277 
278 void
279 InterferenceHelper::AppendEvent (Ptr<Event> event, bool isStartOfdmaRxing)
280 {
281  NS_LOG_FUNCTION (this << event << isStartOfdmaRxing);
282  RxPowerWattPerChannelBand rxPowerWattPerChannelBand = event->GetRxPowerWPerBand ();
283  for (auto const& it : rxPowerWattPerChannelBand)
284  {
285  WifiSpectrumBand band = it.first;
286  auto ni_it = m_niChangesPerBand.find (band);
287  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
288  double previousPowerStart = 0;
289  double previousPowerEnd = 0;
290  previousPowerStart = GetPreviousPosition (event->GetStartTime (), band)->second.GetPower ();
291  previousPowerEnd = GetPreviousPosition (event->GetEndTime (), band)->second.GetPower ();
292  if (!m_rxing)
293  {
294  m_firstPowerPerBand.find (band)->second = previousPowerStart;
295  // Always leave the first zero power noise event in the list
296  ni_it->second.erase (++(ni_it->second.begin ()), GetNextPosition (event->GetStartTime (), band));
297  }
298  else if (isStartOfdmaRxing)
299  {
300  //When the first UL-OFDMA payload is received, we need to set m_firstPowerPerBand
301  //so that it takes into account interferences that arrived between the start of the
302  //UL MU transmission and the start of UL-OFDMA payload.
303  m_firstPowerPerBand.find (band)->second = previousPowerStart;
304  }
305  auto first = AddNiChangeEvent (event->GetStartTime (), NiChange (previousPowerStart, event), band);
306  auto last = AddNiChangeEvent (event->GetEndTime (), NiChange (previousPowerEnd, event), band);
307  for (auto i = first; i != last; ++i)
308  {
309  i->second.AddPower (it.second);
310  }
311  }
312 }
313 
314 void
316 {
317  NS_LOG_FUNCTION (this << event);
318  //This is called for UL MU events, in order to scale power as long as UL MU PPDUs arrive
319  for (auto const& it : rxPower)
320  {
321  WifiSpectrumBand band = it.first;
322  auto ni_it = m_niChangesPerBand.find (band);
323  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
324  auto first = GetPreviousPosition (event->GetStartTime (), band);
325  auto last = GetPreviousPosition (event->GetEndTime (), band);
326  for (auto i = first; i != last; ++i)
327  {
328  i->second.AddPower (it.second);
329  }
330  }
331  event->UpdateRxPowerW (rxPower);
332 }
333 
334 double
335 InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const
336 {
337  NS_LOG_FUNCTION (this << signal << noiseInterference << channelWidth << +nss);
338  //thermal noise at 290K in J/s = W
339  static const double BOLTZMANN = 1.3803e-23;
340  //Nt is the power of thermal noise in W
341  double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
342  //receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
343  double noiseFloor = m_noiseFigure * Nt;
344  double noise = noiseFloor + noiseInterference;
345  double snr = signal / noise; //linear scale
346  NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB");
347  if (m_errorRateModel->IsAwgn ())
348  {
349  double gain = 1;
350  if (m_numRxAntennas > nss)
351  {
352  gain = static_cast<double> (m_numRxAntennas) / nss; //compute gain offered by diversity for AWGN
353  }
354  NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB");
355  snr *= gain;
356  }
357  return snr;
358 }
359 
360 double
362 {
363  NS_LOG_FUNCTION (this << band.first << band.second);
364  auto firstPower_it = m_firstPowerPerBand.find (band);
365  NS_ASSERT (firstPower_it != m_firstPowerPerBand.end ());
366  double noiseInterferenceW = firstPower_it->second;
367  auto ni_it = m_niChangesPerBand.find (band);
368  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
369  auto it = ni_it->second.find (event->GetStartTime ());
370  for (; it != ni_it->second.end () && it->first < Simulator::Now (); ++it)
371  {
372  noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW (band);
373  }
374  it = ni_it->second.find (event->GetStartTime ());
375  NS_ASSERT (it != ni_it->second.end ());
376  for (; it != ni_it->second.end () && it->second.GetEvent () != event; ++it);
377  NiChanges ni;
378  ni.emplace (event->GetStartTime (), NiChange (0, event));
379  while (++it != ni_it->second.end () && it->second.GetEvent () != event)
380  {
381  ni.insert (*it);
382  }
383  ni.emplace (event->GetEndTime (), NiChange (0, event));
384  nis->insert ({band, ni});
385  NS_ASSERT_MSG (noiseInterferenceW >= 0, "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
386  return noiseInterferenceW;
387 }
388 
389 double
390 InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, const WifiTxVector& txVector, WifiPpduField field) const
391 {
392  if (duration.IsZero ())
393  {
394  return 1.0;
395  }
396  uint64_t rate = mode.GetDataRate (txVector.GetChannelWidth ());
397  uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
398  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits, m_numRxAntennas, field);
399  return csr;
400 }
401 
402 double
403 InterferenceHelper::CalculatePayloadChunkSuccessRate (double snir, Time duration, const WifiTxVector& txVector, uint16_t staId) const
404 {
405  if (duration.IsZero ())
406  {
407  return 1.0;
408  }
409  WifiMode mode = txVector.GetMode (staId);
410  uint64_t rate = mode.GetDataRate (txVector, staId);
411  uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
412  nbits /= txVector.GetNss (staId); //divide effective number of bits by NSS to achieve same chunk error rate as SISO for AWGN
413  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits, m_numRxAntennas, WIFI_PPDU_FIELD_DATA, staId);
414  return csr;
415 }
416 
417 double
420  uint16_t staId, std::pair<Time, Time> window) const
421 {
422  NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << window.first << window.second);
423  double psr = 1.0; /* Packet Success Rate */
424  auto ni_it = nis->find (band)->second;
425  auto j = ni_it.begin ();
426  Time previous = j->first;
427  WifiMode payloadMode = event->GetTxVector ().GetMode (staId);
428  Time phyPayloadStart = j->first;
429  if (event->GetPpdu ()->GetType () != WIFI_PPDU_TYPE_UL_MU) //j->first corresponds to the start of the UL-OFDMA payload
430  {
431  phyPayloadStart = j->first + WifiPhy::CalculatePhyPreambleAndHeaderDuration (event->GetTxVector ());
432  }
433  Time windowStart = phyPayloadStart + window.first;
434  Time windowEnd = phyPayloadStart + window.second;
435  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
436  double powerW = event->GetRxPowerW (band);
437  while (++j != ni_it.end ())
438  {
439  Time current = j->first;
440  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
441  NS_ASSERT (current >= previous);
442  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, event->GetTxVector ().GetNss (staId));
443  //Case 1: Both previous and current point to the windowed payload
444  if (previous >= windowStart)
445  {
446  psr *= CalculatePayloadChunkSuccessRate (snr, Min (windowEnd, current) - previous, event->GetTxVector (), staId);
447  NS_LOG_DEBUG ("Both previous and current point to the windowed payload: mode=" << payloadMode << ", psr=" << psr);
448  }
449  //Case 2: previous is before windowed payload and current is in the windowed payload
450  else if (current >= windowStart)
451  {
452  psr *= CalculatePayloadChunkSuccessRate (snr, Min (windowEnd, current) - windowStart, event->GetTxVector (), staId);
453  NS_LOG_DEBUG ("previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode << ", psr=" << psr);
454  }
455  noiseInterferenceW = j->second.GetPower () - powerW;
456  previous = j->first;
457  if (previous > windowEnd)
458  {
459  NS_LOG_DEBUG ("Stop: new previous=" << previous << " after time window end=" << windowEnd);
460  break;
461  }
462  }
463  double per = 1 - psr;
464  return per;
465 }
466 
467 double
469  uint16_t channelWidth, WifiSpectrumBand band,
470  PhyEntity::PhyHeaderSections phyHeaderSections) const
471 {
472  NS_LOG_FUNCTION (this << band.first << band.second);
473  double psr = 1.0; /* Packet Success Rate */
474  auto ni_it = nis->find (band)->second;
475  auto j = ni_it.begin ();
476 
477  NS_ASSERT (!phyHeaderSections.empty ());
478  Time stopLastSection = Seconds (0);
479  for (const auto & section : phyHeaderSections)
480  {
481  stopLastSection = Max (stopLastSection, section.second.first.second);
482  }
483 
484  Time previous = j->first;
485  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
486  double powerW = event->GetRxPowerW (band);
487  while (++j != ni_it.end ())
488  {
489  Time current = j->first;
490  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
491  NS_ASSERT (current >= previous);
492  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
493  for (const auto & section : phyHeaderSections)
494  {
495  Time start = section.second.first.first;
496  Time stop = section.second.first.second;
497 
498  if (previous <= stop || current >= start)
499  {
500  Time duration = Min (stop, current) - Max (start, previous);
501  if (duration.IsStrictlyPositive ())
502  {
503  psr *= CalculateChunkSuccessRate (snr, duration, section.second.second, event->GetTxVector (), section.first);
504  NS_LOG_DEBUG ("Current NI change in " << section.first << " [" << start << ", " << stop << "] for "
505  << duration.As (Time::NS) << ": mode=" << section.second.second << ", psr=" << psr);
506  }
507  }
508  }
509  noiseInterferenceW = j->second.GetPower () - powerW;
510  previous = j->first;
511  if (previous > stopLastSection)
512  {
513  NS_LOG_DEBUG ("Stop: new previous=" << previous << " after stop of last section=" << stopLastSection);
514  break;
515  }
516  }
517  return psr;
518 }
519 
520 double
522  uint16_t channelWidth, WifiSpectrumBand band,
523  WifiPpduField header) const
524 {
525  NS_LOG_FUNCTION (this << band.first << band.second << header);
526  auto ni_it = nis->find (band)->second;
527  auto phyEntity = WifiPhy::GetStaticPhyEntity (event->GetTxVector ().GetModulationClass ());
528 
530  for (const auto & section : phyEntity->GetPhyHeaderSections (event->GetTxVector (), ni_it.begin ()->first))
531  {
532  if (section.first == header)
533  {
534  sections[header] = section.second;
535  }
536  }
537 
538  double psr = 1.0;
539  if (!sections.empty () > 0)
540  {
541  psr = CalculatePhyHeaderSectionPsr (event, nis, channelWidth, band, sections);
542  }
543  return 1 - psr;
544 }
545 
546 struct PhyEntity::SnrPer
547 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
548  uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const
549 {
550  NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << relativeMpduStartStop.first << relativeMpduStartStop.second);
551  NiChangesPerBand ni;
552  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
553  double snr = CalculateSnr (event->GetRxPowerW (band),
554  noiseInterferenceW,
555  channelWidth,
556  event->GetTxVector ().GetNss (staId));
557 
558  /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
559  * all SNIR changes in the SNIR vector.
560  */
561  double per = CalculatePayloadPer (event, channelWidth, &ni, band, staId, relativeMpduStartStop);
562 
563  return PhyEntity::SnrPer (snr, per);
564 }
565 
566 double
567 InterferenceHelper::CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
568 {
569  NiChangesPerBand ni;
570  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
571  double snr = CalculateSnr (event->GetRxPowerW (band),
572  noiseInterferenceW,
573  channelWidth,
574  nss);
575  return snr;
576 }
577 
578 struct PhyEntity::SnrPer
579 InterferenceHelper::CalculatePhyHeaderSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
580  WifiPpduField header) const
581 {
582  NS_LOG_FUNCTION (this << band.first << band.second << header);
583  NiChangesPerBand ni;
584  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
585  double snr = CalculateSnr (event->GetRxPowerW (band),
586  noiseInterferenceW,
587  channelWidth,
588  1);
589 
590  /* calculate the SNIR at the start of the PHY header and accumulate
591  * all SNIR changes in the SNIR vector.
592  */
593  double per = CalculatePhyHeaderPer (event, &ni, channelWidth, band, header);
594 
595  return PhyEntity::SnrPer (snr, per);
596 }
597 
598 void
600 {
601  for (auto it : m_niChangesPerBand)
602  {
603  it.second.clear ();
604  // Always have a zero power noise event in the list
605  AddNiChangeEvent (Time (0), NiChange (0.0, 0), it.first);
606  m_firstPowerPerBand.at (it.first) = 0.0;
607  }
608  m_rxing = false;
609 }
610 
611 InterferenceHelper::NiChanges::iterator
613 {
614  auto it = m_niChangesPerBand.find (band);
615  NS_ASSERT (it != m_niChangesPerBand.end ());
616  return it->second.upper_bound (moment);
617 }
618 
619 InterferenceHelper::NiChanges::iterator
621 {
622  auto it = GetNextPosition (moment, band);
623  // This is safe since there is always an NiChange at time 0,
624  // before moment.
625  --it;
626  return it;
627 }
628 
629 InterferenceHelper::NiChanges::iterator
631 {
632  auto it = m_niChangesPerBand.find (band);
633  NS_ASSERT (it != m_niChangesPerBand.end ());
634  return it->second.insert (GetNextPosition (moment, band), std::make_pair (moment, change));
635 }
636 
637 void
639 {
640  NS_LOG_FUNCTION (this);
641  m_rxing = true;
642 }
643 
644 void
646 {
647  NS_LOG_FUNCTION (this << endTime);
648  m_rxing = false;
649  //Update m_firstPowerPerBand for frame capture
650  for (auto ni : m_niChangesPerBand)
651  {
652  NS_ASSERT (ni.second.size () > 1);
653  auto it = GetPreviousPosition (endTime, ni.first);
654  it--;
655  m_firstPowerPerBand.find (ni.first)->second = it->second.GetPower ();
656  }
657 }
658 
659 } //namespace ns3
handles interference calculations
Time m_endTime
end time
RxPowerWattPerChannelBand GetRxPowerWPerBand(void) const
Return the received power (W) for all bands.
WifiTxVector m_txVector
TXVECTOR.
Time m_startTime
start time
Ptr< const WifiPpdu > m_ppdu
PPDU.
void UpdateRxPowerW(RxPowerWattPerChannelBand rxPower)
Update the received power (W) for all bands, i.e.
const WifiTxVector & GetTxVector(void) const
Return the TXVECTOR of the PPDU.
Time GetDuration(void) const
Return the duration of the signal.
Ptr< const WifiPpdu > GetPpdu(void) const
Return the PPDU.
RxPowerWattPerChannelBand m_rxPowerW
received power in watts per band
Time GetStartTime(void) const
Return the start time of the signal.
Event(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand rxPower)
Create an Event with the given parameters.
double GetRxPowerW(void) const
Return the total received power (W).
Time GetEndTime(void) const
Return the end time of the signal.
Noise and Interference (thus Ni) event.
void AddPower(double power)
Add a given amount of power.
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
double GetPower(void) const
Return the power.
Ptr< Event > GetEvent(void) const
Return the event causes the corresponding NI change.
handles interference calculations
void SetNoiseFigure(double value)
Set the noise figure.
double m_noiseFigure
noise figure (linear)
NiChanges::iterator AddNiChangeEvent(Time moment, NiChange change, WifiSpectrumBand band)
Add NiChange to the list at the appropriate position and return the iterator of the new event.
bool m_rxing
flag whether it is in receiving state
void EraseEvents(void)
Erase all events.
std::map< WifiSpectrumBand, NiChanges > NiChangesPerBand
Map of NiChanges per band.
void UpdateEvent(Ptr< Event > event, RxPowerWattPerChannelBand rxPower)
Update event to scale its received power (W) per band.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand rxPower, bool isStartOfdmaRxing=false)
Add the PPDU-related signal to interference helper.
void NotifyRxEnd(Time endTime)
Notify that RX has ended.
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate noise and interference power in W.
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChange
Time GetEnergyDuration(double energyW, WifiSpectrumBand band)
NiChanges::iterator GetPreviousPosition(Time moment, WifiSpectrumBand band)
Returns an iterator to the last NiChange that is before than moment.
double CalculatePayloadChunkSuccessRate(double snir, Time duration, const WifiTxVector &txVector, uint16_t staId=SU_STA_ID) const
Calculate the success rate of the payload chunk given the SINR, duration, and TXVECTOR.
void AddForeignSignal(Time duration, RxPowerWattPerChannelBand rxPower)
Add a non-Wifi signal to interference helper.
Ptr< ErrorRateModel > m_errorRateModel
error rate model
void AppendEvent(Ptr< Event > event, bool isStartOfdmaRxing)
Append the given Event.
NiChanges::iterator GetNextPosition(Time moment, WifiSpectrumBand band)
Returns an iterator to the first NiChange that is later than moment.
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
void NotifyRxStart()
Notify that RX has started.
double CalculateSnr(Ptr< Event > event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
Calculate the SNIR for the event (starting from now until the event end).
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, const WifiTxVector &txVector, WifiPpduField field) const
Calculate the success rate of the chunk given the SINR, duration, and TXVECTOR.
double CalculatePayloadPer(Ptr< const Event > event, uint16_t channelWidth, NiChangesPerBand *nis, WifiSpectrumBand band, uint16_t staId, std::pair< Time, Time > window) const
Calculate the error rate of the given PHY payload only in the provided time window (thus enabling per...
void RemoveBands(void)
Remove the frequency bands.
double CalculatePhyHeaderSectionPsr(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, PhyEntity::PhyHeaderSections phyHeaderSections) const
Calculate the success rate of the PHY header sections for the provided event.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
void AddBand(WifiSpectrumBand band)
Add a frequency band.
double CalculatePhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, WifiSpectrumBand band, WifiPpduField header) const
Calculate the error rate of the PHY header.
NiChangesPerBand m_niChangesPerBand
NI Changes for each band.
std::map< WifiSpectrumBand, double > m_firstPowerPerBand
first power of each band in watts
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:301
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Control the scheduling of simulation events.
Definition: simulator.h:69
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
@ NS
nanosecond
Definition: nstime.h:118
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
Implements the IEEE 802.11 MAC header.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
represent a single transmission mode
Definition: wifi-mode.h:48
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:100
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:870
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1604
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
uint16_t GetChannelWidth(void) const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:230
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:218
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_PPDU_TYPE_UL_MU
@ WIFI_PPDU_FIELD_DATA
data field
Definition: first.py:1
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
@ WIFI_MAC_QOSDATA
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
def start()
Definition: core.py:1855
A struct for both SNR and PER.
Definition: phy-entity.h:137
double snr
SNR in linear scale.
Definition: phy-entity.h:138