wifi: Extend multiple PHY interfaces test with an EMLSR use case

This commit is contained in:
Sébastien Deronne
2024-02-26 17:54:30 +01:00
committed by Sébastien Deronne
parent 5d54b694f3
commit 8f3053fcf2

View File

@@ -820,8 +820,9 @@ class SpectrumWifiPhyMultipleInterfacesTest : public TestCase
* \param phy the PHY to transmit the signal
* \param txPowerDbm the power in dBm to transmit the signal (this is also the received power
* since we do not have propagation loss to simplify)
* \param payloadSize the payload size in bytes
*/
void SendPpdu(Ptr<SpectrumWifiPhy> phy, double txPowerDbm);
void SendPpdu(Ptr<SpectrumWifiPhy> phy, double txPowerDbm, uint32_t payloadSize);
/**
* Callback triggered when a packet is received by a PHY
@@ -833,6 +834,27 @@ class SpectrumWifiPhyMultipleInterfacesTest : public TestCase
Ptr<const Packet> packet,
RxPowerWattPerChannelBand rxPowersW);
/**
* Receive success function
* \param index index of the RX STA
* \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 RxSuccess(std::size_t index,
Ptr<const WifiPsdu> psdu,
RxSignalInfo rxSignalInfo,
WifiTxVector txVector,
std::vector<bool> statusPerMpdu);
/**
* Receive failure function
* \param index index of the RX STA
* \param psdu the PSDU
*/
void RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu);
/**
* Schedule now to check the interferences
* \param phy the PHY for which the check has to be executed
@@ -860,6 +882,8 @@ class SpectrumWifiPhyMultipleInterfacesTest : public TestCase
*
* \param index the index to identify the RX PHY to check
* \param expectedNumRx the expected number of RX events for that PHY
* \param expectedNumRxSuccess the expected amount of successfully received packets
* \param expectedRxBytes the expected amount of received bytes
* \param expectedFrequencyRangeActiveRfInterface the expected frequency range (in MHz) of the
* active RF interface
* \param expectedConnectedPhysPerChannel the expected
@@ -867,6 +891,8 @@ class SpectrumWifiPhyMultipleInterfacesTest : public TestCase
*/
void CheckResults(std::size_t index,
uint32_t expectedNumRx,
uint32_t expectedNumRxSuccess,
uint32_t expectedRxBytes,
FrequencyRange expectedFrequencyRangeActiveRfInterface,
const std::vector<std::size_t>& expectedConnectedPhysPerChannel);
@@ -894,7 +920,12 @@ class SpectrumWifiPhyMultipleInterfacesTest : public TestCase
std::vector<Ptr<SpectrumWifiPhy>> m_rxPhys{}; //!< RX PHYs
std::vector<std::shared_ptr<TestPhyListener>> m_listeners{}; //!< listeners
std::vector<uint32_t> m_counts{0}; //!< count number of packets received by PHYs
std::vector<uint32_t> m_counts; //!< count number of packets received by PHYs
std::vector<uint32_t>
m_countRxSuccess; //!< count number of packets successfully received by PHYs
std::vector<uint32_t>
m_countRxFailure; //!< count number of packets unsuccessfully received by PHYs
std::vector<uint32_t> m_rxBytes; //!< count number of received bytes
Time m_lastTxStart{0}; //!< hold the time at which the last transmission started
Time m_lastTxEnd{0}; //!< hold the time at which the last transmission ended
@@ -923,14 +954,16 @@ SpectrumWifiPhyMultipleInterfacesTest::SwitchChannel(std::size_t index,
}
void
SpectrumWifiPhyMultipleInterfacesTest::SendPpdu(Ptr<SpectrumWifiPhy> phy, double txPowerDbm)
SpectrumWifiPhyMultipleInterfacesTest::SendPpdu(Ptr<SpectrumWifiPhy> phy,
double txPowerDbm,
uint32_t payloadSize)
{
NS_LOG_FUNCTION(this << phy << txPowerDbm << phy->GetCurrentFrequencyRange()
NS_LOG_FUNCTION(this << phy << txPowerDbm << payloadSize << phy->GetCurrentFrequencyRange()
<< phy->GetChannelWidth() << phy->GetChannelNumber());
WifiTxVector txVector =
WifiTxVector(HePhy::GetHeMcs0(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
Ptr<Packet> pkt = Create<Packet>(1000);
WifiTxVector(HePhy::GetHeMcs11(), 0, WIFI_PREAMBLE_HE_SU, 800, 1, 1, 0, 20, false, false);
Ptr<Packet> pkt = Create<Packet>(payloadSize);
WifiMacHeader hdr;
hdr.SetType(WIFI_MAC_QOSDATA);
hdr.SetQosTid(0);
@@ -949,13 +982,33 @@ SpectrumWifiPhyMultipleInterfacesTest::SendPpdu(Ptr<SpectrumWifiPhy> phy, double
void
SpectrumWifiPhyMultipleInterfacesTest::RxCallback(std::size_t index,
Ptr<const Packet> /*packet*/,
Ptr<const Packet> packet,
RxPowerWattPerChannelBand /*rxPowersW*/)
{
auto phy = m_rxPhys.at(index);
NS_LOG_FUNCTION(this << index << phy->GetCurrentFrequencyRange() << phy->GetChannelWidth()
<< phy->GetChannelNumber());
const auto payloadBytes = packet->GetSize() - 30;
NS_LOG_FUNCTION(this << index << payloadBytes << phy->GetCurrentFrequencyRange()
<< phy->GetChannelWidth() << phy->GetChannelNumber());
m_counts.at(index)++;
m_rxBytes.at(index) += payloadBytes;
}
void
SpectrumWifiPhyMultipleInterfacesTest::RxSuccess(std::size_t index,
Ptr<const WifiPsdu> psdu,
RxSignalInfo rxSignalInfo,
WifiTxVector txVector,
std::vector<bool> /*statusPerMpdu*/)
{
NS_LOG_FUNCTION(this << index << *psdu << rxSignalInfo << txVector);
m_countRxSuccess.at(index)++;
}
void
SpectrumWifiPhyMultipleInterfacesTest::RxFailure(std::size_t index, Ptr<const WifiPsdu> psdu)
{
NS_LOG_FUNCTION(this << index << *psdu);
m_countRxFailure.at(index)++;
}
void
@@ -998,10 +1051,13 @@ void
SpectrumWifiPhyMultipleInterfacesTest::CheckResults(
std::size_t index,
uint32_t expectedNumRx,
uint32_t expectedNumRxSuccess,
uint32_t expectedRxBytes,
FrequencyRange expectedFrequencyRangeActiveRfInterface,
const std::vector<std::size_t>& expectedConnectedPhysPerChannel)
{
NS_LOG_FUNCTION(this << index << expectedNumRx << expectedFrequencyRangeActiveRfInterface);
NS_LOG_FUNCTION(this << index << expectedNumRx << expectedNumRxSuccess << expectedRxBytes
<< expectedFrequencyRangeActiveRfInterface);
const auto phy = m_rxPhys.at(index);
std::size_t numActiveInterfaces = 0;
for (const auto& [freqRange, interface] : phy->GetSpectrumPhyInterfaces())
@@ -1022,12 +1078,16 @@ SpectrumWifiPhyMultipleInterfacesTest::CheckResults(
expectedConnectedPhysPerChannel.at(i),
"Incorrect number of PHYs attached to the spectrum channel");
}
NS_TEST_ASSERT_MSG_EQ(m_counts.at(index),
expectedNumRx,
"Didn't receive right number of packets");
NS_TEST_ASSERT_MSG_EQ(m_counts.at(index), expectedNumRx, "Unexpected amount of RX events");
NS_TEST_ASSERT_MSG_EQ(m_countRxSuccess.at(index),
expectedNumRxSuccess,
"Unexpected amount of successfully received packets");
NS_TEST_ASSERT_MSG_EQ(m_countRxFailure.at(index),
0,
"Unexpected amount of unsuccessfully received packets");
NS_TEST_ASSERT_MSG_EQ(m_listeners.at(index)->m_notifyRxStart,
expectedNumRx,
"Didn't receive NotifyRxStart");
expectedNumRxSuccess,
"Unexpected amount of RX payload start indication");
}
void
@@ -1072,6 +1132,19 @@ SpectrumWifiPhyMultipleInterfacesTest::Reset()
txPhy->GetChannelNumber(),
txPhy->GetChannelWidth());
}
// reset counters
for (auto& countRxSuccess : m_countRxSuccess)
{
countRxSuccess = 0;
}
for (auto& countRxFailure : m_countRxFailure)
{
countRxFailure = 0;
}
for (auto& rxBytes : m_rxBytes)
{
rxBytes = 0;
}
}
void
@@ -1155,12 +1228,20 @@ SpectrumWifiPhyMultipleInterfacesTest::DoSetup()
"PhyRxBegin",
MakeCallback(&SpectrumWifiPhyMultipleInterfacesTest::RxCallback, this).Bind(index));
rxPhy->SetReceiveOkCallback(
MakeCallback(&SpectrumWifiPhyMultipleInterfacesTest::RxSuccess, this).Bind(index));
rxPhy->SetReceiveErrorCallback(
MakeCallback(&SpectrumWifiPhyMultipleInterfacesTest::RxFailure, this).Bind(index));
auto listener = std::make_shared<TestPhyListener>();
rxPhy->RegisterListener(listener);
m_listeners.push_back(std::move(listener));
m_rxPhys.push_back(rxPhy);
m_counts.push_back(0);
m_countRxSuccess.push_back(0);
m_countRxFailure.push_back(0);
m_rxBytes.push_back(0);
}
}
@@ -1207,6 +1288,7 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
// interferences on inactive interfaces
std::vector<std::size_t>{2, 2, 2, 2}; // default channels active for all PHYs: each PHY
// only receives from its associated TX
for (std::size_t i = 0; i < 4; ++i)
{
auto txPpduPhy = m_txPhys.at(i);
@@ -1215,7 +1297,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
0);
0,
1000);
for (std::size_t j = 0; j < 4; ++j)
{
auto txPhy = m_txPhys.at(j);
@@ -1233,6 +1316,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
this,
j,
(i == j) ? 1 : 0,
(i == j) ? 1 : 0,
(i == j) ? 1000 : 0,
expectedFreqRange,
expectedConnectedPhysPerChannel);
}
@@ -1250,7 +1335,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
0);
0,
1000);
const auto& expectedFreqRange = txPpduPhy->GetCurrentFrequencyRange();
for (std::size_t j = 0; j < 4; ++j)
{
@@ -1281,6 +1367,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
this,
j,
1,
1,
1000,
expectedFreqRange,
expectedConnectedPhysPerChannel);
}
@@ -1302,7 +1390,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
0);
0,
1000);
for (std::size_t j = 0; j < 4; ++j)
{
if (!m_trackSignalsInactiveInterfaces)
@@ -1325,6 +1414,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
this,
j,
(i == secondSpectrumChannelIndex) ? 1 : 0,
(i == secondSpectrumChannelIndex) ? 1 : 0,
(i == secondSpectrumChannelIndex) ? 1000 : 0,
expectedFreqRange,
expectedConnectedPhysPerChannel);
}
@@ -1361,7 +1452,8 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
txPowerDbm);
txPowerDbm,
1000);
Simulator::Schedule(delay + txOngoingAfterTxStartedDelay,
&SpectrumWifiPhyMultipleInterfacesTest::SwitchChannel,
this,
@@ -1396,6 +1488,82 @@ SpectrumWifiPhyMultipleInterfacesTest::DoRun()
}
}
/* Reproduce an EMLSR scenario where a PHY is on an initial band and receives a packet.
* Then, the PHY switches to another band where it starts receiving another packet.
* During reception of the PHY header, the PHY switches back to the initial band and starts
* receiving yet another packet. In this case, first and last packets should be successfully
* received (no interference), the second packet reception has been interrupted (before the
* payload reception does start, hence it does not reach the RX state). */
if (m_trackSignalsInactiveInterfaces)
{
// first TX on initial band
auto txPpduPhy = m_txPhys.at(0);
delay += Seconds(1);
Simulator::Schedule(delay,
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
20,
500);
// switch channel to other band
delay += Seconds(1);
txPpduPhy = m_txPhys.at(1);
Simulator::Schedule(delay,
&SpectrumWifiPhyMultipleInterfacesTest::SwitchChannel,
this,
0,
txPpduPhy->GetPhyBand(),
txPpduPhy->GetChannelNumber(),
txPpduPhy->GetChannelWidth());
// TX on other band with high power
delay += Seconds(1);
Simulator::Schedule(delay,
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
0,
1000);
// switch back to initial band during PHY header reception
txPpduPhy = m_txPhys.at(0);
delay += MicroSeconds(20); // right after legacy PHY header reception
Simulator::Schedule(delay,
&SpectrumWifiPhyMultipleInterfacesTest::SwitchChannel,
this,
0,
txPpduPhy->GetPhyBand(),
txPpduPhy->GetChannelNumber(),
txPpduPhy->GetChannelWidth());
// TX once more on the initial band
delay += Seconds(1);
Simulator::Schedule(delay,
&SpectrumWifiPhyMultipleInterfacesTest::SendPpdu,
this,
txPpduPhy,
0,
1500);
// check results
Simulator::Schedule(delay + checkResultsDelay,
&SpectrumWifiPhyMultipleInterfacesTest::CheckResults,
this,
0,
3, // 3 RX events
2, // 2 packets should have been successfully received, 1 packet should
// have been interrupted (switch during PHY header reception)
2000, // 500 bytes (firstpacket) and 1500 bytes (third packet)
txPpduPhy->GetCurrentFrequencyRange(),
expectedConnectedPhysPerChannel);
// reset
Simulator::Schedule(delay + flushResultsDelay,
&SpectrumWifiPhyMultipleInterfacesTest::Reset,
this);
}
delay += Seconds(1);
Simulator::Stop(delay);
Simulator::Run();