A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
multi-user-scheduler.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stavallo@unina.it>
7 */
8
10
11#include "he-configuration.h"
13
14#include "ns3/abort.h"
15#include "ns3/log.h"
16#include "ns3/qos-txop.h"
17#include "ns3/wifi-acknowledgment.h"
18#include "ns3/wifi-mac-trailer.h"
19#include "ns3/wifi-protection.h"
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("MultiUserScheduler");
25
26NS_OBJECT_ENSURE_REGISTERED(MultiUserScheduler);
27
28TypeId
30{
31 static TypeId tid =
32 TypeId("ns3::MultiUserScheduler")
34 .SetGroupName("Wifi")
35 .AddAttribute("AccessReqInterval",
36 "Duration of the interval between two consecutive requests for "
37 "channel access made by the MultiUserScheduler. Such requests are "
38 "made independently of the presence of frames in the queues of the "
39 "AP and are intended to allow the AP to coordinate UL MU transmissions "
40 "even without DL traffic. A null duration indicates that such "
41 "requests shall not be made.",
46 .AddAttribute("AccessReqAc",
47 "The Access Category for which the MultiUserScheduler makes requests "
48 "for channel access.",
52 "AC_BE",
54 "AC_VI",
56 "AC_VO",
58 "AC_BK"))
59 .AddAttribute("DelayAccessReqUponAccess",
60 "If enabled, the access request interval is measured starting "
61 "from the last time an EDCA function obtained channel access. "
62 "Otherwise, the access request interval is measured starting "
63 "from the last time the MultiUserScheduler made a request for "
64 "channel access.",
65 BooleanValue(true),
68 .AddAttribute("DefaultTbPpduDuration",
69 "Default duration of TB PPDUs solicited via a Basic Trigger Frame. "
70 "This value is used to compute the Duration/ID field of BSRP Trigger "
71 "Frames sent when the TXOP Limit is zero and the FrameExchangeManager "
72 "continues the TXOP a SIFS after receiving response to the BSRP TF. "
73 "This value shall also be used by subclasses when they have no other "
74 "information available to determine the TX duration of solicited PPDUs. "
75 "The default value roughly corresponds to half the maximum PPDU TX "
76 "duration.",
80 return tid;
81}
82
84 : m_isUnprotectedEmlsrClient([this](uint8_t linkId, Mac48Address address) {
85 return m_apMac->GetWifiRemoteStationManager(linkId)->GetEmlsrEnabled(address) &&
86 !m_apMac->GetFrameExchangeManager(linkId)->GetProtectedStas().contains(address);
87 })
88{
89}
90
95
96void
98{
99 NS_LOG_FUNCTION(this);
100 m_apMac = nullptr;
101 m_edca = nullptr;
102 m_lastTxInfo.clear();
103 for (auto& accessReqTimer : m_accessReqTimers)
104 {
105 accessReqTimer.Cancel();
106 }
108}
109
110void
112{
113 NS_LOG_FUNCTION(this);
114 if (!m_apMac)
115 {
116 Ptr<ApWifiMac> apMac = this->GetObject<ApWifiMac>();
117 // verify that it's a valid AP mac and that
118 // the AP mac was not set before
119 if (apMac)
120 {
121 this->SetWifiMac(apMac);
122 }
123 }
125}
126
127void
129{
130 NS_LOG_FUNCTION(this);
131
133 {
135 for (uint8_t id = 0; id < m_apMac->GetNLinks(); ++id)
136 {
137 m_accessReqTimers.emplace_back(
140 this,
141 id));
142 }
143 }
144}
145
146void
148{
149 NS_LOG_FUNCTION(this << interval.As(Time::MS));
150 m_accessReqInterval = interval;
151 // if interval is non-zero, start the timers that are not running if we are past initialization
153 {
154 m_accessReqTimers.resize(m_apMac->GetNLinks());
155 for (uint8_t id = 0; id < m_apMac->GetNLinks(); ++id)
156 {
157 if (!m_accessReqTimers[id].IsPending())
158 {
161 this,
162 id);
163 }
164 }
165 }
166}
167
168Time
173
174void
176{
177 NS_LOG_FUNCTION(this << mac);
178 m_apMac = mac;
179
180 // When VHT DL MU-MIMO will be supported, we will have to lower this requirement
181 // and allow a Multi-user scheduler to be installed on a VHT AP.
182 NS_ABORT_MSG_IF(!m_apMac || !m_apMac->GetHeConfiguration(),
183 "MultiUserScheduler can only be installed on HE APs");
184
185 for (uint8_t linkId = 0; linkId < m_apMac->GetNLinks(); linkId++)
186 {
187 auto heFem = DynamicCast<HeFrameExchangeManager>(m_apMac->GetFrameExchangeManager(linkId));
188 NS_ASSERT(heFem);
189 heFem->SetMultiUserScheduler(this);
190 }
191}
192
195{
196 return m_apMac->GetWifiRemoteStationManager(linkId);
197}
198
200MultiUserScheduler::GetHeFem(uint8_t linkId) const
201{
202 return StaticCast<HeFrameExchangeManager>(m_apMac->GetFrameExchangeManager(linkId));
203}
204
205Time
210
211void
213{
214 NS_LOG_FUNCTION(this << linkId);
215
216 // request channel access if not requested yet
217 auto edca = m_apMac->GetQosTxop(m_accessReqAc);
218
219 if (edca->GetAccessStatus(linkId) == Txop::NOT_REQUESTED)
220 {
221 m_apMac->GetChannelAccessManager(linkId)->RequestAccess(edca);
222 }
223
224 // restart timer
226 {
227 NS_ASSERT(m_accessReqTimers.size() > linkId);
230 this,
231 linkId);
232 }
233}
234
237 Time availableTime,
238 bool initialFrame,
239 MHz_u allowedWidth,
240 uint8_t linkId)
241{
242 NS_LOG_FUNCTION(this << edca << availableTime << initialFrame << allowedWidth << linkId);
243
244 m_edca = edca;
245 m_availableTime = availableTime;
246 m_initialFrame = initialFrame;
247 m_allowedWidth = allowedWidth;
248 m_linkId = linkId;
249
250 if (m_accessReqTimers.size() > linkId && m_accessReqTimers[linkId].IsPending() &&
252 {
253 // restart access timer
254 m_accessReqTimers[linkId].Cancel();
256 {
259 this,
260 linkId);
261 }
262 }
263
264 TxFormat txFormat = SelectTxFormat();
265
266 if (txFormat == DL_MU_TX)
267 {
268 m_lastTxInfo[linkId].dlInfo = ComputeDlMuInfo();
269 }
270 else if (txFormat == UL_MU_TX)
271 {
272 m_lastTxInfo[linkId].ulInfo = ComputeUlMuInfo();
274 }
275
276 if (txFormat != NO_TX)
277 {
278 m_lastTxInfo[linkId].lastTxFormat = txFormat;
279 }
280 return txFormat;
281}
282
285{
286 const auto it = m_lastTxInfo.find(linkId);
287 return it != m_lastTxInfo.cend() ? it->second.lastTxFormat : NO_TX;
288}
289
292{
293 NS_ABORT_MSG_IF(m_lastTxInfo[linkId].lastTxFormat != DL_MU_TX,
294 "Next transmission is not DL MU");
295
296#ifdef NS3_BUILD_PROFILE_DEBUG
297 // check that all the addressed stations support HE
298 for (auto& psdu : m_lastTxInfo[linkId].dlInfo.psduMap)
299 {
300 auto receiver = psdu.second->GetAddr1();
301 auto linkId = m_apMac->IsAssociated(receiver);
302 NS_ABORT_MSG_IF(!linkId, "Station " << receiver << " should be associated");
303 NS_ABORT_MSG_IF(!GetWifiRemoteStationManager(*linkId)->GetHeSupported(receiver),
304 "Station " << psdu.second->GetAddr1() << " does not support HE");
305 }
306#endif
307
308 return m_lastTxInfo[linkId].dlInfo;
309}
310
313{
314 NS_ABORT_MSG_IF(m_lastTxInfo[linkId].lastTxFormat != UL_MU_TX,
315 "Next transmission is not UL MU");
316
317 return m_lastTxInfo[linkId].ulInfo;
318}
319
321MultiUserScheduler::GetTriggerFrame(const CtrlTriggerHeader& trigger, uint8_t linkId) const
322{
323 NS_LOG_FUNCTION(this << linkId);
324
325 Ptr<Packet> packet = Create<Packet>();
326 packet->AddHeader(trigger);
327
329 if (trigger.GetNUserInfoFields() == 1)
330 {
331 auto aid = trigger.begin()->GetAid12();
332 auto aidAddrMapIt = m_apMac->GetStaList(linkId).find(aid);
333 NS_ASSERT(aidAddrMapIt != m_apMac->GetStaList(linkId).end());
334 receiver = aidAddrMapIt->second;
335 }
336
338 hdr.SetAddr1(receiver);
339 hdr.SetAddr2(GetHeFem(linkId)->GetAddress());
340 hdr.SetDsNotTo();
341 hdr.SetDsNotFrom();
342
343 return Create<WifiMpdu>(packet, hdr);
344}
345
346void
348{
349 NS_LOG_FUNCTION(this);
350
351 // Set the CS Required subfield to true, unless the UL Length subfield is less
352 // than or equal to 76 (see Section 26.5.2.5 of 802.11ax-2021)
353 m_lastTxInfo[m_linkId].ulInfo.trigger.SetCsRequired(
354 m_lastTxInfo[m_linkId].ulInfo.trigger.GetUlLength() > 76);
355
356 GetHeFem(m_linkId)->SetTargetRssi(m_lastTxInfo[m_linkId].ulInfo.trigger);
357}
358
359void
361 uint8_t linkId,
362 CtrlTriggerHeader& trigger,
363 WifiTxParameters& txParams,
364 std::function<bool(uint8_t, Mac48Address)> predicate) const
365{
366 NS_LOG_FUNCTION(this << linkId << &txParams);
367
368 const auto& aidAddrMap = m_apMac->GetStaList(linkId);
369
370 for (auto userInfoIt = trigger.begin(); userInfoIt != trigger.end();)
371 {
372 const auto addressIt = aidAddrMap.find(userInfoIt->GetAid12());
373 NS_ASSERT_MSG(addressIt != aidAddrMap.cend(),
374 "AID " << userInfoIt->GetAid12() << " not found");
375 const auto address = addressIt->second;
376
377 if (predicate(linkId, address))
378 {
379 NS_LOG_INFO("Removing User Info field addressed to " << address);
380
381 userInfoIt = trigger.RemoveUserInfoField(userInfoIt);
382
384 {
385 auto acknowledgment =
386 static_cast<WifiUlMuMultiStaBa*>(txParams.m_acknowledgment.get());
387 for (auto it = acknowledgment->stationsReceivingMultiStaBa.begin();
388 it != acknowledgment->stationsReceivingMultiStaBa.end();)
389 {
390 if (it->first.first == address)
391 {
392 it = acknowledgment->stationsReceivingMultiStaBa.erase(it);
393 }
394 else
395 {
396 ++it;
397 }
398 }
399 }
400 }
401 else
402 {
403 ++userInfoIt;
404 }
405 }
406}
407
408void
410 uint8_t linkId,
411 WifiPsduMap& psduMap,
412 WifiTxParameters& txParams,
413 std::function<bool(uint8_t, Mac48Address)> predicate) const
414{
415 NS_LOG_FUNCTION(this << linkId << &txParams);
416
417 const auto& aidAddrMap = m_apMac->GetStaList(linkId);
418
419 for (auto psduMapIt = psduMap.begin(); psduMapIt != psduMap.end();)
420 {
421 const auto addressIt = aidAddrMap.find(psduMapIt->first);
422 NS_ASSERT_MSG(addressIt != aidAddrMap.cend(), "AID " << psduMapIt->first << " not found");
423 const auto address = addressIt->second;
424
425 if (predicate(linkId, address))
426 {
427 NS_LOG_INFO("Removing PSDU addressed to " << address);
428
429 txParams.m_txVector.GetHeMuUserInfoMap().erase(psduMapIt->first);
430 psduMapIt = psduMap.erase(psduMapIt);
431
433 {
434 auto acknowledgment =
435 static_cast<WifiDlMuBarBaSequence*>(txParams.m_acknowledgment.get());
436 acknowledgment->stationsReplyingWithNormalAck.erase(address);
437 acknowledgment->stationsReplyingWithBlockAck.erase(address);
438 acknowledgment->stationsSendBlockAckReqTo.erase(address);
439 }
440 else if (txParams.m_acknowledgment->method == WifiAcknowledgment::DL_MU_TF_MU_BAR)
441 {
442 auto acknowledgment =
443 static_cast<WifiDlMuTfMuBar*>(txParams.m_acknowledgment.get());
444 acknowledgment->stationsReplyingWithBlockAck.erase(address);
445 }
446 else if (txParams.m_acknowledgment->method == WifiAcknowledgment::DL_MU_AGGREGATE_TF)
447 {
448 auto acknowledgment =
449 static_cast<WifiDlMuAggregateTf*>(txParams.m_acknowledgment.get());
450 acknowledgment->stationsReplyingWithBlockAck.erase(address);
451 }
452 }
453 else
454 {
455 ++psduMapIt;
456 }
457 }
458}
459
460void
462 WifiPsduMap& psduMap,
463 WifiTxParameters& txParams)
464{
465 NS_LOG_FUNCTION(this << linkId << &txParams);
466
467 if (txParams.m_txVector.IsDlMu())
468 {
470
471 UpdateDlMuAfterProtection(linkId, psduMap, txParams);
472 }
473 else if (IsTrigger(psduMap))
474 {
476
477 UpdateTriggerFrameAfterProtection(linkId, GetUlMuInfo(linkId).trigger, txParams);
478
479 if (GetUlMuInfo(linkId).trigger.GetNUserInfoFields() == 0)
480 {
481 NS_LOG_INFO("No User Info field left");
482 psduMap.clear();
483 }
484 else
485 {
486 auto mpdu = GetTriggerFrame(GetUlMuInfo(linkId).trigger, linkId);
487 GetUlMuInfo(linkId).macHdr = mpdu->GetHeader();
488 psduMap =
489 WifiPsduMap{{SU_STA_ID, GetHeFem(linkId)->GetWifiPsdu(mpdu, txParams.m_txVector)}};
490 }
491 }
492}
493
496{
497 // find the maximum number of TIDs for which a BlockAck agreement has been established
498 // with an STA, among all the STAs solicited by the given Trigger Frame
499 uint8_t maxNTids = 0;
500 for (const auto& userInfo : trigger)
501 {
502 auto address = m_apMac->GetMldOrLinkAddressByAid(userInfo.GetAid12());
503 NS_ASSERT_MSG(address, "AID " << userInfo.GetAid12() << " not found");
504
505 uint8_t staNTids = 0;
506 for (uint8_t tid = 0; tid < 8; tid++)
507 {
508 if (m_apMac->GetBaAgreementEstablishedAsRecipient(*address, tid))
509 {
510 staNTids++;
511 }
512 }
513 maxNTids = std::max(maxNTids, staNTids);
514 }
515
516 // compute the size in bytes of maxNTids QoS Null frames
518 header.SetDsTo();
519 header.SetDsNotFrom();
520 uint32_t headerSize = header.GetSerializedSize();
521 uint32_t maxSize = 0;
522
523 for (uint8_t i = 0; i < maxNTids; i++)
524 {
525 maxSize = MpduAggregator::GetSizeIfAggregated(headerSize + WIFI_MAC_FCS_LENGTH, maxSize);
526 }
527
528 return maxSize;
529}
530
531} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
Headers for Trigger frames.
ConstIterator end() const
Get a const iterator indicating past-the-last User Info field in the list.
ConstIterator begin() const
Get a const iterator pointing to the first User Info field in the list.
std::size_t GetNUserInfoFields() const
Get the number of User Info fields in this Trigger Frame.
Iterator RemoveUserInfoField(ConstIterator userInfoIt)
Remove a User Info field from the Trigger Frame.
Hold variables of type enum.
Definition enum.h:52
an EUI-48 address
static Mac48Address GetBroadcast()
static uint32_t GetSizeIfAggregated(uint32_t mpduSize, uint32_t ampduSize)
Compute the size of the A-MPDU resulting from the aggregation of an MPDU of size mpduSize and an A-MP...
bool m_initialFrame
true if a TXOP is being started
void NotifyNewAggregate() override
Notify all Objects aggregated to this one of a new Object being aggregated.
void DoInitialize() override
Initialize() implementation.
Ptr< ApWifiMac > m_apMac
the AP wifi MAC
std::vector< EventId > m_accessReqTimers
the per-link timer controlling additional channel access requests
void CheckTriggerFrame()
Ensure that the Trigger Frame returned in case of UL MU transmission is correct.
static TypeId GetTypeId()
Get the type ID.
Time m_availableTime
the time available for frame exchange
void RemoveRecipientsFromTf(uint8_t linkId, CtrlTriggerHeader &trigger, WifiTxParameters &txParams, std::function< bool(uint8_t, Mac48Address)> predicate) const
Remove the User Info fields for which the given predicate is true from the given Trigger Frame.
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId) const
Get the station manager attached to the AP on the given link.
UlMuInfo & GetUlMuInfo(uint8_t linkId)
Get the information required to solicit an UL MU transmission on the given link.
uint8_t m_linkId
the ID of the link over which channel access has been granted
virtual TxFormat SelectTxFormat()=0
Select the format of the next transmission.
void SetAccessReqInterval(Time interval)
Set the duration of the interval between two consecutive requests for channel access made by the Mult...
uint32_t GetMaxSizeOfQosNullAmpdu(const CtrlTriggerHeader &trigger) const
Get the maximum size in bytes among the A-MPDUs containing QoS Null frames and solicited by the given...
virtual void UpdateTriggerFrameAfterProtection(uint8_t linkId, CtrlTriggerHeader &trigger, WifiTxParameters &txParams) const
Update the given Trigger Frame after protection is completed on the given link.
bool m_restartTimerUponAccess
whether the channel access timer has to be restarted upon channel access
virtual DlMuInfo ComputeDlMuInfo()=0
Compute the information required to perform a DL MU transmission.
Ptr< QosTxop > m_edca
the AC that gained channel access
void NotifyProtectionCompleted(uint8_t linkId, WifiPsduMap &psduMap, WifiTxParameters &txParams)
This method is called when a protection mechanism for an MU transmission is completed and gives the M...
virtual UlMuInfo ComputeUlMuInfo()=0
Prepare the information required to solicit an UL MU transmission.
Time m_defaultTbPpduDuration
the default duration of TB PPDUs solicited by Basic TFs
TxFormat GetLastTxFormat(uint8_t linkId) const
Get the format of the last transmission on the given link, as determined by the last call to NotifyAc...
void DoDispose() override
Destructor implementation.
Ptr< WifiMpdu > GetTriggerFrame(const CtrlTriggerHeader &trigger, uint8_t linkId) const
Get an MPDU containing the given Trigger Frame.
AcIndex m_accessReqAc
AC we request channel access for.
DlMuInfo & GetDlMuInfo(uint8_t linkId)
Get the information required to perform a DL MU transmission on the given link.
MHz_u m_allowedWidth
the allowed width for the current transmission
Ptr< HeFrameExchangeManager > GetHeFem(uint8_t linkId) const
Get the HE Frame Exchange Manager attached to the AP on the given link.
Time m_accessReqInterval
duration of the interval between channel access requests
TxFormat NotifyAccessGranted(Ptr< QosTxop > edca, Time availableTime, bool initialFrame, MHz_u allowedWidth, uint8_t linkId)
Notify the Multi-user Scheduler that the given AC of the AP gained channel access.
void SetWifiMac(Ptr< ApWifiMac > mac)
Set the wifi MAC.
virtual Time GetExtraTimeForBsrpTfDurationId(uint8_t linkId) const
When the TXOP limit is zero and the TXOP continues a SIFS after receiving a response to a BSRP TF,...
TxFormat
Enumeration of the possible transmission formats.
virtual void UpdateDlMuAfterProtection(uint8_t linkId, WifiPsduMap &psduMap, WifiTxParameters &txParams) const
Update the given PSDU map after protection is completed on the given link.
std::map< uint8_t, LastTxInfo > m_lastTxInfo
Information about the last transmission.
void RemoveRecipientsFromDlMu(uint8_t linkId, WifiPsduMap &psduMap, WifiTxParameters &txParams, std::function< bool(uint8_t, Mac48Address)> predicate) const
Remove PSDUs for which the given predicate is true from the given PSDU map.
void AccessReqTimeout(uint8_t linkId)
Perform actions required on expiration of the channel access request timer associated with the given ...
A base class which provides memory management and object aggregation.
Definition object.h:78
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Definition object.cc:412
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
bool IsInitialized() const
Check if the object has been initialized.
Definition object.cc:240
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
bool IsStrictlyPositive() const
Exactly equivalent to t > 0.
Definition nstime.h:340
@ MS
millisecond
Definition nstime.h:106
AttributeValue implementation for Time.
Definition nstime.h:1431
@ NOT_REQUESTED
Definition txop.h:77
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Implements the IEEE 802.11 MAC header.
uint32_t GetSerializedSize() const override
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetDsTo()
Set the To DS bit in the Frame Control field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
This class stores the TX parameters (TX vector, protection mechanism, acknowledgment mechanism,...
std::unique_ptr< WifiAcknowledgment > m_acknowledgment
acknowledgment method
WifiTxVector m_txVector
TXVECTOR of the frame being prepared.
const HeMuUserInfoMap & GetHeMuUserInfoMap() const
Get a const reference to the map HE MU user-specific transmission information indexed by STA-ID.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition enum.h:221
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition nstime.h:1432
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
@ AC_BE
Best Effort.
Definition qos-utils.h:64
@ AC_VO
Voice.
Definition qos-utils.h:70
@ AC_VI
Video.
Definition qos-utils.h:68
@ AC_BK
Background.
Definition qos-utils.h:66
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static const uint16_t WIFI_MAC_FCS_LENGTH
The length in octets of the IEEE 802.11 MAC FCS field.
bool IsTrigger(const WifiPsduMap &psduMap)
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition enum.h:179
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
@ WIFI_MAC_CTL_TRIGGER
@ WIFI_MAC_QOSDATA_NULL
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:587
static constexpr uint16_t SU_STA_ID
STA_ID to identify a single user (SU)
Definition wifi-mode.h:24
std::unordered_map< uint16_t, Ptr< WifiPsdu > > WifiPsduMap
Map of PSDUs indexed by STA-ID.
Information to be provided in case of DL MU transmission.
Information to be provided in case of UL MU transmission.
WifiMacHeader macHdr
the MAC header for the Trigger Frame
WifiDlMuAggregateTf specifies that a DL MU PPDU made of PSDUs including each a MU-BAR Trigger Frame i...
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame.
WifiDlMuBarBaSequence specifies that a DL MU PPDU is acknowledged through a sequence of BlockAckReq a...
std::map< Mac48Address, AckInfo > stationsReplyingWithNormalAck
Set of stations replying with an Ack frame (no more than one)
WifiDlMuTfMuBar specifies that a DL MU PPDU is followed after a SIFS duration by a MU-BAR Trigger Fra...
std::map< Mac48Address, BlockAckInfo > stationsReplyingWithBlockAck
Set of stations replying with a BlockAck frame.
WifiUlMuMultiStaBa specifies that a Basic Trigger Frame is being sent to solicit TB PPDUs that will b...
std::map< std::pair< Mac48Address, uint8_t >, std::size_t > stationsReceivingMultiStaBa
Map (originator, tid) pairs to the their index in baType.