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/interference-helper.h"
32 #include "ns3/simulator.h"
33 #include "ns3/log.h"
34 #include "ns3/assert.h"
35 #include <algorithm>
36 
37 namespace ns3 {
38 
39 NS_LOG_COMPONENT_DEFINE ("HePhy");
40 
41 /*******************************************************
42  * HE PHY (P802.11ax/D4.0, clause 27)
43  *******************************************************/
44 
45 /* *NS_CHECK_STYLE_OFF* */
46 const PhyEntity::PpduFormats HePhy::m_hePpduFormats { //Ignoring PE (Packet Extension)
47  { WIFI_PREAMBLE_HE_SU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
48  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
49  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
50  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
52  { WIFI_PREAMBLE_HE_MU, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
53  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
54  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
55  WIFI_PPDU_FIELD_SIG_B, //HE-SIG-B
56  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
58  { WIFI_PREAMBLE_HE_TB, { WIFI_PPDU_FIELD_PREAMBLE, //L-STF + L-LTF
59  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
60  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
61  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
64  WIFI_PPDU_FIELD_NON_HT_HEADER, //L-SIG + RL-SIG
65  WIFI_PPDU_FIELD_SIG_A, //HE-SIG-A
66  WIFI_PPDU_FIELD_TRAINING, //HE-STF + HE-LTFs
68 };
69 /* *NS_CHECK_STYLE_ON* */
70 
71 HePhy::HePhy (bool buildModeList /* = true */)
72  : VhtPhy (false), //don't add VHT modes to list
73  m_trigVectorExpirationTime (Seconds (0))
74 {
75  NS_LOG_FUNCTION (this << buildModeList);
77  m_maxMcsIndexPerSs = 11;
79  m_currentHeTbPpduUid = UINT64_MAX;
80  m_previouslyTxPpduUid = UINT64_MAX;
81  if (buildModeList)
82  {
83  BuildModeList ();
84  }
85 }
86 
88 {
89  NS_LOG_FUNCTION (this);
90 }
91 
92 void
94 {
95  NS_LOG_FUNCTION (this);
96  NS_ASSERT (m_modeList.empty ());
98  for (uint8_t index = 0; index <= m_maxSupportedMcsIndexPerSs; ++index)
99  {
100  NS_LOG_LOGIC ("Add HeMcs" << +index << " to list");
101  m_modeList.emplace_back (CreateHeMcs (index));
102  }
103 }
104 
105 WifiMode
106 HePhy::GetSigMode (WifiPpduField field, const WifiTxVector& txVector) const
107 {
108  switch (field)
109  {
110  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)
111  if (txVector.IsDlMu ())
112  {
114  //Training comes after SIG-B
115  return GetSigBMode (txVector);
116  }
117  else
118  {
119  //Training comes after SIG-A
120  return GetSigAMode ();
121  }
122  default:
123  return VhtPhy::GetSigMode (field, txVector);
124  }
125 }
126 
127 WifiMode
128 HePhy::GetSigAMode (void) const
129 {
130  return GetVhtMcs0 (); //same number of data tones as VHT for 20 MHz (i.e. 52)
131 }
132 
133 WifiMode
134 HePhy::GetSigBMode (const WifiTxVector& txVector) const
135 {
136  NS_ABORT_MSG_IF (!txVector.IsDlMu () || (txVector.GetModulationClass () != WIFI_MOD_CLASS_HE), "HE-SIG-B only available for HE MU");
143  uint8_t smallestMcs = 5; //maximum MCS for HE-SIG-B
144  for (auto & info : txVector.GetHeMuUserInfoMap ())
145  {
146  smallestMcs = std::min (smallestMcs, info.second.mcs.GetMcsValue ());
147  }
148  switch (smallestMcs) //GetVhtMcs (mcs) is not static
149  {
150  case 0:
151  return GetVhtMcs0 ();
152  case 1:
153  return GetVhtMcs1 ();
154  case 2:
155  return GetVhtMcs2 ();
156  case 3:
157  return GetVhtMcs3 ();
158  case 4:
159  return GetVhtMcs4 ();
160  case 5:
161  default:
162  return GetVhtMcs5 ();
163  }
164 }
165 
168 {
169  return m_hePpduFormats;
170 }
171 
172 Time
173 HePhy::GetLSigDuration (WifiPreamble /* preamble */) const
174 {
175  return MicroSeconds (8); //L-SIG + RL-SIG
176 }
177 
178 Time
180  uint8_t nDataLtf, uint8_t nExtensionLtf /* = 0 */) const
181 {
182  Time ltfDuration = MicroSeconds (8); //TODO extract from TxVector when available
183  Time stfDuration;
184  if (txVector.IsUlMu ())
185  {
187  stfDuration = MicroSeconds (8);
188  }
189  else
190  {
191  stfDuration = MicroSeconds (4);
192  }
193  NS_ABORT_MSG_IF (nDataLtf > 8, "Unsupported number of LTFs " << +nDataLtf << " for HE");
194  NS_ABORT_MSG_IF (nExtensionLtf > 0, "No extension LTFs expected for HE");
195  return stfDuration + ltfDuration * nDataLtf; //HE-STF + HE-LTFs
196 }
197 
198 Time
200 {
201  return (preamble == WIFI_PREAMBLE_HE_ER_SU) ? MicroSeconds (16) : MicroSeconds (8); //HE-SIG-A (first and second symbol)
202 }
203 
204 Time
205 HePhy::GetSigBDuration (const WifiTxVector& txVector) const
206 {
207  if (txVector.IsDlMu ()) //See section 27.3.10.8 of IEEE 802.11ax draft 4.0.
208  {
210  /*
211  * Compute the number of bits used by common field.
212  * Assume that compression bit in HE-SIG-A is not set (i.e. not
213  * full band MU-MIMO); the field is present.
214  */
215  uint16_t bw = txVector.GetChannelWidth ();
216  std::size_t commonFieldSize = 4 /* CRC */ + 6 /* tail */;
217  if (bw <= 40)
218  {
219  commonFieldSize += 8; //only one allocation subfield
220  }
221  else
222  {
223  commonFieldSize += 8 * (bw / 40) /* one allocation field per 40 MHz */ + 1 /* center RU */;
224  }
225 
226  /*
227  * Compute the number of bits used by user-specific field.
228  * MU-MIMO is not supported; only one station per RU.
229  * The user-specific field is composed of N user block fields
230  * spread over each corresponding HE-SIG-B content channel.
231  * Each user block field contains either two or one users' data
232  * (the latter being for odd number of stations per content channel).
233  * Padding will be handled further down in the code.
234  */
235  std::pair<std::size_t, std::size_t> numStaPerContentChannel = txVector.GetNumRusPerHeSigBContentChannel ();
236  std::size_t maxNumStaPerContentChannel = std::max (numStaPerContentChannel.first, numStaPerContentChannel.second);
237  std::size_t maxNumUserBlockFields = maxNumStaPerContentChannel / 2; //handle last user block with single user, if any, further down
238  std::size_t userSpecificFieldSize = maxNumUserBlockFields * (2 * 21 /* user fields (2 users) */ + 4 /* tail */ + 6 /* CRC */);
239  if (maxNumStaPerContentChannel % 2 != 0)
240  {
241  userSpecificFieldSize += 21 /* last user field */ + 4 /* CRC */ + 6 /* tail */;
242  }
243 
244  /*
245  * Compute duration of HE-SIG-B considering that padding
246  * is added up to the next OFDM symbol.
247  * Nss = 1 and GI = 800 ns for HE-SIG-B.
248  */
249  Time symbolDuration = MicroSeconds (4);
250  double numDataBitsPerSymbol = GetSigBMode (txVector).GetDataRate (20, 800, 1) * symbolDuration.GetNanoSeconds () / 1e9;
251  double numSymbols = ceil ((commonFieldSize + userSpecificFieldSize) / numDataBitsPerSymbol);
252 
253  return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
254  }
255  else
256  {
257  // no SIG-B
258  return MicroSeconds (0);
259  }
260 }
261 
262 Time
263 HePhy::GetValidPpduDuration (Time ppduDuration, const WifiTxVector& txVector,
264  WifiPhyBand band)
265 {
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 = (band == WIFI_PHY_BAND_2_4GHZ ? 6 : 0);
269  uint32_t nSymbols = floor (static_cast<double> ((ppduDuration - preambleDuration).GetNanoSeconds () - (sigExtension * 1000)) / tSymbol.GetNanoSeconds ());
270  return preambleDuration + (nSymbols * tSymbol) + MicroSeconds (sigExtension);
271 }
272 
273 std::pair<uint16_t, Time>
275  WifiPhyBand band)
276 {
277  NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () != WIFI_MOD_CLASS_HE));
278  // update ppduDuration so that it is a valid PPDU duration
279  ppduDuration = GetValidPpduDuration (ppduDuration, txVector, band);
280  uint8_t sigExtension = (band == WIFI_PHY_BAND_2_4GHZ ? 6 : 0);
281  uint8_t m = 2; //HE TB PPDU so m is set to 2
282  uint16_t length = ((ceil ((static_cast<double> (ppduDuration.GetNanoSeconds () - (20 * 1000) - (sigExtension * 1000)) / 1000) / 4.0) * 3) - 3 - m);
283  return {length, ppduDuration};
284 }
285 
286 Time
288 {
289  NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () != WIFI_MOD_CLASS_HE));
290  uint8_t sigExtension = (band == WIFI_PHY_BAND_2_4GHZ ? 6 : 0);
291  uint8_t m = 2; //HE TB PPDU so m is set to 2
292  //Equation 27-11 of IEEE P802.11ax/D4.0
293  Time calculatedDuration = MicroSeconds (((ceil (static_cast<double> (length + 3 + m) / 3)) * 4) + 20 + sigExtension);
294  return GetValidPpduDuration (calculatedDuration, txVector, band);
295 }
296 
297 Time
299 {
300  NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () != WIFI_MOD_CLASS_HE));
301  Time duration = GetDuration (WIFI_PPDU_FIELD_PREAMBLE, txVector)
303  + GetDuration (WIFI_PPDU_FIELD_SIG_A, txVector);
304  return duration;
305 }
306 
307 uint8_t
308 HePhy::GetNumberBccEncoders (const WifiTxVector& /* txVector */) const
309 {
310  return 1; //only 1 BCC encoder for HE since higher rates are obtained using LDPC
311 }
312 
313 Time
314 HePhy::GetSymbolDuration (const WifiTxVector& txVector) const
315 {
316  uint16_t gi = txVector.GetGuardInterval ();
317  NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
318  return NanoSeconds (12800 + gi);
319 }
320 
321 void
322 HePhy::SetTrigVector (const WifiTxVector& trigVector, Time validity)
323 {
324  m_trigVector = trigVector;
327 }
328 
330 HePhy::BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration)
331 {
332  NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration);
333  HePpdu::TxPsdFlag flag;
334  if (txVector.IsUlMu ())
335  {
338  }
339  else
340  {
341  flag = HePpdu::PSD_NON_HE_TB;
342  }
343  return Create<HePpdu> (psdus, txVector, ppduDuration, m_wifiPhy->GetPhyBand (),
344  ObtainNextUid (txVector), flag,
346 }
347 
348 void
350  Time rxDuration)
351 {
352  NS_LOG_FUNCTION (this << ppdu << rxDuration);
353  const WifiTxVector& txVector = ppdu->GetTxVector ();
354  auto hePpdu = DynamicCast<HePpdu> (ppdu);
355  NS_ASSERT (hePpdu);
356  HePpdu::TxPsdFlag psdFlag = hePpdu->GetTxPsdFlag ();
357  if (txVector.IsUlMu () && psdFlag == HePpdu::PSD_HE_TB_OFDMA_PORTION)
358  {
360  if (m_currentHeTbPpduUid == ppdu->GetUid ()
361  && GetCurrentEvent () != 0)
362  {
363  //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)
364  bool ofdmaStarted = !m_beginOfdmaPayloadRxEvents.empty ();
365  NS_LOG_INFO ("Switch to OFDMA part (already started? " << (ofdmaStarted ? "Y" : "N") << ") " <<
366  "and schedule OFDMA payload reception in " << GetDuration (WIFI_PPDU_FIELD_TRAINING, txVector).As (Time::NS));
367  Ptr<Event> event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW, !ofdmaStarted);
368  uint16_t staId = GetStaId (ppdu);
371  &HePhy::StartReceiveOfdmaPayload, this, event);
372  }
373  else
374  {
375  //PHY receives the OFDMA payload while having dropped the preamble
376  NS_LOG_INFO ("Consider OFDMA part of the HE TB PPDU as interference since device dropped the preamble");
377  CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
378  //the OFDMA part of the HE TB PPDUs will be noise _after_ the completion of the current event
379  ErasePreambleEvent (ppdu, rxDuration);
380  }
381  }
382  else
383  {
384  PhyEntity::StartReceivePreamble (ppdu, rxPowersW, ppdu->GetTxDuration ()); // The actual duration of the PPDU should be used
385  }
386 }
387 
388 void
390 {
391  NS_LOG_FUNCTION (this);
392  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
393  {
394  beginOfdmaPayloadRxEvent.second.Cancel ();
395  }
398 }
399 
400 void
402 {
403  NS_LOG_FUNCTION (this << reason);
404  if (reason != OBSS_PD_CCA_RESET)
405  {
406  for (auto & endMpduEvent : m_endOfMpduEvents)
407  {
408  endMpduEvent.Cancel ();
409  }
410  m_endOfMpduEvents.clear ();
411  }
412  else
413  {
415  }
416 }
417 
418 void
420 {
421  NS_LOG_FUNCTION (this << *event);
422  if (event->GetPpdu ()->GetType () != WIFI_PPDU_TYPE_UL_MU)
423  {
424  NS_ASSERT (event->GetEndTime () == Simulator::Now ());
425  }
426  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
427  {
428  beginOfdmaPayloadRxEvent.second.Cancel ();
429  }
431 }
432 
435 {
436  Ptr<Event> event;
437  //We store all incoming preamble events, and a decision is made at the end of the preamble detection window.
438  //If a preamble is received after the preamble detection window, it is stored anyway because this is needed for HE TB PPDUs in
439  //order to properly update the received power in InterferenceHelper. The map is cleaned anyway at the end of the current reception.
440  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
441  {
442  auto uidPreamblePair = std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ());
443  const WifiTxVector& txVector = ppdu->GetTxVector ();
444  Time rxDuration = CalculateNonOfdmaDurationForHeTb (txVector); //the OFDMA part of the transmission will be added later on
445  const auto & currentPreambleEvents = GetCurrentPreambleEvents ();
446  auto it = currentPreambleEvents.find (uidPreamblePair);
447  if (it != currentPreambleEvents.end ())
448  {
449  NS_LOG_DEBUG ("Received another HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
450  event = it->second;
451 
452  //Update received power of the event associated to that UL MU transmission
453  UpdateInterferenceEvent (event, rxPowersW);
454 
455  if ((GetCurrentEvent () != 0) && (GetCurrentEvent ()->GetPpdu ()->GetUid () != ppdu->GetUid ()))
456  {
457  NS_LOG_DEBUG ("Drop packet because already receiving another HE TB PPDU");
459  }
460  return nullptr;
461  }
462  else
463  {
464  NS_LOG_DEBUG ("Received a new HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
465  event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
466  AddPreambleEvent (event);
467  }
468  }
469  else
470  {
471  event = PhyEntity::DoGetEvent (ppdu, rxPowersW);
472  }
473  return event;
474 }
475 
478 {
479  if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU || ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
480  {
481  auto hePpdu = DynamicCast<const HePpdu> (ppdu);
482  NS_ASSERT (hePpdu);
483  return hePpdu->GetPsdu (GetBssColor (), GetStaId (ppdu));
484  }
485  return PhyEntity::GetAddressedPsduInPpdu (ppdu);
486 }
487 
488 uint8_t
489 HePhy::GetBssColor (void) const
490 {
491  uint8_t bssColor = 0;
492  if (m_wifiPhy->GetDevice () != nullptr)
493  {
495  if (heConfiguration)
496  {
497  bssColor = heConfiguration->GetBssColor ();
498  }
499  }
500  return bssColor;
501 }
502 
503 uint16_t
505 {
506  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
507  {
508  return ppdu->GetStaId ();
509  }
510  else if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
511  {
512  Ptr<StaWifiMac> mac = DynamicCast<StaWifiMac> (m_wifiPhy->GetDevice ()->GetMac ());
513  if (mac && mac->IsAssociated ())
514  {
515  return mac->GetAssociationId ();
516  }
517  }
518  return PhyEntity::GetStaId (ppdu);
519 }
520 
523 {
524  NS_LOG_FUNCTION (this << *event << status);
525  //Notify end of SIG-A (in all cases)
526  WifiTxVector txVector = event->GetTxVector ();
527  HeSigAParameters params;
528  params.rssiW = GetRxPowerWForPpdu (event);
529  params.bssColor = txVector.GetBssColor ();
530  NotifyEndOfHeSigA (params); //if OBSS_PD CCA_RESET, set power restriction first and wait till field is processed before switching to IDLE
531 
532  if (status.isSuccess)
533  {
534  //Check if PPDU is filtered based on the BSS color
535  uint8_t myBssColor = GetBssColor ();
536  uint8_t rxBssColor = txVector.GetBssColor ();
537  if (myBssColor != 0 && rxBssColor != 0 && myBssColor != rxBssColor)
538  {
539  NS_LOG_DEBUG ("The BSS color of this PPDU (" << +rxBssColor << ") does not match the device's (" << +myBssColor << "). The PPDU is filtered.");
540  return PhyFieldRxStatus (false, FILTERED, DROP);
541  }
542 
543  // When SIG-A is decoded, we know the type of frame being received. If we stored a
544  // valid TRIGVECTOR and we are not receiving a TB PPDU, we drop the frame.
545  if (m_trigVectorExpirationTime >= Simulator::Now () && !txVector.IsUlMu ())
546  {
547  NS_LOG_DEBUG ("Expected an HE TB PPDU, receiving a " << txVector.GetPreambleType ());
548  return PhyFieldRxStatus (false, FILTERED, DROP);
549  }
550 
551  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
552  if (txVector.IsUlMu ())
553  {
555  // check that the stored TRIGVECTOR is still valid
557  {
558  NS_LOG_DEBUG ("No valid TRIGVECTOR, the PHY was not expecting a TB PPDU");
559  return PhyFieldRxStatus (false, FILTERED, DROP);
560  }
561  // We expected a TB PPDU and we are receiving a TB PPDU. However, despite
562  // the previous check on BSS Color, we may be receiving a TB PPDU from an
563  // OBSS, as BSS Colors are not guaranteed to be different for all APs in
564  // range (an example is when BSS Color is 0). We can detect this situation
565  // by comparing the TRIGVECTOR with the TXVECTOR of the TB PPDU being received
566  if (m_trigVector.GetChannelWidth () != txVector.GetChannelWidth ())
567  {
568  NS_LOG_DEBUG ("Received channel width different than in TRIGVECTOR");
569  return PhyFieldRxStatus (false, FILTERED, DROP);
570  }
571  if (m_trigVector.GetLength () != txVector.GetLength ())
572  {
573  NS_LOG_DEBUG ("Received UL Length (" << txVector.GetLength () <<
574  ") different than in TRIGVECTOR (" << m_trigVector.GetLength ()
575  << ")");
576  return PhyFieldRxStatus (false, FILTERED, DROP);
577  }
578  uint16_t staId = ppdu->GetStaId ();
579  if (m_trigVector.GetHeMuUserInfoMap ().find (staId) == m_trigVector.GetHeMuUserInfoMap ().end ()
580  || m_trigVector.GetHeMuUserInfo (staId) != txVector.GetHeMuUserInfo (staId))
581  {
582  NS_LOG_DEBUG ("User Info map of TB PPDU being received differs from that of TRIGVECTOR");
583  return PhyFieldRxStatus (false, FILTERED, DROP);
584  }
585 
586  m_currentHeTbPpduUid = ppdu->GetUid (); //to be able to correctly schedule start of OFDMA payload
587  }
588 
589  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
590  {
591  NS_ASSERT (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU);
592  NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
593  return PhyFieldRxStatus (false, FILTERED, DROP);
594  }
595  }
596  return status;
597 }
598 
599 void
601 {
602  m_endOfHeSigACallback = callback;
603 }
604 
605 void
607 {
609  {
610  m_endOfHeSigACallback (params);
611  }
612 }
613 
616 {
617  NS_LOG_FUNCTION (this << *event << status);
618  if (status.isSuccess)
619  {
620  //Check if PPDU is filtered only if the SIG-B content is supported (not explicitly stated but assumed based on behavior for SIG-A)
621  if (!GetAddressedPsduInPpdu (event->GetPpdu ()))
622  {
623  NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
624  return PhyFieldRxStatus (false, FILTERED, DROP);
625  }
626  }
627  return status;
628 }
629 
630 bool
632 {
633  const WifiTxVector& txVector = ppdu->GetTxVector ();
634  uint16_t staId = GetStaId (ppdu);
635  WifiMode txMode = txVector.GetMode (staId);
636  uint8_t nss = txVector.GetNssMax ();
637  if (txVector.IsDlMu ())
638  {
640  for (auto info : txVector.GetHeMuUserInfoMap ())
641  {
642  if (info.first == staId)
643  {
644  nss = info.second.nss; //no need to look at other PSDUs
645  break;
646  }
647  }
648  }
649 
651  {
652  NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
653  return false;
654  }
655  if (!IsModeSupported (txMode))
656  {
657  NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txVector.GetMode () << ")");
658  return false;
659  }
660  return true;
661 }
662 
663 void
665 {
666  NS_LOG_FUNCTION (this << *event);
667  const WifiTxVector& txVector = event->GetTxVector ();
668  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
669  if (txVector.IsUlMu ())
670  {
672  bool isAp = (DynamicCast<ApWifiMac> (m_wifiPhy->GetDevice ()->GetMac ()) != 0);
673  if (!isAp)
674  {
675  NS_LOG_DEBUG ("Ignore HE TB PPDU payload received by STA but keep state in Rx");
676  m_endRxPayloadEvents.push_back (Simulator::Schedule (ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector),
677  &PhyEntity::ResetReceive, this, event));
678  //Cancel all scheduled events for OFDMA payload reception
679  NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty () && m_beginOfdmaPayloadRxEvents.begin ()->second.IsRunning ());
680  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
681  {
682  beginOfdmaPayloadRxEvent.second.Cancel ();
683  }
685  }
686  else
687  {
688  NS_LOG_DEBUG ("Receiving PSDU in HE TB PPDU");
689  uint16_t staId = GetStaId (ppdu);
690  m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
691  m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
692  //for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload
693  NS_ASSERT (isAp);
695  for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
696  {
697  NS_ASSERT (beginOfdmaPayloadRxEvent.second.IsRunning ());
698  }
699  }
700  }
701  else
702  {
704  }
705 }
706 
707 void
709 {
710  NS_LOG_FUNCTION (this << ppdu);
711  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
712  {
713  for (auto it = m_endRxPayloadEvents.begin (); it != m_endRxPayloadEvents.end (); )
714  {
715  if (it->IsExpired ())
716  {
717  it = m_endRxPayloadEvents.erase (it);
718  }
719  else
720  {
721  it++;
722  }
723  }
724  if (m_endRxPayloadEvents.empty ())
725  {
726  //We've got the last PPDU of the UL-OFDMA transmission
727  NotifyInterferenceRxEndAndClear (true); //reset WifiPhy
728  }
729  }
730  else
731  {
734  }
735 }
736 
737 void
739 {
740  Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
741  const RxPowerWattPerChannelBand& rxPowersW = event->GetRxPowerWPerBand ();
742  //The total RX power corresponds to the maximum over all the bands.
743  //Only perform this computation if the result needs to be logged.
744  auto it = rxPowersW.end ();
745  if (g_log.IsEnabled (ns3::LOG_FUNCTION))
746  {
747  it = std::max_element (rxPowersW.begin (), rxPowersW.end (),
748  [] (const std::pair<WifiSpectrumBand, double> &p1, const std::pair<WifiSpectrumBand, double> &p2) {
749  return p1.second < p2.second;
750  });
751 
752  }
753  NS_LOG_FUNCTION (this << *event << it->second);
754  NS_ASSERT (GetCurrentEvent () != 0);
755  auto itEvent = m_beginOfdmaPayloadRxEvents.find (GetStaId (ppdu));
761  NS_ASSERT (itEvent != m_beginOfdmaPayloadRxEvents.end () && itEvent->second.IsExpired ());
762  m_beginOfdmaPayloadRxEvents.erase (itEvent);
763 
764  Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (ppdu->GetTxVector ());
766  ScheduleEndOfMpdus (event);
767  m_endRxPayloadEvents.push_back (Simulator::Schedule (payloadDuration, &PhyEntity::EndReceivePayload, this, event));
768  m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), SignalNoiseDbm ()});
769  m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), std::vector<bool> ()});
770  // Notify the MAC about the start of a new HE TB PPDU, so that it can reschedule the timeout
771  NotifyPayloadBegin (ppdu->GetTxVector (), payloadDuration);
772 }
773 
774 std::pair<uint16_t, WifiSpectrumBand>
775 HePhy::GetChannelWidthAndBand (const WifiTxVector& txVector, uint16_t staId) const
776 {
777  if (txVector.IsMu ())
778  {
779  return std::make_pair (HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ()),
780  GetRuBandForRx (txVector, staId));
781  }
782  else
783  {
784  return PhyEntity::GetChannelWidthAndBand (txVector, staId);
785  }
786 }
787 
789 HePhy::GetRuBandForTx (const WifiTxVector& txVector, uint16_t staId) const
790 {
791  NS_ASSERT (txVector.IsMu ());
792  WifiSpectrumBand band;
793  HeRu::RuSpec ru = txVector.GetRu (staId);
794  uint16_t channelWidth = txVector.GetChannelWidth ();
795  NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
796  HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetPhyIndex ());
797  HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
798  // for a TX spectrum, the guard bandwidth is a function of the transmission channel width
799  // and the spectrum width equals the transmission channel width (hence bandIndex equals 0)
800  band = m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (channelWidth),
801  range, 0);
802  return band;
803 }
804 
806 HePhy::GetRuBandForRx (const WifiTxVector& txVector, uint16_t staId) const
807 {
808  NS_ASSERT (txVector.IsMu ());
809  WifiSpectrumBand band;
810  HeRu::RuSpec ru = txVector.GetRu (staId);
811  uint16_t channelWidth = txVector.GetChannelWidth ();
812  NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
813  HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetPhyIndex ());
814  HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
815  // for an RX spectrum, the guard bandwidth is a function of the operating channel width
816  // and the spectrum width equals the operating channel width
818  range, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (channelWidth));
819  return band;
820 }
821 
823 HePhy::GetNonOfdmaBand (const WifiTxVector& txVector, uint16_t staId) const
824 {
825  NS_ASSERT (txVector.IsUlMu () && (txVector.GetModulationClass () == WIFI_MOD_CLASS_HE));
826  uint16_t channelWidth = txVector.GetChannelWidth ();
827  NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
828 
829  HeRu::RuSpec ru = txVector.GetRu (staId);
830  uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
831 
832  // Find the RU that encompasses the non-OFDMA part of the HE TB PPDU for the STA-ID
833  HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (channelWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
834  nonOfdmaRu.SetPhyIndex (channelWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
835 
836  HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.GetRuType (), nonOfdmaRu.GetPhyIndex ());
837  HeRu::SubcarrierRange range = std::make_pair (groupPreamble.front ().first, groupPreamble.back ().second);
838  return m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (m_wifiPhy->GetChannelWidth ()), range,
840 }
841 
842 uint16_t
844 {
845  if (ru.GetRuType () == HeRu::RU_26_TONE && ru.GetIndex () == 19)
846  {
847  // the center 26-tone RU in an 80 MHz channel is not fully covered by
848  // any 20 MHz channel, but only by an 80 MHz channel
849  return 80;
850  }
851  return std::max<uint16_t> (HeRu::GetBandwidth (ru.GetRuType ()), 20);
852 }
853 
854 uint64_t
856 {
857  return m_currentHeTbPpduUid;
858 }
859 
860 uint16_t
862 {
863  uint16_t channelWidth = PhyEntity::GetMeasurementChannelWidth (ppdu);
871  if (channelWidth >= 40 && ppdu->GetUid () != m_previouslyTxPpduUid)
872  {
873  channelWidth = 20;
874  }
875  return channelWidth;
876 }
877 
878 uint64_t
880 {
881  NS_LOG_FUNCTION (this << txVector);
882  uint64_t uid;
883  if (txVector.IsUlMu ())
884  {
886  //Use UID of PPDU containing trigger frame to identify resulting HE TB PPDUs, since the latter should immediately follow the former
888  NS_ASSERT (uid != UINT64_MAX);
889  }
890  else
891  {
892  uid = m_globalPpduUid++;
893  }
894  m_previouslyTxPpduUid = uid; //to be able to identify solicited HE TB PPDUs
895  return uid;
896 }
897 
900 {
901  const WifiTxVector& txVector = ppdu->GetTxVector ();
902  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
903  uint16_t channelWidth = txVector.GetChannelWidth ();
904  NS_LOG_FUNCTION (this << centerFrequency << channelWidth << txPowerW);
905  auto hePpdu = DynamicCast<const HePpdu> (ppdu);
906  NS_ASSERT (hePpdu);
907  HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
910  {
911  WifiSpectrumBand band = GetRuBandForTx (txVector, GetStaId (hePpdu));
912  v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
913  }
914  else
915  {
917  {
918  //non-OFDMA portion is sent only on the 20 MHz channels covering the RU
919  uint16_t staId = GetStaId (hePpdu);
920  centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId);
921  uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
922  channelWidth = ruWidth < 20 ? 20 : ruWidth;
923  }
924  const auto & txMaskRejectionParams = GetTxMaskRejectionParams ();
925  v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth),
926  std::get<0> (txMaskRejectionParams), std::get<1> (txMaskRejectionParams), std::get<2> (txMaskRejectionParams));
927  }
928  return v;
929 }
930 
931 uint16_t
932 HePhy::GetCenterFrequencyForNonOfdmaPart (const WifiTxVector& txVector, uint16_t staId) const
933 {
934  NS_LOG_FUNCTION (this << txVector << staId);
935  NS_ASSERT (txVector.IsUlMu () && (txVector.GetModulationClass () == WIFI_MOD_CLASS_HE));
936  uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
937  uint16_t currentWidth = txVector.GetChannelWidth ();
938 
939  HeRu::RuSpec ru = txVector.GetRu (staId);
940  uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
941  if (nonOfdmaWidth != currentWidth)
942  {
943  //Obtain the index of the non-OFDMA portion
944  HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (currentWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
945  nonOfdmaRu.SetPhyIndex (currentWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
946 
947  uint16_t startingFrequency = centerFrequency - (currentWidth / 2);
948  centerFrequency = startingFrequency + nonOfdmaWidth * (nonOfdmaRu.GetPhyIndex () - 1) + nonOfdmaWidth / 2;
949  }
950  return centerFrequency;
951 }
952 
953 void
955 {
956  NS_LOG_FUNCTION (this << ppdu);
957  if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
958  {
959  //non-OFDMA part
960  Time nonOfdmaDuration = CalculateNonOfdmaDurationForHeTb (ppdu->GetTxVector ());
961  Transmit (nonOfdmaDuration, ppdu, "non-OFDMA transmission");
962 
963  //OFDMA part
964  auto hePpdu = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
965  NS_ASSERT (hePpdu);
966  hePpdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
967  Time ofdmaDuration = ppdu->GetTxDuration () - nonOfdmaDuration;
968  Simulator::Schedule (nonOfdmaDuration, &PhyEntity::Transmit, this, ofdmaDuration, hePpdu, "OFDMA transmission");
969  }
970  else
971  {
972  PhyEntity::StartTx (ppdu);
973  }
974 }
975 
976 Time
978 {
979  if (txVector.IsUlMu ())
980  {
982  return ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band);
983  }
984 
985  Time maxDuration = Seconds (0);
986  for (auto & staIdPsdu : psduMap)
987  {
988  if (txVector.IsDlMu ())
989  {
991  WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap ();
992  NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector");
993  }
994  Time current = WifiPhy::CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band,
995  staIdPsdu.first);
996  if (current > maxDuration)
997  {
998  maxDuration = current;
999  }
1000  }
1001  NS_ASSERT (maxDuration.IsStrictlyPositive ());
1002  return maxDuration;
1003 }
1004 
1005 void
1007 {
1008  for (uint8_t i = 0; i < 12; ++i)
1009  {
1010  GetHeMcs (i);
1011  }
1012 }
1013 
1014 WifiMode
1015 HePhy::GetHeMcs (uint8_t index)
1016 {
1017 #define CASE(x) \
1018 case x: \
1019  return GetHeMcs ## x (); \
1020 
1021  switch (index)
1022  {
1023  CASE ( 0)
1024  CASE ( 1)
1025  CASE ( 2)
1026  CASE ( 3)
1027  CASE ( 4)
1028  CASE ( 5)
1029  CASE ( 6)
1030  CASE ( 7)
1031  CASE ( 8)
1032  CASE ( 9)
1033  CASE (10)
1034  CASE (11)
1035  default:
1036  NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for HE");
1037  return WifiMode ();
1038  }
1039 #undef CASE
1040 }
1041 
1042 #define GET_HE_MCS(x) \
1043 WifiMode \
1044 HePhy::GetHeMcs ## x (void) \
1045 { \
1046  static WifiMode mcs = CreateHeMcs (x); \
1047  return mcs; \
1048 }; \
1049 
1050 GET_HE_MCS (0)
1051 GET_HE_MCS (1)
1052 GET_HE_MCS (2)
1053 GET_HE_MCS (3)
1054 GET_HE_MCS (4)
1055 GET_HE_MCS (5)
1056 GET_HE_MCS (6)
1057 GET_HE_MCS (7)
1058 GET_HE_MCS (8)
1059 GET_HE_MCS (9)
1060 GET_HE_MCS (10)
1061 GET_HE_MCS (11)
1062 #undef GET_HE_MCS
1063 
1064 WifiMode
1065 HePhy::CreateHeMcs (uint8_t index)
1066 {
1067  NS_ASSERT_MSG (index <= 11, "HeMcs index must be <= 11!");
1068  return WifiModeFactory::CreateWifiMcs ("HeMcs" + std::to_string (index),
1069  index,
1071  false,
1072  MakeBoundCallback (&GetCodeRate, index),
1077  MakeCallback (&IsAllowed));
1078 }
1079 
1081 HePhy::GetCodeRate (uint8_t mcsValue)
1082 {
1083  switch (mcsValue)
1084  {
1085  case 10:
1086  return WIFI_CODE_RATE_3_4;
1087  case 11:
1088  return WIFI_CODE_RATE_5_6;
1089  default:
1090  return VhtPhy::GetCodeRate (mcsValue);
1091  }
1092 }
1093 
1094 uint16_t
1096 {
1097  switch (mcsValue)
1098  {
1099  case 10:
1100  case 11:
1101  return 1024;
1102  default:
1103  return VhtPhy::GetConstellationSize (mcsValue);
1104  }
1105 }
1106 
1107 uint64_t
1108 HePhy::GetPhyRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1109 {
1110  WifiCodeRate codeRate = GetCodeRate (mcsValue);
1111  uint64_t dataRate = GetDataRate (mcsValue, channelWidth, guardInterval, nss);
1112  return HtPhy::CalculatePhyRate (codeRate, dataRate);
1113 }
1114 
1115 uint64_t
1116 HePhy::GetPhyRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1117 {
1118  uint16_t bw = txVector.GetChannelWidth ();
1119  if (txVector.IsMu ())
1120  {
1121  bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1122  }
1123  return HePhy::GetPhyRate (txVector.GetMode (staId).GetMcsValue (),
1124  bw,
1125  txVector.GetGuardInterval (),
1126  txVector.GetNss (staId));
1127 }
1128 
1129 uint64_t
1130 HePhy::GetDataRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1131 {
1132  uint16_t bw = txVector.GetChannelWidth ();
1133  if (txVector.IsMu ())
1134  {
1135  bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1136  }
1137  return HePhy::GetDataRate (txVector.GetMode (staId).GetMcsValue (),
1138  bw,
1139  txVector.GetGuardInterval (),
1140  txVector.GetNss (staId));
1141 }
1142 
1143 uint64_t
1144 HePhy::GetDataRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1145 {
1146  NS_ASSERT (guardInterval == 800 || guardInterval == 1600 || guardInterval == 3200);
1147  NS_ASSERT (nss <= 8);
1148  return HtPhy::CalculateDataRate (12.8, guardInterval,
1149  GetUsableSubcarriers (channelWidth),
1150  static_cast<uint16_t> (log2 (GetConstellationSize (mcsValue))),
1151  HtPhy::GetCodeRatio (GetCodeRate (mcsValue)), nss);
1152 }
1153 
1154 uint16_t
1155 HePhy::GetUsableSubcarriers (uint16_t channelWidth)
1156 {
1157  switch (channelWidth)
1158  {
1159  case 2: //26-tone RU
1160  return 24;
1161  case 4: //52-tone RU
1162  return 48;
1163  case 8: //106-tone RU
1164  return 102;
1165  case 20:
1166  default:
1167  return 234;
1168  case 40:
1169  return 468;
1170  case 80:
1171  return 980;
1172  case 160:
1173  return 1960;
1174  }
1175 }
1176 
1177 uint64_t
1179 {
1180  WifiCodeRate codeRate = GetCodeRate (mcsValue);
1181  uint16_t constellationSize = GetConstellationSize (mcsValue);
1182  return CalculateNonHtReferenceRate (codeRate, constellationSize);
1183 }
1184 
1185 uint64_t
1186 HePhy::CalculateNonHtReferenceRate (WifiCodeRate codeRate, uint16_t constellationSize)
1187 {
1188  uint64_t dataRate;
1189  switch (constellationSize)
1190  {
1191  case 1024:
1192  if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
1193  {
1194  dataRate = 54000000;
1195  }
1196  else
1197  {
1198  NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
1199  }
1200  break;
1201  default:
1202  dataRate = VhtPhy::CalculateNonHtReferenceRate (codeRate, constellationSize);
1203  }
1204  return dataRate;
1205 }
1206 
1207 bool
1208 HePhy::IsAllowed (const WifiTxVector& /*txVector*/)
1209 {
1210  return true;
1211 }
1212 
1215 {
1216  uint16_t staId = SU_STA_ID;
1217 
1218  if (txVector.IsUlMu ())
1219  {
1220  NS_ASSERT (txVector.GetHeMuUserInfoMap ().size () == 1);
1221  staId = txVector.GetHeMuUserInfoMap ().begin ()->first;
1222  }
1223 
1224  return WifiConstPsduMap ({std::make_pair (staId, psdu)});
1225 }
1226 
1227 uint32_t
1229 {
1230  return 6500631;
1231 }
1232 
1233 } //namespace ns3
1234 
1235 namespace {
1236 
1240 static class ConstructorHe
1241 {
1242 public:
1244  {
1246  ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HE, ns3::Create<ns3::HePhy> ());
1247  }
1249 
1250 }
#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:1241
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:167
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:522
Time GetLSigDuration(WifiPreamble preamble) const override
Definition: he-phy.cc:173
static Time ConvertLSigLengthToHeTbPpduDuration(uint16_t length, const WifiTxVector &txVector, WifiPhyBand band)
Definition: he-phy.cc:287
void StartReceiveOfdmaPayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: he-phy.cc:738
WifiMode GetSigAMode(void) const override
Definition: he-phy.cc:128
Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW) override
Get the event corresponding to the incoming PPDU.
Definition: he-phy.cc:434
Time GetSymbolDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:314
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:823
void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration) override
Start receiving the PHY preamble of a PPDU (i.e.
Definition: he-phy.cc:349
void DoAbortCurrentReception(WifiPhyRxfailureReason reason) override
Perform amendment-specific actions before aborting the current reception.
Definition: he-phy.cc:401
uint64_t m_currentHeTbPpduUid
UID of the HE TB PPDU being received.
Definition: he-phy.h:428
Time CalculateTxDuration(WifiConstPsduMap psduMap, const WifiTxVector &txVector, WifiPhyBand band) const override
Definition: he-phy.cc:977
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:775
uint8_t GetBssColor(void) const
Definition: he-phy.cc:489
Time GetSigBDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:205
static WifiMode CreateHeMcs(uint8_t index)
Create and return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1065
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1015
static uint16_t GetUsableSubcarriers(uint16_t channelWidth)
Definition: he-phy.cc:1155
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:1214
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:843
void BuildModeList(void) override
Build mode list.
Definition: he-phy.cc:93
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:1186
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:954
std::map< uint16_t, EventId > m_beginOfdmaPayloadRxEvents
the beginning of the OFDMA payload reception events (indexed by STA-ID)
Definition: he-phy.h:430
void SetEndOfHeSigACallback(EndOfHeSigACallback callback)
Set a callback for a end of HE-SIG-A.
Definition: he-phy.cc:600
Time m_trigVectorExpirationTime
expiration time of the TRIGVECTOR
Definition: he-phy.h:434
uint64_t GetCurrentHeTbPpduUid(void) const
Definition: he-phy.cc:855
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition: he-phy.h:427
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1081
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:806
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:615
EndOfHeSigACallback m_endOfHeSigACallback
end of HE-SIG-A callback
Definition: he-phy.h:432
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:477
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:106
uint64_t ObtainNextUid(const WifiTxVector &txVector) override
Obtain the next UID for the PPDU to transmit.
Definition: he-phy.cc:879
uint32_t GetMaxPsduSize(void) const override
Get the maximum PSDU size in bytes.
Definition: he-phy.cc:1228
WifiTxVector m_trigVector
the TRIGVECTOR
Definition: he-phy.h:433
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:1116
void CancelAllEvents(void) override
Cancel and clear all running events.
Definition: he-phy.cc:389
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:932
static void InitializeModes(void)
Initialize all HE modes.
Definition: he-phy.cc:1006
Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector &txVector) const
Definition: he-phy.cc:298
static Time GetValidPpduDuration(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Given a PPDU duration value, the TXVECTOR used to transmit the PPDU and the PHY band,...
Definition: he-phy.cc:263
uint8_t GetNumberBccEncoders(const WifiTxVector &txVector) const override
Definition: he-phy.cc:308
static bool IsAllowed(const WifiTxVector &txVector)
Check whether the combination in TXVECTOR is allowed.
Definition: he-phy.cc:1208
Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
Definition: he-phy.cc:330
void NotifyEndOfHeSigA(HeSigAParameters params)
Fire a EndOfHeSigA callback (if connected) once HE-SIG-A field has been received.
Definition: he-phy.cc:606
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:1144
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:1108
virtual ~HePhy()
Destructor for HE PHY.
Definition: he-phy.cc:87
void DoStartReceivePayload(Ptr< Event > event) override
Start receiving the PSDU (i.e.
Definition: he-phy.cc:664
static const PpduFormats m_hePpduFormats
HE PPDU formats.
Definition: he-phy.h:464
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:1130
HePhy(bool buildModeList=true)
Constructor for HE PHY.
Definition: he-phy.cc:71
bool IsConfigSupported(Ptr< const WifiPpdu > ppdu) const override
Checks if the signaled configuration (excluding bandwidth) is supported by the PHY.
Definition: he-phy.cc:631
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:504
void SetTrigVector(const WifiTxVector &trigVector, Time validity)
Set the TRIGVECTOR and the associated expiration time.
Definition: he-phy.cc:322
static std::pair< uint16_t, Time > ConvertHeTbPpduDurationToLSigLength(Time ppduDuration, const WifiTxVector &txVector, WifiPhyBand band)
Compute the L-SIG length value corresponding to the given HE TB PPDU duration.
Definition: he-phy.cc:274
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:1178
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:789
WifiMode GetSigBMode(const WifiTxVector &txVector) const override
Definition: he-phy.cc:134
void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu) override
Perform amendment-specific actions at the end of the reception of the payload.
Definition: he-phy.cc:708
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:419
Time GetSigADuration(WifiPreamble preamble) const override
Definition: he-phy.cc:199
Time GetTrainingDuration(const WifiTxVector &txVector, uint8_t nDataLtf, uint8_t nExtensionLtf=0) const override
Definition: he-phy.cc:179
Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const override
Definition: he-phy.cc:899
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Definition: he-phy.cc:861
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1095
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:527
uint8_t m_maxMcsIndexPerSs
the maximum MCS index per spatial stream as defined by the standard
Definition: ht-phy.h:525
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:526
void NotifyPayloadBegin(const WifiTxVector &txVector, const Time &payloadDuration)
Fire the trace indicating that the PHY is starting to receive the payload of a PPDU.
Definition: phy-entity.cc:1042
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:726
virtual void CancelAllEvents(void)
Cancel and clear all running events.
Definition: phy-entity.cc:914
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:752
virtual void StartReceivePreamble(Ptr< WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: phy-entity.cc:364
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:807
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:791
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: phy-entity.h:797
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:719
std::tuple< double, double, double > GetTxMaskRejectionParams(void) const
Definition: phy-entity.cc:1080
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
Definition: phy-entity.cc:966
void EndReceivePayload(Ptr< Event > event)
The last symbol of the PPDU has arrived.
Definition: phy-entity.cc:634
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:809
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition: phy-entity.h:799
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
Definition: phy-entity.cc:740
double GetRxPowerWForPpdu(Ptr< Event > event) const
Obtain the received power (W) for a given band.
Definition: phy-entity.cc:1003
virtual void DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:543
Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector) const
Definition: phy-entity.cc:188
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:764
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:806
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:522
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:1048
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:1055
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1074
virtual bool IsModeSupported(WifiMode mode) const
Check if the WifiMode is supported.
Definition: phy-entity.cc:91
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:980
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:794
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:205
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:501
Ptr< const Event > GetCurrentEvent(void) const
Get the pointer to the current event (stored in WifiPhy).
Definition: phy-entity.cc:1009
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:732
virtual void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu)
Perform amendment-specific actions at the end of the reception of the payload.
Definition: phy-entity.cc:673
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:1034
virtual uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const
Return the channel width used to measure the RSSI.
Definition: phy-entity.cc:1015
@ DROP
drop PPDU and set CCA_BUSY
Definition: phy-entity.h:102
void UpdateInterferenceEvent(Ptr< Event > event, const RxPowerWattPerChannelBand &rxPower)
Update an event in WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:758
void ScheduleEndOfMpdus(Ptr< Event > event)
Schedule end of MPDUs events.
Definition: phy-entity.cc:557
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:556
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:103
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:399
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:332
@ US
microsecond
Definition: nstime.h:116
@ NS
nanosecond
Definition: nstime.h:117
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
int64_t GetNanoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:391
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:146
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:110
static WifiMode CreateWifiMcs(std::string uniqueName, uint8_t mcsValue, WifiModulationClass modClass, bool isMandatory, CodeRateCallback codeRateCallback, ConstellationSizeCallback constellationSizeCallback, PhyRateCallback phyRateCallback, DataRateCallback dataRateCallback, NonHtReferenceRateCallback nonHtReferenceRateCallback, AllowedCallback isAllowedCallback)
Definition: wifi-mode.cc:305
represent a single transmission mode
Definition: wifi-mode.h:48
uint8_t GetMcsValue(void) const
Definition: wifi-mode.cc:155
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:114
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:900
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:887
Ptr< WifiNetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:541
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1420
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1138
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1327
static const Ptr< const PhyEntity > GetStaticPhyEntity(WifiModulationClass modulation)
Get the implemented PHY entity corresponding to the modulation class.
Definition: wifi-phy.cc:636
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const
Definition: wifi-phy.cc:1642
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:652
uint64_t GetPreviouslyRxPpduUid(void) const
Definition: wifi-phy.cc:1605
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:1863
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:918
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.
bool IsDlMu(void) const
Return true if this TX vector is used for a downlink multi-user transmission.
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.
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
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.
WifiModulationClass GetModulationClass(void) const
Get the modulation class specified by this TXVECTOR.
#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:1709
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1284
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
@ 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:1042
#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
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.h:25255
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
@ LOG_FUNCTION
Function tracing.
Definition: log.h:109
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:1648
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