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 ';'>((void(WifiPhy::*)(const ChannelSegments&)) & WifiPhy::SetOperatingChannel),
103 "BAND_2_4GHZ",
105 "BAND_5GHZ",
107 "BAND_6GHZ",
109 "BAND_UNSPECIFIED"),
111 .AddAttribute("Frequency",
112 "The center frequency (MHz) of the current operating channel.",
114 UintegerValue(0),
117 .AddAttribute("ChannelNumber",
118 "The channel number of the current operating channel.",
120 UintegerValue(0),
123 .AddAttribute(
124 "ChannelWidth",
125 "The width in MHz of the current operating channel (5, 10, 20, 22, 40, 80 or 160). "
126 "If 80+80MHz is used, this corresponds to the total channel width, hence 160 MHz.",
128 UintegerValue(0),
131 .AddAttribute(
132 "Primary20MHzIndex",
133 "The index of the primary 20 MHz channel within the current operating channel "
134 "(0 indicates the 20 MHz subchannel with the lowest center frequency).",
135 UintegerValue(0),
138 .AddAttribute("FixedPhyBand",
139 "If set to true, changing PHY band is prohibited after initialization.",
140 BooleanValue(false),
143 .AddAttribute(
144 "RxSensitivity",
145 "The energy of a received signal should be higher than "
146 "this threshold (dBm) for the PHY to detect the signal. "
147 "This threshold refers to a width of 20 MHz and will be "
148 "scaled to match the width of the received signal.",
149 DoubleValue(-101.0),
152 .AddAttribute(
153 "CcaEdThreshold",
154 "The energy of all received signals should be higher than "
155 "this threshold (dBm) in the primary channel to allow the PHY layer "
156 "to declare CCA BUSY state.",
157 DoubleValue(-62.0),
160 .AddAttribute("CcaSensitivity",
161 "The energy of a received wifi signal should be higher than "
162 "this threshold (dBm) in the primary channel to allow the PHY layer "
163 "to declare CCA BUSY state.",
164 DoubleValue(-82.0),
168 .AddAttribute("TxGain",
169 "Transmission gain (dB).",
170 DoubleValue(0.0),
173 .AddAttribute("RxGain",
174 "Reception gain (dB).",
175 DoubleValue(0.0),
178 .AddAttribute("TxPowerLevels",
179 "Number of transmission power levels available between "
180 "TxPowerStart and TxPowerEnd included.",
181 UintegerValue(1),
184 .AddAttribute("TxPowerEnd",
185 "Maximum available transmission level (dBm).",
186 DoubleValue(16.0206),
189 .AddAttribute("TxPowerStart",
190 "Minimum available transmission level (dBm).",
191 DoubleValue(16.0206),
194 .AddAttribute(
195 "RxNoiseFigure",
196 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
197 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
198 "\"the difference in decibels (dB) between"
199 " the noise output of the actual receiver to the noise output of an "
200 " ideal receiver with the same overall gain and bandwidth when the receivers "
201 " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
202 DoubleValue(7),
205 .AddAttribute("State",
206 "The state of the PHY layer.",
207 PointerValue(),
210 .AddAttribute("ChannelSwitchDelay",
211 "Delay between two short frames transmitted on different frequencies.",
215 .AddAttribute(
216 "Antennas",
217 "The number of antennas on the device.",
218 UintegerValue(1),
221 .AddAttribute("MaxSupportedTxSpatialStreams",
222 "The maximum number of supported TX spatial streams."
223 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
224 UintegerValue(1),
228 .AddAttribute("MaxSupportedRxSpatialStreams",
229 "The maximum number of supported RX spatial streams."
230 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
231 UintegerValue(1),
235 .AddAttribute("ShortPlcpPreambleSupported",
236 "Whether or not short PHY preamble is supported."
237 "This parameter is only valuable for 802.11b STAs and APs."
238 "Note: 802.11g APs and STAs always support short PHY preamble.",
239 BooleanValue(false),
243 .AddAttribute("FrameCaptureModel",
244 "Ptr to an object that implements the frame capture model",
245 PointerValue(),
248 .AddAttribute("PreambleDetectionModel",
249 "Ptr to an object that implements the preamble detection model",
250 PointerValue(),
253 .AddAttribute("PostReceptionErrorModel",
254 "An optional packet error model can be added to the receive "
255 "packet process after any propagation-based (SNR-based) error "
256 "models have been applied. Typically this is used to force "
257 "specific packet drops, for testing purposes.",
258 PointerValue(),
261 .AddAttribute("InterferenceHelper",
262 "Ptr to an object that implements the interference helper",
263 PointerValue(),
266 .AddAttribute("Sifs",
267 "The duration of the Short Interframe Space. "
268 "NOTE that the default value is overwritten by the value defined "
269 "by the standard; if you want to set this attribute, you have to "
270 "do it after that the PHY object is initialized.",
274 .AddAttribute("Slot",
275 "The duration of a slot. "
276 "NOTE that the default value is overwritten by the value defined "
277 "by the standard; if you want to set this attribute, you have to "
278 "do it after that the PHY object is initialized.",
282 .AddAttribute("Pifs",
283 "The duration of the PCF Interframe Space. "
284 "NOTE that the default value is overwritten by the value defined "
285 "by the standard; if you want to set this attribute, you have to "
286 "do it after that the PHY object is initialized.",
290 .AddAttribute("PowerDensityLimit",
291 "The mean equivalent isotropically radiated power density"
292 "limit (in dBm/MHz) set by regulators.",
293 DoubleValue(100.0), // set to a high value so as to have no effect
296 .AddAttribute("NotifyMacHdrRxEnd",
297 "Whether the PHY is capable of notifying the MAC about the end of "
298 "the reception of the MAC header of every MPDU.",
299 BooleanValue(false),
302 .AddTraceSource(
303 "PhyTxBegin",
304 "Trace source indicating a packet has begun transmitting over the medium; "
305 "the packet holds a single MPDU even if the MPDU is transmitted within an A-MPDU "
306 "(in which case this trace fires for each MPDU in the "
307 "A-MPDU).",
309 "ns3::WifiPhy::PhyTxBeginTracedCallback")
310 .AddTraceSource(
311 "PhyTxPsduBegin",
312 "Trace source indicating a PSDU has begun transmitting over the channel medium; "
313 "this trace returns a WifiConstPsduMap with a single element (in the case of SU "
314 "PPDU) "
315 "or multiple elements (in the case of MU PPDU)",
317 "ns3::WifiPhy::PsduTxBeginCallback")
318 .AddTraceSource("PhyTxEnd",
319 "Trace source indicating a packet "
320 "has been completely transmitted over the channel.",
322 "ns3::Packet::TracedCallback")
323 .AddTraceSource("PhyTxDrop",
324 "Trace source indicating a packet "
325 "has been dropped by the device during transmission",
327 "ns3::Packet::TracedCallback")
328 .AddTraceSource("PhyRxBegin",
329 "Trace source indicating a packet "
330 "has begun being received from the channel medium "
331 "by the device",
333 "ns3::WifiPhy::PhyRxBeginTracedCallback")
334 .AddTraceSource("PhyRxPayloadBegin",
335 "Trace source indicating the reception of the "
336 "payload of a PPDU has begun",
338 "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
339 .AddTraceSource("PhyRxMacHeaderEnd",
340 "Trace source indicating the MAC header of an MPDU has been "
341 "completely received.",
343 "ns3::WifiPhy::PhyRxMacHeaderEndTracedCallback")
344 .AddTraceSource("PhyRxEnd",
345 "Trace source indicating a packet "
346 "has been completely received from the channel medium "
347 "by the device",
349 "ns3::Packet::TracedCallback")
350 .AddTraceSource("PhyRxDrop",
351 "Trace source indicating a packet "
352 "has been dropped by the device during reception",
354 "ns3::WifiPhy::PhyRxDropTracedCallback")
355 .AddTraceSource("PhyRxPpduDrop",
356 "Trace source indicating a ppdu "
357 "has been dropped by the device during reception",
359 "ns3::WifiPhy::PhyRxPpduDropTracedCallback")
360 .AddTraceSource("MonitorSnifferRx",
361 "Trace source simulating a wifi device in monitor mode "
362 "sniffing all received frames",
364 "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
365 .AddTraceSource("MonitorSnifferTx",
366 "Trace source simulating the capability of a wifi device "
367 "in monitor mode to sniff all frames being transmitted",
369 "ns3::WifiPhy::MonitorSnifferTxTracedCallback")
370 .AddTraceSource("SignalTransmission",
371 "Trace start of signal transmission",
373 "ns3::SpectrumWifiPhy::SignalTransmissionCallback");
374 return tid;
375}
376
378 : m_phyId(0),
379 m_txMpduReferenceNumber(0xffffffff),
380 m_rxMpduReferenceNumber(0xffffffff),
381 m_endPhyRxEvent(),
382 m_endTxEvent(),
383 m_currentEvent(nullptr),
384 m_previouslyRxPpduUid(UINT64_MAX),
385 m_standard(WIFI_STANDARD_UNSPECIFIED),
386 m_maxModClassSupported(WIFI_MOD_CLASS_UNKNOWN),
388 m_sifs(),
389 m_slot(),
390 m_pifs(),
391 m_ackTxTime(),
392 m_blockAckTxTime(),
393 m_powerRestricted(false),
394 m_channelAccessRequested(false),
395 m_txSpatialStreams(1),
396 m_rxSpatialStreams(1),
397 m_wifiRadioEnergyModel(nullptr),
398 m_timeLastPreambleDetected()
399{
400 NS_LOG_FUNCTION(this);
403}
404
406{
407 NS_LOG_FUNCTION(this);
408}
409
410void
412{
413 NS_LOG_FUNCTION(this);
414
415 // This method ensures that the local mobility model pointer holds
416 // a pointer to the Node's aggregated mobility model (if one exists)
417 // in the case that the user has not directly called SetMobility()
418 // on this WifiPhy during simulation setup. If the mobility model
419 // needs to be added or changed during simulation runtime, users must
420 // call SetMobility() on this object.
421
422 if (!m_mobility)
423 {
425 "Either install a MobilityModel on this object or ensure that this "
426 "object is part of a Node and NetDevice");
427 m_mobility = m_device->GetNode()->GetObject<MobilityModel>();
428 if (!m_mobility)
429 {
430 NS_LOG_WARN("Mobility not found, propagation models might not work properly");
431 }
432 }
433}
434
435void
437{
438 NS_LOG_FUNCTION(this);
439
440 m_device = nullptr;
441 m_mobility = nullptr;
442 m_frameCaptureModel = nullptr;
443 m_preambleDetectionModel = nullptr;
444 m_wifiRadioEnergyModel = nullptr;
446 if (m_interference)
447 {
448 m_interference->Dispose();
449 }
450 m_interference = nullptr;
451 m_random = nullptr;
452 m_state = nullptr;
453
454 Reset();
455
456 // this should be done after calling the Reset function
457 for (auto& phyEntity : m_phyEntities)
458 {
459 phyEntity.second = nullptr;
460 }
461 m_phyEntities.clear();
462}
463
464std::map<WifiModulationClass, Ptr<PhyEntity>>&
466{
467 static std::map<WifiModulationClass, Ptr<PhyEntity>> g_staticPhyEntities;
468 return g_staticPhyEntities;
469}
470
473{
474 return m_state;
475}
476
477void
479{
480 m_state->SetReceiveOkCallback(callback);
481}
482
483void
485{
486 m_state->SetReceiveErrorCallback(callback);
487}
488
489void
490WifiPhy::RegisterListener(const std::shared_ptr<WifiPhyListener>& listener)
491{
492 m_state->RegisterListener(listener);
493 if (IsInitialized())
494 {
495 // provide CCA busy information upon registering a PHY listener
496 SwitchMaybeToCcaBusy(nullptr);
497 }
498}
499
500void
501WifiPhy::UnregisterListener(const std::shared_ptr<WifiPhyListener>& listener)
502{
503 m_state->UnregisterListener(listener);
504}
505
506void
511
512void
514{
515 NS_LOG_FUNCTION(this << threshold);
516 m_rxSensitivity = threshold;
517}
518
519dBm_u
521{
522 return m_rxSensitivity;
523}
524
525void
527{
528 NS_LOG_FUNCTION(this << threshold);
529 m_ccaEdThreshold = threshold;
530}
531
532dBm_u
534{
535 return m_ccaEdThreshold;
536}
537
538void
540{
541 NS_LOG_FUNCTION(this << threshold);
542 m_ccaSensitivityThreshold = threshold;
543}
544
545dBm_u
550
551void
553{
554 NS_LOG_FUNCTION(this << noiseFigure);
555 if (m_interference)
556 {
557 m_interference->SetNoiseFigure(DbToRatio(noiseFigure));
558 }
559 m_noiseFigure = noiseFigure;
560}
561
562void
564{
565 NS_LOG_FUNCTION(this << start);
566 m_txPowerBase = start;
567}
568
569dBm_u
571{
572 return m_txPowerBase;
573}
574
575void
577{
578 NS_LOG_FUNCTION(this << end);
579 m_txPowerEnd = end;
580}
581
582dBm_u
584{
585 return m_txPowerEnd;
586}
587
588void
590{
591 NS_LOG_FUNCTION(this << +n);
592 m_nTxPower = n;
593}
594
595uint8_t
597{
598 return m_nTxPower;
599}
600
601void
603{
604 NS_LOG_FUNCTION(this << gain);
605 m_txGain = gain;
606}
607
608dB_u
610{
611 return m_txGain;
612}
613
614void
616{
617 NS_LOG_FUNCTION(this << gain);
618 m_rxGain = gain;
619}
620
621dB_u
623{
624 return m_rxGain;
625}
626
627void
629{
630 NS_LOG_FUNCTION(this << enable);
631 m_shortPreamble = enable;
632}
633
634bool
639
640void
642{
643 m_device = device;
644}
645
648{
649 return m_device;
650}
651
652void
654{
655 m_mobility = mobility;
656}
657
660{
661 return m_mobility;
662}
663
664void
665WifiPhy::SetPhyId(uint8_t phyId)
666{
667 NS_LOG_FUNCTION(this << phyId);
668 m_phyId = phyId;
669}
670
671uint8_t
673{
674 return m_phyId;
675}
676
677void
679{
680 NS_LOG_FUNCTION(this << helper);
681 m_interference = helper;
682 m_interference->SetNoiseFigure(DbToRatio(m_noiseFigure));
683 m_interference->SetNumberOfReceiveAntennas(m_numberOfAntennas);
684}
685
686void
688{
689 NS_LOG_FUNCTION(this << model);
691 m_interference->SetErrorRateModel(model);
692}
693
694void
700
701void
706
707void
712
713void
715{
716 m_wifiRadioEnergyModel = wifiRadioEnergyModel;
717}
718
719dBm_u
720WifiPhy::GetPower(uint8_t powerLevel) const
721{
724 dBm_u dbm;
725 if (m_nTxPower > 1)
726 {
727 dbm = m_txPowerBase + dB_u{powerLevel * (m_txPowerEnd - m_txPowerBase) / (m_nTxPower - 1)};
728 }
729 else
730 {
732 "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
733 dbm = m_txPowerBase;
734 }
735 return dbm;
736}
737
738Time
743
744double
745WifiPhy::CalculateSnr(const WifiTxVector& txVector, double ber) const
746{
747 return m_interference->GetErrorRateModel()->CalculateSnr(txVector, ber);
748}
749
752{
753 const auto it = GetStaticPhyEntities().find(modulation);
755 "Unimplemented Wi-Fi modulation class " << modulation);
756 return it->second;
757}
758
761{
762 const auto it = m_phyEntities.find(modulation);
763 NS_ABORT_MSG_IF(it == m_phyEntities.cend(),
764 "Unsupported Wi-Fi modulation class " << modulation);
765 return it->second;
766}
767
770{
772}
773
779
782{
783 NS_ABORT_IF(!ppdu);
784 const auto modulation = ppdu->GetModulation();
785 if (modulation > m_phyEntities.rbegin()->first)
786 {
787 // unsupported modulation: start reception process with latest PHY entity
788 return GetLatestPhyEntity();
789 }
790 if (modulation < WIFI_MOD_CLASS_HT)
791 {
792 // for non-HT (duplicate), call the latest PHY entity since some extra processing can be
793 // done in PHYs implemented in HT and later (e.g. channel width selection for non-HT
794 // duplicates)
795 return GetLatestPhyEntity();
796 }
797 return GetPhyEntity(modulation);
798}
799
800void
802{
803 NS_ASSERT_MSG(!GetStaticPhyEntities().contains(modulation),
804 "The PHY entity has already been added. The setting should only be done once per "
805 "modulation class");
806 GetStaticPhyEntities()[modulation] = phyEntity;
807}
808
809void
811{
812 NS_LOG_FUNCTION(this << modulation);
813 NS_ABORT_MSG_IF(!GetStaticPhyEntities().contains(modulation),
814 "Cannot add an unimplemented PHY to supported list. Update the former first.");
815 NS_ASSERT_MSG(m_phyEntities.find(modulation) == m_phyEntities.end(),
816 "The PHY entity has already been added. The setting should only be done once per "
817 "modulation class");
818 phyEntity->SetOwner(this);
819 m_phyEntities[modulation] = phyEntity;
820}
821
822void
824{
825 m_sifs = sifs;
826}
827
828Time
830{
831 return m_sifs;
832}
833
834void
836{
837 m_slot = slot;
838}
839
840Time
842{
843 return m_slot;
844}
845
846void
848{
849 m_pifs = pifs;
850}
851
852Time
854{
855 return m_pifs;
856}
857
858Time
860{
861 return m_ackTxTime;
862}
863
864Time
866{
867 return m_blockAckTxTime;
868}
869
870void
872{
873 NS_LOG_FUNCTION(this);
875
876 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
879 SetPifs(GetSifs() + GetSlot());
880 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
881 // of the PPDU causing the EIFS" of 802.11-2016
883}
884
885void
887{
888 NS_LOG_FUNCTION(this);
889 Ptr<DsssPhy> phyEntity = Create<DsssPhy>();
891 AddPhyEntity(WIFI_MOD_CLASS_DSSS, phyEntity); // when plain DSSS modes are used
892
893 // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
896 SetPifs(GetSifs() + GetSlot());
897 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
898 // of the PPDU causing the EIFS" of 802.11-2016
900}
901
902void
904{
905 NS_LOG_FUNCTION(this);
906 // See Table 18-5 "ERP characteristics" of 802.11-2016
907 // Slot time defaults to the "long slot time" of 20 us in the standard
908 // according to mixed 802.11b/g deployments. Short slot time is enabled
909 // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
910 // consists of only ERP STAs capable of supporting this option.
913}
914
915void
917{
918 NS_LOG_FUNCTION(this);
919 if (GetChannelWidth() == MHz_u{10})
920 {
922
923 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
926 SetPifs(GetSifs() + GetSlot());
928 }
929 else if (GetChannelWidth() == MHz_u{5})
930 {
932
933 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
936 SetPifs(GetSifs() + GetSlot());
938 }
939 else
940 {
941 NS_FATAL_ERROR("802.11p configured with a wrong channel width!");
942 }
943}
944
945void
947{
948 NS_LOG_FUNCTION(this);
950 {
952 }
953 else
954 {
956 }
958
959 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
960 // of the PPDU causing the EIFS" of 802.11-2016
962}
963
964void
971
972void
974{
975 NS_LOG_FUNCTION(this);
977 {
979 }
980 else
981 {
983 }
985}
986
987void
994
995void
1001
1007
1008void
1010{
1011 NS_LOG_FUNCTION(this << standard);
1012
1014 "Cannot change standard");
1015
1016 m_standard = standard;
1017
1019 {
1021 }
1022
1024 {
1025 NS_LOG_DEBUG("Setting the operating channel first");
1027 // return because we are called back by SetOperatingChannel
1028 return;
1029 }
1030
1031 // this function is called when changing PHY band, hence we have to delete
1032 // the previous PHY entities
1033 m_phyEntities.clear();
1034
1035 switch (standard)
1036 {
1039 break;
1042 break;
1045 break;
1048 break;
1051 break;
1054 break;
1057 break;
1060 break;
1062 default:
1063 NS_ASSERT_MSG(false, "Unsupported standard");
1064 break;
1065 }
1066}
1067
1070{
1071 return m_band;
1072}
1073
1076{
1077 return m_standard;
1078}
1079
1082{
1083 return m_operatingChannel;
1084}
1085
1086MHz_u
1088{
1090}
1091
1092uint8_t
1094{
1096}
1097
1098MHz_u
1103
1104uint8_t
1109
1110void
1112{
1113 m_fixedPhyBand = enable;
1114}
1115
1116bool
1118{
1119 return m_fixedPhyBand;
1120}
1121
1122MHz_u
1123WifiPhy::GetTxBandwidth(WifiMode mode, MHz_u maxAllowedWidth) const
1124{
1125 auto modulation = mode.GetModulationClass();
1126 if (modulation == WIFI_MOD_CLASS_DSSS || modulation == WIFI_MOD_CLASS_HR_DSSS)
1127 {
1128 return MHz_u{22};
1129 }
1130
1131 return std::min({GetChannelWidth(), GetMaximumChannelWidth(modulation), maxAllowedWidth});
1132}
1133
1134void
1136{
1137 NS_LOG_FUNCTION(this << channel);
1138 ChannelSegments segments{};
1139 for (std::size_t segmentId = 0; segmentId < channel.GetNSegments(); ++segmentId)
1140 {
1141 segments.emplace_back(channel.GetNumber(segmentId),
1142 channel.GetWidth(segmentId),
1143 channel.GetPhyBand(),
1144 channel.GetPrimaryChannelIndex(MHz_u{20}));
1145 }
1146 SetOperatingChannel(segments);
1147}
1148
1149void
1154
1155void
1157{
1158 NS_LOG_FUNCTION(this << +std::get<0>(channelSegments.front())
1159 << std::get<1>(channelSegments.front())
1160 << static_cast<WifiPhyBand>(std::get<2>(channelSegments.front()))
1161 << +std::get<3>(channelSegments.front()));
1162
1163 m_channelSettings = channelSegments;
1164
1166 {
1167 NS_LOG_DEBUG("Channel information will be applied when a standard is configured");
1168 return;
1169 }
1170
1171 if (IsInitialized())
1172 {
1173 const auto delay = GetDelayUntilChannelSwitch();
1174 if (!delay.has_value())
1175 {
1176 // switching channel is not possible now
1177 return;
1178 }
1179 if (delay.value().IsStrictlyPositive())
1180 {
1181 // switching channel has been postponed
1183 Simulator::Schedule(delay.value(), fp, this, channelSegments);
1184 return;
1185 }
1186 }
1187
1188 // channel can be switched now.
1190}
1191
1192std::optional<Time>
1194{
1195 if (!IsInitialized())
1196 {
1197 // this is not channel switch, this is initialization
1198 NS_LOG_DEBUG("Before initialization, nothing to do");
1199 return Seconds(0);
1200 }
1201
1202 std::optional<Time> delay;
1203 switch (m_state->GetState())
1204 {
1205 case WifiPhyState::RX:
1206 NS_LOG_DEBUG("drop packet because of channel switching while reception");
1208 delay = Seconds(0);
1209 break;
1210 case WifiPhyState::TX:
1211 NS_LOG_DEBUG("channel switching postponed until end of current transmission");
1212 delay = GetDelayUntilIdle();
1213 break;
1215 case WifiPhyState::IDLE:
1216 Reset();
1217 delay = Seconds(0);
1218 break;
1220 delay = Seconds(0);
1221 break;
1223 NS_LOG_DEBUG("channel switching ignored in sleep mode");
1224 break;
1225 default:
1226 NS_ASSERT(false);
1227 break;
1228 }
1229
1230 return delay;
1231}
1232
1233void
1235{
1236 NS_LOG_FUNCTION(this);
1237
1238 m_powerRestricted = false;
1240
1241 // Update unspecified parameters with default values
1242 std::optional<uint8_t> prevChannelNumber{};
1243 for (auto& [number, width, band, primary20] : m_channelSettings)
1244 {
1245 if (band == WIFI_PHY_BAND_UNSPECIFIED)
1246 {
1248 }
1249 if (width == MHz_u{0} && number == 0)
1250 {
1251 width = GetDefaultChannelWidth(m_standard, static_cast<WifiPhyBand>(band));
1252 }
1253 if (number == 0)
1254 {
1255 number =
1257 m_standard,
1258 static_cast<WifiPhyBand>(band),
1259 prevChannelNumber);
1260 }
1261 prevChannelNumber = number;
1262 }
1263
1264 // We need to call SetStandard if this is the first time we set a channel or we
1265 // are changing PHY band. Checking if the new PHY band is different than the
1266 // previous one covers both cases because initially the PHY band is unspecified
1267 bool changingPhyBand =
1268 (static_cast<WifiPhyBand>(std::get<2>(m_channelSettings.front())) != m_band);
1269
1270 NS_ABORT_MSG_IF(IsInitialized() && m_fixedPhyBand && changingPhyBand,
1271 "Trying to change PHY band while prohibited.");
1272
1273 m_band = static_cast<WifiPhyBand>(std::get<2>(m_channelSettings.front()));
1274
1275 NS_LOG_DEBUG("switching channel");
1276 std::vector<FrequencyChannelInfo> segments{};
1277 std::transform(m_channelSettings.cbegin(),
1278 m_channelSettings.cend(),
1279 std::back_inserter(segments),
1280 [this](const auto& channelTuple) {
1281 return FrequencyChannelInfo{std::get<0>(channelTuple),
1282 MHz_u{0},
1283 std::get<1>(channelTuple),
1284 m_band};
1285 });
1286 m_operatingChannel.Set(segments, m_standard);
1287 m_operatingChannel.SetPrimary20Index(std::get<3>(m_channelSettings.front()));
1288
1289 // check that the channel width is supported
1290 const auto chWidth = GetChannelWidth();
1291
1292 if (m_device)
1293 {
1294 if (auto htConfig = m_device->GetHtConfiguration();
1295 htConfig && !htConfig->m_40MHzSupported && chWidth > MHz_u{20})
1296 {
1297 NS_ABORT_MSG("Attempting to set a " << chWidth
1298 << " MHz channel on"
1299 "a station only supporting 20 MHz operation");
1300 }
1302 if (auto vhtConfig = m_device->GetVhtConfiguration();
1303 vhtConfig && !vhtConfig->m_160MHzSupported && chWidth > MHz_u{80})
1304 {
1305 NS_ABORT_MSG("Attempting to set a " << chWidth
1306 << " MHz channel on"
1307 "a station supporting up to 80 MHz operation");
1308 }
1309 }
1310
1311 if (changingPhyBand)
1312 {
1313 ConfigureStandard(m_standard);
1314 }
1315
1316 FinalizeChannelSwitch();
1317
1318 if (IsInitialized())
1319 {
1320 // notify channel switching
1321 m_state->SwitchToChannelSwitching(GetChannelSwitchDelay());
1322 /*
1323 * Needed here to be able to correctly sensed the medium for the first
1324 * time after the switching. The actual switching is not performed until
1325 * after m_channelSwitchDelay. Packets received during the switching
1326 * state are added to the event list and are employed later to figure
1327 * out the state of the medium after the switching.
1328 */
1329 SwitchMaybeToCcaBusy(nullptr);
1330 }
1331}
1332
1333void
1334WifiPhy::SetNumberOfAntennas(uint8_t antennas)
1335{
1336 NS_LOG_FUNCTION(this << +antennas);
1337 NS_ASSERT_MSG(antennas > 0 && antennas <= 8, "unsupported number of antennas");
1338 m_numberOfAntennas = antennas;
1339 if (m_interference)
1340 {
1341 m_interference->SetNumberOfReceiveAntennas(antennas);
1342 }
1343}
1344
1345uint8_t
1346WifiPhy::GetNumberOfAntennas() const
1347{
1348 return m_numberOfAntennas;
1349}
1350
1351void
1352WifiPhy::SetMaxSupportedTxSpatialStreams(uint8_t streams)
1353{
1354 NS_ASSERT(streams <= GetNumberOfAntennas());
1355 bool changed = (m_txSpatialStreams != streams);
1356 m_txSpatialStreams = streams;
1357 if (changed)
1358 {
1359 auto phyEntity = m_phyEntities.find(WIFI_MOD_CLASS_HT);
1360 if (phyEntity != m_phyEntities.end())
1361 {
1362 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity->second);
1363 if (htPhy)
1364 {
1365 htPhy->SetMaxSupportedNss(
1366 m_txSpatialStreams); // this is essential to have the right MCSs configured
1367 }
1368
1369 if (!m_capabilitiesChangedCallback.IsNull())
1370 {
1371 m_capabilitiesChangedCallback();
1372 }
1373 }
1374 }
1375}
1376
1377uint8_t
1378WifiPhy::GetMaxSupportedTxSpatialStreams() const
1379{
1380 return m_txSpatialStreams;
1381}
1382
1383void
1384WifiPhy::SetMaxSupportedRxSpatialStreams(uint8_t streams)
1385{
1386 NS_ASSERT(streams <= GetNumberOfAntennas());
1387 bool changed = (m_rxSpatialStreams != streams);
1388 m_rxSpatialStreams = streams;
1389 if (changed && !m_capabilitiesChangedCallback.IsNull())
1390 {
1391 m_capabilitiesChangedCallback();
1392 }
1393}
1394
1395uint8_t
1396WifiPhy::GetMaxSupportedRxSpatialStreams() const
1397{
1398 return m_rxSpatialStreams;
1399}
1400
1401std::list<uint8_t>
1402WifiPhy::GetBssMembershipSelectorList() const
1403{
1404 std::list<uint8_t> list;
1405 for (const auto& phyEntity : m_phyEntities)
1406 {
1407 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity.second);
1408 if (htPhy)
1409 {
1410 list.emplace_back(htPhy->GetBssMembershipSelector());
1411 }
1412 }
1413 return list;
1414}
1415
1416void
1417WifiPhy::SetSleepMode(bool forceSleepInRx)
1418{
1419 NS_LOG_FUNCTION(this);
1420 m_powerRestricted = false;
1421 m_channelAccessRequested = false;
1422 switch (m_state->GetState())
1423 {
1424 case WifiPhyState::TX:
1425 NS_LOG_DEBUG("setting sleep mode postponed until end of current transmission");
1426 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this, forceSleepInRx);
1427 break;
1428 case WifiPhyState::RX:
1429 NS_LOG_DEBUG("setting sleep mode"
1430 << (forceSleepInRx ? "" : "postponed until end of current reception"));
1431 if (forceSleepInRx)
1432 {
1433 AbortCurrentReception(WifiPhyRxfailureReason::SLEEPING);
1434 m_state->SwitchToSleep();
1435 }
1436 else
1437 {
1438 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this, forceSleepInRx);
1439 }
1440 break;
1441 case WifiPhyState::SWITCHING:
1442 NS_LOG_DEBUG("setting sleep mode postponed until end of channel switching");
1443 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this, forceSleepInRx);
1444 break;
1445 case WifiPhyState::CCA_BUSY:
1446 case WifiPhyState::IDLE:
1447 NS_LOG_DEBUG("setting sleep mode");
1448 // The PHY object may be in CCA_BUSY state because it is receiving a preamble. Cancel
1449 // preamble events before switching to sleep state
1450 Reset();
1451 m_state->SwitchToSleep();
1452 break;
1453 case WifiPhyState::SLEEP:
1454 NS_LOG_DEBUG("already in sleep mode");
1455 break;
1456 default:
1457 NS_ASSERT(false);
1458 break;
1459 }
1460}
1461
1462void
1463WifiPhy::SetOffMode()
1464{
1465 NS_LOG_FUNCTION(this);
1466 m_powerRestricted = false;
1467 m_channelAccessRequested = false;
1468 Reset();
1469 m_state->SwitchToOff();
1470}
1471
1472void
1473WifiPhy::ResumeFromSleep()
1474{
1475 NS_LOG_FUNCTION(this);
1476 switch (m_state->GetState())
1477 {
1478 case WifiPhyState::TX:
1479 case WifiPhyState::RX:
1480 case WifiPhyState::IDLE:
1481 case WifiPhyState::CCA_BUSY:
1482 case WifiPhyState::SWITCHING: {
1483 NS_LOG_DEBUG("not in sleep mode, there is nothing to resume");
1484 break;
1485 }
1486 case WifiPhyState::SLEEP: {
1487 NS_LOG_DEBUG("resuming from sleep mode");
1488 m_state->SwitchFromSleep();
1489 SwitchMaybeToCcaBusy();
1490 break;
1491 }
1492 default: {
1493 NS_ASSERT(false);
1494 break;
1495 }
1496 }
1497}
1498
1499void
1500WifiPhy::ResumeFromOff()
1501{
1502 NS_LOG_FUNCTION(this);
1503 switch (m_state->GetState())
1504 {
1505 case WifiPhyState::TX:
1506 case WifiPhyState::RX:
1507 case WifiPhyState::IDLE:
1508 case WifiPhyState::CCA_BUSY:
1509 case WifiPhyState::SWITCHING:
1510 case WifiPhyState::SLEEP: {
1511 NS_LOG_DEBUG("not in off mode, there is nothing to resume");
1512 break;
1513 }
1514 case WifiPhyState::OFF: {
1515 NS_LOG_DEBUG("resuming from off mode");
1516 m_state->SwitchFromOff();
1517 SwitchMaybeToCcaBusy();
1518 break;
1519 }
1520 default: {
1521 NS_ASSERT(false);
1522 break;
1523 }
1524 }
1525}
1526
1527Time
1528WifiPhy::GetPreambleDetectionDuration()
1529{
1530 return MicroSeconds(4);
1531}
1532
1533Time
1534WifiPhy::GetStartOfPacketDuration(const WifiTxVector& txVector)
1535{
1536 return MicroSeconds(4);
1537}
1538
1539Time
1540WifiPhy::GetPayloadDuration(uint32_t size,
1541 const WifiTxVector& txVector,
1542 WifiPhyBand band,
1543 MpduType mpdutype,
1544 uint16_t staId)
1545{
1546 uint32_t totalAmpduSize;
1547 double totalAmpduNumSymbols;
1548 return GetPayloadDuration(size,
1549 txVector,
1550 band,
1551 mpdutype,
1552 false,
1553 totalAmpduSize,
1554 totalAmpduNumSymbols,
1555 staId);
1556}
1557
1558Time
1559WifiPhy::GetPayloadDuration(uint32_t size,
1560 const WifiTxVector& txVector,
1561 WifiPhyBand band,
1562 MpduType mpdutype,
1563 bool incFlag,
1564 uint32_t& totalAmpduSize,
1565 double& totalAmpduNumSymbols,
1566 uint16_t staId)
1567{
1568 return GetStaticPhyEntity(txVector.GetModulationClass())
1569 ->GetPayloadDuration(size,
1570 txVector,
1571 band,
1572 mpdutype,
1573 incFlag,
1574 totalAmpduSize,
1575 totalAmpduNumSymbols,
1576 staId);
1577}
1578
1579Time
1580WifiPhy::CalculatePhyPreambleAndHeaderDuration(const WifiTxVector& txVector)
1581{
1582 return GetStaticPhyEntity(txVector.GetModulationClass())
1583 ->CalculatePhyPreambleAndHeaderDuration(txVector);
1584}
1585
1586Time
1587WifiPhy::CalculateTxDuration(uint32_t size,
1588 const WifiTxVector& txVector,
1589 WifiPhyBand band,
1590 uint16_t staId)
1591{
1592 Time duration = CalculatePhyPreambleAndHeaderDuration(txVector) +
1593 GetPayloadDuration(size, txVector, band, NORMAL_MPDU, staId);
1594 NS_ASSERT(duration.IsStrictlyPositive());
1595 return duration;
1596}
1597
1598Time
1599WifiPhy::CalculateTxDuration(Ptr<const WifiPsdu> psdu,
1600 const WifiTxVector& txVector,
1601 WifiPhyBand band)
1602{
1603 return CalculateTxDuration(GetWifiConstPsduMap(psdu, txVector), txVector, band);
1604}
1605
1606Time
1607WifiPhy::CalculateTxDuration(const WifiConstPsduMap& psduMap,
1608 const WifiTxVector& txVector,
1609 WifiPhyBand band)
1610{
1611 return GetStaticPhyEntity(txVector.GetModulationClass())
1612 ->CalculateTxDuration(psduMap, txVector, band);
1613}
1614
1616WifiPhy::GetMaxPsduSize(WifiModulationClass modulation)
1617{
1618 return GetStaticPhyEntity(modulation)->GetMaxPsduSize();
1619}
1620
1621void
1622WifiPhy::NotifyTxBegin(const WifiConstPsduMap& psdus, Watt_u txPower)
1623{
1624 if (!m_phyTxBeginTrace.IsEmpty())
1625 {
1626 for (const auto& psdu : psdus)
1627 {
1628 for (auto& mpdu : *PeekPointer(psdu.second))
1629 {
1630 m_phyTxBeginTrace(mpdu->GetProtocolDataUnit(), txPower);
1631 }
1632 }
1633 }
1634}
1635
1636void
1637WifiPhy::NotifyTxEnd(const WifiConstPsduMap& psdus)
1638{
1639 if (!m_phyTxEndTrace.IsEmpty())
1640 {
1641 for (const auto& psdu : psdus)
1642 {
1643 for (auto& mpdu : *PeekPointer(psdu.second))
1644 {
1645 m_phyTxEndTrace(mpdu->GetProtocolDataUnit());
1646 }
1647 }
1648 }
1649}
1650
1651void
1652WifiPhy::NotifyTxDrop(Ptr<const WifiPsdu> psdu)
1653{
1654 if (!m_phyTxDropTrace.IsEmpty())
1655 {
1656 for (auto& mpdu : *PeekPointer(psdu))
1657 {
1658 m_phyTxDropTrace(mpdu->GetProtocolDataUnit());
1659 }
1660 }
1661}
1662
1663void
1664WifiPhy::NotifyRxBegin(Ptr<const WifiPsdu> psdu, const RxPowerWattPerChannelBand& rxPowersW)
1665{
1666 if (psdu && !m_phyRxBeginTrace.IsEmpty())
1667 {
1668 for (auto& mpdu : *PeekPointer(psdu))
1669 {
1670 m_phyRxBeginTrace(mpdu->GetProtocolDataUnit(), rxPowersW);
1671 }
1672 }
1673}
1674
1675void
1676WifiPhy::NotifyRxEnd(Ptr<const WifiPsdu> psdu)
1677{
1678 if (psdu && !m_phyRxEndTrace.IsEmpty())
1679 {
1680 for (auto& mpdu : *PeekPointer(psdu))
1681 {
1682 m_phyRxEndTrace(mpdu->GetProtocolDataUnit());
1683 }
1684 }
1685}
1686
1687void
1688WifiPhy::NotifyRxDrop(Ptr<const WifiPsdu> psdu, WifiPhyRxfailureReason reason)
1689{
1690 if (psdu && !m_phyRxDropTrace.IsEmpty())
1691 {
1692 for (auto& mpdu : *PeekPointer(psdu))
1693 {
1694 m_phyRxDropTrace(mpdu->GetProtocolDataUnit(), reason);
1695 }
1696 }
1697}
1698
1699void
1700WifiPhy::NotifyRxPpduDrop(Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason)
1701{
1702 NotifyRxDrop(GetAddressedPsduInPpdu(ppdu), reason);
1703 m_phyRxPpduDropTrace(ppdu, reason);
1704}
1705
1706void
1707WifiPhy::NotifyMonitorSniffRx(Ptr<const WifiPsdu> psdu,
1708 MHz_u channelFreq,
1709 const WifiTxVector& txVector,
1710 SignalNoiseDbm signalNoise,
1711 const std::vector<bool>& statusPerMpdu,
1712 uint16_t staId)
1713{
1714 MpduInfo aMpdu;
1715 if (psdu->IsAggregate())
1716 {
1717 // Expand A-MPDU
1718 NS_ASSERT_MSG(txVector.IsAggregation(),
1719 "TxVector with aggregate flag expected here according to PSDU");
1720 aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber;
1721 size_t nMpdus = psdu->GetNMpdus();
1722 NS_ASSERT_MSG(statusPerMpdu.size() == nMpdus, "Should have one reception status per MPDU");
1723 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1724 {
1725 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1726 for (size_t i = 0; i < nMpdus;)
1727 {
1728 if (statusPerMpdu.at(i)) // packet received without error, hand over to sniffer
1729 {
1730 m_phyMonitorSniffRxTrace(psdu->GetAmpduSubframe(i),
1731 static_cast<uint16_t>(channelFreq),
1732 txVector,
1733 aMpdu,
1734 signalNoise,
1735 staId);
1736 }
1737 ++i;
1738 aMpdu.type =
1739 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1740 }
1741 }
1742 }
1743 else
1744 {
1745 NS_ASSERT_MSG(statusPerMpdu.size() == 1,
1746 "Should have one reception status for normal MPDU");
1747 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1748 {
1749 aMpdu.type = NORMAL_MPDU;
1750 m_phyMonitorSniffRxTrace(psdu->GetPacket(),
1751 static_cast<uint16_t>(channelFreq),
1752 txVector,
1753 aMpdu,
1754 signalNoise,
1755 staId);
1756 }
1757 }
1758}
1759
1760void
1761WifiPhy::NotifyMonitorSniffTx(Ptr<const WifiPsdu> psdu,
1762 MHz_u channelFreq,
1763 const WifiTxVector& txVector,
1764 uint16_t staId)
1765{
1766 MpduInfo aMpdu;
1767 if (psdu->IsAggregate())
1768 {
1769 // Expand A-MPDU
1770 NS_ASSERT_MSG(txVector.IsAggregation(),
1771 "TxVector with aggregate flag expected here according to PSDU");
1772 aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber;
1773 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1774 {
1775 size_t nMpdus = psdu->GetNMpdus();
1776 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1777 for (size_t i = 0; i < nMpdus;)
1778 {
1779 m_phyMonitorSniffTxTrace(psdu->GetAmpduSubframe(i),
1780 channelFreq,
1781 txVector,
1782 aMpdu,
1783 staId);
1784 ++i;
1785 aMpdu.type =
1786 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1787 }
1788 }
1789 }
1790 else
1791 {
1792 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1793 {
1794 aMpdu.type = NORMAL_MPDU;
1795 m_phyMonitorSniffTxTrace(psdu->GetPacket(), channelFreq, txVector, aMpdu, staId);
1796 }
1797 }
1798}
1799
1800std::optional<Time>
1801WifiPhy::GetTimeToMacHdrEnd(uint16_t staId) const
1802{
1803 for (auto& [modClass, phyEntity] : m_phyEntities)
1804 {
1805 if (auto remTime = phyEntity->GetTimeToMacHdrEnd(staId))
1806 {
1807 return remTime;
1808 }
1809 }
1810 return std::nullopt;
1811}
1812
1814WifiPhy::GetWifiConstPsduMap(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector)
1815{
1816 return GetStaticPhyEntity(txVector.GetModulationClass())->GetWifiConstPsduMap(psdu, txVector);
1817}
1818
1819void
1820WifiPhy::Send(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector)
1821{
1822 NS_LOG_FUNCTION(this << *psdu << txVector);
1823 Send(GetWifiConstPsduMap(psdu, txVector), txVector);
1824}
1825
1826void
1827WifiPhy::Send(const WifiConstPsduMap& psdus, const WifiTxVector& txVector)
1828{
1829 NS_LOG_FUNCTION(this << psdus << txVector);
1830 /* Transmission can happen if:
1831 * - we are syncing on a packet. It is the responsibility of the
1832 * MAC layer to avoid doing this but the PHY does nothing to
1833 * prevent it.
1834 * - we are idle
1835 */
1836 NS_ASSERT(!m_state->IsStateTx() && !m_state->IsStateSwitching());
1837 NS_ASSERT(m_endTxEvent.IsExpired());
1838
1839 if (!txVector.IsValid(m_band))
1840 {
1841 NS_FATAL_ERROR("TX-VECTOR is invalid!");
1842 }
1843
1844 uint8_t nss = 0;
1845 if (txVector.IsMu())
1846 {
1847 // We do not support mixed OFDMA and MU-MIMO
1848 if (txVector.IsDlMuMimo())
1849 {
1850 nss = txVector.GetNssTotal();
1851 }
1852 else
1853 {
1854 nss = txVector.GetNssMax();
1855 }
1856 }
1857 else
1858 {
1859 nss = txVector.GetNss();
1860 }
1861
1862 if (nss > GetMaxSupportedTxSpatialStreams())
1863 {
1864 NS_FATAL_ERROR("Unsupported number of spatial streams!");
1865 }
1866
1867 if (m_state->IsStateSleep())
1868 {
1869 NS_LOG_DEBUG("Dropping packet because in sleep mode");
1870 for (const auto& psdu : psdus)
1871 {
1872 NotifyTxDrop(psdu.second);
1873 }
1874 return;
1875 }
1876
1877 const auto txDuration = CalculateTxDuration(psdus, txVector, GetPhyBand());
1878
1879 auto noEndPreambleDetectionEvent = true;
1880 for (const auto& [mc, entity] : m_phyEntities)
1881 {
1882 noEndPreambleDetectionEvent =
1883 noEndPreambleDetectionEvent && entity->NoEndPreambleDetectionEvents();
1884 }
1885 if (!noEndPreambleDetectionEvent && !m_currentEvent)
1886 {
1887 // PHY is in the initial few microseconds during which the
1888 // start of RX has occurred but the preamble detection period
1889 // has not elapsed
1890 AbortCurrentReception(SIGNAL_DETECTION_ABORTED_BY_TX);
1891 }
1892 else if (!noEndPreambleDetectionEvent || m_currentEvent)
1893 {
1894 AbortCurrentReception(RECEPTION_ABORTED_BY_TX);
1895 }
1896
1897 if (m_powerRestricted)
1898 {
1899 NS_LOG_DEBUG("Transmitting with power restriction for " << txDuration.As(Time::NS));
1900 }
1901 else
1902 {
1903 NS_LOG_DEBUG("Transmitting without power restriction for " << txDuration.As(Time::NS));
1904 }
1905
1906 if (m_state->GetState() == WifiPhyState::OFF)
1907 {
1908 NS_LOG_DEBUG("Transmission canceled because device is OFF");
1909 return;
1910 }
1911
1912 auto ppdu = GetPhyEntity(txVector.GetModulationClass())->BuildPpdu(psdus, txVector, txDuration);
1913 m_previouslyRxPpduUid = UINT64_MAX; // reset (after creation of PPDU) to use it only once
1914
1915 const auto txPower = DbmToW(GetTxPowerForTransmission(ppdu) + GetTxGain());
1916 NotifyTxBegin(psdus, txPower);
1917 if (!m_phyTxPsduBeginTrace.IsEmpty())
1918 {
1919 m_phyTxPsduBeginTrace(psdus, txVector, txPower);
1920 }
1921 for (const auto& psdu : psdus)
1922 {
1923 NotifyMonitorSniffTx(psdu.second, GetFrequency(), txVector, psdu.first);
1924 }
1925 m_state->SwitchToTx(txDuration, psdus, GetPower(txVector.GetTxPowerLevel()), txVector);
1926
1927 if (m_wifiRadioEnergyModel &&
1928 m_wifiRadioEnergyModel->GetMaximumTimeInState(WifiPhyState::TX) < txDuration)
1929 {
1930 ppdu->SetTruncatedTx();
1931 }
1932
1933 m_endTxEvent =
1934 Simulator::Schedule(txDuration, &WifiPhy::TxDone, this, psdus); // TODO: fix for MU
1935
1936 StartTx(ppdu);
1937 ppdu->ResetTxVector();
1938
1939 m_channelAccessRequested = false;
1940 m_powerRestricted = false;
1941}
1942
1943void
1944WifiPhy::TxDone(const WifiConstPsduMap& psdus)
1945{
1946 NS_LOG_FUNCTION(this << psdus);
1947 NotifyTxEnd(psdus);
1948 Reset();
1949 // we might have received signals during TX
1950 SwitchMaybeToCcaBusy();
1951}
1952
1953uint64_t
1954WifiPhy::GetPreviouslyRxPpduUid() const
1955{
1956 return m_previouslyRxPpduUid;
1957}
1958
1959void
1960WifiPhy::SetPreviouslyRxPpduUid(uint64_t uid)
1961{
1962 NS_ASSERT(m_standard >= WIFI_STANDARD_80211be);
1963 m_previouslyRxPpduUid = uid;
1964}
1965
1966void
1967WifiPhy::Reset()
1968{
1969 NS_LOG_FUNCTION(this);
1970 m_currentPreambleEvents.clear();
1971 bool noEndPreambleDetectionEvent = true;
1972 for (const auto& [mc, entity] : m_phyEntities)
1973 {
1974 noEndPreambleDetectionEvent =
1975 noEndPreambleDetectionEvent && entity->NoEndPreambleDetectionEvents();
1976 }
1977 if (m_interference && (m_currentEvent || !noEndPreambleDetectionEvent))
1978 {
1979 m_interference->NotifyRxEnd(Simulator::Now(), GetCurrentFrequencyRange());
1980 }
1981 m_currentEvent = nullptr;
1982 for (auto& phyEntity : m_phyEntities)
1983 {
1984 phyEntity.second->CancelAllEvents();
1985 }
1986 m_endPhyRxEvent.Cancel();
1987 m_endTxEvent.Cancel();
1988}
1989
1990void
1991WifiPhy::StartReceivePreamble(Ptr<const WifiPpdu> ppdu,
1992 RxPowerWattPerChannelBand& rxPowersW,
1993 Time rxDuration)
1994{
1995 NS_LOG_FUNCTION(this << ppdu << rxDuration);
1996 WifiModulationClass modulation = ppdu->GetModulation();
1997 NS_ASSERT(m_maxModClassSupported != WIFI_MOD_CLASS_UNKNOWN);
1998 if (auto it = m_phyEntities.find(modulation);
1999 it != m_phyEntities.end() && modulation <= m_maxModClassSupported)
2000 {
2001 it->second->StartReceivePreamble(ppdu, rxPowersW, rxDuration);
2002 }
2003 else
2004 {
2005 // TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble
2006 // structure)
2007 NS_LOG_DEBUG("Unsupported modulation received (" << modulation << "), consider as noise");
2008 m_interference->Add(ppdu, rxDuration, rxPowersW, GetCurrentFrequencyRange());
2009 SwitchMaybeToCcaBusy();
2010 }
2011}
2012
2013std::optional<std::reference_wrapper<const WifiTxVector>>
2014WifiPhy::GetInfoIfRxingPhyHeader() const
2015{
2016 if (m_endPhyRxEvent.IsPending())
2017 {
2018 NS_ASSERT_MSG(m_currentEvent, "No current event while receiving PHY header");
2019 return std::cref(m_currentEvent->GetPpdu()->GetTxVector());
2020 }
2021 return std::nullopt;
2022}
2023
2024void
2025WifiPhy::EndReceiveInterBss()
2026{
2027 NS_LOG_FUNCTION(this);
2028 if (!m_channelAccessRequested)
2029 {
2030 m_powerRestricted = false;
2031 }
2032}
2033
2034void
2035WifiPhy::NotifyChannelAccessRequested()
2036{
2037 NS_LOG_FUNCTION(this);
2038 m_channelAccessRequested = true;
2039}
2040
2041bool
2042WifiPhy::IsModeSupported(WifiMode mode) const
2043{
2044 for (const auto& phyEntity : m_phyEntities)
2045 {
2046 if (phyEntity.second->IsModeSupported(mode))
2047 {
2048 return true;
2049 }
2050 }
2051 return false;
2052}
2053
2055WifiPhy::GetDefaultMode() const
2056{
2057 // Start from oldest standards and move up (guaranteed by fact that WifModulationClass is
2058 // ordered)
2059 for (const auto& phyEntity : m_phyEntities)
2060 {
2061 for (const auto& mode : *(phyEntity.second))
2062 {
2063 return mode;
2064 }
2065 }
2066 NS_ASSERT_MSG(false, "Should have found at least one default mode");
2067 return WifiMode();
2068}
2069
2070bool
2071WifiPhy::IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
2072{
2073 const auto phyEntity = m_phyEntities.find(modulation);
2074 if (phyEntity == m_phyEntities.end())
2075 {
2076 return false;
2077 }
2078 return phyEntity->second->IsMcsSupported(mcs);
2079}
2080
2081std::list<WifiMode>
2082WifiPhy::GetModeList() const
2083{
2084 std::list<WifiMode> list;
2085 for (const auto& phyEntity : m_phyEntities)
2086 {
2087 if (!phyEntity.second->HandlesMcsModes()) // to exclude MCSs from search
2088 {
2089 for (const auto& mode : *(phyEntity.second))
2090 {
2091 list.emplace_back(mode);
2092 }
2093 }
2094 }
2095 return list;
2096}
2097
2098std::list<WifiMode>
2099WifiPhy::GetModeList(WifiModulationClass modulation) const
2100{
2101 std::list<WifiMode> list;
2102 const auto phyEntity = m_phyEntities.find(modulation);
2103 if (phyEntity != m_phyEntities.end())
2104 {
2105 if (!phyEntity->second->HandlesMcsModes()) // to exclude MCSs from search
2106 {
2107 for (const auto& mode : *(phyEntity->second))
2108 {
2109 list.emplace_back(mode);
2110 }
2111 }
2112 }
2113 return list;
2114}
2115
2116uint16_t
2117WifiPhy::GetNMcs() const
2118{
2119 uint16_t numMcs = 0;
2120 for (const auto& phyEntity : m_phyEntities)
2121 {
2122 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2123 {
2124 numMcs += phyEntity.second->GetNumModes();
2125 }
2126 }
2127 return numMcs;
2128}
2129
2130std::list<WifiMode>
2131WifiPhy::GetMcsList() const
2132{
2133 std::list<WifiMode> list;
2134 for (const auto& phyEntity : m_phyEntities)
2135 {
2136 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2137 {
2138 for (const auto& mode : *(phyEntity.second))
2139 {
2140 list.emplace_back(mode);
2141 }
2142 }
2143 }
2144 return list;
2145}
2146
2147std::list<WifiMode>
2148WifiPhy::GetMcsList(WifiModulationClass modulation) const
2149{
2150 std::list<WifiMode> list;
2151 auto phyEntity = m_phyEntities.find(modulation);
2152 if (phyEntity != m_phyEntities.end())
2153 {
2154 if (phyEntity->second->HandlesMcsModes()) // to exclude non-MCS modes from search
2155 {
2156 for (const auto& mode : *(phyEntity->second))
2157 {
2158 list.emplace_back(mode);
2159 }
2160 }
2161 }
2162 return list;
2163}
2164
2166WifiPhy::GetMcs(WifiModulationClass modulation, uint8_t mcs) const
2167{
2168 NS_ASSERT_MSG(IsMcsSupported(modulation, mcs), "Unsupported MCS");
2169 return m_phyEntities.at(modulation)->GetMcs(mcs);
2170}
2171
2172bool
2173WifiPhy::IsStateCcaBusy() const
2174{
2175 return m_state->IsStateCcaBusy();
2176}
2177
2178bool
2179WifiPhy::IsStateIdle() const
2180{
2181 return m_state->IsStateIdle();
2182}
2183
2184bool
2185WifiPhy::IsStateRx() const
2186{
2187 return m_state->IsStateRx();
2188}
2189
2190bool
2191WifiPhy::IsStateTx() const
2192{
2193 return m_state->IsStateTx();
2194}
2195
2196bool
2197WifiPhy::IsStateSwitching() const
2198{
2199 return m_state->IsStateSwitching();
2200}
2201
2202bool
2203WifiPhy::IsStateSleep() const
2204{
2205 return m_state->IsStateSleep();
2206}
2207
2208bool
2209WifiPhy::IsStateOff() const
2210{
2211 return m_state->IsStateOff();
2212}
2213
2214Time
2215WifiPhy::GetDelayUntilIdle()
2216{
2217 return m_state->GetDelayUntilIdle();
2218}
2219
2220Time
2221WifiPhy::GetLastRxStartTime() const
2222{
2223 return m_state->GetLastRxStartTime();
2224}
2225
2226Time
2227WifiPhy::GetLastRxEndTime() const
2228{
2229 return m_state->GetLastRxEndTime();
2230}
2231
2232void
2233WifiPhy::SwitchMaybeToCcaBusy(const Ptr<const WifiPpdu> ppdu /* = nullptr */)
2234{
2235 NS_LOG_FUNCTION(this);
2236 GetLatestPhyEntity()->SwitchMaybeToCcaBusy(ppdu);
2237}
2238
2239void
2240WifiPhy::NotifyCcaBusy(const Ptr<const WifiPpdu> ppdu, Time duration)
2241{
2242 NS_LOG_FUNCTION(this << duration);
2243 GetLatestPhyEntity()->NotifyCcaBusy(ppdu, duration, WIFI_CHANLIST_PRIMARY);
2244}
2245
2246void
2247WifiPhy::AbortCurrentReception(WifiPhyRxfailureReason reason)
2248{
2249 NS_LOG_FUNCTION(this << reason);
2250 if (reason != OBSS_PD_CCA_RESET ||
2251 m_currentEvent) // Otherwise abort has already been called previously
2252 {
2253 if (reason == SIGNAL_DETECTION_ABORTED_BY_TX)
2254 {
2255 for (auto signalDetectEvent : m_currentPreambleEvents)
2256 {
2257 NotifyRxPpduDrop(signalDetectEvent.second->GetPpdu(),
2259 }
2260 }
2261 for (auto& phyEntity : m_phyEntities)
2262 {
2263 phyEntity.second->CancelAllEvents();
2264 }
2265 m_endPhyRxEvent.Cancel();
2266 m_interference->NotifyRxEnd(Simulator::Now(), GetCurrentFrequencyRange());
2267 if (!m_currentEvent)
2268 {
2269 return;
2270 }
2271 NotifyRxPpduDrop(m_currentEvent->GetPpdu(), reason);
2272 if (reason == OBSS_PD_CCA_RESET)
2273 {
2274 m_state->SwitchFromRxAbort(GetChannelWidth());
2275 }
2276 if (reason == RECEPTION_ABORTED_BY_TX)
2277 {
2278 Reset();
2279 }
2280 else
2281 {
2282 for (auto it = m_currentPreambleEvents.begin(); it != m_currentPreambleEvents.end();
2283 ++it)
2284 {
2285 if (it->second == m_currentEvent)
2286 {
2287 it = m_currentPreambleEvents.erase(it);
2288 break;
2289 }
2290 }
2291 m_currentEvent = nullptr;
2292 }
2293 }
2294}
2295
2296void
2297WifiPhy::ResetCca(bool powerRestricted, dBm_u txPowerMaxSiso, dBm_u txPowerMaxMimo)
2298{
2299 NS_LOG_FUNCTION(this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2300 // This method might be called multiple times when receiving TB PPDUs with a BSS color
2301 // different than the one of the receiver. The first time this method is called, the call
2302 // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2303 // m_currentEvent is not 0 before executing the instructions below.
2304 if (m_currentEvent)
2305 {
2306 m_powerRestricted = powerRestricted;
2307 m_txPowerMaxSiso = txPowerMaxSiso;
2308 m_txPowerMaxMimo = txPowerMaxMimo;
2309 NS_ASSERT((m_currentEvent->GetEndTime() - Simulator::Now()).IsPositive());
2310 Simulator::Schedule(m_currentEvent->GetEndTime() - Simulator::Now(),
2311 &WifiPhy::EndReceiveInterBss,
2312 this);
2313 Simulator::ScheduleNow(&WifiPhy::AbortCurrentReception,
2314 this,
2315 OBSS_PD_CCA_RESET); // finish processing field first
2316 }
2317}
2318
2319dBm_u
2320WifiPhy::GetTxPowerForTransmission(Ptr<const WifiPpdu> ppdu) const
2321{
2322 NS_LOG_FUNCTION(this << m_powerRestricted << ppdu);
2323 const auto& txVector = ppdu->GetTxVector();
2324 // Get transmit power before antenna gain
2325 dBm_u txPower;
2326 if (!m_powerRestricted)
2327 {
2328 txPower = GetPower(txVector.GetTxPowerLevel());
2329 }
2330 else
2331 {
2332 if (txVector.GetNssMax() > 1 || txVector.GetNssTotal() > 1)
2333 {
2334 txPower = std::min(m_txPowerMaxMimo, GetPower(txVector.GetTxPowerLevel()));
2335 }
2336 else
2337 {
2338 txPower = std::min(m_txPowerMaxSiso, GetPower(txVector.GetTxPowerLevel()));
2339 }
2340 }
2341
2342 // Apply power density constraint on EIRP
2343 const auto channelWidth = ppdu->GetTxChannelWidth();
2344 dBm_per_MHz_u txPowerDbmPerMhz =
2345 (txPower + GetTxGain()) - RatioToDb(channelWidth); // account for antenna gain since EIRP
2346 NS_LOG_INFO("txPower=" << txPower << "dBm with txPowerDbmPerMhz=" << txPowerDbmPerMhz
2347 << " over " << channelWidth << " MHz");
2348 txPower = std::min(txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb(channelWidth);
2349 txPower -= GetTxGain(); // remove antenna gain since will be added right afterwards
2350 NS_LOG_INFO("txPower=" << txPower
2351 << "dBm after applying m_powerDensityLimit=" << m_powerDensityLimit);
2352 return txPower;
2353}
2354
2356WifiPhy::GetAddressedPsduInPpdu(Ptr<const WifiPpdu> ppdu) const
2357{
2358 // TODO: wrapper. See if still needed
2359 return GetPhyEntityForPpdu(ppdu)->GetAddressedPsduInPpdu(ppdu);
2360}
2361
2362int64_t
2363WifiPhy::AssignStreams(int64_t stream)
2364{
2365 NS_LOG_FUNCTION(this << stream);
2366 int64_t currentStream = stream;
2367 m_random->SetStream(currentStream++);
2368 currentStream += m_interference->GetErrorRateModel()->AssignStreams(currentStream);
2369 return (currentStream - stream);
2370}
2371
2372std::ostream&
2373operator<<(std::ostream& os, RxSignalInfo rxSignalInfo)
2374{
2375 os << "SNR:" << RatioToDb(rxSignalInfo.snr) << " dB"
2376 << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2377 return os;
2378}
2379
2380uint8_t
2381WifiPhy::GetPrimaryChannelNumber(MHz_u primaryChannelWidth) const
2382{
2383 return m_operatingChannel.GetPrimaryChannelNumber(primaryChannelWidth, m_standard);
2384}
2385
2386Hz_u
2387WifiPhy::GetSubcarrierSpacing() const
2388{
2389 Hz_u subcarrierSpacing{0};
2390 switch (GetStandard())
2391 {
2397 subcarrierSpacing = Hz_u{312500};
2398 break;
2400 if (GetChannelWidth() == MHz_u{5})
2401 {
2402 subcarrierSpacing = Hz_u{78125};
2403 }
2404 else
2405 {
2406 subcarrierSpacing = Hz_u{156250};
2407 }
2408 break;
2411 subcarrierSpacing = Hz_u{78125};
2412 break;
2413 default:
2414 NS_FATAL_ERROR("Standard unknown: " << GetStandard());
2415 break;
2416 }
2417 return subcarrierSpacing;
2418}
2419
2420} // 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 Time.
Definition nstime.h:1432
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
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:40
WifiModulationClass GetModulationClass() const
Definition wifi-mode.cc:174
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:1334
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition wifi-phy.h:1349
Time GetBlockAckTxTime() const
Return the estimated BlockAck TX time for this PHY.
Definition wifi-phy.cc:865
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition wifi-phy.h:1648
dBm_u m_ccaEdThreshold
Clear channel assessment (CCA) energy detection (ED) threshold.
Definition wifi-phy.h:1621
dBm_u GetTxPowerStart() const
Return the minimum available transmission power level.
Definition wifi-phy.cc:570
WifiModulationClass GetMaxModulationClassSupported() const
Definition wifi-phy.cc:1003
void SetRxGain(dB_u gain)
Sets the reception gain.
Definition wifi-phy.cc:615
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition wifi-phy.cc:678
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition wifi-phy.h:1640
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition wifi-phy.h:1348
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition wifi-phy.h:1652
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:552
void Configure80211ax()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard.
Definition wifi-phy.cc:973
void SetRxSensitivity(dBm_u threshold)
Sets the receive sensitivity threshold.
Definition wifi-phy.cc:513
Time m_channelSwitchDelay
Time required to switch between channel.
Definition wifi-phy.h:1645
dB_u GetTxGain() const
Return the transmission gain.
Definition wifi-phy.cc:609
void SetTxPowerEnd(dBm_u end)
Sets the maximum available transmission power level.
Definition wifi-phy.cc:576
dBm_per_MHz_u m_powerDensityLimit
the power density limit
Definition wifi-phy.h:1630
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition wifi-phy.h:1611
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:1502
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition wifi-phy.cc:687
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition wifi-phy.h:1635
Time GetSlot() const
Return the slot duration for this PHY.
Definition wifi-phy.cc:841
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition wifi-phy.cc:1384
void Configure80211g()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard.
Definition wifi-phy.cc:903
uint8_t GetPrimary20Index() const
Definition wifi-phy.cc:1105
dBm_u m_rxSensitivity
Receive sensitivity threshold.
Definition wifi-phy.h:1620
uint8_t GetNumberOfAntennas() const
Definition wifi-phy.cc:1346
Time m_slot
Slot duration.
Definition wifi-phy.h:1615
dBm_u GetRxSensitivity() const
Return the receive sensitivity threshold.
Definition wifi-phy.cc:520
Time GetDelayUntilIdle()
Definition wifi-phy.cc:2215
bool GetShortPhyPreambleSupported() const
Return whether short PHY preamble is supported.
Definition wifi-phy.cc:635
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition wifi-phy.cc:823
void Configure80211n()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard.
Definition wifi-phy.cc:946
dBm_u m_ccaSensitivityThreshold
Clear channel assessment (CCA) modulation and coding rate sensitivity threshold.
Definition wifi-phy.h:1622
void Configure80211be()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11be standard.
Definition wifi-phy.cc:988
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition wifi-phy.cc:829
bool m_notifyRxMacHeaderEnd
whether the PHY is capable of notifying MAC header RX end
Definition wifi-phy.h:1655
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:940
MHz_u GetFrequency() const
Definition wifi-phy.cc:1087
Ptr< MobilityModel > GetMobility() const
Return the mobility model this PHY is associated with.
Definition wifi-phy.cc:659
Time m_blockAckTxTime
estimated BlockAck TX time
Definition wifi-phy.h:1618
void SetTxPowerStart(dBm_u start)
Sets the minimum available transmission power level.
Definition wifi-phy.cc:563
void Configure80211p()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard.
Definition wifi-phy.cc:916
dBm_u m_txPowerEnd
Maximum transmission power.
Definition wifi-phy.h:1628
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition wifi-phy.cc:2247
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition wifi-phy.h:1650
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition wifi-phy.h:1545
Time GetChannelSwitchDelay() const
Definition wifi-phy.cc:739
void SetTxGain(dB_u gain)
Sets the transmission gain.
Definition wifi-phy.cc:602
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition wifi-phy.cc:1352
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition wifi-phy.h:1614
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition wifi-phy.cc:484
TracedCallback< Ptr< const WifiPpdu >, const WifiTxVector & > m_signalTransmissionCb
Signal Transmission callback.
Definition wifi-phy.h:1387
dBm_u GetTxPowerEnd() const
Return the maximum available transmission power level.
Definition wifi-phy.cc:583
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition wifi-phy.cc:1396
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition wifi-phy.cc:1009
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition wifi-phy.cc:695
uint8_t m_numberOfAntennas
Number of transmitters.
Definition wifi-phy.h:1639
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:1557
dBm_u GetCcaEdThreshold() const
Return the CCA energy detection threshold.
Definition wifi-phy.cc:533
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
Definition wifi-phy.cc:472
dBm_u m_txPowerBase
Minimum transmission power.
Definition wifi-phy.h:1627
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:628
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:589
void SetCcaSensitivityThreshold(dBm_u threshold)
Sets the CCA sensitivity threshold.
Definition wifi-phy.cc:539
WifiPhyBand m_band
WifiPhyBand.
Definition wifi-phy.h:1609
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition wifi-phy.cc:751
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:1596
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1384
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:1123
void SetMaxModulationClassSupported(WifiModulationClass modClass)
Set the maximum modulation class that has to be supported by this PHY object.
Definition wifi-phy.cc:996
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:810
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:1577
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition wifi-phy.h:1653
void RegisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition wifi-phy.cc:490
static std::map< WifiModulationClass, Ptr< PhyEntity > > & GetStaticPhyEntities()
Definition wifi-phy.cc:465
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition wifi-phy.cc:835
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition wifi-phy.cc:1069
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition wifi-phy.cc:760
uint8_t GetChannelNumber() const
Return current channel number.
Definition wifi-phy.cc:1093
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Definition wifi-phy.h:1494
std::optional< Time > GetDelayUntilChannelSwitch()
Perform any actions necessary when user changes operating channel after initialization.
Definition wifi-phy.cc:1193
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition wifi-phy.cc:714
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:1479
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-phy.cc:641
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition wifi-phy.h:1651
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition wifi-phy.cc:853
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:801
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:1486
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
Definition wifi-phy.h:946
dB_u m_txGain
Transmission gain.
Definition wifi-phy.h:1625
MHz_u GetChannelWidth() const
Definition wifi-phy.cc:1099
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:1135
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition wifi-phy.cc:647
WifiStandard m_standard
WifiStandard.
Definition wifi-phy.h:1607
uint8_t m_nTxPower
Number of available transmission power levels.
Definition wifi-phy.h:1629
void DoDispose() override
Destructor implementation.
Definition wifi-phy.cc:436
dB_u GetRxGain() const
Return the reception gain.
Definition wifi-phy.cc:622
void SetPhyId(uint8_t phyId)
Set the index allocated to this PHY.
Definition wifi-phy.cc:665
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition wifi-phy.cc:1234
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:1552
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition wifi-phy.cc:708
uint8_t m_phyId
the index of the PHY in the vector of PHYs held by the WifiNetDevice
Definition wifi-phy.h:1343
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition wifi-phy.cc:847
void Configure80211b()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard.
Definition wifi-phy.cc:886
void SetCcaEdThreshold(dBm_u threshold)
Sets the CCA energy detection threshold.
Definition wifi-phy.cc:526
dB_u m_noiseFigure
The noise figure.
Definition wifi-phy.h:1643
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:2233
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition wifi-phy.cc:653
dB_u m_rxGain
Reception gain.
Definition wifi-phy.h:1626
double CalculateSnr(const WifiTxVector &txVector, double ber) const
Definition wifi-phy.cc:745
void SetFixedPhyBand(bool enable)
Configure whether it is prohibited to change PHY band after initialization.
Definition wifi-phy.cc:1111
~WifiPhy() override
Definition wifi-phy.cc:405
void Configure80211ac()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard.
Definition wifi-phy.cc:965
bool HasFixedPhyBand() const
Definition wifi-phy.cc:1117
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:1510
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition wifi-phy.h:1647
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition wifi-phy.h:1346
void DoInitialize() override
Initialize() implementation.
Definition wifi-phy.cc:411
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition wifi-phy.h:1638
uint8_t GetPhyId() const
Get the index allocated to this PHY.
Definition wifi-phy.cc:672
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition wifi-phy.h:1616
WifiModulationClass m_maxModClassSupported
max modulation class supported
Definition wifi-phy.h:1608
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition wifi-phy.cc:1075
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition wifi-phy.cc:507
void SetReceiveOkCallback(RxOkCallback callback)
Definition wifi-phy.cc:478
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition wifi-phy.cc:702
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition wifi-phy.h:1632
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition wifi-phy.h:1657
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition wifi-phy.cc:781
Time GetAckTxTime() const
Return the estimated Ack TX time for this PHY.
Definition wifi-phy.cc:859
void Reset()
Reset data upon end of TX or RX.
Definition wifi-phy.cc:1967
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition wifi-phy.h:1526
TracedCallback< const WifiMacHeader &, const WifiTxVector &, Time > m_phyRxMacHeaderEndTrace
The trace source fired when the reception of a MAC header ends.
Definition wifi-phy.h:1537
uint8_t GetMaxSupportedTxSpatialStreams() const
Definition wifi-phy.cc:1378
void Configure80211a()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard.
Definition wifi-phy.cc:871
ChannelSegments m_channelSettings
Store operating channel settings until initialization.
Definition wifi-phy.h:1610
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition wifi-phy.cc:1081
dBm_u GetPower(uint8_t powerLevel) const
Get the power of the given power level.
Definition wifi-phy.cc:720
bool m_fixedPhyBand
True to prohibit changing PHY band after initialization.
Definition wifi-phy.h:1612
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition wifi-phy.cc:775
uint8_t GetNTxPower() const
Return the number of available transmission power levels.
Definition wifi-phy.cc:596
Time m_ackTxTime
estimated Ack TX time
Definition wifi-phy.h:1617
void UnregisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition wifi-phy.cc:501
dBm_u GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold.
Definition wifi-phy.cc:546
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(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#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:41
@ 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:53
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
Definition wifi-types.h:43
@ 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:48
@ SINGLE_MPDU
The MPDU is a single MPDU.
Definition wifi-types.h:45
@ 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:51
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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.
dB_u RatioToDb(double ratio)
Convert from ratio to dB.
Definition wifi-utils.cc:46
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.
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:27
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:33
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
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:65
MpduType type
type of MPDU
Definition wifi-types.h:66
uint32_t mpduRefNumber
MPDU ref number.
Definition wifi-types.h:67
RxSignalInfo structure containing info on the received signal.
Definition wifi-types.h:72
double snr
SNR in linear scale.
Definition wifi-types.h:73
dBm_u rssi
RSSI.
Definition wifi-types.h:74
SignalNoiseDbm structure.
Definition wifi-types.h:58
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.