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 "interference-helper.h"
23 #include "wifi-phy.h"
24 #include "error-rate-model.h"
25 #include "ns3/simulator.h"
26 #include "ns3/log.h"
27 #include <algorithm>
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
32 
33 /****************************************************************
34  * Phy event class
35  ****************************************************************/
36 
38  enum WifiPreamble preamble,
39  Time duration, double rxPower)
40  : m_size (size),
41  m_txVector (txVector),
42  m_preamble (preamble),
43  m_startTime (Simulator::Now ()),
44  m_endTime (m_startTime + duration),
45  m_rxPowerW (rxPower)
46 {
47 }
48 
50 {
51 }
52 
53 Time
55 {
56  return m_endTime - m_startTime;
57 }
58 
59 Time
61 {
62  return m_startTime;
63 }
64 
65 Time
67 {
68  return m_endTime;
69 }
70 
71 double
73 {
74  return m_rxPowerW;
75 }
76 
77 uint32_t
79 {
80  return m_size;
81 }
82 
85 {
86  return m_txVector;
87 }
88 
91 {
92  return m_txVector.GetMode ();
93 }
94 
95 enum WifiPreamble
97 {
98  return m_preamble;
99 }
100 
101 
102 /****************************************************************
103  * Class which records SNIR change events for a
104  * short period of time.
105  ****************************************************************/
106 
108  : m_time (time),
109  m_delta (delta)
110 {
111 }
112 
113 Time
115 {
116  return m_time;
117 }
118 
119 double
121 {
122  return m_delta;
123 }
124 
125 bool
127 {
128  return (m_time < o.m_time);
129 }
130 
131 
132 /****************************************************************
133  * The actual InterferenceHelper
134  ****************************************************************/
135 
137  : m_errorRateModel (0),
138  m_firstPower (0.0),
139  m_rxing (false)
140 {
141 }
142 
144 {
145  EraseEvents ();
146  m_errorRateModel = 0;
147 }
148 
150 InterferenceHelper::Add (uint32_t size, WifiTxVector txVector,
151  enum WifiPreamble preamble,
152  Time duration, double rxPowerW)
153 {
155 
156  event = Create<InterferenceHelper::Event> (size,
157  txVector,
158  preamble,
159  duration,
160  rxPowerW);
161  AppendEvent (event);
162  return event;
163 }
164 
165 void
166 InterferenceHelper::AddForeignSignal (Time duration, double rxPowerW)
167 {
168  // Parameters other than duration and rxPowerW are unused for this type
169  // of signal, so we provide dummy versions
170  WifiTxVector fakeTxVector;
171  Add (0, fakeTxVector, WIFI_PREAMBLE_NONE, duration, rxPowerW);
172 }
173 
174 void
176 {
177  m_noiseFigure = value;
178 }
179 
180 double
182 {
183  return m_noiseFigure;
184 }
185 
186 void
188 {
189  m_errorRateModel = rate;
190 }
191 
194 {
195  return m_errorRateModel;
196 }
197 
198 Time
200 {
201  Time now = Simulator::Now ();
202  double noiseInterferenceW = 0.0;
203  Time end = now;
204  noiseInterferenceW = m_firstPower;
205  for (NiChanges::const_iterator i = m_niChanges.begin (); i != m_niChanges.end (); i++)
206  {
207  noiseInterferenceW += i->GetDelta ();
208  end = i->GetTime ();
209  if (end < now)
210  {
211  continue;
212  }
213  if (noiseInterferenceW < energyW)
214  {
215  break;
216  }
217  }
218  return end > now ? end - now : MicroSeconds (0);
219 }
220 
221 void
223 {
224  Time now = Simulator::Now ();
225  if (!m_rxing)
226  {
227  NiChanges::iterator nowIterator = GetPosition (now);
228  for (NiChanges::iterator i = m_niChanges.begin (); i != nowIterator; i++)
229  {
230  m_firstPower += i->GetDelta ();
231  }
232  m_niChanges.erase (m_niChanges.begin (), nowIterator);
233  m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW ()));
234  }
235  else
236  {
237  AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW ()));
238  }
239  AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW ()));
240 
241 }
242 
243 
244 double
245 InterferenceHelper::CalculateSnr (double signal, double noiseInterference, uint32_t channelWidth) const
246 {
247  //thermal noise at 290K in J/s = W
248  static const double BOLTZMANN = 1.3803e-23;
249  //Nt is the power of thermal noise in W
250  double Nt = BOLTZMANN * 290.0 * channelWidth * 1000000;
251  //receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
252  double noiseFloor = m_noiseFigure * Nt;
253  double noise = noiseFloor + noiseInterference;
254  double snr = signal / noise; //linear scale
255  NS_LOG_DEBUG ("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)=" << noiseFloor << ", interference(W)=" << noiseInterference << ", snr(linear)=" << snr);
256  return snr;
257 }
258 
259 double
261 {
262  double noiseInterference = m_firstPower;
263  NS_ASSERT (m_rxing);
264  for (NiChanges::const_iterator i = m_niChanges.begin () + 1; i != m_niChanges.end (); i++)
265  {
266  if ((event->GetEndTime () == i->GetTime ()) && event->GetRxPowerW () == -i->GetDelta ())
267  {
268  break;
269  }
270  ni->push_back (*i);
271  }
272  ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference));
273  ni->push_back (NiChange (event->GetEndTime (), 0));
274  return noiseInterference;
275 }
276 
277 double
278 InterferenceHelper::CalculateChunkSuccessRate (double snir, Time duration, WifiMode mode, WifiTxVector txVector) const
279 {
280  if (duration == NanoSeconds (0))
281  {
282  return 1.0;
283  }
284  uint32_t rate = mode.GetPhyRate (txVector);
285  uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
286  double csr = m_errorRateModel->GetChunkSuccessRate (mode, txVector, snir, (uint32_t)nbits);
287  return csr;
288 }
289 
290 double
292 {
293  NS_LOG_FUNCTION (this);
294  double psr = 1.0; /* Packet Success Rate */
295  NiChanges::iterator j = ni->begin ();
296  Time previous = (*j).GetTime ();
297  WifiMode payloadMode = event->GetPayloadMode ();
298  WifiPreamble preamble = event->GetPreambleType ();
299  Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (event->GetTxVector (), preamble); //packet start time + preamble
300  Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (event->GetTxVector (), preamble); //packet start time + preamble + L-SIG
301  Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpVhtSigA1Duration (preamble) + WifiPhy::GetPlcpVhtSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2)
302  Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble, event->GetTxVector ()) + WifiPhy::GetPlcpVhtSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2) + (V)HT Training + VHT-SIG-B
303  double noiseInterferenceW = (*j).GetDelta ();
304  double powerW = event->GetRxPowerW ();
305  j++;
306  while (ni->end () != j)
307  {
308  Time current = (*j).GetTime ();
309  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
310  NS_ASSERT (current >= previous);
311  //Case 1: Both previous and current point to the payload
312  if (previous >= plcpPayloadStart)
313  {
314  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
315  noiseInterferenceW,
316  event->GetTxVector ().GetChannelWidth ()),
317  current - previous,
318  payloadMode, event->GetTxVector ());
319 
320  NS_LOG_DEBUG ("Both previous and current point to the payload: mode=" << payloadMode << ", psr=" << psr);
321  }
322  //Case 2: previous is before payload and current is in the payload
323  else if (current >= plcpPayloadStart)
324  {
325  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
326  noiseInterferenceW,
327  event->GetTxVector ().GetChannelWidth ()),
328  current - plcpPayloadStart,
329  payloadMode, event->GetTxVector ());
330  NS_LOG_DEBUG ("previous is before payload and current is in the payload: mode=" << payloadMode << ", psr=" << psr);
331  }
332 
333  noiseInterferenceW += (*j).GetDelta ();
334  previous = (*j).GetTime ();
335  j++;
336  }
337 
338  double per = 1 - psr;
339  return per;
340 }
341 
342 double
344 {
345  NS_LOG_FUNCTION (this);
346  double psr = 1.0; /* Packet Success Rate */
347  NiChanges::iterator j = ni->begin ();
348  Time previous = (*j).GetTime ();
349  WifiMode payloadMode = event->GetPayloadMode ();
350  WifiPreamble preamble = event->GetPreambleType ();
351  WifiMode htHeaderMode;
352  if (preamble == WIFI_PREAMBLE_HT_MF)
353  {
354  //mode for PLCP header fields sent with HT modulation
355  htHeaderMode = WifiPhy::GetHtPlcpHeaderMode (payloadMode);
356  }
357  else if (preamble == WIFI_PREAMBLE_VHT)
358  {
359  //mode for PLCP header fields sent with VHT modulation
360  htHeaderMode = WifiPhy::GetVhtPlcpHeaderMode (payloadMode);
361  }
362  WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble, event->GetTxVector ());
363  Time plcpHeaderStart = (*j).GetTime () + WifiPhy::GetPlcpPreambleDuration (event->GetTxVector (), preamble); //packet start time + preamble
364  Time plcpHsigHeaderStart = plcpHeaderStart + WifiPhy::GetPlcpHeaderDuration (event->GetTxVector (), preamble); //packet start time + preamble + L-SIG
365  Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + WifiPhy::GetPlcpHtSigHeaderDuration (preamble) + WifiPhy::GetPlcpVhtSigA1Duration (preamble) + WifiPhy::GetPlcpVhtSigA2Duration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2)
366  Time plcpPayloadStart = plcpHtTrainingSymbolsStart + WifiPhy::GetPlcpHtTrainingSymbolDuration (preamble, event->GetTxVector ()) + WifiPhy::GetPlcpVhtSigBDuration (preamble); //packet start time + preamble + L-SIG + HT-SIG or VHT-SIG-A (A1 + A2) + (V)HT Training + VHT-SIG-B
367  double noiseInterferenceW = (*j).GetDelta ();
368  double powerW = event->GetRxPowerW ();
369  j++;
370  while (ni->end () != j)
371  {
372  Time current = (*j).GetTime ();
373  NS_LOG_DEBUG ("previous= " << previous << ", current=" << current);
374  NS_ASSERT (current >= previous);
375  //Case 1: previous and current after playload start: nothing to do
376  if (previous >= plcpPayloadStart)
377  {
378  psr *= 1;
379  NS_LOG_DEBUG ("Case 1 - previous and current after playload start: nothing to do");
380  }
381  //Case 2: previous is in (V)HT training or in VHT-SIG-B: Non (V)HT will not enter here since it didn't enter in the last two and they are all the same for non (V)HT
382  else if (previous >= plcpHtTrainingSymbolsStart)
383  {
384  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
385  //Case 2a: current after payload start
386  if (current >= plcpPayloadStart)
387  {
388  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
389  noiseInterferenceW,
390  event->GetTxVector ().GetChannelWidth ()),
391  plcpPayloadStart - previous,
392  htHeaderMode, event->GetTxVector ());
393 
394  NS_LOG_DEBUG ("Case 2a - previous is in (V)HT training or in VHT-SIG-B and current after payload start: mode=" << htHeaderMode << ", psr=" << psr);
395  }
396  //Case 2b: current is in (V)HT training or in VHT-SIG-B
397  else
398  {
399  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
400  noiseInterferenceW,
401  event->GetTxVector ().GetChannelWidth ()),
402  current - previous,
403  htHeaderMode, event->GetTxVector ());
404 
405  NS_LOG_DEBUG ("Case 2b - previous is in (V)HT training or in VHT-SIG-B and current is in (V)HT training or in VHT-SIG-B: mode=" << htHeaderMode << ", psr=" << psr);
406  }
407  }
408  //Case 3: previous is in HT-SIG or VHT-SIG-A: Non (V)HT will not enter here since it didn't enter in the last two and they are all the same for non (V)HT
409  else if (previous >= plcpHsigHeaderStart)
410  {
411  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
412  //Case 3a: current after payload start
413  if (current >= plcpPayloadStart)
414  {
415  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
416  noiseInterferenceW,
417  event->GetTxVector ().GetChannelWidth ()),
418  plcpPayloadStart - plcpHtTrainingSymbolsStart,
419  htHeaderMode, event->GetTxVector ());
420 
421  //Case 3ai: VHT format
422  if (preamble == WIFI_PREAMBLE_VHT)
423  {
424  //VHT-SIG-A is sent using legacy OFDM modulation
425  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
426  noiseInterferenceW,
427  event->GetTxVector ().GetChannelWidth ()),
428  plcpHtTrainingSymbolsStart - previous,
429  headerMode, event->GetTxVector ());
430 
431  NS_LOG_DEBUG ("Case 3ai - previous is in VHT-SIG-A and current after payload start: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
432  }
433  //Case 3aii: HT mixed format of HT greenfield
434  else
435  {
436  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
437  noiseInterferenceW,
438  event->GetTxVector ().GetChannelWidth ()),
439  plcpHtTrainingSymbolsStart - previous,
440  htHeaderMode, event->GetTxVector ());
441 
442  NS_LOG_DEBUG ("Case 3aii - previous is in HT-SIG and current after payload start: mode=" << htHeaderMode << ", psr=" << psr);
443  }
444  }
445  //Case 3b: current is in (V)HT training or in VHT-SIG-B
446  else if (current >= plcpHtTrainingSymbolsStart)
447  {
448  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
449  noiseInterferenceW,
450  event->GetTxVector ().GetChannelWidth ()),
451  current - plcpHtTrainingSymbolsStart,
452  htHeaderMode, event->GetTxVector ());
453 
454  //Case 3bi: VHT format
455  if (preamble == WIFI_PREAMBLE_VHT)
456  {
457  //VHT-SIG-A is sent using legacy OFDM modulation
458  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
459  noiseInterferenceW,
460  event->GetTxVector ().GetChannelWidth ()),
461  plcpHtTrainingSymbolsStart - previous,
462  headerMode, event->GetTxVector ());
463 
464  NS_LOG_DEBUG ("Case 3bi - previous is in VHT-SIG-A and current is in VHT training or in VHT-SIG-B: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
465  }
466  //Case 3bii: HT mixed format of HT greenfield
467  else
468  {
469  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
470  noiseInterferenceW,
471  event->GetTxVector ().GetChannelWidth ()),
472  plcpHtTrainingSymbolsStart - previous,
473  htHeaderMode, event->GetTxVector ());
474 
475  NS_LOG_DEBUG ("Case 3bii - previous is in HT-SIG and current is in HT training: mode=" << htHeaderMode << ", psr=" << psr);
476  }
477  }
478  //Case 3c: current with previous in HT-SIG or VHT-SIG-A
479  else
480  {
481  //Case 3bi: VHT format
482  if (preamble == WIFI_PREAMBLE_VHT)
483  {
484  //VHT-SIG-A is sent using legacy OFDM modulation
485  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
486  noiseInterferenceW,
487  event->GetTxVector ().GetChannelWidth ()),
488  current - previous,
489  headerMode, event->GetTxVector ());
490 
491  NS_LOG_DEBUG ("Case 3ci - previous with current in VHT-SIG-A: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
492  }
493  //Case 3bii: HT mixed format of HT greenfield
494  else
495  {
496  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
497  noiseInterferenceW,
498  event->GetTxVector ().GetChannelWidth ()),
499  current - previous,
500  htHeaderMode, event->GetTxVector ());
501 
502  NS_LOG_DEBUG ("Case 3cii - previous with current in HT-SIG: mode=" << htHeaderMode << ", psr=" << psr);
503  }
504  }
505  }
506  //Case 4: previous in L-SIG: HT GF will not reach here because it will execute the previous if and exit
507  else if (previous >= plcpHeaderStart)
508  {
509  NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
510  //Case 4a: current after payload start
511  if (current >= plcpPayloadStart)
512  {
513  //Case 4ai: Non (V)HT format
514  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
515  {
516  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
517  noiseInterferenceW,
518  event->GetTxVector ().GetChannelWidth ()),
519  plcpPayloadStart - previous,
520  headerMode, event->GetTxVector ());
521 
522  NS_LOG_DEBUG ("Case 4ai - previous in L-SIG and current after payload start: mode=" << headerMode << ", psr=" << psr);
523  }
524  //Case 4aii: VHT format
525  else if (preamble == WIFI_PREAMBLE_VHT)
526  {
527  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
528  noiseInterferenceW,
529  event->GetTxVector ().GetChannelWidth ()),
530  plcpPayloadStart - plcpHtTrainingSymbolsStart,
531  htHeaderMode, event->GetTxVector ());
532 
533  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
534  noiseInterferenceW,
535  event->GetTxVector ().GetChannelWidth ()),
536  plcpHtTrainingSymbolsStart - previous,
537  headerMode, event->GetTxVector ());
538 
539  NS_LOG_DEBUG ("Case 4aii - previous is in L-SIG and current after payload start: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
540  }
541  //Case 4aiii: HT mixed format
542  else
543  {
544  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
545  noiseInterferenceW,
546  event->GetTxVector ().GetChannelWidth ()),
547  plcpPayloadStart - plcpHsigHeaderStart,
548  htHeaderMode, event->GetTxVector ());
549 
550  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
551  noiseInterferenceW,
552  event->GetTxVector ().GetChannelWidth ()),
553  plcpHsigHeaderStart - previous,
554  headerMode, event->GetTxVector ());
555 
556  NS_LOG_DEBUG ("Case 4aiii - previous in L-SIG and current after payload start: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
557  }
558  }
559  //Case 4b: current is in (V)HT training or in VHT-SIG-B. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
560  else if (current >= plcpHtTrainingSymbolsStart)
561  {
562  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
563 
564  //Case 4bi: VHT format
565  if (preamble == WIFI_PREAMBLE_VHT)
566  {
567  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
568  noiseInterferenceW,
569  event->GetTxVector ().GetChannelWidth ()),
570  current - plcpHtTrainingSymbolsStart,
571  htHeaderMode, event->GetTxVector ());
572 
573  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
574  noiseInterferenceW,
575  event->GetTxVector ().GetChannelWidth ()),
576  plcpHtTrainingSymbolsStart - previous,
577  headerMode, event->GetTxVector ());
578 
579  NS_LOG_DEBUG ("Case 4bi - previous is in L-SIG and current in VHT training or in VHT-SIG-B: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
580  }
581  //Case 4bii: HT mixed format
582  else
583  {
584  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
585  noiseInterferenceW,
586  event->GetTxVector ().GetChannelWidth ()),
587  current - plcpHsigHeaderStart,
588  htHeaderMode, event->GetTxVector ());
589 
590  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
591  noiseInterferenceW,
592  event->GetTxVector ().GetChannelWidth ()),
593  plcpHsigHeaderStart - previous,
594  headerMode, event->GetTxVector ());
595 
596  NS_LOG_DEBUG ("Case 4bii - previous in L-SIG and current in HT training: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
597  }
598  }
599  //Case 4c: current in HT-SIG or in VHT-SIG-A. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
600  else if (current >= plcpHsigHeaderStart)
601  {
602  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
603 
604  //Case 4ci: VHT format
605  if (preamble == WIFI_PREAMBLE_VHT)
606  {
607  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
608  noiseInterferenceW,
609  event->GetTxVector ().GetChannelWidth ()),
610  current - previous,
611  headerMode, event->GetTxVector ());
612 
613  NS_LOG_DEBUG ("Case 4ci - previous is in L-SIG and current in VHT-SIG-A: mode=" << headerMode << ", psr=" << psr);
614  }
615  //Case 4cii: HT mixed format
616  else
617  {
618  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
619  noiseInterferenceW,
620  event->GetTxVector ().GetChannelWidth ()),
621  current - plcpHsigHeaderStart,
622  htHeaderMode, event->GetTxVector ());
623 
624  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
625  noiseInterferenceW,
626  event->GetTxVector ().GetChannelWidth ()),
627  plcpHsigHeaderStart - previous,
628  headerMode, event->GetTxVector ());
629 
630  NS_LOG_DEBUG ("Case 4cii - previous in L-SIG and current in HT-SIG: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
631  }
632  }
633  //Case 4d: current with previous in L-SIG
634  else
635  {
636  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
637  noiseInterferenceW,
638  event->GetTxVector ().GetChannelWidth ()),
639  current - previous,
640  headerMode, event->GetTxVector ());
641 
642  NS_LOG_DEBUG ("Case 3c - current with previous in L-SIG: mode=" << headerMode << ", psr=" << psr);
643  }
644  }
645  //Case 5: previous is in the preamble works for all cases
646  else
647  {
648  //Case 5a: current after payload start
649  if (current >= plcpPayloadStart)
650  {
651  //Case 5ai: Non HT format (No HT-SIG or Training Symbols)
652  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
653  {
654  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
655  noiseInterferenceW,
656  event->GetTxVector ().GetChannelWidth ()),
657  plcpPayloadStart - plcpHeaderStart,
658  headerMode, event->GetTxVector ());
659 
660  NS_LOG_DEBUG ("Case 5a - previous is in the preamble and current is after payload start: mode=" << headerMode << ", psr=" << psr);
661  }
662  //Case 5aii: VHT format
663  else if (preamble == WIFI_PREAMBLE_VHT)
664  {
665  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
666  noiseInterferenceW,
667  event->GetTxVector ().GetChannelWidth ()),
668  plcpPayloadStart - plcpHtTrainingSymbolsStart,
669  htHeaderMode, event->GetTxVector ());
670 
671  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
672  noiseInterferenceW,
673  event->GetTxVector ().GetChannelWidth ()),
674  plcpHtTrainingSymbolsStart - plcpHeaderStart,
675  headerMode, event->GetTxVector ());
676 
677  NS_LOG_DEBUG ("Case 5aii - previous is in the preamble and current is after payload start: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
678  }
679 
680  //Case 5aiii: HT format
681  else
682  {
683  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
684  noiseInterferenceW,
685  event->GetTxVector ().GetChannelWidth ()),
686  plcpPayloadStart - plcpHsigHeaderStart,
687  htHeaderMode, event->GetTxVector ());
688 
689  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
690  noiseInterferenceW,
691  event->GetTxVector ().GetChannelWidth ()),
692  plcpHsigHeaderStart - plcpHeaderStart, //HT GF: plcpHsigHeaderStart - plcpHeaderStart = 0
693  headerMode, event->GetTxVector ());
694 
695  NS_LOG_DEBUG ("Case 4a - previous is in the preamble and current is after payload start: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
696  }
697  }
698  //Case 5b: current is in (V)HT training or in VHT-SIG-B. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
699  else if (current >= plcpHtTrainingSymbolsStart)
700  {
701  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
702 
703  //Case 5bi: VHT format
704  if (preamble == WIFI_PREAMBLE_VHT)
705  {
706  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
707  noiseInterferenceW,
708  event->GetTxVector ().GetChannelWidth ()),
709  current - plcpHtTrainingSymbolsStart,
710  htHeaderMode, event->GetTxVector ());
711 
712  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
713  noiseInterferenceW,
714  event->GetTxVector ().GetChannelWidth ()),
715  plcpHtTrainingSymbolsStart - plcpHeaderStart,
716  headerMode, event->GetTxVector ());
717 
718  NS_LOG_DEBUG ("Case 5bi - previous is in the preamble and current in VHT training or in VHT-SIG-B: VHT mode=" << htHeaderMode << ", non-VHT mode=" << headerMode << ", psr=" << psr);
719  }
720  //Case 45ii: HT mixed format
721  else
722  {
723  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
724  noiseInterferenceW,
725  event->GetTxVector ().GetChannelWidth ()),
726  current - plcpHsigHeaderStart,
727  htHeaderMode, event->GetTxVector ());
728 
729  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
730  noiseInterferenceW,
731  event->GetTxVector ().GetChannelWidth ()),
732  plcpHsigHeaderStart - plcpHeaderStart,
733  headerMode, event->GetTxVector ());
734 
735  NS_LOG_DEBUG ("Case 5bii - previous is in the preamble and current in HT training: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
736  }
737  }
738  //Case 5c: current in HT-SIG or in VHT-SIG-A. Non (V)HT will not come here since it went in previous if or if the previous if is not true this will be not true
739  else if (current >= plcpHsigHeaderStart)
740  {
741  NS_ASSERT ((preamble != WIFI_PREAMBLE_LONG) && (preamble != WIFI_PREAMBLE_SHORT));
742 
743  //Case 5ci: VHT format
744  if (preamble == WIFI_PREAMBLE_VHT)
745  {
746  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
747  noiseInterferenceW,
748  event->GetTxVector ().GetChannelWidth ()),
749  current - plcpHeaderStart,
750  headerMode, event->GetTxVector ());
751 
752  NS_LOG_DEBUG ("Case 5ci - previous is in preamble and current in VHT-SIG-A: mode=" << headerMode << ", psr=" << psr);
753  }
754  //Case 5cii: HT mixed format
755  else
756  {
757  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
758  noiseInterferenceW,
759  event->GetTxVector ().GetChannelWidth ()),
760  current - plcpHsigHeaderStart,
761  htHeaderMode, event->GetTxVector ());
762 
763  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
764  noiseInterferenceW,
765  event->GetTxVector ().GetChannelWidth ()),
766  plcpHsigHeaderStart - plcpHeaderStart, //HT GF: plcpHsigHeaderStart - plcpHeaderStart = 0
767  headerMode, event->GetTxVector ());
768 
769  NS_LOG_DEBUG ("Case 5cii - previous in preamble and current in HT-SIG: HT mode=" << htHeaderMode << ", non-HT mode=" << headerMode << ", psr=" << psr);
770  }
771  }
772  //Case 5d: current is in L-SIG. HT GF will not come here
773  else if (current >= plcpHeaderStart)
774  {
775  NS_ASSERT (preamble != WIFI_PREAMBLE_HT_GF);
776 
777  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
778  noiseInterferenceW,
779  event->GetTxVector ().GetChannelWidth ()),
780  current - plcpHeaderStart,
781  headerMode, event->GetTxVector ());
782 
783  NS_LOG_DEBUG ("Case 5d - previous is in the preamble and current is in L-SIG: mode=" << headerMode << ", psr=" << psr);
784  }
785  }
786 
787  noiseInterferenceW += (*j).GetDelta ();
788  previous = (*j).GetTime ();
789  j++;
790  }
791 
792  double per = 1 - psr;
793  return per;
794 }
795 
797 InterferenceHelper::CalculatePlcpPayloadSnrPer (Ptr<InterferenceHelper::Event> event)
798 {
799  NiChanges ni;
800  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
801  double snr = CalculateSnr (event->GetRxPowerW (),
802  noiseInterferenceW,
803  event->GetTxVector ().GetChannelWidth ());
804 
805  /* calculate the SNIR at the start of the packet and accumulate
806  * all SNIR changes in the snir vector.
807  */
808  double per = CalculatePlcpPayloadPer (event, &ni);
809 
810  struct SnrPer snrPer;
811  snrPer.snr = snr;
812  snrPer.per = per;
813  return snrPer;
814 }
815 
817 InterferenceHelper::CalculatePlcpHeaderSnrPer (Ptr<InterferenceHelper::Event> event)
818 {
819  NiChanges ni;
820  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
821  double snr = CalculateSnr (event->GetRxPowerW (),
822  noiseInterferenceW,
823  event->GetTxVector ().GetChannelWidth ());
824 
825  /* calculate the SNIR at the start of the plcp header and accumulate
826  * all SNIR changes in the snir vector.
827  */
828  double per = CalculatePlcpHeaderPer (event, &ni);
829 
830  struct SnrPer snrPer;
831  snrPer.snr = snr;
832  snrPer.per = per;
833  return snrPer;
834 }
835 
836 void
838 {
839  m_niChanges.clear ();
840  m_rxing = false;
841  m_firstPower = 0.0;
842 }
843 
844 InterferenceHelper::NiChanges::iterator
846 {
847  return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0));
848 }
849 
850 void
852 {
853  m_niChanges.insert (GetPosition (change.GetTime ()), change);
854 }
855 
856 void
858 {
859  NS_LOG_FUNCTION (this);
860  m_rxing = true;
861 }
862 
863 void
865 {
866  NS_LOG_FUNCTION (this);
867  m_rxing = false;
868 }
869 
870 } //namespace ns3
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.
A struct for both SNR and PER.
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 "...
Control the scheduling of simulation events.
Definition: simulator.h:68
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...
bool operator<(const NiChange &o) const
Compare the event time of two NiChange objects (a < o).
std::vector< NiChange > NiChanges
typedef for a vector of NiChanges
handles interference calculations
static WifiMode GetHtPlcpHeaderMode(WifiMode payloadMode)
Definition: wifi-phy.cc:1347
static Time GetPlcpHtSigHeaderDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1405
#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
Time GetEnergyDuration(double energyW)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
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. ...
double GetRxPowerW(void) const
Return the receive power (w).
Ptr< ErrorRateModel > m_errorRateModel
NiChanges::iterator GetPosition(Time moment)
Returns an iterator to the first nichange, which is later than moment.
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:99
uint32_t GetSize(void) const
Return the size of the packet (bytes).
static WifiMode GetVhtPlcpHeaderMode(WifiMode payloadMode)
Definition: wifi-phy.cc:1353
uint64_t GetPhyRate(uint32_t channelWidth, bool isShortGuardInterval, uint8_t nss) const
Definition: wifi-mode.cc:74
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:30
void SetErrorRateModel(Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChanges *ni) const
Calculate noise and interference power in W.
Time GetStartTime(void) const
Return the start time of the signal.
WifiTxVector GetTxVector(void) const
Return the TXVECTOR of the packet.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:919
static WifiMode GetPlcpHeaderMode(WifiMode payloadMode, WifiPreamble preamble, WifiTxVector txVector)
Definition: wifi-phy.cc:1462
NiChanges m_niChanges
Experimental: needed for energy duration calculation.
void AddNiChangeEvent(NiChange change)
Add NiChange to the list at the appropriate position.
Time GetTime(void) const
Return the event time.
double CalculatePlcpPayloadPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the given plcp payload.
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.
Ptr< InterferenceHelper::Event > Add(uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, Time duration, double rxPower)
Add the packet-related signal to interference helper.
Event(uint32_t size, WifiTxVector txVector, enum WifiPreamble preamble, Time duration, double rxPower)
Create an Event with the given parameters.
double CalculatePlcpHeaderPer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the plcp header.
double GetDelta(void) const
Return the power.
static Time GetPlcpVhtSigA1Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1420
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
Time GetEndTime(void) const
Return the end time of the signal.
enum WifiPreamble GetPreambleType(void) const
Return the preamble type of the packet.
void NotifyRxEnd()
Notify that RX has ended.
NiChange(Time time, double delta)
Create a NiChange at the given time and the amount of NI change.
double CalculateSnr(double signal, double noiseInterference, uint32_t channelWidth) const
Calculate SNR (linear ratio) from the given signal power and noise+interference power.
Time GetDuration(void) const
Return the duration of the signal.
void SetNoiseFigure(double value)
Set the noise figure.
WifiMode GetPayloadMode(void) const
Return the Wi-Fi mode used for the payload.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
static Time GetPlcpHeaderDuration(WifiTxVector txVector, WifiPreamble preamble)
Definition: wifi-phy.cc:1507
void AppendEvent(Ptr< Event > event)
Append the given Event.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:340
double GetNoiseFigure(void) const
Return the noise figure.
static Time GetPlcpHtTrainingSymbolDuration(WifiPreamble preamble, WifiTxVector txVector)
Definition: wifi-phy.cc:1359
static Time GetPlcpVhtSigBDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1448
static Time GetPlcpPreambleDuration(WifiTxVector txVector, WifiPreamble preamble)
Definition: wifi-phy.cc:1571
static Time GetPlcpVhtSigA2Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1434