wifi: Extend EMLSR test to check blocked links at non-AP MLD side
This commit is contained in:
committed by
Stefano Avallone
parent
12b3764437
commit
b2d2d37c14
@@ -184,6 +184,27 @@ class EmlsrOperationsTestBase : public TestCase
|
||||
std::size_t count,
|
||||
std::size_t pktSize) const;
|
||||
|
||||
/**
|
||||
* Check whether QoS data unicast transmissions addressed to the given destination on the
|
||||
* given link are blocked or unblocked for the given reason on the given device.
|
||||
*
|
||||
* \param mac the MAC of the given device
|
||||
* \param dest the MAC address of the given destination
|
||||
* \param linkId the ID of the given link
|
||||
* \param reason the reason for blocking transmissions to test
|
||||
* \param blocked whether transmissions are blocked for the given reason
|
||||
* \param description text indicating when this check is performed
|
||||
* \param testUnblockedForOtherReasons whether to test if transmissions are unblocked for
|
||||
* all the reasons other than the one provided
|
||||
*/
|
||||
void CheckBlockedLink(Ptr<WifiMac> mac,
|
||||
Mac48Address dest,
|
||||
uint8_t linkId,
|
||||
WifiQueueBlockedReason reason,
|
||||
bool blocked,
|
||||
std::string description,
|
||||
bool testUnblockedForOtherReasons = true);
|
||||
|
||||
void DoSetup() override;
|
||||
|
||||
/// Information about transmitted frames
|
||||
@@ -520,6 +541,50 @@ EmlsrOperationsTestBase::SetSsid(uint16_t aid, Mac48Address /* addr */)
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
EmlsrOperationsTestBase::CheckBlockedLink(Ptr<WifiMac> mac,
|
||||
Mac48Address dest,
|
||||
uint8_t linkId,
|
||||
WifiQueueBlockedReason reason,
|
||||
bool blocked,
|
||||
std::string description,
|
||||
bool testUnblockedForOtherReasons)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, dest, 0);
|
||||
auto mask = mac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, linkId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
description << ": Expected to find a mask for EMLSR link " << +linkId);
|
||||
if (blocked)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(static_cast<std::size_t>(reason)),
|
||||
true,
|
||||
description << ": Expected EMLSR link " << +linkId
|
||||
<< " to be blocked for reason " << reason);
|
||||
if (testUnblockedForOtherReasons)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
description << ": Expected EMLSR link " << +linkId
|
||||
<< " to be blocked for one reason only");
|
||||
}
|
||||
}
|
||||
else if (testUnblockedForOtherReasons)
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->none(),
|
||||
true,
|
||||
description << ": Expected EMLSR link " << +linkId
|
||||
<< " to be unblocked");
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(static_cast<std::size_t>(reason)),
|
||||
false,
|
||||
description << ": Expected EMLSR link " << +linkId
|
||||
<< " to be unblocked for reason " << reason);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi-test
|
||||
* \ingroup tests
|
||||
@@ -1961,18 +2026,14 @@ EmlsrDlTxopTest::CheckPmModeAfterAssociation(const Mac48Address& address)
|
||||
<< " not in " << (psModeExpected ? "PS" : "active")
|
||||
<< " mode");
|
||||
// check that AP is blocking transmission of QoS data frames on this link
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, linkId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +linkId << " of EMLSR client " << *staId);
|
||||
auto reason = static_cast<std::size_t>(WifiQueueBlockedReason::POWER_SAVE_MODE);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
psModeExpected,
|
||||
"Expected EMLSR link " << +linkId << " of EMLSR client " << *staId
|
||||
<< " to be "
|
||||
<< (psModeExpected ? "blocked" : "unblocked"));
|
||||
CheckBlockedLink(m_apMac,
|
||||
addr,
|
||||
linkId,
|
||||
WifiQueueBlockedReason::POWER_SAVE_MODE,
|
||||
psModeExpected,
|
||||
"Checking PM mode after association on AP MLD for EMLSR client " +
|
||||
std::to_string(*staId),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2028,18 +2089,15 @@ EmlsrDlTxopTest::CheckEmlNotificationFrame(Ptr<const WifiMpdu> mpdu,
|
||||
"EMLSR link " << +linkId << " of EMLSR client " << *staId
|
||||
<< " not in active mode");
|
||||
// check that AP is not blocking transmission of QoS data frames on this link
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask =
|
||||
m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, linkId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +linkId << " of EMLSR client " << *staId);
|
||||
auto reason = static_cast<std::size_t>(WifiQueueBlockedReason::POWER_SAVE_MODE);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
false,
|
||||
"Expected EMLSR link " << +linkId << " of EMLSR client "
|
||||
<< *staId << " to be unblocked");
|
||||
CheckBlockedLink(
|
||||
m_apMac,
|
||||
addr,
|
||||
linkId,
|
||||
WifiQueueBlockedReason::POWER_SAVE_MODE,
|
||||
false,
|
||||
"Checking EMLSR links on AP MLD after EMLSR mode is enabled on EMLSR client " +
|
||||
std::to_string(*staId),
|
||||
false);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2058,18 +2116,15 @@ EmlsrDlTxopTest::CheckEmlNotificationFrame(Ptr<const WifiMpdu> mpdu,
|
||||
<< +id << " of EMLSR client " << *staId << " not in "
|
||||
<< (psModeExpected ? "PS" : "active") << " mode");
|
||||
// check that AP is blocking transmission of QoS data frames on this link
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << *staId);
|
||||
auto reason = static_cast<std::size_t>(WifiQueueBlockedReason::POWER_SAVE_MODE);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
psModeExpected,
|
||||
"Expected EMLSR link "
|
||||
<< +id << " of EMLSR client " << *staId << " to be "
|
||||
<< (psModeExpected ? "blocked" : "unblocked"));
|
||||
CheckBlockedLink(
|
||||
m_apMac,
|
||||
addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::POWER_SAVE_MODE,
|
||||
psModeExpected,
|
||||
"Checking links on AP MLD after EMLSR mode is disabled on EMLSR client " +
|
||||
std::to_string(*staId),
|
||||
false);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2130,53 +2185,28 @@ EmlsrDlTxopTest::CheckInitialControlFrame(Ptr<const WifiMpdu> mpdu,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (id == linkId)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask =
|
||||
m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << *addr);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->none(),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< *addr << " to be unblocked");
|
||||
continue;
|
||||
}
|
||||
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << *addr);
|
||||
auto reason =
|
||||
static_cast<std::size_t>(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client " << *addr
|
||||
<< " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link "
|
||||
<< +id << " of EMLSR client " << *addr
|
||||
<< " to be blocked for one reason only");
|
||||
CheckBlockedLink(m_apMac,
|
||||
*addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking that AP blocked transmissions on all other EMLSR "
|
||||
"links after sending ICF to client with AID=" +
|
||||
std::to_string(userInfo.GetAid12()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ(found, true, "Expected ICF to be addressed to at least an EMLSR client");
|
||||
|
||||
auto txDuration = WifiPhy::CalculateTxDuration(mpdu->GetSize(),
|
||||
txVector,
|
||||
m_apMac->GetWifiPhy(linkId)->GetPhyBand());
|
||||
|
||||
if (maxPaddingDelay.IsStrictlyPositive())
|
||||
{
|
||||
// compare the TX duration of this Trigger Frame to that of the Trigger Frame with no
|
||||
// padding added
|
||||
auto txDurationWith =
|
||||
WifiPhy::CalculateTxDuration(mpdu->GetSize(),
|
||||
txVector,
|
||||
m_apMac->GetWifiPhy(linkId)->GetPhyBand());
|
||||
trigger.SetPaddingSize(0);
|
||||
auto pkt = Create<Packet>();
|
||||
pkt->AddHeader(trigger);
|
||||
@@ -2185,11 +2215,40 @@ EmlsrDlTxopTest::CheckInitialControlFrame(Ptr<const WifiMpdu> mpdu,
|
||||
txVector,
|
||||
m_apMac->GetWifiPhy(linkId)->GetPhyBand());
|
||||
|
||||
NS_TEST_EXPECT_MSG_EQ(txDurationWith,
|
||||
NS_TEST_EXPECT_MSG_EQ(txDuration,
|
||||
txDurationWithout + maxPaddingDelay,
|
||||
"Unexpected TX duration of the MU-RTS TF with padding "
|
||||
<< maxPaddingDelay.As(Time::US));
|
||||
}
|
||||
|
||||
// check that the EMLSR clients have blocked transmissions on other links after
|
||||
// receiving this ICF
|
||||
for (const auto& userInfo : trigger)
|
||||
{
|
||||
for (std::size_t i = 0; i < m_nEmlsrStations; i++)
|
||||
{
|
||||
if (m_staMacs[i]->GetAssociationId() != userInfo.GetAid12())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Simulator::Schedule(txDuration + NanoSeconds(5), [=]() {
|
||||
for (uint8_t id = 0; id < m_staMacs[i]->GetNLinks(); id++)
|
||||
{
|
||||
// non-EMLSR links or links on which ICF is received are not blocked
|
||||
CheckBlockedLink(m_staMacs[i],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId && m_staMacs[i]->IsEmlsrLink(id),
|
||||
"Checking EMLSR links on EMLSR client " + std::to_string(i) +
|
||||
" after receiving ICF");
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2219,80 +2278,95 @@ EmlsrDlTxopTest::CheckQosFrames(const WifiConstPsduMap& psduMap,
|
||||
// generate another small packet addressed to the first EMLSR client only
|
||||
m_apMac->GetDevice()->GetNode()->AddApplication(
|
||||
GetApplication(DOWNLINK, firstClientId, 1, 40));
|
||||
// both EMLSR clients are about to receive a QoS data frame
|
||||
for (std::size_t clientId : {firstClientId, secondClientId})
|
||||
{
|
||||
Simulator::Schedule(txDuration, [=]() {
|
||||
for (uint8_t id = 0; id < m_staMacs[clientId]->GetNLinks(); id++)
|
||||
{
|
||||
// link on which QoS data is received is not blocked
|
||||
CheckBlockedLink(m_staMacs[clientId],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking EMLSR links on EMLSR client " +
|
||||
std::to_string(clientId) +
|
||||
" after receiving the first QoS data frame");
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// generate another small packet addressed to the second EMLSR client
|
||||
m_apMac->GetDevice()->GetNode()->AddApplication(
|
||||
GetApplication(DOWNLINK, secondClientId, 1, 40));
|
||||
|
||||
// when the transmission of the second QoS data frame starts, both EMLSR clients are
|
||||
// still blocking all the links but the one used to receive the QoS data frame
|
||||
for (std::size_t clientId : {firstClientId, secondClientId})
|
||||
{
|
||||
for (uint8_t id = 0; id < m_staMacs[clientId]->GetNLinks(); id++)
|
||||
{
|
||||
// link on which QoS data is received is not blocked
|
||||
CheckBlockedLink(m_staMacs[clientId],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking EMLSR links on EMLSR client " +
|
||||
std::to_string(clientId) +
|
||||
" when starting the reception of the second QoS frame");
|
||||
}
|
||||
}
|
||||
|
||||
// the EMLSR client that is not the recipient of the QoS frame being transmitted will
|
||||
// switch back to listening mode after a transition delay starting from the end of
|
||||
// the PPDU carrying this QoS data frame
|
||||
|
||||
// immediately before the end of the PPDU, this link is not blocked for the EMLSR client
|
||||
Simulator::Schedule(txDuration - NanoSeconds(1), [=]() {
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, linkId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +linkId << " of EMLSR client " << secondClientId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->none(),
|
||||
true,
|
||||
"Expected EMLSR link " << +linkId << " of EMLSR client "
|
||||
<< secondClientId << " to be unblocked");
|
||||
});
|
||||
// immediately before the end of the PPDU, the other links are blocked for the EMLSR client
|
||||
// immediately before the end of the PPDU, this link only is not blocked for the EMLSR
|
||||
// client on the AP MLD
|
||||
Simulator::Schedule(txDuration - NanoSeconds(1), [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
if (id == linkId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << secondClientId);
|
||||
auto reason =
|
||||
static_cast<std::size_t>(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< secondClientId << " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< secondClientId
|
||||
<< " to be blocked "
|
||||
" for one reason only");
|
||||
CheckBlockedLink(m_apMac,
|
||||
addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking that links of EMLSR client " +
|
||||
std::to_string(secondClientId) +
|
||||
" are blocked on the AP MLD before the end of the PPDU");
|
||||
}
|
||||
});
|
||||
// immediately before the end of the PPDU, all the links on the EMLSR client that is not
|
||||
// the recipient of the second QoS frame are unblocked (they are unblocked when the
|
||||
// PHY-RXSTART.indication is not received)
|
||||
Simulator::Schedule(txDuration - NanoSeconds(1), [=]() {
|
||||
for (uint8_t id = 0; id < m_staMacs[secondClientId]->GetNLinks(); id++)
|
||||
{
|
||||
CheckBlockedLink(m_staMacs[secondClientId],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
false,
|
||||
"Checking that links of EMLSR client " +
|
||||
std::to_string(secondClientId) +
|
||||
" are unblocked before the end of the second QoS frame");
|
||||
}
|
||||
});
|
||||
// immediately after the end of the PPDU, all links are blocked for the EMLSR client
|
||||
Simulator::Schedule(txDuration + NanoSeconds(1), [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << secondClientId);
|
||||
auto reason = static_cast<std::size_t>(
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< secondClientId << " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< secondClientId
|
||||
<< " to be blocked "
|
||||
" for one reason only");
|
||||
CheckBlockedLink(m_apMac,
|
||||
addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY,
|
||||
true,
|
||||
"Checking links of EMLSR client " +
|
||||
std::to_string(secondClientId) +
|
||||
" are all blocked on the AP MLD after the end of the PPDU");
|
||||
}
|
||||
});
|
||||
// immediately before the transition delay, all links are still blocked for the EMLSR client
|
||||
@@ -2301,30 +2375,35 @@ EmlsrDlTxopTest::CheckQosFrames(const WifiConstPsduMap& psduMap,
|
||||
[=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, addr, 0);
|
||||
auto mask =
|
||||
m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << secondClientId);
|
||||
auto reason = static_cast<std::size_t>(
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< secondClientId
|
||||
<< " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< secondClientId
|
||||
<< " to be blocked "
|
||||
" for one reason only");
|
||||
CheckBlockedLink(
|
||||
m_apMac,
|
||||
addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY,
|
||||
true,
|
||||
"Checking links of EMLSR client " + std::to_string(secondClientId) +
|
||||
" are all blocked on the AP MLD before the transition delay");
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
case 3:
|
||||
// at the end of the third QoS frame, this link only is not blocked on the EMLSR
|
||||
// client receiving the frame
|
||||
Simulator::Schedule(txDuration, [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
CheckBlockedLink(m_staMacs[secondClientId],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking EMLSR links on EMLSR client " +
|
||||
std::to_string(secondClientId) +
|
||||
" after receiving the third QoS data frame");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2380,116 +2459,87 @@ EmlsrDlTxopTest::CheckBlockAck(const WifiConstPsduMap& psduMap,
|
||||
// not responded and assumes that the EMLSR client has started the transition to the
|
||||
// listening mode (such transition lasting the transition delay)
|
||||
|
||||
// at the end of the PPDU, this link is not blocked for the EMLSR client
|
||||
Simulator::Schedule(txDuration, [=]() {
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, linkId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +linkId << " of EMLSR client " << clientId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->none(),
|
||||
true,
|
||||
"Expected EMLSR link " << +linkId << " of EMLSR client "
|
||||
<< clientId << " to be unblocked");
|
||||
});
|
||||
// at the end of the PPDU, the other links are blocked for the EMLSR client
|
||||
// at the end of the PPDU, this link only is not blocked on the EMLSR client
|
||||
Simulator::Schedule(txDuration, [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
if (id == linkId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << clientId);
|
||||
auto reason =
|
||||
static_cast<std::size_t>(WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId << " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId
|
||||
<< " to be blocked "
|
||||
" for one reason only");
|
||||
CheckBlockedLink(m_staMacs[clientId],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking links on EMLSR client " + std::to_string(clientId) +
|
||||
" at the end of fourth BlockAck");
|
||||
CheckBlockedLink(m_apMac,
|
||||
*addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking links of EMLSR client " + std::to_string(clientId) +
|
||||
" on the AP MLD before the end of the PPDU plus timeout");
|
||||
}
|
||||
});
|
||||
// immediately after the end of the PPDU, all links are blocked for the EMLSR client
|
||||
Simulator::Schedule(txDuration + MicroSeconds(1), [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << clientId);
|
||||
auto reason = static_cast<std::size_t>(
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId << " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId
|
||||
<< " to be blocked "
|
||||
" for one reason only");
|
||||
CheckBlockedLink(
|
||||
m_apMac,
|
||||
*addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY,
|
||||
true,
|
||||
"Checking links of EMLSR client " + std::to_string(clientId) +
|
||||
" are all blocked on the AP MLD after the end of the PPDU plus timeout");
|
||||
}
|
||||
});
|
||||
// immediately before the transition delay, all links are still blocked for the EMLSR client
|
||||
Simulator::Schedule(txDuration + m_transitionDelay.at(clientId), [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << clientId);
|
||||
auto reason = static_cast<std::size_t>(
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->test(reason),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId << " to be blocked");
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->count(),
|
||||
1,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId
|
||||
<< " to be blocked "
|
||||
" for one reason only");
|
||||
CheckBlockedLink(m_apMac,
|
||||
*addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY,
|
||||
true,
|
||||
"Checking links of EMLSR client " + std::to_string(clientId) +
|
||||
" are all blocked on the AP MLD before the transition delay");
|
||||
}
|
||||
});
|
||||
// immediately after the transition delay, all links are unblocked for the EMLSR client
|
||||
Simulator::Schedule(txDuration + m_transitionDelay.at(clientId) + MicroSeconds(1), [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
WifiContainerQueueId queueId(WIFI_QOSDATA_QUEUE, WIFI_UNICAST, *addr, 0);
|
||||
auto mask = m_apMac->GetMacQueueScheduler()->GetQueueLinkMask(AC_BE, queueId, id);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask.has_value(),
|
||||
true,
|
||||
"Expected to find a mask for EMLSR link "
|
||||
<< +id << " of EMLSR client " << clientId);
|
||||
NS_TEST_EXPECT_MSG_EQ(mask->none(),
|
||||
true,
|
||||
"Expected EMLSR link " << +id << " of EMLSR client "
|
||||
<< clientId << " to be unblocked");
|
||||
CheckBlockedLink(m_apMac,
|
||||
*addr,
|
||||
id,
|
||||
WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY,
|
||||
false,
|
||||
"Checking links of EMLSR client " + std::to_string(clientId) +
|
||||
" are all unblocked on the AP MLD after the transition delay");
|
||||
}
|
||||
});
|
||||
|
||||
// corrupt this BlockAck so that the AP MLD sends a BlockAckReq later on
|
||||
auto uid = psduMap.cbegin()->second->GetPacket()->GetUid();
|
||||
m_errorModel->SetList({uid});
|
||||
{
|
||||
auto uid = psduMap.cbegin()->second->GetPacket()->GetUid();
|
||||
m_errorModel->SetList({uid});
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
// at the end of the PPDU, this link only is not blocked on the EMLSR client
|
||||
Simulator::Schedule(txDuration, [=]() {
|
||||
for (uint8_t id = 0; id < m_apMac->GetNLinks(); id++)
|
||||
{
|
||||
CheckBlockedLink(m_staMacs[clientId],
|
||||
m_apMac->GetAddress(),
|
||||
id,
|
||||
WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
|
||||
id != linkId,
|
||||
"Checking links on EMLSR client " + std::to_string(clientId) +
|
||||
" at the end of fifth BlockAck");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user