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