A Discrete-Event Network Simulator
API
wifi-tx-vector.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010 CTTC
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Nicola Baldo <nbaldo@cttc.es>
18  * Ghada Badawy <gbadawy@gmail.com>
19  */
20 
21 #include "wifi-tx-vector.h"
22 
23 #include "wifi-phy-common.h"
24 
25 #include "ns3/abort.h"
26 #include "ns3/eht-phy.h"
27 
28 #include <algorithm>
29 #include <iterator>
30 #include <numeric>
31 #include <set>
32 
33 namespace ns3
34 {
35 
37  : m_txPowerLevel(1),
38  m_preamble(WIFI_PREAMBLE_LONG),
39  m_channelWidth(20),
40  m_guardInterval(800),
41  m_nTx(1),
42  m_nss(1),
43  m_ness(0),
44  m_aggregation(false),
45  m_stbc(false),
46  m_ldpc(false),
47  m_bssColor(0),
48  m_length(0),
49  m_triggerResponding(false),
50  m_modeInitialized(false),
51  m_inactiveSubchannels(),
52  m_ruAllocation(),
53  m_center26ToneRuIndication(std::nullopt),
54  m_ehtPpduType(1) // SU transmission by default
55 {
56 }
57 
59  uint8_t powerLevel,
60  WifiPreamble preamble,
61  uint16_t guardInterval,
62  uint8_t nTx,
63  uint8_t nss,
64  uint8_t ness,
65  uint16_t channelWidth,
66  bool aggregation,
67  bool stbc,
68  bool ldpc,
69  uint8_t bssColor,
70  uint16_t length,
71  bool triggerResponding)
72  : m_mode(mode),
73  m_txPowerLevel(powerLevel),
74  m_preamble(preamble),
75  m_channelWidth(channelWidth),
76  m_guardInterval(guardInterval),
77  m_nTx(nTx),
78  m_nss(nss),
79  m_ness(ness),
80  m_aggregation(aggregation),
81  m_stbc(stbc),
82  m_ldpc(ldpc),
83  m_bssColor(bssColor),
84  m_length(length),
85  m_triggerResponding(triggerResponding),
86  m_modeInitialized(true),
87  m_inactiveSubchannels(),
88  m_ruAllocation(),
89  m_center26ToneRuIndication(std::nullopt),
90  m_ehtPpduType(1) // SU transmission by default
91 {
92 }
93 
95  : m_mode(txVector.m_mode),
96  m_txPowerLevel(txVector.m_txPowerLevel),
97  m_preamble(txVector.m_preamble),
98  m_channelWidth(txVector.m_channelWidth),
99  m_guardInterval(txVector.m_guardInterval),
100  m_nTx(txVector.m_nTx),
101  m_nss(txVector.m_nss),
102  m_ness(txVector.m_ness),
103  m_aggregation(txVector.m_aggregation),
104  m_stbc(txVector.m_stbc),
105  m_ldpc(txVector.m_ldpc),
106  m_bssColor(txVector.m_bssColor),
107  m_length(txVector.m_length),
108  m_triggerResponding(txVector.m_triggerResponding),
109  m_modeInitialized(txVector.m_modeInitialized),
110  m_inactiveSubchannels(txVector.m_inactiveSubchannels),
111  m_sigBMcs(txVector.m_sigBMcs),
112  m_ruAllocation(txVector.m_ruAllocation),
113  m_center26ToneRuIndication(txVector.m_center26ToneRuIndication),
114  m_ehtPpduType(txVector.m_ehtPpduType)
115 {
116  m_muUserInfos.clear();
117  if (!txVector.m_muUserInfos.empty()) // avoids crashing for loop
118  {
119  for (auto& info : txVector.m_muUserInfos)
120  {
121  m_muUserInfos.insert(std::make_pair(info.first, info.second));
122  }
123  }
124 }
125 
126 bool
128 {
129  return m_modeInitialized;
130 }
131 
132 WifiMode
133 WifiTxVector::GetMode(uint16_t staId) const
134 {
135  if (!m_modeInitialized)
136  {
137  NS_FATAL_ERROR("WifiTxVector mode must be set before using");
138  }
139  if (!IsMu())
140  {
141  return m_mode;
142  }
143  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
144  const auto userInfoIt = m_muUserInfos.find(staId);
145  NS_ASSERT(userInfoIt != m_muUserInfos.cend());
147  {
148  case WIFI_MOD_CLASS_EHT:
149  return EhtPhy::GetEhtMcs(userInfoIt->second.mcs);
150  case WIFI_MOD_CLASS_HE:
151  return HePhy::GetHeMcs(userInfoIt->second.mcs);
152  default:
153  NS_ABORT_MSG("Unsupported modulation class: " << GetModulationClassForPreamble(m_preamble));
154  }
155  return WifiMode(); // invalid WifiMode
156 }
157 
160 {
161  NS_ABORT_MSG_IF(!m_modeInitialized, "WifiTxVector mode must be set before using");
162 
163  if (IsMu())
164  {
165  NS_ASSERT(!m_muUserInfos.empty());
166  // all the modes belong to the same modulation class
168  }
169  return m_mode.GetModulationClass();
170 }
171 
172 uint8_t
174 {
175  return m_txPowerLevel;
176 }
177 
180 {
181  return m_preamble;
182 }
183 
184 uint16_t
186 {
187  return m_channelWidth;
188 }
189 
190 uint16_t
192 {
193  return m_guardInterval;
194 }
195 
196 uint8_t
198 {
199  return m_nTx;
200 }
201 
202 uint8_t
203 WifiTxVector::GetNss(uint16_t staId) const
204 {
205  if (IsMu())
206  {
207  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU (" << staId << ")");
208  NS_ASSERT(m_muUserInfos.find(staId) != m_muUserInfos.end());
209  return m_muUserInfos.at(staId).nss;
210  }
211  return m_nss;
212 }
213 
214 uint8_t
216 {
217  // We do not support mixed OFDMA and MU-MIMO
218  uint8_t nss = 0;
219  if (IsMu())
220  {
221  for (const auto& info : m_muUserInfos)
222  {
223  nss = (nss < info.second.nss) ? info.second.nss : nss;
224  }
225  }
226  else
227  {
228  nss = m_nss;
229  }
230  return nss;
231 }
232 
233 uint8_t
235 {
236  // We do not support mixed OFDMA and MU-MIMO
237  uint8_t nss = 0;
238  if (IsMu())
239  {
240  nss = std::accumulate(
241  m_muUserInfos.cbegin(),
242  m_muUserInfos.cend(),
243  0,
244  [](uint8_t prevNss, const auto& info) { return prevNss + info.second.nss; });
245  }
246  else
247  {
248  nss = m_nss;
249  }
250  return nss;
251 }
252 
253 uint8_t
255 {
256  return m_ness;
257 }
258 
259 bool
261 {
262  return m_aggregation;
263 }
264 
265 bool
267 {
268  return m_stbc;
269 }
270 
271 bool
273 {
274  return m_ldpc;
275 }
276 
277 bool
279 {
280  return ((m_channelWidth >= 40) && !IsMu() && (GetModulationClass() < WIFI_MOD_CLASS_HT));
281 }
282 
283 void
285 {
286  m_mode = mode;
287  m_modeInitialized = true;
288 }
289 
290 void
291 WifiTxVector::SetMode(WifiMode mode, uint16_t staId)
292 {
293  NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
294  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
295  m_muUserInfos[staId].mcs = mode.GetMcsValue();
296  m_modeInitialized = true;
297 }
298 
299 void
300 WifiTxVector::SetTxPowerLevel(uint8_t powerlevel)
301 {
302  m_txPowerLevel = powerlevel;
303 }
304 
305 void
307 {
308  m_preamble = preamble;
309 }
310 
311 void
312 WifiTxVector::SetChannelWidth(uint16_t channelWidth)
313 {
314  m_channelWidth = channelWidth;
315 }
316 
317 void
318 WifiTxVector::SetGuardInterval(uint16_t guardInterval)
319 {
320  m_guardInterval = guardInterval;
321 }
322 
323 void
325 {
326  m_nTx = nTx;
327 }
328 
329 void
331 {
332  m_nss = nss;
333 }
334 
335 void
336 WifiTxVector::SetNss(uint8_t nss, uint16_t staId)
337 {
338  NS_ABORT_MSG_IF(!IsMu(), "Not a MU transmission");
339  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
340  m_muUserInfos[staId].nss = nss;
341 }
342 
343 void
345 {
346  m_ness = ness;
347 }
348 
349 void
351 {
352  m_aggregation = aggregation;
353 }
354 
355 void
357 {
358  m_stbc = stbc;
359 }
360 
361 void
363 {
364  m_ldpc = ldpc;
365 }
366 
367 void
369 {
370  m_bssColor = color;
371 }
372 
373 uint8_t
375 {
376  return m_bssColor;
377 }
378 
379 void
380 WifiTxVector::SetLength(uint16_t length)
381 {
382  m_length = length;
383 }
384 
385 uint16_t
387 {
388  return m_length;
389 }
390 
391 bool
393 {
394  return m_triggerResponding;
395 }
396 
397 void
398 WifiTxVector::SetTriggerResponding(bool triggerResponding)
399 {
400  m_triggerResponding = triggerResponding;
401 }
402 
403 void
405 {
406  m_sigBMcs = mode;
407 }
408 
409 WifiMode
411 {
412  return m_sigBMcs;
413 }
414 
415 void
416 WifiTxVector::SetRuAllocation(const RuAllocation& ruAlloc, uint8_t p20Index)
417 {
418  if (ns3::IsDlMu(m_preamble) && !m_muUserInfos.empty())
419  {
420  NS_ASSERT(ruAlloc == DeriveRuAllocation(p20Index));
421  }
422  m_ruAllocation = ruAlloc;
423 }
424 
425 const RuAllocation&
426 WifiTxVector::GetRuAllocation(uint8_t p20Index) const
427 {
428  if (ns3::IsDlMu(m_preamble) && m_ruAllocation.empty())
429  {
431  }
432  return m_ruAllocation;
433 }
434 
435 void
437 {
440 }
441 
442 uint8_t
444 {
445  return m_ehtPpduType;
446 }
447 
448 bool
450 {
451  if (!GetModeInitialized())
452  {
453  return false;
454  }
455  std::string modeName = m_mode.GetUniqueName();
456  if (m_channelWidth == 20)
457  {
458  if (m_nss != 3 && m_nss != 6)
459  {
460  if (modeName == "VhtMcs9")
461  {
462  return false;
463  }
464  }
465  }
466  else if (m_channelWidth == 80)
467  {
468  if (m_nss == 3 || m_nss == 7)
469  {
470  if (modeName == "VhtMcs6")
471  {
472  return false;
473  }
474  }
475  else if (m_nss == 6)
476  {
477  if (modeName == "VhtMcs9")
478  {
479  return false;
480  }
481  }
482  }
483  else if (m_channelWidth == 160)
484  {
485  if (m_nss == 3)
486  {
487  if (modeName == "VhtMcs9")
488  {
489  return false;
490  }
491  }
492  }
493  for (const auto& userInfo : m_muUserInfos)
494  {
495  if (GetNumStasInRu(userInfo.second.ru) > 8)
496  {
497  return false;
498  }
499  }
500  std::map<HeRu::RuSpec, uint8_t> streamsPerRu{};
501  for (const auto& info : m_muUserInfos)
502  {
503  auto it = streamsPerRu.find(info.second.ru);
504  if (it == streamsPerRu.end())
505  {
506  streamsPerRu[info.second.ru] = info.second.nss;
507  }
508  else
509  {
510  it->second += info.second.nss;
511  }
512  }
513  for (auto& streams : streamsPerRu)
514  {
515  if (streams.second > 8)
516  {
517  return false;
518  }
519  }
520 
521  if (band != WIFI_PHY_BAND_UNSPECIFIED)
522  {
524  "Cannot use OFDM modulation class in the 2.4 GHz band");
526  band != WIFI_PHY_BAND_2_4GHZ,
527  "ERP-OFDM modulation class can only be used in the 2.4 GHz band");
528  }
529 
530  return true;
531 }
532 
533 bool
535 {
536  return IsDlMu() || IsUlMu();
537 }
538 
539 bool
541 {
542  return ns3::IsDlMu(m_preamble) && !(IsEht(m_preamble) && m_ehtPpduType == 1);
543 }
544 
545 bool
547 {
548  return ns3::IsUlMu(m_preamble);
549 }
550 
551 bool
553 {
554  if (!IsDlMu())
555  {
556  return false;
557  }
558  if (IsEht(m_preamble))
559  {
560  return m_ehtPpduType == 0;
561  }
562  if (m_muUserInfos.size() == 1)
563  {
564  return true;
565  }
566  std::set<HeRu::RuSpec> rus{};
567  for (const auto& userInfo : m_muUserInfos)
568  {
569  rus.insert(userInfo.second.ru);
570  if (rus.size() > 1)
571  {
572  return true;
573  }
574  }
575  return false;
576 }
577 
578 bool
580 {
581  if (!IsDlMu())
582  {
583  return false;
584  }
585  if (IsEht(m_preamble))
586  {
587  return m_ehtPpduType == 2;
588  }
589  if (m_muUserInfos.size() < 2)
590  {
591  return false;
592  }
593  // TODO: mixed OFDMA and MU-MIMO is not supported
594  return !IsDlOfdma();
595 }
596 
597 uint8_t
599 {
600  return std::count_if(m_muUserInfos.cbegin(),
601  m_muUserInfos.cend(),
602  [&ru](const auto& info) -> bool { return (ru == info.second.ru); });
603 }
604 
605 bool
606 WifiTxVector::IsAllocated(uint16_t staId) const
607 {
608  return m_muUserInfos.count(staId) > 0;
609 }
610 
612 WifiTxVector::GetRu(uint16_t staId) const
613 {
614  NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
615  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
616  return m_muUserInfos.at(staId).ru;
617 }
618 
619 void
621 {
622  NS_ABORT_MSG_IF(!IsMu(), "RU only available for MU");
623  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
624  m_muUserInfos[staId].ru = ru;
625 }
626 
628 WifiTxVector::GetHeMuUserInfo(uint16_t staId) const
629 {
630  NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
631  return m_muUserInfos.at(staId);
632 }
633 
634 void
636 {
637  NS_ABORT_MSG_IF(!IsMu(), "HE MU user info only available for MU");
638  NS_ABORT_MSG_IF(staId > 2048, "STA-ID should be correctly set for MU");
639  m_muUserInfos[staId] = userInfo;
640  m_modeInitialized = true;
641  m_ruAllocation.clear();
642 }
643 
646 {
647  NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
648  return m_muUserInfos;
649 }
650 
653 {
654  NS_ABORT_MSG_IF(!IsMu(), "HE MU user info map only available for MU");
655  m_ruAllocation.clear();
656  return m_muUserInfos;
657 }
658 
659 bool
661 {
662  return IsDlMuMimo() && !IsDlOfdma();
663 }
664 
665 void
666 WifiTxVector::SetInactiveSubchannels(const std::vector<bool>& inactiveSubchannels)
667 {
669  "Only HE (or later) authorized for preamble puncturing");
671  m_channelWidth < 80,
672  "Preamble puncturing only possible for transmission bandwidth of 80 MHz or larger");
673  NS_ABORT_MSG_IF(!inactiveSubchannels.empty() &&
674  inactiveSubchannels.size() != (m_channelWidth / 20),
675  "The size of the inactive subchannnels bitmap should be equal to the number of "
676  "20 MHz subchannels");
677  m_inactiveSubchannels = inactiveSubchannels;
678 }
679 
680 const std::vector<bool>&
682 {
683  return m_inactiveSubchannels;
684 }
685 
686 void
688 {
689  if (IsDlMu())
690  {
691  NS_ASSERT(center26ToneRuIndication == DeriveCenter26ToneRuIndication());
692  }
693  m_center26ToneRuIndication = center26ToneRuIndication;
694 }
695 
696 std::optional<Center26ToneRuIndication>
698 {
699  if (!IsDlMu() || (m_channelWidth < 80))
700  {
701  return std::nullopt;
702  }
703  if (!m_center26ToneRuIndication.has_value())
704  {
706  }
708 }
709 
710 std::ostream&
711 operator<<(std::ostream& os, const WifiTxVector& v)
712 {
713  if (!v.IsValid())
714  {
715  os << "TXVECTOR not valid";
716  return os;
717  }
718  os << "txpwrlvl: " << +v.GetTxPowerLevel() << " preamble: " << v.GetPreambleType()
719  << " channel width: " << v.GetChannelWidth() << " GI: " << v.GetGuardInterval()
720  << " NTx: " << +v.GetNTx() << " Ness: " << +v.GetNess()
721  << " MPDU aggregation: " << v.IsAggregation() << " STBC: " << v.IsStbc()
722  << " FEC coding: " << (v.IsLdpc() ? "LDPC" : "BCC");
724  {
725  os << " BSS color: " << +v.GetBssColor();
726  }
727  if (v.IsUlMu())
728  {
729  os << " Length: " << v.GetLength();
730  }
731  if (ns3::IsDlMu(v.GetPreambleType()))
732  {
733  os << " SIG-B mode: " << v.GetSigBMode();
734  }
735  if (v.IsMu())
736  {
738  os << " num User Infos: " << userInfoMap.size();
739  for (auto& ui : userInfoMap)
740  {
741  os << ", {STA-ID: " << ui.first << ", " << ui.second.ru << ", MCS: " << +ui.second.mcs
742  << ", Nss: " << +ui.second.nss << "}";
743  }
744  }
745  else
746  {
747  os << " mode: " << v.GetMode() << " Nss: " << +v.GetNss();
748  }
749  const auto& puncturedSubchannels = v.GetInactiveSubchannels();
750  if (!puncturedSubchannels.empty())
751  {
752  os << " Punctured subchannels: ";
753  std::copy(puncturedSubchannels.cbegin(),
754  puncturedSubchannels.cend(),
755  std::ostream_iterator<bool>(os, ", "));
756  }
757  if (IsEht(v.GetPreambleType()))
758  {
759  os << " EHT PPDU type: " << +v.GetEhtPpduType();
760  }
761  return os;
762 }
763 
764 bool
766 {
767  return ru == other.ru && mcs == other.mcs && nss == other.nss;
768 }
769 
770 bool
772 {
773  return !(*this == other);
774 }
775 
778 {
779  auto heRuComparator = HeRu::RuSpecCompare(m_channelWidth, p20Index);
780  UserInfoMapOrderedByRus orderedMap{heRuComparator};
781  for (const auto& userInfo : m_muUserInfos)
782  {
783  const auto ru = userInfo.second.ru;
784  if (auto it = orderedMap.find(ru); it != orderedMap.end())
785  {
786  it->second.emplace(userInfo.first);
787  }
788  else
789  {
790  orderedMap.emplace(userInfo.second.ru, std::set<uint16_t>{userInfo.first});
791  }
792  }
793  return orderedMap;
794 }
795 
797 WifiTxVector::DeriveRuAllocation(uint8_t p20Index) const
798 {
800  std::vector<HeRu::RuType> ruTypes{};
801  ruTypes.resize(ruAllocations.size());
802  const auto& orderedMap = GetUserInfoMapOrderedByRus(p20Index);
803  for (const auto& [ru, staIds] : orderedMap)
804  {
805  const auto ruType = ru.GetRuType();
806  const auto ruBw = HeRu::GetBandwidth(ruType);
807  const auto isPrimary80MHz = ru.GetPrimary80MHz();
808  const auto rusPerSubchannel = HeRu::GetRusOfType(ruBw > 20 ? ruBw : 20, ruType);
809  auto ruIndex = ru.GetIndex();
810  if ((m_channelWidth >= 80) && (ruIndex > 19))
811  {
812  // take into account the center 26-tone RU in the primary 80 MHz
813  ruIndex--;
814  }
815  if ((!isPrimary80MHz) && (ruIndex > 19))
816  {
817  // take into account the center 26-tone RU in the secondary 80 MHz
818  ruIndex--;
819  }
820  if (!isPrimary80MHz && (ruType != HeRu::RU_2x996_TONE))
821  {
823  // adjust RU index for the secondary 80 MHz: in that case index is restarting at 1,
824  // hence we need to add an offset corresponding to the number of RUs of the same type in
825  // the primary 80 MHz
826  ruIndex += HeRu::GetRusOfType(80, ruType).size();
827  }
828  const auto index =
829  (ruBw < 20) ? ((ruIndex - 1) / rusPerSubchannel.size()) : ((ruIndex - 1) * (ruBw / 20));
830  const auto numSubchannelsForRu = (ruBw < 20) ? 1 : (ruBw / 20);
831  NS_ABORT_IF(index >= (m_channelWidth / 20));
832  auto ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, false);
833  if (ruAllocations.at(index) != HeRu::EMPTY_242_TONE_RU)
834  {
835  if (ruType == ruTypes.at(index))
836  {
837  continue;
838  }
839  if (ruType == HeRu::RU_26_TONE)
840  {
841  ruAlloc = HeRu::GetEqualizedRuAllocation(ruTypes.at(index), true);
842  }
843  else if (ruTypes.at(index) == HeRu::RU_26_TONE)
844  {
845  ruAlloc = HeRu::GetEqualizedRuAllocation(ruType, true);
846  }
847  else
848  {
849  NS_ASSERT_MSG(false, "unsupported RU combination");
850  }
851  }
852  for (auto i = 0; i < numSubchannelsForRu; ++i)
853  {
854  ruTypes.at(index + i) = ruType;
855  ruAllocations.at(index + i) = ruAlloc;
856  }
857  }
858  return ruAllocations;
859 }
860 
863 {
864  uint8_t center26ToneRuIndication{0};
865  for (const auto& userInfo : m_muUserInfos)
866  {
867  if ((userInfo.second.ru.GetRuType() == HeRu::RU_26_TONE) &&
868  (userInfo.second.ru.GetIndex() == 19))
869  {
870  center26ToneRuIndication |= (userInfo.second.ru.GetPrimary80MHz())
873  }
874  }
875  return static_cast<Center26ToneRuIndication>(center26ToneRuIndication);
876 }
877 
878 } // namespace ns3
static WifiMode GetEhtMcs(uint8_t index)
Return the EHT MCS corresponding to the provided index.
Definition: eht-phy.cc:240
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:1548
RU Specification.
Definition: he-ru.h:66
static uint16_t GetBandwidth(RuType ruType)
Get the approximate bandwidth occupied by a RU.
Definition: he-ru.cc:763
static constexpr uint8_t EMPTY_242_TONE_RU
Empty 242-tone RU identifier.
Definition: he-ru.h:311
static std::vector< HeRu::RuSpec > GetRusOfType(uint16_t bw, HeRu::RuType ruType)
Get the set of distinct RUs of the given type (number of tones) available in a HE PPDU of the given b...
Definition: he-ru.cc:511
static uint8_t GetEqualizedRuAllocation(RuType ruType, bool isOdd)
Get the RU_ALLOCATION value for equal size RUs.
Definition: he-ru.cc:421
@ RU_26_TONE
Definition: he-ru.h:42
@ RU_2x996_TONE
Definition: he-ru.h:48
represent a single transmission mode
Definition: wifi-mode.h:51
std::string GetUniqueName() const
Definition: wifi-mode.cc:148
WifiModulationClass GetModulationClass() const
Definition: wifi-mode.cc:185
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
uint16_t m_channelWidth
channel width in MHz
void SetCenter26ToneRuIndication(Center26ToneRuIndication center26ToneRuIndication)
Set CENTER_26_TONE_RU field.
void SetRuAllocation(const RuAllocation &ruAlloc, uint8_t p20Index)
Set RU_ALLOCATION field.
void SetStbc(bool stbc)
Sets if STBC is being used.
void SetNess(uint8_t ness)
Sets the Ness number.
UserInfoMapOrderedByRus GetUserInfoMapOrderedByRus(uint8_t p20Index) const
Get the map of specific user info parameters ordered per increasing frequency RUs.
bool IsTriggerResponding() const
Return true if the Trigger Responding parameter is set to true, false otherwise.
bool m_aggregation
Flag whether the PSDU contains A-MPDU.
void SetEhtPpduType(uint8_t type)
Set the EHT_PPDU_TYPE parameter.
uint8_t GetNumStasInRu(const HeRu::RuSpec &ru) const
Get the number of STAs in a given RU.
uint16_t GetGuardInterval() const
bool IsSigBCompression() const
Indicate whether the Common field is present in the HE-SIG-B field.
void SetTxPowerLevel(uint8_t powerlevel)
Sets the selected transmission power level.
void SetLdpc(bool ldpc)
Sets if LDPC FEC coding is being used.
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
uint8_t GetBssColor() const
Get the BSS color.
bool GetModeInitialized() const
const RuAllocation & GetRuAllocation(uint8_t p20Index) const
Get RU_ALLOCATION field.
std::optional< Center26ToneRuIndication > m_center26ToneRuIndication
CENTER_26_TONE_RU field when format is HE_MU and when channel width is set to 80 MHz or larger (Table...
std::vector< bool > m_inactiveSubchannels
Bitmap of inactive subchannels used for preamble puncturing.
WifiMode m_mode
The DATARATE parameter in Table 15-4.
std::map< uint16_t, HeMuUserInfo > HeMuUserInfoMap
map of HE MU specific user info parameters indexed by STA-ID
uint8_t GetNTx() const
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
bool IsValid(WifiPhyBand band=WIFI_PHY_BAND_UNSPECIFIED) const
The standard disallows certain combinations of WifiMode, number of spatial streams,...
std::optional< Center26ToneRuIndication > GetCenter26ToneRuIndication() const
Get CENTER_26_TONE_RU field This field is present if format is HE_MU and when channel width is set to...
void SetTriggerResponding(bool triggerResponding)
Set the Trigger Responding parameter to the given value.
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.
RuAllocation m_ruAllocation
RU allocations that are going to be carried in SIG-B common field per Table 27-1 IEEE.
void SetInactiveSubchannels(const std::vector< bool > &inactiveSubchannels)
Set the 20 MHz subchannels that are punctured.
bool IsStbc() const
Check if STBC is used or not.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
WifiPreamble GetPreambleType() const
HeMuUserInfo GetHeMuUserInfo(uint16_t staId) const
Get the HE MU user-specific transmission information for the given STA-ID.
uint8_t m_nTx
number of TX antennas
bool m_triggerResponding
The Trigger Responding parameter.
void SetAggregation(bool aggregation)
Sets if PSDU contains A-MPDU.
HeRu::RuSpec GetRu(uint16_t staId) const
Get the RU specification for the STA-ID.
HeMuUserInfoMap m_muUserInfos
HE MU specific per-user information indexed by station ID (STA-ID) corresponding to the 11 LSBs of th...
uint8_t m_txPowerLevel
The TXPWR_LEVEL parameter in Table 15-4.
bool m_ldpc
LDPC FEC coding if true, BCC otherwise.
uint16_t GetLength() const
Get the LENGTH field of the L-SIG.
uint16_t m_guardInterval
guard interval duration in nanoseconds
bool IsDlMu() const
bool m_stbc
STBC used or not.
uint8_t m_nss
number of spatial streams
uint8_t GetNssTotal() const
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
void SetRu(HeRu::RuSpec ru, uint16_t staId)
Set the RU specification for the STA-ID.
uint8_t GetEhtPpduType() const
Get the EHT_PPDU_TYPE parameter.
bool IsDlOfdma() const
Return true if this TX vector is used for a downlink multi-user transmission using OFDMA.
WifiModulationClass GetModulationClass() const
Get the modulation class specified by this TXVECTOR.
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.
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
uint8_t GetNssMax() const
bool IsUlMu() const
void SetSigBMode(const WifiMode &mode)
Set the MCS used for SIG-B.
uint16_t m_length
LENGTH field of the L-SIG.
uint8_t m_bssColor
BSS color.
WifiMode m_sigBMcs
MCS_SIG_B per Table 27-1 IEEE 802.11ax-2021.
void SetBssColor(uint8_t color)
Set the BSS color.
bool IsLdpc() const
Check if LDPC FEC coding is used or not.
void SetNTx(uint8_t nTx)
Sets the number of TX antennas.
uint8_t GetTxPowerLevel() const
std::map< HeRu::RuSpec, std::set< uint16_t >, HeRu::RuSpecCompare > UserInfoMapOrderedByRus
map of specific user info parameters ordered per increasing frequency RUs
bool IsAggregation() const
Checks whether the PSDU contains A-MPDU.
uint8_t m_ehtPpduType
EHT_PPDU_TYPE per Table 36-1 IEEE 802.11be D2.3.
bool IsAllocated(uint16_t staId) const
Check if STA ID is allocated.
uint16_t GetChannelWidth() const
WifiPreamble m_preamble
preamble
Center26ToneRuIndication DeriveCenter26ToneRuIndication() const
Derive the CENTER_26_TONE_RU field from the TXVECTOR for which its CENTER_26_TONE_RU has not been set...
RuAllocation DeriveRuAllocation(uint8_t p20Index) const
Derive the RU_ALLOCATION field from the TXVECTOR for which its RU_ALLOCATION field has not been set y...
bool m_modeInitialized
Internal initialization flag.
bool IsDlMuMimo() const
Return true if this TX vector is used for a downlink multi-user transmission using MU-MIMO.
uint8_t GetNess() const
uint8_t m_ness
number of spatial streams in beamforming
bool IsNonHtDuplicate() const
Checks whether this TXVECTOR corresponds to a non-HT duplicate.
void SetMode(WifiMode mode)
Sets the selected payload transmission mode.
WifiMode GetSigBMode() const
Get MCS used for SIG-B.
void SetNss(uint8_t nss)
Sets the number of Nss.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
const std::vector< bool > & GetInactiveSubchannels() const
Get the 20 MHz subchannels that are punctured.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#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:76
WifiPreamble
The type of preamble to be used by an IEEE 802.11 transmission.
Center26ToneRuIndication
Enum for the different values for CENTER_26_TONE_RU.
WifiPhyBand
Identifies the PHY band.
Definition: wifi-phy-band.h:33
WifiModulationClass
This enumeration defines the modulation classes per (Table 10-6 "Modulation classes"; IEEE 802....
@ WIFI_PREAMBLE_LONG
@ WIFI_PREAMBLE_HE_SU
@ CENTER_26_TONE_RU_HIGH_80_MHZ_ALLOCATED
@ CENTER_26_TONE_RU_LOW_80_MHZ_ALLOCATED
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
Definition: wifi-phy-band.h:43
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_MOD_CLASS_OFDM
OFDM (Clause 17)
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ WIFI_MOD_CLASS_ERP_OFDM
ERP-OFDM (18.4)
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsEht(WifiPreamble preamble)
Return true if a preamble corresponds to an EHT transmission.
WifiModulationClass GetModulationClassForPreamble(WifiPreamble preamble)
Return the modulation class corresponding to the given preamble type.
std::vector< uint8_t > RuAllocation
8 bit RU_ALLOCATION per 20 MHz
bool IsDlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a downlink multi-user transmission.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
bool IsUlMu(WifiPreamble preamble)
Return true if a preamble corresponds to a uplink multi-user transmission.
HE MU specific user transmission parameters.
uint8_t mcs
MCS index.
HeRu::RuSpec ru
RU specification.
uint8_t nss
number of spatial streams
bool operator!=(const HeMuUserInfo &other) const
Compare this user info to the given user info.
bool operator==(const HeMuUserInfo &other) const
Compare this user info to the given user info.
Struct providing a function call operator to compare two RUs.
Definition: he-ru.h:141
Declaration of the following enums: