diff --git a/src/wifi/test/wifi-non-ht-dup-test.cc b/src/wifi/test/wifi-non-ht-dup-test.cc index 0b60542af..89616d57e 100644 --- a/src/wifi/test/wifi-non-ht-dup-test.cc +++ b/src/wifi/test/wifi-non-ht-dup-test.cc @@ -661,37 +661,43 @@ class TestMultipleCtsResponsesFromMuRts : public TestCase /** * CTS RX success function + * \param phyIndex the index of the PHY (0 for AP) * \param psdu the PSDU * \param rxSignalInfo the info on the received signal (\see RxSignalInfo) * \param txVector the transmit vector * \param statusPerMpdu reception status per MPDU */ - void RxCtsSuccess(Ptr psdu, + void RxCtsSuccess(std::size_t phyIndex, + Ptr psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector statusPerMpdu); /** * CTS RX failure function + * \param phyIndex the index of the PHY (0 for AP) * \param psdu the PSDU */ - void RxCtsFailure(Ptr psdu); + void RxCtsFailure(std::size_t phyIndex, Ptr psdu); /** * Check the results - * \param expectedRxCtsSuccess the expected number of CTS RX success - * \param expectedRxCtsFailure the expected number of CTS RX failures */ - void CheckResults(std::size_t expectedRxCtsSuccess, std::size_t expectedRxCtsFailure); + void CheckResults(); Ptr m_phyAp; ///< AP PHY std::vector> m_phyStas; ///< STAs PHYs - Ptr m_nonHePhySta; ///< non-HE STA PHY 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 + std::size_t + m_countApRxCtsSuccess; ///< count the number of successfully received CTS frames by the AP + std::size_t + m_countApRxCtsFailure; ///< count the number of unsuccessfully received CTS frames by the AP + std::size_t m_countStaRxCtsSuccess; ///< count the number of successfully received CTS frames by + ///< the non-participating STA + std::size_t m_countStaRxCtsFailure; ///< count the number of unsuccessfully received CTS frames + ///< by the non-participating STA double m_stasTxPowerDbm; ///< TX power in dBm configured for the STAs }; @@ -700,8 +706,10 @@ TestMultipleCtsResponsesFromMuRts::TestMultipleCtsResponsesFromMuRts( const std::vector& ctsTxInfosPerSta) : TestCase{"test PHY reception of multiple CTS frames following a MU-RTS frame"}, m_ctsTxInfosPerSta{ctsTxInfosPerSta}, - m_countRxCtsSuccess{0}, - m_countRxCtsFailure{0}, + m_countApRxCtsSuccess{0}, + m_countApRxCtsFailure{0}, + m_countStaRxCtsSuccess{0}, + m_countStaRxCtsFailure{0}, m_stasTxPowerDbm(10.0) { } @@ -770,49 +778,80 @@ TestMultipleCtsResponsesFromMuRts::TxNonHtDuplicateCts(std::size_t phyIndex) } void -TestMultipleCtsResponsesFromMuRts::RxCtsSuccess(Ptr psdu, +TestMultipleCtsResponsesFromMuRts::RxCtsSuccess(std::size_t phyIndex, + Ptr psdu, RxSignalInfo rxSignalInfo, WifiTxVector txVector, std::vector /*statusPerMpdu*/) { - NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector); + NS_LOG_FUNCTION(this << phyIndex << *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) * successfulCtsInfos.size()), - 0.1, - "RX power is not correct!"); - const auto expectedWidth = + const auto isAp = (phyIndex == 0); + if (isAp) + { + NS_TEST_EXPECT_MSG_EQ_TOL(rxSignalInfo.rssi, + WToDbm(DbmToW(m_stasTxPowerDbm) * successfulCtsInfos.size()), + 0.1, + "RX power is not correct!"); + } + auto expectedWidth = std::max_element(successfulCtsInfos.cbegin(), successfulCtsInfos.cend(), [](const auto& lhs, const auto& rhs) { return lhs.bw < rhs.bw; }) ->bw; + if (!isAp) + { + expectedWidth = std::min(m_ctsTxInfosPerSta.at(phyIndex - 1).bw, expectedWidth); + } NS_TEST_ASSERT_MSG_EQ(txVector.GetChannelWidth(), expectedWidth, "Incorrect channel width in TXVECTOR"); - m_countRxCtsSuccess++; + if (isAp) + { + m_countApRxCtsSuccess++; + } + else + { + m_countStaRxCtsSuccess++; + } } void -TestMultipleCtsResponsesFromMuRts::RxCtsFailure(Ptr psdu) +TestMultipleCtsResponsesFromMuRts::RxCtsFailure(std::size_t phyIndex, Ptr psdu) { - NS_LOG_FUNCTION(this << *psdu); - m_countRxCtsFailure++; + NS_LOG_FUNCTION(this << phyIndex << *psdu); + const auto isAp = (phyIndex == 0); + if (isAp) + { + m_countApRxCtsFailure++; + } + else + { + m_countStaRxCtsFailure++; + } } void -TestMultipleCtsResponsesFromMuRts::CheckResults(std::size_t expectedRxCtsSuccess, - std::size_t expectedRxCtsFailure) +TestMultipleCtsResponsesFromMuRts::CheckResults() { - NS_TEST_ASSERT_MSG_EQ(m_countRxCtsSuccess, - expectedRxCtsSuccess, + NS_TEST_ASSERT_MSG_EQ(m_countApRxCtsSuccess, + 1, "The number of successfully received CTS frames by AP is not correct!"); - NS_TEST_ASSERT_MSG_EQ(m_countRxCtsFailure, - expectedRxCtsFailure, + NS_TEST_ASSERT_MSG_EQ( + m_countStaRxCtsSuccess, + m_ctsTxInfosPerSta.size(), + "The number of successfully received CTS frames by non-participating STAs is not correct!"); + NS_TEST_ASSERT_MSG_EQ(m_countApRxCtsFailure, + 0, "The number of unsuccessfully received CTS frames by AP is not correct!"); + NS_TEST_ASSERT_MSG_EQ(m_countStaRxCtsFailure, + 0, + "The number of unsuccessfully received CTS frames by non-participating " + "STAs is not correct!"); } void @@ -846,9 +885,9 @@ TestMultipleCtsResponsesFromMuRts::DoSetup() m_phyAp->AssignStreams(streamNumber); m_phyAp->SetReceiveOkCallback( - MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsSuccess, this)); + MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsSuccess, this).Bind(0)); m_phyAp->SetReceiveErrorCallback( - MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsFailure, this)); + MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsFailure, this).Bind(0)); const auto apBw = std::max_element(m_ctsTxInfosPerSta.cbegin(), @@ -903,26 +942,55 @@ TestMultipleCtsResponsesFromMuRts::DoSetup() staNode->AggregateObject(staMobility); staNode->AddDevice(staDev); m_phyStas.push_back(phySta); + + // non-participating HE STA + auto nonParticipatingHeStaNode = CreateObject(); + auto nonParticipatingHeStaDev = CreateObject(); + auto nonParticipatingHePhySta = CreateObject(); + auto nonParticipatingHeStaInterferenceHelper = CreateObject(); + nonParticipatingHePhySta->SetInterferenceHelper(nonParticipatingHeStaInterferenceHelper); + auto nonParticipatingHeStaErrorModel = CreateObject(); + nonParticipatingHePhySta->SetErrorRateModel(nonParticipatingHeStaErrorModel); + nonParticipatingHePhySta->SetDevice(nonParticipatingHeStaDev); + nonParticipatingHePhySta->AddChannel(spectrumChannel); + nonParticipatingHePhySta->ConfigureStandard(WIFI_STANDARD_80211ax); + + nonParticipatingHePhySta->SetOperatingChannel( + WifiPhy::ChannelTuple{channelNum, m_ctsTxInfosPerSta.at(i).bw, WIFI_PHY_BAND_5GHZ, 0}); + + auto nonParticipatingHeStaMobility = CreateObject(); + nonParticipatingHePhySta->SetMobility(nonParticipatingHeStaMobility); + nonParticipatingHeStaDev->SetPhy(nonParticipatingHePhySta); + nonParticipatingHeStaDev->SetStandard(WIFI_STANDARD_80211ax); + nonParticipatingHeStaDev->SetHeConfiguration(CreateObject()); + nonParticipatingHePhySta->AssignStreams(streamNumber); + nonParticipatingHeStaNode->AggregateObject(nonParticipatingHeStaMobility); + nonParticipatingHeStaNode->AddDevice(nonParticipatingHeStaDev); + + nonParticipatingHePhySta->SetReceiveOkCallback( + MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsSuccess, this).Bind(i + 1)); + nonParticipatingHePhySta->SetReceiveErrorCallback( + MakeCallback(&TestMultipleCtsResponsesFromMuRts::RxCtsFailure, this).Bind(i + 1)); } // non-HE STA auto nonHeStaNode = CreateObject(); auto nonHeStaDev = CreateObject(); - m_nonHePhySta = CreateObject(); + auto nonHePhySta = CreateObject(); auto nonHeStaInterferenceHelper = CreateObject(); - m_nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper); + nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper); auto nonHeStaErrorModel = CreateObject(); - m_nonHePhySta->SetErrorRateModel(nonHeStaErrorModel); - m_nonHePhySta->SetDevice(nonHeStaDev); - m_nonHePhySta->AddChannel(spectrumChannel); - m_nonHePhySta->ConfigureStandard(WIFI_STANDARD_80211ac); - m_nonHePhySta->SetOperatingChannel( + nonHePhySta->SetErrorRateModel(nonHeStaErrorModel); + nonHePhySta->SetDevice(nonHeStaDev); + nonHePhySta->AddChannel(spectrumChannel); + nonHePhySta->ConfigureStandard(WIFI_STANDARD_80211ac); + nonHePhySta->SetOperatingChannel( WifiPhy::ChannelTuple{apChannelNum, apBw, WIFI_PHY_BAND_5GHZ, 0}); auto nonHeStaMobility = CreateObject(); - m_nonHePhySta->SetMobility(nonHeStaMobility); - nonHeStaDev->SetPhy(m_nonHePhySta); + nonHePhySta->SetMobility(nonHeStaMobility); + nonHeStaDev->SetPhy(nonHePhySta); nonHeStaDev->SetStandard(WIFI_STANDARD_80211ac); - m_nonHePhySta->AssignStreams(streamNumber); + nonHePhySta->AssignStreams(streamNumber); nonHeStaNode->AggregateObject(nonHeStaMobility); nonHeStaNode->AddDevice(nonHeStaDev); } @@ -959,7 +1027,7 @@ TestMultipleCtsResponsesFromMuRts::DoRun() // Verify successful reception of the CTS frames: since multiple copies are sent // simultaneously, a single CTS frame should be forwarded up to the MAC. - Simulator::Schedule(Seconds(1.0), &TestMultipleCtsResponsesFromMuRts::CheckResults, this, 1, 0); + Simulator::Schedule(Seconds(1.0), &TestMultipleCtsResponsesFromMuRts::CheckResults, this); Simulator::Run(); Simulator::Destroy(); @@ -1030,7 +1098,6 @@ WifiNonHtDuplicateTestSuite::WifiNonHtDuplicateTestSuite() {WIFI_STANDARD_80211ac, 5230, 0}}, {false, true, false, false}), TestCase::QUICK); - /* 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);