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
37namespace ns3 {
38
40
41/*******************************************************
42 * HE PHY (P802.11ax/D4.0, clause 27)
43 *******************************************************/
44
45/* *NS_CHECK_STYLE_OFF* */
46const PhyEntity::PpduFormats HePhy::m_hePpduFormats { //Ignoring PE (Packet Extension)
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
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
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
71HePhy::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);
79 m_currentHeTbPpduUid = UINT64_MAX;
80 m_previouslyTxPpduUid = UINT64_MAX;
81 if (buildModeList)
82 {
84 }
85}
86
88{
89 NS_LOG_FUNCTION (this);
90}
91
92void
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
106HePhy::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
129{
130 return GetVhtMcs0 (); //same number of data tones as VHT for 20 MHz (i.e. 52)
131}
132
134HePhy::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
172Time
174{
175 return MicroSeconds (8); //L-SIG + RL-SIG
176}
177
178Time
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
198Time
200{
201 return (preamble == WIFI_PREAMBLE_HE_ER_SU) ? MicroSeconds (16) : MicroSeconds (8); //HE-SIG-A (first and second symbol)
202}
203
204Time
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
262Time
263HePhy::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
273std::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
286Time
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
297Time
299{
300 NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () != WIFI_MOD_CLASS_HE));
301 Time duration = GetDuration (WIFI_PPDU_FIELD_PREAMBLE, txVector)
304 return duration;
305}
306
307uint8_t
308HePhy::GetNumberBccEncoders (const WifiTxVector& /* txVector */) const
309{
310 return 1; //only 1 BCC encoder for HE since higher rates are obtained using LDPC
311}
312
313Time
315{
316 uint16_t gi = txVector.GetGuardInterval ();
317 NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
318 return NanoSeconds (12800 + gi);
319}
320
321void
322HePhy::SetTrigVector (const WifiTxVector& trigVector, Time validity)
323{
324 m_trigVector = trigVector;
327}
328
330HePhy::BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration)
331{
332 NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration);
334 if (txVector.IsUlMu ())
335 {
338 }
339 else
340 {
342 }
343 return Create<HePpdu> (psdus, txVector, ppduDuration, m_wifiPhy->GetPhyBand (),
344 ObtainNextUid (txVector), flag,
346}
347
348void
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
388void
390{
391 NS_LOG_FUNCTION (this);
392 for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
393 {
394 beginOfdmaPayloadRxEvent.second.Cancel ();
395 }
398}
399
400void
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
418void
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 }
486}
487
488uint8_t
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
503uint16_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
599void
601{
602 m_endOfHeSigACallback = callback;
603}
604
605void
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
630bool
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
663void
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
707void
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
737void
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
774std::pair<uint16_t, WifiSpectrumBand>
775HePhy::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
789HePhy::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
806HePhy::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
823HePhy::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);
840}
841
842uint16_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
854uint64_t
856{
858}
859
860uint16_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
878uint64_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
931uint16_t
932HePhy::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
953void
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
976Time
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
1005void
1007{
1008 for (uint8_t i = 0; i < 12; ++i)
1009 {
1010 GetHeMcs (i);
1011 }
1012}
1013
1015HePhy::GetHeMcs (uint8_t index)
1016{
1017#define CASE(x) \
1018case 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) \
1043WifiMode \
1044HePhy::GetHeMcs ## x (void) \
1045{ \
1046 static WifiMode mcs = CreateHeMcs (x); \
1047 return mcs; \
1048}; \
1049
1050GET_HE_MCS (0)
1051GET_HE_MCS (1)
1052GET_HE_MCS (2)
1053GET_HE_MCS (3)
1054GET_HE_MCS (4)
1055GET_HE_MCS (5)
1056GET_HE_MCS (6)
1057GET_HE_MCS (7)
1058GET_HE_MCS (8)
1059GET_HE_MCS (9)
1060GET_HE_MCS (10)
1061GET_HE_MCS (11)
1062#undef GET_HE_MCS
1063
1064WifiMode
1065HePhy::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,
1078}
1079
1081HePhy::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
1094uint16_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
1107uint64_t
1108HePhy::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
1115uint64_t
1116HePhy::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
1129uint64_t
1130HePhy::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
1143uint64_t
1144HePhy::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
1154uint16_t
1155HePhy::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
1177uint64_t
1179{
1180 WifiCodeRate codeRate = GetCodeRate (mcsValue);
1181 uint16_t constellationSize = GetConstellationSize (mcsValue);
1182 return CalculateNonHtReferenceRate (codeRate, constellationSize);
1183}
1184
1185uint64_t
1186HePhy::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
1207bool
1208HePhy::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
1229{
1230 return 6500631;
1231}
1232
1233} //namespace ns3
1234
1235namespace {
1236
1240static class ConstructorHe
1241{
1242public:
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
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:96
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