19#include "ns3/attribute-container.h"
21#include "ns3/pointer.h"
22#include "ns3/shuffle.h"
23#include "ns3/simulator.h"
24#include "ns3/socket.h"
29#undef NS_LOG_APPEND_CONTEXT
30#define NS_LOG_APPEND_CONTEXT WIFI_TXOP_NS_LOG_APPEND_CONTEXT
46 .AddConstructor<
Txop>()
47 .AddAttribute(
"AcIndex",
48 "The AC index of the packets contained in the wifi MAC queue of this "
68 .AddAttribute(
"MinCw",
69 "The minimum value of the contention window (just for the first link, "
70 "in case of 11be multi-link devices).",
77 "Use MinCws attribute instead of MinCw")
80 "The minimum values of the contention window for all the links (sorted in "
81 "increasing order of link ID). An empty vector is ignored and the default value "
82 "as per Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if "
83 "this is a non-AP STA, these values could be overridden by values advertised by "
84 "the AP through EDCA Parameter Set elements.",
88 .AddAttribute(
"MaxCw",
89 "The maximum value of the contention window (just for the first link, "
90 "in case of 11be multi-link devices).",
97 "Use MaxCws attribute instead of MaxCw")
100 "The maximum values of the contention window for all the links (sorted in "
101 "increasing order of link ID). An empty vector is ignored and the default value "
102 "as per Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if "
103 "this is a non-AP STA, these values could be overridden by values advertised by "
104 "the AP through EDCA Parameter Set elements.",
110 "The AIFSN: the default value conforms to non-QOS (just for the first link, "
111 "in case of 11be multi-link devices).",
118 "Use Aifsns attribute instead of Aifsn")
121 "The values of AIFSN for all the links (sorted in increasing order "
122 "of link ID). An empty vector is ignored and the default value as per "
123 "Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if "
124 "this is a non-AP STA, these values could be overridden by values advertised by "
125 "the AP through EDCA Parameter Set elements.",
129 .AddAttribute(
"TxopLimit",
130 "The TXOP limit: the default value conforms to non-QoS "
131 "(just for the first link, in case of 11be multi-link devices).",
138 "Use TxopLimits attribute instead of TxopLimit")
141 "The values of TXOP limit for all the links (sorted in increasing order "
142 "of link ID). An empty vector is ignored and the default value as per "
143 "Table 9-155 of the IEEE 802.11-2020 standard will be used. Note that, if "
144 "this is a non-AP STA, these values could be overridden by values advertised by "
145 "the AP through EDCA Parameter Set elements.",
150 .AddAttribute(
"Queue",
151 "The WifiMacQueue object",
155 .AddTraceSource(
"BackoffTrace",
156 "Trace source for backoff values",
158 "ns3::Txop::BackoffValueTracedCallback")
159 .AddTraceSource(
"CwTrace",
160 "Trace source for contention window values",
162 "ns3::Txop::CwValueTracedCallback");
196std::unique_ptr<Txop::LinkEntity>
199 return std::make_unique<LinkEntity>();
205 auto it =
m_links.find(linkId);
211const std::map<uint8_t, std::unique_ptr<Txop::LinkEntity>>&
224 for (
const auto& [from, to] : links)
226 auto nh = tmp.extract(from);
246 for (
const auto linkId :
m_mac->GetLinkIds())
257 m_queue->TraceConnectWithoutContext(
"DropBeforeEnqueue",
259 m_queue->TraceConnectWithoutContext(
"Expired",
285 "The size of the given vector (" << minCws.size()
286 <<
") does not match the number of links ("
291 for (
const auto& [
id, link] :
m_links)
302 "This function can only be called after that links have been created");
304 bool changed = (link.cwMin != minCw);
328 "The size of the given vector (" << maxCws.size()
329 <<
") does not match the number of links ("
334 for (
const auto& [
id, link] :
m_links)
345 "This function can only be called after that links have been created");
347 bool changed = (link.cwMax != maxCw);
374 link.staRetryCount = 0;
383 if (link.staRetryCount <
m_mac->GetFrameRetryLimit())
389 ++link.staRetryCount;
391 std::min(
GetMaxCw(linkId), (1 << link.staRetryCount) * (
GetMinCw(linkId) + 1) - 1);
398 link.staRetryCount = 0;
423 link.backoffSlots -= nSlots;
424 link.backoffStart = backoffUpdateBound;
425 NS_LOG_DEBUG(
"update slots=" << nSlots <<
" slots, backoff=" << link.backoffSlots);
434 if (link.backoffSlots != 0)
436 NS_LOG_DEBUG(
"reset backoff from " << link.backoffSlots <<
" to " << nSlots <<
" slots");
442 link.backoffSlots = nSlots;
462 "The size of the given vector (" << aifsns.size()
463 <<
") does not match the number of links ("
468 for (
const auto& [
id, link] :
m_links)
479 "This function can only be called after that links have been created");
492 if (txopLimits.empty())
499 "The size of the given vector (" << txopLimits.size()
500 <<
") does not match the number of links ("
505 for (
const auto& [
id, link] :
m_links)
517 "The TXOP limit must be expressed in multiple of 32 microseconds!");
519 "This function can only be called after that links have been created");
538 std::vector<uint32_t> ret;
540 for (
const auto& [
id, link] :
m_links)
542 ret.push_back(link->cwMin);
562 std::vector<uint32_t> ret;
564 for (
const auto& [
id, link] :
m_links)
566 ret.push_back(link->cwMax);
586 std::vector<uint8_t> ret;
588 for (
const auto& [
id, link] :
m_links)
590 ret.push_back(link->aifsn);
610 std::vector<Time> ret;
612 for (
const auto& [
id, link] :
m_links)
614 ret.push_back(link->txopLimit);
628 m_queue->WipeAllExpiredMpdus();
629 bool ret =
static_cast<bool>(
m_queue->Peek(linkId));
641 auto linkIds =
m_mac->GetMacQueueScheduler()->GetLinkIds(
644 {WifiQueueBlockedReason::USING_OTHER_EMLSR_LINK,
645 WifiQueueBlockedReason::WAITING_EMLSR_TRANSITION_DELAY});
648 for (
auto it = linkIds.begin(); it != linkIds.end();)
652 it = linkIds.erase(it);
662 std::map<uint8_t, bool> hasFramesToTransmit;
663 for (
const auto linkId : linkIds)
670 std::vector<uint8_t> shuffledLinkIds(linkIds.cbegin(), linkIds.cend());
675 std::stringstream ss;
676 std::copy(shuffledLinkIds.cbegin(),
677 shuffledLinkIds.cend(),
678 std::ostream_iterator<uint16_t>(ss,
" "));
679 NS_LOG_DEBUG(
"Request channel access on link IDs: " << ss.str());
682 for (
const auto linkId : shuffledLinkIds)
691 hasFramesToTransmit.at(linkId),
700 m_rng->SetStream(stream);
707 NS_LOG_FUNCTION(
this << linkId << hadFramesToTransmit << checkMediumBusy);
709 if (!
m_mac->GetWifiPhy(linkId))
717 NS_LOG_DEBUG(
"Channel access already requested or granted on link " << +linkId);
723 NS_LOG_DEBUG(
"No frames to transmit on link " << +linkId);
727 if (
m_mac->GetChannelAccessManager(linkId)->NeedBackoffUponAccess(
this,
734 m_mac->GetChannelAccessManager(linkId)->RequestAccess(
this);
741 for (
const auto& [
id, link] :
m_links)
786 m_mac->GetChannelAccessManager(linkId)->RequestAccess(
this);
824 for (
const auto& [
id, link] :
m_links)
A container for one type of attribute.
auto Bind(BoundArgs &&... bargs)
Bind a variable number of arguments.
Hold variables of type enum.
A base class which provides memory management and object aggregation.
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
static Time Now()
Return the current simulation virtual time.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Simulation virtual time values and global simulation resolution.
bool IsPositive() const
Exactly equivalent to t >= 0.
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
AttributeValue implementation for Time.
Handles the packet queue and stores DCF/EDCA access parameters (one Txop per AC).
Ptr< WifiMac > m_mac
the wifi MAC
Time GetTxopLimit() const
Return the TXOP limit.
virtual std::unique_ptr< LinkEntity > CreateLinkEntity() const
Create a LinkEntity object.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
virtual ChannelAccessStatus GetAccessStatus(uint8_t linkId) const
Ptr< WifiMacQueue > m_queue
the wifi MAC queue
void StartAccessAfterEvent(uint8_t linkId, bool hadFramesToTransmit, bool checkMediumBusy)
Request channel access on the given link after the occurrence of an event that possibly requires to g...
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the Txop has frames to transmit over the given link.
virtual void NotifyOff()
When off operation occurs, the queue gets cleaned up.
UniformRandomBitGenerator m_shuffleLinkIdsGen
random number generator to shuffle link IDs
std::size_t GetStaRetryCount(uint8_t linkId) const
Get the Station Short Retry Count (SSRC) maintained by non-QoS stations or the QoS STA Retry Count (Q...
Ptr< UniformRandomVariable > m_rng
the random stream
CwValueTracedCallback m_cwTrace
CW trace value.
void DoDispose() override
Destructor implementation.
void SetMaxCw(uint32_t maxCw)
Set the maximum contention window size.
void SetMaxCws(const std::vector< uint32_t > &maxCws)
Set the maximum contention window size for each link.
uint32_t GetMinCw() const
Return the minimum contention window size.
ChannelAccessStatus
Enumeration for channel access status.
virtual void NotifyOn()
When on operation occurs, channel access will be started.
void UpdateFailedCw(uint8_t linkId)
Update the value of the CW variable for the given link to take into account a transmission failure.
void SetAifsns(const std::vector< uint8_t > &aifsns)
Set the number of slots that make up an AIFS for each link.
static constexpr bool DIDNT_HAVE_FRAMES_TO_TRANSMIT
no packet available for transmission was in the queue
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
virtual void SetWifiMac(const Ptr< WifiMac > mac)
Set the wifi MAC this Txop is associated to.
virtual void NotifyWakeUp(uint8_t linkId)
When wake up operation occurs on a link, channel access on that link will be restarted.
virtual void NotifyChannelReleased(uint8_t linkId)
Called by the FrameExchangeManager to notify the completion of the transmissions.
std::vector< uint32_t > GetMaxCws() const
Return the maximum contention window size for each link.
virtual void Queue(Ptr< WifiMpdu > mpdu)
void SetTxopLimit(Time txopLimit)
Set the TXOP limit.
virtual void CreateQueue(AcIndex aci)
Create a wifi MAC queue containing packets of the given AC.
void ResetCw(uint8_t linkId)
Update the value of the CW variable for the given link to take into account a transmission success or...
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
virtual bool IsQosTxop() const
Check for QoS TXOP.
std::vector< uint32_t > GetMinCws() const
Return the minimum contention window size for each link.
std::vector< uint8_t > GetAifsns() const
Return the number of slots that make up an AIFS for each link.
void UpdateBackoffSlotsNow(uint32_t nSlots, Time backoffUpdateBound, uint8_t linkId)
Update backoff slots for the given link that nSlots has passed.
Time GetBackoffStart(uint8_t linkId) const
Return the time when the backoff procedure started on the given link.
void SetTxopLimits(const std::vector< Time > &txopLimits)
Set the TXOP limit for each link.
DroppedMpdu m_droppedMpduCallback
the dropped MPDU callback
void SwapLinks(std::map< uint8_t, uint8_t > links)
Swap the links based on the information included in the given map.
const UserDefinedAccessParams & GetUserAccessParams() const
void SetTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set MacTxMiddle this Txop is associated to.
std::vector< Time > GetTxopLimits() const
Return the TXOP limit for each link.
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
static TypeId GetTypeId()
Get the type ID.
void SetAifsn(uint8_t aifsn)
Set the number of slots that make up an AIFS.
uint32_t GetCw(uint8_t linkId) const
Get the current value of the CW variable for the given link.
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
UserDefinedAccessParams m_userAccessParams
user-defined DCF/EDCA access parameters
virtual void GenerateBackoff(uint8_t linkId)
Generate a new backoff for the given link now.
BackoffValueTracedCallback m_backoffTrace
backoff trace value
virtual void NotifyAccessRequested(uint8_t linkId)
Notify that access request has been received for the given link.
Ptr< MacTxMiddle > m_txMiddle
the MacTxMiddle
static constexpr bool CHECK_MEDIUM_BUSY
generation of backoff (also) depends on the busy/idle state of the medium
void StartBackoffNow(uint32_t nSlots, uint8_t linkId)
virtual void NotifyChannelAccessed(uint8_t linkId, Time txopDuration=Seconds(0))
Called by the FrameExchangeManager to notify that channel access has been granted on the given link f...
std::map< uint8_t, std::unique_ptr< LinkEntity > > m_links
ID-indexed map of LinkEntity objects.
void SetMinCws(const std::vector< uint32_t > &minCws)
Set the minimum contention window size for each link.
void RequestAccess(uint8_t linkId)
Request access to the ChannelAccessManager associated with the given link.
void SetMinCw(uint32_t minCw)
Set the minimum contention window size.
uint8_t GetAifsn() const
Return the number of slots that make up an AIFS.
uint32_t GetBackoffSlots(uint8_t linkId) const
Return the current number of backoff slots on the given link.
virtual void NotifySleep(uint8_t linkId)
Notify that the given link switched to sleep mode.
static constexpr bool DONT_CHECK_MEDIUM_BUSY
generation of backoff is independent of the busy/idle state of the medium
uint32_t GetMaxCw() const
Return the maximum contention window size.
void DoInitialize() override
Initialize() implementation.
a unique identifier for an interface.
@ ATTR_GET
The attribute can be read.
@ ATTR_SET
The attribute can be written.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
@ OBSOLETE
Attribute or trace source is not used anymore; simulation fails.
Hold an unsigned integer type.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Ptr< AttributeChecker > MakeAttributeContainerChecker()
Make uninitialized AttributeContainerChecker using explicit types.
Ptr< const AttributeAccessor > MakeAttributeContainerAccessor(T1 a1)
Make AttributeContainerAccessor using explicit types.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Ptr< const AttributeChecker > MakeUintegerChecker()
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
@ WIFI_MAC_DROP_FAILED_ENQUEUE
@ WIFI_MAC_DROP_EXPIRED_LIFETIME
@ AC_UNDEF
Total number of ACs.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
void Shuffle(RND_ACCESS_ITER first, RND_ACCESS_ITER last, Ptr< UniformRandomVariable > rv)
Shuffle the elements in the range first to last.
@ LOG_DEBUG
Full voluminous logging to support debugging.
Structure holding information specific to a single link.
class ns3::Txop::LinkEntity::@72 accessRequest
access request event, to be used by Txop::Queue() only
ChannelAccessStatus access
channel access status
uint32_t cw
the current contention window
std::size_t staRetryCount
the Station Short Retry Count (SSRC) maintained by non-QoS stations or the QoS STA Retry Count (QSRC)...
uint32_t cwMax
the maximum contention window
Time txopLimit
the TXOP limit time
Time backoffStart
the backoffStart variable is used to keep track of the time at which a backoff was started or the tim...
uint32_t cwMin
the minimum contention window
uint32_t backoffSlots
the number of backoff slots
DCF/EDCA access parameters for all the links provided by users via this class' attributes or the corr...
std::vector< uint32_t > cwMins
the minimum contention window values for all the links
std::vector< uint8_t > aifsns
the AIFSN values for all the links
std::vector< uint32_t > cwMaxs
the maximum contention window values for all the links
std::vector< Time > txopLimits
TXOP limit values for all the links.