wifi: Reset backoff and request access if needed when switching EMLSR links
This commit is contained in:
committed by
Stefano Avallone
parent
fb18aa503c
commit
942e0baca3
@@ -153,9 +153,11 @@ DefaultEmlsrManager::DoNotifyTxopEnd(uint8_t linkId)
|
||||
// is not received and the UL TXOP ends before the main PHY channel switch is completed.
|
||||
// In such cases, wait until the main PHY channel switch is completed before requesting
|
||||
// a new channel switch.
|
||||
// Backoff shall not be reset on the link left by the main PHY because a TXOP ended and
|
||||
// a new backoff value must be generated.
|
||||
if (!mainPhy->IsStateSwitching())
|
||||
{
|
||||
SwitchMainPhy(GetMainPhyId(), false);
|
||||
SwitchMainPhy(GetMainPhyId(), false, DONT_RESET_BACKOFF, REQUEST_ACCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -163,7 +165,9 @@ DefaultEmlsrManager::DoNotifyTxopEnd(uint8_t linkId)
|
||||
&DefaultEmlsrManager::SwitchMainPhy,
|
||||
this,
|
||||
GetMainPhyId(),
|
||||
false);
|
||||
false,
|
||||
DONT_RESET_BACKOFF,
|
||||
REQUEST_ACCESS);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,10 @@ EmlsrManager::NotifyIcfReceived(uint8_t linkId)
|
||||
}
|
||||
|
||||
Simulator::ScheduleNow([=, this]() {
|
||||
SwitchMainPhy(linkId, true); // channel switch should occur instantaneously
|
||||
SwitchMainPhy(linkId,
|
||||
true, // channel switch should occur instantaneously
|
||||
RESET_BACKOFF,
|
||||
DONT_REQUEST_ACCESS);
|
||||
|
||||
// aux PHY received the ICF but main PHY will send the response
|
||||
auto uid = auxPhy->GetPreviouslyRxPpduUid();
|
||||
@@ -423,7 +426,13 @@ EmlsrManager::NotifyUlTxopStart(uint8_t linkId, std::optional<Time> timeToCtsEnd
|
||||
|
||||
NS_ASSERT(delay.IsPositive());
|
||||
NS_LOG_DEBUG("Schedule main Phy switch in " << delay.As(Time::US));
|
||||
Simulator::Schedule(delay, &EmlsrManager::SwitchMainPhy, this, linkId, false);
|
||||
Simulator::Schedule(delay,
|
||||
&EmlsrManager::SwitchMainPhy,
|
||||
this,
|
||||
linkId,
|
||||
false,
|
||||
RESET_BACKOFF,
|
||||
DONT_REQUEST_ACCESS);
|
||||
}
|
||||
|
||||
DoNotifyUlTxopStart(linkId);
|
||||
@@ -487,9 +496,12 @@ EmlsrManager::SetCcaEdThresholdOnLinkSwitch(Ptr<WifiPhy> phy, uint8_t linkId)
|
||||
}
|
||||
|
||||
void
|
||||
EmlsrManager::SwitchMainPhy(uint8_t linkId, bool noSwitchDelay)
|
||||
EmlsrManager::SwitchMainPhy(uint8_t linkId,
|
||||
bool noSwitchDelay,
|
||||
bool resetBackoff,
|
||||
bool requestAccess)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << linkId << noSwitchDelay);
|
||||
NS_LOG_FUNCTION(this << linkId << noSwitchDelay << resetBackoff << requestAccess);
|
||||
|
||||
auto mainPhy = m_staMac->GetDevice()->GetPhy(m_mainPhyId);
|
||||
|
||||
@@ -535,6 +547,28 @@ EmlsrManager::SwitchMainPhy(uint8_t linkId, bool noSwitchDelay)
|
||||
mainPhy->SetSlot(MicroSeconds(9));
|
||||
}
|
||||
|
||||
if (resetBackoff)
|
||||
{
|
||||
// reset the backoffs on the link left by the main PHY
|
||||
m_staMac->GetChannelAccessManager(*currMainPhyLinkId)->ResetAllBackoffs();
|
||||
}
|
||||
|
||||
const auto timeToSwitchEnd = noSwitchDelay ? Seconds(0) : mainPhy->GetChannelSwitchDelay();
|
||||
|
||||
if (requestAccess)
|
||||
{
|
||||
// schedule channel access request on the new link when switch is completed
|
||||
Simulator::Schedule(timeToSwitchEnd, [=, this]() {
|
||||
for (const auto& [acIndex, ac] : wifiAcList)
|
||||
{
|
||||
m_staMac->GetQosTxop(acIndex)->StartAccessAfterEvent(
|
||||
linkId,
|
||||
Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT,
|
||||
Txop::CHECK_MEDIUM_BUSY);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SetCcaEdThresholdOnLinkSwitch(mainPhy, linkId);
|
||||
NotifyMainPhySwitch(*currMainPhyLinkId, linkId);
|
||||
}
|
||||
@@ -562,6 +596,17 @@ EmlsrManager::SwitchAuxPhy(uint8_t currLinkId, uint8_t nextLinkId)
|
||||
auxPhy->SetSlot(MicroSeconds(9));
|
||||
}
|
||||
|
||||
// schedule channel access request on the new link when switch is completed
|
||||
Simulator::Schedule(auxPhy->GetChannelSwitchDelay(), [=, this]() {
|
||||
for (const auto& [acIndex, ac] : wifiAcList)
|
||||
{
|
||||
m_staMac->GetQosTxop(acIndex)->StartAccessAfterEvent(
|
||||
nextLinkId,
|
||||
Txop::DIDNT_HAVE_FRAMES_TO_TRANSMIT,
|
||||
Txop::CHECK_MEDIUM_BUSY);
|
||||
}
|
||||
});
|
||||
|
||||
SetCcaEdThresholdOnLinkSwitch(auxPhy, nextLinkId);
|
||||
}
|
||||
|
||||
|
||||
@@ -285,8 +285,18 @@ class EmlsrManager : public Object
|
||||
*
|
||||
* \param linkId the ID of the link on which the main PHY has to operate
|
||||
* \param noSwitchDelay whether switching delay should be zero
|
||||
* \param resetBackoff whether backoff should be reset on the link on which the main PHY
|
||||
* is operating
|
||||
* \param requestAccess whether channel access should be requested on the link on which the
|
||||
* main PHY is moving onto
|
||||
*/
|
||||
void SwitchMainPhy(uint8_t linkId, bool noSwitchDelay);
|
||||
void SwitchMainPhy(uint8_t linkId, bool noSwitchDelay, bool resetBackoff, bool requestAccess);
|
||||
|
||||
static constexpr bool RESET_BACKOFF = true; //!< reset backoff on main PHY switch
|
||||
static constexpr bool DONT_RESET_BACKOFF = false; //!< do not reset backoff on main PHY switch
|
||||
static constexpr bool REQUEST_ACCESS = true; //!< request channel access when PHY switch ends
|
||||
static constexpr bool DONT_REQUEST_ACCESS =
|
||||
false; //!< do not request channel access when PHY switch ends
|
||||
|
||||
/**
|
||||
* Switch channel on the Aux PHY operating on the given current link so that it operates
|
||||
|
||||
Reference in New Issue
Block a user