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