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 m_rxHeTbPpdus (0)
75{
76 NS_LOG_FUNCTION (this << buildModeList);
80 m_currentHeTbPpduUid = UINT64_MAX;
81 m_previouslyTxPpduUid = UINT64_MAX;
82 if (buildModeList)
83 {
85 }
86}
87
89{
90 NS_LOG_FUNCTION (this);
91}
92
93void
95{
96 NS_LOG_FUNCTION (this);
97 NS_ASSERT (m_modeList.empty ());
99 for (uint8_t index = 0; index <= m_maxSupportedMcsIndexPerSs; ++index)
100 {
101 NS_LOG_LOGIC ("Add HeMcs" << +index << " to list");
102 m_modeList.emplace_back (CreateHeMcs (index));
103 }
104}
105
107HePhy::GetSigMode (WifiPpduField field, const WifiTxVector& txVector) const
108{
109 switch (field)
110 {
111 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)
112 if (txVector.IsDlMu ())
113 {
115 //Training comes after SIG-B
116 return GetSigBMode (txVector);
117 }
118 else
119 {
120 //Training comes after SIG-A
121 return GetSigAMode ();
122 }
123 default:
124 return VhtPhy::GetSigMode (field, txVector);
125 }
126}
127
130{
131 return GetVhtMcs0 (); //same number of data tones as VHT for 20 MHz (i.e. 52)
132}
133
135HePhy::GetSigBMode (const WifiTxVector& txVector) const
136{
137 NS_ABORT_MSG_IF (!IsDlMu (txVector.GetPreambleType ()), "SIG-B only available for DL MU");
144 uint8_t smallestMcs = 5; //maximum MCS for HE-SIG-B
145 for (auto & info : txVector.GetHeMuUserInfoMap ())
146 {
147 smallestMcs = std::min (smallestMcs, info.second.mcs.GetMcsValue ());
148 }
149 switch (smallestMcs)
150 {
151 case 0:
152 return GetVhtMcs0 ();
153 case 1:
154 return GetVhtMcs1 ();
155 case 2:
156 return GetVhtMcs2 ();
157 case 3:
158 return GetVhtMcs3 ();
159 case 4:
160 return GetVhtMcs4 ();
161 case 5:
162 default:
163 return GetVhtMcs5 ();
164 }
165}
166
169{
170 return m_hePpduFormats;
171}
172
173Time
175{
176 return MicroSeconds (8); //L-SIG + RL-SIG
177}
178
179Time
181 uint8_t nDataLtf, uint8_t nExtensionLtf /* = 0 */) const
182{
183 Time ltfDuration = MicroSeconds (8); //TODO extract from TxVector when available
184 Time stfDuration;
185 if (txVector.IsUlMu ())
186 {
188 stfDuration = MicroSeconds (8);
189 }
190 else
191 {
192 stfDuration = MicroSeconds (4);
193 }
194 NS_ABORT_MSG_IF (nDataLtf > 8, "Unsupported number of LTFs " << +nDataLtf << " for HE");
195 NS_ABORT_MSG_IF (nExtensionLtf > 0, "No extension LTFs expected for HE");
196 return stfDuration + ltfDuration * nDataLtf; //HE-STF + HE-LTFs
197}
198
199Time
201{
202 return (preamble == WIFI_PREAMBLE_HE_ER_SU) ? MicroSeconds (16) : MicroSeconds (8); //HE-SIG-A (first and second symbol)
203}
204
205Time
207{
208 if (txVector.IsDlMu ()) //See section 27.3.10.8 of IEEE 802.11ax draft 4.0.
209 {
211 /*
212 * Compute the number of bits used by common field.
213 * Assume that compression bit in HE-SIG-A is not set (i.e. not
214 * full band MU-MIMO); the field is present.
215 */
216 uint16_t bw = txVector.GetChannelWidth ();
217 std::size_t commonFieldSize = 4 /* CRC */ + 6 /* tail */;
218 if (bw <= 40)
219 {
220 commonFieldSize += 8; //only one allocation subfield
221 }
222 else
223 {
224 commonFieldSize += 8 * (bw / 40) /* one allocation field per 40 MHz */ + 1 /* center RU */;
225 }
226
227 /*
228 * Compute the number of bits used by user-specific field.
229 * MU-MIMO is not supported; only one station per RU.
230 * The user-specific field is composed of N user block fields
231 * spread over each corresponding HE-SIG-B content channel.
232 * Each user block field contains either two or one users' data
233 * (the latter being for odd number of stations per content channel).
234 * Padding will be handled further down in the code.
235 */
236 std::pair<std::size_t, std::size_t> numStaPerContentChannel = txVector.GetNumRusPerHeSigBContentChannel ();
237 std::size_t maxNumStaPerContentChannel = std::max (numStaPerContentChannel.first, numStaPerContentChannel.second);
238 std::size_t maxNumUserBlockFields = maxNumStaPerContentChannel / 2; //handle last user block with single user, if any, further down
239 std::size_t userSpecificFieldSize = maxNumUserBlockFields * (2 * 21 /* user fields (2 users) */ + 4 /* tail */ + 6 /* CRC */);
240 if (maxNumStaPerContentChannel % 2 != 0)
241 {
242 userSpecificFieldSize += 21 /* last user field */ + 4 /* CRC */ + 6 /* tail */;
243 }
244
245 /*
246 * Compute duration of HE-SIG-B considering that padding
247 * is added up to the next OFDM symbol.
248 * Nss = 1 and GI = 800 ns for HE-SIG-B.
249 */
250 Time symbolDuration = MicroSeconds (4);
251 double numDataBitsPerSymbol = GetSigBMode (txVector).GetDataRate (20, 800, 1) * symbolDuration.GetNanoSeconds () / 1e9;
252 double numSymbols = ceil ((commonFieldSize + userSpecificFieldSize) / numDataBitsPerSymbol);
253
254 return FemtoSeconds (static_cast<uint64_t> (numSymbols * symbolDuration.GetFemtoSeconds ()));
255 }
256 else
257 {
258 // no SIG-B
259 return MicroSeconds (0);
260 }
261}
262
263Time
264HePhy::GetValidPpduDuration (Time ppduDuration, const WifiTxVector& txVector,
265 WifiPhyBand band)
266{
267 Time tSymbol = NanoSeconds (12800 + txVector.GetGuardInterval ());
268 Time preambleDuration = WifiPhy::CalculatePhyPreambleAndHeaderDuration (txVector);
269 uint8_t sigExtension = (band == WIFI_PHY_BAND_2_4GHZ ? 6 : 0);
270 uint32_t nSymbols = floor (static_cast<double> ((ppduDuration - preambleDuration).GetNanoSeconds () - (sigExtension * 1000)) / tSymbol.GetNanoSeconds ());
271 return preambleDuration + (nSymbols * tSymbol) + MicroSeconds (sigExtension);
272}
273
274std::pair<uint16_t, Time>
276 WifiPhyBand band)
277{
278 NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () < WIFI_MOD_CLASS_HE));
279 // update ppduDuration so that it is a valid PPDU duration
280 ppduDuration = GetValidPpduDuration (ppduDuration, txVector, band);
281 uint8_t sigExtension = (band == WIFI_PHY_BAND_2_4GHZ ? 6 : 0);
282 uint8_t m = 2; //HE TB PPDU so m is set to 2
283 uint16_t length = ((ceil ((static_cast<double> (ppduDuration.GetNanoSeconds () - (20 * 1000) - (sigExtension * 1000)) / 1000) / 4.0) * 3) - 3 - m);
284 return {length, ppduDuration};
285}
286
287Time
289{
290 NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () < WIFI_MOD_CLASS_HE));
291 uint8_t sigExtension = (band == WIFI_PHY_BAND_2_4GHZ ? 6 : 0);
292 uint8_t m = 2; //HE TB PPDU so m is set to 2
293 //Equation 27-11 of IEEE P802.11ax/D4.0
294 Time calculatedDuration = MicroSeconds (((ceil (static_cast<double> (length + 3 + m) / 3)) * 4) + 20 + sigExtension);
295 return GetValidPpduDuration (calculatedDuration, txVector, band);
296}
297
298Time
300{
301 NS_ABORT_IF (!txVector.IsUlMu () || (txVector.GetModulationClass () < WIFI_MOD_CLASS_HE));
302 Time duration = GetDuration (WIFI_PPDU_FIELD_PREAMBLE, txVector)
305 return duration;
306}
307
308uint8_t
309HePhy::GetNumberBccEncoders (const WifiTxVector& /* txVector */) const
310{
311 return 1; //only 1 BCC encoder for HE since higher rates are obtained using LDPC
312}
313
314Time
316{
317 uint16_t gi = txVector.GetGuardInterval ();
318 NS_ASSERT (gi == 800 || gi == 1600 || gi == 3200);
319 return GetSymbolDuration (NanoSeconds (gi));
320}
321
322void
323HePhy::SetTrigVector (const WifiTxVector& trigVector, Time validity)
324{
325 m_trigVector = trigVector;
328}
329
331HePhy::BuildPpdu (const WifiConstPsduMap & psdus, const WifiTxVector& txVector, Time ppduDuration)
332{
333 NS_LOG_FUNCTION (this << psdus << txVector << ppduDuration);
335 if (txVector.IsUlMu ())
336 {
339 }
340 else
341 {
343 }
344 return Create<HePpdu> (psdus, txVector,
346 ppduDuration, m_wifiPhy->GetPhyBand (),
347 ObtainNextUid (txVector), flag,
349}
350
351void
353 Time rxDuration)
354{
355 NS_LOG_FUNCTION (this << ppdu << rxDuration);
356 const WifiTxVector& txVector = ppdu->GetTxVector ();
357 auto hePpdu = DynamicCast<const HePpdu> (ppdu);
358 NS_ASSERT (hePpdu);
359 HePpdu::TxPsdFlag psdFlag = hePpdu->GetTxPsdFlag ();
360 if (txVector.IsUlMu () && psdFlag == HePpdu::PSD_HE_TB_OFDMA_PORTION)
361 {
363 if (m_currentHeTbPpduUid == ppdu->GetUid ()
364 && GetCurrentEvent () != 0)
365 {
366 //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)
367 bool ofdmaStarted = !m_beginOfdmaPayloadRxEvents.empty ();
368 NS_LOG_INFO ("Switch to OFDMA part (already started? " << (ofdmaStarted ? "Y" : "N") << ") " <<
369 "and schedule OFDMA payload reception in " << GetDuration (WIFI_PPDU_FIELD_TRAINING, txVector).As (Time::NS));
370 Ptr<Event> event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW, !ofdmaStarted);
371 uint16_t staId = GetStaId (ppdu);
374 &HePhy::StartReceiveOfdmaPayload, this, event);
375 }
376 else
377 {
378 //PHY receives the OFDMA payload while having dropped the preamble
379 NS_LOG_INFO ("Consider OFDMA part of the HE TB PPDU as interference since device dropped the preamble");
380 CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
381 //the OFDMA part of the HE TB PPDUs will be noise _after_ the completion of the current event
382 ErasePreambleEvent (ppdu, rxDuration);
383 }
384 }
385 else
386 {
387 PhyEntity::StartReceivePreamble (ppdu, rxPowersW, ppdu->GetTxDuration ()); // The actual duration of the PPDU should be used
388 }
389}
390
391void
393{
394 NS_LOG_FUNCTION (this);
395 for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
396 {
397 beginOfdmaPayloadRxEvent.second.Cancel ();
398 }
401}
402
403void
405{
406 NS_LOG_FUNCTION (this << reason);
407 if (reason != OBSS_PD_CCA_RESET)
408 {
409 for (auto & endMpduEvent : m_endOfMpduEvents)
410 {
411 endMpduEvent.Cancel ();
412 }
413 m_endOfMpduEvents.clear ();
414 }
415 else
416 {
418 }
419}
420
421void
423{
424 NS_LOG_FUNCTION (this << *event);
425 if (event->GetPpdu ()->GetType () != WIFI_PPDU_TYPE_UL_MU)
426 {
427 NS_ASSERT (event->GetEndTime () == Simulator::Now ());
428 }
429 for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
430 {
431 beginOfdmaPayloadRxEvent.second.Cancel ();
432 }
434}
435
438{
439 Ptr<Event> event;
440 //We store all incoming preamble events, and a decision is made at the end of the preamble detection window.
441 //If a preamble is received after the preamble detection window, it is stored anyway because this is needed for HE TB PPDUs in
442 //order to properly update the received power in InterferenceHelper. The map is cleaned anyway at the end of the current reception.
443 if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
444 {
445 auto uidPreamblePair = std::make_pair (ppdu->GetUid (), ppdu->GetPreamble ());
446 const WifiTxVector& txVector = ppdu->GetTxVector ();
447 Time rxDuration = CalculateNonOfdmaDurationForHeTb (txVector); //the OFDMA part of the transmission will be added later on
448 const auto & currentPreambleEvents = GetCurrentPreambleEvents ();
449 auto it = currentPreambleEvents.find (uidPreamblePair);
450 if (it != currentPreambleEvents.end ())
451 {
452 NS_LOG_DEBUG ("Received another HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
453 event = it->second;
454
455 auto heConfiguration = m_wifiPhy->GetDevice ()->GetHeConfiguration ();
456 NS_ASSERT (heConfiguration);
457 // DoStartReceivePayload(), which is called when we start receiving the Data field,
458 // computes the max offset among TB PPDUs based on the begin OFDMA payload RX events,
459 // which are scheduled by StartReceivePreamble() when starting the reception of the
460 // OFDMA portion. Therefore, the maximum delay cannot exceed the duration of the
461 // training fields that are between the start of the OFDMA portion and the start
462 // of the Data field.
463 Time maxDelay = GetDuration (WIFI_PPDU_FIELD_TRAINING, txVector);
464 if (heConfiguration->GetMaxTbPpduDelay ().IsStrictlyPositive ())
465 {
466 maxDelay = Min (maxDelay, heConfiguration->GetMaxTbPpduDelay ());
467 }
468
469 if (Simulator::Now () - event->GetStartTime () > maxDelay)
470 {
471 // This HE TB PPDU arrived too late to be decoded properly. The HE TB PPDU
472 // is dropped and added as interference
473 event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
474 NS_LOG_DEBUG ("Drop HE TB PPDU that arrived too late");
476 }
477 else
478 {
479 //Update received power of the event associated to that UL MU transmission
480 UpdateInterferenceEvent (event, rxPowersW);
481 }
482
483 if ((GetCurrentEvent () != 0) && (GetCurrentEvent ()->GetPpdu ()->GetUid () != ppdu->GetUid ()))
484 {
485 NS_LOG_DEBUG ("Drop packet because already receiving another HE TB PPDU");
487 }
488 return nullptr;
489 }
490 else
491 {
492 NS_LOG_DEBUG ("Received a new HE TB PPDU for UID " << ppdu->GetUid () << " from STA-ID " << ppdu->GetStaId () << " and BSS color " << +txVector.GetBssColor ());
493 event = CreateInterferenceEvent (ppdu, txVector, rxDuration, rxPowersW);
494 AddPreambleEvent (event);
495 }
496 }
497 else
498 {
499 event = PhyEntity::DoGetEvent (ppdu, rxPowersW);
500 }
501 return event;
502}
503
506{
507 if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU || ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
508 {
509 auto hePpdu = DynamicCast<const HePpdu> (ppdu);
510 NS_ASSERT (hePpdu);
511 return hePpdu->GetPsdu (GetBssColor (), GetStaId (ppdu));
512 }
514}
515
516uint8_t
518{
519 uint8_t bssColor = 0;
520 if (m_wifiPhy->GetDevice () != nullptr)
521 {
523 if (heConfiguration)
524 {
525 bssColor = heConfiguration->GetBssColor ();
526 }
527 }
528 return bssColor;
529}
530
531uint16_t
533{
534 if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
535 {
536 return ppdu->GetStaId ();
537 }
538 else if (ppdu->GetType () == WIFI_PPDU_TYPE_DL_MU)
539 {
540 Ptr<StaWifiMac> mac = DynamicCast<StaWifiMac> (m_wifiPhy->GetDevice ()->GetMac ());
541 if (mac && mac->IsAssociated ())
542 {
543 return mac->GetAssociationId ();
544 }
545 }
546 return PhyEntity::GetStaId (ppdu);
547}
548
551{
552 NS_LOG_FUNCTION (this << *event << status << field);
553 NS_ASSERT (event->GetTxVector ().GetPreambleType () >= WIFI_PREAMBLE_HE_SU);
554 switch (field)
555 {
557 return ProcessSigA (event, status);
559 return ProcessSigB (event, status);
560 default:
561 NS_ASSERT_MSG (false, "Invalid PPDU field");
562 }
563 return status;
564}
565
568{
569 NS_LOG_FUNCTION (this << *event << status);
570 //Notify end of SIG-A (in all cases)
571 WifiTxVector txVector = event->GetTxVector ();
572 HeSigAParameters params;
573 params.rssiW = GetRxPowerWForPpdu (event);
574 params.bssColor = txVector.GetBssColor ();
575 NotifyEndOfHeSigA (params); //if OBSS_PD CCA_RESET, set power restriction first and wait till field is processed before switching to IDLE
576
577 if (status.isSuccess)
578 {
579 //Check if PPDU is filtered based on the BSS color
580 uint8_t myBssColor = GetBssColor ();
581 uint8_t rxBssColor = txVector.GetBssColor ();
582 if (myBssColor != 0 && rxBssColor != 0 && myBssColor != rxBssColor)
583 {
584 NS_LOG_DEBUG ("The BSS color of this PPDU (" << +rxBssColor << ") does not match the device's (" << +myBssColor << "). The PPDU is filtered.");
585 return PhyFieldRxStatus (false, FILTERED, DROP);
586 }
587
588 // When SIG-A is decoded, we know the type of frame being received. If we stored a
589 // valid TRIGVECTOR and we are not receiving a TB PPDU, we drop the frame.
590 if (m_trigVectorExpirationTime >= Simulator::Now () && !txVector.IsUlMu ())
591 {
592 NS_LOG_DEBUG ("Expected an HE TB PPDU, receiving a " << txVector.GetPreambleType ());
593 return PhyFieldRxStatus (false, FILTERED, DROP);
594 }
595
596 Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
597 if (txVector.IsUlMu ())
598 {
600 // check that the stored TRIGVECTOR is still valid
602 {
603 NS_LOG_DEBUG ("No valid TRIGVECTOR, the PHY was not expecting a TB PPDU");
604 return PhyFieldRxStatus (false, FILTERED, DROP);
605 }
606 // We expected a TB PPDU and we are receiving a TB PPDU. However, despite
607 // the previous check on BSS Color, we may be receiving a TB PPDU from an
608 // OBSS, as BSS Colors are not guaranteed to be different for all APs in
609 // range (an example is when BSS Color is 0). We can detect this situation
610 // by comparing the TRIGVECTOR with the TXVECTOR of the TB PPDU being received
611 if (m_trigVector.GetChannelWidth () != txVector.GetChannelWidth ())
612 {
613 NS_LOG_DEBUG ("Received channel width different than in TRIGVECTOR");
614 return PhyFieldRxStatus (false, FILTERED, DROP);
615 }
616 if (m_trigVector.GetLength () != txVector.GetLength ())
617 {
618 NS_LOG_DEBUG ("Received UL Length (" << txVector.GetLength () <<
619 ") different than in TRIGVECTOR (" << m_trigVector.GetLength ()
620 << ")");
621 return PhyFieldRxStatus (false, FILTERED, DROP);
622 }
623 uint16_t staId = ppdu->GetStaId ();
624 if (m_trigVector.GetHeMuUserInfoMap ().find (staId) == m_trigVector.GetHeMuUserInfoMap ().end ()
625 || m_trigVector.GetHeMuUserInfo (staId) != txVector.GetHeMuUserInfo (staId))
626 {
627 NS_LOG_DEBUG ("User Info map of TB PPDU being received differs from that of TRIGVECTOR");
628 return PhyFieldRxStatus (false, FILTERED, DROP);
629 }
630
631 m_currentHeTbPpduUid = ppdu->GetUid (); //to be able to correctly schedule start of OFDMA payload
632 }
633
634 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
635 {
636 NS_ASSERT (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU);
637 NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
638 return PhyFieldRxStatus (false, FILTERED, DROP);
639 }
640 }
641 return status;
642}
643
644void
646{
647 m_endOfHeSigACallback = callback;
648}
649
650void
652{
654 {
655 m_endOfHeSigACallback (params);
656 }
657}
658
661{
662 NS_LOG_FUNCTION (this << *event << status);
663 NS_ASSERT (IsDlMu (event->GetTxVector ().GetPreambleType ()));
664 if (status.isSuccess)
665 {
666 //Check if PPDU is filtered only if the SIG-B content is supported (not explicitly stated but assumed based on behavior for SIG-A)
667 if (!GetAddressedPsduInPpdu (event->GetPpdu ()))
668 {
669 NS_LOG_DEBUG ("No PSDU addressed to that PHY in the received MU PPDU. The PPDU is filtered.");
670 return PhyFieldRxStatus (false, FILTERED, DROP);
671 }
672 }
673 return status;
674}
675
676bool
678{
679 const WifiTxVector& txVector = ppdu->GetTxVector ();
680 uint16_t staId = GetStaId (ppdu);
681 WifiMode txMode = txVector.GetMode (staId);
682 uint8_t nss = txVector.GetNssMax ();
683 if (txVector.IsDlMu ())
684 {
686 for (auto info : txVector.GetHeMuUserInfoMap ())
687 {
688 if (info.first == staId)
689 {
690 nss = info.second.nss; //no need to look at other PSDUs
691 break;
692 }
693 }
694 }
695
697 {
698 NS_LOG_DEBUG ("Packet reception could not be started because not enough RX antennas");
699 return false;
700 }
701 if (!IsModeSupported (txMode))
702 {
703 NS_LOG_DEBUG ("Drop packet because it was sent using an unsupported mode (" << txVector.GetMode () << ")");
704 return false;
705 }
706 return true;
707}
708
709Time
711{
712 NS_LOG_FUNCTION (this << *event);
713 const WifiTxVector& txVector = event->GetTxVector ();
714 Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
715 if (!txVector.IsUlMu ())
716 {
718 }
719
721 // TX duration is determined by the Length field of TXVECTOR
722 Time payloadDuration = ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (),
723 txVector,
726 // This method is called when we start receiving the first OFDMA payload. To
727 // compute the time to the reception end of the last TB PPDU, we need to add the
728 // offset of the last TB PPDU to the payload duration (same for all TB PPDUs)
729 Time maxOffset {0};
730 for (const auto& beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
731 {
732 maxOffset = Max (maxOffset, Simulator::GetDelayLeft (beginOfdmaPayloadRxEvent.second));
733 }
734 Time timeToEndRx = payloadDuration + maxOffset;
735
736 bool isAp = (DynamicCast<ApWifiMac> (m_wifiPhy->GetDevice ()->GetMac ()) != 0);
737 if (!isAp)
738 {
739 NS_LOG_DEBUG ("Ignore HE TB PPDU payload received by STA but keep state in Rx");
740 NotifyPayloadBegin (txVector, timeToEndRx);
741 m_endRxPayloadEvents.push_back (Simulator::Schedule (timeToEndRx,
742 &PhyEntity::ResetReceive, this, event));
743 //Cancel all scheduled events for OFDMA payload reception
744 NS_ASSERT (!m_beginOfdmaPayloadRxEvents.empty () && m_beginOfdmaPayloadRxEvents.begin ()->second.IsRunning ());
745 for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
746 {
747 beginOfdmaPayloadRxEvent.second.Cancel ();
748 }
750 }
751 else
752 {
753 NS_LOG_DEBUG ("Receiving PSDU in HE TB PPDU");
754 uint16_t staId = GetStaId (ppdu);
755 m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), staId), SignalNoiseDbm ()});
756 m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), staId), std::vector<bool> ()});
757 //for HE TB PPDUs, ScheduleEndOfMpdus and EndReceive are scheduled by StartReceiveOfdmaPayload
758 NS_ASSERT (isAp);
760 for (auto & beginOfdmaPayloadRxEvent : m_beginOfdmaPayloadRxEvents)
761 {
762 NS_ASSERT (beginOfdmaPayloadRxEvent.second.IsRunning ());
763 }
764 }
765
766 return timeToEndRx;
767}
768
769void
771 const WifiTxVector& txVector, uint16_t staId,
772 const std::vector<bool>& statusPerMpdu)
773{
774 NS_LOG_FUNCTION (this << *psdu << txVector);
775 m_state->NotifyRxPsduSucceeded (Copy (psdu), rxSignalInfo, txVector, staId, statusPerMpdu);
776 if (!IsUlMu (txVector.GetPreambleType ()))
777 {
778 m_state->SwitchFromRxEndOk ();
779 }
780 else
781 {
783 }
784}
785
786void
787HePhy::RxPayloadFailed (Ptr<const WifiPsdu> psdu, double snr, const WifiTxVector& txVector)
788{
789 NS_LOG_FUNCTION (this << *psdu << txVector << snr);
790 m_state->NotifyRxPsduFailed (Copy (psdu), snr);
791 if (!txVector.IsUlMu ())
792 {
793 m_state->SwitchFromRxEndError ();
794 }
795}
796
797void
799{
800 NS_LOG_FUNCTION (this << ppdu);
801 if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
802 {
803 for (auto it = m_endRxPayloadEvents.begin (); it != m_endRxPayloadEvents.end (); )
804 {
805 if (it->IsExpired ())
806 {
807 it = m_endRxPayloadEvents.erase (it);
808 }
809 else
810 {
811 it++;
812 }
813 }
814 if (m_endRxPayloadEvents.empty ())
815 {
816 //We've got the last PPDU of the UL-OFDMA transmission.
817 //Indicate a successfull reception is terminated if at least one HE TB PPDU
818 //has been successfully received, otherwise indicate a unsuccessfull reception is terminated.
819 if (m_rxHeTbPpdus > 0)
820 {
821 m_state->SwitchFromRxEndOk ();
822 }
823 else
824 {
825 m_state->SwitchFromRxEndError ();
826 }
827 NotifyInterferenceRxEndAndClear (true); //reset WifiPhy
828 m_rxHeTbPpdus = 0;
829 }
830 }
831 else
832 {
835 }
836}
837
838void
840{
841 Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
842 const RxPowerWattPerChannelBand& rxPowersW = event->GetRxPowerWPerBand ();
843 //The total RX power corresponds to the maximum over all the bands.
844 //Only perform this computation if the result needs to be logged.
845 auto it = rxPowersW.end ();
846 if (g_log.IsEnabled (ns3::LOG_FUNCTION))
847 {
848 it = std::max_element (rxPowersW.begin (), rxPowersW.end (),
849 [] (const std::pair<WifiSpectrumBand, double> &p1, const std::pair<WifiSpectrumBand, double> &p2) {
850 return p1.second < p2.second;
851 });
852
853 }
854 NS_LOG_FUNCTION (this << *event << it->second);
855 NS_ASSERT (GetCurrentEvent () != 0);
857 auto itEvent = m_beginOfdmaPayloadRxEvents.find (GetStaId (ppdu));
863 NS_ASSERT (itEvent != m_beginOfdmaPayloadRxEvents.end () && itEvent->second.IsExpired ());
864 m_beginOfdmaPayloadRxEvents.erase (itEvent);
865
866 Time payloadDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (ppdu->GetTxVector ());
868 ScheduleEndOfMpdus (event);
869 m_endRxPayloadEvents.push_back (Simulator::Schedule (payloadDuration, &PhyEntity::EndReceivePayload, this, event));
870 m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), SignalNoiseDbm ()});
871 m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), std::vector<bool> ()});
872 // Notify the MAC about the start of a new HE TB PPDU, so that it can reschedule the timeout
873 NotifyPayloadBegin (ppdu->GetTxVector (), payloadDuration);
874}
875
876std::pair<uint16_t, WifiSpectrumBand>
877HePhy::GetChannelWidthAndBand (const WifiTxVector& txVector, uint16_t staId) const
878{
879 if (txVector.IsMu ())
880 {
881 return std::make_pair (HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ()),
882 GetRuBandForRx (txVector, staId));
883 }
884 else
885 {
886 return PhyEntity::GetChannelWidthAndBand (txVector, staId);
887 }
888}
889
891HePhy::GetRuBandForTx (const WifiTxVector& txVector, uint16_t staId) const
892{
893 NS_ASSERT (txVector.IsMu ());
894 WifiSpectrumBand band;
895 HeRu::RuSpec ru = txVector.GetRu (staId);
896 uint16_t channelWidth = txVector.GetChannelWidth ();
897 NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
898 HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetPhyIndex ());
899 HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
900 // for a TX spectrum, the guard bandwidth is a function of the transmission channel width
901 // and the spectrum width equals the transmission channel width (hence bandIndex equals 0)
902 band = m_wifiPhy->ConvertHeRuSubcarriers (channelWidth, GetGuardBandwidth (channelWidth),
903 range, 0);
904 return band;
905}
906
908HePhy::GetRuBandForRx (const WifiTxVector& txVector, uint16_t staId) const
909{
910 NS_ASSERT (txVector.IsMu ());
911 WifiSpectrumBand band;
912 HeRu::RuSpec ru = txVector.GetRu (staId);
913 uint16_t channelWidth = txVector.GetChannelWidth ();
914 NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
915 HeRu::SubcarrierGroup group = HeRu::GetSubcarrierGroup (channelWidth, ru.GetRuType (), ru.GetPhyIndex ());
916 HeRu::SubcarrierRange range = std::make_pair (group.front ().first, group.back ().second);
917 // for an RX spectrum, the guard bandwidth is a function of the operating channel width
918 // and the spectrum width equals the operating channel width
920 range, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (channelWidth));
921 return band;
922}
923
925HePhy::GetNonOfdmaBand (const WifiTxVector& txVector, uint16_t staId) const
926{
927 NS_ASSERT (txVector.IsUlMu () && (txVector.GetModulationClass () >= WIFI_MOD_CLASS_HE));
928 uint16_t channelWidth = txVector.GetChannelWidth ();
929 NS_ASSERT (channelWidth <= m_wifiPhy->GetChannelWidth ());
930
931 HeRu::RuSpec ru = txVector.GetRu (staId);
932 uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
933
934 // Find the RU that encompasses the non-OFDMA part of the HE TB PPDU for the STA-ID
935 HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (channelWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
936 nonOfdmaRu.SetPhyIndex (channelWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
937
938 HeRu::SubcarrierGroup groupPreamble = HeRu::GetSubcarrierGroup (channelWidth, nonOfdmaRu.GetRuType (), nonOfdmaRu.GetPhyIndex ());
939 HeRu::SubcarrierRange range = std::make_pair (groupPreamble.front ().first, groupPreamble.back ().second);
942}
943
944uint16_t
946{
947 if (ru.GetRuType () == HeRu::RU_26_TONE && ru.GetIndex () == 19)
948 {
949 // the center 26-tone RU in an 80 MHz channel is not fully covered by
950 // any 20 MHz channel, but only by an 80 MHz channel
951 return 80;
952 }
953 return std::max<uint16_t> (HeRu::GetBandwidth (ru.GetRuType ()), 20);
954}
955
956uint64_t
958{
960}
961
962uint16_t
964{
965 uint16_t channelWidth = OfdmPhy::GetMeasurementChannelWidth (ppdu);
973 if (channelWidth >= 40 && ppdu->GetUid () != m_previouslyTxPpduUid)
974 {
975 channelWidth = 20;
976 }
977 return channelWidth;
978}
979
980uint64_t
982{
983 NS_LOG_FUNCTION (this << txVector);
984 uint64_t uid;
985 if (txVector.IsUlMu ())
986 {
988 //Use UID of PPDU containing trigger frame to identify resulting HE TB PPDUs, since the latter should immediately follow the former
990 NS_ASSERT (uid != UINT64_MAX);
991 }
992 else
993 {
994 uid = m_globalPpduUid++;
995 }
996 m_previouslyTxPpduUid = uid; //to be able to identify solicited HE TB PPDUs
997 return uid;
998}
999
1002{
1003 const WifiTxVector& txVector = ppdu->GetTxVector ();
1004 uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
1005 uint16_t channelWidth = txVector.GetChannelWidth ();
1006 NS_LOG_FUNCTION (this << centerFrequency << channelWidth << txPowerW);
1007 auto hePpdu = DynamicCast<const HePpdu> (ppdu);
1008 NS_ASSERT (hePpdu);
1009 HePpdu::TxPsdFlag flag = hePpdu->GetTxPsdFlag ();
1012 {
1013 WifiSpectrumBand band = GetRuBandForTx (txVector, GetStaId (hePpdu));
1014 v = WifiSpectrumValueHelper::CreateHeMuOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth), band);
1015 }
1016 else
1017 {
1019 {
1020 //non-OFDMA portion is sent only on the 20 MHz channels covering the RU
1021 uint16_t staId = GetStaId (hePpdu);
1022 centerFrequency = GetCenterFrequencyForNonOfdmaPart (txVector, staId);
1023 uint16_t ruWidth = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1024 channelWidth = ruWidth < 20 ? 20 : ruWidth;
1025 }
1026 const auto & txMaskRejectionParams = GetTxMaskRejectionParams ();
1027 v = WifiSpectrumValueHelper::CreateHeOfdmTxPowerSpectralDensity (centerFrequency, channelWidth, txPowerW, GetGuardBandwidth (channelWidth),
1028 std::get<0> (txMaskRejectionParams), std::get<1> (txMaskRejectionParams), std::get<2> (txMaskRejectionParams));
1029 }
1030 return v;
1031}
1032
1033uint16_t
1034HePhy::GetCenterFrequencyForNonOfdmaPart (const WifiTxVector& txVector, uint16_t staId) const
1035{
1036 NS_LOG_FUNCTION (this << txVector << staId);
1037 NS_ASSERT (txVector.IsUlMu () && (txVector.GetModulationClass () >= WIFI_MOD_CLASS_HE));
1038 uint16_t centerFrequency = GetCenterFrequencyForChannelWidth (txVector);
1039 uint16_t currentWidth = txVector.GetChannelWidth ();
1040
1041 HeRu::RuSpec ru = txVector.GetRu (staId);
1042 uint16_t nonOfdmaWidth = GetNonOfdmaWidth (ru);
1043 if (nonOfdmaWidth != currentWidth)
1044 {
1045 //Obtain the index of the non-OFDMA portion
1046 HeRu::RuSpec nonOfdmaRu = HeRu::FindOverlappingRu (currentWidth, ru, HeRu::GetRuType (nonOfdmaWidth));
1047 nonOfdmaRu.SetPhyIndex (currentWidth, m_wifiPhy->GetOperatingChannel ().GetPrimaryChannelIndex (20));
1048
1049 uint16_t startingFrequency = centerFrequency - (currentWidth / 2);
1050 centerFrequency = startingFrequency + nonOfdmaWidth * (nonOfdmaRu.GetPhyIndex () - 1) + nonOfdmaWidth / 2;
1051 }
1052 return centerFrequency;
1053}
1054
1055void
1057{
1058 NS_LOG_FUNCTION (this << ppdu);
1059 if (ppdu->GetType () == WIFI_PPDU_TYPE_UL_MU)
1060 {
1061 //non-OFDMA part
1062 Time nonOfdmaDuration = CalculateNonOfdmaDurationForHeTb (ppdu->GetTxVector ());
1063 Transmit (nonOfdmaDuration, ppdu, "non-OFDMA transmission");
1064
1065 //OFDMA part
1066 auto hePpdu = DynamicCast<HePpdu> (ppdu->Copy ()); //since flag will be modified
1067 NS_ASSERT (hePpdu);
1068 hePpdu->SetTxPsdFlag (HePpdu::PSD_HE_TB_OFDMA_PORTION);
1069 Time ofdmaDuration = ppdu->GetTxDuration () - nonOfdmaDuration;
1070 Simulator::Schedule (nonOfdmaDuration, &PhyEntity::Transmit, this, ofdmaDuration, hePpdu, "OFDMA transmission");
1071 }
1072 else
1073 {
1074 PhyEntity::StartTx (ppdu);
1075 }
1076}
1077
1078Time
1080{
1081 if (txVector.IsUlMu ())
1082 {
1084 return ConvertLSigLengthToHeTbPpduDuration (txVector.GetLength (), txVector, band);
1085 }
1086
1087 Time maxDuration = Seconds (0);
1088 for (auto & staIdPsdu : psduMap)
1089 {
1090 if (txVector.IsDlMu ())
1091 {
1093 WifiTxVector::HeMuUserInfoMap userInfoMap = txVector.GetHeMuUserInfoMap ();
1094 NS_ABORT_MSG_IF (userInfoMap.find (staIdPsdu.first) == userInfoMap.end (), "STA-ID in psduMap (" << staIdPsdu.first << ") should be referenced in txVector");
1095 }
1096 Time current = WifiPhy::CalculateTxDuration (staIdPsdu.second->GetSize (), txVector, band,
1097 staIdPsdu.first);
1098 if (current > maxDuration)
1099 {
1100 maxDuration = current;
1101 }
1102 }
1103 NS_ASSERT (maxDuration.IsStrictlyPositive ());
1104 return maxDuration;
1105}
1106
1107void
1109{
1110 for (uint8_t i = 0; i < 12; ++i)
1111 {
1112 GetHeMcs (i);
1113 }
1114}
1115
1117HePhy::GetHeMcs (uint8_t index)
1118{
1119#define CASE(x) \
1120case x: \
1121 return GetHeMcs ## x (); \
1122
1123 switch (index)
1124 {
1125 CASE ( 0)
1126 CASE ( 1)
1127 CASE ( 2)
1128 CASE ( 3)
1129 CASE ( 4)
1130 CASE ( 5)
1131 CASE ( 6)
1132 CASE ( 7)
1133 CASE ( 8)
1134 CASE ( 9)
1135 CASE (10)
1136 CASE (11)
1137 default:
1138 NS_ABORT_MSG ("Inexistent index (" << +index << ") requested for HE");
1139 return WifiMode ();
1140 }
1141#undef CASE
1142}
1143
1144#define GET_HE_MCS(x) \
1145WifiMode \
1146HePhy::GetHeMcs ## x (void) \
1147{ \
1148 static WifiMode mcs = CreateHeMcs (x); \
1149 return mcs; \
1150}; \
1151
1152GET_HE_MCS (0)
1153GET_HE_MCS (1)
1154GET_HE_MCS (2)
1155GET_HE_MCS (3)
1156GET_HE_MCS (4)
1157GET_HE_MCS (5)
1158GET_HE_MCS (6)
1159GET_HE_MCS (7)
1160GET_HE_MCS (8)
1161GET_HE_MCS (9)
1162GET_HE_MCS (10)
1163GET_HE_MCS (11)
1164#undef GET_HE_MCS
1165
1166WifiMode
1167HePhy::CreateHeMcs (uint8_t index)
1168{
1169 NS_ASSERT_MSG (index <= 11, "HeMcs index must be <= 11!");
1170 return WifiModeFactory::CreateWifiMcs ("HeMcs" + std::to_string (index),
1171 index,
1173 false,
1180}
1181
1183HePhy::GetCodeRate (uint8_t mcsValue)
1184{
1185 switch (mcsValue)
1186 {
1187 case 10:
1188 return WIFI_CODE_RATE_3_4;
1189 case 11:
1190 return WIFI_CODE_RATE_5_6;
1191 default:
1192 return VhtPhy::GetCodeRate (mcsValue);
1193 }
1194}
1195
1196uint16_t
1198{
1199 switch (mcsValue)
1200 {
1201 case 10:
1202 case 11:
1203 return 1024;
1204 default:
1205 return VhtPhy::GetConstellationSize (mcsValue);
1206 }
1207}
1208
1209uint64_t
1210HePhy::GetPhyRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1211{
1212 WifiCodeRate codeRate = GetCodeRate (mcsValue);
1213 uint64_t dataRate = GetDataRate (mcsValue, channelWidth, guardInterval, nss);
1214 return HtPhy::CalculatePhyRate (codeRate, dataRate);
1215}
1216
1217uint64_t
1218HePhy::GetPhyRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1219{
1220 uint16_t bw = txVector.GetChannelWidth ();
1221 if (txVector.IsMu ())
1222 {
1223 bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1224 }
1225 return HePhy::GetPhyRate (txVector.GetMode (staId).GetMcsValue (),
1226 bw,
1227 txVector.GetGuardInterval (),
1228 txVector.GetNss (staId));
1229}
1230
1231uint64_t
1232HePhy::GetDataRateFromTxVector (const WifiTxVector& txVector, uint16_t staId /* = SU_STA_ID */)
1233{
1234 uint16_t bw = txVector.GetChannelWidth ();
1235 if (txVector.IsMu ())
1236 {
1237 bw = HeRu::GetBandwidth (txVector.GetRu (staId).GetRuType ());
1238 }
1239 return HePhy::GetDataRate (txVector.GetMode (staId).GetMcsValue (),
1240 bw,
1241 txVector.GetGuardInterval (),
1242 txVector.GetNss (staId));
1243}
1244
1245uint64_t
1246HePhy::GetDataRate (uint8_t mcsValue, uint16_t channelWidth, uint16_t guardInterval, uint8_t nss)
1247{
1248 NS_ASSERT (guardInterval == 800 || guardInterval == 1600 || guardInterval == 3200);
1249 NS_ASSERT (nss <= 8);
1250 return HtPhy::CalculateDataRate (GetSymbolDuration (NanoSeconds (guardInterval)),
1251 GetUsableSubcarriers (channelWidth),
1252 static_cast<uint16_t> (log2 (GetConstellationSize (mcsValue))),
1253 HtPhy::GetCodeRatio (GetCodeRate (mcsValue)), nss);
1254}
1255
1256uint16_t
1257HePhy::GetUsableSubcarriers (uint16_t channelWidth)
1258{
1259 switch (channelWidth)
1260 {
1261 case 2: //26-tone RU
1262 return 24;
1263 case 4: //52-tone RU
1264 return 48;
1265 case 8: //106-tone RU
1266 return 102;
1267 case 20:
1268 default:
1269 return 234;
1270 case 40:
1271 return 468;
1272 case 80:
1273 return 980;
1274 case 160:
1275 return 1960;
1276 }
1277}
1278
1279Time
1281{
1282 return NanoSeconds (12800) + guardInterval;
1283}
1284
1285uint64_t
1287{
1288 WifiCodeRate codeRate = GetCodeRate (mcsValue);
1289 uint16_t constellationSize = GetConstellationSize (mcsValue);
1290 return CalculateNonHtReferenceRate (codeRate, constellationSize);
1291}
1292
1293uint64_t
1294HePhy::CalculateNonHtReferenceRate (WifiCodeRate codeRate, uint16_t constellationSize)
1295{
1296 uint64_t dataRate;
1297 switch (constellationSize)
1298 {
1299 case 1024:
1300 if (codeRate == WIFI_CODE_RATE_3_4 || codeRate == WIFI_CODE_RATE_5_6)
1301 {
1302 dataRate = 54000000;
1303 }
1304 else
1305 {
1306 NS_FATAL_ERROR ("Trying to get reference rate for a MCS with wrong combination of coding rate and modulation");
1307 }
1308 break;
1309 default:
1310 dataRate = VhtPhy::CalculateNonHtReferenceRate (codeRate, constellationSize);
1311 }
1312 return dataRate;
1313}
1314
1315bool
1316HePhy::IsAllowed (const WifiTxVector& /*txVector*/)
1317{
1318 return true;
1319}
1320
1323{
1324 uint16_t staId = SU_STA_ID;
1325
1326 if (IsUlMu (txVector.GetPreambleType ()))
1327 {
1328 NS_ASSERT (txVector.GetHeMuUserInfoMap ().size () == 1);
1329 staId = txVector.GetHeMuUserInfoMap ().begin ()->first;
1330 }
1331
1332 return WifiConstPsduMap ({std::make_pair (staId, psdu)});
1333}
1334
1337{
1338 return 6500631;
1339}
1340
1341} //namespace ns3
1342
1343namespace {
1344
1348static class ConstructorHe
1349{
1350public:
1352 {
1354 ns3::WifiPhy::AddStaticPhyEntity (ns3::WIFI_MOD_CLASS_HE, ns3::Create<ns3::HePhy> ());
1355 }
1357
1358}
#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:1349
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:168
Time GetLSigDuration(WifiPreamble preamble) const override
Definition: he-phy.cc:174
static Time ConvertLSigLengthToHeTbPpduDuration(uint16_t length, const WifiTxVector &txVector, WifiPhyBand band)
Definition: he-phy.cc:288
void StartReceiveOfdmaPayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: he-phy.cc:839
WifiMode GetSigAMode(void) const override
Definition: he-phy.cc:129
Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW) override
Get the event corresponding to the incoming PPDU.
Definition: he-phy.cc:437
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:925
void DoAbortCurrentReception(WifiPhyRxfailureReason reason) override
Perform amendment-specific actions before aborting the current reception.
Definition: he-phy.cc:404
uint64_t m_currentHeTbPpduUid
UID of the HE TB PPDU being received.
Definition: he-phy.h:458
Time CalculateTxDuration(WifiConstPsduMap psduMap, const WifiTxVector &txVector, WifiPhyBand band) const override
Definition: he-phy.cc:1079
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:877
uint8_t GetBssColor(void) const
Definition: he-phy.cc:517
virtual PhyFieldRxStatus ProcessSigB(Ptr< Event > event, PhyFieldRxStatus status)
Process SIG-B, perform amendment-specific actions, and provide an updated status of the reception.
Definition: he-phy.cc:660
Time GetSigBDuration(const WifiTxVector &txVector) const override
Definition: he-phy.cc:206
static WifiMode CreateHeMcs(uint8_t index)
Create and return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1167
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1117
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:1322
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:945
void BuildModeList(void) override
Build mode list.
Definition: he-phy.cc:94
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:1294
std::map< uint16_t, EventId > m_beginOfdmaPayloadRxEvents
the beginning of the OFDMA payload reception events (indexed by STA-ID)
Definition: he-phy.h:460
void SetEndOfHeSigACallback(EndOfHeSigACallback callback)
Set a callback for a end of HE-SIG-A.
Definition: he-phy.cc:645
Time m_trigVectorExpirationTime
expiration time of the TRIGVECTOR
Definition: he-phy.h:464
uint64_t GetCurrentHeTbPpduUid(void) const
Definition: he-phy.cc:957
uint64_t m_previouslyTxPpduUid
UID of the previously sent PPDU, used by AP to recognize response HE TB PPDUs.
Definition: he-phy.h:457
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1183
void StartTx(Ptr< const WifiPpdu > ppdu) override
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
Definition: he-phy.cc:1056
PhyFieldRxStatus ProcessSig(Ptr< Event > event, PhyFieldRxStatus status, WifiPpduField field) override
Process SIG-A or SIG-B, perform amendment-specific actions, and provide an updated status of the rece...
Definition: he-phy.cc:550
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:908
EndOfHeSigACallback m_endOfHeSigACallback
end of HE-SIG-A callback
Definition: he-phy.h:462
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:505
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:107
uint64_t ObtainNextUid(const WifiTxVector &txVector) override
Obtain the next UID for the PPDU to transmit.
Definition: he-phy.cc:981
uint32_t GetMaxPsduSize(void) const override
Get the maximum PSDU size in bytes.
Definition: he-phy.cc:1336
WifiTxVector m_trigVector
the TRIGVECTOR
Definition: he-phy.h:463
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:1218
void CancelAllEvents(void) override
Cancel and clear all running events.
Definition: he-phy.cc:392
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:1034
static void InitializeModes(void)
Initialize all HE modes.
Definition: he-phy.cc:1108
Time CalculateNonOfdmaDurationForHeTb(const WifiTxVector &txVector) const
Definition: he-phy.cc:299
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:264
uint8_t GetNumberBccEncoders(const WifiTxVector &txVector) const override
Definition: he-phy.cc:309
static bool IsAllowed(const WifiTxVector &txVector)
Check whether the combination in TXVECTOR is allowed.
Definition: he-phy.cc:1316
std::size_t m_rxHeTbPpdus
Number of successfully received HE TB PPDUS.
Definition: he-phy.h:496
Ptr< WifiPpdu > BuildPpdu(const WifiConstPsduMap &psdus, const WifiTxVector &txVector, Time ppduDuration) override
Build amendment-specific PPDU.
Definition: he-phy.cc:331
void NotifyEndOfHeSigA(HeSigAParameters params)
Fire a EndOfHeSigA callback (if connected) once HE-SIG-A field has been received.
Definition: he-phy.cc:651
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:1246
void RxPayloadSucceeded(Ptr< const WifiPsdu > psdu, RxSignalInfo rxSignalInfo, const WifiTxVector &txVector, uint16_t staId, const std::vector< bool > &statusPerMpdu) override
Perform amendment-specific actions when the payload is successfully received.
Definition: he-phy.cc:770
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:1210
virtual ~HePhy()
Destructor for HE PHY.
Definition: he-phy.cc:88
static const PpduFormats m_hePpduFormats
HE PPDU formats.
Definition: he-phy.h:494
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:1232
void RxPayloadFailed(Ptr< const WifiPsdu > psdu, double snr, const WifiTxVector &txVector) override
Perform amendment-specific actions when the payload is unsuccessfully received.
Definition: he-phy.cc:787
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:677
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:532
static Time GetSymbolDuration(Time guardInterval)
Definition: he-phy.cc:1280
void SetTrigVector(const WifiTxVector &trigVector, Time validity)
Set the TRIGVECTOR and the associated expiration time.
Definition: he-phy.cc:323
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:275
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:1286
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:891
WifiMode GetSigBMode(const WifiTxVector &txVector) const override
Definition: he-phy.cc:135
Time DoStartReceivePayload(Ptr< Event > event) override
Start receiving the PSDU (i.e.
Definition: he-phy.cc:710
void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration) override
Start receiving the PHY preamble of a PPDU (i.e.
Definition: he-phy.cc:352
virtual PhyFieldRxStatus ProcessSigA(Ptr< Event > event, PhyFieldRxStatus status)
Process SIG-A, perform amendment-specific actions, and provide an updated status of the reception.
Definition: he-phy.cc:567
void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu) override
Perform amendment-specific actions at the end of the reception of the payload.
Definition: he-phy.cc:798
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:422
Time GetSigADuration(WifiPreamble preamble) const override
Definition: he-phy.cc:200
Time GetTrainingDuration(const WifiTxVector &txVector, uint8_t nDataLtf, uint8_t nExtensionLtf=0) const override
Definition: he-phy.cc:180
Ptr< SpectrumValue > GetTxPowerSpectralDensity(double txPowerW, Ptr< const WifiPpdu > ppdu) const override
Definition: he-phy.cc:1001
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Definition: he-phy.cc:963
static uint16_t GetConstellationSize(uint8_t mcsValue)
Return the constellation size corresponding to the supplied HE MCS index.
Definition: he-phy.cc:1197
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:629
uint8_t m_bssMembershipSelector
the BSS membership selector
Definition: ht-phy.h:540
uint8_t m_maxMcsIndexPerSs
the maximum MCS index per spatial stream as defined by the standard
Definition: ht-phy.h:538
static uint64_t CalculateDataRate(Time symbolDuration, uint16_t usableSubCarriers, uint16_t numberOfBitsPerSubcarrier, double codingRate, uint8_t nss)
Calculates data rate from the supplied parameters.
Definition: ht-phy.cc:676
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:644
uint8_t m_maxSupportedMcsIndexPerSs
the maximum supported MCS index per spatial stream
Definition: ht-phy.h:539
static uint16_t GetUsableSubcarriers(void)
Definition: ofdm-phy.cc:586
uint16_t GetMeasurementChannelWidth(const Ptr< const WifiPpdu > ppdu) const override
Return the channel width used to measure the RSSI.
Definition: ofdm-phy.cc:620
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:1121
void Transmit(Time txDuration, Ptr< const WifiPpdu > ppdu, std::string type)
This function prepares most of the WifiSpectrumSignalParameters parameters and invokes SpectrumWifiPh...
Definition: phy-entity.cc:1134
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:744
Ptr< WifiPhyStateHelper > m_state
Pointer to WifiPhyStateHelper of the WifiPhy (to make it reachable for child classes)
Definition: phy-entity.h:875
virtual void CancelAllEvents(void)
Cancel and clear all running events.
Definition: phy-entity.cc:932
virtual Time DoStartReceivePayload(Ptr< Event > event)
Start receiving the PSDU (i.e.
Definition: phy-entity.cc:539
virtual void StartReceivePreamble(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW, Time rxDuration)
Start receiving the PHY preamble of a PPDU (i.e.
Definition: phy-entity.cc:365
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:770
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:890
Ptr< WifiPhy > m_wifiPhy
Pointer to the owning WifiPhy.
Definition: phy-entity.h:874
std::vector< EventId > m_endOfMpduEvents
the end of MPDU events (only used for A-MPDUs)
Definition: phy-entity.h:880
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:737
std::tuple< double, double, double > GetTxMaskRejectionParams(void) const
Definition: phy-entity.cc:1159
virtual void DoAbortCurrentReception(WifiPhyRxfailureReason reason)
Perform amendment-specific actions before aborting the current reception.
Definition: phy-entity.cc:984
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:480
static uint64_t m_globalPpduUid
Global counter of the PPDU UID.
Definition: phy-entity.h:892
std::vector< EventId > m_endRxPayloadEvents
the end of receive events (only one unless UL MU reception)
Definition: phy-entity.h:882
virtual Ptr< Event > DoGetEvent(Ptr< const WifiPpdu > ppdu, RxPowerWattPerChannelBand &rxPowersW)
Get the event corresponding to the incoming PPDU.
Definition: phy-entity.cc:758
double GetRxPowerWForPpdu(Ptr< Event > event) const
Obtain the received power (W) for a given band.
Definition: phy-entity.cc:1025
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:782
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:889
virtual void StartTx(Ptr< const WifiPpdu > ppdu)
This function is called by SpectrumWifiPhy to send the PPDU while performing amendment-specific actio...
Definition: phy-entity.cc:1127
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:523
uint16_t GetGuardBandwidth(uint16_t currentChannelWidth) const
Definition: phy-entity.cc:1153
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:998
std::list< WifiMode > m_modeList
the list of supported modes
Definition: phy-entity.h:877
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:502
Ptr< const Event > GetCurrentEvent(void) const
Get the pointer to the current event (stored in WifiPhy).
Definition: phy-entity.cc:1031
void AddPreambleEvent(Ptr< Event > event)
Add an entry to the map of current preamble events (stored in WifiPhy).
Definition: phy-entity.cc:750
virtual void DoEndReceivePayload(Ptr< const WifiPpdu > ppdu)
Perform amendment-specific actions at the end of the reception of the payload.
Definition: phy-entity.cc:691
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:1113
@ DROP
drop PPDU and set CCA_BUSY
Definition: phy-entity.h:104
void UpdateInterferenceEvent(Ptr< Event > event, const RxPowerWattPerChannelBand &rxPower)
Update an event in WifiPhy's InterferenceHelper class.
Definition: phy-entity.cc:776
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:555
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
int64_t GetFemtoSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:400
bool IsStrictlyPositive(void) const
Exactly equivalent to t > 0.
Definition: nstime.h:333
@ US
microsecond
Definition: nstime.h:117
@ NS
nanosecond
Definition: nstime.h:118
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:392
PHY entity for VHT (11ac)
Definition: vht-phy.h:49
static WifiMode GetVhtMcs4(void)
Return MCS 4 from VHT MCS values.
static WifiCodeRate GetCodeRate(uint8_t mcsValue)
Return the coding rate corresponding to the supplied VHT MCS index.
Definition: vht-phy.cc:396
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:168
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:483
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:410
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:132
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:945
WifiPhyBand GetPhyBand(void) const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:932
Ptr< WifiNetDevice > GetDevice(void) const
Return the device this PHY is associated with.
Definition: wifi-phy.cc:569
void NotifyRxDrop(Ptr< const WifiPsdu > psdu, WifiPhyRxfailureReason reason)
Public method used to fire a PhyRxDrop trace.
Definition: wifi-phy.cc:1461
uint8_t GetMaxSupportedRxSpatialStreams(void) const
Definition: wifi-phy.cc:1200
static Time CalculateTxDuration(uint32_t size, const WifiTxVector &txVector, WifiPhyBand band, uint16_t staId=SU_STA_ID)
Definition: wifi-phy.cc:1368
virtual WifiSpectrumBand ConvertHeRuSubcarriers(uint16_t bandWidth, uint16_t guardBandwidth, HeRu::SubcarrierRange range, uint8_t bandIndex=0) const
Definition: wifi-phy.cc:1683
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:686
uint64_t GetPreviouslyRxPpduUid(void) const
Definition: wifi-phy.cc:1646
Time GetLastRxEndTime(void) const
Return the end time of the last received packet.
Definition: wifi-phy.cc:1893
uint16_t GetChannelWidth(void) const
Definition: wifi-phy.cc:963
static Time CalculatePhyPreambleAndHeaderDuration(const WifiTxVector &txVector)
Definition: wifi-phy.cc:1362
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...
uint16_t GetPrimaryChannelCenterFrequency(uint16_t primaryChannelWidth) const
Get the center frequency of the primary channel of the given width.
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
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:230
int64x64_t Min(const int64x64_t &a, const int64x64_t &b)
Minimum.
Definition: int64x64.h:218
#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:1261
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
Time FemtoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1285
WifiPhyRxfailureReason
Enumeration of the possible reception failure reasons.
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiPpduField
The type of PPDU field (grouped for convenience)
@ OBSS_PD_CCA_RESET
@ HE_TB_PPDU_TOO_LATE
@ WIFI_PREAMBLE_HE_ER_SU
@ WIFI_PREAMBLE_HE_TB
@ WIFI_PREAMBLE_HE_MU
@ WIFI_PREAMBLE_HE_SU
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PPDU_TYPE_DL_MU
@ WIFI_PPDU_TYPE_UL_MU
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_PPDU_FIELD_SIG_B
SIG-B field.
@ WIFI_PPDU_FIELD_TRAINING
STF + LTF fields (excluding those in preamble for HT-GF)
@ WIFI_PPDU_FIELD_NON_HT_HEADER
PHY header field for DSSS or ERP, short PHY header field for HR/DSSS or ERP, field not present for HT...
@ WIFI_PPDU_FIELD_PREAMBLE
SYNC + SFD fields for DSSS or ERP, shortSYNC + shortSFD fields for HR/DSSS or ERP,...
@ WIFI_PPDU_FIELD_DATA
data field
@ WIFI_PPDU_FIELD_SIG_A
SIG-A field.
#define GET_HE_MCS(x)
Definition: he-phy.cc:1144
#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:77
uint16_t WifiCodeRate
These constants define the various convolutional coding rates used for the OFDM transmission modes in...
Ptr< T > Copy(Ptr< T > object)
Return a deep copy of a Ptr.
Definition: ptr.h:555
const uint16_t WIFI_CODE_RATE_5_6
5/6 coding rate
@ LOG_FUNCTION
Function tracing.
Definition: log.h:109
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
bool IsUlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a uplink multi-user transmission.
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:87
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:113
bool isSuccess
outcome (true if success) of the reception
Definition: phy-entity.h:115
RxSignalInfo structure containing info on the received signal.
Definition: phy-entity.h:69
SignalNoiseDbm structure.
Definition: phy-entity.h:55
#define SU_STA_ID
Definition: wifi-mode.h:32