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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "wifi-mac.h"
10
13#include "mac-rx-middle.h"
14#include "mac-tx-middle.h"
15#include "mgt-action-headers.h"
16#include "qos-txop.h"
17#include "ssid.h"
18#include "wifi-mac-queue.h"
19#include "wifi-net-device.h"
20
21#include "ns3/eht-configuration.h"
22#include "ns3/eht-frame-exchange-manager.h"
23#include "ns3/he-configuration.h"
24#include "ns3/ht-configuration.h"
25#include "ns3/log.h"
26#include "ns3/object-vector.h"
27#include "ns3/packet.h"
28#include "ns3/pointer.h"
29#include "ns3/shuffle.h"
30#include "ns3/socket.h"
31#include "ns3/string.h"
32#include "ns3/vht-configuration.h"
33
34#include <algorithm>
35#include <cmath>
36#include <iterator>
37#include <sstream>
38
39namespace ns3
40{
41
43
45
47 : m_qosSupported(false)
48{
49 NS_LOG_FUNCTION(this);
50
52 m_rxMiddle->SetForwardCallback(MakeCallback(&WifiMac::Receive, this));
53
55}
56
61
64{
65 static TypeId tid =
66 TypeId("ns3::WifiMac")
68 .SetGroupName("Wifi")
69 .AddAttribute("Ssid",
70 "The ssid we want to belong to.",
71 SsidValue(Ssid("default")),
74 .AddAttribute("QosSupported",
75 "This Boolean attribute is set to enable 802.11e/WMM-style QoS support "
76 "at this STA.",
78 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
79 BooleanValue(false),
82 .AddAttribute("CtsToSelfSupported",
83 "Use CTS to Self when using a rate that is not in the basic rate set.",
84 BooleanValue(false),
87 .AddAttribute(
88 "ShortSlotTimeSupported",
89 "Whether or not short slot time is supported (only used by ERP APs or STAs).",
90 BooleanValue(true),
94 .AddAttribute("Txop",
95 "The Txop object.",
97 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
101 .AddAttribute("VO_Txop",
102 "Queue that manages packets belonging to AC_VO access class.",
104 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
105 PointerValue(),
108 .AddAttribute("VI_Txop",
109 "Queue that manages packets belonging to AC_VI access class.",
111 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
112 PointerValue(),
115 .AddAttribute("BE_Txop",
116 "Queue that manages packets belonging to AC_BE access class.",
118 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
119 PointerValue(),
122 .AddAttribute("BK_Txop",
123 "Queue that manages packets belonging to AC_BK access class.",
125 TypeId::ATTR_CONSTRUCT, // prevent setting after construction
126 PointerValue(),
129 .AddAttribute(
130 "ChannelAccessManagers",
131 "The Channel Access Manager(s) attached to this device.",
135 .AddAttribute(
136 "FrameExchangeManagers",
137 "The Frame Exchange Manager(s) attached to this device.",
141 .AddAttribute(
142 "MpduBufferSize",
143 "The size (in number of MPDUs) of the buffer used for each BlockAck "
144 "agreement in which this node is a recipient. The provided value is "
145 "capped to the maximum allowed value based on the supported standard.",
146 UintegerValue(1024),
149 .AddAttribute("VO_MaxAmsduSize",
150 "Maximum length in bytes of an A-MSDU for AC_VO access class "
151 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
152 "Value 0 means A-MSDU aggregation is disabled for that AC.",
153 UintegerValue(0),
156 .AddAttribute("VI_MaxAmsduSize",
157 "Maximum length in bytes of an A-MSDU for AC_VI access class "
158 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
159 "Value 0 means A-MSDU aggregation is disabled for that AC.",
160 UintegerValue(0),
163 .AddAttribute("BE_MaxAmsduSize",
164 "Maximum length in bytes of an A-MSDU for AC_BE access class "
165 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
166 "Value 0 means A-MSDU aggregation is disabled for that AC.",
167 UintegerValue(0),
170 .AddAttribute("BK_MaxAmsduSize",
171 "Maximum length in bytes of an A-MSDU for AC_BK access class "
172 "(capped to 7935 for HT PPDUs and 11398 for VHT/HE/EHT PPDUs). "
173 "Value 0 means A-MSDU aggregation is disabled for that AC.",
174 UintegerValue(0),
177 .AddAttribute(
178 "VO_MaxAmpduSize",
179 "Maximum length in bytes of an A-MPDU for AC_VO 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(0),
186 .AddAttribute(
187 "VI_MaxAmpduSize",
188 "Maximum length in bytes of an A-MPDU for AC_VI 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(65535),
195 .AddAttribute(
196 "BE_MaxAmpduSize",
197 "Maximum length in bytes of an A-MPDU for AC_BE access class "
198 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
199 "and 15523200 for EHT PPDUs). "
200 "Value 0 means A-MPDU aggregation is disabled for that AC.",
201 UintegerValue(65535),
204 .AddAttribute(
205 "BK_MaxAmpduSize",
206 "Maximum length in bytes of an A-MPDU for AC_BK access class "
207 "(capped to 65535 for HT PPDUs, 1048575 for VHT PPDUs, 6500631 for HE PPDUs "
208 "and 15523200 for EHT PPDUs). "
209 "Value 0 means A-MPDU aggregation is disabled for that AC.",
210 UintegerValue(0),
213 .AddAttribute(
214 "VO_BlockAckThreshold",
215 "If number of packets in VO 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),
221 .AddAttribute(
222 "VI_BlockAckThreshold",
223 "If number of packets in VI 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),
229 .AddAttribute(
230 "BE_BlockAckThreshold",
231 "If number of packets in BE queue reaches this value, "
232 "block ack mechanism is used. If this value is 0, block ack is never used."
233 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
234 UintegerValue(0),
237 .AddAttribute(
238 "BK_BlockAckThreshold",
239 "If number of packets in BK queue reaches this value, "
240 "block ack mechanism is used. If this value is 0, block ack is never used."
241 "When A-MPDU is enabled, block ack mechanism is used regardless of this value.",
242 UintegerValue(0),
245 .AddAttribute(
246 "VO_BlockAckInactivityTimeout",
247 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
248 "inactivity for AC_VO. If this value isn't equal to 0 a timer start after that a"
249 "block ack setup is completed and will be reset every time that a block ack"
250 "frame is received. If this value is 0, block ack inactivity timeout won't be "
251 "used.",
252 UintegerValue(0),
255 .AddAttribute(
256 "VI_BlockAckInactivityTimeout",
257 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
258 "inactivity for AC_VI. If this value isn't equal to 0 a timer start after that a"
259 "block ack setup is completed and will be reset every time that a block ack"
260 "frame is received. If this value is 0, block ack inactivity timeout won't be "
261 "used.",
262 UintegerValue(0),
265 .AddAttribute(
266 "BE_BlockAckInactivityTimeout",
267 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
268 "inactivity for AC_BE. If this value isn't equal to 0 a timer start after that a"
269 "block ack setup is completed and will be reset every time that a block ack"
270 "frame is received. If this value is 0, block ack inactivity timeout won't be "
271 "used.",
272 UintegerValue(0),
275 .AddAttribute(
276 "BK_BlockAckInactivityTimeout",
277 "Represents max time (blocks of 1024 microseconds) allowed for block ack"
278 "inactivity for AC_BK. If this value isn't equal to 0 a timer start after that a"
279 "block ack setup is completed and will be reset every time that a block ack"
280 "frame is received. If this value is 0, block ack inactivity timeout won't be "
281 "used.",
282 UintegerValue(0),
285 .AddTraceSource("MacTx",
286 "A packet has been received from higher layers and is being processed "
287 "in preparation for "
288 "queueing for transmission.",
290 "ns3::Packet::TracedCallback")
291 .AddTraceSource(
292 "MacTxDrop",
293 "A packet has been dropped in the MAC layer before being queued for transmission. "
294 "This trace source is fired, e.g., when an AP's MAC receives from the upper layer "
295 "a packet destined to a station that is not associated with the AP or a STA's MAC "
296 "receives a packet from the upper layer while it is not associated with any AP.",
298 "ns3::Packet::TracedCallback")
299 .AddTraceSource(
300 "MacPromiscRx",
301 "A packet has been received by this device, has been passed up from the physical "
302 "layer "
303 "and is being forwarded up the local protocol stack. This is a promiscuous trace.",
305 "ns3::Packet::TracedCallback")
306 .AddTraceSource("MacRx",
307 "A packet has been received by this device, has been passed up from "
308 "the physical layer "
309 "and is being forwarded up the local protocol stack. This is a "
310 "non-promiscuous trace.",
312 "ns3::Packet::TracedCallback")
313 .AddTraceSource("MacRxDrop",
314 "A packet has been dropped in the MAC layer after it has been passed "
315 "up from the physical layer.",
317 "ns3::Packet::TracedCallback")
318 .AddTraceSource("AckedMpdu",
319 "An MPDU that was successfully acknowledged, via either a "
320 "Normal Ack or a Block Ack.",
322 "ns3::WifiMpdu::TracedCallback")
323 .AddTraceSource("NAckedMpdu",
324 "An MPDU that was negatively acknowledged via a Block Ack.",
326 "ns3::WifiMpdu::TracedCallback")
327 .AddTraceSource(
328 "DroppedMpdu",
329 "An MPDU that was dropped for the given reason (see WifiMacDropReason).",
331 "ns3::WifiMac::DroppedMpduCallback")
332 .AddTraceSource(
333 "MpduResponseTimeout",
334 "An MPDU whose response was not received before the timeout, along with "
335 "an identifier of the type of timeout (see WifiTxTimer::Reason) and the "
336 "TXVECTOR used to transmit the MPDU. This trace source is fired when a "
337 "CTS is missing after an RTS, when all CTS frames are missing after an MU-RTS, "
338 "or when a Normal Ack is missing after an MPDU or after a DL MU PPDU "
339 "acknowledged in SU format.",
341 "ns3::WifiMac::MpduResponseTimeoutCallback")
342 .AddTraceSource(
343 "PsduResponseTimeout",
344 "A PSDU whose response was not received before the timeout, along with "
345 "an identifier of the type of timeout (see WifiTxTimer::Reason) and the "
346 "TXVECTOR used to transmit the PSDU. This trace source is fired when a "
347 "BlockAck is missing after an A-MPDU, a BlockAckReq (possibly in the "
348 "context of the acknowledgment of a DL MU PPDU in SU format) or a TB PPDU "
349 "(in the latter case the missing BlockAck is a Multi-STA BlockAck).",
351 "ns3::WifiMac::PsduResponseTimeoutCallback")
352 .AddTraceSource(
353 "PsduMapResponseTimeout",
354 "A PSDU map for which not all the responses were received before the timeout, "
355 "along with an identifier of the type of timeout (see WifiTxTimer::Reason), "
356 "the set of MAC addresses of the stations that did not respond and the total "
357 "number of stations that had to respond. This trace source is fired when not "
358 "all the addressed stations responded to an MU-BAR Trigger frame (either sent as "
359 "a SU frame or aggregated to PSDUs in the DL MU PPDU), a Basic Trigger Frame or "
360 "a BSRP Trigger Frame.",
362 "ns3::WifiMac::PsduMapResponseTimeoutCallback")
363 .AddTraceSource("IcfDropReason",
364 "An ICF is dropped by an EMLSR client for the given reason on the "
365 "link with the given ID. This trace source is actually fed by the "
366 "EHT Frame Exchange Manager through the m_icfDropCallback member "
367 "variable.",
369 "ns3::WifiMac::IcfDropCallback");
370 return tid;
371}
372
373int64_t
375{
376 NS_LOG_FUNCTION(this << stream);
377 if (GetNLinks() > 1)
378 {
379 m_shuffleLinkIdsGen.GetRv()->SetStream(stream);
380 return 1;
381 }
382 return 0;
383}
384
385void
387{
388 NS_LOG_FUNCTION(this);
389
390 if (!m_qosSupported)
391 {
393 return;
394 }
395
396 for (const auto& [aci, ac] : wifiAcList)
397 {
398 SetupEdcaQueue(aci);
399 }
400}
401
402void
404{
405 NS_LOG_FUNCTION(this);
406
407 if (m_txop)
408 {
410 }
411
412 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
413 {
414 it->second->Initialize();
415 }
416
417 for (const auto& [id, link] : m_links)
418 {
419 if (auto cam = link->channelAccessManager)
420 {
421 cam->Initialize();
422 }
423 }
424}
425
426void
428{
429 NS_LOG_FUNCTION(this);
430
431 m_rxMiddle = nullptr;
432 m_txMiddle = nullptr;
433 m_links.clear();
434
435 if (m_txop)
436 {
437 m_txop->Dispose();
438 }
439 m_txop = nullptr;
440
441 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
442 {
443 it->second->Dispose();
444 it->second = nullptr;
445 }
446
447 m_device = nullptr;
448 if (m_scheduler != nullptr)
449 {
450 m_scheduler->Dispose();
451 }
452 m_scheduler = nullptr;
453}
454
456{
457 // WifiMac owns pointers to ChannelAccessManager and FrameExchangeManager
459 {
460 channelAccessManager->Dispose();
461 }
462 if (feManager)
463 {
464 feManager->Dispose();
465 }
466}
467
468void
470{
471 NS_LOG_FUNCTION(this << type);
472 m_typeOfStation = type;
473}
474
477{
478 return m_typeOfStation;
479}
480
481void
483{
484 m_device = device;
485 if (device->GetHtConfiguration())
486 {
487 // the configured BlockAck buffer size can now be capped
489 }
490}
491
494{
495 return m_device;
496}
497
498void
500{
501 NS_LOG_FUNCTION(this << address);
502 m_address = address;
503}
504
507{
508 return m_address;
509}
510
511void
513{
514 NS_LOG_FUNCTION(this << ssid);
515 m_ssid = ssid;
516}
517
518Ssid
520{
521 return m_ssid;
522}
523
524void
525WifiMac::SetBssid(Mac48Address bssid, uint8_t linkId)
526{
527 NS_LOG_FUNCTION(this << bssid << +linkId);
528 GetLink(linkId).feManager->SetBssid(bssid);
529}
530
532WifiMac::GetBssid(uint8_t linkId) const
533{
534 return GetLink(linkId).feManager->GetBssid();
535}
536
537void
539{
540 for (auto& [id, link] : m_links)
541 {
542 link->feManager->SetPromisc();
543 }
544}
545
546void
548{
549 NS_LOG_FUNCTION(this << dcf);
550 if (!m_qosSupported)
551 {
552 m_txop = dcf;
553 }
554}
555
558{
559 return m_txop;
560}
561
562void
564{
565 NS_LOG_FUNCTION(this << edca);
566 if (m_qosSupported)
567 {
568 m_edca.emplace(AC_VO, edca);
569 }
570}
571
572void
574{
575 NS_LOG_FUNCTION(this << edca);
576 if (m_qosSupported)
577 {
578 m_edca.emplace(AC_VI, edca);
579 }
580}
581
582void
584{
585 NS_LOG_FUNCTION(this << edca);
586 if (m_qosSupported)
587 {
588 m_edca.emplace(AC_BE, edca);
589 }
590}
591
592void
594{
595 NS_LOG_FUNCTION(this << edca);
596 if (m_qosSupported)
597 {
598 m_edca.emplace(AC_BK, edca);
599 }
600}
601
604{
605 // Use std::find_if() instead of std::map::find() because the latter compares
606 // the given AC index with the AC index of an element in the map by using the
607 // operator< defined for AcIndex, which aborts if an operand is not a QoS AC
608 // (the AC index passed to this method may not be a QoS AC).
609 // The performance penalty is limited because std::map::find() performs 3
610 // comparisons in the worst case, while std::find_if() performs 4 comparisons
611 // in the worst case.
612 const auto it = std::find_if(m_edca.cbegin(), m_edca.cend(), [ac](const auto& pair) {
613 return pair.first == ac;
614 });
615 return (it == m_edca.cend() ? nullptr : it->second);
616}
617
619WifiMac::GetQosTxop(uint8_t tid) const
620{
621 return GetQosTxop(QosUtilsMapTidToAc(tid));
622}
623
626{
627 return (m_qosSupported ? GetQosTxop(AC_VO) : nullptr);
628}
629
632{
633 return (m_qosSupported ? GetQosTxop(AC_VI) : nullptr);
634}
635
638{
639 return (m_qosSupported ? GetQosTxop(AC_BE) : nullptr);
640}
641
644{
645 return (m_qosSupported ? GetQosTxop(AC_BK) : nullptr);
646}
647
650{
651 Ptr<Txop> txop = (ac == AC_BE_NQOS ? m_txop : StaticCast<Txop>(GetQosTxop(ac)));
652 return (txop ? txop->GetWifiMacQueue() : nullptr);
653}
654
655bool
657{
658 if (m_txop && m_txop->HasFramesToTransmit(linkId))
659 {
660 return true;
661 }
662 for (const auto& [aci, qosTxop] : m_edca)
663 {
664 if (qosTxop->HasFramesToTransmit(linkId))
665 {
666 return true;
667 }
668 }
669 return false;
670}
671
672void
674{
675 m_scheduler = scheduler;
676 m_scheduler->SetWifiMac(this);
677}
678
681{
682 return m_scheduler;
683}
684
685void
687{
688 NS_LOG_FUNCTION(this << +linkId);
689
690 // we may have changed PHY band, in which case it is necessary to re-configure
691 // the PHY dependent parameters. In any case, this makes no harm
693
694 // Reset remote station manager
695 GetLink(linkId).stationManager->Reset();
696}
697
698void
700{
701 m_macTxTrace(packet);
702}
703
704void
709
710void
712{
713 m_macRxTrace(packet);
714}
715
716void
721
722void
727
728void
730{
731 NS_LOG_FUNCTION(this);
733
736 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
737}
738
739void
741{
742 NS_LOG_FUNCTION(this << ac);
743
744 auto edcaIt = m_edca.find(ac);
745 NS_ASSERT(edcaIt != m_edca.cend());
746
747 edcaIt->second->SetTxMiddle(m_txMiddle);
748 edcaIt->second->GetBaManager()->SetTxOkCallback(
749 MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
750 edcaIt->second->GetBaManager()->SetTxFailedCallback(
751 MakeCallback(&MpduTracedCallback::operator(), &m_nackedMpduCallback));
752 edcaIt->second->SetDroppedMpduCallback(
753 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
754}
755
756void
758{
759 std::list<bool> isDsssOnly;
760 for (const auto& [id, link] : m_links)
761 {
762 isDsssOnly.push_back(link->dsssSupported && !link->erpSupported);
763 }
764
765 if (m_txop)
766 {
767 // The special value of AC_BE_NQOS which exists in the Access
768 // Category enumeration allows us to configure plain old DCF.
769 ConfigureDcf(m_txop, cwMin, cwMax, isDsssOnly, AC_BE_NQOS);
770 }
771
772 // Now we configure the EDCA functions
773 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
774 {
775 ConfigureDcf(it->second, cwMin, cwMax, isDsssOnly, it->first);
776 }
777}
778
779void
781 uint32_t cwmin,
782 uint32_t cwmax,
783 std::list<bool> isDsss,
784 AcIndex ac)
785{
786 NS_LOG_FUNCTION(this << dcf << cwmin << cwmax << +ac);
787
788 uint32_t cwMinValue = 0;
789 uint32_t cwMaxValue = 0;
790 uint8_t aifsnValue = 0;
791 Time txopLimitDsss(0);
792 Time txopLimitNoDsss(0);
793
794 /* see IEEE 802.11-2020 Table 9-155 "Default EDCA Parameter Set element parameter values" */
795 switch (ac)
796 {
797 case AC_VO:
798 cwMinValue = (cwmin + 1) / 4 - 1;
799 cwMaxValue = (cwmin + 1) / 2 - 1;
800 aifsnValue = 2;
801 txopLimitDsss = MicroSeconds(3264);
802 txopLimitNoDsss = MicroSeconds(2080);
803 break;
804 case AC_VI:
805 cwMinValue = (cwmin + 1) / 2 - 1;
806 cwMaxValue = cwmin;
807 aifsnValue = 2;
808 txopLimitDsss = MicroSeconds(6016);
809 txopLimitNoDsss = MicroSeconds(4096);
810 break;
811 case AC_BE:
812 cwMinValue = cwmin;
813 cwMaxValue = cwmax;
814 aifsnValue = 3;
815 txopLimitDsss = MicroSeconds(0); // TODO should be MicroSeconds (3264)
816 txopLimitNoDsss = MicroSeconds(0); // TODO should be MicroSeconds (2528)
817 break;
818 case AC_BK:
819 cwMinValue = cwmin;
820 cwMaxValue = cwmax;
821 aifsnValue = 7;
822 txopLimitDsss = MicroSeconds(0); // TODO should be MicroSeconds (3264)
823 txopLimitNoDsss = MicroSeconds(0); // TODO should be MicroSeconds (2528)
824 break;
825 case AC_BE_NQOS:
826 cwMinValue = cwmin;
827 cwMaxValue = cwmax;
828 aifsnValue = 2;
829 txopLimitDsss = txopLimitNoDsss = MicroSeconds(0);
830 break;
831 case AC_BEACON:
832 // done by ApWifiMac
833 break;
834 case AC_UNDEF:
835 NS_FATAL_ERROR("I don't know what to do with this");
836 break;
837 }
838
839 const auto& userDefinedParams = dcf->GetUserAccessParams();
840
841 dcf->SetMinCws(!userDefinedParams.cwMins.empty()
842 ? userDefinedParams.cwMins
843 : std::vector<uint32_t>(m_links.size(), cwMinValue));
844 dcf->SetMaxCws(!userDefinedParams.cwMaxs.empty()
845 ? userDefinedParams.cwMaxs
846 : std::vector<uint32_t>(m_links.size(), cwMaxValue));
847 dcf->SetAifsns(!userDefinedParams.aifsns.empty()
848 ? userDefinedParams.aifsns
849 : std::vector<uint8_t>(m_links.size(), aifsnValue));
850
851 if (!userDefinedParams.txopLimits.empty())
852 {
853 dcf->SetTxopLimits(userDefinedParams.txopLimits);
854 }
855 else
856 {
857 std::vector<Time> txopLimitValues(m_links.size());
858 std::transform(isDsss.begin(),
859 isDsss.end(),
860 txopLimitValues.begin(),
861 [&txopLimitDsss, &txopLimitNoDsss](bool dsss) {
862 return (dsss ? txopLimitDsss : txopLimitNoDsss);
863 });
864 dcf->SetTxopLimits(txopLimitValues);
865 }
866}
867
868void
870{
871 NS_ASSERT_MSG(!m_links.empty(), "CompleteConfig cannot be called before creating links");
872
873 const auto& link = *m_links.cbegin()->second;
874
875 if (!link.phy || !link.stationManager || !link.channelAccessManager || !link.feManager)
876 {
877 return;
878 }
879
880 NS_LOG_FUNCTION(this);
881
882 for (auto& [id, link] : m_links)
883 {
885 !link->phy || !link->phy->GetOperatingChannel().IsSet(),
886 "[LinkID " << +id
887 << "] PHY must have been set and an operating channel must have been set");
889 NS_ABORT_MSG_IF(!link->channelAccessManager,
890 "[LinkID " << +id << "] A channel access manager must have been set");
891
892 NS_ABORT_MSG_IF(!link->feManager,
893 "[LinkID " << +id << "] A frame exchange manager must have been set");
894
895 link->channelAccessManager->SetupPhyListener(link->phy);
896 link->channelAccessManager->SetupFrameExchangeManager(link->feManager);
897
898 link->feManager->SetWifiPhy(link->phy);
899 link->feManager->SetMacTxMiddle(m_txMiddle);
900 link->feManager->SetMacRxMiddle(m_rxMiddle);
901
902 if (m_txop)
903 {
904 m_txop->SetWifiMac(this);
905 link->channelAccessManager->Add(m_txop);
906 }
907 for (auto it = m_edca.begin(); it != m_edca.end(); ++it)
908 {
909 it->second->SetWifiMac(this);
910 link->channelAccessManager->Add(it->second);
911 }
912
915
917}
918
919void
921{
922 NS_LOG_FUNCTION(this << +linkId);
923
924 WifiStandard standard = GetLink(linkId).phy->GetStandard();
925
926 uint32_t cwmin = (standard == WIFI_STANDARD_80211b ? 31 : 15);
927 uint32_t cwmax = 1023;
928
929 SetDsssSupported(standard == WIFI_STANDARD_80211b, linkId);
931 m_links[linkId]->phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ,
932 linkId);
933
934 ConfigureContentionWindow(cwmin, cwmax);
935}
936
937bool
939{
940 if (!m_links.empty())
941 {
942 return false;
943 }
944
945 for (std::size_t i = 0; i < nLinks; i++)
946 {
947 m_links.emplace(i, CreateLinkEntity());
948 m_linkIds.insert(i);
949 }
950 return true;
951}
952
953void
955{
956 NS_LOG_FUNCTION(this);
957
958 if (!CreateLinksIfNeeded(feManagers.size()))
959 {
960 NS_ABORT_MSG_IF(feManagers.size() != m_links.size(),
961 "The number of provided Frame Exchange Manager objects ("
962 << feManagers.size() << ") must match the number of existing links ("
963 << m_links.size() << ")");
964 }
965
966 for (auto managerIt = feManagers.cbegin(); auto& [id, link] : m_links)
967 {
968 link->feManager = *managerIt++;
969 link->feManager->SetWifiMac(this);
970 link->feManager->SetLinkId(id);
971 // connect callbacks
972 link->feManager->GetWifiTxTimer().SetMpduResponseTimeoutCallback(
973 MakeCallback(&MpduResponseTimeoutTracedCallback::operator(),
975 link->feManager->GetWifiTxTimer().SetPsduResponseTimeoutCallback(
976 MakeCallback(&PsduResponseTimeoutTracedCallback::operator(),
978 link->feManager->GetWifiTxTimer().SetPsduMapResponseTimeoutCallback(
979 MakeCallback(&PsduMapResponseTimeoutTracedCallback::operator(),
981 link->feManager->SetDroppedMpduCallback(
982 MakeCallback(&DroppedMpduTracedCallback::operator(), &m_droppedMpduCallback));
983 link->feManager->SetAckedMpduCallback(
984 MakeCallback(&MpduTracedCallback::operator(), &m_ackedMpduCallback));
985 if (auto ehtFem = DynamicCast<EhtFrameExchangeManager>(link->feManager))
986 {
987 ehtFem->m_icfDropCallback.ConnectWithoutContext(
988 MakeCallback(&IcfDropTracedCallback::operator(), &m_icfDropCallback));
989 }
990 }
991
993}
994
997{
998 return GetLink(linkId).feManager;
999}
1000
1001void
1003{
1004 NS_LOG_FUNCTION(this);
1005
1006 if (!CreateLinksIfNeeded(caManagers.size()))
1007 {
1008 NS_ABORT_MSG_IF(caManagers.size() != m_links.size(),
1009 "The number of provided Channel Access Manager objects ("
1010 << caManagers.size() << ") must match the number of existing links ("
1011 << m_links.size() << ")");
1012 }
1013
1014 for (auto managerIt = caManagers.cbegin(); auto& [id, link] : m_links)
1015 {
1016 link->channelAccessManager = *managerIt++;
1017 link->channelAccessManager->SetLinkId(id);
1018 }
1019
1021}
1022
1025{
1026 return GetLink(linkId).channelAccessManager;
1027}
1028
1029void
1031{
1032 NS_LOG_FUNCTION(this << stationManager);
1033 SetWifiRemoteStationManagers({stationManager});
1034}
1035
1036void
1038 const std::vector<Ptr<WifiRemoteStationManager>>& stationManagers)
1039{
1040 NS_LOG_FUNCTION(this);
1041
1042 if (!CreateLinksIfNeeded(stationManagers.size()))
1043 {
1044 NS_ABORT_MSG_IF(stationManagers.size() != m_links.size(),
1045 "The number of provided Remote Manager objects ("
1046 << stationManagers.size()
1047 << ") must match the number of existing links (" << m_links.size()
1048 << ")");
1049 }
1050
1051 for (auto managerIt = stationManagers.cbegin(); auto& [id, link] : m_links)
1052 {
1053 link->stationManager = *managerIt++;
1054 }
1055
1057}
1058
1061{
1062 return GetLink(linkId).stationManager;
1063}
1064
1065std::unique_ptr<WifiMac::LinkEntity>
1067{
1068 return std::make_unique<LinkEntity>();
1069}
1070
1071const std::map<uint8_t, std::unique_ptr<WifiMac::LinkEntity>>&
1073{
1074 return m_links;
1075}
1076
1078WifiMac::GetLink(uint8_t linkId) const
1079{
1080 auto it = m_links.find(linkId);
1081 NS_ASSERT(it != m_links.cend());
1082 NS_ASSERT(it->second); // check that the pointer owns an object
1083 return *it->second;
1084}
1085
1086uint8_t
1088{
1089 return m_links.size();
1090}
1091
1092const std::set<uint8_t>&
1094{
1095 return m_linkIds;
1096}
1097
1098void
1100{
1101 NS_LOG_FUNCTION(this << id);
1102
1103 auto& link = GetLink(id);
1104 if (link.feManager)
1105 {
1106 link.feManager->SetLinkId(id);
1107 }
1108 if (link.channelAccessManager)
1109 {
1110 link.channelAccessManager->SetLinkId(id);
1111 }
1112}
1113
1114std::optional<uint8_t>
1116{
1117 for (const auto& [id, link] : m_links)
1118 {
1119 if (link->feManager->GetAddress() == address)
1120 {
1121 return id;
1122 }
1123 }
1124 return std::nullopt;
1125}
1126
1127std::optional<uint8_t>
1129{
1130 for (const auto& [id, link] : m_links)
1131 {
1132 if (link->phy == phy)
1133 {
1134 return id;
1135 }
1136 }
1137 return std::nullopt;
1138}
1139
1140std::optional<uint8_t>
1141WifiMac::GetLinkForPhy(std::size_t phyId) const
1142{
1143 NS_ABORT_UNLESS(phyId < m_device->GetNPhys());
1144 auto phy = m_device->GetPhy(phyId);
1145 return GetLinkForPhy(phy);
1146}
1147
1148void
1149WifiMac::SwapLinks(std::map<uint8_t, uint8_t> links)
1150{
1151 NS_LOG_FUNCTION(this);
1152
1153 // save the initial mapping between link IDs and link Entities
1154 std::map<uint8_t, std::reference_wrapper<const LinkEntity>> origLinkRefMap;
1155 for (const auto& [id, link] : m_links)
1156 {
1157 origLinkRefMap.insert_or_assign(id, *link.get());
1158 }
1159
1160 while (!links.empty())
1161 {
1162 auto from = links.cbegin()->first;
1163 auto to = links.cbegin()->second;
1164
1165 if (from == to)
1166 {
1167 // nothing to do
1168 links.erase(links.cbegin());
1169 continue;
1170 }
1171
1172 std::unique_ptr<LinkEntity> linkToMove;
1173 NS_ASSERT(m_links.contains(from));
1174 linkToMove.swap(m_links.at(from)); // from is now out of m_links
1175 auto empty = from; // track empty cell in m_links
1176
1177 do
1178 {
1179 auto [it, inserted] =
1180 m_links.emplace(to, nullptr); // insert an element with key to if not present
1181 m_links[to].swap(linkToMove); // to is the link to move now
1182 links.erase(from);
1183 if (!linkToMove)
1184 {
1185 if (inserted)
1186 {
1187 m_links.erase(empty);
1188 }
1189 break;
1190 }
1191
1192 auto nextTo = links.find(to);
1193 if (nextTo == links.cend())
1194 {
1195 // no new position specified for 'to', use the current empty cell
1196 m_links[empty].swap(linkToMove);
1197 break;
1198 }
1199
1200 from = to;
1201 to = nextTo->second;
1202 } while (true);
1203 }
1204
1205 m_linkIds.clear();
1206 for (const auto& [id, link] : m_links)
1207 {
1208 m_linkIds.insert(id);
1209 }
1210
1211 std::map<uint8_t, uint8_t> actualPairs;
1212 for (const auto& [from, ref] : origLinkRefMap)
1213 {
1214 // find the pointer in the current link map
1215 for (const auto& [to, link] : m_links)
1216 {
1217 if (link.get() == &ref.get())
1218 {
1219 actualPairs[from] = to; // link 'from' became link 'to'
1220 UpdateLinkId(to);
1221 break;
1222 }
1223 }
1224 }
1225 NS_ASSERT_MSG(actualPairs.size() == m_links.size(), "Missing some link(s)");
1226
1227 if (m_txop)
1228 {
1229 m_txop->SwapLinks(actualPairs);
1230 }
1231 for (auto& [ac, edca] : m_edca)
1232 {
1233 edca->SwapLinks(actualPairs);
1234 }
1235}
1236
1237bool
1238WifiMac::Is6GhzBand(uint8_t linkId) const
1239{
1240 auto phy = GetLink(linkId).phy;
1241 NS_ASSERT(phy);
1242 return phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ;
1243}
1244
1245void
1248 const WifiTidLinkMapping& mapping)
1249{
1250 NS_LOG_FUNCTION(this << mldAddr);
1251
1253 "DL and UL directions for TID-to-Link mapping must be set separately");
1254
1256
1257 auto [it, inserted] = mappings.emplace(mldAddr, mapping);
1258
1259 if (inserted)
1260 {
1261 // we are done
1262 return;
1263 }
1264
1265 // a previous mapping is stored for this MLD
1266 if (mapping.empty())
1267 {
1268 // the default mapping has been now negotiated
1269 it->second.clear();
1270 return;
1271 }
1272
1273 for (const auto& [tid, linkSet] : mapping)
1274 {
1275 it->second[tid] = linkSet;
1276 }
1277}
1278
1279std::optional<std::reference_wrapper<const WifiTidLinkMapping>>
1281{
1283 "Cannot request TID-to-Link mapping for both directions");
1284
1285 const auto& mappings =
1287
1288 if (const auto it = mappings.find(mldAddr); it != mappings.cend())
1289 {
1290 return it->second;
1291 }
1292 return std::nullopt;
1293}
1294
1295bool
1296WifiMac::TidMappedOnLink(Mac48Address mldAddr, WifiDirection dir, uint8_t tid, uint8_t linkId) const
1297{
1299 "Cannot request TID-to-Link mapping for both directions");
1300
1301 const auto& mappings =
1303
1304 const auto it = mappings.find(mldAddr);
1305
1306 if (it == mappings.cend())
1307 {
1308 // TID-to-link mapping was not negotiated, TIDs are mapped to all setup links
1309 return GetWifiRemoteStationManager(linkId)->GetMldAddress(mldAddr).has_value();
1310 }
1311
1312 auto linkSetIt = it->second.find(tid);
1313
1314 if (linkSetIt == it->second.cend())
1315 {
1316 // If there is no successfully negotiated TID-to-link mapping for a TID, then the TID
1317 // is mapped to all setup links for DL and UL (Sec. 35.3.7.1.3 of 802.11be D3.1)
1318 return GetWifiRemoteStationManager(linkId)->GetMldAddress(mldAddr).has_value();
1319 }
1320
1321 return std::find(linkSetIt->second.cbegin(), linkSetIt->second.cend(), linkId) !=
1322 linkSetIt->second.cend();
1323}
1324
1325void
1326WifiMac::SetWifiPhys(const std::vector<Ptr<WifiPhy>>& phys)
1327{
1328 NS_LOG_FUNCTION(this);
1329 ResetWifiPhys();
1330
1331 if (!CreateLinksIfNeeded(phys.size()))
1332 {
1333 NS_ABORT_MSG_IF(phys.size() != m_links.size(),
1334 "The number of provided PHY objects ("
1335 << phys.size() << ") must match the number of existing links ("
1336 << m_links.size() << ")");
1337 }
1338
1339 for (auto phyIt = phys.cbegin(); auto& [id, link] : m_links)
1340 {
1341 link->phy = *phyIt++;
1342 }
1343
1345}
1346
1348WifiMac::GetWifiPhy(uint8_t linkId) const
1349{
1350 return GetLink(linkId).phy;
1351}
1352
1353void
1355{
1356 NS_LOG_FUNCTION(this);
1357 for (auto& [id, link] : m_links)
1358 {
1359 if (link->feManager)
1360 {
1361 link->feManager->ResetPhy();
1362 }
1363 if (link->channelAccessManager)
1364 {
1365 link->channelAccessManager->RemovePhyListener(link->phy);
1366 }
1367 link->phy = nullptr;
1368 }
1369}
1370
1371void
1373{
1374 NS_LOG_FUNCTION(this << enable);
1376 m_qosSupported = enable;
1377}
1378
1379bool
1381{
1382 return m_qosSupported;
1383}
1384
1385bool
1386WifiMac::GetErpSupported(uint8_t linkId) const
1387{
1388 return GetLink(linkId).erpSupported;
1389}
1390
1391void
1392WifiMac::SetErpSupported(bool enable, uint8_t linkId)
1393{
1394 NS_LOG_FUNCTION(this << enable << +linkId);
1395 if (enable)
1396 {
1397 SetDsssSupported(true, linkId);
1398 }
1399 GetLink(linkId).erpSupported = enable;
1400}
1401
1402void
1403WifiMac::SetDsssSupported(bool enable, uint8_t linkId)
1404{
1405 NS_LOG_FUNCTION(this << enable << +linkId);
1406 GetLink(linkId).dsssSupported = enable;
1407}
1408
1409bool
1410WifiMac::GetDsssSupported(uint8_t linkId) const
1411{
1412 return GetLink(linkId).dsssSupported;
1413}
1414
1415void
1417{
1418 NS_LOG_FUNCTION(this);
1419 m_ctsToSelfSupported = enable;
1420}
1421
1422void
1424{
1425 NS_LOG_FUNCTION(this << enable);
1426 m_shortSlotTimeSupported = enable;
1427}
1428
1429bool
1434
1435bool
1437{
1438 return false;
1439}
1440
1441void
1443{
1444 NS_LOG_FUNCTION(this);
1445 m_forwardUp = upCallback;
1446}
1447
1448void
1450{
1451 NS_LOG_FUNCTION(this);
1452 m_linkUp = linkUp;
1453}
1454
1455void
1457{
1458 NS_LOG_FUNCTION(this);
1459 m_linkDown = linkDown;
1460}
1461
1462void
1464{
1465 NS_LOG_FUNCTION(this << mldAddr);
1466
1469 "This method can be used to enforce TID-to-Link mapping for one direction at a time");
1470
1471 const auto& mappings =
1473
1474 auto it = mappings.find(mldAddr);
1475
1476 if (it == mappings.cend())
1477 {
1478 // no mapping has been ever negotiated with the given MLD, the default mapping is used
1479 return;
1480 }
1481
1482 std::set<uint8_t> setupLinks;
1483
1484 // find the IDs of the links setup with the given MLD
1485 for (const auto& [id, link] : m_links)
1486 {
1487 if (link->stationManager->GetMldAddress(mldAddr))
1488 {
1489 setupLinks.insert(id);
1490 }
1491 }
1492
1493 auto linkMapping = it->second;
1494
1495 if (linkMapping.empty())
1496 {
1497 // default link mapping, each TID mapped on all setup links
1498 for (uint8_t tid = 0; tid < 8; tid++)
1499 {
1500 linkMapping.emplace(tid, setupLinks);
1501 }
1502 }
1503
1504 for (const auto& [tid, linkSet] : linkMapping)
1505 {
1506 decltype(setupLinks) mappedLinks; // empty
1507 auto notMappedLinks = setupLinks; // all setup links
1508
1509 for (const auto id : linkSet)
1510 {
1511 if (setupLinks.find(id) != setupLinks.cend())
1512 {
1513 // link is mapped
1514 mappedLinks.insert(id);
1515 notMappedLinks.erase(id);
1516 }
1517 }
1518
1519 // unblock mapped links
1520 NS_ABORT_MSG_IF(mappedLinks.empty(), "Every TID must be mapped to at least a link");
1521
1523 QosUtilsMapTidToAc(tid),
1525 mldAddr,
1526 GetAddress(),
1527 {tid},
1528 mappedLinks);
1529
1530 // block unmapped links
1531 if (!notMappedLinks.empty())
1532 {
1534 QosUtilsMapTidToAc(tid),
1536 mldAddr,
1537 GetAddress(),
1538 {tid},
1539 notMappedLinks);
1540 }
1541 }
1542}
1543
1544void
1546 const Mac48Address& address,
1547 const std::set<uint8_t>& linkIds)
1548{
1549 std::stringstream ss;
1550 if (g_log.IsEnabled(ns3::LOG_FUNCTION))
1551 {
1552 std::copy(linkIds.cbegin(), linkIds.cend(), std::ostream_iterator<uint16_t>(ss, " "));
1553 }
1554 NS_LOG_FUNCTION(this << reason << address << ss.str());
1556
1557 for (const auto linkId : linkIds)
1558 {
1559 auto& link = GetLink(linkId);
1560 auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address).value_or(address);
1561
1562 if (link.stationManager->GetMldAddress(address) == address && linkAddr == address)
1563 {
1564 NS_LOG_DEBUG("Link " << +linkId << " has not been setup with the MLD, skip");
1565 continue;
1566 }
1567
1568 for (const auto& [acIndex, ac] : wifiAcList)
1569 {
1570 // block queues storing QoS data frames and control frames that use MLD addresses
1571 m_scheduler->BlockQueues(reason,
1572 acIndex,
1574 address,
1575 GetAddress(),
1576 {ac.GetLowTid(), ac.GetHighTid()},
1577 {linkId});
1578 // block queues storing management and control frames that use link addresses
1579 m_scheduler->BlockQueues(reason,
1580 acIndex,
1582 linkAddr,
1583 link.feManager->GetAddress(),
1584 {},
1585 {linkId});
1586 }
1587 }
1588}
1589
1590void
1592 const Mac48Address& address,
1593 const std::set<uint8_t>& linkIds)
1594{
1596
1597 // shuffle link IDs not to unblock links always in the same order
1598 std::vector<uint8_t> shuffledLinkIds(linkIds.cbegin(), linkIds.cend());
1599 Shuffle(shuffledLinkIds.begin(), shuffledLinkIds.end(), m_shuffleLinkIdsGen.GetRv());
1600
1601 std::stringstream ss;
1602 if (g_log.IsEnabled(ns3::LOG_FUNCTION))
1603 {
1604 std::copy(shuffledLinkIds.cbegin(),
1605 shuffledLinkIds.cend(),
1606 std::ostream_iterator<uint16_t>(ss, " "));
1607 }
1608 NS_LOG_FUNCTION(this << reason << address << ss.str());
1609
1610 for (const auto linkId : shuffledLinkIds)
1611 {
1612 auto& link = GetLink(linkId);
1613 auto linkAddr = link.stationManager->GetAffiliatedStaAddress(address).value_or(address);
1614
1615 if (link.stationManager->GetMldAddress(address) == address && linkAddr == address)
1616 {
1617 NS_LOG_DEBUG("Link " << +linkId << " has not been setup with the MLD, skip");
1618 continue;
1619 }
1620
1621 for (const auto& [acIndex, ac] : wifiAcList)
1622 {
1623 // save the status of the AC queues before unblocking the requested queues
1624 auto hasFramesToTransmit = GetQosTxop(acIndex)->HasFramesToTransmit(linkId);
1625
1626 // unblock queues storing QoS data frames and control frames that use MLD addresses
1627 m_scheduler->UnblockQueues(reason,
1628 acIndex,
1630 address,
1631 GetAddress(),
1632 {ac.GetLowTid(), ac.GetHighTid()},
1633 {linkId});
1634 // unblock queues storing management and control frames that use link addresses
1635 m_scheduler->UnblockQueues(reason,
1636 acIndex,
1638 linkAddr,
1639 link.feManager->GetAddress(),
1640 {},
1641 {linkId});
1642 // request channel access if needed (schedule now because multiple invocations
1643 // of this method may be done in a loop at the caller)
1645 GetQosTxop(acIndex),
1646 linkId,
1647 hasFramesToTransmit,
1648 Txop::CHECK_MEDIUM_BUSY); // generate backoff if medium busy
1649 }
1650 }
1651}
1652
1653bool
1655 const WifiContainerQueueId& queueId,
1656 uint8_t linkId,
1657 WifiQueueBlockedReason reason) const
1658{
1659 auto mask = m_scheduler->GetQueueLinkMask(ac, queueId, linkId);
1660
1661 if (!mask.has_value())
1662 {
1663 return true; // the link may have not been setup
1664 }
1666 {
1667 return mask->any();
1668 }
1669 return mask->test(static_cast<std::size_t>(reason));
1670}
1671
1672void
1674{
1675 NS_LOG_FUNCTION(this << packet << to);
1676 // We're sending this packet with a from address that is our own. We
1677 // get that address from the lower MAC and make use of the
1678 // from-spoofing Enqueue() method to avoid duplicated code.
1679 Enqueue(packet, to, GetAddress());
1680}
1681
1682void
1684{
1685 NS_LOG_FUNCTION(this << packet << to << from);
1686
1687 // If we are not a QoS AP then we definitely want to use AC_BE to
1688 // transmit the packet. A TID of zero will map to AC_BE (through \c
1689 // QosUtilsMapTidToAc()), so we use that as our default here.
1690 uint8_t tid = 0;
1691
1693 if (packet->RemovePacketTag(qos) && qos.GetPriority() < 8)
1694 {
1695 tid = qos.GetPriority();
1696 }
1697
1698 Enqueue(packet, to, from, tid);
1699}
1700
1701void
1703{
1704 NS_LOG_FUNCTION(this << packet << to << from << tid);
1705
1707 "This Mac does not support forwarding frames");
1708
1709 if (!CanForwardPacketsTo(to))
1710 {
1711 NotifyTxDrop(packet);
1712 NotifyDropPacketToEnqueue(packet, to);
1713 return;
1714 }
1715
1716 WifiMacHeader hdr;
1717
1718 // For now, an AP that supports QoS does not support non-QoS
1719 // associations, and vice versa. In future the AP model should
1720 // support simultaneously associated QoS and non-QoS STAs, at which
1721 // point there will need to be per-association QoS state maintained
1722 // by the association state machine, and consulted here.
1723 if (GetQosSupported())
1724 {
1727 hdr.SetQosNoEosp();
1728 hdr.SetQosNoAmsdu();
1729 hdr.SetQosTid(tid);
1730 hdr.SetNoOrder(); // explicitly set to 0 for the time being since HT control field is not
1731 // yet implemented (set it to 1 when implemented)
1732 }
1733 else
1734 {
1736 }
1737
1738 // create an MPDU and pass it to subclasses to finalize MAC header
1739 Enqueue(Create<WifiMpdu>(packet, hdr), to, from);
1740}
1741
1742void
1744{
1745 NS_LOG_FUNCTION(this << packet << to);
1746}
1747
1748void
1750{
1751 NS_LOG_FUNCTION(this << packet << from << to);
1752 m_forwardUp(packet, from, to);
1753}
1754
1755void
1757{
1758 NS_LOG_FUNCTION(this << *mpdu << linkId);
1759
1760 const auto& hdr = mpdu->GetOriginal()->GetHeader();
1761 const auto to = hdr.GetAddr1();
1762 const auto myAddr = hdr.IsData() ? Mac48Address::ConvertFrom(GetDevice()->GetAddress())
1763 : GetFrameExchangeManager(linkId)->GetAddress();
1764
1765 // We don't know how to deal with any frame that is not addressed to
1766 // us (and odds are there is nothing sensible we could do anyway),
1767 // so we ignore such frames.
1768 //
1769 // The derived class may also do some such filtering, but it doesn't
1770 // hurt to have it here too as a backstop.
1771 if (to != myAddr)
1772 {
1773 return;
1774 }
1775
1776 // Nothing to do with (QoS) Null Data frames or management frames
1777 if ((hdr.IsData() && !hdr.HasData()) || hdr.IsMgt())
1778 {
1779 return;
1780 }
1781
1782 NS_FATAL_ERROR("Don't know how to handle frame (type=" << hdr.GetType());
1783}
1784
1785void
1787{
1788 NS_LOG_FUNCTION(this << *mpdu);
1789 for (auto& msduPair : *PeekPointer(mpdu))
1790 {
1791 ForwardUp(msduPair.first,
1792 msduPair.second.GetSourceAddr(),
1793 msduPair.second.GetDestinationAddr());
1794 }
1795}
1796
1797std::optional<Mac48Address>
1798WifiMac::GetMldAddress(const Mac48Address& remoteAddr) const
1799{
1800 for (const auto& [id, link] : m_links)
1801 {
1802 if (auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
1803 {
1804 return *mldAddress;
1805 }
1806 }
1807 return std::nullopt;
1808}
1809
1812{
1813 for (const auto& [id, link] : m_links)
1814 {
1815 if (auto mldAddress = link->stationManager->GetMldAddress(remoteAddr))
1816 {
1817 // this is a link setup with remote MLD
1818 if (mldAddress != remoteAddr)
1819 {
1820 // the remote address is the address of a STA affiliated with the remote MLD
1821 return link->feManager->GetAddress();
1822 }
1823 // we have to return our MLD address
1824 return m_address;
1825 }
1826 }
1827 // we get here if no ML setup was established between this device and the remote device,
1828 // i.e., they are not both multi-link devices
1829 if (GetNLinks() == 1)
1830 {
1831 // this is a single link device
1832 return m_address;
1833 }
1834 // this is an MLD (hence the remote device is single link or unknown)
1835 return DoGetLocalAddress(remoteAddr);
1836}
1837
1839WifiMac::DoGetLocalAddress(const Mac48Address& remoteAddr [[maybe_unused]]) const
1840{
1841 return m_address;
1842}
1843
1846{
1847 // BA agreements are indexed by the MLD address if ML setup was performed
1848 recipient = GetMldAddress(recipient).value_or(recipient);
1849
1850 auto agreement = GetQosTxop(tid)->GetBaManager()->GetAgreementAsOriginator(recipient, tid);
1851 if (!agreement || !agreement->get().IsEstablished())
1852 {
1853 return std::nullopt;
1854 }
1855 return agreement;
1856}
1857
1860{
1861 // BA agreements are indexed by the MLD address if ML setup was performed
1862 originator = GetMldAddress(originator).value_or(originator);
1863 return GetQosTxop(tid)->GetBaManager()->GetAgreementAsRecipient(originator, tid);
1864}
1865
1867WifiMac::GetBaTypeAsOriginator(const Mac48Address& recipient, uint8_t tid) const
1868{
1869 auto agreement = GetBaAgreementEstablishedAsOriginator(recipient, tid);
1870 NS_ABORT_MSG_IF(!agreement,
1871 "No existing Block Ack agreement with " << recipient << " TID: " << +tid);
1872 return agreement->get().GetBlockAckType();
1873}
1874
1876WifiMac::GetBarTypeAsOriginator(const Mac48Address& recipient, uint8_t tid) const
1877{
1878 auto agreement = GetBaAgreementEstablishedAsOriginator(recipient, tid);
1879 NS_ABORT_MSG_IF(!agreement,
1880 "No existing Block Ack agreement with " << recipient << " TID: " << +tid);
1881 return agreement->get().GetBlockAckReqType();
1882}
1883
1885WifiMac::GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
1886{
1887 auto agreement = GetBaAgreementEstablishedAsRecipient(originator, tid);
1888 NS_ABORT_MSG_IF(!agreement,
1889 "No existing Block Ack agreement with " << originator << " TID: " << +tid);
1890 return agreement->get().GetBlockAckType();
1891}
1892
1894WifiMac::GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
1895{
1896 auto agreement = GetBaAgreementEstablishedAsRecipient(originator, tid);
1897 NS_ABORT_MSG_IF(!agreement,
1898 "No existing Block Ack agreement with " << originator << " TID: " << +tid);
1899 return agreement->get().GetBlockAckReqType();
1900}
1901
1904{
1905 return GetDevice()->GetHtConfiguration();
1906}
1907
1910{
1911 return GetDevice()->GetVhtConfiguration();
1912}
1913
1916{
1917 return GetDevice()->GetHeConfiguration();
1918}
1919
1922{
1923 return GetDevice()->GetEhtConfiguration();
1924}
1925
1926bool
1927WifiMac::GetHtSupported(uint8_t linkId) const
1928{
1929 return (GetDevice()->GetHtConfiguration() &&
1930 GetWifiPhy(linkId)->GetPhyBand() != WIFI_PHY_BAND_6GHZ);
1931}
1932
1933bool
1934WifiMac::GetVhtSupported(uint8_t linkId) const
1935{
1936 return (GetDevice()->GetVhtConfiguration() &&
1937 GetWifiPhy(linkId)->GetPhyBand() != WIFI_PHY_BAND_2_4GHZ &&
1938 GetWifiPhy(linkId)->GetPhyBand() != WIFI_PHY_BAND_6GHZ);
1939}
1940
1941bool
1943{
1944 return bool(GetDevice()->GetHeConfiguration());
1945}
1946
1947bool
1949{
1950 return bool(GetDevice()->GetEhtConfiguration());
1951}
1952
1953bool
1955{
1956 for (const auto& [id, link] : m_links)
1957 {
1958 if (link->stationManager->GetHtSupported(address))
1959 {
1960 return true;
1961 }
1962 }
1963 return false;
1964}
1965
1966bool
1968{
1969 for (const auto& [id, link] : m_links)
1970 {
1971 if (link->stationManager->GetVhtSupported(address))
1972 {
1973 return true;
1974 }
1975 }
1976 return false;
1977}
1978
1979bool
1981{
1982 for (const auto& [id, link] : m_links)
1983 {
1984 if (link->stationManager->GetHeSupported(address))
1985 {
1986 return true;
1987 }
1988 }
1989 return false;
1990}
1991
1992bool
1994{
1995 for (const auto& [id, link] : m_links)
1996 {
1997 if (link->stationManager->GetEhtSupported(address))
1998 {
1999 return true;
2000 }
2001 }
2002 return false;
2003}
2004
2005uint16_t
2006WifiMac::GetMaxBaBufferSize(std::optional<Mac48Address> address) const
2007{
2008 if (address ? GetEhtSupported(*address) : GetEhtSupported())
2009 {
2010 return 1024;
2011 }
2012 if (address ? GetHeSupported(*address) : GetHeSupported())
2013 {
2014 return 256;
2015 }
2016 NS_ASSERT(address ? GetHtSupported(*address) : static_cast<bool>(GetHtConfiguration()));
2017 return 64;
2018}
2019
2020void
2022{
2023 NS_LOG_FUNCTION(this << size);
2024
2025 // the cap can be computed if the device has been configured
2026 m_mpduBufferSize = m_device ? std::min(size, GetMaxBaBufferSize()) : size;
2027}
2028
2029uint16_t
2031{
2032 return m_mpduBufferSize;
2033}
2034
2035void
2037{
2038 NS_LOG_FUNCTION(this << +threshold);
2039 if (m_qosSupported)
2040 {
2041 GetVOQueue()->SetBlockAckThreshold(threshold);
2042 }
2043}
2044
2045void
2047{
2048 NS_LOG_FUNCTION(this << +threshold);
2049 if (m_qosSupported)
2050 {
2051 GetVIQueue()->SetBlockAckThreshold(threshold);
2052 }
2053}
2054
2055void
2057{
2058 NS_LOG_FUNCTION(this << +threshold);
2059 if (m_qosSupported)
2060 {
2061 GetBEQueue()->SetBlockAckThreshold(threshold);
2062 }
2063}
2064
2065void
2067{
2068 NS_LOG_FUNCTION(this << +threshold);
2069 if (m_qosSupported)
2070 {
2071 GetBKQueue()->SetBlockAckThreshold(threshold);
2072 }
2073}
2074
2075void
2084
2085void
2094
2095void
2104
2105void
2114
2117{
2118 NS_LOG_FUNCTION(this);
2119 ExtendedCapabilities capabilities;
2120 // TODO: to be completed
2121 return capabilities;
2122}
2123
2125WifiMac::GetHtCapabilities(uint8_t linkId) const
2126{
2127 NS_LOG_FUNCTION(this << +linkId);
2128 NS_ASSERT(GetHtSupported(linkId));
2129 HtCapabilities capabilities;
2130
2131 auto phy = GetWifiPhy(linkId);
2132 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
2133 bool sgiSupported = htConfiguration->GetShortGuardIntervalSupported();
2134 capabilities.SetLdpc(htConfiguration->GetLdpcSupported());
2135 capabilities.SetSupportedChannelWidth(htConfiguration->Get40MHzOperationSupported() ? 1 : 0);
2136 capabilities.SetShortGuardInterval20(sgiSupported);
2137 capabilities.SetShortGuardInterval40(sgiSupported);
2138 // Set Maximum A-MSDU Length subfield
2139 uint16_t maxAmsduSize =
2141 if (maxAmsduSize <= 3839)
2142 {
2143 capabilities.SetMaxAmsduLength(3839);
2144 }
2145 else
2146 {
2147 capabilities.SetMaxAmsduLength(7935);
2148 }
2149 uint32_t maxAmpduLength =
2151 // round to the next power of two minus one
2152 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2153 // The maximum A-MPDU length in HT capabilities elements ranges from 2^13-1 to 2^16-1
2154 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 65535U));
2155
2156 capabilities.SetLSigProtectionSupport(true);
2157 uint64_t maxSupportedRate = 0; // in bit/s
2158 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HT))
2159 {
2160 capabilities.SetRxMcsBitmask(mcs.GetMcsValue());
2161 uint8_t nss = (mcs.GetMcsValue() / 8) + 1;
2162 NS_ASSERT(nss > 0 && nss < 5);
2163 uint64_t dataRate = mcs.GetDataRate(htConfiguration->Get40MHzOperationSupported() ? 40 : 20,
2164 NanoSeconds(sgiSupported ? 400 : 800),
2165 nss);
2166 if (dataRate > maxSupportedRate)
2167 {
2168 maxSupportedRate = dataRate;
2169 NS_LOG_DEBUG("Updating maxSupportedRate to " << maxSupportedRate);
2170 }
2171 }
2172 capabilities.SetRxHighestSupportedDataRate(
2173 static_cast<uint16_t>(maxSupportedRate / 1e6)); // in Mbit/s
2174 capabilities.SetTxMcsSetDefined(phy->GetNMcs() > 0);
2175 capabilities.SetTxMaxNSpatialStreams(phy->GetMaxSupportedTxSpatialStreams());
2176 // we do not support unequal modulations
2177 capabilities.SetTxRxMcsSetUnequal(0);
2178 capabilities.SetTxUnequalModulation(0);
2179
2180 return capabilities;
2181}
2182
2184WifiMac::GetVhtCapabilities(uint8_t linkId) const
2185{
2186 NS_LOG_FUNCTION(this << +linkId);
2187 NS_ASSERT(GetVhtSupported(linkId));
2188 VhtCapabilities capabilities;
2189
2190 auto phy = GetWifiPhy(linkId);
2191 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
2192 NS_ABORT_MSG_IF(!htConfiguration->Get40MHzOperationSupported(),
2193 "VHT stations have to support 40 MHz operation");
2194 Ptr<VhtConfiguration> vhtConfiguration = GetVhtConfiguration();
2195 bool sgiSupported = htConfiguration->GetShortGuardIntervalSupported();
2196 capabilities.SetSupportedChannelWidthSet(vhtConfiguration->Get160MHzOperationSupported() ? 1
2197 : 0);
2198 // Set Maximum MPDU Length subfield
2199 uint16_t maxAmsduSize =
2201 if (maxAmsduSize <= 3839)
2202 {
2203 capabilities.SetMaxMpduLength(3895);
2204 }
2205 else if (maxAmsduSize <= 7935)
2206 {
2207 capabilities.SetMaxMpduLength(7991);
2208 }
2209 else
2210 {
2211 capabilities.SetMaxMpduLength(11454);
2212 }
2213 uint32_t maxAmpduLength =
2215 // round to the next power of two minus one
2216 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2217 // The maximum A-MPDU length in VHT capabilities elements ranges from 2^13-1 to 2^20-1
2218 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 1048575U));
2219
2220 capabilities.SetRxLdpc(htConfiguration->GetLdpcSupported());
2221 capabilities.SetShortGuardIntervalFor80Mhz(sgiSupported);
2222 capabilities.SetShortGuardIntervalFor160Mhz(sgiSupported);
2223 uint8_t maxMcs = 0;
2224 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
2225 {
2226 if (mcs.GetMcsValue() > maxMcs)
2227 {
2228 maxMcs = mcs.GetMcsValue();
2229 }
2230 }
2231 // Support same MaxMCS for each spatial stream
2232 for (uint8_t nss = 1; nss <= phy->GetMaxSupportedRxSpatialStreams(); nss++)
2233 {
2234 capabilities.SetRxMcsMap(maxMcs, nss);
2235 }
2236 for (uint8_t nss = 1; nss <= phy->GetMaxSupportedTxSpatialStreams(); nss++)
2237 {
2238 capabilities.SetTxMcsMap(maxMcs, nss);
2239 }
2240 uint64_t maxSupportedRateLGI = 0; // in bit/s
2241 MHz_u maxWidth = vhtConfiguration->Get160MHzOperationSupported() ? 160 : 80;
2242 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
2243 {
2244 if (!mcs.IsAllowed(maxWidth, 1))
2245 {
2246 continue;
2247 }
2248 if (mcs.GetDataRate(maxWidth) > maxSupportedRateLGI)
2249 {
2250 maxSupportedRateLGI = mcs.GetDataRate(maxWidth);
2251 NS_LOG_DEBUG("Updating maxSupportedRateLGI to " << maxSupportedRateLGI);
2252 }
2253 }
2255 static_cast<uint16_t>(maxSupportedRateLGI / 1e6)); // in Mbit/s
2257 static_cast<uint16_t>(maxSupportedRateLGI / 1e6)); // in Mbit/s
2258 // To be filled in once supported
2259 capabilities.SetRxStbc(0);
2260 capabilities.SetTxStbc(0);
2261
2262 return capabilities;
2263}
2264
2266WifiMac::GetHeCapabilities(uint8_t linkId) const
2267{
2268 NS_LOG_FUNCTION(this << +linkId);
2270 HeCapabilities capabilities;
2271
2272 Ptr<WifiPhy> phy = GetLink(linkId).phy;
2273 Ptr<HtConfiguration> htConfiguration = GetHtConfiguration();
2274 Ptr<VhtConfiguration> vhtConfiguration = GetVhtConfiguration();
2275 Ptr<HeConfiguration> heConfiguration = GetHeConfiguration();
2276 uint8_t channelWidthSet = 0;
2277 if ((htConfiguration->Get40MHzOperationSupported()) &&
2278 (phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ))
2279 {
2280 channelWidthSet |= 0x01;
2281 }
2282 // we assume that HE stations support 80 MHz operations
2283 if ((phy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ))
2284 {
2285 channelWidthSet |= 0x02;
2286 }
2287 if ((vhtConfiguration->Get160MHzOperationSupported()) &&
2288 ((phy->GetPhyBand() == WIFI_PHY_BAND_5GHZ) || (phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ)))
2289 {
2290 channelWidthSet |= 0x04;
2291 }
2292 capabilities.SetChannelWidthSet(channelWidthSet);
2293 capabilities.SetLdpcCodingInPayload(htConfiguration->GetLdpcSupported());
2294 if (heConfiguration->GetGuardInterval().GetNanoSeconds() == 800)
2295 {
2296 // todo: We assume for now that if we support 800ns GI then 1600ns GI is supported as well
2297 // todo: Assuming reception support for both 1x HE LTF and 4x HE LTF 800 ns
2298 capabilities.SetHeSuPpdu1xHeLtf800nsGi(true);
2299 capabilities.SetHePpdu4xHeLtf800nsGi(true);
2300 }
2301
2302 uint32_t maxAmpduLength =
2304 // round to the next power of two minus one
2305 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2306 // The maximum A-MPDU length in HE capabilities elements ranges from 2^20-1 to 2^23-1
2307 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 1048575U), 8388607U));
2308
2309 uint8_t maxMcs = 0;
2310 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HE))
2311 {
2312 if (mcs.GetMcsValue() > maxMcs)
2313 {
2314 maxMcs = mcs.GetMcsValue();
2315 }
2316 }
2317 capabilities.SetHighestMcsSupported(maxMcs);
2318 capabilities.SetHighestNssSupported(phy->GetMaxSupportedTxSpatialStreams());
2319
2320 return capabilities;
2321}
2322
2325{
2326 auto phy = GetLink(linkId).phy;
2327 NS_ASSERT_MSG(phy->GetPhyBand() == WIFI_PHY_BAND_6GHZ,
2328 "Getting HE 6 GHz band capabilities on band different than 6 GHz");
2329
2330 He6GhzBandCapabilities capabilities;
2331
2332 // Set Maximum MPDU Length subfield
2333 const auto maxAmsduSize =
2335 if (maxAmsduSize <= 3839)
2336 {
2337 capabilities.SetMaxMpduLength(3895);
2338 }
2339 else if (maxAmsduSize <= 7935)
2340 {
2341 capabilities.SetMaxMpduLength(7991);
2342 }
2343 else
2344 {
2345 capabilities.SetMaxMpduLength(11454);
2346 }
2347
2348 auto maxAmpduLength =
2350 // round to the next power of two minus one
2351 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2352 // The maximum A-MPDU length in HE 6 GHz Band Capabilities elements ranges from 2^13-1 to 2^20-1
2353 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8191U), 1048575U));
2354
2355 return capabilities;
2356}
2357
2359WifiMac::GetEhtCapabilities(uint8_t linkId) const
2360{
2361 NS_LOG_FUNCTION(this << +linkId);
2363 EhtCapabilities capabilities;
2364
2365 Ptr<WifiPhy> phy = GetLink(linkId).phy;
2366
2367 // Set Maximum MPDU Length subfield (Reserved when transmitted in 5 GHz or 6 GHz band)
2368 if (phy->GetPhyBand() == WIFI_PHY_BAND_2_4GHZ)
2369 {
2370 uint16_t maxAmsduSize =
2372 // Table 9-34—Maximum data unit sizes (in octets) and durations (in microseconds)
2373 if (maxAmsduSize <= 3839)
2374 {
2375 capabilities.SetMaxMpduLength(3895);
2376 }
2377 else if (maxAmsduSize <= 7935)
2378 {
2379 capabilities.SetMaxMpduLength(7991);
2380 }
2381 else
2382 {
2383 capabilities.SetMaxMpduLength(11454);
2384 }
2385 }
2386
2387 // Set Maximum A-MPDU Length Exponent Extension subfield
2388 uint32_t maxAmpduLength =
2390 // round to the next power of two minus one
2391 maxAmpduLength = (1UL << static_cast<uint32_t>(std::ceil(std::log2(maxAmpduLength + 1)))) - 1;
2392 // The maximum A-MPDU length in EHT capabilities elements ranges from 2^23-1 to 2^24-1
2393 capabilities.SetMaxAmpduLength(std::min(std::max(maxAmpduLength, 8388607U), 16777215U));
2394
2395 // Set the PHY capabilities
2396 const bool support4096Qam = phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, 12);
2398 support4096Qam ? 1 : 0;
2400 support4096Qam ? 1 : 0;
2401
2402 const uint8_t maxTxNss = phy->GetMaxSupportedTxSpatialStreams();
2403 const uint8_t maxRxNss = phy->GetMaxSupportedRxSpatialStreams();
2404 if (auto htConfig = GetHtConfiguration(); !htConfig->Get40MHzOperationSupported())
2405 {
2406 for (auto maxMcs : {7, 9, 11, 13})
2407 {
2408 capabilities.SetSupportedRxEhtMcsAndNss(
2410 maxMcs,
2411 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2412 capabilities.SetSupportedTxEhtMcsAndNss(
2414 maxMcs,
2415 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2416 }
2417 }
2418 else
2419 {
2420 for (auto maxMcs : {9, 11, 13})
2421 {
2422 capabilities.SetSupportedRxEhtMcsAndNss(
2424 maxMcs,
2425 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2426 capabilities.SetSupportedTxEhtMcsAndNss(
2428 maxMcs,
2429 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2430 }
2431 }
2432 if (auto vhtConfig = GetVhtConfiguration(); vhtConfig->Get160MHzOperationSupported())
2433 {
2434 for (auto maxMcs : {9, 11, 13})
2435 {
2436 capabilities.SetSupportedRxEhtMcsAndNss(
2438 maxMcs,
2439 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxRxNss : 0);
2440 capabilities.SetSupportedTxEhtMcsAndNss(
2442 maxMcs,
2443 phy->IsMcsSupported(WIFI_MOD_CLASS_EHT, maxMcs) ? maxTxNss : 0);
2444 }
2445 }
2446 // 320 MHz not supported yet
2447
2448 return capabilities;
2449}
2450
2453{
2454 uint32_t maxSize = 0;
2455 switch (ac)
2456 {
2457 case AC_BE:
2458 maxSize = m_beMaxAmpduSize;
2459 break;
2460 case AC_BK:
2461 maxSize = m_bkMaxAmpduSize;
2462 break;
2463 case AC_VI:
2464 maxSize = m_viMaxAmpduSize;
2465 break;
2466 case AC_VO:
2467 maxSize = m_voMaxAmpduSize;
2468 break;
2469 default:
2470 NS_ABORT_MSG("Unknown AC " << ac);
2471 return 0;
2472 }
2473 return maxSize;
2474}
2475
2476uint16_t
2478{
2479 uint16_t maxSize = 0;
2480 switch (ac)
2481 {
2482 case AC_BE:
2483 maxSize = m_beMaxAmsduSize;
2484 break;
2485 case AC_BK:
2486 maxSize = m_bkMaxAmsduSize;
2487 break;
2488 case AC_VI:
2489 maxSize = m_viMaxAmsduSize;
2490 break;
2491 case AC_VO:
2492 maxSize = m_voMaxAmsduSize;
2493 break;
2494 default:
2495 NS_ABORT_MSG("Unknown AC " << ac);
2496 return 0;
2497 }
2498 return maxSize;
2499}
2500
2501} // namespace ns3
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.
The HE 6 GHz Band Capabilities (IEEE 802.11ax-2021 9.4.2.263)
void SetMaxAmpduLength(uint32_t maxAmpduLength)
Set the maximum AMPDU length.
void SetMaxMpduLength(uint16_t length)
Set the maximum MPDU length.
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.
an EUI-48 address
static Mac48Address ConvertFrom(const Address &address)
A base class which provides memory management and object aggregation.
Definition object.h:78
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition object.cc:203
void Dispose()
Dispose of this Object.
Definition object.cc:247
bool IsInitialized() const
Check if the object has been initialized.
Definition object.cc:240
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
Ptr< BlockAckManager > GetBaManager()
Get the Block Ack Manager associated with this QosTxop.
Definition qos-txop.cc:278
void SetBlockAckThreshold(uint8_t threshold)
Set threshold for block ack mechanism.
Definition qos-txop.cc:708
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:325
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
indicates whether the socket has a priority set.
Definition socket.h:1307
uint8_t GetPriority() const
Get the tag's priority.
Definition socket.cc:849
The IEEE 802.11 SSID Information Element.
Definition ssid.h:25
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
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:682
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the Txop has frames to transmit over the given link.
Definition txop.cc:603
virtual void SetWifiMac(const Ptr< WifiMac > mac)
Set the wifi MAC this Txop is associated to.
Definition txop.cc:242
void SwapLinks(std::map< uint8_t, uint8_t > links)
Swap the links based on the information included in the given map.
Definition txop.cc:218
void SetTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set MacTxMiddle this Txop is associated to.
Definition txop.cc:235
virtual void SetDroppedMpduCallback(DroppedMpdu callback)
Definition txop.cc:253
static constexpr bool CHECK_MEDIUM_BUSY
generation of backoff (also) depends on the busy/idle state of the medium
Definition txop.h:392
a unique identifier for an interface.
Definition type-id.h:48
@ ATTR_GET
The attribute can be read.
Definition type-id.h:53
@ ATTR_CONSTRUCT
The attribute can be written at construction-time.
Definition type-id.h:55
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
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.
Implements the IEEE 802.11 MAC header.
void SetQosAckPolicy(QosAckPolicy policy)
Set the QoS Ack policy in the QoS control field.
void SetNoOrder()
Unset order bit in the frame control field.
void SetQosNoAmsdu()
Set that A-MSDU is not present.
virtual void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
void SetQosNoEosp()
Un-set the end of service period (EOSP) bit in the QoS control field.
virtual void DoCompleteConfig()=0
Allow subclasses to complete the configuration of the MAC layer components.
uint16_t GetMaxAmsduSize(AcIndex ac) const
Return the maximum A-MSDU size of the given Access Category.
Definition wifi-mac.cc:2477
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:996
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
Definition wifi-mac.cc:637
virtual void NotifyChannelSwitching(uint8_t linkId)
Notify that channel on the given link has been switched.
Definition wifi-mac.cc:686
std::optional< Mac48Address > GetMldAddress(const Mac48Address &remoteAddr) const
Definition wifi-mac.cc:1798
virtual void SetMacQueueScheduler(Ptr< WifiMacQueueScheduler > scheduler)
Set the wifi MAC queue scheduler.
Definition wifi-mac.cc:673
Mac48Address GetBssid(uint8_t linkId) const
Definition wifi-mac.cc:532
uint16_t m_viMaxAmsduSize
maximum A-MSDU size for AC_VI (in bytes)
Definition wifi-mac.h:1194
bool m_shortSlotTimeSupported
flag whether short slot time is supported
Definition wifi-mac.h:1172
void ConfigurePhyDependentParameters(uint8_t linkId)
Configure PHY dependent parameters such as CWmin and CWmax on the given link.
Definition wifi-mac.cc:920
Ptr< HeConfiguration > GetHeConfiguration() const
Definition wifi-mac.cc:1915
DroppedMpduTracedCallback m_droppedMpduCallback
This trace indicates that an MPDU was dropped for the given reason.
Definition wifi-mac.h:1266
TypeOfStation GetTypeOfStation() const
Return the type of station.
Definition wifi-mac.cc:476
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:1170
void SetBkQueue(Ptr< QosTxop > edca)
Set the AC_BK channel access function This method is private so that it is only used while constructi...
Definition wifi-mac.cc:593
const std::map< uint8_t, std::unique_ptr< LinkEntity > > & GetLinks() const
Definition wifi-mac.cc:1072
Ptr< Txop > GetTxop() const
Accessor for the Txop object.
Definition wifi-mac.cc:557
VhtCapabilities GetVhtCapabilities(uint8_t linkId) const
Return the VHT capabilities of the device for the given link.
Definition wifi-mac.cc:2184
Callback< void > m_linkDown
Callback when a link is down.
Definition wifi-mac.h:942
bool GetQosSupported() const
Return whether the device supports QoS.
Definition wifi-mac.cc:1380
virtual void SetAddress(Mac48Address address)
Definition wifi-mac.cc:499
void SetFrameExchangeManagers(const std::vector< Ptr< FrameExchangeManager > > &feManagers)
Definition wifi-mac.cc:954
bool CreateLinksIfNeeded(std::size_t nLinks)
If no link has been already created, create the given number links; otherwise, do nothing.
Definition wifi-mac.cc:938
Ptr< Txop > m_txop
TXOP used for transmission of frames to non-QoS peers.
Definition wifi-mac.h:938
void SetQosSupported(bool enable)
Enable or disable QoS support for the device.
Definition wifi-mac.cc:1372
Mac48Address m_address
MAC address of this station.
Definition wifi-mac.h:1181
std::set< uint8_t > m_linkIds
IDs of the links in use.
Definition wifi-mac.h:1179
Ptr< WifiMacQueueScheduler > GetMacQueueScheduler() const
Get the wifi MAC queue scheduler.
Definition wifi-mac.cc:680
uint16_t GetMpduBufferSize() const
Definition wifi-mac.cc:2030
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition wifi-mac.cc:1087
BlockAckType GetBaTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Definition wifi-mac.cc:1885
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:1149
void Enqueue(Ptr< Packet > packet, Mac48Address to)
Definition wifi-mac.cc:1673
uint16_t m_voMaxAmsduSize
maximum A-MSDU size for AC_VO (in bytes)
Definition wifi-mac.h:1193
Ptr< MacRxMiddle > m_rxMiddle
RX middle (defragmentation etc.)
Definition wifi-mac.h:936
Ptr< WifiMacQueueScheduler > m_scheduler
wifi MAC queue scheduler
Definition wifi-mac.h:939
void DoInitialize() override
Initialize() implementation.
Definition wifi-mac.cc:403
TypeOfStation m_typeOfStation
the type of station
Definition wifi-mac.h:1175
uint16_t m_mpduBufferSize
BlockAck buffer size (in number of MPDUs)
Definition wifi-mac.h:1203
uint32_t m_beMaxAmpduSize
maximum A-MPDU size for AC_BE (in bytes)
Definition wifi-mac.h:1200
void SetChannelAccessManagers(const std::vector< Ptr< ChannelAccessManager > > &caManagers)
Definition wifi-mac.cc:1002
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:1296
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:1591
Ssid GetSsid() const
Definition wifi-mac.cc:519
void SetWifiRemoteStationManagers(const std::vector< Ptr< WifiRemoteStationManager > > &stationManagers)
Definition wifi-mac.cc:1037
void SetBeBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BE.
Definition wifi-mac.cc:2056
bool GetErpSupported(uint8_t linkId) const
Return whether the device supports ERP on the given link.
Definition wifi-mac.cc:1386
void ResetWifiPhys()
Remove currently attached WifiPhy objects from this MAC.
Definition wifi-mac.cc:1354
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:1220
void SetErpSupported(bool enable, uint8_t linkId)
Enable or disable ERP support for the given link.
Definition wifi-mac.cc:1392
bool GetTxBlockedOnLink(AcIndex ac, const WifiContainerQueueId &queueId, uint8_t linkId, WifiQueueBlockedReason reason=WifiQueueBlockedReason::REASONS_COUNT) const
Check whether the transmission of the packets in the given container queue of the given Access Catego...
Definition wifi-mac.cc:1654
uint32_t m_voMaxAmpduSize
maximum A-MPDU size for AC_VO (in bytes)
Definition wifi-mac.h:1198
void ConfigureDcf(Ptr< Txop > dcf, uint32_t cwmin, uint32_t cwmax, std::list< bool > isDsss, AcIndex ac)
Definition wifi-mac.cc:780
Ptr< WifiNetDevice > m_device
Pointer to the device.
Definition wifi-mac.h:1177
void SetSsid(Ssid ssid)
Definition wifi-mac.cc:512
virtual void NotifyDropPacketToEnqueue(Ptr< Packet > packet, Mac48Address to)
Allow subclasses to take actions when a packet to enqueue has been dropped.
Definition wifi-mac.cc:1743
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:1099
IcfDropTracedCallback m_icfDropCallback
traced callback for ICF drop events
Definition wifi-mac.h:1350
Ptr< QosTxop > GetVOQueue() const
Accessor for the AC_VO channel access function.
Definition wifi-mac.cc:625
void SetTypeOfStation(TypeOfStation type)
This method is invoked by a subclass to specify what type of station it is implementing.
Definition wifi-mac.cc:469
MpduTracedCallback m_ackedMpduCallback
ack'ed MPDU callback
Definition wifi-mac.h:1271
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Definition wifi-mac.cc:1348
void SetMpduBufferSize(uint16_t size)
Definition wifi-mac.cc:2021
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:1545
MpduTracedCallback m_nackedMpduCallback
nack'ed MPDU callback
Definition wifi-mac.h:1272
bool GetEhtSupported() const
Return whether the device supports EHT.
Definition wifi-mac.cc:1948
void SetTxop(Ptr< Txop > dcf)
Set the Txop object.
Definition wifi-mac.cc:547
bool GetHeSupported() const
Return whether the device supports HE.
Definition wifi-mac.cc:1942
HtCapabilities GetHtCapabilities(uint8_t linkId) const
Return the HT capabilities of the device for the given link.
Definition wifi-mac.cc:2125
void SetBkBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_BK.
Definition wifi-mac.cc:2066
void SetVoBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VO.
Definition wifi-mac.cc:2036
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:1115
std::optional< std::reference_wrapper< const RecipientBlockAckAgreement > > RecipientAgreementOptConstRef
optional const reference to RecipientBlockAckAgreement
Definition wifi-mac.h:670
void NotifyPromiscRx(Ptr< const Packet > packet)
Definition wifi-mac.cc:717
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:1208
void SetVoQueue(Ptr< QosTxop > edca)
Set the AC_VO channel access function This method is private so that it is only used while constructi...
Definition wifi-mac.cc:563
virtual bool HasFramesToTransmit(uint8_t linkId)
Check if the MAC has frames to transmit over the given link.
Definition wifi-mac.cc:656
void SetWifiRemoteStationManager(Ptr< WifiRemoteStationManager > stationManager)
Definition wifi-mac.cc:1030
UniformRandomBitGenerator m_shuffleLinkIdsGen
random number generator to shuffle link IDs
Definition wifi-mac.h:1205
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:1463
void CompleteConfig()
Complete the configuration of the MAC layer components.
Definition wifi-mac.cc:869
RecipientAgreementOptConstRef GetBaAgreementEstablishedAsRecipient(Mac48Address originator, uint8_t tid) const
Definition wifi-mac.cc:1859
void SetBeBlockAckInactivityTimeout(uint16_t timeout)
Set BE block ack inactivity timeout.
Definition wifi-mac.cc:2096
Ptr< EhtConfiguration > GetEhtConfiguration() const
Definition wifi-mac.cc:1921
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:1243
bool GetVhtSupported(uint8_t linkId) const
Return whether the device supports VHT on the given link.
Definition wifi-mac.cc:1934
void SetDsssSupported(bool enable, uint8_t linkId)
Enable or disable DSSS support for the given link.
Definition wifi-mac.cc:1403
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:1227
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition wifi-mac.h:937
void NotifyTx(Ptr< const Packet > packet)
Definition wifi-mac.cc:699
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:374
static TypeId GetTypeId()
Get the type ID.
Definition wifi-mac.cc:63
Ptr< HtConfiguration > GetHtConfiguration() const
Definition wifi-mac.cc:1903
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:1280
uint32_t GetMaxAmpduSize(AcIndex ac) const
Return the maximum A-MPDU size of the given Access Category.
Definition wifi-mac.cc:2452
BlockAckReqType GetBarTypeAsRecipient(Mac48Address originator, uint8_t tid) const
Definition wifi-mac.cc:1894
Ssid m_ssid
Service Set ID (SSID)
Definition wifi-mac.h:1182
std::map< uint8_t, std::unique_ptr< LinkEntity > > m_links
ID-indexed map of Link objects.
Definition wifi-mac.h:1178
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:1786
Ptr< QosTxop > GetVIQueue() const
Accessor for the AC_VI channel access function.
Definition wifi-mac.cc:631
void SetBssid(Mac48Address bssid, uint8_t linkId)
Definition wifi-mac.cc:525
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition wifi-mac.cc:493
void NotifyRx(Ptr< const Packet > packet)
Definition wifi-mac.cc:711
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:1250
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:1246
BlockAckType GetBaTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
Definition wifi-mac.cc:1867
MpduResponseTimeoutTracedCallback m_mpduResponseTimeoutCallback
MPDU response timeout traced callback.
Definition wifi-mac.h:1293
void SetForwardUpCallback(ForwardUpCallback upCallback)
Definition wifi-mac.cc:1442
PsduMapResponseTimeoutTracedCallback m_psduMapResponseTimeoutCallback
PSDU map response timeout traced callback.
Definition wifi-mac.h:1337
ExtendedCapabilities GetExtendedCapabilities() const
Return the extended capabilities of the device.
Definition wifi-mac.cc:2116
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:1235
uint16_t m_bkMaxAmsduSize
maximum A-MSDU size for AC_BK (in bytes)
Definition wifi-mac.h:1196
void SetBkBlockAckInactivityTimeout(uint16_t timeout)
Set BK block ack inactivity timeout.
Definition wifi-mac.cc:2106
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:1210
virtual bool SupportsSendFrom() const
Definition wifi-mac.cc:1436
He6GhzBandCapabilities GetHe6GhzBandCapabilities(uint8_t linkId) const
Return the HE 6GHz band capabilities of the device for the given 6 GHz link.
Definition wifi-mac.cc:2324
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:2006
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:649
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:1128
void SetViBlockAckThreshold(uint8_t threshold)
Set the block ack threshold for AC_VI.
Definition wifi-mac.cc:2046
void SetViBlockAckInactivityTimeout(uint16_t timeout)
Set VI block ack inactivity timeout.
Definition wifi-mac.cc:2086
bool GetShortSlotTimeSupported() const
Definition wifi-mac.cc:1430
BlockAckReqType GetBarTypeAsOriginator(const Mac48Address &recipient, uint8_t tid) const
Definition wifi-mac.cc:1876
void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
Definition wifi-mac.cc:386
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:740
void SetLinkDownCallback(Callback< void > linkDown)
Definition wifi-mac.cc:1456
Ptr< QosTxop > GetBKQueue() const
Accessor for the AC_BK channel access function.
Definition wifi-mac.cc:643
~WifiMac() override
Definition wifi-mac.cc:57
void SetPromisc()
Sets the interface in promiscuous mode.
Definition wifi-mac.cc:538
Ptr< VhtConfiguration > GetVhtConfiguration() const
Definition wifi-mac.cc:1909
void NotifyRxDrop(Ptr< const Packet > packet)
Definition wifi-mac.cc:723
virtual void SetLinkUpCallback(Callback< void > linkUp)
Definition wifi-mac.cc:1449
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition wifi-mac.cc:1060
const std::set< uint8_t > & GetLinkIds() const
Definition wifi-mac.cc:1093
void SetDevice(const Ptr< WifiNetDevice > device)
Sets the device this PHY is associated with.
Definition wifi-mac.cc:482
void SetCtsToSelfSupported(bool enable)
Enable or disable CTS-to-self feature.
Definition wifi-mac.cc:1416
Mac48Address GetLocalAddress(const Mac48Address &remoteAddr) const
Get the local MAC address used to communicate with a remote STA.
Definition wifi-mac.cc:1811
EdcaQueues m_edca
This is a map from Access Category index to the corresponding channel access function.
Definition wifi-mac.h:1191
uint32_t m_bkMaxAmpduSize
maximum A-MPDU size for AC_BK (in bytes)
Definition wifi-mac.h:1201
bool GetHtSupported(uint8_t linkId) const
Return whether the device supports HT on the given link.
Definition wifi-mac.cc:1927
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
Definition wifi-mac.cc:1749
virtual void ConfigureContentionWindow(uint32_t cwMin, uint32_t cwMax)
Definition wifi-mac.cc:757
bool Is6GhzBand(uint8_t linkId) const
Indicate if a given link is on the 6 GHz band.
Definition wifi-mac.cc:1238
OriginatorAgreementOptConstRef GetBaAgreementEstablishedAsOriginator(Mac48Address recipient, uint8_t tid) const
Definition wifi-mac.cc:1845
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:1756
std::optional< std::reference_wrapper< const OriginatorBlockAckAgreement > > OriginatorAgreementOptConstRef
optional const reference to OriginatorBlockAckAgreement
Definition wifi-mac.h:667
Mac48Address GetAddress() const
Definition wifi-mac.cc:506
ForwardUpCallback m_forwardUp
Callback to forward packet up the stack.
Definition wifi-mac.h:1212
EhtCapabilities GetEhtCapabilities(uint8_t linkId) const
Return the EHT capabilities of the device for the given link.
Definition wifi-mac.cc:2359
Callback< void > m_linkUp
Callback when a link is up.
Definition wifi-mac.h:941
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition wifi-mac.cc:1078
void SetupDcfQueue()
This method is a private utility invoked to configure the channel access function for devices that do...
Definition wifi-mac.cc:729
void SetBeQueue(Ptr< QosTxop > edca)
Set the AC_BE channel access function This method is private so that it is only used while constructi...
Definition wifi-mac.cc:583
HeCapabilities GetHeCapabilities(uint8_t linkId) const
Return the HE capabilities of the device for the given link.
Definition wifi-mac.cc:2266
virtual bool CanForwardPacketsTo(Mac48Address to) const =0
Return true if packets can be forwarded to the given destination, false otherwise.
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy > > &phys)
Definition wifi-mac.cc:1326
PsduResponseTimeoutTracedCallback m_psduResponseTimeoutCallback
PSDU response timeout traced callback.
Definition wifi-mac.h:1314
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition wifi-mac.cc:603
void NotifyTxDrop(Ptr< const Packet > packet)
Definition wifi-mac.cc:705
void DoDispose() override
Destructor implementation.
Definition wifi-mac.cc:427
bool GetDsssSupported(uint8_t linkId) const
Return whether the device supports DSSS on the given link.
Definition wifi-mac.cc:1410
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:1024
void SetVoBlockAckInactivityTimeout(uint16_t timeout)
Set VO block ack inactivity timeout.
Definition wifi-mac.cc:2076
virtual std::unique_ptr< LinkEntity > CreateLinkEntity() const
Create a LinkEntity object.
Definition wifi-mac.cc:1066
void SetViQueue(Ptr< QosTxop > edca)
Set the AC_VI channel access function This method is private so that it is only used while constructi...
Definition wifi-mac.cc:573
void SetShortSlotTimeSupported(bool enable)
Enable or disable short slot time feature.
Definition wifi-mac.cc:1423
bool m_ctsToSelfSupported
flag indicating whether CTS-To-Self is supported
Definition wifi-mac.h:1173
uint16_t m_beMaxAmsduSize
maximum A-MSDU size for AC_BE (in bytes)
Definition wifi-mac.h:1195
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:1839
uint32_t m_viMaxAmpduSize
maximum A-MPDU size for AC_VI (in bytes)
Definition wifi-mac.h:1199
WifiStandard GetStandard() const
Get the configured Wi-Fi standard.
Definition wifi-phy.cc:1069
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_ABORT_UNLESS(cond)
Abnormal program termination if a condition is false.
Definition abort.h:118
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time NanoSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
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:57
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:123
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:62
@ WIFI_STANDARD_80211g
@ WIFI_STANDARD_80211b
@ WIFI_PHY_BAND_6GHZ
The 6 GHz band.
@ WIFI_PHY_BAND_2_4GHZ
The 2.4 GHz band.
@ WIFI_PHY_BAND_5GHZ
The 5 GHz band.
@ 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:72
@ AC_BE
Best Effort.
Definition qos-utils.h:64
@ AC_VO
Voice.
Definition qos-utils.h:70
@ AC_VI
Video.
Definition qos-utils.h:68
@ AC_BK
Background.
Definition qos-utils.h:66
@ AC_UNDEF
Total number of ACs.
Definition qos-utils.h:76
@ AC_BEACON
Beacon queue.
Definition qos-utils.h:74
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeChecker > MakeSsidChecker()
Definition ssid.cc:102
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
std:: tuple< WifiContainerQueueType, WifiReceiverAddressType, Mac48Address, std::optional< uint8_t > > WifiContainerQueueId
Tuple (queue type, receiver address type, Address, TID) identifying a container queue.
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:684
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeAccessor > MakeSsidAccessor(T1 a1)
Definition ssid.h:85
Ptr< const AttributeChecker > MakeObjectVectorChecker()
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
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:65
void Shuffle(RND_ACCESS_ITER first, RND_ACCESS_ITER last, Ptr< UniformRandomVariable > rv)
Shuffle the elements in the range first to last.
Definition shuffle.h:48
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:115
@ WIFI_MAC_DATA
@ WIFI_MAC_QOSDATA
WifiDirection
Wifi direction.
Definition wifi-utils.h:34
@ LOG_FUNCTION
Function tracing for non-trivial function calls.
Definition log.h:95
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:587
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
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