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).GetRuType ()),
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.GetRuType (), ru.GetPhyIndex ());
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.GetRuType (), ru.GetPhyIndex ());
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  nonOfdmaRu.SetPhyIndex (channelWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
774 
775  HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.GetRuType (), nonOfdmaRu.GetPhyIndex ());
776  HeRu::SubcarrierRange range = std::make_pair (groupPreamble.front ().first, groupPreamble.back ().second);
777  return m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (m_wifiPhy->GetChannelWidth ()), range,
779 }
780 
781 uint16_t
783 {
784  if (ru.GetRuType () == HeRu::RU_26_TONE && ru.GetIndex () == 19)
785  {
786  // the center 26-tone RU in an 80 MHz channel is not fully covered by
787  // any 20 MHz channel, but only by an 80 MHz channel
788  return 80;
789  }
790  return std::max<uint16_t> (HeRu::GetBandwidth (ru.GetRuType ()), 20);
791 }
792 
793 uint64_t
795 {
796  return m_currentHeTbPpduUid;
797 }
798 
799 uint16_t
801 {
802  uint16_t channelWidth = PhyEntity::GetMeasurementChannelWidth (ppdu);
810  if (channelWidth >= 40 && ppdu->GetUid () != m_previouslyTxPpduUid)
811  {
812  channelWidth = 20;
813  }
814  return channelWidth;
815 }
816 
817 uint64_t
819 {
820  NS_LOG_FUNCTION (this << txVector);
821  uint64_t uid;
822  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
823  {
824  //Use UID of PPDU containing trigger frame to identify resulting HE TB PPDUs, since the latter should immediately follow the former
826  NS_ASSERT (uid != UINT64_MAX);
827  }
828  else
829  {
830  uid = m_globalPpduUid++;
831  }
832  m_previouslyTxPpduUid = uid; //to be able to identify solicited HE TB PPDUs
833  return uid;
834 }
835 
838 {
839  const WifiTxVector& txVector = ppdu->GetTxVector ();
840  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
841  uint16_t channelWidth = txVector.GetChannelWidth ();
842  NS_LOG_FUNCTION (this << centerFrequency << channelWidth << txPowerW);
843  auto hePpdu = DynamicCast<const HePpdu> (ppdu);
844  NS_ASSERT (hePpdu);
845  HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
848  {
849  WifiSpectrumBand band = GetRuBandForTx (txVector, GetStaId (hePpdu));
850  v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
851  }
852  else
853  {
855  {
856  //non-OFDMA portion is sent only on the 20 MHz channels covering the RU
857  uint16_t staId = GetStaId (hePpdu);
858  centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId);
859  uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
860  channelWidth = ruWidth < 20 ? 20 : ruWidth;
861  }
862  const auto & txMaskRejectionParams = GetTxMaskRejectionParams ();
863  v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth),
864  std::get<0> (txMaskRejectionParams), std::get<1> (txMaskRejectionParams), std::get<2> (txMaskRejectionParams));
865  }
866  return v;
867 }
868 
869 uint16_t
870 HePhy::GetCenterFrequencyForNonOfdmaPart (const WifiTxVector& txVector, uint16_t staId) const
871 {
872  NS_LOG_FUNCTION (this << txVector << staId);
874  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
875  uint16_t currentWidth = txVector.GetChannelWidth ();
876 
877  HeRu::RuSpec ru = txVector.GetRu (staId);
878  uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
879  if (nonOfdmaWidth != currentWidth)
880  {
881  //Obtain the index of the non-OFDMA portion
882  HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (currentWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
883  nonOfdmaRu.SetPhyIndex (currentWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
884 
885  uint16_t startingFrequency = centerFrequency - (currentWidth / 2);
886  centerFrequency = startingFrequency + nonOfdmaWidth * (nonOfdmaRu.GetPhyIndex () - 1) + nonOfdmaWidth / 2;
887  }
888  return centerFrequency;
889 }
890 
891 void
893 {
894  NS_LOG_FUNCTION (this << ppdu);
895  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
896  {
897  //non-OFDMA part
898  Time nonOfdmaDuration = CalculateNonOfdmaDurationForHeTb (ppdu->GetTxVector ());
899  Transmit (nonOfdmaDuration, ppdu, "non-OFDMA transmission");
900 
901  //OFDMA part
902  auto hePpdu = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
903  NS_ASSERT (hePpdu);
904  hePpdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
905  Time ofdmaDuration = ppdu->GetTxDuration () - nonOfdmaDuration;
906  Simulator::Schedule (nonOfdmaDuration, &PhyEntity::Transmit, this, ofdmaDuration, hePpdu, "OFDMA transmission");
907  }
908  else
909  {
910  PhyEntity::StartTx (ppdu);
911  }
912 }
913 
914 Time
916 {
917  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_TB)
918  {
919  return ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band);
920  }
921 
922  Time maxDuration = Seconds (0);
923  for (auto & staIdPsdu : psduMap)
924  {
925  if (txVector.GetPreambleType () == WIFI_PREAMBLE_HE_MU)
926  {
927  WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap ();
928  NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector");
929  }
930  Time current = WifiPhy::CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band,
931  staIdPsdu.first);
932  if (current > maxDuration)
933  {
934  maxDuration = current;
935  }
936  }
937  NS_ASSERT (maxDuration.IsStrictlyPositive ());
938  return maxDuration;
939 }
940 
941 void
943 {
944  for (uint8_t i = 0; i < 12; ++i)
945  {
946  GetHeMcs (i);
947  }
948 }
949 
950 WifiMode
951 HePhy::GetHeMcs (uint8_t index)
952 {
953 #define CASE(x) \
954 case x: \
955  return GetHeMcs ## x (); \
956 
957  switch (index)
958  {
959  CASE ( 0)
960  CASE ( 1)
961  CASE ( 2)
962  CASE ( 3)
963  CASE ( 4)
964  CASE ( 5)
965  CASE ( 6)
966  CASE ( 7)
967  CASE ( 8)
968  CASE ( 9)
969  CASE (10)
970  CASE (11)
971  default:
972  NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for HE");
973  return WifiMode ();
974  }
975 #undef CASE
976 }
977 
978 #define GET_HE_MCS(x) \
979 WifiMode \
980 HePhy::GetHeMcs ## x (void) \
981 { \
982  static WifiMode mcs = CreateHeMcs (x); \
983  return mcs; \
984 }; \
985 
986 GET_HE_MCS (0)
987 GET_HE_MCS (1)
988 GET_HE_MCS (2)
989 GET_HE_MCS (3)
990 GET_HE_MCS (4)
991 GET_HE_MCS (5)
992 GET_HE_MCS (6)
993 GET_HE_MCS (7)
994 GET_HE_MCS (8)
995 GET_HE_MCS (9)
996 GET_HE_MCS (10)
997 GET_HE_MCS (11)
998 #undef GET_HE_MCS
999 
1000 WifiMode
1001 HePhy::CreateHeMcs (uint8_t index)
1002 {
1003  NS_ASSERT_MSG (index <= 11, "HeMcs index must be <= 11!");
1004  return WifiModeFactory::CreateWifiMcs ("HeMcs" + std::to_string (index),
1005  index,
1007  MakeBoundCallback (&GetCodeRate, index),
1009  MakeBoundCallback (&GetPhyRate, index),
1011  MakeBoundCallback (&GetDataRate, index),
1015 }
1016 
1018 HePhy::GetCodeRate (uint8_t mcsValue)
1019 {
1020  switch (mcsValue)
1021  {
1022  case 10:
1023  return WIFI_CODE_RATE_3_4;
1024  case 11:
1025  return WIFI_CODE_RATE_5_6;
1026  default:
1027  return VhtPhy::GetCodeRate (mcsValue);
1028  }
1029 }
1030 
1031 uint16_t
1033 {
1034  switch (mcsValue)
1035  {
1036  case 10:
1037  case 11:
1038  return 1024;
1039  default:
1040  return VhtPhy::GetConstellationSize (mcsValue);
1041  }
1042 }
1043 
1044 uint64_t
1045 HePhy::GetPhyRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1046 {
1047  WifiCodeRate codeRate = GetCodeRate (mcsValue);
1048  uint64_t dataRate = GetDataRate (mcsValue, channelWidth, guardInterval, nss);
1049  return HtPhy::CalculatePhyRate (codeRate, dataRate);
1050 }
1051 
1052 uint64_t
1053 HePhy::GetPhyRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1054 {
1055  uint16_t bw = txVector.GetChannelWidth ();
1056  if (txVector.IsMu ())
1057  {
1058  bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1059  }
1060  return HePhy::GetPhyRate (txVector.GetMode (staId).GetMcsValue (),
1061  bw,
1062  txVector.GetGuardInterval (),
1063  txVector.GetNss (staId));
1064 }
1065 
1066 uint64_t
1067 HePhy::GetDataRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1068 {
1069  uint16_t bw = txVector.GetChannelWidth ();
1070  if (txVector.IsMu ())
1071  {
1072  bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1073  }
1074  return HePhy::GetDataRate (txVector.GetMode (staId).GetMcsValue (),
1075  bw,
1076  txVector.GetGuardInterval (),
1077  txVector.GetNss (staId));
1078 }
1079 
1080 uint64_t
1081 HePhy::GetDataRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1082 {
1083  NS_ASSERT (guardInterval == 800 || guardInterval == 1600 || guardInterval == 3200);
1084  NS_ASSERT (nss <= 8);
1085  return HtPhy::CalculateDataRate (12.8, guardInterval,
1086  GetUsableSubcarriers (channelWidth),
1087  static_cast<uint16_t> (log2 (GetConstellationSize (mcsValue))),
1088  HtPhy::GetCodeRatio (GetCodeRate (mcsValue)), nss);
1089 }
1090 
1091 uint16_t
1092 HePhy::GetUsableSubcarriers (uint16_t channelWidth)
1093 {
1094  switch (channelWidth)
1095  {
1096  case 2: //26-tone RU
1097  return 24;
1098  case 4: //52-tone RU
1099  return 48;
1100  case 8: //106-tone RU
1101  return 102;
1102  case 20:
1103  default:
1104  return 234;
1105  case 40:
1106  return 468;
1107  case 80:
1108  return 980;
1109  case 160:
1110  return 1960;
1111  }
1112 }
1113 
1114 uint64_t
1116 {
1117  WifiCodeRate codeRate = GetCodeRate (mcsValue);
1118  uint16_t constellationSize = GetConstellationSize (mcsValue);
1119  return CalculateNonHtReferenceRate (codeRate, constellationSize);
1120 }
1121 
1122 uint64_t
1123 HePhy::CalculateNonHtReferenceRate (WifiCodeRate codeRate, uint16_t constellationSize)
1124 {
1125  uint64_t dataRate;
1126  switch (constellationSize)
1127  {
1128  case 1024:
1129  if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
1130  {
1131  dataRate = 54000000;
1132  }
1133  else
1134  {
1135  NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
1136  }
1137  break;
1138  default:
1139  dataRate = VhtPhy::CalculateNonHtReferenceRate (codeRate, constellationSize);
1140  }
1141  return dataRate;
1142 }
1143 
1144 bool
1145 HePhy::IsModeAllowed (uint16_t /* channelWidth */, uint8_t /* nss */)
1146 {
1147  return true;
1148 }
1149 
1152 {
1153  uint16_t staId = SU_STA_ID;
1154 
1155  if (txVector.IsUlMu ())
1156  {
1157  NS_ASSERT (txVector.GetHeMuUserInfoMap ().size () == 1);
1158  staId = txVector.GetHeMuUserInfoMap ().begin ()->first;
1159  }
1160 
1161  return WifiConstPsduMap ({std::make_pair (staId, psdu)});
1162 }
1163 
1164 uint32_t
1166 {
1167  return 6500631;
1168 }
1169 
1170 } //namespace ns3
1171 
1172 namespace {
1173 
1177 static class ConstructorHe
1178 {
1179 public:
1181  {
1183  ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HE, ns3::Create<ns3::HePhy> ());
1184  }
1186 
1187 }
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
Constructor class for HE modes.
Definition: he-phy.cc:1178
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
const PpduFormats & GetPpduFormats(void) const override
Return the PPDU formats of the PHY.
Definition: he-phy.cc:164
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
Time GetLSigDuration(WifiPreamble preamble) const override
Definition: he-phy.cc:170
static Time ConvertLSigLengthToHeTbPpduDuration(uint16_t length, const WifiTxVector &txVector, WifiPhyBand band)
Definition: he-phy.cc:263
void StartReceiveOfdmaPayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: he-phy.cc:685
WifiMode GetSigAMode(void) const override
Definition: he-phy.cc:125
static uint16_t ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, WifiPhyBand band)
Definition: he-phy.cc:250
Time GetSymbolDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:298
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
void DoAbortCurrentReception(WifiPhyRxfailureReason reason) override
Perform amendment-specific actions before aborting the current reception.
Definition: he-phy.cc:369
uint64_t m_currentHeTbPpduUid
UID of the HE TB PPDU being received.
Definition: he-phy.h:414
Time CalculateTxDuration(WifiConstPsduMap psduMap, const WifiTxVector &txVector, WifiPhyBand band) const override
Definition: he-phy.cc:915
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
uint8_t GetBssColor(void) const
Definition: he-phy.cc:470
Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW) override
Get the event corresponding to the incoming PPDU.
Definition: he-phy.cc:402
Time GetSigBDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:193
static WifiMode CreateHeMcs(uint8_t index)
Create and return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1001
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:951
static uint16_t GetUsableSubcarriers(uint16_t channelWidth)
Definition: he-phy.cc:1092
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:1151
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:782
void BuildModeList(void) override
Build mode list.
Definition: he-phy.cc:91
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:1123
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:892
std::map< uint16_t, EventId > m_beginOfdmaPayloadRxEvents
the beginning of the OFDMA payload reception events (indexed by STA-ID)
Definition: he-phy.h:416
void SetEndOfHeSigACallback(EndOfHeSigACallback callback)
Set a callback for a end of HE-SIG-A.
Definition: he-phy.cc:545
uint64_t GetCurrentHeTbPpduUid(void) const
Definition: he-phy.cc:794
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition: he-phy.h:413
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1018
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
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
EndOfHeSigACallback m_endOfHeSigACallback
end of HE-SIG-A callback
Definition: he-phy.h:418
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
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
uint64_t ObtainNextUid(const WifiTxVector &txVector) override
Obtain the next UID for the PPDU to transmit.
Definition: he-phy.cc:818
uint32_t GetMaxPsduSize(void) const override
Get the maximum PSDU size in bytes.
Definition: he-phy.cc:1165
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:1053
void CancelAllEvents(void) override
Cancel and clear all running events.
Definition: he-phy.cc:357
static bool IsModeAllowed(uint16_t channelWidth, uint8_t nss)
Check whether the combination of <MCS, channel width, NSS> is allowed.
Definition: he-phy.cc:1145
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:870
static void InitializeModes(void)
Initialize all HE modes.
Definition: he-phy.cc:942
Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector &txVector) const
Definition: he-phy.cc:282
uint8_t GetNumberBccEncoders(const WifiTxVector &txVector) const override
Definition: he-phy.cc:292
Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
Definition: he-phy.cc:306
void NotifyEndOfHeSigA(HeSigAParameters params)
Fire a EndOfHeSigA callback (if connected) once HE-SIG-A field has been received.
Definition: he-phy.cc:551
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:1081
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:1045
virtual ~HePhy()
Destructor for HE PHY.
Definition: he-phy.cc:85
void DoStartReceivePayload(Ptr< Event > event) override
Start receiving the PSDU (i.e.
Definition: he-phy.cc:608
static const PpduFormats m_hePpduFormats
HE PPDU formats.
Definition: he-phy.h:435
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:1067
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
HePhy(bool buildModeList=true)
Constructor for HE PHY.
Definition: he-phy.cc:70
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
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 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:1115
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
WifiMode GetSigBMode(const WifiTxVector &txVector) const override
Definition: he-phy.cc:131
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
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
Time GetSigADuration(WifiPreamble preamble) const override
Definition: he-phy.cc:187
Time GetTrainingDuration(const WifiTxVector &txVector, uint8_t nDataLtf, uint8_t nExtensionLtf=0) const override
Definition: he-phy.cc:176
Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const override
Definition: he-phy.cc:837
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Definition: he-phy.cc:800
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1032
TxPsdFlag
The transmit power spectral density flag, namely used to correctly build PSD for HE TB PPDU non-OFDMA...
Definition: he-ppdu.h:159
@ PSD_HE_TB_OFDMA_PORTION
OFDMA portion of HE TB PPDU, which should only be sent on RU.
Definition: he-ppdu.h:162
@ PSD_NON_HE_TB
non-HE TB PPDU transmissions
Definition: he-ppdu.h:160
@ PSD_HE_TB_NON_OFDMA_PORTION
preamble of HE TB PPDU, which should only be sent on minimum subset of 20 MHz channels containing RU
Definition: he-ppdu.h:161
RU Specification.
Definition: he-ru.h:68
RuType GetRuType(void) const
Get the RU type.
Definition: he-ru.cc:167
std::size_t GetIndex(void) const
Get the RU index.
Definition: he-ru.cc:174
void SetPhyIndex(uint16_t bw, uint8_t p20Index)
Set the RU PHY index.
Definition: he-ru.cc:188
std::size_t GetPhyIndex(void) const
Get the RU PHY index.
Definition: he-ru.cc:212
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:410
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:487
static SubcarrierGroup GetSubcarrierGroup(uint16_t bw, RuType ruType, std::size_t phyIndex)
Get the subcarrier group of the RU having the given PHY index among all the RUs of the given type (nu...
Definition: he-ru.cc:313
std::vector< SubcarrierRange > SubcarrierGroup
a vector of subcarrier ranges defining a subcarrier group
Definition: he-ru.h:56
std::pair< int16_t, int16_t > SubcarrierRange
(lowest index, highest index) pair defining a subcarrier range
Definition: he-ru.h:53
@ RU_26_TONE
Definition: he-ru.h:43
static RuType GetRuType(uint16_t bandwidth)
Get the RU corresponding to the approximate bandwidth.
Definition: he-ru.cc:512
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
uint8_t m_bssMembershipSelector
the BSS membership selector
Definition: ht-phy.h:529
uint8_t m_maxMcsIndexPerSs
the maximum MCS index per spatial stream as defined by the standard
Definition: ht-phy.h:527
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 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
uint8_t m_maxSupportedMcsIndexPerSs
the maximum supported MCS index per spatial stream
Definition: ht-phy.h:528
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
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand rxPowersW)
Get the event corresponding to the incoming PPDU.
Definition: phy-entity.cc:739
virtual void CancelAllEvents(void)
Cancel and clear all running events.
Definition: phy-entity.cc:913
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:799
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:783
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: phy-entity.h:789
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
void UpdateInterferenceEvent(Ptr< Event > event, RxPowerWattPerChannelBand rxPower)
Update an event in WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:757
std::tuple< double, double, double > GetTxMaskRejectionParams(void) const
Definition: phy-entity.cc:1067
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
Definition: phy-entity.cc:960
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: phy-entity.cc:633
std::map< WifiPreamble, std::vector< WifiPpduField > > PpduFormats
A map of PPDU field elements per preamble type.
Definition: phy-entity.h:477
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition: phy-entity.h:801
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
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition: phy-entity.h:791
double GetRxPowerWForPpdu(Ptr< Event > event) const
Obtain the received power (W) for a given band.
Definition: phy-entity.cc:997
virtual void DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:540
Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector) const
Definition: phy-entity.cc:186
void NotifyInterferenceRxEndAndClear(bool reset)
Notify WifiPhy's InterferenceHelper of the end of the reception, clear maps and end of MPDU event,...
Definition: phy-entity.cc:763
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:798
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
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:1036
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:1043
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1061
Ptr< Event > CreateInterferenceEvent(Ptr< const WifiPpdu > ppdu, const WifiTxVector &txVector, Time duration, RxPowerWattPerChannelBand rxPower, bool isStartOfdmaRxing=false)
Create an event using WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:751
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
Definition: phy-entity.cc:90
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
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:786
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
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
Ptr< const Event > GetCurrentEvent(void) const
Get the pointer to the current event (stored in WifiPhy).
Definition: phy-entity.cc:1003
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:731
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
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:1028
virtual uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const
Return the channel width used to measure the RSSI.
Definition: phy-entity.cc:1009
@ DROP
drop PPDU and set CCA_BUSY
Definition: phy-entity.h:102
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: phy-entity.cc:554
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:400
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
@ NS
nanosecond
Definition: nstime.h:118
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:392
PHY entity for VHT (11ac)
Definition: vht-phy.h:49
static WifiMode GetVhtMcs4(void)
Return MCS 4 from VHT MCS values.
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied VHT MCS index.
Definition: vht-phy.cc:391
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
static WifiMode GetVhtMcs5(void)
Return MCS 5 from VHT MCS values.
static WifiMode GetVhtMcs0(void)
Return MCS 0 from VHT MCS values.
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
static WifiMode GetVhtMcs3(void)
Return MCS 3 from VHT MCS values.
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied VHT MCS index.
Definition: vht-phy.cc:405
static WifiMode GetVhtMcs2(void)
Return MCS 2 from VHT MCS values.
static WifiMode GetVhtMcs1(void)
Return MCS 1 from VHT MCS values.
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
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
represent a single transmission mode
Definition: wifi-mode.h:48
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:137
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:100
Ptr< WifiMac > GetMac(void) const
Ptr< HeConfiguration > GetHeConfiguration(void) const
const WifiPhyOperatingChannel & GetOperatingChannel(void) const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:1137
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:1124
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1694
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1421
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1610
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:870
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const
Definition: wifi-phy.cc:1928
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
uint64_t GetPreviouslyRxPpduUid(void) const
Definition: wifi-phy.cc:1876
Ptr< NetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:783
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:2149
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:1233
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...
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...
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....
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint8_t GetBssColor(void) const
Get the BSS color.
std::map< uint16_t, HeMuUserInfo > HeMuUserInfoMap
map of HE MU specific user info paramters indexed by 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 GetLength(void) const
Get the LENGTH field of the L-SIG.
WifiPreamble GetPreambleType(void) const
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
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.
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
std::pair< std::size_t, std::size_t > GetNumRusPerHeSigBContentChannel(void) const
Get the number of RUs per HE-SIG-B content channel.
bool IsMu(void) const
Return true if this TX vector is used for a multi-user transmission.
uint16_t GetChannelWidth(void) const
uint16_t GetGuardInterval(void) const
uint8_t GetNssMax(void) const
bool IsUlMu(void) const
Return true if this TX vector is used for an uplink multi-user transmission.
#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
#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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1703
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1305
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1313
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1329
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiPpduField
The type of PPDU field (grouped for convenience)
@ OBSS_PD_CCA_RESET
@ HE_TB_PPDU_TOO_LATE
@ WIFI_PREAMBLE_HE_ER_SU
@ WIFI_PREAMBLE_HE_TB
@ WIFI_PREAMBLE_HE_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PPDU_TYPE_DL_MU
@ WIFI_PPDU_TYPE_UL_MU
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_PPDU_FIELD_SIG_B
SIG-B field.
@ WIFI_PPDU_FIELD_TRAINING
STF + LTF fields (excluding those in preamble for HT-GF)
@ 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
@ WIFI_PPDU_FIELD_SIG_A
SIG-A field.
#define GET_HE_MCS(x)
Definition: he-phy.cc:978
#define CASE(x)
Declaration of ns3::HePhy class and ns3::HeSigAParameters struct.
#define HE_PHY
This defines the BSS membership value for HE PHY.
Definition: he-phy.h:41
Declaration of ns3::HePpdu class.
static class anonymous_namespace{he-phy.cc}::ConstructorHe g_constructor_he
the constructor for HE modes
Every class exported by the ns3 library is enclosed in the ns3 namespace.
const uint16_t WIFI_CODE_RATE_3_4
3/4 coding rate
std::unordered_map< uint16_t, Ptr< const WifiPsdu > > WifiConstPsduMap
Map of const PSDUs indexed by STA-ID.
std::pair< uint32_t, uint32_t > WifiSpectrumBand
typedef for a pair of start and stop sub-band indexes
std::map< WifiSpectrumBand, double > RxPowerWattPerChannelBand
A map of the received power (Watts) for each band.
Definition: phy-entity.h:75
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
const uint16_t WIFI_CODE_RATE_5_6
5/6 coding rate
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
mac
Definition: third.py:99
Parameters for received HE-SIG-A for OBSS_PD based SR.
Definition: he-phy.h:47
uint8_t bssColor
BSS color.
Definition: he-phy.h:49
double rssiW
RSSI in W.
Definition: he-phy.h:48
Status of the reception of the PPDU field.
Definition: phy-entity.h:111
bool isSuccess
outcome (true if success) of the reception
Definition: phy-entity.h:113
SignalNoiseDbm structure.
Definition: phy-entity.h:53
#define SU_STA_ID
Definition: wifi-mode.h:32