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#include "ns3/wifi-phy-operating-channel.h"
32
33#include <algorithm>
34#include <numeric>
35
36namespace ns3
37{
38
39NS_LOG_COMPONENT_DEFINE("InterferenceHelper");
40
41NS_OBJECT_ENSURE_REGISTERED(InterferenceHelper);
42
43/****************************************************************
44 * PHY event class
45 ****************************************************************/
46
48 const WifiTxVector& txVector,
49 Time duration,
51 : m_ppdu(ppdu),
52 m_txVector(txVector),
53 m_startTime(Simulator::Now()),
54 m_endTime(m_startTime + duration),
55 m_rxPowerW(std::move(rxPower))
56{
57}
58
60{
61 m_ppdu = nullptr;
62 m_rxPowerW.clear();
63}
64
67{
68 return m_ppdu;
69}
70
71Time
73{
74 return m_startTime;
75}
76
77Time
79{
80 return m_endTime;
81}
82
83Time
85{
86 return m_endTime - m_startTime;
87}
88
89double
91{
92 NS_ASSERT(!m_rxPowerW.empty());
93 // The total RX power corresponds to the maximum over all the bands
94 auto it =
95 std::max_element(m_rxPowerW.cbegin(),
96 m_rxPowerW.cend(),
97 [](const auto& p1, const auto& p2) { return p1.second < p2.second; });
98 return it->second;
99}
100
101double
103{
104 const auto it = m_rxPowerW.find(band);
105 NS_ASSERT(it != m_rxPowerW.cend());
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 for (auto it : m_niChanges)
212 {
213 it.second.clear();
214 }
215 m_niChanges.clear();
216 m_firstPowers.clear();
217 m_errorRateModel = nullptr;
218}
219
222 const WifiTxVector& txVector,
223 Time duration,
225 bool isStartOfdmaRxing)
226{
227 Ptr<Event> event = Create<Event>(ppdu, txVector, duration, std::move(rxPowerW));
228 AppendEvent(event, isStartOfdmaRxing);
229 return event;
230}
231
232void
234{
235 // Parameters other than duration and rxPowerW are unused for this type
236 // of signal, so we provide dummy versions
237 WifiMacHeader hdr;
239 hdr.SetQosTid(0);
240 Ptr<WifiPpdu> fakePpdu = Create<WifiPpdu>(Create<WifiPsdu>(Create<Packet>(0), hdr),
241 WifiTxVector(),
243 Add(fakePpdu, WifiTxVector(), duration, rxPowerW);
244}
245
246bool
248{
249 return !m_niChanges.empty();
250}
251
252bool
254{
255 return (m_niChanges.count(band) > 0);
256}
257
258void
260{
261 NS_LOG_FUNCTION(this << band);
262 NS_ASSERT(m_niChanges.count(band) == 0);
263 NS_ASSERT(m_firstPowers.count(band) == 0);
264 NiChanges niChanges;
265 auto result = m_niChanges.insert({band, niChanges});
266 NS_ASSERT(result.second);
267 // Always have a zero power noise event in the list
268 AddNiChangeEvent(Time(0), NiChange(0.0, nullptr), result.first);
269 m_firstPowers.insert({band, 0.0});
270}
271
272void
273InterferenceHelper::UpdateBands(const std::vector<WifiSpectrumBandInfo>& bands,
274 const FrequencyRange& freqRange)
275{
276 NS_LOG_FUNCTION(this << freqRange);
277 for (auto it = m_niChanges.begin(); it != m_niChanges.end();)
278 {
279 if (!IsBandInFrequencyRange(it->first, freqRange))
280 {
281 it++;
282 continue;
283 }
284 const auto frequencies = it->first.frequencies;
285 const auto found =
286 std::find_if(bands.cbegin(), bands.cend(), [frequencies](const auto& item) {
287 return frequencies == item.frequencies;
288 }) != std::end(bands);
289 if (!found)
290 {
291 // band does not belong to the new bands, erase it
292 m_firstPowers.erase(it->first);
293 it->second.clear();
294 it = m_niChanges.erase(it);
295 }
296 else
297 {
298 it++;
299 }
300 }
301 for (const auto& band : bands)
302 {
303 if (!HasBand(band))
304 {
305 // this is a new band, add it
306 AddBand(band);
307 }
308 }
309}
310
311void
313{
314 m_noiseFigure = value;
315}
316
317void
319{
320 m_errorRateModel = rate;
321}
322
325{
326 return m_errorRateModel;
327}
328
329void
331{
332 m_numRxAntennas = rx;
333}
334
335Time
337{
338 NS_LOG_FUNCTION(this << energyW << band);
339 Time now = Simulator::Now();
340 auto niIt = m_niChanges.find(band);
341 NS_ABORT_IF(niIt == m_niChanges.end());
342 auto i = GetPreviousPosition(now, niIt);
343 Time end = i->first;
344 for (; i != niIt->second.end(); ++i)
345 {
346 double noiseInterferenceW = i->second.GetPower();
347 end = i->first;
348 if (noiseInterferenceW < energyW)
349 {
350 break;
351 }
352 }
353 return end > now ? end - now : MicroSeconds(0);
354}
355
356void
357InterferenceHelper::AppendEvent(Ptr<Event> event, bool isStartOfdmaRxing)
358{
359 NS_LOG_FUNCTION(this << event << isStartOfdmaRxing);
360 for (const auto& [band, power] : event->GetRxPowerWPerBand())
361 {
362 auto niIt = m_niChanges.find(band);
363 NS_ABORT_IF(niIt == m_niChanges.end());
364 double previousPowerStart = 0;
365 double previousPowerEnd = 0;
366 auto previousPowerPosition = GetPreviousPosition(event->GetStartTime(), niIt);
367 previousPowerStart = previousPowerPosition->second.GetPower();
368 previousPowerEnd = GetPreviousPosition(event->GetEndTime(), niIt)->second.GetPower();
369 if (!m_rxing)
370 {
371 m_firstPowers.find(band)->second = previousPowerStart;
372 // Always leave the first zero power noise event in the list
373 niIt->second.erase(++(niIt->second.begin()), ++previousPowerPosition);
374 }
375 else if (isStartOfdmaRxing)
376 {
377 // When the first UL-OFDMA payload is received, we need to set m_firstPowers
378 // so that it takes into account interferences that arrived between the start of the
379 // UL MU transmission and the start of UL-OFDMA payload.
380 m_firstPowers.find(band)->second = previousPowerStart;
381 }
382 auto first =
383 AddNiChangeEvent(event->GetStartTime(), NiChange(previousPowerStart, event), niIt);
384 auto last = AddNiChangeEvent(event->GetEndTime(), NiChange(previousPowerEnd, event), niIt);
385 for (auto i = first; i != last; ++i)
386 {
387 i->second.AddPower(power);
388 }
389 }
390}
391
392void
394{
395 NS_LOG_FUNCTION(this << event);
396 // This is called for UL MU events, in order to scale power as long as UL MU PPDUs arrive
397 for (const auto& [band, power] : rxPower)
398 {
399 auto niIt = m_niChanges.find(band);
400 NS_ABORT_IF(niIt == m_niChanges.end());
401 auto first = GetPreviousPosition(event->GetStartTime(), niIt);
402 auto last = GetPreviousPosition(event->GetEndTime(), niIt);
403 for (auto i = first; i != last; ++i)
404 {
405 i->second.AddPower(power);
406 }
407 }
408 event->UpdateRxPowerW(rxPower);
409}
410
411double
413 double noiseInterference,
414 uint16_t channelWidth,
415 uint8_t nss) const
416{
417 NS_LOG_FUNCTION(this << signal << noiseInterference << channelWidth << +nss);
418 // thermal noise at 290K in J/s = W
419 static const double BOLTZMANN = 1.3803e-23;
420 // Nt is the power of thermal noise in W
421 double Nt = BOLTZMANN * 290 * channelWidth * 1e6;
422 // receiver noise Floor (W) which accounts for thermal noise and non-idealities of the receiver
423 double noiseFloor = m_noiseFigure * Nt;
424 double noise = noiseFloor + noiseInterference;
425 double snr = signal / noise; // linear scale
426 NS_LOG_DEBUG("bandwidth(MHz)=" << channelWidth << ", signal(W)= " << signal << ", noise(W)="
427 << noiseFloor << ", interference(W)=" << noiseInterference
428 << ", snr=" << RatioToDb(snr) << "dB");
429 if (m_errorRateModel->IsAwgn())
430 {
431 double gain = 1;
432 if (m_numRxAntennas > nss)
433 {
434 gain = static_cast<double>(m_numRxAntennas) /
435 nss; // compute gain offered by diversity for AWGN
436 }
437 NS_LOG_DEBUG("SNR improvement thanks to diversity: " << 10 * std::log10(gain) << "dB");
438 snr *= gain;
439 }
440 return snr;
441}
442
443double
445 NiChangesPerBand* nis,
446 const WifiSpectrumBandInfo& band) const
447{
448 NS_LOG_FUNCTION(this << band);
449 auto firstPower_it = m_firstPowers.find(band);
450 NS_ABORT_IF(firstPower_it == m_firstPowers.end());
451 double noiseInterferenceW = firstPower_it->second;
452 auto niIt = m_niChanges.find(band);
453 NS_ABORT_IF(niIt == m_niChanges.end());
454 auto it = niIt->second.find(event->GetStartTime());
455 for (; it != niIt->second.end() && it->first < Simulator::Now(); ++it)
456 {
457 noiseInterferenceW = it->second.GetPower() - event->GetRxPowerW(band);
458 }
459 it = niIt->second.find(event->GetStartTime());
460 NS_ABORT_IF(it == niIt->second.end());
461 for (; it != niIt->second.end() && it->second.GetEvent() != event; ++it)
462 {
463 ;
464 }
465 NiChanges ni;
466 ni.emplace(event->GetStartTime(), NiChange(0, event));
467 while (++it != niIt->second.end() && it->second.GetEvent() != event)
468 {
469 ni.insert(*it);
470 }
471 ni.emplace(event->GetEndTime(), NiChange(0, event));
472 nis->insert({band, ni});
473 NS_ASSERT_MSG(noiseInterferenceW >= 0,
474 "CalculateNoiseInterferenceW returns negative value " << noiseInterferenceW);
475 return noiseInterferenceW;
476}
477
478double
480 Time duration,
481 WifiMode mode,
482 const WifiTxVector& txVector,
483 WifiPpduField field) const
484{
485 if (duration.IsZero())
486 {
487 return 1.0;
488 }
489 uint64_t rate = mode.GetDataRate(txVector.GetChannelWidth());
490 uint64_t nbits = static_cast<uint64_t>(rate * duration.GetSeconds());
491 double csr =
492 m_errorRateModel->GetChunkSuccessRate(mode, txVector, snir, nbits, m_numRxAntennas, field);
493 return csr;
494}
495
496double
498 Time duration,
499 const WifiTxVector& txVector,
500 uint16_t staId) const
501{
502 if (duration.IsZero())
503 {
504 return 1.0;
505 }
506 WifiMode mode = txVector.GetMode(staId);
507 uint64_t rate = mode.GetDataRate(txVector, staId);
508 uint64_t nbits = static_cast<uint64_t>(rate * duration.GetSeconds());
509 nbits /= txVector.GetNss(staId); // divide effective number of bits by NSS to achieve same chunk
510 // error rate as SISO for AWGN
511 double csr = m_errorRateModel->GetChunkSuccessRate(mode,
512 txVector,
513 snir,
514 nbits,
517 staId);
518 return csr;
519}
520
521double
523 uint16_t channelWidth,
524 NiChangesPerBand* nis,
525 const WifiSpectrumBandInfo& band,
526 uint16_t staId,
527 std::pair<Time, Time> window) const
528{
529 NS_LOG_FUNCTION(this << channelWidth << band << staId << window.first << window.second);
530 double psr = 1.0; /* Packet Success Rate */
531 const auto& niIt = nis->find(band)->second;
532 auto j = niIt.cbegin();
533 Time previous = j->first;
534 WifiMode payloadMode = event->GetTxVector().GetMode(staId);
535 Time phyPayloadStart = j->first;
536 if (event->GetPpdu()->GetType() != WIFI_PPDU_TYPE_UL_MU &&
537 event->GetPpdu()->GetType() !=
538 WIFI_PPDU_TYPE_DL_MU) // j->first corresponds to the start of the OFDMA payload
539 {
540 phyPayloadStart =
541 j->first + WifiPhy::CalculatePhyPreambleAndHeaderDuration(event->GetTxVector());
542 }
543 Time windowStart = phyPayloadStart + window.first;
544 Time windowEnd = phyPayloadStart + window.second;
545 NS_ABORT_IF(m_firstPowers.count(band) == 0);
546 double noiseInterferenceW = m_firstPowers.at(band);
547 double powerW = event->GetRxPowerW(band);
548 while (++j != niIt.cend())
549 {
550 Time current = j->first;
551 NS_LOG_DEBUG("previous= " << previous << ", current=" << current);
552 NS_ASSERT(current >= previous);
553 double snr = CalculateSnr(powerW,
554 noiseInterferenceW,
555 channelWidth,
556 event->GetTxVector().GetNss(staId));
557 // Case 1: Both previous and current point to the windowed payload
558 if (previous >= windowStart)
559 {
561 Min(windowEnd, current) - previous,
562 event->GetTxVector(),
563 staId);
564 NS_LOG_DEBUG("Both previous and current point to the windowed payload: mode="
565 << payloadMode << ", psr=" << psr);
566 }
567 // Case 2: previous is before windowed payload and current is in the windowed payload
568 else if (current >= windowStart)
569 {
571 Min(windowEnd, current) - windowStart,
572 event->GetTxVector(),
573 staId);
575 "previous is before windowed payload and current is in the windowed payload: mode="
576 << payloadMode << ", psr=" << psr);
577 }
578 noiseInterferenceW = j->second.GetPower() - powerW;
579 previous = j->first;
580 if (previous > windowEnd)
581 {
582 NS_LOG_DEBUG("Stop: new previous=" << previous
583 << " after time window end=" << windowEnd);
584 break;
585 }
586 }
587 double per = 1 - psr;
588 return per;
589}
590
591double
593 Ptr<const Event> event,
594 NiChangesPerBand* nis,
595 uint16_t channelWidth,
596 const WifiSpectrumBandInfo& band,
597 PhyEntity::PhyHeaderSections phyHeaderSections) const
598{
599 NS_LOG_FUNCTION(this << band);
600 double psr = 1.0; /* Packet Success Rate */
601 auto niIt = nis->find(band)->second;
602 auto j = niIt.begin();
603
604 NS_ASSERT(!phyHeaderSections.empty());
605 Time stopLastSection = Seconds(0);
606 for (const auto& section : phyHeaderSections)
607 {
608 stopLastSection = Max(stopLastSection, section.second.first.second);
609 }
610
611 Time previous = j->first;
612 NS_ABORT_IF(m_firstPowers.count(band) == 0);
613 double noiseInterferenceW = m_firstPowers.at(band);
614 double powerW = event->GetRxPowerW(band);
615 while (++j != niIt.end())
616 {
617 Time current = j->first;
618 NS_LOG_DEBUG("previous= " << previous << ", current=" << current);
619 NS_ASSERT(current >= previous);
620 double snr = CalculateSnr(powerW, noiseInterferenceW, channelWidth, 1);
621 for (const auto& section : phyHeaderSections)
622 {
623 Time start = section.second.first.first;
624 Time stop = section.second.first.second;
625
626 if (previous <= stop || current >= start)
627 {
628 Time duration = Min(stop, current) - Max(start, previous);
629 if (duration.IsStrictlyPositive())
630 {
631 psr *= CalculateChunkSuccessRate(snr,
632 duration,
633 section.second.second,
634 event->GetTxVector(),
635 section.first);
636 NS_LOG_DEBUG("Current NI change in "
637 << section.first << " [" << start << ", " << stop << "] for "
638 << duration.As(Time::NS) << ": mode=" << section.second.second
639 << ", psr=" << psr);
640 }
641 }
642 }
643 noiseInterferenceW = j->second.GetPower() - powerW;
644 previous = j->first;
645 if (previous > stopLastSection)
646 {
647 NS_LOG_DEBUG("Stop: new previous=" << previous << " after stop of last section="
648 << stopLastSection);
649 break;
650 }
651 }
652 return psr;
653}
654
655double
657 NiChangesPerBand* nis,
658 uint16_t channelWidth,
659 const WifiSpectrumBandInfo& band,
660 WifiPpduField header) const
661{
662 NS_LOG_FUNCTION(this << band << header);
663 auto niIt = nis->find(band)->second;
664 auto phyEntity = WifiPhy::GetStaticPhyEntity(event->GetTxVector().GetModulationClass());
665
667 for (const auto& section :
668 phyEntity->GetPhyHeaderSections(event->GetTxVector(), niIt.begin()->first))
669 {
670 if (section.first == header)
671 {
672 sections[header] = section.second;
673 }
674 }
675
676 double psr = 1.0;
677 if (!sections.empty())
678 {
679 psr = CalculatePhyHeaderSectionPsr(event, nis, channelWidth, band, sections);
680 }
681 return 1 - psr;
682}
683
686 uint16_t channelWidth,
687 const WifiSpectrumBandInfo& band,
688 uint16_t staId,
689 std::pair<Time, Time> relativeMpduStartStop) const
690{
691 NS_LOG_FUNCTION(this << channelWidth << band << staId << relativeMpduStartStop.first
692 << relativeMpduStartStop.second);
694 double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
695 double snr = CalculateSnr(event->GetRxPowerW(band),
696 noiseInterferenceW,
697 channelWidth,
698 event->GetTxVector().GetNss(staId));
699
700 /* calculate the SNIR at the start of the MPDU (located through windowing) and accumulate
701 * all SNIR changes in the SNIR vector.
702 */
703 double per = CalculatePayloadPer(event, channelWidth, &ni, band, staId, relativeMpduStartStop);
704
705 return PhyEntity::SnrPer(snr, per);
706}
707
708double
710 uint16_t channelWidth,
711 uint8_t nss,
712 const WifiSpectrumBandInfo& band) const
713{
715 double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
716 double snr = CalculateSnr(event->GetRxPowerW(band), noiseInterferenceW, channelWidth, nss);
717 return snr;
718}
719
722 uint16_t channelWidth,
723 const WifiSpectrumBandInfo& band,
724 WifiPpduField header) const
725{
726 NS_LOG_FUNCTION(this << band << header);
728 double noiseInterferenceW = CalculateNoiseInterferenceW(event, &ni, band);
729 double snr = CalculateSnr(event->GetRxPowerW(band), noiseInterferenceW, channelWidth, 1);
730
731 /* calculate the SNIR at the start of the PHY header and accumulate
732 * all SNIR changes in the SNIR vector.
733 */
734 double per = CalculatePhyHeaderPer(event, &ni, channelWidth, band, header);
735
736 return PhyEntity::SnrPer(snr, per);
737}
738
739InterferenceHelper::NiChanges::iterator
740InterferenceHelper::GetNextPosition(Time moment, NiChangesPerBand::iterator niIt)
741{
742 return niIt->second.upper_bound(moment);
743}
744
745InterferenceHelper::NiChanges::iterator
746InterferenceHelper::GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt)
747{
748 auto it = GetNextPosition(moment, niIt);
749 // This is safe since there is always an NiChange at time 0,
750 // before moment.
751 --it;
752 return it;
753}
754
755InterferenceHelper::NiChanges::iterator
756InterferenceHelper::AddNiChangeEvent(Time moment, NiChange change, NiChangesPerBand::iterator niIt)
757{
758 return niIt->second.insert(GetNextPosition(moment, niIt), std::make_pair(moment, change));
759}
760
761void
763{
764 NS_LOG_FUNCTION(this);
765 m_rxing = true;
766}
767
768void
770{
771 NS_LOG_FUNCTION(this << endTime << freqRange);
772 m_rxing = false;
773 // Update m_firstPowers for frame capture
774 for (auto niIt = m_niChanges.begin(); niIt != m_niChanges.end(); ++niIt)
775 {
776 if (!IsBandInFrequencyRange(niIt->first, freqRange))
777 {
778 continue;
779 }
780 NS_ASSERT(niIt->second.size() > 1);
781 auto it = GetPreviousPosition(endTime, niIt);
782 it--;
783 m_firstPowers.find(niIt->first)->second = it->second.GetPower();
784 }
785}
786
787bool
789 const FrequencyRange& freqRange) const
790{
791 return ((band.frequencies.second > (freqRange.minFrequency * 1e6)) &&
792 (band.frequencies.first < (freqRange.maxFrequency * 1e6)));
793}
794
795} // 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< WifiSpectrumBandInfo, NiChanges > NiChangesPerBand
Map of NiChanges per band.
uint8_t m_numRxAntennas
the number of RX antennas in the corresponding receiver
bool IsBandInFrequencyRange(const WifiSpectrumBandInfo &band, const FrequencyRange &freqRange) const
Check whether a given band belongs to a given frequency range.
void DoDispose() override
Destructor implementation.
std::multimap< Time, NiChange > NiChanges
typedef for a multimap of NiChange
NiChangesPerBand m_niChanges
NI Changes for each band.
void UpdateBands(const std::vector< WifiSpectrumBandInfo > &bands, const FrequencyRange &freqRange)
Update the frequency bands that belongs to a given frequency range when the spectrum model is changed...
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
bool HasBands() const
Check whether bands are already tracked by this interference helper.
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.
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.
FirstPowerPerBand m_firstPowers
first power of each band in watts
Time GetEnergyDuration(double energyW, const WifiSpectrumBandInfo &band)
double CalculateNoiseInterferenceW(Ptr< Event > event, NiChangesPerBand *nis, const WifiSpectrumBandInfo &band) const
Calculate noise and interference power in W.
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, const WifiSpectrumBandInfo &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...
bool HasBand(const WifiSpectrumBandInfo &band) const
Check whether a given band is tracked by this interference helper.
void AddBand(const WifiSpectrumBandInfo &band)
Add a frequency band.
double CalculatePhyHeaderPer(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, const WifiSpectrumBandInfo &band, WifiPpduField header) const
Calculate the error rate of the PHY header.
NiChanges::iterator GetPreviousPosition(Time moment, NiChangesPerBand::iterator niIt)
Returns an iterator to the last NiChange that is before than moment.
double CalculateSnr(Ptr< Event > event, uint16_t channelWidth, uint8_t nss, const WifiSpectrumBandInfo &band) const
Calculate the SNIR for the event (starting from now until the event end).
PhyEntity::SnrPer CalculatePhyHeaderSnrPer(Ptr< Event > event, uint16_t channelWidth, const WifiSpectrumBandInfo &band, WifiPpduField header) const
Calculate the SNIR at the start of the PHY header and accumulate all SNIR changes in the SNIR vector.
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 NotifyRxEnd(Time endTime, const FrequencyRange &freqRange)
Notify that RX has ended.
double CalculatePhyHeaderSectionPsr(Ptr< const Event > event, NiChangesPerBand *nis, uint16_t channelWidth, const WifiSpectrumBandInfo &band, PhyEntity::PhyHeaderSections phyHeaderSections) const
Calculate the success rate of the PHY header sections for the provided event.
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
PhyEntity::SnrPer CalculatePayloadSnrPer(Ptr< Event > event, uint16_t channelWidth, const WifiSpectrumBandInfo &band, uint16_t staId, std::pair< Time, Time > relativeMpduStartStop) const
Calculate the SNIR at the start of the payload and accumulate all SNIR changes in the SNIR vector for...
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
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:51
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:704
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1489
Class that keeps track of all information about the current PHY operating channel.
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_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#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::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
@ WIFI_MAC_QOSDATA
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:78
STL namespace.
Struct defining a frequency range between minFrequency (MHz) and maxFrequency (MHz).
uint16_t maxFrequency
the maximum frequency in MHz
uint16_t minFrequency
the minimum frequency in MHz
A struct for both SNR and PER.
Definition: phy-entity.h:148
WifiSpectrumBandInfo structure containing info about a spectrum band.
WifiSpectrumBandFrequencies frequencies
the start and stop frequencies of the band