A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-phy.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 * Sébastien Deronne <sebastien.deronne@gmail.com>
8 */
9
10#include "wifi-phy.h"
11
12#include "error-rate-model.h"
13#include "frame-capture-model.h"
14#include "interference-helper.h"
16#include "wifi-net-device.h"
17#include "wifi-ppdu.h"
18#include "wifi-psdu.h"
20#include "wifi-utils.h"
21
22#include "ns3/attribute-container.h"
23#include "ns3/channel.h"
24#include "ns3/dsss-phy.h"
25#include "ns3/eht-phy.h" //also includes OFDM, HT, VHT and HE
26#include "ns3/erp-ofdm-phy.h"
27#include "ns3/error-model.h"
28#include "ns3/ht-configuration.h"
29#include "ns3/log.h"
30#include "ns3/mobility-model.h"
31#include "ns3/pointer.h"
32#include "ns3/random-variable-stream.h"
33#include "ns3/simulator.h"
34#include "ns3/string.h"
35#include "ns3/tuple.h"
36#include "ns3/vht-configuration.h"
37
38#include <algorithm>
39#include <numeric>
40
41#undef NS_LOG_APPEND_CONTEXT
42#define NS_LOG_APPEND_CONTEXT \
43 WIFI_PHY_NS_LOG_APPEND_CONTEXT( \
44 (m_device && (m_device->GetNPhys() > m_phyId) && m_device->GetPhy(m_phyId) \
45 ? m_device->GetPhy(m_phyId) \
46 : nullptr))
47
48namespace ns3
49{
50
52
53/****************************************************************
54 * The actual WifiPhy class
55 ****************************************************************/
56
58
59TypeId
61{
62 static TypeId tid =
63 TypeId("ns3::WifiPhy")
65 .SetGroupName("Wifi")
66 .AddAttribute("Channel",
67 "The channel attached to this PHY",
72 .AddAttribute(
73 "ChannelSettings",
74 "A vector of tuple {channel number, channel width (MHz), PHY band, primary20 "
75 "index} "
76 "describing the settings of the operating channel for each segment. "
77 "The primary20 index (only the value set for the first segment is used) "
78 "is the index of the primary 20 MHz channel within the operating channel "
79 "(0 indicates the 20 MHz subchannel with the lowest center frequency) and "
80 "is only valid if the width of the operating channel is a multiple of 20 MHz. "
81 "If the standard for this object has not been set yet, the value of this "
82 "attribute is saved and will be used to set the operating channel when the "
83 "standard is configured. If the PHY band is left unspecified, the default "
84 "band for the configured standard is used. If the channel width and the "
85 "channel number are both 0, the default channel width for the configured "
86 "standard and band are used. If the channel number is 0, the default "
87 "channel number for the configured standard, band and channel width is used. "
88 "Note that the channel width can be left unspecified (0) if the channel "
89 "number uniquely identify a frequency channel for the given standard and band.",
90 StringValue("{0, 0, BAND_UNSPECIFIED, 0}"),
93 ';'>(static_cast<void (WifiPhy::*)(const ChannelSegments&)>(
104 "BAND_2_4GHZ",
106 "BAND_5GHZ",
108 "BAND_6GHZ",
110 "BAND_UNSPECIFIED"),
112 .AddAttribute("Frequency",
113 "The center frequency (MHz) of the current operating channel.",
115 UintegerValue(0),
118 .AddAttribute("ChannelNumber",
119 "The channel number of the current operating channel.",
121 UintegerValue(0),
124 .AddAttribute(
125 "ChannelWidth",
126 "The width in MHz of the current operating channel (5, 10, 20, 22, 40, 80, 160 or "
127 "320). If 80+80MHz is used, this corresponds to the total channel width, hence 160 "
128 "MHz.",
130 UintegerValue(0),
133 .AddAttribute(
134 "Primary20MHzIndex",
135 "The index of the primary 20 MHz channel within the current operating channel "
136 "(0 indicates the 20 MHz subchannel with the lowest center frequency).",
137 UintegerValue(0),
140 .AddAttribute("FixedPhyBand",
141 "If set to true, changing PHY band is prohibited after initialization.",
142 BooleanValue(false),
145 .AddAttribute(
146 "MaxRadioBw",
147 "The maximum width supported by the radio. It is not possible to configure an "
148 "operating channel with a total width larger than this value. A value of 0 means "
149 "no restriction.",
150 TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, // prevent setting after construction
151 DoubleValue(MHz_u{0}),
154 .AddAttribute(
155 "RxSensitivity",
156 "The energy of a received signal should be higher than "
157 "this threshold (dBm) for the PHY to detect the signal. "
158 "This threshold refers to a width of 20 MHz and will be "
159 "scaled to match the width of the received signal.",
160 DoubleValue(-101.0),
163 .AddAttribute(
164 "CcaEdThreshold",
165 "The energy of all received signals should be higher than "
166 "this threshold (dBm) in the primary channel to allow the PHY layer "
167 "to declare CCA BUSY state.",
168 DoubleValue(-62.0),
171 .AddAttribute("CcaSensitivity",
172 "The energy of a received wifi signal should be higher than "
173 "this threshold (dBm) in the primary channel to allow the PHY layer "
174 "to declare CCA BUSY state.",
175 DoubleValue(-82.0),
179 .AddAttribute("TxGain",
180 "Transmission gain (dB).",
181 DoubleValue(0.0),
184 .AddAttribute("RxGain",
185 "Reception gain (dB).",
186 DoubleValue(0.0),
189 .AddAttribute("TxPowerLevels",
190 "Number of transmission power levels available between "
191 "TxPowerStart and TxPowerEnd included.",
192 UintegerValue(1),
195 .AddAttribute("TxPowerEnd",
196 "Maximum available transmission level (dBm).",
197 DoubleValue(16.0206),
200 .AddAttribute("TxPowerStart",
201 "Minimum available transmission level (dBm).",
202 DoubleValue(16.0206),
205 .AddAttribute(
206 "RxNoiseFigure",
207 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
208 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
209 "\"the difference in decibels (dB) between"
210 " the noise output of the actual receiver to the noise output of an "
211 " ideal receiver with the same overall gain and bandwidth when the receivers "
212 " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
213 DoubleValue(7),
216 .AddAttribute("State",
217 "The state of the PHY layer.",
218 PointerValue(),
221 .AddAttribute("ChannelSwitchDelay",
222 "Delay between two short frames transmitted on different frequencies.",
223 TimeValue(MicroSeconds(250)),
226 .AddAttribute(
227 "Antennas",
228 "The number of antennas on the device.",
229 UintegerValue(1),
232 .AddAttribute("MaxSupportedTxSpatialStreams",
233 "The maximum number of supported TX spatial streams."
234 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
235 UintegerValue(1),
239 .AddAttribute("MaxSupportedRxSpatialStreams",
240 "The maximum number of supported RX spatial streams."
241 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
242 UintegerValue(1),
246 .AddAttribute("ShortPlcpPreambleSupported",
247 "Whether or not short PHY preamble is supported."
248 "This parameter is only valuable for 802.11b STAs and APs."
249 "Note: 802.11g APs and STAs always support short PHY preamble.",
250 BooleanValue(false),
254 .AddAttribute("FrameCaptureModel",
255 "Ptr to an object that implements the frame capture model",
256 PointerValue(),
259 .AddAttribute("PreambleDetectionModel",
260 "Ptr to an object that implements the preamble detection model",
261 PointerValue(),
264 .AddAttribute("PostReceptionErrorModel",
265 "An optional packet error model can be added to the receive "
266 "packet process after any propagation-based (SNR-based) error "
267 "models have been applied. Typically this is used to force "
268 "specific packet drops, for testing purposes.",
269 PointerValue(),
272 .AddAttribute("InterferenceHelper",
273 "Ptr to an object that implements the interference helper",
274 PointerValue(),
277 .AddAttribute("Sifs",
278 "The duration of the Short Interframe Space. "
279 "NOTE that the default value is overwritten by the value defined "
280 "by the standard; if you want to set this attribute, you have to "
281 "do it after that the PHY object is initialized.",
282 TimeValue(MicroSeconds(0)),
285 .AddAttribute("Slot",
286 "The duration of a slot. "
287 "NOTE that the default value is overwritten by the value defined "
288 "by the standard; if you want to set this attribute, you have to "
289 "do it after that the PHY object is initialized.",
290 TimeValue(MicroSeconds(0)),
293 .AddAttribute("Pifs",
294 "The duration of the PCF Interframe Space. "
295 "NOTE that the default value is overwritten by the value defined "
296 "by the standard; if you want to set this attribute, you have to "
297 "do it after that the PHY object is initialized.",
298 TimeValue(MicroSeconds(0)),
301 .AddAttribute("PowerDensityLimit",
302 "The mean equivalent isotropically radiated power density"
303 "limit (in dBm/MHz) set by regulators.",
304 DoubleValue(100.0), // set to a high value so as to have no effect
307 .AddAttribute("NotifyMacHdrRxEnd",
308 "Whether the PHY is capable of notifying the MAC about the end of "
309 "the reception of the MAC header of every MPDU.",
310 BooleanValue(false),
313 .AddTraceSource(
314 "PhyTxBegin",
315 "Trace source indicating a packet has begun transmitting over the medium; "
316 "the packet holds a single MPDU even if the MPDU is transmitted within an A-MPDU "
317 "(in which case this trace fires for each MPDU in the "
318 "A-MPDU).",
320 "ns3::WifiPhy::PhyTxBeginTracedCallback")
321 .AddTraceSource(
322 "PhyTxPsduBegin",
323 "Trace source indicating a PSDU has begun transmitting over the channel medium; "
324 "this trace returns a WifiConstPsduMap with a single element (in the case of SU "
325 "PPDU) "
326 "or multiple elements (in the case of MU PPDU)",
328 "ns3::WifiPhy::PsduTxBeginCallback")
329 .AddTraceSource("PhyTxEnd",
330 "Trace source indicating a packet "
331 "has been completely transmitted over the channel.",
333 "ns3::Packet::TracedCallback")
334 .AddTraceSource("PhyTxDrop",
335 "Trace source indicating a packet "
336 "has been dropped by the device during transmission",
338 "ns3::Packet::TracedCallback")
339 .AddTraceSource("PhyRxBegin",
340 "Trace source indicating a packet "
341 "has begun being received from the channel medium "
342 "by the device",
344 "ns3::WifiPhy::PhyRxBeginTracedCallback")
345 .AddTraceSource("PhyRxPayloadBegin",
346 "Trace source indicating the reception of the "
347 "payload of a PPDU has begun",
349 "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
350 .AddTraceSource("PhyRxMacHeaderEnd",
351 "Trace source indicating the MAC header of an MPDU has been "
352 "completely received.",
354 "ns3::WifiPhy::PhyRxMacHeaderEndTracedCallback")
355 .AddTraceSource("PhyRxEnd",
356 "Trace source indicating a packet "
357 "has been completely received from the channel medium "
358 "by the device",
360 "ns3::Packet::TracedCallback")
361 .AddTraceSource("PhyRxDrop",
362 "Trace source indicating a packet "
363 "has been dropped by the device during reception",
365 "ns3::WifiPhy::PhyRxDropTracedCallback")
366 .AddTraceSource("PhyRxPpduDrop",
367 "Trace source indicating a ppdu "
368 "has been dropped by the device during reception",
370 "ns3::WifiPhy::PhyRxPpduDropTracedCallback")
371 .AddTraceSource("MonitorSnifferRx",
372 "Trace source simulating a wifi device in monitor mode "
373 "sniffing all received frames",
375 "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
376 .AddTraceSource("MonitorSnifferTx",
377 "Trace source simulating the capability of a wifi device "
378 "in monitor mode to sniff all frames being transmitted",
380 "ns3::WifiPhy::MonitorSnifferTxTracedCallback")
381 .AddTraceSource("SignalTransmission",
382 "Trace start of signal transmission",
384 "ns3::SpectrumWifiPhy::SignalTransmissionCallback");
385 return tid;
386}
387
389 : m_phyId(0),
390 m_txMpduReferenceNumber(0xffffffff),
391 m_rxMpduReferenceNumber(0xffffffff),
392 m_endPhyRxEvent(),
393 m_endTxEvent(),
394 m_currentEvent(nullptr),
395 m_previouslyRxPpduUid(UINT64_MAX),
396 m_standard(WIFI_STANDARD_UNSPECIFIED),
397 m_maxModClassSupported(WIFI_MOD_CLASS_UNKNOWN),
399 m_sifs(),
400 m_slot(),
401 m_pifs(),
402 m_powerRestricted(false),
403 m_channelAccessRequested(false),
404 m_txSpatialStreams(1),
405 m_rxSpatialStreams(1),
406 m_wifiRadioEnergyModel(nullptr),
407 m_timeLastPreambleDetected()
408{
409 NS_LOG_FUNCTION(this);
412}
413
415{
416 NS_LOG_FUNCTION(this);
417}
418
419void
421{
422 NS_LOG_FUNCTION(this);
423
424 // This method ensures that the local mobility model pointer holds
425 // a pointer to the Node's aggregated mobility model (if one exists)
426 // in the case that the user has not directly called SetMobility()
427 // on this WifiPhy during simulation setup. If the mobility model
428 // needs to be added or changed during simulation runtime, users must
429 // call SetMobility() on this object.
430
431 if (!m_mobility)
432 {
434 "Either install a MobilityModel on this object or ensure that this "
435 "object is part of a Node and NetDevice");
436 m_mobility = m_device->GetNode()->GetObject<MobilityModel>();
437 if (!m_mobility)
438 {
439 NS_LOG_WARN("Mobility not found, propagation models might not work properly");
440 }
441 }
442}
443
444void
446{
447 NS_LOG_FUNCTION(this);
448
449 m_device = nullptr;
450 m_mobility = nullptr;
451 m_frameCaptureModel = nullptr;
452 m_preambleDetectionModel = nullptr;
453 m_wifiRadioEnergyModel = nullptr;
455 if (m_interference)
456 {
457 m_interference->Dispose();
458 }
459 m_interference = nullptr;
460 m_random = nullptr;
461 m_state = nullptr;
462
463 Reset();
464
465 // this should be done after calling the Reset function
466 for (auto& phyEntity : m_phyEntities)
467 {
468 phyEntity.second = nullptr;
469 }
470 m_phyEntities.clear();
471}
472
473std::map<WifiModulationClass, Ptr<PhyEntity>>&
475{
476 static std::map<WifiModulationClass, Ptr<PhyEntity>> g_staticPhyEntities;
477 return g_staticPhyEntities;
478}
479
482{
483 return m_state;
484}
485
486void
488{
489 m_state->SetReceiveOkCallback(callback);
490}
491
492void
494{
495 m_state->SetReceiveErrorCallback(callback);
496}
497
498void
499WifiPhy::RegisterListener(const std::shared_ptr<WifiPhyListener>& listener)
500{
501 m_state->RegisterListener(listener);
502 if (IsInitialized())
503 {
504 // provide CCA busy information upon registering a PHY listener
505 SwitchMaybeToCcaBusy(nullptr);
506 }
507}
508
509void
510WifiPhy::UnregisterListener(const std::shared_ptr<WifiPhyListener>& listener)
511{
512 m_state->UnregisterListener(listener);
513}
514
515void
520
521void
523{
524 NS_LOG_FUNCTION(this << threshold);
525 m_rxSensitivity = threshold;
526}
527
528dBm_u
530{
531 return m_rxSensitivity;
532}
533
534void
536{
537 NS_LOG_FUNCTION(this << threshold);
538 m_ccaEdThreshold = threshold;
539}
540
541dBm_u
543{
544 return m_ccaEdThreshold;
545}
546
547void
549{
550 NS_LOG_FUNCTION(this << threshold);
551 m_ccaSensitivityThreshold = threshold;
552}
553
554dBm_u
559
560void
562{
563 NS_LOG_FUNCTION(this << noiseFigure);
564 if (m_interference)
565 {
566 m_interference->SetNoiseFigure(DbToRatio(noiseFigure));
567 }
568 m_noiseFigure = noiseFigure;
569}
570
571void
573{
574 NS_LOG_FUNCTION(this << start);
575 m_txPowerBase = start;
576}
577
578dBm_u
580{
581 return m_txPowerBase;
582}
583
584void
586{
587 NS_LOG_FUNCTION(this << end);
588 m_txPowerEnd = end;
589}
590
591dBm_u
593{
594 return m_txPowerEnd;
595}
596
597void
599{
600 NS_LOG_FUNCTION(this << +n);
601 m_nTxPower = n;
602}
603
604uint8_t
606{
607 return m_nTxPower;
608}
609
610void
612{
613 NS_LOG_FUNCTION(this << gain);
614 m_txGain = gain;
615}
616
617dB_u
619{
620 return m_txGain;
621}
622
623void
625{
626 NS_LOG_FUNCTION(this << gain);
627 m_rxGain = gain;
628}
629
630dB_u
632{
633 return m_rxGain;
634}
635
636void
638{
639 NS_LOG_FUNCTION(this << enable);
640 m_shortPreamble = enable;
641}
642
643bool
648
649void
651{
652 m_device = device;
653}
654
657{
658 return m_device;
659}
660
661void
663{
664 m_mobility = mobility;
665}
666
669{
670 return m_mobility;
671}
672
673void
674WifiPhy::SetPhyId(uint8_t phyId)
675{
676 NS_LOG_FUNCTION(this << phyId);
677 m_phyId = phyId;
678}
679
680uint8_t
682{
683 return m_phyId;
684}
685
686void
688{
689 NS_LOG_FUNCTION(this << helper);
690 m_interference = helper;
691 m_interference->SetNoiseFigure(DbToRatio(m_noiseFigure));
692 m_interference->SetNumberOfReceiveAntennas(m_numberOfAntennas);
693}
694
695void
697{
698 NS_LOG_FUNCTION(this << model);
700 m_interference->SetErrorRateModel(model);
701}
702
703void
709
710void
715
716void
721
722void
724{
725 m_wifiRadioEnergyModel = wifiRadioEnergyModel;
726}
727
728dBm_u
729WifiPhy::GetPower(uint8_t powerLevel) const
730{
733 dBm_u dbm;
734 if (m_nTxPower > 1)
735 {
736 dbm = m_txPowerBase + dB_u{powerLevel * (m_txPowerEnd - m_txPowerBase) / (m_nTxPower - 1)};
737 }
738 else
739 {
741 "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
742 dbm = m_txPowerBase;
743 }
744 return dbm;
745}
746
747Time
752
753double
754WifiPhy::CalculateSnr(const WifiTxVector& txVector, double ber) const
755{
756 return m_interference->GetErrorRateModel()->CalculateSnr(txVector, ber);
757}
758
761{
762 const auto it = GetStaticPhyEntities().find(modulation);
764 "Unimplemented Wi-Fi modulation class " << modulation);
765 return it->second;
766}
767
770{
771 const auto it = m_phyEntities.find(modulation);
772 NS_ABORT_MSG_IF(it == m_phyEntities.cend(),
773 "Unsupported Wi-Fi modulation class " << modulation);
774 return it->second;
775}
776
779{
781}
782
788
791{
792 NS_ABORT_IF(!ppdu);
793 const auto modulation = ppdu->GetModulation();
794 if (modulation > m_phyEntities.rbegin()->first)
795 {
796 // unsupported modulation: start reception process with latest PHY entity
797 return GetLatestPhyEntity();
798 }
799 if (modulation < WIFI_MOD_CLASS_HT)
800 {
801 // for non-HT (duplicate), call the latest PHY entity since some extra processing can be
802 // done in PHYs implemented in HT and later (e.g. channel width selection for non-HT
803 // duplicates)
804 return GetLatestPhyEntity();
805 }
806 return GetPhyEntity(modulation);
807}
808
809void
811{
812 NS_ASSERT_MSG(!GetStaticPhyEntities().contains(modulation),
813 "The PHY entity has already been added. The setting should only be done once per "
814 "modulation class");
815 GetStaticPhyEntities()[modulation] = phyEntity;
816}
817
818void
820{
821 NS_LOG_FUNCTION(this << modulation);
822 NS_ABORT_MSG_IF(!GetStaticPhyEntities().contains(modulation),
823 "Cannot add an unimplemented PHY to supported list. Update the former first.");
824 NS_ASSERT_MSG(m_phyEntities.find(modulation) == m_phyEntities.end(),
825 "The PHY entity has already been added. The setting should only be done once per "
826 "modulation class");
827 phyEntity->SetOwner(this);
828 m_phyEntities[modulation] = phyEntity;
829}
830
831void
833{
834 m_sifs = sifs;
835}
836
837Time
839{
840 return m_sifs;
841}
842
843void
845{
846 m_slot = slot;
847}
848
849Time
851{
852 return m_slot;
853}
854
855void
857{
858 m_pifs = pifs;
859}
860
861Time
863{
864 return m_pifs;
865}
866
867void
869{
870 NS_LOG_FUNCTION(this);
872
873 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
876 SetPifs(GetSifs() + GetSlot());
877 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
878 // of the PPDU causing the EIFS" of 802.11-2016
879}
880
881void
883{
884 NS_LOG_FUNCTION(this);
885 Ptr<DsssPhy> phyEntity = Create<DsssPhy>();
887 AddPhyEntity(WIFI_MOD_CLASS_DSSS, phyEntity); // when plain DSSS modes are used
888
891 SetPifs(GetSifs() + GetSlot());
892 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
893 // of the PPDU causing the EIFS" of 802.11-2016
894}
895
896void
898{
899 NS_LOG_FUNCTION(this);
900 // See Table 18-5 "ERP characteristics" of 802.11-2016
901 // Slot time defaults to the "long slot time" of 20 us in the standard
902 // according to mixed 802.11b/g deployments. Short slot time is enabled
903 // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
904 // consists of only ERP STAs capable of supporting this option.
907}
908
909void
911{
912 NS_LOG_FUNCTION(this);
913 if (GetChannelWidth() == MHz_u{10})
914 {
916
917 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
920 SetPifs(GetSifs() + GetSlot());
921 }
922 else if (GetChannelWidth() == MHz_u{5})
923 {
925
926 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
929 SetPifs(GetSifs() + GetSlot());
930 }
931 else
932 {
933 NS_FATAL_ERROR("802.11p configured with a wrong channel width!");
934 }
935}
936
937void
951
952void
959
960void
962{
963 NS_LOG_FUNCTION(this);
965 {
967 }
968 else
969 {
971 }
973}
974
975void
982
983void
989
995
996void
998{
999 NS_LOG_FUNCTION(this << standard);
1000
1002 "Cannot change standard");
1003
1004 m_standard = standard;
1005
1007 {
1009 }
1010
1012 {
1013 NS_LOG_DEBUG("Setting the operating channel first");
1015 // return because we are called back by SetOperatingChannel
1016 return;
1017 }
1018
1019 // this function is called when changing PHY band, hence we have to delete
1020 // the previous PHY entities
1021 m_phyEntities.clear();
1022
1023 switch (standard)
1024 {
1027 break;
1030 break;
1033 break;
1036 break;
1039 break;
1042 break;
1045 break;
1048 break;
1050 default:
1051 NS_ASSERT_MSG(false, "Unsupported standard");
1052 break;
1053 }
1054}
1055
1058{
1059 return m_band;
1060}
1061
1064{
1065 return m_standard;
1066}
1067
1070{
1071 return m_operatingChannel;
1072}
1073
1074MHz_u
1076{
1078}
1079
1080uint8_t
1082{
1084}
1085
1086MHz_u
1091
1092uint8_t
1097
1098void
1100{
1101 m_fixedPhyBand = enable;
1102}
1103
1104bool
1106{
1107 return m_fixedPhyBand;
1108}
1109
1110MHz_u
1111WifiPhy::GetTxBandwidth(WifiMode mode, MHz_u maxAllowedWidth) const
1112{
1113 auto modulation = mode.GetModulationClass();
1114 if (modulation == WIFI_MOD_CLASS_DSSS || modulation == WIFI_MOD_CLASS_HR_DSSS)
1115 {
1116 return MHz_u{22};
1117 }
1118
1119 return std::min({GetChannelWidth(), GetMaximumChannelWidth(modulation), maxAllowedWidth});
1120}
1121
1122void
1124{
1125 NS_LOG_FUNCTION(this << channel);
1126 ChannelSegments segments{};
1127 for (std::size_t segmentId = 0; segmentId < channel.GetNSegments(); ++segmentId)
1128 {
1129 segments.emplace_back(channel.GetNumber(segmentId),
1130 channel.GetWidth(segmentId),
1131 channel.GetPhyBand(),
1132 channel.GetPrimaryChannelIndex(MHz_u{20}));
1133 }
1134 SetOperatingChannel(segments);
1135}
1136
1137void
1142
1143void
1145{
1146 NS_LOG_FUNCTION(this << +std::get<0>(channelSegments.front())
1147 << std::get<1>(channelSegments.front())
1148 << static_cast<WifiPhyBand>(std::get<2>(channelSegments.front()))
1149 << +std::get<3>(channelSegments.front()));
1150
1151 m_channelSettings = channelSegments;
1152
1154 {
1155 NS_LOG_DEBUG("Channel information will be applied when a standard is configured");
1156 return;
1157 }
1158
1159 if (IsInitialized())
1160 {
1161 const auto delay = GetDelayUntilChannelSwitch();
1162 if (!delay.has_value())
1163 {
1164 // switching channel is not possible now
1165 return;
1166 }
1167 if (delay.value().IsStrictlyPositive())
1168 {
1169 // switching channel has been postponed
1171 Simulator::Schedule(delay.value(), fp, this, channelSegments);
1172 return;
1173 }
1174 }
1175
1176 // channel can be switched now.
1178}
1179
1180std::optional<Time>
1182{
1183 if (!IsInitialized())
1184 {
1185 // this is not channel switch, this is initialization
1186 NS_LOG_DEBUG("Before initialization, nothing to do");
1187 return Seconds(0);
1188 }
1189
1190 std::optional<Time> delay;
1191 switch (m_state->GetState())
1192 {
1193 case WifiPhyState::RX:
1194 NS_LOG_DEBUG("drop packet because of channel switching while reception");
1196 delay = Seconds(0);
1197 break;
1198 case WifiPhyState::TX:
1199 NS_LOG_DEBUG("channel switching postponed until end of current transmission");
1200 delay = GetDelayUntilIdle();
1201 break;
1203 case WifiPhyState::IDLE:
1204 Reset();
1205 delay = Seconds(0);
1206 break;
1208 delay = Seconds(0);
1209 break;
1211 NS_LOG_DEBUG("channel switching ignored in sleep mode");
1212 break;
1213 default:
1214 NS_ASSERT(false);
1215 break;
1216 }
1217
1218 return delay;
1219}
1220
1221void
1223{
1224 NS_LOG_FUNCTION(this);
1225
1226 m_powerRestricted = false;
1228
1229 // Update unspecified parameters with default values
1230 std::optional<uint8_t> prevChannelNumber{};
1231 for (auto& [number, width, band, primary20] : m_channelSettings)
1232 {
1233 if (band == WIFI_PHY_BAND_UNSPECIFIED)
1234 {
1236 }
1237 if (width == MHz_u{0} && number == 0)
1238 {
1239 width = GetDefaultChannelWidth(m_standard, static_cast<WifiPhyBand>(band));
1240 }
1241 if (number == 0)
1242 {
1243 number =
1245 m_standard,
1246 static_cast<WifiPhyBand>(band),
1247 prevChannelNumber);
1248 }
1249 prevChannelNumber = number;
1250 }
1251
1252 // We need to call SetStandard if this is the first time we set a channel or we
1253 // are changing PHY band. Checking if the new PHY band is different than the
1254 // previous one covers both cases because initially the PHY band is unspecified
1255 bool changingPhyBand =
1256 (static_cast<WifiPhyBand>(std::get<2>(m_channelSettings.front())) != m_band);
1257
1258 NS_ABORT_MSG_IF(IsInitialized() && m_fixedPhyBand && changingPhyBand,
1259 "Trying to change PHY band while prohibited.");
1260
1261 m_band = static_cast<WifiPhyBand>(std::get<2>(m_channelSettings.front()));
1262
1263 NS_LOG_DEBUG("switching channel");
1264 std::vector<FrequencyChannelInfo> segments{};
1265 std::transform(m_channelSettings.cbegin(),
1266 m_channelSettings.cend(),
1267 std::back_inserter(segments),
1268 [this](const auto& channelTuple) {
1269 return FrequencyChannelInfo{std::get<0>(channelTuple),
1270 MHz_u{0},
1271 std::get<1>(channelTuple),
1272 m_band};
1273 });
1274 m_operatingChannel.Set(segments, m_standard);
1275 m_operatingChannel.SetPrimary20Index(std::get<3>(m_channelSettings.front()));
1276
1277 // check that the channel width is supported
1278 if (const auto chWidth = GetChannelWidth();
1279 (m_maxRadioBw != MHz_u{0}) && (chWidth > m_maxRadioBw))
1280 {
1281 // throw an exception instead of using NS_ABORT_MSG for unit testing this code
1282 throw std::runtime_error("Attempting to set a " + std::to_string(chWidth) +
1283 " MHz channel on a station only supporting " +
1284 std::to_string(m_maxRadioBw) + " MHz operation");
1285 }
1286
1287 if (changingPhyBand)
1288 {
1289 ConfigureStandard(m_standard);
1290 }
1291
1292 FinalizeChannelSwitch();
1293
1294 if (IsInitialized())
1295 {
1296 // notify channel switching
1297 m_state->SwitchToChannelSwitching(GetChannelSwitchDelay());
1299 * Needed here to be able to correctly sensed the medium for the first
1300 * time after the switching. The actual switching is not performed until
1301 * after m_channelSwitchDelay. Packets received during the switching
1302 * state are added to the event list and are employed later to figure
1303 * out the state of the medium after the switching.
1304 */
1305 SwitchMaybeToCcaBusy(nullptr);
1306 }
1307}
1308
1309void
1310WifiPhy::SetNumberOfAntennas(uint8_t antennas)
1311{
1312 NS_LOG_FUNCTION(this << +antennas);
1313 NS_ASSERT_MSG(antennas > 0 && antennas <= 8, "unsupported number of antennas");
1314 m_numberOfAntennas = antennas;
1315 if (m_interference)
1316 {
1317 m_interference->SetNumberOfReceiveAntennas(antennas);
1318 }
1319}
1320
1321uint8_t
1322WifiPhy::GetNumberOfAntennas() const
1323{
1324 return m_numberOfAntennas;
1325}
1326
1327void
1328WifiPhy::SetMaxSupportedTxSpatialStreams(uint8_t streams)
1329{
1330 NS_ASSERT(streams <= GetNumberOfAntennas());
1331 bool changed = (m_txSpatialStreams != streams);
1332 m_txSpatialStreams = streams;
1333 if (changed)
1334 {
1335 auto phyEntity = m_phyEntities.find(WIFI_MOD_CLASS_HT);
1336 if (phyEntity != m_phyEntities.end())
1337 {
1338 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity->second);
1339 if (htPhy)
1340 {
1341 htPhy->SetMaxSupportedNss(
1342 m_txSpatialStreams); // this is essential to have the right MCSs configured
1343 }
1344
1345 if (!m_capabilitiesChangedCallback.IsNull())
1346 {
1347 m_capabilitiesChangedCallback();
1348 }
1349 }
1350 }
1351}
1352
1353uint8_t
1354WifiPhy::GetMaxSupportedTxSpatialStreams() const
1355{
1356 return m_txSpatialStreams;
1357}
1358
1359void
1360WifiPhy::SetMaxSupportedRxSpatialStreams(uint8_t streams)
1361{
1362 NS_ASSERT(streams <= GetNumberOfAntennas());
1363 bool changed = (m_rxSpatialStreams != streams);
1364 m_rxSpatialStreams = streams;
1365 if (changed && !m_capabilitiesChangedCallback.IsNull())
1366 {
1367 m_capabilitiesChangedCallback();
1368 }
1369}
1370
1371uint8_t
1372WifiPhy::GetMaxSupportedRxSpatialStreams() const
1373{
1374 return m_rxSpatialStreams;
1375}
1376
1377std::list<uint8_t>
1378WifiPhy::GetBssMembershipSelectorList() const
1379{
1380 std::list<uint8_t> list;
1381 for (const auto& phyEntity : m_phyEntities)
1382 {
1383 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity.second);
1384 if (htPhy)
1385 {
1386 list.emplace_back(htPhy->GetBssMembershipSelector());
1387 }
1388 }
1389 return list;
1390}
1391
1392void
1393WifiPhy::SetSleepMode(bool forceSleepInRx)
1394{
1395 NS_LOG_FUNCTION(this);
1396 m_powerRestricted = false;
1397 m_channelAccessRequested = false;
1398 switch (m_state->GetState())
1399 {
1400 case WifiPhyState::TX:
1401 NS_LOG_DEBUG("setting sleep mode postponed until end of current transmission");
1402 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this, forceSleepInRx);
1403 break;
1404 case WifiPhyState::RX:
1405 NS_LOG_DEBUG("setting sleep mode"
1406 << (forceSleepInRx ? "" : "postponed until end of current reception"));
1407 if (forceSleepInRx)
1408 {
1409 AbortCurrentReception(WifiPhyRxfailureReason::SLEEPING);
1410 m_state->SwitchToSleep();
1411 }
1412 else
1413 {
1414 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this, forceSleepInRx);
1415 }
1416 break;
1417 case WifiPhyState::SWITCHING:
1418 NS_LOG_DEBUG("setting sleep mode postponed until end of channel switching");
1419 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this, forceSleepInRx);
1420 break;
1421 case WifiPhyState::CCA_BUSY:
1422 case WifiPhyState::IDLE:
1423 NS_LOG_DEBUG("setting sleep mode");
1424 // The PHY object may be in CCA_BUSY state because it is receiving a preamble. Cancel
1425 // preamble events before switching to sleep state
1426 Reset();
1427 m_state->SwitchToSleep();
1428 break;
1429 case WifiPhyState::SLEEP:
1430 NS_LOG_DEBUG("already in sleep mode");
1431 break;
1432 default:
1433 NS_ASSERT(false);
1434 break;
1435 }
1436}
1437
1438void
1439WifiPhy::SetOffMode()
1440{
1441 NS_LOG_FUNCTION(this);
1442 m_powerRestricted = false;
1443 m_channelAccessRequested = false;
1444 Reset();
1445 m_state->SwitchToOff();
1446}
1447
1448void
1449WifiPhy::ResumeFromSleep()
1450{
1451 NS_LOG_FUNCTION(this);
1452 switch (m_state->GetState())
1453 {
1454 case WifiPhyState::TX:
1455 case WifiPhyState::RX:
1456 case WifiPhyState::IDLE:
1457 case WifiPhyState::CCA_BUSY:
1458 case WifiPhyState::SWITCHING: {
1459 NS_LOG_DEBUG("not in sleep mode, there is nothing to resume");
1460 break;
1461 }
1462 case WifiPhyState::SLEEP: {
1463 NS_LOG_DEBUG("resuming from sleep mode");
1464 m_state->SwitchFromSleep();
1465 SwitchMaybeToCcaBusy();
1466 break;
1467 }
1468 default: {
1469 NS_ASSERT(false);
1470 break;
1471 }
1472 }
1473}
1474
1475void
1476WifiPhy::ResumeFromOff()
1477{
1478 NS_LOG_FUNCTION(this);
1479 switch (m_state->GetState())
1480 {
1481 case WifiPhyState::TX:
1482 case WifiPhyState::RX:
1483 case WifiPhyState::IDLE:
1484 case WifiPhyState::CCA_BUSY:
1485 case WifiPhyState::SWITCHING:
1486 case WifiPhyState::SLEEP: {
1487 NS_LOG_DEBUG("not in off mode, there is nothing to resume");
1488 break;
1489 }
1490 case WifiPhyState::OFF: {
1491 NS_LOG_DEBUG("resuming from off mode");
1492 m_state->SwitchFromOff();
1493 SwitchMaybeToCcaBusy();
1494 break;
1495 }
1496 default: {
1497 NS_ASSERT(false);
1498 break;
1499 }
1500 }
1501}
1502
1503Time
1504WifiPhy::GetPreambleDetectionDuration()
1505{
1506 return MicroSeconds(4);
1507}
1508
1509Time
1510WifiPhy::GetStartOfPacketDuration(const WifiTxVector& txVector)
1511{
1512 return MicroSeconds(4);
1513}
1514
1515Time
1516WifiPhy::GetPayloadDuration(uint32_t size,
1517 const WifiTxVector& txVector,
1518 WifiPhyBand band,
1519 MpduType mpdutype,
1520 uint16_t staId)
1521{
1522 uint32_t totalAmpduSize;
1523 double totalAmpduNumSymbols;
1524 return GetPayloadDuration(size,
1525 txVector,
1526 band,
1527 mpdutype,
1528 false,
1529 totalAmpduSize,
1530 totalAmpduNumSymbols,
1531 staId);
1532}
1533
1534Time
1535WifiPhy::GetPayloadDuration(uint32_t size,
1536 const WifiTxVector& txVector,
1537 WifiPhyBand band,
1538 MpduType mpdutype,
1539 bool incFlag,
1540 uint32_t& totalAmpduSize,
1541 double& totalAmpduNumSymbols,
1542 uint16_t staId)
1543{
1544 return GetStaticPhyEntity(txVector.GetModulationClass())
1545 ->GetPayloadDuration(size,
1546 txVector,
1547 band,
1548 mpdutype,
1549 incFlag,
1550 totalAmpduSize,
1551 totalAmpduNumSymbols,
1552 staId);
1553}
1554
1555Time
1556WifiPhy::CalculatePhyPreambleAndHeaderDuration(const WifiTxVector& txVector)
1557{
1558 return GetStaticPhyEntity(txVector.GetModulationClass())
1559 ->CalculatePhyPreambleAndHeaderDuration(txVector);
1560}
1561
1562Time
1563WifiPhy::CalculateTxDuration(uint32_t size,
1564 const WifiTxVector& txVector,
1565 WifiPhyBand band,
1566 uint16_t staId)
1567{
1568 NS_ASSERT(txVector.IsValid(band));
1569 Time duration = CalculatePhyPreambleAndHeaderDuration(txVector) +
1570 GetPayloadDuration(size, txVector, band, NORMAL_MPDU, staId);
1571 NS_ASSERT(duration.IsStrictlyPositive());
1572 return duration;
1573}
1574
1575Time
1576WifiPhy::CalculateTxDuration(Ptr<const WifiPsdu> psdu,
1577 const WifiTxVector& txVector,
1578 WifiPhyBand band)
1579{
1580 return CalculateTxDuration(GetWifiConstPsduMap(psdu, txVector), txVector, band);
1581}
1582
1583Time
1584WifiPhy::CalculateTxDuration(const WifiConstPsduMap& psduMap,
1585 const WifiTxVector& txVector,
1586 WifiPhyBand band)
1587{
1588 NS_ASSERT(txVector.IsValid(band));
1589 return GetStaticPhyEntity(txVector.GetModulationClass())
1590 ->CalculateTxDuration(psduMap, txVector, band);
1591}
1592
1594WifiPhy::GetMaxPsduSize(WifiModulationClass modulation)
1595{
1596 return GetStaticPhyEntity(modulation)->GetMaxPsduSize();
1597}
1598
1599void
1600WifiPhy::NotifyTxBegin(const WifiConstPsduMap& psdus, Watt_u txPower)
1601{
1602 if (!m_phyTxBeginTrace.IsEmpty())
1603 {
1604 for (const auto& psdu : psdus)
1605 {
1606 for (auto& mpdu : *PeekPointer(psdu.second))
1607 {
1608 m_phyTxBeginTrace(mpdu->GetProtocolDataUnit(), txPower);
1609 }
1610 }
1611 }
1612}
1613
1614void
1615WifiPhy::NotifyTxEnd(const WifiConstPsduMap& psdus)
1616{
1617 if (!m_phyTxEndTrace.IsEmpty())
1618 {
1619 for (const auto& psdu : psdus)
1620 {
1621 for (auto& mpdu : *PeekPointer(psdu.second))
1622 {
1623 m_phyTxEndTrace(mpdu->GetProtocolDataUnit());
1624 }
1625 }
1626 }
1627}
1628
1629void
1630WifiPhy::NotifyTxDrop(Ptr<const WifiPsdu> psdu)
1631{
1632 if (!m_phyTxDropTrace.IsEmpty())
1633 {
1634 for (auto& mpdu : *PeekPointer(psdu))
1635 {
1636 m_phyTxDropTrace(mpdu->GetProtocolDataUnit());
1637 }
1638 }
1639}
1640
1641void
1642WifiPhy::NotifyRxBegin(Ptr<const WifiPsdu> psdu, const RxPowerWattPerChannelBand& rxPowersW)
1643{
1644 if (psdu && !m_phyRxBeginTrace.IsEmpty())
1645 {
1646 for (auto& mpdu : *PeekPointer(psdu))
1647 {
1648 m_phyRxBeginTrace(mpdu->GetProtocolDataUnit(), rxPowersW);
1649 }
1650 }
1651}
1652
1653void
1654WifiPhy::NotifyRxEnd(Ptr<const WifiPsdu> psdu)
1655{
1656 if (psdu && !m_phyRxEndTrace.IsEmpty())
1657 {
1658 for (auto& mpdu : *PeekPointer(psdu))
1659 {
1660 m_phyRxEndTrace(mpdu->GetProtocolDataUnit());
1661 }
1662 }
1663}
1664
1665void
1666WifiPhy::NotifyRxDrop(Ptr<const WifiPsdu> psdu, WifiPhyRxfailureReason reason)
1667{
1668 if (psdu && !m_phyRxDropTrace.IsEmpty())
1669 {
1670 for (auto& mpdu : *PeekPointer(psdu))
1671 {
1672 m_phyRxDropTrace(mpdu->GetProtocolDataUnit(), reason);
1673 }
1674 }
1675}
1676
1677void
1678WifiPhy::NotifyRxPpduDrop(Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason)
1679{
1680 NotifyRxDrop(GetAddressedPsduInPpdu(ppdu), reason);
1681 m_phyRxPpduDropTrace(ppdu, reason);
1682}
1683
1684void
1685WifiPhy::NotifyMonitorSniffRx(Ptr<const WifiPsdu> psdu,
1686 MHz_u channelFreq,
1687 const WifiTxVector& txVector,
1688 SignalNoiseDbm signalNoise,
1689 const std::vector<bool>& statusPerMpdu,
1690 uint16_t staId)
1691{
1692 MpduInfo aMpdu;
1693 if (psdu->IsAggregate())
1694 {
1695 // Expand A-MPDU
1696 NS_ASSERT_MSG(txVector.IsAggregation(),
1697 "TxVector with aggregate flag expected here according to PSDU");
1698 aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber;
1699 size_t nMpdus = psdu->GetNMpdus();
1700 NS_ASSERT_MSG(statusPerMpdu.size() == nMpdus, "Should have one reception status per MPDU");
1701 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1702 {
1703 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1704 for (size_t i = 0; i < nMpdus;)
1705 {
1706 if (statusPerMpdu.at(i)) // packet received without error, hand over to sniffer
1707 {
1708 m_phyMonitorSniffRxTrace(psdu->GetAmpduSubframe(i),
1709 static_cast<uint16_t>(channelFreq),
1710 txVector,
1711 aMpdu,
1712 signalNoise,
1713 staId);
1714 }
1715 ++i;
1716 aMpdu.type =
1717 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1718 }
1719 }
1720 }
1721 else
1722 {
1723 NS_ASSERT_MSG(statusPerMpdu.size() == 1,
1724 "Should have one reception status for normal MPDU");
1725 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1726 {
1727 aMpdu.type = NORMAL_MPDU;
1728 m_phyMonitorSniffRxTrace(psdu->GetPacket(),
1729 static_cast<uint16_t>(channelFreq),
1730 txVector,
1731 aMpdu,
1732 signalNoise,
1733 staId);
1734 }
1735 }
1736}
1737
1738void
1739WifiPhy::NotifyMonitorSniffTx(Ptr<const WifiPsdu> psdu,
1740 MHz_u channelFreq,
1741 const WifiTxVector& txVector,
1742 uint16_t staId)
1743{
1744 MpduInfo aMpdu;
1745 if (psdu->IsAggregate())
1746 {
1747 // Expand A-MPDU
1748 NS_ASSERT_MSG(txVector.IsAggregation(),
1749 "TxVector with aggregate flag expected here according to PSDU");
1750 aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber;
1751 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1752 {
1753 size_t nMpdus = psdu->GetNMpdus();
1754 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1755 for (size_t i = 0; i < nMpdus;)
1756 {
1757 m_phyMonitorSniffTxTrace(psdu->GetAmpduSubframe(i),
1758 channelFreq,
1759 txVector,
1760 aMpdu,
1761 staId);
1762 ++i;
1763 aMpdu.type =
1764 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1765 }
1766 }
1767 }
1768 else
1769 {
1770 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1771 {
1772 aMpdu.type = NORMAL_MPDU;
1773 m_phyMonitorSniffTxTrace(psdu->GetPacket(), channelFreq, txVector, aMpdu, staId);
1774 }
1775 }
1776}
1777
1778std::optional<Time>
1779WifiPhy::GetTimeToPreambleDetectionEnd() const
1780{
1781 for (const auto& [modClass, phyEntity] : m_phyEntities)
1782 {
1783 if (auto remTime = phyEntity->GetTimeToPreambleDetectionEnd())
1784 {
1785 return remTime;
1786 }
1787 }
1788 return std::nullopt;
1789}
1790
1791std::optional<Time>
1792WifiPhy::GetTimeToMacHdrEnd(uint16_t staId) const
1793{
1794 for (auto& [modClass, phyEntity] : m_phyEntities)
1795 {
1796 if (auto remTime = phyEntity->GetTimeToMacHdrEnd(staId))
1797 {
1798 return remTime;
1799 }
1800 }
1801 return std::nullopt;
1802}
1803
1805WifiPhy::GetWifiConstPsduMap(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector)
1806{
1807 return GetStaticPhyEntity(txVector.GetModulationClass())->GetWifiConstPsduMap(psdu, txVector);
1808}
1809
1810void
1811WifiPhy::Send(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector)
1812{
1813 NS_LOG_FUNCTION(this << *psdu << txVector);
1814 Send(GetWifiConstPsduMap(psdu, txVector), txVector);
1815}
1816
1817void
1818WifiPhy::Send(const WifiConstPsduMap& psdus, const WifiTxVector& txVector)
1819{
1820 NS_LOG_FUNCTION(this << psdus << txVector);
1821 /* Transmission can happen if:
1822 * - we are syncing on a packet. It is the responsibility of the
1823 * MAC layer to avoid doing this but the PHY does nothing to
1824 * prevent it.
1825 * - we are idle
1826 */
1827 NS_ASSERT(!m_state->IsStateTx() && !m_state->IsStateSwitching());
1828 NS_ASSERT(m_endTxEvent.IsExpired());
1829
1830 if (!txVector.IsValid(m_band))
1831 {
1832 NS_FATAL_ERROR("TX-VECTOR is invalid!");
1833 }
1834
1835 uint8_t nss = 0;
1836 if (txVector.IsMu())
1837 {
1838 // We do not support mixed OFDMA and MU-MIMO
1839 if (txVector.IsDlMuMimo())
1840 {
1841 nss = txVector.GetNssTotal();
1842 }
1843 else
1844 {
1845 nss = txVector.GetNssMax();
1846 }
1847 }
1848 else
1849 {
1850 nss = txVector.GetNss();
1851 }
1852
1853 if (nss > GetMaxSupportedTxSpatialStreams())
1854 {
1855 NS_FATAL_ERROR("Unsupported number of spatial streams!");
1856 }
1857
1858 if (m_state->IsStateSleep())
1859 {
1860 NS_LOG_DEBUG("Dropping packet because in sleep mode");
1861 for (const auto& psdu : psdus)
1862 {
1863 NotifyTxDrop(psdu.second);
1864 }
1865 return;
1866 }
1867
1868 const auto txDuration = CalculateTxDuration(psdus, txVector, GetPhyBand());
1869
1870 if (const auto timeToPreambleDetectionEnd = GetTimeToPreambleDetectionEnd();
1871 timeToPreambleDetectionEnd && !m_currentEvent)
1872 {
1873 // PHY is in the initial few microseconds during which the
1874 // start of RX has occurred but the preamble detection period
1875 // has not elapsed
1876 AbortCurrentReception(SIGNAL_DETECTION_ABORTED_BY_TX);
1877 }
1878 else if (timeToPreambleDetectionEnd || m_currentEvent)
1879 {
1880 AbortCurrentReception(RECEPTION_ABORTED_BY_TX);
1881 }
1882
1883 if (m_powerRestricted)
1884 {
1885 NS_LOG_DEBUG("Transmitting with power restriction for " << txDuration.As(Time::NS));
1886 }
1887 else
1888 {
1889 NS_LOG_DEBUG("Transmitting without power restriction for " << txDuration.As(Time::NS));
1890 }
1891
1892 if (m_state->GetState() == WifiPhyState::OFF)
1893 {
1894 NS_LOG_DEBUG("Transmission canceled because device is OFF");
1895 return;
1896 }
1897
1898 auto ppdu = GetPhyEntity(txVector.GetModulationClass())->BuildPpdu(psdus, txVector, txDuration);
1899 m_previouslyRxPpduUid = UINT64_MAX; // reset (after creation of PPDU) to use it only once
1900
1901 const auto txPower = DbmToW(GetTxPowerForTransmission(ppdu) + GetTxGain());
1902 NotifyTxBegin(psdus, txPower);
1903 if (!m_phyTxPsduBeginTrace.IsEmpty())
1904 {
1905 m_phyTxPsduBeginTrace(psdus, txVector, txPower);
1906 }
1907 for (const auto& psdu : psdus)
1908 {
1909 NotifyMonitorSniffTx(psdu.second, GetFrequency(), txVector, psdu.first);
1910 }
1911 m_state->SwitchToTx(txDuration, psdus, GetPower(txVector.GetTxPowerLevel()), txVector);
1912
1913 if (m_wifiRadioEnergyModel &&
1914 m_wifiRadioEnergyModel->GetMaximumTimeInState(WifiPhyState::TX) < txDuration)
1915 {
1916 ppdu->SetTruncatedTx();
1917 }
1918
1919 m_endTxEvent =
1920 Simulator::Schedule(txDuration, &WifiPhy::TxDone, this, psdus); // TODO: fix for MU
1921
1922 StartTx(ppdu);
1923 ppdu->ResetTxVector();
1924
1925 m_channelAccessRequested = false;
1926 m_powerRestricted = false;
1927}
1928
1929void
1930WifiPhy::TxDone(const WifiConstPsduMap& psdus)
1931{
1932 NS_LOG_FUNCTION(this << psdus);
1933 NotifyTxEnd(psdus);
1934 Reset();
1935 // we might have received signals during TX
1936 SwitchMaybeToCcaBusy();
1937}
1938
1939uint64_t
1940WifiPhy::GetPreviouslyRxPpduUid() const
1941{
1942 return m_previouslyRxPpduUid;
1943}
1944
1945void
1946WifiPhy::SetPreviouslyRxPpduUid(uint64_t uid)
1947{
1948 NS_ASSERT(m_standard >= WIFI_STANDARD_80211be);
1949 m_previouslyRxPpduUid = uid;
1950}
1951
1952void
1953WifiPhy::Reset()
1954{
1955 NS_LOG_FUNCTION(this);
1956 m_currentPreambleEvents.clear();
1957 if (m_interference && (m_currentEvent || GetTimeToPreambleDetectionEnd()))
1958 {
1959 m_interference->NotifyRxEnd(Simulator::Now(), GetCurrentFrequencyRange());
1960 }
1961 m_currentEvent = nullptr;
1962 for (auto& phyEntity : m_phyEntities)
1963 {
1964 phyEntity.second->CancelAllEvents();
1965 }
1966 m_endPhyRxEvent.Cancel();
1967 m_endTxEvent.Cancel();
1968}
1969
1970void
1971WifiPhy::StartReceivePreamble(Ptr<const WifiPpdu> ppdu,
1972 RxPowerWattPerChannelBand& rxPowersW,
1973 Time rxDuration)
1974{
1975 NS_LOG_FUNCTION(this << ppdu << rxDuration);
1976 WifiModulationClass modulation = ppdu->GetModulation();
1977 NS_ASSERT(m_maxModClassSupported != WIFI_MOD_CLASS_UNKNOWN);
1978 if (auto it = m_phyEntities.find(modulation);
1979 it != m_phyEntities.end() && modulation <= m_maxModClassSupported)
1980 {
1981 it->second->StartReceivePreamble(ppdu, rxPowersW, rxDuration);
1982 }
1983 else
1984 {
1985 // TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble
1986 // structure)
1987 NS_LOG_DEBUG("Unsupported modulation received (" << modulation << "), consider as noise");
1988 m_interference->Add(ppdu, rxDuration, rxPowersW, GetCurrentFrequencyRange());
1989 SwitchMaybeToCcaBusy();
1990 }
1991}
1992
1993std::optional<std::reference_wrapper<const WifiTxVector>>
1994WifiPhy::GetInfoIfRxingPhyHeader() const
1995{
1996 if (m_endPhyRxEvent.IsPending())
1997 {
1998 NS_ASSERT_MSG(m_currentEvent, "No current event while receiving PHY header");
1999 return std::cref(m_currentEvent->GetPpdu()->GetTxVector());
2000 }
2001 return std::nullopt;
2002}
2003
2004void
2005WifiPhy::EndReceiveInterBss()
2006{
2007 NS_LOG_FUNCTION(this);
2008 if (!m_channelAccessRequested)
2009 {
2010 m_powerRestricted = false;
2011 }
2012}
2013
2014void
2015WifiPhy::NotifyChannelAccessRequested()
2016{
2017 NS_LOG_FUNCTION(this);
2018 m_channelAccessRequested = true;
2019}
2020
2021bool
2022WifiPhy::IsModeSupported(WifiMode mode) const
2023{
2024 for (const auto& phyEntity : m_phyEntities)
2025 {
2026 if (phyEntity.second->IsModeSupported(mode))
2027 {
2028 return true;
2029 }
2030 }
2031 return false;
2032}
2033
2035WifiPhy::GetDefaultMode() const
2036{
2037 // Start from oldest standards and move up (guaranteed by fact that WifModulationClass is
2038 // ordered)
2039 for (const auto& phyEntity : m_phyEntities)
2040 {
2041 for (const auto& mode : *(phyEntity.second))
2042 {
2043 return mode;
2044 }
2045 }
2046 NS_ASSERT_MSG(false, "Should have found at least one default mode");
2047 return WifiMode();
2048}
2049
2050bool
2051WifiPhy::IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
2052{
2053 const auto phyEntity = m_phyEntities.find(modulation);
2054 if (phyEntity == m_phyEntities.end())
2055 {
2056 return false;
2057 }
2058 return phyEntity->second->IsMcsSupported(mcs);
2059}
2060
2061std::list<WifiMode>
2062WifiPhy::GetModeList() const
2063{
2064 std::list<WifiMode> list;
2065 for (const auto& phyEntity : m_phyEntities)
2066 {
2067 if (!phyEntity.second->HandlesMcsModes()) // to exclude MCSs from search
2068 {
2069 for (const auto& mode : *(phyEntity.second))
2070 {
2071 list.emplace_back(mode);
2072 }
2073 }
2074 }
2075 return list;
2076}
2077
2078std::list<WifiMode>
2079WifiPhy::GetModeList(WifiModulationClass modulation) const
2080{
2081 std::list<WifiMode> list;
2082 const auto phyEntity = m_phyEntities.find(modulation);
2083 if (phyEntity != m_phyEntities.end())
2084 {
2085 if (!phyEntity->second->HandlesMcsModes()) // to exclude MCSs from search
2086 {
2087 for (const auto& mode : *(phyEntity->second))
2088 {
2089 list.emplace_back(mode);
2090 }
2091 }
2092 }
2093 return list;
2094}
2095
2096uint16_t
2097WifiPhy::GetNMcs() const
2098{
2099 uint16_t numMcs = 0;
2100 for (const auto& phyEntity : m_phyEntities)
2101 {
2102 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2103 {
2104 numMcs += phyEntity.second->GetNumModes();
2105 }
2106 }
2107 return numMcs;
2108}
2109
2110std::list<WifiMode>
2111WifiPhy::GetMcsList() const
2112{
2113 std::list<WifiMode> list;
2114 for (const auto& phyEntity : m_phyEntities)
2115 {
2116 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2117 {
2118 for (const auto& mode : *(phyEntity.second))
2119 {
2120 list.emplace_back(mode);
2121 }
2122 }
2123 }
2124 return list;
2125}
2126
2127std::list<WifiMode>
2128WifiPhy::GetMcsList(WifiModulationClass modulation) const
2129{
2130 std::list<WifiMode> list;
2131 auto phyEntity = m_phyEntities.find(modulation);
2132 if (phyEntity != m_phyEntities.end())
2133 {
2134 if (phyEntity->second->HandlesMcsModes()) // to exclude non-MCS modes from search
2135 {
2136 for (const auto& mode : *(phyEntity->second))
2137 {
2138 list.emplace_back(mode);
2139 }
2140 }
2141 }
2142 return list;
2143}
2144
2146WifiPhy::GetMcs(WifiModulationClass modulation, uint8_t mcs) const
2147{
2148 NS_ASSERT_MSG(IsMcsSupported(modulation, mcs), "Unsupported MCS");
2149 return m_phyEntities.at(modulation)->GetMcs(mcs);
2150}
2151
2152bool
2153WifiPhy::IsStateCcaBusy() const
2154{
2155 return m_state->IsStateCcaBusy();
2156}
2157
2158bool
2159WifiPhy::IsStateIdle() const
2160{
2161 return m_state->IsStateIdle();
2162}
2163
2164bool
2165WifiPhy::IsStateRx() const
2166{
2167 return m_state->IsStateRx();
2168}
2169
2170bool
2171WifiPhy::IsStateTx() const
2172{
2173 return m_state->IsStateTx();
2174}
2175
2176bool
2177WifiPhy::IsStateSwitching() const
2178{
2179 return m_state->IsStateSwitching();
2180}
2181
2182bool
2183WifiPhy::IsStateSleep() const
2184{
2185 return m_state->IsStateSleep();
2186}
2187
2188bool
2189WifiPhy::IsStateOff() const
2190{
2191 return m_state->IsStateOff();
2192}
2193
2194Time
2195WifiPhy::GetDelayUntilIdle()
2196{
2197 return m_state->GetDelayUntilIdle();
2198}
2199
2200Time
2201WifiPhy::GetLastRxStartTime() const
2202{
2203 return m_state->GetLastRxStartTime();
2204}
2205
2206Time
2207WifiPhy::GetLastRxEndTime() const
2208{
2209 return m_state->GetLastRxEndTime();
2210}
2211
2212void
2213WifiPhy::SwitchMaybeToCcaBusy(const Ptr<const WifiPpdu> ppdu /* = nullptr */)
2214{
2215 NS_LOG_FUNCTION(this);
2216 GetLatestPhyEntity()->SwitchMaybeToCcaBusy(ppdu);
2217}
2218
2219void
2220WifiPhy::NotifyCcaBusy(const Ptr<const WifiPpdu> ppdu, Time duration)
2221{
2222 NS_LOG_FUNCTION(this << duration);
2223 GetLatestPhyEntity()->NotifyCcaBusy(ppdu, duration, WIFI_CHANLIST_PRIMARY);
2224}
2225
2226void
2227WifiPhy::AbortCurrentReception(WifiPhyRxfailureReason reason)
2228{
2229 NS_LOG_FUNCTION(this << reason);
2230 if (reason != OBSS_PD_CCA_RESET ||
2231 m_currentEvent) // Otherwise abort has already been called previously
2232 {
2233 if (reason == SIGNAL_DETECTION_ABORTED_BY_TX)
2234 {
2235 for (auto signalDetectEvent : m_currentPreambleEvents)
2236 {
2237 NotifyRxPpduDrop(signalDetectEvent.second->GetPpdu(),
2239 }
2240 }
2241 for (auto& phyEntity : m_phyEntities)
2242 {
2243 phyEntity.second->CancelAllEvents();
2244 }
2245 m_endPhyRxEvent.Cancel();
2246 m_interference->NotifyRxEnd(Simulator::Now(), GetCurrentFrequencyRange());
2247 if (!m_currentEvent)
2248 {
2249 return;
2250 }
2251 NotifyRxPpduDrop(m_currentEvent->GetPpdu(), reason);
2252 if (reason == OBSS_PD_CCA_RESET)
2253 {
2254 m_state->SwitchFromRxAbort(GetChannelWidth());
2255 }
2256 if (reason == RECEPTION_ABORTED_BY_TX)
2257 {
2258 Reset();
2259 }
2260 else
2261 {
2262 for (auto it = m_currentPreambleEvents.begin(); it != m_currentPreambleEvents.end();
2263 ++it)
2264 {
2265 if (it->second == m_currentEvent)
2266 {
2267 it = m_currentPreambleEvents.erase(it);
2268 break;
2269 }
2270 }
2271 m_currentEvent = nullptr;
2272 }
2273 }
2274}
2275
2276void
2277WifiPhy::ResetCca(bool powerRestricted, dBm_u txPowerMaxSiso, dBm_u txPowerMaxMimo)
2278{
2279 NS_LOG_FUNCTION(this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2280 // This method might be called multiple times when receiving TB PPDUs with a BSS color
2281 // different than the one of the receiver. The first time this method is called, the call
2282 // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2283 // m_currentEvent is not 0 before executing the instructions below.
2284 if (m_currentEvent)
2285 {
2286 m_powerRestricted = powerRestricted;
2287 m_txPowerMaxSiso = txPowerMaxSiso;
2288 m_txPowerMaxMimo = txPowerMaxMimo;
2289 NS_ASSERT((m_currentEvent->GetEndTime() - Simulator::Now()).IsPositive());
2290 Simulator::Schedule(m_currentEvent->GetEndTime() - Simulator::Now(),
2291 &WifiPhy::EndReceiveInterBss,
2292 this);
2293 Simulator::ScheduleNow(&WifiPhy::AbortCurrentReception,
2294 this,
2295 OBSS_PD_CCA_RESET); // finish processing field first
2296 }
2297}
2298
2299dBm_u
2300WifiPhy::GetTxPowerForTransmission(Ptr<const WifiPpdu> ppdu) const
2301{
2302 NS_LOG_FUNCTION(this << m_powerRestricted << ppdu);
2303 const auto& txVector = ppdu->GetTxVector();
2304 // Get transmit power before antenna gain
2305 dBm_u txPower;
2306 if (!m_powerRestricted)
2307 {
2308 txPower = GetPower(txVector.GetTxPowerLevel());
2309 }
2310 else
2311 {
2312 if (txVector.GetNssMax() > 1 || txVector.GetNssTotal() > 1)
2313 {
2314 txPower = std::min(m_txPowerMaxMimo, GetPower(txVector.GetTxPowerLevel()));
2315 }
2316 else
2317 {
2318 txPower = std::min(m_txPowerMaxSiso, GetPower(txVector.GetTxPowerLevel()));
2319 }
2320 }
2321
2322 // Apply power density constraint on EIRP
2323 const auto channelWidth = ppdu->GetTxChannelWidth();
2324 dBm_per_MHz_u txPowerDbmPerMhz =
2325 (txPower + GetTxGain()) - RatioToDb(channelWidth); // account for antenna gain since EIRP
2326 NS_LOG_INFO("txPower=" << txPower << "dBm with txPowerDbmPerMhz=" << txPowerDbmPerMhz
2327 << " over " << channelWidth << " MHz");
2328 txPower = std::min(txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb(channelWidth);
2329 txPower -= GetTxGain(); // remove antenna gain since will be added right afterwards
2330 NS_LOG_INFO("txPower=" << txPower
2331 << "dBm after applying m_powerDensityLimit=" << m_powerDensityLimit);
2332 return txPower;
2333}
2334
2336WifiPhy::GetAddressedPsduInPpdu(Ptr<const WifiPpdu> ppdu) const
2337{
2338 // TODO: wrapper. See if still needed
2339 return GetPhyEntityForPpdu(ppdu)->GetAddressedPsduInPpdu(ppdu);
2340}
2341
2342int64_t
2343WifiPhy::AssignStreams(int64_t stream)
2344{
2345 NS_LOG_FUNCTION(this << stream);
2346 int64_t currentStream = stream;
2347 m_random->SetStream(currentStream++);
2348 currentStream += m_interference->GetErrorRateModel()->AssignStreams(currentStream);
2349 return (currentStream - stream);
2350}
2351
2352std::ostream&
2353operator<<(std::ostream& os, RxSignalInfo rxSignalInfo)
2354{
2355 os << "SNR:" << RatioToDb(rxSignalInfo.snr) << " dB"
2356 << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2357 return os;
2358}
2359
2360uint8_t
2361WifiPhy::GetPrimaryChannelNumber(MHz_u primaryChannelWidth) const
2362{
2363 return m_operatingChannel.GetPrimaryChannelNumber(primaryChannelWidth, m_standard);
2364}
2365
2366Hz_u
2367WifiPhy::GetSubcarrierSpacing() const
2368{
2369 Hz_u subcarrierSpacing{0};
2370 switch (GetStandard())
2371 {
2377 subcarrierSpacing = SUBCARRIER_FREQUENCY_SPACING;
2378 break;
2380 if (GetChannelWidth() == MHz_u{5})
2381 {
2382 subcarrierSpacing = SUBCARRIER_FREQUENCY_SPACING / 4;
2383 }
2384 else
2385 {
2386 subcarrierSpacing = SUBCARRIER_FREQUENCY_SPACING / 2;
2387 }
2388 break;
2391 subcarrierSpacing = SUBCARRIER_FREQUENCY_SPACING_HE;
2392 break;
2393 default:
2394 NS_FATAL_ERROR("Standard unknown: " << GetStandard());
2395 break;
2396 }
2397 return subcarrierSpacing;
2398}
2399
2400} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
Hold variables of type enum.
Definition enum.h:52
Keep track of the current position and velocity of an object.
A base class which provides memory management and object aggregation.
Definition object.h:78
bool IsInitialized() const
Check if the object has been initialized.
Definition object.cc:240
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition nstime.h:340
AttributeValue implementation for Tuple.
Definition tuple.h:67
a unique identifier for an interface.
Definition type-id.h:49
@ ATTR_GET
The attribute can be read.
Definition type-id.h:54
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
Definition type-id.h:56
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
represent a single transmission mode
Definition wifi-mode.h:38
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:172
802.11 PHY layer model
Definition wifi-phy.h:55
static TypeId GetTypeId()
Get the type ID.
Definition wifi-phy.cc:60
void SetNumberOfAntennas(uint8_t antennas)
Definition wifi-phy.cc:1310
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition wifi-phy.h:1346
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition wifi-phy.h:1645
dBm_u m_ccaEdThreshold
Clear channel assessment (CCA) energy detection (ED) threshold.
Definition wifi-phy.h:1616
dBm_u GetTxPowerStart() const
Return the minimum available transmission power level.
Definition wifi-phy.cc:579
WifiModulationClass GetMaxModulationClassSupported() const
Definition wifi-phy.cc:991
void SetRxGain(dB_u gain)
Sets the reception gain.
Definition wifi-phy.cc:624
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition wifi-phy.cc:687
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition wifi-phy.h:1635
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition wifi-phy.h:1345
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition wifi-phy.h:1649
void SetRxNoiseFigure(dB_u noiseFigure)
Sets the RX loss in the Signal-to-Noise-Ratio due to non-idealities in the receiver.
Definition wifi-phy.cc:561
void Configure80211ax()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard.
Definition wifi-phy.cc:961
void SetRxSensitivity(dBm_u threshold)
Sets the receive sensitivity threshold.
Definition wifi-phy.cc:522
Time m_channelSwitchDelay
Time required to switch between channel.
Definition wifi-phy.h:1640
dB_u GetTxGain() const
Return the transmission gain.
Definition wifi-phy.cc:618
void SetTxPowerEnd(dBm_u end)
Sets the maximum available transmission power level.
Definition wifi-phy.cc:585
dBm_per_MHz_u m_powerDensityLimit
the power density limit
Definition wifi-phy.h:1625
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition wifi-phy.h:1608
TracedCallback< Ptr< const Packet > > m_phyTxDropTrace
The trace source fired when the PHY layer drops a packet as it tries to transmit it.
Definition wifi-phy.h:1499
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition wifi-phy.cc:696
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition wifi-phy.h:1630
Time GetSlot() const
Return the slot duration for this PHY.
Definition wifi-phy.cc:850
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition wifi-phy.cc:1360
void Configure80211g()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard.
Definition wifi-phy.cc:897
uint8_t GetPrimary20Index() const
Definition wifi-phy.cc:1093
dBm_u m_rxSensitivity
Receive sensitivity threshold.
Definition wifi-phy.h:1615
uint8_t GetNumberOfAntennas() const
Definition wifi-phy.cc:1322
Time m_slot
Slot duration.
Definition wifi-phy.h:1612
dBm_u GetRxSensitivity() const
Return the receive sensitivity threshold.
Definition wifi-phy.cc:529
Time GetDelayUntilIdle()
Definition wifi-phy.cc:2195
MHz_u m_maxRadioBw
Maximum radio bandwidth.
Definition wifi-phy.h:1642
bool GetShortPhyPreambleSupported() const
Return whether short PHY preamble is supported.
Definition wifi-phy.cc:644
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition wifi-phy.cc:832
void Configure80211n()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard.
Definition wifi-phy.cc:938
dBm_u m_ccaSensitivityThreshold
Clear channel assessment (CCA) modulation and coding rate sensitivity threshold.
Definition wifi-phy.h:1617
void Configure80211be()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11be standard.
Definition wifi-phy.cc:976
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition wifi-phy.cc:838
bool m_notifyRxMacHeaderEnd
whether the PHY is capable of notifying MAC header RX end
Definition wifi-phy.h:1652
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:937
MHz_u GetFrequency() const
Definition wifi-phy.cc:1075
Ptr< MobilityModel > GetMobility() const
Return the mobility model this PHY is associated with.
Definition wifi-phy.cc:668
void SetTxPowerStart(dBm_u start)
Sets the minimum available transmission power level.
Definition wifi-phy.cc:572
void Configure80211p()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard.
Definition wifi-phy.cc:910
dBm_u m_txPowerEnd
Maximum transmission power.
Definition wifi-phy.h:1623
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition wifi-phy.cc:2227
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition wifi-phy.h:1647
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition wifi-phy.h:1542
Time GetChannelSwitchDelay() const
Definition wifi-phy.cc:748
void SetTxGain(dB_u gain)
Sets the transmission gain.
Definition wifi-phy.cc:611
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition wifi-phy.cc:1328
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition wifi-phy.h:1611
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition wifi-phy.cc:493
TracedCallback< Ptr< const WifiPpdu >, const WifiTxVector & > m_signalTransmissionCb
Signal Transmission callback.
Definition wifi-phy.h:1384
dBm_u GetTxPowerEnd() const
Return the maximum available transmission power level.
Definition wifi-phy.cc:592
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition wifi-phy.cc:1372
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:997
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition wifi-phy.cc:704
uint8_t m_numberOfAntennas
Number of transmitters.
Definition wifi-phy.h:1634
TracedCallback< Ptr< const WifiPpdu >, WifiPhyRxfailureReason > m_phyRxPpduDropTrace
The trace source fired when the PHY layer drops a packet it has received.
Definition wifi-phy.h:1554
dBm_u GetCcaEdThreshold() const
Return the CCA energy detection threshold.
Definition wifi-phy.cc:542
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
Definition wifi-phy.cc:481
dBm_u m_txPowerBase
Minimum transmission power.
Definition wifi-phy.h:1622
virtual Ptr< Channel > GetChannel() const =0
Return the Channel this WifiPhy is connected to.
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition wifi-phy.cc:637
void SetNTxPower(uint8_t n)
Sets the number of transmission power levels available between the minimum level and the maximum leve...
Definition wifi-phy.cc:598
void SetCcaSensitivityThreshold(dBm_u threshold)
Sets the CCA sensitivity threshold.
Definition wifi-phy.cc:548
WifiPhyBand m_band
WifiPhyBand.
Definition wifi-phy.h:1606
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition wifi-phy.cc:760
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, uint16_t > m_phyMonitorSniffTxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being transmitted.
Definition wifi-phy.h:1593
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1381
MHz_u GetTxBandwidth(WifiMode mode, MHz_u maxAllowedBandWidth=MHz_u{ std::numeric_limits< double >::max()}) const
Get the bandwidth for a transmission occurring on the current operating channel and using the given W...
Definition wifi-phy.cc:1111
void SetMaxModulationClassSupported(WifiModulationClass modClass)
Set the maximum modulation class that has to be supported by this PHY object.
Definition wifi-phy.cc:984
void AddPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of supported PHY entities for the given modulation class for the WifiPh...
Definition wifi-phy.cc:819
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, SignalNoiseDbm, uint16_t > m_phyMonitorSniffRxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being received.
Definition wifi-phy.h:1574
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition wifi-phy.h:1650
void RegisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition wifi-phy.cc:499
static std::map< WifiModulationClass, Ptr< PhyEntity > > & GetStaticPhyEntities()
Definition wifi-phy.cc:474
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition wifi-phy.cc:844
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1057
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition wifi-phy.cc:769
uint8_t GetChannelNumber() const
Return current channel number.
Definition wifi-phy.cc:1081
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Definition wifi-phy.h:1491
std::optional< Time > GetDelayUntilChannelSwitch()
Perform any actions necessary when user changes operating channel after initialization.
Definition wifi-phy.cc:1181
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition wifi-phy.cc:723
TracedCallback< Ptr< const Packet >, double > m_phyTxBeginTrace
The trace source fired when a packet begins the transmission process on the medium.
Definition wifi-phy.h:1476
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-phy.cc:650
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition wifi-phy.h:1648
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition wifi-phy.cc:862
static void AddStaticPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of implemented PHY entities for the given modulation class.
Definition wifi-phy.cc:810
TracedCallback< WifiConstPsduMap, WifiTxVector, double > m_phyTxPsduBeginTrace
The trace source fired when a PSDU map begins the transmission process on the medium.
Definition wifi-phy.h:1483
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
Definition wifi-phy.h:943
dB_u m_txGain
Transmission gain.
Definition wifi-phy.h:1620
MHz_u GetChannelWidth() const
Definition wifi-phy.cc:1087
void SetOperatingChannel(const WifiPhyOperatingChannel &channel)
If the standard for this object has not been set yet, store the channel settings corresponding to the...
Definition wifi-phy.cc:1123
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition wifi-phy.cc:656
WifiStandard m_standard
WifiStandard.
Definition wifi-phy.h:1604
uint8_t m_nTxPower
Number of available transmission power levels.
Definition wifi-phy.h:1624
void DoDispose() override
Destructor implementation.
Definition wifi-phy.cc:445
dB_u GetRxGain() const
Return the reception gain.
Definition wifi-phy.cc:631
void SetPhyId(uint8_t phyId)
Set the index allocated to this PHY.
Definition wifi-phy.cc:674
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition wifi-phy.cc:1222
TracedCallback< Ptr< const Packet >, WifiPhyRxfailureReason > m_phyRxDropTrace
The trace source fired when the PHY layer drops a packet it has received.
Definition wifi-phy.h:1549
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition wifi-phy.cc:717
uint8_t m_phyId
the index of the PHY in the vector of PHYs held by the WifiNetDevice
Definition wifi-phy.h:1340
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition wifi-phy.cc:856
void Configure80211b()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard.
Definition wifi-phy.cc:882
void SetCcaEdThreshold(dBm_u threshold)
Sets the CCA energy detection threshold.
Definition wifi-phy.cc:535
dB_u m_noiseFigure
The noise figure.
Definition wifi-phy.h:1638
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:2213
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:662
dB_u m_rxGain
Reception gain.
Definition wifi-phy.h:1621
double CalculateSnr(const WifiTxVector &txVector, double ber) const
Definition wifi-phy.cc:754
void SetFixedPhyBand(bool enable)
Configure whether it is prohibited to change PHY band after initialization.
Definition wifi-phy.cc:1099
~WifiPhy() override
Definition wifi-phy.cc:414
void Configure80211ac()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard.
Definition wifi-phy.cc:953
bool HasFixedPhyBand() const
Definition wifi-phy.cc:1105
TracedCallback< Ptr< const Packet >, RxPowerWattPerChannelBand > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition wifi-phy.h:1507
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition wifi-phy.h:1644
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition wifi-phy.h:1343
void DoInitialize() override
Initialize() implementation.
Definition wifi-phy.cc:420
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition wifi-phy.h:1633
uint8_t GetPhyId() const
Get the index allocated to this PHY.
Definition wifi-phy.cc:681
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition wifi-phy.h:1613
WifiModulationClass m_maxModClassSupported
max modulation class supported
Definition wifi-phy.h:1605
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition wifi-phy.cc:1063
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition wifi-phy.cc:516
void SetReceiveOkCallback(RxOkCallback callback)
Definition wifi-phy.cc:487
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition wifi-phy.cc:711
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition wifi-phy.h:1627
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition wifi-phy.h:1654
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition wifi-phy.cc:790
void Reset()
Reset data upon end of TX or RX.
Definition wifi-phy.cc:1953
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition wifi-phy.h:1523
TracedCallback< const WifiMacHeader &, const WifiTxVector &, Time > m_phyRxMacHeaderEndTrace
The trace source fired when the reception of a MAC header ends.
Definition wifi-phy.h:1534
uint8_t GetMaxSupportedTxSpatialStreams() const
Definition wifi-phy.cc:1354
void Configure80211a()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard.
Definition wifi-phy.cc:868
ChannelSegments m_channelSettings
Store operating channel settings until initialization.
Definition wifi-phy.h:1607
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition wifi-phy.cc:1069
dBm_u GetPower(uint8_t powerLevel) const
Get the power of the given power level.
Definition wifi-phy.cc:729
bool m_fixedPhyBand
True to prohibit changing PHY band after initialization.
Definition wifi-phy.h:1609
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition wifi-phy.cc:784
uint8_t GetNTxPower() const
Return the number of available transmission power levels.
Definition wifi-phy.cc:605
void UnregisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition wifi-phy.cc:510
dBm_u GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold.
Definition wifi-phy.cc:555
Class that keeps track of all information about the current PHY operating channel.
MHz_u GetTotalWidth() const
Return the width of the whole operating channel.
bool IsSet() const
Return true if a valid channel has been set, false otherwise.
uint8_t GetNumber(std::size_t segment=0) const
Return the channel number for a given frequency segment.
static uint8_t GetDefaultChannelNumber(MHz_u width, WifiStandard standard, WifiPhyBand band, std::optional< uint8_t > previousChannelNumber=std::nullopt)
Get the default channel number for a given segment of the given width and for the given standard and ...
uint8_t GetPrimaryChannelIndex(MHz_u primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
MHz_u GetFrequency(std::size_t segment=0) const
Return the center frequency for a given frequency segment.
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
bool IsValid(WifiPhyBand band=WIFI_PHY_BAND_UNSPECIFIED) const
The standard disallows certain combinations of WifiMode, number of spatial streams,...
uint8_t GetNssTotal() const
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
uint8_t GetNssMax() const
uint8_t GetTxPowerLevel() const
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
bool IsDlMuMimo() const
Return true if this TX vector is used for a downlink multi-user transmission using MU-MIMO.
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< AttributeChecker > MakeAttributeContainerChecker()
Make uninitialized AttributeContainerChecker using explicit types.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition boolean.h:70
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition double.h:32
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition nstime.h:1433
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1453
Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition tuple.h:532
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition abort.h:133
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1345
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPhyBand
Identifies the PHY band.
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
MpduType
The type of an MPDU.
Definition wifi-types.h:48
@ WIFI_STANDARD_80211a
@ WIFI_STANDARD_80211p
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ OBSS_PD_CCA_RESET
@ SIGNAL_DETECTION_ABORTED_BY_TX
@ RECEPTION_ABORTED_BY_TX
@ CHANNEL_SWITCHING
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HR_DSSS
HR/DSSS (Clause 16)
@ WIFI_MOD_CLASS_UNKNOWN
Modulation class unknown or unspecified.
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_MOD_CLASS_DSSS
DSSS (Clause 15)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
@ OFDM_PHY_10_MHZ
Definition ofdm-phy.h:35
@ OFDM_PHY_5_MHZ
Definition ofdm-phy.h:36
@ WIFI_CHANLIST_PRIMARY
@ LAST_MPDU_IN_AGGREGATE
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
Definition wifi-types.h:60
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
Definition wifi-types.h:50
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
Definition wifi-types.h:55
@ SINGLE_MPDU
The MPDU is a single MPDU.
Definition wifi-types.h:52
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Definition wifi-types.h:58
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const Time DSSS_SIFS_TIME
aSIFSTime duration for DSSS (Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2020)
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
@ SWITCHING
The PHY layer is switching to other channel.
@ TX
The PHY layer is sending a packet.
@ IDLE
The PHY layer is IDLE.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SLEEP
The PHY layer is sleeping.
@ RX
The PHY layer is receiving a packet.
const Time DSSS_SLOT_TIME
aSlotTime duration for DSSS (Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2020)
const Time OFDM_SIFS_TIME_10MHZ
aSIFSTime value for OFDM (10 MHz channel spacing) (Table 17-21 "OFDM PHY characteristics" of 802....
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
Definition wifi-utils.cc:45
const Time OFDM_SLOT_TIME_20MHZ
aSlotTime duration for OFDM (20 MHz channel spacing) (Table 17-21 "OFDM PHY characteristics" of 802....
double Hz_u
Hz weak type.
Definition wifi-units.h:30
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
MHz_u GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
const Time OFDM_SIFS_TIME_5MHZ
aSIFSTime value for OFDM (5 MHz channel spacing) (Table 17-21 "OFDM PHY characteristics" of 802....
std::map< WifiSpectrumBandInfo, Watt_u > RxPowerWattPerChannelBand
A map of the received power for each band.
Definition phy-entity.h:45
MHz_u GetMaximumChannelWidth(WifiModulationClass modulation)
Get the maximum channel width allowed for the given modulation class.
double dBm_u
dBm weak type
Definition wifi-units.h:27
double DbToRatio(dB_u val)
Convert from dB to ratio.
Definition wifi-utils.cc:26
const Time OFDM_SLOT_TIME_5MHZ
aSlotTime duration for OFDM (5 MHz channel spacing) (Table 17-21 "OFDM PHY characteristics" of 802....
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:32
WifiPhyBand GetDefaultPhyBand(WifiStandard standard)
Get the default PHY band for the given standard.
WifiModulationClass GetModulationClassForStandard(WifiStandard standard)
Return the modulation class corresponding to a given standard.
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
Definition wifi-ppdu.h:38
const Time OFDM_SIFS_TIME_20MHZ
aSIFSTime value for OFDM (20 MHz channel spacing) (Table 17-21 "OFDM PHY characteristics" of 802....
const Time OFDM_SLOT_TIME_10MHZ
aSlotTime duration for OFDM (10 MHz channel spacing) (Table 17-21 "OFDM PHY characteristics" of 802....
double dB_u
dB weak type
Definition wifi-units.h:28
#define list
std::ostream & operator<<(std::ostream &os, const PairObject &obj)
Stream insertion operator.
MpduInfo structure.
Definition wifi-types.h:72
MpduType type
type of MPDU
Definition wifi-types.h:73
uint32_t mpduRefNumber
MPDU ref number.
Definition wifi-types.h:74
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:79
double snr
SNR in linear scale.
Definition wifi-types.h:80
dBm_u rssi
RSSI.
Definition wifi-types.h:81
SignalNoiseDbm structure.
Definition wifi-types.h:65
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.