wifi: Ignore padding when computing MPDU reception status
Also use same path for normal MPDUs and A-MPDUs
This commit is contained in:
committed by
Sebastien Deronne
parent
e2edf298ab
commit
15fb7e2ce7
@@ -3321,10 +3321,7 @@ WifiPhy::StartReceiveOfdmaPayload (Ptr<WifiPpdu> ppdu, RxPowerWattPerChannelBand
|
||||
if (isAp)
|
||||
{
|
||||
Ptr<const WifiPsdu> psdu = GetAddressedPsduInPpdu (ppdu);
|
||||
if (psdu->GetNMpdus () > 1)
|
||||
{
|
||||
ScheduleEndOfMpdus (event);
|
||||
}
|
||||
ScheduleEndOfMpdus (event);
|
||||
m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event));
|
||||
m_signalNoiseMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), SignalNoiseDbm ()});
|
||||
m_statusPerMpduMap.insert ({std::make_pair (ppdu->GetUid (), ppdu->GetStaId ()), std::vector<bool> ()});
|
||||
@@ -3419,10 +3416,7 @@ WifiPhy::StartReceivePayload (Ptr<Event> event)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (psdu->GetNMpdus () > 1)
|
||||
{
|
||||
ScheduleEndOfMpdus (event);
|
||||
}
|
||||
ScheduleEndOfMpdus (event);
|
||||
m_endRxEvents.push_back (Simulator::Schedule (payloadDuration, &WifiPhy::EndReceive, this, event));
|
||||
}
|
||||
}
|
||||
@@ -3482,22 +3476,25 @@ WifiPhy::ScheduleEndOfMpdus (Ptr<Event> event)
|
||||
Time relativeStart = NanoSeconds (0);
|
||||
Time psduDuration = ppdu->GetTxDuration () - CalculatePhyPreambleAndHeaderDuration (txVector);
|
||||
Time remainingAmpduDuration = psduDuration;
|
||||
MpduType mpdutype = FIRST_MPDU_IN_AGGREGATE;
|
||||
size_t nMpdus = psdu->GetNMpdus ();
|
||||
MpduType mpduType = (nMpdus > 1) ? FIRST_MPDU_IN_AGGREGATE : (psdu->IsSingle () ? SINGLE_MPDU : NORMAL_MPDU);
|
||||
uint32_t totalAmpduSize = 0;
|
||||
double totalAmpduNumSymbols = 0.0;
|
||||
size_t nMpdus = psdu->GetNMpdus ();
|
||||
auto mpdu = psdu->begin ();
|
||||
for (size_t i = 0; i < nMpdus && mpdu != psdu->end (); ++mpdu)
|
||||
{
|
||||
Time mpduDuration = GetPayloadDuration (psdu->GetAmpduSubframeSize (i), txVector,
|
||||
GetPhyBand (), mpdutype, true,
|
||||
totalAmpduSize, totalAmpduNumSymbols,
|
||||
staId);
|
||||
uint32_t size = (mpduType == NORMAL_MPDU) ? psdu->GetSize () : psdu->GetAmpduSubframeSize (i);
|
||||
Time mpduDuration = GetPayloadDuration (size, txVector,
|
||||
GetPhyBand (), mpduType, true, totalAmpduSize,
|
||||
totalAmpduNumSymbols, staId);
|
||||
|
||||
remainingAmpduDuration -= mpduDuration;
|
||||
if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero ()) //no more MPDU coming
|
||||
if (i == (nMpdus - 1) && !remainingAmpduDuration.IsZero ()) //no more MPDUs coming
|
||||
{
|
||||
mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
|
||||
if (remainingAmpduDuration < NanoSeconds (txVector.GetGuardInterval ())) //enables to ignore padding
|
||||
{
|
||||
mpduDuration += remainingAmpduDuration; //apply a correction just in case rounding had induced slight shift
|
||||
}
|
||||
}
|
||||
|
||||
endOfMpduDuration += mpduDuration;
|
||||
@@ -3506,7 +3503,7 @@ WifiPhy::ScheduleEndOfMpdus (Ptr<Event> event)
|
||||
//Prepare next iteration
|
||||
++i;
|
||||
relativeStart += mpduDuration;
|
||||
mpdutype = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
|
||||
mpduType = (i == (nMpdus - 1)) ? LAST_MPDU_IN_AGGREGATE : MIDDLE_MPDU_IN_AGGREGATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3543,8 +3540,9 @@ WifiPhy::EndOfMpdu (Ptr<Event> event, Ptr<const WifiPsdu> psdu, size_t mpduIndex
|
||||
NS_ASSERT (statusPerMpduIt != m_statusPerMpduMap.end ());
|
||||
statusPerMpduIt->second.push_back (rxInfo.first);
|
||||
|
||||
if (rxInfo.first)
|
||||
if (rxInfo.first && GetAddressedPsduInPpdu (ppdu)->GetNMpdus () > 1)
|
||||
{
|
||||
//only done for correct MPDU that is part of an A-MPDU
|
||||
m_state->ContinueRxNextMpdu (Copy (psdu), snr, txVector);
|
||||
}
|
||||
}
|
||||
@@ -3583,13 +3581,6 @@ WifiPhy::EndReceive (Ptr<Event> event)
|
||||
NS_ASSERT (signalNoiseIt != m_signalNoiseMap.end ());
|
||||
auto statusPerMpduIt = m_statusPerMpduMap.find (std::make_pair (ppdu->GetUid (), staId));
|
||||
NS_ASSERT (statusPerMpduIt != m_statusPerMpduMap.end ());
|
||||
if (psdu->GetNMpdus () == 1)
|
||||
{
|
||||
//We do not enter here for A-MPDU since this is done in WifiPhy::EndOfMpdu
|
||||
std::pair<bool, SignalNoiseDbm> rxInfo = GetReceptionStatus (psdu, event, staId, NanoSeconds (0), psduDuration);
|
||||
signalNoiseIt->second = rxInfo.second;
|
||||
statusPerMpduIt->second.push_back (rxInfo.first);
|
||||
}
|
||||
|
||||
if (std::count (statusPerMpduIt->second.begin (), statusPerMpduIt->second.end (), true))
|
||||
{
|
||||
@@ -5025,6 +5016,11 @@ WifiPhy::AbortCurrentReception (WifiPhyRxfailureReason reason)
|
||||
{
|
||||
m_endPhyRxEvent.Cancel ();
|
||||
}
|
||||
for (auto & endMpduEvent : m_endOfMpduEvents)
|
||||
{
|
||||
endMpduEvent.Cancel ();
|
||||
}
|
||||
m_endOfMpduEvents.clear ();
|
||||
for (auto & endRxEvent : m_endRxEvents)
|
||||
{
|
||||
endRxEvent.Cancel ();
|
||||
|
||||
@@ -1829,7 +1829,7 @@ TestUlOfdmaPhyTransmission::VerifyEventsCleared (void)
|
||||
void
|
||||
TestUlOfdmaPhyTransmission::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
|
||||
{
|
||||
//This is needed to make sure PHY state will be checked as the last event if a state change occured at the exact same time as the check
|
||||
//This is needed to make sure PHY state will be checked as the last event if a state change occurred at the exact same time as the check
|
||||
Simulator::ScheduleNow (&TestUlOfdmaPhyTransmission::DoCheckPhyState, this, phy, expectedState);
|
||||
}
|
||||
|
||||
@@ -2359,6 +2359,416 @@ TestUlOfdmaPhyTransmission::DoRun (void)
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
*
|
||||
* \brief PHY padding exclusion test
|
||||
*/
|
||||
class TestPhyPaddingExclusion : public TestCase
|
||||
{
|
||||
public:
|
||||
TestPhyPaddingExclusion ();
|
||||
virtual ~TestPhyPaddingExclusion ();
|
||||
|
||||
private:
|
||||
virtual void DoSetup (void);
|
||||
virtual void DoRun (void);
|
||||
|
||||
/**
|
||||
* Send HE TB PPDU function
|
||||
* \param txStaId the ID of the TX STA
|
||||
* \param index the RU index used for the transmission
|
||||
* \param payloadSize the size of the payload in bytes
|
||||
* \param txDuration the duration of the PPDU
|
||||
*/
|
||||
void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration);
|
||||
|
||||
/**
|
||||
* Generate interference function
|
||||
* \param interferencePsd the PSD of the interference to be generated
|
||||
* \param duration the duration of the interference
|
||||
*/
|
||||
void GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration);
|
||||
/**
|
||||
* Stop interference function
|
||||
*/
|
||||
void StopInterference (void);
|
||||
|
||||
/**
|
||||
* Run one function
|
||||
*/
|
||||
void RunOne ();
|
||||
|
||||
/**
|
||||
* Check the received PSDUs from STA1
|
||||
* \param expectedSuccess the expected number of success
|
||||
* \param expectedFailures the expected number of failures
|
||||
* \param expectedBytes the expected number of bytes
|
||||
*/
|
||||
void CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
|
||||
|
||||
/**
|
||||
* Check the received PSDUs from STA2
|
||||
* \param expectedSuccess the expected number of success
|
||||
* \param expectedFailures the expected number of failures
|
||||
* \param expectedBytes the expected number of bytes
|
||||
*/
|
||||
void CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes);
|
||||
|
||||
/**
|
||||
* Verify all events are cleared at end of TX or RX
|
||||
*/
|
||||
void VerifyEventsCleared (void);
|
||||
|
||||
/**
|
||||
* Check the PHY state
|
||||
* \param phy the PHY
|
||||
* \param expectedState the expected state of the PHY
|
||||
*/
|
||||
void CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
|
||||
void DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState);
|
||||
|
||||
/**
|
||||
* Reset function
|
||||
*/
|
||||
void Reset ();
|
||||
|
||||
/**
|
||||
* Receive success function
|
||||
* \param psdu the PSDU
|
||||
* \param snr the SNR
|
||||
* \param txVector the transmit vector
|
||||
* \param statusPerMpdu reception status per MPDU
|
||||
*/
|
||||
void RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> statusPerMpdu);
|
||||
|
||||
/**
|
||||
* Receive failure function
|
||||
* \param psdu the PSDU
|
||||
*/
|
||||
void RxFailure (Ptr<WifiPsdu> psdu);
|
||||
|
||||
Ptr<OfdmaSpectrumWifiPhy> m_phyAp; ///< PHY of AP
|
||||
Ptr<OfdmaSpectrumWifiPhy> m_phySta1; ///< PHY of STA 1
|
||||
Ptr<OfdmaSpectrumWifiPhy> m_phySta2; ///< PHY of STA 2
|
||||
|
||||
Ptr<WaveformGenerator> m_phyInterferer; ///< PHY of interferer
|
||||
|
||||
uint32_t m_countRxSuccessFromSta1; ///< count RX success from STA 1
|
||||
uint32_t m_countRxSuccessFromSta2; ///< count RX success from STA 2
|
||||
uint32_t m_countRxFailureFromSta1; ///< count RX failure from STA 1
|
||||
uint32_t m_countRxFailureFromSta2; ///< count RX failure from STA 2
|
||||
uint32_t m_countRxBytesFromSta1; ///< count RX bytes from STA 1
|
||||
uint32_t m_countRxBytesFromSta2; ///< count RX bytes from STA 2
|
||||
};
|
||||
|
||||
TestPhyPaddingExclusion::TestPhyPaddingExclusion ()
|
||||
: TestCase ("PHY padding exclusion test"),
|
||||
m_countRxSuccessFromSta1 (0),
|
||||
m_countRxSuccessFromSta2 (0),
|
||||
m_countRxFailureFromSta1 (0),
|
||||
m_countRxFailureFromSta2 (0),
|
||||
m_countRxBytesFromSta1 (0),
|
||||
m_countRxBytesFromSta2 (0)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration)
|
||||
{
|
||||
WifiConstPsduMap psdus;
|
||||
|
||||
WifiTxVector txVector = WifiTxVector (WifiPhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false, 1);
|
||||
|
||||
HeRu::RuSpec ru;
|
||||
ru.primary80MHz = false;
|
||||
ru.ruType = HeRu::RU_106_TONE;
|
||||
ru.index = index;
|
||||
txVector.SetRu (ru, txStaId);
|
||||
txVector.SetMode (WifiPhy::GetHeMcs7 (), txStaId);
|
||||
txVector.SetNss (1, txStaId);
|
||||
|
||||
Ptr<Packet> pkt = Create<Packet> (payloadSize);
|
||||
WifiMacHeader hdr;
|
||||
hdr.SetType (WIFI_MAC_QOSDATA);
|
||||
hdr.SetQosTid (0);
|
||||
hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:00"));
|
||||
std::ostringstream addr;
|
||||
addr << "00:00:00:00:00:0" << txStaId;
|
||||
hdr.SetAddr2 (Mac48Address (addr.str ().c_str ()));
|
||||
hdr.SetSequenceNumber (1);
|
||||
Ptr<WifiPsdu> psdu = Create<WifiPsdu> (pkt, hdr);
|
||||
psdus.insert (std::make_pair (txStaId, psdu));
|
||||
|
||||
Ptr<OfdmaSpectrumWifiPhy> phy;
|
||||
if (txStaId == 1)
|
||||
{
|
||||
phy = m_phySta1;
|
||||
}
|
||||
else if (txStaId == 2)
|
||||
{
|
||||
phy = m_phySta2;
|
||||
}
|
||||
|
||||
txVector.SetLength (phy->ConvertHeTbPpduDurationToLSigLength (txDuration, phy->GetPhyBand ()));
|
||||
|
||||
phy->SetPpduUid (0);
|
||||
phy->Send (psdus, txVector);
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::GenerateInterference (Ptr<SpectrumValue> interferencePsd, Time duration)
|
||||
{
|
||||
m_phyInterferer->SetTxPowerSpectralDensity (interferencePsd);
|
||||
m_phyInterferer->SetPeriod (duration);
|
||||
m_phyInterferer->Start ();
|
||||
Simulator::Schedule (duration, &TestPhyPaddingExclusion::StopInterference, this);
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::StopInterference (void)
|
||||
{
|
||||
m_phyInterferer->Stop();
|
||||
}
|
||||
|
||||
TestPhyPaddingExclusion::~TestPhyPaddingExclusion ()
|
||||
{
|
||||
m_phyAp = 0;
|
||||
m_phySta1 = 0;
|
||||
m_phySta2 = 0;
|
||||
m_phyInterferer = 0;
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::RxSuccess (Ptr<WifiPsdu> psdu, double snr, WifiTxVector txVector, std::vector<bool> /*statusPerMpdu*/)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 () << snr << txVector);
|
||||
if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
|
||||
{
|
||||
m_countRxSuccessFromSta1++;
|
||||
m_countRxBytesFromSta1 += (psdu->GetSize () - 30);
|
||||
}
|
||||
else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
|
||||
{
|
||||
m_countRxSuccessFromSta2++;
|
||||
m_countRxBytesFromSta2 += (psdu->GetSize () - 30);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::RxFailure (Ptr<WifiPsdu> psdu)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << *psdu << psdu->GetAddr2 ());
|
||||
if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:01"))
|
||||
{
|
||||
m_countRxFailureFromSta1++;
|
||||
}
|
||||
else if (psdu->GetAddr2 () == Mac48Address ("00:00:00:00:00:02"))
|
||||
{
|
||||
m_countRxFailureFromSta2++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::CheckRxFromSta1 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta1, expectedSuccess, "The number of successfully received packets from STA 1 is not correct!");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta1, expectedFailures, "The number of unsuccessfully received packets from STA 1 is not correct!");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta1, expectedBytes, "The number of bytes received from STA 1 is not correct!");
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::CheckRxFromSta2 (uint32_t expectedSuccess, uint32_t expectedFailures, uint32_t expectedBytes)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (m_countRxSuccessFromSta2, expectedSuccess, "The number of successfully received packets from STA 2 is not correct!");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_countRxFailureFromSta2, expectedFailures, "The number of unsuccessfully received packets from STA 2 is not correct!");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_countRxBytesFromSta2, expectedBytes, "The number of bytes received from STA 2 is not correct!");
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::VerifyEventsCleared (void)
|
||||
{
|
||||
NS_TEST_ASSERT_MSG_EQ (m_phyAp->GetCurrentEvent (), 0, "m_currentEvent for AP was not cleared");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_phySta1->GetCurrentEvent (), 0, "m_currentEvent for STA 1 was not cleared");
|
||||
NS_TEST_ASSERT_MSG_EQ (m_phySta2->GetCurrentEvent (), 0, "m_currentEvent for STA 2 was not cleared");
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::CheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
|
||||
{
|
||||
//This is needed to make sure PHY state will be checked as the last event if a state change occurred at the exact same time as the check
|
||||
Simulator::ScheduleNow (&TestPhyPaddingExclusion::DoCheckPhyState, this, phy, expectedState);
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::DoCheckPhyState (Ptr<OfdmaSpectrumWifiPhy> phy, WifiPhyState expectedState)
|
||||
{
|
||||
WifiPhyState currentState = phy->GetState ()->GetState ();
|
||||
NS_LOG_FUNCTION (this << currentState);
|
||||
NS_TEST_ASSERT_MSG_EQ (currentState, expectedState, "PHY State " << currentState << " does not match expected state " << expectedState << " at " << Simulator::Now ());
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::Reset (void)
|
||||
{
|
||||
m_countRxSuccessFromSta1 = 0;
|
||||
m_countRxSuccessFromSta2 = 0;
|
||||
m_countRxFailureFromSta1 = 0;
|
||||
m_countRxFailureFromSta2 = 0;
|
||||
m_countRxBytesFromSta1 = 0;
|
||||
m_countRxBytesFromSta2 = 0;
|
||||
m_phySta1->SetPpduUid (0);
|
||||
m_phySta1->SetTriggerFrameUid (0);
|
||||
m_phySta2->SetTriggerFrameUid (0);
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::DoSetup (void)
|
||||
{
|
||||
RngSeedManager::SetSeed (1);
|
||||
RngSeedManager::SetRun (1);
|
||||
int64_t streamNumber = 0;
|
||||
|
||||
Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel> ();
|
||||
Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> ();
|
||||
lossModel->SetFrequency (DEFAULT_FREQUENCY * 1e6);
|
||||
spectrumChannel->AddPropagationLossModel (lossModel);
|
||||
Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> ();
|
||||
spectrumChannel->SetPropagationDelayModel (delayModel);
|
||||
|
||||
Ptr<Node> apNode = CreateObject<Node> ();
|
||||
Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
|
||||
Ptr<ApWifiMac> apMac = CreateObject<ApWifiMac> ();
|
||||
apMac->SetAttribute ("BeaconGeneration", BooleanValue (false));
|
||||
apDev->SetMac (apMac);
|
||||
m_phyAp = CreateObject<OfdmaSpectrumWifiPhy> (0);
|
||||
m_phyAp->CreateWifiSpectrumPhyInterface (apDev);
|
||||
m_phyAp->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
|
||||
Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
|
||||
apDev->SetHeConfiguration (heConfiguration);
|
||||
Ptr<ErrorRateModel> error = CreateObject<NistErrorRateModel> ();
|
||||
m_phyAp->SetErrorRateModel (error);
|
||||
m_phyAp->SetDevice (apDev);
|
||||
m_phyAp->SetChannel (spectrumChannel);
|
||||
m_phyAp->AssignStreams (streamNumber);
|
||||
m_phyAp->SetFrequency (DEFAULT_FREQUENCY);
|
||||
m_phyAp->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
|
||||
m_phyAp->SetReceiveOkCallback (MakeCallback (&TestPhyPaddingExclusion::RxSuccess, this));
|
||||
m_phyAp->SetReceiveErrorCallback (MakeCallback (&TestPhyPaddingExclusion::RxFailure, this));
|
||||
Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
m_phyAp->SetMobility (apMobility);
|
||||
apDev->SetPhy (m_phyAp);
|
||||
apNode->AggregateObject (apMobility);
|
||||
apNode->AddDevice (apDev);
|
||||
|
||||
Ptr<Node> sta1Node = CreateObject<Node> ();
|
||||
Ptr<WifiNetDevice> sta1Dev = CreateObject<WifiNetDevice> ();
|
||||
m_phySta1 = CreateObject<OfdmaSpectrumWifiPhy> (1);
|
||||
m_phySta1->CreateWifiSpectrumPhyInterface (sta1Dev);
|
||||
m_phySta1->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
|
||||
m_phySta1->SetErrorRateModel (error);
|
||||
m_phySta1->SetDevice (sta1Dev);
|
||||
m_phySta1->SetChannel (spectrumChannel);
|
||||
m_phySta1->AssignStreams (streamNumber);
|
||||
m_phySta1->SetFrequency (DEFAULT_FREQUENCY);
|
||||
m_phySta1->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
|
||||
Ptr<ConstantPositionMobilityModel> sta1Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
m_phySta1->SetMobility (sta1Mobility);
|
||||
sta1Dev->SetPhy (m_phySta1);
|
||||
sta1Node->AggregateObject (sta1Mobility);
|
||||
sta1Node->AddDevice (sta1Dev);
|
||||
|
||||
Ptr<Node> sta2Node = CreateObject<Node> ();
|
||||
Ptr<WifiNetDevice> sta2Dev = CreateObject<WifiNetDevice> ();
|
||||
m_phySta2 = CreateObject<OfdmaSpectrumWifiPhy> (2);
|
||||
m_phySta2->CreateWifiSpectrumPhyInterface (sta2Dev);
|
||||
m_phySta2->ConfigureStandardAndBand (WIFI_PHY_STANDARD_80211ax, WIFI_PHY_BAND_5GHZ);
|
||||
m_phySta2->SetErrorRateModel (error);
|
||||
m_phySta2->SetDevice (sta2Dev);
|
||||
m_phySta2->SetChannel (spectrumChannel);
|
||||
m_phySta2->AssignStreams (streamNumber);
|
||||
m_phySta2->SetFrequency (DEFAULT_FREQUENCY);
|
||||
m_phySta2->SetChannelWidth (DEFAULT_CHANNEL_WIDTH);
|
||||
Ptr<ConstantPositionMobilityModel> sta2Mobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||
m_phySta2->SetMobility (sta2Mobility);
|
||||
sta2Dev->SetPhy (m_phySta2);
|
||||
sta2Node->AggregateObject (sta2Mobility);
|
||||
sta2Node->AddDevice (sta2Dev);
|
||||
|
||||
Ptr<Node> interfererNode = CreateObject<Node> ();
|
||||
Ptr<NonCommunicatingNetDevice> interfererDev = CreateObject<NonCommunicatingNetDevice> ();
|
||||
m_phyInterferer = CreateObject<WaveformGenerator> ();
|
||||
m_phyInterferer->SetDevice (interfererDev);
|
||||
m_phyInterferer->SetChannel (spectrumChannel);
|
||||
m_phyInterferer->SetDutyCycle (1);
|
||||
interfererNode->AddDevice (interfererDev);
|
||||
}
|
||||
|
||||
void
|
||||
TestPhyPaddingExclusion::DoRun (void)
|
||||
{
|
||||
Time expectedPpduDuration = NanoSeconds (279200);
|
||||
Time ppduWithPaddingDuration = expectedPpduDuration + 10 * NanoSeconds (12800 + 800 /* GI */); //add 10 extra OFDM symbols
|
||||
|
||||
Simulator::Schedule (Seconds (0.0), &TestPhyPaddingExclusion::Reset, this);
|
||||
|
||||
//STA1 and STA2 send MU UL PPDUs addressed to AP:
|
||||
Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
|
||||
Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
|
||||
|
||||
//Verify it takes expectedPpduDuration + padding to transmit the PPDUs
|
||||
Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
|
||||
Simulator::Schedule (Seconds (1.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::IDLE);
|
||||
|
||||
//One PSDU of 1000 bytes should have been successfully received from STA 1
|
||||
Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
|
||||
//One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
|
||||
//Verify events data have been cleared
|
||||
Simulator::Schedule (Seconds (1.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
|
||||
|
||||
Simulator::Schedule (Seconds (1.5), &TestPhyPaddingExclusion::Reset, this);
|
||||
|
||||
|
||||
//STA1 and STA2 send MU UL PPDUs addressed to AP:
|
||||
Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
|
||||
Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
|
||||
|
||||
//A strong non-wifi interference is generated on RU 1 during padding reception
|
||||
BandInfo bandInfo;
|
||||
bandInfo.fc = (DEFAULT_FREQUENCY - (DEFAULT_CHANNEL_WIDTH / 4)) * 1e6;
|
||||
bandInfo.fl = bandInfo.fc - ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
|
||||
bandInfo.fh = bandInfo.fc + ((DEFAULT_CHANNEL_WIDTH / 4) * 1e6);
|
||||
Bands bands;
|
||||
bands.push_back (bandInfo);
|
||||
|
||||
Ptr<SpectrumModel> SpectrumInterferenceRu1 = Create<SpectrumModel> (bands);
|
||||
Ptr<SpectrumValue> interferencePsdRu1 = Create<SpectrumValue> (SpectrumInterferenceRu1);
|
||||
double interferencePower = 0.1; //watts
|
||||
*interferencePsdRu1 = interferencePower / ((DEFAULT_CHANNEL_WIDTH / 2) * 20e6);
|
||||
|
||||
Simulator::Schedule (Seconds (2.0) + MicroSeconds (50) + expectedPpduDuration, &TestPhyPaddingExclusion::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
|
||||
|
||||
//Verify it takes expectedPpduDuration + padding to transmit the PPDUs (PHY should move to CCA_BUSY instead of IDLE due to the interference)
|
||||
Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration - NanoSeconds (1), &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::RX);
|
||||
Simulator::Schedule (Seconds (2.0) + ppduWithPaddingDuration, &TestPhyPaddingExclusion::CheckPhyState, this, m_phyAp, WifiPhyState::CCA_BUSY);
|
||||
|
||||
//One PSDU of 1000 bytes should have been successfully received from STA 1 (since interference occupies RU 1 after payload, during PHY padding)
|
||||
Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta1, this, 1, 0, 1000);
|
||||
//One PSDU of 1001 bytes should have been successfully received from STA 2
|
||||
Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::CheckRxFromSta2, this, 1, 0, 1001);
|
||||
//Verify events data have been cleared
|
||||
Simulator::Schedule (Seconds (2.1), &TestPhyPaddingExclusion::VerifyEventsCleared, this);
|
||||
|
||||
Simulator::Schedule (Seconds (2.5), &TestPhyPaddingExclusion::Reset, this);
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
@@ -2378,6 +2788,7 @@ WifiPhyOfdmaTestSuite::WifiPhyOfdmaTestSuite ()
|
||||
AddTestCase (new TestUlOfdmaPpduUid, TestCase::QUICK);
|
||||
AddTestCase (new TestMultipleHeTbPreambles, TestCase::QUICK);
|
||||
AddTestCase (new TestUlOfdmaPhyTransmission, TestCase::QUICK);
|
||||
AddTestCase (new TestPhyPaddingExclusion, TestCase::QUICK);
|
||||
}
|
||||
|
||||
static WifiPhyOfdmaTestSuite wifiPhyOfdmaTestSuite; ///< the test suite
|
||||
|
||||
Reference in New Issue
Block a user