wifi: WifiMac can create multiple FrameExchangeManagers and ChannelAccessManagers
This commit is contained in:
@@ -205,7 +205,7 @@ MeshWifiInterfaceMac::SwitchFrequencyChannel (uint16_t new_id)
|
||||
*/
|
||||
GetWifiPhy ()->SetOperatingChannel (WifiPhy::ChannelTuple {new_id, 0, GetWifiPhy ()->GetPhyBand (), 0});
|
||||
// Don't know NAV on new channel
|
||||
m_channelAccessManager->NotifyNavResetNow (Seconds (0));
|
||||
GetLink (SINGLE_LINK_OP_ID).channelAccessManager->NotifyNavResetNow (Seconds (0));
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward frame down
|
||||
|
||||
@@ -369,7 +369,7 @@ DefaultChannelScheduler::SwitchToNextChannel (uint32_t curChannelNumber, uint32_
|
||||
// first make current MAC entity in sleep mode.
|
||||
curMacEntity->Suspend ();
|
||||
// second unattached current MAC entity from single PHY device
|
||||
curMacEntity->ResetWifiPhy ();
|
||||
curMacEntity->ResetWifiPhys ();
|
||||
// third switch PHY device from current channel to next channel;
|
||||
m_phy->SetOperatingChannel (WifiPhy::ChannelTuple {nextChannelNumber, 0, WIFI_PHY_BAND_5GHZ, 0});
|
||||
// four attach next MAC entity to single PHY device
|
||||
|
||||
@@ -379,23 +379,24 @@ OcbWifiMac::ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum
|
||||
break;
|
||||
}
|
||||
|
||||
dcf->SetChannelAccessManager (m_channelAccessManager);
|
||||
dcf->SetChannelAccessManager (GetLink (SINGLE_LINK_OP_ID).channelAccessManager);
|
||||
}
|
||||
|
||||
void
|
||||
OcbWifiMac::SetWifiPhy (Ptr<WifiPhy> phy)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << phy);
|
||||
WifiMac::SetWifiPhy (phy);
|
||||
WifiMac::SetWifiPhys ({phy});
|
||||
NS_ABORT_MSG_IF (!phy->GetOperatingChannel ().IsSet (),
|
||||
"PHY operating channel must have been set");
|
||||
if (m_channelAccessManager != nullptr)
|
||||
auto& link = GetLink (SINGLE_LINK_OP_ID);
|
||||
if (link.channelAccessManager != nullptr)
|
||||
{
|
||||
m_channelAccessManager->SetupPhyListener (phy);
|
||||
link.channelAccessManager->SetupPhyListener (phy);
|
||||
}
|
||||
if (m_feManager != nullptr)
|
||||
if (link.feManager != nullptr)
|
||||
{
|
||||
m_feManager->SetWifiPhy (phy);
|
||||
link.feManager->SetWifiPhy (phy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,8 +406,15 @@ OcbWifiMac::ConfigureStandard (enum WifiStandard standard)
|
||||
NS_LOG_FUNCTION (this << standard);
|
||||
NS_ASSERT (standard == WIFI_STANDARD_80211p);
|
||||
|
||||
if (GetNLinks () == 0)
|
||||
{
|
||||
WifiMac::SetWifiPhys ({nullptr}); // for the purpose of adding a link
|
||||
}
|
||||
|
||||
auto& link = GetLink (SINGLE_LINK_OP_ID);
|
||||
|
||||
// Setup ChannelAccessManager
|
||||
m_channelAccessManager = CreateObject<ChannelAccessManager> ();
|
||||
link.channelAccessManager = CreateObject<ChannelAccessManager> ();
|
||||
|
||||
uint32_t cwmin = 15;
|
||||
uint32_t cwmax = 1023;
|
||||
@@ -429,17 +437,18 @@ OcbWifiMac::ConfigureStandard (enum WifiStandard standard)
|
||||
}
|
||||
|
||||
// Setup FrameExchangeManager
|
||||
m_feManager = CreateObject<WaveFrameExchangeManager> ();
|
||||
m_feManager->SetWifiMac (this);
|
||||
m_feManager->SetMacTxMiddle (m_txMiddle);
|
||||
m_feManager->SetMacRxMiddle (m_rxMiddle);
|
||||
m_feManager->SetAddress (GetAddress ());
|
||||
m_channelAccessManager->SetupFrameExchangeManager (m_feManager);
|
||||
auto feManager = CreateObject<WaveFrameExchangeManager> ();
|
||||
feManager->SetWifiMac (this);
|
||||
feManager->SetMacTxMiddle (m_txMiddle);
|
||||
feManager->SetMacRxMiddle (m_rxMiddle);
|
||||
feManager->SetAddress (GetAddress ());
|
||||
link.channelAccessManager->SetupFrameExchangeManager (feManager);
|
||||
if (auto phy = GetWifiPhy (); phy != nullptr)
|
||||
{
|
||||
m_feManager->SetWifiPhy (phy);
|
||||
m_channelAccessManager->SetupPhyListener (phy);
|
||||
feManager->SetWifiPhy (phy);
|
||||
link.channelAccessManager->SetupPhyListener (phy);
|
||||
}
|
||||
link.feManager = feManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -447,8 +456,8 @@ void
|
||||
OcbWifiMac::Suspend (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_channelAccessManager->NotifySleepNow ();
|
||||
m_feManager->NotifySleepNow ();
|
||||
GetLink (SINGLE_LINK_OP_ID).channelAccessManager->NotifySleepNow ();
|
||||
GetLink (SINGLE_LINK_OP_ID).feManager->NotifySleepNow ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -456,14 +465,14 @@ OcbWifiMac::Resume (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
// wake-up operation is not required in m_low object
|
||||
m_channelAccessManager->NotifyWakeupNow ();
|
||||
GetLink (SINGLE_LINK_OP_ID).channelAccessManager->NotifyWakeupNow ();
|
||||
}
|
||||
|
||||
void
|
||||
OcbWifiMac::MakeVirtualBusy (Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration);
|
||||
m_channelAccessManager->NotifyCcaBusyStartNow (duration, WIFI_CHANLIST_PRIMARY, {});
|
||||
GetLink (SINGLE_LINK_OP_ID).channelAccessManager->NotifyCcaBusyStartNow (duration, WIFI_CHANLIST_PRIMARY, {});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -481,8 +490,8 @@ OcbWifiMac::Reset (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
// The switching event is used to notify MAC entity reset its operation.
|
||||
m_channelAccessManager->NotifySwitchingStartNow (Time (0));
|
||||
m_feManager->NotifySwitchingStartNow (Time (0));
|
||||
GetLink (SINGLE_LINK_OP_ID).channelAccessManager->NotifySwitchingStartNow (Time (0));
|
||||
GetLink (SINGLE_LINK_OP_ID).feManager->NotifySwitchingStartNow (Time (0));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -490,7 +499,7 @@ OcbWifiMac::EnableForWave (Ptr<WaveNetDevice> device)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << device);
|
||||
// To extend current OcbWifiMac for WAVE 1609.4, we shall use WaveFrameExchangeManager
|
||||
StaticCast<WaveFrameExchangeManager> (m_feManager)->SetWaveNetDevice (device);
|
||||
StaticCast<WaveFrameExchangeManager> (GetLink (SINGLE_LINK_OP_ID).feManager)->SetWaveNetDevice (device);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -174,10 +174,15 @@ public:
|
||||
* Reset current MAC entity and flush its internal queues.
|
||||
*/
|
||||
void Reset (void);
|
||||
/**
|
||||
* Set the PHY.
|
||||
*
|
||||
* \param phy the PHY object
|
||||
*/
|
||||
void SetWifiPhy (Ptr<WifiPhy> phy);
|
||||
|
||||
// Inherited from base class
|
||||
virtual void ConfigureStandard (enum WifiStandard standard);
|
||||
virtual void SetWifiPhy (Ptr<WifiPhy> phy);
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
private:
|
||||
|
||||
@@ -148,7 +148,7 @@ ApWifiMac::ConfigureStandard (WifiStandard standard)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << standard);
|
||||
WifiMac::ConfigureStandard (standard);
|
||||
m_beaconTxop->SetChannelAccessManager (m_channelAccessManager);
|
||||
m_beaconTxop->SetChannelAccessManager (GetLink (SINGLE_LINK_OP_ID).channelAccessManager);
|
||||
}
|
||||
|
||||
Ptr<WifiMacQueue>
|
||||
|
||||
@@ -167,10 +167,14 @@ FrameExchangeManager::SetWifiPhy (Ptr<WifiPhy> phy)
|
||||
void
|
||||
FrameExchangeManager::ResetPhy (void)
|
||||
{
|
||||
m_phy->TraceDisconnectWithoutContext ("PhyRxPayloadBegin",
|
||||
MakeCallback (&FrameExchangeManager::RxStartIndication, this));
|
||||
m_phy->SetReceiveOkCallback (MakeNullCallback<void, Ptr<WifiPsdu>, RxSignalInfo, WifiTxVector, std::vector<bool>> ());
|
||||
m_phy = 0;
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_phy != nullptr)
|
||||
{
|
||||
m_phy->TraceDisconnectWithoutContext ("PhyRxPayloadBegin",
|
||||
MakeCallback (&FrameExchangeManager::RxStartIndication, this));
|
||||
m_phy->SetReceiveOkCallback (MakeNullCallback<void, Ptr<WifiPsdu>, RxSignalInfo, WifiTxVector, std::vector<bool>> ());
|
||||
m_phy = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -140,11 +140,14 @@ StaWifiMac::GetActiveProbing (void) const
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::SetWifiPhy (const Ptr<WifiPhy> phy)
|
||||
StaWifiMac::SetWifiPhys (const std::vector<Ptr<WifiPhy>>& phys)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << phy);
|
||||
WifiMac::SetWifiPhy (phy);
|
||||
GetWifiPhy ()->SetCapabilitiesChangedCallback (MakeCallback (&StaWifiMac::PhyCapabilitiesChanged, this));
|
||||
NS_LOG_FUNCTION (this);
|
||||
WifiMac::SetWifiPhys (phys);
|
||||
for (auto& phy : phys)
|
||||
{
|
||||
phy->SetCapabilitiesChangedCallback (MakeCallback (&StaWifiMac::PhyCapabilitiesChanged, this));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -133,9 +133,9 @@ public:
|
||||
bool CanForwardPacketsTo (Mac48Address to) const override;
|
||||
|
||||
/**
|
||||
* \param phy the physical layer attached to this MAC.
|
||||
* \param phys the physical layers attached to this MAC.
|
||||
*/
|
||||
void SetWifiPhy (const Ptr<WifiPhy> phy) override;
|
||||
void SetWifiPhys (const std::vector<Ptr<WifiPhy>>& phys) override;
|
||||
|
||||
/**
|
||||
* Return whether we are associated with an AP.
|
||||
|
||||
@@ -342,12 +342,7 @@ WifiMac::DoDispose ()
|
||||
|
||||
m_rxMiddle = 0;
|
||||
m_txMiddle = 0;
|
||||
|
||||
if (m_channelAccessManager != nullptr)
|
||||
{
|
||||
m_channelAccessManager->Dispose ();
|
||||
}
|
||||
m_channelAccessManager = 0;
|
||||
m_links.clear ();
|
||||
|
||||
if (m_txop != nullptr)
|
||||
{
|
||||
@@ -361,18 +356,23 @@ WifiMac::DoDispose ()
|
||||
it->second = 0;
|
||||
}
|
||||
|
||||
if (m_feManager != 0)
|
||||
{
|
||||
m_feManager->Dispose ();
|
||||
}
|
||||
m_feManager = 0;
|
||||
|
||||
m_stationManager = 0;
|
||||
m_phy = 0;
|
||||
|
||||
m_device = 0;
|
||||
}
|
||||
|
||||
WifiMac::LinkEntity::~LinkEntity ()
|
||||
{
|
||||
// WifiMac owns pointers to ChannelAccessManager and FrameExchangeManager
|
||||
if (channelAccessManager != nullptr)
|
||||
{
|
||||
channelAccessManager->Dispose ();
|
||||
}
|
||||
if (feManager != nullptr)
|
||||
{
|
||||
feManager->Dispose ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::SetTypeOfStation (TypeOfStation type)
|
||||
{
|
||||
@@ -429,9 +429,9 @@ WifiMac::SetBssid (Mac48Address bssid)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << bssid);
|
||||
m_bssid = bssid;
|
||||
if (m_feManager)
|
||||
for (auto& link : m_links)
|
||||
{
|
||||
m_feManager->SetBssid (bssid);
|
||||
link->feManager->SetBssid (bssid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,8 +444,10 @@ WifiMac::GetBssid (void) const
|
||||
void
|
||||
WifiMac::SetPromisc (void)
|
||||
{
|
||||
NS_ASSERT (m_feManager != 0);
|
||||
m_feManager->SetPromisc ();
|
||||
for (auto& link : m_links)
|
||||
{
|
||||
link->feManager->SetPromisc ();
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Txop>
|
||||
@@ -518,7 +520,7 @@ WifiMac::NotifyChannelSwitching (void)
|
||||
// SetupPhy not only resets the remote station manager, but also sets the
|
||||
// default TX mode and MCS, which is required when switching to a channel
|
||||
// in a different band
|
||||
m_stationManager->SetupPhy (m_phy);
|
||||
m_stationManager->SetupPhy (GetLink (SINGLE_LINK_OP_ID).phy);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -656,39 +658,54 @@ WifiMac::ConfigureStandard (WifiStandard standard)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << standard);
|
||||
NS_ABORT_IF (standard >= WIFI_STANDARD_80211n && !m_qosSupported);
|
||||
NS_ABORT_MSG_IF (m_phy == nullptr || !m_phy->GetOperatingChannel ().IsSet (),
|
||||
"PHY must have been set and an operating channel must have been set");
|
||||
NS_ABORT_MSG_IF (m_links.empty (), "No PHY configured yet");
|
||||
|
||||
m_channelAccessManager = CreateObject<ChannelAccessManager> ();
|
||||
m_channelAccessManager->SetupPhyListener (m_phy);
|
||||
for (auto& link : m_links)
|
||||
{
|
||||
NS_ABORT_MSG_IF (link->phy == nullptr || !link->phy->GetOperatingChannel ().IsSet (),
|
||||
"[LinkID " << link->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 == nullptr)
|
||||
{
|
||||
link->channelAccessManager = CreateObject<ChannelAccessManager> ();
|
||||
}
|
||||
link->channelAccessManager->SetupPhyListener (link->phy);
|
||||
|
||||
if (link->feManager == nullptr)
|
||||
{
|
||||
link->feManager = SetupFrameExchangeManager (standard);
|
||||
}
|
||||
link->feManager->SetWifiPhy (link->phy);
|
||||
link->feManager->SetWifiMac (this);
|
||||
link->channelAccessManager->SetupFrameExchangeManager (link->feManager);
|
||||
}
|
||||
|
||||
ConfigurePhyDependentParameters ();
|
||||
|
||||
SetupFrameExchangeManager (standard);
|
||||
m_feManager->SetWifiPhy (m_phy);
|
||||
m_channelAccessManager->SetupFrameExchangeManager (m_feManager);
|
||||
|
||||
if (m_txop != nullptr)
|
||||
{
|
||||
m_txop->SetChannelAccessManager (m_channelAccessManager);
|
||||
m_txop->SetChannelAccessManager (m_links[SINGLE_LINK_OP_ID]->channelAccessManager);
|
||||
}
|
||||
for (auto it = m_edca.begin (); it!= m_edca.end (); ++it)
|
||||
{
|
||||
it->second->SetChannelAccessManager (m_channelAccessManager);
|
||||
it->second->SetChannelAccessManager (m_links[SINGLE_LINK_OP_ID]->channelAccessManager);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::ConfigurePhyDependentParameters (void)
|
||||
{
|
||||
WifiPhyBand band = m_phy->GetPhyBand ();
|
||||
auto& link = GetLink (SINGLE_LINK_OP_ID);
|
||||
NS_ASSERT (link.phy != nullptr);
|
||||
WifiPhyBand band = link.phy->GetPhyBand ();
|
||||
NS_LOG_FUNCTION (this << band);
|
||||
|
||||
uint32_t cwmin = 0;
|
||||
uint32_t cwmax = 0;
|
||||
|
||||
NS_ASSERT (m_phy != 0);
|
||||
WifiStandard standard = m_phy->GetStandard ();
|
||||
WifiStandard standard = link.phy->GetStandard ();
|
||||
|
||||
if (standard == WIFI_STANDARD_80211b)
|
||||
{
|
||||
@@ -710,60 +727,61 @@ WifiMac::ConfigurePhyDependentParameters (void)
|
||||
ConfigureContentionWindow (cwmin, cwmax);
|
||||
}
|
||||
|
||||
void
|
||||
Ptr<FrameExchangeManager>
|
||||
WifiMac::SetupFrameExchangeManager (WifiStandard standard)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << standard);
|
||||
NS_ABORT_MSG_IF (standard == WIFI_STANDARD_UNSPECIFIED, "Wifi standard not set");
|
||||
Ptr<FrameExchangeManager> feManager;
|
||||
|
||||
if (standard >= WIFI_STANDARD_80211ax)
|
||||
{
|
||||
m_feManager = CreateObject<HeFrameExchangeManager> ();
|
||||
feManager = CreateObject<HeFrameExchangeManager> ();
|
||||
}
|
||||
else if (standard >= WIFI_STANDARD_80211ac)
|
||||
{
|
||||
m_feManager = CreateObject<VhtFrameExchangeManager> ();
|
||||
feManager = CreateObject<VhtFrameExchangeManager> ();
|
||||
}
|
||||
else if (standard >= WIFI_STANDARD_80211n)
|
||||
{
|
||||
m_feManager = CreateObject<HtFrameExchangeManager> ();
|
||||
feManager = CreateObject<HtFrameExchangeManager> ();
|
||||
}
|
||||
else if (m_qosSupported)
|
||||
{
|
||||
m_feManager = CreateObject<QosFrameExchangeManager> ();
|
||||
feManager = CreateObject<QosFrameExchangeManager> ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_feManager = CreateObject<FrameExchangeManager> ();
|
||||
feManager = CreateObject<FrameExchangeManager> ();
|
||||
}
|
||||
|
||||
m_feManager->SetWifiMac (this);
|
||||
m_feManager->SetMacTxMiddle (m_txMiddle);
|
||||
m_feManager->SetMacRxMiddle (m_rxMiddle);
|
||||
m_feManager->SetAddress (GetAddress ());
|
||||
m_feManager->SetBssid (GetBssid ());
|
||||
m_feManager->GetWifiTxTimer ().SetMpduResponseTimeoutCallback (MakeCallback (&MpduResponseTimeoutTracedCallback::operator(),
|
||||
&m_mpduResponseTimeoutCallback));
|
||||
m_feManager->GetWifiTxTimer ().SetPsduResponseTimeoutCallback (MakeCallback (&PsduResponseTimeoutTracedCallback::operator(),
|
||||
&m_psduResponseTimeoutCallback));
|
||||
m_feManager->GetWifiTxTimer ().SetPsduMapResponseTimeoutCallback (MakeCallback (&PsduMapResponseTimeoutTracedCallback::operator(),
|
||||
&m_psduMapResponseTimeoutCallback));
|
||||
m_feManager->SetDroppedMpduCallback (MakeCallback (&DroppedMpduTracedCallback::operator(),
|
||||
&m_droppedMpduCallback));
|
||||
m_feManager->SetAckedMpduCallback (MakeCallback (&MpduTracedCallback::operator(),
|
||||
&m_ackedMpduCallback));
|
||||
feManager->SetMacTxMiddle (m_txMiddle);
|
||||
feManager->SetMacRxMiddle (m_rxMiddle);
|
||||
feManager->SetAddress (GetAddress ());
|
||||
feManager->SetBssid (GetBssid ());
|
||||
feManager->GetWifiTxTimer ().SetMpduResponseTimeoutCallback (MakeCallback (&MpduResponseTimeoutTracedCallback::operator(),
|
||||
&m_mpduResponseTimeoutCallback));
|
||||
feManager->GetWifiTxTimer ().SetPsduResponseTimeoutCallback (MakeCallback (&PsduResponseTimeoutTracedCallback::operator(),
|
||||
&m_psduResponseTimeoutCallback));
|
||||
feManager->GetWifiTxTimer ().SetPsduMapResponseTimeoutCallback (MakeCallback (&PsduMapResponseTimeoutTracedCallback::operator(),
|
||||
&m_psduMapResponseTimeoutCallback));
|
||||
feManager->SetDroppedMpduCallback (MakeCallback (&DroppedMpduTracedCallback::operator(),
|
||||
&m_droppedMpduCallback));
|
||||
feManager->SetAckedMpduCallback (MakeCallback (&MpduTracedCallback::operator(),
|
||||
&m_ackedMpduCallback));
|
||||
return feManager;
|
||||
}
|
||||
|
||||
Ptr<FrameExchangeManager>
|
||||
WifiMac::GetFrameExchangeManager (void) const
|
||||
WifiMac::GetFrameExchangeManager (uint8_t linkId) const
|
||||
{
|
||||
return m_feManager;
|
||||
return GetLink (linkId).feManager;
|
||||
}
|
||||
|
||||
Ptr<ChannelAccessManager>
|
||||
WifiMac::GetChannelAccessManager (void) const
|
||||
WifiMac::GetChannelAccessManager (uint8_t linkId) const
|
||||
{
|
||||
return m_channelAccessManager;
|
||||
return GetLink (linkId).channelAccessManager;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -779,28 +797,74 @@ WifiMac::GetWifiRemoteStationManager () const
|
||||
return m_stationManager;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::SetWifiPhy (const Ptr<WifiPhy> phy)
|
||||
std::unique_ptr<WifiMac::LinkEntity>
|
||||
WifiMac::CreateLinkEntity (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << phy);
|
||||
m_phy = phy;
|
||||
return std::make_unique<LinkEntity> ();
|
||||
}
|
||||
|
||||
WifiMac::LinkEntity&
|
||||
WifiMac::GetLink (uint8_t linkId) const
|
||||
{
|
||||
NS_ASSERT (linkId < m_links.size ());
|
||||
NS_ASSERT (m_links.at (linkId)); // check that the pointer owns an object
|
||||
return *m_links.at (linkId);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
WifiMac::GetNLinks (void) const
|
||||
{
|
||||
return m_links.size ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::SetWifiPhys (const std::vector<Ptr<WifiPhy>>& phys)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
ResetWifiPhys ();
|
||||
|
||||
NS_ABORT_MSG_UNLESS (m_links.size () == 0 || m_links.size () == phys.size (),
|
||||
"If links have been already created, the number of provided "
|
||||
"PHY objects (" << phys.size () << ") must match the number "
|
||||
"of links (" << m_links.size () << ")");
|
||||
|
||||
for (std::size_t i = 0; i < phys.size (); i++)
|
||||
{
|
||||
// the link may already exist in case we are setting new PHY objects
|
||||
// (ResetWifiPhys just nullified the PHY(s) but left the links)
|
||||
if (i == m_links.size ())
|
||||
{
|
||||
m_links.push_back (CreateLinkEntity ());
|
||||
m_links.back ()->id = i;
|
||||
}
|
||||
NS_ABORT_IF (i != m_links[i]->id);
|
||||
m_links[i]->phy = phys[i];
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<WifiPhy>
|
||||
WifiMac::GetWifiPhy (void) const
|
||||
WifiMac::GetWifiPhy (uint8_t linkId) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_phy;
|
||||
NS_LOG_FUNCTION (this << +linkId);
|
||||
return GetLink (linkId).phy;
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::ResetWifiPhy (void)
|
||||
WifiMac::ResetWifiPhys (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (m_feManager != 0);
|
||||
m_feManager->ResetPhy ();
|
||||
m_channelAccessManager->RemovePhyListener (m_phy);
|
||||
m_phy = 0;
|
||||
for (auto& link : m_links)
|
||||
{
|
||||
if (link->feManager != nullptr)
|
||||
{
|
||||
link->feManager->ResetPhy ();
|
||||
}
|
||||
if (link->channelAccessManager != nullptr)
|
||||
{
|
||||
link->channelAccessManager->RemovePhyListener (link->phy);
|
||||
}
|
||||
link->phy = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -941,6 +1005,7 @@ WifiMac::Receive (Ptr<WifiMacQueueItem> mpdu)
|
||||
Ptr<Packet> packet = mpdu->GetPacket ()->Copy ();
|
||||
Mac48Address to = hdr->GetAddr1 ();
|
||||
Mac48Address from = hdr->GetAddr2 ();
|
||||
auto& link = GetLink (SINGLE_LINK_OP_ID);
|
||||
|
||||
//We don't know how to deal with any frame that is not addressed to
|
||||
//us (and odds are there is nothing sensible we could do anyway),
|
||||
@@ -976,8 +1041,8 @@ WifiMac::Receive (Ptr<WifiMacQueueItem> mpdu)
|
||||
//We've received an ADDBA Request. Our policy here is
|
||||
//to automatically accept it, so we get the ADDBA
|
||||
//Response on it's way immediately.
|
||||
NS_ASSERT (m_feManager != 0);
|
||||
Ptr<HtFrameExchangeManager> htFem = DynamicCast<HtFrameExchangeManager> (m_feManager);
|
||||
NS_ASSERT (link.feManager != nullptr);
|
||||
auto htFem = DynamicCast<HtFrameExchangeManager> (link.feManager);
|
||||
if (htFem != 0)
|
||||
{
|
||||
htFem->SendAddBaResponse (&reqHdr, from);
|
||||
@@ -997,7 +1062,7 @@ WifiMac::Receive (Ptr<WifiMacQueueItem> mpdu)
|
||||
//and act by locally establishing the agreement on
|
||||
//the appropriate queue.
|
||||
GetQosTxop (respHdr.GetTid ())->GotAddBaResponse (&respHdr, from);
|
||||
auto htFem = DynamicCast<HtFrameExchangeManager> (m_feManager);
|
||||
auto htFem = DynamicCast<HtFrameExchangeManager> (link.feManager);
|
||||
if (htFem != 0)
|
||||
{
|
||||
GetQosTxop (respHdr.GetTid ())->GetBaManager ()->SetBlockAckInactivityCallback (MakeCallback (&HtFrameExchangeManager::SendDelbaFrame, htFem));
|
||||
@@ -1016,8 +1081,8 @@ WifiMac::Receive (Ptr<WifiMacQueueItem> mpdu)
|
||||
//this means that an ingoing established
|
||||
//agreement exists in HtFrameExchangeManager and we need to
|
||||
//destroy it.
|
||||
NS_ASSERT (m_feManager != 0);
|
||||
Ptr<HtFrameExchangeManager> htFem = DynamicCast<HtFrameExchangeManager> (m_feManager);
|
||||
NS_ASSERT (link.feManager != nullptr);
|
||||
auto htFem = DynamicCast<HtFrameExchangeManager> (link.feManager);
|
||||
if (htFem != 0)
|
||||
{
|
||||
htFem->DestroyBlockAckAgreement (from, delBaHdr.GetTid ());
|
||||
@@ -1352,19 +1417,20 @@ WifiMac::GetHeCapabilities (void) const
|
||||
HeCapabilities capabilities;
|
||||
if (GetHeSupported ())
|
||||
{
|
||||
Ptr<WifiPhy> phy = GetLink (SINGLE_LINK_OP_ID).phy;
|
||||
Ptr<HtConfiguration> htConfiguration = GetHtConfiguration ();
|
||||
Ptr<HeConfiguration> heConfiguration = GetHeConfiguration ();
|
||||
capabilities.SetHeSupported (1);
|
||||
uint8_t channelWidthSet = 0;
|
||||
if ((m_phy->GetChannelWidth () >= 40) && (m_phy->GetPhyBand () == WIFI_PHY_BAND_2_4GHZ))
|
||||
if ((phy->GetChannelWidth () >= 40) && (phy->GetPhyBand () == WIFI_PHY_BAND_2_4GHZ))
|
||||
{
|
||||
channelWidthSet |= 0x01;
|
||||
}
|
||||
if ((m_phy->GetChannelWidth () >= 80) && ((m_phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (m_phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
|
||||
if ((phy->GetChannelWidth () >= 80) && ((phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
|
||||
{
|
||||
channelWidthSet |= 0x02;
|
||||
}
|
||||
if ((m_phy->GetChannelWidth () >= 160) && ((m_phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (m_phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
|
||||
if ((phy->GetChannelWidth () >= 160) && ((phy->GetPhyBand () == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand () == WIFI_PHY_BAND_6GHZ)))
|
||||
{
|
||||
channelWidthSet |= 0x04;
|
||||
}
|
||||
@@ -1386,7 +1452,7 @@ WifiMac::GetHeCapabilities (void) const
|
||||
capabilities.SetMaxAmpduLength (std::min (std::max (maxAmpduLength, 1048575u), 8388607u));
|
||||
|
||||
uint8_t maxMcs = 0;
|
||||
for (const auto & mcs : m_phy->GetMcsList (WIFI_MOD_CLASS_HE))
|
||||
for (const auto & mcs : phy->GetMcsList (WIFI_MOD_CLASS_HE))
|
||||
{
|
||||
if (mcs.GetMcsValue () > maxMcs)
|
||||
{
|
||||
@@ -1394,7 +1460,7 @@ WifiMac::GetHeCapabilities (void) const
|
||||
}
|
||||
}
|
||||
capabilities.SetHighestMcsSupported (maxMcs);
|
||||
capabilities.SetHighestNssSupported (m_phy->GetMaxSupportedTxSpatialStreams ());
|
||||
capabilities.SetHighestNssSupported (phy->GetMaxSupportedTxSpatialStreams ());
|
||||
}
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "wifi-remote-station-manager.h"
|
||||
#include "qos-utils.h"
|
||||
#include "ssid.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -112,17 +114,27 @@ public:
|
||||
Ptr<WifiNetDevice> GetDevice (void) const;
|
||||
|
||||
/**
|
||||
* Get the Frame Exchange Manager
|
||||
* Get the Frame Exchange Manager associated with the given link
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return the Frame Exchange Manager
|
||||
*/
|
||||
Ptr<FrameExchangeManager> GetFrameExchangeManager (void) const;
|
||||
Ptr<FrameExchangeManager> GetFrameExchangeManager (uint8_t linkId = SINGLE_LINK_OP_ID) const;
|
||||
|
||||
/**
|
||||
* Get the Channel Access Manager
|
||||
* Get the Channel Access Manager associated with the given link
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return the Channel Access Manager
|
||||
*/
|
||||
Ptr<ChannelAccessManager> GetChannelAccessManager (void) const;
|
||||
Ptr<ChannelAccessManager> GetChannelAccessManager (uint8_t linkId = SINGLE_LINK_OP_ID) const;
|
||||
|
||||
/**
|
||||
* Get the number of links (can be greater than 1 for 11be devices only).
|
||||
*
|
||||
* \return the number of links used by this MAC
|
||||
*/
|
||||
uint8_t GetNLinks (void) const;
|
||||
|
||||
/**
|
||||
* Accessor for the Txop object
|
||||
@@ -249,17 +261,18 @@ public:
|
||||
virtual bool SupportsSendFrom (void) const;
|
||||
|
||||
/**
|
||||
* \param phy the physical layer attached to this MAC.
|
||||
* \param phys the physical layers attached to this MAC.
|
||||
*/
|
||||
virtual void SetWifiPhy (Ptr<WifiPhy> phy);
|
||||
virtual void SetWifiPhys (const std::vector<Ptr<WifiPhy>>& phys);
|
||||
/**
|
||||
* \param linkId the index (starting at 0) of the PHY object to retrieve
|
||||
* \return the physical layer attached to this MAC
|
||||
*/
|
||||
Ptr<WifiPhy> GetWifiPhy (void) const;
|
||||
Ptr<WifiPhy> GetWifiPhy (uint8_t linkId = SINGLE_LINK_OP_ID) const;
|
||||
/**
|
||||
* Remove currently attached WifiPhy device from this MAC.
|
||||
* Remove currently attached WifiPhy objects from this MAC.
|
||||
*/
|
||||
void ResetWifiPhy (void);
|
||||
void ResetWifiPhys (void);
|
||||
|
||||
/**
|
||||
* \param stationManager the station manager attached to this MAC.
|
||||
@@ -544,11 +557,35 @@ protected:
|
||||
*/
|
||||
virtual void DeaggregateAmsduAndForward (Ptr<WifiMacQueueItem> mpdu);
|
||||
|
||||
/**
|
||||
* Structure holding information specific to a single link. Here, the meaning of
|
||||
* "link" is that of the 11be amendment which introduced multi-link devices. For
|
||||
* previous amendments, only one link can be created. Therefore, "link" has not
|
||||
* to be confused with the general concept of link for a NetDevice (used by the
|
||||
* m_linkUp and m_linkDown callbacks).
|
||||
*/
|
||||
struct LinkEntity
|
||||
{
|
||||
/// Destructor (a virtual method is needed to make this struct polymorphic)
|
||||
virtual ~LinkEntity ();
|
||||
|
||||
uint8_t id; //!< Link ID (starting at 0)
|
||||
Ptr<WifiPhy> phy; //!< Wifi PHY object
|
||||
Ptr<ChannelAccessManager> channelAccessManager; //!< channel access manager object
|
||||
Ptr<FrameExchangeManager> feManager; //!< Frame Exchange Manager object
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a reference to the link associated with the given ID.
|
||||
*
|
||||
* \param linkId the given link ID
|
||||
* \return a reference to the link associated with the given ID
|
||||
*/
|
||||
LinkEntity& GetLink (uint8_t linkId) const;
|
||||
|
||||
Ptr<MacRxMiddle> m_rxMiddle; //!< RX middle (defragmentation etc.)
|
||||
Ptr<MacTxMiddle> m_txMiddle; //!< TX middle (aggregation etc.)
|
||||
Ptr<ChannelAccessManager> m_channelAccessManager; //!< channel access manager
|
||||
Ptr<FrameExchangeManager> m_feManager; //!< Frame Exchange Manager
|
||||
Ptr<Txop> m_txop; //!< TXOP used for transmission of frames to non-QoS peers.
|
||||
Ptr<Txop> m_txop; //!< TXOP used for transmission of frames to non-QoS peers.
|
||||
|
||||
Callback<void> m_linkUp; //!< Callback when a link is up
|
||||
Callback<void> m_linkDown; //!< Callback when a link is down
|
||||
@@ -584,8 +621,16 @@ private:
|
||||
* of the standard.
|
||||
*
|
||||
* \param standard the supported version of the standard
|
||||
* \return the created Frame Exchange Manager
|
||||
*/
|
||||
void SetupFrameExchangeManager (WifiStandard standard);
|
||||
Ptr<FrameExchangeManager> SetupFrameExchangeManager (WifiStandard standard);
|
||||
|
||||
/**
|
||||
* Create a LinkEntity object.
|
||||
*
|
||||
* \return a unique pointer to the created LinkEntity object
|
||||
*/
|
||||
virtual std::unique_ptr<LinkEntity> CreateLinkEntity (void) const;
|
||||
|
||||
/**
|
||||
* Enable or disable ERP support for the device.
|
||||
@@ -681,8 +726,8 @@ private:
|
||||
TypeOfStation m_typeOfStation; //!< the type of station
|
||||
|
||||
Ptr<WifiNetDevice> m_device; //!< Pointer to the device
|
||||
Ptr<WifiPhy> m_phy; //!< Wifi PHY
|
||||
Ptr<WifiRemoteStationManager> m_stationManager; //!< Remote station manager (rate control, RTS/CTS/fragmentation thresholds etc.)
|
||||
std::vector<std::unique_ptr<LinkEntity>> m_links; //!< vector of Link objects
|
||||
|
||||
Mac48Address m_address; //!< MAC address of this station
|
||||
Ssid m_ssid; //!< Service Set ID (SSID)
|
||||
|
||||
@@ -195,7 +195,7 @@ WifiNetDevice::CompleteConfig (void)
|
||||
return;
|
||||
}
|
||||
m_mac->SetWifiRemoteStationManager (m_stationManager);
|
||||
m_mac->SetWifiPhy (m_phys[SINGLE_LINK_OP_ID]);
|
||||
m_mac->SetWifiPhys (m_phys);
|
||||
m_mac->SetForwardUpCallback (MakeCallback (&WifiNetDevice::ForwardUp, this));
|
||||
m_mac->SetLinkUpCallback (MakeCallback (&WifiNetDevice::LinkUp, this));
|
||||
m_mac->SetLinkDownCallback (MakeCallback (&WifiNetDevice::LinkDown, this));
|
||||
|
||||
@@ -126,7 +126,7 @@ AmpduAggregationTest::DoRun (void)
|
||||
m_mac->SetDevice (m_device);
|
||||
m_mac->SetWifiRemoteStationManager (m_manager);
|
||||
m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01"));
|
||||
m_mac->SetWifiPhy (m_phy);
|
||||
m_mac->SetWifiPhys ({m_phy});
|
||||
m_mac->ConfigureStandard (WIFI_STANDARD_80211n);
|
||||
Ptr<FrameExchangeManager> fem = m_mac->GetFrameExchangeManager ();
|
||||
Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager> ();
|
||||
@@ -377,7 +377,7 @@ TwoLevelAggregationTest::DoRun (void)
|
||||
m_mac->SetDevice (m_device);
|
||||
m_mac->SetWifiRemoteStationManager (m_manager);
|
||||
m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01"));
|
||||
m_mac->SetWifiPhy (m_phy);
|
||||
m_mac->SetWifiPhys ({m_phy});
|
||||
m_mac->ConfigureStandard (WIFI_STANDARD_80211n);
|
||||
Ptr<FrameExchangeManager> fem = m_mac->GetFrameExchangeManager ();
|
||||
Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager> ();
|
||||
@@ -613,7 +613,7 @@ HeAggregationTest::DoRunSubTest (uint16_t bufferSize)
|
||||
m_mac->SetDevice (m_device);
|
||||
m_mac->SetWifiRemoteStationManager (m_manager);
|
||||
m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01"));
|
||||
m_mac->SetWifiPhy (m_phy);
|
||||
m_mac->SetWifiPhys ({m_phy});
|
||||
m_mac->ConfigureStandard (WIFI_STANDARD_80211ax);
|
||||
Ptr<FrameExchangeManager> fem = m_mac->GetFrameExchangeManager ();
|
||||
Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager> ();
|
||||
|
||||
Reference in New Issue
Block a user