wifi: ChannelAccessManager attributes can be set through WifiMacHelper

This commit is contained in:
Stefano Avallone
2024-04-29 10:38:52 +02:00
committed by Stefano Avallone
parent 91c6b4b782
commit f004f0109f
8 changed files with 80 additions and 17 deletions

View File

@@ -143,6 +143,7 @@ MeshHelper::CreateInterface(const WifiPhyHelper& phyHelper,
mac->SetAddress(Mac48Address::Allocate());
device->SetMac(mac);
mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
mac->ConfigureStandard(m_standard);
Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
if (fem)

View File

@@ -33,6 +33,7 @@
#include "ns3/wifi-protection-manager.h"
#include <sstream>
#include <vector>
namespace ns3
{
@@ -48,6 +49,7 @@ WifiMacHelper::WifiMacHelper()
auto [it, inserted] = m_edca.try_emplace(aci);
it->second.SetTypeId("ns3::QosTxop");
}
m_channelAccessManager.SetTypeId("ns3::ChannelAccessManager");
m_assocManager.SetTypeId("ns3::WifiDefaultAssocManager");
m_queueScheduler.SetTypeId("ns3::FcfsWifiQueueScheduler");
m_protectionManager.SetTypeId("ns3::WifiDefaultProtectionManager");
@@ -88,19 +90,29 @@ WifiMacHelper::Create(Ptr<WifiNetDevice> device, WifiStandard standard) const
macObjectFactory.Set(s, PointerValue(edca.Create<QosTxop>()));
}
// WaveNetDevice (through ns-3.38) stores PHY entities in a different member than WifiNetDevice,
// hence GetNPhys() would return 0
auto nLinks = std::max<uint8_t>(device->GetNPhys(), 1);
// create Channel Access Managers
std::vector<Ptr<ChannelAccessManager>> caManagers;
for (uint8_t linkId = 0; linkId < nLinks; ++linkId)
{
caManagers.emplace_back(m_channelAccessManager.Create<ChannelAccessManager>());
}
Ptr<WifiMac> mac = macObjectFactory.Create<WifiMac>();
mac->SetDevice(device);
mac->SetAddress(Mac48Address::Allocate());
device->SetMac(mac);
mac->SetChannelAccessManagers(caManagers);
mac->ConfigureStandard(standard);
Ptr<WifiMacQueueScheduler> queueScheduler = m_queueScheduler.Create<WifiMacQueueScheduler>();
mac->SetMacQueueScheduler(queueScheduler);
// WaveNetDevice (through ns-3.38) stores PHY entities in a different member than WifiNetDevice,
// hence GetNPhys() would return 0. We have to attach a protection manager and an ack manager to
// the unique instance of frame exchange manager anyway
for (uint8_t linkId = 0; linkId < std::max<uint8_t>(device->GetNPhys(), 1); ++linkId)
// attach a protection manager and an ack manager to every instance of frame exchange manager
for (uint8_t linkId = 0; linkId < nLinks; ++linkId)
{
auto fem = mac->GetFrameExchangeManager(linkId);

View File

@@ -90,6 +90,15 @@ class WifiMacHelper
template <typename... Args>
void SetEdca(AcIndex aci, Args&&... args);
/**
* Helper function used to set the Channel Access Manager object.
*
* \tparam Args \deduced Template type parameter pack for the sequence of name-value pairs.
* \param args A sequence of name-value pairs of the attributes to set.
*/
template <typename... Args>
void SetChannelAccessManager(Args&&... args);
/**
* Helper function used to set the Association Manager.
*
@@ -164,12 +173,13 @@ class WifiMacHelper
ObjectFactory m_mac; ///< MAC object factory
ObjectFactory m_dcf; ///< Txop (DCF) object factory
std::map<AcIndex, ObjectFactory, std::greater<>> m_edca; ///< QosTxop (EDCA) object factories
ObjectFactory m_assocManager; ///< Association Manager
ObjectFactory m_queueScheduler; ///< MAC queue scheduler
ObjectFactory m_protectionManager; ///< Factory to create a protection manager
ObjectFactory m_ackManager; ///< Factory to create an acknowledgment manager
ObjectFactory m_muScheduler; ///< Multi-user Scheduler object factory
ObjectFactory m_emlsrManager; ///< EMLSR Manager object factory
ObjectFactory m_channelAccessManager; ///< Channel Access Manager object factory
ObjectFactory m_assocManager; ///< Association Manager
ObjectFactory m_queueScheduler; ///< MAC queue scheduler
ObjectFactory m_protectionManager; ///< Factory to create a protection manager
ObjectFactory m_ackManager; ///< Factory to create an acknowledgment manager
ObjectFactory m_muScheduler; ///< Multi-user Scheduler object factory
ObjectFactory m_emlsrManager; ///< EMLSR Manager object factory
};
} // namespace ns3
@@ -205,6 +215,13 @@ WifiMacHelper::SetEdca(AcIndex aci, Args&&... args)
it->second.Set(args...);
}
template <typename... Args>
void
WifiMacHelper::SetChannelAccessManager(Args&&... args)
{
m_channelAccessManager.Set(args...);
}
template <typename... Args>
void
WifiMacHelper::SetAssocManager(std::string type, Args&&... args)

View File

@@ -867,12 +867,9 @@ WifiMac::ConfigureStandard(WifiStandard standard)
"[LinkID " << +id
<< "] PHY must have been set and an operating channel must have been set");
// do not create a ChannelAccessManager and a FrameExchangeManager if they
// already exist (this function may be called after ResetWifiPhys)
if (!link->channelAccessManager)
{
link->channelAccessManager = CreateObject<ChannelAccessManager>();
}
NS_ABORT_MSG_IF(!link->channelAccessManager,
"[LinkID " << +id << "] A channel access manager must have been set");
link->channelAccessManager->SetupPhyListener(link->phy);
if (!link->feManager)
@@ -882,7 +879,6 @@ WifiMac::ConfigureStandard(WifiStandard standard)
link->feManager->SetWifiPhy(link->phy);
link->feManager->SetWifiMac(this);
link->feManager->SetLinkId(id);
link->channelAccessManager->SetLinkId(id);
link->channelAccessManager->SetupFrameExchangeManager(link->feManager);
if (m_txop)
@@ -991,6 +987,26 @@ WifiMac::GetFrameExchangeManager(uint8_t linkId) const
return GetLink(linkId).feManager;
}
void
WifiMac::SetChannelAccessManagers(const std::vector<Ptr<ChannelAccessManager>>& caManagers)
{
NS_LOG_FUNCTION(this);
if (!CreateLinksIfNeeded(caManagers.size()))
{
NS_ABORT_MSG_IF(caManagers.size() != m_links.size(),
"The number of provided Channel Access Manager objects ("
<< caManagers.size() << ") must match the number of existing links ("
<< m_links.size() << ")");
}
for (auto managerIt = caManagers.cbegin(); auto& [id, link] : m_links)
{
link->channelAccessManager = *managerIt++;
link->channelAccessManager->SetLinkId(id);
}
}
Ptr<ChannelAccessManager>
WifiMac::GetChannelAccessManager(uint8_t linkId) const
{

View File

@@ -151,6 +151,11 @@ class WifiMac : public Object
*/
Ptr<ChannelAccessManager> GetChannelAccessManager(uint8_t linkId = SINGLE_LINK_OP_ID) const;
/**
* \param caManagers the channel access managers attached to this MAC.
*/
void SetChannelAccessManagers(const std::vector<Ptr<ChannelAccessManager>>& caManagers);
/**
* Get the number of links (can be greater than 1 for 11be devices only).
*

View File

@@ -123,6 +123,7 @@ PowerRateAdaptationTest::ConfigureNode()
mac->SetDevice(dev);
mac->SetAddress(Mac48Address::Allocate());
dev->SetMac(mac);
mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
mac->ConfigureStandard(WIFI_STANDARD_80211a);
mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();

View File

@@ -234,6 +234,12 @@ AmpduAggregationTest::DoSetup()
m_mac->SetAddress(Mac48Address("00:00:00:00:00:01"));
m_device->SetMac(m_mac);
m_mac->SetWifiPhys(m_phys);
std::vector<Ptr<ChannelAccessManager>> caManagers;
for (uint8_t i = 0; i < m_params.nLinks; i++)
{
caManagers.emplace_back(CreateObject<ChannelAccessManager>());
}
m_mac->SetChannelAccessManagers(caManagers);
m_mac->ConfigureStandard(m_params.standard);
for (uint8_t i = 0; i < m_params.nLinks; i++)
{

View File

@@ -165,6 +165,7 @@ WifiTest::CreateOne(Vector pos, Ptr<YansWifiChannel> channel)
mac->SetDevice(dev);
mac->SetAddress(Mac48Address::Allocate());
dev->SetMac(mac);
mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
mac->ConfigureStandard(WIFI_STANDARD_80211a);
if (mac->GetTypeOfStation() == STA)
{
@@ -360,6 +361,7 @@ InterferenceHelperSequenceTest::CreateOne(Vector pos, Ptr<YansWifiChannel> chann
mac->SetDevice(dev);
mac->SetAddress(Mac48Address::Allocate());
dev->SetMac(mac);
mac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
mac->ConfigureStandard(WIFI_STANDARD_80211a);
mac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager();
@@ -580,6 +582,7 @@ DcfImmediateAccessBroadcastTestCase::DoRun()
txMac->SetDevice(txDev);
txMac->SetAddress(Mac48Address::Allocate());
txDev->SetMac(txMac);
txMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
txMac->ConfigureStandard(WIFI_STANDARD_80211a);
txMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
auto fem = txMac->GetFrameExchangeManager();
@@ -1865,6 +1868,7 @@ Bug2831TestCase::DoRun()
apMac->SetDevice(apDev);
apMac->SetAddress(Mac48Address::Allocate());
apDev->SetMac(apMac);
apMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
apMac->ConfigureStandard(WIFI_STANDARD_80211ax);
apMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());
Ptr<FrameExchangeManager> fem = apMac->GetFrameExchangeManager();
@@ -1909,6 +1913,7 @@ Bug2831TestCase::DoRun()
staDev->SetMac(staMac);
staMac->SetDevice(staDev);
staMac->SetAddress(Mac48Address::Allocate());
staMac->SetChannelAccessManagers({CreateObject<ChannelAccessManager>()});
staMac->ConfigureStandard(WIFI_STANDARD_80211ax);
StaticCast<StaWifiMac>(staMac)->SetAssocManager(CreateObject<WifiDefaultAssocManager>());
staMac->SetMacQueueScheduler(CreateObject<FcfsWifiQueueScheduler>());