wifi: Extend non-HT duplicate tests to consider cases where a STA does not respond
This commit is contained in:
committed by
Sébastien Deronne
parent
9e3068aac0
commit
a6fa6bba4f
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user