wifi: Use access parameters from MU EDCA Parameter Set when needed

This commit is contained in:
Stefano Avallone
2019-10-29 22:12:18 +01:00
parent 25dc12a8e4
commit 015719dfcd
7 changed files with 152 additions and 10 deletions

View File

@@ -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)
{

View File

@@ -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
*

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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
};

View File

@@ -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;
}

View File

@@ -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.
*