wifi: Extend UL OFDMA PHY tests to verify RX start and RX end notifications
This commit is contained in:
committed by
Stefano Avallone
parent
18f8b488d3
commit
f97d297bb2
@@ -18,6 +18,7 @@
|
||||
* Author: Sébastien Deronne <sebastien.deronne@gmail.com>
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/test.h"
|
||||
#include "ns3/node.h"
|
||||
@@ -45,6 +46,7 @@
|
||||
#include "ns3/ctrl-headers.h"
|
||||
#include "ns3/threshold-preamble-detection-model.h"
|
||||
#include "ns3/he-phy.h"
|
||||
#include "ns3/wifi-phy-listener.h"
|
||||
#include "ns3/waveform-generator.h"
|
||||
#include "ns3/non-communicating-net-device.h"
|
||||
#include "ns3/spectrum-wifi-helper.h"
|
||||
@@ -1670,6 +1672,140 @@ TestMultipleHeTbPreambles::DoRun (void)
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief PHY listener for OFDMA tests
|
||||
*/
|
||||
class OfdmaTestPhyListener : public ns3::WifiPhyListener
|
||||
{
|
||||
public:
|
||||
OfdmaTestPhyListener (void) = default;
|
||||
|
||||
void NotifyRxStart (Time duration) override
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration);
|
||||
m_lastRxStart = Simulator::Now ();
|
||||
++m_notifyRxStart;
|
||||
m_lastRxSuccess = false;
|
||||
}
|
||||
|
||||
void NotifyRxEndOk (void) override
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_lastRxEnd = Simulator::Now ();
|
||||
++m_notifyRxEnd;
|
||||
m_lastRxSuccess = true;
|
||||
}
|
||||
|
||||
void NotifyRxEndError (void) override
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_lastRxEnd = Simulator::Now ();
|
||||
++m_notifyRxEnd;
|
||||
m_lastRxSuccess = false;
|
||||
}
|
||||
|
||||
void NotifyTxStart (Time duration, double txPowerDbm) override
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration << txPowerDbm);
|
||||
}
|
||||
|
||||
void NotifyCcaBusyStart (Time duration, WifiChannelListType channelType,
|
||||
const std::vector<Time>& /*per20MhzDurations*/) override
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration << channelType);
|
||||
}
|
||||
|
||||
void NotifySwitchingStart (Time duration) override
|
||||
{
|
||||
}
|
||||
|
||||
void NotifySleep (void) override
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyOff (void) override
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyWakeup (void) override
|
||||
{
|
||||
}
|
||||
|
||||
void NotifyOn (void) override
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset function.
|
||||
*/
|
||||
void Reset (void)
|
||||
{
|
||||
m_notifyRxStart = 0;
|
||||
m_notifyRxEnd = 0;
|
||||
m_lastRxStart = Seconds (0);
|
||||
m_lastRxEnd = Seconds (0);
|
||||
m_lastRxSuccess = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of RX start notifications that has been received since the last reset.
|
||||
* \return the number of RX start notifications that has been received
|
||||
*/
|
||||
uint32_t GetNumRxStartNotifications (void) const
|
||||
{
|
||||
return m_notifyRxStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of RX end notifications that has been received since the last reset.
|
||||
* \return the number of RX end notifications that has been received
|
||||
*/
|
||||
uint32_t GetNumRxEndNotifications (void) const
|
||||
{
|
||||
return m_notifyRxEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time at which the last RX start notification has been received.
|
||||
* \return the time at which the last RX start notification has been received
|
||||
*/
|
||||
Time GetLastRxStartNotification (void) const
|
||||
{
|
||||
return m_lastRxStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time at which the last RX end notification has been received.
|
||||
* \return the time at which the last RX end notification has been received
|
||||
*/
|
||||
Time GetLastRxEndNotification (void) const
|
||||
{
|
||||
return m_lastRxEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether last RX has been successfull.
|
||||
* \return true if last RX has been successfull, false otherwise
|
||||
*/
|
||||
bool IsLastRxSuccess (void) const
|
||||
{
|
||||
return m_lastRxSuccess;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
uint32_t m_notifyRxStart {0}; ///< count number of RX start notifications
|
||||
uint32_t m_notifyRxEnd {0}; ///< count number of RX end notifications
|
||||
Time m_lastRxStart {Seconds (0)}; ///< last time a RX start notification has been received
|
||||
Time m_lastRxEnd {Seconds (0)}; ///< last time a RX end notification has been received
|
||||
bool m_lastRxSuccess {false}; ///< flag whether last RX has been successfull
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
@@ -1809,6 +1945,20 @@ private:
|
||||
/// \copydoc CheckPhyState
|
||||
void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
|
||||
|
||||
/**
|
||||
* Check the the number of RX start notifications at the AP as well as the last time a RX start has been notified
|
||||
* \param expectedNotifications the expected number of RX start notifications at the AP
|
||||
* \param expectedLastNotification the expected time of the last RX start notification at the AP
|
||||
*/
|
||||
void CheckApRxStart (uint32_t expectedNotifications, Time expectedLastNotification);
|
||||
/**
|
||||
* Check the the number of RX end notifications at the AP as well as the last time a RX end has been notified
|
||||
* \param expectedNotifications the expected number of RX end notifications at the AP
|
||||
* \param expectedLastNotification the expected time of the last RX end notification at the AP
|
||||
* \param expectedSuccess true if the last RX notification indicates a success, false otherwise
|
||||
*/
|
||||
void CheckApRxEnd (uint32_t expectedNotifications, Time expectedLastNotification, bool expectedSuccess);
|
||||
|
||||
/**
|
||||
* Reset function
|
||||
*/
|
||||
@@ -1843,14 +1993,15 @@ private:
|
||||
* \param expectedFailuresFromSta2 the expected number of failures from STA 2
|
||||
* \param expectedBytesFromSta2 the expected number of bytes from STA 2
|
||||
* \param scheduleTxSta1 flag indicating to schedule a HE TB PPDU from STA 1
|
||||
* \param ulTimeDifference delay between HE TB PPDU from STA 1 and HE TB PPDU from STA 2 are received
|
||||
* \param expectedStateBeforeEnd the expected state of the PHY before the end of the transmission
|
||||
* \param error the erroneous info (if any) in the TRIGVECTOR to set
|
||||
*/
|
||||
void ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
|
||||
uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
|
||||
uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
|
||||
bool scheduleTxSta1 = true, WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX,
|
||||
TrigVectorInfo error = NONE);
|
||||
bool scheduleTxSta1 = true, Time ulTimeDifference = Seconds (0),
|
||||
WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX, TrigVectorInfo error = NONE);
|
||||
|
||||
/**
|
||||
* Schedule power measurement related checks.
|
||||
@@ -1875,6 +2026,8 @@ private:
|
||||
Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
|
||||
Ptr<OfdmaSpectrumWifiPhy> m_phySta3; ///< PHY of STA 3
|
||||
|
||||
std::unique_ptr<OfdmaTestPhyListener> m_apPhyStateListener; ///< listener for AP PHY state transitions
|
||||
|
||||
Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
|
||||
|
||||
uint32_t m_countRxSuccessFromSta1; ///< count RX success from STA 1
|
||||
@@ -2216,6 +2369,36 @@ TestUlOfdmaPhyTransmission::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, Wifi
|
||||
NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
|
||||
}
|
||||
|
||||
void
|
||||
TestUlOfdmaPhyTransmission::CheckApRxStart (uint32_t expectedNotifications, Time expectedLastNotification)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (m_apPhyStateListener->GetNumRxStartNotifications (), expectedNotifications,
|
||||
"Number of RX start notifications " << m_apPhyStateListener->GetNumRxStartNotifications () <<
|
||||
" does not match expected count " << expectedNotifications <<
|
||||
" for AP at " << Simulator::Now ());
|
||||
NS_TEST_ASSERT_MSG_EQ (m_apPhyStateListener->GetLastRxStartNotification (), expectedLastNotification,
|
||||
"Last time RX start notification has been received " << m_apPhyStateListener->GetLastRxStartNotification () <<
|
||||
" does not match expected time " << expectedLastNotification <<
|
||||
" for AP at " << Simulator::Now ());
|
||||
}
|
||||
|
||||
void
|
||||
TestUlOfdmaPhyTransmission::CheckApRxEnd (uint32_t expectedNotifications, Time expectedLastNotification, bool expectedSuccess)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (m_apPhyStateListener->GetNumRxEndNotifications (), expectedNotifications,
|
||||
"Number of RX end notifications " << m_apPhyStateListener->GetNumRxEndNotifications () <<
|
||||
" does not match expected count " << expectedNotifications <<
|
||||
" for AP at " << Simulator::Now ());
|
||||
NS_TEST_ASSERT_MSG_EQ (m_apPhyStateListener->GetLastRxEndNotification (), expectedLastNotification,
|
||||
"Last time RX end notification has been received " << m_apPhyStateListener->GetLastRxEndNotification () <<
|
||||
" does not match expected time " << expectedLastNotification <<
|
||||
" for AP at " << Simulator::Now ());
|
||||
NS_TEST_ASSERT_MSG_EQ (m_apPhyStateListener->IsLastRxSuccess (), expectedSuccess,
|
||||
"Last time RX end notification indicated a " << (m_apPhyStateListener->IsLastRxSuccess () ? "success" : "failure") <<
|
||||
" but expected a " << (expectedSuccess ? "success" : "failure") <<
|
||||
" for AP at " << Simulator::Now ());
|
||||
}
|
||||
|
||||
void
|
||||
TestUlOfdmaPhyTransmission::Reset (void)
|
||||
{
|
||||
@@ -2229,6 +2412,7 @@ TestUlOfdmaPhyTransmission::Reset (void)
|
||||
m_phySta1->SetTriggerFrameUid (0);
|
||||
m_phySta2->SetTriggerFrameUid (0);
|
||||
SetBssColor (m_phyAp, 0);
|
||||
m_apPhyStateListener->Reset ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2282,6 +2466,8 @@ TestUlOfdmaPhyTransmission::DoSetup (void)
|
||||
m_phyAp->SetPreambleDetectionModel (preambleDetectionModel);
|
||||
Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
m_phyAp->SetMobility (apMobility);
|
||||
m_apPhyStateListener = std::make_unique<OfdmaTestPhyListener> ();
|
||||
m_phyAp->RegisterListener (m_apPhyStateListener.get ());
|
||||
apDev->SetPhy (m_phyAp);
|
||||
apNode->AggregateObject (apMobility);
|
||||
apNode->AddDevice (apDev);
|
||||
@@ -2391,8 +2577,7 @@ void
|
||||
TestUlOfdmaPhyTransmission::ScheduleTest (Time delay, bool solicited, WifiPhyState expectedStateAtEnd,
|
||||
uint32_t expectedSuccessFromSta1, uint32_t expectedFailuresFromSta1, uint32_t expectedBytesFromSta1,
|
||||
uint32_t expectedSuccessFromSta2, uint32_t expectedFailuresFromSta2, uint32_t expectedBytesFromSta2,
|
||||
bool scheduleTxSta1, WifiPhyState expectedStateBeforeEnd,
|
||||
TrigVectorInfo error)
|
||||
bool scheduleTxSta1, Time ulTimeDifference, WifiPhyState expectedStateBeforeEnd, TrigVectorInfo error)
|
||||
{
|
||||
static uint64_t uid = 0;
|
||||
|
||||
@@ -2408,17 +2593,34 @@ TestUlOfdmaPhyTransmission::ScheduleTest (Time delay, bool solicited, WifiPhySta
|
||||
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SetTrigVector, this, 0, error);
|
||||
}
|
||||
//STA1 and STA2 send MU UL PPDUs addressed to AP
|
||||
Simulator::Schedule (delay - MilliSeconds (1), &OfdmaTestPhyListener::Reset, m_apPhyStateListener.get ());
|
||||
if (scheduleTxSta1)
|
||||
{
|
||||
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 1, 1, 1000, uid, 0);
|
||||
}
|
||||
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 2, 2, 1001, uid, 0);
|
||||
Simulator::Schedule (delay + ulTimeDifference, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 2, 2, 1001, uid, 0);
|
||||
|
||||
//Verify it takes m_expectedPpduDuration to transmit the PPDUs
|
||||
Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateBeforeEnd);
|
||||
Simulator::Schedule (delay + m_expectedPpduDuration, &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateAtEnd);
|
||||
Simulator::Schedule (delay + m_expectedPpduDuration + ulTimeDifference, &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phyAp, expectedStateAtEnd);
|
||||
//TODO: add checks on TX stop for STAs
|
||||
|
||||
if (expectedSuccessFromSta1 + expectedFailuresFromSta1 + expectedSuccessFromSta2 + expectedFailuresFromSta2 > 0)
|
||||
{
|
||||
//RxEndOk if at least one HE TB PPDU has been successfully received, RxEndError otherwise
|
||||
const bool isSuccess = (expectedSuccessFromSta1 > 0) || (expectedSuccessFromSta2 > 0);
|
||||
//The expected time at which the reception is started corresponds to the time at which the test is started,
|
||||
//plus the time to transmit the PHY preamble and the PHY headers.
|
||||
const Time expectedPayloadStart = delay + MicroSeconds (48);
|
||||
//The expected time at which the reception is terminated corresponds to the time at which the test is started,
|
||||
//plus the time to transmit the PPDU, plus the delay between the first received HE TB PPDU and the last received HE TB PPDU.
|
||||
const Time expectedPayloadEnd = delay + m_expectedPpduDuration + ulTimeDifference;
|
||||
//At the end of the transmission, verify that a single RX start notification shall have been notified when the reception of the first HE RB PPDU starts.
|
||||
Simulator::Schedule (expectedPayloadEnd, &TestUlOfdmaPhyTransmission::CheckApRxStart, this, 1, Simulator::Now () + expectedPayloadStart);
|
||||
//After the reception (hence we add 1ns to expectedPayloadEnd), a single RX end notification shall have been notified when the reception of the last HE RB PPDU ends
|
||||
Simulator::Schedule (expectedPayloadEnd + NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckApRxEnd, this, 1, Simulator::Now () + expectedPayloadEnd, isSuccess);
|
||||
}
|
||||
|
||||
delay += MilliSeconds (100);
|
||||
//Check reception state from STA 1
|
||||
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::CheckRxFromSta1, this,
|
||||
@@ -2561,6 +2763,17 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//Verify that two solicited HE TB PPDUs with delay (< 400ns) between the two signals have been corrected received
|
||||
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
|
||||
"Reception of solicited HE TB PPDUs with delay (< 400ns) between the two signals");
|
||||
ScheduleTest (delay, true,
|
||||
WifiPhyState::IDLE,
|
||||
1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
|
||||
1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
true, NanoSeconds (100));
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//Verify that no unsolicited HE TB PPDU is received
|
||||
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
|
||||
@@ -2569,7 +2782,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //PSDU from STA 1 is not received (no TRIGVECTOR)
|
||||
0, 0, 0, //PSDU from STA 2 is not received (no TRIGVECTOR)
|
||||
true, WifiPhyState::CCA_BUSY);
|
||||
true, Seconds (0), WifiPhyState::CCA_BUSY);
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2580,7 +2793,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //PSDU from STA 1 is not received (no TRIGVECTOR)
|
||||
0, 0, 0, //PSDU from STA 2 is not received (no TRIGVECTOR)
|
||||
true, WifiPhyState::CCA_BUSY, CHANNEL_WIDTH);
|
||||
true, Seconds (0), WifiPhyState::CCA_BUSY, CHANNEL_WIDTH);
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2591,7 +2804,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //PSDU from STA 1 is not received (no TRIGVECTOR)
|
||||
0, 0, 0, //PSDU from STA 2 is not received (no TRIGVECTOR)
|
||||
true, WifiPhyState::CCA_BUSY, UL_LENGTH);
|
||||
true, Seconds (0), WifiPhyState::CCA_BUSY, UL_LENGTH);
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2602,7 +2815,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //PSDU from STA 1 is not received (no TRIGVECTOR)
|
||||
0, 0, 0, //PSDU from STA 2 is not received (no TRIGVECTOR)
|
||||
true, WifiPhyState::CCA_BUSY, AID);
|
||||
true, Seconds (0), WifiPhyState::CCA_BUSY, AID);
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2613,7 +2826,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //PSDU from STA 1 is not received (no TRIGVECTOR)
|
||||
0, 0, 0, //PSDU from STA 2 is not received (no TRIGVECTOR)
|
||||
true, WifiPhyState::CCA_BUSY, RU_TYPE);
|
||||
true, Seconds (0), WifiPhyState::CCA_BUSY, RU_TYPE);
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2624,7 +2837,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //PSDU from STA 1 is not received (no TRIGVECTOR)
|
||||
0, 0, 0, //PSDU from STA 2 is not received (no TRIGVECTOR)
|
||||
true, WifiPhyState::CCA_BUSY, MCS);
|
||||
true, Seconds (0), WifiPhyState::CCA_BUSY, MCS);
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2775,7 +2988,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //No transmission scheduled for STA 1
|
||||
1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
false, WifiPhyState::RX); //Measurement channel is total channel width
|
||||
false, Seconds (0), WifiPhyState::RX); //Measurement channel is total channel width
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2790,7 +3003,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //No transmission scheduled for STA 1
|
||||
1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
false, WifiPhyState::RX); //Measurement channel is total channel width
|
||||
false, Seconds (0), WifiPhyState::RX); //Measurement channel is total channel width
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -2819,7 +3032,7 @@ TestUlOfdmaPhyTransmission::RunOne (void)
|
||||
WifiPhyState::IDLE,
|
||||
0, 0, 0, //No transmission scheduled for STA 1
|
||||
1, 0, 1001, //One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
false, WifiPhyState::RX); //Measurement channel is total channel width
|
||||
false, Seconds (0), WifiPhyState::RX); //Measurement channel is total channel width
|
||||
delay += Seconds (1.0);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user