A Discrete-Event Network Simulator
API
wifi-phy.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include "ns3/simulator.h"
23 #include "ns3/log.h"
24 #include "ns3/pointer.h"
25 #include "ns3/mobility-model.h"
26 #include "ns3/random-variable-stream.h"
27 #include "ns3/error-model.h"
28 #include "wifi-phy.h"
29 #include "ampdu-tag.h"
30 #include "wifi-utils.h"
31 #include "frame-capture-model.h"
34 #include "error-rate-model.h"
35 #include "wifi-net-device.h"
36 #include "ht-configuration.h"
37 #include "he-configuration.h"
38 #include "mpdu-aggregator.h"
39 #include "wifi-psdu.h"
40 #include "wifi-ppdu.h"
41 
42 namespace ns3 {
43 
44 NS_LOG_COMPONENT_DEFINE ("WifiPhy");
45 
46 /****************************************************************
47  * The actual WifiPhy class
48  ****************************************************************/
49 
51 
61 {
62  // 802.11b uses width of 22, while OFDM modes use width of 20
63  { std::make_pair (1, WIFI_PHY_STANDARD_80211b), std::make_pair (2412, 22) },
64  { std::make_pair (1, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2412, 20) },
65  { std::make_pair (2, WIFI_PHY_STANDARD_80211b), std::make_pair (2417, 22) },
66  { std::make_pair (2, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2417, 20) },
67  { std::make_pair (3, WIFI_PHY_STANDARD_80211b), std::make_pair (2422, 22) },
68  { std::make_pair (3, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2422, 20) },
69  { std::make_pair (4, WIFI_PHY_STANDARD_80211b), std::make_pair (2427, 22) },
70  { std::make_pair (4, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2427, 20) },
71  { std::make_pair (5, WIFI_PHY_STANDARD_80211b), std::make_pair (2432, 22) },
72  { std::make_pair (5, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2432, 20) },
73  { std::make_pair (6, WIFI_PHY_STANDARD_80211b), std::make_pair (2437, 22) },
74  { std::make_pair (6, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2437, 20) },
75  { std::make_pair (7, WIFI_PHY_STANDARD_80211b), std::make_pair (2442, 22) },
76  { std::make_pair (7, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2442, 20) },
77  { std::make_pair (8, WIFI_PHY_STANDARD_80211b), std::make_pair (2447, 22) },
78  { std::make_pair (8, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2447, 20) },
79  { std::make_pair (9, WIFI_PHY_STANDARD_80211b), std::make_pair (2452, 22) },
80  { std::make_pair (9, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2452, 20) },
81  { std::make_pair (10, WIFI_PHY_STANDARD_80211b), std::make_pair (2457, 22) },
82  { std::make_pair (10, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2457, 20) },
83  { std::make_pair (11, WIFI_PHY_STANDARD_80211b), std::make_pair (2462, 22) },
84  { std::make_pair (11, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2462, 20) },
85  { std::make_pair (12, WIFI_PHY_STANDARD_80211b), std::make_pair (2467, 22) },
86  { std::make_pair (12, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2467, 20) },
87  { std::make_pair (13, WIFI_PHY_STANDARD_80211b), std::make_pair (2472, 22) },
88  { std::make_pair (13, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (2472, 20) },
89  // Only defined for 802.11b
90  { std::make_pair (14, WIFI_PHY_STANDARD_80211b), std::make_pair (2484, 22) },
91 
92  // Now the 5GHz channels; UNSPECIFIED for 802.11a/n/ac/ax channels
93  // 20 MHz channels
94  { std::make_pair (36, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5180, 20) },
95  { std::make_pair (40, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5200, 20) },
96  { std::make_pair (44, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5220, 20) },
97  { std::make_pair (48, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5240, 20) },
98  { std::make_pair (52, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5260, 20) },
99  { std::make_pair (56, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5280, 20) },
100  { std::make_pair (60, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5300, 20) },
101  { std::make_pair (64, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5320, 20) },
102  { std::make_pair (100, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5500, 20) },
103  { std::make_pair (104, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5520, 20) },
104  { std::make_pair (108, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5540, 20) },
105  { std::make_pair (112, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5560, 20) },
106  { std::make_pair (116, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5580, 20) },
107  { std::make_pair (120, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5600, 20) },
108  { std::make_pair (124, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5620, 20) },
109  { std::make_pair (128, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5640, 20) },
110  { std::make_pair (132, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5660, 20) },
111  { std::make_pair (136, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5680, 20) },
112  { std::make_pair (140, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5700, 20) },
113  { std::make_pair (144, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5720, 20) },
114  { std::make_pair (149, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5745, 20) },
115  { std::make_pair (153, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5765, 20) },
116  { std::make_pair (157, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5785, 20) },
117  { std::make_pair (161, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5805, 20) },
118  { std::make_pair (165, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5825, 20) },
119  { std::make_pair (169, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5845, 20) },
120  { std::make_pair (173, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5865, 20) },
121  { std::make_pair (177, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5885, 20) },
122  { std::make_pair (181, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5905, 20) },
123  // 40 MHz channels
124  { std::make_pair (38, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5190, 40) },
125  { std::make_pair (46, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5230, 40) },
126  { std::make_pair (54, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5270, 40) },
127  { std::make_pair (62, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5310, 40) },
128  { std::make_pair (102, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5510, 40) },
129  { std::make_pair (110, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5550, 40) },
130  { std::make_pair (118, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5590, 40) },
131  { std::make_pair (126, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5630, 40) },
132  { std::make_pair (134, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5670, 40) },
133  { std::make_pair (142, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5710, 40) },
134  { std::make_pair (151, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5755, 40) },
135  { std::make_pair (159, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5795, 40) },
136  { std::make_pair (167, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5835, 40) },
137  { std::make_pair (175, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5875, 40) },
138  // 80 MHz channels
139  { std::make_pair (42, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5210, 80) },
140  { std::make_pair (58, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5290, 80) },
141  { std::make_pair (106, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5530, 80) },
142  { std::make_pair (122, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5610, 80) },
143  { std::make_pair (138, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5690, 80) },
144  { std::make_pair (155, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5775, 80) },
145  { std::make_pair (171, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5855, 80) },
146  // 160 MHz channels
147  { std::make_pair (50, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5250, 160) },
148  { std::make_pair (114, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5570, 160) },
149  { std::make_pair (163, WIFI_PHY_STANDARD_UNSPECIFIED), std::make_pair (5815, 160) },
150 
151  // 802.11p (10 MHz channels at the 5.855-5.925 band
152  { std::make_pair (172, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5860, 10) },
153  { std::make_pair (174, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5870, 10) },
154  { std::make_pair (176, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5880, 10) },
155  { std::make_pair (178, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5890, 10) },
156  { std::make_pair (180, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5900, 10) },
157  { std::make_pair (182, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5910, 10) },
158  { std::make_pair (184, WIFI_PHY_STANDARD_80211_10MHZ), std::make_pair (5920, 10) }
159 };
160 
161 TypeId
163 {
164  static TypeId tid = TypeId ("ns3::WifiPhy")
165  .SetParent<Object> ()
166  .SetGroupName ("Wifi")
167  .AddAttribute ("Frequency",
168  "The operating center frequency (MHz)",
169  UintegerValue (0),
172  MakeUintegerChecker<uint16_t> ())
173  .AddAttribute ("ChannelWidth",
174  "Whether 5MHz, 10MHz, 20MHz, 22MHz, 40MHz, 80 MHz or 160 MHz.",
175  UintegerValue (20),
178  MakeUintegerChecker<uint16_t> (5, 160))
179  .AddAttribute ("ChannelNumber",
180  "If set to non-zero defined value, will control Frequency and ChannelWidth assignment",
181  UintegerValue (0),
184  MakeUintegerChecker<uint8_t> (0, 196))
185  .AddAttribute ("EnergyDetectionThreshold",
186  "The energy of a received signal should be higher than "
187  "this threshold (dBm) to allow the PHY layer to detect the signal.",
188  DoubleValue (-101.0),
190  MakeDoubleChecker<double> (),
191  TypeId::DEPRECATED, "Replaced by RxSensitivity.")
192  .AddAttribute ("RxSensitivity",
193  "The energy of a received signal should be higher than "
194  "this threshold (dBm) for the PHY to detect the signal.",
195  DoubleValue (-101.0),
198  MakeDoubleChecker<double> ())
199  .AddAttribute ("CcaEdThreshold",
200  "The energy of a non Wi-Fi received signal should be higher than "
201  "this threshold (dBm) to allow the PHY layer to declare CCA BUSY state. "
202  "This check is performed on the 20 MHz primary channel only.",
203  DoubleValue (-62.0),
206  MakeDoubleChecker<double> ())
207  .AddAttribute ("TxGain",
208  "Transmission gain (dB).",
209  DoubleValue (0.0),
212  MakeDoubleChecker<double> ())
213  .AddAttribute ("RxGain",
214  "Reception gain (dB).",
215  DoubleValue (0.0),
218  MakeDoubleChecker<double> ())
219  .AddAttribute ("TxPowerLevels",
220  "Number of transmission power levels available between "
221  "TxPowerStart and TxPowerEnd included.",
222  UintegerValue (1),
224  MakeUintegerChecker<uint8_t> ())
225  .AddAttribute ("TxPowerEnd",
226  "Maximum available transmission level (dBm).",
227  DoubleValue (16.0206),
230  MakeDoubleChecker<double> ())
231  .AddAttribute ("TxPowerStart",
232  "Minimum available transmission level (dBm).",
233  DoubleValue (16.0206),
236  MakeDoubleChecker<double> ())
237  .AddAttribute ("RxNoiseFigure",
238  "Loss (dB) in the Signal-to-Noise-Ratio due to non-idealities in the receiver."
239  " According to Wikipedia (http://en.wikipedia.org/wiki/Noise_figure), this is "
240  "\"the difference in decibels (dB) between"
241  " the noise output of the actual receiver to the noise output of an "
242  " ideal receiver with the same overall gain and bandwidth when the receivers "
243  " are connected to sources at the standard noise temperature T0 (usually 290 K)\".",
244  DoubleValue (7),
246  MakeDoubleChecker<double> ())
247  .AddAttribute ("State",
248  "The state of the PHY layer.",
249  PointerValue (),
251  MakePointerChecker<WifiPhyStateHelper> ())
252  .AddAttribute ("ChannelSwitchDelay",
253  "Delay between two short frames transmitted on different frequencies.",
254  TimeValue (MicroSeconds (250)),
256  MakeTimeChecker ())
257  .AddAttribute ("Antennas",
258  "The number of antennas on the device.",
259  UintegerValue (1),
262  MakeUintegerChecker<uint8_t> (1, 8))
263  .AddAttribute ("MaxSupportedTxSpatialStreams",
264  "The maximum number of supported TX spatial streams."
265  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
266  UintegerValue (1),
269  MakeUintegerChecker<uint8_t> (1, 8))
270  .AddAttribute ("MaxSupportedRxSpatialStreams",
271  "The maximum number of supported RX spatial streams."
272  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
273  UintegerValue (1),
276  MakeUintegerChecker<uint8_t> (1, 8))
277  .AddAttribute ("ShortGuardEnabled",
278  "Whether or not short guard interval is enabled for HT/VHT transmissions."
279  "This parameter is only valuable for 802.11n/ac/ax STAs and APs.",
280  BooleanValue (false),
284  TypeId::DEPRECATED, "Use the HtConfiguration instead")
285  .AddAttribute ("GuardInterval",
286  "Whether 800ns, 1600ns or 3200ns guard interval is used for HE transmissions."
287  "This parameter is only valuable for 802.11ax STAs and APs.",
288  TimeValue (NanoSeconds (3200)),
291  MakeTimeChecker (NanoSeconds (800), NanoSeconds (3200)),
292  TypeId::DEPRECATED, "Use the HeConfiguration instead")
293  .AddAttribute ("GreenfieldEnabled",
294  "Whether or not Greenfield is enabled."
295  "This parameter is only valuable for 802.11n STAs and APs.",
296  BooleanValue (false),
300  TypeId::DEPRECATED, "Use the HtConfiguration instead")
301  .AddAttribute ("ShortPlcpPreambleSupported",
302  "Whether or not short PHY preamble is supported."
303  "This parameter is only valuable for 802.11b STAs and APs."
304  "Note: 802.11g APs and STAs always support short PHY preamble.",
305  BooleanValue (false),
309  .AddAttribute ("FrameCaptureModel",
310  "Ptr to an object that implements the frame capture model",
311  PointerValue (),
313  MakePointerChecker <FrameCaptureModel> ())
314  .AddAttribute ("PreambleDetectionModel",
315  "Ptr to an object that implements the preamble detection model",
316  PointerValue (),
318  MakePointerChecker <PreambleDetectionModel> ())
319  .AddAttribute ("PostReceptionErrorModel",
320  "An optional packet error model can be added to the receive "
321  "packet process after any propagation-based (SNR-based) error "
322  "models have been applied. Typically this is used to force "
323  "specific packet drops, for testing purposes.",
324  PointerValue (),
326  MakePointerChecker<ErrorModel> ())
327  .AddTraceSource ("PhyTxBegin",
328  "Trace source indicating a packet "
329  "has begun transmitting over the channel medium",
331  "ns3::Packet::TracedCallback")
332  .AddTraceSource ("PhyTxPsduBegin",
333  "Trace source indicating a PSDU "
334  "has begun transmitting over the channel medium",
336  "ns3::WifiPhy::PsduTxBeginCallback")
337  .AddTraceSource ("PhyTxEnd",
338  "Trace source indicating a packet "
339  "has been completely transmitted over the channel.",
341  "ns3::Packet::TracedCallback")
342  .AddTraceSource ("PhyTxDrop",
343  "Trace source indicating a packet "
344  "has been dropped by the device during transmission",
346  "ns3::Packet::TracedCallback")
347  .AddTraceSource ("PhyRxBegin",
348  "Trace source indicating a packet "
349  "has begun being received from the channel medium "
350  "by the device",
352  "ns3::Packet::TracedCallback")
353  .AddTraceSource ("PhyRxPayloadBegin",
354  "Trace source indicating the reception of the "
355  "payload of a PPDU has begun",
357  "ns3::WifiPhy::PhyRxPayloadBeginTracedCallback")
358  .AddTraceSource ("PhyRxEnd",
359  "Trace source indicating a packet "
360  "has been completely received from the channel medium "
361  "by the device",
363  "ns3::Packet::TracedCallback")
364  .AddTraceSource ("PhyRxDrop",
365  "Trace source indicating a packet "
366  "has been dropped by the device during reception",
368  "ns3::Packet::TracedCallback")
369  .AddTraceSource ("MonitorSnifferRx",
370  "Trace source simulating a wifi device in monitor mode "
371  "sniffing all received frames",
373  "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
374  .AddTraceSource ("MonitorSnifferTx",
375  "Trace source simulating the capability of a wifi device "
376  "in monitor mode to sniff all frames being transmitted",
378  "ns3::WifiPhy::MonitorSnifferTxTracedCallback")
379  .AddTraceSource ("EndOfHePreamble",
380  "Trace source indicating the end of the 802.11ax preamble (after training fields)",
382  "ns3::WifiPhy::EndOfHePreambleTracedCallback")
383  ;
384  return tid;
385 }
386 
388  : m_txMpduReferenceNumber (0xffffffff),
389  m_rxMpduReferenceNumber (0xffffffff),
390  m_endRxEvent (),
391  m_endPhyRxEvent (),
392  m_endPreambleDetectionEvent (),
393  m_endTxEvent (),
394  m_standard (WIFI_PHY_STANDARD_UNSPECIFIED),
395  m_isConstructed (false),
396  m_channelCenterFrequency (0),
397  m_initialFrequency (0),
398  m_frequencyChannelNumberInitialized (false),
399  m_channelWidth (0),
400  m_powerRestricted (false),
401  m_channelAccessRequested (false),
402  m_txSpatialStreams (0),
403  m_rxSpatialStreams (0),
404  m_channelNumber (0),
405  m_initialChannelNumber (0),
406  m_currentEvent (0),
407  m_wifiRadioEnergyModel (0),
408  m_timeLastPreambleDetected (Seconds (0))
409 {
410  NS_LOG_FUNCTION (this);
411  m_random = CreateObject<UniformRandomVariable> ();
412  m_state = CreateObject<WifiPhyStateHelper> ();
413 }
414 
416 {
417  NS_LOG_FUNCTION (this);
418 }
419 
420 void
422 {
423  NS_LOG_FUNCTION (this);
424  m_endTxEvent.Cancel ();
425  m_endRxEvent.Cancel ();
428  m_device = 0;
429  m_mobility = 0;
430  m_state = 0;
433  m_deviceRateSet.clear ();
434  m_deviceMcsSet.clear ();
435  m_mcsIndexMap.clear ();
436 }
437 
438 void
440 {
441  NS_LOG_FUNCTION (this);
442  m_isConstructed = true;
444  {
445  NS_LOG_DEBUG ("Frequency already initialized");
446  return;
447  }
449 }
450 
452 WifiPhy::GetState (void) const
453 {
454  return m_state;
455 }
456 
457 void
459 {
460  m_state->SetReceiveOkCallback (callback);
461 }
462 
463 void
465 {
466  m_state->SetReceiveErrorCallback (callback);
467 }
468 
469 void
471 {
472  m_state->RegisterListener (listener);
473 }
474 
475 void
477 {
478  m_state->UnregisterListener (listener);
479 }
480 
481 void
483 {
485 }
486 
487 void
489 {
490  NS_LOG_FUNCTION (this);
491 
492  NS_ASSERT_MSG (m_frequencyChannelNumberInitialized == false, "Initialization called twice");
493 
494  // If frequency has been set to a non-zero value during attribute
495  // construction phase, the frequency and channel width will drive the
496  // initial configuration. If frequency has not been set, but both
497  // standard and channel number have been set, that pair will instead
498  // drive the configuration, and frequency and channel number will be
499  // aligned
500  if (m_initialFrequency != 0)
501  {
503  }
505  {
507  }
509  {
510  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " was set by user, but neither a standard nor a frequency");
511  }
513 }
514 
515 void
516 WifiPhy::SetEdThreshold (double threshold)
517 {
518  SetRxSensitivity (threshold);
519 }
520 
521 void
522 WifiPhy::SetRxSensitivity (double threshold)
523 {
524  NS_LOG_FUNCTION (this << threshold);
525  m_rxSensitivityW = DbmToW (threshold);
526 }
527 
528 double
530 {
531  return WToDbm (m_rxSensitivityW);
532 }
533 
534 void
535 WifiPhy::SetCcaEdThreshold (double threshold)
536 {
537  NS_LOG_FUNCTION (this << threshold);
538  m_ccaEdThresholdW = DbmToW (threshold);
539 }
540 
541 double
543 {
544  return WToDbm (m_ccaEdThresholdW);
545 }
546 
547 void
548 WifiPhy::SetRxNoiseFigure (double noiseFigureDb)
549 {
550  NS_LOG_FUNCTION (this << noiseFigureDb);
551  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
553 }
554 
555 void
557 {
558  NS_LOG_FUNCTION (this << start);
560 }
561 
562 double
564 {
565  return m_txPowerBaseDbm;
566 }
567 
568 void
570 {
571  NS_LOG_FUNCTION (this << end);
572  m_txPowerEndDbm = end;
573 }
574 
575 double
577 {
578  return m_txPowerEndDbm;
579 }
580 
581 void
583 {
584  NS_LOG_FUNCTION (this << +n);
585  m_nTxPower = n;
586 }
587 
588 uint8_t
590 {
591  return m_nTxPower;
592 }
593 
594 void
595 WifiPhy::SetTxGain (double gain)
596 {
597  NS_LOG_FUNCTION (this << gain);
598  m_txGainDb = gain;
599 }
600 
601 double
602 WifiPhy::GetTxGain (void) const
603 {
604  return m_txGainDb;
605 }
606 
607 void
608 WifiPhy::SetRxGain (double gain)
609 {
610  NS_LOG_FUNCTION (this << gain);
611  m_rxGainDb = gain;
612 }
613 
614 double
615 WifiPhy::GetRxGain (void) const
616 {
617  return m_rxGainDb;
618 }
619 
620 void
621 WifiPhy::SetGreenfield (bool greenfield)
622 {
623  NS_LOG_FUNCTION (this << greenfield);
624  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
625  if (device)
626  {
627  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
628  if (htConfiguration)
629  {
630  htConfiguration->SetGreenfieldSupported (greenfield);
631  }
632  }
633  m_greenfield = greenfield;
634 }
635 
636 bool
638 {
639  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
640  if (device)
641  {
642  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
643  if (htConfiguration)
644  {
645  return htConfiguration->GetGreenfieldSupported ();
646  }
647  }
648  return m_greenfield;
649 }
650 
651 void
652 WifiPhy::SetShortGuardInterval (bool shortGuardInterval)
653 {
654  NS_LOG_FUNCTION (this << shortGuardInterval);
655  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
656  if (device)
657  {
658  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
659  if (htConfiguration)
660  {
661  htConfiguration->SetShortGuardIntervalSupported (shortGuardInterval);
662  }
663  }
664  m_shortGuardInterval = shortGuardInterval;
665 }
666 
667 bool
669 {
670  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
671  if (device)
672  {
673  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
674  if (htConfiguration)
675  {
676  return htConfiguration->GetShortGuardIntervalSupported ();
677  }
678  }
679  return m_shortGuardInterval;
680 }
681 
682 void
684 {
685  NS_LOG_FUNCTION (this << guardInterval);
686  NS_ASSERT (guardInterval == NanoSeconds (800) || guardInterval == NanoSeconds (1600) || guardInterval == NanoSeconds (3200));
687  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
688  if (device)
689  {
690  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
691  if (heConfiguration)
692  {
693  heConfiguration->SetGuardInterval (guardInterval);
694  }
695  }
696  m_guardInterval = guardInterval;
697 }
698 
699 Time
701 {
702  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
703  if (device)
704  {
705  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
706  if (heConfiguration)
707  {
708  return heConfiguration->GetGuardInterval ();
709  }
710  }
711  return m_guardInterval;
712 }
713 
714 void
716 {
717  NS_LOG_FUNCTION (this << enable);
718  m_shortPreamble = enable;
719 }
720 
721 bool
723 {
724  return m_shortPreamble;
725 }
726 
727 void
729 {
730  m_device = device;
731  //TODO: to be removed once deprecated API is cleaned up
732  Ptr<HtConfiguration> htConfiguration = DynamicCast<WifiNetDevice> (device)->GetHtConfiguration ();
733  if (htConfiguration)
734  {
735  htConfiguration->SetShortGuardIntervalSupported (m_shortGuardInterval);
736  htConfiguration->SetGreenfieldSupported (m_greenfield);
737  }
738  Ptr<HeConfiguration> heConfiguration = DynamicCast<WifiNetDevice> (device)->GetHeConfiguration ();
739  if (heConfiguration)
740  {
741  heConfiguration->SetGuardInterval (m_guardInterval);
742  }
743 }
744 
746 WifiPhy::GetDevice (void) const
747 {
748  return m_device;
749 }
750 
751 void
753 {
755 }
756 
759 {
760  if (m_mobility != 0)
761  {
762  return m_mobility;
763  }
764  else
765  {
766  return m_device->GetNode ()->GetObject<MobilityModel> ();
767  }
768 }
769 
770 void
772 {
775 }
776 
777 void
779 {
780  NS_LOG_FUNCTION (this << em);
782 }
783 
784 void
786 {
787  m_frameCaptureModel = model;
788 }
789 
790 void
792 {
793  m_preambleDetectionModel = model;
794 }
795 
796 void
798 {
799  m_wifiRadioEnergyModel = wifiRadioEnergyModel;
800 }
801 
802 double
803 WifiPhy::GetPowerDbm (uint8_t power) const
804 {
806  NS_ASSERT (m_nTxPower > 0);
807  double dbm;
808  if (m_nTxPower > 1)
809  {
810  dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / (m_nTxPower - 1);
811  }
812  else
813  {
814  NS_ASSERT_MSG (m_txPowerBaseDbm == m_txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
815  dbm = m_txPowerBaseDbm;
816  }
817  return dbm;
818 }
819 
820 Time
822 {
823  return m_channelSwitchDelay;
824 }
825 
826 double
827 WifiPhy::CalculateSnr (WifiTxVector txVector, double ber) const
828 {
829  return m_interference.GetErrorRateModel ()->CalculateSnr (txVector, ber);
830 }
831 
832 void
834 {
835  NS_LOG_FUNCTION (this << standard);
836  switch (standard)
837  {
839  SetChannelWidth (20);
840  SetFrequency (5180);
841  // Channel number should be aligned by SetFrequency () to 36
842  NS_ASSERT (GetChannelNumber () == 36);
843  break;
845  SetChannelWidth (22);
846  SetFrequency (2412);
847  // Channel number should be aligned by SetFrequency () to 1
848  NS_ASSERT (GetChannelNumber () == 1);
849  break;
851  SetChannelWidth (20);
852  SetFrequency (2412);
853  // Channel number should be aligned by SetFrequency () to 1
854  NS_ASSERT (GetChannelNumber () == 1);
855  break;
857  SetChannelWidth (10);
858  SetFrequency (5860);
859  // Channel number should be aligned by SetFrequency () to 172
860  NS_ASSERT (GetChannelNumber () == 172);
861  break;
863  SetChannelWidth (5);
864  SetFrequency (5860);
865  // Channel number should be aligned by SetFrequency () to 0
866  NS_ASSERT (GetChannelNumber () == 0);
867  break;
869  SetChannelWidth (20);
870  SetFrequency (5180);
871  // Channel number should be aligned by SetFrequency () to 36
872  NS_ASSERT (GetChannelNumber () == 36);
873  break;
875  SetChannelWidth (20);
876  SetFrequency (2412);
877  // Channel number should be aligned by SetFrequency () to 1
878  NS_ASSERT (GetChannelNumber () == 1);
879  break;
881  SetChannelWidth (20);
882  SetFrequency (5180);
883  // Channel number should be aligned by SetFrequency () to 36
884  NS_ASSERT (GetChannelNumber () == 36);
885  break;
887  SetChannelWidth (80);
888  SetFrequency (5210);
889  // Channel number should be aligned by SetFrequency () to 42
890  NS_ASSERT (GetChannelNumber () == 42);
891  break;
893  SetChannelWidth (20);
894  SetFrequency (2412);
895  // Channel number should be aligned by SetFrequency () to 1
896  NS_ASSERT (GetChannelNumber () == 1);
897  break;
899  SetChannelWidth (80);
900  SetFrequency (5210);
901  // Channel number should be aligned by SetFrequency () to 42
902  NS_ASSERT (GetChannelNumber () == 42);
903  break;
905  default:
906  NS_LOG_WARN ("Configuring unspecified standard; performing no action");
907  break;
908  }
909 }
910 
911 void
913 {
914  NS_LOG_FUNCTION (this);
915 
924 }
925 
926 void
928 {
929  NS_LOG_FUNCTION (this);
930 
935 }
936 
937 void
939 {
940  NS_LOG_FUNCTION (this);
941  Configure80211b ();
942 
951 }
952 
953 void
955 {
956  NS_LOG_FUNCTION (this);
957 
966 }
967 
968 void
970 {
971  NS_LOG_FUNCTION (this);
972 
981 }
982 
983 void
985 {
986  NS_LOG_FUNCTION (this);
987 
993 }
994 
995 void
997 {
998  NS_LOG_FUNCTION (this << mode);
999 
1000  WifiModulationClass modulation = mode.GetModulationClass ();
1001  NS_ASSERT (modulation == WIFI_MOD_CLASS_HT || modulation == WIFI_MOD_CLASS_VHT
1002  || modulation == WIFI_MOD_CLASS_HE);
1003 
1004  m_mcsIndexMap[modulation][mode.GetMcsValue ()] = m_deviceMcsSet.size ();
1005  m_deviceMcsSet.push_back (mode);
1006 }
1007 
1008 void
1010 {
1011  NS_LOG_FUNCTION (this);
1012  m_mcsIndexMap.clear ();
1013  uint8_t index = 0;
1014  for (auto& mode : m_deviceMcsSet)
1015  {
1016  m_mcsIndexMap[mode.GetModulationClass ()][mode.GetMcsValue ()] = index++;
1017  }
1018 }
1019 
1020 void
1022 {
1023  NS_LOG_FUNCTION (this);
1024 
1025  bool htFound = false;
1026  for (std::vector<uint8_t>::size_type i = 0; i < m_bssMembershipSelectorSet.size (); i++)
1027  {
1029  {
1030  htFound = true;
1031  break;
1032  }
1033  }
1034  if (htFound)
1035  {
1036  // erase all HtMcs modes from deviceMcsSet
1037  std::size_t index = m_deviceMcsSet.size () - 1;
1038  for (std::vector<WifiMode>::reverse_iterator rit = m_deviceMcsSet.rbegin (); rit != m_deviceMcsSet.rend (); ++rit, --index)
1039  {
1040  if (m_deviceMcsSet[index].GetModulationClass () == WIFI_MOD_CLASS_HT)
1041  {
1042  m_deviceMcsSet.erase (m_deviceMcsSet.begin () + index);
1043  }
1044  }
1045  RebuildMcsMap ();
1055  {
1064  }
1066  {
1075  }
1077  {
1086  }
1087  }
1088 }
1089 
1090 void
1092 {
1093  NS_LOG_FUNCTION (this);
1094  if (Is2_4Ghz (GetFrequency ()))
1095  {
1096  Configure80211b ();
1097  Configure80211g ();
1098  }
1099  if (Is5Ghz (GetFrequency ()))
1100  {
1101  Configure80211a ();
1102  }
1103  m_bssMembershipSelectorSet.push_back (HT_PHY);
1105 }
1106 
1107 void
1109 {
1110  NS_LOG_FUNCTION (this);
1111  Configure80211n ();
1112 
1123 
1124  m_bssMembershipSelectorSet.push_back (VHT_PHY);
1125 }
1126 
1127 void
1129 {
1130  NS_LOG_FUNCTION (this);
1131  if (Is5Ghz (GetFrequency ()))
1132  {
1133  Configure80211ac ();
1134  }
1135  else
1136  {
1137  Configure80211n ();
1138  }
1139 
1152 
1153  m_bssMembershipSelectorSet.push_back (HE_PHY);
1154 }
1155 
1156 bool
1157 WifiPhy::DefineChannelNumber (uint8_t channelNumber, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
1158 {
1159  NS_LOG_FUNCTION (this << +channelNumber << standard << frequency << channelWidth);
1160  ChannelNumberStandardPair p = std::make_pair (channelNumber, standard);
1161  ChannelToFrequencyWidthMap::const_iterator it;
1162  it = m_channelToFrequencyWidth.find (p);
1163  if (it != m_channelToFrequencyWidth.end ())
1164  {
1165  NS_LOG_DEBUG ("channel number/standard already defined; returning false");
1166  return false;
1167  }
1168  FrequencyWidthPair f = std::make_pair (frequency, channelWidth);
1170  return true;
1171 }
1172 
1173 uint8_t
1174 WifiPhy::FindChannelNumberForFrequencyWidth (uint16_t frequency, uint16_t width) const
1175 {
1176  NS_LOG_FUNCTION (this << frequency << width);
1177  bool found = false;
1178  FrequencyWidthPair f = std::make_pair (frequency, width);
1179  ChannelToFrequencyWidthMap::const_iterator it = m_channelToFrequencyWidth.begin ();
1180  while (it != m_channelToFrequencyWidth.end ())
1181  {
1182  if (it->second == f)
1183  {
1184  found = true;
1185  break;
1186  }
1187  ++it;
1188  }
1189  if (found)
1190  {
1191  NS_LOG_DEBUG ("Found, returning " << +it->first.first);
1192  return (it->first.first);
1193  }
1194  else
1195  {
1196  NS_LOG_DEBUG ("Not found, returning 0");
1197  return 0;
1198  }
1199 }
1200 
1201 void
1203 {
1204  NS_LOG_FUNCTION (this << standard);
1205  // If the user has configured both Frequency and ChannelNumber, Frequency
1206  // takes precedence
1207  if (GetFrequency () != 0)
1208  {
1209  // If Frequency is already set, then see whether a ChannelNumber can
1210  // be found that matches Frequency and ChannelWidth. If so, configure
1211  // the ChannelNumber to that channel number. If not, set ChannelNumber to zero.
1212  NS_LOG_DEBUG ("Frequency set; checking whether a channel number corresponds");
1213  uint8_t channelNumberSearched = FindChannelNumberForFrequencyWidth (GetFrequency (), GetChannelWidth ());
1214  if (channelNumberSearched)
1215  {
1216  NS_LOG_DEBUG ("Channel number found; setting to " << +channelNumberSearched);
1217  SetChannelNumber (channelNumberSearched);
1218  }
1219  else
1220  {
1221  NS_LOG_DEBUG ("Channel number not found; setting to zero");
1222  SetChannelNumber (0);
1223  }
1224  }
1225  else if (GetChannelNumber () != 0)
1226  {
1227  // If the channel number is known for this particular standard or for
1228  // the unspecified standard, configure using the known values;
1229  // otherwise, this is a configuration error
1230  NS_LOG_DEBUG ("Configuring for channel number " << +GetChannelNumber ());
1232  if (f.first == 0)
1233  {
1234  // the specific pair of number/standard is not known
1235  NS_LOG_DEBUG ("Falling back to check WIFI_PHY_STANDARD_UNSPECIFIED");
1237  }
1238  if (f.first == 0)
1239  {
1240  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " is unknown for this standard");
1241  }
1242  else
1243  {
1244  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1245  SetFrequency (f.first);
1246  SetChannelWidth (f.second);
1247  }
1248  }
1249 }
1250 
1251 void
1253 {
1254  NS_LOG_FUNCTION (this << standard);
1255  m_standard = standard;
1256  m_isConstructed = true;
1258  {
1260  }
1261  if (GetFrequency () == 0 && GetChannelNumber () == 0)
1262  {
1263  ConfigureDefaultsForStandard (standard);
1264  }
1265  else
1266  {
1267  // The user has configured either (or both) Frequency or ChannelNumber
1268  ConfigureChannelForStandard (standard);
1269  }
1270  switch (standard)
1271  {
1273  Configure80211a ();
1274  break;
1276  Configure80211b ();
1277  break;
1279  Configure80211g ();
1280  break;
1283  break;
1286  break;
1288  ConfigureHolland ();
1289  break;
1292  Configure80211n ();
1293  break;
1295  Configure80211ac ();
1296  break;
1299  Configure80211ax ();
1300  break;
1302  default:
1303  NS_ASSERT (false);
1304  break;
1305  }
1306 }
1307 
1310 {
1311  return m_standard;
1312 }
1313 
1314 void
1315 WifiPhy::SetFrequency (uint16_t frequency)
1316 {
1317  NS_LOG_FUNCTION (this << frequency);
1318  if (m_isConstructed == false)
1319  {
1320  NS_LOG_DEBUG ("Saving frequency configuration for initialization");
1321  m_initialFrequency = frequency;
1322  return;
1323  }
1324  if (GetFrequency () == frequency)
1325  {
1326  NS_LOG_DEBUG ("No frequency change requested");
1327  return;
1328  }
1329  if (frequency == 0)
1330  {
1331  DoFrequencySwitch (0);
1332  NS_LOG_DEBUG ("Setting frequency and channel number to zero");
1334  m_channelNumber = 0;
1335  return;
1336  }
1337  // If the user has configured both Frequency and ChannelNumber, Frequency
1338  // takes precedence. Lookup the channel number corresponding to the
1339  // requested frequency.
1340  uint8_t nch = FindChannelNumberForFrequencyWidth (frequency, GetChannelWidth ());
1341  if (nch != 0)
1342  {
1343  NS_LOG_DEBUG ("Setting frequency " << frequency << " corresponds to channel " << +nch);
1344  if (DoFrequencySwitch (frequency))
1345  {
1346  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << +nch);
1347  m_channelCenterFrequency = frequency;
1348  m_channelNumber = nch;
1349  }
1350  else
1351  {
1352  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1353  }
1354  }
1355  else
1356  {
1357  NS_LOG_DEBUG ("Channel number is unknown for frequency " << frequency);
1358  if (DoFrequencySwitch (frequency))
1359  {
1360  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << 0);
1361  m_channelCenterFrequency = frequency;
1362  m_channelNumber = 0;
1363  }
1364  else
1365  {
1366  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1367  }
1368  }
1369 }
1370 
1371 uint16_t
1373 {
1374  return m_channelCenterFrequency;
1375 }
1376 
1377 void
1378 WifiPhy::SetChannelWidth (uint16_t channelWidth)
1379 {
1380  NS_LOG_FUNCTION (this << channelWidth);
1381  NS_ASSERT_MSG (channelWidth == 5 || channelWidth == 10 || channelWidth == 20 || channelWidth == 22 || channelWidth == 40 || channelWidth == 80 || channelWidth == 160, "wrong channel width value");
1382  bool changed = (m_channelWidth != channelWidth);
1383  m_channelWidth = channelWidth;
1384  AddSupportedChannelWidth (channelWidth);
1385  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1386  {
1388  }
1389 }
1390 
1391 uint16_t
1393 {
1394  return m_channelWidth;
1395 }
1396 
1397 void
1399 {
1400  NS_ASSERT_MSG (antennas > 0 && antennas <= 4, "unsupported number of antennas");
1401  m_numberOfAntennas = antennas;
1403 }
1404 
1405 uint8_t
1407 {
1408  return m_numberOfAntennas;
1409 }
1410 
1411 void
1413 {
1414  NS_ASSERT (streams <= GetNumberOfAntennas ());
1415  bool changed = (m_txSpatialStreams != streams);
1416  m_txSpatialStreams = streams;
1418  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1419  {
1421  }
1422 }
1423 
1424 uint8_t
1426 {
1427  return m_txSpatialStreams;
1428 }
1429 
1430 void
1432 {
1433  NS_ASSERT (streams <= GetNumberOfAntennas ());
1434  bool changed = (m_rxSpatialStreams != streams);
1435  m_rxSpatialStreams = streams;
1436  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1437  {
1439  }
1440 }
1441 
1442 uint8_t
1444 {
1445  return m_rxSpatialStreams;
1446 }
1447 
1448 uint8_t
1450 {
1451  return static_cast<uint8_t> (m_bssMembershipSelectorSet.size ());
1452 }
1453 
1454 uint8_t
1455 WifiPhy::GetBssMembershipSelector (uint8_t selector) const
1456 {
1457  return m_bssMembershipSelectorSet[selector];
1458 }
1459 
1460 void
1462 {
1463  NS_LOG_FUNCTION (this << width);
1464  for (std::vector<uint32_t>::size_type i = 0; i != m_supportedChannelWidthSet.size (); i++)
1465  {
1466  if (m_supportedChannelWidthSet[i] == width)
1467  {
1468  return;
1469  }
1470  }
1471  NS_LOG_FUNCTION ("Adding " << width << " to supported channel width set");
1472  m_supportedChannelWidthSet.push_back (width);
1473 }
1474 
1475 std::vector<uint16_t>
1477 {
1479 }
1480 
1483 {
1484  ChannelNumberStandardPair p = std::make_pair (channelNumber, standard);
1486  return f;
1487 }
1488 
1489 void
1491 {
1492  NS_LOG_FUNCTION (this << +nch);
1493  if (m_isConstructed == false)
1494  {
1495  NS_LOG_DEBUG ("Saving channel number configuration for initialization");
1496  m_initialChannelNumber = nch;
1497  return;
1498  }
1499  if (GetChannelNumber () == nch)
1500  {
1501  NS_LOG_DEBUG ("No channel change requested");
1502  return;
1503  }
1504  if (nch == 0)
1505  {
1506  // This case corresponds to when there is not a known channel
1507  // number for the requested frequency. There is no need to call
1508  // DoChannelSwitch () because DoFrequencySwitch () should have been
1509  // called by the client
1510  NS_LOG_DEBUG ("Setting channel number to zero");
1511  m_channelNumber = 0;
1512  return;
1513  }
1514 
1515  // First make sure that the channel number is defined for the standard
1516  // in use
1518  if (f.first == 0)
1519  {
1521  }
1522  if (f.first != 0)
1523  {
1524  if (DoChannelSwitch (nch))
1525  {
1526  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1527  m_channelCenterFrequency = f.first;
1528  SetChannelWidth (f.second);
1529  m_channelNumber = nch;
1530  }
1531  else
1532  {
1533  // Subclass may have suppressed (e.g. waiting for state change)
1534  NS_LOG_DEBUG ("Channel switch suppressed");
1535  }
1536  }
1537  else
1538  {
1539  NS_FATAL_ERROR ("Frequency not found for channel number " << +nch);
1540  }
1541 }
1542 
1543 uint8_t
1545 {
1546  return m_channelNumber;
1547 }
1548 
1549 bool
1551 {
1552  m_powerRestricted = false;
1553  m_channelAccessRequested = false;
1554  if (!IsInitialized ())
1555  {
1556  //this is not channel switch, this is initialization
1557  NS_LOG_DEBUG ("initialize to channel " << +nch);
1558  return true;
1559  }
1560 
1562  switch (m_state->GetState ())
1563  {
1564  case WifiPhyState::RX:
1565  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
1567  m_endRxEvent.Cancel ();
1569  goto switchChannel;
1570  break;
1571  case WifiPhyState::TX:
1572  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
1574  break;
1576  case WifiPhyState::IDLE:
1578  {
1580  m_endRxEvent.Cancel ();
1581  }
1582  goto switchChannel;
1583  break;
1584  case WifiPhyState::SLEEP:
1585  NS_LOG_DEBUG ("channel switching ignored in sleep mode");
1586  break;
1587  default:
1588  NS_ASSERT (false);
1589  break;
1590  }
1591 
1592  return false;
1593 
1594 switchChannel:
1595 
1596  NS_LOG_DEBUG ("switching channel " << +GetChannelNumber () << " -> " << +nch);
1597  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1599  /*
1600  * Needed here to be able to correctly sensed the medium for the first
1601  * time after the switching. The actual switching is not performed until
1602  * after m_channelSwitchDelay. Packets received during the switching
1603  * state are added to the event list and are employed later to figure
1604  * out the state of the medium after the switching.
1605  */
1606  return true;
1607 }
1608 
1609 bool
1610 WifiPhy::DoFrequencySwitch (uint16_t frequency)
1611 {
1612  m_powerRestricted = false;
1613  m_channelAccessRequested = false;
1614  if (!IsInitialized ())
1615  {
1616  //this is not channel switch, this is initialization
1617  NS_LOG_DEBUG ("start at frequency " << frequency);
1618  return true;
1619  }
1620 
1622  switch (m_state->GetState ())
1623  {
1624  case WifiPhyState::RX:
1625  NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
1627  m_endRxEvent.Cancel ();
1629  goto switchFrequency;
1630  break;
1631  case WifiPhyState::TX:
1632  NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
1634  break;
1636  case WifiPhyState::IDLE:
1638  {
1640  m_endRxEvent.Cancel ();
1641  }
1642  goto switchFrequency;
1643  break;
1644  case WifiPhyState::SLEEP:
1645  NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
1646  break;
1647  default:
1648  NS_ASSERT (false);
1649  break;
1650  }
1651 
1652  return false;
1653 
1654 switchFrequency:
1655 
1656  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
1657  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1659  /*
1660  * Needed here to be able to correctly sensed the medium for the first
1661  * time after the switching. The actual switching is not performed until
1662  * after m_channelSwitchDelay. Packets received during the switching
1663  * state are added to the event list and are employed later to figure
1664  * out the state of the medium after the switching.
1665  */
1666  return true;
1667 }
1668 
1669 void
1671 {
1672  NS_LOG_FUNCTION (this);
1673  m_powerRestricted = false;
1674  m_channelAccessRequested = false;
1675  switch (m_state->GetState ())
1676  {
1677  case WifiPhyState::TX:
1678  NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
1680  break;
1681  case WifiPhyState::RX:
1682  NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
1684  break;
1686  NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
1688  break;
1690  case WifiPhyState::IDLE:
1691  NS_LOG_DEBUG ("setting sleep mode");
1692  m_state->SwitchToSleep ();
1693  break;
1694  case WifiPhyState::SLEEP:
1695  NS_LOG_DEBUG ("already in sleep mode");
1696  break;
1697  default:
1698  NS_ASSERT (false);
1699  break;
1700  }
1701 }
1702 
1703 void
1705 {
1706  NS_LOG_FUNCTION (this);
1707  m_powerRestricted = false;
1708  m_channelAccessRequested = false;
1710  m_endRxEvent.Cancel ();
1712  m_endTxEvent.Cancel ();
1713  m_state->SwitchToOff ();
1714 }
1715 
1716 void
1718 {
1719  NS_LOG_FUNCTION (this);
1720  switch (m_state->GetState ())
1721  {
1722  case WifiPhyState::TX:
1723  case WifiPhyState::RX:
1724  case WifiPhyState::IDLE:
1727  {
1728  NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
1729  break;
1730  }
1731  case WifiPhyState::SLEEP:
1732  {
1733  NS_LOG_DEBUG ("resuming from sleep mode");
1735  m_state->SwitchFromSleep (delayUntilCcaEnd);
1736  break;
1737  }
1738  default:
1739  {
1740  NS_ASSERT (false);
1741  break;
1742  }
1743  }
1744 }
1745 
1746 void
1748 {
1749  NS_LOG_FUNCTION (this);
1750  switch (m_state->GetState ())
1751  {
1752  case WifiPhyState::TX:
1753  case WifiPhyState::RX:
1754  case WifiPhyState::IDLE:
1757  case WifiPhyState::SLEEP:
1758  {
1759  NS_LOG_DEBUG ("not in off mode, there is nothing to resume");
1760  break;
1761  }
1762  case WifiPhyState::OFF:
1763  {
1764  NS_LOG_DEBUG ("resuming from off mode");
1766  m_state->SwitchFromOff (delayUntilCcaEnd);
1767  break;
1768  }
1769  default:
1770  {
1771  NS_ASSERT (false);
1772  break;
1773  }
1774  }
1775 }
1776 
1777 WifiMode
1779 {
1780  return WifiPhy::GetHtMcs0 ();
1781 }
1782 
1783 WifiMode
1785 {
1786  return WifiPhy::GetVhtMcs0 ();
1787 }
1788 
1789 WifiMode
1791 {
1792  return WifiPhy::GetHeMcs0 ();
1793 }
1794 
1795 Time
1797 {
1798  return MicroSeconds (4);
1799 }
1800 
1801 Time
1803 {
1804  uint8_t Ndltf, Neltf;
1805  //We suppose here that STBC = 0.
1806  //If STBC > 0, we need a different mapping between Nss and Nltf (IEEE 802.11n-2012 standard, page 1682).
1807  if (txVector.GetNss () < 3)
1808  {
1809  Ndltf = txVector.GetNss ();
1810  }
1811  else if (txVector.GetNss () < 5)
1812  {
1813  Ndltf = 4;
1814  }
1815  else if (txVector.GetNss () < 7)
1816  {
1817  Ndltf = 6;
1818  }
1819  else
1820  {
1821  Ndltf = 8;
1822  }
1823 
1824  if (txVector.GetNess () < 3)
1825  {
1826  Neltf = txVector.GetNess ();
1827  }
1828  else
1829  {
1830  Neltf = 4;
1831  }
1832 
1833  switch (txVector.GetPreambleType ())
1834  {
1835  case WIFI_PREAMBLE_HT_MF:
1836  return MicroSeconds (4 + (4 * Ndltf) + (4 * Neltf));
1837  case WIFI_PREAMBLE_HT_GF:
1838  return MicroSeconds ((4 * Ndltf) + (4 * Neltf));
1839  case WIFI_PREAMBLE_VHT_SU:
1840  case WIFI_PREAMBLE_VHT_MU:
1841  return MicroSeconds (4 + (4 * Ndltf));
1842  case WIFI_PREAMBLE_HE_SU:
1843  case WIFI_PREAMBLE_HE_MU:
1844  return MicroSeconds (4 + (8 * Ndltf));
1845  default:
1846  return MicroSeconds (0);
1847  }
1848 }
1849 
1850 Time
1852 {
1853  switch (preamble)
1854  {
1855  case WIFI_PREAMBLE_HT_MF:
1856  case WIFI_PREAMBLE_HT_GF:
1857  //HT-SIG
1858  return MicroSeconds (8);
1859  default:
1860  //no HT-SIG for non HT
1861  return MicroSeconds (0);
1862  }
1863 }
1864 
1865 Time
1867 {
1868  switch (preamble)
1869  {
1870  case WIFI_PREAMBLE_VHT_SU:
1871  case WIFI_PREAMBLE_HE_SU:
1872  case WIFI_PREAMBLE_VHT_MU:
1873  case WIFI_PREAMBLE_HE_MU:
1874  //VHT-SIG-A1 and HE-SIG-A1
1875  return MicroSeconds (4);
1876  default:
1877  // no SIG-A1
1878  return MicroSeconds (0);
1879  }
1880 }
1881 
1882 Time
1884 {
1885  switch (preamble)
1886  {
1887  case WIFI_PREAMBLE_VHT_SU:
1888  case WIFI_PREAMBLE_HE_SU:
1889  case WIFI_PREAMBLE_VHT_MU:
1890  case WIFI_PREAMBLE_HE_MU:
1891  //VHT-SIG-A2 and HE-SIG-A2
1892  return MicroSeconds (4);
1893  default:
1894  // no SIG-A2
1895  return MicroSeconds (0);
1896  }
1897 }
1898 
1899 Time
1901 {
1902  switch (preamble)
1903  {
1904  case WIFI_PREAMBLE_VHT_MU:
1905  case WIFI_PREAMBLE_HE_MU:
1906  return MicroSeconds (4);
1907  default:
1908  // no SIG-B
1909  return MicroSeconds (0);
1910  }
1911 }
1912 
1913 WifiMode
1915 {
1916  WifiPreamble preamble = txVector.GetPreambleType ();
1917  switch (preamble)
1918  {
1919  case WIFI_PREAMBLE_LONG:
1920  case WIFI_PREAMBLE_SHORT:
1921  {
1922  switch (txVector.GetMode ().GetModulationClass ())
1923  {
1924  case WIFI_MOD_CLASS_OFDM:
1925  {
1926  switch (txVector.GetChannelWidth ())
1927  {
1928  case 5:
1930  case 10:
1932  case 20:
1933  default:
1934  //(Section 17.3.2 "PPDU frame format"; IEEE Std 802.11-2016)
1935  //actually this is only the first part of the PhyHeader,
1936  //because the last 16 bits of the PhyHeader are using the
1937  //same mode of the payload
1938  return WifiPhy::GetOfdmRate6Mbps ();
1939  }
1940  }
1942  return WifiPhy::GetErpOfdmRate6Mbps ();
1943  case WIFI_MOD_CLASS_DSSS:
1945  {
1946  if (preamble == WIFI_PREAMBLE_LONG || txVector.GetMode () == WifiPhy::GetDsssRate1Mbps ())
1947  {
1948  //(Section 16.2.3 "PPDU field definitions" and Section 16.2.2.2 "Long PPDU format"; IEEE Std 802.11-2016)
1949  return WifiPhy::GetDsssRate1Mbps ();
1950  }
1951  else
1952  {
1953  //(Section 16.2.2.3 "Short PPDU format"; IEEE Std 802.11-2016)
1954  return WifiPhy::GetDsssRate2Mbps ();
1955  }
1956  }
1957  default:
1958  NS_FATAL_ERROR ("unsupported modulation class");
1959  return WifiMode ();
1960  }
1961  }
1962  case WIFI_PREAMBLE_HT_MF:
1963  case WIFI_PREAMBLE_HT_GF:
1964  case WIFI_PREAMBLE_VHT_SU:
1965  case WIFI_PREAMBLE_VHT_MU:
1966  case WIFI_PREAMBLE_HE_SU:
1968  case WIFI_PREAMBLE_HE_MU:
1969  case WIFI_PREAMBLE_HE_TB:
1970  return WifiPhy::GetOfdmRate6Mbps ();
1971  default:
1972  NS_FATAL_ERROR ("unsupported preamble type");
1973  return WifiMode ();
1974  }
1975 }
1976 
1977 Time
1979 {
1980  WifiPreamble preamble = txVector.GetPreambleType ();
1981  switch (txVector.GetPreambleType ())
1982  {
1983  case WIFI_PREAMBLE_LONG:
1984  case WIFI_PREAMBLE_SHORT:
1985  {
1986  switch (txVector.GetMode ().GetModulationClass ())
1987  {
1988  case WIFI_MOD_CLASS_OFDM:
1989  {
1990  switch (txVector.GetChannelWidth ())
1991  {
1992  case 20:
1993  default:
1994  //(Section 17.3.3 "PHY preamble (SYNC))" and Figure 17-4 "OFDM training structure"; IEEE Std 802.11-2016)
1995  //also (Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
1996  //We return the duration of the SIGNAL field only, since the
1997  //SERVICE field (which strictly speaking belongs to the PHY
1998  //header, see Section 17.3.2 and Figure 17-1) is sent using the
1999  //payload mode.
2000  return MicroSeconds (4);
2001  case 10:
2002  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2003  return MicroSeconds (8);
2004  case 5:
2005  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std 802.11-2016)
2006  return MicroSeconds (16);
2007  }
2008  }
2010  return MicroSeconds (4);
2011  case WIFI_MOD_CLASS_DSSS:
2013  {
2014  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2015  {
2016  //(Section 16.2.2.3 "Short PPDU format" and Figure 16-2 "Short PPDU format"; IEEE Std 802.11-2016)
2017  return MicroSeconds (24);
2018  }
2019  else
2020  {
2021  //(Section 16.2.2.2 "Long PPDU format" and Figure 16-1 "Short PPDU format"; IEEE Std 802.11-2016)
2022  return MicroSeconds (48);
2023  }
2024  }
2025  default:
2026  NS_FATAL_ERROR ("modulation class is not matching the preamble type");
2027  return MicroSeconds (0);
2028  }
2029  }
2030  case WIFI_PREAMBLE_HT_MF:
2031  case WIFI_PREAMBLE_VHT_SU:
2032  case WIFI_PREAMBLE_VHT_MU:
2033  //L-SIG
2034  return MicroSeconds (4);
2035  case WIFI_PREAMBLE_HE_SU:
2037  case WIFI_PREAMBLE_HE_MU:
2038  case WIFI_PREAMBLE_HE_TB:
2039  //LSIG + R-LSIG
2040  return MicroSeconds (8);
2041  case WIFI_PREAMBLE_HT_GF:
2042  return MicroSeconds (0);
2043  default:
2044  NS_FATAL_ERROR ("unsupported preamble type");
2045  return MicroSeconds (0);
2046  }
2047 }
2048 
2049 Time
2051 {
2052  return MicroSeconds (4);
2053 }
2054 
2055 Time
2057 {
2058  WifiPreamble preamble = txVector.GetPreambleType ();
2059  switch (txVector.GetPreambleType ())
2060  {
2061  case WIFI_PREAMBLE_LONG:
2062  case WIFI_PREAMBLE_SHORT:
2063  {
2064  switch (txVector.GetMode ().GetModulationClass ())
2065  {
2066  case WIFI_MOD_CLASS_OFDM:
2067  {
2068  switch (txVector.GetChannelWidth ())
2069  {
2070  case 20:
2071  default:
2072  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2073  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2074  return MicroSeconds (16);
2075  case 10:
2076  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2077  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2078  return MicroSeconds (32);
2079  case 5:
2080  //(Section 17.3.3 "PHY preamble (SYNC))" Figure 17-4 "OFDM training structure"
2081  //also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent parameters"; IEEE Std 802.11-2016)
2082  return MicroSeconds (64);
2083  }
2084  }
2086  return MicroSeconds (16);
2087  case WIFI_MOD_CLASS_DSSS:
2089  {
2090  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2091  {
2092  //(Section 17.2.2.3 "Short PPDU format)" Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
2093  return MicroSeconds (72);
2094  }
2095  else
2096  {
2097  //(Section 17.2.2.2 "Long PPDU format)" Figure 17-1 "Long PPDU format"; IEEE Std 802.11-2012)
2098  return MicroSeconds (144);
2099  }
2100  }
2101  default:
2102  NS_FATAL_ERROR ("modulation class is not matching the preamble type");
2103  return MicroSeconds (0);
2104  }
2105  }
2106  case WIFI_PREAMBLE_HT_MF:
2107  case WIFI_PREAMBLE_VHT_SU:
2108  case WIFI_PREAMBLE_VHT_MU:
2109  case WIFI_PREAMBLE_HE_SU:
2111  case WIFI_PREAMBLE_HE_MU:
2112  case WIFI_PREAMBLE_HE_TB:
2113  //L-STF + L-LTF
2114  return MicroSeconds (16);
2115  case WIFI_PREAMBLE_HT_GF:
2116  //HT-GF-STF + HT-LTF1
2117  return MicroSeconds (16);
2118  default:
2119  NS_FATAL_ERROR ("unsupported preamble type");
2120  return MicroSeconds (0);
2121  }
2122 }
2123 
2124 Time
2125 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency, MpduType mpdutype)
2126 {
2127  uint32_t totalAmpduSize;
2128  double totalAmpduNumSymbols;
2129  return GetPayloadDuration (size, txVector, frequency, mpdutype, false, totalAmpduSize, totalAmpduNumSymbols);
2130 }
2131 
2132 Time
2133 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency, MpduType mpdutype,
2134  bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols)
2135 {
2136  WifiMode payloadMode = txVector.GetMode ();
2137  NS_LOG_FUNCTION (size << payloadMode);
2138 
2139  double stbc = 1;
2140  if (txVector.IsStbc ()
2141  && (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT
2142  || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
2143  {
2144  stbc = 2;
2145  }
2146 
2147  double Nes = 1;
2148  //todo: improve logic to reduce the number of if cases
2149  //todo: extend to NSS > 4 for VHT rates
2150  if (payloadMode == GetHtMcs21 ()
2151  || payloadMode == GetHtMcs22 ()
2152  || payloadMode == GetHtMcs23 ()
2153  || payloadMode == GetHtMcs28 ()
2154  || payloadMode == GetHtMcs29 ()
2155  || payloadMode == GetHtMcs30 ()
2156  || payloadMode == GetHtMcs31 ())
2157  {
2158  Nes = 2;
2159  }
2160  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
2161  {
2162  if (txVector.GetChannelWidth () == 40
2163  && txVector.GetNss () == 3
2164  && payloadMode.GetMcsValue () >= 8)
2165  {
2166  Nes = 2;
2167  }
2168  if (txVector.GetChannelWidth () == 80
2169  && txVector.GetNss () == 2
2170  && payloadMode.GetMcsValue () >= 7)
2171  {
2172  Nes = 2;
2173  }
2174  if (txVector.GetChannelWidth () == 80
2175  && txVector.GetNss () == 3
2176  && payloadMode.GetMcsValue () >= 7)
2177  {
2178  Nes = 2;
2179  }
2180  if (txVector.GetChannelWidth () == 80
2181  && txVector.GetNss () == 3
2182  && payloadMode.GetMcsValue () == 9)
2183  {
2184  Nes = 3;
2185  }
2186  if (txVector.GetChannelWidth () == 80
2187  && txVector.GetNss () == 4
2188  && payloadMode.GetMcsValue () >= 4)
2189  {
2190  Nes = 2;
2191  }
2192  if (txVector.GetChannelWidth () == 80
2193  && txVector.GetNss () == 4
2194  && payloadMode.GetMcsValue () >= 7)
2195  {
2196  Nes = 3;
2197  }
2198  if (txVector.GetChannelWidth () == 160
2199  && payloadMode.GetMcsValue () >= 7)
2200  {
2201  Nes = 2;
2202  }
2203  if (txVector.GetChannelWidth () == 160
2204  && txVector.GetNss () == 2
2205  && payloadMode.GetMcsValue () >= 4)
2206  {
2207  Nes = 2;
2208  }
2209  if (txVector.GetChannelWidth () == 160
2210  && txVector.GetNss () == 2
2211  && payloadMode.GetMcsValue () >= 7)
2212  {
2213  Nes = 3;
2214  }
2215  if (txVector.GetChannelWidth () == 160
2216  && txVector.GetNss () == 3
2217  && payloadMode.GetMcsValue () >= 3)
2218  {
2219  Nes = 2;
2220  }
2221  if (txVector.GetChannelWidth () == 160
2222  && txVector.GetNss () == 3
2223  && payloadMode.GetMcsValue () >= 5)
2224  {
2225  Nes = 3;
2226  }
2227  if (txVector.GetChannelWidth () == 160
2228  && txVector.GetNss () == 3
2229  && payloadMode.GetMcsValue () >= 7)
2230  {
2231  Nes = 4;
2232  }
2233  if (txVector.GetChannelWidth () == 160
2234  && txVector.GetNss () == 4
2235  && payloadMode.GetMcsValue () >= 2)
2236  {
2237  Nes = 2;
2238  }
2239  if (txVector.GetChannelWidth () == 160
2240  && txVector.GetNss () == 4
2241  && payloadMode.GetMcsValue () >= 4)
2242  {
2243  Nes = 3;
2244  }
2245  if (txVector.GetChannelWidth () == 160
2246  && txVector.GetNss () == 4
2247  && payloadMode.GetMcsValue () >= 5)
2248  {
2249  Nes = 4;
2250  }
2251  if (txVector.GetChannelWidth () == 160
2252  && txVector.GetNss () == 4
2253  && payloadMode.GetMcsValue () >= 7)
2254  {
2255  Nes = 6;
2256  }
2257  }
2258 
2259  Time symbolDuration = Seconds (0);
2260  switch (payloadMode.GetModulationClass ())
2261  {
2262  case WIFI_MOD_CLASS_OFDM:
2264  {
2265  //(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012
2266  //corresponds to T_{SYM} in the table)
2267  switch (txVector.GetChannelWidth ())
2268  {
2269  case 20:
2270  default:
2271  symbolDuration = MicroSeconds (4);
2272  break;
2273  case 10:
2274  symbolDuration = MicroSeconds (8);
2275  break;
2276  case 5:
2277  symbolDuration = MicroSeconds (16);
2278  break;
2279  }
2280  break;
2281  }
2282  case WIFI_MOD_CLASS_HT:
2283  case WIFI_MOD_CLASS_VHT:
2284  {
2285  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2286  //In the future has to create a station manager that only uses these data rates if sender and receiver support GI
2287  uint16_t gi = txVector.GetGuardInterval ();
2288  NS_ASSERT (gi == 400 || gi == 800);
2289  symbolDuration = NanoSeconds (3200 + gi);
2290  }
2291  break;
2292  case WIFI_MOD_CLASS_HE:
2293  {
2294  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2295  //In the future has to create a station manager that only uses these data rates if sender and receiver support GI
2296  uint16_t gi = txVector.GetGuardInterval ();
2297  NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
2298  symbolDuration = NanoSeconds (12800 + gi);
2299  }
2300  break;
2301  default:
2302  break;
2303  }
2304 
2305  double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector) * symbolDuration.GetNanoSeconds () / 1e9;
2306 
2307  double numSymbols = 0;
2308  if (mpdutype == FIRST_MPDU_IN_AGGREGATE)
2309  {
2310  //First packet in an A-MPDU
2311  numSymbols = (stbc * (16 + size * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol));
2312  if (incFlag == 1)
2313  {
2314  totalAmpduSize += size;
2315  totalAmpduNumSymbols += numSymbols;
2316  }
2317  }
2318  else if (mpdutype == MIDDLE_MPDU_IN_AGGREGATE)
2319  {
2320  //consecutive packets in an A-MPDU
2321  numSymbols = (stbc * size * 8.0) / (stbc * numDataBitsPerSymbol);
2322  if (incFlag == 1)
2323  {
2324  totalAmpduSize += size;
2325  totalAmpduNumSymbols += numSymbols;
2326  }
2327  }
2328  else if (mpdutype == LAST_MPDU_IN_AGGREGATE)
2329  {
2330  //last packet in an A-MPDU
2331  uint32_t totalSize = totalAmpduSize + size;
2332  numSymbols = lrint (stbc * ceil ((16 + totalSize * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol)));
2333  NS_ASSERT (totalAmpduNumSymbols <= numSymbols);
2334  numSymbols -= totalAmpduNumSymbols;
2335  if (incFlag == 1)
2336  {
2337  totalAmpduSize = 0;
2338  totalAmpduNumSymbols = 0;
2339  }
2340  }
2341  else if (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU)
2342  {
2343  //Not an A-MPDU or single MPDU (i.e. the current payload contains both service and padding)
2344  //The number of OFDM symbols in the data field when BCC encoding
2345  //is used is given in equation 19-32 of the IEEE 802.11-2016 standard.
2346  numSymbols = lrint (stbc * ceil ((16 + size * 8.0 + 6.0 * Nes) / (stbc * numDataBitsPerSymbol)));
2347  }
2348  else
2349  {
2350  NS_FATAL_ERROR ("Unknown MPDU type");
2351  }
2352 
2353  switch (payloadMode.GetModulationClass ())
2354  {
2355  case WIFI_MOD_CLASS_OFDM:
2357  {
2358  //Add signal extension for ERP PHY
2359  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
2360  {
2361  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2362  }
2363  else
2364  {
2365  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2366  }
2367  }
2368  case WIFI_MOD_CLASS_HT:
2369  case WIFI_MOD_CLASS_VHT:
2370  {
2371  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT && Is2_4Ghz (frequency)
2372  && (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE)) //at 2.4 GHz
2373  {
2374  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2375  }
2376  else //at 5 GHz
2377  {
2378  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2379  }
2380  }
2381  case WIFI_MOD_CLASS_HE:
2382  {
2383  if (Is2_4Ghz (frequency)
2384  && ((mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE))) //at 2.4 GHz
2385  {
2386  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2387  }
2388  else //at 5 GHz
2389  {
2390  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2391  }
2392  }
2393  case WIFI_MOD_CLASS_DSSS:
2395  return MicroSeconds (lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate (22) / 1.0e6))));
2396  default:
2397  NS_FATAL_ERROR ("unsupported modulation class");
2398  return MicroSeconds (0);
2399  }
2400 }
2401 
2402 Time
2404 {
2405  WifiPreamble preamble = txVector.GetPreambleType ();
2406  Time duration = GetPhyPreambleDuration (txVector)
2407  + GetPhyHeaderDuration (txVector)
2408  + GetPhyHtSigHeaderDuration (preamble)
2409  + GetPhySigA1Duration (preamble)
2410  + GetPhySigA2Duration (preamble)
2411  + GetPhyTrainingSymbolDuration (txVector)
2412  + GetPhySigBDuration (preamble);
2413  return duration;
2414 }
2415 
2416 Time
2417 WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency)
2418 {
2419  Time duration = CalculatePhyPreambleAndHeaderDuration (txVector)
2420  + GetPayloadDuration (size, txVector, frequency);
2421  return duration;
2422 }
2423 
2424 void
2426 {
2427  for (auto& mpdu : *PeekPointer (psdu))
2428  {
2429  m_phyTxBeginTrace (mpdu->GetProtocolDataUnit (), txPowerW);
2430  }
2431 }
2432 
2433 void
2435 {
2436  for (auto& mpdu : *PeekPointer (psdu))
2437  {
2438  m_phyTxEndTrace (mpdu->GetProtocolDataUnit ());
2439  }
2440 }
2441 
2442 void
2444 {
2445  for (auto& mpdu : *PeekPointer (psdu))
2446  {
2447  m_phyTxDropTrace (mpdu->GetProtocolDataUnit ());
2448  }
2449 }
2450 
2451 void
2453 {
2454  for (auto& mpdu : *PeekPointer (psdu))
2455  {
2456  m_phyRxBeginTrace (mpdu->GetProtocolDataUnit ());
2457  }
2458 }
2459 
2460 void
2462 {
2463  for (auto& mpdu : *PeekPointer (psdu))
2464  {
2465  m_phyRxEndTrace (mpdu->GetProtocolDataUnit ());
2466  }
2467 }
2468 
2469 void
2471 {
2472  for (auto& mpdu : *PeekPointer (psdu))
2473  {
2474  m_phyRxDropTrace (mpdu->GetProtocolDataUnit (), reason);
2475  }
2476 }
2477 
2478 void
2479 WifiPhy::NotifyMonitorSniffRx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector,
2480  SignalNoiseDbm signalNoise, std::vector<bool> statusPerMpdu)
2481 {
2482  MpduInfo aMpdu;
2483  if (psdu->IsAggregate ())
2484  {
2485  //Expand A-MPDU
2486  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
2488  size_t nMpdus = psdu->GetNMpdus ();
2489  NS_ASSERT_MSG (statusPerMpdu.size () == nMpdus, "Should have one reception status per MPDU");
2490  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2491  for (size_t i = 0; i < nMpdus;)
2492  {
2493  if (statusPerMpdu.at (i)) //packet received without error, hand over to sniffer
2494  {
2495  m_phyMonitorSniffRxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu, signalNoise);
2496  }
2497  ++i;
2498  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2499  }
2500  }
2501  else
2502  {
2503  aMpdu.type = NORMAL_MPDU;
2504  NS_ASSERT_MSG (statusPerMpdu.size () == 1, "Should have one reception status for normal MPDU");
2505  m_phyMonitorSniffRxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu, signalNoise);
2506  }
2507 }
2508 
2509 void
2510 WifiPhy::NotifyMonitorSniffTx (Ptr<const WifiPsdu> psdu, uint16_t channelFreqMhz, WifiTxVector txVector)
2511 {
2512  MpduInfo aMpdu;
2513  if (psdu->IsAggregate ())
2514  {
2515  //Expand A-MPDU
2516  NS_ASSERT_MSG (txVector.IsAggregation (), "TxVector with aggregate flag expected here according to PSDU");
2518  size_t nMpdus = psdu->GetNMpdus ();
2519  aMpdu.type = (psdu->IsSingle ()) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2520  for (size_t i = 0; i < nMpdus;)
2521  {
2522  m_phyMonitorSniffTxTrace (psdu->GetAmpduSubframe (i), channelFreqMhz, txVector, aMpdu);
2523  ++i;
2524  aMpdu.type = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2525  }
2526  }
2527  else
2528  {
2529  aMpdu.type = NORMAL_MPDU;
2530  m_phyMonitorSniffTxTrace (psdu->GetPacket (), channelFreqMhz, txVector, aMpdu);
2531  }
2532 }
2533 
2534 void
2536 {
2537  m_phyEndOfHePreambleTrace (params);
2538 }
2539 
2540 void
2542 {
2543  NS_LOG_FUNCTION (this << *psdu << txVector);
2544  /* Transmission can happen if:
2545  * - we are syncing on a packet. It is the responsibility of the
2546  * MAC layer to avoid doing this but the PHY does nothing to
2547  * prevent it.
2548  * - we are idle
2549  */
2550  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2552 
2553  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
2554  {
2555  NS_FATAL_ERROR ("Unsupported number of spatial streams!");
2556  }
2557 
2558  if (m_state->IsStateSleep ())
2559  {
2560  NS_LOG_DEBUG ("Dropping packet because in sleep mode");
2561  NotifyTxDrop (psdu);
2562  return;
2563  }
2564 
2565  Time txDuration = CalculateTxDuration (psdu->GetSize (), txVector, GetFrequency ());
2566  NS_ASSERT (txDuration.IsStrictlyPositive ());
2567 
2568  if ((m_currentEvent != 0) && (m_currentEvent->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ())))
2569  {
2570  //that packet will be noise _after_ the transmission.
2572  }
2573 
2574  if (m_currentEvent != 0)
2575  {
2577  }
2578 
2579  if (m_powerRestricted)
2580  {
2581  NS_LOG_DEBUG ("Transmitting with power restriction");
2582  }
2583  else
2584  {
2585  NS_LOG_DEBUG ("Transmitting without power restriction");
2586  }
2587 
2588  if (m_state->GetState () == WifiPhyState::OFF)
2589  {
2590  NS_LOG_DEBUG ("Transmission canceled because device is OFF");
2591  return;
2592  }
2593 
2594  double txPowerW = DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ());
2595  NotifyTxBegin (psdu, txPowerW);
2596  m_phyTxPsduBeginTrace (psdu, txVector, txPowerW);
2597  NotifyMonitorSniffTx (psdu, GetFrequency (), txVector);
2598  m_state->SwitchToTx (txDuration, psdu->GetPacket (), GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
2599 
2600  Ptr<WifiPpdu> ppdu = Create<WifiPpdu> (psdu, txVector, txDuration, GetFrequency ());
2601 
2602  if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
2603  {
2604  ppdu->SetTruncatedTx ();
2605  }
2606 
2607  m_endTxEvent = Simulator::Schedule (txDuration, &WifiPhy::NotifyTxEnd, this, psdu);
2608 
2609  StartTx (ppdu);
2610 
2611  m_channelAccessRequested = false;
2612  m_powerRestricted = false;
2613 }
2614 
2615 void
2617 {
2618  NS_LOG_FUNCTION (this << *event);
2619  NS_ASSERT (!IsStateRx ());
2621  NS_ASSERT (m_currentEvent != 0);
2622  NS_ASSERT (event->GetStartTime () == m_currentEvent->GetStartTime ());
2623  NS_ASSERT (event->GetEndTime () == m_currentEvent->GetEndTime ());
2624 
2626  double snr = snrPer.snr;
2627  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2628 
2629  if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (event->GetRxPowerW (), snr, m_channelWidth)))
2630  {
2631  NotifyRxBegin (event->GetPsdu ());
2632 
2634  WifiTxVector txVector = event->GetTxVector ();
2635 
2636  if ((txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT) && (txVector.GetPreambleType () == WIFI_PREAMBLE_HT_GF))
2637  {
2638  //No non-HT PHY header for HT GF
2639  Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2640  m_state->SwitchMaybeToCcaBusy (remainingPreambleHeaderDuration);
2641  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2642  }
2643  else
2644  {
2645  //Schedule end of non-HT PHY header
2646  Time remainingPreambleAndNonHtHeaderDuration = GetPhyPreambleDuration (txVector) + GetPhyHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2647  m_state->SwitchMaybeToCcaBusy (remainingPreambleAndNonHtHeaderDuration);
2648  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleAndNonHtHeaderDuration, &WifiPhy::ContinueReceiveHeader, this, event);
2649  }
2650  }
2651  else
2652  {
2653  NS_LOG_DEBUG ("Drop packet because PHY preamble detection failed");
2654  NotifyRxDrop (event->GetPsdu (), PREAMBLE_DETECT_FAILURE);
2656  m_currentEvent = 0;
2657 
2658  // Like CCA-SD, CCA-ED is governed by the 4μs CCA window to flag CCA-BUSY
2659  // for any received signal greater than the CCA-ED threshold.
2660  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2661  {
2663  }
2664  }
2665 }
2666 
2667 void
2669 {
2670  NS_LOG_FUNCTION (this << *event);
2672 
2675 
2676  if (m_random->GetValue () > snrPer.per) //non-HT PHY header reception succeeded
2677  {
2678  NS_LOG_DEBUG ("Received non-HT PHY header");
2679  WifiTxVector txVector = event->GetTxVector ();
2680  Time remainingRxDuration = event->GetEndTime () - Simulator::Now ();
2681  m_state->SwitchMaybeToCcaBusy (remainingRxDuration);
2682  Time remainingPreambleHeaderDuration = CalculatePhyPreambleAndHeaderDuration (txVector) - GetPhyPreambleDuration (txVector) - GetPhyHeaderDuration (txVector);
2683  m_endPhyRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2684  }
2685  else //non-HT PHY header reception failed
2686  {
2687  NS_LOG_DEBUG ("Abort reception because non-HT PHY header reception failed");
2689  if (event->GetEndTime () > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2690  {
2692  }
2693  }
2694 }
2695 
2696 void
2698 {
2699  NS_LOG_FUNCTION (this << *ppdu << rxPowerW);
2700  WifiTxVector txVector = ppdu->GetTxVector ();
2701  Time rxDuration = ppdu->GetTxDuration ();
2702  Ptr<const WifiPsdu> psdu = ppdu->GetPsdu ();
2703  Ptr<Event> event = m_interference.Add (ppdu, txVector, rxDuration, rxPowerW);
2704  Time endRx = Simulator::Now () + rxDuration;
2705 
2706  if (m_state->GetState () == WifiPhyState::OFF)
2707  {
2708  NS_LOG_DEBUG ("Cannot start RX because device is OFF");
2709  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2710  {
2712  }
2713  return;
2714  }
2715 
2716  if (ppdu->IsTruncatedTx ())
2717  {
2718  NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off");
2719  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2720  {
2722  }
2723  return;
2724  }
2725 
2726  if (!txVector.GetModeInitialized ())
2727  {
2728  //If SetRate method was not called above when filling in txVector, this means the PHY does support the rate indicated in PHY SIG headers
2729  NS_LOG_DEBUG ("drop packet because of unsupported RX mode");
2731  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2732  {
2734  }
2735  return;
2736  }
2737 
2738  switch (m_state->GetState ())
2739  {
2741  NS_LOG_DEBUG ("drop packet because of channel switching");
2743  /*
2744  * Packets received on the upcoming channel are added to the event list
2745  * during the switching state. This way the medium can be correctly sensed
2746  * when the device listens to the channel for the first time after the
2747  * switching e.g. after channel switching, the channel may be sensed as
2748  * busy due to other devices' transmissions started before the end of
2749  * the switching.
2750  */
2751  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2752  {
2753  //that packet will be noise _after_ the completion of the channel switching.
2755  }
2756  break;
2757  case WifiPhyState::RX:
2758  NS_ASSERT (m_currentEvent != 0);
2759  if (m_frameCaptureModel != 0
2760  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2761  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2762  {
2764  NS_LOG_DEBUG ("Switch to new packet");
2765  StartRx (event, rxPowerW);
2766  }
2767  else
2768  {
2769  NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
2770  rxPowerW << "W)");
2771  NotifyRxDrop (psdu, RXING);
2772  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2773  {
2774  //that packet will be noise _after_ the reception of the currently-received packet.
2776  }
2777  }
2778  break;
2779  case WifiPhyState::TX:
2780  NS_LOG_DEBUG ("Drop packet because already in Tx (power=" <<
2781  rxPowerW << "W)");
2782  NotifyRxDrop (psdu, TXING);
2783  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2784  {
2785  //that packet will be noise _after_ the transmission of the currently-transmitted packet.
2787  }
2788  break;
2790  if (m_currentEvent != 0)
2791  {
2792  if (m_frameCaptureModel != 0
2793  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2794  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2795  {
2797  NS_LOG_DEBUG ("Switch to new packet");
2798  StartRx (event, rxPowerW);
2799  }
2800  else
2801  {
2802  NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
2803  rxPowerW << "W)");
2804  NotifyRxDrop (psdu, RXING);
2805  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2806  {
2807  //that packet will be noise _after_ the reception of the currently-received packet.
2809  }
2810  }
2811  }
2812  else
2813  {
2814  StartRx (event, rxPowerW);
2815  }
2816  break;
2817  case WifiPhyState::IDLE:
2818  StartRx (event, rxPowerW);
2819  break;
2820  case WifiPhyState::SLEEP:
2821  NS_LOG_DEBUG ("Drop packet because in sleep mode");
2822  NotifyRxDrop (psdu, SLEEPING);
2823  if (endRx > (Simulator::Now () + m_state->GetDelayUntilIdle ()))
2824  {
2825  //that packet will be noise _after_ the sleep period.
2827  }
2828  break;
2829  default:
2830  NS_FATAL_ERROR ("Invalid WifiPhy state.");
2831  break;
2832  }
2833 }
2834 
2835 void
2837 {
2838  //We are here because we have received the first bit of a packet and we are
2839  //not going to be able to synchronize on it
2840  //In this model, CCA becomes busy when the aggregation of all signals as
2841  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2842 
2844  if (!delayUntilCcaEnd.IsZero ())
2845  {
2846  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
2847  }
2848 }
2849 
2850 void
2852 {
2853  NS_LOG_FUNCTION (this << *event);
2856  WifiTxVector txVector = event->GetTxVector ();
2857  WifiMode txMode = txVector.GetMode ();
2858  bool canReceivePayload;
2859  if (txMode.GetModulationClass () >= WIFI_MOD_CLASS_HT)
2860  {
2862  snrPer = m_interference.CalculateHtPhyHeaderSnrPer (event);
2863  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2864  canReceivePayload = (m_random->GetValue () > snrPer.per);
2865  }
2866  else
2867  {
2868  //If we are here, this means non-HT PHY header was already successfully received
2869  canReceivePayload = true;
2870  }
2871  Time payloadDuration = event->GetEndTime () - event->GetStartTime () - CalculatePhyPreambleAndHeaderDuration (txVector);
2872  if (canReceivePayload) //PHY reception succeeded
2873  {
2874  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
2875  {
2876  NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
2877  NotifyRxDrop (event->GetPsdu (), UNSUPPORTED_SETTINGS);
2878  }
2879  else if ((txVector.GetChannelWidth () >= 40) && (txVector.GetChannelWidth () > GetChannelWidth ()))
2880  {
2881  NS_LOG_DEBUG ("Packet reception could not be started because not enough channel width");
2882  NotifyRxDrop (event->GetPsdu (), UNSUPPORTED_SETTINGS);
2883  }
2884  else if (!IsModeSupported (txMode) && !IsMcsSupported (txMode))
2885  {
2886  NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")");
2887  NotifyRxDrop (event->GetPsdu (), UNSUPPORTED_SETTINGS);
2888  }
2889  else
2890  {
2891  m_state->SwitchToRx (payloadDuration);
2892  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
2893  NS_LOG_DEBUG ("Receiving PSDU");
2894  m_phyRxPayloadBeginTrace (txVector, payloadDuration); //this callback (equivalent to PHY-RXSTART primitive) is triggered only if headers have been correctly decoded and that the mode within is supported
2895  if (txMode.GetModulationClass () == WIFI_MOD_CLASS_HE)
2896  {
2897  HePreambleParameters params;
2898  params.rssiW = event->GetRxPowerW ();
2899  params.bssColor = event->GetTxVector ().GetBssColor ();
2900  NotifyEndOfHePreamble (params);
2901  }
2902  return;
2903  }
2904  }
2905  else //PHY reception failed
2906  {
2907  NS_LOG_DEBUG ("Drop packet because HT PHY header reception failed");
2908  NotifyRxDrop (event->GetPsdu (), SIG_A_FAILURE);
2909  }
2910  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::ResetReceive, this, event);
2911 }
2912 
2913 void
2915 {
2916  Time psduDuration = event->GetEndTime () - event->GetStartTime ();
2917  NS_LOG_FUNCTION (this << *event << psduDuration);
2919  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
2920 
2921  double snr = m_interference.CalculateSnr (event);
2922  std::vector<bool> statusPerMpdu;
2923  SignalNoiseDbm signalNoise;
2924 
2925  Ptr<const WifiPsdu> psdu = event->GetPsdu ();
2926  Time relativeStart = NanoSeconds (0);
2927  bool receptionOkAtLeastForOneMpdu = false;
2928  std::pair<bool, SignalNoiseDbm> rxInfo;
2929  WifiTxVector txVector = event->GetTxVector ();
2930  size_t nMpdus = psdu->GetNMpdus ();
2931  if (nMpdus > 1)
2932  {
2933  //Extract all MPDUs of the A-MPDU to compute per-MPDU PER stats
2934  Time remainingAmpduDuration = psduDuration;
2935  MpduType mpdutype = FIRST_MPDU_IN_AGGREGATE;
2936  auto mpdu = psdu->begin ();
2937  uint32_t totalAmpduSize = 0;
2938  double totalAmpduNumSymbols = 0.0;
2939  for (size_t i = 0; i < nMpdus && mpdu != psdu->end (); ++mpdu)
2940  {
2941  Time mpduDuration = GetPayloadDuration (psdu->GetAmpduSubframeSize (i), txVector,
2942  GetFrequency (), mpdutype, true, totalAmpduSize, totalAmpduNumSymbols);
2943  remainingAmpduDuration -= mpduDuration;
2944  if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero ()) //no more MPDU coming
2945  {
2946  mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
2947  }
2948  rxInfo = GetReceptionStatus (Create<WifiPsdu> (*mpdu, false),
2949  event, relativeStart, mpduDuration);
2950  NS_LOG_DEBUG ("Extracted MPDU #" << i << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
2951  ", correct reception: " << rxInfo.first <<
2952  ", Signal/Noise: " << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
2953  signalNoise = rxInfo.second; //same information for all MPDUs
2954  statusPerMpdu.push_back (rxInfo.first);
2955  receptionOkAtLeastForOneMpdu |= rxInfo.first;
2956 
2957  //Prepare next iteration
2958  ++i;
2959  relativeStart += mpduDuration;
2960  mpdutype = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2961  }
2962  }
2963  else
2964  {
2965  rxInfo = GetReceptionStatus (psdu, event, relativeStart, psduDuration);
2966  signalNoise = rxInfo.second; //same information for all MPDUs
2967  statusPerMpdu.push_back (rxInfo.first);
2968  receptionOkAtLeastForOneMpdu = rxInfo.first;
2969  }
2970 
2971  NotifyRxEnd (psdu);
2972 
2973  if (receptionOkAtLeastForOneMpdu)
2974  {
2975  NotifyMonitorSniffRx (psdu, GetFrequency (), txVector, signalNoise, statusPerMpdu);
2976  m_state->SwitchFromRxEndOk (Copy (psdu), snr, txVector, statusPerMpdu);
2977  }
2978  else
2979  {
2980  m_state->SwitchFromRxEndError (Copy (psdu), snr);
2981  }
2982 
2984  m_currentEvent = 0;
2986 }
2987 
2988 std::pair<bool, SignalNoiseDbm>
2989 WifiPhy::GetReceptionStatus (Ptr<const WifiPsdu> psdu, Ptr<Event> event, Time relativeMpduStart, Time mpduDuration)
2990 {
2991  NS_LOG_FUNCTION (this << *psdu << *event << relativeMpduStart << mpduDuration);
2993  snrPer = m_interference.CalculatePayloadSnrPer (event, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
2994 
2995  NS_LOG_DEBUG ("mode=" << (event->GetTxVector ().GetMode ().GetDataRate (event->GetTxVector ())) <<
2996  ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << psdu->GetSize () <<
2997  ", relativeStart = " << relativeMpduStart.GetNanoSeconds () << "ns, duration = " << mpduDuration.GetNanoSeconds () << "ns");
2998 
2999  // There are two error checks: PER and receive error model check.
3000  // PER check models is typical for Wi-Fi and is based on signal modulation;
3001  // Receive error model is optional, if we have an error model and
3002  // it indicates that the packet is corrupt, drop the packet.
3003  SignalNoiseDbm signalNoise;
3004  signalNoise.signal = WToDbm (event->GetRxPowerW ());
3005  signalNoise.noise = WToDbm (event->GetRxPowerW () / snrPer.snr);
3006  if (m_random->GetValue () > snrPer.per &&
3007  !(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (psdu->GetPacket ()->Copy ())))
3008  {
3009  NS_LOG_DEBUG ("Reception succeeded: " << psdu);
3010  return std::make_pair (true, signalNoise);
3011  }
3012  else
3013  {
3014  NS_LOG_DEBUG ("Reception failed: " << psdu);
3015  return std::make_pair (false, signalNoise);
3016  }
3017 }
3018 
3019 void
3021 {
3022  NS_LOG_FUNCTION (this);
3024  {
3025  m_powerRestricted = false;
3026  }
3027 }
3028 
3029 void
3031 {
3032  NS_LOG_FUNCTION (this << *event);
3033  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
3034  NS_ASSERT (!IsStateRx ());
3036  m_currentEvent = 0;
3038 }
3039 
3040 void
3042 {
3043  NS_LOG_FUNCTION (this);
3044  m_channelAccessRequested = true;
3045 }
3046 
3047 // Clause 15 rates (DSSS)
3048 
3049 WifiMode
3051 {
3052  static WifiMode mode =
3053  WifiModeFactory::CreateWifiMode ("DsssRate1Mbps",
3055  true,
3057  2);
3058  return mode;
3059 }
3060 
3061 WifiMode
3063 {
3064  static WifiMode mode =
3065  WifiModeFactory::CreateWifiMode ("DsssRate2Mbps",
3067  true,
3069  4);
3070  return mode;
3071 }
3072 
3073 
3074 // Clause 18 rates (HR/DSSS)
3075 
3076 WifiMode
3078 {
3079  static WifiMode mode =
3080  WifiModeFactory::CreateWifiMode ("DsssRate5_5Mbps",
3082  true,
3084  16);
3085  return mode;
3086 }
3087 
3088 WifiMode
3090 {
3091  static WifiMode mode =
3092  WifiModeFactory::CreateWifiMode ("DsssRate11Mbps",
3094  true,
3096  256);
3097  return mode;
3098 }
3099 
3100 
3101 // Clause 19.5 rates (ERP-OFDM)
3102 
3103 WifiMode
3105 {
3106  static WifiMode mode =
3107  WifiModeFactory::CreateWifiMode ("ErpOfdmRate6Mbps",
3109  true,
3111  2);
3112  return mode;
3113 }
3114 
3115 WifiMode
3117 {
3118  static WifiMode mode =
3119  WifiModeFactory::CreateWifiMode ("ErpOfdmRate9Mbps",
3121  false,
3123  2);
3124  return mode;
3125 }
3126 
3127 WifiMode
3129 {
3130  static WifiMode mode =
3131  WifiModeFactory::CreateWifiMode ("ErpOfdmRate12Mbps",
3133  true,
3135  4);
3136  return mode;
3137 }
3138 
3139 WifiMode
3141 {
3142  static WifiMode mode =
3143  WifiModeFactory::CreateWifiMode ("ErpOfdmRate18Mbps",
3145  false,
3147  4);
3148  return mode;
3149 }
3150 
3151 WifiMode
3153 {
3154  static WifiMode mode =
3155  WifiModeFactory::CreateWifiMode ("ErpOfdmRate24Mbps",
3157  true,
3159  16);
3160  return mode;
3161 }
3162 
3163 WifiMode
3165 {
3166  static WifiMode mode =
3167  WifiModeFactory::CreateWifiMode ("ErpOfdmRate36Mbps",
3169  false,
3171  16);
3172  return mode;
3173 }
3174 
3175 WifiMode
3177 {
3178  static WifiMode mode =
3179  WifiModeFactory::CreateWifiMode ("ErpOfdmRate48Mbps",
3181  false,
3183  64);
3184  return mode;
3185 }
3186 
3187 WifiMode
3189 {
3190  static WifiMode mode =
3191  WifiModeFactory::CreateWifiMode ("ErpOfdmRate54Mbps",
3193  false,
3195  64);
3196  return mode;
3197 }
3198 
3199 
3200 // Clause 17 rates (OFDM)
3201 
3202 WifiMode
3204 {
3205  static WifiMode mode =
3206  WifiModeFactory::CreateWifiMode ("OfdmRate6Mbps",
3208  true,
3210  2);
3211  return mode;
3212 }
3213 
3214 WifiMode
3216 {
3217  static WifiMode mode =
3218  WifiModeFactory::CreateWifiMode ("OfdmRate9Mbps",
3220  false,
3222  2);
3223  return mode;
3224 }
3225 
3226 WifiMode
3228 {
3229  static WifiMode mode =
3230  WifiModeFactory::CreateWifiMode ("OfdmRate12Mbps",
3232  true,
3234  4);
3235  return mode;
3236 }
3237 
3238 WifiMode
3240 {
3241  static WifiMode mode =
3242  WifiModeFactory::CreateWifiMode ("OfdmRate18Mbps",
3244  false,
3246  4);
3247  return mode;
3248 }
3249 
3250 WifiMode
3252 {
3253  static WifiMode mode =
3254  WifiModeFactory::CreateWifiMode ("OfdmRate24Mbps",
3256  true,
3258  16);
3259  return mode;
3260 }
3261 
3262 WifiMode
3264 {
3265  static WifiMode mode =
3266  WifiModeFactory::CreateWifiMode ("OfdmRate36Mbps",
3268  false,
3270  16);
3271  return mode;
3272 }
3273 
3274 WifiMode
3276 {
3277  static WifiMode mode =
3278  WifiModeFactory::CreateWifiMode ("OfdmRate48Mbps",
3280  false,
3282  64);
3283  return mode;
3284 }
3285 
3286 WifiMode
3288 {
3289  static WifiMode mode =
3290  WifiModeFactory::CreateWifiMode ("OfdmRate54Mbps",
3292  false,
3294  64);
3295  return mode;
3296 }
3297 
3298 
3299 // 10 MHz channel rates
3300 
3301 WifiMode
3303 {
3304  static WifiMode mode =
3305  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW10MHz",
3307  true,
3309  2);
3310  return mode;
3311 }
3312 
3313 WifiMode
3315 {
3316  static WifiMode mode =
3317  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW10MHz",
3319  false,
3321  2);
3322  return mode;
3323 }
3324 
3325 WifiMode
3327 {
3328  static WifiMode mode =
3329  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW10MHz",
3331  true,
3333  4);
3334  return mode;
3335 }
3336 
3337 WifiMode
3339 {
3340  static WifiMode mode =
3341  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW10MHz",
3343  false,
3345  4);
3346  return mode;
3347 }
3348 
3349 WifiMode
3351 {
3352  static WifiMode mode =
3353  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW10MHz",
3355  true,
3357  16);
3358  return mode;
3359 }
3360 
3361 WifiMode
3363 {
3364  static WifiMode mode =
3365  WifiModeFactory::CreateWifiMode ("OfdmRate18MbpsBW10MHz",
3367  false,
3369  16);
3370  return mode;
3371 }
3372 
3373 WifiMode
3375 {
3376  static WifiMode mode =
3377  WifiModeFactory::CreateWifiMode ("OfdmRate24MbpsBW10MHz",
3379  false,
3381  64);
3382  return mode;
3383 }
3384 
3385 WifiMode
3387 {
3388  static WifiMode mode =
3389  WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW10MHz",
3391  false,
3393  64);
3394  return mode;
3395 }
3396 
3397 
3398 // 5 MHz channel rates
3399 
3400 WifiMode
3402 {
3403  static WifiMode mode =
3404  WifiModeFactory::CreateWifiMode ("OfdmRate1_5MbpsBW5MHz",
3406  true,
3408  2);
3409  return mode;
3410 }
3411 
3412 WifiMode
3414 {
3415  static WifiMode mode =
3416  WifiModeFactory::CreateWifiMode ("OfdmRate2_25MbpsBW5MHz",
3418  false,
3420  2);
3421  return mode;
3422 }
3423 
3424 WifiMode
3426 {
3427  static WifiMode mode =
3428  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW5MHz",
3430  true,
3432  4);
3433  return mode;
3434 }
3435 
3436 WifiMode
3438 {
3439  static WifiMode mode =
3440  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW5MHz",
3442  false,
3444  4);
3445  return mode;
3446 }
3447 
3448 WifiMode
3450 {
3451  static WifiMode mode =
3452  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW5MHz",
3454  true,
3456  16);
3457  return mode;
3458 }
3459 
3460 WifiMode
3462 {
3463  static WifiMode mode =
3464  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW5MHz",
3466  false,
3468  16);
3469  return mode;
3470 }
3471 
3472 WifiMode
3474 {
3475  static WifiMode mode =
3476  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW5MHz",
3478  false,
3480  64);
3481  return mode;
3482 }
3483 
3484 WifiMode
3486 {
3487  static WifiMode mode =
3488  WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW5MHz",
3490  false,
3492  64);
3493  return mode;
3494 }
3495 
3496 
3497 // Clause 20
3498 
3499 WifiMode
3501 {
3502  static WifiMode mcs =
3504  return mcs;
3505 }
3506 
3507 WifiMode
3509 {
3510  static WifiMode mcs =
3512  return mcs;
3513 }
3514 
3515 WifiMode
3517 {
3518  static WifiMode mcs =
3520  return mcs;
3521 }
3522 
3523 WifiMode
3525 {
3526  static WifiMode mcs =
3528  return mcs;
3529 }
3530 
3531 WifiMode
3533 {
3534  static WifiMode mcs =
3536  return mcs;
3537 }
3538 
3539 WifiMode
3541 {
3542  static WifiMode mcs =
3544  return mcs;
3545 }
3546 
3547 WifiMode
3549 {
3550  static WifiMode mcs =
3552  return mcs;
3553 }
3554 
3555 WifiMode
3557 {
3558  static WifiMode mcs =
3560  return mcs;
3561 }
3562 
3563 WifiMode
3565 {
3566  static WifiMode mcs =
3568  return mcs;
3569 }
3570 
3571 WifiMode
3573 {
3574  static WifiMode mcs =
3576  return mcs;
3577 }
3578 
3579 WifiMode
3581 {
3582  static WifiMode mcs =
3584  return mcs;
3585 }
3586 
3587 WifiMode
3589 {
3590  static WifiMode mcs =
3592  return mcs;
3593 }
3594 
3595 WifiMode
3597 {
3598  static WifiMode mcs =
3600  return mcs;
3601 }
3602 
3603 WifiMode
3605 {
3606  static WifiMode mcs =
3608  return mcs;
3609 }
3610 
3611 WifiMode
3613 {
3614  static WifiMode mcs =
3616  return mcs;
3617 }
3618 
3619 WifiMode
3621 {
3622  static WifiMode mcs =
3624  return mcs;
3625 }
3626 
3627 WifiMode
3629 {
3630  static WifiMode mcs =
3632  return mcs;
3633 }
3634 
3635 WifiMode
3637 {
3638  static WifiMode mcs =
3640  return mcs;
3641 }
3642 
3643 WifiMode
3645 {
3646  static WifiMode mcs =
3648  return mcs;
3649 }
3650 
3651 WifiMode
3653 {
3654  static WifiMode mcs =
3656  return mcs;
3657 }
3658 
3659 WifiMode
3661 {
3662  static WifiMode mcs =
3664  return mcs;
3665 }
3666 
3667 WifiMode
3669 {
3670  static WifiMode mcs =
3672  return mcs;
3673 }
3674 
3675 WifiMode
3677 {
3678  static WifiMode mcs =
3680  return mcs;
3681 }
3682 
3683 WifiMode
3685 {
3686  static WifiMode mcs =
3688  return mcs;
3689 }
3690 
3691 WifiMode
3693 {
3694  static WifiMode mcs =
3696  return mcs;
3697 }
3698 
3699 WifiMode
3701 {
3702  static WifiMode mcs =
3704  return mcs;
3705 }
3706 
3707 WifiMode
3709 {
3710  static WifiMode mcs =
3712  return mcs;
3713 }
3714 
3715 WifiMode
3717 {
3718  static WifiMode mcs =
3720  return mcs;
3721 }
3722 
3723 WifiMode
3725 {
3726  static WifiMode mcs =
3728  return mcs;
3729 }
3730 
3731 WifiMode
3733 {
3734  static WifiMode mcs =
3736  return mcs;
3737 }
3738 
3739 WifiMode
3741 {
3742  static WifiMode mcs =
3744  return mcs;
3745 }
3746 
3747 WifiMode
3749 {
3750  static WifiMode mcs =
3752  return mcs;
3753 }
3754 
3755 
3756 // Clause 22
3757 
3758 WifiMode
3760 {
3761  static WifiMode mcs =
3763  return mcs;
3764 }
3765 
3766 WifiMode
3768 {
3769  static WifiMode mcs =
3771  return mcs;
3772 }
3773 
3774 WifiMode
3776 {
3777  static WifiMode mcs =
3779  return mcs;
3780 }
3781 
3782 WifiMode
3784 {
3785  static WifiMode mcs =
3787  return mcs;
3788 }
3789 
3790 WifiMode
3792 {
3793  static WifiMode mcs =
3795  return mcs;
3796 }
3797 
3798 WifiMode
3800 {
3801  static WifiMode mcs =
3803  return mcs;
3804 }
3805 
3806 WifiMode
3808 {
3809  static WifiMode mcs =
3811  return mcs;
3812 }
3813 
3814 WifiMode
3816 {
3817  static WifiMode mcs =
3819  return mcs;
3820 }
3821 
3822 WifiMode
3824 {
3825  static WifiMode mcs =
3827  return mcs;
3828 }
3829 
3830 WifiMode
3832 {
3833  static WifiMode mcs =
3835  return mcs;
3836 }
3837 
3838 // Clause 26
3839 
3840 WifiMode
3842 {
3843  static WifiMode mcs =
3845  return mcs;
3846 }
3847 
3848 WifiMode
3850 {
3851  static WifiMode mcs =
3853  return mcs;
3854 }
3855 
3856 WifiMode
3858 {
3859  static WifiMode mcs =
3861  return mcs;
3862 }
3863 
3864 WifiMode
3866 {
3867  static WifiMode mcs =
3869  return mcs;
3870 }
3871 
3872 WifiMode
3874 {
3875  static WifiMode mcs =
3877  return mcs;
3878 }
3879 
3880 WifiMode
3882 {
3883  static WifiMode mcs =
3885  return mcs;
3886 }
3887 
3888 WifiMode
3890 {
3891  static WifiMode mcs =
3893  return mcs;
3894 }
3895 
3896 WifiMode
3898 {
3899  static WifiMode mcs =
3901  return mcs;
3902 }
3903 
3904 WifiMode
3906 {
3907  static WifiMode mcs =
3909  return mcs;
3910 }
3911 
3912 WifiMode
3914 {
3915  static WifiMode mcs =
3917  return mcs;
3918 }
3919 
3920 WifiMode
3922 {
3923  static WifiMode mcs =
3925  return mcs;
3926 }
3927 
3928 WifiMode
3930 {
3931  static WifiMode mcs =
3933  return mcs;
3934 }
3935 
3936 bool
3938 {
3939  for (uint8_t i = 0; i < GetNModes (); i++)
3940  {
3941  if (mode == GetMode (i))
3942  {
3943  return true;
3944  }
3945  }
3946  return false;
3947 }
3948 
3949 bool
3951 {
3952  WifiModulationClass modulation = mcs.GetModulationClass ();
3953  if (modulation == WIFI_MOD_CLASS_HT || modulation == WIFI_MOD_CLASS_VHT
3954  || modulation == WIFI_MOD_CLASS_HE)
3955  {
3956  return IsMcsSupported (modulation, mcs.GetMcsValue ());
3957  }
3958  return false;
3959 }
3960 
3961 bool
3963 {
3964  if (m_mcsIndexMap.find (mc) == m_mcsIndexMap.end ())
3965  {
3966  return false;
3967  }
3968  if (m_mcsIndexMap.at (mc).find (mcs) == m_mcsIndexMap.at (mc).end ())
3969  {
3970  return false;
3971  }
3972  return true;
3973 }
3974 
3975 uint8_t
3977 {
3978  return static_cast<uint8_t> (m_deviceRateSet.size ());
3979 }
3980 
3981 WifiMode
3982 WifiPhy::GetMode (uint8_t mode) const
3983 {
3984  return m_deviceRateSet[mode];
3985 }
3986 
3987 uint8_t
3988 WifiPhy::GetNMcs (void) const
3989 {
3990  return static_cast<uint8_t> (m_deviceMcsSet.size ());
3991 }
3992 
3993 WifiMode
3994 WifiPhy::GetMcs (uint8_t mcs) const
3995 {
3996  return m_deviceMcsSet[mcs];
3997 }
3998 
3999 WifiMode
4000 WifiPhy::GetMcs (WifiModulationClass modulation, uint8_t mcs) const
4001 {
4002  NS_ASSERT_MSG (IsMcsSupported (modulation, mcs), "Unsupported MCS");
4003  uint8_t index = m_mcsIndexMap.at (modulation).at (mcs);
4004  NS_ASSERT (index < m_deviceMcsSet.size ());
4005  WifiMode mode = m_deviceMcsSet[index];
4006  NS_ASSERT (mode.GetModulationClass () == modulation);
4007  NS_ASSERT (mode.GetMcsValue () == mcs);
4008  return mode;
4009 }
4010 
4011 WifiMode
4012 WifiPhy::GetHtMcs (uint8_t mcs) const
4013 {
4014  return GetMcs (WIFI_MOD_CLASS_HT, mcs);
4015 }
4016 
4017 WifiMode
4018 WifiPhy::GetVhtMcs (uint8_t mcs) const
4019 {
4020  return GetMcs (WIFI_MOD_CLASS_VHT, mcs);
4021 }
4022 
4023 WifiMode
4024 WifiPhy::GetHeMcs (uint8_t mcs) const
4025 {
4026  return GetMcs (WIFI_MOD_CLASS_HE, mcs);
4027 }
4028 
4029 bool
4031 {
4032  return m_state->IsStateCcaBusy ();
4033 }
4034 
4035 bool
4037 {
4038  return m_state->IsStateIdle ();
4039 }
4040 
4041 bool
4043 {
4044  return m_state->IsStateRx ();
4045 }
4046 
4047 bool
4049 {
4050  return m_state->IsStateTx ();
4051 }
4052 
4053 bool
4055 {
4056  return m_state->IsStateSwitching ();
4057 }
4058 
4059 bool
4061 {
4062  return m_state->IsStateSleep ();
4063 }
4064 
4065 bool
4067 {
4068  return m_state->IsStateOff ();
4069 }
4070 
4071 Time
4073 {
4074  return m_state->GetDelayUntilIdle ();
4075 }
4076 
4077 Time
4079 {
4080  return m_state->GetLastRxStartTime ();
4081 }
4082 
4083 Time
4085 {
4086  return m_state->GetLastRxEndTime ();
4087 }
4088 
4089 void
4091 {
4092  NS_LOG_FUNCTION (this);
4093  //We are here because we have received the first bit of a packet and we are
4094  //not going to be able to synchronize on it
4095  //In this model, CCA becomes busy when the aggregation of all signals as
4096  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
4097 
4099  if (!delayUntilCcaEnd.IsZero ())
4100  {
4101  NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
4102  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
4103  }
4104 }
4105 
4106 void
4108 {
4109  NS_LOG_FUNCTION (this << reason);
4111  {
4113  }
4114  if (m_endPhyRxEvent.IsRunning ())
4115  {
4117  }
4118  if (m_endRxEvent.IsRunning ())
4119  {
4120  m_endRxEvent.Cancel ();
4121  }
4122  NotifyRxDrop (m_currentEvent->GetPsdu (), reason);
4124  if (reason == OBSS_PD_CCA_RESET)
4125  {
4126  m_state->SwitchFromRxAbort ();
4127  }
4128  m_currentEvent = 0;
4129 }
4130 
4131 void
4132 WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
4133 {
4134  NS_LOG_FUNCTION (this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
4135  m_powerRestricted = powerRestricted;
4136  m_txPowerMaxSiso = txPowerMaxSiso;
4137  m_txPowerMaxMimo = txPowerMaxMimo;
4138  NS_ASSERT ((m_currentEvent->GetEndTime () - Simulator::Now ()).IsPositive ());
4141 }
4142 
4143 double
4145 {
4147  if (!m_powerRestricted)
4148  {
4149  return GetPowerDbm (txVector.GetTxPowerLevel ());
4150  }
4151  else
4152  {
4153  if (txVector.GetNss () > 1)
4154  {
4155  return std::min (m_txPowerMaxMimo, GetPowerDbm (txVector.GetTxPowerLevel ()));
4156  }
4157  else
4158  {
4159  return std::min (m_txPowerMaxSiso, GetPowerDbm (txVector.GetTxPowerLevel ()));
4160  }
4161  }
4162 }
4163 
4164 void
4165 WifiPhy::StartRx (Ptr<Event> event, double rxPowerW)
4166 {
4167  NS_LOG_FUNCTION (this << *event << rxPowerW);
4168 
4169  NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
4170  m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events
4171 
4173  {
4174  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4175  Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
4176  m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
4177  }
4178  else if ((m_frameCaptureModel != 0) && (rxPowerW > m_currentEvent->GetRxPowerW ()))
4179  {
4180  NS_LOG_DEBUG ("Received a stronger signal during preamble detection: drop current packet and switch to new packet");
4185  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4186  Time remainingRxDuration = event->GetDuration () - startOfPreambleDuration;
4187  m_endPreambleDetectionEvent = Simulator::Schedule (startOfPreambleDuration, &WifiPhy::StartReceiveHeader, this, event);
4188  }
4189  else
4190  {
4191  NS_LOG_DEBUG ("Drop packet because RX is already decoding preamble");
4192  NotifyRxDrop (event->GetPsdu (), BUSY_DECODING_PREAMBLE);
4193  return;
4194  }
4195  m_currentEvent = event;
4196 }
4197 
4198 int64_t
4199 WifiPhy::AssignStreams (int64_t stream)
4200 {
4201  NS_LOG_FUNCTION (this << stream);
4202  m_random->SetStream (stream);
4203  return 1;
4204 }
4205 
4206 } //namespace ns3
4207 
4208 namespace {
4209 
4213 static class Constructor
4214 {
4215 public:
4217  {
4308  }
4309 } g_constructor;
4310 
4311 }
static class anonymous_namespace{wifi-phy.cc}::Constructor g_constructor
the constructor
ERP-OFDM PHY (Clause 19, Section 19.5)
MpduInfo structure.
Definition: wifi-phy.h:124
static WifiMode GetVhtMcs6()
Return MCS 6 from VHT MCS values.
Definition: wifi-phy.cc:3807
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:2470
static WifiMode GetOfdmRate9MbpsBW5MHz()
Return a WifiMode for OFDM at 9Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3461
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: wifi-phy.h:1923
Ptr< NetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:2073
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
static WifiMode GetErpOfdmRate24Mbps()
Return a WifiMode for ERP-OFDM at 24Mbps.
Definition: wifi-phy.cc:3152
uint8_t GetNTxPower(void) const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:589
bool IsStateSwitching(void) const
Definition: wifi-phy.cc:4054
static WifiMode GetDsssRate11Mbps()
Return a WifiMode for DSSS at 11Mbps.
Definition: wifi-phy.cc:3089
bool IsStateOff(void) const
Definition: wifi-phy.cc:4066
double signal
in dBm
Definition: wifi-phy.h:119
bool IsAggregation(void) const
Checks whether the PSDU contains A-MPDU.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
static WifiMode GetHeMcs7()
Return MCS 7 from HE MCS values.
Definition: wifi-phy.cc:3897
std::pair< uint8_t, WifiPhyStandard > ChannelNumberStandardPair
A pair of a ChannelNumber and WifiPhyStandard.
Definition: wifi-phy.h:654
static WifiMode GetErpOfdmRate36Mbps()
Return a WifiMode for ERP-OFDM at 36Mbps.
Definition: wifi-phy.cc:3164
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
OFDM PHY for the 5 GHz band (Clause 17 with 5 MHz channel bandwidth)
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
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:582
uint8_t m_channelNumber
Operating channel number.
Definition: wifi-phy.h:2068
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:2044
bool DefineChannelNumber(uint8_t channelNumber, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
Add a channel definition to the WifiPhy.
Definition: wifi-phy.cc:1157
static WifiMode GetVhtMcs8()
Return MCS 8 from VHT MCS values.
Definition: wifi-phy.cc:3823
ERP-OFDM PHY (19.5)
Definition: wifi-mode.h:54
AttributeValue implementation for Boolean.
Definition: boolean.h:36
void SetNumberOfReceiveAntennas(uint8_t rx)
Set the number of RX antennas in the receiver corresponding to this interference helper.
Ptr< HeConfiguration > GetHeConfiguration(void) const
double GetRxGain(void) const
Return the reception gain (dB).
Definition: wifi-phy.cc:615
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:3937
void AddSupportedChannelWidth(uint16_t width)
Definition: wifi-phy.cc:1461
WifiMode GetHeMcs(uint8_t mcs) const
Get the WifiMode object corresponding to the given MCS of the HE modulation class.
Definition: wifi-phy.cc:4024
static WifiMode GetOfdmRate9Mbps()
Return a WifiMode for OFDM at 9Mbps.
Definition: wifi-phy.cc:3215
double GetCcaEdThreshold(void) const
Return the CCA threshold (dBm).
Definition: wifi-phy.cc:542
HT PHY for the 5 GHz band (clause 20)
Ptr< ErrorRateModel > GetErrorRateModel(void) const
Return the error rate model.
static WifiMode GetOfdmRate18MbpsBW10MHz()
Return a WifiMode for OFDM at 18Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3362
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
static WifiMode GetOfdmRate27MbpsBW10MHz()
Return a WifiMode for OFDM at 27Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3386
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, SignalNoiseDbm > m_phyMonitorSniffRxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being received...
Definition: wifi-phy.h:1968
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:2043
WifiMode GetMcs(uint8_t mcs) const
The WifiPhy::GetMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of tr...
Definition: wifi-phy.cc:3994
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
static WifiMode GetOfdmRate3MbpsBW5MHz()
Return a WifiMode for OFDM at 3Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3425
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Definition: wifi-phy.cc:3759
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted...
Definition: wifi-phy.cc:4107
void MaybeCcaBusyDuration(void)
Eventually switch to CCA busy.
Definition: wifi-phy.cc:2836
WifiPhyStandard GetStandard(void) const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1309
virtual ~WifiPhy()
Definition: wifi-phy.cc:415
static WifiMode GetDsssRate1Mbps()
Return a WifiMode for DSSS at 1Mbps.
Definition: wifi-phy.cc:3050
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
void ResumeFromOff(void)
Resume from off mode.
Definition: wifi-phy.cc:1747
Ptr< WifiPhyStateHelper > GetState(void) const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:452
void ResumeFromSleep(void)
Resume from sleep mode.
Definition: wifi-phy.cc:1717
#define min(a, b)
Definition: 80211b.c:42
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:2041
bool GetShortGuardInterval(void) const
Return whether short guard interval is supported.
Definition: wifi-phy.cc:668
bool GetGreenfield(void) const
Return whether Greenfield is supported.
Definition: wifi-phy.cc:637
static WifiMode GetHeMcs5()
Return MCS 5 from HE MCS values.
Definition: wifi-phy.cc:3881
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition: wifi-phy.h:2081
static WifiMode GetErpOfdmRate18Mbps()
Return a WifiMode for ERP-OFDM at 18Mbps.
Definition: wifi-phy.cc:3140
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:595
void Configure80211ax(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard...
Definition: wifi-phy.cc:1128
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:41
static WifiMode GetHtMcs7()
Return MCS 7 from HT MCS values.
Definition: wifi-phy.cc:3556
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:522
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:85
virtual void DoDispose(void)
Destructor implementation.
Definition: wifi-phy.cc:421
static WifiMode GetHePhyHeaderMode()
Definition: wifi-phy.cc:1790
def start()
Definition: core.py:1855
bool Is2_4Ghz(double frequency)
Definition: wifi-utils.cc:59
void RebuildMcsMap(void)
Rebuild the mapping of MCS values to indices in the device MCS set.
Definition: wifi-phy.cc:1009
TracedCallback< Ptr< const WifiPsdu >, WifiTxVector, double > m_phyTxPsduBeginTrace
The trace source fired when a PSDU begins the transmission process on the medium. ...
Definition: wifi-phy.h:1899
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
Definition: wifi-phy.cc:3799
uint8_t GetNBssMembershipSelectors(void) const
The WifiPhy::NBssMembershipSelectors() method is used (e.g., by a WifiRemoteStationManager) to determ...
Definition: wifi-phy.cc:1449
The PHY layer is sleeping.
static WifiMode GetHtMcs22()
Return MCS 22 from HT MCS values.
Definition: wifi-phy.cc:3676
static WifiMode GetHtMcs14()
Return MCS 14 from HT MCS values.
Definition: wifi-phy.cc:3612
static WifiMode GetOfdmRate12Mbps()
Return a WifiMode for OFDM at 12Mbps.
Definition: wifi-phy.cc:3227
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1947
#define HE_PHY
Definition: wifi-phy.h:35
bool IsStateCcaBusy(void) const
Definition: wifi-phy.cc:4030
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:464
static WifiMode GetHtMcs31()
Return MCS 31 from HT MCS values.
Definition: wifi-phy.cc:3748
static WifiMode GetHtMcs21()
Return MCS 21 from HT MCS values.
Definition: wifi-phy.cc:3668
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
bool IsInitialized(void) const
Check if the object has been initialized.
Definition: object.cc:208
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:411
static WifiMode GetHtMcs30()
Return MCS 30 from HT MCS values.
Definition: wifi-phy.cc:3740
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Set the error rate model for this interference helper.
std::vector< uint8_t > m_bssMembershipSelectorSet
the BSS membership selector set
Definition: wifi-phy.h:2032
HE PHY for the 2.4 GHz band (clause 26)
std::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< const WifiPsdu > psdu, Ptr< Event > event, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
Definition: wifi-phy.cc:2989
static WifiMode GetHtMcs10()
Return MCS 10 from HT MCS values.
Definition: wifi-phy.cc:3580
static Time GetPhyPreambleDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2056
void SetShortPhyPreambleSupported(bool preamble)
Enable or disable short PHY preamble.
Definition: wifi-phy.cc:715
static WifiMode GetHtMcs26()
Return MCS 26 from HT MCS values.
Definition: wifi-phy.cc:3708
TracedCallback< WifiTxVector, Time > m_phyRxPayloadBeginTrace
The trace source fired when the reception of the PHY payload (PSDU) begins.
Definition: wifi-phy.h:1939
static WifiMode GetOfdmRate1_5MbpsBW5MHz()
Return a WifiMode for OFDM at 1.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3401
OFDM PHY for the 5 GHz band (Clause 17 with 10 MHz channel bandwidth)
static WifiMode GetHtMcs17()
Return MCS 17 from HT MCS values.
Definition: wifi-phy.cc:3636
static WifiMode GetHtMcs24()
Return MCS 24 from HT MCS values.
Definition: wifi-phy.cc:3692
EventId m_endPhyRxEvent
the end of PHY receive event
Definition: wifi-phy.h:1742
bool IsStbc(void) const
Check if STBC is used or not.
static WifiMode GetOfdmRate4_5MbpsBW10MHz()
Return a WifiMode for OFDM at 4.5Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3314
bool GetModeInitialized(void) const
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54Mbps.
Definition: wifi-phy.cc:3287
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:752
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:476
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:548
WifiMode GetVhtMcs(uint8_t mcs) const
Get the WifiMode object corresponding to the given MCS of the VHT modulation class.
Definition: wifi-phy.cc:4018
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
bool IsStrictlyPositive(void) const
Definition: nstime.h:314
static WifiMode GetHeMcs4()
Return MCS 4 from HE MCS values.
Definition: wifi-phy.cc:3873
uint8_t GetNess(void) const
void ConfigureHolland(void)
Configure WifiPhy with appropriate channel frequency and supported rates for Holland.
Definition: wifi-phy.cc:984
bool IsStateIdle(void) const
Definition: wifi-phy.cc:4036
uint16_t GetGuardInterval(void) const
bool Is5Ghz(double frequency)
Definition: wifi-utils.cc:65
HT PHY for the 2.4 GHz band (clause 20)
void SetGreenfield(bool greenfield)
Enable or disable Greenfield support.
Definition: wifi-phy.cc:621
VHT PHY (Clause 22)
Definition: wifi-mode.h:60
void Configure80211_10Mhz(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard with 10...
Definition: wifi-phy.cc:954
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
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:1954
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:48
std::pair< uint16_t, uint16_t > FrequencyWidthPair
A pair of a center Frequency (MHz) and a ChannelWidth (MHz)
Definition: wifi-phy.h:658
static WifiMode GetHtMcs8()
Return MCS 8 from HT MCS values.
Definition: wifi-phy.cc:3564
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:2047
static WifiMode GetHtMcs18()
Return MCS 18 from HT MCS values.
Definition: wifi-phy.cc:3644
double GetTxPowerForTransmission(WifiTxVector txVector) const
Compute the transmit power (in dBm) for the next transmission.
Definition: wifi-phy.cc:4144
virtual void SetFrequency(uint16_t freq)
Definition: wifi-phy.cc:1315
static WifiMode GetVhtMcs4()
Return MCS 4 from VHT MCS values.
Definition: wifi-phy.cc:3791
static WifiMode GetHtMcs27()
Return MCS 27 from HT MCS values.
Definition: wifi-phy.cc:3716
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:785
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:4132
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo > m_phyMonitorSniffTxTrace
A trace source that emulates a Wi-Fi device in monitor mode sniffing a packet being transmitted...
Definition: wifi-phy.h:1982
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:97
static WifiMode GetOfdmRate36Mbps()
Return a WifiMode for OFDM at 36Mbps.
Definition: wifi-phy.cc:3263
uint8_t m_initialChannelNumber
Initial channel number.
Definition: wifi-phy.h:2069
void NotifyRxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:2461
static WifiMode GetVhtMcs7()
Return MCS 7 from VHT MCS values.
Definition: wifi-phy.cc:3815
static WifiMode GetOfdmRate6MbpsBW5MHz()
Return a WifiMode for OFDM at 6Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3449
bool IsStateSleep(void) const
Definition: wifi-phy.cc:4060
void NotifyEndOfHePreamble(HePreambleParameters params)
Public method used to fire a EndOfHePreamble trace once both HE SIG fields have been received...
Definition: wifi-phy.cc:2535
double snr
SNR in linear scale.
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
static WifiMode GetVhtMcs3()
Return MCS 3 from VHT MCS values.
Definition: wifi-phy.cc:3783
void ConfigureDefaultsForStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:833
struct InterferenceHelper::SnrPer CalculateNonHtPhyHeaderSnrPer(Ptr< Event > event) const
Calculate the SNIR at the start of the non-HT PHY header and accumulate all SNIR changes in the SNIR ...
MpduType
The type of an MPDU.
double GetRxSensitivity(void) const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:529
void NotifyTxEnd(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:2434
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
WifiModeList m_deviceMcsSet
the device MCS set
Definition: wifi-phy.h:2028
mobility
Definition: third.py:108
uint16_t m_channelCenterFrequency
Center frequency in MHz.
Definition: wifi-phy.h:2036
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:728
static WifiMode GetHtMcs16()
Return MCS 16 from HT MCS values.
Definition: wifi-phy.cc:3628
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1392
bool m_powerRestricted
Flag whether transmit power is restricted by OBSS PD SR.
Definition: wifi-phy.h:2049
static WifiMode GetErpOfdmRate54Mbps()
Return a WifiMode for ERP-OFDM at 54Mbps.
Definition: wifi-phy.cc:3188
WifiPreamble GetPreambleType(void) const
static Time GetPhyHtSigHeaderDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1851
static WifiMode GetHtMcs29()
Return MCS 29 from HT MCS values.
Definition: wifi-phy.cc:3732
static WifiMode GetHtMcs11()
Return MCS 11 from HT MCS values.
Definition: wifi-phy.cc:3588
uint8_t GetNMcs(void) const
The WifiPhy::GetNMcs() method is used (e.g., by a WifiRemoteStationManager) to determine the set of t...
Definition: wifi-phy.cc:3988
static Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2417
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:32
Keep track of the current position and velocity of an object.
static ChannelToFrequencyWidthMap m_channelToFrequencyWidth
the channel to frequency width map
Definition: wifi-phy.h:2065
WifiPhyStandard
Identifies the PHY specification that a Wifi device is configured to use.
The MPDU is not part of an A-MPDU.
double rssiW
RSSI in W.
Definition: wifi-phy.h:133
uint8_t bssColor
BSS color.
Definition: wifi-phy.h:134
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate...
HE PHY for the 5 GHz band (clause 26)
bool DoFrequencySwitch(uint16_t frequency)
The default implementation does nothing and returns true.
Definition: wifi-phy.cc:1610
static WifiMode GetHtMcs2()
Return MCS 2 from HT MCS values.
Definition: wifi-phy.cc:3516
void StartReceiveHeader(Ptr< Event > event)
Start receiving the PHY header of a PPDU (i.e.
Definition: wifi-phy.cc:2616
static WifiMode GetHtPhyHeaderMode()
Definition: wifi-phy.cc:1778
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:227
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:2074
bool IsZero(void) const
Definition: nstime.h:294
AttributeValue implementation for Time.
Definition: nstime.h:1124
void StartRx(Ptr< Event > event, double rxPowerW)
Starting receiving the PPDU after having detected the medium is idle or after a reception switch...
Definition: wifi-phy.cc:4165
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1086
receive notifications about PHY events.
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:1915
Time GetEnergyDuration(double energyW) const
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:2051
bool m_shortPreamble
Flag if short PHY preamble is supported.
Definition: wifi-phy.h:2056
static WifiMode GetHeMcs3()
Return MCS 3 from HE MCS values.
Definition: wifi-phy.cc:3865
Hold an unsigned integer type.
Definition: uinteger.h:44
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, WifiCodeRate codingRate, uint16_t constellationSize)
Definition: wifi-mode.cc:657
EventId m_endTxEvent
the end of transmit event
Definition: wifi-phy.h:1745
static WifiMode GetHtMcs12()
Return MCS 12 from HT MCS values.
Definition: wifi-phy.cc:3596
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:2079
static WifiMode GetErpOfdmRate48Mbps()
Return a WifiMode for ERP-OFDM at 48Mbps.
Definition: wifi-phy.cc:3176
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:569
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:791
The MPDU is part of an A-MPDU with multiple MPDUs, but is neither the first nor the last aggregate...
static WifiMode GetOfdmRate12MbpsBW10MHz()
Return a WifiMode for OFDM at 12Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3350
WifiMode GetHtMcs(uint8_t mcs) const
Get the WifiMode object corresponding to the given MCS of the HT modulation class.
Definition: wifi-phy.cc:4012
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:3041
WifiMode GetMode(void) const
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
Definition: wifi-phy.cc:3929
The PHY layer has sense the medium busy through the CCA mechanism.
HT PHY (Clause 20)
Definition: wifi-mode.h:58
Time GetDelayUntilIdle(void)
Definition: wifi-phy.cc:4072
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1739
void Configure80211_5Mhz()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard with 5M...
Definition: wifi-phy.cc:969
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard(uint8_t channelNumber, WifiPhyStandard standard) const
Lookup frequency/width pair for channelNumber/standard pair.
Definition: wifi-phy.cc:1482
TracedCallback< HePreambleParameters > m_phyEndOfHePreambleTrace
A trace source that indicates the end of both HE SIG fields as well as training fields for received 8...
Definition: wifi-phy.h:1989
double CalculateSnr(WifiTxVector txVector, double ber) const
Definition: wifi-phy.cc:827
static WifiMode GetOfdmRate18Mbps()
Return a WifiMode for OFDM at 18Mbps.
Definition: wifi-phy.cc:3239
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:482
void SetOffMode(void)
Put in off mode.
Definition: wifi-phy.cc:1704
static WifiMode GetOfdmRate9MbpsBW10MHz()
Return a WifiMode for OFDM at 9Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3338
static WifiMode GetOfdmRate12MbpsBW5MHz()
Return a WifiMode for OFDM at 12Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3473
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:463
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:2078
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:803
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
Definition: wifi-phy.cc:3767
EventId m_endPreambleDetectionEvent
the end of preamble detection event
Definition: wifi-phy.h:1743
This is intended to be the configuration used in this paper: Gavin Holland, Nitin Vaidya and Paramvir...
static WifiMode GetOfdmRate48Mbps()
Return a WifiMode for OFDM at 48Mbps.
Definition: wifi-phy.cc:3275
void NotifyRxBegin(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:2452
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:771
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, double rxPowerW)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: wifi-phy.cc:2697
static WifiMode GetVhtPhyHeaderMode()
Definition: wifi-phy.cc:1784
static WifiMode GetHeMcs9()
Return MCS 9 from HE MCS values.
Definition: wifi-phy.cc:3913
double f(double x, void *params)
Definition: 80211b.c:70
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
Definition: wifi-phy.cc:3500
Ptr< MobilityModel > GetMobility(void) const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:758
static Time GetPreambleDetectionDuration(void)
Definition: wifi-phy.cc:1796
static Time GetPhySigA1Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1866
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:778
static TypeId GetTypeId(void)
Get the type ID.
Definition: wifi-phy.cc:162
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:821
OFDM PHY for the 5 GHz band (Clause 17)
void ContinueReceiveHeader(Ptr< Event > event)
Continue receiving the PHY header of a PPDU (i.e.
Definition: wifi-phy.cc:2668
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyRxStart()
Notify that RX has started.
Hold objects of type Ptr<T>.
Definition: pointer.h:36
void SetWifiRadioEnergyModel(const Ptr< WifiRadioEnergyModel > wifiRadioEnergyModel)
Sets the wifi radio energy model.
Definition: wifi-phy.cc:797
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:373
Time m_guardInterval
Supported HE guard interval (deprecated)
Definition: wifi-phy.h:2058
void EraseEvents(void)
Erase all events.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1372
The PHY layer is IDLE.
uint8_t GetNumberOfAntennas(void) const
Definition: wifi-phy.cc:1406
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24Mbps.
Definition: wifi-phy.cc:3251
void NotifyTxDrop(Ptr< const WifiPsdu > psdu)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:2443
static WifiMode GetHeMcs1()
Return MCS 1 from HE MCS values.
Definition: wifi-phy.cc:3849
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:1892
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
virtual void StartTx(Ptr< WifiPpdu > ppdu)=0
static WifiMode GetHtMcs13()
Return MCS 13 from HT MCS values.
Definition: wifi-phy.cc:3604
void SetShortGuardInterval(bool shortGuardInterval)
Enable or disable support for HT/VHT short guard interval.
Definition: wifi-phy.cc:652
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
Definition: wifi-phy.cc:3841
struct InterferenceHelper::SnrPer CalculateHtPhyHeaderSnrPer(Ptr< Event > event) const
Calculate the SNIR at the start of the HT PHY header and accumulate all SNIR changes in the SNIR vect...
static WifiMode GetHeMcs10()
Return MCS 10 from HE MCS values.
Definition: wifi-phy.cc:3921
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
static WifiMode GetHtMcs20()
Return MCS 20 from HT MCS values.
Definition: wifi-phy.cc:3660
static WifiMode GetHeMcs2()
Return MCS 2 from HE MCS values.
Definition: wifi-phy.cc:3857
static Time GetPhyTrainingSymbolDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1802
static WifiMode GetHtMcs5()
Return MCS 5 from HT MCS values.
Definition: wifi-phy.cc:3540
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1431
bool GetShortPhyPreambleSupported(void) const
Return whether short PHY preamble is supported.
Definition: wifi-phy.cc:722
double CalculateSnr(Ptr< Event > event) const
Calculate the SNIR for the event (starting from now until the event end).
double m_ccaEdThresholdW
Clear channel assessment (CCA) threshold in watts.
Definition: wifi-phy.h:2042
static WifiMode GetVhtMcs2()
Return MCS 2 from VHT MCS values.
Definition: wifi-phy.cc:3775
virtual void SetChannelNumber(uint8_t id)
Set channel number.
Definition: wifi-phy.cc:1490
static WifiMode GetDsssRate5_5Mbps()
Return a WifiMode for DSSS at 5.5Mbps.
Definition: wifi-phy.cc:3077
void Configure80211ac(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard...
Definition: wifi-phy.cc:1108
virtual void DoInitialize(void)
Initialize() implementation.
Definition: wifi-phy.cc:439
static WifiMode GetOfdmRate2_25MbpsBW5MHz()
Return a WifiMode for OFDM at 2.25Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3413
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:1125
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:47
uint8_t GetChannelNumber(void) const
Return current channel number.
Definition: wifi-phy.cc:1544
WifiPhyStandard m_standard
WifiPhyStandard.
Definition: wifi-phy.h:2034
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void SetGuardInterval(Time guardInterval)
Definition: wifi-phy.cc:683
uint8_t FindChannelNumberForFrequencyWidth(uint16_t frequency, uint16_t width) const
Look for channel number matching the frequency and width.
Definition: wifi-phy.cc:1174
bool m_channelAccessRequested
Flag if channels access has been requested (used for OBSS_PD SR)
Definition: wifi-phy.h:2052
static WifiMode GetErpOfdmRate9Mbps()
Return a WifiMode for ERP-OFDM at 9Mbps.
Definition: wifi-phy.cc:3116
void EndReceive(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: wifi-phy.cc:2914
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1735
Ptr< Event > Add(Ptr< const WifiPpdu > ppdu, WifiTxVector txVector, Time duration, double rxPower)
Add the PPDU-related signal to interference helper.
struct InterferenceHelper::SnrPer CalculatePayloadSnrPer(Ptr< Event > event, std::pair< Time, Time > relativeMpduStartStop) const
Calculate the SNIR at the start of the payload and accumulate all SNIR changes in the SNIR vector for...
static Time GetPayloadDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency, MpduType mpdutype=NORMAL_MPDU)
Definition: wifi-phy.cc:2125
double DbToRatio(double dB)
Convert from dB to ratio.
Definition: wifi-utils.cc:35
uint8_t m_txSpatialStreams
Number of supported TX spatial streams.
Definition: wifi-phy.h:2061
double GetTxPowerStart(void) const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:563
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:2080
static WifiMode GetPhyHeaderMode(WifiTxVector txVector)
Definition: wifi-phy.cc:1914
void InitializeFrequencyChannelNumber(void)
post-construction setting of frequency and/or channel number
Definition: wifi-phy.cc:488
std::vector< uint16_t > GetSupportedChannelWidthSet(void) const
Definition: wifi-phy.cc:1476
uint8_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3976
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:2077
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:42
void SetRxGain(double gain)
Sets the reception gain (dB).
Definition: wifi-phy.cc:608
void Configure80211b(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard...
Definition: wifi-phy.cc:927
No explicit coding (e.g., DSSS rates)
Definition: wifi-mode.h:75
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:458
WifiMode GetMode(uint8_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:3982
uint16_t m_channelWidth
Channel width (MHz)
Definition: wifi-phy.h:2039
uint8_t GetBssMembershipSelector(uint8_t selector) const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1455
static WifiMode GetErpOfdmRate6Mbps()
Return a WifiMode for ERP-OFDM at 6Mbps.
Definition: wifi-phy.cc:3104
void RegisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:470
bool IsStateTx(void) const
Definition: wifi-phy.cc:4048
void ConfigureChannelForStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1202
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1412
The PHY layer is sending a packet.
static WifiMode GetErpOfdmRate12Mbps()
Return a WifiMode for ERP-OFDM at 12Mbps.
Definition: wifi-phy.cc:3128
bool m_greenfield
Flag if GreenField format is supported (deprecated)
Definition: wifi-phy.h:2054
WifiModulationClass
This enumeration defines the modulation classes per (Table 9-4 "Modulation classes"; IEEE 802...
Definition: wifi-mode.h:36
EventId m_endRxEvent
the end of receive event
Definition: wifi-phy.h:1741
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1736
void SetEdThreshold(double threshold)
Sets the energy detection threshold (dBm).
Definition: wifi-phy.cc:516
void Configure80211n(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard...
Definition: wifi-phy.cc:1091
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:556
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:2045
bool IsMcsSupported(WifiMode mcs) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:3950
void NotifyRxEnd()
Notify that RX has ended.
void SetNoiseFigure(double value)
Set the noise figure.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
void ResetReceive(Ptr< Event > event)
Reset PHY at the end of the packet under reception after it has failed the PHY header.
Definition: wifi-phy.cc:3030
SignalNoiseDbm structure.
Definition: wifi-phy.h:117
uint32_t mpduRefNumber
MPDU ref number.
Definition: wifi-phy.h:127
bool m_frequencyChannelNumberInitialized
Store initialization state.
Definition: wifi-phy.h:2038
static WifiMode GetHtMcs19()
Return MCS 19 from HT MCS values.
Definition: wifi-phy.cc:3652
InterferenceHelper m_interference
Pointer to InterferenceHelper.
Definition: wifi-phy.h:1734
virtual void SetChannelWidth(uint16_t channelWidth)
Definition: wifi-phy.cc:1378
static WifiMode GetHtMcs6()
Return MCS 6 from HT MCS values.
Definition: wifi-phy.cc:3548
bool m_isConstructed
true when ready to set frequency
Definition: wifi-phy.h:2035
void NotifyTxBegin(Ptr< const WifiPsdu > psdu, double txPowerW)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:2425
The MPDU is the last aggregate in an A-MPDU with multiple MPDUs.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
void ConfigureHtDeviceMcsSet(void)
Configure the device MCS set with the appropriate HtMcs modes for the number of available transmit sp...
Definition: wifi-phy.cc:1021
void PushMcs(WifiMode mode)
Add the given MCS to the device MCS set.
Definition: wifi-phy.cc:996
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
Definition: wifi-phy.h:53
The PHY layer is receiving a packet.
OFDM PHY (Clause 17)
Definition: wifi-mode.h:56
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
static Time GetPhySigA2Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1883
static WifiMode GetHtMcs28()
Return MCS 28 from HT MCS values.
Definition: wifi-phy.cc:3724
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
double GetTxPowerEnd(void) const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:576
static WifiMode GetHtMcs9()
Return MCS 9 from HT MCS values.
Definition: wifi-phy.cc:3572
void EndReceiveInterBss(void)
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:3020
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:73
static WifiMode GetHtMcs4()
Return MCS 4 from HT MCS values.
Definition: wifi-phy.cc:3532
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
void StartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: wifi-phy.cc:2851
static WifiMode GetHtMcs25()
Return MCS 25 from HT MCS values.
Definition: wifi-phy.cc:3700
static WifiMode GetHeMcs8()
Return MCS 8 from HE MCS values.
Definition: wifi-phy.cc:3905
The PHY layer is switched off.
void Send(Ptr< const WifiPsdu > psdu, WifiTxVector txVector)
Definition: wifi-phy.cc:2541
void Configure80211g(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard...
Definition: wifi-phy.cc:938
Ptr< NetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:746
uint8_t GetTxPowerLevel(void) const
void NotifyMonitorSniffTx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being transmitted.
Definition: wifi-phy.cc:2510
double GetTxGain(void) const
Return the transmission gain (dB).
Definition: wifi-phy.cc:602
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:449
The PHY layer is switching to other channel.
void SetSleepMode(void)
Put in sleep mode.
Definition: wifi-phy.cc:1670
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1078
WifiModeList m_deviceRateSet
This vector holds the set of transmission modes that this WifiPhy(-derived class) can support...
Definition: wifi-phy.h:2027
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1398
uint16_t GetChannelWidth(void) const
second
Definition: nstime.h:114
static WifiMode GetHtMcs1()
Return MCS 1 from HT MCS values.
Definition: wifi-phy.cc:3508
std::map< WifiModulationClass, std::map< uint8_t, uint8_t > > m_mcsIndexMap
Maps MCS values to indices in m_deviceMcsSet, for HT, VHT and HE modulation classes.
Definition: wifi-phy.h:2030
static WifiMode GetHtMcs23()
Return MCS 23 from HT MCS values.
Definition: wifi-phy.cc:3684
static Time GetPhyHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1978
A base class which provides memory management and object aggregation.
Definition: object.h:87
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1102
static WifiMode GetDsssRate2Mbps()
Return a WifiMode for DSSS at 2Mbps.
Definition: wifi-phy.cc:3062
static WifiMode GetVhtMcs9()
Return MCS 9 from VHT MCS values.
Definition: wifi-phy.cc:3831
#define HT_PHY
Definition: wifi-phy.h:37
virtual void ConfigureStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1252
static Time GetStartOfPacketDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2050
static WifiMode GetOfdmRate6MbpsBW10MHz()
Return a WifiMode for OFDM at 6Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3326
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:381
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:2046
#define VHT_PHY
Definition: wifi-phy.h:36
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
This class can be used to hold variables of floating point type such as &#39;double&#39; or &#39;float&#39;...
Definition: double.h:41
static WifiMode GetOfdmRate24MbpsBW10MHz()
Return a WifiMode for OFDM at 24Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3374
The MPDU is a single MPDU.
MpduType type
type
Definition: wifi-phy.h:126
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:2071
static WifiMode GetOfdmRate13_5MbpsBW5MHz()
Return a WifiMode for OFDM at 13.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3485
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:4084
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:441
Ptr< HtConfiguration > GetHtConfiguration(void) const
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:45
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass)
Definition: wifi-mode.cc:695
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:2060
uint8_t GetMaxSupportedTxSpatialStreams(void) const
Definition: wifi-phy.cc:1425
a unique identifier for an interface.
Definition: type-id.h:58
static WifiMode GetHtMcs15()
Return MCS 15 from HT MCS values.
Definition: wifi-phy.cc:3620
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:2076
static Time GetPhySigBDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1900
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Time GetLastRxStartTime(void) const
Return the start time of the last received packet.
Definition: wifi-phy.cc:4078
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction (dBm)
Definition: wifi-phy.h:2050
bool IsStateRx(void) const
Definition: wifi-phy.cc:4042
static WifiMode GetHtMcs3()
Return MCS 3 from HT MCS values.
Definition: wifi-phy.cc:3524
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:2062
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:536
std::vector< uint16_t > m_supportedChannelWidthSet
Supported channel width set (MHz)
Definition: wifi-phy.h:2067
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6Mbps.
Definition: wifi-phy.cc:3203
void SwitchMaybeToCcaBusy(void)
Check if PHY state should move to CCA busy state based on current state of interference tracker...
Definition: wifi-phy.cc:4090
void SetCcaEdThreshold(double threshold)
Sets the CCA threshold (dBm).
Definition: wifi-phy.cc:535
bool m_shortGuardInterval
Flag if HT/VHT short guard interval is supported (deprecated)
Definition: wifi-phy.h:2055
HE PHY (Clause 26)
Definition: wifi-mode.h:62
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:119
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:4199
DSSS PHY (Clause 15)
Definition: wifi-mode.h:46
static WifiMode GetHeMcs6()
Return MCS 6 from HE MCS values.
Definition: wifi-phy.cc:3889
void NotifyMonitorSniffRx(Ptr< const WifiPsdu > psdu, uint16_t channelFreqMhz, WifiTxVector txVector, SignalNoiseDbm signalNoise, std::vector< bool > statusPerMpdu)
Public method used to fire a MonitorSniffer trace for a wifi PSDU being received. ...
Definition: wifi-phy.cc:2479
static WifiMode GetOfdmRate4_5MbpsBW5MHz()
Return a WifiMode for OFDM at 4.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3437
uint8_t GetNss(void) const
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:2083
void Configure80211a(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard...
Definition: wifi-phy.cc:912
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1443
std::map< ChannelNumberStandardPair, FrequencyWidthPair > ChannelToFrequencyWidthMap
channel to frequency width map typedef
Definition: wifi-phy.h:2064
static WifiMode GetOfdmRate3MbpsBW10MHz()
Return a WifiMode for OFDM at 3Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3302
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...
Definition: wifi-phy.h:1907
uint16_t m_initialFrequency
Store frequency until initialization (MHz)
Definition: wifi-phy.h:2037
Parameters for receive HE preamble.
Definition: wifi-phy.h:131
static Time CalculatePhyPreambleAndHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2403
bool DoChannelSwitch(uint8_t id)
The default implementation does nothing and returns true.
Definition: wifi-phy.cc:1550
Time GetGuardInterval(void) const
Definition: wifi-phy.cc:700