From 262918d22ccb375b57d79c1bbfd17b8af991670e Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Mon, 28 Feb 2022 17:39:33 +0100 Subject: [PATCH] wifi: Txop holds per-link contention window information --- src/wave/model/ocb-wifi-mac.cc | 6 +- src/wifi/examples/wifi-bianchi.cc | 6 +- src/wifi/model/ap-wifi-mac.cc | 30 +-- src/wifi/model/channel-access-manager.cc | 14 +- src/wifi/model/frame-exchange-manager.cc | 14 +- .../model/he/he-frame-exchange-manager.cc | 22 +-- .../model/ht/ht-frame-exchange-manager.cc | 6 +- src/wifi/model/qos-txop.cc | 95 ++++----- src/wifi/model/qos-txop.h | 112 +++++++---- src/wifi/model/sta-wifi-mac.cc | 14 +- src/wifi/model/txop.cc | 181 ++++++++++++++---- src/wifi/model/txop.h | 142 ++++++++++++-- src/wifi/model/wifi-mac.cc | 30 +-- src/wifi/test/channel-access-manager-test.cc | 2 +- src/wifi/test/wifi-mac-ofdma-test.cc | 7 +- src/wifi/test/wifi-txop-test.cc | 4 +- 16 files changed, 468 insertions(+), 217 deletions(-) diff --git a/src/wave/model/ocb-wifi-mac.cc b/src/wave/model/ocb-wifi-mac.cc index 24a05323f..ed6fffa52 100644 --- a/src/wave/model/ocb-wifi-mac.cc +++ b/src/wave/model/ocb-wifi-mac.cc @@ -343,30 +343,35 @@ OcbWifiMac::ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum { case AC_VO: dcf = WifiMac::GetVOQueue (); + dcf->SetWifiMac (this); dcf->SetMinCw ((cwmin + 1) / 4 - 1); dcf->SetMaxCw ((cwmin + 1) / 2 - 1); dcf->SetAifsn (aifsn); break; case AC_VI: dcf = WifiMac::GetVIQueue (); + dcf->SetWifiMac (this); dcf->SetMinCw ((cwmin + 1) / 2 - 1); dcf->SetMaxCw (cwmin); dcf->SetAifsn (aifsn); break; case AC_BE: dcf = WifiMac::GetBEQueue (); + dcf->SetWifiMac (this); dcf->SetMinCw (cwmin); dcf->SetMaxCw (cwmax); dcf->SetAifsn (aifsn); break; case AC_BK: dcf = WifiMac::GetBKQueue (); + dcf->SetWifiMac (this); dcf->SetMinCw (cwmin); dcf->SetMaxCw (cwmax); dcf->SetAifsn (aifsn); break; case AC_BE_NQOS: dcf = WifiMac::GetTxop (); + dcf->SetWifiMac (this); dcf->SetMinCw (cwmin); dcf->SetMaxCw (cwmax); dcf->SetAifsn (aifsn); @@ -379,7 +384,6 @@ OcbWifiMac::ConfigureEdca (uint32_t cwmin, uint32_t cwmax, uint32_t aifsn, enum break; } - dcf->SetWifiMac (this); GetLink (SINGLE_LINK_OP_ID).channelAccessManager-> Add (dcf); } diff --git a/src/wifi/examples/wifi-bianchi.cc b/src/wifi/examples/wifi-bianchi.cc index 888c70175..00ade2af1 100644 --- a/src/wifi/examples/wifi-bianchi.cc +++ b/src/wifi/examples/wifi-bianchi.cc @@ -600,12 +600,12 @@ TracePacketReception (std::string context, Ptr p, uint16_t channel } void -CwTrace (std::string context, uint32_t oldVal, uint32_t newVal) +CwTrace (std::string context, uint32_t cw, uint8_t /* linkId */) { - NS_LOG_INFO ("CW time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << newVal); + NS_LOG_INFO ("CW time=" << Simulator::Now () << " node=" << ContextToNodeId (context) << " val=" << cw); if (tracing) { - cwTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << newVal << std::endl; + cwTraceFile << Simulator::Now ().GetSeconds () << " " << ContextToNodeId (context) << " " << cw << std::endl; } } diff --git a/src/wifi/model/ap-wifi-mac.cc b/src/wifi/model/ap-wifi-mac.cc index cf5775aaf..03940f160 100644 --- a/src/wifi/model/ap-wifi-mac.cc +++ b/src/wifi/model/ap-wifi-mac.cc @@ -106,9 +106,6 @@ ApWifiMac::ApWifiMac () { NS_LOG_FUNCTION (this); m_beaconTxop = CreateObject (CreateObject (AC_BEACON)); - m_beaconTxop->SetAifsn (1); - m_beaconTxop->SetMinCw (0); - m_beaconTxop->SetMaxCw (0); m_beaconTxop->SetTxMiddle (m_txMiddle); //Let the lower layers know that we are acting as an AP. @@ -148,6 +145,9 @@ ApWifiMac::ConfigureStandard (WifiStandard standard) NS_LOG_FUNCTION (this << standard); WifiMac::ConfigureStandard (standard); m_beaconTxop->SetWifiMac (this); + m_beaconTxop->SetAifsns (std::vector (GetNLinks (), 1)); + m_beaconTxop->SetMinCws (std::vector (GetNLinks (), 0)); + m_beaconTxop->SetMaxCws (std::vector (GetNLinks (), 0)); for (uint8_t linkId = 0; linkId < GetNLinks (); linkId++) { GetLink (linkId).channelAccessManager->Add (m_beaconTxop); @@ -482,33 +482,33 @@ ApWifiMac::GetEdcaParameterSet (void) const edca = GetQosTxop (AC_BE); txopLimit = edca->GetTxopLimit (); edcaParameters.SetBeAci (0); - edcaParameters.SetBeCWmin (edca->GetMinCw ()); - edcaParameters.SetBeCWmax (edca->GetMaxCw ()); - edcaParameters.SetBeAifsn (edca->GetAifsn ()); + edcaParameters.SetBeCWmin (edca->GetMinCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetBeCWmax (edca->GetMaxCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetBeAifsn (edca->GetAifsn (SINGLE_LINK_OP_ID)); edcaParameters.SetBeTxopLimit (static_cast (txopLimit.GetMicroSeconds () / 32)); edca = GetQosTxop (AC_BK); txopLimit = edca->GetTxopLimit (); edcaParameters.SetBkAci (1); - edcaParameters.SetBkCWmin (edca->GetMinCw ()); - edcaParameters.SetBkCWmax (edca->GetMaxCw ()); - edcaParameters.SetBkAifsn (edca->GetAifsn ()); + edcaParameters.SetBkCWmin (edca->GetMinCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetBkCWmax (edca->GetMaxCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetBkAifsn (edca->GetAifsn (SINGLE_LINK_OP_ID)); edcaParameters.SetBkTxopLimit (static_cast (txopLimit.GetMicroSeconds () / 32)); edca = GetQosTxop (AC_VI); txopLimit = edca->GetTxopLimit (); edcaParameters.SetViAci (2); - edcaParameters.SetViCWmin (edca->GetMinCw ()); - edcaParameters.SetViCWmax (edca->GetMaxCw ()); - edcaParameters.SetViAifsn (edca->GetAifsn ()); + edcaParameters.SetViCWmin (edca->GetMinCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetViCWmax (edca->GetMaxCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetViAifsn (edca->GetAifsn (SINGLE_LINK_OP_ID)); edcaParameters.SetViTxopLimit (static_cast (txopLimit.GetMicroSeconds () / 32)); edca = GetQosTxop (AC_VO); txopLimit = edca->GetTxopLimit (); edcaParameters.SetVoAci (3); - edcaParameters.SetVoCWmin (edca->GetMinCw ()); - edcaParameters.SetVoCWmax (edca->GetMaxCw ()); - edcaParameters.SetVoAifsn (edca->GetAifsn ()); + edcaParameters.SetVoCWmin (edca->GetMinCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetVoCWmax (edca->GetMaxCw (SINGLE_LINK_OP_ID)); + edcaParameters.SetVoAifsn (edca->GetAifsn (SINGLE_LINK_OP_ID)); edcaParameters.SetVoTxopLimit (static_cast (txopLimit.GetMicroSeconds () / 32)); edcaParameters.SetQosInfo (0); diff --git a/src/wifi/model/channel-access-manager.cc b/src/wifi/model/channel-access-manager.cc index 05a489dc2..a87ad0563 100644 --- a/src/wifi/model/channel-access-manager.cc +++ b/src/wifi/model/channel-access-manager.cc @@ -302,7 +302,7 @@ ChannelAccessManager::NeedBackoffUponAccess (Ptr txop) // to correctly align the backoff start time at the next slot boundary // (performed by the next call to ChannelAccessManager::RequestAccess()) Time delay = (txop->IsQosTxop () ? Seconds (0) - : GetSifs () + txop->GetAifsn () * GetSlot ()); + : GetSifs () + txop->GetAifsn (m_linkId) * GetSlot ()); txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay, m_linkId); } else @@ -330,7 +330,7 @@ ChannelAccessManager::RequestAccess (Ptr txop) /* * EDCAF operations shall be performed at slot boundaries (Sec. 10.22.2.4 of 802.11-2016) */ - Time accessGrantStart = GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ()); + Time accessGrantStart = GetAccessGrantStart () + (txop->GetAifsn (m_linkId) * GetSlot ()); if (txop->IsQosTxop () && txop->GetBackoffStart (m_linkId) > accessGrantStart) { @@ -358,7 +358,7 @@ ChannelAccessManager::DoGrantDcfAccess (void) { Ptr txop = *i; if (txop->GetAccessStatus () == Txop::REQUESTED - && (!txop->IsQosTxop () || !StaticCast (txop)->EdcaDisabled ()) + && (!txop->IsQosTxop () || !StaticCast (txop)->EdcaDisabled (m_linkId)) && GetBackoffEndFor (txop) <= Simulator::Now () ) { /** @@ -478,7 +478,7 @@ ChannelAccessManager::GetBackoffStartFor (Ptr txop) { NS_LOG_FUNCTION (this << txop); Time mostRecentEvent = std::max ({txop->GetBackoffStart (m_linkId), - GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ())}); + GetAccessGrantStart () + (txop->GetAifsn (m_linkId) * GetSlot ())}); NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US)); return mostRecentEvent; @@ -728,7 +728,7 @@ ChannelAccessManager::NotifySwitchingStartNow (Time duration) txop->UpdateBackoffSlotsNow (remainingSlots, now, m_linkId); NS_ASSERT (txop->GetBackoffSlots (m_linkId) == 0); } - txop->ResetCw (); + txop->ResetCw (m_linkId); txop->m_access = Txop::NOT_REQUESTED; } @@ -785,7 +785,7 @@ ChannelAccessManager::NotifyWakeupNow (void) txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now (), m_linkId); NS_ASSERT (txop->GetBackoffSlots (m_linkId) == 0); } - txop->ResetCw (); + txop->ResetCw (m_linkId); txop->m_access = Txop::NOT_REQUESTED; txop->NotifyWakeUp (); } @@ -804,7 +804,7 @@ ChannelAccessManager::NotifyOnNow (void) txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now (), m_linkId); NS_ASSERT (txop->GetBackoffSlots (m_linkId) == 0); } - txop->ResetCw (); + txop->ResetCw (m_linkId); txop->m_access = Txop::NOT_REQUESTED; txop->NotifyOn (); } diff --git a/src/wifi/model/frame-exchange-manager.cc b/src/wifi/model/frame-exchange-manager.cc index a8fa9741d..e3597306e 100644 --- a/src/wifi/model/frame-exchange-manager.cc +++ b/src/wifi/model/frame-exchange-manager.cc @@ -797,14 +797,14 @@ FrameExchangeManager::NormalAckTimeout (Ptr mpdu, const WifiTx // Dequeue the MPDU if it is stored in a queue DequeueMpdu (mpdu); m_mac->GetWifiRemoteStationManager ()->ReportFinalDataFailed (mpdu); - m_dcf->ResetCw (); + m_dcf->ResetCw (m_linkId); } else { NS_LOG_DEBUG ("Missed Ack, retransmit MPDU"); mpdu->GetHeader ().SetRetry (); RetransmitMpduAfterMissedAck (mpdu); - m_dcf->UpdateFailedCw (); + m_dcf->UpdateFailedCw (m_linkId); } m_mpdu = 0; @@ -843,12 +843,12 @@ FrameExchangeManager::DoCtsTimeout (Ptr psdu) DequeueMpdu (mpdu); NotifyPacketDiscarded (mpdu); } - m_dcf->ResetCw (); + m_dcf->ResetCw (m_linkId); } else { NS_LOG_DEBUG ("Missed CTS, retransmit MPDU(s)"); - m_dcf->UpdateFailedCw (); + m_dcf->UpdateFailedCw (m_linkId); } // Make the sequence numbers of the MPDUs available again if the MPDUs have never // been transmitted, both in case the MPDUs have been discarded and in case the @@ -907,12 +907,12 @@ FrameExchangeManager::NotifyInternalCollision (Ptr txop) m_mac->GetWifiRemoteStationManager ()->ReportFinalDataFailed (mpdu); DequeueMpdu (mpdu); NotifyPacketDiscarded (mpdu); - txop->ResetCw (); + txop->ResetCw (m_linkId); } else { NS_LOG_DEBUG ("Update CW"); - txop->UpdateFailedCw (); + txop->UpdateFailedCw (m_linkId); } } @@ -1186,7 +1186,7 @@ FrameExchangeManager::ReceivedNormalAck (Ptr mpdu, const WifiT // The CW shall be reset to aCWmin after every successful attempt to transmit // a frame containing all or part of an MSDU or MMPDU (sec. 10.3.3 of 802.11-2016) - m_dcf->ResetCw (); + m_dcf->ResetCw (m_linkId); if (mpdu->GetHeader ().IsMoreFragments ()) { diff --git a/src/wifi/model/he/he-frame-exchange-manager.cc b/src/wifi/model/he/he-frame-exchange-manager.cc index 3a4b4ae9b..06e615ba8 100644 --- a/src/wifi/model/he/he-frame-exchange-manager.cc +++ b/src/wifi/model/he/he-frame-exchange-manager.cc @@ -904,13 +904,13 @@ HeFrameExchangeManager::TbPpduTimeout (WifiPsduMap* psduMap, if (staMissedTbPpduFrom->size () == nSolicitedStations) { // no station replied, the transmission failed - m_edca->UpdateFailedCw (); + m_edca->UpdateFailedCw (m_linkId); TransmissionFailed (); } else if (!m_multiStaBaEvent.IsRunning ()) { - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); TransmissionSucceeded (); } @@ -966,11 +966,11 @@ HeFrameExchangeManager::BlockAcksInTbPpduTimeout (WifiPsduMap* psduMap, if (resetCw) { - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); } else { - m_edca->UpdateFailedCw (); + m_edca->UpdateFailedCw (m_linkId); } if (staMissedBlockAckFrom->size () == nSolicitedStations) @@ -1238,7 +1238,7 @@ HeFrameExchangeManager::SendMultiStaBlockAck (const WifiTxParameters& txParams) // continue with the TXOP if time remains m_psduMap.clear (); - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); m_muSnrTag.Reset (); Simulator::Schedule (txDuration, &HeFrameExchangeManager::TransmissionSucceeded, this); } @@ -1528,7 +1528,7 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx // all of the stations that replied with a TB PPDU sent QoS Null frames. NS_LOG_DEBUG ("Continue the TXOP"); m_psduMap.clear (); - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); TransmissionSucceeded (); } } @@ -1567,7 +1567,7 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx NS_ASSERT (m_edca != 0); m_psduMap.clear (); - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); TransmissionSucceeded (); } @@ -1653,7 +1653,7 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx m_channelAccessManager->NotifyAckTimeoutResetNow (); m_triggerFrame = nullptr; // this is strictly needed for DL_MU_TF_MU_BAR only - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); m_psduMap.clear (); TransmissionSucceeded (); } @@ -1731,7 +1731,7 @@ HeFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx // 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 (); + m_mac->GetQosTxop (tid)->StartMuEdcaTimerNow (m_linkId); } } @@ -1900,7 +1900,7 @@ HeFrameExchangeManager::EndReceiveAmpdu (Ptr psdu, const RxSigna // all of the stations that replied with a TB PPDU sent QoS Null frames. NS_LOG_DEBUG ("Continue the TXOP"); m_psduMap.clear (); - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); TransmissionSucceeded (); } } @@ -1941,7 +1941,7 @@ HeFrameExchangeManager::EndReceiveAmpdu (Ptr psdu, const RxSigna NS_ASSERT (m_edca != 0); m_psduMap.clear (); - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); TransmissionSucceeded (); } diff --git a/src/wifi/model/ht/ht-frame-exchange-manager.cc b/src/wifi/model/ht/ht-frame-exchange-manager.cc index 65a96a80a..3d3cd3179 100644 --- a/src/wifi/model/ht/ht-frame-exchange-manager.cc +++ b/src/wifi/model/ht/ht-frame-exchange-manager.cc @@ -1114,11 +1114,11 @@ HtFrameExchangeManager::BlockAckTimeout (Ptr psdu, const WifiTxVector& if (resetCw) { - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); } else { - m_edca->UpdateFailedCw (); + m_edca->UpdateFailedCw (m_linkId); } m_psdu = 0; @@ -1324,7 +1324,7 @@ HtFrameExchangeManager::ReceiveMpdu (Ptr mpdu, RxSignalInfo rx m_channelAccessManager->NotifyAckTimeoutResetNow (); // Reset the CW - m_edca->ResetCw (); + m_edca->ResetCw (m_linkId); m_psdu = 0; TransmissionSucceeded (); diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index f3a6bfa59..fc6df1131 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -94,12 +94,7 @@ QosTxop::QosTxop (AcIndex ac) : Txop (CreateObject (ac)), m_ac (ac), m_startTxop (Seconds (0)), - m_txopDuration (Seconds (0)), - m_muCwMin (0), - m_muCwMax (0), - m_muAifsn (0), - m_muEdcaTimer (Seconds (0)), - m_muEdcaTimerStartTime (Seconds (0)) + m_txopDuration (Seconds (0)) { NS_LOG_FUNCTION (this); m_qosBlockedDestinations = Create (); @@ -128,6 +123,18 @@ QosTxop::DoDispose (void) Txop::DoDispose (); } +std::unique_ptr +QosTxop::CreateLinkEntity (void) const +{ + return std::make_unique (); +} + +QosTxop::QosLinkEntity& +QosTxop::GetLink (uint8_t linkId) const +{ + return static_cast (Txop::GetLink (linkId)); +} + uint8_t QosTxop::GetQosQueueSize (uint8_t tid, Mac48Address receiver) const { @@ -147,88 +154,90 @@ QosTxop::SetDroppedMpduCallback (DroppedMpdu callback) } void -QosTxop::SetMuCwMin (uint16_t cwMin) +QosTxop::SetMuCwMin (uint16_t cwMin, uint8_t linkId) { - NS_LOG_FUNCTION (this << cwMin); - m_muCwMin = cwMin; + NS_LOG_FUNCTION (this << cwMin << +linkId); + GetLink (linkId).muCwMin = cwMin; } void -QosTxop::SetMuCwMax (uint16_t cwMax) +QosTxop::SetMuCwMax (uint16_t cwMax, uint8_t linkId) { - NS_LOG_FUNCTION (this << cwMax); - m_muCwMax = cwMax; + NS_LOG_FUNCTION (this << cwMax << +linkId); + GetLink (linkId).muCwMax = cwMax; } void -QosTxop::SetMuAifsn (uint8_t aifsn) +QosTxop::SetMuAifsn (uint8_t aifsn, uint8_t linkId) { - NS_LOG_FUNCTION (this << +aifsn); - m_muAifsn = aifsn; + NS_LOG_FUNCTION (this << +aifsn << +linkId); + GetLink (linkId).muAifsn = aifsn; } void -QosTxop::SetMuEdcaTimer (Time timer) +QosTxop::SetMuEdcaTimer (Time timer, uint8_t linkId) { - NS_LOG_FUNCTION (this << timer); - m_muEdcaTimer = timer; + NS_LOG_FUNCTION (this << timer << +linkId); + GetLink (linkId).muEdcaTimer = timer; } void -QosTxop::StartMuEdcaTimerNow (void) +QosTxop::StartMuEdcaTimerNow (uint8_t linkId) { - NS_LOG_FUNCTION (this); - m_muEdcaTimerStartTime = Simulator::Now (); - if (EdcaDisabled ()) + NS_LOG_FUNCTION (this << +linkId); + auto& link = GetLink (linkId); + link.muEdcaTimerStartTime = Simulator::Now (); + if (EdcaDisabled (linkId)) { - NS_LOG_DEBUG ("Disable EDCA for " << m_muEdcaTimer.As (Time::MS)); - m_mac->GetChannelAccessManager (SINGLE_LINK_OP_ID)->DisableEdcaFor (this, m_muEdcaTimer); + NS_LOG_DEBUG ("Disable EDCA for " << link.muEdcaTimer.As (Time::MS)); + m_mac->GetChannelAccessManager (linkId)->DisableEdcaFor (this, link.muEdcaTimer); } } bool -QosTxop::MuEdcaTimerRunning (void) const +QosTxop::MuEdcaTimerRunning (uint8_t linkId) const { - return (m_muEdcaTimerStartTime.IsStrictlyPositive () && m_muEdcaTimer.IsStrictlyPositive () - && m_muEdcaTimerStartTime + m_muEdcaTimer > Simulator::Now ()); + auto& link = GetLink (linkId); + return (link.muEdcaTimerStartTime.IsStrictlyPositive () && link.muEdcaTimer.IsStrictlyPositive () + && link.muEdcaTimerStartTime + link.muEdcaTimer > Simulator::Now ()); } bool -QosTxop::EdcaDisabled (void) const +QosTxop::EdcaDisabled (uint8_t linkId) const { - return (MuEdcaTimerRunning () && m_muAifsn == 0); + return (MuEdcaTimerRunning (linkId) && GetLink (linkId).muAifsn == 0); } uint32_t -QosTxop::GetMinCw (void) const +QosTxop::GetMinCw (uint8_t linkId) const { - if (!MuEdcaTimerRunning ()) + if (!MuEdcaTimerRunning (linkId)) { - return m_cwMin; + return GetLink (linkId).cwMin; } - NS_ASSERT (!EdcaDisabled ()); - return m_muCwMin; + NS_ASSERT (!EdcaDisabled (linkId)); + return GetLink (linkId).muCwMin; } uint32_t -QosTxop::GetMaxCw (void) const +QosTxop::GetMaxCw (uint8_t linkId) const { - if (!MuEdcaTimerRunning ()) + if (!MuEdcaTimerRunning (linkId)) { - return m_cwMax; + return GetLink (linkId).cwMax; } - NS_ASSERT (!EdcaDisabled ()); - return m_muCwMax; + NS_ASSERT (!EdcaDisabled (linkId)); + return GetLink (linkId).muCwMax; } uint8_t -QosTxop::GetAifsn (void) const +QosTxop::GetAifsn (uint8_t linkId) const { - if (!MuEdcaTimerRunning ()) + if (!MuEdcaTimerRunning (linkId)) { - return m_aifsn; + return GetLink (linkId).aifsn; } - return m_muAifsn; + return GetLink (linkId).muAifsn; } Ptr diff --git a/src/wifi/model/qos-txop.h b/src/wifi/model/qos-txop.h index 7da4f0848..dfc9f0405 100644 --- a/src/wifi/model/qos-txop.h +++ b/src/wifi/model/qos-txop.h @@ -366,80 +366,118 @@ public: /** * Set the minimum contention window size to use while the MU EDCA Timer - * is running. + * is running for the given link. * * \param cwMin the minimum contention window size. + * \param linkId the ID of the given link */ - void SetMuCwMin (uint16_t cwMin); + void SetMuCwMin (uint16_t cwMin, uint8_t linkId); /** * Set the maximum contention window size to use while the MU EDCA Timer - * is running. + * is running for the given link. * * \param cwMax the maximum contention window size. + * \param linkId the ID of the given link */ - void SetMuCwMax (uint16_t cwMax); + void SetMuCwMax (uint16_t cwMax, uint8_t linkId); /** * Set the number of slots that make up an AIFS while the MU EDCA Timer - * is running. + * is running for the given link. * * \param aifsn the number of slots that make up an AIFS. + * \param linkId the ID of the given link */ - void SetMuAifsn (uint8_t aifsn); + void SetMuAifsn (uint8_t aifsn, uint8_t linkId); /** - * Set the MU EDCA Timer. + * Set the MU EDCA Timer for the given link. * * \param timer the timer duration. + * \param linkId the ID of the given link */ - void SetMuEdcaTimer (Time timer); + void SetMuEdcaTimer (Time timer, uint8_t linkId); /** - * Start the MU EDCA Timer. - */ - void StartMuEdcaTimerNow (void); - /** - * Return true if the MU EDCA Timer is running, false otherwise. + * Start the MU EDCA Timer for the given link. * + * \param linkId the ID of the given link + */ + void StartMuEdcaTimerNow (uint8_t linkId); + /** + * Return true if the MU EDCA Timer is running for the given link, false otherwise. + * + * \param linkId the ID of the given link * \return whether the MU EDCA Timer is running */ - bool MuEdcaTimerRunning (void) const; + bool MuEdcaTimerRunning (uint8_t linkId) const; /** * Return true if the EDCA is disabled (the MU EDCA Timer is running and the - * MU AIFSN is zero), false otherwise. + * MU AIFSN is zero) for the given link, false otherwise. * + * \param linkId the ID of the given link * \return whether the EDCA is disabled */ - bool EdcaDisabled (void) const; + bool EdcaDisabled (uint8_t linkId) 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 + * For the given link, 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. * + * \param linkId the ID of the given link + * \return the currently used minimum contention window size. + */ + uint32_t GetMinCw (uint8_t linkId) const override; + /** + * For the given link, 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. + * + * \param linkId the ID of the given link + * \return the currently used maximum contention window size. + */ + uint32_t GetMaxCw (uint8_t linkId) const override; + /** + * For the given link, 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. + * + * \param linkId the ID of the given link * \return the number of slots that currently make up an AIFS. */ - uint8_t GetAifsn (void) const override; + uint8_t GetAifsn (uint8_t linkId) const override; protected: + /** + * 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. + */ + struct QosLinkEntity : public Txop::LinkEntity + { + /// Destructor (a virtual method is needed to make this struct polymorphic) + virtual ~QosLinkEntity () = default; + + uint32_t muCwMin {0}; //!< the MU CW minimum + uint32_t muCwMax {0}; //!< the MU CW maximum + uint8_t muAifsn {0}; //!< the MU AIFSN + Time muEdcaTimer {0}; //!< the MU EDCA Timer + Time muEdcaTimerStartTime {0}; //!< last start time of the MU EDCA Timer + }; + void DoDispose (void) override; + /** + * 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 + */ + QosLinkEntity& GetLink (uint8_t linkId) const; + private: /// allow AggregationCapableTransmissionListener class access friend class AggregationCapableTransmissionListener; + std::unique_ptr CreateLinkEntity (void) const override; + /** * Check if the given MPDU is to be considered old according to the current * starting sequence number of the transmit window, provided that a block ack @@ -463,12 +501,6 @@ 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 - Time m_muEdcaTimerStartTime; //!< last start time of the MU EDCA Timer - TracedCallback m_txopTrace; //!< TXOP trace callback }; diff --git a/src/wifi/model/sta-wifi-mac.cc b/src/wifi/model/sta-wifi-mac.cc index d78058f81..4d452b396 100644 --- a/src/wifi/model/sta-wifi-mac.cc +++ b/src/wifi/model/sta-wifi-mac.cc @@ -1181,9 +1181,9 @@ void StaWifiMac::SetEdcaParameters (AcIndex ac, uint32_t cwMin, uint32_t cwMax, uint8_t aifsn, Time txopLimit) { Ptr edca = GetQosTxop (ac); - edca->SetMinCw (cwMin); - edca->SetMaxCw (cwMax); - edca->SetAifsn (aifsn); + edca->SetMinCw (cwMin, SINGLE_LINK_OP_ID); + edca->SetMaxCw (cwMax, SINGLE_LINK_OP_ID); + edca->SetAifsn (aifsn, SINGLE_LINK_OP_ID); edca->SetTxopLimit (txopLimit); } @@ -1191,10 +1191,10 @@ void StaWifiMac::SetMuEdcaParameters (AcIndex ac, uint16_t cwMin, uint16_t cwMax, uint8_t aifsn, Time muEdcaTimer) { Ptr edca = GetQosTxop (ac); - edca->SetMuCwMin (cwMin); - edca->SetMuCwMax (cwMax); - edca->SetMuAifsn (aifsn); - edca->SetMuEdcaTimer (muEdcaTimer); + edca->SetMuCwMin (cwMin, SINGLE_LINK_OP_ID); + edca->SetMuCwMax (cwMax, SINGLE_LINK_OP_ID); + edca->SetMuAifsn (aifsn, SINGLE_LINK_OP_ID); + edca->SetMuEdcaTimer (muEdcaTimer, SINGLE_LINK_OP_ID); } void diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index 9e8835c45..a3b017cb7 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -46,20 +46,27 @@ Txop::GetTypeId (void) .SetParent () .SetGroupName ("Wifi") .AddConstructor () - .AddAttribute ("MinCw", "The minimum value of the contention window.", + .AddAttribute ("MinCw", + "The minimum value of the contention window (just for the first link, " + "in case of 11be multi-link devices).", + TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time UintegerValue (15), - MakeUintegerAccessor (&Txop::SetMinCw, - &Txop::GetMinCw), + MakeUintegerAccessor ((void (Txop::*) (uint32_t)) &Txop::SetMinCw, + (uint32_t (Txop::*) (void) const) &Txop::GetMinCw), MakeUintegerChecker ()) - .AddAttribute ("MaxCw", "The maximum value of the contention window.", + .AddAttribute ("MaxCw", "The maximum value of the contention window (just for the first link, " + "in case of 11be multi-link devices).", + TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time UintegerValue (1023), - MakeUintegerAccessor (&Txop::SetMaxCw, - &Txop::GetMaxCw), + MakeUintegerAccessor ((void (Txop::*) (uint32_t)) &Txop::SetMaxCw, + (uint32_t (Txop::*) (void) const) &Txop::GetMaxCw), MakeUintegerChecker ()) - .AddAttribute ("Aifsn", "The AIFSN: the default value conforms to non-QOS.", + .AddAttribute ("Aifsn", "The AIFSN: the default value conforms to non-QOS (just for the first link, " + "in case of 11be multi-link devices).", + TypeId::ATTR_GET | TypeId::ATTR_SET, // do not set at construction time UintegerValue (2), - MakeUintegerAccessor (&Txop::SetAifsn, - &Txop::GetAifsn), + MakeUintegerAccessor ((void (Txop::*) (uint8_t)) &Txop::SetAifsn, + (uint8_t (Txop::*) (void) const) &Txop::GetAifsn), MakeUintegerChecker ()) .AddAttribute ("TxopLimit", "The TXOP limit: the default value conforms to non-QoS.", TimeValue (MilliSeconds (0)), @@ -77,7 +84,7 @@ Txop::GetTypeId (void) .AddTraceSource ("CwTrace", "Trace source for contention window values", MakeTraceSourceAccessor (&Txop::m_cwTrace), - "ns3::TracedValueCallback::Uint32") + "ns3::Txop::CwValueTracedCallback") ; return tid; } @@ -89,9 +96,6 @@ Txop::Txop () Txop::Txop (Ptr queue) : m_queue (queue), - m_cwMin (0), - m_cwMax (0), - m_cw (0), m_access (NOT_REQUESTED) { NS_LOG_FUNCTION (this); @@ -175,50 +179,86 @@ Txop::GetWifiMacQueue () const void Txop::SetMinCw (uint32_t minCw) { - NS_LOG_FUNCTION (this << minCw); - bool changed = (m_cwMin != minCw); - m_cwMin = minCw; + SetMinCw (minCw, 0); +} + +void +Txop::SetMinCws (std::vector minCws) +{ + NS_ABORT_IF (minCws.size () != m_links.size ()); + for (uint8_t linkId = 0; linkId < minCws.size (); linkId++) + { + SetMinCw (minCws[linkId], linkId); + } +} + +void +Txop::SetMinCw (uint32_t minCw, uint8_t linkId) +{ + NS_LOG_FUNCTION (this << minCw << +linkId); + auto& link = GetLink (linkId); + bool changed = (link.cwMin != minCw); + link.cwMin = minCw; if (changed == true) { - ResetCw (); + ResetCw (linkId); } } void Txop::SetMaxCw (uint32_t maxCw) { - NS_LOG_FUNCTION (this << maxCw); - bool changed = (m_cwMax != maxCw); - m_cwMax = maxCw; + SetMaxCw (maxCw, 0); +} + +void +Txop::SetMaxCws (std::vector maxCws) +{ + NS_ABORT_IF (maxCws.size () != m_links.size ()); + for (uint8_t linkId = 0; linkId < maxCws.size (); linkId++) + { + SetMaxCw (maxCws[linkId], linkId); + } +} + +void +Txop::SetMaxCw (uint32_t maxCw, uint8_t linkId) +{ + NS_LOG_FUNCTION (this << maxCw << +linkId); + auto& link = GetLink (linkId); + bool changed = (link.cwMax != maxCw); + link.cwMax = maxCw; if (changed == true) { - ResetCw (); + ResetCw (linkId); } } uint32_t -Txop::GetCw (void) const +Txop::GetCw (uint8_t linkId) const { - return m_cw; + return GetLink (linkId).cw; } void -Txop::ResetCw (void) +Txop::ResetCw (uint8_t linkId) { NS_LOG_FUNCTION (this); - m_cw = GetMinCw (); - m_cwTrace = m_cw; + auto& link = GetLink (linkId); + link.cw = GetMinCw (linkId); + m_cwTrace (link.cw, linkId); } void -Txop::UpdateFailedCw (void) +Txop::UpdateFailedCw (uint8_t linkId) { NS_LOG_FUNCTION (this); + auto& link = GetLink (linkId); //see 802.11-2012, section 9.19.2.5 - m_cw = std::min ( 2 * (m_cw + 1) - 1, GetMaxCw ()); + link.cw = std::min ( 2 * (link.cw + 1) - 1, GetMaxCw (linkId)); // 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; + link.cw = std::max (link.cw, GetMinCw (linkId)); + m_cwTrace (link.cw, linkId); } uint32_t @@ -265,8 +305,24 @@ Txop::StartBackoffNow (uint32_t nSlots, uint8_t linkId) void Txop::SetAifsn (uint8_t aifsn) { - NS_LOG_FUNCTION (this << +aifsn); - m_aifsn = aifsn; + SetAifsn (aifsn, 0); +} + +void +Txop::SetAifsns (std::vector aifsns) +{ + NS_ABORT_IF (aifsns.size () != m_links.size ()); + for (uint8_t linkId = 0; linkId < aifsns.size (); linkId++) + { + SetAifsn (aifsns[linkId], linkId); + } +} + +void +Txop::SetAifsn (uint8_t aifsn, uint8_t linkId) +{ + NS_LOG_FUNCTION (this << +aifsn << +linkId); + GetLink (linkId).aifsn = aifsn; } void @@ -280,19 +336,70 @@ Txop::SetTxopLimit (Time txopLimit) uint32_t Txop::GetMinCw (void) const { - return m_cwMin; + return GetMinCw (0); +} + +std::vector +Txop::GetMinCws (void) const +{ + std::vector ret; + for (uint8_t linkId = 0; linkId < m_links.size (); linkId++) + { + ret.push_back (GetMinCw (linkId)); + } + return ret; +} + +uint32_t +Txop::GetMinCw (uint8_t linkId) const +{ + return GetLink (linkId).cwMin; } uint32_t Txop::GetMaxCw (void) const { - return m_cwMax; + return GetMaxCw (0); +} + +std::vector +Txop::GetMaxCws (void) const +{ + std::vector ret; + for (uint8_t linkId = 0; linkId < m_links.size (); linkId++) + { + ret.push_back (GetMaxCw (linkId)); + } + return ret; +} + +uint32_t +Txop::GetMaxCw (uint8_t linkId) const +{ + return GetLink (linkId).cwMax; } uint8_t Txop::GetAifsn (void) const { - return m_aifsn; + return GetAifsn (0); +} + +std::vector +Txop::GetAifsns (void) const +{ + std::vector ret; + for (uint8_t linkId = 0; linkId < m_links.size (); linkId++) + { + ret.push_back (GetAifsn (linkId)); + } + return ret; +} + +uint8_t +Txop::GetAifsn (uint8_t linkId) const +{ + return GetLink (linkId).aifsn; } Time @@ -346,9 +453,9 @@ void Txop::DoInitialize () { NS_LOG_FUNCTION (this); - ResetCw (); for (uint8_t linkId = 0; linkId < m_links.size (); linkId++) { + ResetCw (linkId); GenerateBackoff (linkId); } } @@ -398,7 +505,7 @@ void Txop::GenerateBackoff (uint8_t linkId) { NS_LOG_FUNCTION (this << +linkId); - uint32_t backoff = m_rng->GetInteger (0, GetCw ()); + uint32_t backoff = m_rng->GetInteger (0, GetCw (linkId)); m_backoffTrace (backoff, linkId); StartBackoffNow (backoff, linkId); } diff --git a/src/wifi/model/txop.h b/src/wifi/model/txop.h index 73475f43b..94392b20f 100644 --- a/src/wifi/model/txop.h +++ b/src/wifi/model/txop.h @@ -24,6 +24,7 @@ #include "ns3/traced-value.h" #include "wifi-mac-header.h" #include +#include namespace ns3 { @@ -130,23 +131,71 @@ public: Ptr GetWifiMacQueue () const; /** - * Set the minimum contention window size. + * Set the minimum contention window size. For 11be multi-link devices, + * set the minimum contention window size on the first link. * * \param minCw the minimum contention window size. */ void SetMinCw (uint32_t minCw); /** - * Set the maximum contention window size. + * Set the minimum contention window size for each link. + * Note that the size of minCws must match the number + * of links. + * + * \param minCws the minimum contention window size values. + */ + void SetMinCws (std::vector minCws); + /** + * Set the minimum contention window size for the given link. + * + * \param minCw the minimum contention window size. + * \param linkId the ID of the given link + */ + void SetMinCw (uint32_t minCw, uint8_t linkId); + /** + * Set the maximum contention window size. For 11be multi-link devices, + * set the maximum contention window size on the first link. * * \param maxCw the maximum contention window size. */ void SetMaxCw (uint32_t maxCw); /** - * Set the number of slots that make up an AIFS. + * Set the maximum contention window size for each link. + * Note that the size of maxCws must match the number + * of links. + * + * \param maxCws the maximum contention window size values. + */ + void SetMaxCws (std::vector maxCws); + /** + * Set the maximum contention window size for the given link. + * + * \param maxCw the maximum contention window size. + * \param linkId the ID of the given link + */ + void SetMaxCw (uint32_t maxCw, uint8_t linkId); + /** + * Set the number of slots that make up an AIFS. For 11be multi-link devices, + * set the number of slots that make up an AIFS on the first link. * * \param aifsn the number of slots that make up an AIFS. */ void SetAifsn (uint8_t aifsn); + /** + * Set the number of slots that make up an AIFS for each link. + * Note that the size of aifsns must match the number + * of links. + * + * \param aifsns the number of slots that make up an AIFS for each link. + */ + void SetAifsns (std::vector aifsns); + /** + * Set the number of slots that make up an AIFS for the given link. + * + * \param aifsn the number of slots that make up an AIFS. + * \param linkId the ID of the given link + */ + void SetAifsn (uint8_t aifsn, uint8_t linkId); /** * Set the TXOP limit. * @@ -155,23 +204,65 @@ public: */ void SetTxopLimit (Time txopLimit); /** - * Return the minimum contention window size. + * Return the minimum contention window size. For 11be multi-link devices, + * return the minimum contention window size on the first link. * * \return the minimum contention window size. */ - virtual uint32_t GetMinCw (void) const; + uint32_t GetMinCw (void) const; /** - * Return the maximum contention window size. + * Return the minimum contention window size for each link. + * + * \return the minimum contention window size values. + */ + std::vector GetMinCws (void) const; + /** + * Return the minimum contention window size for the given link. + * + * \param linkId the ID of the given link + * \return the minimum contention window size. + */ + virtual uint32_t GetMinCw (uint8_t linkId) const; + /** + * Return the maximum contention window size. For 11be multi-link devices, + * return the maximum contention window size on the first link. * * \return the maximum contention window size. */ - virtual uint32_t GetMaxCw (void) const; + uint32_t GetMaxCw (void) const; /** - * Return the number of slots that make up an AIFS. + * Return the maximum contention window size for each link. + * + * \return the maximum contention window size values. + */ + std::vector GetMaxCws (void) const; + /** + * Return the maximum contention window size for the given link. + * + * \param linkId the ID of the given link + * \return the maximum contention window size. + */ + virtual uint32_t GetMaxCw (uint8_t linkId) const; + /** + * Return the number of slots that make up an AIFS. For 11be multi-link devices, + * return the number of slots that make up an AIFS on the first link. * * \return the number of slots that make up an AIFS. */ - virtual uint8_t GetAifsn (void) const; + uint8_t GetAifsn (void) const; + /** + * Return the number of slots that make up an AIFS for each link. + * + * \return the number of slots that make up an AIFS for each link. + */ + std::vector GetAifsns (void) const; + /** + * Return the number of slots that make up an AIFS for the given link. + * + * \param linkId the ID of the given link + * \return the number of slots that make up an AIFS. + */ + virtual uint8_t GetAifsn (uint8_t linkId) const; /** * Return the TXOP limit. * @@ -179,18 +270,22 @@ public: */ Time GetTxopLimit (void) const; /** - * Update the value of the CW variable to take into account + * Update the value of the CW variable for the given link to take into account * a transmission success or a transmission abort (stop transmission * of a packet after the maximum number of retransmissions has been * reached). By default, this resets the CW variable to minCW. + * + * \param linkId the ID of the given link */ - void ResetCw (void); + void ResetCw (uint8_t linkId); /** - * Update the value of the CW variable to take into account + * Update the value of the CW variable for the given link to take into account * a transmission failure. By default, this triggers a doubling * of CW (capped by maxCW). + * + * \param linkId the ID of the given link */ - void UpdateFailedCw (void); + void UpdateFailedCw (uint8_t linkId); /** * When sleep operation occurs, if there is a pending packet transmission, @@ -294,10 +389,13 @@ protected: void RequestAccess (void); /** - * \returns the current value of the CW variable. The initial value is - * minCW. + * Get the current value of the CW variable for the given link. The initial + * value is minCw. + * + * \param linkId the ID of the given link + * \return the current value of the CW variable for the given link */ - uint32_t GetCw (void) const; + uint32_t GetCw (uint8_t linkId) const; /** * Return the current number of backoff slots on the given link. * @@ -337,6 +435,10 @@ protected: track of the time at which a backoff was started or the time at which the backoff counter was last updated */ + uint32_t cw {0}; //!< the current contention window + uint32_t cwMin {0}; //!< the minimum contention window + uint32_t cwMax {0}; //!< the maximum contention window + uint8_t aifsn {0}; //!< the AIFSN }; /** @@ -359,19 +461,17 @@ protected: Ptr m_mac; //!< the wifi MAC Ptr m_rng; //!< the random stream - uint32_t m_cwMin; //!< the minimum contention window - uint32_t m_cwMax; //!< the maximum contention window - uint32_t m_cw; //!< the current contention window ChannelAccessStatus m_access; //!< channel access status - uint8_t m_aifsn; //!< the AIFSN Time m_txopLimit; //!< the TXOP limit time /// TracedCallback for backoff trace value typedef typedef TracedCallback BackoffValueTracedCallback; + /// TracedCallback for CW trace value typedef + typedef TracedCallback CwValueTracedCallback; BackoffValueTracedCallback m_backoffTrace; //!< backoff trace value - TracedValue m_cwTrace; //!< CW trace value + CwValueTracedCallback m_cwTrace; //!< CW trace value private: /** diff --git a/src/wifi/model/wifi-mac.cc b/src/wifi/model/wifi-mac.cc index faa4aa98f..7deda087a 100644 --- a/src/wifi/model/wifi-mac.cc +++ b/src/wifi/model/wifi-mac.cc @@ -600,9 +600,9 @@ WifiMac::ConfigureDcf (Ptr dcf, uint32_t cwmin, uint32_t cwmax, bool isDss switch (ac) { case AC_VO: - dcf->SetMinCw ((cwmin + 1) / 4 - 1); - dcf->SetMaxCw ((cwmin + 1) / 2 - 1); - dcf->SetAifsn (2); + dcf->SetMinCw ((cwmin + 1) / 4 - 1, SINGLE_LINK_OP_ID); + dcf->SetMaxCw ((cwmin + 1) / 2 - 1, SINGLE_LINK_OP_ID); + dcf->SetAifsn (2, SINGLE_LINK_OP_ID); if (isDsss) { dcf->SetTxopLimit (MicroSeconds (3264)); @@ -613,9 +613,9 @@ WifiMac::ConfigureDcf (Ptr dcf, uint32_t cwmin, uint32_t cwmax, bool isDss } break; case AC_VI: - dcf->SetMinCw ((cwmin + 1) / 2 - 1); - dcf->SetMaxCw (cwmin); - dcf->SetAifsn (2); + dcf->SetMinCw ((cwmin + 1) / 2 - 1, SINGLE_LINK_OP_ID); + dcf->SetMaxCw (cwmin, SINGLE_LINK_OP_ID); + dcf->SetAifsn (2, SINGLE_LINK_OP_ID); if (isDsss) { dcf->SetTxopLimit (MicroSeconds (6016)); @@ -626,21 +626,21 @@ WifiMac::ConfigureDcf (Ptr dcf, uint32_t cwmin, uint32_t cwmax, bool isDss } break; case AC_BE: - dcf->SetMinCw (cwmin); - dcf->SetMaxCw (cwmax); - dcf->SetAifsn (3); + dcf->SetMinCw (cwmin, SINGLE_LINK_OP_ID); + dcf->SetMaxCw (cwmax, SINGLE_LINK_OP_ID); + dcf->SetAifsn (3, SINGLE_LINK_OP_ID); dcf->SetTxopLimit (MicroSeconds (0)); break; case AC_BK: - dcf->SetMinCw (cwmin); - dcf->SetMaxCw (cwmax); - dcf->SetAifsn (7); + dcf->SetMinCw (cwmin, SINGLE_LINK_OP_ID); + dcf->SetMaxCw (cwmax, SINGLE_LINK_OP_ID); + dcf->SetAifsn (7, SINGLE_LINK_OP_ID); dcf->SetTxopLimit (MicroSeconds (0)); break; case AC_BE_NQOS: - dcf->SetMinCw (cwmin); - dcf->SetMaxCw (cwmax); - dcf->SetAifsn (2); + dcf->SetMinCw (cwmin, SINGLE_LINK_OP_ID); + dcf->SetMaxCw (cwmax, SINGLE_LINK_OP_ID); + dcf->SetAifsn (2, SINGLE_LINK_OP_ID); dcf->SetTxopLimit (MicroSeconds (0)); break; case AC_BEACON: diff --git a/src/wifi/test/channel-access-manager-test.cc b/src/wifi/test/channel-access-manager-test.cc index ee6cec1eb..6b6b6dbb8 100644 --- a/src/wifi/test/channel-access-manager-test.cc +++ b/src/wifi/test/channel-access-manager-test.cc @@ -592,13 +592,13 @@ void ChannelAccessManagerTest::AddTxop (uint32_t aifsn) { Ptr> txop = CreateObject> (this, m_txop.size ()); - txop->SetAifsn (aifsn); m_txop.push_back (txop); m_ChannelAccessManager->Add (txop); // the following causes the creation of a link for the txop object auto mac = CreateObject (); mac->SetWifiPhys ({nullptr}); txop->SetWifiMac (mac); + txop->SetAifsn (aifsn); } template diff --git a/src/wifi/test/wifi-mac-ofdma-test.cc b/src/wifi/test/wifi-mac-ofdma-test.cc index a86567cac..e3e5c717f 100644 --- a/src/wifi/test/wifi-mac-ofdma-test.cc +++ b/src/wifi/test/wifi-mac-ofdma-test.cc @@ -361,10 +361,9 @@ public: /** * Function to trace CW value used by the given station after the MU exchange * \param staIndex the index of the given station - * \param oldCw the previous Contention Window value * \param cw the current Contention Window value */ - void TraceCw (uint32_t staIndex, uint32_t oldCw, uint32_t cw); + void TraceCw (uint32_t staIndex, uint32_t cw, uint8_t /* linkId */); /** * Callback invoked when FrameExchangeManager passes PSDUs to the PHY * \param context the context @@ -444,7 +443,7 @@ OfdmaAckSequenceTest::L7Receive (std::string context, Ptr p, const } void -OfdmaAckSequenceTest::TraceCw (uint32_t staIndex, uint32_t oldCw, uint32_t cw) +OfdmaAckSequenceTest::TraceCw (uint32_t staIndex, uint32_t cw, uint8_t /* linkId */) { if (m_cwValues.at (staIndex) == 2) { @@ -1268,7 +1267,7 @@ OfdmaAckSequenceTest::DoRun (void) Simulator::Run (); CheckResults (dev->GetMac ()->GetWifiPhy ()->GetSifs (), dev->GetMac ()->GetWifiPhy ()->GetSlot (), - apBeQosTxop->GetAifsn ()); + apBeQosTxop->Txop::GetAifsn ()); Simulator::Destroy (); } diff --git a/src/wifi/test/wifi-txop-test.cc b/src/wifi/test/wifi-txop-test.cc index d1f03c7d5..77c0a7ee2 100644 --- a/src/wifi/test/wifi-txop-test.cc +++ b/src/wifi/test/wifi-txop-test.cc @@ -224,8 +224,8 @@ WifiTxopTest::DoRun (void) PointerValue ptr; dev->GetMac ()->GetAttribute ("BE_Txop", ptr); ptr.Get ()->SetTxopLimit (m_txopLimit); - m_aifsn = ptr.Get ()->GetAifsn (); - m_cwMin = ptr.Get ()->GetMinCw (); + m_aifsn = ptr.Get ()->Txop::GetAifsn (); + m_cwMin = ptr.Get ()->Txop::GetMinCw (); PacketSocketHelper packetSocket; packetSocket.Install (wifiApNode);