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-ppdu.h"
32 #include "wifi-psdu.h"
33 
34 namespace ns3 {
35 
36 NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
37 
38 /****************************************************************
39  * PHY event class
40  ****************************************************************/
41 
43  : m_ppdu (ppdu),
44  m_txVector (txVector),
45  m_startTime (Simulator::Now ()),
46  m_endTime (m_startTime + duration),
47  m_rxPowerW (rxPower)
48 {
49 }
50 
52 {
53 }
54 
56 Event::GetPpdu (void) const
57 {
58  return m_ppdu;
59 }
60 
61 Time
62 Event::GetStartTime (void) const
63 {
64  return m_startTime;
65 }
66 
67 Time
68 Event::GetEndTime (void) const
69 {
70  return m_endTime;
71 }
72 
73 Time
74 Event::GetDuration (void) const
75 {
76  return m_endTime - m_startTime;
77 }
78 
79 double
80 Event::GetRxPowerW (void) const
81 {
82  NS_ASSERT (m_rxPowerW.size () > 0);
83  //The total RX power corresponds to the maximum over all the bands
84  auto it = std::max_element (m_rxPowerW.begin (), m_rxPowerW.end (),
85  [] (const std::pair<WifiSpectrumBand, double>& p1, const std::pair<WifiSpectrumBand, double>& p2) {
86  return p1.second < p2.second;
87  });
88  return it->second;
89 }
90 
91 double
93 {
94  auto it = m_rxPowerW.find (band);
95  NS_ASSERT (it != m_rxPowerW.end ());
96  return it->second;
97 }
98 
101 {
102  return m_rxPowerW;
103 }
104 
106 Event::GetTxVector (void) const
107 {
108  return m_txVector;
109 }
110 
111 std::ostream & operator << (std::ostream &os, const Event &event)
112 {
113  os << "start=" << event.GetStartTime () << ", end=" << event.GetEndTime ()
114  << ", TXVECTOR=" << event.GetTxVector ()
115  << ", power=" << event.GetRxPowerW () << "W"
116  << ", PPDU=" << event.GetPpdu ();
117  return os;
118 }
119 
120 /****************************************************************
121  * Class which records SNIR change events for a
122  * short period of time.
123  ****************************************************************/
124 
126  : m_power (power),
127  m_event (event)
128 {
129 }
130 
131 double
133 {
134  return m_power;
135 }
136 
137 void
139 {
140  m_power += power;
141 }
142 
145 {
146  return m_event;
147 }
148 
149 
150 /****************************************************************
151  * The actual InterferenceHelper
152  ****************************************************************/
153 
155  : m_errorRateModel (0),
156  m_numRxAntennas (1),
157  m_rxing (false)
158 {
159 }
160 
162 {
163  EraseEvents ();
164  m_errorRateModel = 0;
165 }
166 
169 {
170  Ptr<Event> event = Create<Event> (ppdu, txVector, duration, rxPowerW);
171  AppendEvent (event);
172  return event;
173 }
174 
175 void
177 {
178  // Parameters other than duration and rxPowerW are unused for this type
179  // of signal, so we provide dummy versions
180  WifiMacHeader hdr;
182  Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu> (Create<WifiPsdu> (Create<Packet> (0), hdr),
184  Add (fakePpdu, WifiTxVector (), duration, rxPowerW);
185 }
186 
187 void
189 {
190  NS_LOG_FUNCTION (this);
191  m_niChangesPerBand.clear();
192  m_firstPowerPerBand.clear();
193 }
194 
195 void
197 {
198  NS_LOG_FUNCTION (this << band.first << band.second);
199  NS_ASSERT (m_niChangesPerBand.find (band) == m_niChangesPerBand.end ());
200  NiChanges niChanges;
201  m_niChangesPerBand.insert ({band, niChanges});
202  // Always have a zero power noise event in the list
203  AddNiChangeEvent (Time (0), NiChange (0.0, 0), band);
204  m_firstPowerPerBand.insert ({band, 0.0});
205 }
206 
207 void
209 {
210  m_noiseFigure = value;
211 }
212 
213 void
215 {
216  m_errorRateModel = rate;
217 }
218 
221 {
222  return m_errorRateModel;
223 }
224 
225 void
227 {
228  m_numRxAntennas = rx;
229 }
230 
231 Time
233 {
234  Time now = Simulator::Now ();
235  auto i = GetPreviousPosition (now, band);
236  Time end = i->first;
237  auto ni_it = m_niChangesPerBand.find (band);
238  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
239  for (; i != ni_it->second.end (); ++i)
240  {
241  double noiseInterferenceW = i->second.GetPower ();
242  end = i->first;
243  if (noiseInterferenceW < energyW)
244  {
245  break;
246  }
247  }
248  return end > now ? end - now : MicroSeconds (0);
249 }
250 
251 void
253 {
254  NS_LOG_FUNCTION (this);
255  RxPowerWattPerChannelBand rxPowerWattPerChannelBand = event->GetRxPowerWPerBand ();
256  for (auto const& it : rxPowerWattPerChannelBand)
257  {
258  WifiSpectrumBand band = it.first;
259  auto ni_it = m_niChangesPerBand.find (band);
260  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
261  double previousPowerStart = 0;
262  double previousPowerEnd = 0;
263  previousPowerStart = GetPreviousPosition (event->GetStartTime (), band)->second.GetPower ();
264  previousPowerEnd = GetPreviousPosition (event->GetEndTime (), band)->second.GetPower ();
265  if (!m_rxing)
266  {
267  m_firstPowerPerBand.find (band)->second = previousPowerStart;
268  // Always leave the first zero power noise event in the list
269  ni_it->second.erase (++(ni_it->second.begin ()), GetNextPosition (event->GetStartTime (), band));
270  }
271  auto first = AddNiChangeEvent (event->GetStartTime (), NiChange (previousPowerStart, event), band);
272  auto last = AddNiChangeEvent (event->GetEndTime (), NiChange (previousPowerEnd, event), band);
273  for (auto i = first; i != last; ++i)
274  {
275  i->second.AddPower (it.second);
276  }
277  }
278 }
279 
280 double
281 InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint16_t channelWidth, uint8_t nss) const
282 {
283  NS_LOG_FUNCTION (this << signal << noiseInterference << channelWidth << +nss);
284  //thermal noise at 290K in J/s = W
285  static const double BOLTZMANN = 1.3803e-23;
286  //Nt is the power of thermal noise in W
287  double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
288  //receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
289  double noiseFloor = m_noiseFigure * Nt;
290  double noise = noiseFloor + noiseInterference;
291  double snr = signal / noise; //linear scale
292  NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr=" << RatioToDb(snr) << "dB");
293  double gain = 1;
294  if (m_numRxAntennas > nss)
295  {
296  gain = static_cast<double>(m_numRxAntennas) / nss; //compute gain offered by diversity for AWGN
297  }
298  NS_LOG_DEBUG ("SNR improvement thanks to diversity: " << 10 * std::log10 (gain) << "dB");
299  snr *= gain;
300  return snr;
301 }
302 
303 double
305 {
306  NS_LOG_FUNCTION (this << band.first << band.second);
307  auto firstPower_it = m_firstPowerPerBand.find (band);
308  NS_ASSERT (firstPower_it != m_firstPowerPerBand.end ());
309  double noiseInterferenceW = firstPower_it->second;
310  auto ni_it = m_niChangesPerBand.find (band);
311  NS_ASSERT (ni_it != m_niChangesPerBand.end ());
312  auto it = ni_it->second.find (event->GetStartTime ());
313  for (; it != ni_it->second.end () && it->first < Simulator::Now (); ++it)
314  {
315  noiseInterferenceW = it->second.GetPower () - event->GetRxPowerW (band);
316  }
317  it = ni_it->second.find (event->GetStartTime ());
318  NS_ASSERT (it != ni_it->second.end ());
319  for (; it != ni_it->second.end () && it->second.GetEvent () != event; ++it);
320  NiChanges ni;
321  ni.emplace (event->GetStartTime (), NiChange (0, event));
322  while (++it != ni_it->second.end () && it->second.GetEvent () != event)
323  {
324  ni.insert (*it);
325  }
326  ni.emplace (event->GetEndTime (), NiChange (0, event));
327  nis->insert ({band, ni});
328  NS_ASSERT_MSG (noiseInterferenceW >= 0, "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
329  return noiseInterferenceW;
330 }
331 
332 double
333 InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
334 {
335  if (duration.IsZero ())
336  {
337  return 1.0;
338  }
339  uint64_t rate = mode.GetDataRate (txVector.GetChannelWidth ());
340  uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
341  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
342  return csr;
343 }
344 
345 double
346 InterferenceHelper::CalculatePayloadChunkSuccessRate (double snir, Time duration, WifiTxVector txVector, uint16_t staId) const
347 {
348  if (duration.IsZero ())
349  {
350  return 1.0;
351  }
352  WifiMode mode = txVector.GetMode (staId);
353  uint64_t rate = mode.GetDataRate (txVector, staId);
354  uint64_t nbits = static_cast<uint64_t> (rate * duration.GetSeconds ());
355  nbits /= txVector.GetNss (staId); //divide effective number of bits by NSS to achieve same chunk error rate as SISO for AWGN
356  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, nbits);
357  return csr;
358 }
359 
360 double
363  uint16_t staId, std::pair<Time, Time> window) const
364 {
365  NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << window.first << window.second);
366  const WifiTxVector txVector = event->GetTxVector ();
367  double psr = 1.0; /* Packet Success Rate */
368  auto ni_it = nis->find (band)->second;
369  auto j = ni_it.begin ();
370  Time previous = j->first;
371  WifiMode payloadMode = txVector.GetMode (staId);
372  WifiPreamble preamble = txVector.GetPreambleType ();
373  Time phyHeaderStart = j->first + WifiPhy::GetPhyPreambleDuration (txVector); //PPDU start time + preamble
374  Time phyHtSigHeaderStart = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
375  Time phyTrainingSymbolsStart = phyHtSigHeaderStart + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
376  Time phyPayloadStart = phyTrainingSymbolsStart + WifiPhy::GetPhyTrainingSymbolDuration (txVector) + WifiPhy::GetPhySigBDuration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B
377  Time windowStart = phyPayloadStart + window.first;
378  Time windowEnd = phyPayloadStart + window.second;
379  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
380  double powerW = event->GetRxPowerW (band);
381  while (++j != ni_it.end ())
382  {
383  Time current = j->first;
384  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
385  NS_ASSERT (current >= previous);
386  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, txVector.GetNss (staId));
387  //Case 1: Both previous and current point to the windowed payload
388  if (previous >= windowStart)
389  {
390  psr *= CalculatePayloadChunkSuccessRate (snr, Min (windowEnd, current) - previous, txVector, staId);
391  NS_LOG_DEBUG ("Both previous and current point to the windowed payload: mode=" << payloadMode << ", psr=" << psr);
392  }
393  //Case 2: previous is before windowed payload and current is in the windowed payload
394  else if (current >= windowStart)
395  {
396  psr *= CalculatePayloadChunkSuccessRate (snr, Min (windowEnd, current) - windowStart, txVector, staId);
397  NS_LOG_DEBUG ("previous is before windowed payload and current is in the windowed payload: mode=" << payloadMode << ", psr=" << psr);
398  }
399  noiseInterferenceW = j->second.GetPower () - powerW;
400  previous = j->first;
401  if (previous > windowEnd)
402  {
403  NS_LOG_DEBUG ("Stop: new previous=" << previous << " after time window end=" << windowEnd);
404  break;
405  }
406  }
407  double per = 1 - psr;
408  return per;
409 }
410 
411 double
413 {
414  NS_LOG_FUNCTION (this << band.first << band.second);
415  const WifiTxVector txVector = event->GetTxVector ();
416  uint16_t channelWidth = txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth (); //calculate PER on the 20 MHz primary channel for L-SIG
417  double psr = 1.0; /* Packet Success Rate */
418  auto ni_it = nis->find (band)->second;
419  auto j = ni_it.begin ();
420  Time previous = j->first;
421  WifiPreamble preamble = txVector.GetPreambleType ();
422  WifiMode headerMode = WifiPhy::GetPhyHeaderMode (txVector);
423  Time phyHeaderStart = j->first + WifiPhy::GetPhyPreambleDuration (txVector); //PPDU start time + preamble
424  Time phyLSigHeaderEnd = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
425  Time phyTrainingSymbolsStart = phyLSigHeaderEnd + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
426  Time phyPayloadStart = phyTrainingSymbolsStart + WifiPhy::GetPhyTrainingSymbolDuration (txVector) + WifiPhy::GetPhySigBDuration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B
427  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
428  double powerW = event->GetRxPowerW (band);
429  while (++j != ni_it.end ())
430  {
431  Time current = j->first;
432  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
433  NS_ASSERT (current >= previous);
434  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
435  //Case 1: previous and current after payload start
436  if (previous >= phyPayloadStart)
437  {
438  psr *= 1;
439  NS_LOG_DEBUG ("Case 1 - previous and current after payload start: nothing to do");
440  }
441  //Case 2: previous is in training or in SIG-B: non-HT will not enter here since it didn't enter in the last two and they are all the same for non-HT
442  else if (previous >= phyTrainingSymbolsStart)
443  {
444  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
445  psr *= 1;
446  NS_LOG_DEBUG ("Case 2 - previous is in training or in SIG-B: nothing to do");
447  }
448  //Case 3: previous is in HT-SIG or SIG-A: non-HT will not enter here since it didn't enter in the last two and they are all the same for non-HT
449  else if (previous >= phyLSigHeaderEnd)
450  {
451  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
452  psr *= 1;
453  NS_LOG_DEBUG ("Case 3cii - previous is in HT-SIG or SIG-A: nothing to do");
454  }
455  //Case 4: previous in L-SIG: HT GF will not reach here because it will execute the previous if and exit
456  else if (previous >= phyHeaderStart)
457  {
458  NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
459  //Case 4a: current after payload start
460  if (current >= phyPayloadStart)
461  {
462  psr *= CalculateChunkSuccessRate (snr, phyLSigHeaderEnd - previous, headerMode, txVector);
463  NS_LOG_DEBUG ("Case 4a - previous in L-SIG and current after payload start: mode=" << headerMode << ", psr=" << psr);
464  }
465  //Case 4b: current is in training or in SIG-B. non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
466  else if (current >= phyTrainingSymbolsStart)
467  {
468  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
469  psr *= CalculateChunkSuccessRate (snr, phyLSigHeaderEnd - previous, headerMode, txVector);
470  NS_LOG_DEBUG ("Case 4a - previous in L-SIG and current is in training or in SIG-B: mode=" << headerMode << ", psr=" << psr);
471  }
472  //Case 4c: current in HT-SIG or in SIG-A. non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
473  else if (current >= phyLSigHeaderEnd)
474  {
475  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
476  psr *= CalculateChunkSuccessRate (snr, phyLSigHeaderEnd - previous, headerMode, txVector);
477  NS_LOG_DEBUG ("Case 4ci - previous is in L-SIG and current in HT-SIG or in SIG-A: mode=" << headerMode << ", psr=" << psr);
478  }
479  //Case 4d: current with previous in L-SIG
480  else
481  {
482  psr *= CalculateChunkSuccessRate (snr, current - previous, headerMode, txVector);
483  NS_LOG_DEBUG ("Case 4d - current with previous in L-SIG: mode=" << headerMode << ", psr=" << psr);
484  }
485  }
486  //Case 5: previous is in the preamble works for all cases
487  else
488  {
489  //Case 5a: current after payload start
490  if (current >= phyPayloadStart)
491  {
492  psr *= CalculateChunkSuccessRate (snr, phyLSigHeaderEnd - phyHeaderStart, headerMode, txVector);
493  NS_LOG_DEBUG ("Case 5aii - previous is in the preamble and current is after payload start: mode=" << headerMode << ", psr=" << psr);
494  }
495  //Case 5b: current is in training or in SIG-B. non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
496  else if (current >= phyTrainingSymbolsStart)
497  {
498  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
499  psr *= CalculateChunkSuccessRate (snr, phyLSigHeaderEnd - phyHeaderStart, headerMode, txVector);
500  NS_LOG_DEBUG ("Case 5b - previous is in the preamble and current is in training or in SIG-B: mode=" << headerMode << ", psr=" << psr);
501  }
502  //Case 5c: current in HT-SIG or in SIG-A. non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
503  else if (current >= phyLSigHeaderEnd)
504  {
505  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
506  psr *= CalculateChunkSuccessRate (snr, phyLSigHeaderEnd - phyHeaderStart, headerMode, txVector);
507  NS_LOG_DEBUG ("Case 5b - previous is in the preamble and current in HT-SIG or in SIG-A: mode=" << headerMode << ", psr=" << psr);
508  }
509  //Case 5d: current is in L-SIG.
510  else if (current >= phyHeaderStart)
511  {
512  NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
513  psr *= CalculateChunkSuccessRate (snr, current - phyHeaderStart, headerMode, txVector);
514  NS_LOG_DEBUG ("Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode << ", psr=" << psr);
515  }
516  }
517 
518  noiseInterferenceW = j->second.GetPower () - powerW;
519  previous = j->first;
520  }
521 
522  double per = 1 - psr;
523  return per;
524 }
525 
526 double
528 {
529  NS_LOG_FUNCTION (this << band.first << band.second);
530  const WifiTxVector txVector = event->GetTxVector ();
531  uint16_t channelWidth = txVector.GetChannelWidth () >= 40 ? 20 : txVector.GetChannelWidth (); //calculate PER on the 20 MHz primary channel for PHY headers
532  double psr = 1.0; /* Packet Success Rate */
533  auto ni_it = nis->find (band)->second;
534  auto j = ni_it.begin ();
535  Time previous = j->first;
536  WifiPreamble preamble = txVector.GetPreambleType ();
537  WifiMode mcsHeaderMode;
538  if (IsHt (preamble))
539  {
540  //mode for PHY header fields sent with HT modulation
541  mcsHeaderMode = WifiPhy::GetHtPhyHeaderMode ();
542  }
543  else if (IsVht (preamble))
544  {
545  //mode for PHY header fields sent with VHT modulation
546  mcsHeaderMode = WifiPhy::GetVhtPhyHeaderMode ();
547  }
548  else if (IsHe (preamble))
549  {
550  //mode for PHY header fields sent with HE modulation
551  mcsHeaderMode = WifiPhy::GetHePhyHeaderMode ();
552  }
553  WifiMode headerMode = WifiPhy::GetPhyHeaderMode (txVector);
554  Time phyHeaderStart = j->first + WifiPhy::GetPhyPreambleDuration (txVector); //PPDU start time + preamble
555  Time phyLSigHeaderEnd = phyHeaderStart + WifiPhy::GetPhyHeaderDuration (txVector); //PPDU start time + preamble + L-SIG
556  Time phyTrainingSymbolsStart = phyLSigHeaderEnd + WifiPhy::GetPhyHtSigHeaderDuration (preamble) + WifiPhy::GetPhySigA1Duration (preamble) + WifiPhy::GetPhySigA2Duration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A
557  Time phyPayloadStart = phyTrainingSymbolsStart + WifiPhy::GetPhyTrainingSymbolDuration (txVector) + WifiPhy::GetPhySigBDuration (preamble); //PPDU start time + preamble + L-SIG + HT-SIG or SIG-A + Training + SIG-B
558  double noiseInterferenceW = m_firstPowerPerBand.find (band)->second;
559  double powerW = event->GetRxPowerW (band);
560  while (++j != ni_it.end ())
561  {
562  Time current = j->first;
563  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
564  NS_ASSERT (current >= previous);
565  double snr = CalculateSnr (powerW, noiseInterferenceW, channelWidth, 1);
566  //Case 1: previous and current after payload start: nothing to do
567  if (previous >= phyPayloadStart)
568  {
569  psr *= 1;
570  NS_LOG_DEBUG ("Case 1 - previous and current after payload start: nothing to do");
571  }
572  //Case 2: previous is in training or in SIG-B: non-HT will not enter here since it didn't enter in the last two and they are all the same for non-HT
573  else if (previous >= phyTrainingSymbolsStart)
574  {
575  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
576  //Case 2a: current after payload start
577  if (current >= phyPayloadStart)
578  {
579  psr *= CalculateChunkSuccessRate (snr, phyPayloadStart - previous, mcsHeaderMode, txVector);
580  NS_LOG_DEBUG ("Case 2a - previous is in training or in SIG-B and current after payload start: mode=" << mcsHeaderMode << ", psr=" << psr);
581  }
582  //Case 2b: current is in training or in SIG-B
583  else
584  {
585  psr *= CalculateChunkSuccessRate (snr, current - previous, mcsHeaderMode, txVector);
586  NS_LOG_DEBUG ("Case 2b - previous is in training or in SIG-B and current is in training or in SIG-B: mode=" << mcsHeaderMode << ", psr=" << psr);
587  }
588  }
589  //Case 3: previous is in HT-SIG or SIG-A: non-HT will not enter here since it didn't enter in the last two and they are all the same for non-HT
590  else if (previous >= phyLSigHeaderEnd)
591  {
592  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
593  //Case 3a: current after payload start
594  if (current >= phyPayloadStart)
595  {
596  psr *= CalculateChunkSuccessRate (snr, phyPayloadStart - phyTrainingSymbolsStart, mcsHeaderMode, txVector);
597  //Case 3ai: VHT or HE format
598  if (IsVht (preamble) || IsHe (preamble))
599  {
600  //SIG-A is sent using non-HT OFDM modulation
601  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - previous, headerMode, txVector);
602  NS_LOG_DEBUG ("Case 3ai - previous is in SIG-A and current after payload start: mcs mode=" << mcsHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
603  }
604  //Case 3aii: HT formats
605  else
606  {
607  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - previous, mcsHeaderMode, txVector);
608  NS_LOG_DEBUG ("Case 3aii - previous is in HT-SIG and current after payload start: mode=" << mcsHeaderMode << ", psr=" << psr);
609  }
610  }
611  //Case 3b: current is in training or in SIG-B
612  else if (current >= phyTrainingSymbolsStart)
613  {
614  psr *= CalculateChunkSuccessRate (snr, current - phyTrainingSymbolsStart, mcsHeaderMode, txVector);
615  //Case 3bi: VHT or HE format
616  if (IsVht (preamble) || IsHe (preamble))
617  {
618  //SIG-A is sent using non-HT OFDM modulation
619  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - previous, headerMode, txVector);
620  NS_LOG_DEBUG ("Case 3bi - previous is in SIG-A and current is in training or in SIG-B: mode=" << headerMode << ", psr=" << psr);
621  }
622  //Case 3bii: HT formats
623  else
624  {
625  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - previous, mcsHeaderMode, txVector);
626  NS_LOG_DEBUG ("Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << mcsHeaderMode << ", psr=" << psr);
627  }
628  }
629  //Case 3c: current with previous in HT-SIG or SIG-A
630  else
631  {
632  //Case 3ci: VHT or HE format
633  if (IsVht (preamble) || IsHe (preamble))
634  {
635  //SIG-A is sent using non-HT OFDM modulation
636  psr *= CalculateChunkSuccessRate (snr, current - previous, headerMode, txVector);
637  NS_LOG_DEBUG ("Case 3ci - previous with current in SIG-A: mode=" << headerMode << ", psr=" << psr);
638  }
639  //Case 3cii: HT mixed format or HT greenfield
640  else
641  {
642  psr *= CalculateChunkSuccessRate (snr, current - previous, mcsHeaderMode, txVector);
643  NS_LOG_DEBUG ("Case 3cii - previous with current in HT-SIG: mode=" << mcsHeaderMode << ", psr=" << psr);
644  }
645  }
646  }
647  //Case 4: previous in L-SIG: HT GF will not reach here because it will execute the previous if and exit
648  else if (previous >= phyHeaderStart)
649  {
650  NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
651  //Case 4a: current after payload start
652  if (current >= phyPayloadStart)
653  {
654  //Case 4ai: non-HT format
655  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
656  {
657  psr *= 1;
658  NS_LOG_DEBUG ("Case 4ai - previous in L-SIG and current after payload start: nothing to do");
659  }
660  //Case 4aii: VHT or HE format
661  else if (IsVht (preamble) || IsHe (preamble))
662  {
663  psr *= CalculateChunkSuccessRate (snr, phyPayloadStart - phyTrainingSymbolsStart, mcsHeaderMode, txVector);
664  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - phyLSigHeaderEnd, headerMode, txVector);
665  NS_LOG_DEBUG ("Case 4aii - previous is in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
666  }
667  //Case 4aiii: HT mixed format
668  else
669  {
670  psr *= CalculateChunkSuccessRate (snr, phyPayloadStart - phyLSigHeaderEnd, mcsHeaderMode, txVector);
671  NS_LOG_DEBUG ("Case 4aiii - previous in L-SIG and current after payload start: mcs mode=" << mcsHeaderMode << ", psr=" << psr);
672  }
673  }
674  //Case 4b: current is in training or in SIG-B. non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
675  else if (current >= phyTrainingSymbolsStart)
676  {
677  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
678  //Case 4bi: VHT or HE format
679  if (IsVht (preamble) || IsHe (preamble))
680  {
681  psr *= CalculateChunkSuccessRate (snr, current - phyTrainingSymbolsStart, mcsHeaderMode, txVector);
682  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - phyLSigHeaderEnd, headerMode, txVector);
683  NS_LOG_DEBUG ("Case 4bi - previous is in L-SIG and current in training or in SIG-B: mcs mode=" << mcsHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
684  }
685  //Case 4bii: HT mixed format
686  else
687  {
688  psr *= CalculateChunkSuccessRate (snr, current - phyLSigHeaderEnd, mcsHeaderMode, txVector);
689  NS_LOG_DEBUG ("Case 4bii - previous in L-SIG and current in HT training: mcs mode=" << mcsHeaderMode << ", psr=" << psr);
690  }
691  }
692  //Case 4c: current in HT-SIG or in SIG-A. Non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
693  else if (current >= phyLSigHeaderEnd)
694  {
695  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
696  //Case 4ci: VHT format
697  if (IsVht (preamble) || IsHe (preamble))
698  {
699  psr *= CalculateChunkSuccessRate (snr, current - phyLSigHeaderEnd, headerMode, txVector);
700  NS_LOG_DEBUG ("Case 4ci - previous is in L-SIG and current in SIG-A: mode=" << headerMode << ", psr=" << psr);
701  }
702  //Case 4cii: HT mixed format
703  else
704  {
705  psr *= CalculateChunkSuccessRate (snr, current - phyLSigHeaderEnd, mcsHeaderMode, txVector);
706  NS_LOG_DEBUG ("Case 4cii - previous in L-SIG and current in HT-SIG: mcs mode=" << mcsHeaderMode << ", psr=" << psr);
707  }
708  }
709  //Case 4d: current with previous in L-SIG
710  else
711  {
712  psr *= 1;
713  NS_LOG_DEBUG ("Case 4d - current with previous in L-SIG: nothing to do");
714  }
715  }
716  //Case 5: previous is in the preamble works for all cases
717  else
718  {
719  //Case 5a: current after payload start
720  if (current >= phyPayloadStart)
721  {
722  //Case 5ai: non-HT format (No HT-SIG or Training Symbols)
723  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
724  {
725  psr *= 1;
726  NS_LOG_DEBUG ("Case 5ai - previous is in the preamble and current is after payload start: nothing to do");
727  }
728  //Case 5aii: VHT or HE format
729  else if (IsVht (preamble) || IsHe (preamble))
730  {
731  psr *= CalculateChunkSuccessRate (snr, phyPayloadStart - phyTrainingSymbolsStart, mcsHeaderMode, txVector);
732  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - phyLSigHeaderEnd, headerMode, txVector);
733  NS_LOG_DEBUG ("Case 5aii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
734  }
735  //Case 5aiii: HT formats
736  else
737  {
738  psr *= CalculateChunkSuccessRate (snr, phyPayloadStart - phyLSigHeaderEnd, mcsHeaderMode, txVector);
739  NS_LOG_DEBUG ("Case 5aiii - previous is in the preamble and current is after payload start: mcs mode=" << mcsHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
740  }
741  }
742  //Case 5b: current is in training or in SIG-B. Non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
743  else if (current >= phyTrainingSymbolsStart)
744  {
745  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
746  //Case 5bi: VHT or HE format
747  if (IsVht (preamble) || IsHe (preamble))
748  {
749  psr *= CalculateChunkSuccessRate (snr, current - phyTrainingSymbolsStart, mcsHeaderMode, txVector);
750  psr *= CalculateChunkSuccessRate (snr, phyTrainingSymbolsStart - phyLSigHeaderEnd, headerMode, txVector);
751  NS_LOG_DEBUG ("Case 5bi - previous is in the preamble and current in training or in SIG-B: mcs mode=" << mcsHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
752  }
753  //Case 5bii: HT mixed format
754  else
755  {
756  psr *= CalculateChunkSuccessRate (snr, current - phyLSigHeaderEnd, mcsHeaderMode, txVector);
757  NS_LOG_DEBUG ("Case 5bii - previous is in the preamble and current in HT training: mcs mode=" << mcsHeaderMode << ", psr=" << psr);
758  }
759  }
760  //Case 5c: current in HT-SIG or in SIG-A. Non-HT will not come here since it went in previous if or if the previous if is not true this will be not true
761  else if (current >= phyLSigHeaderEnd)
762  {
763  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
764  //Case 5ci: VHT or HE format
765  if (IsVht (preamble) || IsHe (preamble))
766  {
767  psr *= CalculateChunkSuccessRate (snr, current - phyLSigHeaderEnd, headerMode, txVector);
768  NS_LOG_DEBUG ("Case 5ci - previous is in preamble and current in SIG-A: mode=" << headerMode << ", psr=" << psr);
769  }
770  //Case 5cii: HT formats
771  else
772  {
773  psr *= CalculateChunkSuccessRate (snr, current - phyLSigHeaderEnd, mcsHeaderMode, txVector);
774  NS_LOG_DEBUG ("Case 5cii - previous in preamble and current in HT-SIG: mcs mode=" << mcsHeaderMode << ", psr=" << psr);
775  }
776  }
777  //Case 5d: current is in L-SIG. HT-GF will not come here
778  else if (current >= phyHeaderStart)
779  {
780  NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
781  psr *= 1;
782  NS_LOG_DEBUG ("Case 5d - previous is in the preamble and current is in L-SIG: nothing to do");
783  }
784  }
785 
786  noiseInterferenceW = j->second.GetPower () - powerW;
787  previous = j->first;
788  }
789 
790  double per = 1 - psr;
791  return per;
792 }
793 
795 InterferenceHelper::CalculatePayloadSnrPer (Ptr<Event> event, uint16_t channelWidth, WifiSpectrumBand band,
796  uint16_t staId, std::pair<Time, Time> relativeMpduStartStop) const
797 {
798  NS_LOG_FUNCTION (this << channelWidth << band.first << band.second << staId << relativeMpduStartStop.first << relativeMpduStartStop.second);
799  NiChangesPerBand ni;
800  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
801  double snr = CalculateSnr (event->GetRxPowerW (band),
802  noiseInterferenceW,
803  channelWidth,
804  event->GetTxVector ().GetNss (staId));
805 
806  /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
807  * all SNIR changes in the SNIR vector.
808  */
809  double per = CalculatePayloadPer (event, channelWidth, &ni, band, staId, relativeMpduStartStop);
810 
811  struct SnrPer snrPer;
812  snrPer.snr = snr;
813  snrPer.per = per;
814  return snrPer;
815 }
816 
817 double
818 InterferenceHelper::CalculateSnr (Ptr<Event> event, uint16_t channelWidth, uint8_t nss, WifiSpectrumBand band) const
819 {
820  NiChangesPerBand ni;
821  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
822  double snr = CalculateSnr (event->GetRxPowerW (band),
823  noiseInterferenceW,
824  channelWidth,
825  nss);
826  return snr;
827 }
828 
830 InterferenceHelper::CalculateNonHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const
831 {
832  NS_LOG_FUNCTION (this << band.first << band.second);
833  NiChangesPerBand ni;
834  uint16_t channelWidth;
835  if (event->GetTxVector ().GetChannelWidth () >= 40)
836  {
837  channelWidth = 20; //calculate PER on the 20 MHz primary channel for L-SIG
838  }
839  else
840  {
841  channelWidth = event->GetTxVector ().GetChannelWidth ();
842  }
843  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
844  double snr = CalculateSnr (event->GetRxPowerW (band),
845  noiseInterferenceW,
846  channelWidth,
847  1);
848 
849  /* calculate the SNIR at the start of the PHY header and accumulate
850  * all SNIR changes in the SNIR vector.
851  */
852  double per = CalculateNonHtPhyHeaderPer (event, &ni, band);
853 
854  struct SnrPer snrPer;
855  snrPer.snr = snr;
856  snrPer.per = per;
857  return snrPer;
858 }
859 
861 InterferenceHelper::CalculateHtPhyHeaderSnrPer (Ptr<Event> event, WifiSpectrumBand band) const
862 {
863  NS_LOG_FUNCTION (this << band.first << band.second);
864  NiChangesPerBand ni;
865  uint16_t channelWidth;
866  if (event->GetTxVector ().GetChannelWidth () >= 40)
867  {
868  channelWidth = 20; //calculate PER on the 20 MHz primary channel for PHY headers
869  }
870  else
871  {
872  channelWidth = event->GetTxVector ().GetChannelWidth ();
873  }
874  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni, band);
875  double snr = CalculateSnr (event->GetRxPowerW (band),
876  noiseInterferenceW,
877  channelWidth,
878  1);
879 
880  /* calculate the SNIR at the start of the PHY header and accumulate
881  * all SNIR changes in the SNIR vector.
882  */
883  double per = CalculateHtPhyHeaderPer (event, &ni, band);
884 
885  struct SnrPer snrPer;
886  snrPer.snr = snr;
887  snrPer.per = per;
888  return snrPer;
889 }
890 
891 void
893 {
894  for (auto it : m_niChangesPerBand)
895  {
896  it.second.clear ();
897  // Always have a zero power noise event in the list
898  AddNiChangeEvent (Time (0), NiChange (0.0, 0), it.first);
899  m_firstPowerPerBand.at (it.first) = 0.0;
900  }
901  m_rxing = false;
902 }
903 
904 InterferenceHelper::NiChanges::const_iterator
906 {
907  auto it = m_niChangesPerBand.find (band);
908  NS_ASSERT (it != m_niChangesPerBand.end ());
909  return it->second.upper_bound (moment);
910 }
911 
912 InterferenceHelper::NiChanges::const_iterator
914 {
915  auto it = GetNextPosition (moment, band);
916  // This is safe since there is always an NiChange at time 0,
917  // before moment.
918  --it;
919  return it;
920 }
921 
922 InterferenceHelper::NiChanges::iterator
924 {
925  auto it = m_niChangesPerBand.find (band);
926  NS_ASSERT (it != m_niChangesPerBand.end ());
927  return it->second.insert (GetNextPosition (moment, band), std::make_pair (moment, change));
928 }
929 
930 void
932 {
933  NS_LOG_FUNCTION (this);
934  m_rxing = true;
935 }
936 
937 void
939 {
940  NS_LOG_FUNCTION (this);
941  m_rxing = false;
942  //Update m_firstPower for frame capture
943  for (auto ni : m_niChangesPerBand)
944  {
945  NS_ASSERT (ni.second.size () > 1);
946  auto it = GetPreviousPosition (Simulator::Now (), ni.first);
947  it--;
948  m_firstPowerPerBand.find (ni.first)->second = it->second.GetPower ();
949  }
950 }
951 
952 } //namespace ns3
double GetRxPowerW(void) const
Return the total received power (W).
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 AddPower(double power)
Add a given amount of power.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
NiChanges::const_iterator GetNextPosition(Time moment, WifiSpectrumBand band) const
Returns an iterator to the first NiChange that is later than moment.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Time GetEnergyDuration(double energyW, WifiSpectrumBand band) const
Control the scheduling of simulation events.
Definition: simulator.h:68
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
Definition: second.py:1
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Time GetEndTime(void) const
Return the end time of the signal.
void RemoveBands(void)
Remove the frequency bands.
handles interference calculations
static WifiMode GetHePhyHeaderMode()
Definition: wifi-phy.cc:1915
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
double CalculatePayloadChunkSuccessRate(double snir, Time duration, WifiTxVector txVector, uint16_t staId) const
Calculate the success rate of the payload chunk given the SINR, duration, and Wi-Fi mode...
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
NiChangesPerBand m_niChangesPerBand
NI Changes for each band.
static Time GetPhyPreambleDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2184
Time GetStartTime(void) const
Return the start time of the signal.
Ptr< Event > GetEvent(void) const
Return the event causes the corresponding NI change.
Ptr< const WifiPpdu > GetPpdu(void) const
Return the PPDU.
Event(Ptr< const WifiPpdu > ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPower)
Create an Event with the given parameters.
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.
bool IsVht(WifiPreamble preamble)
Return whether the preamble is a VHT format preamble.
Definition: wifi-utils.cc:274
bool IsHe(WifiPreamble preamble)
Return whether the preamble is a HE format preamble.
Definition: wifi-utils.cc:280
Ptr< ErrorRateModel > m_errorRateModel
error rate model
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, WifiTxVector txVector, Time duration, RxPowerWattPerChannelBand rxPower)
Add the PPDU-related signal to interference helper.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
double snr
SNR in linear scale.
Ptr< const WifiPpdu > m_ppdu
PPDU.
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...
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...
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode. ...
WifiPreamble GetPreambleType(void) const
static Time GetPhyHtSigHeaderDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1978
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:32
std::map< WifiSpectrumBand, double > m_firstPowerPerBand
first power of each band in watts
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:218
static WifiMode GetHtPhyHeaderMode()
Definition: wifi-phy.cc:1903
bool IsZero(void) const
Exactly equivalent to t == 0.
Definition: nstime.h:301
Time GetDuration(void) const
Return the duration of the signal.
std::map< WifiSpectrumBand, NiChanges > NiChangesPerBand
Map of NiChanges per band.
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
WifiTxVector GetTxVector(void) const
Return the TXVECTOR of the PPDU.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
static WifiMode GetVhtPhyHeaderMode()
Definition: wifi-phy.cc:1909
double m_noiseFigure
noise figure (linear)
static Time GetPhySigA1Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1993
double CalculateNonHtPhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate the error rate of the non-HT PHY header.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyRxStart()
Notify that RX has started.
Noise and Interference (thus Ni) event.
void EraseEvents(void)
Erase all events.
static Time GetPhyTrainingSymbolDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1927
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
static WifiMode GetPhyHeaderMode(WifiTxVector txVector)
Definition: wifi-phy.cc:2042
#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
void AddBand(WifiSpectrumBand band)
Add a frequency band.
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate noise and interference power in W.
NiChanges::const_iterator GetPreviousPosition(Time moment, WifiSpectrumBand band) const
Returns an iterator to the last NiChange that is before than moment.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void NotifyRxEnd()
Notify that RX has ended.
void AddForeignSignal(Time duration, RxPowerWattPerChannelBand rxPower)
Add a non-Wifi signal to interference helper.
double CalculateHtPhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, WifiSpectrumBand band) const
Calculate the error rate of the HT PHY header.
void SetNoiseFigure(double value)
Set the noise figure.
bool IsHt(WifiPreamble preamble)
Return whether the preamble is a HT format preamble.
Definition: wifi-utils.cc:268
RxPowerWattPerChannelBand m_rxPowerW
received power in watts per band
NiChange(double power, Ptr< Event > event)
Create a NiChange at the given time and the amount of NI change.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
static Time GetPhySigA2Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:2011
WifiTxVector m_txVector
TXVECTOR.
void AppendEvent(Ptr< Event > event)
Append the given Event.
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).
Time m_endTime
end time
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
double GetPower(void) const
Return the power.
uint16_t GetChannelWidth(void) const
static Time GetPhyHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2106
handles interference calculations
RxPowerWattPerChannelBand GetRxPowerWPerBand(void) const
Return the received power (W) for all bands.
Definition: first.py:1
static Time GetPhySigBDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:2028
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:127
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Implements the IEEE 802.11 MAC header.
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChange
bool m_rxing
flag whether it is in receiving state
Time m_startTime
start time