wifi: PHY operates on EMLSR link until another PHY completes channel switching
This commit is contained in:
committed by
Stefano Avallone
parent
7dfb732a0d
commit
5ae9fabf49
@@ -133,7 +133,10 @@ DefaultEmlsrManager::DoNotifyTxopEnd(uint8_t linkId)
|
||||
auto phy = m_auxPhyToReconnect;
|
||||
SwitchMainPhy(*m_linkIdForMainPhyAfterTxop, false);
|
||||
// Reconnect the aux PHY to its original link
|
||||
Simulator::ScheduleNow(&StaWifiMac::NotifySwitchingEmlsrLink, GetStaMac(), phy, linkId);
|
||||
Simulator::ScheduleNow([=, this]() {
|
||||
// the Aux PHY is not actually switching (hence no switching delay)
|
||||
GetStaMac()->NotifySwitchingEmlsrLink(phy, linkId, Seconds(0));
|
||||
});
|
||||
SetCcaEdThresholdOnLinkSwitch(phy, linkId);
|
||||
}
|
||||
m_linkIdForMainPhyAfterTxop.reset();
|
||||
|
||||
@@ -407,12 +407,14 @@ EhtFrameExchangeManager::NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t link
|
||||
|
||||
// if we receive the notification from a PHY that is not connected to us, it means that
|
||||
// we have been already connected to another PHY operating on this link, hence we do not
|
||||
// have to reset the connected PHY
|
||||
if (phy == m_phy)
|
||||
// have to reset the connected PHY. Similarly, we do not have to reset the connected PHY if
|
||||
// the link does not change (this occurs when changing the channel width of aux PHYs upon
|
||||
// enabling the EMLSR mode).
|
||||
if (phy == m_phy && linkId != m_linkId)
|
||||
{
|
||||
ResetPhy();
|
||||
}
|
||||
m_staMac->NotifySwitchingEmlsrLink(phy, linkId);
|
||||
m_staMac->NotifySwitchingEmlsrLink(phy, linkId, delay);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -882,12 +882,22 @@ EmlsrManager::ApplyMaxChannelWidthAndModClassOnAuxPhys()
|
||||
// this channel switch must not have such a consequence. We already have a method
|
||||
// for doing so, i.e., inform the MAC that the PHY is switching channel to operate
|
||||
// on the "same" link.
|
||||
m_staMac->GetChannelAccessManager(linkId)->NotifySwitchingEmlsrLink(auxPhy,
|
||||
channel,
|
||||
linkId);
|
||||
auto cam = m_staMac->GetChannelAccessManager(linkId);
|
||||
cam->NotifySwitchingEmlsrLink(auxPhy, channel, linkId);
|
||||
|
||||
void (WifiPhy::*fp)(const WifiPhyOperatingChannel&) = &WifiPhy::SetOperatingChannel;
|
||||
Simulator::ScheduleNow(fp, auxPhy, channel);
|
||||
|
||||
// the way the ChannelAccessManager handles EMLSR link switch implies that a PHY listener
|
||||
// is removed when the channel switch starts and another one is attached when the channel
|
||||
// switch ends. In the meantime, no PHY is connected to the ChannelAccessManager. Inform
|
||||
// the ChannelAccessManager that this channel switch is related to EMLSR operations, so
|
||||
// that the ChannelAccessManager does not complain if events requiring access to the PHY
|
||||
// occur during the channel switch.
|
||||
cam->NotifyStartUsingOtherEmlsrLink();
|
||||
Simulator::Schedule(auxPhy->GetChannelSwitchDelay(),
|
||||
&ChannelAccessManager::NotifyStopUsingOtherEmlsrLink,
|
||||
cam);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2024,34 +2024,50 @@ StaWifiMac::PhyCapabilitiesChanged()
|
||||
*/
|
||||
|
||||
void
|
||||
StaWifiMac::NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId)
|
||||
StaWifiMac::NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId, Time delay)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << phy << linkId);
|
||||
NS_LOG_FUNCTION(this << phy << linkId << delay.As(Time::US));
|
||||
|
||||
// if any link points to the PHY that switched channel, reset the phy pointer
|
||||
// If the PHY is switching channel to operate on another link, then it is no longer operating
|
||||
// on the current link. If any link (other than the current link) points to the PHY that is
|
||||
// switching channel, reset the phy pointer of the link
|
||||
for (auto& [id, link] : GetLinks())
|
||||
{
|
||||
// auto& link = GetStaLink(lnk);
|
||||
if (link->phy == phy)
|
||||
if (link->phy == phy && id != linkId)
|
||||
{
|
||||
link->phy = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto& newLink = GetLink(linkId);
|
||||
// The MAC stack associated with the new link uses the given PHY
|
||||
newLink.phy = phy;
|
||||
// Setup a PHY listener for the given PHY on the CAM associated with the new link
|
||||
newLink.channelAccessManager->SetupPhyListener(phy);
|
||||
NS_ASSERT(m_emlsrManager);
|
||||
if (m_emlsrManager->GetCamStateReset())
|
||||
// lambda to connect the PHY to the new link
|
||||
auto connectPhy = [=, this]() mutable {
|
||||
auto& newLink = GetLink(linkId);
|
||||
// The MAC stack associated with the new link uses the given PHY
|
||||
newLink.phy = phy;
|
||||
// Setup a PHY listener for the given PHY on the CAM associated with the new link
|
||||
newLink.channelAccessManager->SetupPhyListener(phy);
|
||||
NS_ASSERT(m_emlsrManager);
|
||||
if (m_emlsrManager->GetCamStateReset())
|
||||
{
|
||||
newLink.channelAccessManager->ResetState();
|
||||
}
|
||||
// Disconnect the FEM on the new link from the current PHY
|
||||
newLink.feManager->ResetPhy();
|
||||
// Connect the FEM on the new link to the given PHY
|
||||
newLink.feManager->SetWifiPhy(phy);
|
||||
};
|
||||
|
||||
// if there is no PHY operating on the new link, connect the PHY to the new link now.
|
||||
// Otherwise, wait until the channel switch is completed, so that the PHY operating on the new
|
||||
// link can possibly continue receiving frames in the meantime.
|
||||
if (!GetLink(linkId).phy)
|
||||
{
|
||||
newLink.channelAccessManager->ResetState();
|
||||
connectPhy();
|
||||
}
|
||||
else
|
||||
{
|
||||
Simulator::Schedule(delay, connectPhy);
|
||||
}
|
||||
// Disconnect the FEM on the new link from the current PHY
|
||||
newLink.feManager->ResetPhy();
|
||||
// Connect the FEM on the new link to the given PHY
|
||||
newLink.feManager->SetWifiPhy(phy);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -307,8 +307,9 @@ class StaWifiMac : public WifiMac
|
||||
*
|
||||
* \param phy the given PHY
|
||||
* \param linkId the ID of the EMLSR link on which the given PHY is operating
|
||||
* \param delay the delay after which the channel switch will be completed
|
||||
*/
|
||||
void NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId);
|
||||
void NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId, Time delay);
|
||||
|
||||
/**
|
||||
* Block transmissions on the given link for the given reason.
|
||||
|
||||
Reference in New Issue
Block a user