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