From 4b34ad4f5c9b838ac4e434b067293d367ead5180 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Sat, 13 Jan 2024 22:20:29 +0100 Subject: [PATCH] wifi: Switch main PHY back to primary link only if no TXOP is ongoing on another EMLSR link Aux PHY sends RTS and schedules main PHY switch; no CTS is received and CTS timeout occurs while main PHY is switching. Do not unconditionally schedule switching the main PHY back to the primary link when the ongoing channel switch terminates; indeed, channel access may be obtained in the meantime and the main PHY will be requested to switch the link on which channel access has been obtained. --- src/wifi/model/eht/default-emlsr-manager.cc | 17 ++++++++++------- src/wifi/test/wifi-emlsr-test.cc | 6 ++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/wifi/model/eht/default-emlsr-manager.cc b/src/wifi/model/eht/default-emlsr-manager.cc index f7e750df6..cd2b39ae2 100644 --- a/src/wifi/model/eht/default-emlsr-manager.cc +++ b/src/wifi/model/eht/default-emlsr-manager.cc @@ -19,6 +19,8 @@ #include "default-emlsr-manager.h" +#include "eht-frame-exchange-manager.h" + #include "ns3/boolean.h" #include "ns3/channel-access-manager.h" #include "ns3/log.h" @@ -161,13 +163,14 @@ DefaultEmlsrManager::DoNotifyTxopEnd(uint8_t linkId) } else { - Simulator::Schedule(mainPhy->GetDelayUntilIdle(), - &DefaultEmlsrManager::SwitchMainPhy, - this, - GetMainPhyId(), - false, - DONT_RESET_BACKOFF, - REQUEST_ACCESS); + Simulator::Schedule(mainPhy->GetDelayUntilIdle(), [=, this]() { + // request the main PHY to switch back to the primary link only if in the meantime + // no TXOP started on another link (which will require the main PHY to switch link) + if (!GetEhtFem(linkId)->UsingOtherEmlsrLink()) + { + SwitchMainPhy(GetMainPhyId(), false, DONT_RESET_BACKOFF, REQUEST_ACCESS); + } + }); } return; } diff --git a/src/wifi/test/wifi-emlsr-test.cc b/src/wifi/test/wifi-emlsr-test.cc index a7ff8dd1a..b72d5770d 100644 --- a/src/wifi/test/wifi-emlsr-test.cc +++ b/src/wifi/test/wifi-emlsr-test.cc @@ -3585,6 +3585,12 @@ EmlsrLinkSwitchTest::CheckResults() // m_txPsdusPos points to ADDBA_RESPONSE, then ACK and then ICF auto psduIt = std::next(m_txPsdus.cbegin(), m_txPsdusPos + 2); + // skip first PSDU if it contains a Beacon frame + if (psduIt->psduMap.at(SU_STA_ID)->GetHeader(0).IsBeacon()) + { + psduIt++; + } + for (std::size_t i = 0; i < nRxOk; i++) { NS_TEST_EXPECT_MSG_EQ((psduIt->psduMap.size() == 1 &&