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