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("SignalArrival",
92 "Signal arrival",
94 "ns3::SpectrumWifiPhy::SignalArrivalCallback");
95 return tid;
96}
97
99 : m_spectrumPhyInterfaces{},
100 m_currentSpectrumPhyInterface{nullptr}
101{
102 NS_LOG_FUNCTION(this);
103}
104
106{
107 NS_LOG_FUNCTION(this);
108}
109
110void
112{
113 NS_LOG_FUNCTION(this);
116 m_antenna = nullptr;
119}
120
121void
123{
124 NS_LOG_FUNCTION(this);
126}
127
130{
131 NS_LOG_FUNCTION(this << spectrumPhyInterface);
132 WifiSpectrumBands bands{};
133 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
134 if (channelWidth < 20)
135 {
136 bands.push_back(GetBandForInterface(spectrumPhyInterface, channelWidth));
137 }
138 else
139 {
140 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
141 {
142 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
143 {
144 bands.push_back(GetBandForInterface(spectrumPhyInterface, bw, i));
145 }
146 }
147 }
148 return bands;
149}
150
153 uint16_t guardBandwidth)
154{
155 HeRuBands heRuBands{};
156 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
157 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
158 {
159 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
160 {
161 for (uint32_t type = 0; type < 7; type++)
162 {
163 auto ruType = static_cast<HeRu::RuType>(type);
164 std::size_t nRus = HeRu::GetNRus(bw, ruType);
165 for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++)
166 {
167 HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup(bw, ruType, phyIndex);
168 HeRu::SubcarrierRange subcarrierRange =
169 std::make_pair(group.front().first, group.back().second);
170 const auto bandIndices = HePhy::ConvertHeRuSubcarriers(bw,
171 guardBandwidth,
173 subcarrierRange,
174 i);
175 const auto bandFrequencies =
176 ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, bandIndices);
177 WifiSpectrumBandInfo band = {bandIndices, bandFrequencies};
178 std::size_t index =
179 (bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex);
180 const auto p20Index = GetOperatingChannel().GetPrimaryChannelIndex(20);
181 bool primary80IsLower80 = (p20Index < bw / 40);
182 bool primary80 = (bw < 160 || ruType == HeRu::RU_2x996_TONE ||
183 (primary80IsLower80 && phyIndex <= nRus / 2) ||
184 (!primary80IsLower80 && phyIndex > nRus / 2));
185 HeRu::RuSpec ru(ruType, index, primary80);
186 NS_ABORT_IF(ru.GetPhyIndex(bw, p20Index) != phyIndex);
187 heRuBands.insert({band, ru});
188 }
189 }
190 }
191 }
192 return heRuBands;
193}
194
195void
197{
198 NS_LOG_FUNCTION(this << spectrumPhyInterface);
199 auto&& bands = ComputeBands(spectrumPhyInterface);
200 WifiSpectrumBands allBands{bands};
202 {
203 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
204 auto&& heRuBands = GetHeRuBands(spectrumPhyInterface, GetGuardBandwidth(channelWidth));
205 for (const auto& bandRuPair : heRuBands)
206 {
207 allBands.push_back(bandRuPair.first);
208 }
209 spectrumPhyInterface->SetHeRuBands(std::move(heRuBands));
210 }
211
212 spectrumPhyInterface->SetBands(std::move(bands));
213
214 if (m_interference->HasBands())
215 {
216 m_interference->UpdateBands(allBands, spectrumPhyInterface->GetFrequencyRange());
217 }
218 else
219 {
220 for (const auto& band : allBands)
221 {
222 m_interference->AddBand(band);
223 }
224 }
225}
226
229{
231 return m_currentSpectrumPhyInterface->GetChannel();
232}
233
234void
236{
237 NS_LOG_FUNCTION(this << channel << freqRange);
238
239 const auto foundOverlappingChannel =
240 std::any_of(m_spectrumPhyInterfaces.cbegin(),
242 [freqRange, channel](const auto& item) {
243 const auto spectrumRange = item.first;
244 const auto noOverlap =
245 ((freqRange.minFrequency >= spectrumRange.maxFrequency) ||
246 (freqRange.maxFrequency <= spectrumRange.minFrequency));
247 return (!noOverlap);
248 });
249 NS_ABORT_MSG_IF(foundOverlappingChannel,
250 "Added a wifi spectrum channel that overlaps with another existing wifi "
251 "spectrum channel");
252
253 auto wifiSpectrumPhyInterface = CreateObject<WifiSpectrumPhyInterface>(freqRange);
254 wifiSpectrumPhyInterface->SetSpectrumWifiPhy(this);
255 wifiSpectrumPhyInterface->SetChannel(channel);
256 if (GetDevice())
257 {
258 wifiSpectrumPhyInterface->SetDevice(GetDevice());
259 }
260 m_spectrumPhyInterfaces.emplace(freqRange, wifiSpectrumPhyInterface);
261}
262
263void
265 uint16_t centerFrequency,
266 uint16_t channelWidth)
267{
268 NS_LOG_FUNCTION(this << spectrumPhyInterface << centerFrequency << channelWidth);
269
270 // We have to reset the spectrum model because we changed RF channel. Consequently,
271 // we also have to add the spectrum interface to the spectrum channel again because
272 // MultiModelSpectrumChannel keeps spectrum interfaces in a map indexed by the RX
273 // spectrum model UID (which has changed after channel switching).
274 // Both SingleModelSpectrumChannel and MultiModelSpectrumChannel ensure not to keep
275 // duplicated spectrum interfaces (the latter removes the spectrum interface and adds
276 // it again in the entry associated with the new RX spectrum model UID)
277
278 // Replace existing spectrum model with new one
279 spectrumPhyInterface->SetRxSpectrumModel(centerFrequency,
280 channelWidth,
282 GetGuardBandwidth(channelWidth));
283
284 spectrumPhyInterface->GetChannel()->AddRx(spectrumPhyInterface);
285
286 UpdateInterferenceHelperBands(spectrumPhyInterface);
287}
288
289void
291{
292 NS_LOG_FUNCTION(this);
293 const auto frequencyBefore = GetOperatingChannel().IsSet() ? GetFrequency() : 0;
294 const auto widthBefore = GetOperatingChannel().IsSet() ? GetChannelWidth() : 0;
296 const auto frequencyAfter = GetFrequency();
297 const auto widthAfter = GetChannelWidth();
298 if ((frequencyBefore == frequencyAfter) && (widthBefore == widthAfter))
299 {
300 NS_LOG_DEBUG("Same RF channel as before, do nothing");
301 if (IsInitialized())
302 {
303 SwitchMaybeToCcaBusy(nullptr);
304 }
305 return;
306 }
307
308 auto newSpectrumPhyInterface = GetInterfaceCoveringChannelBand(frequencyAfter, widthAfter);
309 const auto interfaceChanged = (newSpectrumPhyInterface != m_currentSpectrumPhyInterface);
310
311 NS_ABORT_MSG_IF(!newSpectrumPhyInterface,
312 "No spectrum channel covers frequency range ["
313 << frequencyAfter - (widthAfter / 2) << " MHz - "
314 << frequencyAfter + (widthAfter / 2) << " MHz]");
315
316 if (interfaceChanged)
317 {
318 NS_LOG_DEBUG("Switch to existing RF interface with frequency/width pair of ("
319 << frequencyAfter << ", " << widthAfter << ")");
321 {
323 }
324 }
325
326 m_currentSpectrumPhyInterface = newSpectrumPhyInterface;
327
328 auto reset = true;
329 if (m_currentSpectrumPhyInterface->GetCenterFrequency() == frequencyAfter)
330 {
331 // Center frequency has not changed for that interface, hence we do not need to
332 // reset the spectrum model nor update any band stored in the interference helper
334 {
335 // If we are not tracking signals from inactive interface,
336 // this means the spectrum interface has been disconnected
337 // from the spectrum channel and has to be connected back
339 }
340 reset = false;
341 }
342
343 if (reset)
344 {
345 ResetSpectrumModel(m_currentSpectrumPhyInterface, frequencyAfter, widthAfter);
346 }
347
348 if (IsInitialized())
349 {
350 SwitchMaybeToCcaBusy(nullptr);
351 }
352
354}
355
356void
358{
360 {
362 }
363}
364
365void
366SpectrumWifiPhy::ConfigureInterface(uint16_t frequency, uint16_t width)
367{
368 NS_LOG_FUNCTION(this << frequency << width);
369
371 {
372 NS_LOG_DEBUG("Tracking of signals on inactive interfaces is not enabled");
373 return;
374 }
375
376 auto spectrumPhyInterface = GetInterfaceCoveringChannelBand(frequency, width);
377
378 NS_ABORT_MSG_IF(!spectrumPhyInterface,
379 "No spectrum channel covers frequency range ["
380 << frequency - (width / 2) << " MHz - " << frequency + (width / 2)
381 << " MHz]");
382
383 NS_ABORT_MSG_IF(spectrumPhyInterface == m_currentSpectrumPhyInterface,
384 "This method should not be called for the current interface");
385
386 if ((frequency == spectrumPhyInterface->GetCenterFrequency()) &&
387 (width == spectrumPhyInterface->GetChannelWidth()))
388 {
389 NS_LOG_DEBUG("Same RF channel as before on that interface, do nothing");
390 return;
391 }
392
393 ResetSpectrumModel(spectrumPhyInterface, frequency, width);
394}
395
396bool
398{
399 return GetLatestPhyEntity()->CanStartRx(ppdu);
400}
401
402void
405{
406 NS_LOG_FUNCTION(this << rxParams << interface);
407 Time rxDuration = rxParams->duration;
408 Ptr<SpectrumValue> receivedSignalPsd = rxParams->psd;
409 NS_LOG_DEBUG("Received signal with PSD " << *receivedSignalPsd << " and duration "
410 << rxDuration.As(Time::NS));
411 uint32_t senderNodeId = 0;
412 if (rxParams->txPhy)
413 {
414 senderNodeId = rxParams->txPhy->GetDevice()->GetNode()->GetId();
415 }
416 NS_LOG_DEBUG("Received signal from " << senderNodeId << " with unfiltered power "
417 << WToDbm(Integral(*receivedSignalPsd)) << " dBm");
418
419 // Integrate over our receive bandwidth (i.e., all that the receive
420 // spectral mask representing our filtering allows) to find the
421 // total energy apparent to the "demodulator".
422 // This is done per 20 MHz channel band.
423 const auto channelWidth = interface ? interface->GetChannelWidth() : GetChannelWidth();
424 const auto& bands =
425 interface ? interface->GetBands() : m_currentSpectrumPhyInterface->GetBands();
426 double totalRxPowerW = 0;
428
429 const auto rxGainRatio = DbToRatio(GetRxGain());
430
431 std::size_t index = 0;
432 uint16_t prevBw = 0;
433 for (const auto& band : bands)
434 {
435 uint16_t bw = (band.frequencies.second - band.frequencies.first) / 1e6;
436 NS_ASSERT(bw <= channelWidth);
437 index = ((bw != prevBw) ? 0 : (index + 1));
438 double rxPowerPerBandW =
439 WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices);
440 NS_LOG_DEBUG("Signal power received (watts) before antenna gain for "
441 << bw << " MHz channel band " << index << ": " << band);
442 rxPowerPerBandW *= rxGainRatio;
443 rxPowerW.insert({band, rxPowerPerBandW});
444 NS_LOG_DEBUG("Signal power received after antenna gain for "
445 << bw << " MHz channel band " << index << ": " << rxPowerPerBandW << " W ("
446 << WToDbm(rxPowerPerBandW) << " dBm)");
447 if (bw <= 20)
448 {
449 totalRxPowerW += rxPowerPerBandW;
450 }
451 prevBw = bw;
452 }
453
455 {
456 const auto& heRuBands =
457 interface ? interface->GetHeRuBands() : m_currentSpectrumPhyInterface->GetHeRuBands();
458 NS_ASSERT(!heRuBands.empty());
459 for (const auto& [band, ru] : heRuBands)
460 {
461 double rxPowerPerBandW =
462 WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices);
463 rxPowerPerBandW *= rxGainRatio;
464 rxPowerW.insert({band, rxPowerPerBandW});
465 }
466 }
467
468 NS_LOG_DEBUG("Total signal power received after antenna gain: "
469 << totalRxPowerW << " W (" << WToDbm(totalRxPowerW) << " dBm)");
470
472 DynamicCast<WifiSpectrumSignalParameters>(rxParams);
473
474 // Log the signal arrival to the trace source
475 m_signalCb(bool(wifiRxParams), senderNodeId, WToDbm(totalRxPowerW), rxDuration);
476
477 if (!wifiRxParams)
478 {
479 NS_LOG_INFO("Received non Wi-Fi signal");
480 m_interference->AddForeignSignal(rxDuration, rxPowerW, GetCurrentFrequencyRange());
481 SwitchMaybeToCcaBusy(nullptr);
482 return;
483 }
484
485 if (wifiRxParams && m_disableWifiReception)
486 {
487 NS_LOG_INFO("Received Wi-Fi signal but blocked from syncing");
488 m_interference->AddForeignSignal(rxDuration, rxPowerW, GetCurrentFrequencyRange());
489 SwitchMaybeToCcaBusy(nullptr);
490 return;
491 }
492
493 if (m_trackSignalsInactiveInterfaces && interface &&
494 (interface != m_currentSpectrumPhyInterface))
495 {
496 NS_LOG_INFO("Received Wi-Fi signal from a non-active PHY interface "
497 << interface->GetFrequencyRange());
498 m_interference->AddForeignSignal(rxDuration, rxPowerW, interface->GetFrequencyRange());
499 SwitchMaybeToCcaBusy(nullptr);
500 return;
501 }
502
503 // Do no further processing if signal is too weak
504 // Current implementation assumes constant RX power over the PPDU duration
505 // Compare received TX power per MHz to normalized RX sensitivity
506 const auto ppdu = GetRxPpduFromTxPpdu(wifiRxParams->ppdu);
507 if (totalRxPowerW < DbmToW(GetRxSensitivity()) * (ppdu->GetTxChannelWidth() / 20.0))
508 {
509 NS_LOG_INFO("Received signal too weak to process: " << WToDbm(totalRxPowerW) << " dBm");
510 m_interference->Add(ppdu, rxDuration, rxPowerW, GetCurrentFrequencyRange());
511 SwitchMaybeToCcaBusy(nullptr);
512 return;
513 }
514
515 if (wifiRxParams->txPhy)
516 {
517 if (!CanStartRx(ppdu))
518 {
519 NS_LOG_INFO("Cannot start reception of the PPDU, consider it as interference");
520 m_interference->Add(ppdu, rxDuration, rxPowerW, GetCurrentFrequencyRange());
522 return;
523 }
524 }
525
526 NS_LOG_INFO("Received Wi-Fi signal");
527 StartReceivePreamble(ppdu, rxPowerW, rxDuration);
528}
529
532{
533 return GetPhyEntityForPpdu(ppdu)->GetRxPpduFromTxPpdu(ppdu);
534}
535
538{
539 return m_antenna;
540}
541
542void
544{
545 NS_LOG_FUNCTION(this << a);
546 m_antenna = a;
547}
548
549void
551{
552 NS_LOG_FUNCTION(this << device);
553 WifiPhy::SetDevice(device);
554 for (auto& spectrumPhyInterface : m_spectrumPhyInterfaces)
555 {
556 spectrumPhyInterface.second->SetDevice(device);
557 }
558}
559
560void
562{
563 NS_LOG_FUNCTION(this << ppdu);
564 GetPhyEntity(ppdu->GetModulation())->StartTx(ppdu);
565}
566
567void
569{
570 NS_LOG_FUNCTION(this << txParams);
572 m_currentSpectrumPhyInterface->StartTx(txParams);
573}
574
575uint16_t
576SpectrumWifiPhy::GetGuardBandwidth(uint16_t currentChannelWidth) const
577{
578 uint16_t guardBandwidth = 0;
579 if (currentChannelWidth == 22)
580 {
581 // handle case of DSSS transmission
582 guardBandwidth = 10;
583 }
584 else
585 {
586 // In order to properly model out of band transmissions for OFDM, the guard
587 // band has been configured so as to expand the modeled spectrum up to the
588 // outermost referenced point in "Transmit spectrum mask" sections' PSDs of
589 // each PHY specification of 802.11-2016 standard. It thus ultimately corresponds
590 // to the currently considered channel bandwidth (which can be different from
591 // supported channel width).
592 guardBandwidth = currentChannelWidth;
593 }
594 return guardBandwidth;
595}
596
599 uint16_t bandWidth,
600 uint8_t bandIndex /* = 0 */)
601{
602 const auto subcarrierSpacing = GetSubcarrierSpacing();
603 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
604 const auto numBandsInBand = static_cast<size_t>(bandWidth * 1e6 / subcarrierSpacing);
605 auto numBandsInChannel = static_cast<size_t>(channelWidth * 1e6 / subcarrierSpacing);
606 if (numBandsInBand % 2 == 0)
607 {
608 numBandsInChannel += 1; // symmetry around center frequency
609 }
610 auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel();
611 size_t totalNumBands = rxSpectrumModel->GetNumBands();
612 NS_ASSERT_MSG((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1),
613 "Should have odd number of bands");
614 NS_ASSERT_MSG((bandIndex * bandWidth) < channelWidth, "Band index is out of bound");
615 NS_ASSERT(totalNumBands >= numBandsInChannel);
616 auto startIndex = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand);
617 auto stopIndex = startIndex + numBandsInBand - 1;
618 auto frequencies =
619 ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, {startIndex, stopIndex});
620 auto freqRange = spectrumPhyInterface->GetFrequencyRange();
621 NS_ASSERT(frequencies.first >= (freqRange.minFrequency * 1e6));
622 NS_ASSERT(frequencies.second <= (freqRange.maxFrequency * 1e6));
623 NS_ASSERT((frequencies.second - frequencies.first) == (bandWidth * 1e6));
624 if (startIndex >= totalNumBands / 2)
625 {
626 // step past DC
627 startIndex += 1;
628 }
629 return {{startIndex, stopIndex}, frequencies};
630}
631
633SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */)
634{
636 return GetBandForInterface(m_currentSpectrumPhyInterface, bandWidth, bandIndex);
637}
638
641{
644}
645
648 Ptr<WifiSpectrumPhyInterface> spectrumPhyInterface,
649 const WifiSpectrumBandIndices& indices) const
650{
651 NS_ABORT_IF(!spectrumPhyInterface);
652 auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel();
653 auto startGuardBand = rxSpectrumModel->Begin();
654 auto startChannel = std::next(startGuardBand, indices.first);
655 auto endChannel = std::next(startGuardBand, indices.second + 1);
656 auto lowFreq = static_cast<uint64_t>(startChannel->fc);
657 auto highFreq = static_cast<uint64_t>(endChannel->fc);
658 return {lowFreq, highFreq};
659}
660
661std::tuple<double, double, double>
663{
664 return std::make_tuple(m_txMaskInnerBandMinimumRejection,
667}
668
671{
673 return m_currentSpectrumPhyInterface->GetFrequencyRange();
674}
675
676const std::map<FrequencyRange, Ptr<WifiSpectrumPhyInterface>>&
678{
680}
681
683SpectrumWifiPhy::GetInterfaceCoveringChannelBand(uint16_t frequency, uint16_t width) const
684{
685 const auto lowFreq = frequency - (width / 2);
686 const auto highFreq = frequency + (width / 2);
687 const auto it = std::find_if(m_spectrumPhyInterfaces.cbegin(),
689 [lowFreq, highFreq](const auto& item) {
690 return ((lowFreq >= item.first.minFrequency) &&
691 (highFreq <= item.first.maxFrequency));
692 });
693 if (it == std::end(m_spectrumPhyInterfaces))
694 {
695 return nullptr;
696 }
697 return it->second;
698}
699
702{
704}
705
706void
708{
709 m_channelSwitchedCallback = callback;
710}
711
712} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
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
TracedCallback< bool, uint32_t, double, Time > m_signalCb
Signal callback.
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.
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:2283
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1073
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:494
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1061
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:734
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:615
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1900
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:621
void DoDispose() override
Destructor implementation.
Definition: wifi-phy.cc:415
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition: wifi-phy.cc:1196
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:2137
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1288
void DoInitialize() override
Initialize() implementation.
Definition: wifi-phy.cc:390
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1049
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:755
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1055
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition: wifi-phy.cc:749
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
#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.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
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:40
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
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:34
Struct defining a frequency range between minFrequency (MHz) and maxFrequency (MHz).
WifiSpectrumBandInfo structure containing info about a spectrum band.