A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "interference-helper.h"
21 #include "wifi-phy.h"
22 #include "error-rate-model.h"
23 #include "ns3/simulator.h"
24 #include "ns3/log.h"
25 #include <algorithm>
26 
27 NS_LOG_COMPONENT_DEFINE ("InterferenceHelper");
28 
29 namespace ns3 {
30 
31 /****************************************************************
32  * Phy event class
33  ****************************************************************/
34 
35 InterferenceHelper::Event::Event (uint32_t size, WifiMode payloadMode,
36  enum WifiPreamble preamble,
37  Time duration, double rxPower, WifiTxVector txVector)
38  : m_size (size),
39  m_payloadMode (payloadMode),
40  m_preamble (preamble),
41  m_startTime (Simulator::Now ()),
42  m_endTime (m_startTime + duration),
43  m_rxPowerW (rxPower),
44  m_txVector (txVector)
45 {
46 }
48 {
49 }
50 
51 Time
53 {
54  return m_endTime - m_startTime;
55 }
56 Time
58 {
59  return m_startTime;
60 }
61 Time
63 {
64  return m_endTime;
65 }
66 double
68 {
69  return m_rxPowerW;
70 }
71 uint32_t
73 {
74  return m_size;
75 }
78 {
79  return m_payloadMode;
80 }
81 enum WifiPreamble
83 {
84  return m_preamble;
85 }
86 
89 {
90  return m_txVector;
91 }
92 
93 
94 /****************************************************************
95  * Class which records SNIR change events for a
96  * short period of time.
97  ****************************************************************/
98 
100  : m_time (time),
101  m_delta (delta)
102 {
103 }
104 Time
106 {
107  return m_time;
108 }
109 double
111 {
112  return m_delta;
113 }
114 bool
116 {
117  return (m_time < o.m_time);
118 }
119 
120 /****************************************************************
121  * The actual InterferenceHelper
122  ****************************************************************/
123 
125  : m_errorRateModel (0),
126  m_firstPower (0.0),
127  m_rxing (false)
128 {
129 }
131 {
132  EraseEvents ();
133  m_errorRateModel = 0;
134 }
135 
137 InterferenceHelper::Add (uint32_t size, WifiMode payloadMode,
138  enum WifiPreamble preamble,
139  Time duration, double rxPowerW, WifiTxVector txVector)
140 {
142 
143  event = Create<InterferenceHelper::Event> (size,
144  payloadMode,
145  preamble,
146  duration,
147  rxPowerW,
148  txVector);
149  AppendEvent (event);
150  return event;
151 }
152 
153 
154 void
156 {
157  m_noiseFigure = value;
158 }
159 
160 double
162 {
163  return m_noiseFigure;
164 }
165 
166 void
168 {
169  m_errorRateModel = rate;
170 }
171 
174 {
175  return m_errorRateModel;
176 }
177 
178 Time
180 {
181  Time now = Simulator::Now ();
182  double noiseInterferenceW = 0.0;
183  Time end = now;
184  noiseInterferenceW = m_firstPower;
185  for (NiChanges::const_iterator i = m_niChanges.begin (); i != m_niChanges.end (); i++)
186  {
187  noiseInterferenceW += i->GetDelta ();
188  end = i->GetTime ();
189  if (end < now)
190  {
191  continue;
192  }
193  if (noiseInterferenceW < energyW)
194  {
195  break;
196  }
197  }
198  return end > now ? end - now : MicroSeconds (0);
199 }
200 
201 void
203 {
204  Time now = Simulator::Now ();
205  if (!m_rxing)
206  {
207  NiChanges::iterator nowIterator = GetPosition (now);
208  for (NiChanges::iterator i = m_niChanges.begin (); i != nowIterator; i++)
209  {
210  m_firstPower += i->GetDelta ();
211  }
212  m_niChanges.erase (m_niChanges.begin (), nowIterator);
213  m_niChanges.insert (m_niChanges.begin (), NiChange (event->GetStartTime (), event->GetRxPowerW ()));
214  }
215  else
216  {
217  AddNiChangeEvent (NiChange (event->GetStartTime (), event->GetRxPowerW ()));
218  }
219  AddNiChangeEvent (NiChange (event->GetEndTime (), -event->GetRxPowerW ()));
220 
221 }
222 
223 
224 double
225 InterferenceHelper::CalculateSnr (double signal, double noiseInterference, WifiMode mode) const
226 {
227  // thermal noise at 290K in J/s = W
228  static const double BOLTZMANN = 1.3803e-23;
229  // Nt is the power of thermal noise in W
230  double Nt = BOLTZMANN * 290.0 * mode.GetBandwidth ();
231  // receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
232  double noiseFloor = m_noiseFigure * Nt;
233  double noise = noiseFloor + noiseInterference;
234  double snr = signal / noise;
235  return snr;
236 }
237 
238 double
240 {
241  double noiseInterference = m_firstPower;
242  NS_ASSERT (m_rxing);
243  for (NiChanges::const_iterator i = m_niChanges.begin () + 1; i != m_niChanges.end (); i++)
244  {
245  if ((event->GetEndTime () == i->GetTime ()) && event->GetRxPowerW () == -i->GetDelta ())
246  {
247  break;
248  }
249  ni->push_back (*i);
250  }
251  ni->insert (ni->begin (), NiChange (event->GetStartTime (), noiseInterference));
252  ni->push_back (NiChange (event->GetEndTime (), 0));
253  return noiseInterference;
254 }
255 
256 double
258 {
259  if (duration == NanoSeconds (0))
260  {
261  return 1.0;
262  }
263  uint32_t rate = mode.GetPhyRate ();
264  uint64_t nbits = (uint64_t)(rate * duration.GetSeconds ());
265  double csr = m_errorRateModel->GetChunkSuccessRate (mode, snir, (uint32_t)nbits);
266  return csr;
267 }
268 
269 double
271 {
272  double psr = 1.0; /* Packet Success Rate */
273  NiChanges::iterator j = ni->begin ();
274  Time previous = (*j).GetTime ();
275  WifiMode payloadMode = event->GetPayloadMode ();
276  WifiPreamble preamble = event->GetPreambleType ();
277  WifiMode MfHeaderMode ;
278  if (preamble==WIFI_PREAMBLE_HT_MF)
279  {
280  MfHeaderMode = WifiPhy::GetMFPlcpHeaderMode (payloadMode, preamble); //return L-SIG mode
281 
282  }
283  WifiMode headerMode = WifiPhy::GetPlcpHeaderMode (payloadMode, preamble);
284  Time plcpHeaderStart = (*j).GetTime () + MicroSeconds (WifiPhy::GetPlcpPreambleDurationMicroSeconds (payloadMode, preamble)); //packet start time+ preamble
285  Time plcpHsigHeaderStart=plcpHeaderStart+ MicroSeconds (WifiPhy::GetPlcpHeaderDurationMicroSeconds (payloadMode, preamble));//packet start time+ preamble+L SIG
286  Time plcpHtTrainingSymbolsStart = plcpHsigHeaderStart + MicroSeconds (WifiPhy::GetPlcpHtSigHeaderDurationMicroSeconds (payloadMode, preamble));//packet start time+ preamble+L SIG+HT SIG
287  Time plcpPayloadStart =plcpHtTrainingSymbolsStart + MicroSeconds (WifiPhy::GetPlcpHtTrainingSymbolDurationMicroSeconds (payloadMode, preamble,event->GetTxVector())); //packet start time+ preamble+L SIG+HT SIG+Training
288  double noiseInterferenceW = (*j).GetDelta ();
289  double powerW = event->GetRxPowerW ();
290  j++;
291  while (ni->end () != j)
292  {
293  Time current = (*j).GetTime ();
294  NS_ASSERT (current >= previous);
295  //Case 1: Both prev and curr point to the payload
296  if (previous >= plcpPayloadStart)
297  {
298  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
299  noiseInterferenceW,
300  payloadMode),
301  current - previous,
302  payloadMode);
303  }
304  //Case 2: previous is before payload
305  else if (previous >= plcpHtTrainingSymbolsStart)
306  {
307  //Case 2a: current is after payload
308  if (current >= plcpPayloadStart)
309  {
310  //Case 2ai and 2aii: All formats
311  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
312  noiseInterferenceW,
313  payloadMode),
314  current - plcpPayloadStart,
315  payloadMode);
316 
317  }
318  }
319  //Case 3: previous is in HT-SIG: Non HT will not enter here since it didn't enter in the last two and they are all the same for non HT
320  else if (previous >=plcpHsigHeaderStart)
321  {
322  //Case 3a: cuurent after payload start
323  if (current >=plcpPayloadStart)
324  {
325  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
326  noiseInterferenceW,
327  payloadMode),
328  current - plcpPayloadStart,
329  payloadMode);
330 
331  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
332  noiseInterferenceW,
333  headerMode),
334  plcpHtTrainingSymbolsStart - previous,
335  headerMode);
336  }
337  //case 3b: current after HT training symbols start
338  else if (current >=plcpHtTrainingSymbolsStart)
339  {
340  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
341  noiseInterferenceW,
342  headerMode),
343  plcpHtTrainingSymbolsStart - previous,
344  headerMode);
345 
346  }
347  //Case 3c: current is with previous in HT sig
348  else
349  {
350  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
351  noiseInterferenceW,
352  headerMode),
353  current- previous,
354  headerMode);
355 
356  }
357  }
358  //Case 4: previous in L-SIG: GF will not reach here because it will execute the previous if and exit
359  else if (previous >= plcpHeaderStart)
360  {
361  //Case 4a: current after payload start
362  if (current >=plcpPayloadStart)
363  {
364  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
365  noiseInterferenceW,
366  payloadMode),
367  current - plcpPayloadStart,
368  payloadMode);
369  //Case 4ai: Non HT format (No HT-SIG or Training Symbols)
370  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT) //plcpHtTrainingSymbolsStart==plcpHeaderStart)
371  {
372  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
373  noiseInterferenceW,
374  headerMode),
375  plcpPayloadStart - previous,
376  headerMode);
377  }
378 
379  else{
380  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
381  noiseInterferenceW,
382  headerMode),
383  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
384  headerMode);
385  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
386  noiseInterferenceW,
387  MfHeaderMode),
388  plcpHsigHeaderStart - previous,
389  MfHeaderMode);
390  }
391  }
392  //Case 4b: current in HT training symbol. non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
393  else if (current >=plcpHtTrainingSymbolsStart)
394  {
395  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
396  noiseInterferenceW,
397  headerMode),
398  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
399  headerMode);
400  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
401  noiseInterferenceW,
402  MfHeaderMode),
403  plcpHsigHeaderStart - previous,
404  MfHeaderMode);
405  }
406  //Case 4c: current in H sig.non HT will not come here since it went in previous if or if the previous ifis not true this will be not true
407  else if (current >=plcpHsigHeaderStart)
408  {
409  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
410  noiseInterferenceW,
411  headerMode),
412  current - plcpHsigHeaderStart,
413  headerMode);
414  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
415  noiseInterferenceW,
416  MfHeaderMode),
417  plcpHsigHeaderStart - previous,
418  MfHeaderMode);
419 
420  }
421  //Case 4d: Current with prev in L SIG
422  else
423  {
424  //Case 4di: Non HT format (No HT-SIG or Training Symbols)
425  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT) //plcpHtTrainingSymbolsStart==plcpHeaderStart)
426  {
427  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
428  noiseInterferenceW,
429  headerMode),
430  current - previous,
431  headerMode);
432  }
433  else
434  {
435  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
436  noiseInterferenceW,
437  MfHeaderMode),
438  current - previous,
439  MfHeaderMode);
440  }
441  }
442  }
443  //Case 5: previous is in the preamble works for all cases
444  else
445  {
446  if (current >= plcpPayloadStart)
447  {
448  //for all
449  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
450  noiseInterferenceW,
451  payloadMode),
452  current - plcpPayloadStart,
453  payloadMode);
454 
455  // Non HT format (No HT-SIG or Training Symbols)
456  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
457  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
458  noiseInterferenceW,
459  headerMode),
460  plcpPayloadStart - plcpHeaderStart,
461  headerMode);
462  else
463  // Greenfield or Mixed format
464  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
465  noiseInterferenceW,
466  headerMode),
467  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
468  headerMode);
469  if (preamble == WIFI_PREAMBLE_HT_MF)
470  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
471  noiseInterferenceW,
472  MfHeaderMode),
473  plcpHsigHeaderStart-plcpHeaderStart,
474  MfHeaderMode);
475  }
476  else if (current >=plcpHtTrainingSymbolsStart )
477  {
478  // Non HT format will not come here since it will execute prev if
479  // Greenfield or Mixed format
480  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
481  noiseInterferenceW,
482  headerMode),
483  plcpHtTrainingSymbolsStart - plcpHsigHeaderStart,
484  headerMode);
485  if (preamble == WIFI_PREAMBLE_HT_MF)
486  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
487  noiseInterferenceW,
488  MfHeaderMode),
489  plcpHsigHeaderStart-plcpHeaderStart,
490  MfHeaderMode);
491  }
492  //non HT will not come here
493  else if (current >=plcpHsigHeaderStart)
494  {
495  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
496  noiseInterferenceW,
497  headerMode),
498  current- plcpHsigHeaderStart,
499  headerMode);
500  if (preamble != WIFI_PREAMBLE_HT_GF)
501  {
502  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
503  noiseInterferenceW,
504  MfHeaderMode),
505  plcpHsigHeaderStart-plcpHeaderStart,
506  MfHeaderMode);
507  }
508  }
509  // GF will not come here
510  else if (current >= plcpHeaderStart)
511  {
512  if (preamble == WIFI_PREAMBLE_LONG || preamble == WIFI_PREAMBLE_SHORT)
513  {
514  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
515  noiseInterferenceW,
516  headerMode),
517  current - plcpHeaderStart,
518  headerMode);
519  }
520  else
521  {
522  psr *= CalculateChunkSuccessRate (CalculateSnr (powerW,
523  noiseInterferenceW,
524  MfHeaderMode),
525  current - plcpHeaderStart,
526  MfHeaderMode);
527  }
528  }
529  }
530 
531  noiseInterferenceW += (*j).GetDelta ();
532  previous = (*j).GetTime ();
533  j++;
534  }
535 
536  double per = 1 - psr;
537  return per;
538 }
539 
540 
542 InterferenceHelper::CalculateSnrPer (Ptr<InterferenceHelper::Event> event)
543 {
544  NiChanges ni;
545  double noiseInterferenceW = CalculateNoiseInterferenceW (event, &ni);
546  double snr = CalculateSnr (event->GetRxPowerW (),
547  noiseInterferenceW,
548  event->GetPayloadMode ());
549 
550  /* calculate the SNIR at the start of the packet and accumulate
551  * all SNIR changes in the snir vector.
552  */
553  double per = CalculatePer (event, &ni);
554 
555  struct SnrPer snrPer;
556  snrPer.snr = snr;
557  snrPer.per = per;
558  return snrPer;
559 }
560 
561 void
563 {
564  m_niChanges.clear ();
565  m_rxing = false;
566  m_firstPower = 0.0;
567 }
568 InterferenceHelper::NiChanges::iterator
570 {
571  return std::upper_bound (m_niChanges.begin (), m_niChanges.end (), NiChange (moment, 0));
572 
573 }
574 void
576 {
577  m_niChanges.insert (GetPosition (change.GetTime ()), change);
578 }
579 void
581 {
582  m_rxing = true;
583 }
584 void
586 {
587  m_rxing = false;
588 }
589 } // namespace ns3
static uint32_t GetPlcpHeaderDurationMicroSeconds(WifiMode payloadMode, WifiPreamble preamble)
Definition: wifi-phy.cc:221
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
A struct for both SNR and PER.
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
Control the scheduling of simulation events.
Definition: simulator.h:63
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...
double CalculatePer(Ptr< const Event > event, NiChanges *ni) const
Calculate the error rate of the given packet.
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
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
Time GetEnergyDuration(double energyW)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
static WifiMode GetMFPlcpHeaderMode(WifiMode payloadMode, WifiPreamble preamble)
Definition: wifi-phy.cc:100
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:91
uint32_t GetSize(void) const
Return the size of the packet (bytes).
double CalculateChunkSuccessRate(double snir, Time duration, WifiMode mode) const
Calculate the success rate of the chunk given the SINR, duration, and Wi-Fi mode. ...
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:29
void SetErrorRateModel(Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
double GetSeconds(void) const
Definition: nstime.h:272
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.
NiChanges m_niChanges
Experimental: needed for energy duration calculation.
void AddNiChangeEvent(NiChange change)
Add NiChange to the list at the appropriate position.
static WifiMode GetPlcpHeaderMode(WifiMode payloadMode, WifiPreamble preamble)
Definition: wifi-phy.cc:148
Time GetTime(void) const
Return the event time.
Ptr< InterferenceHelper::Event > Add(uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble, Time duration, double rxPower, WifiTxVector txvector)
Add the packet-related signal to interference helper.
uint32_t GetBandwidth(void) const
Definition: wifi-mode.cc:67
double m_noiseFigure
noise figure (linear)
void NotifyRxStart()
Notify that RX has started.
Noise and Interference (thus Ni) event.
void EraseEvents(void)
Erase all events.
uint64_t GetPhyRate(void) const
Definition: wifi-mode.cc:73
static uint32_t GetPlcpHtTrainingSymbolDurationMicroSeconds(WifiMode payloadMode, WifiPreamble preamble, WifiTxVector txvector)
Definition: wifi-phy.cc:113
double GetDelta(void) const
Return the power.
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
Time GetEndTime(void) const
Return the end time of the signal.
enum WifiPreamble GetPreambleType(void) const
Return the preamble type of the packet.
Time current
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.
Time GetDuration(void) const
Return the duration of the signal.
void SetNoiseFigure(double value)
Set the noise figure.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
WifiMode GetPayloadMode(void) const
Return the Wi-Fi mode used for the payload.
Event(uint32_t size, WifiMode payloadMode, enum WifiPreamble preamble, Time duration, double rxPower, WifiTxVector txvector)
Create an Event with the given parameters.
double CalculateSnr(double signal, double noiseInterference, WifiMode mode) const
Calculate SNR (linear ratio) from the given signal power and noise+interference power.
void AppendEvent(Ptr< Event > event)
Append the given Event.
double GetNoiseFigure(void) const
Return the noise figure.
static uint32_t GetPlcpPreambleDurationMicroSeconds(WifiMode payloadMode, WifiPreamble preamble)
Definition: wifi-phy.cc:284
static uint32_t GetPlcpHtSigHeaderDurationMicroSeconds(WifiMode payloadMode, WifiPreamble preamble)
Definition: wifi-phy.cc:129