wifi: Extend non-HT duplicate tests to verify channel width in TXVECTOR for non-participating HE STAs

This commit is contained in:
Sébastien Deronne
2023-09-03 12:39:15 +02:00
committed by Sébastien Deronne
parent a6fa6bba4f
commit 3396b046e8

View File

@@ -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<const WifiPsdu> psdu,
void RxCtsSuccess(std::size_t phyIndex,
Ptr<const WifiPsdu> psdu,
RxSignalInfo rxSignalInfo,
WifiTxVector txVector,
std::vector<bool> statusPerMpdu);
/**
* CTS RX failure function
* \param phyIndex the index of the PHY (0 for AP)
* \param psdu the PSDU
*/
void RxCtsFailure(Ptr<const WifiPsdu> psdu);
void RxCtsFailure(std::size_t phyIndex, Ptr<const WifiPsdu> 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<MuRtsCtsSpectrumWifiPhy> m_phyAp; ///< AP PHY
std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas; ///< STAs PHYs
Ptr<SpectrumWifiPhy> m_nonHePhySta; ///< non-HE STA PHY
std::vector<CtsTxInfos> 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<CtsTxInfos>& 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<const WifiPsdu> psdu,
TestMultipleCtsResponsesFromMuRts::RxCtsSuccess(std::size_t phyIndex,
Ptr<const WifiPsdu> psdu,
RxSignalInfo rxSignalInfo,
WifiTxVector txVector,
std::vector<bool> /*statusPerMpdu*/)
{
NS_LOG_FUNCTION(this << *psdu << rxSignalInfo << txVector);
NS_LOG_FUNCTION(this << phyIndex << *psdu << rxSignalInfo << txVector);
std::vector<CtsTxInfos> 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<const WifiPsdu> psdu)
TestMultipleCtsResponsesFromMuRts::RxCtsFailure(std::size_t phyIndex, Ptr<const WifiPsdu> 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<Node>();
auto nonParticipatingHeStaDev = CreateObject<WifiNetDevice>();
auto nonParticipatingHePhySta = CreateObject<SpectrumWifiPhy>();
auto nonParticipatingHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
nonParticipatingHePhySta->SetInterferenceHelper(nonParticipatingHeStaInterferenceHelper);
auto nonParticipatingHeStaErrorModel = CreateObject<NistErrorRateModel>();
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<ConstantPositionMobilityModel>();
nonParticipatingHePhySta->SetMobility(nonParticipatingHeStaMobility);
nonParticipatingHeStaDev->SetPhy(nonParticipatingHePhySta);
nonParticipatingHeStaDev->SetStandard(WIFI_STANDARD_80211ax);
nonParticipatingHeStaDev->SetHeConfiguration(CreateObject<HeConfiguration>());
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<Node>();
auto nonHeStaDev = CreateObject<WifiNetDevice>();
m_nonHePhySta = CreateObject<SpectrumWifiPhy>();
auto nonHePhySta = CreateObject<SpectrumWifiPhy>();
auto nonHeStaInterferenceHelper = CreateObject<InterferenceHelper>();
m_nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
nonHePhySta->SetInterferenceHelper(nonHeStaInterferenceHelper);
auto nonHeStaErrorModel = CreateObject<NistErrorRateModel>();
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<ConstantPositionMobilityModel>();
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);