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