From 3f189d8ac18a3dcbfe756f06d62b9641b2a18f08 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Mon, 20 Mar 2023 09:25:10 +0100 Subject: [PATCH] wifi: Don't use protection if destinations already received (MU-)RTS in the TXOP --- .../model/wifi-default-protection-manager.cc | 28 +- src/wifi/test/wifi-mac-ofdma-test.cc | 457 ++++++++++-------- 2 files changed, 278 insertions(+), 207 deletions(-) diff --git a/src/wifi/model/wifi-default-protection-manager.cc b/src/wifi/model/wifi-default-protection-manager.cc index 0e2f17878..dd1a89d75 100644 --- a/src/wifi/model/wifi-default-protection-manager.cc +++ b/src/wifi/model/wifi-default-protection-manager.cc @@ -20,6 +20,7 @@ #include "wifi-default-protection-manager.h" #include "ap-wifi-mac.h" +#include "frame-exchange-manager.h" #include "wifi-mpdu.h" #include "wifi-tx-parameters.h" @@ -173,6 +174,12 @@ WifiDefaultProtectionManager::GetPsduProtection(const WifiMacHeader& hdr, return std::unique_ptr(new WifiNoProtection()); } + // no need to use protection if destination already received an RTS in this TXOP + if (m_mac->GetFrameExchangeManager(m_linkId)->GetProtectedStas().count(hdr.GetAddr1()) == 1) + { + return std::unique_ptr(new WifiNoProtection()); + } + // check if RTS/CTS is needed if (GetWifiRemoteStationManager()->NeedRts(hdr, size)) { @@ -203,9 +210,13 @@ WifiDefaultProtectionManager::TryAddMpduToMuPpdu(Ptr mpdu, NS_LOG_FUNCTION(this << *mpdu << &txParams); NS_ASSERT(txParams.m_txVector.IsDlMu()); - if (!m_sendMuRts) + auto receiver = mpdu->GetHeader().GetAddr1(); + auto isProtected = + m_mac->GetFrameExchangeManager(m_linkId)->GetProtectedStas().count(receiver) == 1; + + if (!m_sendMuRts || isProtected) { - // No protection because sending MU-RTS is disabled + // No protection needed if (txParams.m_protection && txParams.m_protection->method == WifiProtection::NONE) { return nullptr; @@ -219,8 +230,6 @@ WifiDefaultProtectionManager::TryAddMpduToMuPpdu(Ptr mpdu, protection = static_cast(txParams.m_protection.get()); } - auto receiver = mpdu->GetHeader().GetAddr1(); - if (txParams.GetPsduInfo(receiver) == nullptr) { // we get here if this is the first MPDU for this receiver. @@ -311,6 +320,8 @@ WifiDefaultProtectionManager::TryUlMuTransmission(Ptr mpdu, const auto& staList = StaticCast(m_mac)->GetStaList(m_linkId); std::remove_reference_t::const_iterator staIt; + bool allProtected = true; + for (const auto& userInfo : trigger) { // Add a User Info field to the MU-RTS for this solicited station @@ -319,6 +330,15 @@ WifiDefaultProtectionManager::TryUlMuTransmission(Ptr mpdu, staIt = staList.find(userInfo.GetAid12()); NS_ASSERT(staIt != staList.cend()); AddUserInfoToMuRts(protection->muRts, txWidth, staIt->second); + allProtected = + allProtected && + m_mac->GetFrameExchangeManager(m_linkId)->GetProtectedStas().count(staIt->second) == 1; + } + + if (allProtected) + { + // No protection needed + return std::unique_ptr(new WifiNoProtection()); } // compute the TXVECTOR to use to send the MU-RTS Trigger Frame diff --git a/src/wifi/test/wifi-mac-ofdma-test.cc b/src/wifi/test/wifi-mac-ofdma-test.cc index a079e6ec4..c10288967 100644 --- a/src/wifi/test/wifi-mac-ofdma-test.cc +++ b/src/wifi/test/wifi-mac-ofdma-test.cc @@ -545,6 +545,8 @@ OfdmaAckSequenceTest::OfdmaAckSequenceTest(uint16_t width, default: NS_ABORT_MSG("Unhandled channel width (" << m_channelWidth << " MHz)"); } + + m_txPsdus.reserve(35); } OfdmaAckSequenceTest::~OfdmaAckSequenceTest() @@ -1009,27 +1011,6 @@ OfdmaAckSequenceTest::CheckResults(Time sifs, Time slotTime, uint8_t aifsn) NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, qosNullNavEnd, "Duration/ID in QoS Null is too short"); NS_TEST_EXPECT_MSG_LT(qosNullNavEnd, navEnd + tolerance, "Duration/ID in QoS Null is too long"); - // the AP sends another MU-RTS Trigger Frame to protect the Basic TF - NS_TEST_ASSERT_MSG_GT_OR_EQ(m_txPsdus.size(), 15, "Expected at least 15 transmitted packet"); - NS_TEST_EXPECT_MSG_EQ((m_txPsdus[10].psduMap.size() == 1 && - m_txPsdus[10].psduMap[SU_STA_ID]->GetHeader(0).IsTrigger() && - m_txPsdus[10].psduMap[SU_STA_ID]->GetHeader(0).GetAddr1().IsBroadcast()), - true, - "Expected a Trigger Frame"); - m_txPsdus[10].psduMap[SU_STA_ID]->GetPayload(0)->PeekHeader(trigger); - NS_TEST_EXPECT_MSG_EQ(trigger.IsMuRts(), true, "Expected an MU-RTS Trigger Frame"); - NS_TEST_EXPECT_MSG_EQ(trigger.GetNUserInfoFields(), - 4, - "Expected one User Info field per station"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[10].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the MU-RTS to occupy the entire channel width"); - for (const auto& userInfo : trigger) - { - NS_TEST_EXPECT_MSG_EQ(+userInfo.GetMuRtsRuAllocation(), - +m_muRtsRuAllocation, - "Unexpected RU Allocation value in MU-RTS"); - } tEnd = m_txPsdus[9].endTx; tStart = m_txPsdus[10].startTx; NS_TEST_EXPECT_MSG_LT(tEnd + ifs, tStart, "Basic Trigger Frame sent too early"); @@ -1043,89 +1024,136 @@ OfdmaAckSequenceTest::CheckResults(Time sifs, Time slotTime, uint8_t aifsn) NS_TEST_EXPECT_MSG_LT(muRtsNavEnd, navEnd + tolerance, "Duration/ID in MU-RTS is too long"); } - // NAV end is now set by the Duration/ID of the second MU-RTS TF - tEnd = m_txPsdus[10].endTx; - navEnd = tEnd + m_txPsdus[10].psduMap[SU_STA_ID]->GetDuration(); + // if the TXOP limit is not null, MU-RTS protection is not used because the next transmission + // is protected by the previous MU-RTS Trigger Frame + if (m_txopLimit == 0) + { + // the AP sends another MU-RTS Trigger Frame to protect the Basic TF + NS_TEST_ASSERT_MSG_GT_OR_EQ(m_txPsdus.size(), + 15, + "Expected at least 15 transmitted packet"); + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[10].psduMap.size() == 1 && + m_txPsdus[10].psduMap[SU_STA_ID]->GetHeader(0).IsTrigger() && + m_txPsdus[10].psduMap[SU_STA_ID]->GetHeader(0).GetAddr1().IsBroadcast()), + true, + "Expected a Trigger Frame"); + m_txPsdus[10].psduMap[SU_STA_ID]->GetPayload(0)->PeekHeader(trigger); + NS_TEST_EXPECT_MSG_EQ(trigger.IsMuRts(), true, "Expected an MU-RTS Trigger Frame"); + NS_TEST_EXPECT_MSG_EQ(trigger.GetNUserInfoFields(), + 4, + "Expected one User Info field per station"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[10].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the MU-RTS to occupy the entire channel width"); + for (const auto& userInfo : trigger) + { + NS_TEST_EXPECT_MSG_EQ(+userInfo.GetMuRtsRuAllocation(), + +m_muRtsRuAllocation, + "Unexpected RU Allocation value in MU-RTS"); + } - // A first STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[11].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[11].psduMap.size() == 1 && - m_txPsdus[11].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[11].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[11].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); + // NAV end is now set by the Duration/ID of the second MU-RTS TF + tEnd = m_txPsdus[10].endTx; + navEnd = tEnd + m_txPsdus[10].psduMap[SU_STA_ID]->GetDuration(); - tStart = m_txPsdus[11].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[11].endTx + m_txPsdus[11].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); + // A first STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[11].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[11].psduMap.size() == 1 && + m_txPsdus[11].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[11].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[11].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); - // A second STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[12].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[12].psduMap.size() == 1 && - m_txPsdus[12].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[12].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[12].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); + tStart = m_txPsdus[11].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[11].endTx + m_txPsdus[11].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); - tStart = m_txPsdus[12].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[12].endTx + m_txPsdus[12].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); + // A second STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[12].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[12].psduMap.size() == 1 && + m_txPsdus[12].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[12].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[12].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); - // A third STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[13].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[13].psduMap.size() == 1 && - m_txPsdus[13].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[13].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[13].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); + tStart = m_txPsdus[12].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[12].endTx + m_txPsdus[12].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); - tStart = m_txPsdus[13].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[13].endTx + m_txPsdus[13].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); + // A third STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[13].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[13].psduMap.size() == 1 && + m_txPsdus[13].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[13].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[13].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); - // A fourth STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[14].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[14].psduMap.size() == 1 && - m_txPsdus[14].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[14].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[14].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); + tStart = m_txPsdus[13].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[13].endTx + m_txPsdus[13].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); - tStart = m_txPsdus[14].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[14].endTx + m_txPsdus[14].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); + // A fourth STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[14].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[14].psduMap.size() == 1 && + m_txPsdus[14].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[14].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[14].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); + + tStart = m_txPsdus[14].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[14].endTx + m_txPsdus[14].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); + + tEnd = m_txPsdus[14].endTx; + } + else + { + // insert 5 elements in m_txPsdus to align the index of the following frames in the + // two cases (TXOP limit null and not null) + m_txPsdus.insert(std::next(m_txPsdus.begin(), 10), 5, {}); + tEnd = m_txPsdus[9].endTx; + } // the AP sends a Basic Trigger Frame to solicit QoS data frames NS_TEST_ASSERT_MSG_GT_OR_EQ(m_txPsdus.size(), 21, "Expected at least 21 transmitted packets"); @@ -1139,7 +1167,6 @@ OfdmaAckSequenceTest::CheckResults(Time sifs, Time slotTime, uint8_t aifsn) NS_TEST_EXPECT_MSG_EQ(trigger.GetNUserInfoFields(), 4, "Expected one User Info field per station"); - tEnd = m_txPsdus[14].endTx; tStart = m_txPsdus[15].startTx; NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "Basic Trigger Frame sent too early"); NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "Basic Trigger Frame sent too late"); @@ -1250,112 +1277,137 @@ OfdmaAckSequenceTest::CheckResults(Time sifs, Time slotTime, uint8_t aifsn) navEnd + tolerance, "Duration/ID in Multi-STA BlockAck is too long"); - // the AP sends an MU-RTS Trigger Frame to protect the DL MU PPDU - NS_TEST_ASSERT_MSG_GT_OR_EQ(m_txPsdus.size(), 26, "Expected at least 26 transmitted packet"); - NS_TEST_EXPECT_MSG_EQ((m_txPsdus[21].psduMap.size() == 1 && - m_txPsdus[21].psduMap[SU_STA_ID]->GetHeader(0).IsTrigger() && - m_txPsdus[21].psduMap[SU_STA_ID]->GetHeader(0).GetAddr1().IsBroadcast()), - true, - "Expected a Trigger Frame"); - m_txPsdus[21].psduMap[SU_STA_ID]->GetPayload(0)->PeekHeader(trigger); - NS_TEST_EXPECT_MSG_EQ(trigger.IsMuRts(), true, "Expected an MU-RTS Trigger Frame"); - NS_TEST_EXPECT_MSG_EQ(trigger.GetNUserInfoFields(), - 4, - "Expected one User Info field per station"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[21].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the MU-RTS to occupy the entire channel width"); - for (const auto& userInfo : trigger) + // if the TXOP limit is not null, MU-RTS protection is not used because the next transmission + // is protected by the previous MU-RTS Trigger Frame + if (m_txopLimit == 0) { - NS_TEST_EXPECT_MSG_EQ(+userInfo.GetMuRtsRuAllocation(), - +m_muRtsRuAllocation, - "Unexpected RU Allocation value in MU-RTS"); + // the AP sends an MU-RTS Trigger Frame to protect the DL MU PPDU + NS_TEST_ASSERT_MSG_GT_OR_EQ(m_txPsdus.size(), + 26, + "Expected at least 26 transmitted packet"); + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[21].psduMap.size() == 1 && + m_txPsdus[21].psduMap[SU_STA_ID]->GetHeader(0).IsTrigger() && + m_txPsdus[21].psduMap[SU_STA_ID]->GetHeader(0).GetAddr1().IsBroadcast()), + true, + "Expected a Trigger Frame"); + m_txPsdus[21].psduMap[SU_STA_ID]->GetPayload(0)->PeekHeader(trigger); + NS_TEST_EXPECT_MSG_EQ(trigger.IsMuRts(), true, "Expected an MU-RTS Trigger Frame"); + NS_TEST_EXPECT_MSG_EQ(trigger.GetNUserInfoFields(), + 4, + "Expected one User Info field per station"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[21].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the MU-RTS to occupy the entire channel width"); + for (const auto& userInfo : trigger) + { + NS_TEST_EXPECT_MSG_EQ(+userInfo.GetMuRtsRuAllocation(), + +m_muRtsRuAllocation, + "Unexpected RU Allocation value in MU-RTS"); + } + tEnd = m_txPsdus[20].endTx; + tStart = m_txPsdus[21].startTx; + NS_TEST_EXPECT_MSG_LT_OR_EQ(tEnd + ifs, tStart, "MU-RTS Trigger Frame sent too early"); + tEnd = m_txPsdus[21].endTx; + navEnd = tEnd + m_txPsdus[21].psduMap[SU_STA_ID]->GetDuration(); + + // A first STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[22].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[22].psduMap.size() == 1 && + m_txPsdus[22].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[22].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[22].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); + + tStart = m_txPsdus[22].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[22].endTx + m_txPsdus[22].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); + + // A second STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[23].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[23].psduMap.size() == 1 && + m_txPsdus[23].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[23].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[23].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); + + tStart = m_txPsdus[23].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[23].endTx + m_txPsdus[23].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); + + // A third STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[24].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[24].psduMap.size() == 1 && + m_txPsdus[24].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[24].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[24].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); + + tStart = m_txPsdus[24].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[24].endTx + m_txPsdus[24].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); + + // A fourth STA sends a CTS frame a SIFS after the reception of the MU-RTS TF + NS_TEST_EXPECT_MSG_EQ( + (m_txPsdus[25].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && + m_txPsdus[25].psduMap.size() == 1 && + m_txPsdus[25].psduMap.begin()->second->GetNMpdus() == 1 && + m_txPsdus[25].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), + true, + "Expected a CTS frame"); + NS_TEST_EXPECT_MSG_EQ(m_txPsdus[25].txVector.GetChannelWidth(), + m_channelWidth, + "Expected the CTS to occupy the entire channel width"); + + tStart = m_txPsdus[25].startTx; + NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); + NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); + ctsNavEnd = m_txPsdus[25].endTx + m_txPsdus[25].psduMap[SU_STA_ID]->GetDuration(); + // navEnd <= ctsNavEnd < navEnd + tolerance + NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); + NS_TEST_EXPECT_MSG_LT(ctsNavEnd, + navEnd + tolerance, + "Duration/ID in CTS frame is too long"); + + tEnd = m_txPsdus[25].endTx; + } + else + { + // insert 5 elements in m_txPsdus to align the index of the following frames in the + // two cases (TXOP limit null and not null) + m_txPsdus.insert(std::next(m_txPsdus.begin(), 21), 5, {}); + tEnd = m_txPsdus[20].endTx; } - tEnd = m_txPsdus[20].endTx; - tStart = m_txPsdus[21].startTx; - NS_TEST_EXPECT_MSG_LT_OR_EQ(tEnd + ifs, tStart, "MU-RTS Trigger Frame sent too early"); - tEnd = m_txPsdus[21].endTx; - navEnd = tEnd + m_txPsdus[21].psduMap[SU_STA_ID]->GetDuration(); - - // A first STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[22].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[22].psduMap.size() == 1 && - m_txPsdus[22].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[22].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[22].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); - - tStart = m_txPsdus[22].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[22].endTx + m_txPsdus[22].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); - - // A second STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[23].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[23].psduMap.size() == 1 && - m_txPsdus[23].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[23].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[23].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); - - tStart = m_txPsdus[23].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[23].endTx + m_txPsdus[23].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); - - // A third STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[24].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[24].psduMap.size() == 1 && - m_txPsdus[24].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[24].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[24].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); - - tStart = m_txPsdus[24].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[24].endTx + m_txPsdus[24].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); - - // A fourth STA sends a CTS frame a SIFS after the reception of the MU-RTS TF - NS_TEST_EXPECT_MSG_EQ( - (m_txPsdus[25].txVector.GetPreambleType() != WIFI_PREAMBLE_HE_TB && - m_txPsdus[25].psduMap.size() == 1 && - m_txPsdus[25].psduMap.begin()->second->GetNMpdus() == 1 && - m_txPsdus[25].psduMap.begin()->second->GetHeader(0).GetType() == WIFI_MAC_CTL_CTS), - true, - "Expected a CTS frame"); - NS_TEST_EXPECT_MSG_EQ(m_txPsdus[25].txVector.GetChannelWidth(), - m_channelWidth, - "Expected the CTS to occupy the entire channel width"); - - tStart = m_txPsdus[25].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "CTS frame sent too early"); - NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "CTS frame sent too late"); - ctsNavEnd = m_txPsdus[25].endTx + m_txPsdus[25].psduMap[SU_STA_ID]->GetDuration(); - // navEnd <= ctsNavEnd < navEnd + tolerance - NS_TEST_EXPECT_MSG_LT_OR_EQ(navEnd, ctsNavEnd, "Duration/ID in CTS frame is too short"); - NS_TEST_EXPECT_MSG_LT(ctsNavEnd, navEnd + tolerance, "Duration/ID in CTS frame is too long"); // the AP sends a DL MU PPDU NS_TEST_ASSERT_MSG_GT_OR_EQ(m_txPsdus.size(), 27, "Expected at least 27 transmitted packet"); @@ -1375,9 +1427,8 @@ OfdmaAckSequenceTest::CheckResults(Time sifs, Time slotTime, uint8_t aifsn) m_maxAmpduSize, "Max A-MPDU size exceeded"); } - tEnd = m_txPsdus[25].endTx; tStart = m_txPsdus[26].startTx; - NS_TEST_EXPECT_MSG_LT(tEnd + sifs, tStart, "DL MU PPDU sent too early"); + NS_TEST_EXPECT_MSG_LT_OR_EQ(tEnd + sifs, tStart, "DL MU PPDU sent too early"); NS_TEST_EXPECT_MSG_LT(tStart, tEnd + sifs + tolerance, "DL MU PPDU sent too late"); // The Duration/ID field is the same for all the PSDUs