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