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 "wifi-phy-tag.h"
30 #include "ampdu-tag.h"
31 #include "wifi-utils.h"
32 #include "frame-capture-model.h"
35 #include "error-rate-model.h"
36 #include "wifi-net-device.h"
37 #include "ht-configuration.h"
38 #include "he-configuration.h"
39 #include "mpdu-aggregator.h"
40 #include "wifi-phy-header.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 PLCP 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 PLCP 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 ("PhyTxEnd",
333  "Trace source indicating a packet "
334  "has been completely transmitted over the channel. "
335  "NOTE: the only official WifiPhy implementation "
336  "available to this date never fires "
337  "this trace source.",
339  "ns3::Packet::TracedCallback")
340  .AddTraceSource ("PhyTxDrop",
341  "Trace source indicating a packet "
342  "has been dropped by the device during transmission",
344  "ns3::Packet::TracedCallback")
345  .AddTraceSource ("PhyRxBegin",
346  "Trace source indicating a packet "
347  "has begun being received from the channel medium "
348  "by the device",
350  "ns3::Packet::TracedCallback")
351  .AddTraceSource ("PhyRxEnd",
352  "Trace source indicating a packet "
353  "has been completely received from the channel medium "
354  "by the device",
356  "ns3::Packet::TracedCallback")
357  .AddTraceSource ("PhyRxDrop",
358  "Trace source indicating a packet "
359  "has been dropped by the device during reception",
361  "ns3::Packet::TracedCallback")
362  .AddTraceSource ("MonitorSnifferRx",
363  "Trace source simulating a wifi device in monitor mode "
364  "sniffing all received frames",
366  "ns3::WifiPhy::MonitorSnifferRxTracedCallback")
367  .AddTraceSource ("MonitorSnifferTx",
368  "Trace source simulating the capability of a wifi device "
369  "in monitor mode to sniff all frames being transmitted",
371  "ns3::WifiPhy::MonitorSnifferTxTracedCallback")
372  .AddTraceSource ("EndOfHePreamble",
373  "Trace source indicating the end of the 802.11ax preamble (after training fields)",
375  "ns3::WifiPhy::EndOfHePreambleTracedCallback")
376  ;
377  return tid;
378 }
379 
381  : m_txMpduReferenceNumber (0xffffffff),
382  m_rxMpduReferenceNumber (0xffffffff),
383  m_endRxEvent (),
384  m_endPlcpRxEvent (),
385  m_endPreambleDetectionEvent (),
386  m_standard (WIFI_PHY_STANDARD_UNSPECIFIED),
387  m_isConstructed (false),
388  m_channelCenterFrequency (0),
389  m_initialFrequency (0),
390  m_frequencyChannelNumberInitialized (false),
391  m_channelWidth (0),
392  m_channelAccessRequested (false),
393  m_txSpatialStreams (0),
394  m_rxSpatialStreams (0),
395  m_channelNumber (0),
396  m_initialChannelNumber (0),
397  m_totalAmpduSize (0),
398  m_totalAmpduNumSymbols (0),
399  m_currentEvent (0),
400  m_wifiRadioEnergyModel (0),
401  m_timeLastPreambleDetected (Seconds (0))
402 {
403  NS_LOG_FUNCTION (this);
404  m_random = CreateObject<UniformRandomVariable> ();
405  m_state = CreateObject<WifiPhyStateHelper> ();
406 }
407 
409 {
410  NS_LOG_FUNCTION (this);
411 }
412 
413 void
415 {
416  NS_LOG_FUNCTION (this);
417  m_endRxEvent.Cancel ();
420  m_device = 0;
421  m_mobility = 0;
422  m_state = 0;
425  m_deviceRateSet.clear ();
426  m_deviceMcsSet.clear ();
427 }
428 
429 void
431 {
432  NS_LOG_FUNCTION (this);
433  m_isConstructed = true;
435  {
436  NS_LOG_DEBUG ("Frequency already initialized");
437  return;
438  }
440 }
441 
443 WifiPhy::GetState (void) const
444 {
445  return m_state;
446 }
447 
448 void
450 {
451  m_state->SetReceiveOkCallback (callback);
452 }
453 
454 void
456 {
457  m_state->SetReceiveErrorCallback (callback);
458 }
459 
460 void
462 {
463  m_state->RegisterListener (listener);
464 }
465 
466 void
468 {
469  m_state->UnregisterListener (listener);
470 }
471 
472 void
474 {
476 }
477 
478 void
480 {
481  NS_LOG_FUNCTION (this);
482 
483  NS_ASSERT_MSG (m_frequencyChannelNumberInitialized == false, "Initialization called twice");
484 
485  // If frequency has been set to a non-zero value during attribute
486  // construction phase, the frequency and channel width will drive the
487  // initial configuration. If frequency has not been set, but both
488  // standard and channel number have been set, that pair will instead
489  // drive the configuration, and frequency and channel number will be
490  // aligned
491  if (m_initialFrequency != 0)
492  {
494  }
496  {
498  }
500  {
501  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " was set by user, but neither a standard nor a frequency");
502  }
504 }
505 
506 void
507 WifiPhy::SetEdThreshold (double threshold)
508 {
509  SetRxSensitivity (threshold);
510 }
511 
512 void
513 WifiPhy::SetRxSensitivity (double threshold)
514 {
515  NS_LOG_FUNCTION (this << threshold);
516  m_rxSensitivityW = DbmToW (threshold);
517 }
518 
519 double
521 {
522  return WToDbm (m_rxSensitivityW);
523 }
524 
525 void
526 WifiPhy::SetCcaEdThreshold (double threshold)
527 {
528  NS_LOG_FUNCTION (this << threshold);
529  m_ccaEdThresholdW = DbmToW (threshold);
530 }
531 
532 double
534 {
535  return WToDbm (m_ccaEdThresholdW);
536 }
537 
538 void
539 WifiPhy::SetRxNoiseFigure (double noiseFigureDb)
540 {
541  NS_LOG_FUNCTION (this << noiseFigureDb);
542  m_interference.SetNoiseFigure (DbToRatio (noiseFigureDb));
544 }
545 
546 void
548 {
549  NS_LOG_FUNCTION (this << start);
551 }
552 
553 double
555 {
556  return m_txPowerBaseDbm;
557 }
558 
559 void
561 {
562  NS_LOG_FUNCTION (this << end);
563  m_txPowerEndDbm = end;
564 }
565 
566 double
568 {
569  return m_txPowerEndDbm;
570 }
571 
572 void
574 {
575  NS_LOG_FUNCTION (this << +n);
576  m_nTxPower = n;
577 }
578 
579 uint8_t
581 {
582  return m_nTxPower;
583 }
584 
585 void
586 WifiPhy::SetTxGain (double gain)
587 {
588  NS_LOG_FUNCTION (this << gain);
589  m_txGainDb = gain;
590 }
591 
592 double
593 WifiPhy::GetTxGain (void) const
594 {
595  return m_txGainDb;
596 }
597 
598 void
599 WifiPhy::SetRxGain (double gain)
600 {
601  NS_LOG_FUNCTION (this << gain);
602  m_rxGainDb = gain;
603 }
604 
605 double
606 WifiPhy::GetRxGain (void) const
607 {
608  return m_rxGainDb;
609 }
610 
611 void
612 WifiPhy::SetGreenfield (bool greenfield)
613 {
614  NS_LOG_FUNCTION (this << greenfield);
615  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
616  if (device)
617  {
618  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
619  if (htConfiguration)
620  {
621  htConfiguration->SetGreenfieldSupported (greenfield);
622  }
623  }
624  m_greenfield = greenfield;
625 }
626 
627 bool
629 {
630  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
631  if (device)
632  {
633  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
634  if (htConfiguration)
635  {
636  return htConfiguration->GetGreenfieldSupported ();
637  }
638  }
639  return m_greenfield;
640 }
641 
642 void
643 WifiPhy::SetShortGuardInterval (bool shortGuardInterval)
644 {
645  NS_LOG_FUNCTION (this << shortGuardInterval);
646  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
647  if (device)
648  {
649  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
650  if (htConfiguration)
651  {
652  htConfiguration->SetShortGuardIntervalSupported (shortGuardInterval);
653  }
654  }
655  m_shortGuardInterval = shortGuardInterval;
656 }
657 
658 bool
660 {
661  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
662  if (device)
663  {
664  Ptr<HtConfiguration> htConfiguration = device->GetHtConfiguration ();
665  if (htConfiguration)
666  {
667  return htConfiguration->GetShortGuardIntervalSupported ();
668  }
669  }
670  return m_shortGuardInterval;
671 }
672 
673 void
675 {
676  NS_LOG_FUNCTION (this << guardInterval);
677  NS_ASSERT (guardInterval == NanoSeconds (800) || guardInterval == NanoSeconds (1600) || guardInterval == NanoSeconds (3200));
678  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
679  if (device)
680  {
681  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
682  if (heConfiguration)
683  {
684  heConfiguration->SetGuardInterval (guardInterval);
685  }
686  }
687  m_guardInterval = guardInterval;
688 }
689 
690 Time
692 {
693  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
694  if (device)
695  {
696  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
697  if (heConfiguration)
698  {
699  return heConfiguration->GetGuardInterval ();
700  }
701  }
702  return m_guardInterval;
703 }
704 
705 void
707 {
708  NS_LOG_FUNCTION (this << enable);
709  m_shortPreamble = enable;
710 }
711 
712 bool
714 {
715  return m_shortPreamble;
716 }
717 
718 void
720 {
721  m_device = device;
722  //TODO: to be removed once deprecated API is cleaned up
723  Ptr<HtConfiguration> htConfiguration = DynamicCast<WifiNetDevice> (device)->GetHtConfiguration ();
724  if (htConfiguration)
725  {
726  htConfiguration->SetShortGuardIntervalSupported (m_shortGuardInterval);
727  htConfiguration->SetGreenfieldSupported (m_greenfield);
728  }
729  Ptr<HeConfiguration> heConfiguration = DynamicCast<WifiNetDevice> (device)->GetHeConfiguration ();
730  if (heConfiguration)
731  {
732  heConfiguration->SetGuardInterval (m_guardInterval);
733  }
734 }
735 
737 WifiPhy::GetDevice (void) const
738 {
739  return m_device;
740 }
741 
742 void
744 {
746 }
747 
750 {
751  if (m_mobility != 0)
752  {
753  return m_mobility;
754  }
755  else
756  {
757  return m_device->GetNode ()->GetObject<MobilityModel> ();
758  }
759 }
760 
761 void
763 {
766 }
767 
768 void
770 {
771  NS_LOG_FUNCTION (this << em);
773 }
774 
775 void
777 {
778  m_frameCaptureModel = model;
779 }
780 
781 void
783 {
784  m_preambleDetectionModel = model;
785 }
786 
787 void
789 {
790  m_wifiRadioEnergyModel = wifiRadioEnergyModel;
791 }
792 
793 double
794 WifiPhy::GetPowerDbm (uint8_t power) const
795 {
797  NS_ASSERT (m_nTxPower > 0);
798  double dbm;
799  if (m_nTxPower > 1)
800  {
801  dbm = m_txPowerBaseDbm + power * (m_txPowerEndDbm - m_txPowerBaseDbm) / (m_nTxPower - 1);
802  }
803  else
804  {
805  NS_ASSERT_MSG (m_txPowerBaseDbm == m_txPowerEndDbm, "cannot have TxPowerEnd != TxPowerStart with TxPowerLevels == 1");
806  dbm = m_txPowerBaseDbm;
807  }
808  return dbm;
809 }
810 
811 Time
813 {
814  return m_channelSwitchDelay;
815 }
816 
817 double
818 WifiPhy::CalculateSnr (WifiTxVector txVector, double ber) const
819 {
820  return m_interference.GetErrorRateModel ()->CalculateSnr (txVector, ber);
821 }
822 
823 void
825 {
826  NS_LOG_FUNCTION (this << standard);
827  switch (standard)
828  {
830  SetChannelWidth (20);
831  SetFrequency (5180);
832  // Channel number should be aligned by SetFrequency () to 36
833  NS_ASSERT (GetChannelNumber () == 36);
834  break;
836  SetChannelWidth (22);
837  SetFrequency (2412);
838  // Channel number should be aligned by SetFrequency () to 1
839  NS_ASSERT (GetChannelNumber () == 1);
840  break;
842  SetChannelWidth (20);
843  SetFrequency (2412);
844  // Channel number should be aligned by SetFrequency () to 1
845  NS_ASSERT (GetChannelNumber () == 1);
846  break;
848  SetChannelWidth (10);
849  SetFrequency (5860);
850  // Channel number should be aligned by SetFrequency () to 172
851  NS_ASSERT (GetChannelNumber () == 172);
852  break;
854  SetChannelWidth (5);
855  SetFrequency (5860);
856  // Channel number should be aligned by SetFrequency () to 0
857  NS_ASSERT (GetChannelNumber () == 0);
858  break;
860  SetChannelWidth (20);
861  SetFrequency (5180);
862  // Channel number should be aligned by SetFrequency () to 36
863  NS_ASSERT (GetChannelNumber () == 36);
864  break;
866  SetChannelWidth (20);
867  SetFrequency (2412);
868  // Channel number should be aligned by SetFrequency () to 1
869  NS_ASSERT (GetChannelNumber () == 1);
870  break;
872  SetChannelWidth (20);
873  SetFrequency (5180);
874  // Channel number should be aligned by SetFrequency () to 36
875  NS_ASSERT (GetChannelNumber () == 36);
876  break;
878  SetChannelWidth (80);
879  SetFrequency (5210);
880  // Channel number should be aligned by SetFrequency () to 42
881  NS_ASSERT (GetChannelNumber () == 42);
882  break;
884  SetChannelWidth (20);
885  SetFrequency (2412);
886  // Channel number should be aligned by SetFrequency () to 1
887  NS_ASSERT (GetChannelNumber () == 1);
888  break;
890  SetChannelWidth (80);
891  SetFrequency (5210);
892  // Channel number should be aligned by SetFrequency () to 42
893  NS_ASSERT (GetChannelNumber () == 42);
894  break;
896  default:
897  NS_LOG_WARN ("Configuring unspecified standard; performing no action");
898  break;
899  }
900 }
901 
902 void
904 {
905  NS_LOG_FUNCTION (this);
906 
915 }
916 
917 void
919 {
920  NS_LOG_FUNCTION (this);
921 
926 }
927 
928 void
930 {
931  NS_LOG_FUNCTION (this);
932  Configure80211b ();
933 
942 }
943 
944 void
946 {
947  NS_LOG_FUNCTION (this);
948 
957 }
958 
959 void
961 {
962  NS_LOG_FUNCTION (this);
963 
972 }
973 
974 void
976 {
977  NS_LOG_FUNCTION (this);
978 
984 }
985 
986 void
988 {
989  NS_LOG_FUNCTION (this);
990 
991  bool htFound = false;
992  for (std::vector<uint8_t>::size_type i = 0; i < m_bssMembershipSelectorSet.size (); i++)
993  {
995  {
996  htFound = true;
997  break;
998  }
999  }
1000  if (htFound)
1001  {
1002  // erase all HtMcs modes from deviceMcsSet
1003  std::size_t index = m_deviceMcsSet.size () - 1;
1004  for (std::vector<WifiMode>::reverse_iterator rit = m_deviceMcsSet.rbegin (); rit != m_deviceMcsSet.rend (); ++rit, --index)
1005  {
1006  if (m_deviceMcsSet[index].GetModulationClass () == WIFI_MOD_CLASS_HT)
1007  {
1008  m_deviceMcsSet.erase (m_deviceMcsSet.begin () + index);
1009  }
1010  }
1011  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs0 ());
1012  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs1 ());
1013  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs2 ());
1014  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs3 ());
1015  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs4 ());
1016  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs5 ());
1017  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs6 ());
1018  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs7 ());
1020  {
1021  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs8 ());
1022  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs9 ());
1023  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs10 ());
1024  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs11 ());
1025  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs12 ());
1026  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs13 ());
1027  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs14 ());
1028  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs15 ());
1029  }
1031  {
1032  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs16 ());
1033  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs17 ());
1034  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs18 ());
1035  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs19 ());
1036  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs20 ());
1037  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs21 ());
1038  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs22 ());
1039  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs23 ());
1040  }
1042  {
1043  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs24 ());
1044  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs25 ());
1045  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs26 ());
1046  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs27 ());
1047  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs28 ());
1048  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs29 ());
1049  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs30 ());
1050  m_deviceMcsSet.push_back (WifiPhy::GetHtMcs31 ());
1051  }
1052  }
1053 }
1054 
1055 void
1057 {
1058  NS_LOG_FUNCTION (this);
1059  if (Is2_4Ghz (GetFrequency ()))
1060  {
1061  Configure80211b ();
1062  Configure80211g ();
1063  }
1064  if (Is5Ghz (GetFrequency ()))
1065  {
1066  Configure80211a ();
1067  }
1068  m_bssMembershipSelectorSet.push_back (HT_PHY);
1070 }
1071 
1072 void
1074 {
1075  NS_LOG_FUNCTION (this);
1076  Configure80211n ();
1077 
1078  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs0 ());
1079  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs1 ());
1080  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs2 ());
1081  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs3 ());
1082  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs4 ());
1083  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs5 ());
1084  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs6 ());
1085  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs7 ());
1086  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs8 ());
1087  m_deviceMcsSet.push_back (WifiPhy::GetVhtMcs9 ());
1088 
1089  m_bssMembershipSelectorSet.push_back (VHT_PHY);
1090 }
1091 
1092 void
1094 {
1095  NS_LOG_FUNCTION (this);
1096  if (Is5Ghz (GetFrequency ()))
1097  {
1098  Configure80211ac ();
1099  }
1100  else
1101  {
1102  Configure80211n ();
1103  }
1104 
1105  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs0 ());
1106  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs1 ());
1107  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs2 ());
1108  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs3 ());
1109  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs4 ());
1110  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs5 ());
1111  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs6 ());
1112  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs7 ());
1113  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs8 ());
1114  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs9 ());
1115  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs10 ());
1116  m_deviceMcsSet.push_back (WifiPhy::GetHeMcs11 ());
1117 
1118  m_bssMembershipSelectorSet.push_back (HE_PHY);
1119 }
1120 
1121 bool
1122 WifiPhy::DefineChannelNumber (uint8_t channelNumber, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
1123 {
1124  NS_LOG_FUNCTION (this << +channelNumber << standard << frequency << channelWidth);
1125  ChannelNumberStandardPair p = std::make_pair (channelNumber, standard);
1126  ChannelToFrequencyWidthMap::const_iterator it;
1127  it = m_channelToFrequencyWidth.find (p);
1128  if (it != m_channelToFrequencyWidth.end ())
1129  {
1130  NS_LOG_DEBUG ("channel number/standard already defined; returning false");
1131  return false;
1132  }
1133  FrequencyWidthPair f = std::make_pair (frequency, channelWidth);
1135  return true;
1136 }
1137 
1138 uint8_t
1139 WifiPhy::FindChannelNumberForFrequencyWidth (uint16_t frequency, uint16_t width) const
1140 {
1141  NS_LOG_FUNCTION (this << frequency << width);
1142  bool found = false;
1143  FrequencyWidthPair f = std::make_pair (frequency, width);
1144  ChannelToFrequencyWidthMap::const_iterator it = m_channelToFrequencyWidth.begin ();
1145  while (it != m_channelToFrequencyWidth.end ())
1146  {
1147  if (it->second == f)
1148  {
1149  found = true;
1150  break;
1151  }
1152  ++it;
1153  }
1154  if (found)
1155  {
1156  NS_LOG_DEBUG ("Found, returning " << +it->first.first);
1157  return (it->first.first);
1158  }
1159  else
1160  {
1161  NS_LOG_DEBUG ("Not found, returning 0");
1162  return 0;
1163  }
1164 }
1165 
1166 void
1168 {
1169  NS_LOG_FUNCTION (this << standard);
1170  // If the user has configured both Frequency and ChannelNumber, Frequency
1171  // takes precedence
1172  if (GetFrequency () != 0)
1173  {
1174  // If Frequency is already set, then see whether a ChannelNumber can
1175  // be found that matches Frequency and ChannelWidth. If so, configure
1176  // the ChannelNumber to that channel number. If not, set ChannelNumber to zero.
1177  NS_LOG_DEBUG ("Frequency set; checking whether a channel number corresponds");
1178  uint8_t channelNumberSearched = FindChannelNumberForFrequencyWidth (GetFrequency (), GetChannelWidth ());
1179  if (channelNumberSearched)
1180  {
1181  NS_LOG_DEBUG ("Channel number found; setting to " << +channelNumberSearched);
1182  SetChannelNumber (channelNumberSearched);
1183  }
1184  else
1185  {
1186  NS_LOG_DEBUG ("Channel number not found; setting to zero");
1187  SetChannelNumber (0);
1188  }
1189  }
1190  else if (GetChannelNumber () != 0)
1191  {
1192  // If the channel number is known for this particular standard or for
1193  // the unspecified standard, configure using the known values;
1194  // otherwise, this is a configuration error
1195  NS_LOG_DEBUG ("Configuring for channel number " << +GetChannelNumber ());
1197  if (f.first == 0)
1198  {
1199  // the specific pair of number/standard is not known
1200  NS_LOG_DEBUG ("Falling back to check WIFI_PHY_STANDARD_UNSPECIFIED");
1202  }
1203  if (f.first == 0)
1204  {
1205  NS_FATAL_ERROR ("Error, ChannelNumber " << +GetChannelNumber () << " is unknown for this standard");
1206  }
1207  else
1208  {
1209  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1210  SetFrequency (f.first);
1211  SetChannelWidth (f.second);
1212  }
1213  }
1214 }
1215 
1216 void
1218 {
1219  NS_LOG_FUNCTION (this << standard);
1220  m_standard = standard;
1221  m_isConstructed = true;
1223  {
1225  }
1226  if (GetFrequency () == 0 && GetChannelNumber () == 0)
1227  {
1228  ConfigureDefaultsForStandard (standard);
1229  }
1230  else
1231  {
1232  // The user has configured either (or both) Frequency or ChannelNumber
1233  ConfigureChannelForStandard (standard);
1234  }
1235  switch (standard)
1236  {
1238  Configure80211a ();
1239  break;
1241  Configure80211b ();
1242  break;
1244  Configure80211g ();
1245  break;
1248  break;
1251  break;
1253  ConfigureHolland ();
1254  break;
1257  Configure80211n ();
1258  break;
1260  Configure80211ac ();
1261  break;
1264  Configure80211ax ();
1265  break;
1267  default:
1268  NS_ASSERT (false);
1269  break;
1270  }
1271 }
1272 
1275 {
1276  return m_standard;
1277 }
1278 
1279 void
1280 WifiPhy::SetFrequency (uint16_t frequency)
1281 {
1282  NS_LOG_FUNCTION (this << frequency);
1283  if (m_isConstructed == false)
1284  {
1285  NS_LOG_DEBUG ("Saving frequency configuration for initialization");
1286  m_initialFrequency = frequency;
1287  return;
1288  }
1289  if (GetFrequency () == frequency)
1290  {
1291  NS_LOG_DEBUG ("No frequency change requested");
1292  return;
1293  }
1294  if (frequency == 0)
1295  {
1296  DoFrequencySwitch (0);
1297  NS_LOG_DEBUG ("Setting frequency and channel number to zero");
1299  m_channelNumber = 0;
1300  return;
1301  }
1302  // If the user has configured both Frequency and ChannelNumber, Frequency
1303  // takes precedence. Lookup the channel number corresponding to the
1304  // requested frequency.
1305  uint8_t nch = FindChannelNumberForFrequencyWidth (frequency, GetChannelWidth ());
1306  if (nch != 0)
1307  {
1308  NS_LOG_DEBUG ("Setting frequency " << frequency << " corresponds to channel " << +nch);
1309  if (DoFrequencySwitch (frequency))
1310  {
1311  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << +nch);
1312  m_channelCenterFrequency = frequency;
1313  m_channelNumber = nch;
1314  }
1315  else
1316  {
1317  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1318  }
1319  }
1320  else
1321  {
1322  NS_LOG_DEBUG ("Channel number is unknown for frequency " << frequency);
1323  if (DoFrequencySwitch (frequency))
1324  {
1325  NS_LOG_DEBUG ("Channel frequency switched to " << frequency << "; channel number to " << 0);
1326  m_channelCenterFrequency = frequency;
1327  m_channelNumber = 0;
1328  }
1329  else
1330  {
1331  NS_LOG_DEBUG ("Suppressing reassignment of frequency");
1332  }
1333  }
1334 }
1335 
1336 uint16_t
1338 {
1339  return m_channelCenterFrequency;
1340 }
1341 
1342 void
1343 WifiPhy::SetChannelWidth (uint16_t channelwidth)
1344 {
1345  NS_LOG_FUNCTION (this << channelwidth);
1346  NS_ASSERT_MSG (channelwidth == 5 || channelwidth == 10 || channelwidth == 20 || channelwidth == 22 || channelwidth == 40 || channelwidth == 80 || channelwidth == 160, "wrong channel width value");
1347  bool changed = (m_channelWidth == channelwidth);
1348  m_channelWidth = channelwidth;
1349  AddSupportedChannelWidth (channelwidth);
1350  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1351  {
1353  }
1354 }
1355 
1356 uint16_t
1358 {
1359  return m_channelWidth;
1360 }
1361 
1362 void
1364 {
1365  NS_ASSERT_MSG (antennas > 0 && antennas <= 4, "unsupported number of antennas");
1366  m_numberOfAntennas = antennas;
1368 }
1369 
1370 uint8_t
1372 {
1373  return m_numberOfAntennas;
1374 }
1375 
1376 void
1378 {
1379  NS_ASSERT (streams <= GetNumberOfAntennas ());
1380  bool changed = (m_txSpatialStreams == streams);
1381  m_txSpatialStreams = streams;
1383  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1384  {
1386  }
1387 }
1388 
1389 uint8_t
1391 {
1392  return m_txSpatialStreams;
1393 }
1394 
1395 void
1397 {
1398  NS_ASSERT (streams <= GetNumberOfAntennas ());
1399  bool changed = (m_rxSpatialStreams == streams);
1400  m_rxSpatialStreams = streams;
1401  if (changed && !m_capabilitiesChangedCallback.IsNull ())
1402  {
1404  }
1405 }
1406 
1407 uint8_t
1409 {
1410  return m_rxSpatialStreams;
1411 }
1412 
1413 uint8_t
1415 {
1416  return static_cast<uint8_t> (m_bssMembershipSelectorSet.size ());
1417 }
1418 
1419 uint8_t
1420 WifiPhy::GetBssMembershipSelector (uint8_t selector) const
1421 {
1422  return m_bssMembershipSelectorSet[selector];
1423 }
1424 
1425 void
1427 {
1428  NS_LOG_FUNCTION (this << width);
1429  for (std::vector<uint32_t>::size_type i = 0; i != m_supportedChannelWidthSet.size (); i++)
1430  {
1431  if (m_supportedChannelWidthSet[i] == width)
1432  {
1433  return;
1434  }
1435  }
1436  NS_LOG_FUNCTION ("Adding " << width << " to supported channel width set");
1437  m_supportedChannelWidthSet.push_back (width);
1438 }
1439 
1440 std::vector<uint16_t>
1442 {
1444 }
1445 
1448 {
1449  ChannelNumberStandardPair p = std::make_pair (channelNumber, standard);
1451  return f;
1452 }
1453 
1454 void
1456 {
1457  NS_LOG_FUNCTION (this << +nch);
1458  if (m_isConstructed == false)
1459  {
1460  NS_LOG_DEBUG ("Saving channel number configuration for initialization");
1461  m_initialChannelNumber = nch;
1462  return;
1463  }
1464  if (GetChannelNumber () == nch)
1465  {
1466  NS_LOG_DEBUG ("No channel change requested");
1467  return;
1468  }
1469  if (nch == 0)
1470  {
1471  // This case corresponds to when there is not a known channel
1472  // number for the requested frequency. There is no need to call
1473  // DoChannelSwitch () because DoFrequencySwitch () should have been
1474  // called by the client
1475  NS_LOG_DEBUG ("Setting channel number to zero");
1476  m_channelNumber = 0;
1477  return;
1478  }
1479 
1480  // First make sure that the channel number is defined for the standard
1481  // in use
1483  if (f.first == 0)
1484  {
1486  }
1487  if (f.first != 0)
1488  {
1489  if (DoChannelSwitch (nch))
1490  {
1491  NS_LOG_DEBUG ("Setting frequency to " << f.first << "; width to " << +f.second);
1492  m_channelCenterFrequency = f.first;
1493  SetChannelWidth (f.second);
1494  m_channelNumber = nch;
1495  }
1496  else
1497  {
1498  // Subclass may have suppressed (e.g. waiting for state change)
1499  NS_LOG_DEBUG ("Channel switch suppressed");
1500  }
1501  }
1502  else
1503  {
1504  NS_FATAL_ERROR ("Frequency not found for channel number " << +nch);
1505  }
1506 }
1507 
1508 uint8_t
1510 {
1511  return m_channelNumber;
1512 }
1513 
1514 bool
1516 {
1517  m_powerRestricted = false;
1518  m_channelAccessRequested = false;
1519  if (!IsInitialized ())
1520  {
1521  //this is not channel switch, this is initialization
1522  NS_LOG_DEBUG ("initialize to channel " << +nch);
1523  return true;
1524  }
1525 
1527  switch (m_state->GetState ())
1528  {
1529  case WifiPhyState::RX:
1530  NS_LOG_DEBUG ("drop packet because of channel switching while reception");
1532  m_endRxEvent.Cancel ();
1534  goto switchChannel;
1535  break;
1536  case WifiPhyState::TX:
1537  NS_LOG_DEBUG ("channel switching postponed until end of current transmission");
1539  break;
1541  case WifiPhyState::IDLE:
1543  {
1545  m_endRxEvent.Cancel ();
1546  }
1547  goto switchChannel;
1548  break;
1549  case WifiPhyState::SLEEP:
1550  NS_LOG_DEBUG ("channel switching ignored in sleep mode");
1551  break;
1552  default:
1553  NS_ASSERT (false);
1554  break;
1555  }
1556 
1557  return false;
1558 
1559 switchChannel:
1560 
1561  NS_LOG_DEBUG ("switching channel " << +GetChannelNumber () << " -> " << +nch);
1562  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1564  /*
1565  * Needed here to be able to correctly sensed the medium for the first
1566  * time after the switching. The actual switching is not performed until
1567  * after m_channelSwitchDelay. Packets received during the switching
1568  * state are added to the event list and are employed later to figure
1569  * out the state of the medium after the switching.
1570  */
1571  return true;
1572 }
1573 
1574 bool
1575 WifiPhy::DoFrequencySwitch (uint16_t frequency)
1576 {
1577  m_powerRestricted = false;
1578  m_channelAccessRequested = false;
1579  if (!IsInitialized ())
1580  {
1581  //this is not channel switch, this is initialization
1582  NS_LOG_DEBUG ("start at frequency " << frequency);
1583  return true;
1584  }
1585 
1587  switch (m_state->GetState ())
1588  {
1589  case WifiPhyState::RX:
1590  NS_LOG_DEBUG ("drop packet because of channel/frequency switching while reception");
1592  m_endRxEvent.Cancel ();
1594  goto switchFrequency;
1595  break;
1596  case WifiPhyState::TX:
1597  NS_LOG_DEBUG ("channel/frequency switching postponed until end of current transmission");
1599  break;
1601  case WifiPhyState::IDLE:
1603  {
1605  m_endRxEvent.Cancel ();
1606  }
1607  goto switchFrequency;
1608  break;
1609  case WifiPhyState::SLEEP:
1610  NS_LOG_DEBUG ("frequency switching ignored in sleep mode");
1611  break;
1612  default:
1613  NS_ASSERT (false);
1614  break;
1615  }
1616 
1617  return false;
1618 
1619 switchFrequency:
1620 
1621  NS_LOG_DEBUG ("switching frequency " << GetFrequency () << " -> " << frequency);
1622  m_state->SwitchToChannelSwitching (GetChannelSwitchDelay ());
1624  /*
1625  * Needed here to be able to correctly sensed the medium for the first
1626  * time after the switching. The actual switching is not performed until
1627  * after m_channelSwitchDelay. Packets received during the switching
1628  * state are added to the event list and are employed later to figure
1629  * out the state of the medium after the switching.
1630  */
1631  return true;
1632 }
1633 
1634 void
1636 {
1637  NS_LOG_FUNCTION (this);
1638  m_powerRestricted = false;
1639  m_channelAccessRequested = false;
1640  switch (m_state->GetState ())
1641  {
1642  case WifiPhyState::TX:
1643  NS_LOG_DEBUG ("setting sleep mode postponed until end of current transmission");
1645  break;
1646  case WifiPhyState::RX:
1647  NS_LOG_DEBUG ("setting sleep mode postponed until end of current reception");
1649  break;
1651  NS_LOG_DEBUG ("setting sleep mode postponed until end of channel switching");
1653  break;
1655  case WifiPhyState::IDLE:
1656  NS_LOG_DEBUG ("setting sleep mode");
1657  m_state->SwitchToSleep ();
1658  break;
1659  case WifiPhyState::SLEEP:
1660  NS_LOG_DEBUG ("already in sleep mode");
1661  break;
1662  default:
1663  NS_ASSERT (false);
1664  break;
1665  }
1666 }
1667 
1668 void
1670 {
1671  NS_LOG_FUNCTION (this);
1672  m_powerRestricted = false;
1673  m_channelAccessRequested = false;
1675  m_endRxEvent.Cancel ();
1677  m_state->SwitchToOff ();
1678 }
1679 
1680 void
1682 {
1683  NS_LOG_FUNCTION (this);
1684  switch (m_state->GetState ())
1685  {
1686  case WifiPhyState::TX:
1687  case WifiPhyState::RX:
1688  case WifiPhyState::IDLE:
1691  {
1692  NS_LOG_DEBUG ("not in sleep mode, there is nothing to resume");
1693  break;
1694  }
1695  case WifiPhyState::SLEEP:
1696  {
1697  NS_LOG_DEBUG ("resuming from sleep mode");
1699  m_state->SwitchFromSleep (delayUntilCcaEnd);
1700  break;
1701  }
1702  default:
1703  {
1704  NS_ASSERT (false);
1705  break;
1706  }
1707  }
1708 }
1709 
1710 void
1712 {
1713  NS_LOG_FUNCTION (this);
1714  switch (m_state->GetState ())
1715  {
1716  case WifiPhyState::TX:
1717  case WifiPhyState::RX:
1718  case WifiPhyState::IDLE:
1721  case WifiPhyState::SLEEP:
1722  {
1723  NS_LOG_DEBUG ("not in off mode, there is nothing to resume");
1724  break;
1725  }
1726  case WifiPhyState::OFF:
1727  {
1728  NS_LOG_DEBUG ("resuming from off mode");
1730  m_state->SwitchFromOff (delayUntilCcaEnd);
1731  break;
1732  }
1733  default:
1734  {
1735  NS_ASSERT (false);
1736  break;
1737  }
1738  }
1739 }
1740 
1741 WifiMode
1743 {
1744  return WifiPhy::GetHtMcs0 ();
1745 }
1746 
1747 WifiMode
1749 {
1750  return WifiPhy::GetVhtMcs0 ();
1751 }
1752 
1753 WifiMode
1755 {
1756  return WifiPhy::GetHeMcs0 ();
1757 }
1758 
1759 Time
1761 {
1762  return MicroSeconds (4);
1763 }
1764 
1765 Time
1767 {
1768  uint8_t Ndltf, Neltf;
1769  //We suppose here that STBC = 0.
1770  //If STBC > 0, we need a different mapping between Nss and Nltf (IEEE 802.11n-2012 standard, page 1682).
1771  if (txVector.GetNss () < 3)
1772  {
1773  Ndltf = txVector.GetNss ();
1774  }
1775  else if (txVector.GetNss () < 5)
1776  {
1777  Ndltf = 4;
1778  }
1779  else if (txVector.GetNss () < 7)
1780  {
1781  Ndltf = 6;
1782  }
1783  else
1784  {
1785  Ndltf = 8;
1786  }
1787 
1788  if (txVector.GetNess () < 3)
1789  {
1790  Neltf = txVector.GetNess ();
1791  }
1792  else
1793  {
1794  Neltf = 4;
1795  }
1796 
1797  switch (txVector.GetPreambleType ())
1798  {
1799  case WIFI_PREAMBLE_HT_MF:
1800  return MicroSeconds (4 + (4 * Ndltf) + (4 * Neltf));
1801  case WIFI_PREAMBLE_HT_GF:
1802  return MicroSeconds ((4 * Ndltf) + (4 * Neltf));
1803  case WIFI_PREAMBLE_VHT_SU:
1804  case WIFI_PREAMBLE_VHT_MU:
1805  return MicroSeconds (4 + (4 * Ndltf));
1806  case WIFI_PREAMBLE_HE_SU:
1807  case WIFI_PREAMBLE_HE_MU:
1808  return MicroSeconds (4 + (8 * Ndltf));
1809  default:
1810  return MicroSeconds (0);
1811  }
1812 }
1813 
1814 Time
1816 {
1817  switch (preamble)
1818  {
1819  case WIFI_PREAMBLE_HT_MF:
1820  case WIFI_PREAMBLE_HT_GF:
1821  //HT-SIG
1822  return MicroSeconds (8);
1823  default:
1824  //no HT-SIG for non HT
1825  return MicroSeconds (0);
1826  }
1827 }
1828 
1829 Time
1831 {
1832  switch (preamble)
1833  {
1834  case WIFI_PREAMBLE_VHT_SU:
1835  case WIFI_PREAMBLE_HE_SU:
1836  case WIFI_PREAMBLE_VHT_MU:
1837  case WIFI_PREAMBLE_HE_MU:
1838  //VHT-SIG-A1 and HE-SIG-A1
1839  return MicroSeconds (4);
1840  default:
1841  // no SIG-A1
1842  return MicroSeconds (0);
1843  }
1844 }
1845 
1846 Time
1848 {
1849  switch (preamble)
1850  {
1851  case WIFI_PREAMBLE_VHT_SU:
1852  case WIFI_PREAMBLE_HE_SU:
1853  case WIFI_PREAMBLE_VHT_MU:
1854  case WIFI_PREAMBLE_HE_MU:
1855  //VHT-SIG-A2 and HE-SIG-A2
1856  return MicroSeconds (4);
1857  default:
1858  // no SIG-A2
1859  return MicroSeconds (0);
1860  }
1861 }
1862 
1863 Time
1865 {
1866  switch (preamble)
1867  {
1868  case WIFI_PREAMBLE_VHT_MU:
1869  case WIFI_PREAMBLE_HE_MU:
1870  return MicroSeconds (4);
1871  default:
1872  // no SIG-B
1873  return MicroSeconds (0);
1874  }
1875 }
1876 
1877 WifiMode
1879 {
1880  switch (txVector.GetMode ().GetModulationClass ())
1881  {
1882  case WIFI_MOD_CLASS_OFDM:
1883  case WIFI_MOD_CLASS_HT:
1884  case WIFI_MOD_CLASS_VHT:
1885  case WIFI_MOD_CLASS_HE:
1886  switch (txVector.GetChannelWidth ())
1887  {
1888  case 5:
1890  case 10:
1892  case 20:
1893  case 40:
1894  case 80:
1895  case 160:
1896  default:
1897  //(Section 18.3.2 "PLCP frame format"; IEEE Std 802.11-2012)
1898  //actually this is only the first part of the PlcpHeader,
1899  //because the last 16 bits of the PlcpHeader are using the
1900  //same mode of the payload
1901  return WifiPhy::GetOfdmRate6Mbps ();
1902  }
1904  return WifiPhy::GetErpOfdmRate6Mbps ();
1905  case WIFI_MOD_CLASS_DSSS:
1907  if (txVector.GetPreambleType () == WIFI_PREAMBLE_LONG || txVector.GetMode () == WifiPhy::GetDsssRate1Mbps ())
1908  {
1909  //(Section 16.2.3 "PLCP field definitions" and Section 17.2.2.2 "Long PPDU format"; IEEE Std 802.11-2012)
1910  return WifiPhy::GetDsssRate1Mbps ();
1911  }
1912  else //WIFI_PREAMBLE_SHORT
1913  {
1914  //(Section 17.2.2.3 "Short PPDU format"; IEEE Std 802.11-2012)
1915  return WifiPhy::GetDsssRate2Mbps ();
1916  }
1917  default:
1918  NS_FATAL_ERROR ("unsupported modulation class");
1919  return WifiMode ();
1920  }
1921 }
1922 
1923 Time
1925 {
1926  WifiPreamble preamble = txVector.GetPreambleType ();
1927  switch (txVector.GetMode ().GetModulationClass ())
1928  {
1929  case WIFI_MOD_CLASS_OFDM:
1930  {
1931  switch (txVector.GetChannelWidth ())
1932  {
1933  case 20:
1934  default:
1935  //(Section 18.3.3 "PLCP preamble (SYNC))" and Figure 18-4 "OFDM training structure"; IEEE Std 802.11-2012)
1936  //also (Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012)
1937  //We return the duration of the SIGNAL field only, since the
1938  //SERVICE field (which strictly speaking belongs to the PLCP
1939  //header, see Section 18.3.2 and Figure 18-1) is sent using the
1940  //payload mode.
1941  return MicroSeconds (4);
1942  case 10:
1943  //(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012)
1944  return MicroSeconds (8);
1945  case 5:
1946  //(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012)
1947  return MicroSeconds (16);
1948  }
1949  }
1950  case WIFI_MOD_CLASS_HT:
1951  {
1952  //L-SIG
1953  //IEEE 802.11n Figure 20.1
1954  switch (preamble)
1955  {
1956  case WIFI_PREAMBLE_HT_MF:
1957  default:
1958  return MicroSeconds (4);
1959  case WIFI_PREAMBLE_HT_GF:
1960  return MicroSeconds (0);
1961  }
1962  }
1964  case WIFI_MOD_CLASS_VHT:
1965  //L-SIG
1966  return MicroSeconds (4);
1967  case WIFI_MOD_CLASS_HE:
1968  //LSIG + R-LSIG
1969  return MicroSeconds (8);
1970  case WIFI_MOD_CLASS_DSSS:
1972  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
1973  {
1974  //(Section 17.2.2.3 "Short PPDU format" and Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
1975  return MicroSeconds (24);
1976  }
1977  else //WIFI_PREAMBLE_LONG
1978  {
1979  //(Section 17.2.2.2 "Long PPDU format" and Figure 17-1 "Short PPDU format"; IEEE Std 802.11-2012)
1980  return MicroSeconds (48);
1981  }
1982  default:
1983  NS_FATAL_ERROR ("unsupported modulation class");
1984  return MicroSeconds (0);
1985  }
1986 }
1987 
1988 Time
1990 {
1991  return MicroSeconds (4);
1992 }
1993 
1994 Time
1996 {
1997  WifiPreamble preamble = txVector.GetPreambleType ();
1998  switch (txVector.GetMode ().GetModulationClass ())
1999  {
2000  case WIFI_MOD_CLASS_OFDM:
2001  {
2002  switch (txVector.GetChannelWidth ())
2003  {
2004  case 20:
2005  default:
2006  //(Section 18.3.3 "PLCP preamble (SYNC))" Figure 18-4 "OFDM training structure"
2007  //also Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012)
2008  return MicroSeconds (16);
2009  case 10:
2010  //(Section 18.3.3 "PLCP preamble (SYNC))" Figure 18-4 "OFDM training structure"
2011  //also Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012)
2012  return MicroSeconds (32);
2013  case 5:
2014  //(Section 18.3.3 "PLCP preamble (SYNC))" Figure 18-4 "OFDM training structure"
2015  //also Section 18.3.2.3 "Modulation-dependent parameters" Table 18-4 "Modulation-dependent parameters"; IEEE Std 802.11-2012)
2016  return MicroSeconds (64);
2017  }
2018  }
2019  case WIFI_MOD_CLASS_HT:
2020  case WIFI_MOD_CLASS_VHT:
2021  case WIFI_MOD_CLASS_HE:
2022  //L-STF + L-LTF
2023  return MicroSeconds (16);
2025  return MicroSeconds (16);
2026  case WIFI_MOD_CLASS_DSSS:
2028  if ((preamble == WIFI_PREAMBLE_SHORT) && (txVector.GetMode ().GetDataRate (22) > 1000000))
2029  {
2030  //(Section 17.2.2.3 "Short PPDU format)" Figure 17-2 "Short PPDU format"; IEEE Std 802.11-2012)
2031  return MicroSeconds (72);
2032  }
2033  else //WIFI_PREAMBLE_LONG
2034  {
2035  //(Section 17.2.2.2 "Long PPDU format)" Figure 17-1 "Long PPDU format"; IEEE Std 802.11-2012)
2036  return MicroSeconds (144);
2037  }
2038  default:
2039  NS_FATAL_ERROR ("unsupported modulation class");
2040  return MicroSeconds (0);
2041  }
2042 }
2043 
2044 Time
2045 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency)
2046 {
2047  return GetPayloadDuration (size, txVector, frequency, NORMAL_MPDU, 0);
2048 }
2049 
2050 Time
2051 WifiPhy::GetPayloadDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency,
2052  MpduType mpdutype, uint8_t incFlag)
2053 {
2054  WifiMode payloadMode = txVector.GetMode ();
2055  NS_LOG_FUNCTION (size << payloadMode);
2056 
2057  double stbc = 1;
2058  if (txVector.IsStbc ()
2059  && (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT
2060  || payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT))
2061  {
2062  stbc = 2;
2063  }
2064 
2065  double Nes = 1;
2066  //todo: improve logic to reduce the number of if cases
2067  //todo: extend to NSS > 4 for VHT rates
2068  if (payloadMode == GetHtMcs21 ()
2069  || payloadMode == GetHtMcs22 ()
2070  || payloadMode == GetHtMcs23 ()
2071  || payloadMode == GetHtMcs28 ()
2072  || payloadMode == GetHtMcs29 ()
2073  || payloadMode == GetHtMcs30 ()
2074  || payloadMode == GetHtMcs31 ())
2075  {
2076  Nes = 2;
2077  }
2078  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_VHT)
2079  {
2080  if (txVector.GetChannelWidth () == 40
2081  && txVector.GetNss () == 3
2082  && payloadMode.GetMcsValue () >= 8)
2083  {
2084  Nes = 2;
2085  }
2086  if (txVector.GetChannelWidth () == 80
2087  && txVector.GetNss () == 2
2088  && payloadMode.GetMcsValue () >= 7)
2089  {
2090  Nes = 2;
2091  }
2092  if (txVector.GetChannelWidth () == 80
2093  && txVector.GetNss () == 3
2094  && payloadMode.GetMcsValue () >= 7)
2095  {
2096  Nes = 2;
2097  }
2098  if (txVector.GetChannelWidth () == 80
2099  && txVector.GetNss () == 3
2100  && payloadMode.GetMcsValue () == 9)
2101  {
2102  Nes = 3;
2103  }
2104  if (txVector.GetChannelWidth () == 80
2105  && txVector.GetNss () == 4
2106  && payloadMode.GetMcsValue () >= 4)
2107  {
2108  Nes = 2;
2109  }
2110  if (txVector.GetChannelWidth () == 80
2111  && txVector.GetNss () == 4
2112  && payloadMode.GetMcsValue () >= 7)
2113  {
2114  Nes = 3;
2115  }
2116  if (txVector.GetChannelWidth () == 160
2117  && payloadMode.GetMcsValue () >= 7)
2118  {
2119  Nes = 2;
2120  }
2121  if (txVector.GetChannelWidth () == 160
2122  && txVector.GetNss () == 2
2123  && payloadMode.GetMcsValue () >= 4)
2124  {
2125  Nes = 2;
2126  }
2127  if (txVector.GetChannelWidth () == 160
2128  && txVector.GetNss () == 2
2129  && payloadMode.GetMcsValue () >= 7)
2130  {
2131  Nes = 3;
2132  }
2133  if (txVector.GetChannelWidth () == 160
2134  && txVector.GetNss () == 3
2135  && payloadMode.GetMcsValue () >= 3)
2136  {
2137  Nes = 2;
2138  }
2139  if (txVector.GetChannelWidth () == 160
2140  && txVector.GetNss () == 3
2141  && payloadMode.GetMcsValue () >= 5)
2142  {
2143  Nes = 3;
2144  }
2145  if (txVector.GetChannelWidth () == 160
2146  && txVector.GetNss () == 3
2147  && payloadMode.GetMcsValue () >= 7)
2148  {
2149  Nes = 4;
2150  }
2151  if (txVector.GetChannelWidth () == 160
2152  && txVector.GetNss () == 4
2153  && payloadMode.GetMcsValue () >= 2)
2154  {
2155  Nes = 2;
2156  }
2157  if (txVector.GetChannelWidth () == 160
2158  && txVector.GetNss () == 4
2159  && payloadMode.GetMcsValue () >= 4)
2160  {
2161  Nes = 3;
2162  }
2163  if (txVector.GetChannelWidth () == 160
2164  && txVector.GetNss () == 4
2165  && payloadMode.GetMcsValue () >= 5)
2166  {
2167  Nes = 4;
2168  }
2169  if (txVector.GetChannelWidth () == 160
2170  && txVector.GetNss () == 4
2171  && payloadMode.GetMcsValue () >= 7)
2172  {
2173  Nes = 6;
2174  }
2175  }
2176 
2177  Time symbolDuration = Seconds (0);
2178  switch (payloadMode.GetModulationClass ())
2179  {
2180  case WIFI_MOD_CLASS_OFDM:
2182  {
2183  //(Section 18.3.2.4 "Timing related parameters" Table 18-5 "Timing-related parameters"; IEEE Std 802.11-2012
2184  //corresponds to T_{SYM} in the table)
2185  switch (txVector.GetChannelWidth ())
2186  {
2187  case 20:
2188  default:
2189  symbolDuration = MicroSeconds (4);
2190  break;
2191  case 10:
2192  symbolDuration = MicroSeconds (8);
2193  break;
2194  case 5:
2195  symbolDuration = MicroSeconds (16);
2196  break;
2197  }
2198  break;
2199  }
2200  case WIFI_MOD_CLASS_HT:
2201  case WIFI_MOD_CLASS_VHT:
2202  {
2203  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2204  //In the future has to create a stationmanager that only uses these data rates if sender and receiver support GI
2205  uint16_t gi = txVector.GetGuardInterval ();
2206  NS_ASSERT (gi == 400 || gi == 800);
2207  symbolDuration = NanoSeconds (3200 + gi);
2208  }
2209  break;
2210  case WIFI_MOD_CLASS_HE:
2211  {
2212  //if short GI data rate is used then symbol duration is 3.6us else symbol duration is 4us
2213  //In the future has to create a stationmanager that only uses these data rates if sender and receiver support GI
2214  uint16_t gi = txVector.GetGuardInterval ();
2215  NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
2216  symbolDuration = NanoSeconds (12800 + gi);
2217  }
2218  break;
2219  default:
2220  break;
2221  }
2222 
2223  double numDataBitsPerSymbol = payloadMode.GetDataRate (txVector) * symbolDuration.GetNanoSeconds () / 1e9;
2224 
2225  double numSymbols = 0;
2226  if (mpdutype == FIRST_MPDU_IN_AGGREGATE)
2227  {
2228  //First packet in an A-MPDU
2229  numSymbols = (stbc * (16 + size * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol));
2230  if (incFlag == 1)
2231  {
2232  m_totalAmpduSize += size;
2233  m_totalAmpduNumSymbols += numSymbols;
2234  }
2235  }
2236  else if (mpdutype == MIDDLE_MPDU_IN_AGGREGATE)
2237  {
2238  //consecutive packets in an A-MPDU
2239  numSymbols = (stbc * size * 8.0) / (stbc * numDataBitsPerSymbol);
2240  if (incFlag == 1)
2241  {
2242  m_totalAmpduSize += size;
2243  m_totalAmpduNumSymbols += numSymbols;
2244  }
2245  }
2246  else if (mpdutype == LAST_MPDU_IN_AGGREGATE)
2247  {
2248  //last packet in an A-MPDU
2249  uint32_t totalAmpduSize = m_totalAmpduSize + size;
2250  numSymbols = lrint (stbc * ceil ((16 + totalAmpduSize * 8.0 + 6 * Nes) / (stbc * numDataBitsPerSymbol)));
2251  NS_ASSERT (m_totalAmpduNumSymbols <= numSymbols);
2252  numSymbols -= m_totalAmpduNumSymbols;
2253  if (incFlag == 1)
2254  {
2255  m_totalAmpduSize = 0;
2257  }
2258  }
2259  else if (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU)
2260  {
2261  //Not an A-MPDU or single MPDU (i.e. the current payload contains both service and padding)
2262  //The number of OFDM symbols in the data field when BCC encoding
2263  //is used is given in equation 19-32 of the IEEE 802.11-2016 standard.
2264  numSymbols = lrint (stbc * ceil ((16 + size * 8.0 + 6.0 * Nes) / (stbc * numDataBitsPerSymbol)));
2265  }
2266  else
2267  {
2268  NS_FATAL_ERROR ("Unknown MPDU type");
2269  }
2270 
2271  switch (payloadMode.GetModulationClass ())
2272  {
2273  case WIFI_MOD_CLASS_OFDM:
2275  {
2276  //Add signal extension for ERP PHY
2277  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
2278  {
2279  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2280  }
2281  else
2282  {
2283  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2284  }
2285  }
2286  case WIFI_MOD_CLASS_HT:
2287  case WIFI_MOD_CLASS_VHT:
2288  {
2289  if (payloadMode.GetModulationClass () == WIFI_MOD_CLASS_HT && Is2_4Ghz (frequency)
2290  && (mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE)) //at 2.4 GHz
2291  {
2292  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2293  }
2294  else //at 5 GHz
2295  {
2296  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2297  }
2298  }
2299  case WIFI_MOD_CLASS_HE:
2300  {
2301  if (Is2_4Ghz (frequency)
2302  && ((mpdutype == NORMAL_MPDU || mpdutype == SINGLE_MPDU || mpdutype == LAST_MPDU_IN_AGGREGATE))) //at 2.4 GHz
2303  {
2304  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ())) + MicroSeconds (6);
2305  }
2306  else //at 5 GHz
2307  {
2308  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
2309  }
2310  }
2311  case WIFI_MOD_CLASS_DSSS:
2313  return MicroSeconds (lrint (ceil ((size * 8.0) / (payloadMode.GetDataRate (22) / 1.0e6))));
2314  default:
2315  NS_FATAL_ERROR ("unsupported modulation class");
2316  return MicroSeconds (0);
2317  }
2318 }
2319 
2320 Time
2322 {
2323  WifiPreamble preamble = txVector.GetPreambleType ();
2324  Time duration = GetPlcpPreambleDuration (txVector)
2325  + GetPlcpHeaderDuration (txVector)
2326  + GetPlcpHtSigHeaderDuration (preamble)
2327  + GetPlcpSigA1Duration (preamble)
2328  + GetPlcpSigA2Duration (preamble)
2329  + GetPlcpTrainingSymbolDuration (txVector)
2330  + GetPlcpSigBDuration (preamble);
2331  return duration;
2332 }
2333 
2334 Time
2335 WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency,
2336  MpduType mpdutype, uint8_t incFlag)
2337 {
2338  Time duration = CalculatePlcpPreambleAndHeaderDuration (txVector)
2339  + GetPayloadDuration (size, txVector, frequency, mpdutype, incFlag);
2340  return duration;
2341 }
2342 
2343 Time
2344 WifiPhy::CalculateTxDuration (uint32_t size, WifiTxVector txVector, uint16_t frequency)
2345 {
2346  return CalculateTxDuration (size, txVector, frequency, NORMAL_MPDU, 0);
2347 }
2348 
2349 void
2351 {
2352  if (IsAmpdu (packet))
2353  {
2354  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (packet);
2355  for (auto & mpdu : mpdus)
2356  {
2357  m_phyTxBeginTrace (mpdu, txPowerW);
2358  }
2359  }
2360  else
2361  {
2362  m_phyTxBeginTrace (packet, txPowerW);
2363  }
2364 }
2365 
2366 void
2368 {
2369  if (IsAmpdu (packet))
2370  {
2371  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (packet);
2372  for (auto & mpdu : mpdus)
2373  {
2374  m_phyTxEndTrace (mpdu);
2375  }
2376  }
2377  else
2378  {
2379  m_phyTxEndTrace (packet);
2380  }
2381 }
2382 
2383 void
2385 {
2386  if (IsAmpdu (packet))
2387  {
2388  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (packet);
2389  for (auto & mpdu : mpdus)
2390  {
2391  m_phyTxDropTrace (mpdu);
2392  }
2393  }
2394  else
2395  {
2396  m_phyTxDropTrace (packet);
2397  }
2398 }
2399 
2400 void
2402 {
2403  if (IsAmpdu (packet))
2404  {
2405  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (packet);
2406  for (auto & mpdu : mpdus)
2407  {
2408  m_phyRxBeginTrace (mpdu);
2409  }
2410  }
2411  else
2412  {
2413  m_phyRxBeginTrace (packet);
2414  }
2415 }
2416 
2417 void
2419 {
2420  if (IsAmpdu (packet))
2421  {
2422  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (packet);
2423  for (auto & mpdu : mpdus)
2424  {
2425  m_phyRxEndTrace (mpdu);
2426  }
2427  }
2428  else
2429  {
2430  m_phyRxEndTrace (packet);
2431  }
2432 }
2433 
2434 void
2436 {
2437  if (IsAmpdu (packet))
2438  {
2439  std::list<Ptr<const Packet>> mpdus = MpduAggregator::PeekMpdus (packet);
2440  for (auto & mpdu : mpdus)
2441  {
2442  m_phyRxDropTrace (mpdu, reason);
2443  }
2444  }
2445  else
2446  {
2447  m_phyRxDropTrace (packet, reason);
2448  }
2449 }
2450 
2451 void
2452 WifiPhy::NotifyMonitorSniffRx (Ptr<const Packet> packet, uint16_t channelFreqMhz, WifiTxVector txVector,
2453  SignalNoiseDbm signalNoise, std::vector<bool> statusPerMpdu)
2454 {
2455  MpduInfo aMpdu;
2456  if (txVector.IsAggregation ())
2457  {
2458  //Expand A-MPDU
2460  std::list<Ptr<const Packet>> ampduSubframes = MpduAggregator::PeekAmpduSubframes (packet);
2461  size_t numberOfMpdus = ampduSubframes.size ();
2462  NS_ABORT_MSG_IF (statusPerMpdu.size () != numberOfMpdus, "Should have one reception status per MPDU");
2463  size_t i = 0;
2464  aMpdu.type = (numberOfMpdus == 1) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2465  for (const auto & subframe : ampduSubframes)
2466  {
2467  if (statusPerMpdu.at (i)) //packet received without error, hand over to sniffer
2468  {
2469  m_phyMonitorSniffRxTrace (subframe, channelFreqMhz, txVector, aMpdu, signalNoise);
2470  }
2471  ++i;
2472  aMpdu.type = (i == (numberOfMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2473  }
2474  }
2475  else
2476  {
2477  aMpdu.type = NORMAL_MPDU;
2478  NS_ABORT_MSG_IF (statusPerMpdu.size () != 1, "Should have one reception status for normal MPDU");
2479  m_phyMonitorSniffRxTrace (packet, channelFreqMhz, txVector, aMpdu, signalNoise);
2480  }
2481 }
2482 
2483 void
2484 WifiPhy::NotifyMonitorSniffTx (Ptr<const Packet> packet, uint16_t channelFreqMhz, WifiTxVector txVector)
2485 {
2486  MpduInfo aMpdu;
2487  if (txVector.IsAggregation ())
2488  {
2489  //Expand A-MPDU
2491  std::list<Ptr<const Packet>> ampduSubframes = MpduAggregator::PeekAmpduSubframes (packet);
2492  size_t numberOfMpdus = ampduSubframes.size ();
2493  size_t i = 0;
2494  aMpdu.type = (numberOfMpdus == 1) ? SINGLE_MPDU: FIRST_MPDU_IN_AGGREGATE;
2495  for (const auto & subframe : ampduSubframes)
2496  {
2497  m_phyMonitorSniffTxTrace (subframe, channelFreqMhz, txVector, aMpdu);
2498  ++i;
2499  aMpdu.type = (i == (numberOfMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
2500  }
2501  }
2502  else
2503  {
2504  aMpdu.type = NORMAL_MPDU;
2505  m_phyMonitorSniffTxTrace (packet, channelFreqMhz, txVector, aMpdu);
2506  }
2507 }
2508 
2509 void
2511 {
2512  m_phyEndOfHePreambleTrace (params);
2513 }
2514 
2515 void
2517 {
2518  NS_LOG_FUNCTION (this << packet << txVector);
2519  /* Transmission can happen if:
2520  * - we are syncing on a packet. It is the responsibility of the
2521  * MAC layer to avoid doing this but the PHY does nothing to
2522  * prevent it.
2523  * - we are idle
2524  */
2525  NS_ASSERT (!m_state->IsStateTx () && !m_state->IsStateSwitching ());
2526 
2527  if (txVector.GetNss () > GetMaxSupportedTxSpatialStreams ())
2528  {
2529  NS_FATAL_ERROR ("Unsupported number of spatial streams!");
2530  }
2531 
2532  if (m_state->IsStateSleep ())
2533  {
2534  NS_LOG_DEBUG ("Dropping packet because in sleep mode");
2535  NotifyTxDrop (packet);
2536  return;
2537  }
2538 
2539  Time txDuration = CalculateTxDuration (packet->GetSize (), txVector, GetFrequency ());
2540  NS_ASSERT (txDuration.IsStrictlyPositive ());
2541 
2543  {
2545  }
2546  if (m_endPlcpRxEvent.IsRunning ())
2547  {
2549  }
2550  if (m_endRxEvent.IsRunning ())
2551  {
2552  m_endRxEvent.Cancel ();
2553  }
2554  if (m_state->IsStateRx ())
2555  {
2557  }
2558 
2559  if (m_powerRestricted)
2560  {
2561  NS_LOG_DEBUG ("Transmitting with power restriction");
2562  }
2563  else
2564  {
2565  NS_LOG_DEBUG ("Transmitting without power restriction");
2566  }
2567 
2568  NotifyTxBegin (packet, DbmToW (GetTxPowerForTransmission (txVector) + GetTxGain ()));
2569  NotifyMonitorSniffTx (packet, GetFrequency (), txVector);
2570  m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector);
2571 
2572  Ptr<Packet> newPacket = packet->Copy (); // obtain non-const Packet
2573  WifiPhyTag oldtag;
2574  newPacket->RemovePacketTag (oldtag);
2575  if (m_state->GetState () == WifiPhyState::OFF)
2576  {
2577  NS_LOG_DEBUG ("Transmission canceled because device is OFF");
2578  return;
2579  }
2580 
2581  if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT)
2582  {
2583  HtSigHeader htSig;
2584  htSig.SetMcs (txVector.GetMode ().GetMcsValue ());
2585  htSig.SetChannelWidth (txVector.GetChannelWidth ());
2586  htSig.SetHtLength (packet->GetSize ());
2587  htSig.SetAggregation (txVector.IsAggregation ());
2588  htSig.SetShortGuardInterval (txVector.GetGuardInterval () == 400);
2589  newPacket->AddHeader (htSig);
2590  }
2591  else if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT)
2592  {
2593  VhtSigHeader vhtSig;
2594  vhtSig.SetMuFlag (txVector.GetPreambleType () == WIFI_PREAMBLE_VHT_MU);
2595  vhtSig.SetChannelWidth (txVector.GetChannelWidth ());
2596  vhtSig.SetShortGuardInterval (txVector.GetGuardInterval () == 400);
2597  uint32_t nSymbols = (static_cast<double> ((txDuration - CalculatePlcpPreambleAndHeaderDuration (txVector)).GetNanoSeconds ()) / (3200 + txVector.GetGuardInterval ()));
2598  vhtSig.SetShortGuardIntervalDisambiguation ((nSymbols % 10) == 9);
2599  vhtSig.SetSuMcs (txVector.GetMode ().GetMcsValue ());
2600  vhtSig.SetNStreams (txVector.GetNss ());
2601  newPacket->AddHeader (vhtSig);
2602  }
2603  else if (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HE)
2604  {
2605  HeSigHeader heSig;
2606  heSig.SetMuFlag (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU);
2607  heSig.SetMcs (txVector.GetMode ().GetMcsValue ());
2608  heSig.SetBssColor (txVector.GetBssColor ());
2609  heSig.SetChannelWidth (txVector.GetChannelWidth ());
2610  heSig.SetGuardIntervalAndLtfSize (txVector.GetGuardInterval (), 2/*NLTF currently unused*/);
2611  heSig.SetNStreams (txVector.GetNss ());
2612  newPacket->AddHeader (heSig);
2613  }
2614  if ((txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
2615  {
2616  DsssSigHeader sig;
2617  sig.SetRate (txVector.GetMode ().GetDataRate (22));
2618  Time psduDuration = txDuration - CalculatePlcpPreambleAndHeaderDuration (txVector);
2619  sig.SetLength (psduDuration.GetMicroSeconds ());
2620  newPacket->AddHeader (sig);
2621  }
2622  else if ((txVector.GetMode ().GetModulationClass () != WIFI_MOD_CLASS_HT) || (txVector.GetPreambleType () != WIFI_PREAMBLE_HT_GF))
2623  {
2624  LSigHeader sig;
2626  {
2627  sig.SetRate (txVector.GetMode ().GetDataRate (txVector), GetChannelWidth ());
2628  sig.SetLength (packet->GetSize ());
2629  }
2630  else //HT, VHT or HE
2631  {
2632  uint8_t sigExtention = 0;
2633  if (Is2_4Ghz (GetFrequency ()))
2634  {
2635  sigExtention = 6;
2636  }
2637  uint8_t m = 0;
2638  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_SU)
2639  {
2640  m = 2;
2641  }
2642  else if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
2643  {
2644  m = 1;
2645  }
2646  //Equation 27-11 of IEEE P802.11/D4.0
2647  uint16_t length = ((ceil ((static_cast<double> (txDuration.GetNanoSeconds () - (20 * 1000) - (sigExtention * 1000)) / 1000) / 4.0) * 3) - 3 - m);
2648  sig.SetLength (length);
2649  }
2650  newPacket->AddHeader (sig);
2651  }
2652 
2653  uint8_t isFrameComplete = 1;
2654  if (m_wifiRadioEnergyModel != 0 && m_wifiRadioEnergyModel->GetMaximumTimeInState (WifiPhyState::TX) < txDuration)
2655  {
2656  isFrameComplete = 0;
2657  }
2658  WifiPhyTag tag (txVector.GetPreambleType (), txVector.GetMode ().GetModulationClass (), isFrameComplete);
2659  newPacket->AddPacketTag (tag);
2660 
2661  StartTx (newPacket, txVector, txDuration);
2662 
2663  m_channelAccessRequested = false;
2664  m_powerRestricted = false;
2665 }
2666 
2667 void
2669 {
2670  NS_LOG_FUNCTION (this << event->GetPacket () << event->GetTxVector () << event << rxDuration);
2671  NS_ASSERT (!IsStateRx ());
2673 
2675  double snr = snrPer.snr;
2676  NS_LOG_DEBUG ("snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per);
2677 
2678  if (!m_preambleDetectionModel || (m_preambleDetectionModel->IsPreambleDetected (event->GetRxPowerW (), snr, m_channelWidth)))
2679  {
2680  m_state->SwitchToRx (rxDuration);
2681  NotifyRxBegin (event->GetPacket ());
2682 
2684 
2685  WifiTxVector txVector = event->GetTxVector ();
2686 
2687  if (txVector.GetNss () > GetMaxSupportedRxSpatialStreams ())
2688  {
2689  NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
2690  NotifyRxDrop (event->GetPacket (), UNSUPPORTED_SETTINGS);
2692  return;
2693  }
2694 
2695  if ((txVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HT) && (txVector.GetPreambleType () == WIFI_PREAMBLE_HT_GF))
2696  {
2697  //No legacy PHY header for HT GF
2698  Time remainingPreambleHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2699  m_endPlcpRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2700  }
2701  else
2702  {
2703  //Schedule end of legacy PHY header
2704  Time remainingPreambleAndLegacyHeaderDuration = GetPlcpPreambleDuration (txVector) + GetPlcpHeaderDuration (txVector) - GetPreambleDetectionDuration ();
2705  m_endPlcpRxEvent = Simulator::Schedule (remainingPreambleAndLegacyHeaderDuration, &WifiPhy::ContinueReceiveHeader, this, event);
2706  }
2707  }
2708  else
2709  {
2710  NS_LOG_DEBUG ("Drop packet because PHY preamble detection failed");
2711  NotifyRxDrop (event->GetPacket (), PREAMBLE_DETECT_FAILURE);
2713  }
2714  // Like CCA-SD, CCA-ED is governed by the 4μs CCA window to flag CCA-BUSY
2715  // for any received signal greater than the CCA-ED threshold.
2717 }
2718 
2719 void
2721 {
2722  NS_LOG_FUNCTION (this << event->GetPacket () << event->GetTxVector () << event);
2723  NS_ASSERT (IsStateRx ());
2725 
2728 
2729  if (m_random->GetValue () > snrPer.per) //legacy PHY header reception succeeded
2730  {
2731  NS_LOG_DEBUG ("Received legacy PHY header");
2732  WifiTxVector txVector = event->GetTxVector ();
2733  Time remainingPreambleHeaderDuration = CalculatePlcpPreambleAndHeaderDuration (txVector) - GetPlcpPreambleDuration (txVector) - GetPlcpHeaderDuration (txVector);
2734  m_endPlcpRxEvent = Simulator::Schedule (remainingPreambleHeaderDuration, &WifiPhy::StartReceivePayload, this, event);
2735  }
2736  else //legacy PHY header reception failed
2737  {
2738  NS_LOG_DEBUG ("Abort reception because legacy PHY header reception failed");
2740  }
2741 }
2742 
2743 void
2744 WifiPhy::StartReceivePreamble (Ptr<Packet> packet, double rxPowerW, Time rxDuration)
2745 {
2746  NS_LOG_FUNCTION (this << packet << rxPowerW << rxDuration);
2747  WifiPhyTag tag;
2748  bool found = packet->RemovePacketTag (tag);
2749  if (!found)
2750  {
2751  NS_FATAL_ERROR ("Received Wi-Fi Signal with no WifiPhyTag");
2752  return;
2753  }
2754 
2755  WifiPreamble preamble = tag.GetPreambleType ();
2756  WifiModulationClass modulation = tag.GetModulation ();
2757  WifiTxVector txVector;
2758  txVector.SetPreambleType (preamble);
2759  if ((modulation == WIFI_MOD_CLASS_DSSS) || (modulation == WIFI_MOD_CLASS_HR_DSSS))
2760  {
2761  DsssSigHeader dsssSigHdr;
2762  found = packet->RemoveHeader (dsssSigHdr);
2763  if (!found)
2764  {
2765  NS_FATAL_ERROR ("Received 802.11b signal with no SIG field");
2766  return;
2767  }
2768  txVector.SetChannelWidth (22);
2769  for (uint8_t i = 0; i < GetNModes (); i++)
2770  {
2771  WifiMode mode = GetMode (i);
2773  && (mode.GetDataRate (22) == dsssSigHdr.GetRate ()))
2774  {
2775  txVector.SetMode (mode);
2776  break;
2777  }
2778  }
2779  }
2780  else if ((modulation != WIFI_MOD_CLASS_HT) || (preamble != WIFI_PREAMBLE_HT_GF))
2781  {
2782  LSigHeader lSigHdr;
2783  found = packet->RemoveHeader (lSigHdr);
2784  if (!found)
2785  {
2786  NS_FATAL_ERROR ("Received OFDM 802.11 signal with no SIG field");
2787  return;
2788  }
2789  uint16_t channelWidth = GetChannelWidth ();
2790  txVector.SetChannelWidth (channelWidth > 20 ? 20 : channelWidth);
2791  for (uint8_t i = 0; i < GetNModes (); i++)
2792  {
2793  WifiMode mode = GetMode (i);
2794  if (mode.GetDataRate (GetChannelWidth ()) == lSigHdr.GetRate (GetChannelWidth ()))
2795  {
2796  txVector.SetMode (mode);
2797  break;
2798  }
2799  }
2800  }
2801  if (modulation == WIFI_MOD_CLASS_HT)
2802  {
2803  HtSigHeader htSigHdr;
2804  found = packet->RemoveHeader (htSigHdr);
2805  if (!found)
2806  {
2807  NS_FATAL_ERROR ("Received 802.11n signal with no HT-SIG field");
2808  return;
2809  }
2810  txVector.SetChannelWidth (htSigHdr.GetChannelWidth ());
2811  for (uint8_t i = 0; i < GetNMcs (); i++)
2812  {
2813  WifiMode mode = GetMcs (i);
2814  if ((mode.GetModulationClass () == WIFI_MOD_CLASS_HT) && (mode.GetMcsValue () == htSigHdr.GetMcs ()))
2815  {
2816  txVector.SetMode (mode);
2817  txVector.SetNss (1 + (txVector.GetMode ().GetMcsValue () / 8));
2818  break;
2819  }
2820  }
2821  txVector.SetGuardInterval(htSigHdr.GetShortGuardInterval () ? 400 : 800);
2822  txVector.SetAggregation (htSigHdr.GetAggregation ());
2823  }
2824  else if (modulation == WIFI_MOD_CLASS_VHT)
2825  {
2826  VhtSigHeader vhtSigHdr;
2827  vhtSigHdr.SetMuFlag (preamble == WIFI_PREAMBLE_VHT_MU);
2828  found = packet->RemoveHeader (vhtSigHdr);
2829  if (!found)
2830  {
2831  NS_FATAL_ERROR ("Received 802.11ac signal with no VHT-SIG field");
2832  return;
2833  }
2834  txVector.SetChannelWidth (vhtSigHdr.GetChannelWidth ());
2835  txVector.SetNss (vhtSigHdr.GetNStreams ());
2836  for (uint8_t i = 0; i < GetNMcs (); i++)
2837  {
2838  WifiMode mode = GetMcs (i);
2839  if ((mode.GetModulationClass () == WIFI_MOD_CLASS_VHT) && (mode.GetMcsValue () == vhtSigHdr.GetSuMcs ()))
2840  {
2841  txVector.SetMode (mode);
2842  break;
2843  }
2844  }
2845  txVector.SetGuardInterval (vhtSigHdr.GetShortGuardInterval () ? 400 : 800);
2846  if (IsAmpdu (packet))
2847  {
2848  txVector.SetAggregation (true);
2849  }
2850  }
2851  else if (modulation == WIFI_MOD_CLASS_HE)
2852  {
2853  HeSigHeader heSigHdr;
2854  heSigHdr.SetMuFlag (preamble == WIFI_PREAMBLE_HE_MU);
2855  found = packet->RemoveHeader (heSigHdr);
2856  if (!found)
2857  {
2858  NS_FATAL_ERROR ("Received 802.11ax signal with no HE-SIG field");
2859  return;
2860  }
2861  txVector.SetChannelWidth (heSigHdr.GetChannelWidth ());
2862  txVector.SetNss (heSigHdr.GetNStreams ());
2863  for (uint8_t i = 0; i < GetNMcs (); i++)
2864  {
2865  WifiMode mode = GetMcs (i);
2866  if ((mode.GetModulationClass () == WIFI_MOD_CLASS_HE) && (mode.GetMcsValue () == heSigHdr.GetMcs ()))
2867  {
2868  txVector.SetMode (mode);
2869  break;
2870  }
2871  }
2872  txVector.SetGuardInterval (heSigHdr.GetGuardInterval ());
2873  txVector.SetBssColor (heSigHdr.GetBssColor ());
2874  if (IsAmpdu (packet))
2875  {
2876  txVector.SetAggregation (true);
2877  }
2878  }
2879 
2880  Ptr<Event> event;
2881  event = m_interference.Add (packet,
2882  txVector,
2883  rxDuration,
2884  rxPowerW);
2885 
2886  if (m_state->GetState () == WifiPhyState::OFF)
2887  {
2888  NS_LOG_DEBUG ("Cannot start RX because device is OFF");
2889  return;
2890  }
2891 
2892  if (tag.GetFrameComplete () == 0)
2893  {
2894  NS_LOG_DEBUG ("Packet reception stopped because transmitter has been switched off");
2895  return;
2896  }
2897 
2898  if (!txVector.GetModeInitialized ())
2899  {
2900  //If SetRate method was not called above when filling in txVector, this means the PHY does support the rate indicated in PHY SIG headers
2901  NS_LOG_DEBUG ("drop packet because of unsupported RX mode");
2903  return;
2904  }
2905 
2906  Time endRx = Simulator::Now () + rxDuration;
2907  switch (m_state->GetState ())
2908  {
2910  NS_LOG_DEBUG ("drop packet because of channel switching");
2911  NotifyRxDrop (packet, NOT_ALLOWED);
2912  /*
2913  * Packets received on the upcoming channel are added to the event list
2914  * during the switching state. This way the medium can be correctly sensed
2915  * when the device listens to the channel for the first time after the
2916  * switching e.g. after channel switching, the channel may be sensed as
2917  * busy due to other devices' tramissions started before the end of
2918  * the switching.
2919  */
2920  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2921  {
2922  //that packet will be noise _after_ the completion of the channel switching.
2924  return;
2925  }
2926  break;
2927  case WifiPhyState::RX:
2928  NS_ASSERT (m_currentEvent != 0);
2929  if (m_frameCaptureModel != 0
2930  && m_frameCaptureModel->IsInCaptureWindow (m_timeLastPreambleDetected)
2931  && m_frameCaptureModel->CaptureNewFrame (m_currentEvent, event))
2932  {
2934  NS_LOG_DEBUG ("Switch to new packet");
2935  StartRx (event, rxPowerW, rxDuration);
2936  }
2937  else
2938  {
2939  NS_LOG_DEBUG ("Drop packet because already in Rx (power=" <<
2940  rxPowerW << "W)");
2941  NotifyRxDrop (packet, NOT_ALLOWED);
2942  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2943  {
2944  //that packet will be noise _after_ the reception of the currently-received packet.
2946  return;
2947  }
2948  }
2949  break;
2950  case WifiPhyState::TX:
2951  NS_LOG_DEBUG ("Drop packet because already in Tx (power=" <<
2952  rxPowerW << "W)");
2953  NotifyRxDrop (packet, NOT_ALLOWED);
2954  if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
2955  {
2956  //that packet will be noise _after_ the transmission of the currently-transmitted packet.
2958  return;
2959  }
2960  break;
2962  case WifiPhyState::IDLE:
2963  StartRx (event, rxPowerW, rxDuration);
2964  break;
2965  case WifiPhyState::SLEEP:
2966  NS_LOG_DEBUG ("Drop packet because in sleep mode");
2967  NotifyRxDrop (packet, NOT_ALLOWED);
2968  break;
2969  default:
2970  NS_FATAL_ERROR ("Invalid WifiPhy state.");
2971  break;
2972  }
2973 }
2974 
2975 void
2977 {
2978  //We are here because we have received the first bit of a packet and we are
2979  //not going to be able to synchronize on it
2980  //In this model, CCA becomes busy when the aggregation of all signals as
2981  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
2982 
2984  if (!delayUntilCcaEnd.IsZero ())
2985  {
2986  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
2987  }
2988 }
2989 
2990 void
2992 {
2993  NS_LOG_FUNCTION (this << event->GetPacket () << event->GetTxVector ());
2994  NS_ASSERT (IsStateRx ());
2997  WifiTxVector txVector = event->GetTxVector ();
2998  WifiMode txMode = txVector.GetMode ();
2999  bool canReceivePayload;
3001  {
3004  canReceivePayload = (m_random->GetValue () > snrPer.per);
3005  }
3006  else
3007  {
3008  //If we are here, this means legacy PHY header was already successfully received
3009  canReceivePayload = true;
3010  }
3011  if (canReceivePayload) //plcp reception succeeded
3012  {
3013  if (IsModeSupported (txMode) || IsMcsSupported (txMode))
3014  {
3015  Time payloadDuration = event->GetEndTime () - event->GetStartTime () - CalculatePlcpPreambleAndHeaderDuration (txVector);
3016  m_endRxEvent = Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event);
3017  NS_LOG_DEBUG ("Receiving payload");
3018  if (txMode.GetModulationClass () == WIFI_MOD_CLASS_HE)
3019  {
3020  HePreambleParameters params;
3021  params.rssiW = event->GetRxPowerW ();
3022  params.bssColor = event->GetTxVector ().GetBssColor ();
3023  NotifyEndOfHePreamble (params);
3024  }
3025  }
3026  else //mode is not allowed
3027  {
3028  NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txMode << ")");
3029  NotifyRxDrop (event->GetPacket (), UNSUPPORTED_SETTINGS);
3030  }
3031  }
3032  else //plcp reception failed
3033  {
3034  NS_LOG_DEBUG ("Drop packet because non-legacy PHY header reception failed");
3035  NotifyRxDrop (event->GetPacket (), SIG_A_FAILURE);
3036  }
3037 }
3038 
3039 void
3041 {
3042  Time psduDuration = event->GetEndTime () - event->GetStartTime ();
3043  NS_LOG_FUNCTION (this << event->GetPacket () << event->GetTxVector () << event << psduDuration);
3044  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
3045 
3046  double snr = m_interference.CalculateSnr (event);
3047  std::vector<bool> statusPerMpdu;
3048  SignalNoiseDbm signalNoise;
3049 
3050  Ptr<const Packet> packet = event->GetPacket ();
3051  Time relativeStart = NanoSeconds (0);
3052  bool receptionOkAtLeastForOneMpdu = true;
3053  std::pair<bool, SignalNoiseDbm> rxInfo;
3054  WifiTxVector txVector = event->GetTxVector ();
3055  if (txVector.IsAggregation ())
3056  {
3057  //Extract all MPDUs of the A-MPDU to compute per-MPDU PER stats
3058  //TODO remove PLCP header first
3059  std::list<Ptr<const Packet>> ampduSubframes = MpduAggregator::PeekAmpduSubframes (packet);
3060  size_t nbOfRemainingMpdus = ampduSubframes.size ();
3061  Time remainingAmpduDuration = event->GetEndTime () - event->GetStartTime ();
3062  MpduType mpdutype = (nbOfRemainingMpdus == 1) ? SINGLE_MPDU : FIRST_MPDU_IN_AGGREGATE;
3063  for (const auto & subframe : ampduSubframes)
3064  {
3065  Time mpduDuration = GetPayloadDuration (subframe->GetSize (), txVector, GetFrequency (), mpdutype, 1);
3066  remainingAmpduDuration -= mpduDuration;
3067  --nbOfRemainingMpdus;
3068  if (nbOfRemainingMpdus == 0 && !remainingAmpduDuration.IsZero ()) //no more MPDU coming
3069  {
3070  mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
3071  }
3072  rxInfo = GetReceptionStatus (MpduAggregator::PeekMpduInAmpduSubframe (subframe), event, relativeStart, mpduDuration);
3073  NS_LOG_DEBUG ("Extracted MPDU #" << ampduSubframes.size () - nbOfRemainingMpdus - 1 << ": duration: " << mpduDuration.GetNanoSeconds () << "ns" <<
3074  ", correct reception: " << rxInfo.first <<
3075  ", Signal/Noise: " << rxInfo.second.signal << "/" << rxInfo.second.noise << "dBm");
3076  signalNoise = rxInfo.second; //same information for all MPDUs
3077  statusPerMpdu.push_back (rxInfo.first);
3078  receptionOkAtLeastForOneMpdu |= rxInfo.first;
3079  relativeStart += mpduDuration;
3080  mpdutype = (nbOfRemainingMpdus == 1) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
3081  }
3082  }
3083  else
3084  {
3085  //Simple MPDU
3086  rxInfo = GetReceptionStatus (packet, event, relativeStart, psduDuration);
3087  signalNoise = rxInfo.second; //same information for all MPDUs
3088  statusPerMpdu.push_back (rxInfo.first);
3089  receptionOkAtLeastForOneMpdu = rxInfo.first;
3090  }
3091 
3092  if (receptionOkAtLeastForOneMpdu)
3093  {
3094  NotifyMonitorSniffRx (packet, GetFrequency (), txVector, signalNoise, statusPerMpdu);
3095  m_state->SwitchFromRxEndOk (packet->Copy (), snr, txVector, statusPerMpdu);
3096  }
3097  else
3098  {
3099  m_state->SwitchFromRxEndError (packet->Copy (), snr);
3100  }
3101 
3103  m_currentEvent = 0;
3104 }
3105 
3106 std::pair<bool, SignalNoiseDbm>
3107 WifiPhy::GetReceptionStatus (Ptr<const Packet> mpdu, Ptr<Event> event, Time relativeMpduStart, Time mpduDuration)
3108 {
3109  NS_LOG_FUNCTION (this << mpdu << event->GetTxVector () << event << relativeMpduStart << mpduDuration);
3111  snrPer = m_interference.CalculatePayloadSnrPer (event, std::make_pair (relativeMpduStart, relativeMpduStart + mpduDuration));
3112 
3113  NS_LOG_DEBUG ("mode=" << (event->GetTxVector ().GetMode ().GetDataRate (event->GetTxVector ())) <<
3114  ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << mpdu->GetSize () <<
3115  ", relativeStart = " << relativeMpduStart.GetNanoSeconds () << "ns, duration = " << mpduDuration.GetNanoSeconds () << "ns");
3116 
3117  // There are two error checks: PER and receive error model check.
3118  // PER check models is typical for Wi-Fi and is based on signal modulation;
3119  // Receive error model is optional, if we have an error model and
3120  // it indicates that the packet is corrupt, drop the packet.
3121  SignalNoiseDbm signalNoise;
3122  signalNoise.signal = WToDbm (event->GetRxPowerW ());
3123  signalNoise.noise = WToDbm (event->GetRxPowerW () / snrPer.snr);
3124  if (m_random->GetValue () > snrPer.per &&
3125  !(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (mpdu->Copy ())))
3126  {
3127  NS_LOG_DEBUG ("Reception succeeded: " << mpdu->ToString ());
3128  NotifyRxEnd (mpdu);
3129  return std::make_pair (true, signalNoise);
3130  }
3131  else
3132  {
3133  NS_LOG_DEBUG ("Reception failed: " << mpdu->ToString ());
3134  NotifyRxDrop (mpdu, ERRONEOUS_FRAME);
3135  return std::make_pair (false, signalNoise);
3136  }
3137 }
3138 
3139 void
3141 {
3142  NS_LOG_FUNCTION (this);
3144  {
3145  m_powerRestricted = false;
3146  }
3147 }
3148 
3149 void
3151 {
3152  NS_LOG_FUNCTION (this);
3153  m_channelAccessRequested = true;
3154 }
3155 
3156 // Clause 15 rates (DSSS)
3157 
3158 WifiMode
3160 {
3161  static WifiMode mode =
3162  WifiModeFactory::CreateWifiMode ("DsssRate1Mbps",
3164  true,
3166  2);
3167  return mode;
3168 }
3169 
3170 WifiMode
3172 {
3173  static WifiMode mode =
3174  WifiModeFactory::CreateWifiMode ("DsssRate2Mbps",
3176  true,
3178  4);
3179  return mode;
3180 }
3181 
3182 
3183 // Clause 18 rates (HR/DSSS)
3184 
3185 WifiMode
3187 {
3188  static WifiMode mode =
3189  WifiModeFactory::CreateWifiMode ("DsssRate5_5Mbps",
3191  true,
3193  16);
3194  return mode;
3195 }
3196 
3197 WifiMode
3199 {
3200  static WifiMode mode =
3201  WifiModeFactory::CreateWifiMode ("DsssRate11Mbps",
3203  true,
3205  256);
3206  return mode;
3207 }
3208 
3209 
3210 // Clause 19.5 rates (ERP-OFDM)
3211 
3212 WifiMode
3214 {
3215  static WifiMode mode =
3216  WifiModeFactory::CreateWifiMode ("ErpOfdmRate6Mbps",
3218  true,
3220  2);
3221  return mode;
3222 }
3223 
3224 WifiMode
3226 {
3227  static WifiMode mode =
3228  WifiModeFactory::CreateWifiMode ("ErpOfdmRate9Mbps",
3230  false,
3232  2);
3233  return mode;
3234 }
3235 
3236 WifiMode
3238 {
3239  static WifiMode mode =
3240  WifiModeFactory::CreateWifiMode ("ErpOfdmRate12Mbps",
3242  true,
3244  4);
3245  return mode;
3246 }
3247 
3248 WifiMode
3250 {
3251  static WifiMode mode =
3252  WifiModeFactory::CreateWifiMode ("ErpOfdmRate18Mbps",
3254  false,
3256  4);
3257  return mode;
3258 }
3259 
3260 WifiMode
3262 {
3263  static WifiMode mode =
3264  WifiModeFactory::CreateWifiMode ("ErpOfdmRate24Mbps",
3266  true,
3268  16);
3269  return mode;
3270 }
3271 
3272 WifiMode
3274 {
3275  static WifiMode mode =
3276  WifiModeFactory::CreateWifiMode ("ErpOfdmRate36Mbps",
3278  false,
3280  16);
3281  return mode;
3282 }
3283 
3284 WifiMode
3286 {
3287  static WifiMode mode =
3288  WifiModeFactory::CreateWifiMode ("ErpOfdmRate48Mbps",
3290  false,
3292  64);
3293  return mode;
3294 }
3295 
3296 WifiMode
3298 {
3299  static WifiMode mode =
3300  WifiModeFactory::CreateWifiMode ("ErpOfdmRate54Mbps",
3302  false,
3304  64);
3305  return mode;
3306 }
3307 
3308 
3309 // Clause 17 rates (OFDM)
3310 
3311 WifiMode
3313 {
3314  static WifiMode mode =
3315  WifiModeFactory::CreateWifiMode ("OfdmRate6Mbps",
3317  true,
3319  2);
3320  return mode;
3321 }
3322 
3323 WifiMode
3325 {
3326  static WifiMode mode =
3327  WifiModeFactory::CreateWifiMode ("OfdmRate9Mbps",
3329  false,
3331  2);
3332  return mode;
3333 }
3334 
3335 WifiMode
3337 {
3338  static WifiMode mode =
3339  WifiModeFactory::CreateWifiMode ("OfdmRate12Mbps",
3341  true,
3343  4);
3344  return mode;
3345 }
3346 
3347 WifiMode
3349 {
3350  static WifiMode mode =
3351  WifiModeFactory::CreateWifiMode ("OfdmRate18Mbps",
3353  false,
3355  4);
3356  return mode;
3357 }
3358 
3359 WifiMode
3361 {
3362  static WifiMode mode =
3363  WifiModeFactory::CreateWifiMode ("OfdmRate24Mbps",
3365  true,
3367  16);
3368  return mode;
3369 }
3370 
3371 WifiMode
3373 {
3374  static WifiMode mode =
3375  WifiModeFactory::CreateWifiMode ("OfdmRate36Mbps",
3377  false,
3379  16);
3380  return mode;
3381 }
3382 
3383 WifiMode
3385 {
3386  static WifiMode mode =
3387  WifiModeFactory::CreateWifiMode ("OfdmRate48Mbps",
3389  false,
3391  64);
3392  return mode;
3393 }
3394 
3395 WifiMode
3397 {
3398  static WifiMode mode =
3399  WifiModeFactory::CreateWifiMode ("OfdmRate54Mbps",
3401  false,
3403  64);
3404  return mode;
3405 }
3406 
3407 
3408 // 10 MHz channel rates
3409 
3410 WifiMode
3412 {
3413  static WifiMode mode =
3414  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW10MHz",
3416  true,
3418  2);
3419  return mode;
3420 }
3421 
3422 WifiMode
3424 {
3425  static WifiMode mode =
3426  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW10MHz",
3428  false,
3430  2);
3431  return mode;
3432 }
3433 
3434 WifiMode
3436 {
3437  static WifiMode mode =
3438  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW10MHz",
3440  true,
3442  4);
3443  return mode;
3444 }
3445 
3446 WifiMode
3448 {
3449  static WifiMode mode =
3450  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW10MHz",
3452  false,
3454  4);
3455  return mode;
3456 }
3457 
3458 WifiMode
3460 {
3461  static WifiMode mode =
3462  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW10MHz",
3464  true,
3466  16);
3467  return mode;
3468 }
3469 
3470 WifiMode
3472 {
3473  static WifiMode mode =
3474  WifiModeFactory::CreateWifiMode ("OfdmRate18MbpsBW10MHz",
3476  false,
3478  16);
3479  return mode;
3480 }
3481 
3482 WifiMode
3484 {
3485  static WifiMode mode =
3486  WifiModeFactory::CreateWifiMode ("OfdmRate24MbpsBW10MHz",
3488  false,
3490  64);
3491  return mode;
3492 }
3493 
3494 WifiMode
3496 {
3497  static WifiMode mode =
3498  WifiModeFactory::CreateWifiMode ("OfdmRate27MbpsBW10MHz",
3500  false,
3502  64);
3503  return mode;
3504 }
3505 
3506 
3507 // 5 MHz channel rates
3508 
3509 WifiMode
3511 {
3512  static WifiMode mode =
3513  WifiModeFactory::CreateWifiMode ("OfdmRate1_5MbpsBW5MHz",
3515  true,
3517  2);
3518  return mode;
3519 }
3520 
3521 WifiMode
3523 {
3524  static WifiMode mode =
3525  WifiModeFactory::CreateWifiMode ("OfdmRate2_25MbpsBW5MHz",
3527  false,
3529  2);
3530  return mode;
3531 }
3532 
3533 WifiMode
3535 {
3536  static WifiMode mode =
3537  WifiModeFactory::CreateWifiMode ("OfdmRate3MbpsBW5MHz",
3539  true,
3541  4);
3542  return mode;
3543 }
3544 
3545 WifiMode
3547 {
3548  static WifiMode mode =
3549  WifiModeFactory::CreateWifiMode ("OfdmRate4_5MbpsBW5MHz",
3551  false,
3553  4);
3554  return mode;
3555 }
3556 
3557 WifiMode
3559 {
3560  static WifiMode mode =
3561  WifiModeFactory::CreateWifiMode ("OfdmRate6MbpsBW5MHz",
3563  true,
3565  16);
3566  return mode;
3567 }
3568 
3569 WifiMode
3571 {
3572  static WifiMode mode =
3573  WifiModeFactory::CreateWifiMode ("OfdmRate9MbpsBW5MHz",
3575  false,
3577  16);
3578  return mode;
3579 }
3580 
3581 WifiMode
3583 {
3584  static WifiMode mode =
3585  WifiModeFactory::CreateWifiMode ("OfdmRate12MbpsBW5MHz",
3587  false,
3589  64);
3590  return mode;
3591 }
3592 
3593 WifiMode
3595 {
3596  static WifiMode mode =
3597  WifiModeFactory::CreateWifiMode ("OfdmRate13_5MbpsBW5MHz",
3599  false,
3601  64);
3602  return mode;
3603 }
3604 
3605 
3606 // Clause 20
3607 
3608 WifiMode
3610 {
3611  static WifiMode mcs =
3613  return mcs;
3614 }
3615 
3616 WifiMode
3618 {
3619  static WifiMode mcs =
3621  return mcs;
3622 }
3623 
3624 WifiMode
3626 {
3627  static WifiMode mcs =
3629  return mcs;
3630 }
3631 
3632 WifiMode
3634 {
3635  static WifiMode mcs =
3637  return mcs;
3638 }
3639 
3640 WifiMode
3642 {
3643  static WifiMode mcs =
3645  return mcs;
3646 }
3647 
3648 WifiMode
3650 {
3651  static WifiMode mcs =
3653  return mcs;
3654 }
3655 
3656 WifiMode
3658 {
3659  static WifiMode mcs =
3661  return mcs;
3662 }
3663 
3664 WifiMode
3666 {
3667  static WifiMode mcs =
3669  return mcs;
3670 }
3671 
3672 WifiMode
3674 {
3675  static WifiMode mcs =
3677  return mcs;
3678 }
3679 
3680 WifiMode
3682 {
3683  static WifiMode mcs =
3685  return mcs;
3686 }
3687 
3688 WifiMode
3690 {
3691  static WifiMode mcs =
3693  return mcs;
3694 }
3695 
3696 WifiMode
3698 {
3699  static WifiMode mcs =
3701  return mcs;
3702 }
3703 
3704 WifiMode
3706 {
3707  static WifiMode mcs =
3709  return mcs;
3710 }
3711 
3712 WifiMode
3714 {
3715  static WifiMode mcs =
3717  return mcs;
3718 }
3719 
3720 WifiMode
3722 {
3723  static WifiMode mcs =
3725  return mcs;
3726 }
3727 
3728 WifiMode
3730 {
3731  static WifiMode mcs =
3733  return mcs;
3734 }
3735 
3736 WifiMode
3738 {
3739  static WifiMode mcs =
3741  return mcs;
3742 }
3743 
3744 WifiMode
3746 {
3747  static WifiMode mcs =
3749  return mcs;
3750 }
3751 
3752 WifiMode
3754 {
3755  static WifiMode mcs =
3757  return mcs;
3758 }
3759 
3760 WifiMode
3762 {
3763  static WifiMode mcs =
3765  return mcs;
3766 }
3767 
3768 WifiMode
3770 {
3771  static WifiMode mcs =
3773  return mcs;
3774 }
3775 
3776 WifiMode
3778 {
3779  static WifiMode mcs =
3781  return mcs;
3782 }
3783 
3784 WifiMode
3786 {
3787  static WifiMode mcs =
3789  return mcs;
3790 }
3791 
3792 WifiMode
3794 {
3795  static WifiMode mcs =
3797  return mcs;
3798 }
3799 
3800 WifiMode
3802 {
3803  static WifiMode mcs =
3805  return mcs;
3806 }
3807 
3808 WifiMode
3810 {
3811  static WifiMode mcs =
3813  return mcs;
3814 }
3815 
3816 WifiMode
3818 {
3819  static WifiMode mcs =
3821  return mcs;
3822 }
3823 
3824 WifiMode
3826 {
3827  static WifiMode mcs =
3829  return mcs;
3830 }
3831 
3832 WifiMode
3834 {
3835  static WifiMode mcs =
3837  return mcs;
3838 }
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 
3865 // Clause 22
3866 
3867 WifiMode
3869 {
3870  static WifiMode mcs =
3872  return mcs;
3873 }
3874 
3875 WifiMode
3877 {
3878  static WifiMode mcs =
3880  return mcs;
3881 }
3882 
3883 WifiMode
3885 {
3886  static WifiMode mcs =
3888  return mcs;
3889 }
3890 
3891 WifiMode
3893 {
3894  static WifiMode mcs =
3896  return mcs;
3897 }
3898 
3899 WifiMode
3901 {
3902  static WifiMode mcs =
3904  return mcs;
3905 }
3906 
3907 WifiMode
3909 {
3910  static WifiMode mcs =
3912  return mcs;
3913 }
3914 
3915 WifiMode
3917 {
3918  static WifiMode mcs =
3920  return mcs;
3921 }
3922 
3923 WifiMode
3925 {
3926  static WifiMode mcs =
3928  return mcs;
3929 }
3930 
3931 WifiMode
3933 {
3934  static WifiMode mcs =
3936  return mcs;
3937 }
3938 
3939 WifiMode
3941 {
3942  static WifiMode mcs =
3944  return mcs;
3945 }
3946 
3947 // Clause 26
3948 
3949 WifiMode
3951 {
3952  static WifiMode mcs =
3954  return mcs;
3955 }
3956 
3957 WifiMode
3959 {
3960  static WifiMode mcs =
3962  return mcs;
3963 }
3964 
3965 WifiMode
3967 {
3968  static WifiMode mcs =
3970  return mcs;
3971 }
3972 
3973 WifiMode
3975 {
3976  static WifiMode mcs =
3978  return mcs;
3979 }
3980 
3981 WifiMode
3983 {
3984  static WifiMode mcs =
3986  return mcs;
3987 }
3988 
3989 WifiMode
3991 {
3992  static WifiMode mcs =
3994  return mcs;
3995 }
3996 
3997 WifiMode
3999 {
4000  static WifiMode mcs =
4002  return mcs;
4003 }
4004 
4005 WifiMode
4007 {
4008  static WifiMode mcs =
4010  return mcs;
4011 }
4012 
4013 WifiMode
4015 {
4016  static WifiMode mcs =
4018  return mcs;
4019 }
4020 
4021 WifiMode
4023 {
4024  static WifiMode mcs =
4026  return mcs;
4027 }
4028 
4029 WifiMode
4031 {
4032  static WifiMode mcs =
4034  return mcs;
4035 }
4036 
4037 WifiMode
4039 {
4040  static WifiMode mcs =
4042  return mcs;
4043 }
4044 
4045 bool
4047 {
4048  for (uint8_t i = 0; i < GetNModes (); i++)
4049  {
4050  if (mode == GetMode (i))
4051  {
4052  return true;
4053  }
4054  }
4055  return false;
4056 }
4057 
4058 bool
4060 {
4061  for (uint8_t i = 0; i < GetNMcs (); i++)
4062  {
4063  if (mcs == GetMcs (i))
4064  {
4065  return true;
4066  }
4067  }
4068  return false;
4069 }
4070 
4071 uint8_t
4073 {
4074  return static_cast<uint8_t> (m_deviceRateSet.size ());
4075 }
4076 
4077 WifiMode
4078 WifiPhy::GetMode (uint8_t mode) const
4079 {
4080  return m_deviceRateSet[mode];
4081 }
4082 
4083 uint8_t
4084 WifiPhy::GetNMcs (void) const
4085 {
4086  return static_cast<uint8_t> (m_deviceMcsSet.size ());
4087 }
4088 
4089 WifiMode
4090 WifiPhy::GetMcs (uint8_t mcs) const
4091 {
4092  return m_deviceMcsSet[mcs];
4093 }
4094 
4095 bool
4097 {
4098  return m_state->IsStateCcaBusy ();
4099 }
4100 
4101 bool
4103 {
4104  return m_state->IsStateIdle ();
4105 }
4106 
4107 bool
4109 {
4110  return m_state->IsStateRx ();
4111 }
4112 
4113 bool
4115 {
4116  return m_state->IsStateTx ();
4117 }
4118 
4119 bool
4121 {
4122  return m_state->IsStateSwitching ();
4123 }
4124 
4125 bool
4127 {
4128  return m_state->IsStateSleep ();
4129 }
4130 
4131 bool
4133 {
4134  return m_state->IsStateOff ();
4135 }
4136 
4137 Time
4139 {
4140  return m_state->GetDelayUntilIdle ();
4141 }
4142 
4143 Time
4145 {
4146  return m_state->GetLastRxStartTime ();
4147 }
4148 
4149 void
4151 {
4152  NS_LOG_FUNCTION (this);
4153  //We are here because we have received the first bit of a packet and we are
4154  //not going to be able to synchronize on it
4155  //In this model, CCA becomes busy when the aggregation of all signals as
4156  //tracked by the InterferenceHelper class is higher than the CcaBusyThreshold
4157 
4159  if (!delayUntilCcaEnd.IsZero ())
4160  {
4161  NS_LOG_DEBUG ("Calling SwitchMaybeToCcaBusy for " << delayUntilCcaEnd.As (Time::S));
4162  m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
4163  }
4164 }
4165 
4166 void
4168 {
4169  NS_LOG_FUNCTION (this << reason);
4171  {
4173  }
4174  if (m_endPlcpRxEvent.IsRunning ())
4175  {
4177  }
4178  if (m_endRxEvent.IsRunning ())
4179  {
4180  m_endRxEvent.Cancel ();
4181  }
4182  NotifyRxDrop (m_currentEvent->GetPacket (), reason);
4184  bool is_failure = (reason != OBSS_PD_CCA_RESET);
4185  m_state->SwitchFromRxAbort (is_failure);
4186  m_currentEvent = 0;
4187 }
4188 
4189 void
4190 WifiPhy::ResetCca (bool powerRestricted, double txPowerMaxSiso, double txPowerMaxMimo)
4191 {
4192  NS_LOG_FUNCTION (this << powerRestricted << txPowerMaxSiso << txPowerMaxMimo);
4193  m_powerRestricted = powerRestricted;
4194  m_txPowerMaxSiso = txPowerMaxSiso;
4195  m_txPowerMaxMimo = txPowerMaxMimo;
4196  NS_ASSERT ((m_currentEvent->GetEndTime () - Simulator::Now ()).IsPositive ());
4199 }
4200 
4201 double
4203 {
4205  if (!m_powerRestricted)
4206  {
4207  return GetPowerDbm (txVector.GetTxPowerLevel ());
4208  }
4209  else
4210  {
4211  if (txVector.GetNss () > 1)
4212  {
4213  return std::min (m_txPowerMaxMimo, GetPowerDbm (txVector.GetTxPowerLevel ()));
4214  }
4215  else
4216  {
4217  return std::min (m_txPowerMaxSiso, GetPowerDbm (txVector.GetTxPowerLevel ()));
4218  }
4219  }
4220 }
4221 
4222 void
4223 WifiPhy::StartRx (Ptr<Event> event, double rxPowerW, Time rxDuration)
4224 {
4225  NS_LOG_FUNCTION (this << event->GetPacket () << event->GetTxVector () << event << rxPowerW << rxDuration);
4226 
4227  NS_LOG_DEBUG ("sync to signal (power=" << rxPowerW << "W)");
4228  m_interference.NotifyRxStart (); //We need to notify it now so that it starts recording events
4229 
4231  {
4232  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4233  Time remainingRxDuration = rxDuration - startOfPreambleDuration;
4235  event, remainingRxDuration);
4236  }
4237  else if ((m_frameCaptureModel != 0) && (rxPowerW > m_currentEvent->GetRxPowerW ()))
4238  {
4239  NS_LOG_DEBUG ("Received a stronger signal during preamble detection: drop current packet and switch to new packet");
4244  Time startOfPreambleDuration = GetPreambleDetectionDuration ();
4245  Time remainingRxDuration = rxDuration - startOfPreambleDuration;
4247  event, remainingRxDuration);
4248  }
4249  else
4250  {
4251  NS_LOG_DEBUG ("Drop packet because RX is already decoding preamble");
4252  NotifyRxDrop (event->GetPacket (), NOT_ALLOWED);
4253  return;
4254  }
4255  m_currentEvent = event;
4256 }
4257 
4258 int64_t
4259 WifiPhy::AssignStreams (int64_t stream)
4260 {
4261  NS_LOG_FUNCTION (this << stream);
4262  m_random->SetStream (stream);
4263  return 1;
4264 }
4265 
4266 std::ostream& operator<< (std::ostream& os, WifiPhyState state)
4267 {
4268  switch (state)
4269  {
4270  case WifiPhyState::IDLE:
4271  return (os << "IDLE");
4273  return (os << "CCA_BUSY");
4274  case WifiPhyState::TX:
4275  return (os << "TX");
4276  case WifiPhyState::RX:
4277  return (os << "RX");
4279  return (os << "SWITCHING");
4280  case WifiPhyState::SLEEP:
4281  return (os << "SLEEP");
4282  case WifiPhyState::OFF:
4283  return (os << "OFF");
4284  default:
4285  NS_FATAL_ERROR ("Invalid WifiPhy state");
4286  return (os << "INVALID");
4287  }
4288 }
4289 
4290 } //namespace ns3
4291 
4292 namespace {
4293 
4297 static class Constructor
4298 {
4299 public:
4301  {
4392  }
4393 } g_constructor;
4394 
4395 }
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:71
static WifiMode GetVhtMcs6()
Return MCS 6 from VHT MCS values.
Definition: wifi-phy.cc:3916
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
static WifiMode GetOfdmRate9MbpsBW5MHz()
Return a WifiMode for OFDM at 9Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3570
uint16_t GetChannelWidth(void) const
Return the channel width (in MHz).
TracedCallback< Ptr< const Packet > > m_phyRxBeginTrace
The trace source fired when a packet begins the reception process from the medium.
Definition: wifi-phy.h:1782
Ptr< NetDevice > m_device
Pointer to the device.
Definition: wifi-phy.h:1916
static WifiMode GetErpOfdmRate24Mbps()
Return a WifiMode for ERP-OFDM at 24Mbps.
Definition: wifi-phy.cc:3261
uint8_t GetNTxPower(void) const
Return the number of available transmission power levels.
Definition: wifi-phy.cc:580
uint32_t m_txMpduReferenceNumber
A-MPDU reference number to identify all transmitted subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1614
bool IsStateSwitching(void) const
Definition: wifi-phy.cc:4120
static WifiMode GetDsssRate11Mbps()
Return a WifiMode for DSSS at 11Mbps.
Definition: wifi-phy.cc:3198
bool IsStateOff(void) const
Definition: wifi-phy.cc:4132
struct InterferenceHelper::SnrPer CalculateNonLegacyPhyHeaderSnrPer(Ptr< Event > event) const
Calculate the SNIR at the start of the non-legacy PHY header and accumulate all SNIR changes in the s...
double signal
in dBm
Definition: wifi-phy.h:66
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:4006
std::pair< uint8_t, WifiPhyStandard > ChannelNumberStandardPair
A pair of a ChannelNumber and WifiPhyStandard.
Definition: wifi-phy.h:547
static WifiMode GetErpOfdmRate36Mbps()
Return a WifiMode for ERP-OFDM at 36Mbps.
Definition: wifi-phy.cc:3273
Signal event for a packet.
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:573
uint8_t m_channelNumber
Operating channel number.
Definition: wifi-phy.h:1909
double m_rxGainDb
Reception gain (dB)
Definition: wifi-phy.h:1885
bool DefineChannelNumber(uint8_t channelNumber, WifiPhyStandard standard, uint16_t frequency, uint16_t channelWidth)
Add a channel definition to the WifiPhy.
Definition: wifi-phy.cc:1122
static WifiMode GetVhtMcs8()
Return MCS 8 from VHT MCS values.
Definition: wifi-phy.cc:3932
ERP-OFDM PHY (19.5)
Definition: wifi-mode.h:54
void SetMcs(uint8_t mcs)
Fill the MCS field of HT-SIG.
void SetShortPlcpPreambleSupported(bool preamble)
Enable or disable short PLCP preamble.
Definition: wifi-phy.cc:706
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:606
bool IsModeSupported(WifiMode mode) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:4046
void SendPacket(Ptr< const Packet > packet, WifiTxVector txVector)
Definition: wifi-phy.cc:2516
static WifiMode GetOfdmRate9Mbps()
Return a WifiMode for OFDM at 9Mbps.
Definition: wifi-phy.cc:3324
double GetCcaEdThreshold(void) const
Return the CCA threshold (dBm).
Definition: wifi-phy.cc:533
void StartReceiveHeader(Ptr< Event > event, Time rxDuration)
Start receiving the PHY header of a packet (i.e.
Definition: wifi-phy.cc:2668
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:3471
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:3495
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo, SignalNoiseDbm > m_phyMonitorSniffRxTrace
A trace source that emulates a wifi device in monitor mode sniffing a packet being received...
Definition: wifi-phy.h:1811
double m_txGainDb
Transmission gain (dB)
Definition: wifi-phy.h:1884
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:4090
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of VHT-SIG-A1 (in MHz).
static WifiMode GetOfdmRate3MbpsBW5MHz()
Return a WifiMode for OFDM at 3Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3534
static WifiMode GetVhtMcs0()
Return MCS 0 from VHT MCS values.
Definition: wifi-phy.cc:3868
void AbortCurrentReception(WifiPhyRxfailureReason reason)
Due to newly arrived signal, the current reception cannot be continued and has to be aborted...
Definition: wifi-phy.cc:4167
void MaybeCcaBusyDuration(void)
Eventually switch to CCA busy.
Definition: wifi-phy.cc:2976
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
WifiPhyStandard GetStandard(void) const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1274
virtual ~WifiPhy()
Definition: wifi-phy.cc:408
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
static WifiMode GetDsssRate1Mbps()
Return a WifiMode for DSSS at 1Mbps.
Definition: wifi-phy.cc:3159
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
void ResumeFromOff(void)
Resume from off mode.
Definition: wifi-phy.cc:1711
Ptr< WifiPhyStateHelper > GetState(void) const
Return the WifiPhyStateHelper of this PHY.
Definition: wifi-phy.cc:443
void ResumeFromSleep(void)
Resume from sleep mode.
Definition: wifi-phy.cc:1681
#define min(a, b)
Definition: 80211b.c:42
double m_rxSensitivityW
Receive sensitivity threshold in watts.
Definition: wifi-phy.h:1882
bool GetShortGuardInterval(void) const
Return whether short guard interval is supported.
Definition: wifi-phy.cc:659
uint16_t GetChannelWidth(void) const
Return the channel width (in MHz).
void SetBssColor(uint8_t color)
Set the BSS color.
bool GetGreenfield(void) const
Return whether Greenfield is supported.
Definition: wifi-phy.cc:628
static WifiMode GetHeMcs5()
Return MCS 5 from HE MCS values.
Definition: wifi-phy.cc:3990
void SetMuFlag(bool mu)
Set the Multi-User (MU) flag.
Time m_timeLastPreambleDetected
Record the time the last preamble was detected.
Definition: wifi-phy.h:1924
static WifiMode GetErpOfdmRate18Mbps()
Return a WifiMode for ERP-OFDM at 18Mbps.
Definition: wifi-phy.cc:3249
void SetTxGain(double gain)
Sets the transmission gain (dB).
Definition: wifi-phy.cc:586
void Configure80211ax(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ax standard...
Definition: wifi-phy.cc:1093
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:3665
void SetRxSensitivity(double threshold)
Sets the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:513
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:84
virtual void DoDispose(void)
Destructor implementation.
Definition: wifi-phy.cc:414
void SetNStreams(uint8_t nStreams)
Fill the number of streams field of HE-SIG-A1.
static Ptr< const Packet > PeekMpduInAmpduSubframe(Ptr< const Packet > ampduSubframe)
Peeks the MPDU contained in the A-MPDU subframe.
def start()
Definition: core.py:1858
bool Is2_4Ghz(double frequency)
Definition: wifi-utils.cc:59
static Time GetPlcpHtSigHeaderDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1815
static WifiMode GetVhtMcs5()
Return MCS 5 from VHT MCS values.
Definition: wifi-phy.cc:3908
uint8_t GetNBssMembershipSelectors(void) const
The WifiPhy::NBssMembershipSelectors() method is used (e.g., by a WifiRemoteStationManager) to determ...
Definition: wifi-phy.cc:1414
The PHY layer is sleeping.
static WifiMode GetHtMcs22()
Return MCS 22 from HT MCS values.
Definition: wifi-phy.cc:3785
static WifiMode GetHtMcs14()
Return MCS 14 from HT MCS values.
Definition: wifi-phy.cc:3721
static WifiMode GetOfdmRate12Mbps()
Return a WifiMode for OFDM at 12Mbps.
Definition: wifi-phy.cc:3336
TracedCallback< Ptr< const Packet > > m_phyRxEndTrace
The trace source fired when a packet ends the reception process from the medium.
Definition: wifi-phy.h:1790
Implements the IEEE 802.11ac PHY header (VHT-SIG-A1/A2/B).
#define HE_PHY
Definition: wifi-phy.h:35
bool IsStateCcaBusy(void) const
Definition: wifi-phy.cc:4096
void SetReceiveErrorCallback(RxErrorCallback callback)
Definition: wifi-phy.cc:455
static WifiMode GetHtMcs31()
Return MCS 31 from HT MCS values.
Definition: wifi-phy.cc:3857
static WifiMode GetHtMcs21()
Return MCS 21 from HT MCS values.
Definition: wifi-phy.cc:3777
#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
static WifiMode GetHtMcs30()
Return MCS 30 from HT MCS values.
Definition: wifi-phy.cc:3849
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
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:1873
HE PHY for the 2.4 GHz band (clause 26)
static WifiMode GetHtMcs10()
Return MCS 10 from HT MCS values.
Definition: wifi-phy.cc:3689
static WifiMode GetHtMcs26()
Return MCS 26 from HT MCS values.
Definition: wifi-phy.cc:3817
static WifiMode GetOfdmRate1_5MbpsBW5MHz()
Return a WifiMode for OFDM at 1.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3510
void StartRx(Ptr< Event > event, double rxPowerW, Time rxDuration)
Starting receiving the packet after having detected the medium is idle or after a reception switch...
Definition: wifi-phy.cc:4223
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:3745
static WifiMode GetHtMcs24()
Return MCS 24 from HT MCS values.
Definition: wifi-phy.cc:3801
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:3423
bool GetModeInitialized(void) const
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54Mbps.
Definition: wifi-phy.cc:3396
void SetMobility(const Ptr< MobilityModel > mobility)
assign a mobility model to this device
Definition: wifi-phy.cc:743
uint16_t GetChannelWidth(void) const
Return the channel width (in MHz).
void UnregisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:467
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:539
#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:308
static WifiMode GetHeMcs4()
Return MCS 4 from HE MCS values.
Definition: wifi-phy.cc:3982
uint8_t GetNess(void) const
void SetShortGuardIntervalDisambiguation(bool disambiguation)
Fill the short GI NSYM disambiguation field of VHT-SIG-A2.
void ConfigureHolland(void)
Configure WifiPhy with appropriate channel frequency and supported rates for holland.
Definition: wifi-phy.cc:975
bool IsStateIdle(void) const
Definition: wifi-phy.cc:4102
uint16_t GetGuardInterval(void) const
bool Is5Ghz(double frequency)
Definition: wifi-utils.cc:65
void SetRate(uint64_t rate, uint16_t channelWidth=20)
Fill the RATE field of L-SIG (in bit/s).
void NotifyTxDrop(Ptr< const Packet > packet)
Public method used to fire a PhyTxDrop trace.
Definition: wifi-phy.cc:2384
HT PHY for the 2.4 GHz band (clause 20)
void SetGreenfield(bool greenfield)
Enable or disable Greenfield support.
Definition: wifi-phy.cc:612
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:945
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
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:1797
void SetBssColor(uint8_t bssColor)
Fill the BSS Color field of HE-SIG-A1.
HR/DSSS PHY (Clause 18)
Definition: wifi-mode.h:48
void SetRate(uint64_t rate)
Fill the RATE field of L-SIG (in bit/s).
std::pair< uint16_t, uint16_t > FrequencyWidthPair
A pair of a center Frequency and a ChannelWidth.
Definition: wifi-phy.h:551
static WifiMode GetHtMcs8()
Return MCS 8 from HT MCS values.
Definition: wifi-phy.cc:3673
uint8_t m_nTxPower
Number of available transmission power levels.
Definition: wifi-phy.h:1888
static WifiMode GetHtMcs18()
Return MCS 18 from HT MCS values.
Definition: wifi-phy.cc:3753
double GetTxPowerForTransmission(WifiTxVector txVector) const
Compute the transmit power (in dBm) for the next transmission.
Definition: wifi-phy.cc:4202
virtual void SetFrequency(uint16_t freq)
Definition: wifi-phy.cc:1280
static WifiMode GetVhtMcs4()
Return MCS 4 from VHT MCS values.
Definition: wifi-phy.cc:3900
static WifiMode GetHtMcs27()
Return MCS 27 from HT MCS values.
Definition: wifi-phy.cc:3825
void SetFrameCaptureModel(const Ptr< FrameCaptureModel > frameCaptureModel)
Sets the frame capture model.
Definition: wifi-phy.cc:776
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:4190
TracedCallback< Ptr< const Packet >, uint16_t, WifiTxVector, MpduInfo > m_phyMonitorSniffTxTrace
A trace source that emulates a wifi device in monitor mode sniffing a packet being transmitted...
Definition: wifi-phy.h:1825
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:3372
uint8_t m_initialChannelNumber
Initial channel number.
Definition: wifi-phy.h:1910
static WifiMode GetVhtMcs7()
Return MCS 7 from VHT MCS values.
Definition: wifi-phy.cc:3924
static WifiMode GetOfdmRate6MbpsBW5MHz()
Return a WifiMode for OFDM at 6Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3558
bool IsStateSleep(void) const
Definition: wifi-phy.cc:4126
void NotifyEndOfHePreamble(HePreambleParameters params)
Public method used to fire a EndOfHePreamble trace once both HE SIG fields have been received...
Definition: wifi-phy.cc:2510
void NotifyRxDrop(Ptr< const Packet > packet, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:2435
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
static WifiMode GetVhtMcs3()
Return MCS 3 from VHT MCS values.
Definition: wifi-phy.cc:3892
void ConfigureDefaultsForStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:824
uint8_t GetMcs(void) const
Return the MCS field of HE-SIG-A1.
static Time GetPlcpSigA1Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1830
MpduType
The type of an MPDU.
double GetRxSensitivity(void) const
Return the receive sensitivity threshold (dBm).
Definition: wifi-phy.cc:520
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:1871
void NotifyMonitorSniffRx(Ptr< const Packet > packet, uint16_t channelFreqMhz, WifiTxVector txVector, SignalNoiseDbm signalNoise, std::vector< bool > statusPerMpdu)
Public method used to fire a MonitorSniffer trace for a wifi packet being received.
Definition: wifi-phy.cc:2452
mobility
Definition: third.py:101
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
uint16_t m_channelCenterFrequency
Center frequency in MHz.
Definition: wifi-phy.h:1877
void SetDevice(const Ptr< NetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-phy.cc:719
bool GetShortPlcpPreambleSupported(void) const
Return whether short PLCP preamble is supported.
Definition: wifi-phy.cc:713
static WifiMode GetHtMcs16()
Return MCS 16 from HT MCS values.
Definition: wifi-phy.cc:3737
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1357
bool m_powerRestricted
Flag whether transmit power is retricted by OBSS PD SR.
Definition: wifi-phy.h:1890
static WifiMode GetErpOfdmRate54Mbps()
Return a WifiMode for ERP-OFDM at 54Mbps.
Definition: wifi-phy.cc:3297
WifiPreamble GetPreambleType(void) const
void AddSupportedChannelWidth(uint16_t channelwidth)
Definition: wifi-phy.cc:1426
static WifiMode GetHtMcs29()
Return MCS 29 from HT MCS values.
Definition: wifi-phy.cc:3841
static WifiMode GetHtMcs11()
Return MCS 11 from HT MCS values.
Definition: wifi-phy.cc:3697
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:4084
Time CalculateTxDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2344
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Definition: wifi-preamble.h:30
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:1906
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:80
uint8_t bssColor
BSS color.
Definition: wifi-phy.h:81
The MPDU is the first aggregate in an A-MPDU with multiple MPDUs, but is not the last aggregate...
static Time GetPlcpSigA2Duration(WifiPreamble preamble)
Definition: wifi-phy.cc:1847
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:1575
static WifiMode GetHtMcs2()
Return MCS 2 from HT MCS values.
Definition: wifi-phy.cc:3625
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:220
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1389
void SetMcs(uint8_t mcs)
Fill the MCS field of HE-SIG-A1.
Ptr< MobilityModel > m_mobility
Pointer to the mobility model.
Definition: wifi-phy.h:1917
bool IsZero(void) const
Definition: nstime.h:288
virtual void StartTx(Ptr< Packet > packet, WifiTxVector txVector, Time txDuration)=0
void SetNStreams(uint8_t nStreams)
Fill the number of streams field of VHT-SIG-A1.
AttributeValue implementation for Time.
Definition: nstime.h:1124
static std::list< Ptr< const Packet > > PeekMpdus(Ptr< const Packet > aggregatedPacket)
Peeks the MPDUs of the provided A-MPDU.
static Time GetPlcpPreambleDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1995
void SetSuMcs(uint8_t mcs)
Fill the SU VHT MCS field of VHT-SIG-A2.
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1086
receive notifications about phy events.
std::pair< bool, SignalNoiseDbm > GetReceptionStatus(Ptr< const Packet > mpdu, Ptr< Event > event, Time relativeMpduStart, Time mpduDuration)
Get the reception status for the provided MPDU and notify.
Definition: wifi-phy.cc:3107
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:1774
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
Time GetEnergyDuration(double energyW) const
double m_txPowerMaxMimo
MIMO maximum transmit power due to OBSS PD SR power restriction.
Definition: wifi-phy.h:1892
bool m_shortPreamble
Flag if short PLCP preamble is supported.
Definition: wifi-phy.h:1897
Ptr< Event > Add(Ptr< const Packet > packet, WifiTxVector txVector, Time duration, double rxPower)
Add the packet-related signal to interference helper.
static WifiMode GetHeMcs3()
Return MCS 3 from HE MCS values.
Definition: wifi-phy.cc:3974
void NotifyMonitorSniffTx(Ptr< const Packet > packet, uint16_t channelFreqMhz, WifiTxVector txVector)
Public method used to fire a MonitorSniffer trace for a wifi packet being transmitted.
Definition: wifi-phy.cc:2484
static Time GetPlcpSigBDuration(WifiPreamble preamble)
Definition: wifi-phy.cc:1864
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:688
bool GetShortGuardInterval(void) const
Return the short guard interval field of HT-SIG.
EventId m_endPlcpRxEvent
the end of PLCP receive event
Definition: wifi-phy.h:1618
static WifiMode GetHtMcs12()
Return MCS 12 from HT MCS values.
Definition: wifi-phy.cc:3705
Ptr< WifiRadioEnergyModel > m_wifiRadioEnergyModel
Wifi radio energy model.
Definition: wifi-phy.h:1922
static WifiMode GetErpOfdmRate48Mbps()
Return a WifiMode for ERP-OFDM at 48Mbps.
Definition: wifi-phy.cc:3285
static Time CalculatePlcpPreambleAndHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:2321
void SetTxPowerEnd(double end)
Sets the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:560
void SetPreambleDetectionModel(const Ptr< PreambleDetectionModel > preambleDetectionModel)
Sets the preamble detection model.
Definition: wifi-phy.cc:782
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:3459
std::string ToString(void) const
Return a string representation of the packet.
Definition: packet.cc:426
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:3150
WifiMode GetMode(void) const
static WifiMode GetHeMcs11()
Return MCS 11 from HE MCS values.
Definition: wifi-phy.cc:4038
The PHY layer has sense the medium busy through the CCA mechanism.
Implements the IEEE 802.11 OFDM and ERP OFDM L-SIG PHY header.
HT PHY (Clause 20)
Definition: wifi-mode.h:58
Time GetDelayUntilIdle(void)
Definition: wifi-phy.cc:4138
uint32_t m_rxMpduReferenceNumber
A-MPDU reference number to identify all received subframes belonging to the same received A-MPDU...
Definition: wifi-phy.h:1615
void SetMuFlag(bool mu)
Set the Multi-User (MU) flag.
WifiPreamble GetPreambleType(void) const
Getter for preamble parameter.
Definition: wifi-phy-tag.cc:80
void Configure80211_5Mhz()
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard with 5M...
Definition: wifi-phy.cc:960
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard(uint8_t channelNumber, WifiPhyStandard standard) const
Lookup frequency/width pair for channelNumber/standard pair.
Definition: wifi-phy.cc:1447
TracedCallback< HePreambleParameters > m_phyEndOfHePreambleTrace
A trace source that indiates the end of both HE SIG fields as well as training fields for received 80...
Definition: wifi-phy.h:1832
uint8_t GetNStreams(void) const
Return the number of streams.
struct InterferenceHelper::SnrPer CalculateLegacyPhyHeaderSnrPer(Ptr< Event > event) const
Calculate the SNIR at the start of the legacy PHY header and accumulate all SNIR changes in the snir ...
double CalculateSnr(WifiTxVector txVector, double ber) const
Definition: wifi-phy.cc:818
void NotifyRxBegin(Ptr< const Packet > packet)
Public method used to fire a PhyRxBegin trace.
Definition: wifi-phy.cc:2401
static WifiMode GetOfdmRate18Mbps()
Return a WifiMode for OFDM at 18Mbps.
Definition: wifi-phy.cc:3348
void SetCapabilitiesChangedCallback(Callback< void > callback)
Definition: wifi-phy.cc:473
void SetOffMode(void)
Put in off mode.
Definition: wifi-phy.cc:1669
void SetLength(uint16_t length)
Fill the LENGTH field of L-SIG (in bytes).
static WifiMode GetOfdmRate9MbpsBW10MHz()
Return a WifiMode for OFDM at 9Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3447
uint8_t GetNStreams(void) const
Return the number of streams.
static WifiMode GetOfdmRate12MbpsBW5MHz()
Return a WifiMode for OFDM at 12Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3582
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:494
void SetAggregation(bool aggregation)
Fill the aggregation field of HT-SIG.
Ptr< PreambleDetectionModel > m_preambleDetectionModel
Preamble detection model.
Definition: wifi-phy.h:1921
double GetPowerDbm(uint8_t power) const
Get the power of the given power level in dBm.
Definition: wifi-phy.cc:794
static WifiMode GetVhtMcs1()
Return MCS 1 from VHT MCS values.
Definition: wifi-phy.cc:3876
void SetNss(uint8_t nss)
Sets the number of Nss refer to IEEE 802.11n Table 20-28 for explanation and range.
EventId m_endPreambleDetectionEvent
the end of preamble detection event
Definition: wifi-phy.h:1619
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:3384
void SetErrorRateModel(const Ptr< ErrorRateModel > rate)
Sets the error rate model.
Definition: wifi-phy.cc:762
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of HE-SIG-A1 (in MHz).
static WifiMode GetHeMcs9()
Return MCS 9 from HE MCS values.
Definition: wifi-phy.cc:4022
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:363
double f(double x, void *params)
Definition: 80211b.c:70
static WifiMode GetHtMcs0()
Return MCS 0 from HT MCS values.
Definition: wifi-phy.cc:3609
Ptr< MobilityModel > GetMobility(void) const
Return the mobility model this PHY is associated with.
Definition: wifi-phy.cc:749
static Time GetPreambleDetectionDuration(void)
Definition: wifi-phy.cc:1760
void SetPostReceptionErrorModel(const Ptr< ErrorModel > em)
Attach a receive ErrorModel to the WifiPhy.
Definition: wifi-phy.cc:769
static TypeId GetTypeId(void)
Get the type ID.
Definition: wifi-phy.cc:162
bool IsAmpdu(Ptr< const Packet > packet)
Definition: wifi-utils.cc:270
Time GetChannelSwitchDelay(void) const
Definition: wifi-phy.cc:812
OFDM PHY for the 5 GHz band (Clause 17)
void ContinueReceiveHeader(Ptr< Event > event)
Continue receiving the PHY header of a packet (i.e.
Definition: wifi-phy.cc:2720
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:788
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:367
Time m_guardInterval
Supported HE guard interval (deprecated)
Definition: wifi-phy.h:1899
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
void EraseEvents(void)
Erase all events.
uint16_t GetFrequency(void) const
Definition: wifi-phy.cc:1337
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
The PHY layer is IDLE.
uint8_t GetNumberOfAntennas(void) const
Definition: wifi-phy.cc:1371
bool GetAggregation(void) const
Return the aggregation field of HT-SIG.
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24Mbps.
Definition: wifi-phy.cc:3360
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
virtual void SetChannelWidth(uint16_t channelwidth)
Definition: wifi-phy.cc:1343
WifiPhyState
The state of the PHY layer.
static WifiMode GetHeMcs1()
Return MCS 1 from HE MCS values.
Definition: wifi-phy.cc:3958
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:1758
DSSS PHY (Clause 15) and HR/DSSS PHY (Clause 18)
void StartReceivePreamble(Ptr< Packet > packet, double rxPowerW, Time rxDuration)
Start receiving the PHY preamble of a packet (i.e.
Definition: wifi-phy.cc:2744
static WifiMode GetHtMcs13()
Return MCS 13 from HT MCS values.
Definition: wifi-phy.cc:3713
void SetShortGuardInterval(bool shortGuardInterval)
Enable or disable support for HT/VHT short guard interval.
Definition: wifi-phy.cc:643
uint8_t GetMcs(void) const
Return the MCS field of HT-SIG.
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
static WifiMode GetHeMcs0()
Return MCS 0 from HE MCS values.
Definition: wifi-phy.cc:3950
static WifiMode GetHeMcs10()
Return MCS 10 from HE MCS values.
Definition: wifi-phy.cc:4030
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:3769
static WifiMode GetHeMcs2()
Return MCS 2 from HE MCS values.
Definition: wifi-phy.cc:3966
static WifiMode GetHtMcs5()
Return MCS 5 from HT MCS values.
Definition: wifi-phy.cc:3649
void SetMaxSupportedRxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1396
void SetChannelWidth(uint16_t channelWidth)
Fill the channel width field of HT-SIG (in MHz).
uint64_t GetRate(void) const
Return the RATE field of L-SIG (in bit/s).
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:1883
static WifiMode GetVhtMcs2()
Return MCS 2 from VHT MCS values.
Definition: wifi-phy.cc:3884
virtual void SetChannelNumber(uint8_t id)
Set channel number.
Definition: wifi-phy.cc:1455
static WifiMode GetDsssRate5_5Mbps()
Return a WifiMode for DSSS at 5.5Mbps.
Definition: wifi-phy.cc:3186
void Configure80211ac(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11ac standard...
Definition: wifi-phy.cc:1073
virtual void DoInitialize(void)
Initialize() implementation.
Definition: wifi-phy.cc:430
static WifiMode GetOfdmRate2_25MbpsBW5MHz()
Return a WifiMode for OFDM at 2.25Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3522
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:1509
WifiPhyStandard m_standard
WifiPhyStandard.
Definition: wifi-phy.h:1875
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
void SetGuardInterval(Time guardInterval)
Definition: wifi-phy.cc:674
uint8_t FindChannelNumberForFrequencyWidth(uint16_t frequency, uint16_t width) const
Look for channel number matching the frequency and width.
Definition: wifi-phy.cc:1139
bool m_channelAccessRequested
Definition: wifi-phy.h:1893
void NotifyTxBegin(Ptr< const Packet > packet, double txPowerW)
Public method used to fire a PhyTxBegin trace.
Definition: wifi-phy.cc:2350
static WifiMode GetErpOfdmRate9Mbps()
Return a WifiMode for ERP-OFDM at 9Mbps.
Definition: wifi-phy.cc:3225
void EndReceive(Ptr< Event > event)
The last bit of the packet has arrived.
Definition: wifi-phy.cc:3040
void NotifyTxEnd(Ptr< const Packet > packet)
Public method used to fire a PhyTxEnd trace.
Definition: wifi-phy.cc:2367
Ptr< UniformRandomVariable > m_random
Provides uniform random variables.
Definition: wifi-phy.h:1611
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...
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:1902
double GetTxPowerStart(void) const
Return the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:554
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:53
Implements the IEEE 802.11n PHY header (HT-SIG1/2).
Ptr< ErrorModel > m_postReceptionErrorModel
Error model for receive packet events.
Definition: wifi-phy.h:1923
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
void InitializeFrequencyChannelNumber(void)
post-construction setting of frequency and/or channel number
Definition: wifi-phy.cc:479
WifiModulationClass GetModulation(void) const
Getter for modulation parameter.
Definition: wifi-phy-tag.cc:86
std::vector< uint16_t > GetSupportedChannelWidthSet(void) const
Definition: wifi-phy.cc:1441
uint8_t GetNModes(void) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:4072
Ptr< FrameCaptureModel > m_frameCaptureModel
Frame capture model.
Definition: wifi-phy.h:1920
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:599
void Configure80211b(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11b standard...
Definition: wifi-phy.cc:918
void SetHtLength(uint16_t length)
Fill the HT length field of HT-SIG (in bytes).
uint8_t GetSuMcs(void) const
Return the SU VHT MCS field of VHT-SIG-A2.
No explicit coding (e.g., DSSS rates)
Definition: wifi-mode.h:75
bool GetShortGuardInterval(void) const
Return the short GI field of VHT-SIG-A2.
void SetReceiveOkCallback(RxOkCallback callback)
Definition: wifi-phy.cc:449
WifiMode GetMode(uint8_t mode) const
The WifiPhy::GetNModes() and WifiPhy::GetMode() methods are used (e.g., by a WifiRemoteStationManager...
Definition: wifi-phy.cc:4078
uint16_t m_channelWidth
Channel width.
Definition: wifi-phy.h:1880
uint8_t GetBssMembershipSelector(uint8_t selector) const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1420
static WifiMode GetErpOfdmRate6Mbps()
Return a WifiMode for ERP-OFDM at 6Mbps.
Definition: wifi-phy.cc:3213
uint8_t GetFrameComplete(void) const
Getter for frameComplete parameter.
Definition: wifi-phy-tag.cc:92
Implements the IEEE 802.11ax HE-SIG PHY header (HE-SIG-A1/A2/B)
void RegisterListener(WifiPhyListener *listener)
Definition: wifi-phy.cc:461
bool IsStateTx(void) const
Definition: wifi-phy.cc:4114
void ConfigureChannelForStandard(WifiPhyStandard standard)
Configure the PHY-level parameters for different Wi-Fi standard.
Definition: wifi-phy.cc:1167
void SetMaxSupportedTxSpatialStreams(uint8_t streams)
Definition: wifi-phy.cc:1377
The PHY layer is sending a packet.
static WifiMode GetErpOfdmRate12Mbps()
Return a WifiMode for ERP-OFDM at 12Mbps.
Definition: wifi-phy.cc:3237
bool m_greenfield
Flag if GreenField format is supported (deprecated)
Definition: wifi-phy.h:1895
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:1617
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper.
Definition: wifi-phy.h:1612
void SetEdThreshold(double threshold)
Sets the energy detection threshold (dBm).
Definition: wifi-phy.cc:507
void NotifyRxEnd(Ptr< const Packet > packet)
Public method used to fire a PhyRxEnd trace.
Definition: wifi-phy.cc:2418
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
void Configure80211n(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11n standard...
Definition: wifi-phy.cc:1056
void SetTxPowerStart(double start)
Sets the minimum available transmission power level (dBm).
Definition: wifi-phy.cc:547
double m_txPowerBaseDbm
Minimum transmission power (dBm)
Definition: wifi-phy.h:1886
bool IsMcsSupported(WifiMode mcs) const
Check if the given WifiMode is supported by the PHY.
Definition: wifi-phy.cc:4059
void NotifyRxEnd()
Notify that RX has ended.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:863
Implements the IEEE 802.11 DSSS SIG PHY header.
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:264
SignalNoiseDbm structure.
Definition: wifi-phy.h:64
uint32_t mpduRefNumber
MPDU ref number.
Definition: wifi-phy.h:74
bool m_frequencyChannelNumberInitialized
Store initialization state.
Definition: wifi-phy.h:1879
static WifiMode GetHtMcs19()
Return MCS 19 from HT MCS values.
Definition: wifi-phy.cc:3761
InterferenceHelper m_interference
Pointer to InterferenceHelper.
Definition: wifi-phy.h:1610
void SetGuardIntervalAndLtfSize(uint16_t gi, uint8_t ltf)
Fill the GI + LTF size field of HE-SIG-A1.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:870
uint8_t GetBssColor(void) const
Get the BSS color.
static WifiMode GetHtMcs6()
Return MCS 6 from HT MCS values.
Definition: wifi-phy.cc:3657
bool m_isConstructed
true when ready to set frequency
Definition: wifi-phy.h:1876
void SetLength(uint16_t length)
Fill the LENGTH field of L-SIG (in bytes).
The MPDU is the last aggregate in an A-MPDU with muliple MPDUs.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
void ConfigureHtDeviceMcsSet(void)
Configure the device Mcs set with the appropriate HtMcs modes for the number of available transmit sp...
Definition: wifi-phy.cc:987
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
WifiPhyRxfailureReason
Definition: wifi-phy.h:48
The PHY layer is receiving a packet.
OFDM PHY (Clause 17)
Definition: wifi-mode.h:56
static WifiMode GetVhtPlcpHeaderMode()
Definition: wifi-phy.cc:1748
double m_totalAmpduNumSymbols
Number of symbols previously transmitted for the MPDUs in an A-MPDU, used for the computation of the ...
Definition: wifi-phy.h:1914
static WifiMode GetHtMcs28()
Return MCS 28 from HT MCS values.
Definition: wifi-phy.cc:3833
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
double GetTxPowerEnd(void) const
Return the maximum available transmission power level (dBm).
Definition: wifi-phy.cc:567
static WifiMode GetHtMcs9()
Return MCS 9 from HT MCS values.
Definition: wifi-phy.cc:3681
void EndReceiveInterBss(void)
For HE receptions only, check and possibly modify the transmit power restriction state at the end of ...
Definition: wifi-phy.cc:3140
Attribute or trace source is deprecated; user is warned.
Definition: type-id.h:72
static WifiMode GetHtMcs4()
Return MCS 4 from HT MCS values.
Definition: wifi-phy.cc:3641
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 payload of a packet (i.e.
Definition: wifi-phy.cc:2991
static WifiMode GetHtMcs25()
Return MCS 25 from HT MCS values.
Definition: wifi-phy.cc:3809
static WifiMode GetHeMcs8()
Return MCS 8 from HE MCS values.
Definition: wifi-phy.cc:4014
Tag for WifiTxVector and WifiPreamble information to be embedded in outgoing transmissions as a Packe...
Definition: wifi-phy-tag.h:36
The PHY layer is switched off.
void SetShortGuardInterval(bool sgi)
Fill the short guard interval field of VHT-SIG-A2.
void Configure80211g(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11g standard...
Definition: wifi-phy.cc:929
static WifiMode GetHePlcpHeaderMode()
Definition: wifi-phy.cc:1754
Ptr< NetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:737
uint8_t GetTxPowerLevel(void) const
double GetTxGain(void) const
Return the transmission gain (dB).
Definition: wifi-phy.cc:593
The PHY layer is switching to other channel.
void SetSleepMode(void)
Put in sleep mode.
Definition: wifi-phy.cc:1635
uint32_t m_totalAmpduSize
Total size of the previously transmitted MPDUs in an A-MPDU, used for the computation of the number o...
Definition: wifi-phy.h:1913
uint16_t GetGuardInterval(void) const
Return the guard interval (in nanoseconds).
uint64_t GetRate(uint16_t channelWidth=20) const
Return the RATE field of L-SIG (in bit/s).
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:1870
static std::list< Ptr< const Packet > > PeekAmpduSubframes(Ptr< const Packet > aggregatedPacket)
Peeks the A-MPDU subframes of the provided A-MPDU.
Time GetPayloadDuration(uint32_t size, WifiTxVector txVector, uint16_t frequency)
Definition: wifi-phy.cc:2045
void SetNumberOfAntennas(uint8_t antennas)
Definition: wifi-phy.cc:1363
uint16_t GetChannelWidth(void) const
second
Definition: nstime.h:114
static WifiMode GetHtMcs1()
Return MCS 1 from HT MCS values.
Definition: wifi-phy.cc:3617
uint8_t GetBssColor(void) const
Return the BSS Color field in the HE-SIG-A1.
static WifiMode GetHtMcs23()
Return MCS 23 from HT MCS values.
Definition: wifi-phy.cc:3793
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:3171
static WifiMode GetVhtMcs9()
Return MCS 9 from VHT MCS values.
Definition: wifi-phy.cc:3940
#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:1217
static Time GetStartOfPacketDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1989
static WifiMode GetOfdmRate6MbpsBW10MHz()
Return a WifiMode for OFDM at 6Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3435
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:375
double m_txPowerEndDbm
Maximum transmission power (dBm)
Definition: wifi-phy.h:1887
#define VHT_PHY
Definition: wifi-phy.h:36
void SetShortGuardInterval(bool sgi)
Fill the short guard interval field of HT-SIG.
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
static WifiMode GetPlcpHeaderMode(WifiTxVector txVector)
Definition: wifi-phy.cc:1878
static Time GetPlcpTrainingSymbolDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1766
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:3483
The MPDU is a single MPDU.
MpduType type
type
Definition: wifi-phy.h:73
Time m_channelSwitchDelay
Time required to switch between channel.
Definition: wifi-phy.h:1912
static WifiMode GetOfdmRate13_5MbpsBW5MHz()
Return a WifiMode for OFDM at 13.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3594
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:472
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:726
uint8_t m_numberOfAntennas
Number of transmitters.
Definition: wifi-phy.h:1901
static Time GetPlcpHeaderDuration(WifiTxVector txVector)
Definition: wifi-phy.cc:1924
uint8_t GetMaxSupportedTxSpatialStreams(void) const
Definition: wifi-phy.cc:1390
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:3729
Ptr< Event > m_currentEvent
Hold the current event.
Definition: wifi-phy.h:1919
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
Time GetLastRxStartTime(void) const
Return the start time of the last received packet.
Definition: wifi-phy.cc:4144
double m_txPowerMaxSiso
SISO maximum transmit power due to OBSS PD SR power restriction.
Definition: wifi-phy.h:1891
bool IsStateRx(void) const
Definition: wifi-phy.cc:4108
static WifiMode GetHtMcs3()
Return MCS 3 from HT MCS values.
Definition: wifi-phy.cc:3633
uint8_t m_rxSpatialStreams
Number of supported RX spatial streams.
Definition: wifi-phy.h:1903
std::vector< uint16_t > m_supportedChannelWidthSet
Supported channel width.
Definition: wifi-phy.h:1908
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6Mbps.
Definition: wifi-phy.cc:3312
void SwitchMaybeToCcaBusy(void)
Check if Phy state should move to CCA busy state based on current state of interference tracker...
Definition: wifi-phy.cc:4150
void SetCcaEdThreshold(double threshold)
Sets the CCA threshold (dBm).
Definition: wifi-phy.cc:526
bool m_shortGuardInterval
Flag if HT/VHT short guard interval is supported (deprecated)
Definition: wifi-phy.h:1896
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:150
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:4259
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
DSSS PHY (Clause 15)
Definition: wifi-mode.h:46
static WifiMode GetHeMcs6()
Return MCS 6 from HE MCS values.
Definition: wifi-phy.cc:3998
static WifiMode GetHtPlcpHeaderMode()
Definition: wifi-phy.cc:1742
static WifiMode GetOfdmRate4_5MbpsBW5MHz()
Return a WifiMode for OFDM at 4.5Mbps with 5MHz channel spacing.
Definition: wifi-phy.cc:3546
uint8_t GetNss(void) const
Callback< void > m_capabilitiesChangedCallback
Callback when PHY capabilities changed.
Definition: wifi-phy.h:1926
void Configure80211a(void)
Configure WifiPhy with appropriate channel frequency and supported rates for 802.11a standard...
Definition: wifi-phy.cc:903
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1408
std::map< ChannelNumberStandardPair, FrequencyWidthPair > ChannelToFrequencyWidthMap
channel to frequency width map typedef
Definition: wifi-phy.h:1905
static WifiMode GetOfdmRate3MbpsBW10MHz()
Return a WifiMode for OFDM at 3Mbps with 10MHz channel spacing.
Definition: wifi-phy.cc:3411
TracedCallback< Ptr< const Packet > > m_phyTxEndTrace
The trace source fired when a packet ends the transmission process on the medium. ...
Definition: wifi-phy.h:1766
uint16_t m_initialFrequency
Store frequency until initialization.
Definition: wifi-phy.h:1878
bool DoChannelSwitch(uint8_t id)
The default implementation does nothing and returns true.
Definition: wifi-phy.cc:1515
Time GetGuardInterval(void) const
Definition: wifi-phy.cc:691