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