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