A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
eht-capabilities.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 DERONNE SOFTWARE ENGINEERING
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
7 */
8
9#include "eht-capabilities.h"
10
11#include <bitset>
12#include <cmath>
13
14namespace ns3
15{
16
17uint16_t
19{
20 return 2;
21}
22
23void
33
34uint16_t
36{
37 Buffer::Iterator i = start;
38 uint16_t val = i.ReadLsbtohU16();
39 epcsPriorityAccessSupported = val & 0x0001;
40 ehtOmControlSupport = (val >> 1) & 0x0001;
41 triggeredTxopSharingMode1Support = (val >> 2) & 0x0001;
42 triggeredTxopSharingMode2Support = (val >> 3) & 0x0001;
43 restrictedTwtSupport = (val >> 4) & 0x0001;
44 scsTrafficDescriptionSupport = (val >> 5) & 0x0001;
45 maxMpduLength = (val >> 6) & 0x0003;
46 maxAmpduLengthExponentExtension = (val >> 8) & 0x0001;
47 return 2;
48}
49
50uint16_t
52{
53 return 9;
54}
55
56void
58{
59 uint64_t val1 =
63 (beamformeeSs160Mhz << 10) | (beamformeeSs320Mhz << 13) |
65 (nSoundingDimensions320Mhz << 22) | (ng16SuFeedback << 25) | (ng16MuFeedback << 26) |
69 (static_cast<uint64_t>(psrBasedSpatialReuseSupport) << 33) |
70 (static_cast<uint64_t>(powerBoostFactorSupport) << 34) |
71 (static_cast<uint64_t>(muPpdu4xEhtLtfAnd800nsGi) << 35) |
72 (static_cast<uint64_t>(maxNc) << 36) |
73 (static_cast<uint64_t>(nonTriggeredCqiFeedback) << 40) |
74 (static_cast<uint64_t>(supportTx1024And4096QamForRuSmallerThan242Tones) << 41) |
75 (static_cast<uint64_t>(supportRx1024And4096QamForRuSmallerThan242Tones) << 42) |
76 (static_cast<uint64_t>(ppeThresholdsPresent) << 43) |
77 (static_cast<uint64_t>(commonNominalPacketPadding) << 44) |
78 (static_cast<uint64_t>(maxNumSupportedEhtLtfs) << 46) |
79 (static_cast<uint64_t>(supportMcs15) << 51) |
80 (static_cast<uint64_t>(supportEhtDupIn6GHz) << 55) |
81 (static_cast<uint64_t>(support20MhzOperatingStaReceivingNdpWithWiderBw) << 56) |
82 (static_cast<uint64_t>(nonOfdmaUlMuMimoBwNotLargerThan80Mhz) << 57) |
83 (static_cast<uint64_t>(nonOfdmaUlMuMimo160Mhz) << 58) |
84 (static_cast<uint64_t>(nonOfdmaUlMuMimo320Mhz) << 59) |
85 (static_cast<uint64_t>(muBeamformerBwNotLargerThan80Mhz) << 60) |
86 (static_cast<uint64_t>(muBeamformer160Mhz) << 61) |
87 (static_cast<uint64_t>(muBeamformer320Mhz) << 62) |
88 (static_cast<uint64_t>(tbSoundingFeedbackRateLimit) << 63);
90 start.WriteHtolsbU64(val1);
91 start.WriteU8(val2);
92}
93
94uint16_t
96{
97 Buffer::Iterator i = start;
98 uint64_t val1 = i.ReadLsbtohU64();
99 uint8_t val2 = i.ReadU8();
100
101 support320MhzIn6Ghz = (val1 >> 1) & 0x0001;
102 support242ToneRuInBwLargerThan20Mhz = (val1 >> 2) & 0x0001;
103 ndpWith4TimesEhtLtfAnd32usGi = (val1 >> 3) & 0x0001;
104 partialBandwidthUlMuMimo = (val1 >> 4) & 0x0001;
105 suBeamformer = (val1 >> 5) & 0x0001;
106 suBeamformee = (val1 >> 6) & 0x0001;
107 beamformeeSsBwNotLargerThan80Mhz = (val1 >> 7) & 0x0007;
108 beamformeeSs160Mhz = (val1 >> 10) & 0x0007;
109 beamformeeSs320Mhz = (val1 >> 13) & 0x0007;
110 nSoundingDimensionsBwNotLargerThan80Mhz = (val1 >> 16) & 0x0007;
111 nSoundingDimensions160Mhz = (val1 >> 19) & 0x0007;
112 nSoundingDimensions320Mhz = (val1 >> 22) & 0x0007;
113 ng16SuFeedback = (val1 >> 25) & 0x0001;
114 ng16MuFeedback = (val1 >> 26) & 0x0001;
115 codebooksizeSuFeedback = (val1 >> 27) & 0x0001;
116 codebooksizeMuFeedback = (val1 >> 28) & 0x0001;
117 triggeredSuBeamformingFeedback = (val1 >> 29) & 0x0001;
118 triggeredMuBeamformingPartialBwFeedback = (val1 >> 30) & 0x0001;
119 triggeredCqiFeedback = (val1 >> 31) & 0x0001;
120 partialBandwidthDlMuMimo = (val1 >> 32) & 0x0001;
121 psrBasedSpatialReuseSupport = (val1 >> 33) & 0x0001;
122 powerBoostFactorSupport = (val1 >> 34) & 0x0001;
123 muPpdu4xEhtLtfAnd800nsGi = (val1 >> 35) & 0x0001;
124 maxNc = (val1 >> 36) & 0x000f;
125 nonTriggeredCqiFeedback = (val1 >> 40) & 0x0001;
128 ppeThresholdsPresent = (val1 >> 43) & 0x0001;
129 commonNominalPacketPadding = (val1 >> 44) & 0x0003;
130 maxNumSupportedEhtLtfs = (val1 >> 46) & 0x001f;
131 supportMcs15 = (val1 >> 51) & 0x000f;
132 supportEhtDupIn6GHz = (val1 >> 55) & 0x0001;
134 nonOfdmaUlMuMimoBwNotLargerThan80Mhz = (val1 >> 57) & 0x0001;
135 nonOfdmaUlMuMimo160Mhz = (val1 >> 58) & 0x0001;
136 nonOfdmaUlMuMimo320Mhz = (val1 >> 59) & 0x0001;
137 muBeamformerBwNotLargerThan80Mhz = (val1 >> 60) & 0x0001;
138 muBeamformer160Mhz = (val1 >> 61) & 0x0001;
139 muBeamformer320Mhz = (val1 >> 62) & 0x0001;
140 tbSoundingFeedbackRateLimit = (val1 >> 63) & 0x0001;
141
143 rx4096QamInWiderBwDlOfdmaSupport = (val2 >> 1) & 0x01;
144
145 return 9;
146}
147
148uint16_t
150{
151 if (supportedEhtMcsAndNssSet.empty())
152 {
153 return 0;
154 }
155 uint16_t size = 0;
156 for (const auto& ehtMcsAndNssSet : supportedEhtMcsAndNssSet)
157 {
158 size += ehtMcsAndNssSet.second.size();
159 }
160 return size;
161}
162
163void
165{
167 for (const auto& ehtMcsAndNssSet : supportedEhtMcsAndNssSet)
168 {
169 for (const auto& byte : ehtMcsAndNssSet.second)
170 {
171 start.WriteU8(byte);
172 }
173 }
174}
175
176uint16_t
178 bool is2_4Ghz,
179 uint8_t heSupportedChannelWidthSet,
180 bool support320MhzIn6Ghz)
181{
182 Buffer::Iterator i = start;
183 uint16_t count = 0;
185 std::vector<uint8_t> bytes;
186 if (is2_4Ghz)
187 {
188 if ((heSupportedChannelWidthSet & 0x01) == 0)
189 {
190 bytes.clear();
191 for (std::size_t j = 0; j < 4; ++j)
192 {
193 uint8_t byte = i.ReadU8();
194 bytes.push_back(byte);
195 count++;
196 }
198 }
199 else
200 {
201 bytes.clear();
202 for (std::size_t j = 0; j < 3; ++j)
203 {
204 uint8_t byte = i.ReadU8();
205 bytes.push_back(byte);
206 count++;
207 }
209 }
210 }
211 else
212 {
213 if ((heSupportedChannelWidthSet & 0x0e) == 0)
214 {
215 bytes.clear();
216 for (std::size_t j = 0; j < 4; ++j)
217 {
218 uint8_t byte = i.ReadU8();
219 bytes.push_back(byte);
220 count++;
221 }
223 }
224 if ((heSupportedChannelWidthSet & 0x02) != 0)
225 {
226 bytes.clear();
227 for (std::size_t j = 0; j < 3; ++j)
228 {
229 uint8_t byte = i.ReadU8();
230 bytes.push_back(byte);
231 count++;
232 }
234 }
235 if ((heSupportedChannelWidthSet & 0x04) != 0)
236 {
237 bytes.clear();
238 for (std::size_t j = 0; j < 3; ++j)
239 {
240 uint8_t byte = i.ReadU8();
241 bytes.push_back(byte);
242 count++;
243 }
245 }
246 if (support320MhzIn6Ghz)
247 {
248 bytes.clear();
249 for (std::size_t j = 0; j < 3; ++j)
250 {
251 uint8_t byte = i.ReadU8();
252 bytes.push_back(byte);
253 count++;
254 }
256 }
257 }
258 return count;
259}
260
261uint16_t
263{
264 const auto numBitsSet = std::bitset<5>(ruIndexBitmask).count();
265 const uint64_t nBitsNoPadding = 4 + 5 + (6 * numBitsSet * (nssPe + 1));
266 return std::ceil(static_cast<double>(nBitsNoPadding) / 8.0);
267}
268
269void
271{
272 uint64_t nBitsNoPadding = 0;
273 uint8_t val = nssPe | ((ruIndexBitmask & 0x0f) << 4);
274 start.WriteU8(val);
275 nBitsNoPadding += 8;
276 val = (ruIndexBitmask & 0x10) >> 4;
277 nBitsNoPadding += 1;
278 uint8_t bitsPerPpet = 3;
279 for (const auto& info : ppeThresholdsInfo)
280 {
281 uint8_t offset = nBitsNoPadding % 8;
282 uint8_t bitsLeft = (8 - offset);
283 uint8_t bitMask = (0x01 << bitsLeft) - 0x01;
284 val |= (info.ppetMax & bitMask) << offset;
285 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
286 if (nBitsNoPadding % 8 == 0)
287 {
288 start.WriteU8(val);
289 if (bitsLeft < 3)
290 {
291 const uint8_t remainingBits = (3 - bitsLeft);
292 bitMask = (0x01 << remainingBits) - 0x01;
293 val = (info.ppetMax >> bitsLeft) & bitMask;
294 nBitsNoPadding += remainingBits;
295 }
296 else
297 {
298 val = 0;
299 }
300 }
301 offset = nBitsNoPadding % 8;
302 bitsLeft = (8 - offset);
303 bitMask = (0x01 << bitsLeft) - 0x01;
304 val |= (info.ppet8 & bitMask) << offset;
305 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
306 if (nBitsNoPadding % 8 == 0)
307 {
308 start.WriteU8(val);
309 if (bitsLeft < 3)
310 {
311 const uint8_t remainingBits = (3 - bitsLeft);
312 bitMask = (0x01 << remainingBits) - 0x01;
313 val = (info.ppet8 >> bitsLeft) & bitMask;
314 nBitsNoPadding += remainingBits;
315 }
316 else
317 {
318 val = 0;
319 }
320 }
321 }
322 if (nBitsNoPadding % 8 > 0)
323 {
324 start.WriteU8(val);
325 }
326}
327
328uint16_t
330{
331 Buffer::Iterator i = start;
332 uint64_t nBitsNoPadding = 0;
333 uint8_t val = i.ReadU8();
334 nssPe = val & 0x0f;
335 ruIndexBitmask = ((val >> 4) & 0x0f);
336 nBitsNoPadding += 8;
337 val = i.ReadU8();
338 ruIndexBitmask |= ((val & 0x01) << 4);
339 nBitsNoPadding += 1;
340 const auto numBitsSet = std::bitset<5>(ruIndexBitmask).count();
341 const uint64_t bitsToDeserialize = (4 + 5 + (6 * numBitsSet * (nssPe + 1)));
342 uint8_t bitsPerPpet = 3;
343 while (nBitsNoPadding < bitsToDeserialize)
344 {
346 uint8_t offset = nBitsNoPadding % 8;
347 uint8_t bitsLeft = (8 - offset);
348 uint8_t bitMask = (1 << bitsLeft) - 1;
349 info.ppetMax = ((val >> offset) & bitMask);
350 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
351 if (nBitsNoPadding % 8 == 0)
352 {
353 val = i.ReadU8();
354 if (bitsLeft < 3)
355 {
356 const uint8_t remainingBits = (3 - bitsLeft);
357 bitMask = (1 << remainingBits) - 1;
358 info.ppetMax |= ((val & bitMask) << bitsLeft);
359 nBitsNoPadding += remainingBits;
360 }
361 }
362 offset = nBitsNoPadding % 8;
363 bitsLeft = (8 - offset);
364 bitMask = (1 << bitsLeft) - 1;
365 info.ppet8 = ((val >> offset) & bitMask);
366 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
367 if (nBitsNoPadding % 8 == 0)
368 {
369 val = i.ReadU8();
370 if (bitsLeft < 3)
371 {
372 const uint8_t remainingBits = (3 - bitsLeft);
373 bitMask = (1 << remainingBits) - 1;
374 info.ppet8 |= ((val & bitMask) << bitsLeft);
375 nBitsNoPadding += remainingBits;
376 }
377 }
378 ppeThresholdsInfo.push_back(info);
379 }
380 return std::ceil(static_cast<double>(bitsToDeserialize) / 8.0);
381}
382
384 : m_macCapabilities{},
385 m_phyCapabilities{},
386 m_supportedEhtMcsAndNssSet{},
387 m_ppeThresholds{},
388 m_is2_4Ghz{false},
389 m_heCapabilities{std::nullopt}
390{
391}
392
393EhtCapabilities::EhtCapabilities(bool is2_4Ghz, const std::optional<HeCapabilities>& heCapabilities)
394 : m_macCapabilities{},
395 m_phyCapabilities{},
396 m_supportedEhtMcsAndNssSet{},
397 m_ppeThresholds{},
398 m_is2_4Ghz{is2_4Ghz},
399 m_heCapabilities{heCapabilities}
400{
401}
402
405{
406 return IE_EXTENSION;
407}
408
414
415void
416EhtCapabilities::Print(std::ostream& os) const
417{
418 os << "EHT Capabilities="; // TODO
419}
420
421uint16_t
423{
424 uint16_t size = 1 + // ElementIdExt
428 {
429 size += m_ppeThresholds.GetSize();
430 }
431 return size;
432}
433
434void
436{
437 switch (length)
438 {
439 case 3895:
441 break;
442 case 7991:
444 break;
445 case 11454:
447 break;
448 default:
449 NS_ABORT_MSG("Invalid MPDU Max Length value");
450 }
451}
452
453uint16_t
455{
457 {
458 case 0:
459 return 3895;
460 case 1:
461 return 7991;
462 case 2:
463 return 11454;
464 default:
465 NS_ABORT_MSG("The value 3 is reserved");
466 }
467 return 0;
468}
469
470void
472{
473 for (uint8_t i = 0; i <= 1; i++)
474 {
475 if ((1UL << (23 + i)) - 1 == maxAmpduLength)
476 {
478 return;
479 }
480 }
481 NS_ABORT_MSG("Invalid A-MPDU Max Length value");
482}
483
486{
487 return std::min<uint32_t>((1UL << (23 + m_macCapabilities.maxAmpduLengthExponentExtension)) - 1,
488 15523200);
489}
490
491void
493 uint8_t upperMcs,
494 uint8_t maxNss)
495{
496 NS_ASSERT_MSG(maxNss <= 8, "Invalid maximum NSS " << maxNss);
497 std::size_t index = 0;
498 switch (upperMcs)
499 {
500 case 7:
502 index = 0;
503 break;
504 case 9:
505 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 1 : 0;
506 break;
507 case 11:
508 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 2 : 1;
509 break;
510 case 13:
511 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2;
512 break;
513 default:
514 NS_ASSERT_MSG(false, "Invalid upper MCS " << +upperMcs);
515 }
516 uint8_t nBytes = 0;
517 switch (mapType)
518 {
520 nBytes = 4;
521 break;
525 nBytes = 3;
526 break;
527 default:
528 NS_ASSERT_MSG(false, "Invalid map type " << mapType);
529 }
532 {
534 m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet[mapType][index] = (maxNss & 0x0f);
535 }
536 else
537 {
538 NS_ASSERT(it->second.size() == nBytes);
539 it->second[index] |= (maxNss & 0x0f);
540 }
541}
542
543void
545 uint8_t upperMcs,
546 uint8_t maxNss)
547{
548 NS_ASSERT_MSG(maxNss <= 8, "Invalid maximum NSS " << maxNss);
549 std::size_t index = 0;
550 switch (upperMcs)
551 {
552 case 7:
554 index = 0;
555 break;
556 case 9:
557 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 1 : 0;
558 break;
559 case 11:
560 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 2 : 1;
561 break;
562 case 13:
563 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2;
564 break;
565 default:
566 NS_ASSERT_MSG(false, "Invalid upper MCS " << upperMcs);
567 }
568 uint8_t nBytes = 0;
569 switch (mapType)
570 {
572 nBytes = 4;
573 break;
577 nBytes = 3;
578 break;
579 default:
580 NS_ASSERT_MSG(false, "Invalid map type " << mapType);
581 }
584 {
587 ((maxNss & 0x0f) << 4);
588 }
589 else
590 {
591 NS_ASSERT(it->second.size() == nBytes);
592 it->second[index] |= ((maxNss & 0x0f) << 4);
593 }
594}
595
596uint8_t
598{
599 const auto it = m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.find(mapType);
601 {
602 return 0;
603 }
604 int8_t index = -1;
605 for (int8_t i = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2; i >= 0; i--)
606 {
607 if ((it->second[i] & 0x0f) > 0)
608 {
609 index = i;
610 break;
611 }
612 }
613 NS_ASSERT_MSG(index >= 0, "Supported EHT-MCS And NSS Set subfield is incorrect");
614 switch (index)
615 {
616 case 0:
617 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 7 : 9;
618 case 1:
619 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 9 : 11;
620 case 2:
621 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 11 : 13;
622 case 3:
624 return 13;
625 default:
626 NS_ASSERT(false);
627 }
628 return 0;
629}
630
631uint8_t
633{
634 const auto it = m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.find(mapType);
636 {
637 return 0;
638 }
639 int8_t index = -1;
640 for (int8_t i = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2; i >= 0; i--)
641 {
642 if ((it->second[i] & 0xf0) > 0)
643 {
644 index = i;
645 break;
646 }
647 }
648 NS_ASSERT_MSG(index >= 0, "Supported EHT-MCS And NSS Set subfield is incorrect");
649 switch (index)
650 {
651 case 0:
652 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 7 : 9;
653 case 1:
654 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 9 : 11;
655 case 2:
656 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 11 : 13;
657 case 3:
659 return 13;
660 default:
661 NS_ASSERT(false);
662 }
663 return 0;
664}
665
666void
668 uint8_t ruIndexBitmask,
669 const std::vector<std::pair<uint8_t, uint8_t>>& ppeThresholds)
670{
671 NS_ASSERT(ppeThresholds.size() == (std::bitset<5>(ruIndexBitmask).count() * (nssPe + 1)));
673 m_ppeThresholds.nssPe = nssPe;
674 m_ppeThresholds.ruIndexBitmask = ruIndexBitmask;
676 for (const auto& [ppetMax, ppet8] : ppeThresholds)
677 {
678 m_ppeThresholds.ppeThresholdsInfo.push_back({ppetMax, ppet8});
679 }
680}
681
682void
693
694uint16_t
696{
697 uint16_t count = 0;
698 Buffer::Iterator i = start;
699
700 uint16_t nBytes = m_macCapabilities.Deserialize(i);
701 i.Next(nBytes);
702 count += nBytes;
703
704 nBytes = m_phyCapabilities.Deserialize(i);
705 i.Next(nBytes);
706 count += nBytes;
707
708 NS_ASSERT(m_heCapabilities.has_value());
711 m_heCapabilities->GetChannelWidthSet(),
713 i.Next(nBytes);
714 count += nBytes;
715
717 {
718 count += m_ppeThresholds.Deserialize(i);
719 }
720
721 return count;
722}
723
724} // namespace ns3
iterator in a Buffer instance
Definition buffer.h:89
uint16_t ReadLsbtohU16()
Definition buffer.cc:1053
uint64_t ReadLsbtohU64()
Definition buffer.cc:1083
void Next()
go forward by one byte
Definition buffer.h:842
uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override
Deserialize information (i.e., the body of the IE, not including the Element ID and length octets)
void SetPpeThresholds(uint8_t nssPe, uint8_t ruIndexBitmask, const std::vector< std::pair< uint8_t, uint8_t > > &ppeThresholds)
Set the EHT PPE threshold info subfield.
void SerializeInformationField(Buffer::Iterator start) const override
Serialize information (i.e., the body of the IE, not including the Element ID and length octets)
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
void SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType, uint8_t upperMcs, uint8_t maxNss)
Set a subfield of the Supported EHT-MCS And NSS Set.
bool m_is2_4Ghz
flag indicating whether PHY is operating in 2.4 GHz based on other IEs contained in the same manageme...
WifiInformationElementId ElementIdExt() const override
Get the wifi information element ID extension.
EhtCapabilities()
Constructor.
void Print(std::ostream &os) const override
Generate human-readable form of IE.
EhtMcsAndNssSet m_supportedEhtMcsAndNssSet
Supported EHT-MCS And NSS Set subfield.
uint16_t GetInformationFieldSize() const override
Length of serialized information (i.e., the length of the body of the IE, not including the Element I...
EhtPpeThresholds m_ppeThresholds
EHT PPE Threshold Info subfield.
EhtPhyCapabilities m_phyCapabilities
EHT PHY Capabilities Info subfield.
uint8_t GetHighestSupportedTxMcs(EhtMcsAndNssSet::EhtMcsMapType mapType)
Get the highest supported TX MCS for a given EHT-MCS map type.
WifiInformationElementId ElementId() const override
Get the wifi information element ID.
uint32_t GetMaxAmpduLength() const
Return the maximum A-MPDU length.
EhtMacCapabilities m_macCapabilities
EHT MAC Capabilities Info subfield.
uint16_t GetMaxMpduLength() const
Get the maximum MPDU length.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum A-MPDU length.
void SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType, uint8_t upperMcs, uint8_t maxNss)
Set a subfield of the Supported EHT-MCS And NSS Set.
uint8_t GetHighestSupportedRxMcs(EhtMcsAndNssSet::EhtMcsMapType mapType)
Get the highest supported RX MCS for a given EHT-MCS map type.
std::optional< HeCapabilities > m_heCapabilities
HE capabilities contained in the same management frame if present.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint8_t WifiInformationElementId
This type is used to represent an Information Element ID.
STL namespace.
uint16_t GetSize() const
Get the size of the serialized EHT MAC capabilities subfield.
uint8_t maxMpduLength
Maximum MPDU Length.
uint8_t epcsPriorityAccessSupported
EPCS Priority Access Supported.
uint8_t triggeredTxopSharingMode1Support
Triggered TXOP Sharing Mode 1 Support.
uint8_t restrictedTwtSupport
Restricted TWT Support.
uint8_t ehtOmControlSupport
EHT OM Control Support.
void Serialize(Buffer::Iterator &start) const
Serialize the EHT MAC capabilities subfield.
uint16_t Deserialize(Buffer::Iterator start)
Deserialize the EHT MAC capabilities subfield.
uint8_t scsTrafficDescriptionSupport
SCS Traffic Description Support.
uint8_t maxAmpduLengthExponentExtension
Maximum A-MPDU length exponent extension.
uint8_t triggeredTxopSharingMode2Support
Triggered TXOP Sharing Mode 2 Support.
uint16_t Deserialize(Buffer::Iterator start, bool is2_4Ghz, uint8_t heSupportedChannelWidthSet, bool support320MhzIn6Ghz)
Deserialize the Supported EHT-MCS And NSS Set subfield.
uint16_t GetSize() const
Get the size of the serialized Supported EHT-MCS And NSS Set subfield.
void Serialize(Buffer::Iterator &start) const
Serialize the Supported EHT-MCS And NSS Set subfield.
std::map< EhtMcsMapType, std::vector< uint8_t > > supportedEhtMcsAndNssSet
Supported EHT-MCS And NSS Set.
EhtMcsMapType
The different EHT-MCS map types as defined in 9.4.2.313.4 Supported EHT-MCS And NSS Set field.
uint8_t support242ToneRuInBwLargerThan20Mhz
Support For 242-tone RU In BW Wider Than 20 MHz.
uint8_t triggeredSuBeamformingFeedback
Triggered SU Beamforming Feedback.
uint8_t ndpWith4TimesEhtLtfAnd32usGi
NDP With 4x EHT-LTF And 3.2 μs GI.
uint8_t ppeThresholdsPresent
PPE Thresholds Present.
uint8_t muBeamformer320Mhz
MU Beamformer (BW = 320 MHz)
uint8_t nSoundingDimensions160Mhz
Beamformee SS (= 160 MHz)
uint8_t rx1024QamInWiderBwDlOfdmaSupport
Rx 1024-QAM In Wider Bandwidth DL OFDMA Support.
uint8_t supportMcs15
Support Of MCS 15.
uint8_t beamformeeSsBwNotLargerThan80Mhz
Beamformee SS (≤ 80 MHz)
uint8_t partialBandwidthDlMuMimo
Partial Bandwidth DL MU-MIMO.
uint8_t nonOfdmaUlMuMimo320Mhz
Non-OFDMA UL MU-MIMO (BW = 320 MHz)
uint8_t muBeamformerBwNotLargerThan80Mhz
MU Beamformer (BW ≤ 80 MHz)
uint8_t triggeredCqiFeedback
Triggered CQI Feedback.
uint8_t nonOfdmaUlMuMimoBwNotLargerThan80Mhz
Non-OFDMA UL MU-MIMO (BW ≤ 80 MHz)
uint16_t GetSize() const
Get the size of the serialized EHT PHY capabilities subfield.
uint8_t nSoundingDimensions320Mhz
Beamformee SS (= 320 MHz)
uint8_t beamformeeSs320Mhz
Beamformee SS (= 320 MHz)
uint8_t partialBandwidthUlMuMimo
Partial Bandwidth UL MU-MIMO.
uint8_t psrBasedSpatialReuseSupport
EHT PSR-Based SR Support.
uint8_t nonOfdmaUlMuMimo160Mhz
Non-OFDMA UL MU-MIMO (BW = 160 MHz)
uint8_t suBeamformee
SU Beamformee.
uint8_t rx4096QamInWiderBwDlOfdmaSupport
Rx 4096-QAM In Wider Bandwidth DL OFDMA Support.
uint8_t tbSoundingFeedbackRateLimit
TB Sounding Feedback Rate Limit.
uint8_t muPpdu4xEhtLtfAnd800nsGi
EHT MU PPDU With 4x EHT-LTF And 0.8 μs GI.
uint8_t muBeamformer160Mhz
MU Beamformer (BW = 160 MHz)
uint8_t support320MhzIn6Ghz
Support For 320 MHz In 6 GHz.
uint8_t support20MhzOperatingStaReceivingNdpWithWiderBw
Support For 20 MHz Operating STA Receiving NDP With Wider Bandwidth.
uint8_t beamformeeSs160Mhz
Beamformee SS (= 160 MHz)
uint8_t codebooksizeSuFeedback
Support for a codebook size for SU feedback.
uint8_t triggeredMuBeamformingPartialBwFeedback
Triggered MU Beamforming Partial BW Feedback.
uint8_t nonTriggeredCqiFeedback
Non-Triggered CQI Feedback.
uint8_t powerBoostFactorSupport
Power Boost Factor Support.
uint16_t Deserialize(Buffer::Iterator start)
Deserialize the EHT PHY capabilities subfield.
uint8_t supportEhtDupIn6GHz
Support Of EHT DUP (MCS 14) In 6 GHz.
uint8_t ng16MuFeedback
Support for subcarrier grouping of 16 for MU feedback.
uint8_t ng16SuFeedback
Support for subcarrier grouping of 16 for SU feedback.
uint8_t commonNominalPacketPadding
Common Nominal Packet Padding.
uint8_t codebooksizeMuFeedback
Support for a codebook size for MU feedback.
void Serialize(Buffer::Iterator &start) const
Serialize the EHT PHY capabilities subfield.
uint8_t supportTx1024And4096QamForRuSmallerThan242Tones
Tx 1024-QAM And 4096-QAM < 242-tone RU Support.
uint8_t suBeamformer
SU Beamformer.
uint8_t nSoundingDimensionsBwNotLargerThan80Mhz
Beamformee SS (≤ 80 MHz)
uint8_t supportRx1024And4096QamForRuSmallerThan242Tones
Rx 1024-QAM And 4096-QAM < 242-tone RU Support.
uint8_t maxNumSupportedEhtLtfs
Maximum Number Of Supported EHT-LTFs.
uint16_t Deserialize(Buffer::Iterator start)
Deserialize the EHT PPE Thresholds subfield.
std::vector< EhtPpeThresholdsInfo > ppeThresholdsInfo
PPE Thresholds Info.
void Serialize(Buffer::Iterator &start) const
Serialize the EHT PPE Thresholds subfield.
uint8_t ruIndexBitmask
RU Index Bitmask.
uint16_t GetSize() const
Get the size of the serialized EHT PPE Thresholds subfield.
#define IE_EXT_EHT_CAPABILITIES
#define IE_EXTENSION