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::Packet::TracedCallback")
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(Seconds(0)),
389 m_slot(Seconds(0)),
390 m_pifs(Seconds(0)),
391 m_ackTxTime(Seconds(0)),
392 m_blockAckTxTime(Seconds(0)),
393 m_powerRestricted(false),
394 m_channelAccessRequested(false),
395 m_txSpatialStreams(1),
396 m_rxSpatialStreams(1),
397 m_wifiRadioEnergyModel(nullptr),
398 m_timeLastPreambleDetected(Seconds(0))
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 + 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() == 10)
920 {
922
923 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
926 SetPifs(GetSifs() + GetSlot());
928 }
929 else if (GetChannelWidth() == 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 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(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 == 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 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->Get40MHzOperationSupported() && chWidth > 20)
1296 {
1297 NS_ABORT_MSG("Attempting to set a " << chWidth
1298 << " MHz channel on"
1299 "a station only supporting 20 MHz operation");
1300 }
1301
1302 if (auto vhtConfig = m_device->GetVhtConfiguration();
1303 vhtConfig && !vhtConfig->Get160MHzOperationSupported() && chWidth > 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()
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);
1427 break;
1428 case WifiPhyState::RX:
1429 NS_LOG_DEBUG("setting sleep mode postponed until end of current reception");
1430 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this);
1431 break;
1432 case WifiPhyState::SWITCHING:
1433 NS_LOG_DEBUG("setting sleep mode postponed until end of channel switching");
1434 Simulator::Schedule(GetDelayUntilIdle(), &WifiPhy::SetSleepMode, this);
1435 break;
1436 case WifiPhyState::CCA_BUSY:
1437 case WifiPhyState::IDLE:
1438 NS_LOG_DEBUG("setting sleep mode");
1439 // The PHY object may be in CCA_BUSY state because it is receiving a preamble. Cancel
1440 // preamble events before switching to sleep state
1441 Reset();
1442 m_state->SwitchToSleep();
1443 break;
1444 case WifiPhyState::SLEEP:
1445 NS_LOG_DEBUG("already in sleep mode");
1446 break;
1447 default:
1448 NS_ASSERT(false);
1449 break;
1450 }
1451}
1452
1453void
1454WifiPhy::SetOffMode()
1455{
1456 NS_LOG_FUNCTION(this);
1457 m_powerRestricted = false;
1458 m_channelAccessRequested = false;
1459 Reset();
1460 m_state->SwitchToOff();
1461}
1462
1463void
1464WifiPhy::ResumeFromSleep()
1465{
1466 NS_LOG_FUNCTION(this);
1467 switch (m_state->GetState())
1468 {
1469 case WifiPhyState::TX:
1470 case WifiPhyState::RX:
1471 case WifiPhyState::IDLE:
1472 case WifiPhyState::CCA_BUSY:
1473 case WifiPhyState::SWITCHING: {
1474 NS_LOG_DEBUG("not in sleep mode, there is nothing to resume");
1475 break;
1476 }
1477 case WifiPhyState::SLEEP: {
1478 NS_LOG_DEBUG("resuming from sleep mode");
1479 m_state->SwitchFromSleep();
1480 SwitchMaybeToCcaBusy();
1481 break;
1482 }
1483 default: {
1484 NS_ASSERT(false);
1485 break;
1486 }
1487 }
1488}
1489
1490void
1491WifiPhy::ResumeFromOff()
1492{
1493 NS_LOG_FUNCTION(this);
1494 switch (m_state->GetState())
1495 {
1496 case WifiPhyState::TX:
1497 case WifiPhyState::RX:
1498 case WifiPhyState::IDLE:
1499 case WifiPhyState::CCA_BUSY:
1500 case WifiPhyState::SWITCHING:
1501 case WifiPhyState::SLEEP: {
1502 NS_LOG_DEBUG("not in off mode, there is nothing to resume");
1503 break;
1504 }
1505 case WifiPhyState::OFF: {
1506 NS_LOG_DEBUG("resuming from off mode");
1507 m_state->SwitchFromOff();
1508 SwitchMaybeToCcaBusy();
1509 break;
1510 }
1511 default: {
1512 NS_ASSERT(false);
1513 break;
1514 }
1515 }
1516}
1517
1518Time
1519WifiPhy::GetPreambleDetectionDuration()
1520{
1521 return MicroSeconds(4);
1522}
1523
1524Time
1525WifiPhy::GetStartOfPacketDuration(const WifiTxVector& txVector)
1526{
1527 return MicroSeconds(4);
1528}
1529
1530Time
1531WifiPhy::GetPayloadDuration(uint32_t size,
1532 const WifiTxVector& txVector,
1533 WifiPhyBand band,
1534 MpduType mpdutype,
1535 uint16_t staId)
1536{
1537 uint32_t totalAmpduSize;
1538 double totalAmpduNumSymbols;
1539 return GetPayloadDuration(size,
1540 txVector,
1541 band,
1542 mpdutype,
1543 false,
1544 totalAmpduSize,
1545 totalAmpduNumSymbols,
1546 staId);
1547}
1548
1549Time
1550WifiPhy::GetPayloadDuration(uint32_t size,
1551 const WifiTxVector& txVector,
1552 WifiPhyBand band,
1553 MpduType mpdutype,
1554 bool incFlag,
1555 uint32_t& totalAmpduSize,
1556 double& totalAmpduNumSymbols,
1557 uint16_t staId)
1558{
1559 return GetStaticPhyEntity(txVector.GetModulationClass())
1560 ->GetPayloadDuration(size,
1561 txVector,
1562 band,
1563 mpdutype,
1564 incFlag,
1565 totalAmpduSize,
1566 totalAmpduNumSymbols,
1567 staId);
1568}
1569
1570Time
1571WifiPhy::CalculatePhyPreambleAndHeaderDuration(const WifiTxVector& txVector)
1572{
1573 return GetStaticPhyEntity(txVector.GetModulationClass())
1574 ->CalculatePhyPreambleAndHeaderDuration(txVector);
1575}
1576
1577Time
1578WifiPhy::CalculateTxDuration(uint32_t size,
1579 const WifiTxVector& txVector,
1580 WifiPhyBand band,
1581 uint16_t staId)
1582{
1583 Time duration = CalculatePhyPreambleAndHeaderDuration(txVector) +
1584 GetPayloadDuration(size, txVector, band, NORMAL_MPDU, staId);
1585 NS_ASSERT(duration.IsStrictlyPositive());
1586 return duration;
1587}
1588
1589Time
1590WifiPhy::CalculateTxDuration(Ptr<const WifiPsdu> psdu,
1591 const WifiTxVector& txVector,
1592 WifiPhyBand band)
1593{
1594 return CalculateTxDuration(GetWifiConstPsduMap(psdu, txVector), txVector, band);
1595}
1596
1597Time
1598WifiPhy::CalculateTxDuration(const WifiConstPsduMap& psduMap,
1599 const WifiTxVector& txVector,
1600 WifiPhyBand band)
1601{
1602 return GetStaticPhyEntity(txVector.GetModulationClass())
1603 ->CalculateTxDuration(psduMap, txVector, band);
1604}
1605
1607WifiPhy::GetMaxPsduSize(WifiModulationClass modulation)
1608{
1609 return GetStaticPhyEntity(modulation)->GetMaxPsduSize();
1610}
1611
1612void
1613WifiPhy::NotifyTxBegin(const WifiConstPsduMap& psdus, Watt_u txPower)
1614{
1615 if (!m_phyTxBeginTrace.IsEmpty())
1616 {
1617 for (const auto& psdu : psdus)
1618 {
1619 for (auto& mpdu : *PeekPointer(psdu.second))
1620 {
1621 m_phyTxBeginTrace(mpdu->GetProtocolDataUnit(), txPower);
1622 }
1623 }
1624 }
1625}
1626
1627void
1628WifiPhy::NotifyTxEnd(const WifiConstPsduMap& psdus)
1629{
1630 if (!m_phyTxEndTrace.IsEmpty())
1631 {
1632 for (const auto& psdu : psdus)
1633 {
1634 for (auto& mpdu : *PeekPointer(psdu.second))
1635 {
1636 m_phyTxEndTrace(mpdu->GetProtocolDataUnit());
1637 }
1638 }
1639 }
1640}
1641
1642void
1643WifiPhy::NotifyTxDrop(Ptr<const WifiPsdu> psdu)
1644{
1645 if (!m_phyTxDropTrace.IsEmpty())
1646 {
1647 for (auto& mpdu : *PeekPointer(psdu))
1648 {
1649 m_phyTxDropTrace(mpdu->GetProtocolDataUnit());
1650 }
1651 }
1652}
1653
1654void
1655WifiPhy::NotifyRxBegin(Ptr<const WifiPsdu> psdu, const RxPowerWattPerChannelBand& rxPowersW)
1656{
1657 if (psdu && !m_phyRxBeginTrace.IsEmpty())
1658 {
1659 for (auto& mpdu : *PeekPointer(psdu))
1660 {
1661 m_phyRxBeginTrace(mpdu->GetProtocolDataUnit(), rxPowersW);
1662 }
1663 }
1664}
1665
1666void
1667WifiPhy::NotifyRxEnd(Ptr<const WifiPsdu> psdu)
1668{
1669 if (psdu && !m_phyRxEndTrace.IsEmpty())
1670 {
1671 for (auto& mpdu : *PeekPointer(psdu))
1672 {
1673 m_phyRxEndTrace(mpdu->GetProtocolDataUnit());
1674 }
1675 }
1676}
1677
1678void
1679WifiPhy::NotifyRxDrop(Ptr<const WifiPsdu> psdu, WifiPhyRxfailureReason reason)
1680{
1681 if (psdu && !m_phyRxDropTrace.IsEmpty())
1682 {
1683 for (auto& mpdu : *PeekPointer(psdu))
1684 {
1685 m_phyRxDropTrace(mpdu->GetProtocolDataUnit(), reason);
1686 }
1687 }
1688}
1689
1690void
1691WifiPhy::NotifyRxPpduDrop(Ptr<const WifiPpdu> ppdu, WifiPhyRxfailureReason reason)
1692{
1693 NotifyRxDrop(GetAddressedPsduInPpdu(ppdu), reason);
1694 m_phyRxPpduDropTrace(ppdu, reason);
1695}
1696
1697void
1698WifiPhy::NotifyMonitorSniffRx(Ptr<const WifiPsdu> psdu,
1699 MHz_u channelFreq,
1700 const WifiTxVector& txVector,
1701 SignalNoiseDbm signalNoise,
1702 const std::vector<bool>& statusPerMpdu,
1703 uint16_t staId)
1704{
1705 MpduInfo aMpdu;
1706 if (psdu->IsAggregate())
1707 {
1708 // Expand A-MPDU
1709 NS_ASSERT_MSG(txVector.IsAggregation(),
1710 "TxVector with aggregate flag expected here according to PSDU");
1711 aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber;
1712 size_t nMpdus = psdu->GetNMpdus();
1713 NS_ASSERT_MSG(statusPerMpdu.size() == nMpdus, "Should have one reception status per MPDU");
1714 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1715 {
1716 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1717 for (size_t i = 0; i < nMpdus;)
1718 {
1719 if (statusPerMpdu.at(i)) // packet received without error, hand over to sniffer
1720 {
1721 m_phyMonitorSniffRxTrace(psdu->GetAmpduSubframe(i),
1722 static_cast<uint16_t>(channelFreq),
1723 txVector,
1724 aMpdu,
1725 signalNoise,
1726 staId);
1727 }
1728 ++i;
1729 aMpdu.type =
1730 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1731 }
1732 }
1733 }
1734 else
1735 {
1736 NS_ASSERT_MSG(statusPerMpdu.size() == 1,
1737 "Should have one reception status for normal MPDU");
1738 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1739 {
1740 aMpdu.type = NORMAL_MPDU;
1741 m_phyMonitorSniffRxTrace(psdu->GetPacket(),
1742 static_cast<uint16_t>(channelFreq),
1743 txVector,
1744 aMpdu,
1745 signalNoise,
1746 staId);
1747 }
1748 }
1749}
1750
1751void
1752WifiPhy::NotifyMonitorSniffTx(Ptr<const WifiPsdu> psdu,
1753 MHz_u channelFreq,
1754 const WifiTxVector& txVector,
1755 uint16_t staId)
1756{
1757 MpduInfo aMpdu;
1758 if (psdu->IsAggregate())
1759 {
1760 // Expand A-MPDU
1761 NS_ASSERT_MSG(txVector.IsAggregation(),
1762 "TxVector with aggregate flag expected here according to PSDU");
1763 aMpdu.mpduRefNumber = ++m_rxMpduReferenceNumber;
1764 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1765 {
1766 size_t nMpdus = psdu->GetNMpdus();
1767 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1768 for (size_t i = 0; i < nMpdus;)
1769 {
1770 m_phyMonitorSniffTxTrace(psdu->GetAmpduSubframe(i),
1771 channelFreq,
1772 txVector,
1773 aMpdu,
1774 staId);
1775 ++i;
1776 aMpdu.type =
1777 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1778 }
1779 }
1780 }
1781 else
1782 {
1783 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1784 {
1785 aMpdu.type = NORMAL_MPDU;
1786 m_phyMonitorSniffTxTrace(psdu->GetPacket(), channelFreq, txVector, aMpdu, staId);
1787 }
1788 }
1789}
1790
1792WifiPhy::GetWifiConstPsduMap(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector)
1793{
1794 return GetStaticPhyEntity(txVector.GetModulationClass())->GetWifiConstPsduMap(psdu, txVector);
1795}
1796
1797void
1798WifiPhy::Send(Ptr<const WifiPsdu> psdu, const WifiTxVector& txVector)
1799{
1800 NS_LOG_FUNCTION(this << *psdu << txVector);
1801 Send(GetWifiConstPsduMap(psdu, txVector), txVector);
1802}
1803
1804void
1805WifiPhy::Send(const WifiConstPsduMap& psdus, const WifiTxVector& txVector)
1806{
1807 NS_LOG_FUNCTION(this << psdus << txVector);
1808 /* Transmission can happen if:
1809 * - we are syncing on a packet. It is the responsibility of the
1810 * MAC layer to avoid doing this but the PHY does nothing to
1811 * prevent it.
1812 * - we are idle
1813 */
1814 NS_ASSERT(!m_state->IsStateTx() && !m_state->IsStateSwitching());
1815 NS_ASSERT(m_endTxEvent.IsExpired());
1816
1817 if (!txVector.IsValid(m_band))
1818 {
1819 NS_FATAL_ERROR("TX-VECTOR is invalid!");
1820 }
1821
1822 uint8_t nss = 0;
1823 if (txVector.IsMu())
1824 {
1825 // We do not support mixed OFDMA and MU-MIMO
1826 if (txVector.IsDlMuMimo())
1827 {
1828 nss = txVector.GetNssTotal();
1829 }
1830 else
1831 {
1832 nss = txVector.GetNssMax();
1833 }
1834 }
1835 else
1836 {
1837 nss = txVector.GetNss();
1838 }
1839
1840 if (nss > GetMaxSupportedTxSpatialStreams())
1841 {
1842 NS_FATAL_ERROR("Unsupported number of spatial streams!");
1843 }
1844
1845 if (m_state->IsStateSleep())
1846 {
1847 NS_LOG_DEBUG("Dropping packet because in sleep mode");
1848 for (const auto& psdu : psdus)
1849 {
1850 NotifyTxDrop(psdu.second);
1851 }
1852 return;
1853 }
1854
1855 const auto txDuration = CalculateTxDuration(psdus, txVector, GetPhyBand());
1856
1857 auto noEndPreambleDetectionEvent = true;
1858 for (const auto& [mc, entity] : m_phyEntities)
1859 {
1860 noEndPreambleDetectionEvent =
1861 noEndPreambleDetectionEvent && entity->NoEndPreambleDetectionEvents();
1862 }
1863 if (!noEndPreambleDetectionEvent && !m_currentEvent)
1864 {
1865 // PHY is in the initial few microseconds during which the
1866 // start of RX has occurred but the preamble detection period
1867 // has not elapsed
1868 AbortCurrentReception(SIGNAL_DETECTION_ABORTED_BY_TX);
1869 }
1870 else if (!noEndPreambleDetectionEvent || m_currentEvent)
1871 {
1872 AbortCurrentReception(RECEPTION_ABORTED_BY_TX);
1873 }
1874
1875 if (m_powerRestricted)
1876 {
1877 NS_LOG_DEBUG("Transmitting with power restriction for " << txDuration.As(Time::NS));
1878 }
1879 else
1880 {
1881 NS_LOG_DEBUG("Transmitting without power restriction for " << txDuration.As(Time::NS));
1882 }
1883
1884 if (m_state->GetState() == WifiPhyState::OFF)
1885 {
1886 NS_LOG_DEBUG("Transmission canceled because device is OFF");
1887 return;
1888 }
1889
1890 auto ppdu = GetPhyEntity(txVector.GetModulationClass())->BuildPpdu(psdus, txVector, txDuration);
1891 m_previouslyRxPpduUid = UINT64_MAX; // reset (after creation of PPDU) to use it only once
1892
1893 const auto txPower = DbmToW(GetTxPowerForTransmission(ppdu) + GetTxGain());
1894 NotifyTxBegin(psdus, txPower);
1895 if (!m_phyTxPsduBeginTrace.IsEmpty())
1896 {
1897 m_phyTxPsduBeginTrace(psdus, txVector, txPower);
1898 }
1899 for (const auto& psdu : psdus)
1900 {
1901 NotifyMonitorSniffTx(psdu.second, GetFrequency(), txVector, psdu.first);
1902 }
1903 m_state->SwitchToTx(txDuration, psdus, GetPower(txVector.GetTxPowerLevel()), txVector);
1904
1905 if (m_wifiRadioEnergyModel &&
1906 m_wifiRadioEnergyModel->GetMaximumTimeInState(WifiPhyState::TX) < txDuration)
1907 {
1908 ppdu->SetTruncatedTx();
1909 }
1910
1911 m_endTxEvent =
1912 Simulator::Schedule(txDuration, &WifiPhy::TxDone, this, psdus); // TODO: fix for MU
1913
1914 StartTx(ppdu);
1915 ppdu->ResetTxVector();
1916
1917 m_channelAccessRequested = false;
1918 m_powerRestricted = false;
1919}
1920
1921void
1922WifiPhy::TxDone(const WifiConstPsduMap& psdus)
1923{
1924 NS_LOG_FUNCTION(this << psdus);
1925 NotifyTxEnd(psdus);
1926 Reset();
1927 // we might have received signals during TX
1928 SwitchMaybeToCcaBusy();
1929}
1930
1931uint64_t
1932WifiPhy::GetPreviouslyRxPpduUid() const
1933{
1934 return m_previouslyRxPpduUid;
1935}
1936
1937void
1938WifiPhy::SetPreviouslyRxPpduUid(uint64_t uid)
1939{
1940 NS_ASSERT(m_standard >= WIFI_STANDARD_80211be);
1941 m_previouslyRxPpduUid = uid;
1942}
1943
1944void
1945WifiPhy::Reset()
1946{
1947 NS_LOG_FUNCTION(this);
1948 m_currentPreambleEvents.clear();
1949 bool noEndPreambleDetectionEvent = true;
1950 for (const auto& [mc, entity] : m_phyEntities)
1951 {
1952 noEndPreambleDetectionEvent =
1953 noEndPreambleDetectionEvent && entity->NoEndPreambleDetectionEvents();
1954 }
1955 if (m_interference && (m_currentEvent || !noEndPreambleDetectionEvent))
1956 {
1957 m_interference->NotifyRxEnd(Simulator::Now(), GetCurrentFrequencyRange());
1958 }
1959 m_currentEvent = nullptr;
1960 for (auto& phyEntity : m_phyEntities)
1961 {
1962 phyEntity.second->CancelAllEvents();
1963 }
1964 m_endPhyRxEvent.Cancel();
1965 m_endTxEvent.Cancel();
1966}
1967
1968void
1969WifiPhy::StartReceivePreamble(Ptr<const WifiPpdu> ppdu,
1970 RxPowerWattPerChannelBand& rxPowersW,
1971 Time rxDuration)
1972{
1973 NS_LOG_FUNCTION(this << ppdu << rxDuration);
1974 WifiModulationClass modulation = ppdu->GetModulation();
1975 NS_ASSERT(m_maxModClassSupported != WIFI_MOD_CLASS_UNKNOWN);
1976 if (auto it = m_phyEntities.find(modulation);
1977 it != m_phyEntities.end() && modulation <= m_maxModClassSupported)
1978 {
1979 it->second->StartReceivePreamble(ppdu, rxPowersW, rxDuration);
1980 }
1981 else
1982 {
1983 // TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble
1984 // structure)
1985 NS_LOG_DEBUG("Unsupported modulation received (" << modulation << "), consider as noise");
1986 m_interference->Add(ppdu, rxDuration, rxPowersW, GetCurrentFrequencyRange());
1987 SwitchMaybeToCcaBusy();
1988 }
1989}
1990
1991bool
1992WifiPhy::IsReceivingPhyHeader() const
1993{
1994 return m_endPhyRxEvent.IsPending();
1995}
1996
1997void
1998WifiPhy::EndReceiveInterBss()
1999{
2000 NS_LOG_FUNCTION(this);
2001 if (!m_channelAccessRequested)
2002 {
2003 m_powerRestricted = false;
2004 }
2005}
2006
2007void
2008WifiPhy::NotifyChannelAccessRequested()
2009{
2010 NS_LOG_FUNCTION(this);
2011 m_channelAccessRequested = true;
2012}
2013
2014bool
2015WifiPhy::IsModeSupported(WifiMode mode) const
2016{
2017 for (const auto& phyEntity : m_phyEntities)
2018 {
2019 if (phyEntity.second->IsModeSupported(mode))
2020 {
2021 return true;
2022 }
2023 }
2024 return false;
2025}
2026
2028WifiPhy::GetDefaultMode() const
2029{
2030 // Start from oldest standards and move up (guaranteed by fact that WifModulationClass is
2031 // ordered)
2032 for (const auto& phyEntity : m_phyEntities)
2033 {
2034 for (const auto& mode : *(phyEntity.second))
2035 {
2036 return mode;
2037 }
2038 }
2039 NS_ASSERT_MSG(false, "Should have found at least one default mode");
2040 return WifiMode();
2041}
2042
2043bool
2044WifiPhy::IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
2045{
2046 const auto phyEntity = m_phyEntities.find(modulation);
2047 if (phyEntity == m_phyEntities.end())
2048 {
2049 return false;
2050 }
2051 return phyEntity->second->IsMcsSupported(mcs);
2052}
2053
2054std::list<WifiMode>
2055WifiPhy::GetModeList() const
2056{
2057 std::list<WifiMode> list;
2058 for (const auto& phyEntity : m_phyEntities)
2059 {
2060 if (!phyEntity.second->HandlesMcsModes()) // to exclude MCSs from search
2061 {
2062 for (const auto& mode : *(phyEntity.second))
2063 {
2064 list.emplace_back(mode);
2065 }
2066 }
2067 }
2068 return list;
2069}
2070
2071std::list<WifiMode>
2072WifiPhy::GetModeList(WifiModulationClass modulation) const
2073{
2074 std::list<WifiMode> list;
2075 const auto phyEntity = m_phyEntities.find(modulation);
2076 if (phyEntity != m_phyEntities.end())
2077 {
2078 if (!phyEntity->second->HandlesMcsModes()) // to exclude MCSs from search
2079 {
2080 for (const auto& mode : *(phyEntity->second))
2081 {
2082 list.emplace_back(mode);
2083 }
2084 }
2085 }
2086 return list;
2087}
2088
2089uint16_t
2090WifiPhy::GetNMcs() const
2091{
2092 uint16_t numMcs = 0;
2093 for (const auto& phyEntity : m_phyEntities)
2094 {
2095 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2096 {
2097 numMcs += phyEntity.second->GetNumModes();
2098 }
2099 }
2100 return numMcs;
2101}
2102
2103std::list<WifiMode>
2104WifiPhy::GetMcsList() const
2105{
2106 std::list<WifiMode> list;
2107 for (const auto& phyEntity : m_phyEntities)
2108 {
2109 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2110 {
2111 for (const auto& mode : *(phyEntity.second))
2112 {
2113 list.emplace_back(mode);
2114 }
2115 }
2116 }
2117 return list;
2118}
2119
2120std::list<WifiMode>
2121WifiPhy::GetMcsList(WifiModulationClass modulation) const
2122{
2123 std::list<WifiMode> list;
2124 auto phyEntity = m_phyEntities.find(modulation);
2125 if (phyEntity != m_phyEntities.end())
2126 {
2127 if (phyEntity->second->HandlesMcsModes()) // to exclude non-MCS modes from search
2128 {
2129 for (const auto& mode : *(phyEntity->second))
2130 {
2131 list.emplace_back(mode);
2132 }
2133 }
2134 }
2135 return list;
2136}
2137
2139WifiPhy::GetMcs(WifiModulationClass modulation, uint8_t mcs) const
2140{
2141 NS_ASSERT_MSG(IsMcsSupported(modulation, mcs), "Unsupported MCS");
2142 return m_phyEntities.at(modulation)->GetMcs(mcs);
2143}
2144
2145bool
2146WifiPhy::IsStateCcaBusy() const
2147{
2148 return m_state->IsStateCcaBusy();
2149}
2150
2151bool
2152WifiPhy::IsStateIdle() const
2153{
2154 return m_state->IsStateIdle();
2155}
2156
2157bool
2158WifiPhy::IsStateRx() const
2159{
2160 return m_state->IsStateRx();
2161}
2162
2163bool
2164WifiPhy::IsStateTx() const
2165{
2166 return m_state->IsStateTx();
2167}
2168
2169bool
2170WifiPhy::IsStateSwitching() const
2171{
2172 return m_state->IsStateSwitching();
2173}
2174
2175bool
2176WifiPhy::IsStateSleep() const
2177{
2178 return m_state->IsStateSleep();
2179}
2180
2181bool
2182WifiPhy::IsStateOff() const
2183{
2184 return m_state->IsStateOff();
2185}
2186
2187Time
2188WifiPhy::GetDelayUntilIdle()
2189{
2190 return m_state->GetDelayUntilIdle();
2191}
2192
2193Time
2194WifiPhy::GetLastRxStartTime() const
2195{
2196 return m_state->GetLastRxStartTime();
2197}
2198
2199Time
2200WifiPhy::GetLastRxEndTime() const
2201{
2202 return m_state->GetLastRxEndTime();
2203}
2204
2205void
2206WifiPhy::SwitchMaybeToCcaBusy(const Ptr<const WifiPpdu> ppdu /* = nullptr */)
2207{
2208 NS_LOG_FUNCTION(this);
2209 GetLatestPhyEntity()->SwitchMaybeToCcaBusy(ppdu);
2210}
2211
2212void
2213WifiPhy::NotifyCcaBusy(const Ptr<const WifiPpdu> ppdu, Time duration)
2214{
2215 NS_LOG_FUNCTION(this << duration);
2216 GetLatestPhyEntity()->NotifyCcaBusy(ppdu, duration, WIFI_CHANLIST_PRIMARY);
2217}
2218
2219void
2220WifiPhy::AbortCurrentReception(WifiPhyRxfailureReason reason)
2221{
2222 NS_LOG_FUNCTION(this << reason);
2223 if (reason != OBSS_PD_CCA_RESET ||
2224 m_currentEvent) // Otherwise abort has already been called previously
2225 {
2226 if (reason == SIGNAL_DETECTION_ABORTED_BY_TX)
2227 {
2228 for (auto signalDetectEvent : m_currentPreambleEvents)
2229 {
2230 NotifyRxPpduDrop(signalDetectEvent.second->GetPpdu(),
2232 }
2233 }
2234 for (auto& phyEntity : m_phyEntities)
2235 {
2236 phyEntity.second->CancelAllEvents();
2237 }
2238 m_endPhyRxEvent.Cancel();
2239 m_interference->NotifyRxEnd(Simulator::Now(), GetCurrentFrequencyRange());
2240 if (!m_currentEvent)
2241 {
2242 return;
2243 }
2244 NotifyRxPpduDrop(m_currentEvent->GetPpdu(), reason);
2245 if (reason == OBSS_PD_CCA_RESET)
2246 {
2247 m_state->SwitchFromRxAbort(GetChannelWidth());
2248 }
2249 if (reason == RECEPTION_ABORTED_BY_TX)
2250 {
2251 Reset();
2252 }
2253 else
2254 {
2255 for (auto it = m_currentPreambleEvents.begin(); it != m_currentPreambleEvents.end();
2256 ++it)
2257 {
2258 if (it->second == m_currentEvent)
2259 {
2260 it = m_currentPreambleEvents.erase(it);
2261 break;
2262 }
2263 }
2264 m_currentEvent = nullptr;
2265 }
2266 }
2267}
2268
2269void
2270WifiPhy::ResetCca(bool powerRestricted, dBm_u txPowerMaxSiso, dBm_u txPowerMaxMimo)
2271{
2272 NS_LOG_FUNCTION(this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2273 // This method might be called multiple times when receiving TB PPDUs with a BSS color
2274 // different than the one of the receiver. The first time this method is called, the call
2275 // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2276 // m_currentEvent is not 0 before executing the instructions below.
2277 if (m_currentEvent)
2278 {
2279 m_powerRestricted = powerRestricted;
2280 m_txPowerMaxSiso = txPowerMaxSiso;
2281 m_txPowerMaxMimo = txPowerMaxMimo;
2282 NS_ASSERT((m_currentEvent->GetEndTime() - Simulator::Now()).IsPositive());
2283 Simulator::Schedule(m_currentEvent->GetEndTime() - Simulator::Now(),
2284 &WifiPhy::EndReceiveInterBss,
2285 this);
2286 Simulator::ScheduleNow(&WifiPhy::AbortCurrentReception,
2287 this,
2288 OBSS_PD_CCA_RESET); // finish processing field first
2289 }
2290}
2291
2292dBm_u
2293WifiPhy::GetTxPowerForTransmission(Ptr<const WifiPpdu> ppdu) const
2294{
2295 NS_LOG_FUNCTION(this << m_powerRestricted << ppdu);
2296 const auto& txVector = ppdu->GetTxVector();
2297 // Get transmit power before antenna gain
2298 dBm_u txPower;
2299 if (!m_powerRestricted)
2300 {
2301 txPower = GetPower(txVector.GetTxPowerLevel());
2302 }
2303 else
2304 {
2305 if (txVector.GetNssMax() > 1 || txVector.GetNssTotal() > 1)
2306 {
2307 txPower = std::min(m_txPowerMaxMimo, GetPower(txVector.GetTxPowerLevel()));
2308 }
2309 else
2310 {
2311 txPower = std::min(m_txPowerMaxSiso, GetPower(txVector.GetTxPowerLevel()));
2312 }
2313 }
2314
2315 // Apply power density constraint on EIRP
2316 const auto channelWidth = ppdu->GetTxChannelWidth();
2317 dBm_per_MHz_u txPowerDbmPerMhz =
2318 (txPower + GetTxGain()) - RatioToDb(channelWidth); // account for antenna gain since EIRP
2319 NS_LOG_INFO("txPower=" << txPower << "dBm with txPowerDbmPerMhz=" << txPowerDbmPerMhz
2320 << " over " << channelWidth << " MHz");
2321 txPower = std::min(txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb(channelWidth);
2322 txPower -= GetTxGain(); // remove antenna gain since will be added right afterwards
2323 NS_LOG_INFO("txPower=" << txPower
2324 << "dBm after applying m_powerDensityLimit=" << m_powerDensityLimit);
2325 return txPower;
2326}
2327
2329WifiPhy::GetAddressedPsduInPpdu(Ptr<const WifiPpdu> ppdu) const
2330{
2331 // TODO: wrapper. See if still needed
2332 return GetPhyEntityForPpdu(ppdu)->GetAddressedPsduInPpdu(ppdu);
2333}
2334
2335int64_t
2336WifiPhy::AssignStreams(int64_t stream)
2337{
2338 NS_LOG_FUNCTION(this << stream);
2339 int64_t currentStream = stream;
2340 m_random->SetStream(currentStream++);
2341 currentStream += m_interference->GetErrorRateModel()->AssignStreams(currentStream);
2342 return (currentStream - stream);
2343}
2344
2345std::ostream&
2346operator<<(std::ostream& os, RxSignalInfo rxSignalInfo)
2347{
2348 os << "SNR:" << RatioToDb(rxSignalInfo.snr) << " dB"
2349 << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2350 return os;
2351}
2352
2353uint8_t
2354WifiPhy::GetPrimaryChannelNumber(MHz_u primaryChannelWidth) const
2355{
2356 return m_operatingChannel.GetPrimaryChannelNumber(primaryChannelWidth, m_standard);
2357}
2358
2359Hz_u
2360WifiPhy::GetSubcarrierSpacing() const
2361{
2362 Hz_u subcarrierSpacing = 0;
2363 switch (GetStandard())
2364 {
2370 subcarrierSpacing = 312500;
2371 break;
2373 if (GetChannelWidth() == 5)
2374 {
2375 subcarrierSpacing = 78125;
2376 }
2377 else
2378 {
2379 subcarrierSpacing = 156250;
2380 }
2381 break;
2384 subcarrierSpacing = 78125;
2385 break;
2386 default:
2387 NS_FATAL_ERROR("Standard unknown: " << GetStandard());
2388 break;
2389 }
2390 return subcarrierSpacing;
2391}
2392
2393} // 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:560
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:1395
AttributeValue implementation for Tuple.
Definition tuple.h:67
a unique identifier for an interface.
Definition type-id.h:48
@ ATTR_GET
The attribute can be read.
Definition type-id.h:53
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:1325
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:1624
dBm_u m_ccaEdThreshold
Clear channel assessment (CCA) energy detection (ED) threshold.
Definition wifi-phy.h:1597
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:1616
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition wifi-phy.h:1324
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition wifi-phy.h:1628
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:1621
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:1606
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition wifi-phy.h:1587
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:1478
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:1611
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:1596
uint8_t GetNumberOfAntennas() const
Definition wifi-phy.cc:1346
Time m_slot
Slot duration.
Definition wifi-phy.h:1591
dBm_u GetRxSensitivity() const
Return the receive sensitivity threshold.
Definition wifi-phy.cc:520
Time GetDelayUntilIdle()
Definition wifi-phy.cc:2188
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:1598
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:1631
std::tuple< uint8_t, MHz_u, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying a segment of an operating channel.
Definition wifi-phy.h:919
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:1594
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:1604
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition wifi-phy.cc:2220
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition wifi-phy.h:1626
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition wifi-phy.h:1521
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:1590
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition wifi-phy.cc:484
TracedCallback< Ptr< const WifiPpdu >, const WifiTxVector & > m_signalTransmissionCb
Signal Transmission callback.
Definition wifi-phy.h:1363
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
MHz_u GetTxBandwidth(WifiMode mode, MHz_u maxAllowedBandWidth=std::numeric_limits< MHz_u >::max()) const
Get the bandwidth for a transmission occurring on the current operating channel and using the given W...
Definition wifi-phy.cc:1123
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:1615
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:1533
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:1603
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:1585
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:1572
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition wifi-phy.h:1360
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:1553
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition wifi-phy.h:1629
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:1470
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:1455
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:1627
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:1462
std::vector< ChannelTuple > ChannelSegments
segments identifying an operating channel
Definition wifi-phy.h:925
dB_u m_txGain
Transmission gain.
Definition wifi-phy.h:1601
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:1583
uint8_t m_nTxPower
Number of available transmission power levels.
Definition wifi-phy.h:1605
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:1528
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:1319
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:1619
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:2206
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:1602
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:1486
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition wifi-phy.h:1623
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition wifi-phy.h:1322
void DoInitialize() override
Initialize() implementation.
Definition wifi-phy.cc:411
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition wifi-phy.h:1614
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:1592
WifiModulationClass m_maxModClassSupported
max modulation class supported
Definition wifi-phy.h:1584
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:1608
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition wifi-phy.h:1633
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:1945
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition wifi-phy.h:1502
TracedCallback< const WifiMacHeader &, const WifiTxVector &, Time > m_phyRxMacHeaderEndTrace
The trace source fired when the reception of a MAC header ends.
Definition wifi-phy.h:1513
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:1586
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:1588
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:1593
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:1396
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1416
Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition tuple.h:529
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:1332
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
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
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
@ 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:44
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:25
Watt_u DbmToW(dBm_u val)
Convert from dBm to Watts.
Definition wifi-utils.cc:31
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.
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.