A Discrete-Event Network Simulator
API
ofdm-phy.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Orange Labs
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Rediet <getachew.redieteab@orange.com>
18  * Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy)
19  * Mathieu Lacage <mathieu.lacage@sophia.inria.fr> (for logic ported from wifi-phy)
20  */
21 
22 #include "ofdm-phy.h"
23 
24 #include "ofdm-ppdu.h"
25 
26 #include "ns3/interference-helper.h"
27 #include "ns3/log.h"
28 #include "ns3/simulator.h"
29 #include "ns3/wifi-phy.h"
30 #include "ns3/wifi-psdu.h"
31 #include "ns3/wifi-utils.h"
32 
33 #include <array>
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("OfdmPhy");
39 
40 /*******************************************************
41  * OFDM PHY (IEEE 802.11-2016, clause 17)
42  *******************************************************/
43 
44 // clang-format off
45 
50 };
51 
53  // Unique name Code rate Constellation size
54  { "OfdmRate6Mbps", { WIFI_CODE_RATE_1_2, 2 } }, // 20 MHz
55  { "OfdmRate9Mbps", { WIFI_CODE_RATE_3_4, 2 } }, // |
56  { "OfdmRate12Mbps", { WIFI_CODE_RATE_1_2, 4 } }, // V
57  { "OfdmRate18Mbps", { WIFI_CODE_RATE_3_4, 4 } },
58  { "OfdmRate24Mbps", { WIFI_CODE_RATE_1_2, 16 } },
59  { "OfdmRate36Mbps", { WIFI_CODE_RATE_3_4, 16 } },
60  { "OfdmRate48Mbps", { WIFI_CODE_RATE_2_3, 64 } },
61  { "OfdmRate54Mbps", { WIFI_CODE_RATE_3_4, 64 } },
62  { "OfdmRate3MbpsBW10MHz", { WIFI_CODE_RATE_1_2, 2 } }, // 10 MHz
63  { "OfdmRate4_5MbpsBW10MHz", { WIFI_CODE_RATE_3_4, 2 } }, // |
64  { "OfdmRate6MbpsBW10MHz", { WIFI_CODE_RATE_1_2, 4 } }, // V
65  { "OfdmRate9MbpsBW10MHz", { WIFI_CODE_RATE_3_4, 4 } },
66  { "OfdmRate12MbpsBW10MHz", { WIFI_CODE_RATE_1_2, 16 } },
67  { "OfdmRate18MbpsBW10MHz", { WIFI_CODE_RATE_3_4, 16 } },
68  { "OfdmRate24MbpsBW10MHz", { WIFI_CODE_RATE_2_3, 64 } },
69  { "OfdmRate27MbpsBW10MHz", { WIFI_CODE_RATE_3_4, 64 } },
70  { "OfdmRate1_5MbpsBW5MHz", { WIFI_CODE_RATE_1_2, 2 } }, // 5 MHz
71  { "OfdmRate2_25MbpsBW5MHz", { WIFI_CODE_RATE_3_4, 2 } }, // |
72  { "OfdmRate3MbpsBW5MHz", { WIFI_CODE_RATE_1_2, 4 } }, // V
73  { "OfdmRate4_5MbpsBW5MHz", { WIFI_CODE_RATE_3_4, 4 } },
74  { "OfdmRate6MbpsBW5MHz", { WIFI_CODE_RATE_1_2, 16 } },
75  { "OfdmRate9MbpsBW5MHz", { WIFI_CODE_RATE_3_4, 16 } },
76  { "OfdmRate12MbpsBW5MHz", { WIFI_CODE_RATE_2_3, 64 } },
77  { "OfdmRate13_5MbpsBW5MHz", { WIFI_CODE_RATE_3_4, 64 } }
78 };
79 
81 const std::map<uint16_t, std::array<uint64_t, 8> > s_ofdmRatesBpsList =
82  {{ 20, // MHz
83  { 6000000, 9000000, 12000000, 18000000,
84  24000000, 36000000, 48000000, 54000000 }},
85  { 10, // MHz
86  { 3000000, 4500000, 6000000, 9000000,
87  12000000, 18000000, 24000000, 27000000 }},
88  { 5, // MHz
89  { 1500000, 2250000, 3000000, 4500000,
90  6000000, 9000000, 12000000, 13500000 }},
91 };
92 
93 // clang-format on
94 
100 const std::map<uint16_t, std::array<uint64_t, 8>>&
102 {
103  return s_ofdmRatesBpsList;
104 }
105 
106 OfdmPhy::OfdmPhy(OfdmPhyVariant variant /* = OFDM_PHY_DEFAULT */, bool buildModeList /* = true */)
107 {
108  NS_LOG_FUNCTION(this << variant << buildModeList);
109 
110  if (buildModeList)
111  {
112  auto bwRatesMap = GetOfdmRatesBpsList();
113 
114  switch (variant)
115  {
116  case OFDM_PHY_DEFAULT:
117  for (const auto& rate : bwRatesMap.at(20))
118  {
119  WifiMode mode = GetOfdmRate(rate, 20);
120  NS_LOG_LOGIC("Add " << mode << " to list");
121  m_modeList.emplace_back(mode);
122  }
123  break;
124  case OFDM_PHY_10_MHZ:
125  for (const auto& rate : bwRatesMap.at(10))
126  {
127  WifiMode mode = GetOfdmRate(rate, 10);
128  NS_LOG_LOGIC("Add " << mode << " to list");
129  m_modeList.emplace_back(mode);
130  }
131  break;
132  case OFDM_PHY_5_MHZ:
133  for (const auto& rate : bwRatesMap.at(5))
134  {
135  WifiMode mode = GetOfdmRate(rate, 5);
136  NS_LOG_LOGIC("Add " << mode << " to list");
137  m_modeList.emplace_back(mode);
138  }
139  break;
140  default:
141  NS_ABORT_MSG("Unsupported 11a OFDM variant");
142  }
143  }
144 }
145 
147 {
148  NS_LOG_FUNCTION(this);
149 }
150 
151 WifiMode
152 OfdmPhy::GetSigMode(WifiPpduField field, const WifiTxVector& txVector) const
153 {
154  switch (field)
155  {
156  case WIFI_PPDU_FIELD_PREAMBLE: // consider header mode for preamble (useful for
157  // InterferenceHelper)
159  return GetHeaderMode(txVector);
160  default:
161  return PhyEntity::GetSigMode(field, txVector);
162  }
163 }
164 
165 WifiMode
166 OfdmPhy::GetHeaderMode(const WifiTxVector& txVector) const
167 {
168  switch (txVector.GetChannelWidth())
169  {
170  case 5:
171  return GetOfdmRate1_5MbpsBW5MHz();
172  case 10:
173  return GetOfdmRate3MbpsBW10MHz();
174  case 20:
175  default:
176  // Section 17.3.2 "PPDU frame format"; IEEE Std 802.11-2016.
177  // Actually this is only the first part of the PhyHeader,
178  // because the last 16 bits of the PhyHeader are using the
179  // same mode of the payload
180  return GetOfdmRate6Mbps();
181  }
182 }
183 
186 {
187  return m_ofdmPpduFormats;
188 }
189 
190 Time
191 OfdmPhy::GetDuration(WifiPpduField field, const WifiTxVector& txVector) const
192 {
193  switch (field)
194  {
196  return GetPreambleDuration(txVector); // L-STF + L-LTF
198  return GetHeaderDuration(txVector); // L-SIG
199  default:
200  return PhyEntity::GetDuration(field, txVector);
201  }
202 }
203 
204 Time
206 {
207  switch (txVector.GetChannelWidth())
208  {
209  case 20:
210  default:
211  // Section 17.3.3 "PHY preamble (SYNC)" Figure 17-4 "OFDM training structure"
212  // also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent
213  // parameters"; IEEE Std 802.11-2016
214  return MicroSeconds(16);
215  case 10:
216  // Section 17.3.3 "PHY preamble (SYNC)" Figure 17-4 "OFDM training structure"
217  // also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent
218  // parameters"; IEEE Std 802.11-2016
219  return MicroSeconds(32);
220  case 5:
221  // Section 17.3.3 "PHY preamble (SYNC)" Figure 17-4 "OFDM training structure"
222  // also Section 17.3.2.3 "Modulation-dependent parameters" Table 17-4 "Modulation-dependent
223  // parameters"; IEEE Std 802.11-2016
224  return MicroSeconds(64);
225  }
226 }
227 
228 Time
230 {
231  switch (txVector.GetChannelWidth())
232  {
233  case 20:
234  default:
235  // Section 17.3.3 "PHY preamble (SYNC)" and Figure 17-4 "OFDM training structure"; IEEE Std
236  // 802.11-2016 also Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related
237  // parameters"; IEEE Std 802.11-2016 We return the duration of the SIGNAL field only, since
238  // the SERVICE field (which strictly speaking belongs to the PHY header, see Section 17.3.2
239  // and Figure 17-1) is sent using the payload mode.
240  return MicroSeconds(4);
241  case 10:
242  // Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE
243  // Std 802.11-2016
244  return MicroSeconds(8);
245  case 5:
246  // Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE
247  // Std 802.11-2016
248  return MicroSeconds(16);
249  }
250 }
251 
252 Time
254  const WifiTxVector& txVector,
255  WifiPhyBand band,
256  MpduType /* mpdutype */,
257  bool /* incFlag */,
258  uint32_t& /* totalAmpduSize */,
259  double& /* totalAmpduNumSymbols */,
260  uint16_t /* staId */) const
261 {
262  //(Section 17.3.2.4 "Timing related parameters" Table 17-5 "Timing-related parameters"; IEEE Std
263  // 802.11-2016 corresponds to T_{SYM} in the table)
264  Time symbolDuration = MicroSeconds(4);
265 
266  double numDataBitsPerSymbol =
267  txVector.GetMode().GetDataRate(txVector) * symbolDuration.GetNanoSeconds() / 1e9;
268 
269  // The number of OFDM symbols in the data field when BCC encoding
270  // is used is given in equation 19-32 of the IEEE 802.11-2016 standard.
271  double numSymbols =
272  lrint(ceil((GetNumberServiceBits() + size * 8.0 + 6.0) / (numDataBitsPerSymbol)));
273 
274  Time payloadDuration =
275  FemtoSeconds(static_cast<uint64_t>(numSymbols * symbolDuration.GetFemtoSeconds()));
276  payloadDuration += GetSignalExtension(band);
277  return payloadDuration;
278 }
279 
280 uint8_t
282 {
283  return 16;
284 }
285 
286 Time
288 {
289  return (band == WIFI_PHY_BAND_2_4GHZ) ? MicroSeconds(6) : MicroSeconds(0);
290 }
291 
294  const WifiTxVector& txVector,
295  Time /* ppduDuration */)
296 {
297  NS_LOG_FUNCTION(this << psdus << txVector);
298  return Create<OfdmPpdu>(
299  psdus.begin()->second,
300  txVector,
302  m_wifiPhy->GetLatestPhyEntity()->ObtainNextUid(
303  txVector)); // use latest PHY entity to handle MU-RTS sent with non-HT rate
304 }
305 
308 {
309  NS_LOG_FUNCTION(this << field << *event);
310  if (field == WIFI_PPDU_FIELD_NON_HT_HEADER)
311  {
312  return EndReceiveHeader(event); // L-SIG
313  }
314  return PhyEntity::DoEndReceiveField(field, event);
315 }
316 
319 {
320  NS_LOG_FUNCTION(this << *event);
322  NS_LOG_DEBUG("L-SIG: SNR(dB)=" << RatioToDb(snrPer.snr) << ", PER=" << snrPer.per);
323  PhyFieldRxStatus status(GetRandomValue() > snrPer.per);
324  if (status.isSuccess)
325  {
326  NS_LOG_DEBUG("Received non-HT PHY header");
327  if (!IsAllConfigSupported(WIFI_PPDU_FIELD_NON_HT_HEADER, event->GetPpdu()))
328  {
329  status = PhyFieldRxStatus(false, UNSUPPORTED_SETTINGS, DROP);
330  }
331  }
332  else
333  {
334  NS_LOG_DEBUG("Abort reception because non-HT PHY header reception failed");
335  status.reason = L_SIG_FAILURE;
336  status.actionIfFailure = ABORT;
337  }
338  return status;
339 }
340 
341 bool
343 {
344  uint16_t channelWidth = ppdu->GetTxVector().GetChannelWidth();
345  if ((channelWidth >= 40) && (channelWidth > m_wifiPhy->GetChannelWidth()))
346  {
347  NS_LOG_DEBUG("Packet reception could not be started because not enough channel width ("
348  << channelWidth << " vs " << m_wifiPhy->GetChannelWidth() << ")");
349  return false;
350  }
351  return true;
352 }
353 
354 bool
356 {
357  if (!IsChannelWidthSupported(ppdu))
358  {
359  return false;
360  }
361  return IsConfigSupported(ppdu);
362 }
363 
366 {
367  const auto& txVector = ppdu->GetTxVector();
368  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth(txVector);
369  uint16_t channelWidth = txVector.GetChannelWidth();
370  NS_LOG_FUNCTION(this << centerFrequency << channelWidth << txPowerW);
371  const auto& txMaskRejectionParams = GetTxMaskRejectionParams();
373  if (txVector.IsNonHtDuplicate())
374  {
376  centerFrequency,
377  channelWidth,
378  txPowerW,
379  GetGuardBandwidth(channelWidth),
380  std::get<0>(txMaskRejectionParams),
381  std::get<1>(txMaskRejectionParams),
382  std::get<2>(txMaskRejectionParams));
383  }
384  else
385  {
387  centerFrequency,
388  channelWidth,
389  txPowerW,
390  GetGuardBandwidth(channelWidth),
391  std::get<0>(txMaskRejectionParams),
392  std::get<1>(txMaskRejectionParams),
393  std::get<2>(txMaskRejectionParams));
394  }
395  return v;
396 }
397 
398 void
400 {
401  for (const auto& ratesPerBw : GetOfdmRatesBpsList())
402  {
403  for (const auto& rate : ratesPerBw.second)
404  {
405  GetOfdmRate(rate, ratesPerBw.first);
406  }
407  }
408 }
409 
410 WifiMode
411 OfdmPhy::GetOfdmRate(uint64_t rate, uint16_t bw)
412 {
413  switch (bw)
414  {
415  case 20:
416  switch (rate)
417  {
418  case 6000000:
419  return GetOfdmRate6Mbps();
420  case 9000000:
421  return GetOfdmRate9Mbps();
422  case 12000000:
423  return GetOfdmRate12Mbps();
424  case 18000000:
425  return GetOfdmRate18Mbps();
426  case 24000000:
427  return GetOfdmRate24Mbps();
428  case 36000000:
429  return GetOfdmRate36Mbps();
430  case 48000000:
431  return GetOfdmRate48Mbps();
432  case 54000000:
433  return GetOfdmRate54Mbps();
434  default:
435  NS_ABORT_MSG("Inexistent rate (" << rate << " bps) requested for 11a OFDM (default)");
436  return WifiMode();
437  }
438  break;
439  case 10:
440  switch (rate)
441  {
442  case 3000000:
443  return GetOfdmRate3MbpsBW10MHz();
444  case 4500000:
445  return GetOfdmRate4_5MbpsBW10MHz();
446  case 6000000:
447  return GetOfdmRate6MbpsBW10MHz();
448  case 9000000:
449  return GetOfdmRate9MbpsBW10MHz();
450  case 12000000:
451  return GetOfdmRate12MbpsBW10MHz();
452  case 18000000:
453  return GetOfdmRate18MbpsBW10MHz();
454  case 24000000:
455  return GetOfdmRate24MbpsBW10MHz();
456  case 27000000:
457  return GetOfdmRate27MbpsBW10MHz();
458  default:
459  NS_ABORT_MSG("Inexistent rate (" << rate << " bps) requested for 11a OFDM (10 MHz)");
460  return WifiMode();
461  }
462  break;
463  case 5:
464  switch (rate)
465  {
466  case 1500000:
467  return GetOfdmRate1_5MbpsBW5MHz();
468  case 2250000:
469  return GetOfdmRate2_25MbpsBW5MHz();
470  case 3000000:
471  return GetOfdmRate3MbpsBW5MHz();
472  case 4500000:
473  return GetOfdmRate4_5MbpsBW5MHz();
474  case 6000000:
475  return GetOfdmRate6MbpsBW5MHz();
476  case 9000000:
477  return GetOfdmRate9MbpsBW5MHz();
478  case 12000000:
479  return GetOfdmRate12MbpsBW5MHz();
480  case 13500000:
481  return GetOfdmRate13_5MbpsBW5MHz();
482  default:
483  NS_ABORT_MSG("Inexistent rate (" << rate << " bps) requested for 11a OFDM (5 MHz)");
484  return WifiMode();
485  }
486  break;
487  default:
488  NS_ABORT_MSG("Inexistent bandwidth (" << +bw << " MHz) requested for 11a OFDM");
489  return WifiMode();
490  }
491 }
492 
493 #define GET_OFDM_MODE(x, f) \
494  WifiMode OfdmPhy::Get##x() \
495  { \
496  static WifiMode mode = CreateOfdmMode(#x, f); \
497  return mode; \
498  }
499 
500 // 20 MHz channel rates (default)
501 GET_OFDM_MODE(OfdmRate6Mbps, true)
502 GET_OFDM_MODE(OfdmRate9Mbps, false)
503 GET_OFDM_MODE(OfdmRate12Mbps, true)
504 GET_OFDM_MODE(OfdmRate18Mbps, false)
505 GET_OFDM_MODE(OfdmRate24Mbps, true)
506 GET_OFDM_MODE(OfdmRate36Mbps, false)
507 GET_OFDM_MODE(OfdmRate48Mbps, false)
508 GET_OFDM_MODE(OfdmRate54Mbps, false)
509 // 10 MHz channel rates
510 GET_OFDM_MODE(OfdmRate3MbpsBW10MHz, true)
511 GET_OFDM_MODE(OfdmRate4_5MbpsBW10MHz, false)
512 GET_OFDM_MODE(OfdmRate6MbpsBW10MHz, true)
513 GET_OFDM_MODE(OfdmRate9MbpsBW10MHz, false)
514 GET_OFDM_MODE(OfdmRate12MbpsBW10MHz, true)
515 GET_OFDM_MODE(OfdmRate18MbpsBW10MHz, false)
516 GET_OFDM_MODE(OfdmRate24MbpsBW10MHz, false)
517 GET_OFDM_MODE(OfdmRate27MbpsBW10MHz, false)
518 // 5 MHz channel rates
519 GET_OFDM_MODE(OfdmRate1_5MbpsBW5MHz, true)
520 GET_OFDM_MODE(OfdmRate2_25MbpsBW5MHz, false)
521 GET_OFDM_MODE(OfdmRate3MbpsBW5MHz, true)
522 GET_OFDM_MODE(OfdmRate4_5MbpsBW5MHz, false)
523 GET_OFDM_MODE(OfdmRate6MbpsBW5MHz, true)
524 GET_OFDM_MODE(OfdmRate9MbpsBW5MHz, false)
525 GET_OFDM_MODE(OfdmRate12MbpsBW5MHz, false)
526 GET_OFDM_MODE(OfdmRate13_5MbpsBW5MHz, false)
527 #undef GET_OFDM_MODE
528 
529 WifiMode
530 OfdmPhy::CreateOfdmMode(std::string uniqueName, bool isMandatory)
531 {
532  // Check whether uniqueName is in lookup table
533  const auto it = m_ofdmModulationLookupTable.find(uniqueName);
535  "OFDM mode cannot be created because it is not in the lookup table!");
536 
537  return WifiModeFactory::CreateWifiMode(uniqueName,
539  isMandatory,
540  MakeBoundCallback(&GetCodeRate, uniqueName),
545 }
546 
548 OfdmPhy::GetCodeRate(const std::string& name)
549 {
550  return m_ofdmModulationLookupTable.at(name).first;
551 }
552 
553 uint16_t
554 OfdmPhy::GetConstellationSize(const std::string& name)
555 {
556  return m_ofdmModulationLookupTable.at(name).second;
557 }
558 
559 uint64_t
560 OfdmPhy::GetPhyRate(const std::string& name, uint16_t channelWidth)
561 {
562  WifiCodeRate codeRate = GetCodeRate(name);
563  uint64_t dataRate = GetDataRate(name, channelWidth);
564  return CalculatePhyRate(codeRate, dataRate);
565 }
566 
567 uint64_t
568 OfdmPhy::CalculatePhyRate(WifiCodeRate codeRate, uint64_t dataRate)
569 {
570  return (dataRate / GetCodeRatio(codeRate));
571 }
572 
573 uint64_t
574 OfdmPhy::GetPhyRateFromTxVector(const WifiTxVector& txVector, uint16_t /* staId */)
575 {
576  return GetPhyRate(txVector.GetMode().GetUniqueName(), txVector.GetChannelWidth());
577 }
578 
579 double
581 {
582  switch (codeRate)
583  {
584  case WIFI_CODE_RATE_3_4:
585  return (3.0 / 4.0);
586  case WIFI_CODE_RATE_2_3:
587  return (2.0 / 3.0);
588  case WIFI_CODE_RATE_1_2:
589  return (1.0 / 2.0);
591  default:
592  NS_FATAL_ERROR("trying to get code ratio for undefined coding rate");
593  return 0;
594  }
595 }
596 
597 uint64_t
598 OfdmPhy::GetDataRateFromTxVector(const WifiTxVector& txVector, uint16_t /* staId */)
599 {
600  return GetDataRate(txVector.GetMode().GetUniqueName(), txVector.GetChannelWidth());
601 }
602 
603 uint64_t
604 OfdmPhy::GetDataRate(const std::string& name, uint16_t channelWidth)
605 {
606  WifiCodeRate codeRate = GetCodeRate(name);
607  uint16_t constellationSize = GetConstellationSize(name);
608  return CalculateDataRate(codeRate, constellationSize, channelWidth);
609 }
610 
611 uint64_t
612 OfdmPhy::CalculateDataRate(WifiCodeRate codeRate, uint16_t constellationSize, uint16_t channelWidth)
613 {
614  return CalculateDataRate(GetSymbolDuration(channelWidth),
616  static_cast<uint16_t>(log2(constellationSize)),
617  GetCodeRatio(codeRate));
618 }
619 
620 uint64_t
622  uint16_t usableSubCarriers,
623  uint16_t numberOfBitsPerSubcarrier,
624  double codingRate)
625 {
626  double symbolRate = (1e9 / static_cast<double>(symbolDuration.GetNanoSeconds()));
627  return lrint(ceil(symbolRate * usableSubCarriers * numberOfBitsPerSubcarrier * codingRate));
628 }
629 
630 uint16_t
632 {
633  return 48;
634 }
635 
636 Time
637 OfdmPhy::GetSymbolDuration(uint16_t channelWidth)
638 {
639  Time symbolDuration = MicroSeconds(4);
640  uint8_t bwFactor = 1;
641  if (channelWidth == 10)
642  {
643  bwFactor = 2;
644  }
645  else if (channelWidth == 5)
646  {
647  bwFactor = 4;
648  }
649  return bwFactor * symbolDuration;
650 }
651 
652 bool
653 OfdmPhy::IsAllowed(const WifiTxVector& /*txVector*/)
654 {
655  return true;
656 }
657 
658 uint32_t
660 {
661  return 4095;
662 }
663 
664 uint16_t
666 {
667  if (!ppdu)
668  {
669  return 20;
670  }
671  return GetRxChannelWidth(ppdu->GetTxVector());
672 }
673 
674 double
676 {
677  if (ppdu && ppdu->GetTxVector().GetChannelWidth() < 20)
678  {
679  // scale CCA sensitivity threshold for BW of 5 and 10 MHz
680  uint16_t bw = GetRxChannelWidth(ppdu->GetTxVector());
681  double thresholdW = DbmToW(m_wifiPhy->GetCcaSensitivityThreshold()) * (bw / 20.0);
682  return WToDbm(thresholdW);
683  }
684  return PhyEntity::GetCcaThreshold(ppdu, channelType);
685 }
686 
689 {
690  const auto txWidth = ppdu->GetTxChannelWidth();
691  const auto& txVector = ppdu->GetTxVector();
692  // Update channel width in TXVECTOR for non-HT duplicate PPDUs.
693  if (txVector.IsNonHtDuplicate() && txWidth > m_wifiPhy->GetChannelWidth())
694  {
695  // We also do a copy of the PPDU for non-HT duplicate PPDUs since other
696  // PHYs might set a different channel width in the reconstructed TXVECTOR.
697  auto rxPpdu = ppdu->Copy();
698  auto updatedTxVector = txVector;
699  updatedTxVector.SetChannelWidth(std::min(txWidth, m_wifiPhy->GetChannelWidth()));
700  rxPpdu->UpdateTxVector(updatedTxVector);
701  return rxPpdu;
702  }
703  return PhyEntity::GetRxPpduFromTxPpdu(ppdu);
704 }
705 
706 } // namespace ns3
707 
708 namespace
709 {
710 
715 {
716  public:
718  {
721  ns3::Create<ns3::OfdmPhy>()); // default variant will do
722  }
724 
725 } // namespace
#define min(a, b)
Definition: 80211b.c:41
Constructor class for OFDM modes.
Definition: ofdm-phy.cc:715
static WifiMode GetOfdmRate6Mbps()
Return a WifiMode for OFDM at 6 Mbps.
uint32_t GetMaxPsduSize() const override
Get the maximum PSDU size in bytes.
Definition: ofdm-phy.cc:659
~OfdmPhy() override
Destructor for OFDM PHY.
Definition: ofdm-phy.cc:146
static WifiMode GetOfdmRate13_5MbpsBW5MHz()
Return a WifiMode for OFDM at 13.5 Mbps with 5 MHz channel spacing.
static WifiMode GetOfdmRate48Mbps()
Return a WifiMode for OFDM at 48 Mbps.
static const PpduFormats m_ofdmPpduFormats
OFDM PPDU formats.
Definition: ofdm-phy.h:452
static uint16_t GetConstellationSize(const std::string &name)
Return the constellation size from the OFDM mode's unique name using ModulationLookupTable.
Definition: ofdm-phy.cc:554
static WifiMode GetOfdmRate54Mbps()
Return a WifiMode for OFDM at 54 Mbps.
uint8_t GetNumberServiceBits() const
Definition: ofdm-phy.cc:281
static WifiCodeRate GetCodeRate(const std::string &name)
Return the WifiCodeRate from the OFDM mode's unique name using ModulationLookupTable.
Definition: ofdm-phy.cc:548
double GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const override
Return the CCA threshold in dBm for a given channel type.
Definition: ofdm-phy.cc:675
static uint64_t GetPhyRateFromTxVector(const WifiTxVector &txVector, uint16_t staId)
Return the PHY rate corresponding to the supplied TXVECTOR.
Definition: ofdm-phy.cc:574
static uint64_t CalculateDataRate(WifiCodeRate codeRate, uint16_t constellationSize, uint16_t channelWidth)
Calculates data rate from the supplied parameters.
Definition: ofdm-phy.cc:612
static WifiMode GetOfdmRate36Mbps()
Return a WifiMode for OFDM at 36 Mbps.
static WifiMode GetOfdmRate3MbpsBW10MHz()
Return a WifiMode for OFDM at 3 Mbps with 10 MHz channel spacing.
static void InitializeModes()
Initialize all OFDM modes (for all variants).
Definition: ofdm-phy.cc:399
virtual bool IsAllConfigSupported(WifiPpduField field, Ptr< const WifiPpdu > ppdu) const
Checks if the signaled configuration (including bandwidth) is supported by the PHY.
Definition: ofdm-phy.cc:355
PhyFieldRxStatus EndReceiveHeader(Ptr< Event > event)
End receiving the header, perform OFDM-specific actions, and provide the status of the reception.
Definition: ofdm-phy.cc:318
static WifiMode GetOfdmRate2_25MbpsBW5MHz()
Return a WifiMode for OFDM at 2.25 Mbps with 5 MHz channel spacing.
const PpduFormats & GetPpduFormats() const override
Return the PPDU formats of the PHY.
Definition: ofdm-phy.cc:185
static bool IsAllowed(const WifiTxVector &txVector)
Check whether the combination in TXVECTOR is allowed.
Definition: ofdm-phy.cc:653
static WifiMode GetOfdmRate6MbpsBW5MHz()
Return a WifiMode for OFDM at 6 Mbps with 5 MHz channel spacing.
OfdmPhy(OfdmPhyVariant variant=OFDM_PHY_DEFAULT, bool buildModeList=true)
Constructor for OFDM PHY.
Definition: ofdm-phy.cc:106
static uint64_t GetDataRateFromTxVector(const WifiTxVector &txVector, uint16_t staId)
Return the data rate corresponding to the supplied TXVECTOR.
Definition: ofdm-phy.cc:598
static WifiMode GetOfdmRate1_5MbpsBW5MHz()
Return a WifiMode for OFDM at 1.5 Mbps with 5 MHz channel spacing.
static WifiMode GetOfdmRate18MbpsBW10MHz()
Return a WifiMode for OFDM at 18 Mbps with 10 MHz channel spacing.
static Time GetSymbolDuration(uint16_t channelWidth)
Definition: ofdm-phy.cc:637
static uint64_t GetPhyRate(const std::string &name, uint16_t channelWidth)
Return the PHY rate from the OFDM mode's unique name and the supplied parameters.
Definition: ofdm-phy.cc:560
static WifiMode GetOfdmRate12MbpsBW10MHz()
Return a WifiMode for OFDM at 12 Mbps with 10 MHz channel spacing.
static uint16_t GetUsableSubcarriers()
Definition: ofdm-phy.cc:631
static WifiMode GetOfdmRate9MbpsBW10MHz()
Return a WifiMode for OFDM at 9 Mbps with 10 MHz channel spacing.
static WifiMode GetOfdmRate4_5MbpsBW5MHz()
Return a WifiMode for OFDM at 4.5 Mbps with 5 MHz channel spacing.
static WifiMode GetOfdmRate3MbpsBW5MHz()
Return a WifiMode for OFDM at 3 Mbps with 5 MHz channel spacing.
virtual Time GetPreambleDuration(const WifiTxVector &txVector) const
Definition: ofdm-phy.cc:205
Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu) override
The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel.
Definition: ofdm-phy.cc:688
static WifiMode GetOfdmRate(uint64_t rate, uint16_t bw=20)
Return a WifiMode for OFDM corresponding to the provided rate and the channel bandwidth (20,...
Definition: ofdm-phy.cc:411
static WifiMode GetOfdmRate27MbpsBW10MHz()
Return a WifiMode for OFDM at 27 Mbps with 10 MHz channel spacing.
static WifiMode GetOfdmRate9MbpsBW5MHz()
Return a WifiMode for OFDM at 9 Mbps with 5 MHz channel spacing.
Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
Definition: ofdm-phy.cc:293
static WifiMode GetOfdmRate12Mbps()
Return a WifiMode for OFDM at 12Mbps.
static WifiMode CreateOfdmMode(std::string uniqueName, bool isMandatory)
Create an OFDM mode from a unique name, the unique name must already be contained inside ModulationLo...
Definition: ofdm-phy.cc:530
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Definition: ofdm-phy.cc:665
static WifiMode GetOfdmRate24MbpsBW10MHz()
Return a WifiMode for OFDM at 24 Mbps with 10 MHz channel spacing.
static WifiMode GetOfdmRate18Mbps()
Return a WifiMode for OFDM at 18 Mbps.
Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const override
Definition: ofdm-phy.cc:365
static uint64_t CalculatePhyRate(WifiCodeRate codeRate, uint64_t dataRate)
Calculate the PHY rate in bps from code rate and data rate.
Definition: ofdm-phy.cc:568
static WifiMode GetOfdmRate6MbpsBW10MHz()
Return a WifiMode for OFDM at 6 Mbps with 10 MHz channel spacing.
static WifiMode GetOfdmRate24Mbps()
Return a WifiMode for OFDM at 24 Mbps.
Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const override
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
Definition: ofdm-phy.cc:191
PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event) override
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
Definition: ofdm-phy.cc:307
virtual Time GetHeaderDuration(const WifiTxVector &txVector) const
Definition: ofdm-phy.cc:229
virtual WifiMode GetHeaderMode(const WifiTxVector &txVector) const
Definition: ofdm-phy.cc:166
WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
Definition: ofdm-phy.cc:152
static WifiMode GetOfdmRate12MbpsBW5MHz()
Return a WifiMode for OFDM at 12 Mbps with 5 MHz channel spacing.
static const ModulationLookupTable m_ofdmModulationLookupTable
lookup table to retrieve code rate and constellation size corresponding to a unique name of modulatio...
Definition: ofdm-phy.h:455
static uint64_t GetDataRate(const std::string &name, uint16_t channelWidth)
Return the data rate from the OFDM mode's unique name and the supplied parameters.
Definition: ofdm-phy.cc:604
static WifiMode GetOfdmRate4_5MbpsBW10MHz()
Return a WifiMode for OFDM at 4.5 Mbps with 10 MHz channel spacing.
static WifiMode GetOfdmRate9Mbps()
Return a WifiMode for OFDM at 9 Mbps.
virtual bool IsChannelWidthSupported(Ptr< const WifiPpdu > ppdu) const
Checks if the PPDU's bandwidth is supported by the PHY.
Definition: ofdm-phy.cc:342
static double GetCodeRatio(WifiCodeRate codeRate)
Convert WifiCodeRate to a ratio, e.g., code ratio of WIFI_CODE_RATE_1_2 is 0.5.
Definition: ofdm-phy.cc:580
Time GetSignalExtension(WifiPhyBand band) const
Definition: ofdm-phy.cc:287
Time GetPayloadDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, MpduType mpdutype, bool incFlag, uint32_t &totalAmpduSize, double &totalAmpduNumSymbols, uint16_t staId) const override
Definition: ofdm-phy.cc:253
virtual Time GetDuration(WifiPpduField field, const WifiTxVector &txVector) const
Get the duration of the PPDU field (or group of fields) used by this entity for the given transmissio...
Definition: phy-entity.cc:190
std::tuple< double, double, double > GetTxMaskRejectionParams() const
Definition: phy-entity.cc:1349
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:981
std::map< std::string, CodeRateConstellationSizePair > ModulationLookupTable
A modulation lookup table using unique name of modulation as key.
Definition: phy-entity.h:571
virtual double GetCcaThreshold(const Ptr< const WifiPpdu > ppdu, WifiChannelListType channelType) const
Return the CCA threshold in dBm for a given channel type.
Definition: phy-entity.cc:1220
std::map< WifiPreamble, std::vector< WifiPpduField > > PpduFormats
A map of PPDU field elements per preamble type.
Definition: phy-entity.h:561
virtual WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const
Get the WifiMode for the SIG field specified by the PPDU field.
Definition: phy-entity.cc:150
virtual uint16_t GetRxChannelWidth(const WifiTxVector &txVector) const
Return the channel width used in the reception spectrum model.
Definition: phy-entity.cc:1214
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1343
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:985
double GetRandomValue() const
Obtain a random value from the WifiPhy's generator.
Definition: phy-entity.cc:1177
SnrPer GetPhyHeaderSnrPer(WifiPpduField field, Ptr< Event > event) const
Obtain the SNR and PER of the PPDU field from the WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:268
virtual Ptr< const WifiPpdu > GetRxPpduFromTxPpdu(Ptr< const WifiPpdu > ppdu)
The WifiPpdu from the TX PHY is received by each RX PHY attached to the same channel.
Definition: phy-entity.cc:1386
uint16_t GetCenterFrequencyForChannelWidth(const WifiTxVector &txVector) const
Get the center frequency of the channel corresponding the current TxVector rather than that of the su...
Definition: phy-entity.cc:1294
virtual bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Definition: phy-entity.cc:1087
@ DROP
drop PPDU and set CCA_BUSY
Definition: phy-entity.h:103
@ ABORT
abort reception of PPDU
Definition: phy-entity.h:104
virtual PhyFieldRxStatus DoEndReceiveField(WifiPpduField field, Ptr< Event > event)
End receiving a given field, perform amendment-specific actions, and provide the status of the recept...
Definition: phy-entity.cc:385
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
int64_t GetNanoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:418
int64_t GetFemtoSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:428
static WifiMode CreateWifiMode(std::string uniqueName, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, AllowedCallback isAllowedCallback)
Definition: wifi-mode.cc:270
represent a single transmission mode
Definition: wifi-mode.h:51
std::string GetUniqueName() const
Definition: wifi-mode.cc:148
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
uint16_t GetChannelWidth() const
Definition: wifi-phy.cc:1051
static void AddStaticPhyEntity(WifiModulationClass modulation, Ptr< PhyEntity > phyEntity)
Add the PHY entity to the map of implemented PHY entities for the given modulation class.
Definition: wifi-phy.cc:752
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1033
double GetCcaSensitivityThreshold() const
Return the CCA sensitivity threshold (dBm).
Definition: wifi-phy.cc:512
Ptr< PhyEntity > GetLatestPhyEntity() const
Get the latest PHY entity supported by this PHY instance.
Definition: wifi-phy.cc:726
static Ptr< SpectrumValue > CreateDuplicated20MhzTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, double minInnerBandDbr=-20, double minOuterbandDbr=-28, double lowestPointDbr=-40, const std::vector< bool > &puncturedSubchannels=std::vector< bool >{})
Create a transmit power spectral density corresponding to OFDM duplicated over multiple 20 MHz subcha...
static Ptr< SpectrumValue > CreateOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, double minInnerBandDbr=-20, double minOuterbandDbr=-28, double lowestPointDbr=-40)
Create a transmit power spectral density corresponding to OFDM (802.11a/g).
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
WifiMode GetMode(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the selected payload transmission mode.
uint16_t GetChannelWidth() const
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
auto MakeBoundCallback(R(*fnPtr)(Args...), BArgs &&... bargs)
Make Callbacks with varying number of bound arguments.
Definition: callback.h:765
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1386
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
OfdmPhyVariant
The OFDM (11a) PHY variants.
Definition: ofdm-phy.h:44
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
WifiPpduField
The type of PPDU field (grouped for convenience)
MpduType
The type of an MPDU.
@ UNSUPPORTED_SETTINGS
@ L_SIG_FAILURE
@ WIFI_PREAMBLE_LONG
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ OFDM_PHY_10_MHZ
Definition: ofdm-phy.h:46
@ OFDM_PHY_DEFAULT
Definition: ofdm-phy.h:45
@ OFDM_PHY_5_MHZ
Definition: ofdm-phy.h:47
@ WIFI_PPDU_FIELD_NON_HT_HEADER
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_DATA
data field
class anonymous_namespace{ofdm-phy.cc}::ConstructorOfdm g_constructor_ofdm
the constructor for OFDM modes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double RatioToDb(double ratio)
Convert from ratio to dB.
Definition: wifi-utils.cc:52
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
double WToDbm(double w)
Convert from Watts to dBm.
Definition: wifi-utils.cc:46
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
const std::map< uint16_t, std::array< uint64_t, 8 > > s_ofdmRatesBpsList
OFDM rates in bits per second for each bandwidth (MHz)
Definition: ofdm-phy.cc:81
double DbmToW(double dBm)
Convert from dBm to Watts.
Definition: wifi-utils.cc:40
const std::map< uint16_t, std::array< uint64_t, 8 > > & GetOfdmRatesBpsList()
Get the array of possible OFDM rates for each bandwidth (MHz).
Definition: ofdm-phy.cc:101
WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
@ WIFI_CODE_RATE_2_3
2/3 coding rate
@ WIFI_CODE_RATE_1_2
1/2 coding rate
@ WIFI_CODE_RATE_3_4
3/4 coding rate
@ WIFI_CODE_RATE_UNDEFINED
undefined coding rate
#define GET_OFDM_MODE(x, f)
Definition: ofdm-phy.cc:493
Declaration of ns3::OfdmPhy class and ns3::OfdmPhyVariant enum.
Declaration of ns3::OfdmPpdu class.
Status of the reception of the PPDU field.
Definition: phy-entity.h:112
WifiPhyRxfailureReason reason
failure reason
Definition: phy-entity.h:114
PhyRxFailureAction actionIfFailure
action to perform in case of failure
Definition: phy-entity.h:115
bool isSuccess
outcome (true if success) of the reception
Definition: phy-entity.h:113
A struct for both SNR and PER.
Definition: phy-entity.h:147
double snr
SNR in linear scale.
Definition: phy-entity.h:148