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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 * Sébastien Deronne <sebastien.deronne@gmail.com>
19 */
20
21#include "wifi-phy.h"
22
23#include "error-rate-model.h"
24#include "frame-capture-model.h"
25#include "interference-helper.h"
27#include "wifi-net-device.h"
28#include "wifi-ppdu.h"
29#include "wifi-psdu.h"
31#include "wifi-utils.h"
32
33#include "ns3/channel.h"
34#include "ns3/dsss-phy.h"
35#include "ns3/eht-phy.h" //also includes OFDM, HT, VHT and HE
36#include "ns3/erp-ofdm-phy.h"
37#include "ns3/error-model.h"
38#include "ns3/ht-configuration.h"
39#include "ns3/log.h"
40#include "ns3/mobility-model.h"
41#include "ns3/pointer.h"
42#include "ns3/random-variable-stream.h"
43#include "ns3/simulator.h"
44#include "ns3/string.h"
45#include "ns3/tuple.h"
46#include "ns3/vht-configuration.h"
47
48#include <algorithm>
49
50#undef NS_LOG_APPEND_CONTEXT
51#define NS_LOG_APPEND_CONTEXT \
52 WIFI_PHY_NS_LOG_APPEND_CONTEXT( \
53 (m_device && m_device->GetPhy(m_phyId) ? m_device->GetPhy(m_phyId) : nullptr))
54
55namespace ns3
56{
57
59
60/****************************************************************
61 * The actual WifiPhy class
62 ****************************************************************/
63
65
66TypeId
68{
69 static TypeId tid =
70 TypeId("ns3::WifiPhy")
72 .SetGroupName("Wifi")
73 .AddAttribute("Channel",
74 "The channel attached to this PHY",
78 MakePointerChecker<Channel>())
79 .AddAttribute(
80 "ChannelSettings",
81 "Tuple {channel number, channel width (MHz), PHY band, primary20 index} "
82 "describing the settings of the operating channel. The primary20 index is "
83 "the index of the primary 20 MHz channel within the operating channel "
84 "(0 indicates the 20 MHz subchannel with the lowest center frequency) and "
85 "is only valid if the width of the operating channel is a multiple of 20 MHz. "
86 "If the standard for this object has not been set yet, the value of this "
87 "attribute is saved and will be used to set the operating channel when the "
88 "standard is configured. If the PHY band is left unspecified, the default "
89 "band for the configured standard is used. If the channel width and the "
90 "channel number are both 0, the default channel width for the configured "
91 "standard and band are used. If the channel number is 0, the default "
92 "channel number for the configured standard, band and channel width is used."
93 "Note that the channel width can be left unspecified (0) if the channel "
94 "number uniquely identify a frequency channel for the given standard and band.",
95 StringValue("{0, 0, BAND_UNSPECIFIED, 0}"),
99 UintegerValue>((void(WifiPhy::*)(const ChannelTuple&)) &
105 MakeUintegerChecker<uint8_t>(0, 233),
106 MakeUintegerChecker<uint16_t>(0, 160),
108 "BAND_2_4GHZ",
110 "BAND_5GHZ",
112 "BAND_6GHZ",
114 "BAND_UNSPECIFIED"),
115 MakeUintegerChecker<uint8_t>(0, 7)))
116 .AddAttribute("Frequency",
117 "The center frequency (MHz) of the current operating channel.",
119 UintegerValue(0),
121 MakeUintegerChecker<uint16_t>())
122 .AddAttribute("ChannelNumber",
123 "The channel number of the current operating channel.",
125 UintegerValue(0),
127 MakeUintegerChecker<uint8_t>(0, 233))
128 .AddAttribute(
129 "ChannelWidth",
130 "The width in MHz of the current operating channel (5, 10, 20, 22, 40, 80 or 160).",
132 UintegerValue(0),
134 MakeUintegerChecker<uint16_t>(5, 160))
135 .AddAttribute(
136 "Primary20MHzIndex",
137 "The index of the primary 20 MHz channel within the current operating channel "
138 "(0 indicates the 20 MHz subchannel with the lowest center frequency).",
139 UintegerValue(0),
141 MakeUintegerChecker<uint8_t>(0, 7))
142 .AddAttribute("FixedPhyBand",
143 "If set to true, changing PHY band is prohibited after initialization.",
144 BooleanValue(false),
147 .AddAttribute(
148 "RxSensitivity",
149 "The energy of a received signal should be higher than "
150 "this threshold (dBm) for the PHY to detect the signal. "
151 "This threshold refers to a width of 20 MHz and will be "
152 "scaled to match the width of the received signal.",
153 DoubleValue(-101.0),
155 MakeDoubleChecker<double>())
156 .AddAttribute(
157 "CcaEdThreshold",
158 "The energy of all received signals should be higher than "
159 "this threshold (dBm) in the primary channel to allow the PHY layer "
160 "to declare CCA BUSY state.",
161 DoubleValue(-62.0),
163 MakeDoubleChecker<double>())
164 .AddAttribute("CcaSensitivity",
165 "The energy of a received wifi signal should be higher than "
166 "this threshold (dBm) in the primary channel to allow the PHY layer "
167 "to declare CCA BUSY state.",
168 DoubleValue(-82.0),
171 MakeDoubleChecker<double>())
172 .AddAttribute("TxGain",
173 "Transmission gain (dB).",
174 DoubleValue(0.0),
176 MakeDoubleChecker<double>())
177 .AddAttribute("RxGain",
178 "Reception gain (dB).",
179 DoubleValue(0.0),
181 MakeDoubleChecker<double>())
182 .AddAttribute("TxPowerLevels",
183 "Number of transmission power levels available between "
184 "TxPowerStart and TxPowerEnd included.",
185 UintegerValue(1),
187 MakeUintegerChecker<uint8_t>())
188 .AddAttribute("TxPowerEnd",
189 "Maximum available transmission level (dBm).",
190 DoubleValue(16.0206),
192 MakeDoubleChecker<double>())
193 .AddAttribute("TxPowerStart",
194 "Minimum available transmission level (dBm).",
195 DoubleValue(16.0206),
197 MakeDoubleChecker<double>())
198 .AddAttribute(
199 "RxNoiseFigure",
200 "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
201 " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
202 "\"the difference in decibels (dB) between"
203 " the noise output of the actual receiver to the noise output of an "
204 " ideal receiver with the same overall gain and bandwidth when the receivers "
205 " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
206 DoubleValue(7),
208 MakeDoubleChecker<double>())
209 .AddAttribute("State",
210 "The state of the PHY layer.",
211 PointerValue(),
213 MakePointerChecker<WifiPhyStateHelper>())
214 .AddAttribute("ChannelSwitchDelay",
215 "Delay between two short frames transmitted on different frequencies.",
219 .AddAttribute(
220 "Antennas",
221 "The number of antennas on the device.",
222 UintegerValue(1),
224 MakeUintegerChecker<uint8_t>(1, 8))
225 .AddAttribute("MaxSupportedTxSpatialStreams",
226 "The maximum number of supported TX spatial streams."
227 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
228 UintegerValue(1),
231 MakeUintegerChecker<uint8_t>(1, 8))
232 .AddAttribute("MaxSupportedRxSpatialStreams",
233 "The maximum number of supported RX spatial streams."
234 "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
235 UintegerValue(1),
238 MakeUintegerChecker<uint8_t>(1, 8))
239 .AddAttribute("ShortPlcpPreambleSupported",
240 "Whether or not short PHY preamble is supported."
241 "This parameter is only valuable for 802.11b STAs and APs."
242 "Note: 802.11g APs and STAs always support short PHY preamble.",
243 BooleanValue(false),
247 .AddAttribute("FrameCaptureModel",
248 "Ptr to an object that implements the frame capture model",
249 PointerValue(),
251 MakePointerChecker<FrameCaptureModel>())
252 .AddAttribute("PreambleDetectionModel",
253 "Ptr to an object that implements the preamble detection model",
254 PointerValue(),
256 MakePointerChecker<PreambleDetectionModel>())
257 .AddAttribute("PostReceptionErrorModel",
258 "An optional packet error model can be added to the receive "
259 "packet process after any propagation-based (SNR-based) error "
260 "models have been applied. Typically this is used to force "
261 "specific packet drops, for testing purposes.",
262 PointerValue(),
264 MakePointerChecker<ErrorModel>())
265 .AddAttribute("InterferenceHelper",
266 "Ptr to an object that implements the interference helper",
267 PointerValue(),
269 MakePointerChecker<InterferenceHelper>())
270 .AddAttribute("Sifs",
271 "The duration of the Short Interframe Space. "
272 "NOTE that the default value is overwritten by the value defined "
273 "by the standard; if you want to set this attribute, you have to "
274 "do it after that the PHY object is initialized.",
278 .AddAttribute("Slot",
279 "The duration of a slot. "
280 "NOTE that the default value is overwritten by the value defined "
281 "by the standard; if you want to set this attribute, you have to "
282 "do it after that the PHY object is initialized.",
286 .AddAttribute("Pifs",
287 "The duration of the PCF Interframe Space. "
288 "NOTE that the default value is overwritten by the value defined "
289 "by the standard; if you want to set this attribute, you have to "
290 "do it after that the PHY object is initialized.",
294 .AddAttribute("PowerDensityLimit",
295 "The mean equivalent isotropically radiated power density"
296 "limit (in dBm/MHz) set by regulators.",
297 DoubleValue(100.0), // set to a high value so as to have no effect
299 MakeDoubleChecker<double>())
300 .AddTraceSource("PhyTxBegin",
301 "Trace source indicating a packet "
302 "has begun transmitting over the channel medium",
304 "ns3::WifiPhy::PhyTxBeginTracedCallback")
305 .AddTraceSource("PhyTxPsduBegin",
306 "Trace source indicating a PSDU "
307 "has begun transmitting over the channel medium",
309 "ns3::WifiPhy::PsduTxBeginCallback")
310 .AddTraceSource("PhyTxEnd",
311 "Trace source indicating a packet "
312 "has been completely transmitted over the channel.",
314 "ns3::Packet::TracedCallback")
315 .AddTraceSource("PhyTxDrop",
316 "Trace source indicating a packet "
317 "has been dropped by the device during transmission",
319 "ns3::Packet::TracedCallback")
320 .AddTraceSource("PhyRxBegin",
321 "Trace source indicating a packet "
322 "has begun being received from the channel medium "
323 "by the device",
325 "ns3::WifiPhy::PhyRxBeginTracedCallback")
326 .AddTraceSource("PhyRxPayloadBegin",
327 "Trace source indicating the reception of the "
328 "payload of a PPDU has begun",
330 "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
331 .AddTraceSource("PhyRxEnd",
332 "Trace source indicating a packet "
333 "has been completely received from the channel medium "
334 "by the device",
336 "ns3::Packet::TracedCallback")
337 .AddTraceSource("PhyRxDrop",
338 "Trace source indicating a packet "
339 "has been dropped by the device during reception",
341 "ns3::Packet::TracedCallback")
342 .AddTraceSource("MonitorSnifferRx",
343 "Trace source simulating a wifi device in monitor mode "
344 "sniffing all received frames",
346 "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
347 .AddTraceSource("MonitorSnifferTx",
348 "Trace source simulating the capability of a wifi device "
349 "in monitor mode to sniff all frames being transmitted",
351 "ns3::WifiPhy::MonitorSnifferTxTracedCallback");
352 return tid;
353}
354
356 : m_phyId(0),
357 m_txMpduReferenceNumber(0xffffffff),
358 m_rxMpduReferenceNumber(0xffffffff),
359 m_endPhyRxEvent(),
360 m_endTxEvent(),
361 m_currentEvent(nullptr),
362 m_previouslyRxPpduUid(UINT64_MAX),
363 m_standard(WIFI_STANDARD_UNSPECIFIED),
364 m_maxModClassSupported(WIFI_MOD_CLASS_UNKNOWN),
366 m_sifs(Seconds(0)),
367 m_slot(Seconds(0)),
368 m_pifs(Seconds(0)),
369 m_ackTxTime(Seconds(0)),
370 m_blockAckTxTime(Seconds(0)),
371 m_powerRestricted(false),
372 m_channelAccessRequested(false),
373 m_txSpatialStreams(1),
374 m_rxSpatialStreams(1),
375 m_wifiRadioEnergyModel(nullptr),
376 m_timeLastPreambleDetected(Seconds(0))
377{
378 NS_LOG_FUNCTION(this);
379 m_random = CreateObject<UniformRandomVariable>();
380 m_state = CreateObject<WifiPhyStateHelper>();
381}
382
384{
385 NS_LOG_FUNCTION(this);
386}
387
388void
390{
391 NS_LOG_FUNCTION(this);
392
393 // This method ensures that the local mobility model pointer holds
394 // a pointer to the Node's aggregated mobility model (if one exists)
395 // in the case that the user has not directly called SetMobility()
396 // on this WifiPhy during simulation setup. If the mobility model
397 // needs to be added or changed during simulation runtime, users must
398 // call SetMobility() on this object.
399
400 if (!m_mobility)
401 {
403 "Either install a MobilityModel on this object or ensure that this "
404 "object is part of a Node and NetDevice");
406 if (!m_mobility)
407 {
408 NS_LOG_WARN("Mobility not found, propagation models might not work properly");
409 }
410 }
411}
412
413void
415{
416 NS_LOG_FUNCTION(this);
417
418 m_device = nullptr;
419 m_mobility = nullptr;
420 m_frameCaptureModel = nullptr;
421 m_preambleDetectionModel = nullptr;
422 m_wifiRadioEnergyModel = nullptr;
424 if (m_interference)
425 {
426 m_interference->Dispose();
427 }
428 m_interference = nullptr;
429 m_random = nullptr;
430 m_state = nullptr;
431
432 Reset();
433
434 // this should be done after calling the Reset function
435 for (auto& phyEntity : m_phyEntities)
436 {
437 phyEntity.second = nullptr;
438 }
439 m_phyEntities.clear();
440}
441
442std::map<WifiModulationClass, Ptr<PhyEntity>>&
444{
445 static std::map<WifiModulationClass, Ptr<PhyEntity>> g_staticPhyEntities;
446 return g_staticPhyEntities;
447}
448
451{
452 return m_state;
453}
454
455void
457{
458 m_state->SetReceiveOkCallback(callback);
459}
460
461void
463{
464 m_state->SetReceiveErrorCallback(callback);
465}
466
467void
468WifiPhy::RegisterListener(const std::shared_ptr<WifiPhyListener>& listener)
469{
470 m_state->RegisterListener(listener);
471}
472
473void
474WifiPhy::UnregisterListener(const std::shared_ptr<WifiPhyListener>& listener)
475{
476 m_state->UnregisterListener(listener);
477}
478
479void
481{
483}
484
485void
487{
488 NS_LOG_FUNCTION(this << threshold);
489 m_rxSensitivityDbm = threshold;
490}
491
492double
494{
495 return m_rxSensitivityDbm;
496}
497
498void
500{
501 NS_LOG_FUNCTION(this << threshold);
502 m_ccaEdThresholdW = DbmToW(threshold);
503}
504
505double
507{
509}
510
511void
513{
514 NS_LOG_FUNCTION(this << threshold);
516}
517
518double
520{
522}
523
524void
525WifiPhy::SetRxNoiseFigure(double noiseFigureDb)
526{
527 NS_LOG_FUNCTION(this << noiseFigureDb);
528 if (m_interference)
529 {
530 m_interference->SetNoiseFigure(DbToRatio(noiseFigureDb));
531 }
532 m_noiseFigureDb = noiseFigureDb;
533}
534
535void
537{
538 NS_LOG_FUNCTION(this << start);
539 m_txPowerBaseDbm = start;
540}
541
542double
544{
545 return m_txPowerBaseDbm;
546}
547
548void
550{
551 NS_LOG_FUNCTION(this << end);
552 m_txPowerEndDbm = end;
553}
554
555double
557{
558 return m_txPowerEndDbm;
559}
560
561void
563{
564 NS_LOG_FUNCTION(this << +n);
565 m_nTxPower = n;
566}
567
568uint8_t
570{
571 return m_nTxPower;
572}
573
574void
576{
577 NS_LOG_FUNCTION(this << gain);
578 m_txGainDb = gain;
579}
580
581double
583{
584 return m_txGainDb;
585}
586
587void
589{
590 NS_LOG_FUNCTION(this << gain);
591 m_rxGainDb = gain;
592}
593
594double
596{
597 return m_rxGainDb;
598}
599
600void
602{
603 NS_LOG_FUNCTION(this << enable);
604 m_shortPreamble = enable;
605}
606
607bool
609{
610 return m_shortPreamble;
611}
612
613void
615{
616 m_device = device;
617}
618
621{
622 return m_device;
623}
624
625void
627{
628 m_mobility = mobility;
629}
630
633{
634 return m_mobility;
635}
636
637void
638WifiPhy::SetPhyId(uint8_t phyId)
639{
640 NS_LOG_FUNCTION(this << phyId);
641 m_phyId = phyId;
642}
643
644uint8_t
646{
647 return m_phyId;
648}
649
650void
652{
653 NS_LOG_FUNCTION(this << helper);
654 m_interference = helper;
655 m_interference->SetNoiseFigure(DbToRatio(m_noiseFigureDb));
656 m_interference->SetNumberOfReceiveAntennas(m_numberOfAntennas);
657}
658
659void
661{
662 NS_LOG_FUNCTION(this << model);
664 m_interference->SetErrorRateModel(model);
665}
666
667void
669{
670 NS_LOG_FUNCTION(this << em);
672}
673
674void
676{
677 m_frameCaptureModel = model;
678}
679
680void
682{
684}
685
686void
688{
689 m_wifiRadioEnergyModel = wifiRadioEnergyModel;
690}
691
692double
693WifiPhy::GetPowerDbm(uint8_t power) const
694{
697 double dbm;
698 if (m_nTxPower > 1)
699 {
701 }
702 else
703 {
705 "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
706 dbm = m_txPowerBaseDbm;
707 }
708 return dbm;
709}
710
711Time
713{
715}
716
717double
718WifiPhy::CalculateSnr(const WifiTxVector& txVector, double ber) const
719{
720 return m_interference->GetErrorRateModel()->CalculateSnr(txVector, ber);
721}
722
725{
726 const auto it = GetStaticPhyEntities().find(modulation);
728 "Unimplemented Wi-Fi modulation class " << modulation);
729 return it->second;
730}
731
734{
735 const auto it = m_phyEntities.find(modulation);
736 NS_ABORT_MSG_IF(it == m_phyEntities.cend(),
737 "Unsupported Wi-Fi modulation class " << modulation);
738 return it->second;
739}
740
743{
745}
746
749{
750 return GetPhyEntity(m_standard);
751}
752
755{
756 NS_ABORT_IF(!ppdu);
757 const auto modulation = ppdu->GetModulation();
758 if (modulation > m_phyEntities.rbegin()->first)
759 {
760 // unsupported modulation: start reception process with latest PHY entity
761 return GetLatestPhyEntity();
762 }
763 if (modulation < WIFI_MOD_CLASS_HT)
764 {
765 // for non-HT (duplicate), call the latest PHY entity since some extra processing can be
766 // done in PHYs implemented in HT and later (e.g. channel width selection for non-HT
767 // duplicates)
768 return GetLatestPhyEntity();
769 }
770 return GetPhyEntity(modulation);
771}
772
773void
775{
776 NS_ASSERT_MSG(!GetStaticPhyEntities().contains(modulation),
777 "The PHY entity has already been added. The setting should only be done once per "
778 "modulation class");
779 GetStaticPhyEntities()[modulation] = phyEntity;
780}
781
782void
784{
785 NS_LOG_FUNCTION(this << modulation);
786 NS_ABORT_MSG_IF(!GetStaticPhyEntities().contains(modulation),
787 "Cannot add an unimplemented PHY to supported list. Update the former first.");
788 NS_ASSERT_MSG(m_phyEntities.find(modulation) == m_phyEntities.end(),
789 "The PHY entity has already been added. The setting should only be done once per "
790 "modulation class");
791 phyEntity->SetOwner(this);
792 m_phyEntities[modulation] = phyEntity;
793}
794
795void
797{
798 m_sifs = sifs;
799}
800
801Time
803{
804 return m_sifs;
805}
806
807void
809{
810 m_slot = slot;
811}
812
813Time
815{
816 return m_slot;
817}
818
819void
821{
822 m_pifs = pifs;
823}
824
825Time
827{
828 return m_pifs;
829}
830
831Time
833{
834 return m_ackTxTime;
835}
836
837Time
839{
840 return m_blockAckTxTime;
841}
842
843void
845{
846 NS_LOG_FUNCTION(this);
847 AddPhyEntity(WIFI_MOD_CLASS_OFDM, Create<OfdmPhy>());
848
849 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
852 SetPifs(GetSifs() + GetSlot());
853 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
854 // of the PPDU causing the EIFS" of 802.11-2016
856}
857
858void
860{
861 NS_LOG_FUNCTION(this);
862 Ptr<DsssPhy> phyEntity = Create<DsssPhy>();
864 AddPhyEntity(WIFI_MOD_CLASS_DSSS, phyEntity); // when plain DSSS modes are used
865
866 // See Table 16-4 "HR/DSSS PHY characteristics" of 802.11-2016
869 SetPifs(GetSifs() + GetSlot());
870 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
871 // of the PPDU causing the EIFS" of 802.11-2016
873}
874
875void
877{
878 NS_LOG_FUNCTION(this);
879 // See Table 18-5 "ERP characteristics" of 802.11-2016
880 // Slot time defaults to the "long slot time" of 20 us in the standard
881 // according to mixed 802.11b/g deployments. Short slot time is enabled
882 // if the user sets the ShortSlotTimeSupported flag to true and when the BSS
883 // consists of only ERP STAs capable of supporting this option.
885 AddPhyEntity(WIFI_MOD_CLASS_ERP_OFDM, Create<ErpOfdmPhy>());
886}
887
888void
890{
891 NS_LOG_FUNCTION(this);
892 if (GetChannelWidth() == 10)
893 {
895
896 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
899 SetPifs(GetSifs() + GetSlot());
901 }
902 else if (GetChannelWidth() == 5)
903 {
905
906 // See Table 17-21 "OFDM PHY characteristics" of 802.11-2016
909 SetPifs(GetSifs() + GetSlot());
911 }
912 else
913 {
914 NS_FATAL_ERROR("802.11p configured with a wrong channel width!");
915 }
916}
917
918void
920{
921 NS_LOG_FUNCTION(this);
923 {
925 }
926 else
927 {
929 }
931
932 // See Table 10-5 "Determination of the EstimatedAckTxTime based on properties
933 // of the PPDU causing the EIFS" of 802.11-2016
935}
936
937void
939{
940 NS_LOG_FUNCTION(this);
942 AddPhyEntity(WIFI_MOD_CLASS_VHT, Create<VhtPhy>());
943}
944
945void
947{
948 NS_LOG_FUNCTION(this);
950 {
952 }
953 else
954 {
956 }
957 AddPhyEntity(WIFI_MOD_CLASS_HE, Create<HePhy>());
958}
959
960void
962{
963 NS_LOG_FUNCTION(this);
965 AddPhyEntity(WIFI_MOD_CLASS_EHT, Create<EhtPhy>());
966}
967
968void
970{
971 NS_LOG_FUNCTION(this << modClass);
972 m_maxModClassSupported = modClass;
973}
974
977{
979}
980
981void
983{
984 NS_LOG_FUNCTION(this << standard);
985
987 "Cannot change standard");
988
989 m_standard = standard;
990
992 {
994 }
995
997 {
998 NS_LOG_DEBUG("Setting the operating channel first");
1000 // return because we are called back by SetOperatingChannel
1001 return;
1002 }
1003
1004 // this function is called when changing PHY band, hence we have to delete
1005 // the previous PHY entities
1006 m_phyEntities.clear();
1007
1008 switch (standard)
1009 {
1012 break;
1015 break;
1018 break;
1021 break;
1024 break;
1027 break;
1030 break;
1033 break;
1035 default:
1036 NS_ASSERT_MSG(false, "Unsupported standard");
1037 break;
1038 }
1039}
1040
1043{
1044 return m_band;
1045}
1046
1049{
1050 return m_standard;
1051}
1052
1055{
1056 return m_operatingChannel;
1057}
1058
1059uint16_t
1061{
1063}
1064
1065uint8_t
1067{
1069}
1070
1071uint16_t
1073{
1075}
1076
1077uint8_t
1079{
1081}
1082
1083void
1085{
1086 m_fixedPhyBand = enable;
1087}
1088
1089bool
1091{
1092 return m_fixedPhyBand;
1093}
1094
1095uint16_t
1096WifiPhy::GetTxBandwidth(WifiMode mode, uint16_t maxAllowedWidth) const
1097{
1098 auto modulation = mode.GetModulationClass();
1099 if (modulation == WIFI_MOD_CLASS_DSSS || modulation == WIFI_MOD_CLASS_HR_DSSS)
1100 {
1101 return 22;
1102 }
1103
1104 return std::min({GetChannelWidth(), GetMaximumChannelWidth(modulation), maxAllowedWidth});
1105}
1106
1107void
1109{
1110 NS_LOG_FUNCTION(this << channel);
1111 WifiPhy::ChannelTuple tuple(channel.GetNumber(),
1112 channel.GetWidth(),
1113 channel.GetPhyBand(),
1114 channel.GetPrimaryChannelIndex(20));
1115 SetOperatingChannel(tuple);
1116}
1117
1118void
1120{
1121 // the generic operator<< for tuples does not give a pretty result
1122 NS_LOG_FUNCTION(this << +std::get<0>(channelTuple) << std::get<1>(channelTuple)
1123 << static_cast<WifiPhyBand>(std::get<2>(channelTuple))
1124 << +std::get<3>(channelTuple));
1125
1126 m_channelSettings = channelTuple;
1127
1129 {
1130 NS_LOG_DEBUG("Channel information will be applied when a standard is configured");
1131 return;
1132 }
1133
1134 if (IsInitialized())
1135 {
1136 const auto delay = GetDelayUntilChannelSwitch();
1137 if (!delay.has_value())
1138 {
1139 // switching channel is not possible now
1140 return;
1141 }
1142 if (delay.value().IsStrictlyPositive())
1143 {
1144 // switching channel has been postponed
1145 void (WifiPhy::*fp)(const ChannelTuple&) = &WifiPhy::SetOperatingChannel;
1146 Simulator::Schedule(delay.value(), fp, this, channelTuple);
1147 return;
1148 }
1149 }
1150
1151 // channel can be switched now.
1153}
1154
1155std::optional<Time>
1157{
1158 if (!IsInitialized())
1159 {
1160 // this is not channel switch, this is initialization
1161 NS_LOG_DEBUG("Before initialization, nothing to do");
1162 return Seconds(0);
1163 }
1164
1166 std::optional<Time> delay;
1167 switch (m_state->GetState())
1168 {
1169 case WifiPhyState::RX:
1170 NS_LOG_DEBUG("drop packet because of channel switching while reception");
1172 delay = Seconds(0);
1173 break;
1174 case WifiPhyState::TX:
1175 NS_LOG_DEBUG("channel switching postponed until end of current transmission");
1176 delay = GetDelayUntilIdle();
1177 break;
1179 case WifiPhyState::IDLE:
1180 Reset();
1181 delay = Seconds(0);
1182 break;
1184 NS_LOG_DEBUG("channel switching ignored in sleep mode");
1185 break;
1186 default:
1187 NS_ASSERT(false);
1188 break;
1189 }
1190
1191 return delay;
1192}
1193
1194void
1196{
1197 NS_LOG_FUNCTION(this);
1198
1199 m_powerRestricted = false;
1201
1202 // Update unspecified parameters with default values
1203 {
1204 auto& [number, width, band, primary20] = m_channelSettings;
1205 if (band == WIFI_PHY_BAND_UNSPECIFIED)
1206 {
1208 }
1209 if (width == 0 && number == 0)
1210 {
1211 width = GetDefaultChannelWidth(m_standard, static_cast<WifiPhyBand>(band));
1212 }
1213 if (number == 0)
1214 {
1215 number =
1217 m_standard,
1218 static_cast<WifiPhyBand>(band));
1219 }
1220 }
1221
1222 // We need to call SetStandard if this is the first time we set a channel or we
1223 // are changing PHY band. Checking if the new PHY band is different than the
1224 // previous one covers both cases because initially the PHY band is unspecified
1225 bool changingPhyBand = (static_cast<WifiPhyBand>(std::get<2>(m_channelSettings)) != m_band);
1226
1227 NS_ABORT_MSG_IF(IsInitialized() && m_fixedPhyBand && changingPhyBand,
1228 "Trying to change PHY band while prohibited.");
1229
1230 m_band = static_cast<WifiPhyBand>(std::get<2>(m_channelSettings));
1231
1232 // check that the channel width is supported
1233 uint16_t chWidth = std::get<1>(m_channelSettings);
1234
1235 if (m_device)
1236 {
1237 if (auto htConfig = m_device->GetHtConfiguration();
1238 htConfig && !htConfig->Get40MHzOperationSupported() && chWidth > 20)
1239 {
1240 NS_ABORT_MSG("Attempting to set a " << chWidth
1241 << " MHz channel on"
1242 "a station only supporting 20 MHz operation");
1243 }
1244
1245 if (auto vhtConfig = m_device->GetVhtConfiguration();
1246 vhtConfig && !vhtConfig->Get160MHzOperationSupported() && chWidth > 80)
1247 {
1248 NS_ABORT_MSG("Attempting to set a " << chWidth
1249 << " MHz channel on"
1250 "a station supporting up to 80 MHz operation");
1251 }
1252 }
1253
1254 NS_LOG_DEBUG("switching channel");
1255 m_operatingChannel.Set(std::get<0>(m_channelSettings), 0, chWidth, m_standard, m_band);
1257
1258 if (changingPhyBand)
1259 {
1261 }
1262
1263 if (IsInitialized())
1264 {
1265 // notify channel switching
1266 m_state->SwitchToChannelSwitching(GetChannelSwitchDelay());
1267 /*
1268 * Needed here to be able to correctly sensed the medium for the first
1269 * time after the switching. The actual switching is not performed until
1270 * after m_channelSwitchDelay. Packets received during the switching
1271 * state are added to the event list and are employed later to figure
1272 * out the state of the medium after the switching.
1273 */
1274 }
1275}
1276
1277void
1279{
1280 NS_LOG_FUNCTION(this << +antennas);
1281 NS_ASSERT_MSG(antennas > 0 && antennas <= 8, "unsupported number of antennas");
1282 m_numberOfAntennas = antennas;
1283 if (m_interference)
1284 {
1285 m_interference->SetNumberOfReceiveAntennas(antennas);
1286 }
1287}
1288
1289uint8_t
1291{
1292 return m_numberOfAntennas;
1293}
1294
1295void
1297{
1298 NS_ASSERT(streams <= GetNumberOfAntennas());
1299 bool changed = (m_txSpatialStreams != streams);
1300 m_txSpatialStreams = streams;
1301 if (changed)
1302 {
1303 auto phyEntity = m_phyEntities.find(WIFI_MOD_CLASS_HT);
1304 if (phyEntity != m_phyEntities.end())
1305 {
1306 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity->second);
1307 if (htPhy)
1308 {
1309 htPhy->SetMaxSupportedNss(
1310 m_txSpatialStreams); // this is essential to have the right MCSs configured
1311 }
1312
1314 {
1316 }
1317 }
1318 }
1319}
1320
1321uint8_t
1323{
1324 return m_txSpatialStreams;
1325}
1326
1327void
1329{
1330 NS_ASSERT(streams <= GetNumberOfAntennas());
1331 bool changed = (m_rxSpatialStreams != streams);
1332 m_rxSpatialStreams = streams;
1333 if (changed && !m_capabilitiesChangedCallback.IsNull())
1334 {
1336 }
1337}
1338
1339uint8_t
1341{
1342 return m_rxSpatialStreams;
1343}
1344
1345std::list<uint8_t>
1347{
1348 std::list<uint8_t> list;
1349 for (const auto& phyEntity : m_phyEntities)
1350 {
1351 Ptr<HtPhy> htPhy = DynamicCast<HtPhy>(phyEntity.second);
1352 if (htPhy)
1353 {
1354 list.emplace_back(htPhy->GetBssMembershipSelector());
1355 }
1356 }
1357 return list;
1358}
1359
1360void
1362{
1363 NS_LOG_FUNCTION(this);
1364 m_powerRestricted = false;
1366 switch (m_state->GetState())
1367 {
1368 case WifiPhyState::TX:
1369 NS_LOG_DEBUG("setting sleep mode postponed until end of current transmission");
1371 break;
1372 case WifiPhyState::RX:
1373 NS_LOG_DEBUG("setting sleep mode postponed until end of current reception");
1375 break;
1377 NS_LOG_DEBUG("setting sleep mode postponed until end of channel switching");
1379 break;
1381 case WifiPhyState::IDLE:
1382 NS_LOG_DEBUG("setting sleep mode");
1383 // The PHY object may be in CCA_BUSY state because it is receiving a preamble. Cancel
1384 // preamble events before switching to sleep state
1385 Reset();
1386 // It may happen that we request to switch to sleep at the same time the reception of
1387 // a PPDU ends. In such a case, WifiPhyStateHelper::GetState() does not return RX
1388 // (m_endRx equals now), we get here and set the state to SLEEP. However,
1389 // WifiPhyStateHelper::DoSwitchFromRx() may be called after this function (at the same
1390 // simulation time), thus hitting the assert that checks that the state is IDLE or
1391 // CCA_BUSY.
1393 break;
1395 NS_LOG_DEBUG("already in sleep mode");
1396 break;
1397 default:
1398 NS_ASSERT(false);
1399 break;
1400 }
1401}
1402
1403void
1405{
1406 NS_LOG_FUNCTION(this);
1407 m_powerRestricted = false;
1409 Reset();
1410 m_state->SwitchToOff();
1411}
1412
1413void
1415{
1416 NS_LOG_FUNCTION(this);
1417 switch (m_state->GetState())
1418 {
1419 case WifiPhyState::TX:
1420 case WifiPhyState::RX:
1421 case WifiPhyState::IDLE:
1424 NS_LOG_DEBUG("not in sleep mode, there is nothing to resume");
1425 break;
1426 }
1427 case WifiPhyState::SLEEP: {
1428 NS_LOG_DEBUG("resuming from sleep mode");
1429 m_state->SwitchFromSleep();
1431 break;
1432 }
1433 default: {
1434 NS_ASSERT(false);
1435 break;
1436 }
1437 }
1438}
1439
1440void
1442{
1443 NS_LOG_FUNCTION(this);
1444 switch (m_state->GetState())
1445 {
1446 case WifiPhyState::TX:
1447 case WifiPhyState::RX:
1448 case WifiPhyState::IDLE:
1451 case WifiPhyState::SLEEP: {
1452 NS_LOG_DEBUG("not in off mode, there is nothing to resume");
1453 break;
1454 }
1455 case WifiPhyState::OFF: {
1456 NS_LOG_DEBUG("resuming from off mode");
1457 m_state->SwitchFromOff();
1459 break;
1460 }
1461 default: {
1462 NS_ASSERT(false);
1463 break;
1464 }
1465 }
1466}
1467
1468Time
1470{
1471 return MicroSeconds(4);
1472}
1473
1474Time
1476{
1477 return MicroSeconds(4);
1478}
1479
1480Time
1482 const WifiTxVector& txVector,
1483 WifiPhyBand band,
1484 MpduType mpdutype,
1485 uint16_t staId)
1486{
1487 uint32_t totalAmpduSize;
1488 double totalAmpduNumSymbols;
1489 return GetPayloadDuration(size,
1490 txVector,
1491 band,
1492 mpdutype,
1493 false,
1494 totalAmpduSize,
1495 totalAmpduNumSymbols,
1496 staId);
1497}
1498
1499Time
1501 const WifiTxVector& txVector,
1502 WifiPhyBand band,
1503 MpduType mpdutype,
1504 bool incFlag,
1505 uint32_t& totalAmpduSize,
1506 double& totalAmpduNumSymbols,
1507 uint16_t staId)
1508{
1509 return GetStaticPhyEntity(txVector.GetModulationClass())
1510 ->GetPayloadDuration(size,
1511 txVector,
1512 band,
1513 mpdutype,
1514 incFlag,
1515 totalAmpduSize,
1516 totalAmpduNumSymbols,
1517 staId);
1518}
1519
1520Time
1522{
1523 return GetStaticPhyEntity(txVector.GetModulationClass())
1524 ->CalculatePhyPreambleAndHeaderDuration(txVector);
1525}
1526
1527Time
1529 const WifiTxVector& txVector,
1530 WifiPhyBand band,
1531 uint16_t staId)
1532{
1533 Time duration = CalculatePhyPreambleAndHeaderDuration(txVector) +
1534 GetPayloadDuration(size, txVector, band, NORMAL_MPDU, staId);
1535 NS_ASSERT(duration.IsStrictlyPositive());
1536 return duration;
1537}
1538
1539Time
1541 const WifiTxVector& txVector,
1542 WifiPhyBand band)
1543{
1544 return CalculateTxDuration(GetWifiConstPsduMap(psdu, txVector), txVector, band);
1545}
1546
1547Time
1549 const WifiTxVector& txVector,
1550 WifiPhyBand band)
1551{
1552 return GetStaticPhyEntity(txVector.GetModulationClass())
1553 ->CalculateTxDuration(psduMap, txVector, band);
1554}
1555
1558{
1559 return GetStaticPhyEntity(modulation)->GetMaxPsduSize();
1560}
1561
1562void
1564{
1565 if (!m_phyTxBeginTrace.IsEmpty())
1566 {
1567 for (const auto& psdu : psdus)
1568 {
1569 for (auto& mpdu : *PeekPointer(psdu.second))
1570 {
1571 m_phyTxBeginTrace(mpdu->GetProtocolDataUnit(), txPowerW);
1572 }
1573 }
1574 }
1575}
1576
1577void
1579{
1580 if (!m_phyTxEndTrace.IsEmpty())
1581 {
1582 for (const auto& psdu : psdus)
1583 {
1584 for (auto& mpdu : *PeekPointer(psdu.second))
1585 {
1586 m_phyTxEndTrace(mpdu->GetProtocolDataUnit());
1587 }
1588 }
1589 }
1590}
1591
1592void
1594{
1596 {
1597 for (auto& mpdu : *PeekPointer(psdu))
1598 {
1599 m_phyTxDropTrace(mpdu->GetProtocolDataUnit());
1600 }
1601 }
1602}
1603
1604void
1606{
1607 if (psdu && !m_phyRxBeginTrace.IsEmpty())
1608 {
1609 for (auto& mpdu : *PeekPointer(psdu))
1610 {
1611 m_phyRxBeginTrace(mpdu->GetProtocolDataUnit(), rxPowersW);
1612 }
1613 }
1614}
1615
1616void
1618{
1619 if (psdu && !m_phyRxEndTrace.IsEmpty())
1620 {
1621 for (auto& mpdu : *PeekPointer(psdu))
1622 {
1623 m_phyRxEndTrace(mpdu->GetProtocolDataUnit());
1624 }
1625 }
1626}
1627
1628void
1630{
1631 if (psdu && !m_phyRxDropTrace.IsEmpty())
1632 {
1633 for (auto& mpdu : *PeekPointer(psdu))
1634 {
1635 m_phyRxDropTrace(mpdu->GetProtocolDataUnit(), reason);
1636 }
1637 }
1638}
1639
1640void
1642 uint16_t channelFreqMhz,
1643 WifiTxVector txVector,
1644 SignalNoiseDbm signalNoise,
1645 std::vector<bool> statusPerMpdu,
1646 uint16_t staId)
1647{
1648 MpduInfo aMpdu;
1649 if (psdu->IsAggregate())
1650 {
1651 // Expand A-MPDU
1652 NS_ASSERT_MSG(txVector.IsAggregation(),
1653 "TxVector with aggregate flag expected here according to PSDU");
1655 size_t nMpdus = psdu->GetNMpdus();
1656 NS_ASSERT_MSG(statusPerMpdu.size() == nMpdus, "Should have one reception status per MPDU");
1657 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1658 {
1659 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1660 for (size_t i = 0; i < nMpdus;)
1661 {
1662 if (statusPerMpdu.at(i)) // packet received without error, hand over to sniffer
1663 {
1664 m_phyMonitorSniffRxTrace(psdu->GetAmpduSubframe(i),
1665 channelFreqMhz,
1666 txVector,
1667 aMpdu,
1668 signalNoise,
1669 staId);
1670 }
1671 ++i;
1672 aMpdu.type =
1673 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1674 }
1675 }
1676 }
1677 else
1678 {
1679 NS_ASSERT_MSG(statusPerMpdu.size() == 1,
1680 "Should have one reception status for normal MPDU");
1681 if (!m_phyMonitorSniffRxTrace.IsEmpty())
1682 {
1683 aMpdu.type = NORMAL_MPDU;
1684 m_phyMonitorSniffRxTrace(psdu->GetPacket(),
1685 channelFreqMhz,
1686 txVector,
1687 aMpdu,
1688 signalNoise,
1689 staId);
1690 }
1691 }
1692}
1693
1694void
1696 uint16_t channelFreqMhz,
1697 WifiTxVector txVector,
1698 uint16_t staId)
1699{
1700 MpduInfo aMpdu;
1701 if (psdu->IsAggregate())
1702 {
1703 // Expand A-MPDU
1704 NS_ASSERT_MSG(txVector.IsAggregation(),
1705 "TxVector with aggregate flag expected here according to PSDU");
1707 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1708 {
1709 size_t nMpdus = psdu->GetNMpdus();
1710 aMpdu.type = (psdu->IsSingle()) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
1711 for (size_t i = 0; i < nMpdus;)
1712 {
1713 m_phyMonitorSniffTxTrace(psdu->GetAmpduSubframe(i),
1714 channelFreqMhz,
1715 txVector,
1716 aMpdu,
1717 staId);
1718 ++i;
1719 aMpdu.type =
1720 (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
1721 }
1722 }
1723 }
1724 else
1725 {
1726 if (!m_phyMonitorSniffTxTrace.IsEmpty())
1727 {
1728 aMpdu.type = NORMAL_MPDU;
1729 m_phyMonitorSniffTxTrace(psdu->GetPacket(), channelFreqMhz, txVector, aMpdu, staId);
1730 }
1731 }
1732}
1733
1736{
1737 return GetStaticPhyEntity(txVector.GetModulationClass())->GetWifiConstPsduMap(psdu, txVector);
1738}
1739
1740void
1742{
1743 NS_LOG_FUNCTION(this << *psdu << txVector);
1744 Send(GetWifiConstPsduMap(psdu, txVector), txVector);
1745}
1746
1747void
1749{
1750 NS_LOG_FUNCTION(this << psdus << txVector);
1751 /* Transmission can happen if:
1752 * - we are syncing on a packet. It is the responsibility of the
1753 * MAC layer to avoid doing this but the PHY does nothing to
1754 * prevent it.
1755 * - we are idle
1756 */
1757 NS_ASSERT(!m_state->IsStateTx() && !m_state->IsStateSwitching());
1759
1760 if (!txVector.IsValid(m_band))
1761 {
1762 NS_FATAL_ERROR("TX-VECTOR is invalid!");
1763 }
1764
1765 uint8_t nss = 0;
1766 if (txVector.IsMu())
1767 {
1768 // We do not support mixed OFDMA and MU-MIMO
1769 if (txVector.IsDlMuMimo())
1770 {
1771 nss = txVector.GetNssTotal();
1772 }
1773 else
1774 {
1775 nss = txVector.GetNssMax();
1776 }
1777 }
1778 else
1779 {
1780 nss = txVector.GetNss();
1781 }
1782
1784 {
1785 NS_FATAL_ERROR("Unsupported number of spatial streams!");
1786 }
1787
1788 if (m_state->IsStateSleep())
1789 {
1790 NS_LOG_DEBUG("Dropping packet because in sleep mode");
1791 for (const auto& psdu : psdus)
1792 {
1793 NotifyTxDrop(psdu.second);
1794 }
1795 return;
1796 }
1797
1798 Time txDuration = CalculateTxDuration(psdus, txVector, GetPhyBand());
1799
1800 bool noEndPreambleDetectionEvent = true;
1801 for (const auto& it : m_phyEntities)
1802 {
1803 noEndPreambleDetectionEvent &= it.second->NoEndPreambleDetectionEvents();
1804 }
1805 if (!noEndPreambleDetectionEvent || m_currentEvent)
1806 {
1808 }
1809
1811 {
1812 NS_LOG_DEBUG("Transmitting with power restriction for " << txDuration.As(Time::NS));
1813 }
1814 else
1815 {
1816 NS_LOG_DEBUG("Transmitting without power restriction for " << txDuration.As(Time::NS));
1817 }
1818
1819 if (m_state->GetState() == WifiPhyState::OFF)
1820 {
1821 NS_LOG_DEBUG("Transmission canceled because device is OFF");
1822 return;
1823 }
1824
1825 Ptr<WifiPpdu> ppdu =
1826 GetPhyEntity(txVector.GetModulationClass())->BuildPpdu(psdus, txVector, txDuration);
1827 m_previouslyRxPpduUid = UINT64_MAX; // reset (after creation of PPDU) to use it only once
1828
1829 double txPowerW = DbmToW(GetTxPowerForTransmission(ppdu) + GetTxGain());
1830 NotifyTxBegin(psdus, txPowerW);
1831 if (!m_phyTxPsduBeginTrace.IsEmpty())
1832 {
1833 m_phyTxPsduBeginTrace(psdus, txVector, txPowerW);
1834 }
1835 for (const auto& psdu : psdus)
1836 {
1837 NotifyMonitorSniffTx(psdu.second, GetFrequency(), txVector, psdu.first);
1838 }
1839 m_state->SwitchToTx(txDuration, psdus, GetPowerDbm(txVector.GetTxPowerLevel()), txVector);
1840
1842 m_wifiRadioEnergyModel->GetMaximumTimeInState(WifiPhyState::TX) < txDuration)
1843 {
1844 ppdu->SetTruncatedTx();
1845 }
1846
1847 m_endTxEvent =
1848 Simulator::Schedule(txDuration, &WifiPhy::TxDone, this, psdus); // TODO: fix for MU
1849
1850 StartTx(ppdu);
1851 ppdu->ResetTxVector();
1852
1854 m_powerRestricted = false;
1855}
1856
1857void
1859{
1860 NS_LOG_FUNCTION(this << psdus);
1861 NotifyTxEnd(psdus);
1862 Reset();
1863 // we might have received signals during TX
1865}
1866
1867uint64_t
1869{
1870 return m_previouslyRxPpduUid;
1871}
1872
1873void
1875{
1878}
1879
1880void
1882{
1883 NS_LOG_FUNCTION(this);
1886 {
1888 }
1889 m_currentEvent = nullptr;
1890 for (auto& phyEntity : m_phyEntities)
1891 {
1892 phyEntity.second->CancelAllEvents();
1893 }
1896}
1897
1898void
1900 RxPowerWattPerChannelBand& rxPowersW,
1901 Time rxDuration)
1902{
1903 NS_LOG_FUNCTION(this << ppdu << rxDuration);
1904 WifiModulationClass modulation = ppdu->GetModulation();
1906 if (auto it = m_phyEntities.find(modulation);
1907 it != m_phyEntities.end() && modulation <= m_maxModClassSupported)
1908 {
1909 it->second->StartReceivePreamble(ppdu, rxPowersW, rxDuration);
1910 }
1911 else
1912 {
1913 // TODO find a fallback PHY for receiving the PPDU (e.g. 11a for 11ax due to preamble
1914 // structure)
1915 NS_LOG_DEBUG("Unsupported modulation received (" << modulation << "), consider as noise");
1916 m_interference->Add(ppdu, rxDuration, rxPowersW, GetCurrentFrequencyRange());
1918 }
1919}
1920
1921bool
1923{
1924 return m_endPhyRxEvent.IsRunning();
1925}
1926
1927void
1929{
1930 NS_LOG_FUNCTION(this);
1932 {
1933 m_powerRestricted = false;
1934 }
1935}
1936
1937void
1939{
1940 NS_LOG_FUNCTION(this);
1942}
1943
1944bool
1946{
1947 for (const auto& phyEntity : m_phyEntities)
1948 {
1949 if (phyEntity.second->IsModeSupported(mode))
1950 {
1951 return true;
1952 }
1953 }
1954 return false;
1955}
1956
1959{
1960 // Start from oldest standards and move up (guaranteed by fact that WifModulationClass is
1961 // ordered)
1962 for (const auto& phyEntity : m_phyEntities)
1963 {
1964 for (const auto& mode : *(phyEntity.second))
1965 {
1966 return mode;
1967 }
1968 }
1969 NS_ASSERT_MSG(false, "Should have found at least one default mode");
1970 return WifiMode();
1971}
1972
1973bool
1974WifiPhy::IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
1975{
1976 const auto phyEntity = m_phyEntities.find(modulation);
1977 if (phyEntity == m_phyEntities.end())
1978 {
1979 return false;
1980 }
1981 return phyEntity->second->IsMcsSupported(mcs);
1982}
1983
1984std::list<WifiMode>
1986{
1987 std::list<WifiMode> list;
1988 for (const auto& phyEntity : m_phyEntities)
1989 {
1990 if (!phyEntity.second->HandlesMcsModes()) // to exclude MCSs from search
1991 {
1992 for (const auto& mode : *(phyEntity.second))
1993 {
1994 list.emplace_back(mode);
1995 }
1996 }
1997 }
1998 return list;
1999}
2000
2001std::list<WifiMode>
2003{
2004 std::list<WifiMode> list;
2005 const auto phyEntity = m_phyEntities.find(modulation);
2006 if (phyEntity != m_phyEntities.end())
2007 {
2008 if (!phyEntity->second->HandlesMcsModes()) // to exclude MCSs from search
2009 {
2010 for (const auto& mode : *(phyEntity->second))
2011 {
2012 list.emplace_back(mode);
2013 }
2014 }
2015 }
2016 return list;
2017}
2018
2019uint16_t
2021{
2022 uint16_t numMcs = 0;
2023 for (const auto& phyEntity : m_phyEntities)
2024 {
2025 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2026 {
2027 numMcs += phyEntity.second->GetNumModes();
2028 }
2029 }
2030 return numMcs;
2031}
2032
2033std::list<WifiMode>
2035{
2036 std::list<WifiMode> list;
2037 for (const auto& phyEntity : m_phyEntities)
2038 {
2039 if (phyEntity.second->HandlesMcsModes()) // to exclude non-MCS modes from search
2040 {
2041 for (const auto& mode : *(phyEntity.second))
2042 {
2043 list.emplace_back(mode);
2044 }
2045 }
2046 }
2047 return list;
2048}
2049
2050std::list<WifiMode>
2052{
2053 std::list<WifiMode> list;
2054 auto phyEntity = m_phyEntities.find(modulation);
2055 if (phyEntity != m_phyEntities.end())
2056 {
2057 if (phyEntity->second->HandlesMcsModes()) // to exclude non-MCS modes from search
2058 {
2059 for (const auto& mode : *(phyEntity->second))
2060 {
2061 list.emplace_back(mode);
2062 }
2063 }
2064 }
2065 return list;
2066}
2067
2069WifiPhy::GetMcs(WifiModulationClass modulation, uint8_t mcs) const
2070{
2071 NS_ASSERT_MSG(IsMcsSupported(modulation, mcs), "Unsupported MCS");
2072 return m_phyEntities.at(modulation)->GetMcs(mcs);
2073}
2074
2075bool
2077{
2078 return m_state->IsStateCcaBusy();
2079}
2080
2081bool
2083{
2084 return m_state->IsStateIdle();
2085}
2086
2087bool
2089{
2090 return m_state->IsStateRx();
2091}
2092
2093bool
2095{
2096 return m_state->IsStateTx();
2097}
2098
2099bool
2101{
2102 return m_state->IsStateSwitching();
2103}
2104
2105bool
2107{
2108 return m_state->IsStateSleep();
2109}
2110
2111bool
2113{
2114 return m_state->IsStateOff();
2115}
2116
2117Time
2119{
2120 return m_state->GetDelayUntilIdle();
2121}
2122
2123Time
2125{
2126 return m_state->GetLastRxStartTime();
2127}
2128
2129Time
2131{
2132 return m_state->GetLastRxEndTime();
2133}
2134
2135void
2137{
2138 NS_LOG_FUNCTION(this);
2139 GetLatestPhyEntity()->SwitchMaybeToCcaBusy(ppdu);
2140}
2141
2142void
2144{
2145 NS_LOG_FUNCTION(this << duration);
2146 GetLatestPhyEntity()->NotifyCcaBusy(ppdu, duration, WIFI_CHANLIST_PRIMARY);
2147}
2148
2149void
2151{
2152 NS_LOG_FUNCTION(this << reason);
2153 if (reason != OBSS_PD_CCA_RESET ||
2154 m_currentEvent) // Otherwise abort has already been called previously
2155 {
2156 for (auto& phyEntity : m_phyEntities)
2157 {
2158 phyEntity.second->CancelAllEvents();
2159 }
2162 if (!m_currentEvent)
2163 {
2164 return;
2165 }
2167 if (reason == OBSS_PD_CCA_RESET)
2168 {
2169 m_state->SwitchFromRxAbort(GetChannelWidth());
2170 }
2171 if (reason == RECEPTION_ABORTED_BY_TX)
2172 {
2173 Reset();
2174 }
2175 else
2176 {
2177 for (auto it = m_currentPreambleEvents.begin(); it != m_currentPreambleEvents.end();
2178 ++it)
2179 {
2180 if (it->second == m_currentEvent)
2181 {
2182 it = m_currentPreambleEvents.erase(it);
2183 break;
2184 }
2185 }
2186 m_currentEvent = nullptr;
2187 }
2188 }
2189}
2190
2191void
2192WifiPhy::ResetCca(bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
2193{
2194 NS_LOG_FUNCTION(this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
2195 // This method might be called multiple times when receiving TB PPDUs with a BSS color
2196 // different than the one of the receiver. The first time this method is called, the call
2197 // to AbortCurrentReception sets m_currentEvent to 0. Therefore, we need to check whether
2198 // m_currentEvent is not 0 before executing the instructions below.
2199 if (m_currentEvent)
2200 {
2201 m_powerRestricted = powerRestricted;
2202 m_txPowerMaxSiso = txPowerMaxSiso;
2203 m_txPowerMaxMimo = txPowerMaxMimo;
2204 NS_ASSERT((m_currentEvent->GetEndTime() - Simulator::Now()).IsPositive());
2207 this);
2209 this,
2210 OBSS_PD_CCA_RESET); // finish processing field first
2211 }
2212}
2213
2214double
2216{
2217 NS_LOG_FUNCTION(this << m_powerRestricted << ppdu);
2218 const auto& txVector = ppdu->GetTxVector();
2219 // Get transmit power before antenna gain
2220 double txPowerDbm;
2221 if (!m_powerRestricted)
2222 {
2223 txPowerDbm = GetPowerDbm(txVector.GetTxPowerLevel());
2224 }
2225 else
2226 {
2227 if (txVector.GetNssMax() > 1 || txVector.GetNssTotal() > 1)
2228 {
2229 txPowerDbm = std::min(m_txPowerMaxMimo, GetPowerDbm(txVector.GetTxPowerLevel()));
2230 }
2231 else
2232 {
2233 txPowerDbm = std::min(m_txPowerMaxSiso, GetPowerDbm(txVector.GetTxPowerLevel()));
2234 }
2235 }
2236
2237 // Apply power density constraint on EIRP
2238 uint16_t channelWidth = ppdu->GetTxChannelWidth();
2239 double txPowerDbmPerMhz =
2240 (txPowerDbm + GetTxGain()) - RatioToDb(channelWidth); // account for antenna gain since EIRP
2241 NS_LOG_INFO("txPowerDbm=" << txPowerDbm << " with txPowerDbmPerMhz=" << txPowerDbmPerMhz
2242 << " over " << channelWidth << " MHz");
2243 txPowerDbm = std::min(txPowerDbmPerMhz, m_powerDensityLimit) + RatioToDb(channelWidth);
2244 txPowerDbm -= GetTxGain(); // remove antenna gain since will be added right afterwards
2245 NS_LOG_INFO("txPowerDbm=" << txPowerDbm
2246 << " after applying m_powerDensityLimit=" << m_powerDensityLimit);
2247 return txPowerDbm;
2248}
2249
2252{
2253 // TODO: wrapper. See if still needed
2254 return GetPhyEntityForPpdu(ppdu)->GetAddressedPsduInPpdu(ppdu);
2255}
2256
2257int64_t
2259{
2260 NS_LOG_FUNCTION(this << stream);
2261 int64_t currentStream = stream;
2262 m_random->SetStream(currentStream++);
2263 currentStream += m_interference->GetErrorRateModel()->AssignStreams(currentStream);
2264 return (currentStream - stream);
2265}
2266
2267std::ostream&
2268operator<<(std::ostream& os, RxSignalInfo rxSignalInfo)
2269{
2270 os << "SNR:" << RatioToDb(rxSignalInfo.snr) << " dB"
2271 << ", RSSI:" << rxSignalInfo.rssi << " dBm";
2272 return os;
2273}
2274
2275uint8_t
2276WifiPhy::GetPrimaryChannelNumber(uint16_t primaryChannelWidth) const
2277{
2278 return m_operatingChannel.GetPrimaryChannelNumber(primaryChannelWidth, m_standard);
2279}
2280
2283{
2284 uint32_t subcarrierSpacing = 0;
2285 switch (GetStandard())
2286 {
2292 subcarrierSpacing = 312500;
2293 break;
2295 if (GetChannelWidth() == 5)
2296 {
2297 subcarrierSpacing = 78125;
2298 }
2299 else
2300 {
2301 subcarrierSpacing = 156250;
2302 }
2303 break;
2306 subcarrierSpacing = 78125;
2307 break;
2308 default:
2309 NS_FATAL_ERROR("Standard unknown: " << GetStandard());
2310 break;
2311 }
2312 return subcarrierSpacing;
2313}
2314
2315} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:571
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:62
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Keep track of the current position and velocity of an object.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:522
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:251
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition: nstime.h:351
@ NS
nanosecond
Definition: nstime.h:119
AttributeValue implementation for Time.
Definition: nstime.h:1406
bool IsEmpty() const
Checks if the Callbacks list is empty.
a unique identifier for an interface.
Definition: type-id.h:59
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:64
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
bool Get160MHzOperationSupported() const
represent a single transmission mode
Definition: wifi-mode.h:51
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
Ptr< VhtConfiguration > GetVhtConfiguration() const
Ptr< HtConfiguration > GetHtConfiguration() const
Ptr< Node > GetNode() const override
802.11 PHY layer model
Definition: wifi-phy.h:65
static TypeId GetTypeId()
Get the type ID.
Definition: wifi-phy.cc:67
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1278
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1291
Time GetBlockAckTxTime() const
Return the estimated BlockAck TX time for this PHY.
Definition: wifi-phy.cc:838
double GetCcaEdThreshold() const
Return the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:506
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:1544
bool IsStateTx() const
Definition: wifi-phy.cc:2094
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:1568
WifiModulationClass GetMaxModulationClassSupported() const
Definition: wifi-phy.cc:976
bool IsStateIdle() const
Definition: wifi-phy.cc:2082
virtual void SetInterferenceHelper(const Ptr< InterferenceHelper > helper)
Sets the interference helper.
Definition: wifi-phy.cc:651
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition: wifi-phy.h:1560
bool IsStateCcaBusy() const
Definition: wifi-phy.cc:2076
void Send(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
This function is a wrapper for the Send variant that accepts a WifiConstPsduMap as first argument.
Definition: wifi-phy.cc:1741
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1290
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:1572
void Configure80211ax()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard.
Definition: wifi-phy.cc:946
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:1565
void SetCcaEdThreshold(double threshold)
Sets the CCA energy detection threshold (dBm).
Definition: wifi-phy.cc:499
void NotifyCcaBusy(const Ptr< const WifiPpdu > ppdu, Time duration)
Notify PHY state helper to switch to CCA busy state,.
Definition: wifi-phy.cc:2143
WifiPhyOperatingChannel m_operatingChannel
Operating channel.
Definition: wifi-phy.h:1528
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:1435
void SetErrorRateModel(const Ptr< ErrorRateModel > model)
Sets the error rate model.
Definition: wifi-phy.cc:660
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition: wifi-phy.h:1555
static Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype=NORMAL_MPDU, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1481
Time GetSlot() const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:814
uint32_t GetSubcarrierSpacing() const
Definition: wifi-phy.cc:2282
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1328
Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: wifi-phy.cc:2251
void Configure80211g()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard.
Definition: wifi-phy.cc:876
uint8_t GetPrimary20Index() const
Definition: wifi-phy.cc:1078
void NotifyTxEnd(WifiConstPsduMap psdus)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:1578
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1072
std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > m_currentPreambleEvents
store event associated to a PPDU (that has a unique ID and preamble combination) whose preamble is be...
Definition: wifi-phy.h:1303
uint8_t GetNumberOfAntennas() const
Definition: wifi-phy.cc:1290
Time m_slot
Slot duration.
Definition: wifi-phy.h:1532
double m_powerDensityLimit
the power density limit (dBm/MHz)
Definition: wifi-phy.h:1548
Time GetDelayUntilIdle()
Definition: wifi-phy.cc:2118
double GetRxSensitivity() const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:493
bool GetShortPhyPreambleSupported() const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:608
void SetSifs(Time sifs)
Set the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:796
std::list< uint8_t > GetBssMembershipSelectorList() const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1346
void Configure80211n()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard.
Definition: wifi-phy.cc:919
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1298
double GetTxGain() const
Return the transmission gain (dB).
Definition: wifi-phy.cc:582
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:1545
void Configure80211be()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11be standard.
Definition: wifi-phy.cc:961
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1629
bool IsStateRx() const
Definition: wifi-phy.cc:2088
bool IsMcsSupported(WifiModulationClass modulation, uint8_t mcs) const
Check if the given MCS of the given modulation class is supported by the PHY.
Definition: wifi-phy.cc:1974
Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:802
uint16_t GetFrequency() const
Definition: wifi-phy.cc:1060
Ptr< MobilityModel > GetMobility() const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:632
uint16_t GetNMcs() const
Definition: wifi-phy.cc:2020
Time m_blockAckTxTime
estimated BlockAck TX time
Definition: wifi-phy.h:1535
uint8_t GetPrimaryChannelNumber(uint16_t primaryChannelWidth) const
Get channel number of the primary channel.
Definition: wifi-phy.cc:2276
void ResetCca(bool powerRestricted, double txPowerMaxSiso=0, double txPowerMaxMimo=0)
Reset PHY to IDLE, with some potential TX power restrictions for the next transmission.
Definition: wifi-phy.cc:2192
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1554
void ResumeFromSleep()
Resume from sleep mode.
Definition: wifi-phy.cc:1414
static Time GetPreambleDetectionDuration()
Definition: wifi-phy.cc:1469
void Configure80211p()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11p standard.
Definition: wifi-phy.cc:889
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted.
Definition: wifi-phy.cc:2150
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1570
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1467
void NotifyRxBegin(Ptr< const WifiPsdu > psdu, const RxPowerWattPerChannelBand &rxPowersW)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:1605
Time GetChannelSwitchDelay() const
Definition: wifi-phy.cc:712
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1296
Time m_sifs
Short Interframe Space (SIFS) duration.
Definition: wifi-phy.h:1531
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:462
bool IsStateOff() const
Definition: wifi-phy.cc:2112
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition: wifi-phy.cc:1340
double GetTxPowerEnd() const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:556
virtual void ConfigureStandard(WifiStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:982
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:668
WifiMode GetMcs(WifiModulationClass modulation, uint8_t mcs) const
Get the WifiMode object corresponding to the given MCS of the given modulation class.
Definition: wifi-phy.cc:2069
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:1559
ChannelTuple m_channelSettings
Store operating channel settings until initialization.
Definition: wifi-phy.h:1527
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1528
static uint32_t GetMaxPsduSize(WifiModulationClass modulation)
Get the maximum PSDU size in bytes for the given modulation class.
Definition: wifi-phy.cc:1557
Ptr< WifiPhyStateHelper > GetState() const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:450
virtual Ptr< Channel > GetChannel() const =0
Return the Channel this WifiPhy is connected to.
void NotifyTxBegin(WifiConstPsduMap psdus, double txPowerW)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:1563
void EndReceiveInterBss()
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:1928
void SetSleepMode()
Put in sleep mode.
Definition: wifi-phy.cc:1361
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:601
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:562
WifiPhyBand m_band
WifiPhyBand.
Definition: wifi-phy.h:1526
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:486
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:724
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:1513
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:1552
std::map< WifiModulationClass, Ptr< PhyEntity > > m_phyEntities
This map holds the supported PHY entities.
Definition: wifi-phy.h:1326
virtual void StartTx(Ptr< const WifiPpdu > ppdu)=0
void SetMaxModulationClassSupported(WifiModulationClass modClass)
Set the maximum modulation class that has to be supported by this PHY object.
Definition: wifi-phy.cc:969
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:783
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:1494
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1573
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1299
double GetRxGain() const
Return the reception gain (dB).
Definition: wifi-phy.cc:595
static WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector)
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
Definition: wifi-phy.cc:1735
double m_rxSensitivityDbm
Receive sensitivity threshold in dBm.
Definition: wifi-phy.h:1537
void RegisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition: wifi-phy.cc:468
static std::map< WifiModulationClass, Ptr< PhyEntity > > & GetStaticPhyEntities()
Definition: wifi-phy.cc:443
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition: wifi-phy.cc:808
void SetOperatingChannel(const ChannelTuple &channelTuple)
If the standard for this object has not been set yet, store the given channel settings.
Definition: wifi-phy.cc:1119
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1042
void SetPreviouslyRxPpduUid(uint64_t uid)
Set the UID of the previously received PPDU.
Definition: wifi-phy.cc:1874
bool IsReceivingPhyHeader() const
Definition: wifi-phy.cc:1922
double m_ccaSensitivityThresholdW
Clear channel assessment (CCA) modulation and coding rate sensitivity threshold in watts.
Definition: wifi-phy.h:1540
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1301
Time GetLastRxStartTime() const
Return the start time of the last received packet.
Definition: wifi-phy.cc:2124
WifiMode GetDefaultMode() const
Get the default WifiMode supported by the PHY.
Definition: wifi-phy.cc:1958
void SetCcaSensitivityThreshold(double threshold)
Sets the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:512
double m_ccaEdThresholdW
Clear channel assessment (CCA) energy detection (ED) threshold in watts.
Definition: wifi-phy.h:1538
void NotifyMonitorSniffTx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, uint16_t staId=SU_STA_ID)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being transmitted.
Definition: wifi-phy.cc:1695
Ptr< PhyEntity > GetPhyEntity(WifiModulationClass modulation) const
Get the supported PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:733
uint8_t GetChannelNumber() const
Return current channel number.
Definition: wifi-phy.cc:1066
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium.
Definition: wifi-phy.h:1427
uint64_t m_previouslyRxPpduUid
UID of the previously received PPDU, reset to UINT64_MAX upon transmission.
Definition: wifi-phy.h:1306
std::optional< Time > GetDelayUntilChannelSwitch()
Perform any actions necessary when user changes operating channel after initialization.
Definition: wifi-phy.cc:1156
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU.
Definition: wifi-phy.h:1295
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition: wifi-phy.cc:687
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:1412
virtual void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:614
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1571
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:549
Time GetPifs() const
Return the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:826
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:774
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:1617
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:1899
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:1419
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:1543
bool IsStateSleep() const
Definition: wifi-phy.cc:2106
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:620
WifiStandard m_standard
WifiStandard.
Definition: wifi-phy.h:1524
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:693
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:1547
void DoDispose() override
Destructor implementation.
Definition: wifi-phy.cc:414
bool IsStateSwitching() const
Definition: wifi-phy.cc:2100
void SetPhyId(uint8_t phyId)
Set the index allocated to this PHY.
Definition: wifi-phy.cc:638
virtual void DoChannelSwitch()
Actually switch channel based on the stored channel settings.
Definition: wifi-phy.cc:1195
void SetOffMode()
Put in off mode.
Definition: wifi-phy.cc:1404
double m_noiseFigureDb
The noise figure in dB.
Definition: wifi-phy.h:1563
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:1474
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:681
uint8_t m_phyId
the index of the PHY in the vector of PHYs held by the WifiNetDevice
Definition: wifi-phy.h:1285
std::tuple< uint8_t, uint16_t, WifiPhyBand, uint8_t > ChannelTuple
Tuple identifying an operating channel.
Definition: wifi-phy.h:903
void SetPifs(Time pifs)
Set the PCF Interframe Space (PIFS) for this PHY.
Definition: wifi-phy.cc:820
void Configure80211b()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard.
Definition: wifi-phy.cc:859
static Time GetStartOfPacketDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1475
virtual FrequencyRange GetCurrentFrequencyRange() const =0
Get the frequency range of the current RF interface.
uint16_t GetTxBandwidth(WifiMode mode, uint16_t maxAllowedBandWidth=std::numeric_limits< uint16_t >::max()) const
Get the bandwidth for a transmission occurring on the current operating channel and using the given W...
Definition: wifi-phy.cc:1096
void SetRxGain(double gain)
Sets the reception gain (dB).
Definition: wifi-phy.cc:588
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:2136
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:626
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:575
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:1561
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:1546
double CalculateSnr(const WifiTxVector &txVector, double ber) const
Definition: wifi-phy.cc:718
void SetFixedPhyBand(bool enable)
Configure whether it is prohibited to change PHY band after initialization.
Definition: wifi-phy.cc:1084
~WifiPhy() override
Definition: wifi-phy.cc:383
void Configure80211ac()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard.
Definition: wifi-phy.cc:938
bool HasFixedPhyBand() const
Definition: wifi-phy.cc:1090
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:1443
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:1567
Ptr< InterferenceHelper > m_interference
Pointer to a helper responsible for interference computations.
Definition: wifi-phy.h:1288
void DoInitialize() override
Initialize() implementation.
Definition: wifi-phy.cc:389
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:1558
uint8_t GetPhyId() const
Get the index allocated to this PHY.
Definition: wifi-phy.cc:645
Time m_pifs
PCF Interframe Space (PIFS) duration.
Definition: wifi-phy.h:1533
WifiModulationClass m_maxModClassSupported
max modulation class supported
Definition: wifi-phy.h:1525
void SetRxNoiseFigure(double noiseFigureDb)
Sets the RX loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver.
Definition: wifi-phy.cc:525
double GetTxPowerStart() const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:543
double GetTxPowerForTransmission(Ptr< const WifiPpdu > ppdu) const
Compute the transmit power for the next transmission.
Definition: wifi-phy.cc:2215
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1048
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:480
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:456
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:675
void NotifyChannelAccessRequested()
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1938
void ResumeFromOff()
Resume from off mode.
Definition: wifi-phy.cc:1441
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:1550
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:1576
void NotifyMonitorSniffRx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, SignalNoiseDbm signalNoise, std::vector< bool > statusPerMpdu, uint16_t staId=SU_STA_ID)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being received.
Definition: wifi-phy.cc:1641
Ptr< PhyEntity > GetPhyEntityForPpdu(const Ptr< const WifiPpdu > ppdu) const
Get the supported PHY entity to use for a received PPDU.
Definition: wifi-phy.cc:754
Time GetAckTxTime() const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:832
uint64_t GetPreviouslyRxPpduUid() const
Definition: wifi-phy.cc:1868
void Reset()
Reset data upon end of TX or RX.
Definition: wifi-phy.cc:1881
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1459
Time GetLastRxEndTime() const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2130
uint8_t GetMaxSupportedTxSpatialStreams() const
Definition: wifi-phy.cc:1322
void Configure80211a()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard.
Definition: wifi-phy.cc:844
std::list< WifiMode > GetMcsList() const
The WifiPhy::GetMcsList() method is used (e.g., by a WifiRemoteStationManager) to determine the set o...
Definition: wifi-phy.cc:2034
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1985
void TxDone(const WifiConstPsduMap &psdus)
Callback function when a transmission is completed.
Definition: wifi-phy.cc:1858
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1054
double GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:519
bool m_fixedPhyBand
True to prohibit changing PHY band after initialization.
Definition: wifi-phy.h:1529
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition: wifi-phy.cc:748
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:536
uint8_t GetNTxPower() const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:569
virtual int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: wifi-phy.cc:2258
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1521
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:1945
Time m_ackTxTime
estimated Ack TX time
Definition: wifi-phy.h:1534
void UnregisterListener(const std::shared_ptr< WifiPhyListener > &listener)
Definition: wifi-phy.cc:474
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:1593
Class that keeps track of all information about the current PHY operating channel.
bool IsSet() const
Return true if a valid channel has been set, false otherwise.
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
void SetPrimary20Index(uint8_t index)
Set the index of the primary 20 MHz channel (0 indicates the 20 MHz subchannel with the lowest center...
void Set(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band)
Set the channel according to the specified parameters if a unique frequency channel matches the speci...
uint8_t GetPrimaryChannelNumber(uint16_t primaryChannelWidth, WifiStandard standard) const
Get channel number of the primary channel.
uint16_t GetWidth() const
Return the width of the whole operating channel (in MHz).
static uint8_t GetDefaultChannelNumber(uint16_t width, WifiStandard standard, WifiPhyBand band)
Get the default channel number of the given width and for the given standard and band.
uint8_t GetNumber() const
Return the channel number identifying the whole operating channel.
uint16_t GetFrequency() const
Return the center frequency of the operating channel (in MHz).
void SwitchToSleep()
Switch to sleep mode.
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.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1427
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1407
Ptr< const AttributeChecker > MakeTupleChecker(Ts... checkers)
Create a TupleChecker from AttributeCheckers associated with TupleValue elements.
Definition: tuple.h:540
Ptr< const AttributeAccessor > MakeTupleAccessor(T1 a1)
Create an AttributeAccessor for a class data member of type tuple, or a lone class get functor or set...
Definition: tuple.h:547
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1343
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1319
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.
Definition: wifi-phy-band.h:33
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
MpduType
The type of an MPDU.
@ 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
@ RECEPTION_ABORTED_BY_TX
@ CHANNEL_SWITCHING
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
Definition: wifi-phy-band.h:43
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ 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:46
@ OFDM_PHY_5_MHZ
Definition: ofdm-phy.h:47
@ WIFI_CHANLIST_PRIMARY
@ LAST_MPDU_IN_AGGREGATE
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
@ NORMAL_MPDU
The MPDU is not part of an A-MPDU.
@ FIRST_MPDU_IN_AGGREGATE
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate.
@ SINGLE_MPDU
The MPDU is a single MPDU.
@ MIDDLE_MPDU_IN_AGGREGATE
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:454
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:52
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.
@ OFF
The PHY layer is switched off.
@ 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.
uint16_t GetMaximumChannelWidth(WifiModulationClass modulation)
Get the maximum channel width in MHz allowed for the given modulation class.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:40
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:189
std::map< WifiSpectrumBandInfo, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:77
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.
uint16_t GetDefaultChannelWidth(WifiStandard standard, WifiPhyBand band)
Get the default channel width for the given PHY standard and band.
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:34
#define list
MpduInfo structure.
Definition: phy-entity.h:62
MpduType type
type of MPDU
Definition: phy-entity.h:63
uint32_t mpduRefNumber
MPDU ref number.
Definition: phy-entity.h:64
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:69
double rssi
RSSI in dBm.
Definition: phy-entity.h:71
double snr
SNR in linear scale.
Definition: phy-entity.h:70
SignalNoiseDbm structure.
Definition: phy-entity.h:55
Declaration of ns3::WifiPpdu class and ns3::WifiConstPsduMap.