wifi: CAM detects if a PHY switched channel to operate on another EMLSR link
This commit is contained in:
committed by
Stefano Avallone
parent
1fd119e9ce
commit
4058d7b933
@@ -19,11 +19,11 @@
|
||||
|
||||
#include "channel-access-manager.h"
|
||||
|
||||
#include "frame-exchange-manager.h"
|
||||
#include "txop.h"
|
||||
#include "wifi-phy-listener.h"
|
||||
#include "wifi-phy.h"
|
||||
|
||||
#include "ns3/eht-frame-exchange-manager.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/simulator.h"
|
||||
|
||||
@@ -122,7 +122,7 @@ class PhyListener : public ns3::WifiPhyListener
|
||||
|
||||
void NotifySwitchingStart(Time duration) override
|
||||
{
|
||||
m_cam->NotifySwitchingStartNow(duration);
|
||||
m_cam->NotifySwitchingStartNow(this, duration);
|
||||
}
|
||||
|
||||
void NotifySleep() override
|
||||
@@ -245,6 +245,12 @@ ChannelAccessManager::SetupPhyListener(Ptr<WifiPhy> phy)
|
||||
}
|
||||
m_phy = phy; // this is the new active PHY
|
||||
InitLastBusyStructs();
|
||||
if (phy->IsStateSwitching())
|
||||
{
|
||||
auto duration = phy->GetDelayUntilIdle();
|
||||
NS_LOG_DEBUG("switching start for " << duration);
|
||||
m_lastSwitchingEnd = Simulator::Now() + duration;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -277,6 +283,17 @@ ChannelAccessManager::DeactivatePhyListener(Ptr<WifiPhy> phy)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy,
|
||||
const WifiPhyOperatingChannel& channel,
|
||||
uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << phy << channel << linkId);
|
||||
NS_ASSERT_MSG(m_switchingEmlsrLinks.count(phy) == 0,
|
||||
"The given PHY is already expected to switch channel");
|
||||
m_switchingEmlsrLinks.emplace(phy, EmlsrLinkSwitchInfo{channel, linkId});
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::SetLinkId(uint8_t linkId)
|
||||
{
|
||||
@@ -845,13 +862,40 @@ ChannelAccessManager::NotifyCcaBusyStartNow(Time duration,
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::NotifySwitchingStartNow(Time duration)
|
||||
ChannelAccessManager::NotifySwitchingStartNow(PhyListener* phyListener, Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << duration);
|
||||
NS_LOG_FUNCTION(this << phyListener << duration);
|
||||
|
||||
Time now = Simulator::Now();
|
||||
NS_ASSERT(m_lastTxEnd <= now);
|
||||
NS_ASSERT(m_lastSwitchingEnd <= now);
|
||||
|
||||
if (phyListener) // to make tests happy
|
||||
{
|
||||
// check if the PHY switched channel to operate on another EMLSR link
|
||||
decltype(m_switchingEmlsrLinks)::const_iterator emlsrInfoIt;
|
||||
|
||||
for (const auto& [phyRef, listener] : m_phyListeners)
|
||||
{
|
||||
Ptr<WifiPhy> phy = phyRef;
|
||||
if (listener.get() == phyListener &&
|
||||
(emlsrInfoIt = m_switchingEmlsrLinks.find(phy)) != m_switchingEmlsrLinks.cend() &&
|
||||
phy->GetOperatingChannel() == emlsrInfoIt->second.channel)
|
||||
{
|
||||
// the PHY associated with the given PHY listener switched channel to
|
||||
// operate on another EMLSR link as expected. We don't need this listener
|
||||
// anymore. The MAC will connect a new listener to the ChannelAccessManager
|
||||
// instance associated with the link the PHY is now operating on
|
||||
RemovePhyListener(phy);
|
||||
auto ehtFem = DynamicCast<EhtFrameExchangeManager>(m_feManager);
|
||||
NS_ASSERT(ehtFem);
|
||||
ehtFem->NotifySwitchingEmlsrLink(phy, emlsrInfoIt->second.linkId, duration);
|
||||
m_switchingEmlsrLinks.erase(emlsrInfoIt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResetState();
|
||||
|
||||
// Notify the FEM, which will in turn notify the MAC
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define CHANNEL_ACCESS_MANAGER_H
|
||||
|
||||
#include "wifi-phy-common.h"
|
||||
#include "wifi-phy-operating-channel.h"
|
||||
|
||||
#include "ns3/event-id.h"
|
||||
#include "ns3/nstime.h"
|
||||
@@ -206,13 +207,14 @@ class ChannelAccessManager : public Object
|
||||
WifiChannelListType channelType,
|
||||
const std::vector<Time>& per20MhzDurations);
|
||||
/**
|
||||
* \param phyListener the PHY listener that sent this notification
|
||||
* \param duration expected duration of channel switching period
|
||||
*
|
||||
* Notify the Txop that a channel switching period has just started.
|
||||
* During switching state, new packets can be enqueued in Txop/QosTxop
|
||||
* but they won't access to the medium until the end of the channel switching.
|
||||
*/
|
||||
void NotifySwitchingStartNow(Time duration);
|
||||
void NotifySwitchingStartNow(PhyListener* phyListener, Time duration);
|
||||
/**
|
||||
* Notify the Txop that the device has been put in sleep mode.
|
||||
*/
|
||||
@@ -276,6 +278,19 @@ class ChannelAccessManager : public Object
|
||||
*/
|
||||
void ResetState();
|
||||
|
||||
/**
|
||||
* Notify that the given PHY is about to switch to the given operating channel, which is
|
||||
* used by the given link. This notification is sent by the EMLSR Manager when a PHY object
|
||||
* switches operating channel to operate on another link.
|
||||
*
|
||||
* \param phy the PHY object that is going to switch channel
|
||||
* \param channel the new operating channel of the given PHY
|
||||
* \param linkId the ID of the link on which the given PHY is going to operate
|
||||
*/
|
||||
void NotifySwitchingEmlsrLink(Ptr<WifiPhy> phy,
|
||||
const WifiPhyOperatingChannel& channel,
|
||||
uint8_t linkId);
|
||||
|
||||
protected:
|
||||
void DoInitialize() override;
|
||||
void DoDispose() override;
|
||||
@@ -390,6 +405,16 @@ class ChannelAccessManager : public Object
|
||||
Time m_eifsNoDifs; //!< EIFS no DIFS time
|
||||
EventId m_accessTimeout; //!< the access timeout ID
|
||||
|
||||
/// Information associated with each PHY that is going to operate on another EMLSR link
|
||||
struct EmlsrLinkSwitchInfo
|
||||
{
|
||||
WifiPhyOperatingChannel channel; //!< new operating channel
|
||||
uint8_t linkId; //!< ID of the EMLSR link on which the PHY is going to operate
|
||||
};
|
||||
|
||||
/// Store information about the PHY objects that are going to operate on another EMLSR link
|
||||
std::unordered_map<Ptr<WifiPhy>, EmlsrLinkSwitchInfo> m_switchingEmlsrLinks;
|
||||
|
||||
/// Maps each PHY listener to the associated PHY
|
||||
using PhyListenerMap = std::unordered_map<Ptr<WifiPhy>, std::unique_ptr<PhyListener>>;
|
||||
|
||||
|
||||
@@ -836,6 +836,7 @@ ChannelAccessManagerTest<TxopType>::AddSwitchingEvt(uint64_t at, uint64_t durati
|
||||
Simulator::Schedule(MicroSeconds(at) - Now(),
|
||||
&ChannelAccessManager::NotifySwitchingStartNow,
|
||||
m_ChannelAccessManager,
|
||||
nullptr,
|
||||
MicroSeconds(duration));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user