From a6fa6bba4f312deb7e6b2078d19f65ada91c3e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deronne?= Date: Tue, 15 Aug 2023 20:09:55 +0200 Subject: [PATCH] wifi: Extend non-HT duplicate tests to consider cases where a STA does not respond --- src/wifi/test/wifi-non-ht-dup-test.cc | 115 ++++++++++++++++++-------- 1 file changed, 79 insertions(+), 36 deletions(-) diff --git a/src/wifi/test/wifi-non-ht-dup-test.cc b/src/wifi/test/wifi-non-ht-dup-test.cc index 93eb99949..0b60542af 100644 --- a/src/wifi/test/wifi-non-ht-dup-test.cc +++ b/src/wifi/test/wifi-non-ht-dup-test.cc @@ -622,16 +622,25 @@ TestNonHtDuplicatePhyReception::DoRun() * MU-RTS frame is successfully received by the AP PHY and that only a single CTS frame is forwarded * up to the MAC. Since the test is focusing on the PHY reception of multiple CTS response, the * transmission of the MU-RTS frame is faked. The test also checks the correct channel width is - * passed to the MAC layer through the TXVECTOR. + * passed to the MAC layer through the TXVECTOR. The test also consider the case some STAs do not + * respond to verify the largest channel width of the successfully CTS responses is reported to the + * MAC. */ class TestMultipleCtsResponsesFromMuRts : public TestCase { public: + /// Information about CTS responses to expect in the test + struct CtsTxInfos + { + uint16_t bw{20}; ///< the width in MHz of the CTS response + bool discard{false}; ///< flag whether the CTS response shall be discarded + }; + /** * Constructor - * \param bwPerSta the bandwidth to use for each STA (in MHz) + * \param ctsTxInfosPerSta the information about CTS responses to generate */ - TestMultipleCtsResponsesFromMuRts(const std::vector& bwPerSta); + TestMultipleCtsResponsesFromMuRts(const std::vector& ctsTxInfosPerSta); private: void DoSetup() override; @@ -646,10 +655,9 @@ class TestMultipleCtsResponsesFromMuRts : public TestCase /** * Function called to trigger a CTS frame sent by a STA using non-HT duplicate. * - * \param phy the PHY of the STA - * \param bw the bandwidth to use for the transmission in MHz + * \param phyIndex the index of the TX PHY */ - void TxNonHtDuplicateCts(Ptr phy, uint16_t bw); + void TxNonHtDuplicateCts(std::size_t phyIndex); /** * CTS RX success function @@ -680,7 +688,7 @@ class TestMultipleCtsResponsesFromMuRts : public TestCase std::vector> m_phyStas; ///< STAs PHYs Ptr m_nonHePhySta; ///< non-HE STA PHY - std::vector m_bwPerSta; ///< Bandwidth per STA in MHz + std::vector m_ctsTxInfosPerSta; ///< information about CTS responses std::size_t m_countRxCtsSuccess; ///< count the number of successfully received CTS frames std::size_t m_countRxCtsFailure; ///< count the number of unsuccessfully received CTS frames @@ -689,9 +697,9 @@ class TestMultipleCtsResponsesFromMuRts : public TestCase }; TestMultipleCtsResponsesFromMuRts::TestMultipleCtsResponsesFromMuRts( - const std::vector& bwPerSta) + const std::vector& ctsTxInfosPerSta) : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"}, - m_bwPerSta{bwPerSta}, + m_ctsTxInfosPerSta{ctsTxInfosPerSta}, m_countRxCtsSuccess{0}, m_countRxCtsFailure{0}, m_stasTxPowerDbm(10.0) @@ -703,7 +711,11 @@ TestMultipleCtsResponsesFromMuRts::FakePreviousMuRts() { NS_LOG_FUNCTION(this); - const auto bw = *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend()); + const auto bw = + std::max_element(m_ctsTxInfosPerSta.cbegin(), + m_ctsTxInfosPerSta.cend(), + [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; }) + ->bw; WifiTxVector txVector; txVector.SetChannelWidth(bw); // only the channel width matters for this test @@ -719,9 +731,16 @@ TestMultipleCtsResponsesFromMuRts::FakePreviousMuRts() } void -TestMultipleCtsResponsesFromMuRts::TxNonHtDuplicateCts(Ptr phy, uint16_t bw) +TestMultipleCtsResponsesFromMuRts::TxNonHtDuplicateCts(std::size_t phyIndex) { - NS_LOG_FUNCTION(this << phy << bw); + const auto bw = m_ctsTxInfosPerSta.at(phyIndex).bw; + const auto discarded = m_ctsTxInfosPerSta.at(phyIndex).discard; + NS_LOG_FUNCTION(this << phyIndex << bw << discarded); + + if (discarded) + { + return; + } WifiTxVector txVector = WifiTxVector(OfdmPhy::GetOfdmRate54Mbps(), // use less robust modulation for test purpose @@ -747,7 +766,7 @@ TestMultipleCtsResponsesFromMuRts::TxNonHtDuplicateCts(Ptr phy, auto mpdu = Create(pkt, hdr); auto psdu = Create(mpdu, false); - phy->Send(psdu, txVector); + m_phyStas.at(phyIndex)->Send(psdu, txVector); } void @@ -757,11 +776,20 @@ TestMultipleCtsResponsesFromMuRts::RxCtsSuccess(Ptr psdu, std::vector /*statusPerMpdu*/) { NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector); + std::vector successfulCtsInfos{}; + std::copy_if(m_ctsTxInfosPerSta.cbegin(), + m_ctsTxInfosPerSta.cend(), + std::back_inserter(successfulCtsInfos), + [](const auto& info) { return !info.discard; }); NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi, - WToDbm(DbmToW(m_stasTxPowerDbm) * m_bwPerSta.size()), + WToDbm(DbmToW(m_stasTxPowerDbm) * successfulCtsInfos.size()), 0.1, "RX power is not correct!"); - const auto expectedWidth = *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend()); + const auto expectedWidth = + std::max_element(successfulCtsInfos.cbegin(), + successfulCtsInfos.cend(), + [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; }) + ->bw; NS_TEST_ASSERT_MSG_EQ(txVector.GetChannelWidth(), expectedWidth, "Incorrect channel width in TXVECTOR"); @@ -822,7 +850,11 @@ TestMultipleCtsResponsesFromMuRts::DoSetup() m_phyAp->SetReceiveErrorCallback( MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsFailure, this)); - const auto apBw = *std::max_element(m_bwPerSta.cbegin(), m_bwPerSta.cend()); + const auto apBw = + std::max_element(m_ctsTxInfosPerSta.cbegin(), + m_ctsTxInfosPerSta.cend(), + [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; }) + ->bw; auto apChannelNum = std::get<0>( *WifiPhyOperatingChannel::FindFirst(0, 0, apBw, WIFI_STANDARD_80211ac, WIFI_PHY_BAND_5GHZ)); @@ -837,7 +869,7 @@ TestMultipleCtsResponsesFromMuRts::DoSetup() apNode->AggregateObject(apMobility); apNode->AddDevice(apDev); - for (std::size_t i = 0; i < m_bwPerSta.size(); ++i) + for (std::size_t i = 0; i < m_ctsTxInfosPerSta.size(); ++i) { auto staNode = CreateObject(); auto staDev = CreateObject(); @@ -853,14 +885,15 @@ TestMultipleCtsResponsesFromMuRts::DoSetup() phySta->SetTxPowerStart(m_stasTxPowerDbm); phySta->SetTxPowerEnd(m_stasTxPowerDbm); - auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0, - 0, - m_bwPerSta.at(i), - WIFI_STANDARD_80211ac, - WIFI_PHY_BAND_5GHZ)); + auto channelNum = + std::get<0>(*WifiPhyOperatingChannel::FindFirst(0, + 0, + m_ctsTxInfosPerSta.at(i).bw, + WIFI_STANDARD_80211ac, + WIFI_PHY_BAND_5GHZ)); phySta->SetOperatingChannel( - WifiPhy::ChannelTuple{channelNum, m_bwPerSta.at(i), WIFI_PHY_BAND_5GHZ, 0}); + WifiPhy::ChannelTuple{channelNum, m_ctsTxInfosPerSta.at(i).bw, WIFI_PHY_BAND_5GHZ, 0}); auto staMobility = CreateObject(); phySta->SetMobility(staMobility); @@ -913,18 +946,15 @@ TestMultipleCtsResponsesFromMuRts::DoRun() // Fake transmission of a MU-RTS frame preceding the CTS responses Simulator::Schedule(Seconds(0.0), &TestMultipleCtsResponsesFromMuRts::FakePreviousMuRts, this); - std::size_t index = 1; - for (auto& phySta : m_phyStas) + for (std::size_t index = 0; index < m_phyStas.size(); ++index) { // Transmit CTS responses over their operating bandwidth with 1 nanosecond delay between // each other - const auto delay = index * NanoSeconds(1.0); - Simulator::Schedule(Seconds(0.0) + delay, + const auto delay = (index + 1) * NanoSeconds(1.0); + Simulator::Schedule(delay, &TestMultipleCtsResponsesFromMuRts::TxNonHtDuplicateCts, this, - phySta, - m_bwPerSta.at(index - 1)); - index++; + index); } // Verify successful reception of the CTS frames: since multiple copies are sent @@ -1003,19 +1033,32 @@ WifiNonHtDuplicateTestSuite::WifiNonHtDuplicateTestSuite() /* test PHY reception of multiple CTS responses following a MU-RTS */ /* 4 STAs operating on 20 MHz */ - AddTestCase(new TestMultipleCtsResponsesFromMuRts({20, 20, 20, 20}), TestCase::QUICK); + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{20}, {20}, {20}, {20}}), TestCase::QUICK); /* 4 STAs operating on 40 MHz */ - AddTestCase(new TestMultipleCtsResponsesFromMuRts({40, 40, 40, 40}), TestCase::QUICK); + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40}, {40}, {40}, {40}}), TestCase::QUICK); /* 4 STAs operating on 80 MHz */ - AddTestCase(new TestMultipleCtsResponsesFromMuRts({80, 80, 80, 80}), TestCase::QUICK); + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80}, {80}, {80}, {80}}), TestCase::QUICK); /* 4 STAs operating on 160 MHz */ - AddTestCase(new TestMultipleCtsResponsesFromMuRts({160, 160, 160, 160}), TestCase::QUICK); + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{160}, {160}, {160}, {160}}), + TestCase::QUICK); /* 4 STAs operating on different bandwidths with PPDUs sent with decreasing BW: 160, 80, 40 and * 20 MHz */ - AddTestCase(new TestMultipleCtsResponsesFromMuRts({160, 80, 40, 20}), TestCase::QUICK); + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{160}, {80}, {40}, {20}}), TestCase::QUICK); /* 4 STAs operating on different bandwidths with PPDUs sent with increasing BW: 20, 40, 80 and * 160 MHz */ - AddTestCase(new TestMultipleCtsResponsesFromMuRts({20, 40, 80, 160}), TestCase::QUICK); + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{20}, {40}, {80}, {160}}), TestCase::QUICK); + /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the first STA + * does not respond */ + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80, true}, {40, false}}), TestCase::QUICK); + /* 2 STAs operating on different bandwidths with PPDUs sent with decreasing BW but the second + * STA does not respond */ + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{80, false}, {40, true}}), TestCase::QUICK); + /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the first STA + * does not respond */ + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40, true}, {80, false}}), TestCase::QUICK); + /* 2 STAs operating on different bandwidths with PPDUs sent with increasing BW but the second + * STA does not respond */ + AddTestCase(new TestMultipleCtsResponsesFromMuRts({{40, false}, {80, true}}), TestCase::QUICK); } static WifiNonHtDuplicateTestSuite wifiNonHtDuplicateTestSuite; ///< the test suite