wifi: Add StaWifiMac and EHT FEM methods to handle EMLSR link switching
This commit is contained in:
committed by
Stefano Avallone
parent
0f04ea7caf
commit
1fd119e9ce
@@ -852,6 +852,21 @@ ChannelAccessManager::NotifySwitchingStartNow(Time duration)
|
||||
NS_ASSERT(m_lastTxEnd <= now);
|
||||
NS_ASSERT(m_lastSwitchingEnd <= now);
|
||||
|
||||
ResetState();
|
||||
|
||||
// Notify the FEM, which will in turn notify the MAC
|
||||
m_feManager->NotifySwitchingStartNow(duration);
|
||||
|
||||
NS_LOG_DEBUG("switching start for " << duration);
|
||||
m_lastSwitchingEnd = now + duration;
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::ResetState()
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
|
||||
Time now = Simulator::Now();
|
||||
m_lastRxReceivedOk = true;
|
||||
UpdateLastIdlePeriod();
|
||||
m_lastRx.end = std::min(m_lastRx.end, now);
|
||||
@@ -859,7 +874,6 @@ ChannelAccessManager::NotifySwitchingStartNow(Time duration)
|
||||
m_lastAckTimeoutEnd = std::min(m_lastAckTimeoutEnd, now);
|
||||
m_lastCtsTimeoutEnd = std::min(m_lastCtsTimeoutEnd, now);
|
||||
|
||||
// the new operating channel may have a different width than the previous one
|
||||
InitLastBusyStructs();
|
||||
|
||||
// Cancel timeout
|
||||
@@ -868,9 +882,6 @@ ChannelAccessManager::NotifySwitchingStartNow(Time duration)
|
||||
m_accessTimeout.Cancel();
|
||||
}
|
||||
|
||||
// Notify the FEM, which will in turn notify the MAC
|
||||
m_feManager->NotifySwitchingStartNow(duration);
|
||||
|
||||
// Reset backoffs
|
||||
for (auto txop : m_txops)
|
||||
{
|
||||
@@ -883,9 +894,6 @@ ChannelAccessManager::NotifySwitchingStartNow(Time duration)
|
||||
txop->ResetCw(m_linkId);
|
||||
txop->GetLink(m_linkId).access = Txop::NOT_REQUESTED;
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG("switching start for " << duration);
|
||||
m_lastSwitchingEnd = now + duration;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -271,6 +271,11 @@ class ChannelAccessManager : public Object
|
||||
*/
|
||||
bool IsBusy() const;
|
||||
|
||||
/**
|
||||
* Reset the state variables of this channel access manager.
|
||||
*/
|
||||
void ResetState();
|
||||
|
||||
protected:
|
||||
void DoInitialize() override;
|
||||
void DoDispose() override;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/ap-wifi-mac.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/sta-wifi-mac.h"
|
||||
#include "ns3/wifi-mac-queue.h"
|
||||
|
||||
#undef NS_LOG_APPEND_CONTEXT
|
||||
@@ -237,6 +238,27 @@ EhtFrameExchangeManager::EmlsrSwitchToListening(const Mac48Address& address, con
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EhtFrameExchangeManager::NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId, Time delay)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << phy << linkId << delay.As(Time::US));
|
||||
|
||||
// TODO Shall we assert that there is no ongoing frame exchange sequence? Or is it possible
|
||||
// that there is an ongoing frame exchange sequence (in such a case, we need to force a
|
||||
// timeout, just like it is done in case of a normal channel switch
|
||||
|
||||
NS_ABORT_MSG_IF(!m_staMac, "This method can only be called on a STA");
|
||||
|
||||
// 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)
|
||||
{
|
||||
ResetPhy();
|
||||
}
|
||||
m_staMac->NotifySwitchingEmlsrLink(phy, linkId);
|
||||
}
|
||||
|
||||
void
|
||||
EhtFrameExchangeManager::SendEmlOperatingModeNotification(
|
||||
const Mac48Address& dest,
|
||||
|
||||
@@ -77,6 +77,16 @@ class EhtFrameExchangeManager : public HeFrameExchangeManager
|
||||
uint16_t aid,
|
||||
const Mac48Address& address) const;
|
||||
|
||||
/**
|
||||
* Notify that the given PHY will switch channel to operate on another EMLSR link
|
||||
* after the given delay.
|
||||
*
|
||||
* \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, Time delay);
|
||||
|
||||
protected:
|
||||
void ForwardPsduDown(Ptr<const WifiPsdu> psdu, WifiTxVector& txVector) override;
|
||||
void ForwardPsduMapDown(WifiConstPsduMap psduMap, WifiTxVector& txVector) override;
|
||||
|
||||
@@ -1922,6 +1922,83 @@ StaWifiMac::PhyCapabilitiesChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial configuration:
|
||||
*
|
||||
* ┌───┬───┬───┐ ┌────┐ ┌───────┐
|
||||
* Link A │FEM│RSM│CAM│◄──────►│Main├──────►│Channel│
|
||||
* │ │ │ │ │PHY │ │ A │
|
||||
* └───┴───┴───┘ └────┘ └───────┘
|
||||
*
|
||||
* ┌───┬───┬───┐ ┌────┐ ┌───────┐
|
||||
* Link B │FEM│RSM│CAM│ │Aux │ │Channel│
|
||||
* │ │ │ │◄──────►│PHY ├──────►│ B │
|
||||
* └───┴───┴───┘ └────┘ └───────┘
|
||||
*
|
||||
* A link switching/swapping is notified by the EMLSR Manager and the Channel Access Manager
|
||||
* (CAM) notifies us that a first PHY (i.e., the Main PHY) switches to Channel B. We connect
|
||||
* the Main PHY to the MAC stack B:
|
||||
*
|
||||
*
|
||||
* ┌───┬───┬───┐ ┌────┐ ┌───────┐
|
||||
* Link A │FEM│RSM│CAM│ ┌───►│Main├───┐ │Channel│
|
||||
* │ │ │ │ │ │PHY │ │ │ A │
|
||||
* └───┴───┴───┘ │ └────┘ │ └───────┘
|
||||
* │ │
|
||||
* ┌───┬───┬───┐ │ ┌────┐ │ ┌───────┐
|
||||
* Link B │FEM│RSM│CAM│◄──┘ │Aux │ └──►│Channel│
|
||||
* │ │ │ │◄─ ─ ─ ─│PHY ├──────►│ B │
|
||||
* └───┴───┴───┘INACTIVE└────┘ └───────┘
|
||||
*
|
||||
* MAC stack B keeps a PHY listener associated with the Aux PHY, even though it is inactive,
|
||||
* meaning that the PHY listener will only notify channel switches (no CCA, no RX).
|
||||
* If the EMLSR Manager requested a link switching, this configuration will be kept until
|
||||
* further requests. If the EMLSR Manager requested a link swapping, link B's CAM will be
|
||||
* notified by its (inactive) PHY listener upon the channel switch performed by the Aux PHY.
|
||||
* In this case, we remove the inactive PHY listener and connect the Aux PHY to MAC stack A:
|
||||
*
|
||||
* ┌───┬───┬───┐ ┌────┐ ┌───────┐
|
||||
* Link A │FEM│RSM│CAM│◄─┐ ┌──►│Main├───┐ │Channel│
|
||||
* │ │ │ │ │ │ │PHY │ ┌─┼──►│ A │
|
||||
* └───┴───┴───┘ │ │ └────┘ │ │ └───────┘
|
||||
* │ │ │ │
|
||||
* ┌───┬───┬───┐ │ │ ┌────┐ │ │ ┌───────┐
|
||||
* Link B │FEM│RSM│CAM│◄─┼─┘ │Aux │ │ └──►│Channel│
|
||||
* │ │ │ │ └────►│PHY ├─┘ │ B │
|
||||
* └───┴───┴───┘ └────┘ └───────┘
|
||||
*/
|
||||
|
||||
void
|
||||
StaWifiMac::NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << phy << linkId);
|
||||
|
||||
// if any link points to the PHY that switched channel, reset the phy pointer
|
||||
for (auto& [id, link] : GetLinks())
|
||||
{
|
||||
// auto& link = GetStaLink(lnk);
|
||||
if (link->phy == phy)
|
||||
{
|
||||
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())
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::NotifyChannelSwitching(uint8_t linkId)
|
||||
{
|
||||
|
||||
@@ -308,6 +308,14 @@ class StaWifiMac : public WifiMac
|
||||
*/
|
||||
bool IsEmlsrLink(uint8_t linkId) const;
|
||||
|
||||
/**
|
||||
* Notify that the given PHY switched channel to operate on another EMLSR link.
|
||||
*
|
||||
* \param phy the given PHY
|
||||
* \param linkId the ID of the EMLSR link on which the given PHY is operating
|
||||
*/
|
||||
void NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy, uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Assign a fixed random variable stream number to the random variables
|
||||
* used by this model. Return the number of streams (possibly zero) that
|
||||
|
||||
Reference in New Issue
Block a user