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
44namespace ns3
45{
46
47NS_LOG_COMPONENT_DEFINE("SpectrumWifiPhy");
48
49NS_OBJECT_ENSURE_REGISTERED(SpectrumWifiPhy);
50
51TypeId
53{
54 static TypeId tid =
55 TypeId("ns3::SpectrumWifiPhy")
57 .SetGroupName("Wifi")
58 .AddConstructor<SpectrumWifiPhy>()
59 .AddAttribute("DisableWifiReception",
60 "Prevent Wi-Fi frame sync from ever happening",
61 BooleanValue(false),
64 .AddAttribute(
65 "TrackSignalsFromInactiveInterfaces",
66 "Enable or disable tracking signals coming from inactive spectrum PHY interfaces",
67 BooleanValue(true),
70 .AddAttribute(
71 "TxMaskInnerBandMinimumRejection",
72 "Minimum rejection (dBr) for the inner band of the transmit spectrum mask",
73 DoubleValue(-20.0),
75 MakeDoubleChecker<double>())
76 .AddAttribute(
77 "TxMaskOuterBandMinimumRejection",
78 "Minimum rejection (dBr) for the outer band of the transmit spectrum mask",
79 DoubleValue(-28.0),
81 MakeDoubleChecker<double>())
82 .AddAttribute(
83 "TxMaskOuterBandMaximumRejection",
84 "Maximum rejection (dBr) for the outer band of the transmit spectrum mask",
85 DoubleValue(-40.0),
87 MakeDoubleChecker<double>())
88 .AddTraceSource("SignalArrival",
89 "Signal arrival",
91 "ns3::SpectrumWifiPhy::SignalArrivalCallback");
92 return tid;
93}
94
96 : m_spectrumPhyInterfaces{},
97 m_currentSpectrumPhyInterface{nullptr}
98{
99 NS_LOG_FUNCTION(this);
100}
101
103{
104 NS_LOG_FUNCTION(this);
105}
106
107void
109{
110 NS_LOG_FUNCTION(this);
113 m_antenna = nullptr;
116}
117
118void
120{
121 NS_LOG_FUNCTION(this);
123}
124
127{
128 NS_LOG_FUNCTION(this << spectrumPhyInterface);
129 WifiSpectrumBands bands{};
130 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
131 if (channelWidth < 20)
132 {
133 bands.push_back(GetBandForInterface(spectrumPhyInterface, channelWidth));
134 }
135 else
136 {
137 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
138 {
139 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
140 {
141 bands.push_back(GetBandForInterface(spectrumPhyInterface, bw, i));
142 }
143 }
144 }
145 return bands;
146}
147
150 uint16_t guardBandwidth)
151{
152 HeRuBands heRuBands{};
153 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
154 for (uint16_t bw = 160; bw >= 20; bw = bw / 2)
155 {
156 for (uint32_t i = 0; i < (channelWidth / bw); ++i)
157 {
158 for (uint32_t type = 0; type < 7; type++)
159 {
160 auto ruType = static_cast<HeRu::RuType>(type);
161 std::size_t nRus = HeRu::GetNRus(bw, ruType);
162 for (std::size_t phyIndex = 1; phyIndex <= nRus; phyIndex++)
163 {
164 HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup(bw, ruType, phyIndex);
165 HeRu::SubcarrierRange subcarrierRange =
166 std::make_pair(group.front().first, group.back().second);
167 const auto bandIndices = HePhy::ConvertHeRuSubcarriers(bw,
168 guardBandwidth,
170 subcarrierRange,
171 i);
172 const auto bandFrequencies =
173 ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, bandIndices);
174 WifiSpectrumBandInfo band = {bandIndices, bandFrequencies};
175 std::size_t index =
176 (bw == 160 && phyIndex > nRus / 2 ? phyIndex - nRus / 2 : phyIndex);
177 const auto p20Index = GetOperatingChannel().GetPrimaryChannelIndex(20);
178 bool primary80IsLower80 = (p20Index < bw / 40);
179 bool primary80 = (bw < 160 || ruType == HeRu::RU_2x996_TONE ||
180 (primary80IsLower80 && phyIndex <= nRus / 2) ||
181 (!primary80IsLower80 && phyIndex > nRus / 2));
182 HeRu::RuSpec ru(ruType, index, primary80);
183 NS_ABORT_IF(ru.GetPhyIndex(bw, p20Index) != phyIndex);
184 heRuBands.insert({band, ru});
185 }
186 }
187 }
188 }
189 return heRuBands;
190}
191
192void
194{
195 NS_LOG_FUNCTION(this << spectrumPhyInterface);
196 auto&& bands = ComputeBands(spectrumPhyInterface);
197 WifiSpectrumBands allBands{bands};
199 {
200 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
201 auto&& heRuBands = GetHeRuBands(spectrumPhyInterface, GetGuardBandwidth(channelWidth));
202 for (const auto& bandRuPair : heRuBands)
203 {
204 allBands.push_back(bandRuPair.first);
205 }
206 spectrumPhyInterface->SetHeRuBands(std::move(heRuBands));
207 }
208
209 spectrumPhyInterface->SetBands(std::move(bands));
210
211 if (m_interference->HasBands())
212 {
213 m_interference->UpdateBands(allBands, spectrumPhyInterface->GetFrequencyRange());
214 }
215 else
216 {
217 for (const auto& band : allBands)
218 {
219 m_interference->AddBand(band);
220 }
221 }
222}
223
226{
228 return m_currentSpectrumPhyInterface->GetChannel();
229}
230
231void
233{
234 NS_LOG_FUNCTION(this << channel << freqRange);
235
236 const auto foundOverlappingChannel =
237 std::any_of(m_spectrumPhyInterfaces.cbegin(),
239 [freqRange, channel](const auto& item) {
240 const auto spectrumRange = item.first;
241 const auto noOverlap =
242 ((freqRange.minFrequency >= spectrumRange.maxFrequency) ||
243 (freqRange.maxFrequency <= spectrumRange.minFrequency));
244 return (!noOverlap);
245 });
246 NS_ABORT_MSG_IF(foundOverlappingChannel,
247 "Added a wifi spectrum channel that overlaps with another existing wifi "
248 "spectrum channel");
249
250 auto wifiSpectrumPhyInterface = CreateObject<WifiSpectrumPhyInterface>(freqRange);
251 wifiSpectrumPhyInterface->SetSpectrumWifiPhy(this);
252 wifiSpectrumPhyInterface->SetChannel(channel);
253 if (GetDevice())
254 {
255 wifiSpectrumPhyInterface->SetDevice(GetDevice());
256 }
257 m_spectrumPhyInterfaces.emplace(freqRange, wifiSpectrumPhyInterface);
258}
259
260void
262 uint16_t centerFrequency,
263 uint16_t channelWidth)
264{
265 NS_LOG_FUNCTION(this << spectrumPhyInterface << centerFrequency << channelWidth);
266
267 // We have to reset the spectrum model because we changed RF channel. Consequently,
268 // we also have to add the spectrum interface to the spectrum channel again because
269 // MultiModelSpectrumChannel keeps spectrum interfaces in a map indexed by the RX
270 // spectrum model UID (which has changed after channel switching).
271 // Both SingleModelSpectrumChannel and MultiModelSpectrumChannel ensure not to keep
272 // duplicated spectrum interfaces (the latter removes the spectrum interface and adds
273 // it again in the entry associated with the new RX spectrum model UID)
274
275 // Replace existing spectrum model with new one
276 spectrumPhyInterface->SetRxSpectrumModel(centerFrequency,
277 channelWidth,
279 GetGuardBandwidth(channelWidth));
280
281 spectrumPhyInterface->GetChannel()->AddRx(spectrumPhyInterface);
282
283 UpdateInterferenceHelperBands(spectrumPhyInterface);
284}
285
286void
288{
289 NS_LOG_FUNCTION(this);
290 const auto frequencyBefore = GetOperatingChannel().IsSet() ? GetFrequency() : 0;
291 const auto widthBefore = GetOperatingChannel().IsSet() ? GetChannelWidth() : 0;
293 const auto frequencyAfter = GetFrequency();
294 const auto widthAfter = GetChannelWidth();
295 if ((frequencyBefore == frequencyAfter) && (widthBefore == widthAfter))
296 {
297 NS_LOG_DEBUG("Same RF channel as before, do nothing");
298 if (IsInitialized())
299 {
300 SwitchMaybeToCcaBusy(nullptr);
301 }
302 return;
303 }
304
305 auto newSpectrumPhyInterface = GetInterfaceCoveringChannelBand(frequencyAfter, widthAfter);
306 const auto interfaceChanged = (newSpectrumPhyInterface != m_currentSpectrumPhyInterface);
307
308 NS_ABORT_MSG_IF(!newSpectrumPhyInterface,
309 "No spectrum channel covers frequency range ["
310 << frequencyAfter - (widthAfter / 2) << " MHz - "
311 << frequencyAfter + (widthAfter / 2) << " MHz]");
312
313 if (interfaceChanged)
314 {
315 NS_LOG_DEBUG("Switch to existing RF interface with frequency/width pair of ("
316 << frequencyAfter << ", " << widthAfter << ")");
318 {
320 }
321 }
322
323 m_currentSpectrumPhyInterface = newSpectrumPhyInterface;
324
325 auto reset = true;
326 if (m_currentSpectrumPhyInterface->GetCenterFrequency() == frequencyAfter)
327 {
328 // Center frequency has not changed for that interface, hence we do not need to
329 // reset the spectrum model nor update any band stored in the interference helper
331 {
332 // If we are not tracking signals from inactive interface,
333 // this means the spectrum interface has been disconnected
334 // from the spectrum channel and has to be connected back
336 }
337 reset = false;
338 }
339
340 if (reset)
341 {
342 ResetSpectrumModel(m_currentSpectrumPhyInterface, frequencyAfter, widthAfter);
343 }
344
345 if (IsInitialized())
346 {
347 SwitchMaybeToCcaBusy(nullptr);
348 }
349
351}
352
353void
355{
357 {
359 }
360}
361
362void
363SpectrumWifiPhy::ConfigureInterface(uint16_t frequency, uint16_t width)
364{
365 NS_LOG_FUNCTION(this << frequency << width);
366
368 {
369 NS_LOG_DEBUG("Tracking of signals on inactive interfaces is not enabled");
370 return;
371 }
372
373 auto spectrumPhyInterface = GetInterfaceCoveringChannelBand(frequency, width);
374
375 NS_ABORT_MSG_IF(!spectrumPhyInterface,
376 "No spectrum channel covers frequency range ["
377 << frequency - (width / 2) << " MHz - " << frequency + (width / 2)
378 << " MHz]");
379
380 NS_ABORT_MSG_IF(spectrumPhyInterface == m_currentSpectrumPhyInterface,
381 "This method should not be called for the current interface");
382
383 if ((frequency == spectrumPhyInterface->GetCenterFrequency()) &&
384 (width == spectrumPhyInterface->GetChannelWidth()))
385 {
386 NS_LOG_DEBUG("Same RF channel as before on that interface, do nothing");
387 return;
388 }
389
390 ResetSpectrumModel(spectrumPhyInterface, frequency, width);
391}
392
393bool
395{
396 return GetLatestPhyEntity()->CanStartRx(ppdu);
397}
398
399void
402{
403 NS_LOG_FUNCTION(this << rxParams << interface);
404 Time rxDuration = rxParams->duration;
405 Ptr<SpectrumValue> receivedSignalPsd = rxParams->psd;
406 NS_LOG_DEBUG("Received signal with PSD " << *receivedSignalPsd << " and duration "
407 << rxDuration.As(Time::NS));
408 uint32_t senderNodeId = 0;
409 if (rxParams->txPhy)
410 {
411 senderNodeId = rxParams->txPhy->GetDevice()->GetNode()->GetId();
412 }
413 NS_LOG_DEBUG("Received signal from " << senderNodeId << " with unfiltered power "
414 << WToDbm(Integral(*receivedSignalPsd)) << " dBm");
415
416 // Integrate over our receive bandwidth (i.e., all that the receive
417 // spectral mask representing our filtering allows) to find the
418 // total energy apparent to the "demodulator".
419 // This is done per 20 MHz channel band.
420 const auto channelWidth = interface ? interface->GetChannelWidth() : GetChannelWidth();
421 const auto& bands =
422 interface ? interface->GetBands() : m_currentSpectrumPhyInterface->GetBands();
423 double totalRxPowerW = 0;
425
426 std::size_t index = 0;
427 uint16_t prevBw = 0;
428 for (const auto& band : bands)
429 {
430 uint16_t bw = (band.frequencies.second - band.frequencies.first) / 1e6;
431 NS_ASSERT(bw <= channelWidth);
432 index = ((bw != prevBw) ? 0 : (index + 1));
433 double rxPowerPerBandW =
434 WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices);
435 NS_LOG_DEBUG("Signal power received (watts) before antenna gain for "
436 << bw << " MHz channel band " << index << ": " << band);
437 rxPowerPerBandW *= DbToRatio(GetRxGain());
438 rxPowerW.insert({band, rxPowerPerBandW});
439 NS_LOG_DEBUG("Signal power received after antenna gain for "
440 << bw << " MHz channel band " << index << ": " << rxPowerPerBandW << " W ("
441 << WToDbm(rxPowerPerBandW) << " dBm)");
442 if (bw <= 20)
443 {
444 totalRxPowerW += rxPowerPerBandW;
445 }
446 prevBw = bw;
447 }
448
450 {
451 const auto& heRuBands =
452 interface ? interface->GetHeRuBands() : m_currentSpectrumPhyInterface->GetHeRuBands();
453 NS_ASSERT(!heRuBands.empty());
454 for (const auto& [band, ru] : heRuBands)
455 {
456 double rxPowerPerBandW =
457 WifiSpectrumValueHelper::GetBandPowerW(receivedSignalPsd, band.indices);
458 NS_LOG_DEBUG("Signal power received (watts) before antenna gain for RU with type "
459 << ru.GetRuType() << " and index " << ru.GetIndex() << " -> ("
460 << band.indices.first << "; " << band.indices.second
461 << "): " << rxPowerPerBandW);
462 rxPowerPerBandW *= DbToRatio(GetRxGain());
463 NS_LOG_DEBUG("Signal power received after antenna gain for RU with type "
464 << ru.GetRuType() << " and index " << ru.GetIndex() << " -> ("
465 << band.indices.first << "; " << band.indices.second << "): "
466 << rxPowerPerBandW << " W (" << WToDbm(rxPowerPerBandW) << " dBm)");
467 rxPowerW.insert({band, rxPowerPerBandW});
468 }
469 }
470
471 NS_LOG_DEBUG("Total signal power received after antenna gain: "
472 << totalRxPowerW << " W (" << WToDbm(totalRxPowerW) << " dBm)");
473
475 DynamicCast<WifiSpectrumSignalParameters>(rxParams);
476
477 // Log the signal arrival to the trace source
478 m_signalCb(bool(wifiRxParams), senderNodeId, WToDbm(totalRxPowerW), rxDuration);
479
480 if (!wifiRxParams)
481 {
482 NS_LOG_INFO("Received non Wi-Fi signal");
483 m_interference->AddForeignSignal(rxDuration, rxPowerW);
484 SwitchMaybeToCcaBusy(nullptr);
485 return;
486 }
487
488 if (wifiRxParams && m_disableWifiReception)
489 {
490 NS_LOG_INFO("Received Wi-Fi signal but blocked from syncing");
491 m_interference->AddForeignSignal(rxDuration, rxPowerW);
492 SwitchMaybeToCcaBusy(nullptr);
493 return;
494 }
495
496 if (m_trackSignalsInactiveInterfaces && interface &&
497 (interface != m_currentSpectrumPhyInterface))
498 {
499 NS_LOG_INFO("Received Wi-Fi signal from a non-active PHY interface");
500 m_interference->AddForeignSignal(rxDuration, rxPowerW);
501 SwitchMaybeToCcaBusy(nullptr);
502 return;
503 }
504
505 // Do no further processing if signal is too weak
506 // Current implementation assumes constant RX power over the PPDU duration
507 // Compare received TX power per MHz to normalized RX sensitivity
508 const auto ppdu = GetRxPpduFromTxPpdu(wifiRxParams->ppdu);
509 if (totalRxPowerW < DbmToW(GetRxSensitivity()) * (ppdu->GetTxChannelWidth() / 20.0))
510 {
511 NS_LOG_INFO("Received signal too weak to process: " << WToDbm(totalRxPowerW) << " dBm");
512 m_interference->Add(ppdu, rxDuration, rxPowerW);
513 SwitchMaybeToCcaBusy(nullptr);
514 return;
515 }
516
517 if (wifiRxParams->txPhy)
518 {
519 if (!CanStartRx(ppdu))
520 {
521 NS_LOG_INFO("Cannot start reception of the PPDU, consider it as interference");
522 m_interference->Add(ppdu, rxDuration, rxPowerW);
524 return;
525 }
526 }
527
528 NS_LOG_INFO("Received Wi-Fi signal");
529 StartReceivePreamble(ppdu, rxPowerW, rxDuration);
530}
531
534{
535 return GetPhyEntityForPpdu(ppdu)->GetRxPpduFromTxPpdu(ppdu);
536}
537
540{
541 return m_antenna;
542}
543
544void
546{
547 NS_LOG_FUNCTION(this << a);
548 m_antenna = a;
549}
550
551void
553{
554 NS_LOG_FUNCTION(this << device);
555 WifiPhy::SetDevice(device);
556 for (auto& spectrumPhyInterface : m_spectrumPhyInterfaces)
557 {
558 spectrumPhyInterface.second->SetDevice(device);
559 }
560}
561
562void
564{
565 NS_LOG_FUNCTION(this << ppdu);
566 GetPhyEntity(ppdu->GetModulation())->StartTx(ppdu);
567}
568
569void
571{
572 NS_LOG_FUNCTION(this << txParams);
574 m_currentSpectrumPhyInterface->StartTx(txParams);
575}
576
577uint16_t
578SpectrumWifiPhy::GetGuardBandwidth(uint16_t currentChannelWidth) const
579{
580 uint16_t guardBandwidth = 0;
581 if (currentChannelWidth == 22)
582 {
583 // handle case of DSSS transmission
584 guardBandwidth = 10;
585 }
586 else
587 {
588 // In order to properly model out of band transmissions for OFDM, the guard
589 // band has been configured so as to expand the modeled spectrum up to the
590 // outermost referenced point in "Transmit spectrum mask" sections' PSDs of
591 // each PHY specification of 802.11-2016 standard. It thus ultimately corresponds
592 // to the currently considered channel bandwidth (which can be different from
593 // supported channel width).
594 guardBandwidth = currentChannelWidth;
595 }
596 return guardBandwidth;
597}
598
601 uint16_t bandWidth,
602 uint8_t bandIndex /* = 0 */)
603{
604 const auto subcarrierSpacing = GetSubcarrierSpacing();
605 const auto channelWidth = spectrumPhyInterface->GetChannelWidth();
606 const auto numBandsInBand = static_cast<size_t>(bandWidth * 1e6 / subcarrierSpacing);
607 auto numBandsInChannel = static_cast<size_t>(channelWidth * 1e6 / subcarrierSpacing);
608 if (numBandsInBand % 2 == 0)
609 {
610 numBandsInChannel += 1; // symmetry around center frequency
611 }
612 auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel();
613 size_t totalNumBands = rxSpectrumModel->GetNumBands();
614 NS_ASSERT_MSG((numBandsInChannel % 2 == 1) && (totalNumBands % 2 == 1),
615 "Should have odd number of bands");
616 NS_ASSERT_MSG((bandIndex * bandWidth) < channelWidth, "Band index is out of bound");
617 NS_ASSERT(totalNumBands >= numBandsInChannel);
618 auto startIndex = ((totalNumBands - numBandsInChannel) / 2) + (bandIndex * numBandsInBand);
619 auto stopIndex = startIndex + numBandsInBand - 1;
620 auto frequencies =
621 ConvertIndicesToFrequenciesForInterface(spectrumPhyInterface, {startIndex, stopIndex});
622 auto freqRange = spectrumPhyInterface->GetFrequencyRange();
623 NS_ASSERT(frequencies.first >= (freqRange.minFrequency * 1e6));
624 NS_ASSERT(frequencies.second <= (freqRange.maxFrequency * 1e6));
625 NS_ASSERT((frequencies.second - frequencies.first) == (bandWidth * 1e6));
626 if (startIndex >= totalNumBands / 2)
627 {
628 // step past DC
629 startIndex += 1;
630 }
631 return {{startIndex, stopIndex}, frequencies};
632}
633
635SpectrumWifiPhy::GetBand(uint16_t bandWidth, uint8_t bandIndex /* = 0 */)
636{
638 return GetBandForInterface(m_currentSpectrumPhyInterface, bandWidth, bandIndex);
639}
640
643{
646}
647
650 Ptr<WifiSpectrumPhyInterface> spectrumPhyInterface,
651 const WifiSpectrumBandIndices& indices) const
652{
653 NS_ABORT_IF(!spectrumPhyInterface);
654 auto rxSpectrumModel = spectrumPhyInterface->GetRxSpectrumModel();
655 auto startGuardBand = rxSpectrumModel->Begin();
656 auto startChannel = std::next(startGuardBand, indices.first);
657 auto endChannel = std::next(startGuardBand, indices.second + 1);
658 auto lowFreq = static_cast<uint64_t>(startChannel->fc);
659 auto highFreq = static_cast<uint64_t>(endChannel->fc);
660 return {lowFreq, highFreq};
661}
662
663std::tuple<double, double, double>
665{
666 return std::make_tuple(m_txMaskInnerBandMinimumRejection,
669}
670
673{
675 return m_currentSpectrumPhyInterface->GetFrequencyRange();
676}
677
678const std::map<FrequencyRange, Ptr<WifiSpectrumPhyInterface>>&
680{
682}
683
685SpectrumWifiPhy::GetInterfaceCoveringChannelBand(uint16_t frequency, uint16_t width) const
686{
687 const auto lowFreq = frequency - (width / 2);
688 const auto highFreq = frequency + (width / 2);
689 const auto it = std::find_if(m_spectrumPhyInterfaces.cbegin(),
691 [lowFreq, highFreq](const auto& item) {
692 return ((lowFreq >= item.first.minFrequency) &&
693 (highFreq <= item.first.maxFrequency));
694 });
695 if (it == std::end(m_spectrumPhyInterfaces))
696 {
697 return nullptr;
698 }
699 return it->second;
700}
701
704{
706}
707
708void
710{
711 m_channelSwitchedCallback = callback;
712}
713
714} // 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:575
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
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:1822
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:475
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:587
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:491
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:212
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:592
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:930
802.11 PHY layer model
Definition: wifi-phy.h:53
uint32_t GetSubcarrierSpacing() const
Definition: wifi-phy.cc:2232
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1035
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:488
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1023
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:713
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:609
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1861
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:615
void DoDispose() override
Destructor implementation.
Definition: wifi-phy.cc:401
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition: wifi-phy.cc:1169
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1243
void DoInitialize() override
Initialize() implementation.
Definition: wifi-phy.cc:376
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1011
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:734
void SwitchMaybeToCcaBusy(const Ptr< const WifiPpdu > ppdu)
Check if PHY state should move to CCA busy state based on current state of interference tracker.
Definition: wifi-phy.cc:2091
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1017
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition: wifi-phy.cc:728
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:86
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.