A Discrete-Event Network Simulator
API
ap-wifi-mac.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006, 2009 INRIA
3 * Copyright (c) 2009 MIRKO BANCHI
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 * Mirko Banchi <mk.banchi@gmail.com>
20 */
21
22#include "ap-wifi-mac.h"
23
27#include "mac-rx-middle.h"
28#include "mac-tx-middle.h"
29#include "mgt-headers.h"
30#include "msdu-aggregator.h"
31#include "qos-txop.h"
33#include "wifi-mac-queue.h"
34#include "wifi-net-device.h"
35#include "wifi-phy.h"
36
37#include "ns3/he-configuration.h"
38#include "ns3/ht-configuration.h"
39#include "ns3/log.h"
40#include "ns3/multi-link-element.h"
41#include "ns3/packet.h"
42#include "ns3/pointer.h"
43#include "ns3/random-variable-stream.h"
44#include "ns3/simulator.h"
45#include "ns3/string.h"
46
47namespace ns3
48{
49
50NS_LOG_COMPONENT_DEFINE("ApWifiMac");
51
53
54TypeId
56{
57 static TypeId tid =
58 TypeId("ns3::ApWifiMac")
60 .SetGroupName("Wifi")
61 .AddConstructor<ApWifiMac>()
62 .AddAttribute(
63 "BeaconInterval",
64 "Delay between two beacons",
65 TimeValue(MicroSeconds(102400)),
68 .AddAttribute("BeaconJitter",
69 "A uniform random variable to cause the initial beacon starting time "
70 "(after simulation time 0) "
71 "to be distributed between 0 and the BeaconInterval.",
72 StringValue("ns3::UniformRandomVariable"),
74 MakePointerChecker<UniformRandomVariable>())
75 .AddAttribute("EnableBeaconJitter",
76 "If beacons are enabled, whether to jitter the initial send event.",
77 BooleanValue(true),
80 .AddAttribute("BeaconGeneration",
81 "Whether or not beacons are generated.",
82 BooleanValue(true),
85 .AddAttribute("EnableNonErpProtection",
86 "Whether or not protection mechanism should be used when non-ERP STAs "
87 "are present within the BSS."
88 "This parameter is only used when ERP is supported by the AP.",
89 BooleanValue(true),
92 .AddAttribute("BsrLifetime",
93 "Lifetime of Buffer Status Reports received from stations.",
97 .AddTraceSource("AssociatedSta",
98 "A station associated with this access point.",
100 "ns3::ApWifiMac::AssociationCallback")
101 .AddTraceSource("DeAssociatedSta",
102 "A station lost association with this access point.",
104 "ns3::ApWifiMac::AssociationCallback");
105 return tid;
106}
107
109 : m_enableBeaconGeneration(false)
110{
111 NS_LOG_FUNCTION(this);
112 m_beaconTxop = CreateObject<Txop>(CreateObject<WifiMacQueue>(AC_BEACON));
114
115 // Let the lower layers know that we are acting as an AP.
117}
118
120{
121 NS_LOG_FUNCTION(this);
122}
123
124void
126{
127 NS_LOG_FUNCTION(this);
129 m_beaconTxop = nullptr;
132}
133
135{
138}
139
140std::unique_ptr<WifiMac::LinkEntity>
142{
143 return std::make_unique<ApLinkEntity>();
144}
145
147ApWifiMac::GetLink(uint8_t linkId) const
148{
149 return static_cast<ApLinkEntity&>(WifiMac::GetLink(linkId));
150}
151
152void
154{
155 NS_LOG_FUNCTION(this << standard);
158 m_beaconTxop->SetAifsns(std::vector<uint8_t>(GetNLinks(), 1));
159 m_beaconTxop->SetMinCws(std::vector<uint32_t>(GetNLinks(), 0));
160 m_beaconTxop->SetMaxCws(std::vector<uint32_t>(GetNLinks(), 0));
161 for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
162 {
164 }
165}
166
169{
170 if (ac == AC_BEACON)
171 {
173 }
174 return WifiMac::GetTxopQueue(ac);
175}
176
177void
179{
180 NS_LOG_FUNCTION(this << enable);
181 for (uint8_t linkId = 0; linkId < GetNLinks(); ++linkId)
182 {
183 if (!enable)
184 {
185 GetLink(linkId).beaconEvent.Cancel();
186 }
187 else if (!m_enableBeaconGeneration)
188 {
189 GetLink(linkId).beaconEvent =
191 }
192 }
194}
195
196Time
198{
199 NS_LOG_FUNCTION(this);
200 return m_beaconInterval;
201}
202
203void
205{
206 NS_LOG_FUNCTION(this << &linkUp);
208
209 // The approach taken here is that, from the point of view of an AP,
210 // the link is always up, so we immediately invoke the callback if
211 // one is set
212 linkUp();
213}
214
215void
217{
218 NS_LOG_FUNCTION(this << interval);
219 if ((interval.GetMicroSeconds() % 1024) != 0)
220 {
221 NS_FATAL_ERROR("beacon interval should be multiple of 1024us (802.11 time unit), see IEEE "
222 "Std. 802.11-2012");
223 }
224 if (interval.GetMicroSeconds() > (1024 * 65535))
225 {
227 "beacon interval should be smaller then or equal to 65535 * 1024us (802.11 time unit)");
228 }
229 m_beaconInterval = interval;
230}
231
232int64_t
234{
235 NS_LOG_FUNCTION(this << stream);
236 m_beaconJitter->SetStream(stream);
237 return 1;
238}
239
240void
242{
243 NS_LOG_FUNCTION(this << +linkId);
244 auto& link = GetLink(linkId);
245 if (GetErpSupported(linkId) && GetShortSlotTimeSupported() && (link.numNonErpStations == 0))
246 {
247 for (const auto& sta : link.staList)
248 {
250 {
251 link.shortSlotTimeEnabled = false;
252 return;
253 }
254 }
255 link.shortSlotTimeEnabled = true;
256 }
257 else
258 {
259 link.shortSlotTimeEnabled = false;
260 }
261}
262
263void
265{
266 NS_LOG_FUNCTION(this << +linkId);
267 auto& link = GetLink(linkId);
268 if (GetErpSupported(linkId) && GetWifiPhy(linkId)->GetShortPhyPreambleSupported())
269 {
270 for (const auto& sta : link.staList)
271 {
272 if (!GetWifiRemoteStationManager(linkId)->GetErpOfdmSupported(sta.second) ||
273 !GetWifiRemoteStationManager(linkId)->GetShortPreambleSupported(sta.second))
274 {
275 link.shortPreambleEnabled = false;
276 return;
277 }
278 }
279 link.shortPreambleEnabled = true;
280 }
281 else
282 {
283 link.shortPreambleEnabled = false;
284 }
285}
286
287void
289{
290 NS_LOG_FUNCTION(this << packet << from << to);
291 // If we are not a QoS AP then we definitely want to use AC_BE to
292 // transmit the packet. A TID of zero will map to AC_BE (through \c
293 // QosUtilsMapTidToAc()), so we use that as our default here.
294 uint8_t tid = 0;
295
296 // If we are a QoS AP then we attempt to get a TID for this packet
297 if (GetQosSupported())
298 {
299 tid = QosUtilsGetTidForPacket(packet);
300 // Any value greater than 7 is invalid and likely indicates that
301 // the packet had no QoS tag, so we revert to zero, which'll
302 // mean that AC_BE is used.
303 if (tid > 7)
304 {
305 tid = 0;
306 }
307 }
308
309 ForwardDown(packet, from, to, tid);
310}
311
312void
314{
315 NS_LOG_FUNCTION(this << packet << from << to << +tid);
316 WifiMacHeader hdr;
317
318 // For now, an AP that supports QoS does not support non-QoS
319 // associations, and vice versa. In future the AP model should
320 // support simultaneously associated QoS and non-QoS STAs, at which
321 // point there will need to be per-association QoS state maintained
322 // by the association state machine, and consulted here.
323 if (GetQosSupported())
324 {
327 hdr.SetQosNoEosp();
328 hdr.SetQosNoAmsdu();
329 // Transmission of multiple frames in the same Polled TXOP is not supported for now
330 hdr.SetQosTxopLimit(0);
331 // Fill in the QoS control field in the MAC header
332 hdr.SetQosTid(tid);
333 }
334 else
335 {
337 }
338
339 if (GetQosSupported())
340 {
341 hdr.SetNoOrder(); // explicitly set to 0 for the time being since HT control field is not
342 // yet implemented (set it to 1 when implemented)
343 }
344 hdr.SetAddr1(to);
345 hdr.SetAddr2(GetAddress());
346 hdr.SetAddr3(from);
347 hdr.SetDsFrom();
348 hdr.SetDsNotTo();
349
350 if (GetQosSupported())
351 {
352 // Sanity check that the TID is valid
353 NS_ASSERT(tid < 8);
354 GetQosTxop(tid)->Queue(packet, hdr);
355 }
356 else
357 {
358 GetTxop()->Queue(packet, hdr);
359 }
360}
361
362bool
364{
365 return (to.IsGroup() || GetWifiRemoteStationManager()->IsAssociated(to));
366}
367
368void
370{
371 NS_LOG_FUNCTION(this << packet << to << from);
372 if (CanForwardPacketsTo(to))
373 {
374 ForwardDown(packet, from, to);
375 }
376 else
377 {
378 NotifyTxDrop(packet);
379 }
380}
381
382void
384{
385 NS_LOG_FUNCTION(this << packet << to);
386 // We're sending this packet with a from address that is our own. We
387 // get that address from the lower MAC and make use of the
388 // from-spoofing Enqueue() method to avoid duplicated code.
389 Enqueue(packet, to, GetAddress());
390}
391
392bool
394{
395 NS_LOG_FUNCTION(this);
396 return true;
397}
398
400ApWifiMac::GetSupportedRates(uint8_t linkId) const
401{
402 NS_LOG_FUNCTION(this << +linkId);
403 SupportedRates rates;
404 // Send the set of supported rates and make sure that we indicate
405 // the Basic Rate set in this set of supported rates.
406 for (const auto& mode : GetWifiPhy(linkId)->GetModeList())
407 {
408 uint64_t modeDataRate = mode.GetDataRate(GetWifiPhy(linkId)->GetChannelWidth());
409 NS_LOG_DEBUG("Adding supported rate of " << modeDataRate);
410 rates.AddSupportedRate(modeDataRate);
411 // Add rates that are part of the BSSBasicRateSet (manufacturer dependent!)
412 // here we choose to add the mandatory rates to the BSSBasicRateSet,
413 // except for 802.11b where we assume that only the non HR-DSSS rates are part of the
414 // BSSBasicRateSet
415 if (mode.IsMandatory() && (mode.GetModulationClass() != WIFI_MOD_CLASS_HR_DSSS))
416 {
417 NS_LOG_DEBUG("Adding basic mode " << mode.GetUniqueName());
419 }
420 }
421 // set the basic rates
422 for (uint8_t j = 0; j < GetWifiRemoteStationManager(linkId)->GetNBasicModes(); j++)
423 {
425 uint64_t modeDataRate = mode.GetDataRate(GetWifiPhy(linkId)->GetChannelWidth());
426 NS_LOG_DEBUG("Setting basic rate " << mode.GetUniqueName());
427 rates.SetBasicRate(modeDataRate);
428 }
429 // If it is a HT AP, then add the BSSMembershipSelectorSet
430 // The standard says that the BSSMembershipSelectorSet
431 // must have its MSB set to 1 (must be treated as a Basic Rate)
432 // Also the standard mentioned that at least 1 element should be included in the SupportedRates
433 // the rest can be in the ExtendedSupportedRates
434 if (GetHtSupported())
435 {
436 for (const auto& selector : GetWifiPhy(linkId)->GetBssMembershipSelectorList())
437 {
438 rates.AddBssMembershipSelectorRate(selector);
439 }
440 }
441 return rates;
442}
443
446{
447 NS_LOG_FUNCTION(this << +linkId);
449 DsssParameterSet dsssParameters;
450 dsssParameters.SetCurrentChannel(GetWifiPhy(linkId)->GetChannelNumber());
451 return dsssParameters;
452}
453
455ApWifiMac::GetCapabilities(uint8_t linkId) const
456{
457 NS_LOG_FUNCTION(this << +linkId);
458 CapabilityInformation capabilities;
459 capabilities.SetShortPreamble(GetLink(linkId).shortPreambleEnabled);
460 capabilities.SetShortSlotTime(GetLink(linkId).shortSlotTimeEnabled);
461 capabilities.SetEss();
462 return capabilities;
463}
464
466ApWifiMac::GetErpInformation(uint8_t linkId) const
467{
468 NS_LOG_FUNCTION(this << +linkId);
469 NS_ASSERT(GetErpSupported(linkId));
470 ErpInformation information;
471
472 information.SetNonErpPresent(GetLink(linkId).numNonErpStations > 0);
473 information.SetUseProtection(GetUseNonErpProtection(linkId));
474 if (GetLink(linkId).shortPreambleEnabled)
475 {
476 information.SetBarkerPreambleMode(0);
477 }
478 else
479 {
480 information.SetBarkerPreambleMode(1);
481 }
482
483 return information;
484}
485
488{
489 NS_LOG_FUNCTION(this << +linkId);
491 EdcaParameterSet edcaParameters;
492
493 Ptr<QosTxop> edca;
494 Time txopLimit;
495
496 edca = GetQosTxop(AC_BE);
497 txopLimit = edca->GetTxopLimit(linkId);
498 edcaParameters.SetBeAci(0);
499 edcaParameters.SetBeCWmin(edca->GetMinCw(linkId));
500 edcaParameters.SetBeCWmax(edca->GetMaxCw(linkId));
501 edcaParameters.SetBeAifsn(edca->GetAifsn(linkId));
502 edcaParameters.SetBeTxopLimit(static_cast<uint16_t>(txopLimit.GetMicroSeconds() / 32));
503
504 edca = GetQosTxop(AC_BK);
505 txopLimit = edca->GetTxopLimit(linkId);
506 edcaParameters.SetBkAci(1);
507 edcaParameters.SetBkCWmin(edca->GetMinCw(linkId));
508 edcaParameters.SetBkCWmax(edca->GetMaxCw(linkId));
509 edcaParameters.SetBkAifsn(edca->GetAifsn(linkId));
510 edcaParameters.SetBkTxopLimit(static_cast<uint16_t>(txopLimit.GetMicroSeconds() / 32));
511
512 edca = GetQosTxop(AC_VI);
513 txopLimit = edca->GetTxopLimit(linkId);
514 edcaParameters.SetViAci(2);
515 edcaParameters.SetViCWmin(edca->GetMinCw(linkId));
516 edcaParameters.SetViCWmax(edca->GetMaxCw(linkId));
517 edcaParameters.SetViAifsn(edca->GetAifsn(linkId));
518 edcaParameters.SetViTxopLimit(static_cast<uint16_t>(txopLimit.GetMicroSeconds() / 32));
519
520 edca = GetQosTxop(AC_VO);
521 txopLimit = edca->GetTxopLimit(linkId);
522 edcaParameters.SetVoAci(3);
523 edcaParameters.SetVoCWmin(edca->GetMinCw(linkId));
524 edcaParameters.SetVoCWmax(edca->GetMaxCw(linkId));
525 edcaParameters.SetVoAifsn(edca->GetAifsn(linkId));
526 edcaParameters.SetVoTxopLimit(static_cast<uint16_t>(txopLimit.GetMicroSeconds() / 32));
527
528 edcaParameters.SetQosInfo(0);
529
530 return edcaParameters;
531}
532
533std::optional<MuEdcaParameterSet>
535{
536 NS_LOG_FUNCTION(this);
538
539 Ptr<HeConfiguration> heConfiguration = GetHeConfiguration();
540 NS_ASSERT(heConfiguration);
541
542 MuEdcaParameterSet muEdcaParameters;
543 muEdcaParameters.SetQosInfo(0);
544
545 UintegerValue uintegerValue;
546 TimeValue timeValue;
547
548 heConfiguration->GetAttribute("MuBeAifsn", uintegerValue);
549 muEdcaParameters.SetMuAifsn(AC_BE, uintegerValue.Get());
550 heConfiguration->GetAttribute("MuBeCwMin", uintegerValue);
551 muEdcaParameters.SetMuCwMin(AC_BE, uintegerValue.Get());
552 heConfiguration->GetAttribute("MuBeCwMax", uintegerValue);
553 muEdcaParameters.SetMuCwMax(AC_BE, uintegerValue.Get());
554 heConfiguration->GetAttribute("BeMuEdcaTimer", timeValue);
555 muEdcaParameters.SetMuEdcaTimer(AC_BE, timeValue.Get());
556
557 heConfiguration->GetAttribute("MuBkAifsn", uintegerValue);
558 muEdcaParameters.SetMuAifsn(AC_BK, uintegerValue.Get());
559 heConfiguration->GetAttribute("MuBkCwMin", uintegerValue);
560 muEdcaParameters.SetMuCwMin(AC_BK, uintegerValue.Get());
561 heConfiguration->GetAttribute("MuBkCwMax", uintegerValue);
562 muEdcaParameters.SetMuCwMax(AC_BK, uintegerValue.Get());
563 heConfiguration->GetAttribute("BkMuEdcaTimer", timeValue);
564 muEdcaParameters.SetMuEdcaTimer(AC_BK, timeValue.Get());
565
566 heConfiguration->GetAttribute("MuViAifsn", uintegerValue);
567 muEdcaParameters.SetMuAifsn(AC_VI, uintegerValue.Get());
568 heConfiguration->GetAttribute("MuViCwMin", uintegerValue);
569 muEdcaParameters.SetMuCwMin(AC_VI, uintegerValue.Get());
570 heConfiguration->GetAttribute("MuViCwMax", uintegerValue);
571 muEdcaParameters.SetMuCwMax(AC_VI, uintegerValue.Get());
572 heConfiguration->GetAttribute("ViMuEdcaTimer", timeValue);
573 muEdcaParameters.SetMuEdcaTimer(AC_VI, timeValue.Get());
574
575 heConfiguration->GetAttribute("MuVoAifsn", uintegerValue);
576 muEdcaParameters.SetMuAifsn(AC_VO, uintegerValue.Get());
577 heConfiguration->GetAttribute("MuVoCwMin", uintegerValue);
578 muEdcaParameters.SetMuCwMin(AC_VO, uintegerValue.Get());
579 heConfiguration->GetAttribute("MuVoCwMax", uintegerValue);
580 muEdcaParameters.SetMuCwMax(AC_VO, uintegerValue.Get());
581 heConfiguration->GetAttribute("VoMuEdcaTimer", timeValue);
582 muEdcaParameters.SetMuEdcaTimer(AC_VO, timeValue.Get());
583
584 // The timers of the MU EDCA Parameter Set must be either all zero or all
585 // non-zero. The information element is advertised if all timers are non-zero
586 auto timerNotNull = [&muEdcaParameters](uint8_t aci) {
587 return !muEdcaParameters.GetMuEdcaTimer(aci).IsZero();
588 };
589 auto aci = {0, 1, 2, 3};
590 if (std::all_of(aci.begin(), aci.end(), timerNotNull))
591 {
592 return muEdcaParameters;
593 }
594
595 NS_ABORT_MSG_UNLESS(std::none_of(aci.begin(), aci.end(), timerNotNull),
596 "MU EDCA Timers must be all zero if the IE is not advertised.");
597
598 return std::nullopt;
599}
600
601std::optional<ReducedNeighborReport>
603{
604 NS_LOG_FUNCTION(this << +linkId);
605
606 if (GetNLinks() <= 1)
607 {
608 return std::nullopt;
609 }
610
613
614 for (uint8_t index = 0; index < GetNLinks(); ++index)
615 {
616 if (index != linkId) // all links but the one used to send this Beacon frame
617 {
618 rnr.AddNbrApInfoField();
619 std::size_t nbrId = rnr.GetNNbrApInfoFields() - 1;
621 rnr.AddTbttInformationField(nbrId);
622 rnr.SetBssid(nbrId, 0, GetLink(index).feManager->GetAddress());
623 rnr.SetShortSsid(nbrId, 0, 0);
624 rnr.SetBssParameters(nbrId, 0, 0);
625 rnr.SetPsd20MHz(nbrId, 0, 0);
626 rnr.SetMldParameters(nbrId, 0, 0, index, 0);
627 }
628 }
629 return rnr;
630}
631
633ApWifiMac::GetMultiLinkElement(uint8_t linkId, WifiMacType frameType, const Mac48Address& to)
634{
635 NS_LOG_FUNCTION(this << +linkId << frameType << to);
636 NS_ABORT_IF(GetNLinks() == 1);
637
640 mle.SetLinkIdInfo(linkId);
642
643 // if the Multi-Link Element is being inserted in a (Re)Association Response frame
644 // and the remote station is affiliated with an MLD, try multi-link setup
645 if (auto staMldAddress = GetWifiRemoteStationManager(linkId)->GetMldAddress(to);
646 (frameType == WIFI_MAC_MGT_ASSOCIATION_RESPONSE ||
648 staMldAddress.has_value())
649 {
650 for (uint8_t i = 0; i < GetNLinks(); i++)
651 {
652 auto remoteStationManager = GetWifiRemoteStationManager(i);
653 if (auto staAddress = remoteStationManager->GetAffiliatedStaAddress(*staMldAddress);
654 i != linkId && staAddress.has_value() &&
655 (remoteStationManager->IsWaitAssocTxOk(*staAddress) ||
656 remoteStationManager->IsAssocRefused(*staAddress)))
657 {
658 // For each requested link in addition to the link on which the
659 // (Re)Association Response frame is transmitted, the Link Info field
660 // of the Basic Multi-Link element carried in the (Re)Association
661 // Response frame shall contain the corresponding Per-STA Profile
662 // subelement(s) (Sec. 35.3.5.4 of 802.11be D2.0)
664 auto& perStaProfile = mle.GetPerStaProfile(mle.GetNPerStaProfileSubelements() - 1);
665 // The Link ID subfield of the STA Control field of the Per-STA Profile
666 // subelement for the AP corresponding to a link is set to the link ID
667 // of the AP affiliated with the AP MLD that is operating on that link.
668 perStaProfile.SetLinkId(i);
669 perStaProfile.SetCompleteProfile();
670 // For each Per-STA Profile subelement included in the Link Info field,
671 // the Complete Profile subfield of the STA Control field shall be set to 1
672 perStaProfile.SetStaMacAddress(GetFrameExchangeManager(i)->GetAddress());
673 perStaProfile.SetAssocResponse(GetAssocResp(*staAddress, i));
674 }
675 }
676 }
677
678 return mle;
679}
680
682ApWifiMac::GetHtOperation(uint8_t linkId) const
683{
684 NS_LOG_FUNCTION(this << +linkId);
686 HtOperation operation;
687 auto phy = GetWifiPhy(linkId);
688 auto remoteStationManager = GetWifiRemoteStationManager(linkId);
689
690 operation.SetPrimaryChannel(phy->GetPrimaryChannelNumber(20));
691 operation.SetRifsMode(false);
692 operation.SetNonGfHtStasPresent(true);
693 if (phy->GetChannelWidth() > 20)
694 {
695 operation.SetSecondaryChannelOffset(1);
696 operation.SetStaChannelWidth(1);
697 }
698 if (GetLink(linkId).numNonHtStations == 0)
699 {
701 }
702 else
703 {
705 }
706 uint64_t maxSupportedRate = 0; // in bit/s
707 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HT))
708 {
709 uint8_t nss = (mcs.GetMcsValue() / 8) + 1;
710 NS_ASSERT(nss > 0 && nss < 5);
711 uint64_t dataRate =
712 mcs.GetDataRate(phy->GetChannelWidth(),
713 GetHtConfiguration()->GetShortGuardIntervalSupported() ? 400 : 800,
714 nss);
715 if (dataRate > maxSupportedRate)
716 {
717 maxSupportedRate = dataRate;
718 NS_LOG_DEBUG("Updating maxSupportedRate to " << maxSupportedRate);
719 }
720 }
721 uint8_t maxSpatialStream = phy->GetMaxSupportedTxSpatialStreams();
722 auto mcsList = phy->GetMcsList(WIFI_MOD_CLASS_HT);
723 uint8_t nMcs = mcsList.size();
724 for (const auto& sta : GetLink(linkId).staList)
725 {
726 if (remoteStationManager->GetHtSupported(sta.second))
727 {
728 uint64_t maxSupportedRateByHtSta = 0; // in bit/s
729 auto itMcs = mcsList.begin();
730 for (uint8_t j = 0;
731 j < (std::min(nMcs, remoteStationManager->GetNMcsSupported(sta.second)));
732 j++)
733 {
734 WifiMode mcs = *itMcs++;
735 uint8_t nss = (mcs.GetMcsValue() / 8) + 1;
736 NS_ASSERT(nss > 0 && nss < 5);
737 uint64_t dataRate = mcs.GetDataRate(
738 remoteStationManager->GetChannelWidthSupported(sta.second),
739 remoteStationManager->GetShortGuardIntervalSupported(sta.second) ? 400 : 800,
740 nss);
741 if (dataRate > maxSupportedRateByHtSta)
742 {
743 maxSupportedRateByHtSta = dataRate;
744 }
745 }
746 if (maxSupportedRateByHtSta < maxSupportedRate)
747 {
748 maxSupportedRate = maxSupportedRateByHtSta;
749 }
750 if (remoteStationManager->GetNMcsSupported(sta.second) < nMcs)
751 {
752 nMcs = remoteStationManager->GetNMcsSupported(sta.second);
753 }
754 if (remoteStationManager->GetNumberOfSupportedStreams(sta.second) < maxSpatialStream)
755 {
756 maxSpatialStream = remoteStationManager->GetNumberOfSupportedStreams(sta.second);
757 }
758 }
759 }
761 static_cast<uint16_t>(maxSupportedRate / 1e6)); // in Mbit/s
762 operation.SetTxMcsSetDefined(nMcs > 0);
763 operation.SetTxMaxNSpatialStreams(maxSpatialStream);
764 // To be filled in once supported
765 operation.SetObssNonHtStasPresent(0);
766 operation.SetDualBeacon(0);
767 operation.SetDualCtsProtection(0);
768 operation.SetStbcBeacon(0);
770 operation.SetPcoActive(0);
771 operation.SetPhase(0);
772 operation.SetRxMcsBitmask(0);
773 operation.SetTxRxMcsSetUnequal(0);
774 operation.SetTxUnequalModulation(0);
775
776 return operation;
777}
778
780ApWifiMac::GetVhtOperation(uint8_t linkId) const
781{
782 NS_LOG_FUNCTION(this << +linkId);
783 NS_ASSERT(GetVhtSupported(linkId));
784 VhtOperation operation;
785 auto phy = GetWifiPhy(linkId);
786 auto remoteStationManager = GetWifiRemoteStationManager(linkId);
787
788 const uint16_t bssBandwidth = phy->GetChannelWidth();
789 // Set to 0 for 20 MHz or 40 MHz BSS bandwidth.
790 // Set to 1 for 80 MHz, 160 MHz or 80+80 MHz BSS bandwidth.
791 operation.SetChannelWidth((bssBandwidth > 40) ? 1 : 0);
792 // For 20, 40, or 80 MHz BSS bandwidth, indicates the channel center frequency
793 // index for the 20, 40, or 80 MHz channel on which the VHT BSS operates.
794 // For 160 MHz BSS bandwidth and the Channel Width subfield equal to 1,
795 // indicates the channel center frequency index of the 80 MHz channel
796 // segment that contains the primary channel.
798 (bssBandwidth == 160)
799 ? phy->GetOperatingChannel().GetPrimaryChannelNumber(80, WIFI_STANDARD_80211ac)
800 : phy->GetChannelNumber());
801 // For a 20, 40, or 80 MHz BSS bandwidth, this subfield is set to 0.
802 // For a 160 MHz BSS bandwidth and the Channel Width subfield equal to 1,
803 // indicates the channel center frequency index of the 160 MHz channel on
804 // which the VHT BSS operates.
805 operation.SetChannelCenterFrequencySegment1((bssBandwidth == 160) ? phy->GetChannelNumber()
806 : 0);
807 uint8_t maxSpatialStream = phy->GetMaxSupportedRxSpatialStreams();
808 for (const auto& sta : GetLink(linkId).staList)
809 {
810 if (remoteStationManager->GetVhtSupported(sta.second))
811 {
812 if (remoteStationManager->GetNumberOfSupportedStreams(sta.second) < maxSpatialStream)
813 {
814 maxSpatialStream = remoteStationManager->GetNumberOfSupportedStreams(sta.second);
815 }
816 }
817 }
818 for (uint8_t nss = 1; nss <= maxSpatialStream; nss++)
819 {
820 uint8_t maxMcs =
821 9; // TBD: hardcode to 9 for now since we assume all MCS values are supported
822 operation.SetMaxVhtMcsPerNss(nss, maxMcs);
823 }
824
825 return operation;
826}
827
829ApWifiMac::GetHeOperation(uint8_t linkId) const
830{
831 NS_LOG_FUNCTION(this << +linkId);
833 HeOperation operation;
834 auto remoteStationManager = GetWifiRemoteStationManager(linkId);
835
836 uint8_t maxSpatialStream = GetWifiPhy(linkId)->GetMaxSupportedRxSpatialStreams();
837 for (const auto& sta : GetLink(linkId).staList)
838 {
839 if (remoteStationManager->GetHeSupported(sta.second))
840 {
841 if (remoteStationManager->GetNumberOfSupportedStreams(sta.second) < maxSpatialStream)
842 {
843 maxSpatialStream = remoteStationManager->GetNumberOfSupportedStreams(sta.second);
844 }
845 }
846 }
847 for (uint8_t nss = 1; nss <= maxSpatialStream; nss++)
848 {
849 operation.SetMaxHeMcsPerNss(
850 nss,
851 11); // TBD: hardcode to 11 for now since we assume all MCS values are supported
852 }
853 operation.SetBssColor(GetHeConfiguration()->GetBssColor());
854
855 return operation;
856}
857
858void
860{
861 NS_LOG_FUNCTION(this << to << +linkId);
862 WifiMacHeader hdr;
864 hdr.SetAddr1(to);
865 hdr.SetAddr2(GetLink(linkId).feManager->GetAddress());
866 hdr.SetAddr3(GetLink(linkId).feManager->GetAddress());
867 hdr.SetDsNotFrom();
868 hdr.SetDsNotTo();
869 Ptr<Packet> packet = Create<Packet>();
871 probe.SetSsid(GetSsid());
873 probe.SetBeaconIntervalUs(GetBeaconInterval().GetMicroSeconds());
874 probe.SetCapabilities(GetCapabilities(linkId));
876 GetLink(linkId).shortPreambleEnabled);
878 GetLink(linkId).shortSlotTimeEnabled);
879 if (GetDsssSupported(linkId))
880 {
882 }
883 if (GetErpSupported(linkId))
884 {
886 }
887 if (GetQosSupported())
888 {
890 }
891 if (GetHtSupported())
892 {
895 probe.SetHtOperation(GetHtOperation(linkId));
896 }
898 {
900 probe.SetVhtOperation(GetVhtOperation(linkId));
901 }
902 if (GetHeSupported())
903 {
905 probe.SetHeOperation(GetHeOperation(linkId));
906 if (auto muEdcaParameterSet = GetMuEdcaParameterSet(); muEdcaParameterSet.has_value())
907 {
908 probe.SetMuEdcaParameterSet(std::move(*muEdcaParameterSet));
909 }
910 }
911 if (GetEhtSupported())
912 {
914
915 if (GetNLinks() > 1)
916 {
917 /*
918 * If an AP is affiliated with an AP MLD and does not correspond to a nontransmitted
919 * BSSID, then the Beacon and Probe Response frames transmitted by the AP shall
920 * include a TBTT Information field in a Reduced Neighbor Report element with the
921 * TBTT Information Length field set to 16 or higher, for each of the other APs
922 * (if any) affiliated with the same AP MLD. (Sec. 35.3.4.1 of 802.11be D2.1.1)
923 */
924 if (auto rnr = GetReducedNeighborReport(linkId); rnr.has_value())
925 {
926 probe.SetReducedNeighborReport(std::move(*rnr));
927 }
928 /*
929 * If an AP affiliated with an AP MLD is not in a multiple BSSID set [..], the AP
930 * shall include, in a Beacon frame or a Probe Response frame, which is not a
931 * Multi-Link probe response, only the Common Info field of the Basic Multi-Link
932 * element for the AP MLD unless conditions in 35.3.11 (Multi-link procedures for
933 * channel switching, extended channel switching, and channel quieting) are
934 * satisfied. (Sec. 35.3.4.4 of 802.11be D2.1.1)
935 */
937 }
938 }
939 packet->AddHeader(probe);
940
941 if (!GetQosSupported())
942 {
943 GetTxop()->Queue(packet, hdr);
944 }
945 // "A QoS STA that transmits a Management frame determines access category used
946 // for medium access in transmission of the Management frame as follows
947 // (If dot11QMFActivated is false or not present)
948 // — If the Management frame is individually addressed to a non-QoS STA, category
949 // AC_BE should be selected.
950 // — If category AC_BE was not selected by the previous step, category AC_VO
951 // shall be selected." (Sec. 10.2.3.2 of 802.11-2020)
952 else if (!GetWifiRemoteStationManager(linkId)->GetQosSupported(to))
953 {
954 GetBEQueue()->Queue(packet, hdr);
955 }
956 else
957 {
958 GetVOQueue()->Queue(packet, hdr);
959 }
960}
961
964{
966 StatusCode code;
967 auto remoteStationManager = GetWifiRemoteStationManager(linkId);
968 if (remoteStationManager->IsWaitAssocTxOk(to))
969 {
970 code.SetSuccess();
971 }
972 else
973 {
974 NS_ABORT_IF(!remoteStationManager->IsAssocRefused(to));
975 // reset state
976 remoteStationManager->RecordDisassociated(to);
977 code.SetFailure();
978 }
980 assoc.SetStatusCode(code);
981 assoc.SetCapabilities(GetCapabilities(linkId));
982 if (GetErpSupported(linkId))
983 {
985 }
986 if (GetQosSupported())
987 {
989 }
990 if (GetHtSupported())
991 {
994 assoc.SetHtOperation(GetHtOperation(linkId));
995 }
996 if (GetVhtSupported(linkId))
997 {
999 assoc.SetVhtOperation(GetVhtOperation(linkId));
1000 }
1001 if (GetHeSupported())
1002 {
1003 assoc.SetHeCapabilities(GetHeCapabilities(linkId));
1004 assoc.SetHeOperation(GetHeOperation(linkId));
1005 if (auto muEdcaParameterSet = GetMuEdcaParameterSet(); muEdcaParameterSet.has_value())
1006 {
1007 assoc.SetMuEdcaParameterSet(std::move(*muEdcaParameterSet));
1008 }
1009 }
1010 if (GetEhtSupported())
1011 {
1013 }
1014 return assoc;
1015}
1016
1017void
1019{
1020 NS_LOG_FUNCTION(this << to << +linkId);
1021
1022 // find all the links to setup (i.e., those for which status code is success)
1023 std::list<std::reference_wrapper<MgtAssocResponseHeader>> assocResponses;
1024 std::map<uint8_t /* link ID */, Mac48Address> linkIdStaAddrMap;
1025
1026 if (assoc.GetStatusCode().IsSuccess())
1027 {
1028 assocResponses.push_back(std::ref(assoc));
1029 linkIdStaAddrMap[linkId] = to;
1030 }
1031
1032 const auto& mle = assoc.GetMultiLinkElement();
1033 if (mle.has_value())
1034 {
1035 const auto staMldAddress = GetWifiRemoteStationManager(linkId)->GetMldAddress(to);
1036 NS_ABORT_MSG_IF(!staMldAddress.has_value(),
1037 "Sending a Multi-Link Element to a single link device");
1038 for (std::size_t idx = 0; idx < mle->GetNPerStaProfileSubelements(); idx++)
1039 {
1040 auto& perStaProfile = mle->GetPerStaProfile(idx);
1041 if (perStaProfile.HasAssocResponse() &&
1042 perStaProfile.GetAssocResponse().GetStatusCode().IsSuccess())
1043 {
1044 assocResponses.emplace_back(perStaProfile.GetAssocResponse());
1045 uint8_t otherLinkId = perStaProfile.GetLinkId();
1046 auto staAddress = GetWifiRemoteStationManager(otherLinkId)
1047 ->GetAffiliatedStaAddress(*staMldAddress);
1048 NS_ABORT_MSG_IF(!staAddress.has_value(),
1049 "No STA to associate with on link " << +otherLinkId);
1050 const auto [it, inserted] = linkIdStaAddrMap.insert({otherLinkId, *staAddress});
1051 NS_ABORT_MSG_IF(!inserted,
1052 "More than one Association Response to MLD "
1053 << *staMldAddress << " on link ID " << +otherLinkId);
1054 }
1055 }
1056 }
1057
1058 if (assocResponses.empty())
1059 {
1060 // no link to setup, nothing to do
1061 return;
1062 }
1063
1064 // check if AIDs are already allocated to the STAs that are associating
1065 std::set<uint16_t> aids;
1066 std::map<uint8_t /* link ID */, uint16_t /* AID */> linkIdAidMap;
1067
1068 for (const auto& [id, staAddr] : linkIdStaAddrMap)
1069 {
1070 for (const auto& [aid, addr] : GetLink(id).staList)
1071 {
1072 if (addr == staAddr)
1073 {
1074 aids.insert(aid);
1075 linkIdAidMap[id] = aid;
1076 break;
1077 }
1078 }
1079 }
1080
1081 // check if an AID already assigned to an STA can be assigned to all other STAs
1082 // affiliated with the non-AP MLD we are associating with
1083 while (!aids.empty())
1084 {
1085 const uint16_t aid = *aids.begin();
1086 bool good = true;
1087
1088 for (const auto& [id, staAddr] : linkIdStaAddrMap)
1089 {
1090 if (auto it = GetLink(id).staList.find(aid);
1091 it != GetLink(id).staList.end() && it->second != staAddr)
1092 {
1093 // the AID is already assigned to an STA other than the one affiliated
1094 // with the non-AP MLD we are associating with
1095 aids.erase(aids.begin());
1096 good = false;
1097 break;
1098 }
1099 }
1100
1101 if (good)
1102 {
1103 break;
1104 }
1105 }
1106
1107 uint16_t aid = 0;
1108
1109 if (!aids.empty())
1110 {
1111 // one of the AIDs already assigned to an STA can be assigned to all the other
1112 // STAs affiliated with the non-AP MLD we are associating with
1113 aid = *aids.begin();
1114 }
1115 else
1116 {
1117 std::list<uint8_t> linkIds;
1118 std::transform(linkIdStaAddrMap.cbegin(),
1119 linkIdStaAddrMap.cend(),
1120 std::back_inserter(linkIds),
1121 [](auto&& linkIdStaAddrPair) { return linkIdStaAddrPair.first; });
1122 aid = GetNextAssociationId(linkIds);
1123 }
1124
1125 for (const auto& [id, staAddr] : linkIdStaAddrMap)
1126 {
1127 auto remoteStationManager = GetWifiRemoteStationManager(id);
1128 auto& link = GetLink(id);
1129
1130 if (auto it = linkIdAidMap.find(id); it == linkIdAidMap.end() || it->second != aid)
1131 {
1132 // the STA on this link has no AID assigned or has a different AID assigned
1133 link.staList.insert(std::make_pair(aid, staAddr));
1134 m_assocLogger(aid, staAddr);
1135 remoteStationManager->SetAssociationId(staAddr, aid);
1136
1137 if (it == linkIdAidMap.end())
1138 {
1139 // the STA on this link had no AID assigned
1140 if (remoteStationManager->GetDsssSupported(staAddr) &&
1141 !remoteStationManager->GetErpOfdmSupported(staAddr))
1142 {
1143 link.numNonErpStations++;
1144 }
1145 if (!remoteStationManager->GetHtSupported(staAddr))
1146 {
1147 link.numNonHtStations++;
1148 }
1151 }
1152 else
1153 {
1154 // the STA on this link had a different AID assigned
1155 link.staList.erase(it->second); // free the previous AID
1156 }
1157 }
1158 }
1159
1160 // set the AID in all the Association Responses. NOTE that the Association
1161 // Responses included in the Per-STA Profile Subelements of the Multi-Link
1162 // Element must not contain the AID field. We set the AID field in such
1163 // Association Responses anyway, in order to ease future implementation of
1164 // the inheritance mechanism.
1165 for (auto& assocResp : assocResponses)
1166 {
1167 assocResp.get().SetAssociationId(aid);
1168 }
1169}
1170
1171void
1172ApWifiMac::SendAssocResp(Mac48Address to, bool isReassoc, uint8_t linkId)
1173{
1174 NS_LOG_FUNCTION(this << to << isReassoc << +linkId);
1175 WifiMacHeader hdr;
1178 hdr.SetAddr1(to);
1181 hdr.SetDsNotFrom();
1182 hdr.SetDsNotTo();
1183
1184 MgtAssocResponseHeader assoc = GetAssocResp(to, linkId);
1185
1186 // The AP that is affiliated with the AP MLD and that responds to an (Re)Association
1187 // Request frame that carries a Basic Multi-Link element shall include a Basic
1188 // Multi-Link element in the (Re)Association Response frame that it transmits
1189 // (Sec. 35.3.5.4 of 802.11be D2.0)
1190 // If the STA included a Multi-Link Element in the (Re)Association Request, we
1191 // stored its MLD address in the remote station manager
1192 if (GetNLinks() > 1 && GetWifiRemoteStationManager(linkId)->GetMldAddress(to).has_value())
1193 {
1194 assoc.SetMultiLinkElement(GetMultiLinkElement(linkId, hdr.GetType(), to));
1195 }
1196
1197 SetAid(assoc, to, linkId);
1198
1199 Ptr<Packet> packet = Create<Packet>();
1200 packet->AddHeader(assoc);
1201
1202 if (!GetQosSupported())
1203 {
1204 GetTxop()->Queue(packet, hdr);
1205 }
1206 // "A QoS STA that transmits a Management frame determines access category used
1207 // for medium access in transmission of the Management frame as follows
1208 // (If dot11QMFActivated is false or not present)
1209 // — If the Management frame is individually addressed to a non-QoS STA, category
1210 // AC_BE should be selected.
1211 // — If category AC_BE was not selected by the previous step, category AC_VO
1212 // shall be selected." (Sec. 10.2.3.2 of 802.11-2020)
1213 else if (!GetWifiRemoteStationManager(linkId)->GetQosSupported(to))
1214 {
1215 GetBEQueue()->Queue(packet, hdr);
1216 }
1217 else
1218 {
1219 GetVOQueue()->Queue(packet, hdr);
1220 }
1221}
1222
1223void
1225{
1226 NS_LOG_FUNCTION(this << +linkId);
1227 auto& link = GetLink(linkId);
1228 WifiMacHeader hdr;
1231 hdr.SetAddr2(link.feManager->GetAddress());
1232 hdr.SetAddr3(link.feManager->GetAddress());
1233 hdr.SetDsNotFrom();
1234 hdr.SetDsNotTo();
1235 Ptr<Packet> packet = Create<Packet>();
1236 MgtBeaconHeader beacon;
1237 beacon.SetSsid(GetSsid());
1238 beacon.SetSupportedRates(GetSupportedRates(linkId));
1239 beacon.SetBeaconIntervalUs(GetBeaconInterval().GetMicroSeconds());
1240 beacon.SetCapabilities(GetCapabilities(linkId));
1241 GetWifiRemoteStationManager(linkId)->SetShortPreambleEnabled(link.shortPreambleEnabled);
1242 GetWifiRemoteStationManager(linkId)->SetShortSlotTimeEnabled(link.shortSlotTimeEnabled);
1243 if (GetDsssSupported(linkId))
1244 {
1246 }
1247 if (GetErpSupported(linkId))
1248 {
1249 beacon.SetErpInformation(GetErpInformation(linkId));
1250 }
1251 if (GetQosSupported())
1252 {
1254 }
1255 if (GetHtSupported())
1256 {
1258 beacon.SetHtCapabilities(GetHtCapabilities(linkId));
1259 beacon.SetHtOperation(GetHtOperation(linkId));
1260 }
1261 if (GetVhtSupported(linkId))
1262 {
1263 beacon.SetVhtCapabilities(GetVhtCapabilities(linkId));
1264 beacon.SetVhtOperation(GetVhtOperation(linkId));
1265 }
1266 if (GetHeSupported())
1267 {
1268 beacon.SetHeCapabilities(GetHeCapabilities(linkId));
1269 beacon.SetHeOperation(GetHeOperation(linkId));
1270 if (auto muEdcaParameterSet = GetMuEdcaParameterSet(); muEdcaParameterSet.has_value())
1271 {
1272 beacon.SetMuEdcaParameterSet(std::move(*muEdcaParameterSet));
1273 }
1274 }
1275 if (GetEhtSupported())
1276 {
1277 beacon.SetEhtCapabilities(GetEhtCapabilities(linkId));
1278
1279 if (GetNLinks() > 1)
1280 {
1281 /*
1282 * If an AP is affiliated with an AP MLD and does not correspond to a nontransmitted
1283 * BSSID, then the Beacon and Probe Response frames transmitted by the AP shall
1284 * include a TBTT Information field in a Reduced Neighbor Report element with the
1285 * TBTT Information Length field set to 16 or higher, for each of the other APs
1286 * (if any) affiliated with the same AP MLD. (Sec. 35.3.4.1 of 802.11be D2.1.1)
1287 */
1288 if (auto rnr = GetReducedNeighborReport(linkId); rnr.has_value())
1289 {
1290 beacon.SetReducedNeighborReport(std::move(*rnr));
1291 }
1292 /*
1293 * If an AP affiliated with an AP MLD is not in a multiple BSSID set [..], the AP
1294 * shall include, in a Beacon frame or a Probe Response frame, which is not a
1295 * Multi-Link probe response, only the Common Info field of the Basic Multi-Link
1296 * element for the AP MLD unless conditions in 35.3.11 (Multi-link procedures for
1297 * channel switching, extended channel switching, and channel quieting) are
1298 * satisfied. (Sec. 35.3.4.4 of 802.11be D2.1.1)
1299 */
1301 }
1302 }
1303 packet->AddHeader(beacon);
1304
1305 // The beacon has it's own special queue, so we load it in there
1306 m_beaconTxop->Queue(packet, hdr);
1307 link.beaconEvent =
1309
1310 // If a STA that does not support Short Slot Time associates,
1311 // the AP shall use long slot time beginning at the first Beacon
1312 // subsequent to the association of the long slot time STA.
1313 if (GetErpSupported(linkId))
1314 {
1315 if (link.shortSlotTimeEnabled)
1316 {
1317 // Enable short slot time
1318 GetWifiPhy(linkId)->SetSlot(MicroSeconds(9));
1319 }
1320 else
1321 {
1322 // Disable short slot time
1323 GetWifiPhy(linkId)->SetSlot(MicroSeconds(20));
1324 }
1325 }
1326}
1327
1328void
1330{
1331 NS_LOG_FUNCTION(this << *mpdu);
1332 const WifiMacHeader& hdr = mpdu->GetHeader();
1333
1334 if (hdr.IsAssocResp() || hdr.IsReassocResp())
1335 {
1336 auto linkId = GetLinkIdByAddress(hdr.GetAddr2());
1337 NS_ABORT_MSG_IF(!linkId.has_value(), "No link ID matching the TA");
1338
1340 {
1341 NS_LOG_DEBUG("AP=" << hdr.GetAddr2() << " associated with STA=" << hdr.GetAddr1());
1343 }
1344
1345 if (auto staMldAddress =
1347 staMldAddress.has_value())
1348 {
1349 // the STA is affiliated with an MLD
1350 for (uint8_t i = 0; i < GetNLinks(); i++)
1351 {
1352 auto stationManager = GetWifiRemoteStationManager(i);
1353 if (auto staAddress = stationManager->GetAffiliatedStaAddress(*staMldAddress);
1354 staAddress.has_value() && i != *linkId &&
1355 stationManager->IsWaitAssocTxOk(*staAddress))
1356 {
1358 << " associated with STA=" << *staAddress);
1359 stationManager->RecordGotAssocTxOk(*staAddress);
1360 }
1361 }
1362 }
1363 }
1364}
1365
1366void
1368{
1369 NS_LOG_FUNCTION(this << +timeoutReason << *mpdu);
1370 const WifiMacHeader& hdr = mpdu->GetHeader();
1371
1372 if (hdr.IsAssocResp() || hdr.IsReassocResp())
1373 {
1374 auto linkId = GetLinkIdByAddress(hdr.GetAddr2());
1375 NS_ABORT_MSG_IF(!linkId.has_value(), "No link ID matching the TA");
1376
1378 {
1379 NS_LOG_DEBUG("AP=" << hdr.GetAddr2()
1380 << " association failed with STA=" << hdr.GetAddr1());
1382 }
1383
1384 if (auto staMldAddress =
1386 staMldAddress.has_value())
1387 {
1388 // the STA is affiliated with an MLD
1389 for (uint8_t i = 0; i < GetNLinks(); i++)
1390 {
1391 auto stationManager = GetWifiRemoteStationManager(i);
1392 if (auto staAddress = stationManager->GetAffiliatedStaAddress(*staMldAddress);
1393 staAddress.has_value() && i != *linkId &&
1394 stationManager->IsWaitAssocTxOk(*staAddress))
1395 {
1397 << " association failed with STA=" << *staAddress);
1398 stationManager->RecordGotAssocTxFailed(*staAddress);
1399 }
1400 }
1401 }
1402 }
1403}
1404
1405void
1407{
1408 NS_LOG_FUNCTION(this << *mpdu << +linkId);
1409 const WifiMacHeader* hdr = &mpdu->GetHeader();
1410 Ptr<const Packet> packet = mpdu->GetPacket();
1411 Mac48Address from = hdr->GetAddr2();
1412 if (hdr->IsData())
1413 {
1414 Mac48Address bssid = hdr->GetAddr1();
1415 if (!hdr->IsFromDs() && hdr->IsToDs() && bssid == GetAddress() &&
1416 GetWifiRemoteStationManager()->IsAssociated(from))
1417 {
1418 Mac48Address to = hdr->GetAddr3();
1419 if (to == GetAddress())
1420 {
1421 NS_LOG_DEBUG("frame for me from=" << from);
1422 if (hdr->IsQosData())
1423 {
1424 if (hdr->IsQosAmsdu())
1425 {
1426 NS_LOG_DEBUG("Received A-MSDU from=" << from
1427 << ", size=" << packet->GetSize());
1429 packet = nullptr;
1430 }
1431 else
1432 {
1433 ForwardUp(packet, from, bssid);
1434 }
1435 }
1436 else if (hdr->HasData())
1437 {
1438 ForwardUp(packet, from, bssid);
1439 }
1440 }
1441 else if (to.IsGroup() || GetWifiRemoteStationManager()->IsAssociated(to))
1442 {
1443 NS_LOG_DEBUG("forwarding frame from=" << from << ", to=" << to);
1444 Ptr<Packet> copy = packet->Copy();
1445
1446 // If the frame we are forwarding is of type QoS Data,
1447 // then we need to preserve the UP in the QoS control
1448 // header...
1449 if (hdr->IsQosData())
1450 {
1451 ForwardDown(copy, from, to, hdr->GetQosTid());
1452 }
1453 else
1454 {
1455 ForwardDown(copy, from, to);
1456 }
1457 ForwardUp(packet, from, to);
1458 }
1459 else
1460 {
1461 ForwardUp(packet, from, to);
1462 }
1463 }
1464 else if (hdr->IsFromDs() && hdr->IsToDs())
1465 {
1466 // this is an AP-to-AP frame
1467 // we ignore for now.
1468 NotifyRxDrop(packet);
1469 }
1470 else
1471 {
1472 // we can ignore these frames since
1473 // they are not targeted at the AP
1474 NotifyRxDrop(packet);
1475 }
1476 return;
1477 }
1478 else if (hdr->IsMgt())
1479 {
1480 if (hdr->IsProbeReq() && (hdr->GetAddr1().IsGroup() ||
1481 hdr->GetAddr1() == GetFrameExchangeManager(linkId)->GetAddress()))
1482 {
1483 // In the case where the Address 1 field contains a group address, the
1484 // Address 3 field also is validated to verify that the group addressed
1485 // frame originated from a STA in the BSS of which the receiving STA is
1486 // a member (Section 9.3.3.1 of 802.11-2020)
1487 if (hdr->GetAddr1().IsGroup() && !hdr->GetAddr3().IsBroadcast() &&
1488 hdr->GetAddr3() != GetFrameExchangeManager(linkId)->GetAddress())
1489 {
1490 // not addressed to us
1491 return;
1492 }
1493 MgtProbeRequestHeader probeRequestHeader;
1494 packet->PeekHeader(probeRequestHeader);
1495 const Ssid& ssid = probeRequestHeader.GetSsid();
1496 if (ssid == GetSsid() || ssid.IsBroadcast())
1497 {
1498 NS_LOG_DEBUG("Probe request received from " << from << ": send probe response");
1499 SendProbeResp(from, linkId);
1500 }
1501 return;
1502 }
1503 else if (hdr->GetAddr1() == GetFrameExchangeManager(linkId)->GetAddress())
1504 {
1505 if (hdr->IsAssocReq() || hdr->IsReassocReq())
1506 {
1507 NS_LOG_DEBUG(((hdr->IsAssocReq()) ? "Association" : "Reassociation")
1508 << " request received from " << from
1509 << ((GetNLinks() > 1) ? " on link ID " + std::to_string(linkId) : ""));
1510
1511 MgtAssocRequestHeader assocReq;
1512 MgtReassocRequestHeader reassocReq;
1513 AssocReqRefVariant frame = assocReq;
1514 if (hdr->IsAssocReq())
1515 {
1516 packet->PeekHeader(assocReq);
1517 }
1518 else
1519 {
1520 packet->PeekHeader(reassocReq);
1521 frame = reassocReq;
1522 }
1523 ReceiveAssocRequest(frame, from, linkId);
1524 if (GetNLinks() > 1)
1525 {
1526 ParseReportedStaInfo(frame, from, linkId);
1527 }
1528 SendAssocResp(hdr->GetAddr2(), hdr->IsReassocReq(), linkId);
1529 return;
1530 }
1531 else if (hdr->IsDisassociation())
1532 {
1533 NS_LOG_DEBUG("Disassociation received from " << from);
1535 auto& staList = GetLink(linkId).staList;
1536 for (auto it = staList.begin(); it != staList.end(); ++it)
1537 {
1538 if (it->second == from)
1539 {
1540 staList.erase(it);
1541 m_deAssocLogger(it->first, it->second);
1542 if (GetWifiRemoteStationManager(linkId)->GetDsssSupported(from) &&
1543 !GetWifiRemoteStationManager(linkId)->GetErpOfdmSupported(from))
1544 {
1545 GetLink(linkId).numNonErpStations--;
1546 }
1547 if (!GetWifiRemoteStationManager(linkId)->GetHtSupported(from))
1548 {
1549 GetLink(linkId).numNonHtStations--;
1550 }
1553 break;
1554 }
1555 }
1556 return;
1557 }
1558 }
1559 }
1560
1561 // Invoke the receive handler of our parent class to deal with any
1562 // other frames. Specifically, this will handle Block Ack-related
1563 // Management Action frames.
1564 WifiMac::Receive(Create<WifiMpdu>(packet, *hdr), linkId);
1565}
1566
1567bool
1569 const Mac48Address& from,
1570 uint8_t linkId)
1571{
1572 NS_LOG_FUNCTION(this << from << +linkId);
1573
1574 auto remoteStationManager = GetWifiRemoteStationManager(linkId);
1575
1576 auto failure = [&](const std::string& msg) -> bool {
1577 NS_LOG_DEBUG("Association Request from " << from << " refused: " << msg);
1578 remoteStationManager->RecordAssocRefused(from);
1579 return false;
1580 };
1581
1582 // lambda to process received (Re)Association Request
1583 auto recvAssocRequest = [&](auto&& frameRefWrapper) -> bool {
1584 const auto& frame = frameRefWrapper.get();
1585
1586 // first, verify that the the station's supported
1587 // rate set is compatible with our Basic Rate set
1588 const CapabilityInformation& capabilities = frame.GetCapabilities();
1589 remoteStationManager->AddSupportedPhyPreamble(from, capabilities.IsShortPreamble());
1590 const SupportedRates& rates = frame.GetSupportedRates();
1591
1592 if (rates.GetNRates() == 0)
1593 {
1594 return failure("STA's supported rate set not compatible with our Basic Rate set");
1595 }
1596
1597 if (GetHtSupported())
1598 {
1599 // check whether the HT STA supports all MCSs in Basic MCS Set
1600 const auto& htCapabilities = frame.GetHtCapabilities();
1601 if (htCapabilities.has_value() && htCapabilities->IsSupportedMcs(0))
1602 {
1603 for (uint8_t i = 0; i < remoteStationManager->GetNBasicMcs(); i++)
1604 {
1605 WifiMode mcs = remoteStationManager->GetBasicMcs(i);
1606 if (!htCapabilities->IsSupportedMcs(mcs.GetMcsValue()))
1607 {
1608 return failure("HT STA does not support all MCSs in Basic MCS Set");
1609 }
1610 }
1611 }
1612 }
1613 if (GetVhtSupported(linkId))
1614 {
1615 // check whether the VHT STA supports all MCSs in Basic MCS Set
1616 const auto& vhtCapabilities = frame.GetVhtCapabilities();
1617 if (vhtCapabilities.has_value() && vhtCapabilities->GetVhtCapabilitiesInfo() != 0)
1618 {
1619 for (uint8_t i = 0; i < remoteStationManager->GetNBasicMcs(); i++)
1620 {
1621 WifiMode mcs = remoteStationManager->GetBasicMcs(i);
1622 if (!vhtCapabilities->IsSupportedTxMcs(mcs.GetMcsValue()))
1623 {
1624 return failure("VHT STA does not support all MCSs in Basic MCS Set");
1625 }
1626 }
1627 }
1628 }
1629 if (GetHeSupported())
1630 {
1631 // check whether the HE STA supports all MCSs in Basic MCS Set
1632 const auto& heCapabilities = frame.GetHeCapabilities();
1633 if (heCapabilities.has_value() && heCapabilities->GetSupportedMcsAndNss() != 0)
1634 {
1635 for (uint8_t i = 0; i < remoteStationManager->GetNBasicMcs(); i++)
1636 {
1637 WifiMode mcs = remoteStationManager->GetBasicMcs(i);
1638 if (!heCapabilities->IsSupportedTxMcs(mcs.GetMcsValue()))
1639 {
1640 return failure("HE STA does not support all MCSs in Basic MCS Set");
1641 }
1642 }
1643 }
1644 }
1645 if (GetEhtSupported())
1646 {
1647 // check whether the EHT STA supports all MCSs in Basic MCS Set
1648 // const auto& ehtCapabilities = frame.GetEhtCapabilities ();
1649 // TODO: to be completed
1650 }
1651
1652 // The association request from the station can be accepted.
1653 // Record all its supported modes in its associated WifiRemoteStation
1654 auto phy = GetWifiPhy(linkId);
1655
1656 for (const auto& mode : phy->GetModeList())
1657 {
1658 if (rates.IsSupportedRate(mode.GetDataRate(phy->GetChannelWidth())))
1659 {
1660 remoteStationManager->AddSupportedMode(from, mode);
1661 }
1662 }
1663 if (GetErpSupported(linkId) && remoteStationManager->GetErpOfdmSupported(from) &&
1664 capabilities.IsShortSlotTime())
1665 {
1666 remoteStationManager->AddSupportedErpSlotTime(from, true);
1667 }
1668 if (GetHtSupported())
1669 {
1670 const auto& htCapabilities = frame.GetHtCapabilities();
1671 if (htCapabilities.has_value() && htCapabilities->IsSupportedMcs(0))
1672 {
1673 remoteStationManager->AddStationHtCapabilities(from, *htCapabilities);
1674 }
1675 // const ExtendedCapabilities& extendedCapabilities = frame.GetExtendedCapabilities ();
1676 // TODO: to be completed
1677 }
1678 if (GetVhtSupported(linkId))
1679 {
1680 const auto& vhtCapabilities = frame.GetVhtCapabilities();
1681 // we will always fill in RxHighestSupportedLgiDataRate field at TX, so this can be used
1682 // to check whether it supports VHT
1683 if (vhtCapabilities.has_value() &&
1684 vhtCapabilities->GetRxHighestSupportedLgiDataRate() > 0)
1685 {
1686 remoteStationManager->AddStationVhtCapabilities(from, *vhtCapabilities);
1687 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_VHT))
1688 {
1689 if (vhtCapabilities->IsSupportedTxMcs(mcs.GetMcsValue()))
1690 {
1691 remoteStationManager->AddSupportedMcs(from, mcs);
1692 // here should add a control to add basic MCS when it is implemented
1693 }
1694 }
1695 }
1696 }
1697 if (GetHeSupported())
1698 {
1699 const auto& heCapabilities = frame.GetHeCapabilities();
1700 if (heCapabilities.has_value() && heCapabilities->GetSupportedMcsAndNss() != 0)
1701 {
1702 remoteStationManager->AddStationHeCapabilities(from, *heCapabilities);
1703 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_HE))
1704 {
1705 if (heCapabilities->IsSupportedTxMcs(mcs.GetMcsValue()))
1706 {
1707 remoteStationManager->AddSupportedMcs(from, mcs);
1708 // here should add a control to add basic MCS when it is implemented
1709 }
1710 }
1711 }
1712 }
1713 if (GetEhtSupported())
1714 {
1715 const auto& ehtCapabilities = frame.GetEhtCapabilities();
1716 // TODO: once we support non constant rate managers, we should add checks here whether
1717 // EHT is supported by the peer
1718 remoteStationManager->AddStationEhtCapabilities(from, *ehtCapabilities);
1719 for (const auto& mcs : phy->GetMcsList(WIFI_MOD_CLASS_EHT))
1720 {
1721 // TODO: Add check whether MCS is supported from the capabilities
1722 remoteStationManager->AddSupportedMcs(from, mcs);
1723 // here should add a control to add basic MCS when it is implemented
1724 }
1725 }
1726
1727 NS_LOG_DEBUG("Association Request from " << from << " accepted");
1728 remoteStationManager->RecordWaitAssocTxOk(from);
1729 return true;
1730 ;
1731 };
1732
1733 return std::visit(recvAssocRequest, assoc);
1734}
1735
1736void
1738{
1739 NS_LOG_FUNCTION(this << from << +linkId);
1740
1741 // lambda to process received Multi-Link Element
1742 auto recvMle = [&](auto&& frame) {
1743 const auto& mle = frame.get().GetMultiLinkElement();
1744
1745 if (!mle.has_value())
1746 {
1747 return;
1748 }
1749
1750 GetWifiRemoteStationManager(linkId)->SetMldAddress(from, mle->GetMldMacAddress());
1751
1752 for (std::size_t i = 0; i < mle->GetNPerStaProfileSubelements(); i++)
1753 {
1754 auto& perStaProfile = mle->GetPerStaProfile(i);
1755 if (!perStaProfile.HasStaMacAddress())
1756 {
1757 NS_LOG_DEBUG("[i=" << i
1758 << "] Cannot setup a link if the STA MAC address is missing");
1759 continue;
1760 }
1761 uint8_t newLinkId = perStaProfile.GetLinkId();
1762 if (newLinkId == linkId || newLinkId >= GetNLinks())
1763 {
1764 NS_LOG_DEBUG("[i=" << i << "] Link ID " << newLinkId << " not valid");
1765 continue;
1766 }
1767 if (!perStaProfile.HasAssocRequest() && !perStaProfile.HasReassocRequest())
1768 {
1769 NS_LOG_DEBUG("[i=" << i << "] No (Re)Association Request frame body present");
1770 continue;
1771 }
1772
1773 ReceiveAssocRequest(perStaProfile.GetAssocRequest(),
1774 perStaProfile.GetStaMacAddress(),
1775 newLinkId);
1776 GetWifiRemoteStationManager(newLinkId)->SetMldAddress(perStaProfile.GetStaMacAddress(),
1777 mle->GetMldMacAddress());
1778 }
1779 };
1780
1781 std::visit(recvMle, assoc);
1782}
1783
1784void
1786{
1787 NS_LOG_FUNCTION(this << *mpdu);
1788 for (auto& i : *PeekPointer(mpdu))
1789 {
1790 if (i.second.GetDestinationAddr() == GetAddress())
1791 {
1792 ForwardUp(i.first, i.second.GetSourceAddr(), i.second.GetDestinationAddr());
1793 }
1794 else
1795 {
1796 Mac48Address from = i.second.GetSourceAddr();
1797 Mac48Address to = i.second.GetDestinationAddr();
1798 NS_LOG_DEBUG("forwarding QoS frame from=" << from << ", to=" << to);
1799 ForwardDown(i.first->Copy(), from, to, mpdu->GetHeader().GetQosTid());
1800 }
1801 }
1802}
1803
1804void
1806{
1807 NS_LOG_FUNCTION(this);
1809
1810 for (uint8_t linkId = 0; linkId < GetNLinks(); ++linkId)
1811 {
1812 GetLink(linkId).beaconEvent.Cancel();
1814 {
1815 uint64_t jitterUs =
1817 ? static_cast<uint64_t>(m_beaconJitter->GetValue(0, 1) *
1819 : 0);
1820 NS_LOG_DEBUG("Scheduling initial beacon for access point "
1821 << GetAddress() << " at time " << jitterUs << "us");
1824 this,
1825 linkId);
1826 }
1829 }
1830
1835}
1836
1837bool
1839{
1840 bool useProtection = (GetLink(linkId).numNonErpStations > 0) && m_enableNonErpProtection;
1842 return useProtection;
1843}
1844
1845uint16_t
1846ApWifiMac::GetNextAssociationId(std::list<uint8_t> linkIds)
1847{
1848 // Return the first AID value between 1 and 2007 that is free for all the given links
1849 for (uint16_t nextAid = 1; nextAid <= 2007; nextAid++)
1850 {
1851 if (std::all_of(linkIds.begin(), linkIds.end(), [&](auto&& linkId) {
1852 auto& staList = GetLink(linkId).staList;
1853 return staList.find(nextAid) == staList.end();
1854 }))
1855 {
1856 return nextAid;
1857 }
1858 }
1859 NS_FATAL_ERROR("No free association ID available!");
1860 return 0;
1861}
1862
1863const std::map<uint16_t, Mac48Address>&
1864ApWifiMac::GetStaList(uint8_t linkId) const
1865{
1866 return GetLink(linkId).staList;
1867}
1868
1869uint16_t
1871{
1872 return GetWifiRemoteStationManager(linkId)->GetAssociationId(addr);
1873}
1874
1875uint8_t
1877{
1878 auto it = m_bufferStatus.find(WifiAddressTidPair(address, tid));
1879 if (it == m_bufferStatus.end() || it->second.timestamp + m_bsrLifetime < Simulator::Now())
1880 {
1881 return 255;
1882 }
1883 return it->second.value;
1884}
1885
1886void
1888{
1889 if (size == 255)
1890 {
1891 // no point in storing an unspecified size
1893 }
1894 else
1895 {
1897 }
1898}
1899
1900uint8_t
1902{
1903 uint8_t maxSize = 0;
1904 bool found = false;
1905
1906 for (uint8_t tid = 0; tid < 8; tid++)
1907 {
1908 uint8_t size = GetBufferStatus(tid, address);
1909 if (size != 255)
1910 {
1911 maxSize = std::max(maxSize, size);
1912 found = true;
1913 }
1914 }
1915
1916 if (found)
1917 {
1918 return maxSize;
1919 }
1920 return 255;
1921}
1922
1923} // namespace ns3
#define min(a, b)
Definition: 80211b.c:42
#define max(a, b)
Definition: 80211b.c:43
Wi-Fi AP state machine.
Definition: ap-wifi-mac.h:63
void SendAssocResp(Mac48Address to, bool isReassoc, uint8_t linkId)
Forward an association or a reassociation response packet to the DCF/EDCA.
uint16_t GetAssociationId(Mac48Address addr, uint8_t linkId) const
std::unique_ptr< LinkEntity > CreateLinkEntity() const override
Create a LinkEntity object.
Definition: ap-wifi-mac.cc:141
Ptr< Txop > m_beaconTxop
Dedicated Txop for beacons.
Definition: ap-wifi-mac.h:440
void SetBeaconGeneration(bool enable)
Enable or disable beacon generation of the AP.
Definition: ap-wifi-mac.cc:178
void ParseReportedStaInfo(const AssocReqRefVariant &assoc, Mac48Address from, uint8_t linkId)
Given a (Re)Association Request frame body containing a Multi-Link Element, check if a link can be se...
void SetAid(MgtAssocResponseHeader &assoc, const Mac48Address &to, uint8_t linkId)
Set the AID field of the given Association Response frame, which is going to be sent to the STA with ...
void UpdateShortSlotTimeEnabled(uint8_t linkId)
Update whether short slot time should be enabled or not in the BSS corresponding to the given link.
Definition: ap-wifi-mac.cc:241
void DoDispose() override
Destructor implementation.
Definition: ap-wifi-mac.cc:125
void SetBeaconInterval(Time interval)
Definition: ap-wifi-mac.cc:216
bool ReceiveAssocRequest(const AssocReqRefVariant &assoc, const Mac48Address &from, uint8_t linkId)
Check whether the supported rate set included in the received (Re)Association Request frame is compat...
CapabilityInformation GetCapabilities(uint8_t linkId) const
Return the Capability information of the current AP for the given link.
Definition: ap-wifi-mac.cc:455
Ptr< UniformRandomVariable > m_beaconJitter
UniformRandomVariable used to randomize the time of the first beacon.
Definition: ap-wifi-mac.h:444
SupportedRates GetSupportedRates(uint8_t linkId) const
Return an instance of SupportedRates that contains all rates that we support for the given link (incl...
Definition: ap-wifi-mac.cc:400
bool CanForwardPacketsTo(Mac48Address to) const override
Return true if packets can be forwarded to the given destination, false otherwise.
Definition: ap-wifi-mac.cc:363
bool m_enableNonErpProtection
Flag whether protection mechanism is used or not when non-ERP STAs are present within the BSS.
Definition: ap-wifi-mac.h:446
EdcaParameterSet GetEdcaParameterSet(uint8_t linkId) const
Return the EDCA Parameter Set of the current AP for the given link.
Definition: ap-wifi-mac.cc:487
MultiLinkElement GetMultiLinkElement(uint8_t linkId, WifiMacType frameType, const Mac48Address &to=Mac48Address::GetBroadcast())
Return the Multi-Link Element that the current AP includes in the management frames of the given type...
Definition: ap-wifi-mac.cc:633
HtOperation GetHtOperation(uint8_t linkId) const
Return the HT operation of the current AP for the given link.
Definition: ap-wifi-mac.cc:682
void UpdateShortPreambleEnabled(uint8_t linkId)
Update whether short preamble should be enabled or not in the BSS corresponding to the given link.
Definition: ap-wifi-mac.cc:264
void TxOk(Ptr< const WifiMpdu > mpdu)
The packet we sent was successfully received by the receiver (i.e.
TracedCallback< uint16_t, Mac48Address > m_deAssocLogger
deassociation logger
Definition: ap-wifi-mac.h:469
bool m_enableBeaconGeneration
Flag whether beacons are being generated.
Definition: ap-wifi-mac.h:441
Time m_beaconInterval
Beacon interval.
Definition: ap-wifi-mac.h:442
uint16_t GetNextAssociationId(std::list< uint8_t > linkIds)
bool m_enableBeaconJitter
Flag whether the first beacon should be generated at random time.
Definition: ap-wifi-mac.h:445
void SendProbeResp(Mac48Address to, uint8_t linkId)
Send a Probe Response in response to a Probe Request received from the STA with the given address on ...
Definition: ap-wifi-mac.cc:859
DsssParameterSet GetDsssParameterSet(uint8_t linkId) const
Return the DSSS Parameter Set that we support on the given link.
Definition: ap-wifi-mac.cc:445
TracedCallback< uint16_t, Mac48Address > m_assocLogger
association logger
Definition: ap-wifi-mac.h:468
Time GetBeaconInterval() const
Definition: ap-wifi-mac.cc:197
static TypeId GetTypeId()
Get the type ID.
Definition: ap-wifi-mac.cc:55
std::optional< ReducedNeighborReport > GetReducedNeighborReport(uint8_t linkId) const
Return the Reduced Neighbor Report (RNR) element that the current AP sends on the given link,...
Definition: ap-wifi-mac.cc:602
void Enqueue(Ptr< Packet > packet, Mac48Address to) override
Definition: ap-wifi-mac.cc:383
uint8_t GetMaxBufferStatus(Mac48Address address) const
Return the maximum among the values of the Queue Size subfield of the last QoS Data or QoS Null frame...
Time m_bsrLifetime
Lifetime of Buffer Status Reports.
Definition: ap-wifi-mac.h:448
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Definition: ap-wifi-mac.cc:233
ApLinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: ap-wifi-mac.cc:147
void Receive(Ptr< const WifiMpdu > mpdu, uint8_t linkId) override
This method acts as the MacRxMiddle receive callback and is invoked to notify us that a frame has bee...
uint8_t GetBufferStatus(uint8_t tid, Mac48Address address) const
Return the value of the Queue Size subfield of the last QoS Data or QoS Null frame received from the ...
void ConfigureStandard(WifiStandard standard) override
Definition: ap-wifi-mac.cc:153
ErpInformation GetErpInformation(uint8_t linkId) const
Return the ERP information of the current AP for the given link.
Definition: ap-wifi-mac.cc:466
void SetLinkUpCallback(Callback< void > linkUp) override
Definition: ap-wifi-mac.cc:204
VhtOperation GetVhtOperation(uint8_t linkId) const
Return the VHT operation of the current AP for the given link.
Definition: ap-wifi-mac.cc:780
~ApWifiMac() override
Definition: ap-wifi-mac.cc:119
void TxFailed(WifiMacDropReason timeoutReason, Ptr< const WifiMpdu > mpdu)
The packet we sent was successfully received by the receiver (i.e.
HeOperation GetHeOperation(uint8_t linkId) const
Return the HE operation of the current AP for the given link.
Definition: ap-wifi-mac.cc:829
void SetBufferStatus(uint8_t tid, Mac48Address address, uint8_t size)
Store the value of the Queue Size subfield of the last QoS Data or QoS Null frame received from the s...
std::optional< MuEdcaParameterSet > GetMuEdcaParameterSet() const
Return the MU EDCA Parameter Set of the current AP, if one needs to be advertised.
Definition: ap-wifi-mac.cc:534
void DeaggregateAmsduAndForward(Ptr< const WifiMpdu > mpdu) override
This method is called to de-aggregate an A-MSDU and forward the constituent packets up the stack.
bool SupportsSendFrom() const override
Definition: ap-wifi-mac.cc:393
std::unordered_map< WifiAddressTidPair, bsrType, WifiAddressTidHash > m_bufferStatus
Per (MAC address, TID) buffer status reports.
Definition: ap-wifi-mac.h:458
MgtAssocResponseHeader GetAssocResp(Mac48Address to, uint8_t linkId)
Get the Association Response frame to send on a given link.
Definition: ap-wifi-mac.cc:963
void ForwardDown(Ptr< Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet down to DCF/EDCAF (enqueue the packet).
Definition: ap-wifi-mac.cc:288
void DoInitialize() override
Initialize() implementation.
void SendOneBeacon(uint8_t linkId)
Forward a beacon packet to the beacon special DCF for transmission on the given link.
Ptr< WifiMacQueue > GetTxopQueue(AcIndex ac) const override
Get the wifi MAC queue of the (Qos)Txop associated with the given AC, if such (Qos)Txop is installed,...
Definition: ap-wifi-mac.cc:168
const std::map< uint16_t, Mac48Address > & GetStaList(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get a const reference to the map of associated stations on the given link.
bool GetUseNonErpProtection(uint8_t linkId) const
Return whether protection for non-ERP stations is used in the BSS corresponding to the given link.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
void SetEss()
Set the Extended Service Set (ESS) bit in the capability information field.
bool IsShortSlotTime() const
Check if the short slot time in the capability information field is set to 1.
void SetShortSlotTime(bool shortSlotTime)
Set the short slot time bit in the capability information field.
void SetShortPreamble(bool shortPreamble)
Set the short preamble bit in the capability information field.
bool IsShortPreamble() const
Check if the short preamble bit in the capability information field is set to 1.
The DSSS Parameter Set.
void SetCurrentChannel(uint8_t currentChannel)
Set the Current Channel field in the DsssParameterSet information element.
The EDCA Parameter Set.
void SetViTxopLimit(uint16_t txop)
Set the AC_VI TXOP Limit field in the EdcaParameterSet information element.
void SetViAifsn(uint8_t aifsn)
Set the AC_VI AIFSN field in the EdcaParameterSet information element.
void SetVoAci(uint8_t aci)
Set the AC_VO ACI field in the EdcaParameterSet information element.
void SetVoCWmax(uint32_t cwMax)
Set the AC_VO CWmax field in the EdcaParameterSet information element.
void SetViCWmin(uint32_t cwMin)
Set the AC_VI CWmin field in the EdcaParameterSet information element.
void SetVoTxopLimit(uint16_t txop)
Set the AC_VO TXOP Limit field in the EdcaParameterSet information element.
void SetVoAifsn(uint8_t aifsn)
Set the AC_VO AIFSN field in the EdcaParameterSet information element.
void SetQosInfo(uint8_t qosInfo)
Set the QoS Info field in the EdcaParameterSet information element.
void SetBkCWmin(uint32_t cwMin)
Set the AC_BK CWmin field in the EdcaParameterSet information element.
void SetViAci(uint8_t aci)
Set the AC_VI ACI field in the EdcaParameterSet information element.
void SetViCWmax(uint32_t cwMax)
Set the AC_VI CWmax field in the EdcaParameterSet information element.
void SetVoCWmin(uint32_t cwMin)
Set the AC_VO CWmin field in the EdcaParameterSet information element.
void SetBeTxopLimit(uint16_t txop)
Set the AC_BE TXOP Limit field in the EdcaParameterSet information element.
void SetBeCWmax(uint32_t cwMax)
Set the AC_BE CWmax field in the EdcaParameterSet information element.
void SetBeAci(uint8_t aci)
Set the AC_BE ACI field in the EdcaParameterSet information element.
void SetBkCWmax(uint32_t cwMax)
Set the AC_BK CWmax field in the EdcaParameterSet information element.
void SetBkTxopLimit(uint16_t txop)
Set the AC_BK TXOP Limit field in the EdcaParameterSet information element.
void SetBkAifsn(uint8_t aifsn)
Set the AC_BK AIFSN field in the EdcaParameterSet information element.
void SetBeCWmin(uint32_t cwMin)
Set the AC_BE CWmin field in the EdcaParameterSet information element.
void SetBkAci(uint8_t aci)
Set the AC_BK ACI field in the EdcaParameterSet information element.
void SetBeAifsn(uint8_t aifsn)
Set the AC_BE AIFSN field in the EdcaParameterSet information element.
The ErpInformation Information Element.
void SetBarkerPreambleMode(uint8_t barkerPreambleMode)
Set the Barker_Preamble_Mode field in the ErpInformation information element.
void SetUseProtection(uint8_t useProtection)
Set the Use_Protection field in the ErpInformation information element.
void SetNonErpPresent(uint8_t nonErpPresent)
Set the Non_Erp_Present field in the ErpInformation information element.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
The HE Operation Information Element.
Definition: he-operation.h:36
void SetBssColor(uint8_t bssColor)
Set the BSS color.
void SetMaxHeMcsPerNss(uint8_t nss, uint8_t maxHeMcs)
Set the Basic HE-MCS and NSS field in the HE Operation information element by specifying the tuple (n...
Definition: he-operation.cc:88
The HT Operation Information Element.
Definition: ht-operation.h:51
void SetObssNonHtStasPresent(uint8_t obssNonHtStasPresent)
Set the OBSS non HT STAs present.
void SetRifsMode(uint8_t rifsMode)
Set the RIFS mode.
Definition: ht-operation.cc:90
void SetSecondaryChannelOffset(uint8_t secondaryChannelOffset)
Set the secondary channel offset.
Definition: ht-operation.cc:78
void SetPcoActive(uint8_t pcoActive)
Set the PCO active.
void SetTxUnequalModulation(uint8_t txUnequalModulation)
Set the transmit unequal modulation.
void SetHtProtection(uint8_t htProtection)
Set the HT protection.
Definition: ht-operation.cc:96
void SetTxMaxNSpatialStreams(uint8_t maxTxSpatialStreams)
Set the transmit maximum number spatial streams.
void SetTxRxMcsSetUnequal(uint8_t txRxMcsSetUnequal)
Set the transmit / receive MCS set unequal.
void SetDualBeacon(uint8_t dualBeacon)
Set the dual beacon.
void SetNonGfHtStasPresent(uint8_t nonGfHtStasPresent)
Set the non GF HT STAs present.
void SetTxMcsSetDefined(uint8_t txMcsSetDefined)
Set the transmit MCS set defined.
void SetLSigTxopProtectionFullSupport(uint8_t lSigTxopProtectionFullSupport)
Set the LSIG TXOP protection full support.
void SetStaChannelWidth(uint8_t staChannelWidth)
Set the STA channel width.
Definition: ht-operation.cc:84
void SetRxHighestSupportedDataRate(uint16_t maxSupportedRate)
Set the receive highest supported data rate.
void SetRxMcsBitmask(uint8_t index)
Set the receive MCS bitmask.
void SetPrimaryChannel(uint8_t ctrl)
Set the Primary Channel field in the HT Operation information element.
Definition: ht-operation.cc:72
void SetDualCtsProtection(uint8_t dualCtsProtection)
Set the dual CTS protection.
void SetPhase(uint8_t pcoPhase)
Set the PCO phase.
void SetStbcBeacon(uint8_t stbcBeacon)
Set the STBC beacon.
an EUI-48 address
Definition: mac48-address.h:46
bool IsGroup() const
static Mac48Address GetBroadcast()
bool IsBroadcast() const
Implement the header for management frames of type association request.
Definition: mgt-headers.h:54
Implement the header for management frames of type association and reassociation response.
Definition: mgt-headers.h:446
void SetHeCapabilities(const HeCapabilities &heCapabilities)
Set the HE capabilities.
const std::optional< MultiLinkElement > & GetMultiLinkElement() const
Return the Multi-Link Element information element, if present.
StatusCode GetStatusCode()
Return the status code.
void SetHtOperation(const HtOperation &htOperation)
Set the HT operation.
void SetMuEdcaParameterSet(const MuEdcaParameterSet &muEdcaParameterSet)
Set the MU EDCA Parameter Set.
void SetEdcaParameterSet(const EdcaParameterSet &edcaParameterSet)
Set the EDCA Parameter Set.
void SetEhtCapabilities(const EhtCapabilities &ehtCapabilities)
Set the EHT capabilities.
void SetStatusCode(StatusCode code)
Set the status code.
void SetVhtOperation(const VhtOperation &vhtOperation)
Set the VHT operation.
void SetHeOperation(const HeOperation &heOperation)
Set the HE operation.
void SetCapabilities(const CapabilityInformation &capabilities)
Set the Capability information.
void SetVhtCapabilities(const VhtCapabilities &vhtCapabilities)
Set the VHT capabilities.
void SetSupportedRates(const SupportedRates &rates)
Set the supported rates.
void SetExtendedCapabilities(const ExtendedCapabilities &extendedCapabilities)
Set the extended capabilities.
void SetHtCapabilities(const HtCapabilities &htCapabilities)
Set the HT capabilities.
void SetMultiLinkElement(const MultiLinkElement &multiLinkElement)
Set the Multi-Link Element information element.
void SetErpInformation(const ErpInformation &erpInformation)
Set the ERP information.
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:1222
Implement the header for management frames of type probe request.
Definition: mgt-headers.h:736
const Ssid & GetSsid() const
Return the Service Set Identifier (SSID).
Definition: mgt-headers.cc:53
Implement the header for management frames of type probe response.
Definition: mgt-headers.h:885
void SetVhtOperation(const VhtOperation &vhtOperation)
Set the VHT operation.
Definition: mgt-headers.cc:418
void SetHtOperation(const HtOperation &htOperation)
Set the HT operation.
Definition: mgt-headers.cc:382
void SetDsssParameterSet(const DsssParameterSet &dsssParameterSet)
Set the DSSS Parameter Set.
Definition: mgt-headers.cc:520
void SetCapabilities(const CapabilityInformation &capabilities)
Set the Capability information.
Definition: mgt-headers.cc:328
void SetReducedNeighborReport(const ReducedNeighborReport &reducedNeighborReport)
Set the Reduced Neighbor Report information element.
Definition: mgt-headers.cc:580
void SetEhtCapabilities(const EhtCapabilities &ehtCapabilities)
Set the EHT capabilities.
Definition: mgt-headers.cc:472
void SetVhtCapabilities(const VhtCapabilities &vhtCapabilities)
Set the VHT capabilities.
Definition: mgt-headers.cc:400
void SetHtCapabilities(const HtCapabilities &htCapabilities)
Set the HT capabilities.
Definition: mgt-headers.cc:364
void SetSsid(const Ssid &ssid)
Set the Service Set Identifier (SSID).
Definition: mgt-headers.cc:490
void SetSupportedRates(const SupportedRates &rates)
Set the supported rates.
Definition: mgt-headers.cc:508
void SetHeOperation(const HeOperation &heOperation)
Set the HE operation.
Definition: mgt-headers.cc:454
void SetErpInformation(const ErpInformation &erpInformation)
Set the ERP information.
Definition: mgt-headers.cc:538
void SetExtendedCapabilities(const ExtendedCapabilities &extendedCapabilities)
Set the extended capabilities.
Definition: mgt-headers.cc:346
void SetBeaconIntervalUs(uint64_t us)
Set the beacon interval in microseconds unit.
Definition: mgt-headers.cc:502
void SetEdcaParameterSet(const EdcaParameterSet &edcaParameterSet)
Set the EDCA Parameter Set.
Definition: mgt-headers.cc:556
void SetHeCapabilities(const HeCapabilities &heCapabilities)
Set the HE capabilities.
Definition: mgt-headers.cc:436
void SetMuEdcaParameterSet(const MuEdcaParameterSet &muEdcaParameterSet)
Set the MU EDCA Parameter Set.
Definition: mgt-headers.cc:568
void SetMultiLinkElement(const MultiLinkElement &multiLinkElement)
Set the Multi-Link Element information element.
Definition: mgt-headers.cc:592
Implement the header for management frames of type reassociation request.
Definition: mgt-headers.h:247
The MU EDCA Parameter Set.
void SetMuCwMin(uint8_t aci, uint16_t cwMin)
Set the ECWmin subfield of the ECWmin/ECWmax field in the MU AC Parameter Record field corresponding ...
void SetMuEdcaTimer(uint8_t aci, Time timer)
Set the MU EDCA Timer field in the MU AC Parameter Record field corresponding to the given AC Index (...
void SetMuAifsn(uint8_t aci, uint8_t aifsn)
Set the AIFSN subfield of the ACI/AIFSN field in the MU AC Parameter Record field corresponding to th...
void SetQosInfo(uint8_t qosInfo)
Set the QoS Info field in the MuEdcaParameterSet information element.
Time GetMuEdcaTimer(uint8_t aci) const
Get the MU EDCA Timer value encoded in the MU AC Parameter Record field corresponding to the given AC...
void SetMuCwMax(uint8_t aci, uint16_t cwMax)
Set the ECWmax subfield of the ECWmin/ECWmax field in the MU AC Parameter Record field corresponding ...
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:369
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
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
uint8_t GetAifsn(uint8_t linkId) const override
For the given link, return the number of slots that make up an AIFS according to the EDCA Parameter S...
Definition: qos-txop.cc:245
uint32_t GetMinCw(uint8_t linkId) const override
For the given link, return the minimum contention window size from the EDCA Parameter Set or the MU E...
Definition: qos-txop.cc:223
uint32_t GetMaxCw(uint8_t linkId) const override
For the given link, return the maximum contention window size from the EDCA Parameter Set or the MU E...
Definition: qos-txop.cc:234
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
The Reduced Neighbor Report element.
std::size_t GetNNbrApInfoFields() const
Get the number of Neighbor AP Information fields.
void SetMldParameters(std::size_t nbrApInfoId, std::size_t index, uint8_t mldId, uint8_t linkId, uint8_t changeSequence)
Set the MLD Parameters subfield of the i-th TBTT Information field of the given Neighbor AP Informati...
void SetShortSsid(std::size_t nbrApInfoId, std::size_t index, uint32_t shortSsid)
Set the Short SSID field of the i-th TBTT Information field of the given Neighbor AP Information fiel...
void SetBssid(std::size_t nbrApInfoId, std::size_t index, Mac48Address bssid)
Set the BSSID field of the i-th TBTT Information field of the given Neighbor AP Information field.
void SetPsd20MHz(std::size_t nbrApInfoId, std::size_t index, uint8_t psd20MHz)
Set the 20 MHz PSD field of the i-th TBTT Information field of the given Neighbor AP Information fiel...
void AddNbrApInfoField()
Add a Neighbor AP Information field.
void SetBssParameters(std::size_t nbrApInfoId, std::size_t index, uint8_t bssParameters)
Set the BSS Parameters field of the i-th TBTT Information field of the given Neighbor AP Information ...
void AddTbttInformationField(std::size_t nbrApInfoId)
Add a TBTT Information fields to the TBTT Information Set field of the given Neighbor AP Information ...
void SetOperatingChannel(std::size_t nbrApInfoId, const WifiPhyOperatingChannel &channel)
Set the Operating Class and the Channel Number fields of the given Neighbor AP Information field base...
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
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
Status code for association response.
Definition: status-code.h:32
bool IsSuccess() const
Return whether the status code is success.
Definition: status-code.cc:42
void SetFailure()
Set success bit to 1 (failure).
Definition: status-code.cc:36
void SetSuccess()
Set success bit to 0 (success).
Definition: status-code.cc:30
Hold variables of type string.
Definition: string.h:42
The Supported Rates Information Element.
void SetBasicRate(uint64_t bs)
Set the given rate to basic rates.
void AddBssMembershipSelectorRate(uint64_t bs)
Add a special value to the supported rate set, corresponding to a BSS membership selector.
uint8_t GetNRates() const
Return the number of supported rates.
void AddSupportedRate(uint64_t bs)
Add the given rate to the supported rates.
bool IsSupportedRate(uint64_t bs) const
Check if the given rate is supported.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
int64_t GetMicroSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:412
AttributeValue implementation for Time.
Definition: nstime.h:1425
Time Get() const
Definition: time.cc:532
Time GetTxopLimit() const
Return the TXOP limit.
Definition: txop.cc:473
Ptr< WifiMacQueue > GetWifiMacQueue() const
Return the packet queue associated with this Txop.
Definition: txop.cc:220
virtual void SetWifiMac(const Ptr< WifiMac > mac)
Set the wifi MAC this Txop is associated to.
Definition: txop.cc:195
void SetMaxCws(std::vector< uint32_t > maxCws)
Set the maximum contention window size for each link.
Definition: txop.cc:262
void SetTxMiddle(const Ptr< MacTxMiddle > txMiddle)
Set MacTxMiddle this Txop is associated to.
Definition: txop.cc:188
void SetMinCws(std::vector< uint32_t > minCws)
Set the minimum contention window size for each link.
Definition: txop.cc:233
void SetAifsns(std::vector< uint8_t > aifsns)
Set the number of slots that make up an AIFS for each link.
Definition: txop.cc:359
virtual void Queue(Ptr< Packet > packet, const WifiMacHeader &hdr)
Definition: txop.cc:505
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
uint64_t Get() const
Definition: uinteger.cc:37
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
The VHT Operation Information Element.
Definition: vht-operation.h:36
void SetMaxVhtMcsPerNss(uint8_t nss, uint8_t maxVhtMcs)
Set the Basic VHT-MCS and NSS field in the VHT Operation information element by specifying the tuple ...
void SetChannelWidth(uint8_t channelWidth)
Set the Channel Width field in the VHT Operation information element.
void SetChannelCenterFrequencySegment1(uint8_t channelCenterFrequencySegment1)
Set the Channel Center Frequency Segment 1 field in the VHT Operation information element.
void SetChannelCenterFrequencySegment0(uint8_t channelCenterFrequencySegment0)
Set the Channel Center Frequency Segment 0 field in the VHT Operation information element.
Implements the IEEE 802.11 MAC header.
uint8_t GetQosTid() const
Return the Traffic ID of a QoS header.
bool IsAssocReq() const
Return true if the header is an Association Request header.
void SetQosAckPolicy(QosAckPolicy policy)
Set the QoS Ack policy in the QoS control field.
bool IsProbeReq() const
Return true if the header is a Probe Request header.
bool IsQosAmsdu() const
Check if the A-MSDU present bit is set in the QoS control field.
Mac48Address GetAddr3() const
Return the address in the Address 3 field.
bool IsAssocResp() const
Return true if the header is an Association Response header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
bool IsDisassociation() const
Return true if the header is a Disassociation header.
void SetQosTxopLimit(uint8_t txop)
Set TXOP limit in the QoS control field.
WifiMacType GetType() const
Return the type (enum WifiMacType)
bool IsMgt() const
Return true if the Type is Management.
void SetNoOrder()
Unset order bit in the frame control field.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetQosNoAmsdu()
Set that A-MSDU is not present.
void SetType(WifiMacType type, bool resetToDsFromDs=true)
Set Type/Subtype values with the correct values depending on the given type.
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 IsReassocReq() const
Return true if the header is a Reassociation Request header.
void SetQosTid(uint8_t tid)
Set the TID for the QoS header.
bool IsData() const
Return true if the Type is DATA.
void SetQosNoEosp()
Un-set the end of service period (EOSP) bit in the QoS control field.
bool IsReassocResp() const
Return true if the header is a Reassociation Response header.
void SetDsFrom()
Set the From DS bit in the Frame Control field.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
bool IsQosData() const
Return true if the Type is DATA and Subtype is one of the possible values for QoS Data.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
void SetDsNotTo()
Un-set the To DS bit in the Frame Control field.
base class for all MAC-level wifi objects.
Definition: wifi-mac.h:92
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:835
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
Definition: wifi-mac.cc:523
Ptr< HeConfiguration > GetHeConfiguration() const
Definition: wifi-mac.cc:1250
Ptr< Txop > GetTxop() const
Accessor for the Txop object.
Definition: wifi-mac.cc:483
VhtCapabilities GetVhtCapabilities(uint8_t linkId) const
Return the VHT capabilities of the device for the given link.
Definition: wifi-mac.cc:1435
bool GetQosSupported() const
Return whether the device supports QoS.
Definition: wifi-mac.cc:1011
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:901
void DoInitialize() override
Initialize() implementation.
Definition: wifi-mac.cc:352
virtual void ConfigureStandard(WifiStandard standard)
Definition: wifi-mac.cc:723
Ssid GetSsid() const
Definition: wifi-mac.cc:455
bool GetErpSupported(uint8_t linkId) const
Return whether the device supports ERP on the given link.
Definition: wifi-mac.cc:1017
bool GetHtSupported() const
Return whether the device supports HT.
Definition: wifi-mac.cc:1262
Ptr< QosTxop > GetVOQueue() const
Accessor for the AC_VO channel access function.
Definition: wifi-mac.cc:511
void SetTypeOfStation(TypeOfStation type)
This method is invoked by a subclass to specify what type of station it is implementing.
Definition: wifi-mac.cc:410
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Definition: wifi-mac.cc:949
bool GetEhtSupported() const
Return whether the device supports EHT.
Definition: wifi-mac.cc:1281
bool GetHeSupported() const
Return whether the device supports HE.
Definition: wifi-mac.cc:1275
HtCapabilities GetHtCapabilities(uint8_t linkId) const
Return the HT capabilities of the device for the given link.
Definition: wifi-mac.cc:1378
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:907
bool GetVhtSupported(uint8_t linkId) const
Return whether the device supports VHT on the given link.
Definition: wifi-mac.cc:1268
Ptr< MacTxMiddle > m_txMiddle
TX middle (aggregation etc.)
Definition: wifi-mac.h:639
Ptr< HtConfiguration > GetHtConfiguration() const
Definition: wifi-mac.cc:1238
ExtendedCapabilities GetExtendedCapabilities() const
Return the extended capabilities of the device.
Definition: wifi-mac.cc:1367
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:535
bool GetShortSlotTimeSupported() const
Definition: wifi-mac.cc:1061
void NotifyRxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:594
virtual void SetLinkUpCallback(Callback< void > linkUp)
Definition: wifi-mac.cc:1080
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:881
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
Definition: wifi-mac.cc:1105
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:1112
Mac48Address GetAddress() const
Definition: wifi-mac.cc:442
EhtCapabilities GetEhtCapabilities(uint8_t linkId) const
Return the EHT capabilities of the device for the given link.
Definition: wifi-mac.cc:1572
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: wifi-mac.cc:893
HeCapabilities GetHeCapabilities(uint8_t linkId) const
Return the HE capabilities of the device for the given link.
Definition: wifi-mac.cc:1516
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition: wifi-mac.cc:489
void NotifyTxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:576
void DoDispose() override
Destructor implementation.
Definition: wifi-mac.cc:368
bool GetDsssSupported(uint8_t linkId) const
Return whether the device supports DSSS on the given link.
Definition: wifi-mac.cc:1041
represent a single transmission mode
Definition: wifi-mode.h:50
std::string GetUniqueName() const
Definition: wifi-mode.cc:148
uint64_t GetDataRate(uint16_t channelWidth, uint16_t guardInterval, uint8_t nss) const
Definition: wifi-mode.cc:122
uint8_t GetMcsValue() const
Definition: wifi-mode.cc:163
uint8_t GetMaxSupportedRxSpatialStreams() const
Definition: wifi-phy.cc:1237
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition: wifi-phy.cc:734
const WifiPhyOperatingChannel & GetOperatingChannel() const
Get a const reference to the operating channel.
Definition: wifi-phy.cc:962
void SetShortSlotTimeEnabled(bool enable)
Enable or disable short slot time.
void AddBasicMode(WifiMode mode)
Invoked in a STA upon association to store the set of rates which belong to the BSSBasicRateSet of th...
uint16_t GetAssociationId(Mac48Address remoteAddress) const
Get the AID of a remote station.
uint8_t GetNBasicModes() const
Return the number of basic modes we support.
void SetUseNonErpProtection(bool enable)
Enable or disable protection for non-ERP stations.
std::optional< Mac48Address > GetAffiliatedStaAddress(const Mac48Address &mldAddress) const
Get the address of the remote station operating on this link and affiliated with the MLD having the g...
void SetShortPreambleEnabled(bool enable)
Enable or disable short PHY preambles.
void SetMldAddress(const Mac48Address &address, const Mac48Address &mldAddress)
Set the address of the MLD the given station is affiliated with.
void RecordGotAssocTxOk(Mac48Address address)
Records that we got an ACK for the association response we sent.
WifiMode GetBasicMode(uint8_t i) const
Return a basic mode from the set of basic modes.
void RecordDisassociated(Mac48Address address)
Records that the STA was disassociated.
void RecordGotAssocTxFailed(Mac48Address address)
Records that we missed an ACK for the association response we sent.
std::optional< Mac48Address > GetMldAddress(const Mac48Address &address) const
Get the address of the MLD the given station is affiliated with, if any.
bool IsWaitAssocTxOk(Mac48Address address) const
Return whether we are waiting for an ACK for the association response we sent.
#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:230
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1426
#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:160
#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_NOARGS()
Output the name of the function.
#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:45
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1362
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
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.
WifiMacDropReason
The reason why an MPDU was dropped.
Definition: wifi-mac.h:73
uint8_t QosUtilsGetTidForPacket(Ptr< const Packet > packet)
If a QoS tag is attached to the packet, returns a value < 8.
Definition: qos-utils.cc:158
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:74
@ WIFI_STANDARD_80211ac
@ WIFI_MOD_CLASS_HR_DSSS
HR/DSSS (Clause 16)
@ 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
Best Effort.
Definition: qos-utils.h:76
@ AC_VO
Voice.
Definition: qos-utils.h:82
@ AC_VI
Video.
Definition: qos-utils.h:80
@ AC_BK
Background.
Definition: qos-utils.h:78
@ AC_BEACON
Beacon queue.
Definition: qos-utils.h:86
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:488
@ AP
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:691
std::variant< std::reference_wrapper< MgtAssocRequestHeader >, std::reference_wrapper< MgtReassocRequestHeader > > AssocReqRefVariant
variant holding a reference to a (Re)Association Request
Definition: ap-wifi-mac.h:53
@ NO_PROTECTION
Definition: ht-operation.h:37
@ MIXED_MODE_PROTECTION
Definition: ht-operation.h:40
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
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
WifiMacType
Combination of valid MAC header type/subtype.
@ WIFI_MAC_MGT_BEACON
@ WIFI_MAC_MGT_ASSOCIATION_RESPONSE
@ WIFI_MAC_MGT_PROBE_RESPONSE
@ WIFI_MAC_DATA
@ WIFI_MAC_MGT_REASSOCIATION_RESPONSE
@ WIFI_MAC_QOSDATA
std::pair< Mac48Address, uint8_t > WifiAddressTidPair
(MAC address, TID) pair
Definition: qos-utils.h:33
ssid
Definition: third.py:86
phy
Definition: third.py:82