A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-mac.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "wifi-mac.h"
21
24#include "mac-rx-middle.h"
25#include "mac-tx-middle.h"
26#include "mgt-headers.h"
27#include "qos-txop.h"
28#include "ssid.h"
29#include "wifi-mac-queue.h"
30#include "wifi-net-device.h"
31
32#include "ns3/eht-configuration.h"
33#include "ns3/eht-frame-exchange-manager.h"
34#include "ns3/he-configuration.h"
35#include "ns3/ht-configuration.h"
36#include "ns3/log.h"
37#include "ns3/packet.h"
38#include "ns3/pointer.h"
39#include "ns3/vht-configuration.h"
40
41#include <algorithm>
42
43namespace ns3
44{
45
47
49
51 : m_qosSupported(false)
52{
53 NS_LOG_FUNCTION(this);
54
55 m_rxMiddle = Create<MacRxMiddle>();
56 m_rxMiddle->SetForwardCallback(MakeCallback(&WifiMac::Receive, this));
57
58 m_txMiddle = Create<MacTxMiddle>();
59}
60
62{
63 NS_LOG_FUNCTION(this);
64}
65
68{
69 static TypeId tid =
70 TypeId("ns3::WifiMac")
72 .SetGroupName("Wifi")
73 .AddAttribute("Ssid",
74 "The ssid we want to belong to.",
75 SsidValue(Ssid("default")),
76 MakeSsidAccessor(&WifiMac::GetSsid, &WifiMac::SetSsid),
77 MakeSsidChecker())
78 .AddAttribute("QosSupported",
79 "This Boolean attribute is set to enable 802.11e/WMM-style QoS support "
80 "at this STA.",
82 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
83 BooleanValue(false),
86 .AddAttribute("CtsToSelfSupported",
87 "Use CTS to Self when using a rate that is not in the basic rate set.",
88 BooleanValue(false),
91 .AddAttribute(
92 "ShortSlotTimeSupported",
93 "Whether or not short slot time is supported (only used by ERP APs or STAs).",
94 BooleanValue(true),
98 .AddAttribute("Txop",
99 "The Txop object.",
100 PointerValue(),
102 MakePointerChecker<Txop>())
103 .AddAttribute("VO_Txop",
104 "Queue that manages packets belonging to AC_VO access class.",
105 PointerValue(),
107 MakePointerChecker<QosTxop>())
108 .AddAttribute("VI_Txop",
109 "Queue that manages packets belonging to AC_VI access class.",
110 PointerValue(),
112 MakePointerChecker<QosTxop>())
113 .AddAttribute("BE_Txop",
114 "Queue that manages packets belonging to AC_BE access class.",
115 PointerValue(),
117 MakePointerChecker<QosTxop>())
118 .AddAttribute("BK_Txop",
119 "Queue that manages packets belonging to AC_BK access class.",
120 PointerValue(),
122 MakePointerChecker<QosTxop>())
123 .AddAttribute("VO_MaxAmsduSize",
124 "Maximum length in bytes of an A-MSDU for AC_VO access class "
125 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
126 "Value 0 means A-MSDU aggregation is disabled for that AC.",
127 UintegerValue(0),
129 MakeUintegerChecker<uint16_t>(0, 11398))
130 .AddAttribute("VI_MaxAmsduSize",
131 "Maximum length in bytes of an A-MSDU for AC_VI access class "
132 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
133 "Value 0 means A-MSDU aggregation is disabled for that AC.",
134 UintegerValue(0),
136 MakeUintegerChecker<uint16_t>(0, 11398))
137 .AddAttribute("BE_MaxAmsduSize",
138 "Maximum length in bytes of an A-MSDU for AC_BE access class "
139 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
140 "Value 0 means A-MSDU aggregation is disabled for that AC.",
141 UintegerValue(0),
143 MakeUintegerChecker<uint16_t>(0, 11398))
144 .AddAttribute("BK_MaxAmsduSize",
145 "Maximum length in bytes of an A-MSDU for AC_BK access class "
146 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
147 "Value 0 means A-MSDU aggregation is disabled for that AC.",
148 UintegerValue(0),
150 MakeUintegerChecker<uint16_t>(0, 11398))
151 .AddAttribute(
152 "VO_MaxAmpduSize",
153 "Maximum length in bytes of an A-MPDU for AC_VO access class "
154 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
155 "and 15523200 for EHT PPDUs). "
156 "Value 0 means A-MPDU aggregation is disabled for that AC.",
157 UintegerValue(0),
159 MakeUintegerChecker<uint32_t>(0, 15523200))
160 .AddAttribute(
161 "VI_MaxAmpduSize",
162 "Maximum length in bytes of an A-MPDU for AC_VI access class "
163 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
164 "and 15523200 for EHT PPDUs). "
165 "Value 0 means A-MPDU aggregation is disabled for that AC.",
166 UintegerValue(65535),
168 MakeUintegerChecker<uint32_t>(0, 15523200))
169 .AddAttribute(
170 "BE_MaxAmpduSize",
171 "Maximum length in bytes of an A-MPDU for AC_BE access class "
172 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
173 "and 15523200 for EHT PPDUs). "
174 "Value 0 means A-MPDU aggregation is disabled for that AC.",
175 UintegerValue(65535),
177 MakeUintegerChecker<uint32_t>(0, 15523200))
178 .AddAttribute(
179 "BK_MaxAmpduSize",
180 "Maximum length in bytes of an A-MPDU for AC_BK access class "
181 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
182 "and 15523200 for EHT PPDUs). "
183 "Value 0 means A-MPDU aggregation is disabled for that AC.",
184 UintegerValue(0),
186 MakeUintegerChecker<uint32_t>(0, 15523200))
187 .AddAttribute(
188 "VO_BlockAckThreshold",
189 "If number of packets in VO queue reaches this value, "
190 "block ack mechanism is used. If this value is 0, block ack is never used."
191 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
192 UintegerValue(0),
194 MakeUintegerChecker<uint8_t>(0, 64))
195 .AddAttribute(
196 "VI_BlockAckThreshold",
197 "If number of packets in VI queue reaches this value, "
198 "block ack mechanism is used. If this value is 0, block ack is never used."
199 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
200 UintegerValue(0),
202 MakeUintegerChecker<uint8_t>(0, 64))
203 .AddAttribute(
204 "BE_BlockAckThreshold",
205 "If number of packets in BE queue reaches this value, "
206 "block ack mechanism is used. If this value is 0, block ack is never used."
207 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
208 UintegerValue(0),
210 MakeUintegerChecker<uint8_t>(0, 64))
211 .AddAttribute(
212 "BK_BlockAckThreshold",
213 "If number of packets in BK queue reaches this value, "
214 "block ack mechanism is used. If this value is 0, block ack is never used."
215 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
216 UintegerValue(0),
218 MakeUintegerChecker<uint8_t>(0, 64))
219 .AddAttribute(
220 "VO_BlockAckInactivityTimeout",
221 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
222 "inactivity for AC_VO. If this value isn't equal to 0 a timer start after that a"
223 "block ack setup is completed and will be reset every time that a block ack"
224 "frame is received. If this value is 0, block ack inactivity timeout won't be "
225 "used.",
226 UintegerValue(0),
228 MakeUintegerChecker<uint16_t>())
229 .AddAttribute(
230 "VI_BlockAckInactivityTimeout",
231 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
232 "inactivity for AC_VI. If this value isn't equal to 0 a timer start after that a"
233 "block ack setup is completed and will be reset every time that a block ack"
234 "frame is received. If this value is 0, block ack inactivity timeout won't be "
235 "used.",
236 UintegerValue(0),
238 MakeUintegerChecker<uint16_t>())
239 .AddAttribute(
240 "BE_BlockAckInactivityTimeout",
241 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
242 "inactivity for AC_BE. If this value isn't equal to 0 a timer start after that a"
243 "block ack setup is completed and will be reset every time that a block ack"
244 "frame is received. If this value is 0, block ack inactivity timeout won't be "
245 "used.",
246 UintegerValue(0),
248 MakeUintegerChecker<uint16_t>())
249 .AddAttribute(
250 "BK_BlockAckInactivityTimeout",
251 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
252 "inactivity for AC_BK. If this value isn't equal to 0 a timer start after that a"
253 "block ack setup is completed and will be reset every time that a block ack"
254 "frame is received. If this value is 0, block ack inactivity timeout won't be "
255 "used.",
256 UintegerValue(0),
258 MakeUintegerChecker<uint16_t>())
259 .AddTraceSource("MacTx",
260 "A packet has been received from higher layers and is being processed "
261 "in preparation for "
262 "queueing for transmission.",
264 "ns3::Packet::TracedCallback")
265 .AddTraceSource(
266 "MacTxDrop",
267 "A packet has been dropped in the MAC layer before being queued for transmission. "
268 "This trace source is fired, e.g., when an AP's MAC receives from the upper layer "
269 "a packet destined to a station that is not associated with the AP or a STA's MAC "
270 "receives a packet from the upper layer while it is not associated with any AP.",
272 "ns3::Packet::TracedCallback")
273 .AddTraceSource(
274 "MacPromiscRx",
275 "A packet has been received by this device, has been passed up from the physical "
276 "layer "
277 "and is being forwarded up the local protocol stack. This is a promiscuous trace.",
279 "ns3::Packet::TracedCallback")
280 .AddTraceSource("MacRx",
281 "A packet has been received by this device, has been passed up from "
282 "the physical layer "
283 "and is being forwarded up the local protocol stack. This is a "
284 "non-promiscuous trace.",
286 "ns3::Packet::TracedCallback")
287 .AddTraceSource("MacRxDrop",
288 "A packet has been dropped in the MAC layer after it has been passed "
289 "up from the physical layer.",
291 "ns3::Packet::TracedCallback")
292 .AddTraceSource("TxOkHeader",
293 "The header of successfully transmitted packet.",
295 "ns3::WifiMacHeader::TracedCallback",
297 "Use the AckedMpdu trace instead.")
298 .AddTraceSource("TxErrHeader",
299 "The header of unsuccessfuly transmitted packet.",
301 "ns3::WifiMacHeader::TracedCallback",
303 "Depending on the failure type, use the NAckedMpdu trace, the "
304 "DroppedMpdu trace or one of the traces associated with TX timeouts.")
305 .AddTraceSource("AckedMpdu",
306 "An MPDU that was successfully acknowledged, via either a "
307 "Normal Ack or a Block Ack.",
309 "ns3::WifiMpdu::TracedCallback")
310 .AddTraceSource("NAckedMpdu",
311 "An MPDU that was negatively acknowledged via a Block Ack.",
313 "ns3::WifiMpdu::TracedCallback")
314 .AddTraceSource(
315 "DroppedMpdu",
316 "An MPDU that was dropped for the given reason (see WifiMacDropReason).",
318 "ns3::WifiMac::DroppedMpduCallback")
319 .AddTraceSource(
320 "MpduResponseTimeout",
321 "An MPDU whose response was not received before the timeout, along with "
322 "an identifier of the type of timeout (see WifiTxTimer::Reason) and the "
323 "TXVECTOR used to transmit the MPDU. This trace source is fired when a "
324 "CTS is missing after an RTS, when all CTS frames are missing after an MU-RTS, "
325 "or when a Normal Ack is missing after an MPDU or after a DL MU PPDU "
326 "acknowledged in SU format.",
328 "ns3::WifiMac::MpduResponseTimeoutCallback")
329 .AddTraceSource(
330 "PsduResponseTimeout",
331 "A PSDU whose response was not received before the timeout, along with "
332 "an identifier of the type of timeout (see WifiTxTimer::Reason) and the "
333 "TXVECTOR used to transmit the PSDU. This trace source is fired when a "
334 "BlockAck is missing after an A-MPDU, a BlockAckReq (possibly in the "
335 "context of the acknowledgment of a DL MU PPDU in SU format) or a TB PPDU "
336 "(in the latter case the missing BlockAck is a Multi-STA BlockAck).",
338 "ns3::WifiMac::PsduResponseTimeoutCallback")
339 .AddTraceSource(
340 "PsduMapResponseTimeout",
341 "A PSDU map for which not all the responses were received before the timeout, "
342 "along with an identifier of the type of timeout (see WifiTxTimer::Reason), "
343 "the set of MAC addresses of the stations that did not respond and the total "
344 "number of stations that had to respond. This trace source is fired when not "
345 "all the addressed stations responded to an MU-BAR Trigger frame (either sent as "
346 "a SU frame or aggregated to PSDUs in the DL MU PPDU), a Basic Trigger Frame or "
347 "a BSRP Trigger Frame.",
349 "ns3::WifiMac::PsduMapResponseTimeoutCallback");
350 return tid;
351}
352
353void
355{
356 NS_LOG_FUNCTION(this);
357
358 if (m_txop)
359 {
361 }
362
363 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
364 {
365 it->second->Initialize();
366 }
367
368 for (const auto& [id, link] : m_links)
369 {
370 if (auto cam = link->channelAccessManager)
371 {
372 cam->Initialize();
373 }
374 }
375}
376
377void
379{
380 NS_LOG_FUNCTION(this);
381
382 m_rxMiddle = nullptr;
383 m_txMiddle = nullptr;
384 m_links.clear();
385
386 if (m_txop)
387 {
388 m_txop->Dispose();
389 }
390 m_txop = nullptr;
391
392 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
393 {
394 it->second->Dispose();
395 it->second = nullptr;
396 }
397
398 m_device = nullptr;
399 if (m_scheduler != nullptr)
400 {
401 m_scheduler->Dispose();
402 }
403 m_scheduler = nullptr;
404}
405
407{
408 // WifiMac owns pointers to ChannelAccessManager and FrameExchangeManager
410 {
412 }
413 if (feManager)
414 {
415 feManager->Dispose();
416 }
417}
418
419void
421{
422 NS_LOG_FUNCTION(this << type);
423 m_typeOfStation = type;
424}
425
428{
429 return m_typeOfStation;
430}
431
432void
434{
435 m_device = device;
436}
437
440{
441 return m_device;
442}
443
444void
446{
447 NS_LOG_FUNCTION(this << address);
448 m_address = address;
449}
450
453{
454 return m_address;
455}
456
457void
459{
460 NS_LOG_FUNCTION(this << ssid);
461 m_ssid = ssid;
462}
463
464Ssid
466{
467 return m_ssid;
468}
469
470void
471WifiMac::SetBssid(Mac48Address bssid, uint8_t linkId)
472{
473 NS_LOG_FUNCTION(this << bssid << +linkId);
474 GetLink(linkId).feManager->SetBssid(bssid);
475}
476
478WifiMac::GetBssid(uint8_t linkId) const
479{
480 return GetLink(linkId).feManager->GetBssid();
481}
482
483void
485{
486 for (auto& [id, link] : m_links)
487 {
488 link->feManager->SetPromisc();
489 }
490}
491
494{
495 return m_txop;
496}
497
500{
501 // Use std::find_if() instead of std::map::find() because the latter compares
502 // the given AC index with the AC index of an element in the map by using the
503 // operator< defined for AcIndex, which aborts if an operand is not a QoS AC
504 // (the AC index passed to this method may not be a QoS AC).
505 // The performance penalty is limited because std::map::find() performs 3
506 // comparisons in the worst case, while std::find_if() performs 4 comparisons
507 // in the worst case.
508 const auto it = std::find_if(m_edca.cbegin(), m_edca.cend(), [ac](const auto& pair) {
509 return pair.first == ac;
510 });
511 return (it == m_edca.cend() ? nullptr : it->second);
512}
513
515WifiMac::GetQosTxop(uint8_t tid) const
516{
517 return GetQosTxop(QosUtilsMapTidToAc(tid));
518}
519
522{
523 return (m_qosSupported ? GetQosTxop(AC_VO) : nullptr);
524}
525
528{
529 return (m_qosSupported ? GetQosTxop(AC_VI) : nullptr);
530}
531
534{
535 return (m_qosSupported ? GetQosTxop(AC_BE) : nullptr);
536}
537
540{
541 return (m_qosSupported ? GetQosTxop(AC_BK) : nullptr);
542}
543
546{
547 Ptr<Txop> txop = (ac == AC_BE_NQOS ? m_txop : StaticCast<Txop>(GetQosTxop(ac)));
548 return (txop ? txop->GetWifiMacQueue() : nullptr);
549}
550
551bool
553{
554 if (m_txop && m_txop->HasFramesToTransmit(linkId))
555 {
556 return true;
557 }
558 for (const auto& [aci, qosTxop] : m_edca)
559 {
560 if (qosTxop->HasFramesToTransmit(linkId))
561 {
562 return true;
563 }
564 }
565 return false;
566}
567
568void
570{
571 m_scheduler = scheduler;
572 m_scheduler->SetWifiMac(this);
573}
574
577{
578 return m_scheduler;
579}
580
581void
583{
584 NS_LOG_FUNCTION(this << +linkId);
585
586 // we may have changed PHY band, in which case it is necessary to re-configure
587 // the PHY dependent parameters. In any case, this makes no harm
589
590 // SetupPhy not only resets the remote station manager, but also sets the
591 // default TX mode and MCS, which is required when switching to a channel
592 // in a different band
593 GetLink(linkId).stationManager->SetupPhy(GetLink(linkId).phy);
594}
595
596void
598{
599 m_macTxTrace(packet);
600}
601
602void
604{
605 m_macTxDropTrace(packet);
606}
607
608void
610{
611 m_macRxTrace(packet);
612}
613
614void
616{
617 m_macPromiscRxTrace(packet);
618}
619
620void
622{
623 m_macRxDropTrace(packet);
624}
625
626void
628{
629 NS_LOG_FUNCTION(this << ac);
630
631 // Our caller shouldn't be attempting to setup a queue that is
632 // already configured.
633 NS_ASSERT(m_edca.find(ac) == m_edca.end());
634
635 Ptr<QosTxop> edca = CreateObject<QosTxop>(ac);
636 edca->SetTxMiddle(m_txMiddle);
637 edca->GetBaManager()->SetTxOkCallback(
638 MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
639 edca->GetBaManager()->SetTxFailedCallback(
640 MakeCallback(&MpduTracedCallback::operator(), &m_nackedMpduCallback));
641 edca->SetDroppedMpduCallback(
642 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
643
644 m_edca.insert(std::make_pair(ac, edca));
645}
646
647void
649{
650 std::list<bool> isDsssOnly;
651 for (const auto& [id, link] : m_links)
652 {
653 isDsssOnly.push_back(link->dsssSupported && !link->erpSupported);
654 }
655
656 if (m_txop)
657 {
658 // The special value of AC_BE_NQOS which exists in the Access
659 // Category enumeration allows us to configure plain old DCF.
660 ConfigureDcf(m_txop, cwMin, cwMax, isDsssOnly, AC_BE_NQOS);
661 }
662
663 // Now we configure the EDCA functions
664 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
665 {
666 ConfigureDcf(it->second, cwMin, cwMax, isDsssOnly, it->first);
667 }
668}
669
670void
672 uint32_t cwmin,
673 uint32_t cwmax,
674 std::list<bool> isDsss,
675 AcIndex ac)
676{
677 NS_LOG_FUNCTION(this << dcf << cwmin << cwmax << +ac);
678
679 uint32_t cwMinValue = 0;
680 uint32_t cwMaxValue = 0;
681 uint8_t aifsnValue = 0;
682 Time txopLimitDsss(0);
683 Time txopLimitNoDsss(0);
684
685 /* see IEEE 802.11-2020 Table 9-155 "Default EDCA Parameter Set element parameter values" */
686 switch (ac)
687 {
688 case AC_VO:
689 cwMinValue = (cwmin + 1) / 4 - 1;
690 cwMaxValue = (cwmin + 1) / 2 - 1;
691 aifsnValue = 2;
692 txopLimitDsss = MicroSeconds(3264);
693 txopLimitNoDsss = MicroSeconds(2080);
694 break;
695 case AC_VI:
696 cwMinValue = (cwmin + 1) / 2 - 1;
697 cwMaxValue = cwmin;
698 aifsnValue = 2;
699 txopLimitDsss = MicroSeconds(6016);
700 txopLimitNoDsss = MicroSeconds(4096);
701 break;
702 case AC_BE:
703 cwMinValue = cwmin;
704 cwMaxValue = cwmax;
705 aifsnValue = 3;
706 txopLimitDsss = MicroSeconds(0); // TODO should be MicroSeconds (3264)
707 txopLimitNoDsss = MicroSeconds(0); // TODO should be MicroSeconds (2528)
708 break;
709 case AC_BK:
710 cwMinValue = cwmin;
711 cwMaxValue = cwmax;
712 aifsnValue = 7;
713 txopLimitDsss = MicroSeconds(0); // TODO should be MicroSeconds (3264)
714 txopLimitNoDsss = MicroSeconds(0); // TODO should be MicroSeconds (2528)
715 break;
716 case AC_BE_NQOS:
717 cwMinValue = cwmin;
718 cwMaxValue = cwmax;
719 aifsnValue = 2;
720 txopLimitDsss = txopLimitNoDsss = MicroSeconds(0);
721 break;
722 case AC_BEACON:
723 // done by ApWifiMac
724 break;
725 case AC_UNDEF:
726 NS_FATAL_ERROR("I don't know what to do with this");
727 break;
728 }
729
730 std::vector<uint32_t> cwValues(m_links.size());
731 std::vector<uint8_t> aifsnValues(m_links.size());
732 std::vector<Time> txopLimitValues(m_links.size());
733
734 std::fill(cwValues.begin(), cwValues.end(), cwMinValue);
735 dcf->SetMinCws(cwValues);
736 std::fill(cwValues.begin(), cwValues.end(), cwMaxValue);
737 dcf->SetMaxCws(cwValues);
738 std::fill(aifsnValues.begin(), aifsnValues.end(), aifsnValue);
739 dcf->SetAifsns(aifsnValues);
740 std::transform(isDsss.begin(),
741 isDsss.end(),
742 txopLimitValues.begin(),
743 [&txopLimitDsss, &txopLimitNoDsss](bool dsss) {
744 return (dsss ? txopLimitDsss : txopLimitNoDsss);
745 });
746 dcf->SetTxopLimits(txopLimitValues);
747}
748
749void
751{
752 NS_LOG_FUNCTION(this << standard);
754 NS_ABORT_MSG_IF(m_links.empty(), "No PHY configured yet");
755
756 for (auto& [id, link] : m_links)
757 {
759 !link->phy || !link->phy->GetOperatingChannel().IsSet(),
760 "[LinkID " << +id
761 << "] PHY must have been set and an operating channel must have been set");
762
763 // do not create a ChannelAccessManager and a FrameExchangeManager if they
764 // already exist (this function may be called after ResetWifiPhys)
765 if (!link->channelAccessManager)
766 {
767 link->channelAccessManager = CreateObject<ChannelAccessManager>();
768 }
769 link->channelAccessManager->SetupPhyListener(link->phy);
770
771 if (!link->feManager)
772 {
773 link->feManager = SetupFrameExchangeManager(standard);
774 }
775 link->feManager->SetWifiPhy(link->phy);
776 link->feManager->SetWifiMac(this);
777 link->feManager->SetLinkId(id);
778 link->channelAccessManager->SetLinkId(id);
779 link->channelAccessManager->SetupFrameExchangeManager(link->feManager);
780
781 if (m_txop)
782 {
783 m_txop->SetWifiMac(this);
784 link->channelAccessManager->Add(m_txop);
785 }
786 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
787 {
788 it->second->SetWifiMac(this);
789 link->channelAccessManager->Add(it->second);
790 }
791
793 }
794}
795
796void
798{
799 NS_LOG_FUNCTION(this << +linkId);
800
801 WifiStandard standard = GetLink(linkId).phy->GetStandard();
802
803 uint32_t cwmin = (standard == WIFI_STANDARD_80211b ? 31 : 15);
804 uint32_t cwmax = 1023;
805
806 SetDsssSupported(standard == WIFI_STANDARD_80211b, linkId);
808 m_links[linkId]->phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ,
809 linkId);
810
811 ConfigureContentionWindow(cwmin, cwmax);
812}
813
816{
817 NS_LOG_FUNCTION(this << standard);
818 NS_ABORT_MSG_IF(standard == WIFI_STANDARD_UNSPECIFIED, "Wifi standard not set");
820
821 if (standard >= WIFI_STANDARD_80211be)
822 {
823 feManager = CreateObject<EhtFrameExchangeManager>();
824 }
825 else if (standard >= WIFI_STANDARD_80211ax)
826 {
827 feManager = CreateObject<HeFrameExchangeManager>();
828 }
829 else if (standard >= WIFI_STANDARD_80211ac)
830 {
831 feManager = CreateObject<VhtFrameExchangeManager>();
832 }
833 else if (standard >= WIFI_STANDARD_80211n)
834 {
835 feManager = CreateObject<HtFrameExchangeManager>();
836 }
837 else if (m_qosSupported)
838 {
839 feManager = CreateObject<QosFrameExchangeManager>();
840 }
841 else
842 {
843 feManager = CreateObject<FrameExchangeManager>();
844 }
845
846 feManager->SetMacTxMiddle(m_txMiddle);
847 feManager->SetMacRxMiddle(m_rxMiddle);
848 feManager->SetAddress(GetAddress());
849 feManager->GetWifiTxTimer().SetMpduResponseTimeoutCallback(
850 MakeCallback(&MpduResponseTimeoutTracedCallback::operator(),
852 feManager->GetWifiTxTimer().SetPsduResponseTimeoutCallback(
853 MakeCallback(&PsduResponseTimeoutTracedCallback::operator(),
855 feManager->GetWifiTxTimer().SetPsduMapResponseTimeoutCallback(
856 MakeCallback(&PsduMapResponseTimeoutTracedCallback::operator(),
858 feManager->SetDroppedMpduCallback(
859 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
860 feManager->SetAckedMpduCallback(
861 MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
862 return feManager;
863}
864
867{
868 return GetLink(linkId).feManager;
869}
870
873{
874 return GetLink(linkId).channelAccessManager;
875}
876
877void
879{
880 NS_LOG_FUNCTION(this << stationManager);
881 SetWifiRemoteStationManagers({stationManager});
882}
883
884void
886 const std::vector<Ptr<WifiRemoteStationManager>>& stationManagers)
887{
888 NS_LOG_FUNCTION(this);
889
890 NS_ABORT_MSG_UNLESS(m_links.empty() || m_links.size() == stationManagers.size(),
891 "If links have been already created, the number of provided "
892 "Remote Manager objects ("
893 << stationManagers.size()
894 << ") must "
895 "match the number of links ("
896 << m_links.size() << ")");
897
898 for (std::size_t i = 0; i < stationManagers.size(); i++)
899 {
900 // the link may already exist in case PHY objects were configured first
901 auto [it, inserted] = m_links.emplace(i, CreateLinkEntity());
902 m_linkIds.insert(i);
903 it->second->stationManager = stationManagers[i];
904 }
905}
906
909{
910 return GetLink(linkId).stationManager;
911}
912
913std::unique_ptr<WifiMac::LinkEntity>
915{
916 return std::make_unique<LinkEntity>();
917}
918
919const std::map<uint8_t, std::unique_ptr<WifiMac::LinkEntity>>&
921{
922 return m_links;
923}
924
926WifiMac::GetLink(uint8_t linkId) const
927{
928 auto it = m_links.find(linkId);
929 NS_ASSERT(it != m_links.cend());
930 NS_ASSERT(it->second); // check that the pointer owns an object
931 return *it->second;
932}
933
934uint8_t
936{
937 return m_links.size();
938}
939
940const std::set<uint8_t>&
942{
943 return m_linkIds;
944}
945
946void
948{
949 NS_LOG_FUNCTION(this << id);
950
951 auto& link = GetLink(id);
952 if (link.feManager)
953 {
954 link.feManager->SetLinkId(id);
955 }
956 if (link.channelAccessManager)
957 {
958 link.channelAccessManager->SetLinkId(id);
959 }
960}
961
962std::optional<uint8_t>
964{
965 for (const auto& [id, link] : m_links)
966 {
967 if (link->feManager->GetAddress() == address)
968 {
969 return id;
970 }
971 }
972 return std::nullopt;
973}
974
975std::optional<uint8_t>
977{
978 for (const auto& [id, link] : m_links)
979 {
980 if (link->phy == phy)
981 {
982 return id;
983 }
984 }
985 return std::nullopt;
986}
987
988std::optional<uint8_t>
989WifiMac::GetLinkForPhy(std::size_t phyId) const
990{
991 NS_ABORT_UNLESS(phyId < m_device->GetNPhys());
992 auto phy = m_device->GetPhy(phyId);
993 return GetLinkForPhy(phy);
994}
995
996void
997WifiMac::SwapLinks(std::map<uint8_t, uint8_t> links)
998{
999 NS_LOG_FUNCTION(this);
1000
1001 std::map<uint8_t, uint8_t> actualPairs;
1002
1003 while (!links.empty())
1004 {
1005 auto from = links.cbegin()->first;
1006 auto to = links.cbegin()->second;
1007
1008 if (from == to)
1009 {
1010 // nothing to do
1011 links.erase(links.cbegin());
1012 continue;
1013 }
1014
1015 std::unique_ptr<LinkEntity> linkToMove;
1016 NS_ASSERT(m_links.find(from) != m_links.cend());
1017 linkToMove.swap(m_links.at(from)); // from is now out of m_links
1018 auto empty = from; // track empty cell in m_links
1019
1020 do
1021 {
1022 auto [it, inserted] =
1023 m_links.emplace(to, nullptr); // insert an element with key to if not present
1024 m_links[to].swap(linkToMove); // to is the link to move now
1025 actualPairs.emplace(from, to);
1026 UpdateLinkId(to);
1027 links.erase(from);
1028 if (!linkToMove)
1029 {
1030 if (inserted)
1031 {
1032 m_links.erase(empty);
1033 }
1034 break;
1035 }
1036
1037 auto nextTo = links.find(to);
1038 if (nextTo == links.cend())
1039 {
1040 // no new position specified for 'to', use the current empty cell
1041 m_links[empty].swap(linkToMove);
1042 actualPairs.emplace(to, empty);
1043 break;
1044 }
1045
1046 from = to;
1047 to = nextTo->second;
1048 } while (true);
1049 }
1050
1051 m_linkIds.clear();
1052 for (const auto& [id, link] : m_links)
1053 {
1054 m_linkIds.insert(id);
1055 }
1056
1057 if (m_txop)
1058 {
1059 m_txop->SwapLinks(actualPairs);
1060 }
1061 for (auto& [ac, edca] : m_edca)
1062 {
1063 edca->SwapLinks(actualPairs);
1064 }
1065}
1066
1067void
1070 const WifiTidLinkMapping& mapping)
1071{
1072 NS_LOG_FUNCTION(this << mldAddr);
1073
1075 "DL and UL directions for TID-to-Link mapping must be set separately");
1076
1078
1079 auto [it, inserted] = mappings.emplace(mldAddr, mapping);
1080
1081 if (inserted)
1082 {
1083 // we are done
1084 return;
1085 }
1086
1087 // a previous mapping is stored for this MLD
1088 if (mapping.empty())
1089 {
1090 // the default mapping has been now negotiated
1091 it->second.clear();
1092 return;
1093 }
1094
1095 for (const auto& [tid, linkSet] : mapping)
1096 {
1097 it->second[tid] = linkSet;
1098 }
1099}
1100
1101std::optional<std::reference_wrapper<const WifiTidLinkMapping>>
1103{
1105 "Cannot request TID-to-Link mapping for both directions");
1106
1107 const auto& mappings =
1109
1110 if (const auto it = mappings.find(mldAddr); it != mappings.cend())
1111 {
1112 return it->second;
1113 }
1114 return std::nullopt;
1115}
1116
1117bool
1118WifiMac::TidMappedOnLink(Mac48Address mldAddr, WifiDirection dir, uint8_t tid, uint8_t linkId) const
1119{
1121 "Cannot request TID-to-Link mapping for both directions");
1122
1123 const auto& mappings =
1125
1126 const auto it = mappings.find(mldAddr);
1127
1128 if (it == mappings.cend())
1129 {
1130 // TID-to-link mapping was not negotiated, TIDs are mapped to all setup links
1131 return GetWifiRemoteStationManager(linkId)->GetMldAddress(mldAddr).has_value();
1132 }
1133
1134 auto linkSetIt = it->second.find(tid);
1135
1136 if (linkSetIt == it->second.cend())
1137 {
1138 // If there is no successfully negotiated TID-to-link mapping for a TID, then the TID
1139 // is mapped to all setup links for DL and UL (Sec. 35.3.7.1.3 of 802.11be D3.1)
1140 return GetWifiRemoteStationManager(linkId)->GetMldAddress(mldAddr).has_value();
1141 }
1142
1143 return std::find(linkSetIt->second.cbegin(), linkSetIt->second.cend(), linkId) !=
1144 linkSetIt->second.cend();
1145}
1146
1147void
1148WifiMac::SetWifiPhys(const std::vector<Ptr<WifiPhy>>& phys)
1149{
1150 NS_LOG_FUNCTION(this);
1151 ResetWifiPhys();
1152
1153 NS_ABORT_MSG_UNLESS(m_links.empty() || m_links.size() == phys.size(),
1154 "If links have been already created, the number of provided "
1155 "PHY objects ("
1156 << phys.size()
1157 << ") must match the number "
1158 "of links ("
1159 << m_links.size() << ")");
1160
1161 for (std::size_t i = 0; i < phys.size(); i++)
1162 {
1163 // the link may already exist in case we are setting new PHY objects
1164 // (ResetWifiPhys just nullified the PHY(s) but left the links)
1165 // or the remote station managers were configured first
1166 auto [it, inserted] = m_links.emplace(i, CreateLinkEntity());
1167 m_linkIds.insert(i);
1168 it->second->phy = phys[i];
1169 }
1170}
1171
1173WifiMac::GetWifiPhy(uint8_t linkId) const
1174{
1175 return GetLink(linkId).phy;
1176}
1177
1178void
1180{
1181 NS_LOG_FUNCTION(this);
1182 for (auto& [id, link] : m_links)
1183 {
1184 if (link->feManager)
1185 {
1186 link->feManager->ResetPhy();
1187 }
1188 if (link->channelAccessManager)
1189 {
1190 link->channelAccessManager->RemovePhyListener(link->phy);
1191 }
1192 link->phy = nullptr;
1193 }
1194}
1195
1196void
1198{
1199 NS_LOG_FUNCTION(this << enable);
1201 m_qosSupported = enable;
1202
1203 if (!m_qosSupported)
1204 {
1205 // create a non-QoS TXOP
1206 m_txop = CreateObject<Txop>();
1209 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
1210 }
1211 else
1212 {
1213 // Construct the EDCAFs. The ordering is important - highest
1214 // priority (Table 9-1 UP-to-AC mapping; IEEE 802.11-2012) must be created
1215 // first.
1220 }
1221}
1222
1223bool
1225{
1226 return m_qosSupported;
1227}
1228
1229bool
1230WifiMac::GetErpSupported(uint8_t linkId) const
1231{
1232 return GetLink(linkId).erpSupported;
1233}
1234
1235void
1236WifiMac::SetErpSupported(bool enable, uint8_t linkId)
1237{
1238 NS_LOG_FUNCTION(this << enable << +linkId);
1239 if (enable)
1240 {
1241 SetDsssSupported(true, linkId);
1242 }
1243 GetLink(linkId).erpSupported = enable;
1244}
1245
1246void
1247WifiMac::SetDsssSupported(bool enable, uint8_t linkId)
1248{
1249 NS_LOG_FUNCTION(this << enable << +linkId);
1250 GetLink(linkId).dsssSupported = enable;
1251}
1252
1253bool
1254WifiMac::GetDsssSupported(uint8_t linkId) const
1255{
1256 return GetLink(linkId).dsssSupported;
1257}
1258
1259void
1261{
1262 NS_LOG_FUNCTION(this);
1263 m_ctsToSelfSupported = enable;
1264}
1265
1266void
1268{
1269 NS_LOG_FUNCTION(this << enable);
1270 m_shortSlotTimeSupported = enable;
1271}
1272
1273bool
1275{
1277}
1278
1279bool
1281{
1282 return false;
1283}
1284
1285void
1287{
1288 NS_LOG_FUNCTION(this);
1289 m_forwardUp = upCallback;
1290}
1291
1292void
1294{
1295 NS_LOG_FUNCTION(this);
1296 m_linkUp = linkUp;
1297}
1298
1299void
1301{
1302 NS_LOG_FUNCTION(this);
1303 m_linkDown = linkDown;
1304}
1305
1306void
1308{
1309 NS_LOG_FUNCTION(this << mldAddr);
1310
1313 "This method can be used to enforce TID-to-Link mapping for one direction at a time");
1314
1315 const auto& mappings =
1317
1318 auto it = mappings.find(mldAddr);
1319
1320 if (it == mappings.cend())
1321 {
1322 // no mapping has been ever negotiated with the given MLD, the default mapping is used
1323 return;
1324 }
1325
1326 std::set<uint8_t> setupLinks;
1327
1328 // find the IDs of the links setup with the given MLD
1329 for (const auto& [id, link] : m_links)
1330 {
1331 if (link->stationManager->GetMldAddress(mldAddr))
1332 {
1333 setupLinks.insert(id);
1334 }
1335 }
1336
1337 auto linkMapping = it->second;
1338
1339 if (linkMapping.empty())
1340 {
1341 // default link mapping, each TID mapped on all setup links
1342 for (uint8_t tid = 0; tid < 8; tid++)
1343 {
1344 linkMapping.emplace(tid, setupLinks);
1345 }
1346 }
1347
1348 for (const auto& [tid, linkSet] : linkMapping)
1349 {
1350 decltype(setupLinks) mappedLinks; // empty
1351 auto notMappedLinks = setupLinks; // all setup links
1352
1353 for (const auto id : linkSet)
1354 {
1355 if (setupLinks.find(id) != setupLinks.cend())
1356 {
1357 // link is mapped
1358 mappedLinks.insert(id);
1359 notMappedLinks.erase(id);
1360 }
1361 }
1362
1363 // unblock mapped links
1364 NS_ABORT_MSG_IF(mappedLinks.empty(), "Every TID must be mapped to at least a link");
1365
1367 QosUtilsMapTidToAc(tid),
1369 mldAddr,
1370 GetAddress(),
1371 {tid},
1372 mappedLinks);
1373
1374 // block unmapped links
1375 if (!notMappedLinks.empty())
1376 {
1378 QosUtilsMapTidToAc(tid),
1380 mldAddr,
1381 GetAddress(),
1382 {tid},
1383 notMappedLinks);
1384 }
1385 }
1386}
1387
1388void
1390 const Mac48Address& address,
1391 const std::set<uint8_t>& linkIds)
1392{
1393 NS_LOG_FUNCTION(this << reason << address);
1395
1396 for (const auto linkId : linkIds)
1397 {
1398 auto& link = GetLink(linkId);
1399 auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address).value_or(address);
1400
1401 if (link.stationManager->GetMldAddress(address) == address && linkAddr == address)
1402 {
1403 NS_LOG_DEBUG("Link " << +linkId << " has not been setup with the MLD, skip");
1404 continue;
1405 }
1406
1407 for (const auto [acIndex, ac] : wifiAcList)
1408 {
1409 // block queues storing QoS data frames and control frames that use MLD addresses
1410 m_scheduler->BlockQueues(reason,
1411 acIndex,
1413 address,
1414 GetAddress(),
1415 {ac.GetLowTid(), ac.GetHighTid()},
1416 {linkId});
1417 // block queues storing management and control frames that use link addresses
1418 m_scheduler->BlockQueues(reason,
1419 acIndex,
1421 linkAddr,
1422 link.feManager->GetAddress(),
1423 {},
1424 {linkId});
1425 }
1426 }
1427}
1428
1429void
1431 const Mac48Address& address,
1432 const std::set<uint8_t>& linkIds)
1433{
1434 NS_LOG_FUNCTION(this << reason << address);
1436
1437 for (const auto linkId : linkIds)
1438 {
1439 auto& link = GetLink(linkId);
1440 auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address).value_or(address);
1441
1442 if (link.stationManager->GetMldAddress(address) == address && linkAddr == address)
1443 {
1444 NS_LOG_DEBUG("Link " << +linkId << " has not been setup with the MLD, skip");
1445 continue;
1446 }
1447
1448 for (const auto [acIndex, ac] : wifiAcList)
1449 {
1450 // unblock queues storing QoS data frames and control frames that use MLD addresses
1451 m_scheduler->UnblockQueues(reason,
1452 acIndex,
1454 address,
1455 GetAddress(),
1456 {ac.GetLowTid(), ac.GetHighTid()},
1457 {linkId});
1458 // unblock queues storing management and control frames that use link addresses
1459 m_scheduler->UnblockQueues(reason,
1460 acIndex,
1462 linkAddr,
1463 link.feManager->GetAddress(),
1464 {},
1465 {linkId});
1466 // request channel access if needed (schedule now because multiple invocations
1467 // of this method may be done in a loop at the caller)
1468 auto qosTxop = GetQosTxop(acIndex);
1470 if (qosTxop->GetAccessStatus(linkId) == Txop::NOT_REQUESTED &&
1471 qosTxop->HasFramesToTransmit(linkId))
1472 {
1473 GetLink(linkId).channelAccessManager->RequestAccess(qosTxop);
1474 }
1475 });
1476 }
1477 }
1478}
1479
1480void
1482{
1483 // We expect WifiMac subclasses which do support forwarding (e.g.,
1484 // AP) to override this method. Therefore, we throw a fatal error if
1485 // someone tries to invoke this method on a class which has not done
1486 // this.
1487 NS_FATAL_ERROR("This MAC entity (" << this << ", " << GetAddress()
1488 << ") does not support Enqueue() with from address");
1489}
1490
1491void
1493{
1494 NS_LOG_FUNCTION(this << packet << from << to);
1495 m_forwardUp(packet, from, to);
1496}
1497
1498void
1500{
1501 NS_LOG_FUNCTION(this << *mpdu << linkId);
1502
1503 const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader();
1504 Mac48Address to = hdr->GetAddr1();
1505 Mac48Address from = hdr->GetAddr2();
1506 auto myAddr = hdr->IsData() ? Mac48Address::ConvertFrom(GetDevice()->GetAddress())
1507 : GetFrameExchangeManager(linkId)->GetAddress();
1508
1509 // We don't know how to deal with any frame that is not addressed to
1510 // us (and odds are there is nothing sensible we could do anyway),
1511 // so we ignore such frames.
1512 //
1513 // The derived class may also do some such filtering, but it doesn't
1514 // hurt to have it here too as a backstop.
1515 if (to != myAddr)
1516 {
1517 return;
1518 }
1519
1520 // Nothing to do with (QoS) Null Data frames
1521 if (hdr->IsData() && !hdr->HasData())
1522 {
1523 return;
1524 }
1525
1526 if (hdr->IsMgt() && hdr->IsAction())
1527 {
1528 // There is currently only any reason for Management Action
1529 // frames to be flying about if we are a QoS STA.
1531
1532 auto& link = GetLink(linkId);
1533 WifiActionHeader actionHdr;
1534 Ptr<Packet> packet = mpdu->GetPacket()->Copy();
1535 packet->RemoveHeader(actionHdr);
1536
1537 switch (actionHdr.GetCategory())
1538 {
1540
1541 switch (actionHdr.GetAction().blockAck)
1542 {
1544 MgtAddBaRequestHeader reqHdr;
1545 packet->RemoveHeader(reqHdr);
1546
1547 // We've received an ADDBA Request. Our policy here is
1548 // to automatically accept it, so we get the ADDBA
1549 // Response on it's way immediately.
1550 NS_ASSERT(link.feManager);
1551 auto htFem = DynamicCast<HtFrameExchangeManager>(link.feManager);
1552 if (htFem)
1553 {
1554 htFem->SendAddBaResponse(&reqHdr, from);
1555 }
1556 // This frame is now completely dealt with, so we're done.
1557 return;
1558 }
1560 MgtAddBaResponseHeader respHdr;
1561 packet->RemoveHeader(respHdr);
1562
1563 // We've received an ADDBA Response. We assume that it
1564 // indicates success after an ADDBA Request we have
1565 // sent (we could, in principle, check this, but it
1566 // seems a waste given the level of the current model)
1567 // and act by locally establishing the agreement on
1568 // the appropriate queue.
1569 auto recipientMld = link.stationManager->GetMldAddress(from);
1570 auto recipient = (recipientMld ? *recipientMld : from);
1571 GetQosTxop(respHdr.GetTid())->GotAddBaResponse(respHdr, recipient);
1572 auto htFem = DynamicCast<HtFrameExchangeManager>(link.feManager);
1573 if (htFem)
1574 {
1575 GetQosTxop(respHdr.GetTid())
1576 ->GetBaManager()
1577 ->SetBlockAckInactivityCallback(
1579 }
1580 // This frame is now completely dealt with, so we're done.
1581 return;
1582 }
1584 MgtDelBaHeader delBaHdr;
1585 packet->RemoveHeader(delBaHdr);
1586 auto recipientMld = link.stationManager->GetMldAddress(from);
1587 auto recipient = (recipientMld ? *recipientMld : from);
1588
1589 if (delBaHdr.IsByOriginator())
1590 {
1591 // This DELBA frame was sent by the originator, so
1592 // this means that an ingoing established
1593 // agreement exists in BlockAckManager and we need to
1594 // destroy it.
1595 GetQosTxop(delBaHdr.GetTid())
1596 ->GetBaManager()
1597 ->DestroyRecipientAgreement(recipient, delBaHdr.GetTid());
1598 }
1599 else
1600 {
1601 // We must have been the originator. We need to
1602 // tell the correct queue that the agreement has
1603 // been torn down
1604 GetQosTxop(delBaHdr.GetTid())->GotDelBaFrame(&delBaHdr, recipient);
1605 }
1606 // This frame is now completely dealt with, so we're done.
1607 return;
1608 }
1609 default:
1610 NS_FATAL_ERROR("Unsupported Action field in Block Ack Action frame");
1611 return;
1612 }
1613 default:
1614 NS_FATAL_ERROR("Unsupported Action frame received");
1615 return;
1616 }
1617 }
1618 NS_FATAL_ERROR("Don't know how to handle frame (type=" << hdr->GetType());
1619}
1620
1621void
1623{
1624 NS_LOG_FUNCTION(this << *mpdu);
1625 for (auto& msduPair : *PeekPointer(mpdu))
1626 {
1627 ForwardUp(msduPair.first,
1628 msduPair.second.GetSourceAddr(),
1629 msduPair.second.GetDestinationAddr());
1630 }
1631}
1632
1633std::optional<Mac48Address>
1634WifiMac::GetMldAddress(const Mac48Address& remoteAddr) const
1635{
1636 for (const auto& [id, link] : m_links)
1637 {
1638 if (auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
1639 {
1640 return *mldAddress;
1641 }
1642 }
1643 return std::nullopt;
1644}
1645
1648{
1649 for (const auto& [id, link] : m_links)
1650 {
1651 if (auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
1652 {
1653 // this is a link setup with remote MLD
1654 if (mldAddress != remoteAddr)
1655 {
1656 // the remote address is the address of a STA affiliated with the remote MLD
1657 return link->feManager->GetAddress();
1658 }
1659 // we have to return our MLD address
1660 return m_address;
1661 }
1662 }
1663 // we get here if no ML setup was established between this device and the remote device,
1664 // i.e., they are not both multi-link devices
1665 if (GetNLinks() == 1)
1666 {
1667 // this is a single link device
1668 return m_address;
1669 }
1670 // this is an MLD (hence the remote device is single link)
1671 return DoGetLocalAddress(remoteAddr);
1672}
1673
1675WifiMac::DoGetLocalAddress(const Mac48Address& remoteAddr [[maybe_unused]]) const
1676{
1677 return m_address;
1678}
1679
1682{
1683 // BA agreements are indexed by the MLD address if ML setup was performed
1684 recipient = GetMldAddress(recipient).value_or(recipient);
1685
1686 auto agreement = GetQosTxop(tid)->GetBaManager()->GetAgreementAsOriginator(recipient, tid);
1687 if (!agreement || !agreement->get().IsEstablished())
1688 {
1689 return std::nullopt;
1690 }
1691 return agreement;
1692}
1693
1696{
1697 // BA agreements are indexed by the MLD address if ML setup was performed
1698 originator = GetMldAddress(originator).value_or(originator);
1699 return GetQosTxop(tid)->GetBaManager()->GetAgreementAsRecipient(originator, tid);
1700}
1701
1703WifiMac::GetBaTypeAsOriginator(const Mac48Address& recipient, uint8_t tid) const
1704{
1705 auto agreement = GetBaAgreementEstablishedAsOriginator(recipient, tid);
1706 NS_ABORT_MSG_IF(!agreement,
1707 "No existing Block Ack agreement with " << recipient << " TID: " << +tid);
1708 return agreement->get().GetBlockAckType();
1709}
1710
1712WifiMac::GetBarTypeAsOriginator(const Mac48Address& recipient, uint8_t tid) const
1713{
1714 auto agreement = GetBaAgreementEstablishedAsOriginator(recipient, tid);
1715 NS_ABORT_MSG_IF(!agreement,
1716 "No existing Block Ack agreement with " << recipient << " TID: " << +tid);
1717 return agreement->get().GetBlockAckReqType();
1718}
1719
1721WifiMac::GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
1722{
1723 auto agreement = GetBaAgreementEstablishedAsRecipient(originator, tid);
1724 NS_ABORT_MSG_IF(!agreement,
1725 "No existing Block Ack agreement with " << originator << " TID: " << +tid);
1726 return agreement->get().GetBlockAckType();
1727}
1728
1730WifiMac::GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
1731{
1732 auto agreement = GetBaAgreementEstablishedAsRecipient(originator, tid);
1733 NS_ABORT_MSG_IF(!agreement,
1734 "No existing Block Ack agreement with " << originator << " TID: " << +tid);
1735 return agreement->get().GetBlockAckReqType();
1736}
1737
1740{
1741 return GetDevice()->GetHtConfiguration();
1742}
1743
1746{
1747 return GetDevice()->GetVhtConfiguration();
1748}
1749
1752{
1753 return GetDevice()->GetHeConfiguration();
1754}
1755
1758{
1759 return GetDevice()->GetEhtConfiguration();
1760}
1761
1762bool
1764{
1765 return bool(GetDevice()->GetHtConfiguration());
1766}
1767
1768bool
1769WifiMac::GetVhtSupported(uint8_t linkId) const
1770{
1771 return (GetDevice()->GetVhtConfiguration() &&
1772 GetWifiPhy(linkId)->GetPhyBand() != WIFI_PHY_BAND_2_4GHZ);
1773}
1774
1775bool
1777{
1778 return bool(GetDevice()->GetHeConfiguration());
1779}
1780
1781bool
1783{
1784 return bool(GetDevice()->GetEhtConfiguration());
1785}
1786
1787bool
1789{
1790 for (const auto& [id, link] : m_links)
1791 {
1792 if (link->stationManager->GetHtSupported(address))
1793 {
1794 return true;
1795 }
1796 }
1797 return false;
1798}
1799
1800bool
1802{
1803 for (const auto& [id, link] : m_links)
1804 {
1805 if (link->stationManager->GetVhtSupported(address))
1806 {
1807 return true;
1808 }
1809 }
1810 return false;
1811}
1812
1813bool
1815{
1816 for (const auto& [id, link] : m_links)
1817 {
1818 if (link->stationManager->GetHeSupported(address))
1819 {
1820 return true;
1821 }
1822 }
1823 return false;
1824}
1825
1826bool
1828{
1829 for (const auto& [id, link] : m_links)
1830 {
1831 if (link->stationManager->GetEhtSupported(address))
1832 {
1833 return true;
1834 }
1835 }
1836 return false;
1837}
1838
1839void
1841{
1842 NS_LOG_FUNCTION(this << +threshold);
1843 if (m_qosSupported)
1844 {
1845 GetVOQueue()->SetBlockAckThreshold(threshold);
1846 }
1847}
1848
1849void
1851{
1852 NS_LOG_FUNCTION(this << +threshold);
1853 if (m_qosSupported)
1854 {
1855 GetVIQueue()->SetBlockAckThreshold(threshold);
1856 }
1857}
1858
1859void
1861{
1862 NS_LOG_FUNCTION(this << +threshold);
1863 if (m_qosSupported)
1864 {
1865 GetBEQueue()->SetBlockAckThreshold(threshold);
1866 }
1867}
1868
1869void
1871{
1872 NS_LOG_FUNCTION(this << +threshold);
1873 if (m_qosSupported)
1874 {
1875 GetBKQueue()->SetBlockAckThreshold(threshold);
1876 }
1877}
1878
1879void
1881{
1882 NS_LOG_FUNCTION(this << timeout);
1883 if (m_qosSupported)
1884 {
1886 }
1887}
1888
1889void
1891{
1892 NS_LOG_FUNCTION(this << timeout);
1893 if (m_qosSupported)
1894 {
1896 }
1897}
1898
1899void
1901{
1902 NS_LOG_FUNCTION(this << timeout);
1903 if (m_qosSupported)
1904 {
1906 }
1907}
1908
1909void
1911{
1912 NS_LOG_FUNCTION(this << timeout);
1913 if (m_qosSupported)
1914 {
1916 }
1917}
1918
1921{
1922 NS_LOG_FUNCTION(this);
1923 ExtendedCapabilities capabilities;
1924 capabilities.SetHtSupported(GetHtSupported());
1926 // TODO: to be completed
1927 return capabilities;
1928}
1929
1931WifiMac::GetHtCapabilities(uint8_t linkId) const
1932{
1933 NS_LOG_FUNCTION(this << +linkId);
1935 HtCapabilities capabilities;
1936
1937 auto phy = GetWifiPhy(linkId);
1938 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
1939 bool sgiSupported = htConfiguration->GetShortGuardIntervalSupported();
1940 capabilities.SetLdpc(htConfiguration->GetLdpcSupported());
1941 capabilities.SetSupportedChannelWidth(htConfiguration->Get40MHzOperationSupported() ? 1 : 0);
1942 capabilities.SetShortGuardInterval20(sgiSupported);
1943 capabilities.SetShortGuardInterval40(phy->GetChannelWidth() >= 40 && sgiSupported);
1944 // Set Maximum A-MSDU Length subfield
1945 uint16_t maxAmsduSize =
1947 if (maxAmsduSize <= 3839)
1948 {
1949 capabilities.SetMaxAmsduLength(3839);
1950 }
1951 else
1952 {
1953 capabilities.SetMaxAmsduLength(7935);
1954 }
1955 uint32_t maxAmpduLength =
1957 // round to the next power of two minus one
1958 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
1959 // The maximum A-MPDU length in HT capabilities elements ranges from 2^13-1 to 2^16-1
1960 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 65535U));
1961
1962 capabilities.SetLSigProtectionSupport(true);
1963 uint64_t maxSupportedRate = 0; // in bit/s
1964 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HT))
1965 {
1966 capabilities.SetRxMcsBitmask(mcs.GetMcsValue());
1967 uint8_t nss = (mcs.GetMcsValue() / 8) + 1;
1968 NS_ASSERT(nss > 0 && nss < 5);
1969 uint64_t dataRate = mcs.GetDataRate(phy->GetChannelWidth(), sgiSupported ? 400 : 800, nss);
1970 if (dataRate > maxSupportedRate)
1971 {
1972 maxSupportedRate = dataRate;
1973 NS_LOG_DEBUG("Updating maxSupportedRate to " << maxSupportedRate);
1974 }
1975 }
1976 capabilities.SetRxHighestSupportedDataRate(
1977 static_cast<uint16_t>(maxSupportedRate / 1e6)); // in Mbit/s
1978 capabilities.SetTxMcsSetDefined(phy->GetNMcs() > 0);
1979 capabilities.SetTxMaxNSpatialStreams(phy->GetMaxSupportedTxSpatialStreams());
1980 // we do not support unequal modulations
1981 capabilities.SetTxRxMcsSetUnequal(0);
1982 capabilities.SetTxUnequalModulation(0);
1983
1984 return capabilities;
1985}
1986
1988WifiMac::GetVhtCapabilities(uint8_t linkId) const
1989{
1990 NS_LOG_FUNCTION(this << +linkId);
1991 NS_ASSERT(GetVhtSupported(linkId));
1992 VhtCapabilities capabilities;
1993
1994 auto phy = GetWifiPhy(linkId);
1995 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
1996 NS_ABORT_MSG_IF(!htConfiguration->Get40MHzOperationSupported(),
1997 "VHT stations have to support 40 MHz operation");
1998 Ptr<VhtConfiguration> vhtConfiguration = GetVhtConfiguration();
1999 bool sgiSupported = htConfiguration->GetShortGuardIntervalSupported();
2000 capabilities.SetSupportedChannelWidthSet(vhtConfiguration->Get160MHzOperationSupported() ? 1
2001 : 0);
2002 // Set Maximum MPDU Length subfield
2003 uint16_t maxAmsduSize =
2005 if (maxAmsduSize <= 3839)
2006 {
2007 capabilities.SetMaxMpduLength(3895);
2008 }
2009 else if (maxAmsduSize <= 7935)
2010 {
2011 capabilities.SetMaxMpduLength(7991);
2012 }
2013 else
2014 {
2015 capabilities.SetMaxMpduLength(11454);
2016 }
2017 uint32_t maxAmpduLength =
2019 // round to the next power of two minus one
2020 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2021 // The maximum A-MPDU length in VHT capabilities elements ranges from 2^13-1 to 2^20-1
2022 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 1048575U));
2023
2024 capabilities.SetRxLdpc(htConfiguration->GetLdpcSupported());
2025 capabilities.SetShortGuardIntervalFor80Mhz((phy->GetChannelWidth() == 80) && sgiSupported);
2026 capabilities.SetShortGuardIntervalFor160Mhz((phy->GetChannelWidth() == 160) && sgiSupported);
2027 uint8_t maxMcs = 0;
2028 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
2029 {
2030 if (mcs.GetMcsValue() > maxMcs)
2031 {
2032 maxMcs = mcs.GetMcsValue();
2033 }
2034 }
2035 // Support same MaxMCS for each spatial stream
2036 for (uint8_t nss = 1; nss <= phy->GetMaxSupportedRxSpatialStreams(); nss++)
2037 {
2038 capabilities.SetRxMcsMap(maxMcs, nss);
2039 }
2040 for (uint8_t nss = 1; nss <= phy->GetMaxSupportedTxSpatialStreams(); nss++)
2041 {
2042 capabilities.SetTxMcsMap(maxMcs, nss);
2043 }
2044 uint64_t maxSupportedRateLGI = 0; // in bit/s
2045 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
2046 {
2047 if (!mcs.IsAllowed(phy->GetChannelWidth(), 1))
2048 {
2049 continue;
2050 }
2051 if (mcs.GetDataRate(phy->GetChannelWidth()) > maxSupportedRateLGI)
2052 {
2053 maxSupportedRateLGI = mcs.GetDataRate(phy->GetChannelWidth());
2054 NS_LOG_DEBUG("Updating maxSupportedRateLGI to " << maxSupportedRateLGI);
2055 }
2056 }
2058 static_cast<uint16_t>(maxSupportedRateLGI / 1e6)); // in Mbit/s
2060 static_cast<uint16_t>(maxSupportedRateLGI / 1e6)); // in Mbit/s
2061 // To be filled in once supported
2062 capabilities.SetRxStbc(0);
2063 capabilities.SetTxStbc(0);
2064
2065 return capabilities;
2066}
2067
2069WifiMac::GetHeCapabilities(uint8_t linkId) const
2070{
2071 NS_LOG_FUNCTION(this << +linkId);
2073 HeCapabilities capabilities;
2074
2075 Ptr<WifiPhy> phy = GetLink(linkId).phy;
2076 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
2077 Ptr<HeConfiguration> heConfiguration = GetHeConfiguration();
2078 uint8_t channelWidthSet = 0;
2079 if ((phy->GetChannelWidth() >= 40) && (phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ))
2080 {
2081 channelWidthSet |= 0x01;
2082 }
2083 if (((phy->GetChannelWidth() >= 80) || GetEhtSupported()) &&
2084 ((phy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ)))
2085 {
2086 channelWidthSet |= 0x02;
2087 }
2088 if ((phy->GetChannelWidth() >= 160) &&
2089 ((phy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ)))
2090 {
2091 channelWidthSet |= 0x04;
2092 }
2093 capabilities.SetChannelWidthSet(channelWidthSet);
2094 capabilities.SetLdpcCodingInPayload(htConfiguration->GetLdpcSupported());
2095 if (heConfiguration->GetGuardInterval() == NanoSeconds(800))
2096 {
2097 // todo: We assume for now that if we support 800ns GI then 1600ns GI is supported as well
2098 // todo: Assuming reception support for both 1x HE LTF and 4x HE LTF 800 ns
2099 capabilities.SetHeSuPpdu1xHeLtf800nsGi(true);
2100 capabilities.SetHePpdu4xHeLtf800nsGi(true);
2101 }
2102
2103 uint32_t maxAmpduLength =
2105 // round to the next power of two minus one
2106 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2107 // The maximum A-MPDU length in HE capabilities elements ranges from 2^20-1 to 2^23-1
2108 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 1048575U), 8388607U));
2109
2110 uint8_t maxMcs = 0;
2111 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HE))
2112 {
2113 if (mcs.GetMcsValue() > maxMcs)
2114 {
2115 maxMcs = mcs.GetMcsValue();
2116 }
2117 }
2118 capabilities.SetHighestMcsSupported(maxMcs);
2119 capabilities.SetHighestNssSupported(phy->GetMaxSupportedTxSpatialStreams());
2120
2121 return capabilities;
2122}
2123
2125WifiMac::GetEhtCapabilities(uint8_t linkId) const
2126{
2127 NS_LOG_FUNCTION(this << +linkId);
2129 EhtCapabilities capabilities;
2130
2131 Ptr<WifiPhy> phy = GetLink(linkId).phy;
2132
2133 // Set Maximum MPDU Length subfield (Reserved when transmitted in 5 GHz or 6 GHz band)
2134 if (phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
2135 {
2136 uint16_t maxAmsduSize =
2138 // Table 9-34—Maximum data unit sizes (in octets) and durations (in microseconds)
2139 if (maxAmsduSize <= 3839)
2140 {
2141 capabilities.SetMaxMpduLength(3895);
2142 }
2143 else if (maxAmsduSize <= 7935)
2144 {
2145 capabilities.SetMaxMpduLength(7991);
2146 }
2147 else
2148 {
2149 capabilities.SetMaxMpduLength(11454);
2150 }
2151 }
2152
2153 // Set Maximum A-MPDU Length Exponent Extension subfield
2154 uint32_t maxAmpduLength =
2156 // round to the next power of two minus one
2157 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2158 // The maximum A-MPDU length in EHT capabilities elements ranges from 2^23-1 to 2^24-1
2159 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8388607U), 16777215U));
2160
2161 // Set the PHY capabilities
2162 const bool support4096Qam = phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, 12);
2164 support4096Qam ? 1 : 0;
2166 support4096Qam ? 1 : 0;
2167
2168 const uint8_t maxTxNss = phy->GetMaxSupportedTxSpatialStreams();
2169 const uint8_t maxRxNss = phy->GetMaxSupportedRxSpatialStreams();
2170 if (phy->GetChannelWidth() == 20)
2171 {
2172 for (auto maxMcs : {7, 9, 11, 13})
2173 {
2174 capabilities.SetSupportedRxEhtMcsAndNss(
2176 maxMcs,
2177 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2178 capabilities.SetSupportedTxEhtMcsAndNss(
2180 maxMcs,
2181 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2182 }
2183 }
2184 else
2185 {
2186 for (auto maxMcs : {9, 11, 13})
2187 {
2188 capabilities.SetSupportedRxEhtMcsAndNss(
2190 maxMcs,
2191 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2192 capabilities.SetSupportedTxEhtMcsAndNss(
2194 maxMcs,
2195 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2196 }
2197 }
2198 if (phy->GetChannelWidth() >= 160)
2199 {
2200 for (auto maxMcs : {9, 11, 13})
2201 {
2202 capabilities.SetSupportedRxEhtMcsAndNss(
2204 maxMcs,
2205 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2206 capabilities.SetSupportedTxEhtMcsAndNss(
2208 maxMcs,
2209 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2210 }
2211 }
2212 // 320 MHz not supported yet
2213
2214 return capabilities;
2215}
2216
2219{
2220 uint32_t maxSize = 0;
2221 switch (ac)
2222 {
2223 case AC_BE:
2224 maxSize = m_beMaxAmpduSize;
2225 break;
2226 case AC_BK:
2227 maxSize = m_bkMaxAmpduSize;
2228 break;
2229 case AC_VI:
2230 maxSize = m_viMaxAmpduSize;
2231 break;
2232 case AC_VO:
2233 maxSize = m_voMaxAmpduSize;
2234 break;
2235 default:
2236 NS_ABORT_MSG("Unknown AC " << ac);
2237 return 0;
2238 }
2239 return maxSize;
2240}
2241
2242uint16_t
2244{
2245 uint16_t maxSize = 0;
2246 switch (ac)
2247 {
2248 case AC_BE:
2249 maxSize = m_beMaxAmsduSize;
2250 break;
2251 case AC_BK:
2252 maxSize = m_bkMaxAmsduSize;
2253 break;
2254 case AC_VI:
2255 maxSize = m_viMaxAmsduSize;
2256 break;
2257 case AC_VO:
2258 maxSize = m_voMaxAmsduSize;
2259 break;
2260 default:
2261 NS_ABORT_MSG("Unknown AC " << ac);
2262 return 0;
2263 }
2264 return maxSize;
2265}
2266
2267} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
The IEEE 802.11be EHT Capabilities.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
void SetSupportedTxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType, uint8_t upperMcs, uint8_t maxNss)
Set a subfield of the Supported EHT-MCS And NSS Set.
EhtPhyCapabilities m_phyCapabilities
EHT PHY Capabilities Info subfield.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum A-MPDU length.
void SetSupportedRxEhtMcsAndNss(EhtMcsAndNssSet::EhtMcsMapType mapType, uint8_t upperMcs, uint8_t maxNss)
Set a subfield of the Supported EHT-MCS And NSS Set.
The Extended Capabilities Information Element.
void SetHtSupported(uint8_t htSupported)
Set the HT Supported flag.
void SetVhtSupported(uint8_t vhtSupported)
Set the VHT Supported flag.
The IEEE 802.11ax HE Capabilities.
void SetHeSuPpdu1xHeLtf800nsGi(bool heSuPpdu1xHeLtf800nsGi)
Set 1xHE-LTF and 800ns GI in HE SU PPDU reception support.
void SetLdpcCodingInPayload(uint8_t ldpcCodingInPayload)
Set indication whether the transmission and reception of LDPC encoded packets is supported.
void SetHePpdu4xHeLtf800nsGi(bool heSuPpdu4xHeLtf800nsGi)
Set 4xHE-LTF and 800ns GI in HE SU PPDU and HE MU PPDU reception support.
void SetHighestNssSupported(uint8_t nss)
Set highest NSS supported.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetChannelWidthSet(uint8_t channelWidthSet)
Set channel width set.
void SetHighestMcsSupported(uint8_t mcs)
Set highest MCS supported.
The HT Capabilities Information Element.
void SetLdpc(uint8_t ldpc)
Set the LDPC field.
void SetTxRxMcsSetUnequal(uint8_t txRxMcsSetUnequal)
Set the transmit / receive MCS set unequal.
void SetRxHighestSupportedDataRate(uint16_t maxSupportedRate)
Set the receive highest supported data rate.
void SetLSigProtectionSupport(uint8_t lSigProtection)
Set the LSIG protection support.
void SetMaxAmsduLength(uint16_t maxAmsduLength)
Set the maximum AMSDU length.
void SetTxMaxNSpatialStreams(uint8_t maxTxSpatialStreams)
Set the transmit maximum N spatial streams.
void SetShortGuardInterval20(uint8_t shortGuardInterval)
Set the short guard interval 20 field.
void SetTxUnequalModulation(uint8_t txUnequalModulation)
Set the transmit unequal modulation.
void SetTxMcsSetDefined(uint8_t txMcsSetDefined)
Set the transmit MCS set defined.
void SetRxMcsBitmask(uint8_t index)
Set the receive MCS bitmask.
void SetSupportedChannelWidth(uint8_t supportedChannelWidth)
Set the supported channel width field.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetShortGuardInterval40(uint8_t shortGuardInterval)
Set the short guard interval 40 field.
void SendDelbaFrame(Mac48Address addr, uint8_t tid, bool byOriginator)
Sends DELBA frame to cancel a block ack agreement with STA addressed by addr for TID tid.
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address ConvertFrom(const Address &address)
Implement the header for management frames of type Add Block Ack request.
Definition: mgt-headers.h:795
Implement the header for management frames of type Add Block Ack response.
Definition: mgt-headers.h:926
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Delete Block Ack.
Definition: mgt-headers.h:1045
uint8_t GetTid() const
Return the Traffic ID (TID).
bool IsByOriginator() const
Check if the initiator bit in the DELBA is set.
A base class which provides memory management and object aggregation.
Definition: object.h:89
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:186
void Dispose()
Dispose of this Object.
Definition: object.cc:219
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:212
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:273
void GotAddBaResponse(const MgtAddBaResponseHeader &respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Definition: qos-txop.cc:615
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition: qos-txop.cc:686
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Definition: qos-txop.cc:650
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the BlockAck inactivity timeout.
Definition: qos-txop.cc:694
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:592
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the Txop has frames to transmit over the given link.
Definition: txop.cc:515
@ NOT_REQUESTED
Definition: txop.h:101
virtual void SetWifiMac(const Ptr< WifiMac > mac)
Set the wifi MAC this Txop is associated to.
Definition: txop.cc:209
void SwapLinks(std::map< uint8_t, uint8_t > links)
Swap the links based on the information included in the given map.
Definition: txop.cc:185
void SetTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set MacTxMiddle this Txop is associated to.
Definition: txop.cc:202
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition: txop.cc:220
a unique identifier for an interface.
Definition: type-id.h:59
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:64
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
Definition: type-id.h:66
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:930
@ OBSOLETE
Attribute or trace source is not used anymore; simulation fails.
Definition: type-id.h:76
Hold an unsigned integer type.
Definition: uinteger.h:45
The IEEE 802.11ac VHT Capabilities.
void SetRxHighestSupportedLgiDataRate(uint16_t supportedDatarate)
Set the receive highest supported LGI data rate.
void SetSupportedChannelWidthSet(uint8_t channelWidthSet)
Set the supported channel width set.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
void SetRxLdpc(uint8_t rxLdpc)
Set the receive LDPC.
void SetTxStbc(uint8_t txStbc)
Set the transmit STBC.
void SetTxMcsMap(uint8_t mcs, uint8_t nss)
void SetShortGuardIntervalFor80Mhz(uint8_t shortGuardInterval)
Set the short guard interval 80 MHz.
void SetTxHighestSupportedLgiDataRate(uint16_t supportedDatarate)
Set the transmit highest supported LGI data rate.
void SetShortGuardIntervalFor160Mhz(uint8_t shortGuardInterval)
Set the short guard interval 160 MHz.
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetRxMcsMap(uint8_t mcs, uint8_t nss)
void SetRxStbc(uint8_t rxStbc)
Set the receive STBC.
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
Definition: mgt-headers.h:539
CategoryValue GetCategory() const
Return the category value.
Definition: mgt-headers.cc:658
ActionValue GetAction() const
Return the action value.
Definition: mgt-headers.cc:693
Implements the IEEE 802.11 MAC header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
virtual WifiMacType GetType() const
Return the type (WifiMacType)
bool IsMgt() const
Return true if the Type is Management.
bool IsAction() const
Return true if the header is an Action header.
Mac48Address GetAddr2() const
Return the address in the Address 2 field.
bool HasData() const
Return true if the header type is DATA and is not DATA_NULL.
bool IsData() const
Return true if the Type is DATA.
uint16_t GetMaxAmsduSize(AcIndex ac) const
Return the maximum A-MSDU size of the given Access Category.
Definition: wifi-mac.cc:2243
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:866
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
Definition: wifi-mac.cc:533
virtual void NotifyChannelSwitching(uint8_t linkId)
Notify that channel on the given link has been switched.
Definition: wifi-mac.cc:582
std::optional< Mac48Address > GetMldAddress(const Mac48Address &remoteAddr) const
Definition: wifi-mac.cc:1634
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Definition: wifi-mac.cc:569
Mac48Address GetBssid(uint8_t linkId) const
Definition: wifi-mac.cc:478
uint16_t m_viMaxAmsduSize
maximum A-MSDU size for AC_VI (in bytes)
Definition: wifi-mac.h:1048
bool m_shortSlotTimeSupported
flag whether short slot time is supported
Definition: wifi-mac.h:1026
void ConfigurePhyDependentParameters(uint8_t linkId)
Configure PHY dependent parameters such as CWmin and CWmax on the given link.
Definition: wifi-mac.cc:797
Ptr< HeConfiguration > GetHeConfiguration() const
Definition: wifi-mac.cc:1751
DroppedMpduTracedCallback m_droppedMpduCallback
This trace indicates that an MPDU was dropped for the given reason.
Definition: wifi-mac.h:1119
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition: wifi-mac.cc:427
bool m_qosSupported
This Boolean is set true iff this WifiMac is to model 802.11e/WMM style Quality of Service.
Definition: wifi-mac.h:1024
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
Definition: wifi-mac.cc:920
Ptr< Txop > GetTxop() const
Accessor for the Txop object.
Definition: wifi-mac.cc:493
VhtCapabilities GetVhtCapabilities(uint8_t linkId) const
Return the VHT capabilities of the device for the given link.
Definition: wifi-mac.cc:1988
Callback< void > m_linkDown
Callback when a link is down.
Definition: wifi-mac.h:877
bool GetQosSupported() const
Return whether the device supports QoS.
Definition: wifi-mac.cc:1224
std::optional< std::reference_wrapper< const RecipientBlockAckAgreement > > RecipientAgreementOptConstRef
optional const reference to RecipientBlockAckAgreement
Definition: wifi-mac.h:619
virtual void SetAddress(Mac48Address address)
Definition: wifi-mac.cc:445
Ptr< Txop > m_txop
TXOP used for transmission of frames to non-QoS peers.
Definition: wifi-mac.h:873
void SetQosSupported(bool enable)
Enable or disable QoS support for the device.
Definition: wifi-mac.cc:1197
Mac48Address m_address
MAC address of this station.
Definition: wifi-mac.h:1035
std::set< uint8_t > m_linkIds
IDs of the links in use.
Definition: wifi-mac.h:1033
Ptr< WifiMacQueueScheduler > GetMacQueueScheduler() const
Get the wifi MAC queue scheduler.
Definition: wifi-mac.cc:576
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:935
BlockAckType GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1721
void SwapLinks(std::map< uint8_t, uint8_t > links)
Swap the links based on the information included in the given map.
Definition: wifi-mac.cc:997
uint16_t m_voMaxAmsduSize
maximum A-MSDU size for AC_VO (in bytes)
Definition: wifi-mac.h:1047
Ptr< MacRxMiddle > m_rxMiddle
RX middle (defragmentation etc.)
Definition: wifi-mac.h:871
Ptr< WifiMacQueueScheduler > m_scheduler
wifi MAC queue scheduler
Definition: wifi-mac.h:874
void DoInitialize() override
Initialize() implementation.
Definition: wifi-mac.cc:354
TypeOfStation m_typeOfStation
the type of station
Definition: wifi-mac.h:1029
uint32_t m_beMaxAmpduSize
maximum A-MPDU size for AC_BE (in bytes)
Definition: wifi-mac.h:1054
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:750
bool TidMappedOnLink(Mac48Address mldAddr, WifiDirection dir, uint8_t tid, uint8_t linkId) const
Check whether the given TID is mapped on the given link in the given direction for the given MLD.
Definition: wifi-mac.cc:1118
void UnblockUnicastTxOnLinks(WifiQueueBlockedReason reason, const Mac48Address &address, const std::set< uint8_t > &linkIds)
Unblock the transmission on the given links of all unicast frames addressed to the station with the g...
Definition: wifi-mac.cc:1430
Ssid GetSsid() const
Definition: wifi-mac.cc:465
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
Definition: wifi-mac.cc:885
void SetBeBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BE.
Definition: wifi-mac.cc:1860
bool GetErpSupported(uint8_t linkId) const
Return whether the device supports ERP on the given link.
Definition: wifi-mac.cc:1230
bool GetHtSupported() const
Return whether the device supports HT.
Definition: wifi-mac.cc:1763
void ResetWifiPhys()
Remove currently attached WifiPhy objects from this MAC.
Definition: wifi-mac.cc:1179
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
Definition: wifi-mac.h:1070
void SetErpSupported(bool enable, uint8_t linkId)
Enable or disable ERP support for the given link.
Definition: wifi-mac.cc:1236
uint32_t m_voMaxAmpduSize
maximum A-MPDU size for AC_VO (in bytes)
Definition: wifi-mac.h:1052
void ConfigureDcf(Ptr< Txop > dcf, uint32_t cwmin, uint32_t cwmax, std::list< bool > isDsss, AcIndex ac)
Definition: wifi-mac.cc:671
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition: wifi-mac.h:1031
void SetSsid(Ssid ssid)
Definition: wifi-mac.cc:458
void UpdateLinkId(uint8_t id)
This method is intended to be called when a link changes ID in order to update the link ID stored by ...
Definition: wifi-mac.cc:947
Ptr< QosTxop > GetVOQueue() const
Accessor for the AC_VO channel access function.
Definition: wifi-mac.cc:521
void SetTypeOfStation(TypeOfStation type)
This method is invoked by a subclass to specify what type of station it is implementing.
Definition: wifi-mac.cc:420
MpduTracedCallback m_ackedMpduCallback
ack'ed MPDU callback
Definition: wifi-mac.h:1124
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Definition: wifi-mac.cc:1173
void BlockUnicastTxOnLinks(WifiQueueBlockedReason reason, const Mac48Address &address, const std::set< uint8_t > &linkIds)
Block the transmission on the given links of all unicast frames addressed to the station with the giv...
Definition: wifi-mac.cc:1389
MpduTracedCallback m_nackedMpduCallback
nack'ed MPDU callback
Definition: wifi-mac.h:1125
bool GetEhtSupported() const
Return whether the device supports EHT.
Definition: wifi-mac.cc:1782
bool GetHeSupported() const
Return whether the device supports HE.
Definition: wifi-mac.cc:1776
HtCapabilities GetHtCapabilities(uint8_t linkId) const
Return the HT capabilities of the device for the given link.
Definition: wifi-mac.cc:1931
void SetBkBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BK.
Definition: wifi-mac.cc:1870
void SetVoBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VO.
Definition: wifi-mac.cc:1840
virtual std::optional< uint8_t > GetLinkIdByAddress(const Mac48Address &address) const
Get the ID of the link having the given MAC address, if any.
Definition: wifi-mac.cc:963
void NotifyPromiscRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:615
std::unordered_map< Mac48Address, WifiTidLinkMapping, WifiAddressHash > m_dlTidLinkMappings
DL TID-to-Link Mapping negotiated with an MLD (identified by its MLD address)
Definition: wifi-mac.h:1058
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the MAC has frames to transmit over the given link.
Definition: wifi-mac.cc:552
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > stationManager)
Definition: wifi-mac.cc:878
void ApplyTidLinkMapping(const Mac48Address &mldAddr, WifiDirection dir)
Apply the TID-to-Link Mapping negotiated with the given MLD for the given direction by properly confi...
Definition: wifi-mac.cc:1307
RecipientAgreementOptConstRef GetBaAgreementEstablishedAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1695
void SetBeBlockAckInactivityTimeout(uint16_t timeout)
Set BE block ack inactivity timeout.
Definition: wifi-mac.cc:1900
Ptr< EhtConfiguration > GetEhtConfiguration() const
Definition: wifi-mac.cc:1757
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
Definition: wifi-mac.h:1093
bool GetVhtSupported(uint8_t linkId) const
Return whether the device supports VHT on the given link.
Definition: wifi-mac.cc:1769
void SetDsssSupported(bool enable, uint8_t linkId)
Enable or disable DSSS support for the given link.
Definition: wifi-mac.cc:1247
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
Definition: wifi-mac.h:1077
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition: wifi-mac.h:872
void NotifyTx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:597
static TypeId GetTypeId()
Get the type ID.
Definition: wifi-mac.cc:67
Ptr< HtConfiguration > GetHtConfiguration() const
Definition: wifi-mac.cc:1739
std::optional< std::reference_wrapper< const WifiTidLinkMapping > > GetTidToLinkMapping(Mac48Address mldAddr, WifiDirection dir) const
Get the TID-to-Link Mapping negotiated with the given MLD (if any) for the given direction.
Definition: wifi-mac.cc:1102
uint32_t GetMaxAmpduSize(AcIndex ac) const
Return the maximum A-MPDU size of the given Access Category.
Definition: wifi-mac.cc:2218
BlockAckReqType GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1730
Ssid m_ssid
Service Set ID (SSID)
Definition: wifi-mac.h:1036
std::map< uint8_t, std::unique_ptr< LinkEntity > > m_links
ID-indexed map of Link objects.
Definition: wifi-mac.h:1032
virtual void DeaggregateAmsduAndForward(Ptr< const WifiMpdu > mpdu)
This method can be called to de-aggregate an A-MSDU and forward the constituent packets up the stack.
Definition: wifi-mac.cc:1622
Ptr< QosTxop > GetVIQueue() const
Accessor for the AC_VI channel access function.
Definition: wifi-mac.cc:527
void SetBssid(Mac48Address bssid, uint8_t linkId)
Definition: wifi-mac.cc:471
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-mac.cc:439
Ptr< FrameExchangeManager > SetupFrameExchangeManager(WifiStandard standard)
Create a Frame Exchange Manager depending on the supported version of the standard.
Definition: wifi-mac.cc:815
virtual void Enqueue(Ptr< Packet > packet, Mac48Address to, Mac48Address from)
Definition: wifi-mac.cc:1481
void NotifyRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:609
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired when packets coming into the "top" of the device are dropped at the MAC layer ...
Definition: wifi-mac.h:1100
void UpdateTidToLinkMapping(const Mac48Address &mldAddr, WifiDirection dir, const WifiTidLinkMapping &mapping)
Update the TID-to-Link Mappings for the given MLD in the given direction based on the given negotiate...
Definition: wifi-mac.cc:1068
BlockAckType GetBaTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
Definition: wifi-mac.cc:1703
MpduResponseTimeoutTracedCallback m_mpduResponseTimeoutCallback
MPDU response timeout traced callback.
Definition: wifi-mac.h:1146
void SetForwardUpCallback(ForwardUpCallback upCallback)
Definition: wifi-mac.cc:1286
PsduMapResponseTimeoutTracedCallback m_psduMapResponseTimeoutCallback
PSDU map response timeout traced callback.
Definition: wifi-mac.h:1190
ExtendedCapabilities GetExtendedCapabilities() const
Return the extended capabilities of the device.
Definition: wifi-mac.cc:1920
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
Definition: wifi-mac.h:1085
uint16_t m_bkMaxAmsduSize
maximum A-MSDU size for AC_BK (in bytes)
Definition: wifi-mac.h:1050
void SetBkBlockAckInactivityTimeout(uint16_t timeout)
Set BK block ack inactivity timeout.
Definition: wifi-mac.cc:1910
std::optional< std::reference_wrapper< const OriginatorBlockAckAgreement > > OriginatorAgreementOptConstRef
optional const reference to OriginatorBlockAckAgreement
Definition: wifi-mac.h:616
std::unordered_map< Mac48Address, WifiTidLinkMapping, WifiAddressHash > m_ulTidLinkMappings
UL TID-to-Link Mapping negotiated with an MLD (identified by its MLD address)
Definition: wifi-mac.h:1060
virtual bool SupportsSendFrom() const
Definition: wifi-mac.cc:1280
virtual Ptr< WifiMacQueue > GetTxopQueue(AcIndex ac) const
Get the wifi MAC queue of the (Qos)Txop associated with the given AC, if such (Qos)Txop is installed,...
Definition: wifi-mac.cc:545
std::optional< uint8_t > GetLinkForPhy(Ptr< const WifiPhy > phy) const
Get the ID of the link (if any) on which the given PHY is operating.
Definition: wifi-mac.cc:976
void SetViBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VI.
Definition: wifi-mac.cc:1850
void SetViBlockAckInactivityTimeout(uint16_t timeout)
Set VI block ack inactivity timeout.
Definition: wifi-mac.cc:1890
bool GetShortSlotTimeSupported() const
Definition: wifi-mac.cc:1274
BlockAckReqType GetBarTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
Definition: wifi-mac.cc:1712
void SetupEdcaQueue(AcIndex ac)
This method is a private utility invoked to configure the channel access function for the specified A...
Definition: wifi-mac.cc:627
void SetLinkDownCallback(Callback< void > linkDown)
Definition: wifi-mac.cc:1300
Ptr< QosTxop > GetBKQueue() const
Accessor for the AC_BK channel access function.
Definition: wifi-mac.cc:539
~WifiMac() override
Definition: wifi-mac.cc:61
void SetPromisc()
Sets the interface in promiscuous mode.
Definition: wifi-mac.cc:484
Ptr< VhtConfiguration > GetVhtConfiguration() const
Definition: wifi-mac.cc:1745
void NotifyRxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:621
virtual void SetLinkUpCallback(Callback< void > linkUp)
Definition: wifi-mac.cc:1293
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:908
const std::set< uint8_t > & GetLinkIds() const
Definition: wifi-mac.cc:941
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:433
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self feature.
Definition: wifi-mac.cc:1260
Mac48Address GetLocalAddress(const Mac48Address &remoteAddr) const
Get the local MAC address used to communicate with a remote STA.
Definition: wifi-mac.cc:1647
EdcaQueues m_edca
This is a map from Access Category index to the corresponding channel access function.
Definition: wifi-mac.h:1045
uint32_t m_bkMaxAmpduSize
maximum A-MPDU size for AC_BK (in bytes)
Definition: wifi-mac.h:1055
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
Definition: wifi-mac.cc:1492
virtual void ConfigureContentionWindow(uint32_t cwMin, uint32_t cwMax)
Definition: wifi-mac.cc:648
OriginatorAgreementOptConstRef GetBaAgreementEstablishedAsOriginator(Mac48Address recipient, uint8_t tid) const
Definition: wifi-mac.cc:1681
virtual void Receive(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
This method acts as the MacRxMiddle receive callback and is invoked to notify us that a frame has bee...
Definition: wifi-mac.cc:1499
Mac48Address GetAddress() const
Definition: wifi-mac.cc:452
TracedCallback< const WifiMacHeader & > m_txErrCallback
transmit error callback
Definition: wifi-mac.h:1103
ForwardUpCallback m_forwardUp
Callback to forward packet up the stack.
Definition: wifi-mac.h:1062
EhtCapabilities GetEhtCapabilities(uint8_t linkId) const
Return the EHT capabilities of the device for the given link.
Definition: wifi-mac.cc:2125
Callback< void > m_linkUp
Callback when a link is up.
Definition: wifi-mac.h:876
TracedCallback< const WifiMacHeader & > m_txOkCallback
transmit OK callback
Definition: wifi-mac.h:1102
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: wifi-mac.cc:926
HeCapabilities GetHeCapabilities(uint8_t linkId) const
Return the HE capabilities of the device for the given link.
Definition: wifi-mac.cc:2069
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy > > &phys)
Definition: wifi-mac.cc:1148
PsduResponseTimeoutTracedCallback m_psduResponseTimeoutCallback
PSDU response timeout traced callback.
Definition: wifi-mac.h:1167
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition: wifi-mac.cc:499
void NotifyTxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:603
void DoDispose() override
Destructor implementation.
Definition: wifi-mac.cc:378
bool GetDsssSupported(uint8_t linkId) const
Return whether the device supports DSSS on the given link.
Definition: wifi-mac.cc:1254
Ptr< ChannelAccessManager > GetChannelAccessManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Channel Access Manager associated with the given link.
Definition: wifi-mac.cc:872
void SetVoBlockAckInactivityTimeout(uint16_t timeout)
Set VO block ack inactivity timeout.
Definition: wifi-mac.cc:1880
virtual std::unique_ptr< LinkEntity > CreateLinkEntity() const
Create a LinkEntity object.
Definition: wifi-mac.cc:914
void SetShortSlotTimeSupported(bool enable)
Enable or disable short slot time feature.
Definition: wifi-mac.cc:1267
bool m_ctsToSelfSupported
flag indicating whether CTS-To-Self is supported
Definition: wifi-mac.h:1027
uint16_t m_beMaxAmsduSize
maximum A-MSDU size for AC_BE (in bytes)
Definition: wifi-mac.h:1049
virtual Mac48Address DoGetLocalAddress(const Mac48Address &remoteAddr) const
This method is called if this device is an MLD to determine the MAC address of the affiliated STA use...
Definition: wifi-mac.cc:1675
uint32_t m_viMaxAmpduSize
maximum A-MPDU size for AC_VI (in bytes)
Definition: wifi-mac.h:1053
Ptr< VhtConfiguration > GetVhtConfiguration() const
Ptr< EhtConfiguration > GetEhtConfiguration() const
Ptr< HtConfiguration > GetHtConfiguration() const
Ptr< HeConfiguration > GetHeConfiguration() const
Ptr< WifiPhy > GetPhy() const
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition: wifi-phy.cc:1011
virtual void SetupPhy(const Ptr< WifiPhy > phy)
Set up PHY associated with this device since it is the object that knows the full set of transmit rat...
std::optional< Mac48Address > GetMldAddress(const Mac48Address &address) const
Get the address of the MLD the given station is affiliated with, if any.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_UNLESS(cond)
Abnormal program termination if a condition is false.
Definition: abort.h:129
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1349
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1361
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
TypeOfStation
Enumeration for type of WiFi station.
Definition: wifi-mac.h:64
WifiStandard
Identifies the IEEE 802.11 specifications that a Wifi device can be configured to use.
AcIndex QosUtilsMapTidToAc(uint8_t tid)
Maps TID (Traffic ID) to Access classes.
Definition: qos-utils.cc:134
WifiQueueBlockedReason
Enumeration of the reasons to block container queues.
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:72
@ WIFI_STANDARD_80211be
@ WIFI_STANDARD_80211n
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211ax
@ WIFI_STANDARD_UNSPECIFIED
@ WIFI_STANDARD_80211ac
@ WIFI_STANDARD_80211b
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
Definition: wifi-phy-band.h:39
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
Definition: wifi-phy-band.h:35
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
Definition: wifi-phy-band.h:37
@ WIFI_MOD_CLASS_HT
HT (Clause 19)
@ WIFI_MOD_CLASS_EHT
EHT (Clause 36)
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ AC_BE_NQOS
Non-QoS.
Definition: qos-utils.h:82
@ AC_BE
Best Effort.
Definition: qos-utils.h:74
@ AC_VO
Voice.
Definition: qos-utils.h:80
@ AC_VI
Video.
Definition: qos-utils.h:78
@ AC_BK
Background.
Definition: qos-utils.h:76
@ AC_UNDEF
Total number of ACs.
Definition: qos-utils.h:86
@ AC_BEACON
Beacon queue.
Definition: qos-utils.h:84
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:484
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
static constexpr uint8_t SINGLE_LINK_OP_ID
Link ID for single link operations (helps tracking places where correct link ID is to be used to supp...
Definition: wifi-utils.h:192
const std::map< AcIndex, WifiAc > wifiAcList
Map containing the four ACs in increasing order of priority (according to Table 10-1 "UP-to-AC Mappin...
Definition: qos-utils.cc:126
WifiDirection
Wifi direction.
Definition: wifi-utils.h:43
std::map< uint8_t, std::set< uint8_t > > WifiTidLinkMapping
TID-indexed map of the link set to which the TID is mapped.
Definition: wifi-utils.h:74
ns3::Time timeout
The different BlockAckRequest variants.
The different BlockAck variants.
uint8_t supportTx1024And4096QamForRuSmallerThan242Tones
Tx 1024-QAM And 4096-QAM < 242-tone RU Support.
uint8_t supportRx1024And4096QamForRuSmallerThan242Tones
Rx 1024-QAM And 4096-QAM < 242-tone RU Support.
std::string dir
BlockAckActionValue blockAck
block ack
Definition: mgt-headers.h:725