wifi: Txop holds per-link contention window information

This commit is contained in:
Stefano Avallone
2022-02-28 17:39:33 +01:00
committed by Stefano Avallone
parent 18eb7e47a0
commit 262918d22c
16 changed files with 468 additions and 217 deletions

View File

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

View File

@@ -600,12 +600,12 @@ TracePacketReception (std::string context, Ptr<const Packet> 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;
}
}

View File

@@ -106,9 +106,6 @@ ApWifiMac::ApWifiMac ()
{
NS_LOG_FUNCTION (this);
m_beaconTxop = CreateObject<Txop> (CreateObject<WifiMacQueue> (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<uint8_t> (GetNLinks (), 1));
m_beaconTxop->SetMinCws (std::vector<uint32_t> (GetNLinks (), 0));
m_beaconTxop->SetMaxCws (std::vector<uint32_t> (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<uint16_t> (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<uint16_t> (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<uint16_t> (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<uint16_t> (txopLimit.GetMicroSeconds () / 32));
edcaParameters.SetQosInfo (0);

View File

@@ -302,7 +302,7 @@ ChannelAccessManager::NeedBackoffUponAccess (Ptr<Txop> 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> 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> txop = *i;
if (txop->GetAccessStatus () == Txop::REQUESTED
&& (!txop->IsQosTxop () || !StaticCast<QosTxop> (txop)->EdcaDisabled ())
&& (!txop->IsQosTxop () || !StaticCast<QosTxop> (txop)->EdcaDisabled (m_linkId))
&& GetBackoffEndFor (txop) <= Simulator::Now () )
{
/**
@@ -478,7 +478,7 @@ ChannelAccessManager::GetBackoffStartFor (Ptr<Txop> 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 ();
}

View File

@@ -797,14 +797,14 @@ FrameExchangeManager::NormalAckTimeout (Ptr<WifiMacQueueItem> 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<WifiPsdu> 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> 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<WifiMacQueueItem> 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 ())
{

View File

@@ -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<WifiMacQueueItem> 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<WifiMacQueueItem> 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<WifiMacQueueItem> 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<WifiMacQueueItem> 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<const WifiPsdu> 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<const WifiPsdu> psdu, const RxSigna
NS_ASSERT (m_edca != 0);
m_psduMap.clear ();
m_edca->ResetCw ();
m_edca->ResetCw (m_linkId);
TransmissionSucceeded ();
}

View File

@@ -1114,11 +1114,11 @@ HtFrameExchangeManager::BlockAckTimeout (Ptr<WifiPsdu> 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<WifiMacQueueItem> mpdu, RxSignalInfo rx
m_channelAccessManager->NotifyAckTimeoutResetNow ();
// Reset the CW
m_edca->ResetCw ();
m_edca->ResetCw (m_linkId);
m_psdu = 0;
TransmissionSucceeded ();

View File

@@ -94,12 +94,7 @@ QosTxop::QosTxop (AcIndex ac)
: Txop (CreateObject<WifiMacQueue> (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<QosBlockedDestinations> ();
@@ -128,6 +123,18 @@ QosTxop::DoDispose (void)
Txop::DoDispose ();
}
std::unique_ptr<Txop::LinkEntity>
QosTxop::CreateLinkEntity (void) const
{
return std::make_unique<QosLinkEntity> ();
}
QosTxop::QosLinkEntity&
QosTxop::GetLink (uint8_t linkId) const
{
return static_cast<QosLinkEntity&> (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<BlockAckManager>

View File

@@ -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<LinkEntity> 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<Time, Time> m_txopTrace; //!< TXOP trace callback
};

View File

@@ -1181,9 +1181,9 @@ void
StaWifiMac::SetEdcaParameters (AcIndex ac, uint32_t cwMin, uint32_t cwMax, uint8_t aifsn, Time txopLimit)
{
Ptr<QosTxop> 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<QosTxop> 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

View File

@@ -46,20 +46,27 @@ Txop::GetTypeId (void)
.SetParent<ns3::Object> ()
.SetGroupName ("Wifi")
.AddConstructor<Txop> ()
.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<uint32_t> ())
.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<uint32_t> ())
.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<uint8_t> ())
.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<WifiMacQueue> 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<uint32_t> 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<uint32_t> 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<uint8_t> 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<uint32_t>
Txop::GetMinCws (void) const
{
std::vector<uint32_t> 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<uint32_t>
Txop::GetMaxCws (void) const
{
std::vector<uint32_t> 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<uint8_t>
Txop::GetAifsns (void) const
{
std::vector<uint8_t> 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);
}

View File

@@ -24,6 +24,7 @@
#include "ns3/traced-value.h"
#include "wifi-mac-header.h"
#include <memory>
#include <vector>
namespace ns3 {
@@ -130,23 +131,71 @@ public:
Ptr<WifiMacQueue > 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 <i>minCws</i> must match the number
* of links.
*
* \param minCws the minimum contention window size values.
*/
void SetMinCws (std::vector<uint32_t> 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 <i>maxCws</i> must match the number
* of links.
*
* \param maxCws the maximum contention window size values.
*/
void SetMaxCws (std::vector<uint32_t> 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 <i>aifsns</i> must match the number
* of links.
*
* \param aifsns the number of slots that make up an AIFS for each link.
*/
void SetAifsns (std::vector<uint8_t> 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<uint32_t> 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<uint32_t> 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<uint8_t> 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<WifiMac> m_mac; //!< the wifi MAC
Ptr<UniformRandomVariable> 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<uint32_t /* value */, uint8_t /* linkId */> BackoffValueTracedCallback;
/// TracedCallback for CW trace value typedef
typedef TracedCallback<uint32_t /* value */, uint8_t /* linkId */> CwValueTracedCallback;
BackoffValueTracedCallback m_backoffTrace; //!< backoff trace value
TracedValue<uint32_t> m_cwTrace; //!< CW trace value
CwValueTracedCallback m_cwTrace; //!< CW trace value
private:
/**

View File

@@ -600,9 +600,9 @@ WifiMac::ConfigureDcf (Ptr<Txop> 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<Txop> 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<Txop> 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:

View File

@@ -592,13 +592,13 @@ void
ChannelAccessManagerTest<TxopType>::AddTxop (uint32_t aifsn)
{
Ptr<TxopTest<TxopType>> txop = CreateObject<TxopTest<TxopType>> (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<AdhocWifiMac> ();
mac->SetWifiPhys ({nullptr});
txop->SetWifiMac (mac);
txop->SetAifsn (aifsn);
}
template <typename TxopType>

View File

@@ -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<const Packet> 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 ();
}

View File

@@ -224,8 +224,8 @@ WifiTxopTest::DoRun (void)
PointerValue ptr;
dev->GetMac ()->GetAttribute ("BE_Txop", ptr);
ptr.Get<QosTxop> ()->SetTxopLimit (m_txopLimit);
m_aifsn = ptr.Get<QosTxop> ()->GetAifsn ();
m_cwMin = ptr.Get<QosTxop> ()->GetMinCw ();
m_aifsn = ptr.Get<QosTxop> ()->Txop::GetAifsn ();
m_cwMin = ptr.Get<QosTxop> ()->Txop::GetMinCw ();
PacketSocketHelper packetSocket;
packetSocket.Install (wifiApNode);