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-action-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")),
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(
124 "MpduBufferSize",
125 "The size (in number of MPDUs) of the buffer used for each BlockAck "
126 "agreement in which this node is a recipient. The provided value is "
127 "capped to the maximum allowed value based on the supported standard.",
128 UintegerValue(1024),
130 MakeUintegerChecker<uint16_t>(1, 1024))
131 .AddAttribute("VO_MaxAmsduSize",
132 "Maximum length in bytes of an A-MSDU for AC_VO access class "
133 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
134 "Value 0 means A-MSDU aggregation is disabled for that AC.",
135 UintegerValue(0),
137 MakeUintegerChecker<uint16_t>(0, 11398))
138 .AddAttribute("VI_MaxAmsduSize",
139 "Maximum length in bytes of an A-MSDU for AC_VI access class "
140 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
141 "Value 0 means A-MSDU aggregation is disabled for that AC.",
142 UintegerValue(0),
144 MakeUintegerChecker<uint16_t>(0, 11398))
145 .AddAttribute("BE_MaxAmsduSize",
146 "Maximum length in bytes of an A-MSDU for AC_BE access class "
147 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
148 "Value 0 means A-MSDU aggregation is disabled for that AC.",
149 UintegerValue(0),
151 MakeUintegerChecker<uint16_t>(0, 11398))
152 .AddAttribute("BK_MaxAmsduSize",
153 "Maximum length in bytes of an A-MSDU for AC_BK access class "
154 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
155 "Value 0 means A-MSDU aggregation is disabled for that AC.",
156 UintegerValue(0),
158 MakeUintegerChecker<uint16_t>(0, 11398))
159 .AddAttribute(
160 "VO_MaxAmpduSize",
161 "Maximum length in bytes of an A-MPDU for AC_VO access class "
162 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
163 "and 15523200 for EHT PPDUs). "
164 "Value 0 means A-MPDU aggregation is disabled for that AC.",
165 UintegerValue(0),
167 MakeUintegerChecker<uint32_t>(0, 15523200))
168 .AddAttribute(
169 "VI_MaxAmpduSize",
170 "Maximum length in bytes of an A-MPDU for AC_VI access class "
171 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
172 "and 15523200 for EHT PPDUs). "
173 "Value 0 means A-MPDU aggregation is disabled for that AC.",
174 UintegerValue(65535),
176 MakeUintegerChecker<uint32_t>(0, 15523200))
177 .AddAttribute(
178 "BE_MaxAmpduSize",
179 "Maximum length in bytes of an A-MPDU for AC_BE access class "
180 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
181 "and 15523200 for EHT PPDUs). "
182 "Value 0 means A-MPDU aggregation is disabled for that AC.",
183 UintegerValue(65535),
185 MakeUintegerChecker<uint32_t>(0, 15523200))
186 .AddAttribute(
187 "BK_MaxAmpduSize",
188 "Maximum length in bytes of an A-MPDU for AC_BK access class "
189 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
190 "and 15523200 for EHT PPDUs). "
191 "Value 0 means A-MPDU aggregation is disabled for that AC.",
192 UintegerValue(0),
194 MakeUintegerChecker<uint32_t>(0, 15523200))
195 .AddAttribute(
196 "VO_BlockAckThreshold",
197 "If number of packets in VO 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 "VI_BlockAckThreshold",
205 "If number of packets in VI 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 "BE_BlockAckThreshold",
213 "If number of packets in BE 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 "BK_BlockAckThreshold",
221 "If number of packets in BK queue reaches this value, "
222 "block ack mechanism is used. If this value is 0, block ack is never used."
223 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
224 UintegerValue(0),
226 MakeUintegerChecker<uint8_t>(0, 64))
227 .AddAttribute(
228 "VO_BlockAckInactivityTimeout",
229 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
230 "inactivity for AC_VO. If this value isn't equal to 0 a timer start after that a"
231 "block ack setup is completed and will be reset every time that a block ack"
232 "frame is received. If this value is 0, block ack inactivity timeout won't be "
233 "used.",
234 UintegerValue(0),
236 MakeUintegerChecker<uint16_t>())
237 .AddAttribute(
238 "VI_BlockAckInactivityTimeout",
239 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
240 "inactivity for AC_VI. If this value isn't equal to 0 a timer start after that a"
241 "block ack setup is completed and will be reset every time that a block ack"
242 "frame is received. If this value is 0, block ack inactivity timeout won't be "
243 "used.",
244 UintegerValue(0),
246 MakeUintegerChecker<uint16_t>())
247 .AddAttribute(
248 "BE_BlockAckInactivityTimeout",
249 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
250 "inactivity for AC_BE. If this value isn't equal to 0 a timer start after that a"
251 "block ack setup is completed and will be reset every time that a block ack"
252 "frame is received. If this value is 0, block ack inactivity timeout won't be "
253 "used.",
254 UintegerValue(0),
256 MakeUintegerChecker<uint16_t>())
257 .AddAttribute(
258 "BK_BlockAckInactivityTimeout",
259 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
260 "inactivity for AC_BK. If this value isn't equal to 0 a timer start after that a"
261 "block ack setup is completed and will be reset every time that a block ack"
262 "frame is received. If this value is 0, block ack inactivity timeout won't be "
263 "used.",
264 UintegerValue(0),
266 MakeUintegerChecker<uint16_t>())
267 .AddTraceSource("MacTx",
268 "A packet has been received from higher layers and is being processed "
269 "in preparation for "
270 "queueing for transmission.",
272 "ns3::Packet::TracedCallback")
273 .AddTraceSource(
274 "MacTxDrop",
275 "A packet has been dropped in the MAC layer before being queued for transmission. "
276 "This trace source is fired, e.g., when an AP's MAC receives from the upper layer "
277 "a packet destined to a station that is not associated with the AP or a STA's MAC "
278 "receives a packet from the upper layer while it is not associated with any AP.",
280 "ns3::Packet::TracedCallback")
281 .AddTraceSource(
282 "MacPromiscRx",
283 "A packet has been received by this device, has been passed up from the physical "
284 "layer "
285 "and is being forwarded up the local protocol stack. This is a promiscuous trace.",
287 "ns3::Packet::TracedCallback")
288 .AddTraceSource("MacRx",
289 "A packet has been received by this device, has been passed up from "
290 "the physical layer "
291 "and is being forwarded up the local protocol stack. This is a "
292 "non-promiscuous trace.",
294 "ns3::Packet::TracedCallback")
295 .AddTraceSource("MacRxDrop",
296 "A packet has been dropped in the MAC layer after it has been passed "
297 "up from the physical layer.",
299 "ns3::Packet::TracedCallback")
300 .AddTraceSource("AckedMpdu",
301 "An MPDU that was successfully acknowledged, via either a "
302 "Normal Ack or a Block Ack.",
304 "ns3::WifiMpdu::TracedCallback")
305 .AddTraceSource("NAckedMpdu",
306 "An MPDU that was negatively acknowledged via a Block Ack.",
308 "ns3::WifiMpdu::TracedCallback")
309 .AddTraceSource(
310 "DroppedMpdu",
311 "An MPDU that was dropped for the given reason (see WifiMacDropReason).",
313 "ns3::WifiMac::DroppedMpduCallback")
314 .AddTraceSource(
315 "MpduResponseTimeout",
316 "An MPDU whose response was not received before the timeout, along with "
317 "an identifier of the type of timeout (see WifiTxTimer::Reason) and the "
318 "TXVECTOR used to transmit the MPDU. This trace source is fired when a "
319 "CTS is missing after an RTS, when all CTS frames are missing after an MU-RTS, "
320 "or when a Normal Ack is missing after an MPDU or after a DL MU PPDU "
321 "acknowledged in SU format.",
323 "ns3::WifiMac::MpduResponseTimeoutCallback")
324 .AddTraceSource(
325 "PsduResponseTimeout",
326 "A PSDU whose response was not received before the timeout, along with "
327 "an identifier of the type of timeout (see WifiTxTimer::Reason) and the "
328 "TXVECTOR used to transmit the PSDU. This trace source is fired when a "
329 "BlockAck is missing after an A-MPDU, a BlockAckReq (possibly in the "
330 "context of the acknowledgment of a DL MU PPDU in SU format) or a TB PPDU "
331 "(in the latter case the missing BlockAck is a Multi-STA BlockAck).",
333 "ns3::WifiMac::PsduResponseTimeoutCallback")
334 .AddTraceSource(
335 "PsduMapResponseTimeout",
336 "A PSDU map for which not all the responses were received before the timeout, "
337 "along with an identifier of the type of timeout (see WifiTxTimer::Reason), "
338 "the set of MAC addresses of the stations that did not respond and the total "
339 "number of stations that had to respond. This trace source is fired when not "
340 "all the addressed stations responded to an MU-BAR Trigger frame (either sent as "
341 "a SU frame or aggregated to PSDUs in the DL MU PPDU), a Basic Trigger Frame or "
342 "a BSRP Trigger Frame.",
344 "ns3::WifiMac::PsduMapResponseTimeoutCallback");
345 return tid;
346}
347
348void
350{
351 NS_LOG_FUNCTION(this);
352
353 if (m_txop)
354 {
356 }
357
358 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
359 {
360 it->second->Initialize();
361 }
362
363 for (const auto& [id, link] : m_links)
364 {
365 if (auto cam = link->channelAccessManager)
366 {
367 cam->Initialize();
368 }
369 }
370}
371
372void
374{
375 NS_LOG_FUNCTION(this);
376
377 m_rxMiddle = nullptr;
378 m_txMiddle = nullptr;
379 m_links.clear();
380
381 if (m_txop)
382 {
383 m_txop->Dispose();
384 }
385 m_txop = nullptr;
386
387 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
388 {
389 it->second->Dispose();
390 it->second = nullptr;
391 }
392
393 m_device = nullptr;
394 if (m_scheduler != nullptr)
395 {
396 m_scheduler->Dispose();
397 }
398 m_scheduler = nullptr;
399}
400
402{
403 // WifiMac owns pointers to ChannelAccessManager and FrameExchangeManager
405 {
407 }
408 if (feManager)
409 {
410 feManager->Dispose();
411 }
412}
413
414void
416{
417 NS_LOG_FUNCTION(this << type);
418 m_typeOfStation = type;
419}
420
423{
424 return m_typeOfStation;
425}
426
427void
429{
430 m_device = device;
431 if (GetHtSupported())
432 {
433 // the configured BlockAck buffer size can now be capped
435 }
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 // Reset remote station manager
591 GetLink(linkId).stationManager->Reset();
592}
593
594void
596{
597 m_macTxTrace(packet);
598}
599
600void
602{
603 m_macTxDropTrace(packet);
604}
605
606void
608{
609 m_macRxTrace(packet);
610}
611
612void
614{
615 m_macPromiscRxTrace(packet);
616}
617
618void
620{
621 m_macRxDropTrace(packet);
622}
623
624void
626{
627 NS_LOG_FUNCTION(this << ac);
628
629 // Our caller shouldn't be attempting to setup a queue that is
630 // already configured.
631 NS_ASSERT(!m_edca.contains(ac));
632
633 Ptr<QosTxop> edca = CreateObject<QosTxop>(ac);
634 edca->SetTxMiddle(m_txMiddle);
635 edca->GetBaManager()->SetTxOkCallback(
636 MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
637 edca->GetBaManager()->SetTxFailedCallback(
638 MakeCallback(&MpduTracedCallback::operator(), &m_nackedMpduCallback));
639 edca->SetDroppedMpduCallback(
640 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
641
642 m_edca.insert(std::make_pair(ac, edca));
643}
644
645void
647{
648 std::list<bool> isDsssOnly;
649 for (const auto& [id, link] : m_links)
650 {
651 isDsssOnly.push_back(link->dsssSupported && !link->erpSupported);
652 }
653
654 if (m_txop)
655 {
656 // The special value of AC_BE_NQOS which exists in the Access
657 // Category enumeration allows us to configure plain old DCF.
658 ConfigureDcf(m_txop, cwMin, cwMax, isDsssOnly, AC_BE_NQOS);
659 }
660
661 // Now we configure the EDCA functions
662 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
663 {
664 ConfigureDcf(it->second, cwMin, cwMax, isDsssOnly, it->first);
665 }
666}
667
668void
670 uint32_t cwmin,
671 uint32_t cwmax,
672 std::list<bool> isDsss,
673 AcIndex ac)
674{
675 NS_LOG_FUNCTION(this << dcf << cwmin << cwmax << +ac);
676
677 uint32_t cwMinValue = 0;
678 uint32_t cwMaxValue = 0;
679 uint8_t aifsnValue = 0;
680 Time txopLimitDsss(0);
681 Time txopLimitNoDsss(0);
682
683 /* see IEEE 802.11-2020 Table 9-155 "Default EDCA Parameter Set element parameter values" */
684 switch (ac)
685 {
686 case AC_VO:
687 cwMinValue = (cwmin + 1) / 4 - 1;
688 cwMaxValue = (cwmin + 1) / 2 - 1;
689 aifsnValue = 2;
690 txopLimitDsss = MicroSeconds(3264);
691 txopLimitNoDsss = MicroSeconds(2080);
692 break;
693 case AC_VI:
694 cwMinValue = (cwmin + 1) / 2 - 1;
695 cwMaxValue = cwmin;
696 aifsnValue = 2;
697 txopLimitDsss = MicroSeconds(6016);
698 txopLimitNoDsss = MicroSeconds(4096);
699 break;
700 case AC_BE:
701 cwMinValue = cwmin;
702 cwMaxValue = cwmax;
703 aifsnValue = 3;
704 txopLimitDsss = MicroSeconds(0); // TODO should be MicroSeconds (3264)
705 txopLimitNoDsss = MicroSeconds(0); // TODO should be MicroSeconds (2528)
706 break;
707 case AC_BK:
708 cwMinValue = cwmin;
709 cwMaxValue = cwmax;
710 aifsnValue = 7;
711 txopLimitDsss = MicroSeconds(0); // TODO should be MicroSeconds (3264)
712 txopLimitNoDsss = MicroSeconds(0); // TODO should be MicroSeconds (2528)
713 break;
714 case AC_BE_NQOS:
715 cwMinValue = cwmin;
716 cwMaxValue = cwmax;
717 aifsnValue = 2;
718 txopLimitDsss = txopLimitNoDsss = MicroSeconds(0);
719 break;
720 case AC_BEACON:
721 // done by ApWifiMac
722 break;
723 case AC_UNDEF:
724 NS_FATAL_ERROR("I don't know what to do with this");
725 break;
726 }
727
728 std::vector<uint32_t> cwValues(m_links.size());
729 std::vector<uint8_t> aifsnValues(m_links.size());
730 std::vector<Time> txopLimitValues(m_links.size());
731
732 std::fill(cwValues.begin(), cwValues.end(), cwMinValue);
733 dcf->SetMinCws(cwValues);
734 std::fill(cwValues.begin(), cwValues.end(), cwMaxValue);
735 dcf->SetMaxCws(cwValues);
736 std::fill(aifsnValues.begin(), aifsnValues.end(), aifsnValue);
737 dcf->SetAifsns(aifsnValues);
738 std::transform(isDsss.begin(),
739 isDsss.end(),
740 txopLimitValues.begin(),
741 [&txopLimitDsss, &txopLimitNoDsss](bool dsss) {
742 return (dsss ? txopLimitDsss : txopLimitNoDsss);
743 });
744 dcf->SetTxopLimits(txopLimitValues);
745}
746
747void
749{
750 NS_LOG_FUNCTION(this << standard);
752 NS_ABORT_MSG_IF(m_links.empty(), "No PHY configured yet");
753
754 for (auto& [id, link] : m_links)
755 {
757 !link->phy || !link->phy->GetOperatingChannel().IsSet(),
758 "[LinkID " << +id
759 << "] PHY must have been set and an operating channel must have been set");
760
761 // do not create a ChannelAccessManager and a FrameExchangeManager if they
762 // already exist (this function may be called after ResetWifiPhys)
763 if (!link->channelAccessManager)
764 {
765 link->channelAccessManager = CreateObject<ChannelAccessManager>();
766 }
767 link->channelAccessManager->SetupPhyListener(link->phy);
768
769 if (!link->feManager)
770 {
771 link->feManager = SetupFrameExchangeManager(standard);
772 }
773 link->feManager->SetWifiPhy(link->phy);
774 link->feManager->SetWifiMac(this);
775 link->feManager->SetLinkId(id);
776 link->channelAccessManager->SetLinkId(id);
777 link->channelAccessManager->SetupFrameExchangeManager(link->feManager);
778
779 if (m_txop)
780 {
781 m_txop->SetWifiMac(this);
782 link->channelAccessManager->Add(m_txop);
783 }
784 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
785 {
786 it->second->SetWifiMac(this);
787 link->channelAccessManager->Add(it->second);
788 }
789
791 }
792}
793
794void
796{
797 NS_LOG_FUNCTION(this << +linkId);
798
799 WifiStandard standard = GetLink(linkId).phy->GetStandard();
800
801 uint32_t cwmin = (standard == WIFI_STANDARD_80211b ? 31 : 15);
802 uint32_t cwmax = 1023;
803
804 SetDsssSupported(standard == WIFI_STANDARD_80211b, linkId);
806 m_links[linkId]->phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ,
807 linkId);
808
809 ConfigureContentionWindow(cwmin, cwmax);
810}
811
814{
815 NS_LOG_FUNCTION(this << standard);
816 NS_ABORT_MSG_IF(standard == WIFI_STANDARD_UNSPECIFIED, "Wifi standard not set");
818
819 if (standard >= WIFI_STANDARD_80211be)
820 {
821 feManager = CreateObject<EhtFrameExchangeManager>();
822 }
823 else if (standard >= WIFI_STANDARD_80211ax)
824 {
825 feManager = CreateObject<HeFrameExchangeManager>();
826 }
827 else if (standard >= WIFI_STANDARD_80211ac)
828 {
829 feManager = CreateObject<VhtFrameExchangeManager>();
830 }
831 else if (standard >= WIFI_STANDARD_80211n)
832 {
833 feManager = CreateObject<HtFrameExchangeManager>();
834 }
835 else if (m_qosSupported)
836 {
837 feManager = CreateObject<QosFrameExchangeManager>();
838 }
839 else
840 {
841 feManager = CreateObject<FrameExchangeManager>();
842 }
843
844 feManager->SetMacTxMiddle(m_txMiddle);
845 feManager->SetMacRxMiddle(m_rxMiddle);
846 feManager->SetAddress(GetAddress());
847 feManager->GetWifiTxTimer().SetMpduResponseTimeoutCallback(
848 MakeCallback(&MpduResponseTimeoutTracedCallback::operator(),
850 feManager->GetWifiTxTimer().SetPsduResponseTimeoutCallback(
851 MakeCallback(&PsduResponseTimeoutTracedCallback::operator(),
853 feManager->GetWifiTxTimer().SetPsduMapResponseTimeoutCallback(
854 MakeCallback(&PsduMapResponseTimeoutTracedCallback::operator(),
856 feManager->SetDroppedMpduCallback(
857 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
858 feManager->SetAckedMpduCallback(
859 MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
860 return feManager;
861}
862
865{
866 return GetLink(linkId).feManager;
867}
868
871{
872 return GetLink(linkId).channelAccessManager;
873}
874
875void
877{
878 NS_LOG_FUNCTION(this << stationManager);
879 SetWifiRemoteStationManagers({stationManager});
880}
881
882void
884 const std::vector<Ptr<WifiRemoteStationManager>>& stationManagers)
885{
886 NS_LOG_FUNCTION(this);
887
888 NS_ABORT_MSG_UNLESS(m_links.empty() || m_links.size() == stationManagers.size(),
889 "If links have been already created, the number of provided "
890 "Remote Manager objects ("
891 << stationManagers.size()
892 << ") must "
893 "match the number of links ("
894 << m_links.size() << ")");
895
896 for (std::size_t i = 0; i < stationManagers.size(); i++)
897 {
898 // the link may already exist in case PHY objects were configured first
899 auto [it, inserted] = m_links.emplace(i, CreateLinkEntity());
900 m_linkIds.insert(i);
901 it->second->stationManager = stationManagers[i];
902 }
903}
904
907{
908 return GetLink(linkId).stationManager;
909}
910
911std::unique_ptr<WifiMac::LinkEntity>
913{
914 return std::make_unique<LinkEntity>();
915}
916
917const std::map<uint8_t, std::unique_ptr<WifiMac::LinkEntity>>&
919{
920 return m_links;
921}
922
924WifiMac::GetLink(uint8_t linkId) const
925{
926 auto it = m_links.find(linkId);
927 NS_ASSERT(it != m_links.cend());
928 NS_ASSERT(it->second); // check that the pointer owns an object
929 return *it->second;
930}
931
932uint8_t
934{
935 return m_links.size();
936}
937
938const std::set<uint8_t>&
940{
941 return m_linkIds;
942}
943
944void
946{
947 NS_LOG_FUNCTION(this << id);
948
949 auto& link = GetLink(id);
950 if (link.feManager)
951 {
952 link.feManager->SetLinkId(id);
953 }
954 if (link.channelAccessManager)
955 {
956 link.channelAccessManager->SetLinkId(id);
957 }
958}
959
960std::optional<uint8_t>
962{
963 for (const auto& [id, link] : m_links)
964 {
965 if (link->feManager->GetAddress() == address)
966 {
967 return id;
968 }
969 }
970 return std::nullopt;
971}
972
973std::optional<uint8_t>
975{
976 for (const auto& [id, link] : m_links)
977 {
978 if (link->phy == phy)
979 {
980 return id;
981 }
982 }
983 return std::nullopt;
984}
985
986std::optional<uint8_t>
987WifiMac::GetLinkForPhy(std::size_t phyId) const
988{
989 NS_ABORT_UNLESS(phyId < m_device->GetNPhys());
990 auto phy = m_device->GetPhy(phyId);
991 return GetLinkForPhy(phy);
992}
993
994void
995WifiMac::SwapLinks(std::map<uint8_t, uint8_t> links)
996{
997 NS_LOG_FUNCTION(this);
998
999 std::map<uint8_t, uint8_t> actualPairs;
1000
1001 while (!links.empty())
1002 {
1003 auto from = links.cbegin()->first;
1004 auto to = links.cbegin()->second;
1005
1006 if (from == to)
1007 {
1008 // nothing to do
1009 links.erase(links.cbegin());
1010 continue;
1011 }
1012
1013 std::unique_ptr<LinkEntity> linkToMove;
1014 NS_ASSERT(m_links.contains(from));
1015 linkToMove.swap(m_links.at(from)); // from is now out of m_links
1016 auto empty = from; // track empty cell in m_links
1017
1018 do
1019 {
1020 auto [it, inserted] =
1021 m_links.emplace(to, nullptr); // insert an element with key to if not present
1022 m_links[to].swap(linkToMove); // to is the link to move now
1023 actualPairs.emplace(from, to);
1024 UpdateLinkId(to);
1025 links.erase(from);
1026 if (!linkToMove)
1027 {
1028 if (inserted)
1029 {
1030 m_links.erase(empty);
1031 }
1032 break;
1033 }
1034
1035 auto nextTo = links.find(to);
1036 if (nextTo == links.cend())
1037 {
1038 // no new position specified for 'to', use the current empty cell
1039 m_links[empty].swap(linkToMove);
1040 actualPairs.emplace(to, empty);
1041 break;
1042 }
1043
1044 from = to;
1045 to = nextTo->second;
1046 } while (true);
1047 }
1048
1049 m_linkIds.clear();
1050 for (const auto& [id, link] : m_links)
1051 {
1052 m_linkIds.insert(id);
1053 }
1054
1055 if (m_txop)
1056 {
1057 m_txop->SwapLinks(actualPairs);
1058 }
1059 for (auto& [ac, edca] : m_edca)
1060 {
1061 edca->SwapLinks(actualPairs);
1062 }
1063}
1064
1065void
1068 const WifiTidLinkMapping& mapping)
1069{
1070 NS_LOG_FUNCTION(this << mldAddr);
1071
1073 "DL and UL directions for TID-to-Link mapping must be set separately");
1074
1076
1077 auto [it, inserted] = mappings.emplace(mldAddr, mapping);
1078
1079 if (inserted)
1080 {
1081 // we are done
1082 return;
1083 }
1084
1085 // a previous mapping is stored for this MLD
1086 if (mapping.empty())
1087 {
1088 // the default mapping has been now negotiated
1089 it->second.clear();
1090 return;
1091 }
1092
1093 for (const auto& [tid, linkSet] : mapping)
1094 {
1095 it->second[tid] = linkSet;
1096 }
1097}
1098
1099std::optional<std::reference_wrapper<const WifiTidLinkMapping>>
1101{
1103 "Cannot request TID-to-Link mapping for both directions");
1104
1105 const auto& mappings =
1107
1108 if (const auto it = mappings.find(mldAddr); it != mappings.cend())
1109 {
1110 return it->second;
1111 }
1112 return std::nullopt;
1113}
1114
1115bool
1116WifiMac::TidMappedOnLink(Mac48Address mldAddr, WifiDirection dir, uint8_t tid, uint8_t linkId) const
1117{
1119 "Cannot request TID-to-Link mapping for both directions");
1120
1121 const auto& mappings =
1123
1124 const auto it = mappings.find(mldAddr);
1125
1126 if (it == mappings.cend())
1127 {
1128 // TID-to-link mapping was not negotiated, TIDs are mapped to all setup links
1129 return GetWifiRemoteStationManager(linkId)->GetMldAddress(mldAddr).has_value();
1130 }
1131
1132 auto linkSetIt = it->second.find(tid);
1133
1134 if (linkSetIt == it->second.cend())
1135 {
1136 // If there is no successfully negotiated TID-to-link mapping for a TID, then the TID
1137 // is mapped to all setup links for DL and UL (Sec. 35.3.7.1.3 of 802.11be D3.1)
1138 return GetWifiRemoteStationManager(linkId)->GetMldAddress(mldAddr).has_value();
1139 }
1140
1141 return std::find(linkSetIt->second.cbegin(), linkSetIt->second.cend(), linkId) !=
1142 linkSetIt->second.cend();
1143}
1144
1145void
1146WifiMac::SetWifiPhys(const std::vector<Ptr<WifiPhy>>& phys)
1147{
1148 NS_LOG_FUNCTION(this);
1149 ResetWifiPhys();
1150
1151 NS_ABORT_MSG_UNLESS(m_links.empty() || m_links.size() == phys.size(),
1152 "If links have been already created, the number of provided "
1153 "PHY objects ("
1154 << phys.size()
1155 << ") must match the number "
1156 "of links ("
1157 << m_links.size() << ")");
1158
1159 for (std::size_t i = 0; i < phys.size(); i++)
1160 {
1161 // the link may already exist in case we are setting new PHY objects
1162 // (ResetWifiPhys just nullified the PHY(s) but left the links)
1163 // or the remote station managers were configured first
1164 auto [it, inserted] = m_links.emplace(i, CreateLinkEntity());
1165 m_linkIds.insert(i);
1166 it->second->phy = phys[i];
1167 }
1168}
1169
1171WifiMac::GetWifiPhy(uint8_t linkId) const
1172{
1173 return GetLink(linkId).phy;
1174}
1175
1176void
1178{
1179 NS_LOG_FUNCTION(this);
1180 for (auto& [id, link] : m_links)
1181 {
1182 if (link->feManager)
1183 {
1184 link->feManager->ResetPhy();
1185 }
1186 if (link->channelAccessManager)
1187 {
1188 link->channelAccessManager->RemovePhyListener(link->phy);
1189 }
1190 link->phy = nullptr;
1191 }
1192}
1193
1194void
1196{
1197 NS_LOG_FUNCTION(this << enable);
1199 m_qosSupported = enable;
1200
1201 if (!m_qosSupported)
1202 {
1203 // create a non-QoS TXOP
1204 m_txop = CreateObject<Txop>();
1207 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
1208 }
1209 else
1210 {
1211 // Construct the EDCAFs. The ordering is important - highest
1212 // priority (Table 9-1 UP-to-AC mapping; IEEE 802.11-2012) must be created
1213 // first.
1218 }
1219}
1220
1221bool
1223{
1224 return m_qosSupported;
1225}
1226
1227bool
1228WifiMac::GetErpSupported(uint8_t linkId) const
1229{
1230 return GetLink(linkId).erpSupported;
1231}
1232
1233void
1234WifiMac::SetErpSupported(bool enable, uint8_t linkId)
1235{
1236 NS_LOG_FUNCTION(this << enable << +linkId);
1237 if (enable)
1238 {
1239 SetDsssSupported(true, linkId);
1240 }
1241 GetLink(linkId).erpSupported = enable;
1242}
1243
1244void
1245WifiMac::SetDsssSupported(bool enable, uint8_t linkId)
1246{
1247 NS_LOG_FUNCTION(this << enable << +linkId);
1248 GetLink(linkId).dsssSupported = enable;
1249}
1250
1251bool
1252WifiMac::GetDsssSupported(uint8_t linkId) const
1253{
1254 return GetLink(linkId).dsssSupported;
1255}
1256
1257void
1259{
1260 NS_LOG_FUNCTION(this);
1261 m_ctsToSelfSupported = enable;
1262}
1263
1264void
1266{
1267 NS_LOG_FUNCTION(this << enable);
1268 m_shortSlotTimeSupported = enable;
1269}
1270
1271bool
1273{
1275}
1276
1277bool
1279{
1280 return false;
1281}
1282
1283void
1285{
1286 NS_LOG_FUNCTION(this);
1287 m_forwardUp = upCallback;
1288}
1289
1290void
1292{
1293 NS_LOG_FUNCTION(this);
1294 m_linkUp = linkUp;
1295}
1296
1297void
1299{
1300 NS_LOG_FUNCTION(this);
1301 m_linkDown = linkDown;
1302}
1303
1304void
1306{
1307 NS_LOG_FUNCTION(this << mldAddr);
1308
1311 "This method can be used to enforce TID-to-Link mapping for one direction at a time");
1312
1313 const auto& mappings =
1315
1316 auto it = mappings.find(mldAddr);
1317
1318 if (it == mappings.cend())
1319 {
1320 // no mapping has been ever negotiated with the given MLD, the default mapping is used
1321 return;
1322 }
1323
1324 std::set<uint8_t> setupLinks;
1325
1326 // find the IDs of the links setup with the given MLD
1327 for (const auto& [id, link] : m_links)
1328 {
1329 if (link->stationManager->GetMldAddress(mldAddr))
1330 {
1331 setupLinks.insert(id);
1332 }
1333 }
1334
1335 auto linkMapping = it->second;
1336
1337 if (linkMapping.empty())
1338 {
1339 // default link mapping, each TID mapped on all setup links
1340 for (uint8_t tid = 0; tid < 8; tid++)
1341 {
1342 linkMapping.emplace(tid, setupLinks);
1343 }
1344 }
1345
1346 for (const auto& [tid, linkSet] : linkMapping)
1347 {
1348 decltype(setupLinks) mappedLinks; // empty
1349 auto notMappedLinks = setupLinks; // all setup links
1350
1351 for (const auto id : linkSet)
1352 {
1353 if (setupLinks.find(id) != setupLinks.cend())
1354 {
1355 // link is mapped
1356 mappedLinks.insert(id);
1357 notMappedLinks.erase(id);
1358 }
1359 }
1360
1361 // unblock mapped links
1362 NS_ABORT_MSG_IF(mappedLinks.empty(), "Every TID must be mapped to at least a link");
1363
1365 QosUtilsMapTidToAc(tid),
1367 mldAddr,
1368 GetAddress(),
1369 {tid},
1370 mappedLinks);
1371
1372 // block unmapped links
1373 if (!notMappedLinks.empty())
1374 {
1376 QosUtilsMapTidToAc(tid),
1378 mldAddr,
1379 GetAddress(),
1380 {tid},
1381 notMappedLinks);
1382 }
1383 }
1384}
1385
1386void
1388 const Mac48Address& address,
1389 const std::set<uint8_t>& linkIds)
1390{
1391 NS_LOG_FUNCTION(this << reason << address);
1393
1394 for (const auto linkId : linkIds)
1395 {
1396 auto& link = GetLink(linkId);
1397 auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address).value_or(address);
1398
1399 if (link.stationManager->GetMldAddress(address) == address && linkAddr == address)
1400 {
1401 NS_LOG_DEBUG("Link " << +linkId << " has not been setup with the MLD, skip");
1402 continue;
1403 }
1404
1405 for (const auto& [acIndex, ac] : wifiAcList)
1406 {
1407 // block queues storing QoS data frames and control frames that use MLD addresses
1408 m_scheduler->BlockQueues(reason,
1409 acIndex,
1411 address,
1412 GetAddress(),
1413 {ac.GetLowTid(), ac.GetHighTid()},
1414 {linkId});
1415 // block queues storing management and control frames that use link addresses
1416 m_scheduler->BlockQueues(reason,
1417 acIndex,
1419 linkAddr,
1420 link.feManager->GetAddress(),
1421 {},
1422 {linkId});
1423 }
1424 }
1425}
1426
1427void
1429 const Mac48Address& address,
1430 const std::set<uint8_t>& linkIds)
1431{
1432 NS_LOG_FUNCTION(this << reason << address);
1434
1435 for (const auto linkId : linkIds)
1436 {
1437 auto& link = GetLink(linkId);
1438 auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address).value_or(address);
1439
1440 if (link.stationManager->GetMldAddress(address) == address && linkAddr == address)
1441 {
1442 NS_LOG_DEBUG("Link " << +linkId << " has not been setup with the MLD, skip");
1443 continue;
1444 }
1445
1446 for (const auto& [acIndex, ac] : wifiAcList)
1447 {
1448 // save the status of the AC queues before unblocking the requested queues
1449 auto hasFramesToTransmit = GetQosTxop(acIndex)->HasFramesToTransmit(linkId);
1450
1451 // unblock queues storing QoS data frames and control frames that use MLD addresses
1452 m_scheduler->UnblockQueues(reason,
1453 acIndex,
1455 address,
1456 GetAddress(),
1457 {ac.GetLowTid(), ac.GetHighTid()},
1458 {linkId});
1459 // unblock queues storing management and control frames that use link addresses
1460 m_scheduler->UnblockQueues(reason,
1461 acIndex,
1463 linkAddr,
1464 link.feManager->GetAddress(),
1465 {},
1466 {linkId});
1467 // request channel access if needed (schedule now because multiple invocations
1468 // of this method may be done in a loop at the caller)
1470 GetQosTxop(acIndex),
1471 linkId,
1472 hasFramesToTransmit,
1473 Txop::CHECK_MEDIUM_BUSY); // generate backoff if medium busy
1474 }
1475 }
1476}
1477
1478void
1480{
1481 // We expect WifiMac subclasses which do support forwarding (e.g.,
1482 // AP) to override this method. Therefore, we throw a fatal error if
1483 // someone tries to invoke this method on a class which has not done
1484 // this.
1485 NS_FATAL_ERROR("This MAC entity (" << this << ", " << GetAddress()
1486 << ") does not support Enqueue() with from address");
1487}
1488
1489void
1491{
1492 NS_LOG_FUNCTION(this << packet << from << to);
1493 m_forwardUp(packet, from, to);
1494}
1495
1496void
1498{
1499 NS_LOG_FUNCTION(this << *mpdu << linkId);
1500
1501 const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader();
1502 Mac48Address to = hdr->GetAddr1();
1503 Mac48Address from = hdr->GetAddr2();
1504 auto myAddr = hdr->IsData() ? Mac48Address::ConvertFrom(GetDevice()->GetAddress())
1505 : GetFrameExchangeManager(linkId)->GetAddress();
1506
1507 // We don't know how to deal with any frame that is not addressed to
1508 // us (and odds are there is nothing sensible we could do anyway),
1509 // so we ignore such frames.
1510 //
1511 // The derived class may also do some such filtering, but it doesn't
1512 // hurt to have it here too as a backstop.
1513 if (to != myAddr)
1514 {
1515 return;
1516 }
1517
1518 // Nothing to do with (QoS) Null Data frames
1519 if (hdr->IsData() && !hdr->HasData())
1520 {
1521 return;
1522 }
1523
1524 if (hdr->IsMgt() && hdr->IsAction())
1525 {
1526 // There is currently only any reason for Management Action
1527 // frames to be flying about if we are a QoS STA.
1529
1530 auto& link = GetLink(linkId);
1531 WifiActionHeader actionHdr;
1532 Ptr<Packet> packet = mpdu->GetPacket()->Copy();
1533 packet->RemoveHeader(actionHdr);
1534
1535 switch (actionHdr.GetCategory())
1536 {
1538
1539 switch (actionHdr.GetAction().blockAck)
1540 {
1542 MgtAddBaRequestHeader reqHdr;
1543 packet->RemoveHeader(reqHdr);
1544
1545 // We've received an ADDBA Request. Our policy here is
1546 // to automatically accept it, so we get the ADDBA
1547 // Response on it's way immediately.
1548 NS_ASSERT(link.feManager);
1549 auto htFem = DynamicCast<HtFrameExchangeManager>(link.feManager);
1550 if (htFem)
1551 {
1552 htFem->SendAddBaResponse(&reqHdr, from);
1553 }
1554 // This frame is now completely dealt with, so we're done.
1555 return;
1556 }
1558 MgtAddBaResponseHeader respHdr;
1559 packet->RemoveHeader(respHdr);
1560
1561 // We've received an ADDBA Response. We assume that it
1562 // indicates success after an ADDBA Request we have
1563 // sent (we could, in principle, check this, but it
1564 // seems a waste given the level of the current model)
1565 // and act by locally establishing the agreement on
1566 // the appropriate queue.
1567 auto recipientMld = link.stationManager->GetMldAddress(from);
1568 auto recipient = (recipientMld ? *recipientMld : from);
1569 GetQosTxop(respHdr.GetTid())->GotAddBaResponse(respHdr, recipient);
1570 auto htFem = DynamicCast<HtFrameExchangeManager>(link.feManager);
1571 if (htFem)
1572 {
1573 GetQosTxop(respHdr.GetTid())
1574 ->GetBaManager()
1575 ->SetBlockAckInactivityCallback(
1577 }
1578 // This frame is now completely dealt with, so we're done.
1579 return;
1580 }
1582 MgtDelBaHeader delBaHdr;
1583 packet->RemoveHeader(delBaHdr);
1584 auto recipientMld = link.stationManager->GetMldAddress(from);
1585 auto recipient = (recipientMld ? *recipientMld : from);
1586
1587 if (delBaHdr.IsByOriginator())
1588 {
1589 // This DELBA frame was sent by the originator, so
1590 // this means that an ingoing established
1591 // agreement exists in BlockAckManager and we need to
1592 // destroy it.
1593 GetQosTxop(delBaHdr.GetTid())
1594 ->GetBaManager()
1595 ->DestroyRecipientAgreement(recipient, delBaHdr.GetTid());
1596 }
1597 else
1598 {
1599 // We must have been the originator. We need to
1600 // tell the correct queue that the agreement has
1601 // been torn down
1602 GetQosTxop(delBaHdr.GetTid())->GotDelBaFrame(&delBaHdr, recipient);
1603 }
1604 // This frame is now completely dealt with, so we're done.
1605 return;
1606 }
1607 default:
1608 NS_FATAL_ERROR("Unsupported Action field in Block Ack Action frame");
1609 return;
1610 }
1611 default:
1612 NS_FATAL_ERROR("Unsupported Action frame received");
1613 return;
1614 }
1615 }
1616 NS_FATAL_ERROR("Don't know how to handle frame (type=" << hdr->GetType());
1617}
1618
1619void
1621{
1622 NS_LOG_FUNCTION(this << *mpdu);
1623 for (auto& msduPair : *PeekPointer(mpdu))
1624 {
1625 ForwardUp(msduPair.first,
1626 msduPair.second.GetSourceAddr(),
1627 msduPair.second.GetDestinationAddr());
1628 }
1629}
1630
1631std::optional<Mac48Address>
1632WifiMac::GetMldAddress(const Mac48Address& remoteAddr) const
1633{
1634 for (const auto& [id, link] : m_links)
1635 {
1636 if (auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
1637 {
1638 return *mldAddress;
1639 }
1640 }
1641 return std::nullopt;
1642}
1643
1646{
1647 for (const auto& [id, link] : m_links)
1648 {
1649 if (auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
1650 {
1651 // this is a link setup with remote MLD
1652 if (mldAddress != remoteAddr)
1653 {
1654 // the remote address is the address of a STA affiliated with the remote MLD
1655 return link->feManager->GetAddress();
1656 }
1657 // we have to return our MLD address
1658 return m_address;
1659 }
1660 }
1661 // we get here if no ML setup was established between this device and the remote device,
1662 // i.e., they are not both multi-link devices
1663 if (GetNLinks() == 1)
1664 {
1665 // this is a single link device
1666 return m_address;
1667 }
1668 // this is an MLD (hence the remote device is single link)
1669 return DoGetLocalAddress(remoteAddr);
1670}
1671
1673WifiMac::DoGetLocalAddress(const Mac48Address& remoteAddr [[maybe_unused]]) const
1674{
1675 return m_address;
1676}
1677
1680{
1681 // BA agreements are indexed by the MLD address if ML setup was performed
1682 recipient = GetMldAddress(recipient).value_or(recipient);
1683
1684 auto agreement = GetQosTxop(tid)->GetBaManager()->GetAgreementAsOriginator(recipient, tid);
1685 if (!agreement || !agreement->get().IsEstablished())
1686 {
1687 return std::nullopt;
1688 }
1689 return agreement;
1690}
1691
1694{
1695 // BA agreements are indexed by the MLD address if ML setup was performed
1696 originator = GetMldAddress(originator).value_or(originator);
1697 return GetQosTxop(tid)->GetBaManager()->GetAgreementAsRecipient(originator, tid);
1698}
1699
1701WifiMac::GetBaTypeAsOriginator(const Mac48Address& recipient, uint8_t tid) const
1702{
1703 auto agreement = GetBaAgreementEstablishedAsOriginator(recipient, tid);
1704 NS_ABORT_MSG_IF(!agreement,
1705 "No existing Block Ack agreement with " << recipient << " TID: " << +tid);
1706 return agreement->get().GetBlockAckType();
1707}
1708
1710WifiMac::GetBarTypeAsOriginator(const Mac48Address& recipient, uint8_t tid) const
1711{
1712 auto agreement = GetBaAgreementEstablishedAsOriginator(recipient, tid);
1713 NS_ABORT_MSG_IF(!agreement,
1714 "No existing Block Ack agreement with " << recipient << " TID: " << +tid);
1715 return agreement->get().GetBlockAckReqType();
1716}
1717
1719WifiMac::GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
1720{
1721 auto agreement = GetBaAgreementEstablishedAsRecipient(originator, tid);
1722 NS_ABORT_MSG_IF(!agreement,
1723 "No existing Block Ack agreement with " << originator << " TID: " << +tid);
1724 return agreement->get().GetBlockAckType();
1725}
1726
1728WifiMac::GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
1729{
1730 auto agreement = GetBaAgreementEstablishedAsRecipient(originator, tid);
1731 NS_ABORT_MSG_IF(!agreement,
1732 "No existing Block Ack agreement with " << originator << " TID: " << +tid);
1733 return agreement->get().GetBlockAckReqType();
1734}
1735
1738{
1739 return GetDevice()->GetHtConfiguration();
1740}
1741
1744{
1745 return GetDevice()->GetVhtConfiguration();
1746}
1747
1750{
1751 return GetDevice()->GetHeConfiguration();
1752}
1753
1756{
1757 return GetDevice()->GetEhtConfiguration();
1758}
1759
1760bool
1762{
1763 return bool(GetDevice()->GetHtConfiguration());
1764}
1765
1766bool
1767WifiMac::GetVhtSupported(uint8_t linkId) const
1768{
1769 return (GetDevice()->GetVhtConfiguration() &&
1770 GetWifiPhy(linkId)->GetPhyBand() != WIFI_PHY_BAND_2_4GHZ);
1771}
1772
1773bool
1775{
1776 return bool(GetDevice()->GetHeConfiguration());
1777}
1778
1779bool
1781{
1782 return bool(GetDevice()->GetEhtConfiguration());
1783}
1784
1785bool
1787{
1788 for (const auto& [id, link] : m_links)
1789 {
1790 if (link->stationManager->GetHtSupported(address))
1791 {
1792 return true;
1793 }
1794 }
1795 return false;
1796}
1797
1798bool
1800{
1801 for (const auto& [id, link] : m_links)
1802 {
1803 if (link->stationManager->GetVhtSupported(address))
1804 {
1805 return true;
1806 }
1807 }
1808 return false;
1809}
1810
1811bool
1813{
1814 for (const auto& [id, link] : m_links)
1815 {
1816 if (link->stationManager->GetHeSupported(address))
1817 {
1818 return true;
1819 }
1820 }
1821 return false;
1822}
1823
1824bool
1826{
1827 for (const auto& [id, link] : m_links)
1828 {
1829 if (link->stationManager->GetEhtSupported(address))
1830 {
1831 return true;
1832 }
1833 }
1834 return false;
1835}
1836
1837uint16_t
1838WifiMac::GetMaxBaBufferSize(std::optional<Mac48Address> address) const
1839{
1840 if (address ? GetEhtSupported(*address) : GetEhtSupported())
1841 {
1842 return 1024;
1843 }
1844 if (address ? GetHeSupported(*address) : GetHeSupported())
1845 {
1846 return 256;
1847 }
1848 NS_ASSERT(address ? GetHtSupported(*address) : GetHtSupported());
1849 return 64;
1850}
1851
1852void
1854{
1855 NS_LOG_FUNCTION(this << size);
1856
1857 // the cap can be computed if the device has been configured
1858 m_mpduBufferSize = m_device ? std::min(size, GetMaxBaBufferSize()) : size;
1859}
1860
1861uint16_t
1863{
1864 return m_mpduBufferSize;
1865}
1866
1867void
1869{
1870 NS_LOG_FUNCTION(this << +threshold);
1871 if (m_qosSupported)
1872 {
1873 GetVOQueue()->SetBlockAckThreshold(threshold);
1874 }
1875}
1876
1877void
1879{
1880 NS_LOG_FUNCTION(this << +threshold);
1881 if (m_qosSupported)
1882 {
1883 GetVIQueue()->SetBlockAckThreshold(threshold);
1884 }
1885}
1886
1887void
1889{
1890 NS_LOG_FUNCTION(this << +threshold);
1891 if (m_qosSupported)
1892 {
1893 GetBEQueue()->SetBlockAckThreshold(threshold);
1894 }
1895}
1896
1897void
1899{
1900 NS_LOG_FUNCTION(this << +threshold);
1901 if (m_qosSupported)
1902 {
1903 GetBKQueue()->SetBlockAckThreshold(threshold);
1904 }
1905}
1906
1907void
1909{
1910 NS_LOG_FUNCTION(this << timeout);
1911 if (m_qosSupported)
1912 {
1914 }
1915}
1916
1917void
1919{
1920 NS_LOG_FUNCTION(this << timeout);
1921 if (m_qosSupported)
1922 {
1924 }
1925}
1926
1927void
1929{
1930 NS_LOG_FUNCTION(this << timeout);
1931 if (m_qosSupported)
1932 {
1934 }
1935}
1936
1937void
1939{
1940 NS_LOG_FUNCTION(this << timeout);
1941 if (m_qosSupported)
1942 {
1944 }
1945}
1946
1949{
1950 NS_LOG_FUNCTION(this);
1951 ExtendedCapabilities capabilities;
1952 capabilities.SetHtSupported(GetHtSupported());
1954 // TODO: to be completed
1955 return capabilities;
1956}
1957
1959WifiMac::GetHtCapabilities(uint8_t linkId) const
1960{
1961 NS_LOG_FUNCTION(this << +linkId);
1963 HtCapabilities capabilities;
1964
1965 auto phy = GetWifiPhy(linkId);
1966 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
1967 bool sgiSupported = htConfiguration->GetShortGuardIntervalSupported();
1968 capabilities.SetLdpc(htConfiguration->GetLdpcSupported());
1969 capabilities.SetSupportedChannelWidth(htConfiguration->Get40MHzOperationSupported() ? 1 : 0);
1970 capabilities.SetShortGuardInterval20(sgiSupported);
1971 capabilities.SetShortGuardInterval40(sgiSupported);
1972 // Set Maximum A-MSDU Length subfield
1973 uint16_t maxAmsduSize =
1975 if (maxAmsduSize <= 3839)
1976 {
1977 capabilities.SetMaxAmsduLength(3839);
1978 }
1979 else
1980 {
1981 capabilities.SetMaxAmsduLength(7935);
1982 }
1983 uint32_t maxAmpduLength =
1985 // round to the next power of two minus one
1986 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
1987 // The maximum A-MPDU length in HT capabilities elements ranges from 2^13-1 to 2^16-1
1988 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 65535U));
1989
1990 capabilities.SetLSigProtectionSupport(true);
1991 uint64_t maxSupportedRate = 0; // in bit/s
1992 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HT))
1993 {
1994 capabilities.SetRxMcsBitmask(mcs.GetMcsValue());
1995 uint8_t nss = (mcs.GetMcsValue() / 8) + 1;
1996 NS_ASSERT(nss > 0 && nss < 5);
1997 uint64_t dataRate = mcs.GetDataRate(htConfiguration->Get40MHzOperationSupported() ? 40 : 20,
1998 sgiSupported ? 400 : 800,
1999 nss);
2000 if (dataRate > maxSupportedRate)
2001 {
2002 maxSupportedRate = dataRate;
2003 NS_LOG_DEBUG("Updating maxSupportedRate to " << maxSupportedRate);
2004 }
2005 }
2006 capabilities.SetRxHighestSupportedDataRate(
2007 static_cast<uint16_t>(maxSupportedRate / 1e6)); // in Mbit/s
2008 capabilities.SetTxMcsSetDefined(phy->GetNMcs() > 0);
2009 capabilities.SetTxMaxNSpatialStreams(phy->GetMaxSupportedTxSpatialStreams());
2010 // we do not support unequal modulations
2011 capabilities.SetTxRxMcsSetUnequal(0);
2012 capabilities.SetTxUnequalModulation(0);
2013
2014 return capabilities;
2015}
2016
2018WifiMac::GetVhtCapabilities(uint8_t linkId) const
2019{
2020 NS_LOG_FUNCTION(this << +linkId);
2021 NS_ASSERT(GetVhtSupported(linkId));
2022 VhtCapabilities capabilities;
2023
2024 auto phy = GetWifiPhy(linkId);
2025 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
2026 NS_ABORT_MSG_IF(!htConfiguration->Get40MHzOperationSupported(),
2027 "VHT stations have to support 40 MHz operation");
2028 Ptr<VhtConfiguration> vhtConfiguration = GetVhtConfiguration();
2029 bool sgiSupported = htConfiguration->GetShortGuardIntervalSupported();
2030 capabilities.SetSupportedChannelWidthSet(vhtConfiguration->Get160MHzOperationSupported() ? 1
2031 : 0);
2032 // Set Maximum MPDU Length subfield
2033 uint16_t maxAmsduSize =
2035 if (maxAmsduSize <= 3839)
2036 {
2037 capabilities.SetMaxMpduLength(3895);
2038 }
2039 else if (maxAmsduSize <= 7935)
2040 {
2041 capabilities.SetMaxMpduLength(7991);
2042 }
2043 else
2044 {
2045 capabilities.SetMaxMpduLength(11454);
2046 }
2047 uint32_t maxAmpduLength =
2049 // round to the next power of two minus one
2050 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2051 // The maximum A-MPDU length in VHT capabilities elements ranges from 2^13-1 to 2^20-1
2052 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 1048575U));
2053
2054 capabilities.SetRxLdpc(htConfiguration->GetLdpcSupported());
2055 capabilities.SetShortGuardIntervalFor80Mhz(sgiSupported);
2056 capabilities.SetShortGuardIntervalFor160Mhz(sgiSupported);
2057 uint8_t maxMcs = 0;
2058 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
2059 {
2060 if (mcs.GetMcsValue() > maxMcs)
2061 {
2062 maxMcs = mcs.GetMcsValue();
2063 }
2064 }
2065 // Support same MaxMCS for each spatial stream
2066 for (uint8_t nss = 1; nss <= phy->GetMaxSupportedRxSpatialStreams(); nss++)
2067 {
2068 capabilities.SetRxMcsMap(maxMcs, nss);
2069 }
2070 for (uint8_t nss = 1; nss <= phy->GetMaxSupportedTxSpatialStreams(); nss++)
2071 {
2072 capabilities.SetTxMcsMap(maxMcs, nss);
2073 }
2074 uint64_t maxSupportedRateLGI = 0; // in bit/s
2075 uint16_t maxWidth = vhtConfiguration->Get160MHzOperationSupported() ? 160 : 80;
2076 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
2077 {
2078 if (!mcs.IsAllowed(maxWidth, 1))
2079 {
2080 continue;
2081 }
2082 if (mcs.GetDataRate(maxWidth) > maxSupportedRateLGI)
2083 {
2084 maxSupportedRateLGI = mcs.GetDataRate(maxWidth);
2085 NS_LOG_DEBUG("Updating maxSupportedRateLGI to " << maxSupportedRateLGI);
2086 }
2087 }
2089 static_cast<uint16_t>(maxSupportedRateLGI / 1e6)); // in Mbit/s
2091 static_cast<uint16_t>(maxSupportedRateLGI / 1e6)); // in Mbit/s
2092 // To be filled in once supported
2093 capabilities.SetRxStbc(0);
2094 capabilities.SetTxStbc(0);
2095
2096 return capabilities;
2097}
2098
2100WifiMac::GetHeCapabilities(uint8_t linkId) const
2101{
2102 NS_LOG_FUNCTION(this << +linkId);
2104 HeCapabilities capabilities;
2105
2106 Ptr<WifiPhy> phy = GetLink(linkId).phy;
2107 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
2108 Ptr<VhtConfiguration> vhtConfiguration = GetVhtConfiguration();
2109 Ptr<HeConfiguration> heConfiguration = GetHeConfiguration();
2110 uint8_t channelWidthSet = 0;
2111 if ((htConfiguration->Get40MHzOperationSupported()) &&
2112 (phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ))
2113 {
2114 channelWidthSet |= 0x01;
2115 }
2116 // we assume that HE stations support 80 MHz operations
2117 if ((phy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ))
2118 {
2119 channelWidthSet |= 0x02;
2120 }
2121 if ((vhtConfiguration->Get160MHzOperationSupported()) &&
2122 ((phy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ)))
2123 {
2124 channelWidthSet |= 0x04;
2125 }
2126 capabilities.SetChannelWidthSet(channelWidthSet);
2127 capabilities.SetLdpcCodingInPayload(htConfiguration->GetLdpcSupported());
2128 if (heConfiguration->GetGuardInterval() == NanoSeconds(800))
2129 {
2130 // todo: We assume for now that if we support 800ns GI then 1600ns GI is supported as well
2131 // todo: Assuming reception support for both 1x HE LTF and 4x HE LTF 800 ns
2132 capabilities.SetHeSuPpdu1xHeLtf800nsGi(true);
2133 capabilities.SetHePpdu4xHeLtf800nsGi(true);
2134 }
2135
2136 uint32_t maxAmpduLength =
2138 // round to the next power of two minus one
2139 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2140 // The maximum A-MPDU length in HE capabilities elements ranges from 2^20-1 to 2^23-1
2141 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 1048575U), 8388607U));
2142
2143 uint8_t maxMcs = 0;
2144 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HE))
2145 {
2146 if (mcs.GetMcsValue() > maxMcs)
2147 {
2148 maxMcs = mcs.GetMcsValue();
2149 }
2150 }
2151 capabilities.SetHighestMcsSupported(maxMcs);
2152 capabilities.SetHighestNssSupported(phy->GetMaxSupportedTxSpatialStreams());
2153
2154 return capabilities;
2155}
2156
2158WifiMac::GetEhtCapabilities(uint8_t linkId) const
2159{
2160 NS_LOG_FUNCTION(this << +linkId);
2162 EhtCapabilities capabilities;
2163
2164 Ptr<WifiPhy> phy = GetLink(linkId).phy;
2165
2166 // Set Maximum MPDU Length subfield (Reserved when transmitted in 5 GHz or 6 GHz band)
2167 if (phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
2168 {
2169 uint16_t maxAmsduSize =
2171 // Table 9-34—Maximum data unit sizes (in octets) and durations (in microseconds)
2172 if (maxAmsduSize <= 3839)
2173 {
2174 capabilities.SetMaxMpduLength(3895);
2175 }
2176 else if (maxAmsduSize <= 7935)
2177 {
2178 capabilities.SetMaxMpduLength(7991);
2179 }
2180 else
2181 {
2182 capabilities.SetMaxMpduLength(11454);
2183 }
2184 }
2185
2186 // Set Maximum A-MPDU Length Exponent Extension subfield
2187 uint32_t maxAmpduLength =
2189 // round to the next power of two minus one
2190 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2191 // The maximum A-MPDU length in EHT capabilities elements ranges from 2^23-1 to 2^24-1
2192 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8388607U), 16777215U));
2193
2194 // Set the PHY capabilities
2195 const bool support4096Qam = phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, 12);
2197 support4096Qam ? 1 : 0;
2199 support4096Qam ? 1 : 0;
2200
2201 const uint8_t maxTxNss = phy->GetMaxSupportedTxSpatialStreams();
2202 const uint8_t maxRxNss = phy->GetMaxSupportedRxSpatialStreams();
2203 if (auto htConfig = GetHtConfiguration(); !htConfig->Get40MHzOperationSupported())
2204 {
2205 for (auto maxMcs : {7, 9, 11, 13})
2206 {
2207 capabilities.SetSupportedRxEhtMcsAndNss(
2209 maxMcs,
2210 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2211 capabilities.SetSupportedTxEhtMcsAndNss(
2213 maxMcs,
2214 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2215 }
2216 }
2217 else
2218 {
2219 for (auto maxMcs : {9, 11, 13})
2220 {
2221 capabilities.SetSupportedRxEhtMcsAndNss(
2223 maxMcs,
2224 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2225 capabilities.SetSupportedTxEhtMcsAndNss(
2227 maxMcs,
2228 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2229 }
2230 }
2231 if (auto vhtConfig = GetVhtConfiguration(); vhtConfig->Get160MHzOperationSupported())
2232 {
2233 for (auto maxMcs : {9, 11, 13})
2234 {
2235 capabilities.SetSupportedRxEhtMcsAndNss(
2237 maxMcs,
2238 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2239 capabilities.SetSupportedTxEhtMcsAndNss(
2241 maxMcs,
2242 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2243 }
2244 }
2245 // 320 MHz not supported yet
2246
2247 return capabilities;
2248}
2249
2252{
2253 uint32_t maxSize = 0;
2254 switch (ac)
2255 {
2256 case AC_BE:
2257 maxSize = m_beMaxAmpduSize;
2258 break;
2259 case AC_BK:
2260 maxSize = m_bkMaxAmpduSize;
2261 break;
2262 case AC_VI:
2263 maxSize = m_viMaxAmpduSize;
2264 break;
2265 case AC_VO:
2266 maxSize = m_voMaxAmpduSize;
2267 break;
2268 default:
2269 NS_ABORT_MSG("Unknown AC " << ac);
2270 return 0;
2271 }
2272 return maxSize;
2273}
2274
2275uint16_t
2277{
2278 uint16_t maxSize = 0;
2279 switch (ac)
2280 {
2281 case AC_BE:
2282 maxSize = m_beMaxAmsduSize;
2283 break;
2284 case AC_BK:
2285 maxSize = m_bkMaxAmsduSize;
2286 break;
2287 case AC_VI:
2288 maxSize = m_viMaxAmsduSize;
2289 break;
2290 case AC_VO:
2291 maxSize = m_voMaxAmsduSize;
2292 break;
2293 default:
2294 NS_ABORT_MSG("Unknown AC " << ac);
2295 return 0;
2296 }
2297 return maxSize;
2298}
2299
2300} // 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.
Implement the header for management frames of type Add Block Ack response.
uint8_t GetTid() const
Return the Traffic ID (TID).
Implement the header for management frames of type Delete Block Ack.
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:214
void Dispose()
Dispose of this Object.
Definition: object.cc:258
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:251
AttributeValue implementation for Pointer.
Definition: pointer.h:48
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition: qos-txop.cc:282
void GotAddBaResponse(const MgtAddBaResponseHeader &respHdr, Mac48Address recipient)
Event handler when an ADDBA response is received.
Definition: qos-txop.cc:648
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition: qos-txop.cc:708
void GotDelBaFrame(const MgtDelBaHeader *delBaHdr, Mac48Address recipient)
Event handler when a DELBA frame is received.
Definition: qos-txop.cc:679
void SetBlockAckInactivityTimeout(uint16_t timeout)
Set the BlockAck inactivity timeout.
Definition: qos-txop.cc:716
bool HasFramesToTransmit(uint8_t linkId) override
Check if the Txop has frames to transmit over the given link.
Definition: qos-txop.cc:329
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
The IEEE 802.11 SSID Information Element.
Definition: ssid.h:36
AttributeValue implementation for Ssid.
Definition: ssid.h:96
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
void StartAccessAfterEvent(uint8_t linkId, bool hadFramesToTransmit, bool checkMediumBusy)
Request channel access on the given link after the occurrence of an event that possibly requires to g...
Definition: txop.cc:568
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the Txop has frames to transmit over the given link.
Definition: txop.cc:510
virtual void SetWifiMac(const Ptr< WifiMac > mac)
Set the wifi MAC this Txop is associated to.
Definition: txop.cc:205
void SwapLinks(std::map< uint8_t, uint8_t > links)
Swap the links based on the information included in the given map.
Definition: txop.cc:181
void SetTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set MacTxMiddle this Txop is associated to.
Definition: txop.cc:198
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition: txop.cc:216
static constexpr bool CHECK_MEDIUM_BUSY
generation of backoff (also) depends on the busy/idle state of the medium
Definition: txop.h:425
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:932
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.
bool Get160MHzOperationSupported() const
See IEEE 802.11 chapter 7.3.1.11 Header format: | category: 1 | action value: 1 |.
CategoryValue GetCategory() const
Return the category value.
ActionValue GetAction() const
Return the action value.
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:2276
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:864
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:1632
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:1069
bool m_shortSlotTimeSupported
flag whether short slot time is supported
Definition: wifi-mac.h:1047
void ConfigurePhyDependentParameters(uint8_t linkId)
Configure PHY dependent parameters such as CWmin and CWmax on the given link.
Definition: wifi-mac.cc:795
Ptr< HeConfiguration > GetHeConfiguration() const
Definition: wifi-mac.cc:1749
DroppedMpduTracedCallback m_droppedMpduCallback
This trace indicates that an MPDU was dropped for the given reason.
Definition: wifi-mac.h:1139
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition: wifi-mac.cc:422
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:1045
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
Definition: wifi-mac.cc:918
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:2018
Callback< void > m_linkDown
Callback when a link is down.
Definition: wifi-mac.h:898
bool GetQosSupported() const
Return whether the device supports QoS.
Definition: wifi-mac.cc:1222
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:894
void SetQosSupported(bool enable)
Enable or disable QoS support for the device.
Definition: wifi-mac.cc:1195
Mac48Address m_address
MAC address of this station.
Definition: wifi-mac.h:1056
std::set< uint8_t > m_linkIds
IDs of the links in use.
Definition: wifi-mac.h:1054
Ptr< WifiMacQueueScheduler > GetMacQueueScheduler() const
Get the wifi MAC queue scheduler.
Definition: wifi-mac.cc:576
uint16_t GetMpduBufferSize() const
Definition: wifi-mac.cc:1862
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:933
BlockAckType GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1719
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:995
uint16_t m_voMaxAmsduSize
maximum A-MSDU size for AC_VO (in bytes)
Definition: wifi-mac.h:1068
Ptr< MacRxMiddle > m_rxMiddle
RX middle (defragmentation etc.)
Definition: wifi-mac.h:892
Ptr< WifiMacQueueScheduler > m_scheduler
wifi MAC queue scheduler
Definition: wifi-mac.h:895
void DoInitialize() override
Initialize() implementation.
Definition: wifi-mac.cc:349
TypeOfStation m_typeOfStation
the type of station
Definition: wifi-mac.h:1050
uint16_t m_mpduBufferSize
BlockAck buffer size (in number of MPDUs)
Definition: wifi-mac.h:1078
uint32_t m_beMaxAmpduSize
maximum A-MPDU size for AC_BE (in bytes)
Definition: wifi-mac.h:1075
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:748
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:1116
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:1428
Ssid GetSsid() const
Definition: wifi-mac.cc:465
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
Definition: wifi-mac.cc:883
void SetBeBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BE.
Definition: wifi-mac.cc:1888
bool GetErpSupported(uint8_t linkId) const
Return whether the device supports ERP on the given link.
Definition: wifi-mac.cc:1228
bool GetHtSupported() const
Return whether the device supports HT.
Definition: wifi-mac.cc:1761
void ResetWifiPhys()
Remove currently attached WifiPhy objects from this MAC.
Definition: wifi-mac.cc:1177
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:1093
void SetErpSupported(bool enable, uint8_t linkId)
Enable or disable ERP support for the given link.
Definition: wifi-mac.cc:1234
uint32_t m_voMaxAmpduSize
maximum A-MPDU size for AC_VO (in bytes)
Definition: wifi-mac.h:1073
void ConfigureDcf(Ptr< Txop > dcf, uint32_t cwmin, uint32_t cwmax, std::list< bool > isDsss, AcIndex ac)
Definition: wifi-mac.cc:669
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition: wifi-mac.h:1052
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:945
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:415
MpduTracedCallback m_ackedMpduCallback
ack'ed MPDU callback
Definition: wifi-mac.h:1144
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Definition: wifi-mac.cc:1171
void SetMpduBufferSize(uint16_t size)
Definition: wifi-mac.cc:1853
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:1387
MpduTracedCallback m_nackedMpduCallback
nack'ed MPDU callback
Definition: wifi-mac.h:1145
bool GetEhtSupported() const
Return whether the device supports EHT.
Definition: wifi-mac.cc:1780
bool GetHeSupported() const
Return whether the device supports HE.
Definition: wifi-mac.cc:1774
HtCapabilities GetHtCapabilities(uint8_t linkId) const
Return the HT capabilities of the device for the given link.
Definition: wifi-mac.cc:1959
void SetBkBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BK.
Definition: wifi-mac.cc:1898
void SetVoBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VO.
Definition: wifi-mac.cc:1868
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:961
void NotifyPromiscRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:613
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:1081
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:876
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:1305
RecipientAgreementOptConstRef GetBaAgreementEstablishedAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1693
void SetBeBlockAckInactivityTimeout(uint16_t timeout)
Set BE block ack inactivity timeout.
Definition: wifi-mac.cc:1928
Ptr< EhtConfiguration > GetEhtConfiguration() const
Definition: wifi-mac.cc:1755
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:1116
bool GetVhtSupported(uint8_t linkId) const
Return whether the device supports VHT on the given link.
Definition: wifi-mac.cc:1767
void SetDsssSupported(bool enable, uint8_t linkId)
Enable or disable DSSS support for the given link.
Definition: wifi-mac.cc:1245
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:1100
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition: wifi-mac.h:893
void NotifyTx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:595
static TypeId GetTypeId()
Get the type ID.
Definition: wifi-mac.cc:67
Ptr< HtConfiguration > GetHtConfiguration() const
Definition: wifi-mac.cc:1737
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:1100
uint32_t GetMaxAmpduSize(AcIndex ac) const
Return the maximum A-MPDU size of the given Access Category.
Definition: wifi-mac.cc:2251
BlockAckReqType GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Definition: wifi-mac.cc:1728
Ssid m_ssid
Service Set ID (SSID)
Definition: wifi-mac.h:1057
std::map< uint8_t, std::unique_ptr< LinkEntity > > m_links
ID-indexed map of Link objects.
Definition: wifi-mac.h:1053
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:1620
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:813
virtual void Enqueue(Ptr< Packet > packet, Mac48Address to, Mac48Address from)
Definition: wifi-mac.cc:1479
void NotifyRx(Ptr< const Packet > packet)
Definition: wifi-mac.cc:607
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:1123
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:1066
BlockAckType GetBaTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
Definition: wifi-mac.cc:1701
MpduResponseTimeoutTracedCallback m_mpduResponseTimeoutCallback
MPDU response timeout traced callback.
Definition: wifi-mac.h:1166
void SetForwardUpCallback(ForwardUpCallback upCallback)
Definition: wifi-mac.cc:1284
PsduMapResponseTimeoutTracedCallback m_psduMapResponseTimeoutCallback
PSDU map response timeout traced callback.
Definition: wifi-mac.h:1210
ExtendedCapabilities GetExtendedCapabilities() const
Return the extended capabilities of the device.
Definition: wifi-mac.cc:1948
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:1108
uint16_t m_bkMaxAmsduSize
maximum A-MSDU size for AC_BK (in bytes)
Definition: wifi-mac.h:1071
void SetBkBlockAckInactivityTimeout(uint16_t timeout)
Set BK block ack inactivity timeout.
Definition: wifi-mac.cc:1938
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:1083
virtual bool SupportsSendFrom() const
Definition: wifi-mac.cc:1278
uint16_t GetMaxBaBufferSize(std::optional< Mac48Address > address=std::nullopt) const
Get the maximum Block Ack buffer size (in number of MPDUs) supported by the given device,...
Definition: wifi-mac.cc:1838
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:974
void SetViBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VI.
Definition: wifi-mac.cc:1878
void SetViBlockAckInactivityTimeout(uint16_t timeout)
Set VI block ack inactivity timeout.
Definition: wifi-mac.cc:1918
bool GetShortSlotTimeSupported() const
Definition: wifi-mac.cc:1272
BlockAckReqType GetBarTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
Definition: wifi-mac.cc:1710
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:625
void SetLinkDownCallback(Callback< void > linkDown)
Definition: wifi-mac.cc:1298
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:1743
void NotifyRxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:619
virtual void SetLinkUpCallback(Callback< void > linkUp)
Definition: wifi-mac.cc:1291
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:906
const std::set< uint8_t > & GetLinkIds() const
Definition: wifi-mac.cc:939
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition: wifi-mac.cc:428
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self feature.
Definition: wifi-mac.cc:1258
Mac48Address GetLocalAddress(const Mac48Address &remoteAddr) const
Get the local MAC address used to communicate with a remote STA.
Definition: wifi-mac.cc:1645
EdcaQueues m_edca
This is a map from Access Category index to the corresponding channel access function.
Definition: wifi-mac.h:1066
uint32_t m_bkMaxAmpduSize
maximum A-MPDU size for AC_BK (in bytes)
Definition: wifi-mac.h:1076
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
Definition: wifi-mac.cc:1490
virtual void ConfigureContentionWindow(uint32_t cwMin, uint32_t cwMax)
Definition: wifi-mac.cc:646
OriginatorAgreementOptConstRef GetBaAgreementEstablishedAsOriginator(Mac48Address recipient, uint8_t tid) const
Definition: wifi-mac.cc:1679
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:1497
Mac48Address GetAddress() const
Definition: wifi-mac.cc:452
ForwardUpCallback m_forwardUp
Callback to forward packet up the stack.
Definition: wifi-mac.h:1085
EhtCapabilities GetEhtCapabilities(uint8_t linkId) const
Return the EHT capabilities of the device for the given link.
Definition: wifi-mac.cc:2158
Callback< void > m_linkUp
Callback when a link is up.
Definition: wifi-mac.h:897
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: wifi-mac.cc:924
HeCapabilities GetHeCapabilities(uint8_t linkId) const
Return the HE capabilities of the device for the given link.
Definition: wifi-mac.cc:2100
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy > > &phys)
Definition: wifi-mac.cc:1146
PsduResponseTimeoutTracedCallback m_psduResponseTimeoutCallback
PSDU response timeout traced callback.
Definition: wifi-mac.h:1187
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:601
void DoDispose() override
Destructor implementation.
Definition: wifi-mac.cc:373
bool GetDsssSupported(uint8_t linkId) const
Return whether the device supports DSSS on the given link.
Definition: wifi-mac.cc:1252
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:870
void SetVoBlockAckInactivityTimeout(uint16_t timeout)
Set VO block ack inactivity timeout.
Definition: wifi-mac.cc:1908
virtual std::unique_ptr< LinkEntity > CreateLinkEntity() const
Create a LinkEntity object.
Definition: wifi-mac.cc:912
void SetShortSlotTimeSupported(bool enable)
Enable or disable short slot time feature.
Definition: wifi-mac.cc:1265
bool m_ctsToSelfSupported
flag indicating whether CTS-To-Self is supported
Definition: wifi-mac.h:1048
uint16_t m_beMaxAmsduSize
maximum A-MSDU size for AC_BE (in bytes)
Definition: wifi-mac.h:1070
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:1673
uint32_t m_viMaxAmpduSize
maximum A-MPDU size for AC_VI (in bytes)
Definition: wifi-mac.h:1074
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:1049
#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:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeAccessor > MakeSsidAccessor(T1 a1)
Definition: ssid.h:96
Ptr< const AttributeChecker > MakeSsidChecker()
Definition: ssid.cc:113
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:1350
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1362
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:73
@ 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:83
@ AC_BE
Best Effort.
Definition: qos-utils.h:75
@ AC_VO
Voice.
Definition: qos-utils.h:81
@ AC_VI
Video.
Definition: qos-utils.h:79
@ AC_BK
Background.
Definition: qos-utils.h:77
@ AC_UNDEF
Total number of ACs.
Definition: qos-utils.h:87
@ AC_BEACON
Beacon queue.
Definition: qos-utils.h:85
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:454
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