From aa89420cd70bfd46ab3ecc458ce26e59e470664d Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Tue, 18 Jan 2022 13:25:07 +0100 Subject: [PATCH] wifi: Check TRIGVECTOR when processing SIG-A of HE TB PPDUs --- src/wifi/model/he/he-phy.cc | 39 +++ src/wifi/test/wifi-phy-ofdma-test.cc | 325 ++++++++++++-------- src/wifi/test/wifi-primary-channels-test.cc | 31 +- 3 files changed, 265 insertions(+), 130 deletions(-) diff --git a/src/wifi/model/he/he-phy.cc b/src/wifi/model/he/he-phy.cc index 6a70b4d2a..2629b10b7 100644 --- a/src/wifi/model/he/he-phy.cc +++ b/src/wifi/model/he/he-phy.cc @@ -536,10 +536,49 @@ HePhy::ProcessSigA (Ptr 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 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 } diff --git a/src/wifi/test/wifi-phy-ofdma-test.cc b/src/wifi/test/wifi-phy-ofdma-test.cc index fbd74d230..4f5d4fd1f 100644 --- a/src/wifi/test/wifi-phy-ofdma-test.cc +++ b/src/wifi/test/wifi-phy-ofdma-test.cc @@ -1392,11 +1392,13 @@ private: Ptr 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 pkt = Create (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 (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 (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 (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; diff --git a/src/wifi/test/wifi-primary-channels-test.cc b/src/wifi/test/wifi-primary-channels-test.cc index 986a2e25d..4176fceeb 100644 --- a/src/wifi/test/wifi-primary-channels-test.cc +++ b/src/wifi/test/wifi-primary-channels-test.cc @@ -268,14 +268,14 @@ WifiPrimaryChannelsTest::ReceiveUl (uint8_t bss, Ptr psdu, RxSignalInf WifiTxVector txVector, std::vector 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 (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 psdu = Create (Create (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 (apDev->GetPhy ()->GetPhyEntity (WIFI_MOD_CLASS_HE)); + apHePhy->SetTrigVector (trigVector, duration); } void @@ -867,7 +874,9 @@ WifiPrimaryChannelsTest::CheckReceivedMuPpdus (std::set 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 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 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 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,