wifi: ChannelAccessManager keeps per-20 MHz channel CCA Busy state
This commit is contained in:
committed by
Stefano Avallone
parent
2189585889
commit
5845dbf84a
@@ -106,13 +106,13 @@ ChannelAccessManager::ChannelAccessManager ()
|
||||
m_lastRx ({MicroSeconds (0), MicroSeconds (0)}),
|
||||
m_lastRxReceivedOk (true),
|
||||
m_lastTxEnd (MicroSeconds (0)),
|
||||
m_lastBusyEnd (MicroSeconds (0)),
|
||||
m_lastSwitchingEnd (MicroSeconds (0)),
|
||||
m_sleeping (false),
|
||||
m_off (false),
|
||||
m_phyListener (0)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
InitLastBusyStructs ();
|
||||
}
|
||||
|
||||
ChannelAccessManager::~ChannelAccessManager ()
|
||||
@@ -143,6 +143,7 @@ ChannelAccessManager::SetupPhyListener (Ptr<WifiPhy> phy)
|
||||
m_phyListener = new PhyListener (this);
|
||||
phy->RegisterListener (m_phyListener);
|
||||
m_phy = phy;
|
||||
InitLastBusyStructs ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -198,6 +199,42 @@ ChannelAccessManager::MostRecent (std::initializer_list<Time> list) const
|
||||
return *std::max_element (list.begin (), list.end ());
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::InitLastBusyStructs (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
Time now = Simulator::Now ();
|
||||
m_lastBusyEnd.clear ();
|
||||
m_lastPer20MHzBusyEnd.clear ();
|
||||
m_lastBusyEnd[WIFI_CHANLIST_PRIMARY] = now;
|
||||
|
||||
if (m_phy == nullptr || !m_phy->GetOperatingChannel ().IsOfdm ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t width = m_phy->GetChannelWidth ();
|
||||
|
||||
if (width >= 40)
|
||||
{
|
||||
m_lastBusyEnd[WIFI_CHANLIST_SECONDARY] = now;
|
||||
}
|
||||
if (width >= 80)
|
||||
{
|
||||
m_lastBusyEnd[WIFI_CHANLIST_SECONDARY40] = now;
|
||||
}
|
||||
if (width >= 160)
|
||||
{
|
||||
m_lastBusyEnd[WIFI_CHANLIST_SECONDARY80] = now;
|
||||
}
|
||||
// TODO Add conditions for new channel widths as they get supported
|
||||
|
||||
if (m_phy->GetStandard () >= WIFI_STANDARD_80211ax && width > 20)
|
||||
{
|
||||
m_lastPer20MHzBusyEnd.assign (width / 20, now);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ChannelAccessManager::IsBusy (void) const
|
||||
{
|
||||
@@ -206,7 +243,9 @@ ChannelAccessManager::IsBusy (void) const
|
||||
return (m_lastRx.end > now) // RX
|
||||
|| (m_lastTxEnd > now) // TX
|
||||
|| (m_lastNavEnd > now) // NAV busy
|
||||
|| (m_lastBusyEnd > now); // CCA busy
|
||||
// an EDCA TXOP is obtained based solely on activity of the primary channel
|
||||
// (Sec. 10.23.2.5 of IEEE 802.11-2020)
|
||||
|| (m_lastBusyEnd.at (WIFI_CHANLIST_PRIMARY) > now); // CCA busy
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -387,7 +426,9 @@ ChannelAccessManager::GetAccessGrantStart (bool ignoreNav) const
|
||||
{
|
||||
rxAccessStart += GetEifsNoDifs ();
|
||||
}
|
||||
Time busyAccessStart = m_lastBusyEnd + sifs;
|
||||
// an EDCA TXOP is obtained based solely on activity of the primary channel
|
||||
// (Sec. 10.23.2.5 of IEEE 802.11-2020)
|
||||
Time busyAccessStart = m_lastBusyEnd.at (WIFI_CHANLIST_PRIMARY) + sifs;
|
||||
Time txAccessStart = m_lastTxEnd + sifs;
|
||||
Time navAccessStart = m_lastNavEnd + sifs;
|
||||
Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + sifs;
|
||||
@@ -583,12 +624,23 @@ ChannelAccessManager::NotifyTxStartNow (Time duration)
|
||||
void
|
||||
ChannelAccessManager::NotifyCcaBusyStartNow (Time duration,
|
||||
WifiChannelListType channelType,
|
||||
const std::vector<Time>& /*per20MhzDurations*/)
|
||||
const std::vector<Time>& per20MhzDurations)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << duration << channelType);
|
||||
NS_LOG_DEBUG ("busy start for " << duration);
|
||||
UpdateBackoff ();
|
||||
m_lastBusyEnd = Simulator::Now () + duration;
|
||||
auto lastBusyEndIt = m_lastBusyEnd.find (channelType);
|
||||
NS_ASSERT (lastBusyEndIt != m_lastBusyEnd.end ());
|
||||
Time now = Simulator::Now ();
|
||||
lastBusyEndIt->second = now + duration;
|
||||
// TODO uncomment assert below when PHY passes correct parameters
|
||||
// NS_ASSERT (per20MhzDurations.size () == m_lastPer20MHzBusyEnd.size ());
|
||||
for (std::size_t chIdx = 0; chIdx < per20MhzDurations.size (); ++chIdx)
|
||||
{
|
||||
if (per20MhzDurations[chIdx].IsStrictlyPositive ())
|
||||
{
|
||||
m_lastPer20MHzBusyEnd[chIdx] = now + per20MhzDurations[chIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -602,10 +654,12 @@ ChannelAccessManager::NotifySwitchingStartNow (Time duration)
|
||||
m_lastRxReceivedOk = true;
|
||||
m_lastRx.end = std::min (m_lastRx.end, now);
|
||||
m_lastNavEnd = std::min (m_lastNavEnd, now);
|
||||
m_lastBusyEnd = std::min (m_lastBusyEnd, now);
|
||||
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
|
||||
if (m_accessTimeout.IsRunning ())
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef CHANNEL_ACCESS_MANAGER_H
|
||||
#define CHANNEL_ACCESS_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "ns3/event-id.h"
|
||||
@@ -236,6 +237,11 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize the structures holding busy end times per channel type (primary,
|
||||
* secondary, etc.) and per 20 MHz channel.
|
||||
*/
|
||||
void InitLastBusyStructs (void);
|
||||
/**
|
||||
* Update backoff slots for all Txops.
|
||||
*/
|
||||
@@ -312,22 +318,24 @@ private:
|
||||
*/
|
||||
typedef std::vector<Ptr<Txop>> Txops;
|
||||
|
||||
Txops m_txops; //!< the vector of managed Txops
|
||||
Time m_lastAckTimeoutEnd; //!< the last Ack timeout end time
|
||||
Time m_lastCtsTimeoutEnd; //!< the last CTS timeout end time
|
||||
Time m_lastNavEnd; //!< the last NAV end time
|
||||
Timespan m_lastRx; //!< the last receive start and end time
|
||||
bool m_lastRxReceivedOk; //!< the last receive OK
|
||||
Time m_lastTxEnd; //!< the last transmit end time
|
||||
Time m_lastBusyEnd; //!< the last busy end time
|
||||
Time m_lastSwitchingEnd; //!< the last switching end time
|
||||
bool m_sleeping; //!< flag whether it is in sleeping state
|
||||
bool m_off; //!< flag whether it is in off state
|
||||
Time m_eifsNoDifs; //!< EIFS no DIFS time
|
||||
EventId m_accessTimeout; //!< the access timeout ID
|
||||
PhyListener* m_phyListener; //!< the PHY listener
|
||||
Ptr<WifiPhy> m_phy; //!< pointer to the PHY
|
||||
Ptr<FrameExchangeManager> m_feManager; //!< pointer to the Frame Exchange Manager
|
||||
Txops m_txops; //!< the vector of managed Txops
|
||||
Time m_lastAckTimeoutEnd; //!< the last Ack timeout end time
|
||||
Time m_lastCtsTimeoutEnd; //!< the last CTS timeout end time
|
||||
Time m_lastNavEnd; //!< the last NAV end time
|
||||
Timespan m_lastRx; //!< the last receive start and end time
|
||||
bool m_lastRxReceivedOk; //!< the last receive OK
|
||||
Time m_lastTxEnd; //!< the last transmit end time
|
||||
std::map<WifiChannelListType, Time> m_lastBusyEnd; //!< the last busy end time for each channel type
|
||||
std::vector<Time> m_lastPer20MHzBusyEnd; /**< the last busy end time per 20 MHz channel
|
||||
(HE stations and channel width > 20 MHz only) */
|
||||
Time m_lastSwitchingEnd; //!< the last switching end time
|
||||
bool m_sleeping; //!< flag whether it is in sleeping state
|
||||
bool m_off; //!< flag whether it is in off state
|
||||
Time m_eifsNoDifs; //!< EIFS no DIFS time
|
||||
EventId m_accessTimeout; //!< the access timeout ID
|
||||
PhyListener* m_phyListener; //!< the PHY listener
|
||||
Ptr<WifiPhy> m_phy; //!< pointer to the PHY
|
||||
Ptr<FrameExchangeManager> m_feManager; //!< pointer to the Frame Exchange Manager
|
||||
};
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
Reference in New Issue
Block a user