A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-eht-info-elems-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Universita' degli Studi di Napoli Federico II
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: Stefano Avallone <stavallo@unina.it>
18 */
19
20#include "ns3/address-utils.h"
21#include "ns3/header-serialization-test.h"
22#include "ns3/log.h"
23#include "ns3/mgt-headers.h"
24#include "ns3/multi-link-element.h"
25#include "ns3/reduced-neighbor-report.h"
26#include "ns3/simulator.h"
27#include "ns3/tid-to-link-mapping-element.h"
28#include "ns3/wifi-phy-operating-channel.h"
29#include "ns3/wifi-utils.h"
30
31#include <optional>
32#include <set>
33#include <sstream>
34#include <vector>
35
36using namespace ns3;
37
38NS_LOG_COMPONENT_DEFINE("WifiEhtInfoElemsTest");
39
47{
48 public:
54
64 const CommonInfoBasicMle& commonInfo,
65 std::vector<MultiLinkElement::PerStaProfileSubelement> subelements);
66
67 private:
68 void DoRun() override;
69
71};
72
75 "Check serialization and deserialization of Basic variant Multi-Link elements")
76{
77}
78
80{
81}
82
85 const CommonInfoBasicMle& commonInfo,
86 std::vector<MultiLinkElement::PerStaProfileSubelement> subelements)
87{
89 mle.SetMldMacAddress(commonInfo.m_mldMacAddress);
90 if (commonInfo.m_linkIdInfo.has_value())
91 {
92 mle.SetLinkIdInfo(*commonInfo.m_linkIdInfo);
93 }
94 if (commonInfo.m_bssParamsChangeCount.has_value())
95 {
97 }
98 if (commonInfo.m_mediumSyncDelayInfo.has_value())
99 {
101 MicroSeconds(32 * commonInfo.m_mediumSyncDelayInfo->mediumSyncDuration));
103 commonInfo.m_mediumSyncDelayInfo->mediumSyncOfdmEdThreshold - 72);
104 mle.SetMediumSyncMaxNTxops(commonInfo.m_mediumSyncDelayInfo->mediumSyncMaxNTxops + 1);
105 }
106 if (commonInfo.m_emlCapabilities.has_value())
107 {
108 auto padding = commonInfo.m_emlCapabilities->emlsrPaddingDelay;
109 mle.SetEmlsrPaddingDelay(MicroSeconds(padding == 0 ? 0 : (1 << (4 + padding))));
110 auto transitionD = commonInfo.m_emlCapabilities->emlsrTransitionDelay;
111 mle.SetEmlsrTransitionDelay(MicroSeconds(transitionD == 0 ? 0 : (1 << (3 + transitionD))));
112 auto transitionT = commonInfo.m_emlCapabilities->transitionTimeout;
113 mle.SetTransitionTimeout(MicroSeconds(transitionT == 0 ? 0 : (1 << (6 + transitionT))));
114 }
115
116 for (std::size_t i = 0; i < subelements.size(); ++i)
117 {
119 mle.GetPerStaProfile(i) = std::move(subelements[i]);
120 }
121
122 return mle;
123}
124
125void
127{
128 CommonInfoBasicMle commonInfo = {
129 .m_mldMacAddress = Mac48Address("01:23:45:67:89:ab"),
130 };
131
132 // Common Info with MLD MAC address
134
135 commonInfo.m_linkIdInfo = 3;
136
137 // Adding Link ID Info
139
140 commonInfo.m_bssParamsChangeCount = 1;
141
142 // Adding BSS Parameters Change Count
144
145 commonInfo.m_mediumSyncDelayInfo =
147 .mediumSyncOfdmEdThreshold = 4,
148 .mediumSyncMaxNTxops = 5};
149
150 // Adding Medium Sync Delay Information
152
154 .emlsrPaddingDelay = 4,
155 .emlsrTransitionDelay = 5,
156 .transitionTimeout = 10};
157
158 // Adding Medium Sync Delay Information
160
166 CapabilityInformation capabilities;
167 capabilities.SetShortPreamble(true);
168 capabilities.SetShortSlotTime(true);
169 capabilities.SetEss();
170
172 m_outerAssoc.Capabilities() = capabilities;
173 m_outerAssoc.Get<Ssid>() = Ssid("MySsid");
174
175 AllSupportedRates rates;
176 rates.AddSupportedRate(6e6);
177 rates.AddSupportedRate(9e6);
178 rates.AddSupportedRate(12e6);
179 rates.AddSupportedRate(18e6);
180 rates.AddSupportedRate(24e6);
181 rates.AddSupportedRate(36e6);
182 rates.AddSupportedRate(48e6);
183 rates.AddSupportedRate(54e6);
184 // extended rates
185 rates.AddSupportedRate(1e6);
186 rates.AddSupportedRate(2e6);
187
188 m_outerAssoc.Get<SupportedRates>() = rates.rates;
190
191 EhtCapabilities ehtCapabilities;
192 for (auto maxMcs : {7, 9, 11, 13})
193 {
195 maxMcs,
196 1);
198 maxMcs,
199 1);
200 }
201
202 m_outerAssoc.Get<HeCapabilities>().emplace();
203 m_outerAssoc.Get<EhtCapabilities>() = ehtCapabilities;
204
205 // The Association Request included in the first Per-STA Profile subelement is identical
206 // to the containing frame, so that all the IEs are inherited and the Per-STA Profile
207 // does not contain any Information Element.
208
210 perStaProfile1.SetLinkId(3);
211 perStaProfile1.SetCompleteProfile();
212 perStaProfile1.SetAssocRequest(m_outerAssoc);
213
214 /* Association Request included in the second Per-STA Profile subelement */
216 assoc.Capabilities() = capabilities;
217 // we simulate a "mistake" by adding an Ssid IE, which cannot be included in the
218 // Per-STA Profile subelement. We will check that this Ssid is not serialized
219 assoc.Get<Ssid>() = Ssid("OtherSsid");
220 // another "mistake" of the same type, except that a TID-To-Link Mapping element
221 // is not included in the containing frame
222 assoc.Get<TidToLinkMapping>().emplace_back();
223 // the SupportedRates IE is the same (hence not serialized) as in the containing frame,
224 // while the ExtendedSupportedRatesIE is different (hence serialized)
225 rates.AddSupportedRate(5.5e6);
226 rates.AddSupportedRate(11e6);
227 assoc.Get<SupportedRates>() = rates.rates;
228 assoc.Get<ExtendedSupportedRatesIE>() = rates.extendedRates;
229 // a VhtCapabilities IE is not present in the containing frame, hence it is serialized
230 assoc.Get<VhtCapabilities>().emplace();
231 // HeCapabilities IE is present in the containing frame and in the Per-STA Profile subelement,
232 // hence it is not serialized
233 assoc.Get<HeCapabilities>().emplace();
234 // EhtCapabilities IE is present in the containing frame but not in the Per-STA Profile
235 // subelement, hence it is listed in a Non-Inheritance element
236
238 perStaProfile2.SetLinkId(0);
239 perStaProfile2.SetCompleteProfile();
240 perStaProfile2.SetStaMacAddress(Mac48Address("ba:98:76:54:32:10"));
241 perStaProfile2.SetAssocRequest(assoc);
242
243 // The Association Request included in the third Per-STA Profile subelement has the
244 // EHT Capabilities element (which is inherited and not serialized) but it does not have the
245 // Ssid element, which is not listed in the Non-Inheritance element because it shall not
246 // appear in a Per-STA Profile subelement.
247 assoc.Get<Ssid>().reset();
248 assoc.Get<EhtCapabilities>() = ehtCapabilities;
249
250 auto perStaProfile3 = perStaProfile2;
251 perStaProfile3.SetAssocRequest(assoc);
252
253 // Adding MLE with two Per-STA Profile Subelements
255 GetMultiLinkElement(commonInfo, {perStaProfile1, perStaProfile2, perStaProfile3});
256
257 // first, check that serialization/deserialization of the whole Association Request works
259
260 // now, "manually" serialize and deserialize the header to check that the expected elements
261 // have been serialized
262 Buffer buffer;
263 buffer.AddAtStart(m_outerAssoc.GetSerializedSize());
264 m_outerAssoc.Serialize(buffer.Begin());
265
266 auto i = buffer.Begin();
268 i.ReadLsbtohU16(); // Listen interval
269
270 auto tmp = i;
271 i = Ssid().DeserializeIfPresent(tmp);
272 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "Ssid element not present");
273
275 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "SupportedRates element not present");
276
278 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp),
279 0,
280 "ExtendedSupportedRatesIE element not present");
281
283 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "HeCapabilities element not present");
284
285 // deserialize Multi-Link Element
286 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(), IE_EXTENSION, "IE_EXTENSION expected at the begin of MLE");
287 i.ReadU8(); // length
288 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
290 "IE_EXT_MULTI_LINK_ELEMENT expected");
291
292 uint16_t mlControl = i.ReadLsbtohU16();
293 auto nBytes = CommonInfoBasicMle().Deserialize(i, mlControl >> 4);
294 i.Next(nBytes);
295
296 // first Per-STA Profile subelement
297 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
299 "PER_STA_PROFILE_SUBELEMENT_ID expected");
300 i.ReadU8(); // length
301 i.ReadLsbtohU16(); // STA Control field
302 i.ReadU8(); // STA Info Length
303 // no STA address
305 // no Information Element
306
307 // second Per-STA Profile subelement
308 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
310 "PER_STA_PROFILE_SUBELEMENT_ID expected");
311 i.ReadU8(); // length
312 i.ReadLsbtohU16(); // STA Control field
313 i.ReadU8(); // STA Info Length
314 Mac48Address address;
315 ReadFrom(i, address);
317 // no Listen interval
318 // Ssid element not present (as mandated by specs)
319 // SupportedRates not present because it is inherited
320
322 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp),
323 0,
324 "ExtendedSupportedRatesIE element not present");
325
327 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "VhtCapabilities element not present");
328
329 // HeCapabilities not present because it is inherited
330 NonInheritance nonInheritance;
331 i = nonInheritance.DeserializeIfPresent(tmp = i);
332 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "Non-Inheritance element not present");
334 true,
335 "Non-Inheritance does not indicate EhtCapabilities");
336 NS_TEST_EXPECT_MSG_EQ(nonInheritance.m_elemIdList.size(),
337 0,
338 "Unexpected size for Elem ID list of Non-Inheritance element");
339 NS_TEST_EXPECT_MSG_EQ(nonInheritance.m_elemIdExtList.size(),
340 1,
341 "Unexpected size for Elem ID list of Non-Inheritance element");
342
343 // third Per-STA Profile subelement
344 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
346 "PER_STA_PROFILE_SUBELEMENT_ID expected");
347 i.ReadU8(); // length
348 i.ReadLsbtohU16(); // STA Control field
349 i.ReadU8(); // STA Info Length
350 ReadFrom(i, address);
352 // no Listen interval
353 // Ssid element not present (as mandated by specs)
354 // SupportedRates not present because it is inherited
355
357 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp),
358 0,
359 "ExtendedSupportedRatesIE element not present");
360
362 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "VhtCapabilities element not present");
363
364 // HeCapabilities not present because it is inherited
365 // EhtCapabilities not present because it is inherited
366
367 // the Multi-Link Element is done, we shall now find the EHT Capabilities of the
368 // containing Association Request frame
369 ehtCapabilities = EhtCapabilities(true, m_outerAssoc.Get<HeCapabilities>().value());
370 i = ehtCapabilities.DeserializeIfPresent(tmp = i);
371 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "EhtCapabilities element not present");
372
378 auto count = frame.Deserialize(buffer.Begin());
379
380 NS_TEST_EXPECT_MSG_EQ(count, buffer.GetSize(), "Unexpected number of deserialized bytes");
381
382 // containing frame
383 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().has_value(),
384 true,
385 "Containing frame should have SSID IE");
386 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
387 true,
388 "Containing frame should have Supported Rates IE");
389 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
390 true,
391 "Containing frame should have Extended Supported Rates IE");
392 NS_TEST_EXPECT_MSG_EQ(frame.Get<HtCapabilities>().has_value(),
393 false,
394 "Containing frame should not have HT Capabilities IE");
395 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedCapabilities>().has_value(),
396 false,
397 "Containing frame should not have Extended Capabilities IE");
398 NS_TEST_EXPECT_MSG_EQ(frame.Get<VhtCapabilities>().has_value(),
399 false,
400 "Containing frame should not have VHT Capabilities IE");
401 NS_TEST_EXPECT_MSG_EQ(frame.Get<HeCapabilities>().has_value(),
402 true,
403 "Containing frame should have HE Capabilities IE");
404 NS_TEST_EXPECT_MSG_EQ(frame.Get<MultiLinkElement>().has_value(),
405 true,
406 "Containing frame should have Multi-Link Element IE");
407 NS_TEST_EXPECT_MSG_EQ(frame.Get<EhtCapabilities>().has_value(),
408 true,
409 "Containing frame should have EHT Capabilities IE");
410 NS_TEST_EXPECT_MSG_EQ(frame.Get<TidToLinkMapping>().empty(),
411 true,
412 "Containing frame should not have TID-to-Link Mapping IE");
413
414 auto& mle = frame.Get<MultiLinkElement>().value();
415
416 NS_TEST_EXPECT_MSG_EQ(mle.GetNPerStaProfileSubelements(),
417 3,
418 "Unexpected number of Per-STA Profile subelements");
419
420 // frame in first Per-STA Profile subelement has inherited all the IEs but SSID and
421 // Multi-Link Element IEs
422 auto& perSta1 = mle.GetPerStaProfile(0);
423 NS_TEST_EXPECT_MSG_EQ(perSta1.HasAssocRequest(),
424 true,
425 "First Per-STA Profile should contain an Association Request frame");
426 auto& perSta1Frame =
427 std::get<std::reference_wrapper<MgtAssocRequestHeader>>(perSta1.GetAssocRequest()).get();
428
429 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<Ssid>().has_value(),
430 false,
431 "Frame in first Per-STA Profile should not have SSID IE");
432 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<SupportedRates>().has_value(),
433 true,
434 "Frame in first Per-STA Profile should have Supported Rates IE");
436 (perSta1Frame.Get<SupportedRates>() == frame.Get<SupportedRates>()),
437 true,
438 "Supported Rates IE not correctly inherited by frame in first Per-STA Profile");
439 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<ExtendedSupportedRatesIE>().has_value(),
440 true,
441 "Frame in first Per-STA Profile should have Extended Supported Rates IE");
443 (perSta1Frame.Get<ExtendedSupportedRatesIE>() == frame.Get<ExtendedSupportedRatesIE>()),
444 true,
445 "Extended Supported Rates IE not correctly inherited by frame in first Per-STA Profile");
446 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<HtCapabilities>().has_value(),
447 false,
448 "Frame in first Per-STA Profile should not have HT Capabilities IE");
450 perSta1Frame.Get<ExtendedCapabilities>().has_value(),
451 false,
452 "Frame in first Per-STA Profile should not have Extended Capabilities IE");
453 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<VhtCapabilities>().has_value(),
454 false,
455 "Frame in first Per-STA Profile should not have VHT Capabilities IE");
456 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<HeCapabilities>().has_value(),
457 true,
458 "Frame in first Per-STA Profile should have HE Capabilities IE");
460 (perSta1Frame.Get<HeCapabilities>() == frame.Get<HeCapabilities>()),
461 true,
462 "HE Capabilities IE not correctly inherited by frame in first Per-STA Profile");
463 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<MultiLinkElement>().has_value(),
464 false,
465 "Frame in first Per-STA Profile should not have Multi-Link Element IE");
466 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<EhtCapabilities>().has_value(),
467 true,
468 "Frame in first Per-STA Profile should have EHT Capabilities IE");
470 (perSta1Frame.Get<EhtCapabilities>() == frame.Get<EhtCapabilities>()),
471 true,
472 "EHT Capabilities IE not correctly inherited by frame in first Per-STA Profile");
473 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<TidToLinkMapping>().empty(),
474 true,
475 "Frame in first Per-STA Profile should not have TID-to-Link Mapping IE");
476
477 // frame in second Per-STA Profile subelement includes VHT Capabilities IE and has inherited
478 // all the IEs but SSID IE, Multi-Link Element IE, Extended Supported Rates IE (different
479 // than in containing frame) and EHT Capabilities IE (listed in Non-Inheritance IE).
480 auto& perSta2 = mle.GetPerStaProfile(1);
481 NS_TEST_EXPECT_MSG_EQ(perSta2.HasAssocRequest(),
482 true,
483 "Second Per-STA Profile should contain an Association Request frame");
484 auto& perSta2Frame =
485 std::get<std::reference_wrapper<MgtAssocRequestHeader>>(perSta2.GetAssocRequest()).get();
486
487 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<Ssid>().has_value(),
488 false,
489 "Frame in second Per-STA Profile should not have SSID IE");
490 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<SupportedRates>().has_value(),
491 true,
492 "Frame in second Per-STA Profile should have Supported Rates IE");
494 (perSta2Frame.Get<SupportedRates>() == frame.Get<SupportedRates>()),
495 true,
496 "Supported Rates IE not correctly inherited by frame in second Per-STA Profile");
498 perSta2Frame.Get<ExtendedSupportedRatesIE>().has_value(),
499 true,
500 "Frame in second Per-STA Profile should have Extended Supported Rates IE");
502 (perSta2Frame.Get<ExtendedSupportedRatesIE>() == frame.Get<ExtendedSupportedRatesIE>()),
503 false,
504 "Extended Supported Rates IE should have not been inherited by frame in second Per-STA "
505 "Profile");
506 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<HtCapabilities>().has_value(),
507 false,
508 "Frame in second Per-STA Profile should not have HT Capabilities IE");
510 perSta2Frame.Get<ExtendedCapabilities>().has_value(),
511 false,
512 "Frame in second Per-STA Profile should not have Extended Capabilities IE");
513 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<VhtCapabilities>().has_value(),
514 true,
515 "Frame in second Per-STA Profile should have VHT Capabilities IE");
516 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<HeCapabilities>().has_value(),
517 true,
518 "Frame in second Per-STA Profile should have HE Capabilities IE");
520 (perSta2Frame.Get<HeCapabilities>() == frame.Get<HeCapabilities>()),
521 true,
522 "HE Capabilities IE not correctly inherited by frame in second Per-STA Profile");
523 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<MultiLinkElement>().has_value(),
524 false,
525 "Frame in second Per-STA Profile should not have Multi-Link Element IE");
527 perSta2Frame.Get<EhtCapabilities>().has_value(),
528 false,
529 "Frame in second Per-STA Profile should have not inherited EHT Capabilities IE");
530 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<TidToLinkMapping>().empty(),
531 true,
532 "Frame in second Per-STA Profile should not have TID-to-Link Mapping IE");
533
534 // frame in third Per-STA Profile subelement includes VHT Capabilities IE and has inherited
535 // all the IEs but SSID IE, Multi-Link Element IE and Extended Supported Rates IE (different
536 // than in containing frame).
537 auto& perSta3 = mle.GetPerStaProfile(2);
538 NS_TEST_EXPECT_MSG_EQ(perSta3.HasAssocRequest(),
539 true,
540 "Third Per-STA Profile should contain an Association Request frame");
541 auto& perSta3Frame =
542 std::get<std::reference_wrapper<MgtAssocRequestHeader>>(perSta3.GetAssocRequest()).get();
543
544 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<Ssid>().has_value(),
545 false,
546 "Frame in third Per-STA Profile should not have SSID IE");
547 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<SupportedRates>().has_value(),
548 true,
549 "Frame in third Per-STA Profile should have Supported Rates IE");
551 (perSta3Frame.Get<SupportedRates>() == frame.Get<SupportedRates>()),
552 true,
553 "Supported Rates IE not correctly inherited by frame in third Per-STA Profile");
554 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<ExtendedSupportedRatesIE>().has_value(),
555 true,
556 "Frame in third Per-STA Profile should have Extended Supported Rates IE");
558 (perSta3Frame.Get<ExtendedSupportedRatesIE>() == frame.Get<ExtendedSupportedRatesIE>()),
559 false,
560 "Extended Supported Rates IE should have not been inherited by frame in third Per-STA "
561 "Profile");
562 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<HtCapabilities>().has_value(),
563 false,
564 "Frame in third Per-STA Profile should not have HT Capabilities IE");
566 perSta3Frame.Get<ExtendedCapabilities>().has_value(),
567 false,
568 "Frame in third Per-STA Profile should not have Extended Capabilities IE");
569 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<VhtCapabilities>().has_value(),
570 true,
571 "Frame in third Per-STA Profile should have VHT Capabilities IE");
572 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<HeCapabilities>().has_value(),
573 true,
574 "Frame in third Per-STA Profile should have HE Capabilities IE");
576 (perSta3Frame.Get<HeCapabilities>() == frame.Get<HeCapabilities>()),
577 true,
578 "HE Capabilities IE not correctly inherited by frame in third Per-STA Profile");
579 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<MultiLinkElement>().has_value(),
580 false,
581 "Frame in third Per-STA Profile should not have Multi-Link Element IE");
583 perSta3Frame.Get<EhtCapabilities>().has_value(),
584 true,
585 "Frame in third Per-STA Profile should have inherited EHT Capabilities IE");
587 (perSta3Frame.Get<EhtCapabilities>() == frame.Get<EhtCapabilities>()),
588 true,
589 "EHT Capabilities IE not correctly inherited by frame in third Per-STA Profile");
590 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<TidToLinkMapping>().empty(),
591 true,
592 "Frame in third Per-STA Profile should not have TID-to-Link Mapping IE");
593}
594
602{
603 public:
609
612
622 PhyOpChannelIt channel5It,
623 PhyOpChannelIt channel6It);
624
625 private:
626 void DoRun() override;
627};
628
631 "Check serialization and deserialization of Reduced Neighbor Report elements")
632{
633}
634
636{
637}
638
641 PhyOpChannelIt channel5It,
642 PhyOpChannelIt channel6It)
643{
645
646 std::stringstream info;
647
648 if (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
649 {
650 WifiPhyOperatingChannel channel(channel2_4It);
651
652 info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 2.4 GHz} ";
653 rnr.AddNbrApInfoField();
654 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
655 rnr.SetOperatingChannel(nbrId, channel);
656 // Add a TBTT Information Field
657 rnr.AddTbttInformationField(nbrId);
658 rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:24"));
659 rnr.SetShortSsid(nbrId, 0, 0);
660 rnr.SetBssParameters(nbrId, 0, 10);
661 rnr.SetPsd20MHz(nbrId, 0, 50);
662 rnr.SetMldParameters(nbrId, 0, 0, 2, 3);
663 }
664
665 if (channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
666 {
667 WifiPhyOperatingChannel channel(channel5It);
668
669 info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 5 GHz} ";
670 rnr.AddNbrApInfoField();
671 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
672 rnr.SetOperatingChannel(nbrId, channel);
673 // Add a TBTT Information Field
674 rnr.AddTbttInformationField(nbrId);
675 rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:05"));
676 rnr.SetShortSsid(nbrId, 0, 0);
677 rnr.SetBssParameters(nbrId, 0, 20);
678 rnr.SetPsd20MHz(nbrId, 0, 60);
679 rnr.SetMldParameters(nbrId, 0, 0, 3, 4);
680 // Add another TBTT Information Field
681 rnr.AddTbttInformationField(nbrId);
682 rnr.SetBssid(nbrId, 1, Mac48Address("00:00:00:00:01:05"));
683 rnr.SetShortSsid(nbrId, 1, 0);
684 rnr.SetBssParameters(nbrId, 1, 30);
685 rnr.SetPsd20MHz(nbrId, 1, 70);
686 rnr.SetMldParameters(nbrId, 1, 0, 4, 5);
687 }
688
689 if (channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
690 {
691 WifiPhyOperatingChannel channel(channel6It);
692
693 info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 6 GHz} ";
694 rnr.AddNbrApInfoField();
695 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
696 rnr.SetOperatingChannel(nbrId, channel);
697 // Add a TBTT Information Field
698 rnr.AddTbttInformationField(nbrId);
699 rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:06"));
700 rnr.SetShortSsid(nbrId, 0, 0);
701 rnr.SetBssParameters(nbrId, 0, 40);
702 rnr.SetPsd20MHz(nbrId, 0, 80);
703 rnr.SetMldParameters(nbrId, 0, 0, 5, 6);
704 }
705
706 NS_LOG_DEBUG(info.str());
707 return rnr;
708}
709
710void
712{
713 PhyOpChannelIt channel2_4It;
714 PhyOpChannelIt channel5It;
715 PhyOpChannelIt channel6It;
716 channel2_4It = channel5It = channel6It = WifiPhyOperatingChannel::m_frequencyChannels.cbegin();
717
718 // Test all available frequency channels
719 while (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend() ||
722 {
723 if (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
724 {
725 channel2_4It = WifiPhyOperatingChannel::FindFirst(0,
726 0,
727 0,
730 channel2_4It);
731 }
732 if (channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
733 {
735 0,
736 0,
739 channel5It);
740 }
741 if (channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
742 {
744 0,
745 0,
748 channel6It);
749 }
750
751 TestHeaderSerialization(GetReducedNeighborReport(channel2_4It, channel5It, channel6It));
752
753 // advance all channel iterators
754 if (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
755 {
756 channel2_4It++;
757 }
758 if (channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
759 {
760 channel5It++;
761 }
762 if (channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
763 {
764 channel6It++;
765 }
766 }
767}
768
776{
777 public:
783 WifiEhtCapabilitiesIeTest(bool is2_4Ghz, uint16_t channelWidth);
784 ~WifiEhtCapabilitiesIeTest() override = default;
785
792
801 EhtCapabilities GetEhtCapabilities(uint16_t maxMpduLength,
802 uint32_t maxAmpduSize,
803 uint8_t maxSupportedMcs) const;
804
811 Buffer SerializeIntoBuffer(const EhtCapabilities& ehtCapabilities);
812
820 void CheckSerializedByte(const Buffer& buffer, uint32_t position, uint8_t value);
821
828 void CheckEhtMacCapabilitiesInformation(const Buffer& buffer, uint8_t expectedValueFirstByte);
829
836 void CheckEhtPhyCapabilitiesInformation(const Buffer& buffer, uint8_t expectedValueSixthByte);
837
844 void CheckSupportedEhtMcsAndNssSet(const Buffer& buffer, uint8_t maxSupportedMcs);
845
846 private:
847 void DoRun() override;
848
850 uint16_t m_channelWidth;
851};
852
853WifiEhtCapabilitiesIeTest ::WifiEhtCapabilitiesIeTest(bool is2_4Ghz, uint16_t channelWidth)
854 : HeaderSerializationTestCase{"Check serialization and deserialization of EHT capabilities IE"},
855 m_is2_4Ghz{is2_4Ghz},
856 m_channelWidth{channelWidth}
857{
858}
859
862{
863 HeCapabilities capabilities;
864 uint8_t channelWidthSet = 0;
865 if ((m_channelWidth >= 40) && m_is2_4Ghz)
866 {
867 channelWidthSet |= 0x01;
868 }
869 if ((m_channelWidth >= 80) && !m_is2_4Ghz)
870 {
871 channelWidthSet |= 0x02;
872 }
873 if ((m_channelWidth >= 160) && !m_is2_4Ghz)
874 {
875 channelWidthSet |= 0x04;
876 }
877 capabilities.SetChannelWidthSet(channelWidthSet);
878 return capabilities;
879}
880
883 uint32_t maxAmpduSize,
884 uint8_t maxSupportedMcs) const
885{
886 EhtCapabilities capabilities;
887
888 if (m_is2_4Ghz)
889 {
890 capabilities.SetMaxMpduLength(maxMpduLength);
891 }
892 // round to the next power of two minus one
893 maxAmpduSize = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduSize + 1)))) - 1;
894 // The maximum A-MPDU length in EHT capabilities elements ranges from 2^23-1 to 2^24-1
895 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduSize, 8388607U), 16777215U));
896
898 (maxSupportedMcs >= 12) ? 1 : 0;
900 (maxSupportedMcs >= 12) ? 1 : 0;
901 if (m_channelWidth == 20)
902 {
903 for (auto maxMcs : {7, 9, 11, 13})
904 {
906 maxMcs,
907 maxMcs <= maxSupportedMcs ? 1 : 0);
909 maxMcs,
910 maxMcs <= maxSupportedMcs ? 2 : 0);
911 }
912 }
913 else
914 {
915 for (auto maxMcs : {9, 11, 13})
916 {
917 capabilities.SetSupportedRxEhtMcsAndNss(
919 maxMcs,
920 maxMcs <= maxSupportedMcs ? 3 : 0);
921 capabilities.SetSupportedTxEhtMcsAndNss(
923 maxMcs,
924 maxMcs <= maxSupportedMcs ? 4 : 0);
925 }
926 }
927 if (m_channelWidth >= 160)
928 {
929 for (auto maxMcs : {9, 11, 13})
930 {
932 maxMcs,
933 maxMcs <= maxSupportedMcs ? 2 : 0);
935 maxMcs,
936 maxMcs <= maxSupportedMcs ? 1 : 0);
937 }
938 }
939 if (m_channelWidth == 320)
940 {
941 capabilities.m_phyCapabilities.support320MhzIn6Ghz = 1;
942 for (auto maxMcs : {9, 11, 13})
943 {
945 maxMcs,
946 maxMcs <= maxSupportedMcs ? 4 : 0);
948 maxMcs,
949 maxMcs <= maxSupportedMcs ? 3 : 0);
950 }
951 }
952 else
953 {
954 capabilities.m_phyCapabilities.support320MhzIn6Ghz = 0;
955 }
956
957 return capabilities;
958}
959
960Buffer
962{
963 Buffer buffer;
964 buffer.AddAtStart(ehtCapabilities.GetSerializedSize());
965 ehtCapabilities.Serialize(buffer.Begin());
966 return buffer;
967}
968
969void
971 uint32_t position,
972 uint8_t value)
973{
974 Buffer::Iterator it = buffer.Begin();
975 it.Next(position);
976 uint8_t byte = it.ReadU8();
977 NS_TEST_EXPECT_MSG_EQ(+byte, +value, "Unexpected byte at pos=" << position);
978}
979
980void
982 uint8_t expectedValueFirstByte)
983{
984 CheckSerializedByte(buffer, 3, expectedValueFirstByte);
985 CheckSerializedByte(buffer, 4, 0x00);
986}
987
988void
990 uint8_t expectedValueSixthByte)
991{
992 CheckSerializedByte(buffer, 5, (m_channelWidth == 320) ? 0x02 : 0x00);
993 CheckSerializedByte(buffer, 6, 0x00);
994 CheckSerializedByte(buffer, 7, 0x00);
995 CheckSerializedByte(buffer, 8, 0x00);
996 CheckSerializedByte(buffer, 9, 0x00);
997 CheckSerializedByte(buffer, 10, expectedValueSixthByte);
998 CheckSerializedByte(buffer, 11, 0x00);
999 CheckSerializedByte(buffer, 12, 0x00);
1000 CheckSerializedByte(buffer, 13, 0x00);
1001}
1002
1003void
1005 uint8_t maxSupportedMcs)
1006{
1007 if (m_channelWidth == 20)
1008 {
1009 CheckSerializedByte(buffer, 14, 0x21); // first byte of Supported EHT-MCS And NSS Set
1011 buffer,
1012 15,
1013 maxSupportedMcs >= 8 ? 0x21 : 0x00); // second byte of Supported EHT-MCS And NSS Set
1015 buffer,
1016 16,
1017 maxSupportedMcs >= 10 ? 0x21 : 0x00); // third byte of Supported EHT-MCS And NSS Set
1019 buffer,
1020 17,
1021 maxSupportedMcs >= 12 ? 0x21 : 0x00); // fourth byte of Supported EHT-MCS And NSS Set
1022 }
1023 else
1024 {
1025 CheckSerializedByte(buffer, 14, 0x43); // first byte of Supported EHT-MCS And NSS Set
1027 buffer,
1028 15,
1029 maxSupportedMcs >= 10 ? 0x43 : 0x00); // second byte of Supported EHT-MCS And NSS Set
1031 buffer,
1032 16,
1033 maxSupportedMcs >= 12 ? 0x43 : 0x00); // third byte of Supported EHT-MCS And NSS Set
1034 }
1035 if (m_channelWidth >= 160)
1036 {
1037 CheckSerializedByte(buffer, 17, 0x12); // first byte of EHT-MCS Map (BW = 160 MHz)
1039 buffer,
1040 18,
1041 maxSupportedMcs >= 10 ? 0x12 : 0x00); // second byte of EHT-MCS Map (BW = 160 MHz)
1043 buffer,
1044 19,
1045 maxSupportedMcs >= 12 ? 0x12 : 0x00); // third byte of EHT-MCS Map (BW = 160 MHz)
1046 }
1047 if (m_channelWidth == 320)
1048 {
1049 CheckSerializedByte(buffer, 20, 0x34); // first byte of EHT-MCS Map (BW = 320 MHz)
1051 buffer,
1052 21,
1053 maxSupportedMcs >= 10 ? 0x34 : 0x00); // second byte of EHT-MCS Map (BW = 320 MHz)
1055 buffer,
1056 22,
1057 maxSupportedMcs >= 12 ? 0x34 : 0x00); // third byte of EHT-MCS Map (BW = 320 MHz)
1058 }
1059}
1060
1061void
1063{
1064 uint8_t maxMcs = 0;
1065 uint16_t expectedEhtMcsAndNssSetSize = 0;
1066 switch (m_channelWidth)
1067 {
1068 case 20:
1069 expectedEhtMcsAndNssSetSize = 4;
1070 break;
1071 case 40:
1072 case 80:
1073 expectedEhtMcsAndNssSetSize = 3;
1074 break;
1075 case 160:
1076 expectedEhtMcsAndNssSetSize = (2 * 3);
1077 break;
1078 case 320:
1079 expectedEhtMcsAndNssSetSize = (3 * 3);
1080 break;
1081 default:
1082 NS_ASSERT_MSG(false, "Invalid upper channel width " << m_channelWidth);
1083 }
1084
1085 uint16_t expectedSize = 1 + // Element ID
1086 1 + // Length
1087 1 + // Element ID Extension
1088 2 + // EHT MAC Capabilities Information
1089 9 + // EHT PHY Capabilities Information
1090 expectedEhtMcsAndNssSetSize; // Supported EHT-MCS And NSS Set
1091
1094
1095 {
1096 maxMcs = 11;
1097 HeCapabilities heCapabilities = GetHeCapabilities();
1098 EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
1099
1100 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1101 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1102
1103 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1104 expectedSize,
1105 "Unexpected header size");
1106
1107 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1108
1110
1112
1113 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1114
1115 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1116 }
1117
1118 {
1119 maxMcs = 11;
1120 HeCapabilities heCapabilities = GetHeCapabilities();
1121 EhtCapabilities ehtCapabilities = GetEhtCapabilities(11454, 65535, maxMcs);
1122
1123 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1124 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1125
1126 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1127 expectedSize,
1128 "Unexpected header size");
1129
1130 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1131
1132 CheckEhtMacCapabilitiesInformation(buffer, m_is2_4Ghz ? 0x80 : 0x00);
1133
1135
1136 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1137
1138 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1139 }
1140
1141 {
1142 maxMcs = 13;
1143 HeCapabilities heCapabilities = GetHeCapabilities();
1144 EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
1145
1146 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1147 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1148
1149 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1150 expectedSize,
1151 "Unexpected header size");
1152
1153 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1154
1156
1158
1159 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1160
1161 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1162 }
1163
1164 {
1165 maxMcs = 11;
1166 HeCapabilities heCapabilities = GetHeCapabilities();
1167 EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
1168
1169 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1170 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1171
1172 std::vector<std::pair<uint8_t, uint8_t>> ppeThresholds;
1173 ppeThresholds.emplace_back(1, 2); // NSS1 242-tones RU
1174 ppeThresholds.emplace_back(2, 3); // NSS1 484-tones RU
1175 ppeThresholds.emplace_back(3, 4); // NSS2 242-tones RU
1176 ppeThresholds.emplace_back(4, 3); // NSS2 484-tones RU
1177 ppeThresholds.emplace_back(3, 2); // NSS3 242-tones RU
1178 ppeThresholds.emplace_back(2, 1); // NSS3 484-tones RU
1179 ehtCapabilities.SetPpeThresholds(2, 0x03, ppeThresholds);
1180
1181 expectedSize += 6;
1182
1183 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1184 expectedSize,
1185 "Unexpected header size");
1186
1187 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1188
1190
1192
1193 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1194
1195 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1196 }
1197}
1198
1206{
1207 public:
1217 std::optional<Time> mappingSwitchTime,
1218 std::optional<Time> expectedDuration,
1219 const WifiTidLinkMapping& mappings);
1220
1221 ~TidToLinkMappingElementTest() override = default;
1222
1223 private:
1224 void DoSetup() override;
1225 void DoRun() override;
1226
1228 std::optional<Time> m_mappingSwitchTime;
1229 std::optional<Time> m_expectedDuration;
1232};
1233
1235 std::optional<Time> mappingSwitchTime,
1236 std::optional<Time> expectedDuration,
1237 const WifiTidLinkMapping& mappings)
1239 "Check serialization and deserialization of TID-To-Link Mapping elements"),
1240 m_direction(direction),
1241 m_mappingSwitchTime(mappingSwitchTime),
1242 m_expectedDuration(expectedDuration),
1243 m_mappings(mappings)
1244{
1245}
1246
1247void
1249{
1252
1254 {
1256 std::optional<Time> encoded = m_tidToLinkMapping.GetMappingSwitchTime();
1257 NS_TEST_ASSERT_MSG_EQ(encoded.has_value(), true, "Mapping Switch Time should be present");
1259 *encoded,
1260 "Incorrect Mapping Switch Time value");
1261 }
1263 {
1265 std::optional<Time> encoded = m_tidToLinkMapping.GetExpectedDuration();
1266 NS_TEST_ASSERT_MSG_EQ(encoded.has_value(), true, "Expected Duration should be present");
1267 NS_TEST_EXPECT_MSG_EQ(*m_expectedDuration, *encoded, "Incorrect Expected Duration value");
1268 }
1269
1270 for (const auto& [tid, linkSet] : m_mappings)
1271 {
1275 true,
1276 "Incorrect link set for TID " << +tid);
1277 }
1278}
1279
1280void
1282{
1284
1286}
1287
1295{
1296 public:
1312 uint8_t rxMaxNss0_7,
1313 uint8_t txMaxNss0_7,
1314 uint8_t rxMaxNss8_9,
1315 uint8_t txMaxNss8_9,
1316 uint8_t rxMaxNss10_11,
1317 uint8_t txMaxNss10_11,
1318 uint8_t rxMaxNss12_13,
1319 uint8_t txMaxNss12_13,
1320 std::optional<EhtOperation::EhtOpInfo> opInfo);
1321
1322 ~EhtOperationElementTest() override = default;
1323
1324 private:
1325 void DoRun() override;
1326
1328};
1329
1331 uint8_t rxMaxNss0_7,
1332 uint8_t txMaxNss0_7,
1333 uint8_t rxMaxNss8_9,
1334 uint8_t txMaxNss8_9,
1335 uint8_t rxMaxNss10_11,
1336 uint8_t txMaxNss10_11,
1337 uint8_t rxMaxNss12_13,
1338 uint8_t txMaxNss12_13,
1339 std::optional<EhtOperation::EhtOpInfo> opInfo)
1341 "Check serialization and deserialization of EHT Operation elements")
1342{
1343 m_ehtOperation.m_params = params;
1344 m_ehtOperation.SetMaxRxNss(rxMaxNss0_7, 0, 7);
1345 m_ehtOperation.SetMaxTxNss(txMaxNss0_7, 0, 7);
1346 m_ehtOperation.SetMaxRxNss(rxMaxNss8_9, 8, 9);
1347 m_ehtOperation.SetMaxTxNss(txMaxNss8_9, 8, 9);
1348 m_ehtOperation.SetMaxRxNss(rxMaxNss10_11, 10, 11);
1349 m_ehtOperation.SetMaxTxNss(txMaxNss10_11, 10, 11);
1350 m_ehtOperation.SetMaxRxNss(rxMaxNss12_13, 12, 13);
1351 m_ehtOperation.SetMaxTxNss(txMaxNss12_13, 12, 13);
1352 m_ehtOperation.m_opInfo = opInfo;
1353}
1354
1355void
1357{
1359}
1360
1368{
1369 public:
1371};
1372
1374 : TestSuite("wifi-eht-info-elems", UNIT)
1375{
1386 new TidToLinkMappingElementTest(WifiDirection::DOWNLINK, std::nullopt, std::nullopt, {}),
1388 AddTestCase(new TidToLinkMappingElementTest(WifiDirection::UPLINK,
1389 MicroSeconds(500 * 1024),
1390 MicroSeconds(300 * 1024),
1391 {{3, std::set<uint8_t>{0, 4, 6}}}),
1394 WifiDirection::BOTH_DIRECTIONS,
1395 std::nullopt,
1396 MicroSeconds(100 * 1024),
1397 {{3, std::set<uint8_t>{0, 4, 6}}, {6, std::set<uint8_t>{3, 7, 11, 14}}}),
1399 AddTestCase(new TidToLinkMappingElementTest(WifiDirection::DOWNLINK,
1400 MicroSeconds(100 * 1024),
1401 std::nullopt,
1402 {{0, std::set<uint8_t>{0, 1, 2}},
1403 {1, std::set<uint8_t>{3, 4, 5}},
1404 {2, std::set<uint8_t>{6, 7}},
1405 {3, std::set<uint8_t>{8, 9, 10}},
1406 {4, std::set<uint8_t>{11, 12, 13}},
1407 {5, std::set<uint8_t>{14}},
1408 {6, std::set<uint8_t>{1, 3, 6}},
1409 {7, std::set<uint8_t>{11, 14}}}),
1411 AddTestCase(new EhtOperationElementTest({0, 0, 0, 0, 0}, 1, 2, 3, 4, 5, 6, 7, 8, std::nullopt),
1413 AddTestCase(new EhtOperationElementTest({1, 0, 0, 1, 0},
1414 1,
1415 2,
1416 3,
1417 4,
1418 5,
1419 6,
1420 7,
1421 8,
1422 EhtOperation::EhtOpInfo{{1}, 3, 5}),
1424 AddTestCase(new EhtOperationElementTest({1, 1, 1, 1, 2},
1425 1,
1426 2,
1427 3,
1428 4,
1429 5,
1430 6,
1431 7,
1432 8,
1433 EhtOperation::EhtOpInfo{{2}, 4, 6, 3000}),
1435}
1436
Test EHT Operation information element serialization and deserialization.
void DoRun() override
Implementation to actually run this TestCase.
EhtOperationElementTest(const EhtOperation::EhtOpParams &params, uint8_t rxMaxNss0_7, uint8_t txMaxNss0_7, uint8_t rxMaxNss8_9, uint8_t txMaxNss8_9, uint8_t rxMaxNss10_11, uint8_t txMaxNss10_11, uint8_t rxMaxNss12_13, uint8_t txMaxNss12_13, std::optional< EhtOperation::EhtOpInfo > opInfo)
Constructor.
EhtOperation m_ehtOperation
EHT Operation element.
~EhtOperationElementTest() override=default
Test Reduced Neighbor Report serialization and deserialization.
ReducedNeighborReport GetReducedNeighborReport(PhyOpChannelIt channel2_4It, PhyOpChannelIt channel5It, PhyOpChannelIt channel6It)
Get a Reduced Neighbor Report element including the given operating channels.
void DoRun() override
Implementation to actually run this TestCase.
WifiPhyOperatingChannel::ConstIterator PhyOpChannelIt
typedef for const iterator on the set of available channels
Test serialization and deserialization of EHT capabilities IE.
void CheckSerializedByte(const Buffer &buffer, uint32_t position, uint8_t value)
Check that the given buffer contains the given value at the given position.
void DoRun() override
Implementation to actually run this TestCase.
HeCapabilities GetHeCapabilities() const
Generate the HE capabilities IE.
bool m_is2_4Ghz
whether the PHY is operating in 2.4 GHz
void CheckSupportedEhtMcsAndNssSet(const Buffer &buffer, uint8_t maxSupportedMcs)
Check the content of the Supported EHT-MCS And NSS Set subfield.
~WifiEhtCapabilitiesIeTest() override=default
Buffer SerializeIntoBuffer(const EhtCapabilities &ehtCapabilities)
Serialize the EHT capabilities in a buffer.
uint16_t m_channelWidth
Supported channel width by the PHY (in MHz)
EhtCapabilities GetEhtCapabilities(uint16_t maxMpduLength, uint32_t maxAmpduSize, uint8_t maxSupportedMcs) const
Generate the EHT capabilities IE.
void CheckEhtMacCapabilitiesInformation(const Buffer &buffer, uint8_t expectedValueFirstByte)
Check the content of the EHT MAC Capabilities Information subfield.
void CheckEhtPhyCapabilitiesInformation(const Buffer &buffer, uint8_t expectedValueSixthByte)
Check the content of the EHT PHY Capabilities Information subfield.
wifi EHT Information Elements Test Suite
iterator in a Buffer instance
Definition: buffer.h:100
uint8_t ReadU8()
Definition: buffer.h:1027
uint16_t ReadLsbtohU16()
Definition: buffer.cc:1070
void Next()
go forward by one byte
Definition: buffer.h:853
automatically resized byte buffer
Definition: buffer.h:94
uint32_t GetSize() const
Definition: buffer.h:1068
void AddAtStart(uint32_t start)
Definition: buffer.cc:314
Buffer::Iterator Begin() const
Definition: buffer.h:1074
void SetEss()
Set the Extended Service Set (ESS) bit in the capability information field.
void SetShortSlotTime(bool shortSlotTime)
Set the short slot time bit in the capability information field.
void SetShortPreamble(bool shortPreamble)
Set the short preamble bit in the capability information field.
Buffer::Iterator Deserialize(Buffer::Iterator start)
Deserialize capability information from the given buffer.
The IEEE 802.11be EHT Capabilities.
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 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.
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.
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.
EHT Operation Information Element.
Definition: eht-operation.h:66
void SetMaxTxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
Set the max Tx NSS for input MCS index range.
void SetMaxRxNss(uint8_t maxNss, uint8_t mcsStart, uint8_t mcsEnd)
Set the max Rx NSS for input MCS index range.
EhtOpParams m_params
EHT Operation Parameters.
std::optional< EhtOpInfo > m_opInfo
EHT Operation Information.
The Extended Capabilities Information Element.
The Extended Supported Rates Information Element.
The IEEE 802.11ax HE Capabilities.
void SetChannelWidthSet(uint8_t channelWidthSet)
Set channel width set.
Subclass of TestCase class adding the ability to test the serialization and deserialization of a Head...
void TestHeaderSerialization(const T &hdr, Args &&... args)
Serialize the given header in a buffer, then create a new header by deserializing from the buffer and...
The HT Capabilities Information Element.
an EUI-48 address
Definition: mac48-address.h:46
Implement the header for management frames of type association request.
Definition: mgt-headers.h:161
CapabilityInformation & Capabilities()
Definition: mgt-headers.cc:194
void SetListenInterval(uint16_t interval)
Set the listen interval.
Definition: mgt-headers.cc:182
The IEEE 802.11 Non-Inheritance Information Element.
std::set< uint8_t > m_elemIdList
list of unique Element ID values (in increasing order)
bool IsPresent(uint8_t elemId, uint8_t elemIdExt=0) const
std::set< uint8_t > m_elemIdExtList
list of unique Element ID Extension values
The Reduced Neighbor Report element.
std::size_t GetNNbrApInfoFields() const
Get the number of Neighbor AP Information fields.
void SetMldParameters(std::size_t nbrApInfoId, std::size_t index, uint8_t mldId, uint8_t linkId, uint8_t changeSequence)
Set the MLD Parameters subfield of the i-th TBTT Information field of the given Neighbor AP Informati...
void SetShortSsid(std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid)
Set the Short SSID field of the i-th TBTT Information field of the given Neighbor AP Information fiel...
void SetBssid(std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid)
Set the BSSID field of the i-th TBTT Information field of the given Neighbor AP Information field.
void SetPsd20MHz(std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz)
Set the 20 MHz PSD field of the i-th TBTT Information field of the given Neighbor AP Information fiel...
void AddNbrApInfoField()
Add a Neighbor AP Information field.
void SetBssParameters(std::size_t nbrApInfoId, std::size_t index, uint8_t bssParameters)
Set the BSS Parameters field of the i-th TBTT Information field of the given Neighbor AP Information ...
void AddTbttInformationField(std::size_t nbrApInfoId)
Add a TBTT Information fields to the TBTT Information Set field of the given Neighbor AP Information ...
void SetOperatingChannel(std::size_t nbrApInfoId, const WifiPhyOperatingChannel &channel)
Set the Operating Class and the Channel Number fields of the given Neighbor AP Information field base...
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
The Supported Rates Information Element.
@ QUICK
Fast test.
Definition: test.h:1065
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
The IEEE 802.11ac VHT Capabilities.
uint16_t GetSerializedSize() const
Get the size of the serialized IE including Element ID and length fields (for every element this IE i...
Buffer::Iterator Serialize(Buffer::Iterator i) const
Serialize entire IE including Element ID and length fields.
Buffer::Iterator DeserializeIfPresent(Buffer::Iterator i)
Deserialize entire IE (which may possibly be fragmented into multiple elements) if it is present.
Class that keeps track of all information about the current PHY operating channel.
static const std::set< FrequencyChannelInfo > m_frequencyChannels
Available frequency channels.
static ConstIterator FindFirst(uint8_t number, uint16_t frequency, uint16_t width, WifiStandard standard, WifiPhyBand band, ConstIterator start=m_frequencyChannels.begin())
Find the first channel matching the specified parameters.
std::set< FrequencyChannelInfo >::const_iterator ConstIterator
Typedef for a const iterator pointing to a channel in the set of available channels.
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg)
Test that an actual value is greater than a limit and report if not.
Definition: test.h:956
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1349
@ WIFI_STANDARD_80211be
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiDirection
Wifi direction.
Definition: wifi-utils.h:43
std::map< uint8_t, std::set< uint8_t > > WifiTidLinkMapping
TID-indexed map of the link set to which the TID is mapped.
Definition: wifi-utils.h:74
void ReadFrom(Buffer::Iterator &i, Ipv4Address &ad)
Read an Ipv4Address from a Buffer.
Struct containing all supported rates.
SupportedRates rates
supported rates
std::optional< ExtendedSupportedRatesIE > extendedRates
supported extended rates
void AddSupportedRate(uint64_t bs)
Add the given rate to the supported rates.
Medium Synchronization Delay Information subfield.
uint8_t mediumSyncDuration
Medium Synchronization Duration.
Common Info field of the Basic Multi-Link element.
std::optional< EmlCapabilities > m_emlCapabilities
EML Capabilities.
uint8_t Deserialize(Buffer::Iterator start, uint16_t presence)
Deserialize the Common Info field.
std::optional< MediumSyncDelayInfo > m_mediumSyncDelayInfo
Medium Synchronization Delay Information.
Mac48Address m_mldMacAddress
Subfields.
std::optional< uint8_t > m_bssParamsChangeCount
BSS Parameters Change Count.
std::optional< uint8_t > m_linkIdInfo
Link ID Info.
EHT Operation Information subfield IEEE 802.11be D2.0 Figure 9-1002c.
EHT Operation Parameters subfield IEEE 802.11be D2.0 Figure 9-1002b.
Definition: eht-operation.h:73
uint8_t support320MhzIn6Ghz
Support For 320 MHz In 6 GHz.
uint8_t supportTx1024And4096QamForRuSmallerThan242Tones
Tx 1024-QAM And 4096-QAM < 242-tone RU Support.
uint8_t supportRx1024And4096QamForRuSmallerThan242Tones
Rx 1024-QAM And 4096-QAM < 242-tone RU Support.
static WifiEhtInfoElemsTestSuite g_wifiEhtInfoElemsTestSuite
the test suite
#define IE_EXT_EHT_CAPABILITIES
#define IE_EXTENSION
#define IE_EXT_MULTI_LINK_ELEMENT