diff -r 10ae5ec6a903 src/wifi/model/dcf-manager.h --- a/src/wifi/model/dcf-manager.h Tue Sep 13 16:14:13 2016 -0700 +++ b/src/wifi/model/dcf-manager.h Thu Sep 15 13:19:51 2016 -0700 @@ -140,16 +140,16 @@ */ bool IsAccessRequested (void) const; - -private: - friend class DcfManager; - /** * Return the current number of backoff slots. * * \return the current number of backoff slots */ uint32_t GetBackoffSlots (void) const; + +private: + friend class DcfManager; + /** * Return the time when the backoff procedure started. * @@ -427,6 +427,14 @@ */ void NotifyCtsTimeoutResetNow (); + /** + * Check if the device is busy sending or receiving, + * or NAV busy. + * + * \return true if the device is busy, + * false otherwise + */ + bool IsBusy (void) const; private: /** @@ -527,14 +535,6 @@ * Grant access to DCF */ void DoGrantAccess (void); - /** - * Check if the device is busy sending or receiving, - * or NAV busy. - * - * \return true if the device is busy, - * false otherwise - */ - bool IsBusy (void) const; /** * typedef for a vector of DcfStates diff -r 10ae5ec6a903 src/wifi/model/edca-txop-n.cc --- a/src/wifi/model/edca-txop-n.cc Tue Sep 13 16:14:13 2016 -0700 +++ b/src/wifi/model/edca-txop-n.cc Thu Sep 15 13:19:51 2016 -0700 @@ -718,8 +718,7 @@ { m_dcf->UpdateFailedCw (); } - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } @@ -727,8 +726,7 @@ EdcaTxopN::NotifyCollision (void) { NS_LOG_FUNCTION (this); - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } @@ -862,8 +860,7 @@ m_dcf->UpdateFailedCw (); m_cwTrace = m_dcf->GetCw (); } - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } @@ -899,7 +896,18 @@ NS_LOG_FUNCTION (this << packet << &hdr); m_stationManager->PrepareForQueue (hdr.GetAddr1 (), &hdr, packet); m_queue->Enqueue (packet, hdr); - StartAccessIfNeeded (); + if (m_dcf->GetBackoffSlots () == 0 && m_manager->IsBusy () && !HasTxop ()) + { + NS_LOG_DEBUG ("Starting backoff; slots=" << m_dcf->GetBackoffSlots () << " busy= " << m_manager->IsBusy ()); + m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); + NS_LOG_DEBUG ("Drawing new backoff " << m_backoffTrace); + m_dcf->StartBackoffNow (m_backoffTrace); + RestartAccessIfNeeded (); + } + else + { + StartAccessIfNeeded (); + } } void @@ -938,11 +946,10 @@ } m_currentPacket = 0; m_dcf->ResetCw (); - if (!HasTxop ()) + m_cwTrace = m_dcf->GetCw (); + if (HasPendingQosMpduWithSameTidAndAddress () && !HasTxop () && m_dcf->GetBackoffSlots () == 0) { - m_cwTrace = m_dcf->GetCw (); - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } } @@ -1012,8 +1019,7 @@ m_dcf->UpdateFailedCw (); m_cwTrace = m_dcf->GetCw (); } - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } @@ -1087,8 +1093,7 @@ m_dcf->ResetCw (); m_cwTrace = m_dcf->GetCw (); } - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } @@ -1260,8 +1265,17 @@ &tstamp); if (peekedPacket == 0) { + NS_LOG_DEBUG ("No pending packet; returning"); return; } + if (!HasTxop () && m_dcf->GetBackoffSlots () == 0) + { + NS_LOG_DEBUG ("No TXOP left; start backoff again"); + m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); + NS_LOG_DEBUG ("Drawing new backoff " << m_backoffTrace); + m_dcf->StartBackoffNow (m_backoffTrace); + RestartAccessIfNeeded (); + } MacLowTransmissionParameters params; params.DisableOverrideDurationId (); @@ -1295,6 +1309,18 @@ } } +void +EdcaTxopN::StartBackoffIfNeeded (void) +{ + NS_LOG_FUNCTION (this); + if (m_dcf->GetBackoffSlots () == 0) + { + m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); + NS_LOG_DEBUG ("Drawing new backoff " << m_backoffTrace); + m_dcf->StartBackoffNow (m_backoffTrace); + } +} + Time EdcaTxopN::GetTxopRemaining (void) { @@ -1353,6 +1379,35 @@ return (GetTxopRemaining () >= Low ()->CalculateOverallTxTime (peekedPacket, &hdr, params)); } +bool +EdcaTxopN::HasPendingQosMpduWithSameTidAndAddress (void) const +{ + NS_LOG_FUNCTION (this); + WifiMacHeader hdr; + Time tstamp; + if (!m_currentHdr.IsQosData ()) + { + NS_LOG_DEBUG ("Current header is not QoS data; returning false"); + return false; + } + + Ptr peekedPacket = m_queue->PeekByTidAndAddress (&hdr, + m_currentHdr.GetQosTid (), + WifiMacHeader::ADDR1, + m_currentHdr.GetAddr1 (), + &tstamp); + if (peekedPacket == 0) + { + NS_LOG_DEBUG ("No pending MPDU matching current header TID and address; returning false"); + return false; + } + else + { + NS_LOG_DEBUG ("Pending MPDU found; returning true"); + return true; + } +} + void EdcaTxopN::Cancel (void) { @@ -1368,8 +1423,7 @@ m_currentPacket = 0; m_dcf->ResetCw (); m_cwTrace = m_dcf->GetCw (); - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); StartAccessIfNeeded (); } @@ -1552,8 +1606,7 @@ m_currentPacket = 0; m_dcf->ResetCw (); m_cwTrace = m_dcf->GetCw (); - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); RestartAccessIfNeeded (); } @@ -1830,8 +1883,7 @@ NS_LOG_FUNCTION (this); m_dcf->ResetCw (); m_cwTrace = m_dcf->GetCw (); - m_backoffTrace = m_rng->GetNext (0, m_dcf->GetCw ()); - m_dcf->StartBackoffNow (m_backoffTrace); + StartBackoffIfNeeded (); ns3::Dcf::DoInitialize (); } diff -r 10ae5ec6a903 src/wifi/model/edca-txop-n.h --- a/src/wifi/model/edca-txop-n.h Tue Sep 13 16:14:13 2016 -0700 +++ b/src/wifi/model/edca-txop-n.h Thu Sep 15 13:19:51 2016 -0700 @@ -547,10 +547,20 @@ /* * Check if the station has TXOP granted for the next MPDU. * - * \return true if the station has TXOP granted for the next MPDU, + * \return true if the station has another MPDU ready and TXOP granted for it, * false otherwise */ bool HasTxop (void); + /* + * Check if the station has a MPDU pending with the same TID and address + * as the current packet. + * + * \return true if the station has a MPDU pending with the same TID and + * address as the current packet, false otherwise + */ + bool HasPendingQosMpduWithSameTidAndAddress (void) const; + + void StartBackoffIfNeeded (void); AcIndex m_ac; class Dcf;