wifi: Extend non-HT duplicate tests to consider cases where a STA does not respond

This commit is contained in:
Sébastien Deronne
2023-08-15 20:09:55 +02:00
committed by Sébastien Deronne
parent 9e3068aac0
commit a6fa6bba4f

View File

@@ -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<uint16_t>& bwPerSta);
TestMultipleCtsResponsesFromMuRts(const std::vector<CtsTxInfos>& 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<SpectrumWifiPhy> phy, uint16_t bw);
void TxNonHtDuplicateCts(std::size_t phyIndex);
/**
* CTS RX success function
@@ -680,7 +688,7 @@ class TestMultipleCtsResponsesFromMuRts : public TestCase
std::vector<Ptr<MuRtsCtsSpectrumWifiPhy>> m_phyStas; ///< STAs PHYs
Ptr<SpectrumWifiPhy> m_nonHePhySta; ///< non-HE STA PHY
std::vector<uint16_t> m_bwPerSta; ///< Bandwidth per STA in MHz
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
@@ -689,9 +697,9 @@ class TestMultipleCtsResponsesFromMuRts : public TestCase
};
TestMultipleCtsResponsesFromMuRts::TestMultipleCtsResponsesFromMuRts(
const std::vector<uint16_t>& bwPerSta)
const std::vector<CtsTxInfos>& 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<SpectrumWifiPhy> 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<SpectrumWifiPhy> phy,
auto mpdu = Create<WifiMpdu>(pkt, hdr);
auto psdu = Create<WifiPsdu>(mpdu, false);
phy->Send(psdu, txVector);
m_phyStas.at(phyIndex)->Send(psdu, txVector);
}
void
@@ -757,11 +776,20 @@ TestMultipleCtsResponsesFromMuRts::RxCtsSuccess(Ptr<const WifiPsdu> psdu,
std::vector<bool> /*statusPerMpdu*/)
{
NS_LOG_FUNCTION(this << *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) * 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<Node>();
auto staDev = CreateObject<WifiNetDevice>();
@@ -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<ConstantPositionMobilityModel>();
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