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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
9#include "ns3/address-utils.h"
10#include "ns3/header-serialization-test.h"
11#include "ns3/log.h"
12#include "ns3/mgt-headers.h"
13#include "ns3/multi-link-element.h"
14#include "ns3/reduced-neighbor-report.h"
15#include "ns3/simulator.h"
16#include "ns3/tid-to-link-mapping-element.h"
17#include "ns3/wifi-phy-operating-channel.h"
18#include "ns3/wifi-utils.h"
19
20#include <optional>
21#include <set>
22#include <sstream>
23#include <vector>
24
25using namespace ns3;
26
27NS_LOG_COMPONENT_DEFINE("WifiEhtInfoElemsTest");
28
29/**
30 * @ingroup wifi-test
31 * @ingroup tests
32 *
33 * @brief Test Multi-Link Element (Basic variant) serialization and deserialization
34 */
36{
37 public:
38 /**
39 * Constructor
40 */
43
44 /**
45 * Get a Multi-Link Element including the given Common Info field and the
46 * given Per-STA Profile Subelements
47 *
48 * @param commonInfo the given Common Info field
49 * @param subelements the given set of Per-STA Profile Subelements
50 * @return a Multi-Link Element
51 */
53 const CommonInfoBasicMle& commonInfo,
54 std::vector<MultiLinkElement::PerStaProfileSubelement> subelements);
55
56 private:
57 void DoRun() override;
58
59 MgtAssocRequestHeader m_outerAssoc; //!< the frame containing the MLE
60};
61
64 "Check serialization and deserialization of Basic variant Multi-Link elements")
65{
66}
67
71
74 const CommonInfoBasicMle& commonInfo,
75 std::vector<MultiLinkElement::PerStaProfileSubelement> subelements)
76{
78 mle.SetMldMacAddress(commonInfo.m_mldMacAddress);
79 if (commonInfo.m_linkIdInfo.has_value())
80 {
81 mle.SetLinkIdInfo(*commonInfo.m_linkIdInfo);
82 }
83 if (commonInfo.m_bssParamsChangeCount.has_value())
84 {
86 }
87 if (commonInfo.m_mediumSyncDelayInfo.has_value())
88 {
90 MicroSeconds(32 * commonInfo.m_mediumSyncDelayInfo->mediumSyncDuration));
92 commonInfo.m_mediumSyncDelayInfo->mediumSyncOfdmEdThreshold - 72);
94 commonInfo.m_mediumSyncDelayInfo->mediumSyncMaxNTxops + 1);
95 }
96 if (commonInfo.m_emlCapabilities.has_value())
97 {
98 auto padding = commonInfo.m_emlCapabilities->emlsrPaddingDelay;
99 mle.SetEmlsrPaddingDelay(MicroSeconds(padding == 0 ? 0 : (1 << (4 + padding))));
100 auto transitionD = commonInfo.m_emlCapabilities->emlsrTransitionDelay;
101 mle.SetEmlsrTransitionDelay(MicroSeconds(transitionD == 0 ? 0 : (1 << (3 + transitionD))));
102 auto transitionT = commonInfo.m_emlCapabilities->transitionTimeout;
103 mle.SetTransitionTimeout(MicroSeconds(transitionT == 0 ? 0 : (1 << (6 + transitionT))));
104 }
105
106 for (std::size_t i = 0; i < subelements.size(); ++i)
107 {
109 mle.GetPerStaProfile(i) = std::move(subelements[i]);
110 }
111
112 return mle;
113}
114
115void
117{
118 CommonInfoBasicMle commonInfo = {
119 .m_mldMacAddress = Mac48Address("01:23:45:67:89:ab"),
120 };
121
122 // Common Info with MLD MAC address
124
125 commonInfo.m_linkIdInfo = 3;
126
127 // Adding Link ID Info
129
130 commonInfo.m_bssParamsChangeCount = 1;
131
132 // Adding BSS Parameters Change Count
134
135 commonInfo.m_mediumSyncDelayInfo =
136 CommonInfoBasicMle::MediumSyncDelayInfo{.mediumSyncDuration = 1,
137 .mediumSyncOfdmEdThreshold = 4,
138 .mediumSyncMaxNTxops = 5};
139
140 // Adding Medium Sync Delay Information
142
143 commonInfo.m_emlCapabilities = CommonInfoBasicMle::EmlCapabilities{.emlsrSupport = 1,
144 .emlsrPaddingDelay = 4,
145 .emlsrTransitionDelay = 5,
146 .transitionTimeout = 10};
147
148 // Adding Medium Sync Delay Information
150
151 /**
152 * To test the serialization/deserialization of Per-STA Profile subelements, we include
153 * the Multi-Link Element in an Association Request frame
154 */
155
156 CapabilityInformation capabilities;
157 capabilities.SetShortPreamble(true);
158 capabilities.SetShortSlotTime(true);
159 capabilities.SetEss();
160
161 m_outerAssoc.SetListenInterval(0);
162 m_outerAssoc.Capabilities() = capabilities;
163 m_outerAssoc.Get<Ssid>() = Ssid("MySsid");
164
165 AllSupportedRates rates;
166 rates.AddSupportedRate(6e6);
167 rates.AddSupportedRate(9e6);
168 rates.AddSupportedRate(12e6);
169 rates.AddSupportedRate(18e6);
170 rates.AddSupportedRate(24e6);
171 rates.AddSupportedRate(36e6);
172 rates.AddSupportedRate(48e6);
173 rates.AddSupportedRate(54e6);
174 // extended rates
175 rates.AddSupportedRate(1e6);
176 rates.AddSupportedRate(2e6);
177
178 m_outerAssoc.Get<SupportedRates>() = rates.rates;
180
181 EhtCapabilities ehtCapabilities;
182 for (auto maxMcs : {7, 9, 11, 13})
183 {
185 maxMcs,
186 1);
188 maxMcs,
189 1);
190 }
191
192 m_outerAssoc.Get<HeCapabilities>().emplace();
193 m_outerAssoc.Get<EhtCapabilities>() = ehtCapabilities;
194
195 // The Association Request included in the first Per-STA Profile subelement is identical
196 // to the containing frame, so that all the IEs are inherited and the Per-STA Profile
197 // does not contain any Information Element.
198
200 perStaProfile1.SetLinkId(3);
201 perStaProfile1.SetCompleteProfile();
202 perStaProfile1.SetAssocRequest(m_outerAssoc);
203
204 /* Association Request included in the second Per-STA Profile subelement */
206 assoc.Capabilities() = capabilities;
207 // we simulate a "mistake" by adding an Ssid IE, which cannot be included in the
208 // Per-STA Profile subelement. We will check that this Ssid is not serialized
209 assoc.Get<Ssid>() = Ssid("OtherSsid");
210 // another "mistake" of the same type, except that a TID-To-Link Mapping element
211 // is not included in the containing frame
212 assoc.Get<TidToLinkMapping>().emplace_back();
213 // the SupportedRates IE is the same (hence not serialized) as in the containing frame,
214 // while the ExtendedSupportedRatesIE is different (hence serialized)
215 rates.AddSupportedRate(5.5e6);
216 rates.AddSupportedRate(11e6);
217 assoc.Get<SupportedRates>() = rates.rates;
218 assoc.Get<ExtendedSupportedRatesIE>() = rates.extendedRates;
219 // a VhtCapabilities IE is not present in the containing frame, hence it is serialized
220 assoc.Get<VhtCapabilities>().emplace();
221 // HeCapabilities IE is present in the containing frame and in the Per-STA Profile subelement,
222 // hence it is not serialized
223 assoc.Get<HeCapabilities>().emplace();
224 // EhtCapabilities IE is present in the containing frame but not in the Per-STA Profile
225 // subelement, hence it is listed in a Non-Inheritance element
226
228 perStaProfile2.SetLinkId(0);
229 perStaProfile2.SetCompleteProfile();
230 perStaProfile2.SetStaMacAddress(Mac48Address("ba:98:76:54:32:10"));
231 perStaProfile2.SetAssocRequest(assoc);
232
233 // The Association Request included in the third Per-STA Profile subelement has the
234 // EHT Capabilities element (which is inherited and not serialized) but it does not have the
235 // Ssid element, which is not listed in the Non-Inheritance element because it shall not
236 // appear in a Per-STA Profile subelement.
237 assoc.Get<Ssid>().reset();
238 assoc.Get<EhtCapabilities>() = ehtCapabilities;
239
240 auto perStaProfile3 = perStaProfile2;
241 perStaProfile3.SetAssocRequest(assoc);
242
243 // Adding MLE with two Per-STA Profile Subelements
245 GetMultiLinkElement(commonInfo, {perStaProfile1, perStaProfile2, perStaProfile3});
246
247 // first, check that serialization/deserialization of the whole Association Request works
249
250 // now, "manually" serialize and deserialize the header to check that the expected elements
251 // have been serialized
252 Buffer buffer;
253 buffer.AddAtStart(m_outerAssoc.GetSerializedSize());
254 m_outerAssoc.Serialize(buffer.Begin());
255
256 auto i = buffer.Begin();
258 i.ReadLsbtohU16(); // Listen interval
259
260 auto tmp = i;
261 i = Ssid().DeserializeIfPresent(tmp);
262 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "Ssid element not present");
263
265 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "SupportedRates element not present");
266
268 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp),
269 0,
270 "ExtendedSupportedRatesIE element not present");
271
273 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "HeCapabilities element not present");
274
275 // deserialize Multi-Link Element
276 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(), IE_EXTENSION, "IE_EXTENSION expected at the begin of MLE");
277 i.ReadU8(); // length
278 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
280 "IE_EXT_MULTI_LINK_ELEMENT expected");
281
282 uint16_t mlControl = i.ReadLsbtohU16();
283 auto nBytes = CommonInfoBasicMle().Deserialize(i, mlControl >> 4);
284 i.Next(nBytes);
285
286 // first Per-STA Profile subelement
287 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
289 "PER_STA_PROFILE_SUBELEMENT_ID expected");
290 i.ReadU8(); // length
291 i.ReadLsbtohU16(); // STA Control field
292 i.ReadU8(); // STA Info Length
293 // no STA address
295 // no Information Element
296
297 // second Per-STA Profile subelement
298 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
300 "PER_STA_PROFILE_SUBELEMENT_ID expected");
301 i.ReadU8(); // length
302 i.ReadLsbtohU16(); // STA Control field
303 i.ReadU8(); // STA Info Length
304 Mac48Address address;
305 ReadFrom(i, address);
307 // no Listen interval
308 // Ssid element not present (as mandated by specs)
309 // SupportedRates not present because it is inherited
310
312 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp),
313 0,
314 "ExtendedSupportedRatesIE element not present");
315
317 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "VhtCapabilities element not present");
318
319 // HeCapabilities not present because it is inherited
320 NonInheritance nonInheritance;
321 i = nonInheritance.DeserializeIfPresent(tmp = i);
322 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "Non-Inheritance element not present");
324 true,
325 "Non-Inheritance does not indicate EhtCapabilities");
326 NS_TEST_EXPECT_MSG_EQ(nonInheritance.m_elemIdList.size(),
327 0,
328 "Unexpected size for Elem ID list of Non-Inheritance element");
329 NS_TEST_EXPECT_MSG_EQ(nonInheritance.m_elemIdExtList.size(),
330 1,
331 "Unexpected size for Elem ID list of Non-Inheritance element");
332
333 // third Per-STA Profile subelement
334 NS_TEST_EXPECT_MSG_EQ(i.ReadU8(),
336 "PER_STA_PROFILE_SUBELEMENT_ID expected");
337 i.ReadU8(); // length
338 i.ReadLsbtohU16(); // STA Control field
339 i.ReadU8(); // STA Info Length
340 ReadFrom(i, address);
342 // no Listen interval
343 // Ssid element not present (as mandated by specs)
344 // SupportedRates not present because it is inherited
345
347 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp),
348 0,
349 "ExtendedSupportedRatesIE element not present");
350
352 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "VhtCapabilities element not present");
353
354 // HeCapabilities not present because it is inherited
355 // EhtCapabilities not present because it is inherited
356
357 // the Multi-Link Element is done, we shall now find the EHT Capabilities of the
358 // containing Association Request frame
359 ehtCapabilities = EhtCapabilities(true, m_outerAssoc.Get<HeCapabilities>().value());
360 i = ehtCapabilities.DeserializeIfPresent(tmp = i);
361 NS_TEST_EXPECT_MSG_GT(i.GetDistanceFrom(tmp), 0, "EhtCapabilities element not present");
362
363 /**
364 * Yet another test: use the Deserialize method of the management frame and check that
365 * inherited Information Elements have been copied
366 */
368 auto count = frame.Deserialize(buffer.Begin());
369
370 NS_TEST_EXPECT_MSG_EQ(count, buffer.GetSize(), "Unexpected number of deserialized bytes");
371
372 // containing frame
373 NS_TEST_EXPECT_MSG_EQ(frame.Get<Ssid>().has_value(),
374 true,
375 "Containing frame should have SSID IE");
376 NS_TEST_EXPECT_MSG_EQ(frame.Get<SupportedRates>().has_value(),
377 true,
378 "Containing frame should have Supported Rates IE");
379 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedSupportedRatesIE>().has_value(),
380 true,
381 "Containing frame should have Extended Supported Rates IE");
382 NS_TEST_EXPECT_MSG_EQ(frame.Get<HtCapabilities>().has_value(),
383 false,
384 "Containing frame should not have HT Capabilities IE");
385 NS_TEST_EXPECT_MSG_EQ(frame.Get<ExtendedCapabilities>().has_value(),
386 false,
387 "Containing frame should not have Extended Capabilities IE");
388 NS_TEST_EXPECT_MSG_EQ(frame.Get<VhtCapabilities>().has_value(),
389 false,
390 "Containing frame should not have VHT Capabilities IE");
391 NS_TEST_EXPECT_MSG_EQ(frame.Get<HeCapabilities>().has_value(),
392 true,
393 "Containing frame should have HE Capabilities IE");
394 NS_TEST_EXPECT_MSG_EQ(frame.Get<MultiLinkElement>().has_value(),
395 true,
396 "Containing frame should have Multi-Link Element IE");
397 NS_TEST_EXPECT_MSG_EQ(frame.Get<EhtCapabilities>().has_value(),
398 true,
399 "Containing frame should have EHT Capabilities IE");
400 NS_TEST_EXPECT_MSG_EQ(frame.Get<TidToLinkMapping>().empty(),
401 true,
402 "Containing frame should not have TID-to-Link Mapping IE");
403
404 auto& mle = frame.Get<MultiLinkElement>().value();
405
406 NS_TEST_EXPECT_MSG_EQ(mle.GetNPerStaProfileSubelements(),
407 3,
408 "Unexpected number of Per-STA Profile subelements");
409
410 // frame in first Per-STA Profile subelement has inherited all the IEs but SSID and
411 // Multi-Link Element IEs
412 auto& perSta1 = mle.GetPerStaProfile(0);
413 NS_TEST_EXPECT_MSG_EQ(perSta1.HasAssocRequest(),
414 true,
415 "First Per-STA Profile should contain an Association Request frame");
416 auto& perSta1Frame =
417 std::get<std::reference_wrapper<MgtAssocRequestHeader>>(perSta1.GetAssocRequest()).get();
418
419 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<Ssid>().has_value(),
420 false,
421 "Frame in first Per-STA Profile should not have SSID IE");
422 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<SupportedRates>().has_value(),
423 true,
424 "Frame in first Per-STA Profile should have Supported Rates IE");
426 (perSta1Frame.Get<SupportedRates>() == frame.Get<SupportedRates>()),
427 true,
428 "Supported Rates IE not correctly inherited by frame in first Per-STA Profile");
429 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<ExtendedSupportedRatesIE>().has_value(),
430 true,
431 "Frame in first Per-STA Profile should have Extended Supported Rates IE");
433 (perSta1Frame.Get<ExtendedSupportedRatesIE>() == frame.Get<ExtendedSupportedRatesIE>()),
434 true,
435 "Extended Supported Rates IE not correctly inherited by frame in first Per-STA Profile");
436 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<HtCapabilities>().has_value(),
437 false,
438 "Frame in first Per-STA Profile should not have HT Capabilities IE");
440 perSta1Frame.Get<ExtendedCapabilities>().has_value(),
441 false,
442 "Frame in first Per-STA Profile should not have Extended Capabilities IE");
443 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<VhtCapabilities>().has_value(),
444 false,
445 "Frame in first Per-STA Profile should not have VHT Capabilities IE");
446 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<HeCapabilities>().has_value(),
447 true,
448 "Frame in first Per-STA Profile should have HE Capabilities IE");
450 (perSta1Frame.Get<HeCapabilities>() == frame.Get<HeCapabilities>()),
451 true,
452 "HE Capabilities IE not correctly inherited by frame in first Per-STA Profile");
453 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<MultiLinkElement>().has_value(),
454 false,
455 "Frame in first Per-STA Profile should not have Multi-Link Element IE");
456 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<EhtCapabilities>().has_value(),
457 true,
458 "Frame in first Per-STA Profile should have EHT Capabilities IE");
460 (perSta1Frame.Get<EhtCapabilities>() == frame.Get<EhtCapabilities>()),
461 true,
462 "EHT Capabilities IE not correctly inherited by frame in first Per-STA Profile");
463 NS_TEST_EXPECT_MSG_EQ(perSta1Frame.Get<TidToLinkMapping>().empty(),
464 true,
465 "Frame in first Per-STA Profile should not have TID-to-Link Mapping IE");
466
467 // frame in second Per-STA Profile subelement includes VHT Capabilities IE and has inherited
468 // all the IEs but SSID IE, Multi-Link Element IE, Extended Supported Rates IE (different
469 // than in containing frame) and EHT Capabilities IE (listed in Non-Inheritance IE).
470 auto& perSta2 = mle.GetPerStaProfile(1);
471 NS_TEST_EXPECT_MSG_EQ(perSta2.HasAssocRequest(),
472 true,
473 "Second Per-STA Profile should contain an Association Request frame");
474 auto& perSta2Frame =
475 std::get<std::reference_wrapper<MgtAssocRequestHeader>>(perSta2.GetAssocRequest()).get();
476
477 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<Ssid>().has_value(),
478 false,
479 "Frame in second Per-STA Profile should not have SSID IE");
480 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<SupportedRates>().has_value(),
481 true,
482 "Frame in second Per-STA Profile should have Supported Rates IE");
484 (perSta2Frame.Get<SupportedRates>() == frame.Get<SupportedRates>()),
485 true,
486 "Supported Rates IE not correctly inherited by frame in second Per-STA Profile");
488 perSta2Frame.Get<ExtendedSupportedRatesIE>().has_value(),
489 true,
490 "Frame in second Per-STA Profile should have Extended Supported Rates IE");
492 (perSta2Frame.Get<ExtendedSupportedRatesIE>() == frame.Get<ExtendedSupportedRatesIE>()),
493 false,
494 "Extended Supported Rates IE should have not been inherited by frame in second Per-STA "
495 "Profile");
496 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<HtCapabilities>().has_value(),
497 false,
498 "Frame in second Per-STA Profile should not have HT Capabilities IE");
500 perSta2Frame.Get<ExtendedCapabilities>().has_value(),
501 false,
502 "Frame in second Per-STA Profile should not have Extended Capabilities IE");
503 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<VhtCapabilities>().has_value(),
504 true,
505 "Frame in second Per-STA Profile should have VHT Capabilities IE");
506 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<HeCapabilities>().has_value(),
507 true,
508 "Frame in second Per-STA Profile should have HE Capabilities IE");
510 (perSta2Frame.Get<HeCapabilities>() == frame.Get<HeCapabilities>()),
511 true,
512 "HE Capabilities IE not correctly inherited by frame in second Per-STA Profile");
513 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<MultiLinkElement>().has_value(),
514 false,
515 "Frame in second Per-STA Profile should not have Multi-Link Element IE");
517 perSta2Frame.Get<EhtCapabilities>().has_value(),
518 false,
519 "Frame in second Per-STA Profile should have not inherited EHT Capabilities IE");
520 NS_TEST_EXPECT_MSG_EQ(perSta2Frame.Get<TidToLinkMapping>().empty(),
521 true,
522 "Frame in second Per-STA Profile should not have TID-to-Link Mapping IE");
523
524 // frame in third Per-STA Profile subelement includes VHT Capabilities IE and has inherited
525 // all the IEs but SSID IE, Multi-Link Element IE and Extended Supported Rates IE (different
526 // than in containing frame).
527 auto& perSta3 = mle.GetPerStaProfile(2);
528 NS_TEST_EXPECT_MSG_EQ(perSta3.HasAssocRequest(),
529 true,
530 "Third Per-STA Profile should contain an Association Request frame");
531 auto& perSta3Frame =
532 std::get<std::reference_wrapper<MgtAssocRequestHeader>>(perSta3.GetAssocRequest()).get();
533
534 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<Ssid>().has_value(),
535 false,
536 "Frame in third Per-STA Profile should not have SSID IE");
537 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<SupportedRates>().has_value(),
538 true,
539 "Frame in third Per-STA Profile should have Supported Rates IE");
541 (perSta3Frame.Get<SupportedRates>() == frame.Get<SupportedRates>()),
542 true,
543 "Supported Rates IE not correctly inherited by frame in third Per-STA Profile");
544 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<ExtendedSupportedRatesIE>().has_value(),
545 true,
546 "Frame in third Per-STA Profile should have Extended Supported Rates IE");
548 (perSta3Frame.Get<ExtendedSupportedRatesIE>() == frame.Get<ExtendedSupportedRatesIE>()),
549 false,
550 "Extended Supported Rates IE should have not been inherited by frame in third Per-STA "
551 "Profile");
552 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<HtCapabilities>().has_value(),
553 false,
554 "Frame in third Per-STA Profile should not have HT Capabilities IE");
556 perSta3Frame.Get<ExtendedCapabilities>().has_value(),
557 false,
558 "Frame in third Per-STA Profile should not have Extended Capabilities IE");
559 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<VhtCapabilities>().has_value(),
560 true,
561 "Frame in third Per-STA Profile should have VHT Capabilities IE");
562 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<HeCapabilities>().has_value(),
563 true,
564 "Frame in third Per-STA Profile should have HE Capabilities IE");
566 (perSta3Frame.Get<HeCapabilities>() == frame.Get<HeCapabilities>()),
567 true,
568 "HE Capabilities IE not correctly inherited by frame in third Per-STA Profile");
569 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<MultiLinkElement>().has_value(),
570 false,
571 "Frame in third Per-STA Profile should not have Multi-Link Element IE");
573 perSta3Frame.Get<EhtCapabilities>().has_value(),
574 true,
575 "Frame in third Per-STA Profile should have inherited EHT Capabilities IE");
577 (perSta3Frame.Get<EhtCapabilities>() == frame.Get<EhtCapabilities>()),
578 true,
579 "EHT Capabilities IE not correctly inherited by frame in third Per-STA Profile");
580 NS_TEST_EXPECT_MSG_EQ(perSta3Frame.Get<TidToLinkMapping>().empty(),
581 true,
582 "Frame in third Per-STA Profile should not have TID-to-Link Mapping IE");
583}
584
585/**
586 * @ingroup wifi-test
587 * @ingroup tests
588 *
589 * @brief Test Reduced Neighbor Report serialization and deserialization
590 */
592{
593 public:
594 /**
595 * Constructor
596 */
599
600 /// typedef for const iterator on the set of available channels
602
603 /**
604 * Get a Reduced Neighbor Report element including the given operating channels
605 *
606 * @param channel2_4It a channel in the 2.4 GHz band
607 * @param channel5It a channel in the 5 GHz band
608 * @param channel6It a channel in the 6 GHz band
609 * @return a Reduced Neighbor Report element
610 */
612 PhyOpChannelIt channel5It,
613 PhyOpChannelIt channel6It);
614
615 private:
616 void DoRun() override;
617};
618
621 "Check serialization and deserialization of Reduced Neighbor Report elements")
622{
623}
624
628
631 PhyOpChannelIt channel5It,
632 PhyOpChannelIt channel6It)
633{
635
636 std::stringstream info;
637
638 if (channel2_4It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
639 {
640 WifiPhyOperatingChannel channel(channel2_4It);
641
642 info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 2.4 GHz} ";
643 rnr.AddNbrApInfoField();
644 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
645 rnr.SetOperatingChannel(nbrId, channel);
646 // Add a TBTT Information Field
647 rnr.AddTbttInformationField(nbrId);
648 rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:24"));
649 rnr.SetShortSsid(nbrId, 0, 0);
650 rnr.SetBssParameters(nbrId, 0, 10);
651 rnr.SetPsd20MHz(nbrId, 0, 50);
652 rnr.SetMldParameters(nbrId, 0, {0, 2, 3, 1, 1});
653 }
654
655 if (channel5It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
656 {
657 WifiPhyOperatingChannel channel(channel5It);
658
659 info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 5 GHz} ";
660 rnr.AddNbrApInfoField();
661 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
662 rnr.SetOperatingChannel(nbrId, channel);
663 // Add a TBTT Information Field
664 rnr.AddTbttInformationField(nbrId);
665 rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:05"));
666 rnr.SetShortSsid(nbrId, 0, 0);
667 rnr.SetBssParameters(nbrId, 0, 20);
668 rnr.SetPsd20MHz(nbrId, 0, 60);
669 rnr.SetMldParameters(nbrId, 0, {0, 3, 4, 0, 1});
670 // Add another TBTT Information Field
671 rnr.AddTbttInformationField(nbrId);
672 rnr.SetBssid(nbrId, 1, Mac48Address("00:00:00:00:01:05"));
673 rnr.SetShortSsid(nbrId, 1, 0);
674 rnr.SetBssParameters(nbrId, 1, 30);
675 rnr.SetPsd20MHz(nbrId, 1, 70);
676 rnr.SetMldParameters(nbrId, 1, {0, 4, 5, 1, 0});
677 }
678
679 if (channel6It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
680 {
681 WifiPhyOperatingChannel channel(channel6It);
682
683 info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 6 GHz} ";
684 rnr.AddNbrApInfoField();
685 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
686 rnr.SetOperatingChannel(nbrId, channel);
687 // Add a TBTT Information Field
688 rnr.AddTbttInformationField(nbrId);
689 rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:06"));
690 rnr.SetShortSsid(nbrId, 0, 0);
691 rnr.SetBssParameters(nbrId, 0, 40);
692 rnr.SetPsd20MHz(nbrId, 0, 80);
693 rnr.SetMldParameters(nbrId, 0, {0, 5, 6, 0, 0});
694 }
695
696 NS_LOG_DEBUG(info.str());
697 return rnr;
698}
699
700void
702{
703 PhyOpChannelIt channel2_4It;
704 PhyOpChannelIt channel5It;
705 PhyOpChannelIt channel6It;
706 channel2_4It = channel5It = channel6It =
708
709 // Test all available frequency channels
710 while (channel2_4It != WifiPhyOperatingChannel::GetFrequencyChannels().cend() ||
711 channel5It != WifiPhyOperatingChannel::GetFrequencyChannels().cend() ||
713 {
714 if (channel2_4It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
715 {
716 channel2_4It = WifiPhyOperatingChannel::FindFirst(0,
717 MHz_u{0},
718 MHz_u{0},
721 channel2_4It);
722 }
723 if (channel5It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
724 {
726 MHz_u{0},
727 MHz_u{0},
730 channel5It);
731 }
732 if (channel6It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
733 {
735 MHz_u{0},
736 MHz_u{0},
739 channel6It);
740 }
741
742 TestHeaderSerialization(GetReducedNeighborReport(channel2_4It, channel5It, channel6It));
743
744 // advance all channel iterators
745 if (channel2_4It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
746 {
747 channel2_4It++;
748 }
749 if (channel5It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
750 {
751 channel5It++;
752 }
753 if (channel6It != WifiPhyOperatingChannel::GetFrequencyChannels().cend())
754 {
755 channel6It++;
756 }
757 }
758}
759
760/**
761 * @ingroup wifi-test
762 * @ingroup tests
763 *
764 * @brief Test serialization and deserialization of EHT capabilities IE
765 */
767{
768 public:
769 /**
770 * Constructor
771 * @param is2_4Ghz whether the PHY is operating in 2.4 GHz
772 * @param channelWidth the supported channel width
773 */
774 WifiEhtCapabilitiesIeTest(bool is2_4Ghz, MHz_u channelWidth);
775 ~WifiEhtCapabilitiesIeTest() override = default;
776
777 /**
778 * Generate the HE capabilities IE.
779 *
780 * @return the generated HE capabilities IE
781 */
783
784 /**
785 * Generate the EHT capabilities IE.
786 *
787 * @param maxMpduLength the maximum MPDU length in bytes
788 * @param maxAmpduSize the maximum A-MPDU size in bytes
789 * @param maxSupportedMcs the maximum EHT MCS supported by the PHY
790 * @return the generated EHT capabilities IE
791 */
792 EhtCapabilities GetEhtCapabilities(uint16_t maxMpduLength,
793 uint32_t maxAmpduSize,
794 uint8_t maxSupportedMcs) const;
795
796 /**
797 * Serialize the EHT capabilities in a buffer.
798 *
799 * @param ehtCapabilities the EHT capabilities
800 * @return the buffer in which the EHT capabilities has been serialized
801 */
802 Buffer SerializeIntoBuffer(const EhtCapabilities& ehtCapabilities);
803
804 /**
805 * Check that the given buffer contains the given value at the given position.
806 *
807 * @param buffer the given buffer
808 * @param position the given position (starting at 0)
809 * @param value the given value
810 */
811 void CheckSerializedByte(const Buffer& buffer, uint32_t position, uint8_t value);
812
813 /**
814 * Check the content of the EHT MAC Capabilities Information subfield.
815 *
816 * @param buffer the buffer containing the serialized EHT capabilities
817 * @param expectedValueFirstByte the expected value for the first byte
818 */
819 void CheckEhtMacCapabilitiesInformation(const Buffer& buffer, uint8_t expectedValueFirstByte);
820
821 /**
822 * Check the content of the EHT PHY Capabilities Information subfield.
823 *
824 * @param buffer the buffer containing the serialized EHT capabilities
825 * @param expectedValueSixthByte the expected value for the sixth byte
826 */
827 void CheckEhtPhyCapabilitiesInformation(const Buffer& buffer, uint8_t expectedValueSixthByte);
828
829 /**
830 * Check the content of the Supported EHT-MCS And NSS Set subfield.
831 * @param maxSupportedMcs the maximum EHT MCS supported by the PHY
832 *
833 * @param buffer the buffer containing the serialized EHT capabilities
834 */
835 void CheckSupportedEhtMcsAndNssSet(const Buffer& buffer, uint8_t maxSupportedMcs);
836
837 private:
838 void DoRun() override;
839
840 bool m_is2_4Ghz; //!< whether the PHY is operating in 2.4 GHz
841 MHz_u m_channelWidth; //!< Supported channel width by the PHY
842};
843
844WifiEhtCapabilitiesIeTest ::WifiEhtCapabilitiesIeTest(bool is2_4Ghz, MHz_u channelWidth)
845 : HeaderSerializationTestCase{"Check serialization and deserialization of EHT capabilities IE"},
846 m_is2_4Ghz{is2_4Ghz},
847 m_channelWidth{channelWidth}
848{
849}
850
853{
854 HeCapabilities capabilities;
855 uint8_t channelWidthSet = 0;
856 if ((m_channelWidth >= MHz_u{40}) && m_is2_4Ghz)
857 {
858 channelWidthSet |= 0x01;
859 }
860 if ((m_channelWidth >= MHz_u{80}) && !m_is2_4Ghz)
861 {
862 channelWidthSet |= 0x02;
863 }
864 if ((m_channelWidth >= MHz_u{160}) && !m_is2_4Ghz)
865 {
866 channelWidthSet |= 0x04;
867 }
868 capabilities.SetChannelWidthSet(channelWidthSet);
869 return capabilities;
870}
871
874 uint32_t maxAmpduSize,
875 uint8_t maxSupportedMcs) const
876{
877 EhtCapabilities capabilities;
878
879 if (m_is2_4Ghz)
880 {
881 capabilities.SetMaxMpduLength(maxMpduLength);
882 }
883 // round to the next power of two minus one
884 maxAmpduSize = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduSize + 1)))) - 1;
885 // The maximum A-MPDU length in EHT capabilities elements ranges from 2^23-1 to 2^24-1
886 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduSize, 8388607U), 16777215U));
887
889 (maxSupportedMcs >= 12) ? 1 : 0;
891 (maxSupportedMcs >= 12) ? 1 : 0;
892 if (m_channelWidth == MHz_u{20})
893 {
894 for (auto maxMcs : {7, 9, 11, 13})
895 {
897 maxMcs,
898 maxMcs <= maxSupportedMcs ? 1 : 0);
900 maxMcs,
901 maxMcs <= maxSupportedMcs ? 2 : 0);
902 }
903 }
904 else
905 {
906 for (auto maxMcs : {9, 11, 13})
907 {
908 capabilities.SetSupportedRxEhtMcsAndNss(
910 maxMcs,
911 maxMcs <= maxSupportedMcs ? 3 : 0);
912 capabilities.SetSupportedTxEhtMcsAndNss(
914 maxMcs,
915 maxMcs <= maxSupportedMcs ? 4 : 0);
916 }
917 }
918 if (m_channelWidth >= MHz_u{160})
919 {
920 for (auto maxMcs : {9, 11, 13})
921 {
923 maxMcs,
924 maxMcs <= maxSupportedMcs ? 2 : 0);
926 maxMcs,
927 maxMcs <= maxSupportedMcs ? 1 : 0);
928 }
929 }
930 if (m_channelWidth == MHz_u{320})
931 {
932 capabilities.m_phyCapabilities.support320MhzIn6Ghz = 1;
933 for (auto maxMcs : {9, 11, 13})
934 {
936 maxMcs,
937 maxMcs <= maxSupportedMcs ? 4 : 0);
939 maxMcs,
940 maxMcs <= maxSupportedMcs ? 3 : 0);
941 }
942 }
943 else
944 {
945 capabilities.m_phyCapabilities.support320MhzIn6Ghz = 0;
946 }
947
948 return capabilities;
949}
950
951Buffer
953{
954 Buffer buffer;
955 buffer.AddAtStart(ehtCapabilities.GetSerializedSize());
956 ehtCapabilities.Serialize(buffer.Begin());
957 return buffer;
958}
959
960void
962 uint32_t position,
963 uint8_t value)
964{
965 Buffer::Iterator it = buffer.Begin();
966 it.Next(position);
967 uint8_t byte = it.ReadU8();
968 NS_TEST_EXPECT_MSG_EQ(+byte, +value, "Unexpected byte at pos=" << position);
969}
970
971void
973 uint8_t expectedValueFirstByte)
974{
975 CheckSerializedByte(buffer, 3, expectedValueFirstByte);
976 CheckSerializedByte(buffer, 4, 0x00);
977}
978
979void
981 uint8_t expectedValueSixthByte)
982{
983 CheckSerializedByte(buffer, 5, (m_channelWidth == MHz_u{320}) ? 0x02 : 0x00);
984 CheckSerializedByte(buffer, 6, 0x00);
985 CheckSerializedByte(buffer, 7, 0x00);
986 CheckSerializedByte(buffer, 8, 0x00);
987 CheckSerializedByte(buffer, 9, 0x00);
988 CheckSerializedByte(buffer, 10, expectedValueSixthByte);
989 CheckSerializedByte(buffer, 11, 0x00);
990 CheckSerializedByte(buffer, 12, 0x00);
991 CheckSerializedByte(buffer, 13, 0x00);
992}
993
994void
996 uint8_t maxSupportedMcs)
997{
998 if (m_channelWidth == MHz_u{20})
999 {
1000 CheckSerializedByte(buffer, 14, 0x21); // first byte of Supported EHT-MCS And NSS Set
1002 buffer,
1003 15,
1004 maxSupportedMcs >= 8 ? 0x21 : 0x00); // second byte of Supported EHT-MCS And NSS Set
1006 buffer,
1007 16,
1008 maxSupportedMcs >= 10 ? 0x21 : 0x00); // third byte of Supported EHT-MCS And NSS Set
1010 buffer,
1011 17,
1012 maxSupportedMcs >= 12 ? 0x21 : 0x00); // fourth byte of Supported EHT-MCS And NSS Set
1013 }
1014 else
1015 {
1016 CheckSerializedByte(buffer, 14, 0x43); // first byte of Supported EHT-MCS And NSS Set
1018 buffer,
1019 15,
1020 maxSupportedMcs >= 10 ? 0x43 : 0x00); // second byte of Supported EHT-MCS And NSS Set
1022 buffer,
1023 16,
1024 maxSupportedMcs >= 12 ? 0x43 : 0x00); // third byte of Supported EHT-MCS And NSS Set
1025 }
1026 if (m_channelWidth >= MHz_u{160})
1027 {
1028 CheckSerializedByte(buffer, 17, 0x12); // first byte of EHT-MCS Map (BW = 160 MHz)
1030 buffer,
1031 18,
1032 maxSupportedMcs >= 10 ? 0x12 : 0x00); // second byte of EHT-MCS Map (BW = 160 MHz)
1034 buffer,
1035 19,
1036 maxSupportedMcs >= 12 ? 0x12 : 0x00); // third byte of EHT-MCS Map (BW = 160 MHz)
1037 }
1038 if (m_channelWidth == MHz_u{320})
1039 {
1040 CheckSerializedByte(buffer, 20, 0x34); // first byte of EHT-MCS Map (BW = 320 MHz)
1042 buffer,
1043 21,
1044 maxSupportedMcs >= 10 ? 0x34 : 0x00); // second byte of EHT-MCS Map (BW = 320 MHz)
1046 buffer,
1047 22,
1048 maxSupportedMcs >= 12 ? 0x34 : 0x00); // third byte of EHT-MCS Map (BW = 320 MHz)
1049 }
1050}
1051
1052void
1054{
1055 uint8_t maxMcs = 0;
1056 uint16_t expectedEhtMcsAndNssSetSize = 0;
1057 switch (static_cast<uint16_t>(m_channelWidth))
1058 {
1059 case 20:
1060 expectedEhtMcsAndNssSetSize = 4;
1061 break;
1062 case 40:
1063 case 80:
1064 expectedEhtMcsAndNssSetSize = 3;
1065 break;
1066 case 160:
1067 expectedEhtMcsAndNssSetSize = (2 * 3);
1068 break;
1069 case 320:
1070 expectedEhtMcsAndNssSetSize = (3 * 3);
1071 break;
1072 default:
1073 NS_ASSERT_MSG(false, "Invalid upper channel width " << m_channelWidth);
1074 }
1075
1076 uint16_t expectedSize = 1 + // Element ID
1077 1 + // Length
1078 1 + // Element ID Extension
1079 2 + // EHT MAC Capabilities Information
1080 9 + // EHT PHY Capabilities Information
1081 expectedEhtMcsAndNssSetSize; // Supported EHT-MCS And NSS Set
1082
1083 auto mapType = m_channelWidth == MHz_u{20}
1086
1087 {
1088 maxMcs = 11;
1089 HeCapabilities heCapabilities = GetHeCapabilities();
1090 EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
1091
1092 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1093 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1094
1095 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1096 expectedSize,
1097 "Unexpected header size");
1098
1099 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1100
1102
1104
1105 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1106
1107 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1108 }
1109
1110 {
1111 maxMcs = 11;
1112 HeCapabilities heCapabilities = GetHeCapabilities();
1113 EhtCapabilities ehtCapabilities = GetEhtCapabilities(11454, 65535, maxMcs);
1114
1115 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1116 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1117
1118 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1119 expectedSize,
1120 "Unexpected header size");
1121
1122 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1123
1124 CheckEhtMacCapabilitiesInformation(buffer, m_is2_4Ghz ? 0x80 : 0x00);
1125
1127
1128 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1129
1130 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1131 }
1132
1133 {
1134 maxMcs = 13;
1135 HeCapabilities heCapabilities = GetHeCapabilities();
1136 EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
1137
1138 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1139 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1140
1141 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1142 expectedSize,
1143 "Unexpected header size");
1144
1145 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1146
1148
1150
1151 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1152
1153 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1154 }
1155
1156 {
1157 maxMcs = 11;
1158 HeCapabilities heCapabilities = GetHeCapabilities();
1159 EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
1160
1161 NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
1162 NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
1163
1164 std::vector<std::pair<uint8_t, uint8_t>> ppeThresholds;
1165 ppeThresholds.emplace_back(1, 2); // NSS1 242-tones RU
1166 ppeThresholds.emplace_back(2, 3); // NSS1 484-tones RU
1167 ppeThresholds.emplace_back(3, 4); // NSS2 242-tones RU
1168 ppeThresholds.emplace_back(4, 3); // NSS2 484-tones RU
1169 ppeThresholds.emplace_back(3, 2); // NSS3 242-tones RU
1170 ppeThresholds.emplace_back(2, 1); // NSS3 484-tones RU
1171 ehtCapabilities.SetPpeThresholds(2, 0x03, ppeThresholds);
1172
1173 expectedSize += 6;
1174
1175 NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
1176 expectedSize,
1177 "Unexpected header size");
1178
1179 Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
1180
1182
1184
1185 CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
1186
1187 TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
1188 }
1189}
1190
1191/**
1192 * @ingroup wifi-test
1193 * @ingroup tests
1194 *
1195 * @brief Test TID-To-Link Mapping information element serialization and deserialization
1196 */
1198{
1199 public:
1200 /**
1201 * Constructor
1202 *
1203 * @param direction The direction for the TID-to-link mapping
1204 * @param mappingSwitchTime the Mapping Switching Time
1205 * @param expectedDuration the Expected Duration
1206 * @param mappings A TID-indexed map of the link sets the TIDs are mapped to
1207 */
1209 std::optional<Time> mappingSwitchTime,
1210 std::optional<Time> expectedDuration,
1211 const WifiTidLinkMapping& mappings);
1212
1213 ~TidToLinkMappingElementTest() override = default;
1214
1215 private:
1216 void DoSetup() override;
1217 void DoRun() override;
1218
1219 WifiDirection m_direction; ///< the direction for the TID-to-link mapping
1220 std::optional<Time> m_mappingSwitchTime; ///< the Mapping Switching Time
1221 std::optional<Time> m_expectedDuration; ///< the Expected Duration
1222 WifiTidLinkMapping m_mappings; ///< maps TIDs to link sets
1223 TidToLinkMapping m_tidToLinkMapping; ///< TID-To-Link Mapping element
1224};
1225
1227 std::optional<Time> mappingSwitchTime,
1228 std::optional<Time> expectedDuration,
1229 const WifiTidLinkMapping& mappings)
1231 "Check serialization and deserialization of TID-To-Link Mapping elements"),
1232 m_direction(direction),
1233 m_mappingSwitchTime(mappingSwitchTime),
1234 m_expectedDuration(expectedDuration),
1235 m_mappings(mappings)
1236{
1237}
1238
1239void
1241{
1242 m_tidToLinkMapping.m_control.direction = m_direction;
1243 m_tidToLinkMapping.m_control.defaultMapping = true;
1244
1246 {
1247 m_tidToLinkMapping.SetMappingSwitchTime(*m_mappingSwitchTime);
1248 std::optional<Time> encoded = m_tidToLinkMapping.GetMappingSwitchTime();
1249 NS_TEST_ASSERT_MSG_EQ(encoded.has_value(), true, "Mapping Switch Time should be present");
1251 *encoded,
1252 "Incorrect Mapping Switch Time value");
1253 }
1255 {
1256 m_tidToLinkMapping.SetExpectedDuration(*m_expectedDuration);
1257 std::optional<Time> encoded = m_tidToLinkMapping.GetExpectedDuration();
1258 NS_TEST_ASSERT_MSG_EQ(encoded.has_value(), true, "Expected Duration should be present");
1259 NS_TEST_EXPECT_MSG_EQ(*m_expectedDuration, *encoded, "Incorrect Expected Duration value");
1260 }
1261
1262 for (const auto& [tid, linkSet] : m_mappings)
1263 {
1264 m_tidToLinkMapping.m_control.defaultMapping = false;
1265 m_tidToLinkMapping.SetLinkMappingOfTid(tid, linkSet);
1266 NS_TEST_EXPECT_MSG_EQ((m_tidToLinkMapping.GetLinkMappingOfTid(tid) == linkSet),
1267 true,
1268 "Incorrect link set for TID " << +tid);
1269 }
1270}
1271
1272void
1279
1280/**
1281 * @ingroup wifi-test
1282 * @ingroup tests
1283 *
1284 * @brief Test EHT Operation information element serialization and deserialization
1285 */
1287{
1288 public:
1289 /**
1290 * Constructor
1291 *
1292 * @param params the EHT Operation Parameters field
1293 * @param rxMaxNss0_7 RX max NSS that supports EHT MCS 0-7
1294 * @param txMaxNss0_7 TX max NSS that supports EHT MCS 0-7
1295 * @param rxMaxNss8_9 RX max NSS that supports EHT MCS 8-9
1296 * @param txMaxNss8_9 TX max NSS that supports EHT MCS 8-9
1297 * @param rxMaxNss10_11 RX max NSS that supports EHT MCS 10-11
1298 * @param txMaxNss10_11 TX max NSS that supports EHT MCS 10-11
1299 * @param rxMaxNss12_13 RX max NSS that supports EHT MCS 12-13
1300 * @param txMaxNss12_13 TX max NSS that supports EHT MCS 12-13
1301 * @param opInfo the EHT Operation Information field
1302 */
1304 uint8_t rxMaxNss0_7,
1305 uint8_t txMaxNss0_7,
1306 uint8_t rxMaxNss8_9,
1307 uint8_t txMaxNss8_9,
1308 uint8_t rxMaxNss10_11,
1309 uint8_t txMaxNss10_11,
1310 uint8_t rxMaxNss12_13,
1311 uint8_t txMaxNss12_13,
1312 std::optional<EhtOperation::EhtOpInfo> opInfo);
1313
1314 ~EhtOperationElementTest() override = default;
1315
1316 private:
1317 void DoRun() override;
1318
1319 EhtOperation m_ehtOperation; ///< EHT Operation element
1320};
1321
1323 uint8_t rxMaxNss0_7,
1324 uint8_t txMaxNss0_7,
1325 uint8_t rxMaxNss8_9,
1326 uint8_t txMaxNss8_9,
1327 uint8_t rxMaxNss10_11,
1328 uint8_t txMaxNss10_11,
1329 uint8_t rxMaxNss12_13,
1330 uint8_t txMaxNss12_13,
1331 std::optional<EhtOperation::EhtOpInfo> opInfo)
1333 "Check serialization and deserialization of EHT Operation elements")
1334{
1335 m_ehtOperation.m_params = params;
1336 m_ehtOperation.SetMaxRxNss(rxMaxNss0_7, 0, 7);
1337 m_ehtOperation.SetMaxTxNss(txMaxNss0_7, 0, 7);
1338 m_ehtOperation.SetMaxRxNss(rxMaxNss8_9, 8, 9);
1339 m_ehtOperation.SetMaxTxNss(txMaxNss8_9, 8, 9);
1340 m_ehtOperation.SetMaxRxNss(rxMaxNss10_11, 10, 11);
1341 m_ehtOperation.SetMaxTxNss(txMaxNss10_11, 10, 11);
1342 m_ehtOperation.SetMaxRxNss(rxMaxNss12_13, 12, 13);
1343 m_ehtOperation.SetMaxTxNss(txMaxNss12_13, 12, 13);
1344 m_ehtOperation.m_opInfo = opInfo;
1345}
1346
1347void
1352
1353/**
1354 * @ingroup wifi-test
1355 * @ingroup tests
1356 *
1357 * @brief wifi EHT Information Elements Test Suite
1358 */
1360{
1361 public:
1363};
1364
1366 : TestSuite("wifi-eht-info-elems", Type::UNIT)
1367{
1378 new TidToLinkMappingElementTest(WifiDirection::DOWNLINK, std::nullopt, std::nullopt, {}),
1381 MicroSeconds(500 * 1024),
1382 MicroSeconds(300 * 1024),
1383 {{3, std::set<uint8_t>{0, 4, 6}}}),
1387 std::nullopt,
1388 MicroSeconds(100 * 1024),
1389 {{3, std::set<uint8_t>{0, 4, 6}}, {6, std::set<uint8_t>{3, 7, 11, 14}}}),
1392 MicroSeconds(100 * 1024),
1393 std::nullopt,
1394 {{0, std::set<uint8_t>{0, 1, 2}},
1395 {1, std::set<uint8_t>{3, 4, 5}},
1396 {2, std::set<uint8_t>{6, 7}},
1397 {3, std::set<uint8_t>{8, 9, 10}},
1398 {4, std::set<uint8_t>{11, 12, 13}},
1399 {5, std::set<uint8_t>{14}},
1400 {6, std::set<uint8_t>{1, 3, 6}},
1401 {7, std::set<uint8_t>{11, 14}}}),
1403 AddTestCase(new EhtOperationElementTest({0, 0, 0, 0, 0}, 1, 2, 3, 4, 5, 6, 7, 8, std::nullopt),
1405 AddTestCase(new EhtOperationElementTest({1, 0, 0, 1, 0},
1406 1,
1407 2,
1408 3,
1409 4,
1410 5,
1411 6,
1412 7,
1413 8,
1414 EhtOperation::EhtOpInfo{{1}, 3, 5}),
1416 AddTestCase(new EhtOperationElementTest({1, 1, 1, 1, 2},
1417 1,
1418 2,
1419 3,
1420 4,
1421 5,
1422 6,
1423 7,
1424 8,
1425 EhtOperation::EhtOpInfo{{2}, 4, 6, 3000}),
1427}
1428
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.
WifiEhtCapabilitiesIeTest(bool is2_4Ghz, MHz_u channelWidth)
Constructor.
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
MHz_u m_channelWidth
Supported channel width by the PHY.
Buffer SerializeIntoBuffer(const EhtCapabilities &ehtCapabilities)
Serialize the EHT capabilities in a buffer.
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:89
uint16_t ReadLsbtohU16()
Definition buffer.cc:1053
void Next()
go forward by one byte
Definition buffer.h:842
automatically resized byte buffer
Definition buffer.h:83
uint32_t GetSize() const
Definition buffer.h:1057
void AddAtStart(uint32_t start)
Definition buffer.cc:303
Buffer::Iterator Begin() const
Definition buffer.h:1063
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.
uint8_t GetHighestSupportedTxMcs(EhtMcsAndNssSet::EhtMcsMapType mapType) const
Get the highest supported TX MCS for a given EHT-MCS map type.
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 GetHighestSupportedRxMcs(EhtMcsAndNssSet::EhtMcsMapType mapType) const
Get the highest supported RX 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.
EHT Operation Information Element.
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.
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...
HeaderSerializationTestCase(std::string name)
Constructor.
The HT Capabilities Information Element.
an EUI-48 address
Implement the header for management frames of type association request.
CapabilityInformation & Capabilities()
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 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 SetMldParameters(std::size_t nbrApInfoId, std::size_t index, const MldParameters &mldParams)
Set the MLD Parameters subfield of the i-th TBTT Information field of the given Neighbor AP Informati...
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:131
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
The Supported Rates Information Element.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
@ QUICK
Fast test.
Definition test.h:1055
Type
Type of test.
Definition test.h:1274
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:490
static constexpr auto UNIT
Definition test.h:1291
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.
std::set< FrequencyChannelInfo >::const_iterator ConstIterator
Typedef for a const iterator pointing to a channel in the set of available channels.
static const std::set< FrequencyChannelInfo > & GetFrequencyChannels()
Return a reference to the set of all available frequency channels.
static ConstIterator FindFirst(uint8_t number, MHz_u frequency, MHz_u width, WifiStandard standard, WifiPhyBand band, ConstIterator start=GetFrequencyChannels().begin())
Find the first frequency segment matching the specified parameters.
#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_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:134
#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:946
#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:241
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1393
@ WIFI_STANDARD_80211be
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
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:70
WifiDirection
Wifi direction.
Definition wifi-utils.h:39
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.
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.
void SetMediumSyncOfdmEdThreshold(int8_t threshold)
Set the Medium Synchronization OFDM ED Threshold subfield of the Medium Synchronization Delay Informa...
std::optional< MediumSyncDelayInfo > m_mediumSyncDelayInfo
Medium Synchronization Delay Information.
void SetMediumSyncDelayTimer(Time delay)
Set the Medium Synchronization Duration subfield of the Medium Synchronization Delay Information in t...
Mac48Address m_mldMacAddress
Subfields.
std::optional< uint8_t > m_bssParamsChangeCount
BSS Parameters Change Count.
void SetMediumSyncMaxNTxops(uint8_t nTxops)
Set the Medium Synchronization Maximum Number of TXOPs subfield of the Medium Synchronization Delay I...
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.
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