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 * 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 * Author: Sébastien Deronne <sebastien.deronne@gmail.com>
18 */
19
20#include "eht-capabilities.h"
21
22#include <bitset>
23#include <cmath>
24
25namespace ns3
26{
27
28uint16_t
30{
31 return 2;
32}
33
34void
36{
37 uint16_t val = epcsPriorityAccessSupported | (ehtOmControlSupport << 1) |
42 start.WriteHtolsbU16(val);
43}
44
45uint16_t
47{
48 Buffer::Iterator i = start;
49 uint16_t val = i.ReadLsbtohU16();
50 epcsPriorityAccessSupported = val & 0x0001;
51 ehtOmControlSupport = (val >> 1) & 0x0001;
52 triggeredTxopSharingMode1Support = (val >> 2) & 0x0001;
53 triggeredTxopSharingMode2Support = (val >> 3) & 0x0001;
54 restrictedTwtSupport = (val >> 4) & 0x0001;
55 scsTrafficDescriptionSupport = (val >> 5) & 0x0001;
56 maxMpduLength = (val >> 6) & 0x0003;
57 maxAmpduLengthExponentExtension = (val >> 8) & 0x0001;
58 return 2;
59}
60
61uint16_t
63{
64 return 9;
65}
66
67void
69{
70 uint64_t val1 =
74 (beamformeeSs160Mhz << 10) | (beamformeeSs320Mhz << 13) |
76 (nSoundingDimensions320Mhz << 22) | (ng16SuFeedback << 25) | (ng16MuFeedback << 26) |
79 (triggeredCqiFeedback << 31) | (static_cast<uint64_t>(partialBandwidthDlMuMimo) << 32) |
80 (static_cast<uint64_t>(psrBasedSpatialReuseSupport) << 33) |
81 (static_cast<uint64_t>(powerBoostFactorSupport) << 34) |
82 (static_cast<uint64_t>(muPpdu4xEhtLtfAnd800nsGi) << 35) |
83 (static_cast<uint64_t>(maxNc) << 36) |
84 (static_cast<uint64_t>(nonTriggeredCqiFeedback) << 40) |
85 (static_cast<uint64_t>(supportTx1024And4096QamForRuSmallerThan242Tones) << 41) |
86 (static_cast<uint64_t>(supportRx1024And4096QamForRuSmallerThan242Tones) << 42) |
87 (static_cast<uint64_t>(ppeThresholdsPresent) << 43) |
88 (static_cast<uint64_t>(commonNominalPacketPadding) << 44) |
89 (static_cast<uint64_t>(maxNumSupportedEhtLtfs) << 46) |
90 (static_cast<uint64_t>(supportMcs15) << 51) |
91 (static_cast<uint64_t>(supportEhtDupIn6GHz) << 55) |
92 (static_cast<uint64_t>(support20MhzOperatingStaReceivingNdpWithWiderBw) << 56) |
93 (static_cast<uint64_t>(nonOfdmaUlMuMimoBwNotLargerThan80Mhz) << 57) |
94 (static_cast<uint64_t>(nonOfdmaUlMuMimo160Mhz) << 58) |
95 (static_cast<uint64_t>(nonOfdmaUlMuMimo320Mhz) << 59) |
96 (static_cast<uint64_t>(muBeamformerBwNotLargerThan80Mhz) << 60) |
97 (static_cast<uint64_t>(muBeamformer160Mhz) << 61) |
98 (static_cast<uint64_t>(muBeamformer320Mhz) << 62) |
99 (static_cast<uint64_t>(tbSoundingFeedbackRateLimit) << 63);
101 start.WriteHtolsbU64(val1);
102 start.WriteU8(val2);
103}
104
105uint16_t
107{
108 Buffer::Iterator i = start;
109 uint64_t val1 = i.ReadLsbtohU64();
110 uint8_t val2 = i.ReadU8();
111
112 support320MhzIn6Ghz = (val1 >> 1) & 0x0001;
113 support242ToneRuInBwLargerThan20Mhz = (val1 >> 2) & 0x0001;
114 ndpWith4TimesEhtLtfAnd32usGi = (val1 >> 3) & 0x0001;
115 partialBandwidthUlMuMimo = (val1 >> 4) & 0x0001;
116 suBeamformer = (val1 >> 5) & 0x0001;
117 suBeamformee = (val1 >> 6) & 0x0001;
118 beamformeeSsBwNotLargerThan80Mhz = (val1 >> 7) & 0x0007;
119 beamformeeSs160Mhz = (val1 >> 10) & 0x0007;
120 beamformeeSs320Mhz = (val1 >> 13) & 0x0007;
121 nSoundingDimensionsBwNotLargerThan80Mhz = (val1 >> 16) & 0x0007;
122 nSoundingDimensions160Mhz = (val1 >> 19) & 0x0007;
123 nSoundingDimensions320Mhz = (val1 >> 22) & 0x0007;
124 ng16SuFeedback = (val1 >> 25) & 0x0001;
125 ng16MuFeedback = (val1 >> 26) & 0x0001;
126 codebooksizeSuFeedback = (val1 >> 27) & 0x0001;
127 codebooksizeMuFeedback = (val1 >> 28) & 0x0001;
128 triggeredSuBeamformingFeedback = (val1 >> 29) & 0x0001;
129 triggeredMuBeamformingPartialBwFeedback = (val1 >> 30) & 0x0001;
130 triggeredCqiFeedback = (val1 >> 31) & 0x0001;
131 partialBandwidthDlMuMimo = (val1 >> 32) & 0x0001;
132 psrBasedSpatialReuseSupport = (val1 >> 33) & 0x0001;
133 powerBoostFactorSupport = (val1 >> 34) & 0x0001;
134 muPpdu4xEhtLtfAnd800nsGi = (val1 >> 35) & 0x0001;
135 maxNc = (val1 >> 36) & 0x000f;
136 nonTriggeredCqiFeedback = (val1 >> 40) & 0x0001;
139 ppeThresholdsPresent = (val1 >> 43) & 0x0001;
140 commonNominalPacketPadding = (val1 >> 44) & 0x0003;
141 maxNumSupportedEhtLtfs = (val1 >> 46) & 0x001f;
142 supportMcs15 = (val1 >> 51) & 0x000f;
143 supportEhtDupIn6GHz = (val1 >> 55) & 0x0001;
145 nonOfdmaUlMuMimoBwNotLargerThan80Mhz = (val1 >> 57) & 0x0001;
146 nonOfdmaUlMuMimo160Mhz = (val1 >> 58) & 0x0001;
147 nonOfdmaUlMuMimo320Mhz = (val1 >> 59) & 0x0001;
148 muBeamformerBwNotLargerThan80Mhz = (val1 >> 60) & 0x0001;
149 muBeamformer160Mhz = (val1 >> 61) & 0x0001;
150 muBeamformer320Mhz = (val1 >> 62) & 0x0001;
151 tbSoundingFeedbackRateLimit = (val1 >> 63) & 0x0001;
152
154 rx4096QamInWiderBwDlOfdmaSupport = (val2 >> 1) & 0x01;
155
156 return 9;
157}
158
159uint16_t
161{
162 if (supportedEhtMcsAndNssSet.empty())
163 {
164 return 0;
165 }
166 uint16_t size = 0;
167 for (const auto& ehtMcsAndNssSet : supportedEhtMcsAndNssSet)
168 {
169 size += ehtMcsAndNssSet.second.size();
170 }
171 return size;
172}
173
174void
176{
178 for (const auto& ehtMcsAndNssSet : supportedEhtMcsAndNssSet)
179 {
180 for (const auto& byte : ehtMcsAndNssSet.second)
181 {
182 start.WriteU8(byte);
183 }
184 }
185}
186
187uint16_t
189 bool is2_4Ghz,
190 uint8_t heSupportedChannelWidthSet,
191 bool support320MhzIn6Ghz)
192{
193 Buffer::Iterator i = start;
194 uint16_t count = 0;
196 std::vector<uint8_t> bytes;
197 if (is2_4Ghz)
198 {
199 if ((heSupportedChannelWidthSet & 0x01) == 0)
200 {
201 bytes.clear();
202 for (std::size_t j = 0; j < 4; ++j)
203 {
204 uint8_t byte = i.ReadU8();
205 bytes.push_back(byte);
206 count++;
207 }
209 }
210 else
211 {
212 bytes.clear();
213 for (std::size_t j = 0; j < 3; ++j)
214 {
215 uint8_t byte = i.ReadU8();
216 bytes.push_back(byte);
217 count++;
218 }
220 }
221 }
222 else
223 {
224 if ((heSupportedChannelWidthSet & 0x0e) == 0)
225 {
226 bytes.clear();
227 for (std::size_t j = 0; j < 4; ++j)
228 {
229 uint8_t byte = i.ReadU8();
230 bytes.push_back(byte);
231 count++;
232 }
234 }
235 if ((heSupportedChannelWidthSet & 0x02) != 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 ((heSupportedChannelWidthSet & 0x04) != 0)
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 if (support320MhzIn6Ghz)
258 {
259 bytes.clear();
260 for (std::size_t j = 0; j < 3; ++j)
261 {
262 uint8_t byte = i.ReadU8();
263 bytes.push_back(byte);
264 count++;
265 }
267 }
268 }
269 return count;
270}
271
272uint16_t
274{
275 const auto numBitsSet = std::bitset<5>(ruIndexBitmask).count();
276 const uint64_t nBitsNoPadding = 4 + 5 + (6 * numBitsSet * (nssPe + 1));
277 return std::ceil(static_cast<double>(nBitsNoPadding) / 8.0);
278}
279
280void
282{
283 uint64_t nBitsNoPadding = 0;
284 uint8_t val = nssPe | ((ruIndexBitmask & 0x0f) << 4);
285 start.WriteU8(val);
286 nBitsNoPadding += 8;
287 val = (ruIndexBitmask & 0x10) >> 4;
288 nBitsNoPadding += 1;
289 uint8_t bitsPerPpet = 3;
290 for (const auto& info : ppeThresholdsInfo)
291 {
292 uint8_t offset = nBitsNoPadding % 8;
293 uint8_t bitsLeft = (8 - offset);
294 uint8_t bitMask = (0x01 << bitsLeft) - 0x01;
295 val |= (info.ppetMax & bitMask) << offset;
296 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
297 if (nBitsNoPadding % 8 == 0)
298 {
299 start.WriteU8(val);
300 if (bitsLeft < 3)
301 {
302 const uint8_t remainingBits = (3 - bitsLeft);
303 bitMask = (0x01 << remainingBits) - 0x01;
304 val = (info.ppetMax >> bitsLeft) & bitMask;
305 nBitsNoPadding += remainingBits;
306 }
307 else
308 {
309 val = 0;
310 }
311 }
312 offset = nBitsNoPadding % 8;
313 bitsLeft = (8 - offset);
314 bitMask = (0x01 << bitsLeft) - 0x01;
315 val |= (info.ppet8 & bitMask) << offset;
316 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
317 if (nBitsNoPadding % 8 == 0)
318 {
319 start.WriteU8(val);
320 if (bitsLeft < 3)
321 {
322 const uint8_t remainingBits = (3 - bitsLeft);
323 bitMask = (0x01 << remainingBits) - 0x01;
324 val = (info.ppet8 >> bitsLeft) & bitMask;
325 nBitsNoPadding += remainingBits;
326 }
327 else
328 {
329 val = 0;
330 }
331 }
332 }
333 if (nBitsNoPadding % 8 > 0)
334 {
335 start.WriteU8(val);
336 }
337}
338
339uint16_t
341{
342 Buffer::Iterator i = start;
343 uint64_t nBitsNoPadding = 0;
344 uint8_t val = i.ReadU8();
345 nssPe = val & 0x0f;
346 ruIndexBitmask = ((val >> 4) & 0x0f);
347 nBitsNoPadding += 8;
348 val = i.ReadU8();
349 ruIndexBitmask |= ((val & 0x01) << 4);
350 nBitsNoPadding += 1;
351 const auto numBitsSet = std::bitset<5>(ruIndexBitmask).count();
352 const uint64_t bitsToDeserialize = (4 + 5 + (6 * numBitsSet * (nssPe + 1)));
353 uint8_t bitsPerPpet = 3;
354 while (nBitsNoPadding < bitsToDeserialize)
355 {
357 uint8_t offset = nBitsNoPadding % 8;
358 uint8_t bitsLeft = (8 - offset);
359 uint8_t bitMask = (1 << bitsLeft) - 1;
360 info.ppetMax = ((val >> offset) & bitMask);
361 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
362 if (nBitsNoPadding % 8 == 0)
363 {
364 val = i.ReadU8();
365 if (bitsLeft < 3)
366 {
367 const uint8_t remainingBits = (3 - bitsLeft);
368 bitMask = (1 << remainingBits) - 1;
369 info.ppetMax |= ((val & bitMask) << bitsLeft);
370 nBitsNoPadding += remainingBits;
371 }
372 }
373 offset = nBitsNoPadding % 8;
374 bitsLeft = (8 - offset);
375 bitMask = (1 << bitsLeft) - 1;
376 info.ppet8 = ((val >> offset) & bitMask);
377 nBitsNoPadding += std::min(bitsLeft, bitsPerPpet);
378 if (nBitsNoPadding % 8 == 0)
379 {
380 val = i.ReadU8();
381 if (bitsLeft < 3)
382 {
383 const uint8_t remainingBits = (3 - bitsLeft);
384 bitMask = (1 << remainingBits) - 1;
385 info.ppet8 |= ((val & bitMask) << bitsLeft);
386 nBitsNoPadding += remainingBits;
387 }
388 }
389 ppeThresholdsInfo.push_back(info);
390 }
391 return std::ceil(static_cast<double>(bitsToDeserialize) / 8.0);
392}
393
395 : m_macCapabilities{},
396 m_phyCapabilities{},
397 m_supportedEhtMcsAndNssSet{},
398 m_ppeThresholds{},
399 m_is2_4Ghz{false},
400 m_heCapabilities{std::nullopt}
401{
402}
403
404EhtCapabilities::EhtCapabilities(bool is2_4Ghz, const std::optional<HeCapabilities>& heCapabilities)
405 : m_macCapabilities{},
406 m_phyCapabilities{},
407 m_supportedEhtMcsAndNssSet{},
408 m_ppeThresholds{},
409 m_is2_4Ghz{is2_4Ghz},
410 m_heCapabilities{heCapabilities}
411{
412}
413
416{
417 return IE_EXTENSION;
418}
419
422{
424}
425
426void
427EhtCapabilities::Print(std::ostream& os) const
428{
429 os << "EHT Capabilities="; // TODO
430}
431
432uint16_t
434{
435 uint16_t size = 1 + // ElementIdExt
439 {
440 size += m_ppeThresholds.GetSize();
441 }
442 return size;
443}
444
445void
447{
448 switch (length)
449 {
450 case 3895:
452 break;
453 case 7991:
455 break;
456 case 11454:
458 break;
459 default:
460 NS_ABORT_MSG("Invalid MPDU Max Length value");
461 }
462}
463
464uint16_t
466{
468 {
469 case 0:
470 return 3895;
471 case 1:
472 return 7991;
473 case 2:
474 return 11454;
475 default:
476 NS_ABORT_MSG("The value 3 is reserved");
477 }
478 return 0;
479}
480
481void
483{
484 for (uint8_t i = 0; i <= 1; i++)
485 {
486 if ((1UL << (23 + i)) - 1 == maxAmpduLength)
487 {
489 return;
490 }
491 }
492 NS_ABORT_MSG("Invalid A-MPDU Max Length value");
493}
494
497{
498 return std::min<uint32_t>((1UL << (23 + m_macCapabilities.maxAmpduLengthExponentExtension)) - 1,
499 15523200);
500}
501
502void
504 uint8_t upperMcs,
505 uint8_t maxNss)
506{
507 NS_ASSERT_MSG(maxNss <= 8, "Invalid maximum NSS " << maxNss);
508 std::size_t index = 0;
509 switch (upperMcs)
510 {
511 case 7:
513 index = 0;
514 break;
515 case 9:
516 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 1 : 0;
517 break;
518 case 11:
519 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 2 : 1;
520 break;
521 case 13:
522 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2;
523 break;
524 default:
525 NS_ASSERT_MSG(false, "Invalid upper MCS " << +upperMcs);
526 }
527 uint8_t nBytes = 0;
528 switch (mapType)
529 {
531 nBytes = 4;
532 break;
536 nBytes = 3;
537 break;
538 default:
539 NS_ASSERT_MSG(false, "Invalid map type " << mapType);
540 }
543 {
545 m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet[mapType][index] = (maxNss & 0x0f);
546 }
547 else
548 {
549 NS_ASSERT(it->second.size() == nBytes);
550 it->second[index] |= (maxNss & 0x0f);
551 }
552}
553
554void
556 uint8_t upperMcs,
557 uint8_t maxNss)
558{
559 NS_ASSERT_MSG(maxNss <= 8, "Invalid maximum NSS " << maxNss);
560 std::size_t index = 0;
561 switch (upperMcs)
562 {
563 case 7:
565 index = 0;
566 break;
567 case 9:
568 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 1 : 0;
569 break;
570 case 11:
571 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 2 : 1;
572 break;
573 case 13:
574 index = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2;
575 break;
576 default:
577 NS_ASSERT_MSG(false, "Invalid upper MCS " << upperMcs);
578 }
579 uint8_t nBytes = 0;
580 switch (mapType)
581 {
583 nBytes = 4;
584 break;
588 nBytes = 3;
589 break;
590 default:
591 NS_ASSERT_MSG(false, "Invalid map type " << mapType);
592 }
595 {
598 ((maxNss & 0x0f) << 4);
599 }
600 else
601 {
602 NS_ASSERT(it->second.size() == nBytes);
603 it->second[index] |= ((maxNss & 0x0f) << 4);
604 }
605}
606
607uint8_t
609{
610 const auto it = m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.find(mapType);
612 {
613 return 0;
614 }
615 int8_t index = -1;
616 for (int8_t i = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2; i >= 0; i--)
617 {
618 if ((it->second[i] & 0x0f) > 0)
619 {
620 index = i;
621 break;
622 }
623 }
624 NS_ASSERT_MSG(index >= 0, "Supported EHT-MCS And NSS Set subfield is incorrect");
625 switch (index)
626 {
627 case 0:
628 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 7 : 9;
629 case 1:
630 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 9 : 11;
631 case 2:
632 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 11 : 13;
633 case 3:
635 return 13;
636 default:
637 NS_ASSERT(false);
638 }
639 return 0;
640}
641
642uint8_t
644{
645 const auto it = m_supportedEhtMcsAndNssSet.supportedEhtMcsAndNssSet.find(mapType);
647 {
648 return 0;
649 }
650 int8_t index = -1;
651 for (int8_t i = (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 3 : 2; i >= 0; i--)
652 {
653 if ((it->second[i] & 0xf0) > 0)
654 {
655 index = i;
656 break;
657 }
658 }
659 NS_ASSERT_MSG(index >= 0, "Supported EHT-MCS And NSS Set subfield is incorrect");
660 switch (index)
661 {
662 case 0:
663 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 7 : 9;
664 case 1:
665 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 9 : 11;
666 case 2:
667 return (mapType == EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY) ? 11 : 13;
668 case 3:
670 return 13;
671 default:
672 NS_ASSERT(false);
673 }
674 return 0;
675}
676
677void
679 uint8_t ruIndexBitmask,
680 const std::vector<std::pair<uint8_t, uint8_t>>& ppeThresholds)
681{
682 NS_ASSERT(ppeThresholds.size() == (std::bitset<5>(ruIndexBitmask).count() * (nssPe + 1)));
684 m_ppeThresholds.nssPe = nssPe;
685 m_ppeThresholds.ruIndexBitmask = ruIndexBitmask;
687 for (const auto& [ppetMax, ppet8] : ppeThresholds)
688 {
689 m_ppeThresholds.ppeThresholdsInfo.push_back({ppetMax, ppet8});
690 }
691}
692
693void
695{
700 {
702 }
703}
704
705uint16_t
707{
708 uint16_t count = 0;
709 Buffer::Iterator i = start;
710
711 uint16_t nBytes = m_macCapabilities.Deserialize(i);
712 i.Next(nBytes);
713 count += nBytes;
714
715 nBytes = m_phyCapabilities.Deserialize(i);
716 i.Next(nBytes);
717 count += nBytes;
718
719 NS_ASSERT(m_heCapabilities.has_value());
722 m_heCapabilities->GetChannelWidthSet(),
724 i.Next(nBytes);
725 count += nBytes;
726
728 {
729 count += m_ppeThresholds.Deserialize(i);
730 }
731
732 return count;
733}
734
735} // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint16_t ReadLsbtohU16()
Definition: buffer.cc:1064
uint64_t ReadLsbtohU64()
Definition: buffer.cc:1094
void Next()
go forward by one byte
Definition: buffer.h:853
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: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_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
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