wifi: Check TRIGVECTOR when processing SIG-A of HE TB PPDUs

This commit is contained in:
Stefano Avallone
2022-01-18 13:25:07 +01:00
parent e53f91fc31
commit aa89420cd7
3 changed files with 265 additions and 130 deletions

View File

@@ -536,10 +536,49 @@ HePhy::ProcessSigA (Ptr<Event> event, PhyFieldRxStatus status)
return PhyFieldRxStatus (false, FILTERED, DROP);
}
// When SIG-A is decoded, we know the type of frame being received. If we stored a
// valid TRIGVECTOR and we are not receiving a TB PPDU, we drop the frame.
if (m_trigVectorExpirationTime >= Simulator::Now () && !txVector.IsUlMu ())
{
NS_LOG_DEBUG ("Expected an HE TB PPDU, receiving a " << txVector.GetPreambleType ());
return PhyFieldRxStatus (false, FILTERED, DROP);
}
Ptr<const WifiPpdu> ppdu = event->GetPpdu ();
if (txVector.IsUlMu ())
{
NS_ASSERT (txVector.GetModulationClass () == WIFI_MOD_CLASS_HE);
// check that the stored TRIGVECTOR is still valid
if (m_trigVectorExpirationTime < Simulator::Now ())
{
NS_LOG_DEBUG ("No valid TRIGVECTOR, the PHY was not expecting a TB PPDU");
return PhyFieldRxStatus (false, FILTERED, DROP);
}
// We expected a TB PPDU and we are receiving a TB PPDU. However, despite
// the previous check on BSS Color, we may be receiving a TB PPDU from an
// OBSS, as BSS Colors are not guaranteed to be different for all APs in
// range (an example is when BSS Color is 0). We can detect this situation
// by comparing the TRIGVECTOR with the TXVECTOR of the TB PPDU being received
if (m_trigVector.GetChannelWidth () != txVector.GetChannelWidth ())
{
NS_LOG_DEBUG ("Received channel width different than in TRIGVECTOR");
return PhyFieldRxStatus (false, FILTERED, DROP);
}
if (m_trigVector.GetLength () != txVector.GetLength ())
{
NS_LOG_DEBUG ("Received UL Length (" << txVector.GetLength () <<
") different than in TRIGVECTOR (" << m_trigVector.GetLength ()
<< ")");
return PhyFieldRxStatus (false, FILTERED, DROP);
}
uint16_t staId = ppdu->GetStaId ();
if (m_trigVector.GetHeMuUserInfoMap ().find (staId) == m_trigVector.GetHeMuUserInfoMap ().end ()
|| m_trigVector.GetHeMuUserInfo (staId) != txVector.GetHeMuUserInfo (staId))
{
NS_LOG_DEBUG ("User Info map of TB PPDU being received differs from that of TRIGVECTOR");
return PhyFieldRxStatus (false, FILTERED, DROP);
}
m_currentHeTbPpduUid = ppdu->GetUid (); //to be able to correctly schedule start of OFDMA payload
}

View File

@@ -1392,11 +1392,13 @@ private:
Ptr<OfdmaSpectrumWifiPhy> m_phy; ///< Phy
uint64_t m_totalBytesDropped; ///< total number of dropped bytes
WifiTxVector m_trigVector; ///< TRIGVECTOR
};
TestMultipleHeTbPreambles::TestMultipleHeTbPreambles ()
: TestCase ("UL-OFDMA multiple RX events test"),
m_totalBytesDropped (0)
m_totalBytesDropped (0),
m_trigVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0, DEFAULT_CHANNEL_WIDTH, false, false)
{
}
@@ -1411,6 +1413,7 @@ TestMultipleHeTbPreambles::Reset (void)
m_totalBytesDropped = 0;
//We have to reset PHY here since we do not trigger OFDMA payload RX event in this test
m_phy->Reset ();
m_trigVector.GetHeMuUserInfoMap ().clear ();
}
void
@@ -1452,6 +1455,8 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
txVector.SetMode (HePhy::GetHeMcs7 (), staId);
txVector.SetNss (1, staId);
m_trigVector.GetHeMuUserInfoMap ().insert ({staId, HeMuUserInfo {ru, HePhy::GetHeMcs7 (), 1}});
Ptr<Packet> pkt = Create<Packet> (payloadSize);
WifiMacHeader hdr;
hdr.SetType (WIFI_MAC_QOSDATA);
@@ -1477,6 +1482,11 @@ TestMultipleHeTbPreambles::RxHeTbPpdu (uint64_t uid, uint16_t staId, double txPo
rxParams->duration = nonOfdmaDuration;
rxParams->ppdu = ppdu;
uint16_t length = HePhy::ConvertHeTbPpduDurationToLSigLength (ppduDuration, m_phy->GetPhyBand ());
txVector.SetLength (length);
m_trigVector.SetLength (length);
auto hePhy = DynamicCast<HePhy> (m_phy->GetPhyEntity (WIFI_MOD_CLASS_HE));
hePhy->SetTrigVector (m_trigVector, ppduDuration);
m_phy->StartRx (rxParams);
//Schedule OFDMA part
@@ -1638,6 +1648,19 @@ TestMultipleHeTbPreambles::DoRun (void)
class TestUlOfdmaPhyTransmission : public TestCase
{
public:
/**
* Erroneous info included in a TRIGVECTOR
*/
enum TrigVectorInfo
{
NONE = 0,
CHANNEL_WIDTH,
UL_LENGTH,
AID,
RU_TYPE,
MCS
};
TestUlOfdmaPhyTransmission ();
virtual ~TestUlOfdmaPhyTransmission ();
@@ -1654,6 +1677,13 @@ private:
* \return the TXVECTOR for HE TB PPDU
*/
WifiTxVector GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_t index, uint8_t bssColor) const;
/**
* Set TRIGVECTOR for HE TB PPDU
*
* \param bssColor the BSS color of the TX STA
* \param error the erroneous info (if any) in the TRIGVECTOR to set
*/
void SetTrigVector (uint8_t bssColor, TrigVectorInfo error);
/**
* Send HE TB PPDU function
* \param txStaId the ID of the TX STA
@@ -1783,11 +1813,13 @@ private:
* \param expectedBytesFromSta2 the expected number of bytes from STA 2
* \param scheduleTxSta1 flag indicating to schedule a HE TB PPDU from STA 1
* \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);
bool scheduleTxSta1 = true, WifiPhyState expectedStateBeforeEnd = WifiPhyState::RX,
TrigVectorInfo error = NONE);
/**
* Schedule power measurement related checks.
@@ -1922,6 +1954,67 @@ TestUlOfdmaPhyTransmission::GetTxVectorForHeTbPpdu (uint16_t txStaId, std::size_
return txVector;
}
void
TestUlOfdmaPhyTransmission::SetTrigVector (uint8_t bssColor, TrigVectorInfo error)
{
uint16_t channelWidth = m_channelWidth;
if (error == CHANNEL_WIDTH)
{
channelWidth = (channelWidth == 160 ? 20 : channelWidth * 2);
}
WifiTxVector txVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0,
channelWidth, false, false, false, bssColor);
HeRu::RuType ruType = HeRu::RU_106_TONE;
if (channelWidth == 20)
{
ruType = (error == RU_TYPE ? HeRu::RU_52_TONE : HeRu::RU_106_TONE);
}
else if (channelWidth == 40)
{
ruType = (error == RU_TYPE ? HeRu::RU_106_TONE : HeRu::RU_242_TONE);
}
else if (channelWidth == 80)
{
ruType = (error == RU_TYPE ? HeRu::RU_242_TONE : HeRu::RU_484_TONE);
}
else if (channelWidth == 160)
{
ruType = (error == RU_TYPE ? HeRu::RU_484_TONE : HeRu::RU_996_TONE);
}
else
{
NS_ASSERT_MSG (false, "Unsupported channel width");
}
uint16_t aid1 = (error == AID ? 3 : 1);
uint16_t aid2 = (error == AID ? 4 : 2);
HeRu::RuSpec ru1 (ruType, 1, true);
ru1.SetPhyIndex (channelWidth, 0);
txVector.SetRu (ru1, aid1);
txVector.SetMode ((error == MCS ? HePhy::GetHeMcs5 () : HePhy::GetHeMcs7 ()), aid1);
txVector.SetNss (1, aid1);
HeRu::RuSpec ru2 (ruType, (channelWidth == 160 ? 1 : 2),
(channelWidth == 160 ? false : true));
ru2.SetPhyIndex (channelWidth, 0);
txVector.SetRu (ru2, aid2);
txVector.SetMode ((error == MCS ? HePhy::GetHeMcs5 () : HePhy::GetHeMcs7 ()), aid2);
txVector.SetNss (1, aid2);
uint16_t length = HePhy::ConvertHeTbPpduDurationToLSigLength (m_expectedPpduDuration,
m_phyAp->GetPhyBand ());
if (error == UL_LENGTH)
{
++length;
}
txVector.SetLength (length);
auto hePhyAp = DynamicCast<HePhy> (m_phyAp->GetPhyEntity (WIFI_MOD_CLASS_HE));
hePhyAp->SetTrigVector (txVector, m_expectedPpduDuration);
}
void
TestUlOfdmaPhyTransmission::SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, uint64_t uid, uint8_t bssColor)
{
@@ -2248,16 +2341,28 @@ 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)
bool scheduleTxSta1, WifiPhyState expectedStateBeforeEnd,
TrigVectorInfo error)
{
//AP send SU packet with UID = 0 (2) to mimic transmission of solicited (unsolicited) HE TB PPDUs
Simulator::Schedule (delay - MilliSeconds (10), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 0, 50, solicited ? 0 : 2, 0);
static uint64_t uid = 0;
//AP sends an SU packet preceding HE TB PPDUs
Simulator::Schedule (delay - MilliSeconds (10), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 0, 50, ++uid, 0);
if (!solicited)
{
// UID of TB PPDUs will be different than the one of the preceding frame
++uid;
}
else
{
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SetTrigVector, this, 0, error);
}
//STA1 and STA2 send MU UL PPDUs addressed to AP
if (scheduleTxSta1)
{
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 1, 1, 1000, 0, 0);
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 1, 1, 1000, uid, 0);
}
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 2, 2, 1001, 0, 0);
Simulator::Schedule (delay, &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);
@@ -2407,13 +2512,69 @@ TestUlOfdmaPhyTransmission::RunOne (void)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Verify that both unsolicited HE TB PPDUs have been corrected received
//Verify that no unsolicited HE TB PPDU is received
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs");
"Dropping of unsolicited HE TB PPDUs");
ScheduleTest (delay, false,
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
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);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Verify that HE TB PPDUs with channel width differing from TRIGVECTOR are discarded
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Dropping of HE TB PPDUs with channel width differing from TRIGVECTOR");
ScheduleTest (delay, true,
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);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Verify that HE TB PPDUs with UL Length differing from TRIGVECTOR are discarded
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Dropping of HE TB PPDUs with UL Length differing from TRIGVECTOR");
ScheduleTest (delay, true,
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);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Verify that HE TB PPDUs with AIDs differing from TRIGVECTOR are discarded
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Dropping of HE TB PPDUs with AIDs differing from TRIGVECTOR");
ScheduleTest (delay, true,
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);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Verify that HE TB PPDUs with RU type differing from TRIGVECTOR are discarded
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Dropping of HE TB PPDUs with RU type differing from TRIGVECTOR");
ScheduleTest (delay, true,
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);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Verify that HE TB PPDUs with MCS differing from TRIGVECTOR are discarded
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Dropping of HE TB PPDUs with MCS differing from TRIGVECTOR");
ScheduleTest (delay, true,
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);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
@@ -2440,18 +2601,6 @@ TestUlOfdmaPhyTransmission::RunOne (void)
1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Generate an interference on RU 1 and verify that only STA 1's unsolicited HE TB PPDU has been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs with interference on RU 1 during PSDU reception");
//A strong non-wifi interference is generated on RU 1 during PSDU reception
Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu1, MilliSeconds (100));
ScheduleTest (delay, false,
WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference (primary channel)
0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
1, 0, 1001); //One PSDU of 1001 bytes should have been successfully received from STA 2
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Generate an interference on RU 2 and verify that only STA 2's solicited HE TB PPDU has been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
@@ -2474,18 +2623,6 @@ TestUlOfdmaPhyTransmission::RunOne (void)
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Generate an interference on RU 2 and verify that only STA 2's unsolicited HE TB PPDU has been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs with interference on RU 2 during PSDU reception");
//A strong non-wifi interference is generated on RU 2 during PSDU reception
Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdRu2, MilliSeconds (100));
ScheduleTest (delay, false,
(m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
1, 0, 1000, //One PSDU of 1000 bytes should have been successfully received from STA 1
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Generate an interference on the full band and verify that both solicited HE TB PPDUs have been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
@@ -2508,18 +2645,6 @@ TestUlOfdmaPhyTransmission::RunOne (void)
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Generate an interference on the full band and verify that both unsolicited HE TB PPDUs have been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs with interference on the full band during PSDU reception");
//A strong non-wifi interference is generated on the full band during PSDU reception
Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::GenerateInterference, this, interferencePsdAll, MilliSeconds (100));
ScheduleTest (delay, false,
WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference
0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference occupies RU 1)
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference occupies RU 2)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both solicited HE TB PPDUs have been impacted if they are on the same
// 20 MHz channel. Only STA 1's solicited HE TB PPDU is impacted otherwise.
@@ -2549,19 +2674,6 @@ TestUlOfdmaPhyTransmission::RunOne (void)
succ, fail, bytes);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Send another HE TB PPDU (of another UL MU transmission) on RU 1 and verify that both unsolicited HE TB PPDUs have been impacted if they are on the same
// 20 MHz channel. Only STA 1's unsolicited HE TB PPDU is impacted otherwise.
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU 1 during PSDU reception");
//Another HE TB PPDU arrives at AP on the same RU as STA 1 during PSDU reception
Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 1, 1002, 1, 0);
ScheduleTest (delay, false,
WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE due to the interference on primary channel width
0, 1, 0, //Reception of the PSDU from STA 1 should have failed (since interference from STA 3 on same 20 MHz channel)
succ, fail, bytes); //same as solicited case
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both solicited HE TB PPDUs have been impacted if they are on the same
// 20 MHz channel. Only STA 2's solicited HE TB PPDU is impacted otherwise.
@@ -2590,19 +2702,6 @@ TestUlOfdmaPhyTransmission::RunOne (void)
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Send another HE TB PPDU (of another UL MU transmission) on RU 2 and verify that both unsolicited HE TB PPDUs have been impacted if they are on the same
// 20 MHz channel. Only STA 2's unsolicited HE TB PPDU is impacted otherwise.
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs with another HE TB PPDU arriving on RU2 during payload reception");
//Another HE TB PPDU arrives at AP on the same RU as STA 2 during PSDU reception
Simulator::Schedule (delay + MicroSeconds (50), &TestUlOfdmaPhyTransmission::SendHeTbPpdu, this, 3, 2, 1002, 1, 0);
ScheduleTest (delay, false,
(m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY, //PHY should move to CCA_BUSY instead of IDLE if interference on primary channel
succ, fail, bytes, //same as solicited case
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3 on same 20 MHz channel)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
@@ -2615,25 +2714,13 @@ TestUlOfdmaPhyTransmission::RunOne (void)
0, 1, 0); //Reception of the PSDU from STA 2 should have failed (since interference from STA 3)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Send an HE SU PPDU during 400 ns window and verify that both solicited HE TB PPDUs have been impacted
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs with an HE SU PPDU arriving during the 400 ns window");
//One HE SU arrives at AP during the 400ns window
Simulator::Schedule (delay + NanoSeconds (300), &TestUlOfdmaPhyTransmission::SendHeSuPpdu, this, 3, 1002, 1, 0);
ScheduleTest (delay, false,
WifiPhyState::IDLE,
0, 1, 0, //Reception of the PSDU from STA 1 should have failed failed (since interference from STA 3)
0, 1, 0); //Reception of the PSDU from STA 2 should have failed failed (since interference from STA 3)
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Only send a solicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of solicited HE TB PPDU only on RU 2");
//Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
//Check that STA3 will correctly set its state to CCA_BUSY if in measurement channel or IDLE otherwise
Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
(m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
(m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::CCA_BUSY); //PHY should move to CCA_BUSY instead of IDLE if HE TB PPDU on primary channel;
ScheduleTest (delay, true,
WifiPhyState::IDLE,
0, 0, 0, //No transmission scheduled for STA 1
@@ -2641,39 +2728,6 @@ TestUlOfdmaPhyTransmission::RunOne (void)
false, WifiPhyState::RX); //Measurement channel is total channel width
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Only send an unsolicited HE TB PPDU from STA 2 on RU 2 and verify that it has been correctly received if it's in the
// correct measurement channel
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
"Reception of unsolicited HE TB PPDUs only on RU 2");
//Check that STA3 will correctly set its state to RX if in measurement channel or IDLE otherwise
Simulator::Schedule (delay + m_expectedPpduDuration - NanoSeconds (1), &TestUlOfdmaPhyTransmission::CheckPhyState, this, m_phySta3,
(m_channelWidth >= 40) ? WifiPhyState::IDLE : WifiPhyState::RX); //PHY should move to RX instead of IDLE if HE TB PPDU on primary channel;
//Expected figures from STA 2
WifiPhyState state;
if (m_channelWidth == 20)
{
//One PSDU of 1001 bytes should have been successfully received from STA 2 (since measurement channel is primary channel)
succ = 1;
fail = 0;
bytes = 1001;
state = WifiPhyState::RX;
}
else
{
//No PSDU should have been received from STA 2 (since measurement channel is primary channel)
succ = 0;
fail = 0;
bytes = 0;
state = WifiPhyState::IDLE;
}
ScheduleTest (delay, false,
WifiPhyState::IDLE,
0, 0, 0, //No transmission scheduled for STA 1
succ, fail, bytes,
false, state);
delay += Seconds (1.0);
//---------------------------------------------------------------------------
//Measure the power of a solicited HE TB PPDU from STA 2 on RU 2
Simulator::Schedule (delay, &TestUlOfdmaPhyTransmission::LogScenario, this,
@@ -2805,6 +2859,12 @@ private:
* \param txDuration the duration of the PPDU
*/
void SendHeTbPpdu (uint16_t txStaId, std::size_t index, std::size_t payloadSize, Time txDuration);
/**
* Set TRIGVECTOR for HE TB PPDU
*
* \param ppduDuration the duration of the HE TB PPDU
*/
void SetTrigVector (Time ppduDuration);
/**
* Generate interference function
@@ -3139,6 +3199,23 @@ TestPhyPaddingExclusion::DoTeardown (void)
m_phyInterferer = 0;
}
void
TestPhyPaddingExclusion::SetTrigVector (Time ppduDuration)
{
WifiTxVector trigVector (HePhy::GetHeMcs7 (), 0, WIFI_PREAMBLE_HE_TB, 800, 1, 1, 0,
DEFAULT_CHANNEL_WIDTH, false, false, 1);
trigVector.SetRu (HeRu::RuSpec (HeRu::RU_106_TONE, 1, false), 1);
trigVector.SetMode (HePhy::GetHeMcs7 (), 1);
trigVector.SetNss (1, 1);
trigVector.SetRu (HeRu::RuSpec (HeRu::RU_106_TONE, 2, false), 2);
trigVector.SetMode (HePhy::GetHeMcs7 (), 2);
trigVector.SetNss (1, 2);
trigVector.SetLength (HePhy::ConvertHeTbPpduDurationToLSigLength (ppduDuration,
m_phyAp->GetPhyBand ()));
auto hePhyAp = DynamicCast<HePhy> (m_phyAp->GetPhyEntity (WIFI_MOD_CLASS_HE));
hePhyAp->SetTrigVector (trigVector, ppduDuration);
}
void
TestPhyPaddingExclusion::DoRun (void)
{
@@ -3151,6 +3228,10 @@ TestPhyPaddingExclusion::DoRun (void)
Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
// Set TRIGVECTOR on AP
Simulator::Schedule (Seconds (1.0), &TestPhyPaddingExclusion::SetTrigVector, this,
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);
@@ -3169,6 +3250,10 @@ TestPhyPaddingExclusion::DoRun (void)
Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 1, 1, 1000, ppduWithPaddingDuration);
Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SendHeTbPpdu, this, 2, 2, 1001, ppduWithPaddingDuration);
// Set TRIGVECTOR on AP
Simulator::Schedule (Seconds (2.0), &TestPhyPaddingExclusion::SetTrigVector, this,
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;

View File

@@ -268,14 +268,14 @@ WifiPrimaryChannelsTest::ReceiveUl (uint8_t bss, Ptr<WifiPsdu> psdu, RxSignalInf
WifiTxVector txVector, std::vector<bool> perMpduStatus)
{
// if the BSS color is zero, this AP might receive the frame sent by another AP. Given that
// stations only send TB PPDUs, we discard this frame if the TX vector is UL MU.
// stations only send TB PPDUs, we ignore this frame if the TX vector is not UL MU.
if (psdu->GetNMpdus () == 1 && psdu->GetHeader (0).IsQosData () && txVector.IsUlMu ())
{
auto dev = DynamicCast<WifiNetDevice> (m_apDevices.Get (bss));
uint16_t staId = txVector.GetHeMuUserInfoMap ().begin ()->first;
uint8_t station = staId - 1;
NS_LOG_INFO ("RECEIVED FROM BSS=" << +bss << " STA=" << +station
NS_LOG_INFO ("RECEIVED FROM BSSID=" << psdu->GetHeader (0).GetAddr3 () << " STA=" << +station
<< " " << *psdu);
// the MAC received a PSDU containing a QoS data frame from the PHY
NS_TEST_EXPECT_MSG_EQ (m_received[bss].test (station), false, "AP of BSS " << +bss
@@ -617,7 +617,7 @@ WifiPrimaryChannelsTest::DoRun (void)
}
/*
* Repeat the same scheme as before with DL MU transmissions. For each transmission
* Repeat the same scheme as before with UL MU transmissions. For each transmission
* channel width, every round is repeated as many times as the number of ways in
* which we can partition the transmission channel width in equal sized RUs.
*/
@@ -753,6 +753,7 @@ WifiPrimaryChannelsTest::DoSendHeTbPpdu (uint8_t bss, uint16_t txChannelWidth, H
Time duration = Seconds (0);
uint16_t length = 0;
WifiTxVector trigVector (HePhy::GetHeMcs8 (), 0, WIFI_PREAMBLE_HE_TB, 3200, 1, 1, 0, txChannelWidth, false, false, false, bssColor);
for (std::size_t i = 1; i <= nRus; i++)
{
@@ -767,6 +768,7 @@ WifiPrimaryChannelsTest::DoSendHeTbPpdu (uint8_t bss, uint16_t txChannelWidth, H
WifiTxVector txVector (HePhy::GetHeMcs8 (), 0, WIFI_PREAMBLE_HE_TB, 3200, 1, 1, 0, txChannelWidth, false, false, false, bssColor);
txVector.SetHeMuUserInfo (staId, {{ruType, index, primary80}, HePhy::GetHeMcs8 (), 1});
trigVector.SetHeMuUserInfo (staId, {{ruType, index, primary80}, HePhy::GetHeMcs8 (), 1});
hdr.SetAddr2 (staDev->GetMac ()->GetAddress ());
Ptr<const WifiPsdu> psdu = Create<const WifiPsdu> (Create<Packet> (1000), hdr);
@@ -783,6 +785,11 @@ WifiPrimaryChannelsTest::DoSendHeTbPpdu (uint8_t bss, uint16_t txChannelWidth, H
staDev->GetPhy ()->Send (WifiConstPsduMap {{staId, psdu}}, txVector);
}
// AP's PHY expects to receive a TRIGVECTOR (just once)
trigVector.SetLength (length);
auto apHePhy = StaticCast<HePhy> (apDev->GetPhy ()->GetPhyEntity (WIFI_MOD_CLASS_HE));
apHePhy->SetTrigVector (trigVector, duration);
}
void
@@ -867,7 +874,9 @@ WifiPrimaryChannelsTest::CheckReceivedMuPpdus (std::set<uint8_t> txBss, uint16_t
{
if (txBss.find (bss) != txBss.end ())
{
// Due to AID filtering, only stations that are addressed by the MU PPDU do hear the frame
// There was a transmission in this BSS.
// [DL] Due to AID filtering, only stations that are addressed by the MU PPDU do hear the frame
// [UL] The AP hears a TB PPDU sent by all and only the solicited stations
for (uint8_t sta = 0; sta < nRus; sta++)
{
NS_TEST_EXPECT_MSG_EQ (m_received[bss].test (sta), true,
@@ -885,7 +894,8 @@ WifiPrimaryChannelsTest::CheckReceivedMuPpdus (std::set<uint8_t> txBss, uint16_t
<< (isDlMu ? "by" : "from") << " station [" << +bss << "]["
<< +sta << "]");
}
// only the addressed stations actually processed the frames
// [DL] Only the addressed stations actually processed the frames
// [UL] The AP processed the frames sent by all and only the addressed stations
for (uint8_t sta = 0; sta < nRus; sta++)
{
NS_TEST_EXPECT_MSG_EQ (m_processed[bss].test (sta), true,
@@ -906,10 +916,11 @@ WifiPrimaryChannelsTest::CheckReceivedMuPpdus (std::set<uint8_t> txBss, uint16_t
}
else
{
// There was no transmission in this BSS. If BSS Color filtering is enabled or no frame
// transmission overlaps with the primary20 channel of this BSS, stations in this BSS
// did not hear any frame.
if (m_useDistinctBssColors
// There was no transmission in this BSS.
// [DL] If BSS Color filtering is enabled or no frame transmission overlaps with
// the primary20 channel of this BSS, stations in this BSS did not hear any frame.
// [UL] The AP did not hear any TB PPDU because no TRIGVECTOR was passed to the PHY
if (!isDlMu || m_useDistinctBssColors
|| std::none_of (txBss.begin (), txBss.end (),
[&](const uint8_t& txAp)
{
@@ -931,7 +942,7 @@ WifiPrimaryChannelsTest::CheckReceivedMuPpdus (std::set<uint8_t> txBss, uint16_t
}
else
{
// stations having the same AID of the stations addressed by the MU PPDI received the frame
// [DL] Stations having the same AID of the stations addressed by the MU PPDU received the frame
for (uint8_t sta = 0; sta < nRus; sta++)
{
NS_TEST_EXPECT_MSG_EQ (m_received[bss].test (sta), true,