diff --git a/src/wifi/test/wifi-mac-ofdma-test.cc b/src/wifi/test/wifi-mac-ofdma-test.cc index ecaffeee8..1d3aa090c 100644 --- a/src/wifi/test/wifi-mac-ofdma-test.cc +++ b/src/wifi/test/wifi-mac-ofdma-test.cc @@ -30,6 +30,7 @@ #include "ns3/wifi-psdu.h" #include +#include using namespace ns3; @@ -337,28 +338,42 @@ TestMultiUserScheduler::ComputeWifiTxVector() 0); break; } + case 320: { + ruType = RuType::RU_996_TONE; + NS_ASSERT(IsEht(m_txVector.GetPreambleType())); + m_txVector.SetRuAllocation({80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80}, + 0); + break; + } default: - NS_ABORT_MSG("Unsupported channel width"); + NS_ABORT_MSG("Unsupported channel width: " << bw); } - auto primary80{true}; + auto primary80OrLow80{true}; + auto primary160{true}; std::size_t ruIndex{1}; for (auto& sta : staList) { auto index{ruIndex}; - if (!IsEht(m_txVector.GetPreambleType()) && (bw == MHz_u{160}) && (ruIndex >= 3)) + if (bw > MHz_u{80}) { - index = ruIndex - 2; - primary80 = false; + if (!IsEht(m_txVector.GetPreambleType())) + { + index = HeRu::GetIndexIn80MHzSegment(bw, ruType, ruIndex); + primary80OrLow80 = HeRu::GetPrimary80MHzFlag(bw, ruType, ruIndex, 0); + } + else + { + index = EhtRu::GetIndexIn80MHzSegment(bw, ruType, ruIndex); + const auto& [p160, p80OrLow80] = EhtRu::GetPrimaryFlags(bw, ruType, ruIndex, 0); + primary160 = p160; + primary80OrLow80 = p80OrLow80; + } } - if (IsEht(m_txVector.GetPreambleType()) && (bw > MHz_u{80})) - { - index = EhtRu::GetIndexIn80MHzSegment(bw, ruType, ruIndex); - primary80 = EhtRu::GetPrimaryFlags(bw, ruType, ruIndex, 0).second; - } - const auto ru = IsEht(m_txVector.GetPreambleType()) - ? WifiRu::RuSpec(EhtRu::RuSpec{ruType, index, true, primary80}) - : WifiRu::RuSpec(HeRu::RuSpec{ruType, index, primary80}); + const auto ru = + IsEht(m_txVector.GetPreambleType()) + ? WifiRu::RuSpec(EhtRu::RuSpec{ruType, index, primary160, primary80OrLow80}) + : WifiRu::RuSpec(HeRu::RuSpec{ruType, index, primary80OrLow80}); m_txVector.SetHeMuUserInfo(sta.first, {ru, 11, 1}); ruIndex++; } @@ -566,6 +581,9 @@ OfdmaAckSequenceTest::OfdmaAckSequenceTest(const Params& params) case 160: m_muRtsRuAllocation = 68; break; + case 320: + m_muRtsRuAllocation = 69; + break; default: NS_ABORT_MSG("Unhandled channel width (" << m_channelWidth << " MHz)"); } @@ -607,7 +625,10 @@ OfdmaAckSequenceTest::Transmit(std::string context, // request/response, ADDBA request, ...) if (!psduMap.begin()->second->GetHeader(0).IsBeacon() && Simulator::Now() >= Seconds(1.5)) { - Time txDuration = WifiPhy::CalculateTxDuration(psduMap, txVector, WIFI_PHY_BAND_5GHZ); + Time txDuration = WifiPhy::CalculateTxDuration( + psduMap, + txVector, + (m_channelWidth < MHz_u{320}) ? WIFI_PHY_BAND_5GHZ : WIFI_PHY_BAND_6GHZ); m_txPsdus.push_back({Simulator::Now(), Simulator::Now() + txDuration, psduMap, txVector}); for (const auto& [staId, psdu] : psduMap) @@ -710,7 +731,10 @@ OfdmaAckSequenceTest::Transmit(std::string context, { // the AP is starting the transmission of the Basic Trigger frame, so generate // the configured number of packets at STAs, which are sent in HE TB PPDUs - Time txDuration = WifiPhy::CalculateTxDuration(psduMap, txVector, WIFI_PHY_BAND_5GHZ); + Time txDuration = WifiPhy::CalculateTxDuration( + psduMap, + txVector, + (m_channelWidth < MHz_u{320}) ? WIFI_PHY_BAND_5GHZ : WIFI_PHY_BAND_6GHZ); for (uint16_t i = 0; i < m_nStations; i++) { Ptr client = CreateObject(); @@ -2093,8 +2117,11 @@ OfdmaAckSequenceTest::DoRun() case 160: phy.Set("ChannelSettings", StringValue("{50, 160, BAND_5GHZ, 0}")); break; + case 320: + phy.Set("ChannelSettings", StringValue("{31, 320, BAND_6GHZ, 0}")); + break; default: - NS_ABORT_MSG("Invalid channel bandwidth (must be 20, 40, 80 or 160)"); + NS_ABORT_MSG("Invalid channel bandwidth: " << m_channelWidth); } Config::SetDefault("ns3::HeConfiguration::MuBeAifsn", @@ -2200,9 +2227,12 @@ OfdmaAckSequenceTest::DoRun() : WIFI_STANDARD_80211be); m_staDevices = NetDeviceContainer(m_staDevices, wifi.Install(phy, mac, wifiNewStaNodes)); - // create a listening VHT station - wifi.SetStandard(WIFI_STANDARD_80211ac); - wifi.Install(phy, mac, Create()); + if (m_channelWidth < MHz_u{320}) + { + // create a listening VHT station + wifi.SetStandard(WIFI_STANDARD_80211ac); + wifi.Install(phy, mac, Create()); + } wifi.SetStandard(m_scenario == WifiOfdmaScenario::HE ? WIFI_STANDARD_80211ax : WIFI_STANDARD_80211be); @@ -2376,86 +2406,100 @@ WifiMacOfdmaTestSuite::WifiMacOfdmaTestSuite() : TestSuite("wifi-mac-ofdma", Type::UNIT) { using MuEdcaParams = std::initializer_list; + using ChannelWidths = std::initializer_list>; - for (auto& muEdcaParameterSet : MuEdcaParams{{0, 0, 0, 0} /* no MU EDCA */, - {0, 127, 2047, 100} /* EDCA disabled */, + for (auto& muEdcaParameterSet : MuEdcaParams{{0, 0, 0, 0}, /* no MU EDCA */ + {0, 127, 2047, 100}, /* EDCA disabled */ {10, 127, 2047, 100} /* worse parameters */}) { for (const auto scenario : {WifiOfdmaScenario::HE, WifiOfdmaScenario::HE_EHT, WifiOfdmaScenario::EHT}) { - AddTestCase(new OfdmaAckSequenceTest( - {.channelWidth = MHz_u{20}, - .dlMuAckType = WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE, - .maxAmpduSize = 10000, - .txopLimit = 5632, - .continueTxopAfterBsrp = false, // unused because non-zero TXOP limit - .skipMuRtsBeforeBsrp = true, - .protectedIfResponded = false, - .nPktsPerSta = 15, - .muEdcaParameterSet = muEdcaParameterSet, - .scenario = scenario}), - TestCase::Duration::QUICK); - AddTestCase(new OfdmaAckSequenceTest( - {.channelWidth = MHz_u{20}, - .dlMuAckType = WifiAcknowledgment::DL_MU_AGGREGATE_TF, - .maxAmpduSize = 10000, - .txopLimit = 5632, - .continueTxopAfterBsrp = false, // unused because non-zero TXOP limit - .skipMuRtsBeforeBsrp = false, - .protectedIfResponded = false, - .nPktsPerSta = 15, - .muEdcaParameterSet = muEdcaParameterSet, - .scenario = scenario}), - TestCase::Duration::QUICK); - AddTestCase(new OfdmaAckSequenceTest( - {.channelWidth = MHz_u{20}, - .dlMuAckType = WifiAcknowledgment::DL_MU_TF_MU_BAR, - .maxAmpduSize = 10000, - .txopLimit = 5632, - .continueTxopAfterBsrp = false, // unused because non-zero TXOP limit - .skipMuRtsBeforeBsrp = true, - .protectedIfResponded = true, - .nPktsPerSta = 15, - .muEdcaParameterSet = muEdcaParameterSet, - .scenario = scenario}), - TestCase::Duration::QUICK); - AddTestCase( - new OfdmaAckSequenceTest({.channelWidth = MHz_u{40}, - .dlMuAckType = WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE, - .maxAmpduSize = 10000, - .txopLimit = 0, - .continueTxopAfterBsrp = true, - .skipMuRtsBeforeBsrp = false, - .protectedIfResponded = false, - .nPktsPerSta = 15, - .muEdcaParameterSet = muEdcaParameterSet, - .scenario = scenario}), - TestCase::Duration::QUICK); - AddTestCase( - new OfdmaAckSequenceTest({.channelWidth = MHz_u{40}, - .dlMuAckType = WifiAcknowledgment::DL_MU_AGGREGATE_TF, - .maxAmpduSize = 10000, - .txopLimit = 0, - .continueTxopAfterBsrp = false, - .skipMuRtsBeforeBsrp = true, - .protectedIfResponded = false, - .nPktsPerSta = 15, - .muEdcaParameterSet = muEdcaParameterSet, - .scenario = scenario}), - TestCase::Duration::QUICK); - AddTestCase( - new OfdmaAckSequenceTest({.channelWidth = MHz_u{40}, - .dlMuAckType = WifiAcknowledgment::DL_MU_TF_MU_BAR, - .maxAmpduSize = 10000, - .txopLimit = 0, - .continueTxopAfterBsrp = true, - .skipMuRtsBeforeBsrp = false, - .protectedIfResponded = true, - .nPktsPerSta = 15, - .muEdcaParameterSet = muEdcaParameterSet, - .scenario = scenario}), - TestCase::Duration::QUICK); + // limit test to 2 channel widths per TXOP limit combination + for (const auto& [chWidth1, chWidth2] : ChannelWidths{{MHz_u{20}, MHz_u{40}}, + {MHz_u{80}, MHz_u{160}}, + {MHz_u{320}, MHz_u{320}}}) + { + if ((chWidth1 > MHz_u{160}) && (scenario < WifiOfdmaScenario::EHT)) + { + continue; + } + AddTestCase( + new OfdmaAckSequenceTest( + {.channelWidth = chWidth1, + .dlMuAckType = WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE, + .maxAmpduSize = 10000, + .txopLimit = 5632, + .continueTxopAfterBsrp = false, // unused because non-zero TXOP limit + .skipMuRtsBeforeBsrp = true, + .protectedIfResponded = false, + .nPktsPerSta = 15, + .muEdcaParameterSet = muEdcaParameterSet, + .scenario = scenario}), + TestCase::Duration::QUICK); + AddTestCase( + new OfdmaAckSequenceTest( + {.channelWidth = chWidth1, + .dlMuAckType = WifiAcknowledgment::DL_MU_AGGREGATE_TF, + .maxAmpduSize = 10000, + .txopLimit = 5632, + .continueTxopAfterBsrp = false, // unused because non-zero TXOP limit + .skipMuRtsBeforeBsrp = false, + .protectedIfResponded = false, + .nPktsPerSta = 15, + .muEdcaParameterSet = muEdcaParameterSet, + .scenario = scenario}), + TestCase::Duration::QUICK); + AddTestCase( + new OfdmaAckSequenceTest( + {.channelWidth = chWidth1, + .dlMuAckType = WifiAcknowledgment::DL_MU_TF_MU_BAR, + .maxAmpduSize = 10000, + .txopLimit = 5632, + .continueTxopAfterBsrp = false, // unused because non-zero TXOP limit + .skipMuRtsBeforeBsrp = true, + .protectedIfResponded = true, + .nPktsPerSta = 15, + .muEdcaParameterSet = muEdcaParameterSet, + .scenario = scenario}), + TestCase::Duration::QUICK); + AddTestCase(new OfdmaAckSequenceTest( + {.channelWidth = chWidth2, + .dlMuAckType = WifiAcknowledgment::DL_MU_BAR_BA_SEQUENCE, + .maxAmpduSize = 10000, + .txopLimit = 0, + .continueTxopAfterBsrp = true, + .skipMuRtsBeforeBsrp = false, + .protectedIfResponded = false, + .nPktsPerSta = 15, + .muEdcaParameterSet = muEdcaParameterSet, + .scenario = scenario}), + TestCase::Duration::QUICK); + AddTestCase( + new OfdmaAckSequenceTest({.channelWidth = chWidth2, + .dlMuAckType = WifiAcknowledgment::DL_MU_AGGREGATE_TF, + .maxAmpduSize = 10000, + .txopLimit = 0, + .continueTxopAfterBsrp = false, + .skipMuRtsBeforeBsrp = true, + .protectedIfResponded = false, + .nPktsPerSta = 15, + .muEdcaParameterSet = muEdcaParameterSet, + .scenario = scenario}), + TestCase::Duration::QUICK); + AddTestCase( + new OfdmaAckSequenceTest({.channelWidth = chWidth2, + .dlMuAckType = WifiAcknowledgment::DL_MU_TF_MU_BAR, + .maxAmpduSize = 10000, + .txopLimit = 0, + .continueTxopAfterBsrp = true, + .skipMuRtsBeforeBsrp = false, + .protectedIfResponded = true, + .nPktsPerSta = 15, + .muEdcaParameterSet = muEdcaParameterSet, + .scenario = scenario}), + TestCase::Duration::QUICK); + } } } }