wifi: Use access parameters from MU EDCA Parameter Set when needed
This commit is contained in:
@@ -333,6 +333,7 @@ ChannelAccessManager::DoGrantDcfAccess (void)
|
||||
{
|
||||
Ptr<Txop> txop = *i;
|
||||
if (txop->GetAccessStatus () == Txop::REQUESTED
|
||||
&& (!txop->IsQosTxop () || !StaticCast<QosTxop> (txop)->EdcaDisabled ())
|
||||
&& GetBackoffEndFor (txop) <= Simulator::Now () )
|
||||
{
|
||||
/**
|
||||
@@ -541,6 +542,19 @@ ChannelAccessManager::DoRestartAccessTimeoutIfNeeded (void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::DisableEdcaFor (Ptr<Txop> qosTxop, Time duration)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << qosTxop << duration);
|
||||
NS_ASSERT (qosTxop->IsQosTxop ());
|
||||
UpdateBackoff ();
|
||||
Time resume = Simulator::Now () + duration;
|
||||
NS_LOG_DEBUG ("Backoff will resume at time " << resume << " with "
|
||||
<< qosTxop->GetBackoffSlots () << " remaining slot(s)");
|
||||
qosTxop->UpdateBackoffSlotsNow (0, resume);
|
||||
DoRestartAccessTimeoutIfNeeded ();
|
||||
}
|
||||
|
||||
void
|
||||
ChannelAccessManager::NotifyRxStartNow (Time duration)
|
||||
{
|
||||
|
||||
@@ -114,6 +114,17 @@ public:
|
||||
*/
|
||||
Time GetAccessGrantStart (bool ignoreNav = false) const;
|
||||
|
||||
/**
|
||||
* \param qosTxop a QosTxop that needs to be disabled
|
||||
* \param duration the amount of time during which the QosTxop is disabled
|
||||
*
|
||||
* Disable the given EDCA for the given amount of time. This EDCA will not be
|
||||
* granted channel access during this period and the backoff timer will be frozen.
|
||||
* After this period, the EDCA will start normal operations again by resuming
|
||||
* the backoff timer.
|
||||
*/
|
||||
void DisableEdcaFor (Ptr<Txop> qosTxop, Time duration);
|
||||
|
||||
/**
|
||||
* \param duration expected duration of reception
|
||||
*
|
||||
|
||||
@@ -1506,6 +1506,21 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr<WifiMacQueueItem> mpdu, RxSignalInfo rx
|
||||
ret.second, rxSignalInfo.snr,
|
||||
tag.Get (staId), m_txParams.m_txVector);
|
||||
}
|
||||
|
||||
if (m_psduMap.at (staId)->GetHeader (0).IsQosData ()
|
||||
&& (blockAck.GetAckType (index) // Ack or All-ack context
|
||||
|| std::any_of (blockAck.GetBitmap (index).begin (),
|
||||
blockAck.GetBitmap (index).end (),
|
||||
[](uint8_t b) { return b != 0; })))
|
||||
{
|
||||
NS_ASSERT (m_psduMap.at (staId)->GetHeader (0).HasData ());
|
||||
NS_ASSERT (m_psduMap.at (staId)->GetHeader (0).GetQosTid () == tid);
|
||||
// the station has received a response from the AP for the HE TB PPDU
|
||||
// transmitted in response to a Basic Trigger Frame and at least one
|
||||
// MPDU was acknowledged. Therefore, it needs to update the access
|
||||
// parameters if it received an MU EDCA Parameter Set element.
|
||||
m_mac->GetQosTxop (tid)->StartMuEdcaTimerNow ();
|
||||
}
|
||||
}
|
||||
|
||||
// cancel the timer
|
||||
|
||||
@@ -96,7 +96,8 @@ QosTxop::QosTxop ()
|
||||
m_muCwMin (0),
|
||||
m_muCwMax (0),
|
||||
m_muAifsn (0),
|
||||
m_muEdcaTimer (Seconds (0))
|
||||
m_muEdcaTimer (Seconds (0)),
|
||||
m_muEdcaTimerStartTime (Seconds (0))
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_qosBlockedDestinations = Create<QosBlockedDestinations> ();
|
||||
@@ -177,6 +178,63 @@ QosTxop::SetMuEdcaTimer (Time timer)
|
||||
m_muEdcaTimer = timer;
|
||||
}
|
||||
|
||||
void
|
||||
QosTxop::StartMuEdcaTimerNow (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_muEdcaTimerStartTime = Simulator::Now ();
|
||||
if (EdcaDisabled ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Disable EDCA for " << m_muEdcaTimer.As (Time::MS));
|
||||
m_channelAccessManager->DisableEdcaFor (this, m_muEdcaTimer);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
QosTxop::MuEdcaTimerRunning (void) const
|
||||
{
|
||||
return (m_muEdcaTimerStartTime.IsStrictlyPositive () && m_muEdcaTimer.IsStrictlyPositive ()
|
||||
&& m_muEdcaTimerStartTime + m_muEdcaTimer > Simulator::Now ());
|
||||
}
|
||||
|
||||
bool
|
||||
QosTxop::EdcaDisabled (void) const
|
||||
{
|
||||
return (MuEdcaTimerRunning () && m_muAifsn == 0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
QosTxop::GetMinCw (void) const
|
||||
{
|
||||
if (!MuEdcaTimerRunning ())
|
||||
{
|
||||
return m_cwMin;
|
||||
}
|
||||
NS_ASSERT (!EdcaDisabled ());
|
||||
return m_muCwMin;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
QosTxop::GetMaxCw (void) const
|
||||
{
|
||||
if (!MuEdcaTimerRunning ())
|
||||
{
|
||||
return m_cwMax;
|
||||
}
|
||||
NS_ASSERT (!EdcaDisabled ());
|
||||
return m_muCwMax;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
QosTxop::GetAifsn (void) const
|
||||
{
|
||||
if (!MuEdcaTimerRunning ())
|
||||
{
|
||||
return m_aifsn;
|
||||
}
|
||||
return m_muAifsn;
|
||||
}
|
||||
|
||||
Ptr<BlockAckManager>
|
||||
QosTxop::GetBaManager (void)
|
||||
{
|
||||
|
||||
@@ -416,6 +416,47 @@ public:
|
||||
* \param timer the timer duration.
|
||||
*/
|
||||
void SetMuEdcaTimer (Time timer);
|
||||
/**
|
||||
* Start the MU EDCA Timer.
|
||||
*/
|
||||
void StartMuEdcaTimerNow (void);
|
||||
/**
|
||||
* Return true if the MU EDCA Timer is running, false otherwise.
|
||||
*
|
||||
* \return whether the MU EDCA Timer is running
|
||||
*/
|
||||
bool MuEdcaTimerRunning (void) const;
|
||||
/**
|
||||
* Return true if the EDCA is disabled (the MU EDCA Timer is running and the
|
||||
* MU AIFSN is zero), false otherwise.
|
||||
*
|
||||
* \return whether the EDCA is disabled
|
||||
*/
|
||||
bool EdcaDisabled (void) const;
|
||||
/**
|
||||
* Return the minimum contention window size from the EDCA Parameter Set
|
||||
* or the MU EDCA Parameter Set, depending on whether the MU EDCA Timer is
|
||||
* running or not.
|
||||
*
|
||||
* \return the currently used minimum contention window size.
|
||||
*/
|
||||
uint32_t GetMinCw (void) const override;
|
||||
/**
|
||||
* Return the maximum contention window size from the EDCA Parameter Set
|
||||
* or the MU EDCA Parameter Set, depending on whether the MU EDCA Timer is
|
||||
* running or not.
|
||||
*
|
||||
* \return the currently used maximum contention window size.
|
||||
*/
|
||||
uint32_t GetMaxCw (void) const override;
|
||||
/**
|
||||
* Return the number of slots that make up an AIFS according to the
|
||||
* EDCA Parameter Set or the MU EDCA Parameter Set, depending on whether the
|
||||
* MU EDCA Timer is running or not.
|
||||
*
|
||||
* \return the number of slots that currently make up an AIFS.
|
||||
*/
|
||||
uint8_t GetAifsn (void) const override;
|
||||
|
||||
protected:
|
||||
void DoDispose (void) override;
|
||||
@@ -451,10 +492,11 @@ private:
|
||||
Time m_failedAddBaTimeout; //!< timeout after failed BA agreement
|
||||
bool m_useExplicitBarAfterMissedBlockAck; //!< flag whether explicit BlockAckRequest should be sent upon missed BlockAck Response
|
||||
|
||||
uint32_t m_muCwMin; //!< the MU CW minimum
|
||||
uint32_t m_muCwMax; //!< the MU CW maximum
|
||||
uint8_t m_muAifsn; //!< the MU AIFSN
|
||||
Time m_muEdcaTimer; //!< the MU EDCA Timer
|
||||
uint32_t m_muCwMin; //!< the MU CW minimum
|
||||
uint32_t m_muCwMax; //!< the MU CW maximum
|
||||
uint8_t m_muAifsn; //!< the MU AIFSN
|
||||
Time m_muEdcaTimer; //!< the MU EDCA Timer
|
||||
Time m_muEdcaTimerStartTime; //!< last start time of the MU EDCA Timer
|
||||
|
||||
TracedCallback<Time, Time> m_txopTrace; //!< TXOP trace callback
|
||||
};
|
||||
|
||||
@@ -186,7 +186,7 @@ void
|
||||
Txop::ResetCw (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_cw = m_cwMin;
|
||||
m_cw = GetMinCw ();
|
||||
m_cwTrace = m_cw;
|
||||
}
|
||||
|
||||
@@ -195,7 +195,9 @@ Txop::UpdateFailedCw (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
//see 802.11-2012, section 9.19.2.5
|
||||
m_cw = std::min ( 2 * (m_cw + 1) - 1, m_cwMax);
|
||||
m_cw = std::min ( 2 * (m_cw + 1) - 1, GetMaxCw ());
|
||||
// if the MU EDCA timer is running, CW cannot be less than MU CW min
|
||||
m_cw = std::max (m_cw, GetMinCw ());
|
||||
m_cwTrace = m_cw;
|
||||
}
|
||||
|
||||
|
||||
@@ -166,19 +166,19 @@ public:
|
||||
*
|
||||
* \return the minimum contention window size.
|
||||
*/
|
||||
uint32_t GetMinCw (void) const;
|
||||
virtual uint32_t GetMinCw (void) const;
|
||||
/**
|
||||
* Return the maximum contention window size.
|
||||
*
|
||||
* \return the maximum contention window size.
|
||||
*/
|
||||
uint32_t GetMaxCw (void) const;
|
||||
virtual uint32_t GetMaxCw (void) const;
|
||||
/**
|
||||
* Return the number of slots that make up an AIFS.
|
||||
*
|
||||
* \return the number of slots that make up an AIFS.
|
||||
*/
|
||||
uint8_t GetAifsn (void) const;
|
||||
virtual uint8_t GetAifsn (void) const;
|
||||
/**
|
||||
* Return the TXOP limit.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user