A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
spectrum-wifi-phy.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 * Ghada Badawy <gbadawy@gmail.com>
19 * Sébastien Deronne <sebastien.deronne@gmail.com>
20 *
21 * Ported from yans-wifi-phy.cc by several contributors starting
22 * with Nicola Baldo and Dean Armstrong
23 */
24
25#include "spectrum-wifi-phy.h"
26
27#include "interference-helper.h"
28#include "wifi-net-device.h"
29#include "wifi-psdu.h"
32#include "wifi-utils.h"
33
34#include "ns3/boolean.h"
35#include "ns3/double.h"
36#include "ns3/he-phy.h"
37#include "ns3/log.h"
38#include "ns3/node.h"
39#include "ns3/simulator.h"
40#include "ns3/spectrum-channel.h"
41
42#include <algorithm>
43
44#undef NS_LOG_APPEND_CONTEXT
45#define NS_LOG_APPEND_CONTEXT WIFI_PHY_NS_LOG_APPEND_CONTEXT(Ptr(this))
46
47namespace ns3
48{
49
50NS_LOG_COMPONENT_DEFINE("SpectrumWifiPhy");
51
52NS_OBJECT_ENSURE_REGISTERED(SpectrumWifiPhy);
53
54TypeId
56{
57 static TypeId tid =
58 TypeId("ns3::SpectrumWifiPhy")
60 .SetGroupName("Wifi")
61 .AddConstructor<SpectrumWifiPhy>()
62 .AddAttribute("DisableWifiReception",
63 "Prevent Wi-Fi frame sync from ever happening",
64 BooleanValue(false),
67 .AddAttribute(
68 "TrackSignalsFromInactiveInterfaces",
69 "Enable or disable tracking signals coming from inactive spectrum PHY interfaces",
70 BooleanValue(true),
73 .AddAttribute(
74 "TxMaskInnerBandMinimumRejection",
75 "Minimum rejection (dBr) for the inner band of the transmit spectrum mask",
76 DoubleValue(-20.0),
78 MakeDoubleChecker<double>())
79 .AddAttribute(
80 "TxMaskOuterBandMinimumRejection",
81 "Minimum rejection (dBr) for the outer band of the transmit spectrum mask",
82 DoubleValue(-28.0),
84 MakeDoubleChecker<double>())
85 .AddAttribute(
86 "TxMaskOuterBandMaximumRejection",
87 "Maximum rejection (dBr) for the outer band of the transmit spectrum mask",
88 DoubleValue(-40.0),
90 MakeDoubleChecker<double>())
91 .AddTraceSource(
92 "SignalArrival",
93 "Trace start of all signal arrivals, including weak and foreign signals",
95 "ns3::SpectrumWifiPhy::SignalArrivalCallback");
96 return tid;
97}
98
100 : m_spectrumPhyInterfaces{},
101 m_currentSpectrumPhyInterface{nullptr}
102{
103 NS_LOG_FUNCTION(this);
104}
105
107{
108 NS_LOG_FUNCTION(this);
109}
110
111void
113{
114 NS_LOG_FUNCTION(this);
117 m_antenna = nullptr;
120}
121
122void
124{
125 NS_LOG_FUNCTION(this);
127}
128
131{
132 NS_LOG_FUNCTION(this << spectrumPhyInterface);
133 WifiSpectrumBands bands{};
134 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
135 if (channelWidth < 20)
136 {
137 bands.push_back(GetBandForInterface(spectrumPhyInterface, channelWidth));
138 }
139 else
140 {
141 for (uint16_t bw = channelWidth; bw >= 20; bw = bw / 2)
142 {
143 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
144 {
145 bands.push_back(GetBandForInterface(spectrumPhyInterface, bw, i));
146 }
147 }
148 }
149 return bands;
150}
151
154 uint16_t guardBandwidth)
155{
156 HeRuBands heRuBands{};
157 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
158 for (uint16_t bw = channelWidth; bw >= 20; bw = bw / 2)
159 {
160 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
161 {
162 for (uint32_t type = 0; type < 7; type++)
163 {
164 auto ruType = static_cast<HeRu::RuType>(type);
165 std::size_t nRus = HeRu::GetNRus(bw, ruType);
166 for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++)
167 {
168 HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup(bw, ruType, phyIndex);
169 HeRu::SubcarrierRange subcarrierRange =
170 std::make_pair(group.front().first, group.back().second);
171 const auto bandIndices = HePhy::ConvertHeRuSubcarriers(bw,
172 guardBandwidth,
174 subcarrierRange,
175 i);
176 const auto bandFrequencies =
177 ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, bandIndices);
178 WifiSpectrumBandInfo band = {bandIndices, bandFrequencies};
179 std::size_t index =
180 (bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex);
181 const auto p20Index = GetOperatingChannel().GetPrimaryChannelIndex(20);
182 bool primary80IsLower80 = (p20Index < bw / 40);
183 bool primary80 = (bw < 160 || ruType == HeRu::RU_2x996_TONE ||
184 (primary80IsLower80 && phyIndex <= nRus / 2) ||
185 (!primary80IsLower80 && phyIndex > nRus / 2));
186 HeRu::RuSpec ru(ruType, index, primary80);
187 NS_ABORT_IF(ru.GetPhyIndex(bw, p20Index) != phyIndex);
188 heRuBands.insert({band, ru});
189 }
190 }
191 }
192 }
193 return heRuBands;
194}
195
196void
198{
199 NS_LOG_FUNCTION(this << spectrumPhyInterface);
200 auto&& bands = ComputeBands(spectrumPhyInterface);
201 WifiSpectrumBands allBands{bands};
203 {
204 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
205 auto&& heRuBands = GetHeRuBands(spectrumPhyInterface, GetGuardBandwidth(channelWidth));
206 for (const auto& bandRuPair : heRuBands)
207 {
208 allBands.push_back(bandRuPair.first);
209 }
210 spectrumPhyInterface->SetHeRuBands(std::move(heRuBands));
211 }
212
213 spectrumPhyInterface->SetBands(std::move(bands));
214
215 if (m_interference->HasBands())
216 {
217 m_interference->UpdateBands(allBands, spectrumPhyInterface->GetFrequencyRange());
218 }
219 else
220 {
221 for (const auto& band : allBands)
222 {
223 m_interference->AddBand(band);
224 }
225 }
226}
227
230{
232 return m_currentSpectrumPhyInterface->GetChannel();
233}
234
235void
237{
238 NS_LOG_FUNCTION(this << channel << freqRange);
239
240 const auto foundOverlappingChannel =
241 std::any_of(m_spectrumPhyInterfaces.cbegin(),
243 [freqRange, channel](const auto& item) {
244 const auto spectrumRange = item.first;
245 const auto noOverlap =
246 ((freqRange.minFrequency >= spectrumRange.maxFrequency) ||
247 (freqRange.maxFrequency <= spectrumRange.minFrequency));
248 return (!noOverlap);
249 });
250 NS_ABORT_MSG_IF(foundOverlappingChannel,
251 "Added a wifi spectrum channel that overlaps with another existing wifi "
252 "spectrum channel");
253
254 auto wifiSpectrumPhyInterface = CreateObject<WifiSpectrumPhyInterface>(freqRange);
255 wifiSpectrumPhyInterface->SetSpectrumWifiPhy(this);
256 wifiSpectrumPhyInterface->SetChannel(channel);
257 if (GetDevice())
258 {
259 wifiSpectrumPhyInterface->SetDevice(GetDevice());
260 }
261 m_spectrumPhyInterfaces.emplace(freqRange, wifiSpectrumPhyInterface);
262}
263
264void
266 uint16_t centerFrequency,
267 uint16_t channelWidth)
268{
269 NS_LOG_FUNCTION(this << spectrumPhyInterface << centerFrequency << channelWidth);
270
271 // We have to reset the spectrum model because we changed RF channel. Consequently,
272 // we also have to add the spectrum interface to the spectrum channel again because
273 // MultiModelSpectrumChannel keeps spectrum interfaces in a map indexed by the RX
274 // spectrum model UID (which has changed after channel switching).
275 // Both SingleModelSpectrumChannel and MultiModelSpectrumChannel ensure not to keep
276 // duplicated spectrum interfaces (the latter removes the spectrum interface and adds
277 // it again in the entry associated with the new RX spectrum model UID)
278
279 // Replace existing spectrum model with new one
280 spectrumPhyInterface->SetRxSpectrumModel(centerFrequency,
281 channelWidth,
283 GetGuardBandwidth(channelWidth));
284
285 spectrumPhyInterface->GetChannel()->AddRx(spectrumPhyInterface);
286
287 UpdateInterferenceHelperBands(spectrumPhyInterface);
288}
289
290void
292{
293 NS_LOG_FUNCTION(this);
294 const auto frequencyBefore = GetOperatingChannel().IsSet() ? GetFrequency() : 0;
295 const auto widthBefore = GetOperatingChannel().IsSet() ? GetChannelWidth() : 0;
297 const auto frequencyAfter = GetFrequency();
298 const auto widthAfter = GetChannelWidth();
299 if ((frequencyBefore == frequencyAfter) && (widthBefore == widthAfter))
300 {
301 NS_LOG_DEBUG("Same RF channel as before, do nothing");
302 if (IsInitialized())
303 {
304 SwitchMaybeToCcaBusy(nullptr);
305 }
306 return;
307 }
308
309 auto newSpectrumPhyInterface = GetInterfaceCoveringChannelBand(frequencyAfter, widthAfter);
310 const auto interfaceChanged = (newSpectrumPhyInterface != m_currentSpectrumPhyInterface);
311
312 NS_ABORT_MSG_IF(!newSpectrumPhyInterface,
313 "No spectrum channel covers frequency range ["
314 << frequencyAfter - (widthAfter / 2) << " MHz - "
315 << frequencyAfter + (widthAfter / 2) << " MHz]");
316
317 if (interfaceChanged)
318 {
319 NS_LOG_DEBUG("Switch to existing RF interface with frequency/width pair of ("
320 << frequencyAfter << ", " << widthAfter << ")");
322 {
324 }
325 }
326
327 m_currentSpectrumPhyInterface = newSpectrumPhyInterface;
328
329 auto reset = true;
330 if (m_currentSpectrumPhyInterface->GetCenterFrequency() == frequencyAfter)
331 {
332 // Center frequency has not changed for that interface, hence we do not need to
333 // reset the spectrum model nor update any band stored in the interference helper
335 {
336 // If we are not tracking signals from inactive interface,
337 // this means the spectrum interface has been disconnected
338 // from the spectrum channel and has to be connected back
340 }
341 reset = false;
342 }
343
344 if (reset)
345 {
346 ResetSpectrumModel(m_currentSpectrumPhyInterface, frequencyAfter, widthAfter);
347 }
348
349 if (IsInitialized())
350 {
351 SwitchMaybeToCcaBusy(nullptr);
352 }
353
355}
356
357void
359{
361 {
363 }
364}
365
366void
367SpectrumWifiPhy::ConfigureInterface(uint16_t frequency, uint16_t width)
368{
369 NS_LOG_FUNCTION(this << frequency << width);
370
372 {
373 NS_LOG_DEBUG("Tracking of signals on inactive interfaces is not enabled");
374 return;
375 }
376
377 auto spectrumPhyInterface = GetInterfaceCoveringChannelBand(frequency, width);
378
379 NS_ABORT_MSG_IF(!spectrumPhyInterface,
380 "No spectrum channel covers frequency range ["
381 << frequency - (width / 2) << " MHz - " << frequency + (width / 2)
382 << " MHz]");
383
384 NS_ABORT_MSG_IF(spectrumPhyInterface == m_currentSpectrumPhyInterface,
385 "This method should not be called for the current interface");
386
387 if ((frequency == spectrumPhyInterface->GetCenterFrequency()) &&
388 (width == spectrumPhyInterface->GetChannelWidth()))
389 {
390 NS_LOG_DEBUG("Same RF channel as before on that interface, do nothing");
391 return;
392 }
393
394 ResetSpectrumModel(spectrumPhyInterface, frequency, width);
395}
396
397bool
399{
400 return GetLatestPhyEntity()->CanStartRx(ppdu);
401}
402
403void
406{
407 NS_LOG_FUNCTION(this << rxParams << interface);
408 Time rxDuration = rxParams->duration;
409 Ptr<SpectrumValue> receivedSignalPsd = rxParams->psd;
410 if (interface)
411 {
412 NS_ASSERT_MSG(receivedSignalPsd->GetValuesN() ==
413 interface->GetRxSpectrumModel()->GetNumBands(),
414 "Use multi model spectrum channel if PHYs have different spectrum models!");
415 }
416 NS_LOG_DEBUG("Received signal with PSD " << *receivedSignalPsd << " and duration "
417 << rxDuration.As(Time::NS));
418 uint32_t senderNodeId = 0;
419 if (rxParams->txPhy)
420 {
421 senderNodeId = rxParams->txPhy->GetDevice()->GetNode()->GetId();
422 }
423 NS_LOG_DEBUG("Received signal from " << senderNodeId << " with unfiltered power "
424 << WToDbm(Integral(*receivedSignalPsd)) << " dBm");
425
426 // Integrate over our receive bandwidth (i.e., all that the receive
427 // spectral mask representing our filtering allows) to find the
428 // total energy apparent to the "demodulator".
429 // This is done per 20 MHz channel band.
430 const auto channelWidth = interface ? interface->GetChannelWidth() : GetChannelWidth();
431 const auto& bands =
432 interface ? interface->GetBands() : m_currentSpectrumPhyInterface->GetBands();
433 double totalRxPowerW = 0;
435
436 const auto rxGainRatio = DbToRatio(GetRxGain());
437
438 std::size_t index = 0;
439 uint16_t prevBw = 0;
440 for (const auto& band : bands)
441 {
442 uint16_t bw = (band.frequencies.second - band.frequencies.first) / 1e6;
443 NS_ASSERT(bw <= channelWidth);
444 index = ((bw != prevBw) ? 0 : (index + 1));
445 double rxPowerPerBandW =
446 WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices);
447 NS_LOG_DEBUG("Signal power received (watts) before antenna gain for "
448 << bw << " MHz channel band " << index << ": " << band);
449 rxPowerPerBandW *= rxGainRatio;
450 rxPowerW.insert({band, rxPowerPerBandW});
451 NS_LOG_DEBUG("Signal power received after antenna gain for "
452 << bw << " MHz channel band " << index << ": " << rxPowerPerBandW << " W ("
453 << WToDbm(rxPowerPerBandW) << " dBm)");
454 if (bw <= 20)
455 {
456 totalRxPowerW += rxPowerPerBandW;
457 }
458 prevBw = bw;
459 }
460
462 {
463 const auto& heRuBands =
464 interface ? interface->GetHeRuBands() : m_currentSpectrumPhyInterface->GetHeRuBands();
465 NS_ASSERT(!heRuBands.empty());
466 for (const auto& [band, ru] : heRuBands)
467 {
468 double rxPowerPerBandW =
469 WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices);
470 rxPowerPerBandW *= rxGainRatio;
471 rxPowerW.insert({band, rxPowerPerBandW});
472 }
473 }
474
475 NS_LOG_DEBUG("Total signal power received after antenna gain: "
476 << totalRxPowerW << " W (" << WToDbm(totalRxPowerW) << " dBm)");
477
479 DynamicCast<WifiSpectrumSignalParameters>(rxParams);
480
481 // Log the signal arrival to the trace source
482 m_signalCb(rxParams, senderNodeId, WToDbm(totalRxPowerW), rxDuration);
483
484 if (!wifiRxParams)
485 {
486 NS_LOG_INFO("Received non Wi-Fi signal");
487 m_interference->AddForeignSignal(rxDuration,
488 rxPowerW,
489 interface ? interface->GetFrequencyRange()
491 SwitchMaybeToCcaBusy(nullptr);
492 return;
493 }
494
495 if (wifiRxParams && m_disableWifiReception)
496 {
497 NS_LOG_INFO("Received Wi-Fi signal but blocked from syncing");
498 NS_ASSERT(interface);
499 m_interference->AddForeignSignal(rxDuration, rxPowerW, interface->GetFrequencyRange());
500 SwitchMaybeToCcaBusy(nullptr);
501 return;
502 }
503
504 if (m_trackSignalsInactiveInterfaces && interface &&
505 (interface != m_currentSpectrumPhyInterface))
506 {
507 NS_LOG_INFO("Received Wi-Fi signal from a non-active PHY interface "
508 << interface->GetFrequencyRange());
509 m_interference->AddForeignSignal(rxDuration, rxPowerW, interface->GetFrequencyRange());
510 SwitchMaybeToCcaBusy(nullptr);
511 return;
512 }
513
514 // Do no further processing if signal is too weak
515 // Current implementation assumes constant RX power over the PPDU duration
516 // Compare received TX power per MHz to normalized RX sensitivity
517 const auto ppdu = GetRxPpduFromTxPpdu(wifiRxParams->ppdu);
518 if (totalRxPowerW < DbmToW(GetRxSensitivity()) * (ppdu->GetTxChannelWidth() / 20.0))
519 {
520 NS_LOG_INFO("Received signal too weak to process: " << WToDbm(totalRxPowerW) << " dBm");
521 m_interference->Add(ppdu, rxDuration, rxPowerW, GetCurrentFrequencyRange());
522 SwitchMaybeToCcaBusy(nullptr);
523 return;
524 }
525
526 if (wifiRxParams->txPhy)
527 {
528 if (!CanStartRx(ppdu))
529 {
530 NS_LOG_INFO("Cannot start reception of the PPDU, consider it as interference");
531 m_interference->Add(ppdu, rxDuration, rxPowerW, GetCurrentFrequencyRange());
533 return;
534 }
535 }
536
537 NS_LOG_INFO("Received Wi-Fi signal");
538 StartReceivePreamble(ppdu, rxPowerW, rxDuration);
539}
540
543{
544 return GetPhyEntityForPpdu(ppdu)->GetRxPpduFromTxPpdu(ppdu);
545}
546
549{
550 return m_antenna;
551}
552
553void
555{
556 NS_LOG_FUNCTION(this << a);
557 m_antenna = a;
558}
559
560void
562{
563 NS_LOG_FUNCTION(this << device);
564 WifiPhy::SetDevice(device);
565 for (auto& spectrumPhyInterface : m_spectrumPhyInterfaces)
566 {
567 spectrumPhyInterface.second->SetDevice(device);
568 }
569}
570
571void
573{
574 NS_LOG_FUNCTION(this << ppdu);
575 m_signalTransmissionCb(ppdu, ppdu->GetTxVector());
576 GetPhyEntity(ppdu->GetModulation())->StartTx(ppdu);
577}
578
579void
581{
582 NS_LOG_FUNCTION(this << txParams);
584 m_currentSpectrumPhyInterface->StartTx(txParams);
585}
586
587uint16_t
588SpectrumWifiPhy::GetGuardBandwidth(uint16_t currentChannelWidth) const
589{
590 uint16_t guardBandwidth = 0;
591 if (currentChannelWidth == 22)
592 {
593 // handle case of DSSS transmission
594 guardBandwidth = 10;
595 }
596 else
597 {
598 // In order to properly model out of band transmissions for OFDM, the guard
599 // band has been configured so as to expand the modeled spectrum up to the
600 // outermost referenced point in "Transmit spectrum mask" sections' PSDs of
601 // each PHY specification of 802.11-2016 standard. It thus ultimately corresponds
602 // to the currently considered channel bandwidth (which can be different from
603 // supported channel width).
604 guardBandwidth = currentChannelWidth;
605 }
606 return guardBandwidth;
607}
608
611 uint16_t bandWidth,
612 uint8_t bandIndex /* = 0 */)
613{
614 const auto subcarrierSpacing = GetSubcarrierSpacing();
615 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
616 const auto numBandsInBand = static_cast<size_t>(bandWidth * 1e6 / subcarrierSpacing);
617 auto numBandsInChannel = static_cast<size_t>(channelWidth * 1e6 / subcarrierSpacing);
618 if (numBandsInBand % 2 == 0)
619 {
620 numBandsInChannel += 1; // symmetry around center frequency
621 }
622 auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel();
623 size_t totalNumBands = rxSpectrumModel->GetNumBands();
624 NS_ASSERT_MSG((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1),
625 "Should have odd number of bands");
626 NS_ASSERT_MSG((bandIndex * bandWidth) < channelWidth, "Band index is out of bound");
627 NS_ASSERT(totalNumBands >= numBandsInChannel);
628 auto startIndex = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand);
629 auto stopIndex = startIndex + numBandsInBand - 1;
630 auto frequencies =
631 ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, {startIndex, stopIndex});
632 auto freqRange = spectrumPhyInterface->GetFrequencyRange();
633 NS_ASSERT(frequencies.first >= (freqRange.minFrequency * 1e6));
634 NS_ASSERT(frequencies.second <= (freqRange.maxFrequency * 1e6));
635 NS_ASSERT((frequencies.second - frequencies.first) == (bandWidth * 1e6));
636 if (startIndex >= totalNumBands / 2)
637 {
638 // step past DC
639 startIndex += 1;
640 }
641 return {{startIndex, stopIndex}, frequencies};
642}
643
645SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */)
646{
648 return GetBandForInterface(m_currentSpectrumPhyInterface, bandWidth, bandIndex);
649}
650
653{
656}
657
660 Ptr<WifiSpectrumPhyInterface> spectrumPhyInterface,
661 const WifiSpectrumBandIndices& indices) const
662{
663 NS_ABORT_IF(!spectrumPhyInterface);
664 auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel();
665 auto startGuardBand = rxSpectrumModel->Begin();
666 auto startChannel = std::next(startGuardBand, indices.first);
667 auto endChannel = std::next(startGuardBand, indices.second + 1);
668 auto lowFreq = static_cast<uint64_t>(startChannel->fc);
669 auto highFreq = static_cast<uint64_t>(endChannel->fc);
670 return {lowFreq, highFreq};
671}
672
673std::tuple<double, double, double>
675{
676 return std::make_tuple(m_txMaskInnerBandMinimumRejection,
679}
680
683{
685 return m_currentSpectrumPhyInterface->GetFrequencyRange();
686}
687
688const std::map<FrequencyRange, Ptr<WifiSpectrumPhyInterface>>&
690{
692}
693
695SpectrumWifiPhy::GetInterfaceCoveringChannelBand(uint16_t frequency, uint16_t width) const
696{
697 const auto lowFreq = frequency - (width / 2);
698 const auto highFreq = frequency + (width / 2);
699 const auto it = std::find_if(m_spectrumPhyInterfaces.cbegin(),
701 [lowFreq, highFreq](const auto& item) {
702 return ((lowFreq >= item.first.minFrequency) &&
703 (highFreq <= item.first.maxFrequency));
704 });
705 if (it == std::end(m_spectrumPhyInterfaces))
706 {
707 return nullptr;
708 }
709 return it->second;
710}
711
714{
716}
717
718void
720{
721 m_channelSwitchedCallback = callback;
722}
723
724} // namespace ns3
Callback template class.
Definition: callback.h:438
void Nullify()
Discard the implementation, set it to null.
Definition: callback.h:577
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
static WifiSpectrumBandIndices ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, uint32_t subcarrierSpacing, HeRu::SubcarrierRange subcarrierRange, uint8_t bandIndex=0)
Definition: he-phy.cc:1820
RU Specification.
Definition: he-ru.h:66
std::size_t GetPhyIndex(uint16_t bw, uint8_t p20Index) const
Get the RU PHY index.
Definition: he-ru.cc:479
static SubcarrierGroup GetSubcarrierGroup(uint16_t bw, RuType ruType, std::size_t phyIndex)
Get the subcarrier group of the RU having the given PHY index among all the RUs of the given type (nu...
Definition: he-ru.cc:591
static std::size_t GetNRus(uint16_t bw, RuType ruType)
Get the number of distinct RUs of the given type (number of tones) available in a HE PPDU of the give...
Definition: he-ru.cc:495
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
Definition: he-ru.h:55
std::pair< int16_t, int16_t > SubcarrierRange
(lowest index, highest index) pair defining a subcarrier range
Definition: he-ru.h:52
RuType
The different HE Resource Unit (RU) types.
Definition: he-ru.h:41
@ RU_2x996_TONE
Definition: he-ru.h:48
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:251
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
802.11 PHY layer model
std::tuple< double, double, double > GetTxMaskRejectionParams() const override
void ResetSpectrumModel(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface, uint16_t centerFrequency, uint16_t channelWidth)
Perform run-time spectrum model change.
void SetDevice(const Ptr< WifiNetDevice > device) override
Sets the device this PHY is associated with.
void Transmit(Ptr< WifiSpectrumSignalParameters > txParams)
This function is sending the signal to the Spectrum channel after finishing the configuration of the ...
WifiSpectrumBands ComputeBands(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface)
This function computes the bands that belong to a given spectrum PHY interface.
void StartRx(Ptr< SpectrumSignalParameters > rxParams, Ptr< const WifiSpectrumPhyInterface > interface)
Input method for delivering a signal from the spectrum channel and low-level PHY interface to this Sp...
void DoInitialize() override
Initialize() implementation.
HeRuBands GetHeRuBands(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface, uint16_t guardBandwidth)
This function computes the RU bands that belong to a given spectrum PHY interface.
std::map< FrequencyRange, Ptr< WifiSpectrumPhyInterface > > m_spectrumPhyInterfaces
Spectrum PHY interfaces.
WifiSpectrumBandFrequencies ConvertIndicesToFrequenciesForInterface(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface, const WifiSpectrumBandIndices &indices) const
This is a helper function to convert start and stop indices to start and stop frequencies.
Ptr< AntennaModel > m_antenna
antenna model
FrequencyRange GetCurrentFrequencyRange() const override
Get the frequency range of the current RF interface.
void ConfigureInterface(uint16_t frequency, uint16_t width)
Configure a non-active spectrum PHY interface to operate on a given frequency with a given width.
Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu)
Determine the WifiPpdu to be used by the RX PHY based on the WifiPpdu sent by the TX PHY.
Ptr< WifiSpectrumPhyInterface > GetInterfaceCoveringChannelBand(uint16_t frequency, uint16_t width) const
Get the spectrum PHY interface that covers a band portion of the RF channel.
Ptr< AntennaModel > GetAntenna() const
Get the antenna model used for reception.
Ptr< Channel > GetChannel() const override
Return the Channel this WifiPhy is connected to.
void AddChannel(const Ptr< SpectrumChannel > channel, const FrequencyRange &freqRange=WHOLE_WIFI_SPECTRUM)
Attach a SpectrumChannel to use for a given frequency range.
void SetChannelSwitchedCallback(Callback< void > callback)
Ptr< WifiSpectrumPhyInterface > m_currentSpectrumPhyInterface
The current Spectrum PHY interface (held for performance reasons)
Ptr< WifiSpectrumPhyInterface > GetCurrentInterface() const
Get the currently active spectrum PHY interface.
double m_txMaskInnerBandMinimumRejection
The minimum rejection (in dBr) for the inner band of the transmit spectrum mask.
bool m_trackSignalsInactiveInterfaces
flag whether signals coming from inactive spectrum PHY interfaces are tracked
double m_txMaskOuterBandMinimumRejection
The minimum rejection (in dBr) for the outer band of the transmit spectrum mask.
void DoDispose() override
Destructor implementation.
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const override
WifiSpectrumBandInfo GetBandForInterface(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface, uint16_t bandWidth, uint8_t bandIndex=0)
Get the info of a given band that belongs to a given spectrum PHY interface.
const std::map< FrequencyRange, Ptr< WifiSpectrumPhyInterface > > & GetSpectrumPhyInterfaces() const
Get the map of interfaces attached to this spectrum PHY.
static TypeId GetTypeId()
Get the type ID.
TracedCallback< Ptr< const SpectrumSignalParameters >, uint32_t, double, Time > m_signalCb
Signal callback.
Callback< void > m_channelSwitchedCallback
Callback when channel switched.
void SetAntenna(const Ptr< AntennaModel > antenna)
double m_txMaskOuterBandMaximumRejection
The maximum rejection (in dBr) for the outer band of the transmit spectrum mask.
WifiSpectrumBandInfo GetBand(uint16_t bandWidth, uint8_t bandIndex=0) override
Get the info of a given band.
bool m_disableWifiReception
forces this PHY to fail to sync on any signal
bool CanStartRx(Ptr< const WifiPpdu > ppdu) const
Determine whether the PHY shall issue a PHY-RXSTART.indication primitive in response to a given PPDU.
void UpdateInterferenceHelperBands(Ptr< WifiSpectrumPhyInterface > spectrumPhyInterface)
This function is called to update the bands handled by the InterferenceHelper.
void StartTx(Ptr< const WifiPpdu > ppdu) override
void NotifyChannelSwitched()
Notify the spectrum channel has switched.
void DoChannelSwitch() override
Actually switch channel based on the stored channel settings.
WifiSpectrumBandFrequencies ConvertIndicesToFrequencies(const WifiSpectrumBandIndices &indices) const override
This is a helper function to convert start and stop indices to start and stop frequencies.
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:415
@ NS
nanosecond
Definition: nstime.h:119
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
802.11 PHY layer model
Definition: wifi-phy.h:65
uint32_t GetSubcarrierSpacing() const
Definition: wifi-phy.cc:2322
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1083
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:504
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1071
TracedCallback< Ptr< const WifiPpdu >, const WifiTxVector & > m_signalTransmissionCb
Signal Transmission callback.
Definition: wifi-phy.h:1361
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:744
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:625
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1931
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:631
void DoDispose() override
Destructor implementation.
Definition: wifi-phy.cc:425
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition: wifi-phy.cc:1206
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu=nullptr)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
Definition: wifi-phy.cc:2168
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1320
void DoInitialize() override
Initialize() implementation.
Definition: wifi-phy.cc:400
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1059
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:765
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1065
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition: wifi-phy.cc:759
bool IsSet() const
Return true if a valid channel has been set, false otherwise.
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
#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_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#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_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
@ WIFI_STANDARD_80211ax
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:48
std::pair< uint64_t, uint64_t > WifiSpectrumBandFrequencies
typedef for a pair of start and stop frequencies in Hz to represent a band
double Integral(const SpectrumValue &arg)
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:42
std::vector< WifiSpectrumBandInfo > WifiSpectrumBands
vector of spectrum bands
std::pair< uint32_t, uint32_t > WifiSpectrumBandIndices
typedef for a pair of start and stop sub-band indices
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
std::map< WifiSpectrumBandInfo, HeRu::RuSpec > HeRuBands
Map a spectrum band associated with an RU to the RU specification.
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:36
Struct defining a frequency range between minFrequency (MHz) and maxFrequency (MHz).
WifiSpectrumBandInfo structure containing info about a spectrum band.