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