A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
interference-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
21#include "interference-helper.h"
22
23#include "error-rate-model.h"
24#include "wifi-phy.h"
25#include "wifi-psdu.h"
26#include "wifi-utils.h"
27
28#include "ns3/log.h"
29#include "ns3/packet.h"
30#include "ns3/simulator.h"
31
32#include <algorithm>
33#include <numeric>
34
35namespace ns3
36{
37
38NS_LOG_COMPONENT_DEFINE("InterferenceHelper");
39
40NS_OBJECT_ENSURE_REGISTERED(InterferenceHelper);
41
42/****************************************************************
43 * PHY event class
44 ****************************************************************/
45
47 const WifiTxVector& txVector,
48 Time duration,
50 : m_ppdu(ppdu),
51 m_txVector(txVector),
52 m_startTime(Simulator::Now()),
53 m_endTime(m_startTime + duration),
54 m_rxPowerW(std::move(rxPower))
55{
56}
57
59{
60 m_ppdu = nullptr;
61 m_rxPowerW.clear();
62}
63
66{
67 return m_ppdu;
68}
69
70Time
72{
73 return m_startTime;
74}
75
76Time
78{
79 return m_endTime;
80}
81
82Time
84{
85 return m_endTime - m_startTime;
86}
87
88double
90{
91 NS_ASSERT(!m_rxPowerW.empty());
92 // The total RX power corresponds to the maximum over all the bands
93 auto it = std::max_element(
94 m_rxPowerW.begin(),
95 m_rxPowerW.end(),
96 [](const std::pair<WifiSpectrumBand, double>& p1,
97 const std::pair<WifiSpectrumBand, double>& p2) { return p1.second < p2.second; });
98 return it->second;
99}
100
101double
103{
104 auto it = m_rxPowerW.find(band);
105 NS_ASSERT(it != m_rxPowerW.end());
106 return it->second;
107}
108
111{
112 return m_rxPowerW;
113}
114
115const WifiTxVector&
117{
118 return m_txVector;
119}
120
121void
123{
124 NS_ASSERT(rxPower.size() == m_rxPowerW.size());
125 // Update power band per band
126 for (auto& currentRxPowerW : m_rxPowerW)
127 {
128 auto band = currentRxPowerW.first;
129 auto it = rxPower.find(band);
130 if (it != rxPower.end())
131 {
132 currentRxPowerW.second += it->second;
133 }
134 }
135}
136
137std::ostream&
138operator<<(std::ostream& os, const Event& event)
139{
140 os << "start=" << event.GetStartTime() << ", end=" << event.GetEndTime()
141 << ", TXVECTOR=" << event.GetTxVector() << ", power=" << event.GetRxPowerW() << "W"
142 << ", PPDU=" << event.GetPpdu();
143 return os;
144}
145
146/****************************************************************
147 * Class which records SNIR change events for a
148 * short period of time.
149 ****************************************************************/
150
152 : m_power(power),
153 m_event(event)
154{
155}
156
158{
159 m_event = nullptr;
160}
161
162double
164{
165 return m_power;
166}
167
168void
170{
171 m_power += power;
172}
173
176{
177 return m_event;
178}
179
180/****************************************************************
181 * The actual InterferenceHelper
182 ****************************************************************/
183
185 : m_errorRateModel(nullptr),
187 m_rxing(false)
188{
189 NS_LOG_FUNCTION(this);
190}
191
193{
194 NS_LOG_FUNCTION(this);
195}
196
197TypeId
199{
200 static TypeId tid = TypeId("ns3::InterferenceHelper")
202 .SetGroupName("Wifi")
203 .AddConstructor<InterferenceHelper>();
204 return tid;
205}
206
207void
209{
210 NS_LOG_FUNCTION(this);
211 RemoveBands();
212 m_errorRateModel = nullptr;
213}
214
217 const WifiTxVector& txVector,
218 Time duration,
220 bool isStartOfdmaRxing)
221{
222 Ptr<Event> event = Create<Event>(ppdu, txVector, duration, std::move(rxPowerW));
223 AppendEvent(event, isStartOfdmaRxing);
224 return event;
225}
226
227void
229{
230 // Parameters other than duration and rxPowerW are unused for this type
231 // of signal, so we provide dummy versions
232 WifiMacHeader hdr;
234 hdr.SetQosTid(0);
235 Ptr<WifiPpdu> fakePpdu =
236 Create<WifiPpdu>(Create<WifiPsdu>(Create<Packet>(0), hdr), WifiTxVector(), 0);
237 Add(fakePpdu, WifiTxVector(), duration, rxPowerW);
238}
239
240void
242{
243 NS_LOG_FUNCTION(this);
244 for (auto it : m_niChangesPerBand)
245 {
246 it.second.clear();
247 }
248 m_niChangesPerBand.clear();
249 m_firstPowerPerBand.clear();
250}
251
252void
254{
255 NS_LOG_FUNCTION(this << band.first << band.second);
257 NiChanges niChanges;
258 auto result = m_niChangesPerBand.insert({band, niChanges});
259 NS_ASSERT(result.second);
260 // Always have a zero power noise event in the list
261 AddNiChangeEvent(Time(0), NiChange(0.0, nullptr), result.first);
262 m_firstPowerPerBand.insert({band, 0.0});
263}
264
265void
267{
268 m_noiseFigure = value;
269}
270
271void
273{
274 m_errorRateModel = rate;
275}
276
279{
280 return m_errorRateModel;
281}
282
283void
285{
286 m_numRxAntennas = rx;
287}
288
289Time
291{
292 Time now = Simulator::Now();
293 auto niIt = m_niChangesPerBand.find(band);
294 NS_ASSERT(niIt != m_niChangesPerBand.end());
295 auto i = GetPreviousPosition(now, niIt);
296 Time end = i->first;
297 for (; i != niIt->second.end(); ++i)
298 {
299 double noiseInterferenceW = i->second.GetPower();
300 end = i->first;
301 if (noiseInterferenceW < energyW)
302 {
303 break;
304 }
305 }
306 return end > now ? end - now : MicroSeconds(0);
307}
308
309void
310InterferenceHelper::AppendEvent(Ptr<Event> event, bool isStartOfdmaRxing)
311{
312 NS_LOG_FUNCTION(this << event << isStartOfdmaRxing);
313 for (const auto& it : event->GetRxPowerWPerBand())
314 {
315 WifiSpectrumBand band = it.first;
316 auto niIt = m_niChangesPerBand.find(band);
317 NS_ASSERT(niIt != m_niChangesPerBand.end());
318 double previousPowerStart = 0;
319 double previousPowerEnd = 0;
320 auto previousPowerPosition = GetPreviousPosition(event->GetStartTime(), niIt);
321 previousPowerStart = previousPowerPosition->second.GetPower();
322 previousPowerEnd = GetPreviousPosition(event->GetEndTime(), niIt)->second.GetPower();
323 if (!m_rxing)
324 {
325 m_firstPowerPerBand.find(band)->second = previousPowerStart;
326 // Always leave the first zero power noise event in the list
327 niIt->second.erase(++(niIt->second.begin()), ++previousPowerPosition);
328 }
329 else if (isStartOfdmaRxing)
330 {
331 // When the first UL-OFDMA payload is received, we need to set m_firstPowerPerBand
332 // so that it takes into account interferences that arrived between the start of the
333 // UL MU transmission and the start of UL-OFDMA payload.
334 m_firstPowerPerBand.find(band)->second = previousPowerStart;
335 }
336 auto first =
337 AddNiChangeEvent(event->GetStartTime(), NiChange(previousPowerStart, event), niIt);
338 auto last = AddNiChangeEvent(event->GetEndTime(), NiChange(previousPowerEnd, event), niIt);
339 for (auto i = first; i != last; ++i)
340 {
341 i->second.AddPower(it.second);
342 }
343 }
344}
345
346void
348{
349 NS_LOG_FUNCTION(this << event);
350 // This is called for UL MU events, in order to scale power as long as UL MU PPDUs arrive
351 for (const auto& it : rxPower)
352 {
353 WifiSpectrumBand band = it.first;
354 auto niIt = m_niChangesPerBand.find(band);
355 NS_ASSERT(niIt != m_niChangesPerBand.end());
356 auto first = GetPreviousPosition(event->GetStartTime(), niIt);
357 auto last = GetPreviousPosition(event->GetEndTime(), niIt);
358 for (auto i = first; i != last; ++i)
359 {
360 i->second.AddPower(it.second);
361 }
362 }
363 event->UpdateRxPowerW(rxPower);
364}
365
366double
368 double noiseInterference,
369 uint16_t channelWidth,
370 uint8_t nss) const
371{
372 NS_LOG_FUNCTION(this << signal << noiseInterference << channelWidth << +nss);
373 // thermal noise at 290K in J/s = W
374 static const double BOLTZMANN = 1.3803e-23;
375 // Nt is the power of thermal noise in W
376 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
377 // receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
378 double noiseFloor = m_noiseFigure * Nt;
379 double noise = noiseFloor + noiseInterference;
380 double snr = signal / noise; // linear scale
381 NS_LOG_DEBUG("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)="
382 << noiseFloor << ", interference(W)=" << noiseInterference
383 << ", snr=" << RatioToDb(snr) << "dB");
384 if (m_errorRateModel->IsAwgn())
385 {
386 double gain = 1;
387 if (m_numRxAntennas > nss)
388 {
389 gain = static_cast<double>(m_numRxAntennas) /
390 nss; // compute gain offered by diversity for AWGN
391 }
392 NS_LOG_DEBUG("SNR improvement thanks to diversity: " << 10 * std::log10(gain) << "dB");
393 snr *= gain;
394 }
395 return snr;
396}
397
398double
400 NiChangesPerBand* nis,
401 WifiSpectrumBand band) const
402{
403 NS_LOG_FUNCTION(this << band.first << band.second);
404 auto firstPower_it = m_firstPowerPerBand.find(band);
405 NS_ASSERT(firstPower_it != m_firstPowerPerBand.end());
406 double noiseInterferenceW = firstPower_it->second;
407 auto niIt = m_niChangesPerBand.find(band);
408 NS_ASSERT(niIt != m_niChangesPerBand.end());
409 auto it = niIt->second.find(event->GetStartTime());
410 for (; it != niIt->second.end() && it->first < Simulator::Now(); ++it)
411 {
412 noiseInterferenceW = it->second.GetPower() - event->GetRxPowerW(band);
413 }
414 it = niIt->second.find(event->GetStartTime());
415 NS_ASSERT(it != niIt->second.end());
416 for (; it != niIt->second.end() && it->second.GetEvent() != event; ++it)
417 {
418 ;
419 }
420 NiChanges ni;
421 ni.emplace(event->GetStartTime(), NiChange(0, event));
422 while (++it != niIt->second.end() && it->second.GetEvent() != event)
423 {
424 ni.insert(*it);
425 }
426 ni.emplace(event->GetEndTime(), NiChange(0, event));
427 nis->insert({band, ni});
428 NS_ASSERT_MSG(noiseInterferenceW >= 0,
429 "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
430 return noiseInterferenceW;
431}
432
433double
435 Time duration,
436 WifiMode mode,
437 const WifiTxVector& txVector,
438 WifiPpduField field) const
439{
440 if (duration.IsZero())
441 {
442 return 1.0;
443 }
444 uint64_t rate = mode.GetDataRate(txVector.GetChannelWidth());
445 uint64_t nbits = static_cast<uint64_t>(rate * duration.GetSeconds());
446 double csr =
447 m_errorRateModel->GetChunkSuccessRate(mode, txVector, snir, nbits, m_numRxAntennas, field);
448 return csr;
449}
450
451double
453 Time duration,
454 const WifiTxVector& txVector,
455 uint16_t staId) const
456{
457 if (duration.IsZero())
458 {
459 return 1.0;
460 }
461 WifiMode mode = txVector.GetMode(staId);
462 uint64_t rate = mode.GetDataRate(txVector, staId);
463 uint64_t nbits = static_cast<uint64_t>(rate * duration.GetSeconds());
464 nbits /= txVector.GetNss(staId); // divide effective number of bits by NSS to achieve same chunk
465 // error rate as SISO for AWGN
466 double csr = m_errorRateModel->GetChunkSuccessRate(mode,
467 txVector,
468 snir,
469 nbits,
472 staId);
473 return csr;
474}
475
476double
478 uint16_t channelWidth,
479 NiChangesPerBand* nis,
480 WifiSpectrumBand band,
481 uint16_t staId,
482 std::pair<Time, Time> window) const
483{
484 NS_LOG_FUNCTION(this << channelWidth << band.first << band.second << staId << window.first
485 << window.second);
486 double psr = 1.0; /* Packet Success Rate */
487 const auto& niIt = nis->find(band)->second;
488 auto j = niIt.cbegin();
489 Time previous = j->first;
490 WifiMode payloadMode = event->GetTxVector().GetMode(staId);
491 Time phyPayloadStart = j->first;
492 if (event->GetPpdu()->GetType() != WIFI_PPDU_TYPE_UL_MU &&
493 event->GetPpdu()->GetType() !=
494 WIFI_PPDU_TYPE_DL_MU) // j->first corresponds to the start of the OFDMA payload
495 {
496 phyPayloadStart =
497 j->first + WifiPhy::CalculatePhyPreambleAndHeaderDuration(event->GetTxVector());
498 }
499 Time windowStart = phyPayloadStart + window.first;
500 Time windowEnd = phyPayloadStart + window.second;
501 double noiseInterferenceW = m_firstPowerPerBand.find(band)->second;
502 double powerW = event->GetRxPowerW(band);
503 while (++j != niIt.cend())
504 {
505 Time current = j->first;
506 NS_LOG_DEBUG("previous= " << previous << ", current=" << current);
507 NS_ASSERT(current >= previous);
508 double snr = CalculateSnr(powerW,
509 noiseInterferenceW,
510 channelWidth,
511 event->GetTxVector().GetNss(staId));
512 // Case 1: Both previous and current point to the windowed payload
513 if (previous >= windowStart)
514 {
516 Min(windowEnd, current) - previous,
517 event->GetTxVector(),
518 staId);
519 NS_LOG_DEBUG("Both previous and current point to the windowed payload: mode="
520 << payloadMode << ", psr=" << psr);
521 }
522 // Case 2: previous is before windowed payload and current is in the windowed payload
523 else if (current >= windowStart)
524 {
526 Min(windowEnd, current) - windowStart,
527 event->GetTxVector(),
528 staId);
530 "previous is before windowed payload and current is in the windowed payload: mode="
531 << payloadMode << ", psr=" << psr);
532 }
533 noiseInterferenceW = j->second.GetPower() - powerW;
534 previous = j->first;
535 if (previous > windowEnd)
536 {
537 NS_LOG_DEBUG("Stop: new previous=" << previous
538 << " after time window end=" << windowEnd);
539 break;
540 }
541 }
542 double per = 1 - psr;
543 return per;
544}
545
546double
548 Ptr<const Event> event,
549 NiChangesPerBand* nis,
550 uint16_t channelWidth,
551 WifiSpectrumBand band,
552 PhyEntity::PhyHeaderSections phyHeaderSections) const
553{
554 NS_LOG_FUNCTION(this << band.first << band.second);
555 double psr = 1.0; /* Packet Success Rate */
556 auto niIt = nis->find(band)->second;
557 auto j = niIt.begin();
558
559 NS_ASSERT(!phyHeaderSections.empty());
560 Time stopLastSection = Seconds(0);
561 for (const auto& section : phyHeaderSections)
562 {
563 stopLastSection = Max(stopLastSection, section.second.first.second);
564 }
565
566 Time previous = j->first;
567 double noiseInterferenceW = m_firstPowerPerBand.find(band)->second;
568 double powerW = event->GetRxPowerW(band);
569 while (++j != niIt.end())
570 {
571 Time current = j->first;
572 NS_LOG_DEBUG("previous= " << previous << ", current=" << current);
573 NS_ASSERT(current >= previous);
574 double snr = CalculateSnr(powerW, noiseInterferenceW, channelWidth, 1);
575 for (const auto& section : phyHeaderSections)
576 {
577 Time start = section.second.first.first;
578 Time stop = section.second.first.second;
579
580 if (previous <= stop || current >= start)
581 {
582 Time duration = Min(stop, current) - Max(start, previous);
583 if (duration.IsStrictlyPositive())
584 {
585 psr *= CalculateChunkSuccessRate(snr,
586 duration,
587 section.second.second,
588 event->GetTxVector(),
589 section.first);
590 NS_LOG_DEBUG("Current NI change in "
591 << section.first << " [" << start << ", " << stop << "] for "
592 << duration.As(Time::NS) << ": mode=" << section.second.second
593 << ", psr=" << psr);
594 }
595 }
596 }
597 noiseInterferenceW = j->second.GetPower() - powerW;
598 previous = j->first;
599 if (previous > stopLastSection)
600 {
601 NS_LOG_DEBUG("Stop: new previous=" << previous << " after stop of last section="
602 << stopLastSection);
603 break;
604 }
605 }
606 return psr;
607}
608
609double
611 NiChangesPerBand* nis,
612 uint16_t channelWidth,
613 WifiSpectrumBand band,
614 WifiPpduField header) const
615{
616 NS_LOG_FUNCTION(this << band.first << band.second << header);
617 auto niIt = nis->find(band)->second;
618 auto phyEntity = WifiPhy::GetStaticPhyEntity(event->GetTxVector().GetModulationClass());
619
621 for (const auto& section :
622 phyEntity->GetPhyHeaderSections(event->GetTxVector(), niIt.begin()->first))
623 {
624 if (section.first == header)
625 {
626 sections[header] = section.second;
627 }
628 }
629
630 double psr = 1.0;
631 if (!sections.empty())
632 {
633 psr = CalculatePhyHeaderSectionPsr(event, nis, channelWidth, band, sections);
634 }
635 return 1 - psr;
636}
637
639InterferenceHelper::CalculatePayloadSnrPer(Ptr<Event> event,
640 uint16_t channelWidth,
641 WifiSpectrumBand band,
642 uint16_t staId,
643 std::pair<Time, Time> relativeMpduStartStop) const
644{
645 NS_LOG_FUNCTION(this << channelWidth << band.first << band.second << staId
646 << relativeMpduStartStop.first << relativeMpduStartStop.second);
648 double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
649 double snr = CalculateSnr(event->GetRxPowerW(band),
650 noiseInterferenceW,
651 channelWidth,
652 event->GetTxVector().GetNss(staId));
653
654 /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
655 * all SNIR changes in the SNIR vector.
656 */
657 double per = CalculatePayloadPer(event, channelWidth, &ni, band, staId, relativeMpduStartStop);
658
659 return PhyEntity::SnrPer(snr, per);
660}
661
662double
664 uint16_t channelWidth,
665 uint8_t nss,
666 WifiSpectrumBand band) const
667{
669 double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
670 double snr = CalculateSnr(event->GetRxPowerW(band), noiseInterferenceW, channelWidth, nss);
671 return snr;
672}
673
675InterferenceHelper::CalculatePhyHeaderSnrPer(Ptr<Event> event,
676 uint16_t channelWidth,
677 WifiSpectrumBand band,
678 WifiPpduField header) const
679{
680 NS_LOG_FUNCTION(this << band.first << band.second << header);
682 double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
683 double snr = CalculateSnr(event->GetRxPowerW(band), noiseInterferenceW, channelWidth, 1);
684
685 /* calculate the SNIR at the start of the PHY header and accumulate
686 * all SNIR changes in the SNIR vector.
687 */
688 double per = CalculatePhyHeaderPer(event, &ni, channelWidth, band, header);
689
690 return PhyEntity::SnrPer(snr, per);
691}
692
693void
695{
696 for (auto niIt = m_niChangesPerBand.begin(); niIt != m_niChangesPerBand.end(); ++niIt)
697 {
698 niIt->second.clear();
699 // Always have a zero power noise event in the list
700 AddNiChangeEvent(Time(0), NiChange(0.0, nullptr), niIt);
701 m_firstPowerPerBand.at(niIt->first) = 0.0;
702 }
703 m_rxing = false;
704}
705
706InterferenceHelper::NiChanges::iterator
707InterferenceHelper::GetNextPosition(Time moment, NiChangesPerBand::iterator niIt)
708{
709 return niIt->second.upper_bound(moment);
710}
711
712InterferenceHelper::NiChanges::iterator
713InterferenceHelper::GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt)
714{
715 auto it = GetNextPosition(moment, niIt);
716 // This is safe since there is always an NiChange at time 0,
717 // before moment.
718 --it;
719 return it;
720}
721
722InterferenceHelper::NiChanges::iterator
723InterferenceHelper::AddNiChangeEvent(Time moment, NiChange change, NiChangesPerBand::iterator niIt)
724{
725 return niIt->second.insert(GetNextPosition(moment, niIt), std::make_pair(moment, change));
726}
727
728void
730{
731 NS_LOG_FUNCTION(this);
732 m_rxing = true;
733}
734
735void
737{
738 NS_LOG_FUNCTION(this << endTime);
739 m_rxing = false;
740 // Update m_firstPowerPerBand for frame capture
741 for (auto niIt = m_niChangesPerBand.begin(); niIt != m_niChangesPerBand.end(); ++niIt)
742 {
743 NS_ASSERT(niIt->second.size() > 1);
744 auto it = GetPreviousPosition(endTime, niIt);
745 it--;
746 m_firstPowerPerBand.find(niIt->first)->second = it->second.GetPower();
747 }
748}
749
750} // namespace ns3
#define Max(a, b)
#define Min(a, b)
handles interference calculations
Time m_endTime
end time
WifiTxVector m_txVector
TXVECTOR.
Time m_startTime
start time
Ptr< const WifiPpdu > GetPpdu() const
Return the PPDU.
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.
Time GetEndTime() const
Return the end time of the signal.
Time GetDuration() const
Return the duration of the signal.
double GetRxPowerW() const
Return the total received power (W).
const WifiTxVector & GetTxVector() const
Return the TXVECTOR of the PPDU.
RxPowerWattPerChannelBand m_rxPowerW
received power in watts per band
const RxPowerWattPerChannelBand & GetRxPowerWPerBand() const
Return the received power (W) for all bands.
Time GetStartTime() const
Return the start 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() const
Return the power.
Ptr< Event > GetEvent() 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)
Ptr< ErrorRateModel > GetErrorRateModel() const
Return the error rate model.
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.
std::map< WifiSpectrumBand, NiChanges > NiChangesPerBand
Map of NiChanges per band.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
void DoDispose() override
Destructor implementation.
void RemoveBands()
Remove the frequency bands.
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.
void EraseEvents()
Erase all events.
Ptr< ErrorRateModel > m_errorRateModel
error rate model
void AppendEvent(Ptr< Event > event, bool isStartOfdmaRxing)
Append the given Event.
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.
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.
static TypeId GetTypeId()
Get the type ID.
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
A base class which provides memory management and object aggregation.
Definition: object.h:89
std::map< WifiPpduField, PhyHeaderChunkInfo > PhyHeaderSections
A map of PhyHeaderChunkInfo elements per PPDU field.
Definition: phy-entity.h:327
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Control the scheduling of simulation events.
Definition: simulator.h:68
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:402
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:350
@ NS
nanosecond
Definition: nstime.h:119
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
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:50
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:695
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1473
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() 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:66
#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:86
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
WifiPpduField
The type of PPDU field (grouped for convenience)
@ WIFI_PPDU_TYPE_DL_MU
@ 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:52
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:129
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:78
@ WIFI_MAC_QOSDATA
STL namespace.
A struct for both SNR and PER.
Definition: phy-entity.h:148
double snr
SNR in linear scale.
Definition: phy-entity.h:149