A Discrete-Event Network Simulator
API
he-phy.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2020 Orange Labs
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: Rediet <getachew.redieteab@orange.com>
19  * Sébastien Deronne <sebastien.deronne@gmail.com> (for logic ported from wifi-phy and spectrum-wifi-phy)
20  */
21 
22 #include "he-phy.h"
23 #include "he-ppdu.h"
24 #include "ns3/wifi-psdu.h"
25 #include "ns3/wifi-phy.h"
26 #include "he-configuration.h"
27 #include "ns3/wifi-net-device.h"
28 #include "ns3/sta-wifi-mac.h"
29 #include "ns3/ap-wifi-mac.h"
30 #include "ns3/wifi-utils.h"
31 #include "ns3/simulator.h"
32 #include "ns3/log.h"
33 #include "ns3/assert.h"
34 #include <algorithm>
35 
36 namespace ns3 {
37 
38 NS_LOG_COMPONENT_DEFINE ("HePhy");
39 
40 /*******************************************************
41  * HE PHY (P802.11ax/D4.0, clause 27)
42  *******************************************************/
43 
44 /* *NS_CHECK_STYLE_OFF* */
45 const PhyEntity::PpduFormats HePhy::m_hePpduFormats { //Ignoring PE (Packet Extension)
46  { WIFI_PREAMBLE_HE_SU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
47  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
48  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
49  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
51  { WIFI_PREAMBLE_HE_MU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
52  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
53  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
54  WIFI_PPDU_FIELD_SIG_B, //HE-SIG-B
55  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
57  { WIFI_PREAMBLE_HE_TB, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
58  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
59  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
60  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
63  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
64  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
65  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
67 };
68 /* *NS_CHECK_STYLE_ON* */
69 
70 HePhy::HePhy (bool buildModeList /* = true */)
71  : VhtPhy (false) //don't add VHT modes to list
72 {
73  NS_LOG_FUNCTION (this << buildModeList);
75  m_maxMcsIndexPerSs = 11;
77  m_currentHeTbPpduUid = UINT64_MAX;
78  m_previouslyTxPpduUid = UINT64_MAX;
79  if (buildModeList)
80  {
81  BuildModeList ();
82  }
83 }
84 
86 {
87  NS_LOG_FUNCTION (this);
88 }
89 
90 void
92 {
93  NS_LOG_FUNCTION (this);
94  NS_ASSERT (m_modeList.empty ());
96  for (uint8_t index = 0; index <= m_maxSupportedMcsIndexPerSs; ++index)
97  {
98  NS_LOG_LOGIC ("Add HeMcs" << +index << " to list");
99  m_modeList.emplace_back (CreateHeMcs (index));
100  }
101 }
102 
103 WifiMode
104 HePhy::GetSigMode (WifiPpduField field, const WifiTxVector& txVector) const
105 {
106  switch (field)
107  {
108  case WIFI_PPDU_FIELD_TRAINING: //consider SIG-A (SIG-B) mode for training for the time being for SU/ER-SU/TB (MU) (useful for InterferenceHelper)
109  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
110  {
111  //Training comes after SIG-B
112  return GetSigBMode (txVector);
113  }
114  else
115  {
116  //Training comes after SIG-A
117  return GetSigAMode ();
118  }
119  default:
120  return VhtPhy::GetSigMode (field, txVector);
121  }
122 }
123 
124 WifiMode
125 HePhy::GetSigAMode (void) const
126 {
127  return GetVhtMcs0 (); //same number of data tones as VHT for 20 MHz (i.e. 52)
128 }
129 
130 WifiMode
131 HePhy::GetSigBMode (const WifiTxVector& txVector) const
132 {
133  NS_ABORT_MSG_IF (txVector.GetPreambleType () != WIFI_PREAMBLE_HE_MU, "HE-SIG-B only available for HE MU");
140  uint8_t smallestMcs = 5; //maximum MCS for HE-SIG-B
141  for (auto & info : txVector.GetHeMuUserInfoMap ())
142  {
143  smallestMcs = std::min (smallestMcs, info.second.mcs.GetMcsValue ());
144  }
145  switch (smallestMcs) //GetVhtMcs (mcs) is not static
146  {
147  case 0:
148  return GetVhtMcs0 ();
149  case 1:
150  return GetVhtMcs1 ();
151  case 2:
152  return GetVhtMcs2 ();
153  case 3:
154  return GetVhtMcs3 ();
155  case 4:
156  return GetVhtMcs4 ();
157  case 5:
158  default:
159  return GetVhtMcs5 ();
160  }
161 }
162 
165 {
166  return m_hePpduFormats;
167 }
168 
169 Time
170 HePhy::GetLSigDuration (WifiPreamble /* preamble */) const
171 {
172  return MicroSeconds (8); //L-SIG + RL-SIG
173 }
174 
175 Time
177  uint8_t nDataLtf, uint8_t nExtensionLtf /* = 0 */) const
178 {
179  Time ltfDuration = MicroSeconds (8); //TODO extract from TxVector when available
180  Time stfDuration = (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) ? MicroSeconds (8) : MicroSeconds (4);
181  NS_ABORT_MSG_IF (nDataLtf > 8, "Unsupported number of LTFs " << +nDataLtf << " for HE");
182  NS_ABORT_MSG_IF (nExtensionLtf > 0, "No extension LTFs expected for HE");
183  return stfDuration + ltfDuration * nDataLtf; //HE-STF + HE-LTFs
184 }
185 
186 Time
188 {
189  return (preamble == WIFI_PREAMBLE_HE_ER_SU) ? MicroSeconds (16) : MicroSeconds (8); //HE-SIG-A (first and second symbol)
190 }
191 
192 Time
193 HePhy::GetSigBDuration (const WifiTxVector& txVector) const
194 {
195  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU) //See section 27.3.10.8 of IEEE 802.11ax draft 4.0.
196  {
197  /*
198  * Compute the number of bits used by common field.
199  * Assume that compression bit in HE-SIG-A is not set (i.e. not
200  * full band MU-MIMO); the field is present.
201  */
202  uint16_t bw = txVector.GetChannelWidth ();
203  std::size_t commonFieldSize = 4 /* CRC */ + 6 /* tail */;
204  if (bw <= 40)
205  {
206  commonFieldSize += 8; //only one allocation subfield
207  }
208  else
209  {
210  commonFieldSize += 8 * (bw / 40) /* one allocation field per 40 MHz */ + 1 /* center RU */;
211  }
212 
213  /*
214  * Compute the number of bits used by user-specific field.
215  * MU-MIMO is not supported; only one station per RU.
216  * The user-specific field is composed of N user block fields
217  * spread over each corresponding HE-SIG-B content channel.
218  * Each user block field contains either two or one users' data
219  * (the latter being for odd number of stations per content channel).
220  * Padding will be handled further down in the code.
221  */
222  std::pair<std::size_t, std::size_t> numStaPerContentChannel = txVector.GetNumRusPerHeSigBContentChannel ();
223  std::size_t maxNumStaPerContentChannel = std::max (numStaPerContentChannel.first, numStaPerContentChannel.second);
224  std::size_t maxNumUserBlockFields = maxNumStaPerContentChannel / 2; //handle last user block with single user, if any, further down
225  std::size_t userSpecificFieldSize = maxNumUserBlockFields * (2 * 21 /* user fields (2 users) */ + 4 /* tail */ + 6 /* CRC */);
226  if (maxNumStaPerContentChannel % 2 != 0)
227  {
228  userSpecificFieldSize += 21 /* last user field */ + 4 /* CRC */ + 6 /* tail */;
229  }
230 
231  /*
232  * Compute duration of HE-SIG-B considering that padding
233  * is added up to the next OFDM symbol.
234  * Nss = 1 and GI = 800 ns for HE-SIG-B.
235  */
236  Time symbolDuration = MicroSeconds (4);
237  double numDataBitsPerSymbol = GetSigBMode (txVector).GetDataRate (20, 800, 1) * symbolDuration.GetNanoSeconds () / 1e9;
238  double numSymbols = ceil ((commonFieldSize + userSpecificFieldSize) / numDataBitsPerSymbol);
239 
240  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
241  }
242  else
243  {
244  // no SIG-B
245  return MicroSeconds (0);
246  }
247 }
248 
249 uint16_t
251 {
252  uint8_t sigExtension = 0;
253  if (band == WIFI_PHY_BAND_2_4GHZ)
254  {
255  sigExtension = 6;
256  }
257  uint8_t m = 2; //HE TB PPDU so m is set to 2
258  uint16_t length = ((ceil ((static_cast<double> (ppduDuration.GetNanoSeconds () - (20 * 1000) - (sigExtension * 1000)) / 1000) / 4.0) * 3) - 3 - m);
259  return length;
260 }
261 
262 Time
264 {
266  Time tSymbol = NanoSeconds (12800 + txVector.GetGuardInterval ());
267  Time preambleDuration = WifiPhy::GetStaticPhyEntity (WIFI_MOD_CLASS_HE)->CalculatePhyPreambleAndHeaderDuration (txVector); //this is quite convoluted but only way of keeping the method static
268  uint8_t sigExtension = 0;
269  if (band == WIFI_PHY_BAND_2_4GHZ)
270  {
271  sigExtension = 6;
272  }
273  uint8_t m = 2; //HE TB PPDU so m is set to 2
274  //Equation 27-11 of IEEE P802.11ax/D4.0
275  Time calculatedDuration = MicroSeconds (((ceil (static_cast<double> (length + 3 + m) / 3)) * 4) + 20 + sigExtension);
276  uint32_t nSymbols = floor (static_cast<double> ((calculatedDuration - preambleDuration).GetNanoSeconds () - (sigExtension * 1000)) / tSymbol.GetNanoSeconds ());
277  Time ppduDuration = preambleDuration + (nSymbols * tSymbol) + MicroSeconds (sigExtension);
278  return ppduDuration;
279 }
280 
281 Time
283 {
285  Time duration = GetDuration (WIFI_PPDU_FIELD_PREAMBLE, txVector)
287  + GetDuration (WIFI_PPDU_FIELD_SIG_A, txVector);
288  return duration;
289 }
290 
291 uint8_t
292 HePhy::GetNumberBccEncoders (const WifiTxVector& /* txVector */) const
293 {
294  return 1; //only 1 BCC encoder for HE since higher rates are obtained using LDPC
295 }
296 
297 Time
298 HePhy::GetSymbolDuration (const WifiTxVector& txVector) const
299 {
300  uint16_t gi = txVector.GetGuardInterval ();
301  NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
302  return NanoSeconds (12800 + gi);
303 }
304 
306 HePhy::BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration)
307 {
308  NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration);
309  HePpdu::TxPsdFlag flag = (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB) ?
312  return Create<HePpdu> (psdus, txVector, ppduDuration, m_wifiPhy->GetPhyBand (),
313  ObtainNextUid (txVector), flag);
314 }
315 
316 void
318  Time rxDuration)
319 {
320  NS_LOG_FUNCTION (this << ppdu << rxDuration);
321  const WifiTxVector& txVector = ppdu->GetTxVector ();
322  auto hePpdu = DynamicCast<HePpdu> (ppdu);
323  NS_ASSERT (hePpdu);
324  HePpdu::TxPsdFlag psdFlag = hePpdu->GetTxPsdFlag ();
325  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB
326  && psdFlag == HePpdu::PSD_HE_TB_OFDMA_PORTION)
327  {
328  if (m_currentHeTbPpduUid == ppdu->GetUid ()
329  && GetCurrentEvent () != 0)
330  {
331  //AP or STA has already received non-OFDMA part, switch to OFDMA part, and schedule reception of payload (will be canceled for STAs by StartPayload)
332  bool ofdmaStarted = !m_beginOfdmaPayloadRxEvents.empty ();
333  NS_LOG_INFO ("Switch to OFDMA part (already started? " << (ofdmaStarted ? "Y" : "N") << ") " <<
334  "and schedule OFDMA payload reception in " << GetDuration (WIFI_PPDU_FIELD_TRAINING, txVector).As (Time::NS));
335  Ptr<Event> event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW, !ofdmaStarted);
336  uint16_t staId = GetStaId (ppdu);
339  &HePhy::StartReceiveOfdmaPayload, this, event);
340  }
341  else
342  {
343  //PHY receives the OFDMA payload while having dropped the preamble
344  NS_LOG_INFO ("Consider OFDMA part of the HE TB PPDU as interference since device dropped the preamble");
345  CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
346  //the OFDMA part of the HE TB PPDUs will be noise _after_ the completion of the current event
347  ErasePreambleEvent (ppdu, rxDuration);
348  }
349  }
350  else
351  {
352  PhyEntity::StartReceivePreamble (ppdu, rxPowersW, rxDuration);
353  }
354 }
355 
356 void
358 {
359  NS_LOG_FUNCTION (this);
360  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
361  {
362  beginOfdmaPayloadRxEvent.second.Cancel ();
363  }
366 }
367 
368 void
370 {
371  NS_LOG_FUNCTION (this << reason);
372  if (reason != OBSS_PD_CCA_RESET)
373  {
374  for (auto & endMpduEvent : m_endOfMpduEvents)
375  {
376  endMpduEvent.Cancel ();
377  }
378  m_endOfMpduEvents.clear ();
379  }
380  else
381  {
383  }
384 }
385 
386 void
388 {
389  NS_LOG_FUNCTION (this << *event);
390  if (event->GetPpdu ()->GetType () != WIFI_PPDU_TYPE_UL_MU)
391  {
392  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
393  }
394  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
395  {
396  beginOfdmaPayloadRxEvent.second.Cancel ();
397  }
399 }
400 
403 {
404  Ptr<Event> event;
405  //We store all incoming preamble events, and a decision is made at the end of the preamble detection window.
406  //If a preamble is received after the preamble detection window, it is stored anyway because this is needed for HE TB PPDUs in
407  //order to properly update the received power in InterferenceHelper. The map is cleaned anyway at the end of the current reception.
408  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
409  {
410  auto uidPreamblePair = std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ());
411  const WifiTxVector& txVector = ppdu->GetTxVector ();
412  Time rxDuration = CalculateNonOfdmaDurationForHeTb (txVector); //the OFDMA part of the transmission will be added later on
413  const auto & currentPreambleEvents = GetCurrentPreambleEvents ();
414  auto it = currentPreambleEvents.find (uidPreamblePair);
415  if (it != currentPreambleEvents.end ())
416  {
417  NS_LOG_DEBUG ("Received another HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
418  event = it->second;
419  if (Simulator::Now () - event->GetStartTime () > NanoSeconds (400))
420  {
421  //Section 27.3.14.3 from 802.11ax Draft 4.0: Pre-correction accuracy requirements.
422  //A STA that transmits an HE TB PPDU, non-HT PPDU, or non-HT duplicate PPDU in response to a triggering PPDU
423  //shall ensure that the transmission start time of the HE TB PPDU, non-HT PPDU, or non-HT duplicate PPDU is
424  //within ±0.4 µs + 16 µs from the end, at the STA’s antenna connector, of the last OFDM symbol of the triggering
425  //PPDU (if it contains no PE field) or of the PE field of the triggering PPDU (if the PE field is present).
426  //As a result, if an HE TB PPDU arrives later than 0.4 µs, it is added as an interference but PPDU is dropped.
427  event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
428  NS_LOG_DEBUG ("Drop packet because not received within the 400ns window");
430  }
431  else
432  {
433  //Update received power of the event associated to that UL MU transmission
434  UpdateInterferenceEvent (event, rxPowersW);
435  }
436  if ((GetCurrentEvent () != 0) && (GetCurrentEvent ()->GetPpdu ()->GetUid () != ppdu->GetUid ()))
437  {
438  NS_LOG_DEBUG ("Drop packet because already receiving another HE TB PPDU");
440  }
441  return nullptr;
442  }
443  else
444  {
445  NS_LOG_DEBUG ("Received a new HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
446  event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
447  AddPreambleEvent (event);
448  }
449  }
450  else
451  {
452  event = PhyEntity::DoGetEvent (ppdu, rxPowersW);
453  }
454  return event;
455 }
456 
459 {
460  if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU || ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
461  {
462  auto hePpdu = DynamicCast<const HePpdu> (ppdu);
463  NS_ASSERT (hePpdu);
464  return hePpdu->GetPsdu (GetBssColor (), GetStaId (ppdu));
465  }
466  return PhyEntity::GetAddressedPsduInPpdu (ppdu);
467 }
468 
469 uint8_t
470 HePhy::GetBssColor (void) const
471 {
472  uint8_t bssColor = 0;
473  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
474  if (device)
475  {
476  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
477  if (heConfiguration)
478  {
479  bssColor = heConfiguration->GetBssColor ();
480  }
481  }
482  return bssColor;
483 }
484 
485 uint16_t
487 {
488  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
489  {
490  return ppdu->GetStaId ();
491  }
492  else if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
493  {
494  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
495  if (device)
496  {
497  Ptr<StaWifiMac> mac = DynamicCast<StaWifiMac> (device->GetMac ());
498  if (mac && mac->IsAssociated ())
499  {
500  return mac->GetAssociationId ();
501  }
502  }
503  }
504  return PhyEntity::GetStaId (ppdu);
505 }
506 
509 {
510  NS_LOG_FUNCTION (this << *event << status);
511  //Notify end of SIG-A (in all cases)
512  HeSigAParameters params;
513  params.rssiW = GetRxPowerWForPpdu (event);
514  params.bssColor = event->GetTxVector ().GetBssColor ();
515  NotifyEndOfHeSigA (params); //if OBSS_PD CCA_RESET, set power restriction first and wait till field is processed before switching to IDLE
516 
517  if (status.isSuccess)
518  {
519  //Check if PPDU is filtered based on the BSS color
520  uint8_t myBssColor = GetBssColor ();
521  uint8_t rxBssColor = event->GetTxVector ().GetBssColor ();
522  if (myBssColor != 0 && rxBssColor != 0 && myBssColor != rxBssColor)
523  {
524  NS_LOG_DEBUG ("The BSS color of this PPDU (" << +rxBssColor << ") does not match the device's (" << +myBssColor << "). The PPDU is filtered.");
525  return PhyFieldRxStatus (false, FILTERED, DROP);
526  }
527 
528  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
529  if (event->GetTxVector ().GetPreambleType () == WIFI_PREAMBLE_HE_TB)
530  {
531  m_currentHeTbPpduUid = ppdu->GetUid (); //to be able to correctly schedule start of OFDMA payload
532  }
533 
534  if (ppdu->GetType () != WIFI_PPDU_TYPE_DL_MU && !GetAddressedPsduInPpdu (ppdu)) //Final decision on STA-ID correspondence of DL MU is delayed to end of SIG-B
535  {
536  NS_ASSERT (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU);
537  NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
538  return PhyFieldRxStatus (false, FILTERED, DROP);
539  }
540  }
541  return status;
542 }
543 
544 void
546 {
547  m_endOfHeSigACallback = callback;
548 }
549 
550 void
552 {
554  {
555  m_endOfHeSigACallback (params);
556  }
557 }
558 
561 {
562  NS_LOG_FUNCTION (this << *event << status);
563  if (status.isSuccess)
564  {
565  //Check if PPDU is filtered only if the SIG-B content is supported (not explicitly stated but assumed based on behavior for SIG-A)
566  if (!GetAddressedPsduInPpdu (event->GetPpdu ()))
567  {
568  NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
569  return PhyFieldRxStatus (false, FILTERED, DROP);
570  }
571  }
572  return status;
573 }
574 
575 bool
577 {
578  const WifiTxVector& txVector = ppdu->GetTxVector ();
579  uint16_t staId = GetStaId (ppdu);
580  WifiMode txMode = txVector.GetMode (staId);
581  uint8_t nss = txVector.GetNssMax ();
582  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
583  {
584  for (auto info : txVector.GetHeMuUserInfoMap ())
585  {
586  if (info.first == staId)
587  {
588  nss = info.second.nss; //no need to look at other PSDUs
589  break;
590  }
591  }
592  }
593 
595  {
596  NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
597  return false;
598  }
599  if (!IsModeSupported (txMode))
600  {
601  NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txVector.GetMode () << ")");
602  return false;
603  }
604  return true;
605 }
606 
607 void
609 {
610  NS_LOG_FUNCTION (this << *event);
611  const WifiTxVector& txVector = event->GetTxVector ();
612  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
613  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
614  {
615  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (m_wifiPhy->GetDevice ());
616  bool isAp = device != 0 && (DynamicCast<ApWifiMac> (device->GetMac ()) != 0);
617  if (!isAp)
618  {
619  NS_LOG_DEBUG ("Ignore HE TB PPDU payload received by STA but keep state in Rx");
620  m_endRxPayloadEvents.push_back (Simulator::Schedule (ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector),
621  &PhyEntity::ResetReceive, this, event));
622  //Cancel all scheduled events for OFDMA payload reception
623  NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty () && m_beginOfdmaPayloadRxEvents.begin ()->second.IsRunning ());
624  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
625  {
626  beginOfdmaPayloadRxEvent.second.Cancel ();
627  }
629  }
630  else
631  {
632  NS_LOG_DEBUG ("Receiving PSDU in HE TB PPDU");
633  uint16_t staId = GetStaId (ppdu);
634  m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
635  m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
636  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
637  {
638  //for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload
639  NS_ASSERT (isAp);
641  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
642  {
643  NS_ASSERT (beginOfdmaPayloadRxEvent.second.IsRunning ());
644  }
645  }
646  }
647  }
648  else
649  {
651  }
652 }
653 
654 void
656 {
657  NS_LOG_FUNCTION (this << ppdu);
658  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
659  {
660  for (auto it = m_endRxPayloadEvents.begin (); it != m_endRxPayloadEvents.end (); )
661  {
662  if (it->IsExpired ())
663  {
664  it = m_endRxPayloadEvents.erase (it);
665  }
666  else
667  {
668  it++;
669  }
670  }
671  if (m_endRxPayloadEvents.empty ())
672  {
673  //We've got the last PPDU of the UL-OFDMA transmission
674  NotifyInterferenceRxEndAndClear (true); //reset WifiPhy
675  }
676  }
677  else
678  {
681  }
682 }
683 
684 void
686 {
687  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
688  RxPowerWattPerChannelBand rxPowersW = event->GetRxPowerWPerBand ();
689  //The total RX power corresponds to the maximum over all the bands
690  auto it = std::max_element (rxPowersW.begin (), rxPowersW.end (),
691  [] (const std::pair<WifiSpectrumBand, double> &p1, const std::pair<WifiSpectrumBand, double> &p2) {
692  return p1.second < p2.second;
693  });
694  NS_LOG_FUNCTION (this << *event << it->second);
695  NS_ASSERT (GetCurrentEvent () != 0);
696  auto itEvent = m_beginOfdmaPayloadRxEvents.find (GetStaId (ppdu));
702  NS_ASSERT (itEvent != m_beginOfdmaPayloadRxEvents.end () && itEvent->second.IsExpired ());
703  m_beginOfdmaPayloadRxEvents.erase (itEvent);
704 
705  Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (ppdu->GetTxVector ());
707  ScheduleEndOfMpdus (event);
708  m_endRxPayloadEvents.push_back (Simulator::Schedule (payloadDuration, &PhyEntity::EndReceivePayload, this, event));
709  m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), SignalNoiseDbm ()});
710  m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), std::vector<bool> ()});
711 }
712 
713 std::pair<uint16_t, WifiSpectrumBand>
714 HePhy::GetChannelWidthAndBand (const WifiTxVector& txVector, uint16_t staId) const
715 {
716  if (txVector.IsMu ())
717  {
718  return std::make_pair (HeRu::GetBandwidth (txVector.GetRu (staId).ruType),
719  GetRuBandForRx (txVector, staId));
720  }
721  else
722  {
723  return PhyEntity::GetChannelWidthAndBand (txVector, staId);
724  }
725 }
726 
728 HePhy::GetRuBandForTx (const WifiTxVector& txVector, uint16_t staId) const
729 {
730  NS_ASSERT (txVector.IsMu ());
731  WifiSpectrumBand band;
732  HeRu::RuSpec ru = txVector.GetRu (staId);
733  uint16_t channelWidth = txVector.GetChannelWidth ();
734  NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
735  HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.ruType, ru.index);
736  HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
737  // for a TX spectrum, the guard bandwidth is a function of the transmission channel width
738  // and the spectrum width equals the transmission channel width (hence bandIndex equals 0)
739  band = m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (channelWidth),
740  range, 0);
741  return band;
742 }
743 
745 HePhy::GetRuBandForRx (const WifiTxVector& txVector, uint16_t staId) const
746 {
747  NS_ASSERT (txVector.IsMu ());
748  WifiSpectrumBand band;
749  HeRu::RuSpec ru = txVector.GetRu (staId);
750  uint16_t channelWidth = txVector.GetChannelWidth ();
751  NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
752  HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.ruType, ru.index);
753  HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
754  // for an RX spectrum, the guard bandwidth is a function of the operating channel width
755  // and the spectrum width equals the operating channel width
757  range, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (channelWidth));
758  return band;
759 }
760 
762 HePhy::GetNonOfdmaBand (const WifiTxVector& txVector, uint16_t staId) const
763 {
765  uint16_t channelWidth = txVector.GetChannelWidth ();
766  NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
767 
768  HeRu::RuSpec ru = txVector.GetRu (staId);
769  uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
770 
771  // Find the RU that encompasses the non-OFDMA part of the HE TB PPDU for the STA-ID
772  HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (channelWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
773 
774  HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.ruType, nonOfdmaRu.index);
775  HeRu::SubcarrierRange range = std::make_pair (groupPreamble.front ().first, groupPreamble.back ().second);
776  return m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (m_wifiPhy->GetChannelWidth ()), range,
778 }
779 
780 uint16_t
782 {
783  if (ru.ruType == HeRu::RU_26_TONE && ru.index == 19)
784  {
785  // the center 26-tone RU in an 80 MHz channel is not fully covered by
786  // any 20 MHz channel, but only by an 80 MHz channel
787  return 80;
788  }
789  return std::max<uint16_t> (HeRu::GetBandwidth (ru.ruType), 20);
790 }
791 
792 uint64_t
794 {
795  return m_currentHeTbPpduUid;
796 }
797 
798 uint16_t
800 {
801  uint16_t channelWidth = PhyEntity::GetMeasurementChannelWidth (ppdu);
809  if (channelWidth >= 40 && ppdu->GetUid () != m_previouslyTxPpduUid)
810  {
811  channelWidth = 20;
812  }
813  return channelWidth;
814 }
815 
816 uint64_t
818 {
819  NS_LOG_FUNCTION (this << txVector);
820  uint64_t uid;
821  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
822  {
823  //Use UID of PPDU containing trigger frame to identify resulting HE TB PPDUs, since the latter should immediately follow the former
825  NS_ASSERT (uid != UINT64_MAX);
826  }
827  else
828  {
829  uid = m_globalPpduUid++;
830  }
831  m_previouslyTxPpduUid = uid; //to be able to identify solicited HE TB PPDUs
832  return uid;
833 }
834 
837 {
838  const WifiTxVector& txVector = ppdu->GetTxVector ();
839  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
840  uint16_t channelWidth = txVector.GetChannelWidth ();
841  NS_LOG_FUNCTION (this << centerFrequency << channelWidth << txPowerW);
842  auto hePpdu = DynamicCast<const HePpdu> (ppdu);
843  NS_ASSERT (hePpdu);
844  HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
847  {
848  WifiSpectrumBand band = GetRuBandForTx (txVector, GetStaId (hePpdu));
849  v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
850  }
851  else
852  {
854  {
855  //non-OFDMA portion is sent only on the 20 MHz channels covering the RU
856  uint16_t staId = GetStaId (hePpdu);
857  centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId);
858  uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
859  channelWidth = ruWidth < 20 ? 20 : ruWidth;
860  }
861  const auto & txMaskRejectionParams = GetTxMaskRejectionParams ();
862  v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth),
863  std::get<0> (txMaskRejectionParams), std::get<1> (txMaskRejectionParams), std::get<2> (txMaskRejectionParams));
864  }
865  return v;
866 }
867 
868 uint16_t
869 HePhy::GetCenterFrequencyForNonOfdmaPart (const WifiTxVector& txVector, uint16_t staId) const
870 {
871  NS_LOG_FUNCTION (this << txVector << staId);
873  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
874  uint16_t currentWidth = txVector.GetChannelWidth ();
875 
876  HeRu::RuSpec ru = txVector.GetRu (staId);
877  uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
878  if (nonOfdmaWidth != currentWidth)
879  {
880  //Obtain the index of the non-OFDMA portion
881  HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (currentWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
882 
883  uint16_t startingFrequency = centerFrequency - (currentWidth / 2);
884  centerFrequency = startingFrequency + nonOfdmaWidth * (nonOfdmaRu.index - 1) + nonOfdmaWidth / 2;
885  }
886  return centerFrequency;
887 }
888 
889 void
891 {
892  NS_LOG_FUNCTION (this << ppdu);
893  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
894  {
895  //non-OFDMA part
896  Time nonOfdmaDuration = CalculateNonOfdmaDurationForHeTb (ppdu->GetTxVector ());
897  Transmit (nonOfdmaDuration, ppdu, "non-OFDMA transmission");
898 
899  //OFDMA part
900  auto hePpdu = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
901  NS_ASSERT (hePpdu);
902  hePpdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
903  Time ofdmaDuration = ppdu->GetTxDuration () - nonOfdmaDuration;
904  Simulator::Schedule (nonOfdmaDuration, &PhyEntity::Transmit, this, ofdmaDuration, hePpdu, "OFDMA transmission");
905  }
906  else
907  {
908  PhyEntity::StartTx (ppdu);
909  }
910 }
911 
912 uint16_t
914 {
915  const WifiTxVector& txVector = ppdu->GetTxVector ();
916  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB && ppdu->GetStaId () != SU_STA_ID)
917  {
918  auto hePpdu = DynamicCast<const HePpdu> (ppdu);
919  NS_ASSERT (hePpdu);
920  HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
922  uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (ppdu->GetStaId ()).ruType);
923  uint16_t channelWidth = (flag == HePpdu::PSD_HE_TB_NON_OFDMA_PORTION && ruWidth < 20) ? 20 : ruWidth;
924  NS_LOG_INFO ("Use channelWidth=" << channelWidth << " MHz for HE TB from " << ppdu->GetStaId () << " for " << flag);
925  return channelWidth;
926  }
927  else
928  {
930  }
931 }
932 
933 bool
934 HePhy::CanReceivePpdu (Ptr<WifiPpdu> ppdu, uint16_t txCenterFreq) const
935 {
936  NS_LOG_FUNCTION (this << ppdu << txCenterFreq);
937 
938  if (ppdu->GetTxVector ().IsUlMu ())
939  {
940  // APs are able to receive TB PPDUs sent on a band other than the primary20 channel
941  return true;
942  }
943  return VhtPhy::CanReceivePpdu (ppdu, txCenterFreq);
944 }
945 
946 Time
948 {
949  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
950  {
951  return ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band);
952  }
953 
954  Time maxDuration = Seconds (0);
955  for (auto & staIdPsdu : psduMap)
956  {
957  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
958  {
959  WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap ();
960  NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector");
961  }
962  Time current = WifiPhy::CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band,
963  staIdPsdu.first);
964  if (current > maxDuration)
965  {
966  maxDuration = current;
967  }
968  }
969  NS_ASSERT (maxDuration.IsStrictlyPositive ());
970  return maxDuration;
971 }
972 
973 void
975 {
976  for (uint8_t i = 0; i < 12; ++i)
977  {
978  GetHeMcs (i);
979  }
980 }
981 
982 WifiMode
983 HePhy::GetHeMcs (uint8_t index)
984 {
985 #define CASE(x) \
986 case x: \
987  return GetHeMcs ## x (); \
988 
989  switch (index)
990  {
991  CASE ( 0)
992  CASE ( 1)
993  CASE ( 2)
994  CASE ( 3)
995  CASE ( 4)
996  CASE ( 5)
997  CASE ( 6)
998  CASE ( 7)
999  CASE ( 8)
1000  CASE ( 9)
1001  CASE (10)
1002  CASE (11)
1003  default:
1004  NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for HE");
1005  return WifiMode ();
1006  }
1007 #undef CASE
1008 }
1009 
1010 #define GET_HE_MCS(x) \
1011 WifiMode \
1012 HePhy::GetHeMcs ## x (void) \
1013 { \
1014  static WifiMode mcs = CreateHeMcs (x); \
1015  return mcs; \
1016 } \
1017 
1018 GET_HE_MCS (0);
1019 GET_HE_MCS (1);
1020 GET_HE_MCS (2);
1021 GET_HE_MCS (3);
1022 GET_HE_MCS (4);
1023 GET_HE_MCS (5);
1024 GET_HE_MCS (6);
1025 GET_HE_MCS (7);
1026 GET_HE_MCS (8);
1027 GET_HE_MCS (9);
1028 GET_HE_MCS (10);
1029 GET_HE_MCS (11);
1030 #undef GET_HE_MCS
1031 
1032 WifiMode
1033 HePhy::CreateHeMcs (uint8_t index)
1034 {
1035  NS_ASSERT_MSG (index <= 11, "HeMcs index must be <= 11!");
1036  return WifiModeFactory::CreateWifiMcs ("HeMcs" + std::to_string (index),
1037  index,
1039  MakeBoundCallback (&GetCodeRate, index),
1041  MakeBoundCallback (&GetPhyRate, index),
1043  MakeBoundCallback (&GetDataRate, index),
1047 }
1048 
1050 HePhy::GetCodeRate (uint8_t mcsValue)
1051 {
1052  switch (mcsValue)
1053  {
1054  case 10:
1055  return WIFI_CODE_RATE_3_4;
1056  case 11:
1057  return WIFI_CODE_RATE_5_6;
1058  default:
1059  return VhtPhy::GetCodeRate (mcsValue);
1060  }
1061 }
1062 
1063 uint16_t
1065 {
1066  switch (mcsValue)
1067  {
1068  case 10:
1069  case 11:
1070  return 1024;
1071  default:
1072  return VhtPhy::GetConstellationSize (mcsValue);
1073  }
1074 }
1075 
1076 uint64_t
1077 HePhy::GetPhyRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1078 {
1079  WifiCodeRate codeRate = GetCodeRate (mcsValue);
1080  uint64_t dataRate = GetDataRate (mcsValue, channelWidth, guardInterval, nss);
1081  return HtPhy::CalculatePhyRate (codeRate, dataRate);
1082 }
1083 
1084 uint64_t
1085 HePhy::GetPhyRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1086 {
1087  uint16_t bw = txVector.GetChannelWidth ();
1088  if (txVector.IsMu ())
1089  {
1090  bw = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
1091  }
1092  return HePhy::GetPhyRate (txVector.GetMode (staId).GetMcsValue (),
1093  bw,
1094  txVector.GetGuardInterval (),
1095  txVector.GetNss (staId));
1096 }
1097 
1098 uint64_t
1099 HePhy::GetDataRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1100 {
1101  uint16_t bw = txVector.GetChannelWidth ();
1102  if (txVector.IsMu ())
1103  {
1104  bw = HeRu::GetBandwidth (txVector.GetRu (staId).ruType);
1105  }
1106  return HePhy::GetDataRate (txVector.GetMode (staId).GetMcsValue (),
1107  bw,
1108  txVector.GetGuardInterval (),
1109  txVector.GetNss (staId));
1110 }
1111 
1112 uint64_t
1113 HePhy::GetDataRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1114 {
1115  NS_ASSERT (guardInterval == 800 || guardInterval == 1600 || guardInterval == 3200);
1116  NS_ASSERT (nss <= 8);
1117  return HtPhy::CalculateDataRate (12.8, guardInterval,
1118  GetUsableSubcarriers (channelWidth),
1119  static_cast<uint16_t> (log2 (GetConstellationSize (mcsValue))),
1120  HtPhy::GetCodeRatio (GetCodeRate (mcsValue)), nss);
1121 }
1122 
1123 uint16_t
1124 HePhy::GetUsableSubcarriers (uint16_t channelWidth)
1125 {
1126  switch (channelWidth)
1127  {
1128  case 2: //26-tone RU
1129  return 24;
1130  case 4: //52-tone RU
1131  return 48;
1132  case 8: //106-tone RU
1133  return 102;
1134  case 20:
1135  default:
1136  return 234;
1137  case 40:
1138  return 468;
1139  case 80:
1140  return 980;
1141  case 160:
1142  return 1960;
1143  }
1144 }
1145 
1146 uint64_t
1148 {
1149  WifiCodeRate codeRate = GetCodeRate (mcsValue);
1150  uint16_t constellationSize = GetConstellationSize (mcsValue);
1151  return CalculateNonHtReferenceRate (codeRate, constellationSize);
1152 }
1153 
1154 uint64_t
1155 HePhy::CalculateNonHtReferenceRate (WifiCodeRate codeRate, uint16_t constellationSize)
1156 {
1157  uint64_t dataRate;
1158  switch (constellationSize)
1159  {
1160  case 1024:
1161  if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
1162  {
1163  dataRate = 54000000;
1164  }
1165  else
1166  {
1167  NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
1168  }
1169  break;
1170  default:
1171  dataRate = VhtPhy::CalculateNonHtReferenceRate (codeRate, constellationSize);
1172  }
1173  return dataRate;
1174 }
1175 
1176 bool
1177 HePhy::IsModeAllowed (uint16_t /* channelWidth */, uint8_t /* nss */)
1178 {
1179  return true;
1180 }
1181 
1184 {
1185  uint16_t staId = SU_STA_ID;
1186 
1187  if (txVector.IsUlMu ())
1188  {
1189  NS_ASSERT (txVector.GetHeMuUserInfoMap ().size () == 1);
1190  staId = txVector.GetHeMuUserInfoMap ().begin ()->first;
1191  }
1192 
1193  return WifiConstPsduMap ({std::make_pair (staId, psdu)});
1194 }
1195 
1196 uint32_t
1198 {
1199  return 6500631;
1200 }
1201 
1202 } //namespace ns3
1203 
1204 namespace {
1205 
1209 static class ConstructorHe
1210 {
1211 public:
1213  {
1215  ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HE, ns3::Create<ns3::HePhy> ());
1216  }
1217 } g_constructor_he;
1218 
1219 }
std::map< uint16_t, EventId > m_beginOfdmaPayloadRxEvents
the beginning of the OFDMA payload reception events (indexed by STA-ID)
Definition: he-phy.h:424
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1700
Ptr< const Event > GetCurrentEvent(void) const
Get the pointer to the current event (stored in WifiPhy).
Definition: phy-entity.cc:1003
virtual const PpduFormats & GetPpduFormats(void) const override
Return the PPDU formats of the PHY.
Definition: he-phy.cc:164
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
nanosecond
Definition: nstime.h:118
uint8_t GetNssMax(void) const
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
RuType ruType
RU type.
Definition: he-ru.h:67
std::map< UidStaIdPair, SignalNoiseDbm > m_signalNoiseMap
Map of the latest signal power and noise power in dBm (noise power includes the noise figure) ...
Definition: phy-entity.h:824
static uint64_t GetPhyRate(uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
Return the PHY rate corresponding to the supplied HE MCS index, channel width, guard interval...
Definition: he-phy.cc:1077
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
Definition: he-ru.h:56
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 "...
virtual Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
Definition: he-phy.cc:306
Parameters for received HE-SIG-A for OBSS_PD based SR.
Definition: he-phy.h:46
static uint16_t ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, WifiPhyBand band)
Definition: he-phy.cc:250
void NotifyEndOfHeSigA(HeSigAParameters params)
Fire a EndOfHeSigA callback (if connected) once HE-SIG-A field has been received. ...
Definition: he-phy.cc:551
Ptr< HeConfiguration > GetHeConfiguration(void) const
static WifiMode GetVhtMcs5(void)
Return MCS 5 from VHT MCS values.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector &txVector) const
Definition: he-phy.cc:282
static uint64_t CalculateDataRate(double symbolDuration, uint16_t guardInterval, uint16_t usableSubCarriers, uint16_t numberOfBitsPerSubcarrier, double codingRate, uint8_t nss)
Calculates data rate from the supplied parameters.
Definition: ht-phy.cc:674
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied VHT MCS index.
Definition: vht-phy.cc:391
std::pair< uint16_t, WifiSpectrumBand > GetChannelWidthAndBand(const WifiTxVector &txVector, uint16_t staId) const override
Get the channel width and band to use (will be overloaded by child classes).
Definition: he-phy.cc:714
void StartReceiveOfdmaPayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: he-phy.cc:685
HePhy(bool buildModeList=true)
Constructor for HE PHY.
Definition: he-phy.cc:70
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition: he-phy.h:421
void ResetReceive(Ptr< Event > event)
Reset PHY at the end of the PPDU under reception after it has failed the PHY header.
Definition: phy-entity.cc:974
static uint64_t CalculatePhyRate(WifiCodeRate codeRate, uint64_t dataRate)
Return the PHY rate corresponding to the supplied code rate and data rate.
Definition: ht-phy.cc:627
#define min(a, b)
Definition: 80211b.c:42
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: phy-entity.h:814
virtual Time GetSymbolDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:298
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1124
std::map< uint16_t, HeMuUserInfo > HeMuUserInfoMap
map of HE MU specific user info paramters indexed by STA-ID
PhyFieldRxStatus ProcessSigB(Ptr< Event > event, PhyFieldRxStatus status) override
Process SIG-B, perform amendment-specific actions, and provide an updated status of the reception...
Definition: he-phy.cc:560
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
Definition: phy-entity.cc:960
void StartTx(Ptr< WifiPpdu > ppdu) override
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
Definition: he-phy.cc:890
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW)
Get the event corresponding to the incoming PPDU.
Definition: phy-entity.cc:739
WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
Definition: he-phy.cc:104
#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
virtual bool CanReceivePpdu(Ptr< WifiPpdu > ppdu, uint16_t txCenterFreq) const
Check whether the given PPDU can be received by this PHY entity.
Definition: phy-entity.cc:1081
static WifiMode CreateHeMcs(uint8_t index)
Create and return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1033
virtual bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const override
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Definition: he-phy.cc:576
void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu) override
Perform amendment-specific actions at the end of the reception of the payload.
Definition: he-phy.cc:655
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
virtual void StartTx(Ptr< WifiPpdu > ppdu)
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
Definition: phy-entity.cc:1030
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
virtual uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const
Return the STA ID that has been assigned to the station this PHY belongs to.
Definition: phy-entity.cc:519
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
Constructor class for HE modes.
Definition: he-phy.cc:1209
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
uint16_t GetGuardInterval(void) const
void DoResetReceive(Ptr< Event > event) override
Perform amendment-specific actions before resetting PHY at the end of the PPDU under reception after ...
Definition: he-phy.cc:387
virtual bool CanReceivePpdu(Ptr< WifiPpdu > ppdu, uint16_t txCenterFreq) const override
Check whether the given PPDU can be received by this PHY entity.
Definition: he-phy.cc:934
#define HE_PHY
This defines the BSS membership value for HE PHY.
Definition: he-phy.h:41
uint8_t GetNss(uint16_t staId=SU_STA_ID) const
If this TX vector is associated with an SU PPDU, return the number of spatial streams.
uint8_t bssColor
BSS color.
Definition: he-phy.h:49
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const
Definition: wifi-phy.cc:1924
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:983
static Time ConvertLSigLengthToHeTbPpduDuration(uint16_t length, const WifiTxVector &txVector, WifiPhyBand band)
Definition: he-phy.cc:263
represent a single transmission modeA WifiMode is implemented by a single integer which is used to lo...
Definition: wifi-mode.h:47
const std::map< std::pair< uint64_t, WifiPreamble >, Ptr< Event > > & GetCurrentPreambleEvents(void) const
Get the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:725
const uint16_t WIFI_CODE_RATE_3_4
virtual ~HePhy()
Destructor for HE PHY.
Definition: he-phy.cc:85
std::pair< int16_t, int16_t > SubcarrierRange
(lowest index, highest index) pair defining a subcarrier range
Definition: he-ru.h:53
virtual void DoStartReceivePayload(Ptr< Event > event) override
Start receiving the PSDU (i.e.
Definition: he-phy.cc:608
static WifiMode GetVhtMcs4(void)
Return MCS 4 from VHT MCS values.
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
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(void) const
Definition: wifi-phy.cc:1233
WifiPreamble GetPreambleType(void) const
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP, HT-GF-STF + HT-GF-LTF1 fields for HT-GF, L-STF + L-LTF fields otherwise.
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1616
std::tuple< double, double, double > GetTxMaskRejectionParams(void) const
Definition: phy-entity.cc:1061
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, PhyRateFromTxVectorCallback phyRateFromTxVectorCallback, DataRateCallback dataRateCallback, DataRateFromTxVectorCallback dataRateFromTxVectorCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, ModeAllowedCallback isModeAllowedCallback)
Definition: wifi-mode.cc:291
static class anonymous_namespace{he-phy.cc}::ConstructorHe g_constructor_he
the constructor for HE modes
static RuSpec FindOverlappingRu(uint16_t bw, RuSpec referenceRu, RuType searchedRuType)
Find the RU allocation of the given RU type overlapping the given reference RU allocation.
Definition: he-ru.cc:258
static bool IsModeAllowed(uint16_t channelWidth, uint8_t nss)
Check whether the combination of <MCS, channel width, NSS> is allowed.
Definition: he-phy.cc:1177
uint64_t m_currentHeTbPpduUid
UID of the HE TB PPDU being received.
Definition: he-phy.h:422
virtual Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: phy-entity.cc:203
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:333
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:870
static WifiMode GetVhtMcs1(void)
Return MCS 1 from VHT MCS values.
#define max(a, b)
Definition: 80211b.c:43
virtual std::pair< uint16_t, WifiSpectrumBand > GetChannelWidthAndBand(const WifiTxVector &txVector, uint16_t staId) const
Get the channel width and band to use (will be overloaded by child classes).
Definition: phy-entity.cc:718
Status of the reception of the PPDU field.
Definition: phy-entity.h:110
RU Specification.
Definition: he-ru.h:64
WifiMode GetSigBMode(const WifiTxVector &txVector) const override
Definition: he-phy.cc:131
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
static uint64_t GetDataRate(uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
Return the data rate corresponding to the supplied HE MCS index, channel width, guard interval...
Definition: he-phy.cc:1113
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSD for HE TB PPDU non-OFDMA...
Definition: he-ppdu.h:159
static RuType GetRuType(uint16_t bandwidth)
Get the RU corresponding to the approximate bandwidth.
Definition: he-ru.cc:358
mac
Definition: third.py:99
virtual uint16_t GetTransmissionChannelWidth(Ptr< const WifiPpdu > ppdu) const
Get the channel width over which the PPDU will be effectively be transmitted.
Definition: phy-entity.cc:1067
WifiPpduField
The type of PPDU field (grouped for convenience)
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: phy-entity.cc:633
uint64_t GetCurrentHeTbPpduUid(void) const
Definition: he-phy.cc:793
virtual void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: phy-entity.cc:362
Time CalculateTxDuration(WifiConstPsduMap psduMap, const WifiTxVector &txVector, WifiPhyBand band) const override
Definition: he-phy.cc:947
uint8_t m_maxMcsIndexPerSs
the maximum MCS index per spatial stream as defined by the standard
Definition: ht-phy.h:536
GET_HE_MCS(0)
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
uint16_t GetCenterFrequencyForNonOfdmaPart(const WifiTxVector &txVector, uint16_t staId) const
Get the center frequency of the non-OFDMA part of the current TxVector for the given STA-ID...
Definition: he-phy.cc:869
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(void) const
Get the number of RUs per HE-SIG-B content channel.
static Ptr< SpectrumValue > CreateHeOfdmTxPowerSpectralDensity(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 High Efficiency (HE) (802...
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:1022
EndOfHeSigACallback m_endOfHeSigACallback
end of HE-SIG-A callback
Definition: he-phy.h:426
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
bool isSuccess
outcome (true if success) of the reception
Definition: phy-entity.h:113
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: phy-entity.cc:554
void DoAbortCurrentReception(WifiPhyRxfailureReason reason) override
Perform amendment-specific actions before aborting the current reception.
Definition: he-phy.cc:369
Time GetSigADuration(WifiPreamble preamble) const override
Definition: he-phy.cc:187
void ErasePreambleEvent(Ptr< const WifiPpdu > ppdu, Time rxDuration)
Erase the event corresponding to the PPDU from the list of preamble events, but consider it as noise ...
Definition: phy-entity.cc:498
const uint16_t WIFI_CODE_RATE_5_6
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
void SetEndOfHeSigACallback(EndOfHeSigACallback callback)
Set a callback for a end of HE-SIG-A.
Definition: he-phy.cc:545
static uint64_t CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize)
Return the rate (in bps) of the non-HT Reference Rate which corresponds to the supplied code rate and...
Definition: vht-phy.cc:478
Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector) const
Definition: phy-entity.cc:186
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition: phy-entity.h:816
Every class exported by the ns3 library is enclosed in the ns3 namespace.
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:392
void Transmit(Time txDuration, Ptr< WifiPpdu > ppdu, std::string type)
This function prepares most of the WifiSpectrumSignalParameters parameters and invokes SpectrumWifiPh...
Definition: phy-entity.cc:1037
void UpdateInterferenceEvent(Ptr< Event > event, RxPowerWattPerChannelBand rxPower)
Update an event in WifiPhy&#39;s InterferenceHelper class.
Definition: phy-entity.cc:757
virtual Time GetTrainingDuration(const WifiTxVector &txVector, uint8_t nDataLtf, uint8_t nExtensionLtf=0) const override
Definition: he-phy.cc:176
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition: phy-entity.h:826
virtual void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu)
Perform amendment-specific actions at the end of the reception of the payload.
Definition: phy-entity.cc:672
static WifiMode GetVhtMcs0(void)
Return MCS 0 from VHT MCS values.
virtual void BuildModeList(void) override
Build mode list.
Definition: he-phy.cc:91
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied VHT MCS index.
Definition: vht-phy.cc:405
static uint64_t GetDataRateFromTxVector(const WifiTxVector &txVector, uint16_t staId=SU_STA_ID)
Return the data rate corresponding to the supplied TXVECTOR for the STA-ID.
Definition: he-phy.cc:1099
WifiSpectrumBand GetRuBandForTx(const WifiTxVector &txVector, uint16_t staId) const
Get the band in the TX spectrum associated with the RU used by the PSDU transmitted to/by a given STA...
Definition: he-phy.cc:728
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:731
static SubcarrierGroup GetSubcarrierGroup(uint16_t bw, RuType ruType, std::size_t index)
Get the subcarrier group of the RU having the given index among all the RUs of the given type (number...
Definition: he-ru.cc:172
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:886
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
virtual void DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:540
uint8_t m_maxSupportedMcsIndexPerSs
the maximum supported MCS index per spatial stream
Definition: ht-phy.h:537
static const PpduFormats m_hePpduFormats
HE PPDU formats.
Definition: he-phy.h:443
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
static void InitializeModes(void)
Initialize all HE modes.
Definition: he-phy.cc:974
Ptr< const WifiPsdu > GetAddressedPsduInPpdu(Ptr< const WifiPpdu > ppdu) const override
Get the PSDU addressed to that PHY in a PPDU (useful for MU PPDU).
Definition: he-phy.cc:458
Ptr< Event > CreateInterferenceEvent(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand rxPower, bool isStartOfdmaRxing=false)
Create an event using WifiPhy&#39;s InterferenceHelper class.
Definition: phy-entity.cc:751
uint64_t GetPreviouslyRxPpduUid(void) const
Definition: wifi-phy.cc:1872
virtual WifiConstPsduMap GetWifiConstPsduMap(Ptr< const WifiPsdu > psdu, const WifiTxVector &txVector) const override
Get a WifiConstPsduMap from a PSDU and the TXVECTOR to use to send the PSDU.
Definition: he-phy.cc:1183
non-HE TB PPDU transmissions
Definition: he-ppdu.h:161
drop PPDU and set CCA_BUSY
Definition: phy-entity.h:102
WifiSpectrumBand GetRuBandForRx(const WifiTxVector &txVector, uint16_t staId) const
Get the band in the RX spectrum associated with the RU used by the PSDU transmitted to/by a given STA...
Definition: he-phy.cc:745
double rssiW
RSSI in W.
Definition: he-phy.h:48
#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:88
WifiMode GetSigAMode(void) const override
Definition: he-phy.cc:125
static double GetCodeRatio(WifiCodeRate codeRate)
Convert WifiCodeRate to a ratio, e.g., code ratio of WIFI_CODE_RATE_1_2 is 0.5.
Definition: ht-phy.cc:642
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:32
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
static Ptr< SpectrumValue > CreateHeMuOfdmTxPowerSpectralDensity(uint32_t centerFrequency, uint16_t channelWidth, double txPowerW, uint16_t guardBandwidth, WifiSpectrumBand ru)
Create a transmit power spectral density corresponding to the OFDMA part of HE TB PPDUs for a given R...
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Definition: he-phy.cc:799
uint16_t GetLength(void) const
Get the LENGTH field of the L-SIG.
Ptr< WifiMac > GetMac(void) const
std::map< UidStaIdPair, std::vector< bool > > m_statusPerMpduMap
Map of the current reception status per MPDU that is filled in as long as MPDUs are being processed b...
Definition: phy-entity.h:823
static WifiMode GetVhtMcs2(void)
Return MCS 2 from VHT MCS values.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
uint8_t GetPrimaryChannelIndex(uint16_t primaryChannelWidth) const
If the operating channel width is a multiple of 20 MHz, return the index of the primary channel of th...
#define CASE(x)
SignalNoiseDbm structure.
Definition: phy-entity.h:52
void CancelAllEvents(void) override
Cancel and clear all running events.
Definition: he-phy.cc:357
void NotifyInterferenceRxEndAndClear(bool reset)
Notify WifiPhy&#39;s InterferenceHelper of the end of the reception, clear maps and end of MPDU event...
Definition: phy-entity.cc:763
std::map< WifiPreamble, std::vector< WifiPpduField > > PpduFormats
A map of PPDU field elements per preamble type.
Definition: phy-entity.h:499
bool IsUlMu(void) const
Return true if this TX vector is used for an uplink multi-user transmission.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW) override
Get the event corresponding to the incoming PPDU.
Definition: he-phy.cc:402
std::size_t index
index (starting at 1)
Definition: he-ru.h:68
STF + LTF fields (excluding those in preamble for HT-GF)
PHY entity for VHT (11ac)VHT PHY is based on HT PHY.
Definition: vht-phy.h:48
Time GetSigBDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:193
static uint64_t CalculateNonHtReferenceRate(WifiCodeRate codeRate, uint16_t constellationSize)
Return the rate (in bps) of the non-HT Reference Rate which corresponds to the supplied code rate and...
Definition: he-phy.cc:1155
virtual uint16_t GetStaId(const Ptr< const WifiPpdu > ppdu) const override
Return the STA ID that has been assigned to the station this PHY belongs to.
Definition: he-phy.cc:486
static uint64_t GetPhyRateFromTxVector(const WifiTxVector &txVector, uint16_t staId=SU_STA_ID)
Return the PHY rate corresponding to the supplied TXVECTOR for the STA-ID.
Definition: he-phy.cc:1085
Ptr< NetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:783
static WifiMode GetVhtMcs3(void)
Return MCS 3 from VHT MCS values.
uint64_t ObtainNextUid(const WifiTxVector &txVector) override
Obtain the next UID for the PPDU to transmit.
Definition: he-phy.cc:817
uint8_t GetBssColor(void) const
Definition: he-phy.cc:470
static uint64_t GetNonHtReferenceRate(uint8_t mcsValue)
Calculate the rate in bps of the non-HT Reference Rate corresponding to the supplied HE MCS index...
Definition: he-phy.cc:1147
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
PhyFieldRxStatus ProcessSigA(Ptr< Event > event, PhyFieldRxStatus status) override
Process SIG-A, perform amendment-specific actions, and provide an updated status of the reception...
Definition: he-phy.cc:508
uint16_t GetChannelWidth(void) const
virtual uint32_t GetMaxPsduSize(void) const override
Get the maximum PSDU size in bytes (see Table 27-55 HE PHY characteristics of IEEE 802...
Definition: he-phy.cc:1197
const WifiPhyOperatingChannel & GetOperatingChannel(void) const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1137
uint8_t m_bssMembershipSelector
the BSS membership selector
Definition: ht-phy.h:538
virtual Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const override
Definition: he-phy.cc:836
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1329
virtual void CancelAllEvents(void)
Cancel and clear all running events.
Definition: phy-entity.cc:913
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:400
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
OFDMA portion of HE TB PPDU, which should only be sent on RU.
Definition: he-ppdu.h:163
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW, Time rxDuration) override
Start receiving the PHY preamble of a PPDU (i.e.
Definition: he-phy.cc:317
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get the map HE MU user-specific transmission information indexed by STA-ID.
Declaration of ns3::HePhy class and ns3::HeSigAParameters struct.
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1050
virtual WifiMode GetSigMode(WifiPpduField field, const WifiTxVector &txVector) const override
Get the WifiMode for the SIG field specified by the PPDU field.
Definition: vht-phy.cc:109
uint16_t GetNonOfdmaWidth(HeRu::RuSpec ru) const
Get the width in MHz of the non-OFDMA portion of an HE TB PPDU.
Definition: he-phy.cc:781
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2145
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:137
uint16_t GetTransmissionChannelWidth(Ptr< const WifiPpdu > ppdu) const override
Get the channel width over which the PPDU will be effectively be transmitted.
Definition: he-phy.cc:913
WifiSpectrumBand GetNonOfdmaBand(const WifiTxVector &txVector, uint16_t staId) const
Get the band used to transmit the non-OFDMA part of an HE TB PPDU.
Definition: he-phy.cc:762
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1064
static uint16_t GetUsableSubcarriers(uint16_t channelWidth)
Definition: he-phy.cc:1124
virtual 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: vht-phy.cc:145
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
Definition: phy-entity.cc:90
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
#define SU_STA_ID
Definition: wifi-mode.h:32
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
double GetRxPowerWForPpdu(Ptr< Event > event) const
Obtain the received power (W) for a given band.
Definition: phy-entity.cc:997
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:100
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
preamble of HE TB PPDU, which should only be sent on minimum subset of 20 MHz channels containing RU ...
Definition: he-ppdu.h:162
uint8_t GetNumberBccEncoders(const WifiTxVector &txVector) const override
Definition: he-phy.cc:292
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1421
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:811
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:808
virtual uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const
Return the channel width used to measure the RSSI.
Definition: phy-entity.cc:1009
Time GetLSigDuration(WifiPreamble preamble) const override
Definition: he-phy.cc:170
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1055
Declaration of ns3::HePpdu class.