A Discrete-Event Network Simulator
API
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/header-serialization-test.h"
21 #include "ns3/log.h"
22 #include "ns3/mgt-headers.h"
23 #include "ns3/multi-link-element.h"
24 #include "ns3/reduced-neighbor-report.h"
25 #include "ns3/tid-to-link-mapping-element.h"
26 #include "ns3/wifi-phy-operating-channel.h"
27 
28 #include <sstream>
29 #include <vector>
30 
31 using namespace ns3;
32 
33 NS_LOG_COMPONENT_DEFINE("WifiEhtInfoElemsTest");
34 
42 {
43  public:
48  ~BasicMultiLinkElementTest() override;
49 
58  MultiLinkElement GetMultiLinkElement(
59  const CommonInfoBasicMle& commonInfo,
60  std::vector<MultiLinkElement::PerStaProfileSubelement> subelements);
61 
62  private:
63  void DoRun() override;
64 
66 };
67 
70  "Check serialization and deserialization of Basic variant Multi-Link elements"),
72 {
73 }
74 
76 {
77 }
78 
81  const CommonInfoBasicMle& commonInfo,
82  std::vector<MultiLinkElement::PerStaProfileSubelement> subelements)
83 {
84  MultiLinkElement mle(MultiLinkElement::BASIC_VARIANT, m_frameType);
85  mle.SetMldMacAddress(commonInfo.m_mldMacAddress);
86  if (commonInfo.m_linkIdInfo.has_value())
87  {
88  mle.SetLinkIdInfo(*commonInfo.m_linkIdInfo);
89  }
90  if (commonInfo.m_bssParamsChangeCount.has_value())
91  {
93  }
94  if (commonInfo.m_mediumSyncDelayInfo.has_value())
95  {
97  MicroSeconds(32 * commonInfo.m_mediumSyncDelayInfo->mediumSyncDuration));
99  commonInfo.m_mediumSyncDelayInfo->mediumSyncOfdmEdThreshold - 72);
100  mle.SetMediumSyncMaxNTxops(commonInfo.m_mediumSyncDelayInfo->mediumSyncMaxNTxops + 1);
101  }
102 
103  for (std::size_t i = 0; i < subelements.size(); ++i)
104  {
106  mle.GetPerStaProfile(i) = std::move(subelements[i]);
107  }
108  return mle;
109 }
110 
111 void
113 {
114  CommonInfoBasicMle commonInfo = {
115  .m_mldMacAddress = Mac48Address("01:23:45:67:89:ab"),
116  };
117 
118  // Common Info with MLD MAC address
120 
121  commonInfo.m_linkIdInfo = 3;
122 
123  // Adding Link ID Info
125 
126  commonInfo.m_bssParamsChangeCount = 1;
127 
128  // Adding BSS Parameters Change Count
130 
131  commonInfo.m_mediumSyncDelayInfo =
133  .mediumSyncOfdmEdThreshold = 4,
134  .mediumSyncMaxNTxops = 5};
135 
136  // Adding Medium Sync Delay Information
138 
139  SupportedRates rates;
140  rates.AddSupportedRate(6);
141  rates.AddSupportedRate(12);
142  rates.AddSupportedRate(24);
143 
144  CapabilityInformation capabilities;
145  capabilities.SetShortPreamble(true);
146  capabilities.SetShortSlotTime(true);
147  capabilities.SetEss();
148 
149  MgtAssocRequestHeader assoc;
150  assoc.SetSsid(Ssid("MySsid"));
151  assoc.SetSupportedRates(rates);
152  assoc.SetCapabilities(capabilities);
153  assoc.SetListenInterval(0);
154 
155  MultiLinkElement::PerStaProfileSubelement perStaProfile(MultiLinkElement::BASIC_VARIANT,
156  m_frameType);
157  perStaProfile.SetLinkId(5);
158  perStaProfile.SetCompleteProfile();
159  perStaProfile.SetStaMacAddress(Mac48Address("ba:98:76:54:32:10"));
160  perStaProfile.SetAssocRequest(assoc);
161 
162  // Adding Per-STA Profile Subelement
163  TestHeaderSerialization(GetMultiLinkElement(commonInfo, {perStaProfile}), m_frameType);
164 
165  // Adding two Per-STA Profile Subelements
166  TestHeaderSerialization(GetMultiLinkElement(commonInfo, {perStaProfile, perStaProfile}),
167  m_frameType);
168 }
169 
177 {
178  public:
183  ~ReducedNeighborReportTest() override;
184 
187 
197  PhyOpChannelIt channel5It,
198  PhyOpChannelIt channel6It);
199 
200  private:
201  void DoRun() override;
202 };
203 
206  "Check serialization and deserialization of Reduced Neighbor Report elements")
207 {
208 }
209 
211 {
212 }
213 
216  PhyOpChannelIt channel5It,
217  PhyOpChannelIt channel6It)
218 {
220 
221  std::stringstream info;
222 
223  if (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
224  {
225  WifiPhyOperatingChannel channel(channel2_4It);
226 
227  info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 2.4 GHz} ";
228  rnr.AddNbrApInfoField();
229  std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
230  rnr.SetOperatingChannel(nbrId, channel);
231  // Add a TBTT Information Field
232  rnr.AddTbttInformationField(nbrId);
233  rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:24"));
234  rnr.SetShortSsid(nbrId, 0, 0);
235  rnr.SetBssParameters(nbrId, 0, 10);
236  rnr.SetPsd20MHz(nbrId, 0, 50);
237  rnr.SetMldParameters(nbrId, 0, 0, 2, 3);
238  }
239 
240  if (channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
241  {
242  WifiPhyOperatingChannel channel(channel5It);
243 
244  info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 5 GHz} ";
245  rnr.AddNbrApInfoField();
246  std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
247  rnr.SetOperatingChannel(nbrId, channel);
248  // Add a TBTT Information Field
249  rnr.AddTbttInformationField(nbrId);
250  rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:05"));
251  rnr.SetShortSsid(nbrId, 0, 0);
252  rnr.SetBssParameters(nbrId, 0, 20);
253  rnr.SetPsd20MHz(nbrId, 0, 60);
254  rnr.SetMldParameters(nbrId, 0, 0, 3, 4);
255  // Add another TBTT Information Field
256  rnr.AddTbttInformationField(nbrId);
257  rnr.SetBssid(nbrId, 1, Mac48Address("00:00:00:00:01:05"));
258  rnr.SetShortSsid(nbrId, 1, 0);
259  rnr.SetBssParameters(nbrId, 1, 30);
260  rnr.SetPsd20MHz(nbrId, 1, 70);
261  rnr.SetMldParameters(nbrId, 1, 0, 4, 5);
262  }
263 
264  if (channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
265  {
266  WifiPhyOperatingChannel channel(channel6It);
267 
268  info << "{Ch=" << +channel.GetNumber() << ", Bw=" << channel.GetWidth() << ", 6 GHz} ";
269  rnr.AddNbrApInfoField();
270  std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
271  rnr.SetOperatingChannel(nbrId, channel);
272  // Add a TBTT Information Field
273  rnr.AddTbttInformationField(nbrId);
274  rnr.SetBssid(nbrId, 0, Mac48Address("00:00:00:00:00:06"));
275  rnr.SetShortSsid(nbrId, 0, 0);
276  rnr.SetBssParameters(nbrId, 0, 40);
277  rnr.SetPsd20MHz(nbrId, 0, 80);
278  rnr.SetMldParameters(nbrId, 0, 0, 5, 6);
279  }
280 
281  NS_LOG_DEBUG(info.str());
282  return rnr;
283 }
284 
285 void
287 {
288  PhyOpChannelIt channel2_4It;
289  PhyOpChannelIt channel5It;
290  PhyOpChannelIt channel6It;
291  channel2_4It = channel5It = channel6It = WifiPhyOperatingChannel::m_frequencyChannels.cbegin();
292 
293  // Test all available frequency channels
294  while (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend() ||
295  channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend() ||
296  channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
297  {
298  if (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
299  {
300  channel2_4It = WifiPhyOperatingChannel::FindFirst(0,
301  0,
302  0,
305  channel2_4It);
306  }
307  if (channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
308  {
309  channel5It = WifiPhyOperatingChannel::FindFirst(0,
310  0,
311  0,
314  channel5It);
315  }
316  if (channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
317  {
318  channel6It = WifiPhyOperatingChannel::FindFirst(0,
319  0,
320  0,
323  channel6It);
324  }
325 
326  TestHeaderSerialization(GetReducedNeighborReport(channel2_4It, channel5It, channel6It));
327 
328  // advance all channel iterators
329  if (channel2_4It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
330  {
331  channel2_4It++;
332  }
333  if (channel5It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
334  {
335  channel5It++;
336  }
337  if (channel6It != WifiPhyOperatingChannel::m_frequencyChannels.cend())
338  {
339  channel6It++;
340  }
341  }
342 }
343 
351 {
352  public:
358  WifiEhtCapabilitiesIeTest(bool is2_4Ghz, uint16_t channelWidth);
359  ~WifiEhtCapabilitiesIeTest() override = default;
360 
367 
376  EhtCapabilities GetEhtCapabilities(uint16_t maxMpduLength,
377  uint32_t maxAmpduSize,
378  uint8_t maxSupportedMcs) const;
379 
386  Buffer SerializeIntoBuffer(const EhtCapabilities& ehtCapabilities);
387 
395  void CheckSerializedByte(const Buffer& buffer, uint32_t position, uint8_t value);
396 
403  void CheckEhtMacCapabilitiesInformation(const Buffer& buffer, uint8_t expectedValueFirstByte);
404 
411  void CheckEhtPhyCapabilitiesInformation(const Buffer& buffer, uint8_t expectedValueSixthByte);
412 
419  void CheckSupportedEhtMcsAndNssSet(const Buffer& buffer, uint8_t maxSupportedMcs);
420 
421  private:
422  void DoRun() override;
423 
424  bool m_is2_4Ghz;
425  uint16_t m_channelWidth;
426 };
427 
428 WifiEhtCapabilitiesIeTest ::WifiEhtCapabilitiesIeTest(bool is2_4Ghz, uint16_t channelWidth)
429  : HeaderSerializationTestCase{"Check serialization and deserialization of EHT capabilities IE"},
430  m_is2_4Ghz{is2_4Ghz},
431  m_channelWidth{channelWidth}
432 {
433 }
434 
437 {
438  HeCapabilities capabilities;
439  uint8_t channelWidthSet = 0;
440  if ((m_channelWidth >= 40) && m_is2_4Ghz)
441  {
442  channelWidthSet |= 0x01;
443  }
444  if ((m_channelWidth >= 80) && !m_is2_4Ghz)
445  {
446  channelWidthSet |= 0x02;
447  }
448  if ((m_channelWidth >= 160) && !m_is2_4Ghz)
449  {
450  channelWidthSet |= 0x04;
451  }
452  capabilities.SetChannelWidthSet(channelWidthSet);
453  return capabilities;
454 }
455 
458  uint32_t maxAmpduSize,
459  uint8_t maxSupportedMcs) const
460 {
461  EhtCapabilities capabilities;
462 
463  if (m_is2_4Ghz)
464  {
465  capabilities.SetMaxMpduLength(maxMpduLength);
466  }
467  // round to the next power of two minus one
468  maxAmpduSize = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduSize + 1)))) - 1;
469  // The maximum A-MPDU length in EHT capabilities elements ranges from 2^23-1 to 2^24-1
470  capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduSize, 8388607U), 16777215U));
471 
473  (maxSupportedMcs >= 12) ? 1 : 0;
475  (maxSupportedMcs >= 12) ? 1 : 0;
476  if (m_channelWidth == 20)
477  {
478  for (auto maxMcs : {7, 9, 11, 13})
479  {
480  capabilities.SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY,
481  maxMcs,
482  maxMcs <= maxSupportedMcs ? 1 : 0);
483  capabilities.SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY,
484  maxMcs,
485  maxMcs <= maxSupportedMcs ? 2 : 0);
486  }
487  }
488  else
489  {
490  for (auto maxMcs : {9, 11, 13})
491  {
492  capabilities.SetSupportedRxEhtMcsAndNss(
493  EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ,
494  maxMcs,
495  maxMcs <= maxSupportedMcs ? 3 : 0);
496  capabilities.SetSupportedTxEhtMcsAndNss(
497  EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ,
498  maxMcs,
499  maxMcs <= maxSupportedMcs ? 4 : 0);
500  }
501  }
502  if (m_channelWidth >= 160)
503  {
504  for (auto maxMcs : {9, 11, 13})
505  {
506  capabilities.SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_160_MHZ,
507  maxMcs,
508  maxMcs <= maxSupportedMcs ? 2 : 0);
509  capabilities.SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_160_MHZ,
510  maxMcs,
511  maxMcs <= maxSupportedMcs ? 1 : 0);
512  }
513  }
514  if (m_channelWidth == 320)
515  {
516  capabilities.m_phyCapabilities.support320MhzIn6Ghz = 1;
517  for (auto maxMcs : {9, 11, 13})
518  {
519  capabilities.SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_320_MHZ,
520  maxMcs,
521  maxMcs <= maxSupportedMcs ? 4 : 0);
522  capabilities.SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_320_MHZ,
523  maxMcs,
524  maxMcs <= maxSupportedMcs ? 3 : 0);
525  }
526  }
527  else
528  {
529  capabilities.m_phyCapabilities.support320MhzIn6Ghz = 0;
530  }
531 
532  return capabilities;
533 }
534 
535 Buffer
537 {
538  Buffer buffer;
539  buffer.AddAtStart(ehtCapabilities.GetSerializedSize());
540  ehtCapabilities.Serialize(buffer.Begin());
541  return buffer;
542 }
543 
544 void
546  uint32_t position,
547  uint8_t value)
548 {
549  Buffer::Iterator it = buffer.Begin();
550  it.Next(position);
551  uint8_t byte = it.ReadU8();
552  NS_TEST_EXPECT_MSG_EQ(+byte, +value, "Unexpected byte at pos=" << position);
553 }
554 
555 void
557  uint8_t expectedValueFirstByte)
558 {
559  CheckSerializedByte(buffer, 3, expectedValueFirstByte);
560  CheckSerializedByte(buffer, 4, 0x00);
561 }
562 
563 void
565  uint8_t expectedValueSixthByte)
566 {
567  CheckSerializedByte(buffer, 5, (m_channelWidth == 320) ? 0x02 : 0x00);
568  CheckSerializedByte(buffer, 6, 0x00);
569  CheckSerializedByte(buffer, 7, 0x00);
570  CheckSerializedByte(buffer, 8, 0x00);
571  CheckSerializedByte(buffer, 9, 0x00);
572  CheckSerializedByte(buffer, 10, expectedValueSixthByte);
573  CheckSerializedByte(buffer, 11, 0x00);
574  CheckSerializedByte(buffer, 12, 0x00);
575  CheckSerializedByte(buffer, 13, 0x00);
576 }
577 
578 void
580  uint8_t maxSupportedMcs)
581 {
582  if (m_channelWidth == 20)
583  {
584  CheckSerializedByte(buffer, 14, 0x21); // first byte of Supported EHT-MCS And NSS Set
586  buffer,
587  15,
588  maxSupportedMcs >= 8 ? 0x21 : 0x00); // second byte of Supported EHT-MCS And NSS Set
590  buffer,
591  16,
592  maxSupportedMcs >= 10 ? 0x21 : 0x00); // third byte of Supported EHT-MCS And NSS Set
594  buffer,
595  17,
596  maxSupportedMcs >= 12 ? 0x21 : 0x00); // fourth byte of Supported EHT-MCS And NSS Set
597  }
598  else
599  {
600  CheckSerializedByte(buffer, 14, 0x43); // first byte of Supported EHT-MCS And NSS Set
602  buffer,
603  15,
604  maxSupportedMcs >= 10 ? 0x43 : 0x00); // second byte of Supported EHT-MCS And NSS Set
606  buffer,
607  16,
608  maxSupportedMcs >= 12 ? 0x43 : 0x00); // third byte of Supported EHT-MCS And NSS Set
609  }
610  if (m_channelWidth >= 160)
611  {
612  CheckSerializedByte(buffer, 17, 0x12); // first byte of EHT-MCS Map (BW = 160 MHz)
614  buffer,
615  18,
616  maxSupportedMcs >= 10 ? 0x12 : 0x00); // second byte of EHT-MCS Map (BW = 160 MHz)
618  buffer,
619  19,
620  maxSupportedMcs >= 12 ? 0x12 : 0x00); // third byte of EHT-MCS Map (BW = 160 MHz)
621  }
622  if (m_channelWidth == 320)
623  {
624  CheckSerializedByte(buffer, 20, 0x34); // first byte of EHT-MCS Map (BW = 320 MHz)
626  buffer,
627  21,
628  maxSupportedMcs >= 10 ? 0x34 : 0x00); // second byte of EHT-MCS Map (BW = 320 MHz)
630  buffer,
631  22,
632  maxSupportedMcs >= 12 ? 0x34 : 0x00); // third byte of EHT-MCS Map (BW = 320 MHz)
633  }
634 }
635 
636 void
638 {
639  uint8_t maxMcs = 0;
640  uint16_t expectedEhtMcsAndNssSetSize = 0;
641  switch (m_channelWidth)
642  {
643  case 20:
644  expectedEhtMcsAndNssSetSize = 4;
645  break;
646  case 40:
647  case 80:
648  expectedEhtMcsAndNssSetSize = 3;
649  break;
650  case 160:
651  expectedEhtMcsAndNssSetSize = (2 * 3);
652  break;
653  case 320:
654  expectedEhtMcsAndNssSetSize = (3 * 3);
655  break;
656  default:
657  NS_ASSERT_MSG(false, "Invalid upper channel width " << m_channelWidth);
658  }
659 
660  uint16_t expectedSize = 1 + // Element ID
661  1 + // Length
662  1 + // Element ID Extension
663  2 + // EHT MAC Capabilities Information
664  9 + // EHT PHY Capabilities Information
665  expectedEhtMcsAndNssSetSize; // Supported EHT-MCS And NSS Set
666 
667  auto mapType = m_channelWidth == 20 ? EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_20_MHZ_ONLY
668  : EhtMcsAndNssSet::EHT_MCS_MAP_TYPE_NOT_LARGER_THAN_80_MHZ;
669 
670  {
671  maxMcs = 11;
672  HeCapabilities heCapabilities = GetHeCapabilities();
673  EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
674 
675  NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
676  NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
677 
678  NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
679  expectedSize,
680  "Unexpected header size");
681 
682  Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
683 
685 
687 
688  CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
689 
690  TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
691  }
692 
693  {
694  maxMcs = 11;
695  HeCapabilities heCapabilities = GetHeCapabilities();
696  EhtCapabilities ehtCapabilities = GetEhtCapabilities(11454, 65535, maxMcs);
697 
698  NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
699  NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
700 
701  NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
702  expectedSize,
703  "Unexpected header size");
704 
705  Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
706 
707  CheckEhtMacCapabilitiesInformation(buffer, m_is2_4Ghz ? 0x80 : 0x00);
708 
710 
711  CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
712 
713  TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
714  }
715 
716  {
717  maxMcs = 13;
718  HeCapabilities heCapabilities = GetHeCapabilities();
719  EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
720 
721  NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
722  NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
723 
724  NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
725  expectedSize,
726  "Unexpected header size");
727 
728  Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
729 
731 
733 
734  CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
735 
736  TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
737  }
738 
739  {
740  maxMcs = 11;
741  HeCapabilities heCapabilities = GetHeCapabilities();
742  EhtCapabilities ehtCapabilities = GetEhtCapabilities(3895, 65535, maxMcs);
743 
744  NS_ASSERT(ehtCapabilities.GetHighestSupportedRxMcs(mapType) == maxMcs);
745  NS_ASSERT(ehtCapabilities.GetHighestSupportedTxMcs(mapType) == maxMcs);
746 
747  std::vector<std::pair<uint8_t, uint8_t>> ppeThresholds;
748  ppeThresholds.emplace_back(1, 2); // NSS1 242-tones RU
749  ppeThresholds.emplace_back(2, 3); // NSS1 484-tones RU
750  ppeThresholds.emplace_back(3, 4); // NSS2 242-tones RU
751  ppeThresholds.emplace_back(4, 3); // NSS2 484-tones RU
752  ppeThresholds.emplace_back(3, 2); // NSS3 242-tones RU
753  ppeThresholds.emplace_back(2, 1); // NSS3 484-tones RU
754  ehtCapabilities.SetPpeThresholds(2, 0x03, ppeThresholds);
755 
756  expectedSize += 6;
757 
758  NS_TEST_EXPECT_MSG_EQ(ehtCapabilities.GetSerializedSize(),
759  expectedSize,
760  "Unexpected header size");
761 
762  Buffer buffer = SerializeIntoBuffer(ehtCapabilities);
763 
765 
767 
768  CheckSupportedEhtMcsAndNssSet(buffer, maxMcs);
769 
770  TestHeaderSerialization(ehtCapabilities, m_is2_4Ghz, heCapabilities);
771  }
772 }
773 
781 {
782  public:
790  template <typename... Args>
791  TidToLinkMappingElementTest(TidLinkMapDir direction, Args&&... args);
792 
793  ~TidToLinkMappingElementTest() override = default;
794 
795  private:
804  template <typename... Args>
805  void SetLinkMapping(uint8_t tid, const std::list<uint8_t>& linkIds, Args&&... args);
806 
811  {
812  }
813 
814  void DoRun() override;
815 
817 };
818 
819 template <typename... Args>
822  "Check serialization and deserialization of TID-To-Link Mapping elements")
823 {
826  SetLinkMapping(args...);
827 }
828 
829 template <typename... Args>
830 void
832  const std::list<uint8_t>& linkIds,
833  Args&&... args)
834 {
837  SetLinkMapping(args...);
838 }
839 
840 void
842 {
844 }
845 
853 {
854  public:
870  uint8_t rxMaxNss0_7,
871  uint8_t txMaxNss0_7,
872  uint8_t rxMaxNss8_9,
873  uint8_t txMaxNss8_9,
874  uint8_t rxMaxNss10_11,
875  uint8_t txMaxNss10_11,
876  uint8_t rxMaxNss12_13,
877  uint8_t txMaxNss12_13,
878  std::optional<EhtOperation::EhtOpInfo> opInfo);
879 
880  ~EhtOperationElementTest() override = default;
881 
882  private:
883  void DoRun() override;
884 
886 };
887 
889  uint8_t rxMaxNss0_7,
890  uint8_t txMaxNss0_7,
891  uint8_t rxMaxNss8_9,
892  uint8_t txMaxNss8_9,
893  uint8_t rxMaxNss10_11,
894  uint8_t txMaxNss10_11,
895  uint8_t rxMaxNss12_13,
896  uint8_t txMaxNss12_13,
897  std::optional<EhtOperation::EhtOpInfo> opInfo)
899  "Check serialization and deserialization of EHT Operation elements")
900 {
902  m_ehtOperation.SetMaxRxNss(rxMaxNss0_7, 0, 7);
903  m_ehtOperation.SetMaxTxNss(txMaxNss0_7, 0, 7);
904  m_ehtOperation.SetMaxRxNss(rxMaxNss8_9, 8, 9);
905  m_ehtOperation.SetMaxTxNss(txMaxNss8_9, 8, 9);
906  m_ehtOperation.SetMaxRxNss(rxMaxNss10_11, 10, 11);
907  m_ehtOperation.SetMaxTxNss(txMaxNss10_11, 10, 11);
908  m_ehtOperation.SetMaxRxNss(rxMaxNss12_13, 12, 13);
909  m_ehtOperation.SetMaxTxNss(txMaxNss12_13, 12, 13);
910  m_ehtOperation.m_opInfo = opInfo;
911 }
912 
913 void
915 {
917 }
918 
926 {
927  public:
929 };
930 
932  : TestSuite("wifi-eht-info-elems", UNIT)
933 {
934  AddTestCase(new BasicMultiLinkElementTest(), TestCase::QUICK);
935  AddTestCase(new ReducedNeighborReportTest(), TestCase::QUICK);
936  AddTestCase(new WifiEhtCapabilitiesIeTest(false, 20), TestCase::QUICK);
937  AddTestCase(new WifiEhtCapabilitiesIeTest(true, 20), TestCase::QUICK);
938  AddTestCase(new WifiEhtCapabilitiesIeTest(false, 80), TestCase::QUICK);
939  AddTestCase(new WifiEhtCapabilitiesIeTest(true, 40), TestCase::QUICK);
940  AddTestCase(new WifiEhtCapabilitiesIeTest(true, 80), TestCase::QUICK);
941  AddTestCase(new WifiEhtCapabilitiesIeTest(false, 160), TestCase::QUICK);
942  AddTestCase(new WifiEhtCapabilitiesIeTest(false, 320), TestCase::QUICK);
943  AddTestCase(new TidToLinkMappingElementTest(TidLinkMapDir::DOWNLINK), TestCase::QUICK);
944  AddTestCase(
945  new TidToLinkMappingElementTest(TidLinkMapDir::UPLINK, 3, std::list<uint8_t>{0, 4, 6}),
946  TestCase::QUICK);
947  AddTestCase(new TidToLinkMappingElementTest(TidLinkMapDir::BOTH_DIRECTIONS,
948  3,
949  std::list<uint8_t>{0, 4, 6},
950  6,
951  std::list<uint8_t>{3, 7, 11, 14}),
952  TestCase::QUICK);
953  AddTestCase(new TidToLinkMappingElementTest(TidLinkMapDir::DOWNLINK,
954  0,
955  std::list<uint8_t>{0, 1, 2},
956  1,
957  std::list<uint8_t>{3, 4, 5},
958  2,
959  std::list<uint8_t>{6, 7},
960  3,
961  std::list<uint8_t>{8, 9, 10},
962  4,
963  std::list<uint8_t>{11, 12, 13},
964  5,
965  std::list<uint8_t>{14},
966  6,
967  std::list<uint8_t>{1, 3, 6},
968  7,
969  std::list<uint8_t>{11, 14}),
970  TestCase::QUICK);
971  AddTestCase(new EhtOperationElementTest({0, 0, 0, 0, 0}, 1, 2, 3, 4, 5, 6, 7, 8, std::nullopt),
972  TestCase::QUICK);
973  AddTestCase(new EhtOperationElementTest({1, 0, 0, 1, 0},
974  1,
975  2,
976  3,
977  4,
978  5,
979  6,
980  7,
981  8,
982  EhtOperation::EhtOpInfo{{1}, 3, 5}),
983  TestCase::QUICK);
984  AddTestCase(new EhtOperationElementTest({1, 1, 1, 1, 2},
985  1,
986  2,
987  3,
988  4,
989  5,
990  6,
991  7,
992  8,
993  EhtOperation::EhtOpInfo{{2}, 4, 6, 3000}),
994  TestCase::QUICK);
995 }
996 
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
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.
WifiEhtCapabilitiesIeTest(bool is2_4Ghz, uint16_t channelWidth)
Constructor.
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
void Next()
go forward by one byte
Definition: buffer.h:853
automatically resized byte buffer
Definition: buffer.h:94
void AddAtStart(uint32_t start)
Definition: buffer.cc:311
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.
The IEEE 802.11be EHT Capabilities.
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.
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.
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:67
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 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...
an EUI-48 address
Definition: mac48-address.h:46
Implement the header for management frames of type association request.
Definition: mgt-headers.h:55
void SetSupportedRates(const SupportedRates &rates)
Set the supported rates.
Definition: mgt-headers.cc:941
void SetListenInterval(uint16_t interval)
Set the listen interval.
Definition: mgt-headers.cc:953
void SetCapabilities(const CapabilityInformation &capabilities)
Set the Capability information.
Definition: mgt-headers.cc:959
void SetSsid(const Ssid &ssid)
Set the Service Set Identifier (SSID).
Definition: mgt-headers.cc:929
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...
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
The Supported Rates Information Element.
void AddSupportedRate(uint64_t bs)
Add the given rate to the supported rates.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
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.
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.
#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_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:1360
@ 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.
TidLinkMapDir
TID-to-Link Mapping Control Direction IEEE 802.11be D2.0 Figure 9-1002an.
WifiMacType
Combination of valid MAC header type/subtype.
@ WIFI_MAC_MGT_ASSOCIATION_REQUEST
value
Definition: second.py:41
channel
Definition: third.py:81
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
Medium Synchronization Delay Information subfield.
uint8_t mediumSyncDuration
Medium Synchronization Duration.
Common Info field of the Basic Multi-Link element.
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:74
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