A Discrete-Event Network Simulator
API
sta-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 "sta-wifi-mac.h"
23 
24 #include "channel-access-manager.h"
25 #include "frame-exchange-manager.h"
26 #include "mgt-headers.h"
27 #include "qos-txop.h"
28 #include "snr-tag.h"
29 #include "wifi-assoc-manager.h"
30 #include "wifi-net-device.h"
31 #include "wifi-phy.h"
32 
33 #include "ns3/he-configuration.h"
34 #include "ns3/ht-configuration.h"
35 #include "ns3/log.h"
36 #include "ns3/packet.h"
37 #include "ns3/pointer.h"
38 #include "ns3/random-variable-stream.h"
39 #include "ns3/simulator.h"
40 #include "ns3/string.h"
41 
42 #include <numeric>
43 
44 namespace ns3
45 {
46 
47 NS_LOG_COMPONENT_DEFINE("StaWifiMac");
48 
49 NS_OBJECT_ENSURE_REGISTERED(StaWifiMac);
50 
51 TypeId
53 {
54  static TypeId tid =
55  TypeId("ns3::StaWifiMac")
56  .SetParent<WifiMac>()
57  .SetGroupName("Wifi")
58  .AddConstructor<StaWifiMac>()
59  .AddAttribute("ProbeRequestTimeout",
60  "The duration to actively probe the channel.",
61  TimeValue(Seconds(0.05)),
64  .AddAttribute("WaitBeaconTimeout",
65  "The duration to dwell on a channel while passively scanning for beacon",
66  TimeValue(MilliSeconds(120)),
69  .AddAttribute("AssocRequestTimeout",
70  "The interval between two consecutive association request attempts.",
71  TimeValue(Seconds(0.5)),
74  .AddAttribute("MaxMissedBeacons",
75  "Number of beacons which much be consecutively missed before "
76  "we attempt to restart association.",
77  UintegerValue(10),
79  MakeUintegerChecker<uint32_t>())
80  .AddAttribute(
81  "ActiveProbing",
82  "If true, we send probe requests. If false, we don't."
83  "NOTE: if more than one STA in your simulation is using active probing, "
84  "you should enable it at a different simulation time for each STA, "
85  "otherwise all the STAs will start sending probes at the same time resulting in "
86  "collisions. "
87  "See bug 1060 for more info.",
88  BooleanValue(false),
91  .AddAttribute("ProbeDelay",
92  "Delay (in microseconds) to be used prior to transmitting a "
93  "Probe frame during active scanning.",
94  StringValue("ns3::UniformRandomVariable[Min=50.0|Max=250.0]"),
96  MakePointerChecker<RandomVariableStream>())
97  .AddTraceSource("Assoc",
98  "Associated with an access point. If this is an MLD that associated "
99  "with an AP MLD, the AP MLD address is provided.",
101  "ns3::Mac48Address::TracedCallback")
102  .AddTraceSource("LinkSetupCompleted",
103  "A link was setup in the context of ML setup with an AP MLD. "
104  "Provides ID of the setup link and AP MAC address",
106  "ns3::StaWifiMac::LinkSetupCallback")
107  .AddTraceSource("DeAssoc",
108  "Association with an access point lost. If this is an MLD "
109  "that disassociated with an AP MLD, the AP MLD address is provided.",
111  "ns3::Mac48Address::TracedCallback")
112  .AddTraceSource("LinkSetupCanceled",
113  "A link setup in the context of ML setup with an AP MLD was torn down. "
114  "Provides ID of the setup link and AP MAC address",
116  "ns3::StaWifiMac::LinkSetupCallback")
117  .AddTraceSource("BeaconArrival",
118  "Time of beacons arrival from associated AP",
120  "ns3::Time::TracedCallback")
121  .AddTraceSource("ReceivedBeaconInfo",
122  "Information about every received Beacon frame",
124  "ns3::ApInfo::TracedCallback");
125  return tid;
126 }
127 
129  : m_state(UNASSOCIATED),
130  m_aid(0),
131  m_assocRequestEvent()
132 {
133  NS_LOG_FUNCTION(this);
134 
135  // Let the lower layers know that we are acting as a non-AP STA in
136  // an infrastructure BSS.
138 }
139 
140 void
142 {
143  NS_LOG_FUNCTION(this);
144  StartScanning();
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION(this);
151  if (m_assocManager)
152  {
153  m_assocManager->Dispose();
154  }
155  m_assocManager = nullptr;
157 }
158 
160 {
161  NS_LOG_FUNCTION(this);
162 }
163 
165 {
167 }
168 
169 std::unique_ptr<WifiMac::LinkEntity>
171 {
172  return std::make_unique<StaLinkEntity>();
173 }
174 
176 StaWifiMac::GetLink(uint8_t linkId) const
177 {
178  return static_cast<StaLinkEntity&>(WifiMac::GetLink(linkId));
179 }
180 
181 int64_t
183 {
184  NS_LOG_FUNCTION(this << stream);
185  m_probeDelay->SetStream(stream);
186  return 1;
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION(this << assocManager);
193  m_assocManager = assocManager;
194  m_assocManager->SetStaWifiMac(this);
195 }
196 
197 uint16_t
199 {
200  NS_ASSERT_MSG(IsAssociated(), "This station is not associated to any AP");
201  return m_aid;
202 }
203 
204 void
206 {
207  NS_LOG_FUNCTION(this << enable);
208  m_activeProbing = enable;
209  if (m_state == SCANNING)
210  {
211  NS_LOG_DEBUG("STA is still scanning, reset scanning process");
212  StartScanning();
213  }
214 }
215 
216 bool
218 {
219  return m_activeProbing;
220 }
221 
222 void
223 StaWifiMac::SetWifiPhys(const std::vector<Ptr<WifiPhy>>& phys)
224 {
225  NS_LOG_FUNCTION(this);
226  WifiMac::SetWifiPhys(phys);
227  for (auto& phy : phys)
228  {
229  phy->SetCapabilitiesChangedCallback(
231  }
232 }
233 
235 StaWifiMac::GetCurrentChannel(uint8_t linkId) const
236 {
237  auto phy = GetWifiPhy(linkId);
238  uint16_t width = phy->GetOperatingChannel().IsOfdm() ? 20 : phy->GetChannelWidth();
239  uint8_t ch = phy->GetOperatingChannel().GetPrimaryChannelNumber(width, phy->GetStandard());
240  return {ch, phy->GetPhyBand()};
241 }
242 
243 void
245 {
246  NS_LOG_FUNCTION(this);
247  WifiMacHeader hdr;
250  hdr.SetAddr2(GetAddress());
252  hdr.SetDsNotFrom();
253  hdr.SetDsNotTo();
254  Ptr<Packet> packet = Create<Packet>();
255  MgtProbeRequestHeader probe;
256  probe.SetSsid(GetSsid());
258  if (GetHtSupported())
259  {
262  }
264  {
266  }
267  if (GetHeSupported())
268  {
270  }
271  if (GetEhtSupported())
272  {
274  }
275  packet->AddHeader(probe);
276 
277  if (!GetQosSupported())
278  {
279  GetTxop()->Queue(packet, hdr);
280  }
281  // "A QoS STA that transmits a Management frame determines access category used
282  // for medium access in transmission of the Management frame as follows
283  // (If dot11QMFActivated is false or not present)
284  // — If the Management frame is individually addressed to a non-QoS STA, category
285  // AC_BE should be selected.
286  // — If category AC_BE was not selected by the previous step, category AC_VO
287  // shall be selected." (Sec. 10.2.3.2 of 802.11-2020)
288  else
289  {
290  GetVOQueue()->Queue(packet, hdr);
291  }
292 }
293 
294 std::variant<MgtAssocRequestHeader, MgtReassocRequestHeader>
295 StaWifiMac::GetAssociationRequest(bool isReassoc, uint8_t linkId) const
296 {
297  NS_LOG_FUNCTION(this << isReassoc << +linkId);
298 
299  std::variant<MgtAssocRequestHeader, MgtReassocRequestHeader> mgtFrame;
300 
301  if (isReassoc)
302  {
303  MgtReassocRequestHeader reassoc;
304  reassoc.SetCurrentApAddress(GetBssid(linkId));
305  mgtFrame = std::move(reassoc);
306  }
307  else
308  {
309  mgtFrame = MgtAssocRequestHeader();
310  }
311 
312  // lambda to set the fields of the (Re)Association Request
313  auto fill = [&](auto&& frame) {
314  frame.SetSsid(GetSsid());
315  frame.SetSupportedRates(GetSupportedRates(linkId));
316  frame.SetCapabilities(GetCapabilities(linkId));
317  frame.SetListenInterval(0);
318  if (GetHtSupported())
319  {
320  frame.SetExtendedCapabilities(GetExtendedCapabilities());
321  frame.SetHtCapabilities(GetHtCapabilities(linkId));
322  }
323  if (GetVhtSupported(linkId))
324  {
325  frame.SetVhtCapabilities(GetVhtCapabilities(linkId));
326  }
327  if (GetHeSupported())
328  {
329  frame.SetHeCapabilities(GetHeCapabilities(linkId));
330  }
331  if (GetEhtSupported())
332  {
333  frame.SetEhtCapabilities(GetEhtCapabilities(linkId));
334  }
335  };
336 
337  std::visit(fill, mgtFrame);
338  return mgtFrame;
339 }
340 
342 StaWifiMac::GetMultiLinkElement(bool isReassoc, uint8_t linkId) const
343 {
344  NS_LOG_FUNCTION(this << isReassoc << +linkId);
345 
349  // The Common info field of the Basic Multi-Link element carried in the (Re)Association
350  // Request frame shall include the MLD MAC address, the MLD Capabilities and Operations,
351  // and the EML Capabilities subfields, and shall not include the Link ID Info, the BSS
352  // Parameters Change Count, and the Medium Synchronization Delay Information subfields
353  // (Sec. 35.3.5.4 of 802.11be D2.0)
354  // TODO Add the MLD Capabilities and Operations and the EML Capabilities subfields
355  multiLinkElement.SetMldMacAddress(GetAddress());
356  // For each requested link in addition to the link on which the (Re)Association Request
357  // frame is transmitted, the Link Info field of the Basic Multi-Link element carried
358  // in the (Re)Association Request frame shall contain the corresponding Per-STA Profile
359  // subelement(s).
360  for (uint8_t index = 0; index < GetNLinks(); index++)
361  {
362  auto& link = GetLink(index);
363  if (index != linkId && link.apLinkId.has_value())
364  {
365  multiLinkElement.AddPerStaProfileSubelement();
366  auto& perStaProfile = multiLinkElement.GetPerStaProfile(
367  multiLinkElement.GetNPerStaProfileSubelements() - 1);
368  // The Link ID subfield of the STA Control field of the Per-STA Profile subelement
369  // for the corresponding non-AP STA that requests a link for multi-link (re)setup
370  // with the AP MLD is set to the link ID of the AP affiliated with the AP MLD that
371  // is operating on that link. The link ID is obtained during multi-link discovery
372  perStaProfile.SetLinkId(link.apLinkId.value());
373  // For each Per-STA Profile subelement included in the Link Info field, the
374  // Complete Profile subfield of the STA Control field shall be set to 1
375  perStaProfile.SetCompleteProfile();
376  // The MAC Address Present subfield indicates the presence of the STA MAC Address
377  // subfield in the STA Info field and is set to 1 if the STA MAC Address subfield
378  // is present in the STA Info field; otherwise set to 0. An STA sets this subfield
379  // to 1 when the element carries complete profile.
380  perStaProfile.SetStaMacAddress(link.feManager->GetAddress());
381  perStaProfile.SetAssocRequest(GetAssociationRequest(isReassoc, index));
382  }
383  }
384 
385  return multiLinkElement;
386 }
387 
388 void
390 {
391  // find the link where the (Re)Association Request has to be sent
392  uint8_t linkId = 0;
393  while (linkId < GetNLinks())
394  {
395  if (GetLink(linkId).sendAssocReq)
396  {
397  break;
398  }
399  linkId++;
400  }
401  NS_ABORT_MSG_IF(linkId == GetNLinks(), "No link selected to send the (Re)Association Request");
402  auto& link = GetLink(linkId);
403  NS_ABORT_MSG_IF(!link.bssid.has_value(),
404  "No BSSID set for the link on which the (Re)Association Request is to be sent");
405 
406  NS_LOG_FUNCTION(this << *link.bssid << isReassoc);
407  WifiMacHeader hdr;
409  hdr.SetAddr1(*link.bssid);
410  hdr.SetAddr2(link.feManager->GetAddress());
411  hdr.SetAddr3(*link.bssid);
412  hdr.SetDsNotFrom();
413  hdr.SetDsNotTo();
414  Ptr<Packet> packet = Create<Packet>();
415 
416  auto frame = GetAssociationRequest(isReassoc, linkId);
417 
418  // include a Multi-Link Element if this device has multiple links (independently
419  // of how many links will be setup) and the AP is a multi-link device
420  if (GetNLinks() > 1 &&
421  GetWifiRemoteStationManager(linkId)->GetMldAddress(*link.bssid).has_value())
422  {
423  auto addMle = [&](auto&& frame) {
424  frame.SetMultiLinkElement(GetMultiLinkElement(isReassoc, linkId));
425  };
426  std::visit(addMle, frame);
427  }
428 
429  if (!isReassoc)
430  {
431  packet->AddHeader(std::get<MgtAssocRequestHeader>(frame));
432  }
433  else
434  {
435  packet->AddHeader(std::get<MgtReassocRequestHeader>(frame));
436  }
437 
438  if (!GetQosSupported())
439  {
440  GetTxop()->Queue(packet, hdr);
441  }
442  // "A QoS STA that transmits a Management frame determines access category used
443  // for medium access in transmission of the Management frame as follows
444  // (If dot11QMFActivated is false or not present)
445  // — If the Management frame is individually addressed to a non-QoS STA, category
446  // AC_BE should be selected.
447  // — If category AC_BE was not selected by the previous step, category AC_VO
448  // shall be selected." (Sec. 10.2.3.2 of 802.11-2020)
449  else if (!GetWifiRemoteStationManager(linkId)->GetQosSupported(*link.bssid))
450  {
451  GetBEQueue()->Queue(packet, hdr);
452  }
453  else
454  {
455  GetVOQueue()->Queue(packet, hdr);
456  }
457 
459  {
461  }
464 }
465 
466 void
468 {
469  NS_LOG_FUNCTION(this);
470  switch (m_state)
471  {
472  case ASSOCIATED:
473  return;
474  break;
475  case SCANNING:
476  /* we have initiated active or passive scanning, continue to wait
477  and gather beacons or probe responses until the scanning timeout
478  */
479  break;
480  case UNASSOCIATED:
481  /* we were associated but we missed a bunch of beacons
482  * so we should assume we are not associated anymore.
483  * We try to initiate a scan now.
484  */
485  m_linkDown();
486  StartScanning();
487  break;
488  case WAIT_ASSOC_RESP:
489  /* we have sent an association request so we do not need to
490  re-send an association request right now. We just need to
491  wait until either assoc-request-timeout or until
492  we get an association response.
493  */
494  break;
495  case REFUSED:
496  /* we have sent an association request and received a negative
497  association response. We wait until someone restarts an
498  association with a given SSID.
499  */
500  break;
501  }
502 }
503 
504 void
506 {
507  NS_LOG_FUNCTION(this);
510 
511  WifiScanParams scanParams;
512  scanParams.ssid = GetSsid();
513  for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
514  {
516  (GetWifiPhy(linkId)->HasFixedPhyBand())
519 
520  scanParams.channelList.push_back(channel);
521  }
522  if (m_activeProbing)
523  {
524  scanParams.type = WifiScanParams::ACTIVE;
525  scanParams.probeDelay = MicroSeconds(m_probeDelay->GetValue());
526  scanParams.minChannelTime = scanParams.maxChannelTime = m_probeRequestTimeout;
527  }
528  else
529  {
530  scanParams.type = WifiScanParams::PASSIVE;
531  scanParams.maxChannelTime = m_waitBeaconTimeout;
532  }
533 
534  m_assocManager->StartScanning(std::move(scanParams));
535 }
536 
537 void
538 StaWifiMac::ScanningTimeout(const std::optional<ApInfo>& bestAp)
539 {
540  NS_LOG_FUNCTION(this);
541 
542  if (!bestAp.has_value())
543  {
544  NS_LOG_DEBUG("Exhausted list of candidate AP; restart scanning");
545  StartScanning();
546  return;
547  }
548 
549  NS_LOG_DEBUG("Attempting to associate with AP: " << *bestAp);
550  UpdateApInfo(bestAp->m_frame, bestAp->m_apAddr, bestAp->m_bssid, bestAp->m_linkId);
551  // reset info on links to setup
552  for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
553  {
554  auto& link = GetLink(linkId);
555  link.sendAssocReq = false;
556  link.apLinkId = std::nullopt;
557  link.bssid = std::nullopt;
558  }
559  // send Association Request on the link where the Beacon/Probe Response was received
560  GetLink(bestAp->m_linkId).sendAssocReq = true;
561  GetLink(bestAp->m_linkId).bssid = bestAp->m_bssid;
562  // update info on links to setup (11be MLDs only)
563  for (const auto& [localLinkId, apLinkId] : bestAp->m_setupLinks)
564  {
565  NS_LOG_DEBUG("Setting up link (local ID=" << +localLinkId << ", AP ID=" << +apLinkId
566  << ")");
567  GetLink(localLinkId).apLinkId = apLinkId;
568  if (localLinkId == bestAp->m_linkId)
569  {
570  continue;
571  }
572  auto mldAddress =
573  GetWifiRemoteStationManager(bestAp->m_linkId)->GetMldAddress(bestAp->m_bssid);
574  NS_ABORT_MSG_IF(!mldAddress.has_value(), "AP MLD address not set");
575  auto bssid = GetWifiRemoteStationManager(localLinkId)->GetAffiliatedStaAddress(*mldAddress);
576  NS_ABORT_MSG_IF(!mldAddress.has_value(),
577  "AP link address not set for local link " << +localLinkId);
578  GetLink(localLinkId).bssid = *bssid;
579  }
580  // lambda to get beacon interval from Beacon or Probe Response
581  auto getBeaconInterval = [](auto&& frame) {
582  using T = std::decay_t<decltype(frame)>;
583  if constexpr (std::is_same_v<T, MgtBeaconHeader> ||
584  std::is_same_v<T, MgtProbeResponseHeader>)
585  {
586  return MicroSeconds(frame.GetBeaconIntervalUs());
587  }
588  else
589  {
590  NS_ABORT_MSG("Unexpected frame type");
591  return Seconds(0);
592  }
593  };
594  Time beaconInterval = std::visit(getBeaconInterval, bestAp->m_frame);
595  Time delay = beaconInterval * m_maxMissedBeacons;
596  // restart beacon watchdog for all links to setup
597  for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
598  {
599  if (GetLink(linkId).apLinkId.has_value() || GetNLinks() == 1)
600  {
601  RestartBeaconWatchdog(delay, linkId);
602  }
603  }
605  SendAssociationRequest(false);
606 }
607 
608 void
610 {
611  NS_LOG_FUNCTION(this);
613  SendAssociationRequest(false);
614 }
615 
616 void
618 {
619  NS_LOG_FUNCTION(this << +linkId);
620  auto& link = GetLink(linkId);
621  if (link.beaconWatchdogEnd > Simulator::Now())
622  {
623  if (link.beaconWatchdog.IsRunning())
624  {
625  link.beaconWatchdog.Cancel();
626  }
627  link.beaconWatchdog = Simulator::Schedule(link.beaconWatchdogEnd - Simulator::Now(),
629  this,
630  linkId);
631  return;
632  }
633  NS_LOG_DEBUG("beacon missed");
634  // We need to switch to the UNASSOCIATED state. However, if we are receiving
635  // a frame, wait until the RX is completed (otherwise, crashes may occur if
636  // we are receiving a MU frame because its reception requires the STA-ID)
637  Time delay = Seconds(0);
638  if (GetWifiPhy(linkId)->IsStateRx())
639  {
640  delay = GetWifiPhy(linkId)->GetDelayUntilIdle();
641  }
642  Simulator::Schedule(delay, &StaWifiMac::Disassociated, this, linkId);
643 }
644 
645 void
647 {
648  NS_LOG_FUNCTION(this << +linkId);
649 
650  auto& link = GetLink(linkId);
651  if (link.apLinkId.has_value())
652  {
653  // this is a link setup in an ML setup
654  m_setupCanceled(linkId, GetBssid(linkId));
655  }
656 
657  // disable the given link
658  link.apLinkId = std::nullopt;
659  link.bssid = std::nullopt;
660  link.phy->SetOffMode();
661 
662  for (uint8_t id = 0; id < GetNLinks(); id++)
663  {
664  if (GetLink(id).apLinkId.has_value())
665  {
666  // found an enabled link
667  return;
668  }
669  }
670 
671  NS_LOG_DEBUG("Set state to UNASSOCIATED and start scanning");
673  auto mldAddress = GetWifiRemoteStationManager(linkId)->GetMldAddress(GetBssid(linkId));
674  if (GetNLinks() > 1 && mldAddress.has_value())
675  {
676  // trace the AP MLD address
677  m_deAssocLogger(*mldAddress);
678  }
679  else
680  {
681  m_deAssocLogger(GetBssid(linkId));
682  }
683  m_aid = 0; // reset AID
684  // ensure all links are on
685  for (uint8_t id = 0; id < GetNLinks(); id++)
686  {
687  GetLink(id).phy->ResumeFromOff();
688  }
690 }
691 
692 void
694 {
695  NS_LOG_FUNCTION(this << delay << +linkId);
696  auto& link = GetLink(linkId);
697  link.beaconWatchdogEnd = std::max(Simulator::Now() + delay, link.beaconWatchdogEnd);
698  if (Simulator::GetDelayLeft(link.beaconWatchdog) < delay && link.beaconWatchdog.IsExpired())
699  {
700  NS_LOG_DEBUG("really restart watchdog.");
701  link.beaconWatchdog = Simulator::Schedule(delay, &StaWifiMac::MissedBeacons, this, linkId);
702  }
703 }
704 
705 bool
707 {
708  return m_state == ASSOCIATED;
709 }
710 
711 bool
713 {
714  return m_state == WAIT_ASSOC_RESP;
715 }
716 
717 std::set<uint8_t>
719 {
720  if (!IsAssociated())
721  {
722  return {};
723  }
724 
725  std::set<uint8_t> linkIds;
726  for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
727  {
728  if (GetLink(linkId).bssid)
729  {
730  linkIds.insert(linkId);
731  }
732  }
733  return linkIds;
734 }
735 
738 {
739  auto linkIds = GetSetupLinkIds();
740  NS_ASSERT_MSG(!linkIds.empty(), "Not associated");
741  uint8_t linkId = *linkIds.begin();
742  return GetFrameExchangeManager(linkId)->GetAddress();
743 }
744 
745 bool
747 {
748  return (IsAssociated());
749 }
750 
751 void
753 {
754  NS_LOG_FUNCTION(this << packet << to);
755  if (!CanForwardPacketsTo(to))
756  {
757  NotifyTxDrop(packet);
759  return;
760  }
761  WifiMacHeader hdr;
762 
763  // If we are not a QoS AP then we definitely want to use AC_BE to
764  // transmit the packet. A TID of zero will map to AC_BE (through \c
765  // QosUtilsMapTidToAc()), so we use that as our default here.
766  uint8_t tid = 0;
767 
768  // For now, an AP that supports QoS does not support non-QoS
769  // associations, and vice versa. In future the AP model should
770  // support simultaneously associated QoS and non-QoS STAs, at which
771  // point there will need to be per-association QoS state maintained
772  // by the association state machine, and consulted here.
773  if (GetQosSupported())
774  {
777  hdr.SetQosNoEosp();
778  hdr.SetQosNoAmsdu();
779  // Transmission of multiple frames in the same TXOP is not
780  // supported for now
781  hdr.SetQosTxopLimit(0);
782 
783  // Fill in the QoS control field in the MAC header
784  tid = QosUtilsGetTidForPacket(packet);
785  // Any value greater than 7 is invalid and likely indicates that
786  // the packet had no QoS tag, so we revert to zero, which'll
787  // mean that AC_BE is used.
788  if (tid > 7)
789  {
790  tid = 0;
791  }
792  hdr.SetQosTid(tid);
793  }
794  else
795  {
796  hdr.SetType(WIFI_MAC_DATA);
797  }
798  if (GetQosSupported())
799  {
800  hdr.SetNoOrder(); // explicitly set to 0 for the time being since HT control field is not
801  // yet implemented (set it to 1 when implemented)
802  }
803 
804  // the Receiver Address (RA) and the Transmitter Address (TA) are the MLD addresses only for
805  // non-broadcast data frames exchanged between two MLDs
806  auto linkIds = GetSetupLinkIds();
807  NS_ASSERT(!linkIds.empty());
808  uint8_t linkId = *linkIds.begin();
809  if (const auto apMldAddr = GetWifiRemoteStationManager(linkId)->GetMldAddress(GetBssid(linkId)))
810  {
811  hdr.SetAddr1(*apMldAddr);
812  hdr.SetAddr2(GetAddress());
813  }
814  else
815  {
816  hdr.SetAddr1(GetBssid(linkId));
818  }
819 
820  hdr.SetAddr3(to);
821  hdr.SetDsNotFrom();
822  hdr.SetDsTo();
823 
824  if (GetQosSupported())
825  {
826  // Sanity check that the TID is valid
827  NS_ASSERT(tid < 8);
828  GetQosTxop(tid)->Queue(packet, hdr);
829  }
830  else
831  {
832  GetTxop()->Queue(packet, hdr);
833  }
834 }
835 
836 void
838 {
839  NS_LOG_FUNCTION(this << *mpdu << +linkId);
840  // consider the MAC header of the original MPDU (makes a difference for data frames only)
841  const WifiMacHeader* hdr = &mpdu->GetOriginal()->GetHeader();
842  Ptr<const Packet> packet = mpdu->GetPacket();
843  NS_ASSERT(!hdr->IsCtl());
845  : GetFrameExchangeManager(linkId)->GetAddress();
846  if (hdr->GetAddr3() == myAddr)
847  {
848  NS_LOG_LOGIC("packet sent by us.");
849  return;
850  }
851  if (hdr->GetAddr1() != myAddr && !hdr->GetAddr1().IsGroup())
852  {
853  NS_LOG_LOGIC("packet is not for us");
854  NotifyRxDrop(packet);
855  return;
856  }
857  if (hdr->IsData())
858  {
859  if (!IsAssociated())
860  {
861  NS_LOG_LOGIC("Received data frame while not associated: ignore");
862  NotifyRxDrop(packet);
863  return;
864  }
865  if (!(hdr->IsFromDs() && !hdr->IsToDs()))
866  {
867  NS_LOG_LOGIC("Received data frame not from the DS: ignore");
868  NotifyRxDrop(packet);
869  return;
870  }
871  std::set<Mac48Address> apAddresses; // link addresses of AP
872  for (auto id : GetSetupLinkIds())
873  {
874  apAddresses.insert(GetBssid(id));
875  }
876  if (apAddresses.count(mpdu->GetHeader().GetAddr2()) == 0)
877  {
878  NS_LOG_LOGIC("Received data frame not from the BSS we are associated with: ignore");
879  NotifyRxDrop(packet);
880  return;
881  }
882  if (hdr->IsQosData())
883  {
884  if (hdr->IsQosAmsdu())
885  {
886  NS_ASSERT(apAddresses.count(mpdu->GetHeader().GetAddr3()) != 0);
888  packet = nullptr;
889  }
890  else
891  {
892  ForwardUp(packet, hdr->GetAddr3(), hdr->GetAddr1());
893  }
894  }
895  else if (hdr->HasData())
896  {
897  ForwardUp(packet, hdr->GetAddr3(), hdr->GetAddr1());
898  }
899  return;
900  }
901 
902  switch (hdr->GetType())
903  {
907  // This is a frame aimed at an AP, so we can safely ignore it.
908  NotifyRxDrop(packet);
909  break;
910 
911  case WIFI_MAC_MGT_BEACON:
912  ReceiveBeacon(mpdu, linkId);
913  break;
914 
916  ReceiveProbeResp(mpdu, linkId);
917  break;
918 
921  ReceiveAssocResp(mpdu, linkId);
922  break;
923 
924  default:
925  // Invoke the receive handler of our parent class to deal with any
926  // other frames. Specifically, this will handle Block Ack-related
927  // Management Action frames.
928  WifiMac::Receive(mpdu, linkId);
929  }
930 }
931 
932 void
934 {
935  NS_LOG_FUNCTION(this << *mpdu << +linkId);
936  const WifiMacHeader& hdr = mpdu->GetHeader();
937  NS_ASSERT(hdr.IsBeacon());
938 
939  NS_LOG_DEBUG("Beacon received");
940  MgtBeaconHeader beacon;
941  mpdu->GetPacket()->PeekHeader(beacon);
942  const CapabilityInformation& capabilities = beacon.GetCapabilities();
943  NS_ASSERT(capabilities.IsEss());
944  bool goodBeacon;
945  if (IsWaitAssocResp() || IsAssociated())
946  {
947  // we have to process this Beacon only if sent by the AP we are associated
948  // with or from which we are waiting an Association Response frame
949  auto bssid = GetLink(linkId).bssid;
950  goodBeacon = bssid.has_value() && (hdr.GetAddr3() == *bssid);
951  }
952  else
953  {
954  // we retain this Beacon as candidate AP if the supported rates fit the
955  // configured BSS membership selector
956  goodBeacon = CheckSupportedRates(beacon, linkId);
957  }
958 
959  SnrTag snrTag;
960  bool found = mpdu->GetPacket()->PeekPacketTag(snrTag);
961  NS_ASSERT(found);
962  ApInfo apInfo = {.m_bssid = hdr.GetAddr3(),
963  .m_apAddr = hdr.GetAddr2(),
964  .m_snr = snrTag.Get(),
965  .m_frame = std::move(beacon),
966  .m_channel = {GetCurrentChannel(linkId)},
967  .m_linkId = linkId};
968 
969  if (!m_beaconInfo.IsEmpty())
970  {
971  m_beaconInfo(apInfo);
972  }
973 
974  if (!goodBeacon)
975  {
976  NS_LOG_LOGIC("Beacon is not for us");
977  return;
978  }
979  if (m_state == ASSOCIATED)
980  {
982  Time delay = MicroSeconds(std::get<MgtBeaconHeader>(apInfo.m_frame).GetBeaconIntervalUs() *
984  RestartBeaconWatchdog(delay, linkId);
985  UpdateApInfo(apInfo.m_frame, hdr.GetAddr2(), hdr.GetAddr3(), linkId);
986  }
987  else
988  {
989  NS_LOG_DEBUG("Beacon received from " << hdr.GetAddr2());
990  m_assocManager->NotifyApInfo(std::move(apInfo));
991  }
992 }
993 
994 void
996 {
997  NS_LOG_FUNCTION(this << *mpdu << +linkId);
998  const WifiMacHeader& hdr = mpdu->GetHeader();
999  NS_ASSERT(hdr.IsProbeResp());
1000 
1001  NS_LOG_DEBUG("Probe response received from " << hdr.GetAddr2());
1002  MgtProbeResponseHeader probeResp;
1003  mpdu->GetPacket()->PeekHeader(probeResp);
1004  if (!CheckSupportedRates(probeResp, linkId))
1005  {
1006  return;
1007  }
1008  SnrTag snrTag;
1009  bool found = mpdu->GetPacket()->PeekPacketTag(snrTag);
1010  NS_ASSERT(found);
1011  m_assocManager->NotifyApInfo(ApInfo{.m_bssid = hdr.GetAddr3(),
1012  .m_apAddr = hdr.GetAddr2(),
1013  .m_snr = snrTag.Get(),
1014  .m_frame = std::move(probeResp),
1015  .m_channel = {GetCurrentChannel(linkId)},
1016  .m_linkId = linkId});
1017 }
1018 
1019 void
1021 {
1022  NS_LOG_FUNCTION(this << *mpdu << +linkId);
1023  const WifiMacHeader& hdr = mpdu->GetHeader();
1024  NS_ASSERT(hdr.IsAssocResp() || hdr.IsReassocResp());
1025 
1026  if (m_state != WAIT_ASSOC_RESP)
1027  {
1028  return;
1029  }
1030 
1031  MgtAssocResponseHeader assocResp;
1032  mpdu->GetPacket()->PeekHeader(assocResp);
1034  {
1036  }
1037  if (assocResp.GetStatusCode().IsSuccess())
1038  {
1039  m_aid = assocResp.GetAssociationId();
1040  NS_LOG_DEBUG((hdr.IsReassocResp() ? "reassociation done" : "association completed"));
1041  UpdateApInfo(assocResp, hdr.GetAddr2(), hdr.GetAddr3(), linkId);
1042  NS_ASSERT(GetLink(linkId).bssid.has_value() && *GetLink(linkId).bssid == hdr.GetAddr3());
1043  SetBssid(hdr.GetAddr3(), linkId);
1044  if ((GetNLinks() > 1) && assocResp.GetMultiLinkElement().has_value())
1045  {
1046  // this is an ML setup, trace the MLD address (only once)
1048  m_setupCompleted(linkId, hdr.GetAddr3());
1049  }
1050  else
1051  {
1052  m_assocLogger(hdr.GetAddr3());
1053  }
1055  if (!m_linkUp.IsNull())
1056  {
1057  m_linkUp();
1058  }
1059  }
1060 
1061  // if this is an MLD, check if we can setup (other) links
1062  if (GetNLinks() > 1)
1063  {
1064  // create a list of all local Link IDs. IDs are removed as we find a corresponding
1065  // Per-STA Profile Subelements indicating successful association. Links with
1066  // remaining IDs are not setup
1067  std::list<uint8_t> setupLinks(GetNLinks());
1068  std::iota(setupLinks.begin(), setupLinks.end(), 0);
1069  if (assocResp.GetStatusCode().IsSuccess())
1070  {
1071  setupLinks.remove(linkId);
1072  }
1073 
1074  // if a Multi-Link Element is present, check its content
1075  if (const auto& mle = assocResp.GetMultiLinkElement(); mle.has_value())
1076  {
1077  NS_ABORT_MSG_IF(!GetLink(linkId).apLinkId.has_value(),
1078  "The link on which the Association Response was received "
1079  "is not a link we requested to setup");
1080  NS_ABORT_MSG_IF(*GetLink(linkId).apLinkId != mle->GetLinkIdInfo(),
1081  "The link ID of the AP that transmitted the Association "
1082  "Response does not match the stored link ID");
1084  mle->GetMldMacAddress(),
1085  "The AP MLD MAC address in the received Multi-Link Element does not "
1086  "match the address stored in the station manager for link "
1087  << +linkId);
1088  // process the Per-STA Profile Subelements in the Multi-Link Element
1089  for (std::size_t elem = 0; elem < mle->GetNPerStaProfileSubelements(); elem++)
1090  {
1091  auto& perStaProfile = mle->GetPerStaProfile(elem);
1092  uint8_t apLinkId = perStaProfile.GetLinkId();
1093  uint8_t staLinkid = 0;
1094  while (staLinkid < GetNLinks())
1095  {
1096  if (GetLink(staLinkid).apLinkId == apLinkId)
1097  {
1098  break;
1099  }
1100  staLinkid++;
1101  }
1102  std::optional<Mac48Address> bssid;
1103  NS_ABORT_MSG_IF(staLinkid == GetNLinks() ||
1104  !(bssid = GetLink(staLinkid).bssid).has_value(),
1105  "Setup for AP link ID " << apLinkId << " was not requested");
1106  NS_ABORT_MSG_IF(*bssid != perStaProfile.GetStaMacAddress(),
1107  "The BSSID in the Per-STA Profile for link ID "
1108  << +staLinkid << " does not match the stored BSSID");
1111  perStaProfile.GetStaMacAddress()) != mle->GetMldMacAddress(),
1112  "The AP MLD MAC address in the received Multi-Link Element does not "
1113  "match the address stored in the station manager for link "
1114  << +staLinkid);
1115  // process the Association Response contained in this Per-STA Profile
1116  MgtAssocResponseHeader assoc = perStaProfile.GetAssocResponse();
1117  if (assoc.GetStatusCode().IsSuccess())
1118  {
1119  NS_ABORT_MSG_IF(m_aid != 0 && m_aid != assoc.GetAssociationId(),
1120  "AID should be the same for all the links");
1121  m_aid = assoc.GetAssociationId();
1122  NS_LOG_DEBUG("Setup on link " << staLinkid << " completed");
1123  UpdateApInfo(assoc, *bssid, *bssid, staLinkid);
1124  SetBssid(*bssid, staLinkid);
1125  if (m_state != ASSOCIATED)
1126  {
1127  m_assocLogger(
1128  *GetWifiRemoteStationManager(staLinkid)->GetMldAddress(*bssid));
1129  }
1130  m_setupCompleted(staLinkid, *bssid);
1132  if (!m_linkUp.IsNull())
1133  {
1134  m_linkUp();
1135  }
1136  }
1137  // remove the ID of the link we setup
1138  setupLinks.remove(staLinkid);
1139  }
1140  }
1141  // remaining links in setupLinks are not setup and hence must be disabled
1142  for (const auto& id : setupLinks)
1143  {
1144  GetLink(id).apLinkId = std::nullopt;
1145  GetLink(id).bssid = std::nullopt;
1146  // if at least one link was setup, disable the links that were not setup (if any)
1147  if (m_state == ASSOCIATED)
1148  {
1149  GetLink(id).phy->SetOffMode();
1150  }
1151  }
1152  }
1153 
1154  if (m_state == WAIT_ASSOC_RESP)
1155  {
1156  // if we didn't transition to ASSOCIATED, the request was refused
1157  NS_LOG_DEBUG("association refused");
1158  SetState(REFUSED);
1159  StartScanning();
1160  }
1161 }
1162 
1163 bool
1164 StaWifiMac::CheckSupportedRates(std::variant<MgtBeaconHeader, MgtProbeResponseHeader> frame,
1165  uint8_t linkId)
1166 {
1167  NS_LOG_FUNCTION(this << +linkId);
1168 
1169  // lambda to invoke on the current frame variant
1170  auto check = [&](auto&& mgtFrame) -> bool {
1171  // check supported rates
1172  const SupportedRates& rates = mgtFrame.GetSupportedRates();
1173  for (const auto& selector : GetWifiPhy(linkId)->GetBssMembershipSelectorList())
1174  {
1175  if (!rates.IsBssMembershipSelectorRate(selector))
1176  {
1177  NS_LOG_DEBUG("Supported rates do not fit with the BSS membership selector");
1178  return false;
1179  }
1180  }
1181 
1182  return true;
1183  };
1184 
1185  return std::visit(check, frame);
1186 }
1187 
1188 void
1190  const Mac48Address& apAddr,
1191  const Mac48Address& bssid,
1192  uint8_t linkId)
1193 {
1194  NS_LOG_FUNCTION(this << frame.index() << apAddr << bssid << +linkId);
1195 
1196  // lambda processing Information Elements included in all frame types
1197  auto commonOps = [&](auto&& frame) {
1198  const CapabilityInformation& capabilities = frame.GetCapabilities();
1199  const SupportedRates& rates = frame.GetSupportedRates();
1200  for (const auto& mode : GetWifiPhy(linkId)->GetModeList())
1201  {
1202  if (rates.IsSupportedRate(mode.GetDataRate(GetWifiPhy(linkId)->GetChannelWidth())))
1203  {
1204  GetWifiRemoteStationManager(linkId)->AddSupportedMode(apAddr, mode);
1205  if (rates.IsBasicRate(mode.GetDataRate(GetWifiPhy(linkId)->GetChannelWidth())))
1206  {
1208  }
1209  }
1210  }
1211 
1212  bool isShortPreambleEnabled = capabilities.IsShortPreamble();
1213  if (const auto& erpInformation = frame.GetErpInformation();
1214  erpInformation.has_value() && GetErpSupported(linkId))
1215  {
1216  isShortPreambleEnabled &= !erpInformation->GetBarkerPreambleMode();
1217  if (erpInformation->GetUseProtection() != 0)
1218  {
1220  }
1221  else
1222  {
1224  }
1225  if (capabilities.IsShortSlotTime() == true)
1226  {
1227  // enable short slot time
1228  GetWifiPhy(linkId)->SetSlot(MicroSeconds(9));
1229  }
1230  else
1231  {
1232  // disable short slot time
1233  GetWifiPhy(linkId)->SetSlot(MicroSeconds(20));
1234  }
1235  }
1236  GetWifiRemoteStationManager(linkId)->SetShortPreambleEnabled(isShortPreambleEnabled);
1238  capabilities.IsShortSlotTime());
1239 
1240  if (!GetQosSupported())
1241  {
1242  return;
1243  }
1244  /* QoS station */
1245  bool qosSupported = false;
1246  const auto& edcaParameters = frame.GetEdcaParameterSet();
1247  if (edcaParameters.has_value())
1248  {
1249  qosSupported = true;
1250  // The value of the TXOP Limit field is specified as an unsigned integer, with the least
1251  // significant octet transmitted first, in units of 32 μs.
1253  edcaParameters->GetBeCWmin(),
1254  edcaParameters->GetBeCWmax(),
1255  edcaParameters->GetBeAifsn(),
1256  32 * MicroSeconds(edcaParameters->GetBeTxopLimit()));
1258  edcaParameters->GetBkCWmin(),
1259  edcaParameters->GetBkCWmax(),
1260  edcaParameters->GetBkAifsn(),
1261  32 * MicroSeconds(edcaParameters->GetBkTxopLimit()));
1263  edcaParameters->GetViCWmin(),
1264  edcaParameters->GetViCWmax(),
1265  edcaParameters->GetViAifsn(),
1266  32 * MicroSeconds(edcaParameters->GetViTxopLimit()));
1268  edcaParameters->GetVoCWmin(),
1269  edcaParameters->GetVoCWmax(),
1270  edcaParameters->GetVoAifsn(),
1271  32 * MicroSeconds(edcaParameters->GetVoTxopLimit()));
1272  }
1273  GetWifiRemoteStationManager(linkId)->SetQosSupport(apAddr, qosSupported);
1274 
1275  if (!GetHtSupported())
1276  {
1277  return;
1278  }
1279  /* HT station */
1280  if (const auto& htCapabilities = frame.GetHtCapabilities(); htCapabilities.has_value())
1281  {
1282  if (!htCapabilities->IsSupportedMcs(0))
1283  {
1285  }
1286  else
1287  {
1289  *htCapabilities);
1290  }
1291  }
1292  // TODO: process ExtendedCapabilities
1293  // ExtendedCapabilities extendedCapabilities = frame.GetExtendedCapabilities ();
1294 
1295  // we do not return if VHT is not supported because HE STAs operating in
1296  // the 2.4 GHz band do not support VHT
1297  if (GetVhtSupported(linkId))
1298  {
1299  const auto& vhtCapabilities = frame.GetVhtCapabilities();
1300  // we will always fill in RxHighestSupportedLgiDataRate field at TX, so this can be used
1301  // to check whether it supports VHT
1302  if (vhtCapabilities.has_value() &&
1303  vhtCapabilities->GetRxHighestSupportedLgiDataRate() > 0)
1304  {
1306  *vhtCapabilities);
1307  // const auto& vhtOperation = frame.GetVhtOperation ();
1308  for (const auto& mcs : GetWifiPhy(linkId)->GetMcsList(WIFI_MOD_CLASS_VHT))
1309  {
1310  if (vhtCapabilities->IsSupportedRxMcs(mcs.GetMcsValue()))
1311  {
1312  GetWifiRemoteStationManager(linkId)->AddSupportedMcs(apAddr, mcs);
1313  }
1314  }
1315  }
1316  }
1317 
1318  if (!GetHeSupported())
1319  {
1320  return;
1321  }
1322  /* HE station */
1323  const auto& heCapabilities = frame.GetHeCapabilities();
1324  if (heCapabilities.has_value() && heCapabilities->GetSupportedMcsAndNss() != 0)
1325  {
1326  GetWifiRemoteStationManager(linkId)->AddStationHeCapabilities(apAddr, *heCapabilities);
1327  for (const auto& mcs : GetWifiPhy(linkId)->GetMcsList(WIFI_MOD_CLASS_HE))
1328  {
1329  if (heCapabilities->IsSupportedRxMcs(mcs.GetMcsValue()))
1330  {
1331  GetWifiRemoteStationManager(linkId)->AddSupportedMcs(apAddr, mcs);
1332  }
1333  }
1334  if (const auto& heOperation = frame.GetHeOperation(); heOperation.has_value())
1335  {
1336  GetHeConfiguration()->SetAttribute("BssColor",
1337  UintegerValue(heOperation->GetBssColor()));
1338  }
1339  }
1340 
1341  const auto& muEdcaParameters = frame.GetMuEdcaParameterSet();
1342  if (muEdcaParameters.has_value())
1343  {
1345  muEdcaParameters->GetMuCwMin(AC_BE),
1346  muEdcaParameters->GetMuCwMax(AC_BE),
1347  muEdcaParameters->GetMuAifsn(AC_BE),
1348  muEdcaParameters->GetMuEdcaTimer(AC_BE));
1350  muEdcaParameters->GetMuCwMin(AC_BK),
1351  muEdcaParameters->GetMuCwMax(AC_BK),
1352  muEdcaParameters->GetMuAifsn(AC_BK),
1353  muEdcaParameters->GetMuEdcaTimer(AC_BK));
1355  muEdcaParameters->GetMuCwMin(AC_VI),
1356  muEdcaParameters->GetMuCwMax(AC_VI),
1357  muEdcaParameters->GetMuAifsn(AC_VI),
1358  muEdcaParameters->GetMuEdcaTimer(AC_VI));
1360  muEdcaParameters->GetMuCwMin(AC_VO),
1361  muEdcaParameters->GetMuCwMax(AC_VO),
1362  muEdcaParameters->GetMuAifsn(AC_VO),
1363  muEdcaParameters->GetMuEdcaTimer(AC_VO));
1364  }
1365 
1366  if (!GetEhtSupported())
1367  {
1368  return;
1369  }
1370  /* EHT station */
1371  const auto& ehtCapabilities = frame.GetEhtCapabilities();
1372  // TODO: once we support non constant rate managers, we should add checks here whether EHT
1373  // is supported by the peer
1374  GetWifiRemoteStationManager(linkId)->AddStationEhtCapabilities(apAddr, *ehtCapabilities);
1375  };
1376 
1377  // process Information Elements included in the current frame variant
1378  std::visit(commonOps, frame);
1379 }
1380 
1382 StaWifiMac::GetSupportedRates(uint8_t linkId) const
1383 {
1384  SupportedRates rates;
1385  for (const auto& mode : GetWifiPhy(linkId)->GetModeList())
1386  {
1387  uint64_t modeDataRate = mode.GetDataRate(GetWifiPhy(linkId)->GetChannelWidth());
1388  NS_LOG_DEBUG("Adding supported rate of " << modeDataRate);
1389  rates.AddSupportedRate(modeDataRate);
1390  }
1391  if (GetHtSupported())
1392  {
1393  for (const auto& selector : GetWifiPhy(linkId)->GetBssMembershipSelectorList())
1394  {
1395  rates.AddBssMembershipSelectorRate(selector);
1396  }
1397  }
1398  return rates;
1399 }
1400 
1402 StaWifiMac::GetCapabilities(uint8_t linkId) const
1403 {
1404  CapabilityInformation capabilities;
1405  capabilities.SetShortPreamble(GetWifiPhy(linkId)->GetShortPhyPreambleSupported() ||
1406  GetErpSupported(linkId));
1407  capabilities.SetShortSlotTime(GetShortSlotTimeSupported() && GetErpSupported(linkId));
1408  return capabilities;
1409 }
1410 
1411 void
1413 {
1414  m_state = value;
1415 }
1416 
1417 void
1419  uint32_t cwMin,
1420  uint32_t cwMax,
1421  uint8_t aifsn,
1422  Time txopLimit)
1423 {
1424  Ptr<QosTxop> edca = GetQosTxop(ac);
1425  edca->SetMinCw(cwMin, SINGLE_LINK_OP_ID);
1426  edca->SetMaxCw(cwMax, SINGLE_LINK_OP_ID);
1427  edca->SetAifsn(aifsn, SINGLE_LINK_OP_ID);
1428  edca->SetTxopLimit(txopLimit, SINGLE_LINK_OP_ID);
1429 }
1430 
1431 void
1433  uint16_t cwMin,
1434  uint16_t cwMax,
1435  uint8_t aifsn,
1436  Time muEdcaTimer)
1437 {
1438  Ptr<QosTxop> edca = GetQosTxop(ac);
1439  edca->SetMuCwMin(cwMin, SINGLE_LINK_OP_ID);
1440  edca->SetMuCwMax(cwMax, SINGLE_LINK_OP_ID);
1441  edca->SetMuAifsn(aifsn, SINGLE_LINK_OP_ID);
1442  edca->SetMuEdcaTimer(muEdcaTimer, SINGLE_LINK_OP_ID);
1443 }
1444 
1445 void
1447 {
1448  NS_LOG_FUNCTION(this);
1449  if (IsAssociated())
1450  {
1451  NS_LOG_DEBUG("PHY capabilities changed: send reassociation request");
1453  SendAssociationRequest(true);
1454  }
1455 }
1456 
1457 void
1459 {
1460  NS_LOG_FUNCTION(this << +linkId);
1461 
1463 
1464  if (IsInitialized() && IsAssociated())
1465  {
1466  Disassociated(linkId);
1467  }
1468 
1469  // notify association manager
1470  m_assocManager->NotifyChannelSwitched(linkId);
1471 }
1472 
1473 std::ostream&
1474 operator<<(std::ostream& os, const StaWifiMac::ApInfo& apInfo)
1475 {
1476  os << "BSSID=" << apInfo.m_bssid << ", AP addr=" << apInfo.m_apAddr << ", SNR=" << apInfo.m_snr
1477  << ", Channel={" << apInfo.m_channel.number << "," << apInfo.m_channel.band
1478  << "}, Link ID=" << +apInfo.m_linkId << ", Frame=[";
1479  std::visit([&os](auto&& frame) { frame.Print(os); }, apInfo.m_frame);
1480  os << "]";
1481  return os;
1482 }
1483 
1484 } // namespace ns3
#define max(a, b)
Definition: 80211b.c:43
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
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.
bool IsEss() const
Check if the Extended Service Set (ESS) bit in the capability information field is set to 1.
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.
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
an EUI-48 address
Definition: mac48-address.h:46
bool IsGroup() const
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
Implement the header for management frames of type association request.
Definition: mgt-headers.h:55
Implement the header for management frames of type association and reassociation response.
Definition: mgt-headers.h:447
const std::optional< MultiLinkElement > & GetMultiLinkElement() const
Return the Multi-Link Element information element, if present.
StatusCode GetStatusCode()
Return the status code.
uint16_t GetAssociationId() const
Return the association ID.
Implement the header for management frames of type beacon.
Definition: mgt-headers.h:1257
Implement the header for management frames of type probe request.
Definition: mgt-headers.h:754
void SetSsid(const Ssid &ssid)
Set the Service Set Identifier (SSID).
Definition: mgt-headers.cc:41
void SetSupportedRates(const SupportedRates &rates)
Set the supported rates.
Definition: mgt-headers.cc:59
void SetEhtCapabilities(const EhtCapabilities &ehtCapabilities)
Set the EHT capabilities.
Definition: mgt-headers.cc:143
void SetVhtCapabilities(const VhtCapabilities &vhtCapabilities)
Set the VHT capabilities.
Definition: mgt-headers.cc:107
void SetHeCapabilities(const HeCapabilities &heCapabilities)
Set the HE capabilities.
Definition: mgt-headers.cc:125
void SetHtCapabilities(const HtCapabilities &htCapabilities)
Set the HT capabilities.
Definition: mgt-headers.cc:89
void SetExtendedCapabilities(const ExtendedCapabilities &extendedCapabilities)
Set the extended capabilities.
Definition: mgt-headers.cc:71
Implement the header for management frames of type probe response.
Definition: mgt-headers.h:903
const CapabilityInformation & GetCapabilities() const
Return the Capability information.
Definition: mgt-headers.cc:343
Implement the header for management frames of type reassociation request.
Definition: mgt-headers.h:248
void SetCurrentApAddress(Mac48Address currentApAddr)
Set the address of the current access point.
bool IsInitialized() const
Check if the object has been initialized.
Definition: object.cc:212
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
void SetMuCwMin(uint16_t cwMin, uint8_t linkId)
Set the minimum contention window size to use while the MU EDCA Timer is running for the given link.
Definition: qos-txop.cc:173
void SetMuCwMax(uint16_t cwMax, uint8_t linkId)
Set the maximum contention window size to use while the MU EDCA Timer is running for the given link.
Definition: qos-txop.cc:180
void SetMuAifsn(uint8_t aifsn, uint8_t linkId)
Set the number of slots that make up an AIFS while the MU EDCA Timer is running for the given link.
Definition: qos-txop.cc:187
void SetMuEdcaTimer(Time timer, uint8_t linkId)
Set the MU EDCA Timer for the given link.
Definition: qos-txop.cc:194
virtual double GetValue()=0
Get the next random value drawn from the distribution.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
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 Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:208
Introspection did not find any typical Config paths.
Definition: snr-tag.h:35
double Get() const
Return the SNR value.
Definition: snr-tag.cc:90
The Wifi MAC high model for a non-AP STA in a BSS.
Definition: sta-wifi-mac.h:124
std::set< uint8_t > GetSetupLinkIds() const
Get the IDs of the setup links (if any).
void ScanningTimeout(const std::optional< ApInfo > &bestAp)
This method is called after wait beacon timeout or wait probe request timeout has occurred.
Time m_waitBeaconTimeout
wait beacon timeout
Definition: sta-wifi-mac.h:488
Ptr< WifiAssocManager > m_assocManager
Association Manager.
Definition: sta-wifi-mac.h:487
void MissedBeacons(uint8_t linkId)
This method is called after we have not received a beacon from the AP on the given link.
bool m_activeProbing
active probing
Definition: sta-wifi-mac.h:493
void DoInitialize() override
Initialize() implementation.
void SetAssocManager(Ptr< WifiAssocManager > assocManager)
Set the Association Manager.
bool CanForwardPacketsTo(Mac48Address to) const override
Return true if packets can be forwarded to the given destination, false otherwise.
std::unique_ptr< LinkEntity > CreateLinkEntity() const override
Create a LinkEntity object.
void SetEdcaParameters(AcIndex ac, uint32_t cwMin, uint32_t cwMax, uint8_t aifsn, Time txopLimit)
Set the EDCA parameters.
void SetState(MacState value)
Set the current MAC state.
TracedCallback< Mac48Address > m_deAssocLogger
disassociation logger
Definition: sta-wifi-mac.h:499
MacState
The current MAC state of the STA.
Definition: sta-wifi-mac.h:269
void NotifyChannelSwitching(uint8_t linkId) override
Notify that channel on the given link has been switched.
bool GetActiveProbing() const
Return whether active probing is enabled.
void PhyCapabilitiesChanged()
Indicate that PHY capabilities have changed.
void ReceiveProbeResp(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Process the Probe Response frame received on the given link.
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
WifiScanParams::Channel GetCurrentChannel(uint8_t linkId) const
Get the current primary20 channel used on the given link as a (channel number, PHY band) pair.
uint16_t GetAssociationId() const
Return the association ID.
void TryToEnsureAssociated()
Try to ensure that we are associated with an AP by taking an appropriate action depending on the curr...
void ReceiveAssocResp(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Process the (Re)Association Response frame received on the given link.
void RestartBeaconWatchdog(Time delay, uint8_t linkId)
Restarts the beacon timer for the given link.
std::variant< MgtAssocRequestHeader, MgtReassocRequestHeader > GetAssociationRequest(bool isReassoc, uint8_t linkId) const
Get the (Re)Association Request frame to send on a given link.
static TypeId GetTypeId()
Get the type ID.
Definition: sta-wifi-mac.cc:52
void DoDispose() override
Destructor implementation.
StaLinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
uint32_t m_maxMissedBeacons
maximum missed beacons
Definition: sta-wifi-mac.h:492
TracedCallback< uint8_t, Mac48Address > m_setupCompleted
link setup completed logger
Definition: sta-wifi-mac.h:498
TracedCallback< Mac48Address > m_assocLogger
association logger
Definition: sta-wifi-mac.h:497
void Disassociated(uint8_t linkId)
Check if any enabled link remains after the given link is disabled (because, e.g.,...
SupportedRates GetSupportedRates(uint8_t linkId) const
Return an instance of SupportedRates that contains all rates that we support including HT rates.
TracedCallback< uint8_t, Mac48Address > m_setupCanceled
link setup canceled logger
Definition: sta-wifi-mac.h:500
bool CheckSupportedRates(std::variant< MgtBeaconHeader, MgtProbeResponseHeader > frame, uint8_t linkId)
Determine whether the supported rates indicated in a given Beacon frame or Probe Response frame fit w...
Mac48Address DoGetLocalAddress(const Mac48Address &remoteAddr) const override
This method is called if this device is an MLD to determine the MAC address of the affiliated STA use...
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...
Ptr< RandomVariableStream > m_probeDelay
RandomVariable used to randomize the time of the first Probe Response on each channel.
Definition: sta-wifi-mac.h:494
TracedCallback< ApInfo > m_beaconInfo
beacon info logger
Definition: sta-wifi-mac.h:502
uint16_t m_aid
Association AID.
Definition: sta-wifi-mac.h:486
MacState m_state
MAC state.
Definition: sta-wifi-mac.h:485
void Enqueue(Ptr< Packet > packet, Mac48Address to) override
void SetMuEdcaParameters(AcIndex ac, uint16_t cwMin, uint16_t cwMax, uint8_t aifsn, Time muEdcaTimer)
Set the MU EDCA parameters.
void StartScanning()
Start the scanning process which trigger active or passive scanning based on the active probing flag.
void SetWifiPhys(const std::vector< Ptr< WifiPhy >> &phys) override
TracedCallback< Time > m_beaconArrival
beacon arrival logger
Definition: sta-wifi-mac.h:501
void AssocRequestTimeout()
This method is called after the association timeout occurred.
void UpdateApInfo(const MgtFrameType &frame, const Mac48Address &apAddr, const Mac48Address &bssid, uint8_t linkId)
Update associated AP's information from the given management frame (Beacon, Probe Response or Associa...
void SendProbeRequest()
Forward a probe request packet to the DCF.
Time m_assocRequestTimeout
association request timeout
Definition: sta-wifi-mac.h:490
void ReceiveBeacon(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
Process the Beacon frame received on the given link.
Time m_probeRequestTimeout
probe request timeout
Definition: sta-wifi-mac.h:489
void SetActiveProbing(bool enable)
Enable or disable active probing.
CapabilityInformation GetCapabilities(uint8_t linkId) const
Return the Capability information for the given link.
bool IsAssociated() const
Return whether we are associated with an AP.
~StaWifiMac() override
std::variant< MgtBeaconHeader, MgtProbeResponseHeader, MgtAssocResponseHeader > MgtFrameType
type of the management frames used to get info about APs
Definition: sta-wifi-mac.h:137
bool IsWaitAssocResp() const
Return whether we are waiting for an association response from an AP.
MultiLinkElement GetMultiLinkElement(bool isReassoc, uint8_t linkId) const
Return the Multi-Link Element to include in the management frames transmitted on the given link.
EventId m_assocRequestEvent
association request event
Definition: sta-wifi-mac.h:491
void SendAssociationRequest(bool isReassoc)
Forward an association or reassociation request packet to the DCF.
bool IsSuccess() const
Return whether the status code is success.
Definition: status-code.cc:42
Hold variables of type string.
Definition: string.h:56
The Supported Rates Information Element.
void AddBssMembershipSelectorRate(uint64_t bs)
Add a special value to the supported rate set, corresponding to a BSS membership selector.
bool IsBasicRate(uint64_t bs) const
Check if the given rate is a basic rate.
bool IsBssMembershipSelectorRate(uint64_t bs) const
Check if the given rate is a BSS membership selector value.
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
AttributeValue implementation for Time.
Definition: nstime.h:1423
void SetMaxCw(uint32_t maxCw)
Set the maximum contention window size.
Definition: txop.cc:256
void SetTxopLimit(Time txopLimit)
Set the TXOP limit.
Definition: txop.cc:376
void SetAifsn(uint8_t aifsn)
Set the number of slots that make up an AIFS.
Definition: txop.cc:353
void SetMinCw(uint32_t minCw)
Set the minimum contention window size.
Definition: txop.cc:227
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
Implements the IEEE 802.11 MAC header.
void SetQosAckPolicy(QosAckPolicy policy)
Set the QoS Ack policy in the QoS control field.
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 IsBeacon() const
Return true if the header is a Beacon header.
bool IsAssocResp() const
Return true if the header is an Association Response header.
Mac48Address GetAddr1() const
Return the address in the Address 1 field.
void SetQosTxopLimit(uint8_t txop)
Set TXOP limit in the QoS control field.
WifiMacType GetType() const
Return the type (enum WifiMacType)
bool IsCtl() const
Return true if the Type is Control.
void SetNoOrder()
Unset order bit in the frame control field.
void SetDsNotFrom()
Un-set the From DS bit in the Frame Control field.
bool IsProbeResp() const
Return true if the header is a Probe Response header.
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.
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 SetDsTo()
Set the To 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:94
Ptr< FrameExchangeManager > GetFrameExchangeManager(uint8_t linkId=SINGLE_LINK_OP_ID) const
Get the Frame Exchange Manager associated with the given link.
Definition: wifi-mac.cc:840
Ptr< QosTxop > GetBEQueue() const
Accessor for the AC_BE channel access function.
Definition: wifi-mac.cc:524
virtual void NotifyChannelSwitching(uint8_t linkId)
Notify that channel on the given link has been switched.
Definition: wifi-mac.cc:556
std::optional< Mac48Address > GetMldAddress(const Mac48Address &remoteAddr) const
Definition: wifi-mac.cc:1236
Mac48Address GetBssid(uint8_t linkId) const
Definition: wifi-mac.cc:469
Ptr< HeConfiguration > GetHeConfiguration() const
Definition: wifi-mac.cc:1353
Ptr< Txop > GetTxop() const
Accessor for the Txop object.
Definition: wifi-mac.cc:484
VhtCapabilities GetVhtCapabilities(uint8_t linkId) const
Return the VHT capabilities of the device for the given link.
Definition: wifi-mac.cc:1590
Callback< void > m_linkDown
Callback when a link is down.
Definition: wifi-mac.h:757
bool GetQosSupported() const
Return whether the device supports QoS.
Definition: wifi-mac.cc:1006
uint8_t GetNLinks() const
Get the number of links (can be greater than 1 for 11be devices only).
Definition: wifi-mac.cc:906
Ssid GetSsid() const
Definition: wifi-mac.cc:456
bool GetErpSupported(uint8_t linkId) const
Return whether the device supports ERP on the given link.
Definition: wifi-mac.cc:1012
bool GetHtSupported() const
Return whether the device supports HT.
Definition: wifi-mac.cc:1365
Ptr< QosTxop > GetVOQueue() const
Accessor for the AC_VO channel access function.
Definition: wifi-mac.cc:512
void SetTypeOfStation(TypeOfStation type)
This method is invoked by a subclass to specify what type of station it is implementing.
Definition: wifi-mac.cc:411
Ptr< WifiPhy > GetWifiPhy(uint8_t linkId=SINGLE_LINK_OP_ID) const
Definition: wifi-mac.cc:954
bool GetEhtSupported() const
Return whether the device supports EHT.
Definition: wifi-mac.cc:1384
bool GetHeSupported() const
Return whether the device supports HE.
Definition: wifi-mac.cc:1378
HtCapabilities GetHtCapabilities(uint8_t linkId) const
Return the HT capabilities of the device for the given link.
Definition: wifi-mac.cc:1533
virtual void SetWifiPhys(const std::vector< Ptr< WifiPhy >> &phys)
Definition: wifi-mac.cc:925
bool GetVhtSupported(uint8_t linkId) const
Return whether the device supports VHT on the given link.
Definition: wifi-mac.cc:1371
virtual void DeaggregateAmsduAndForward(Ptr< const WifiMpdu > mpdu)
This method can be called to de-aggregate an A-MSDU and forward the constituent packets up the stack.
Definition: wifi-mac.cc:1224
void SetBssid(Mac48Address bssid, uint8_t linkId)
Definition: wifi-mac.cc:462
Ptr< WifiNetDevice > GetDevice() const
Return the device this PHY is associated with.
Definition: wifi-mac.cc:430
ExtendedCapabilities GetExtendedCapabilities() const
Return the extended capabilities of the device.
Definition: wifi-mac.cc:1522
bool GetShortSlotTimeSupported() const
Definition: wifi-mac.cc:1056
void NotifyRxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:595
Ptr< WifiRemoteStationManager > GetWifiRemoteStationManager(uint8_t linkId=0) const
Definition: wifi-mac.cc:886
void ForwardUp(Ptr< const Packet > packet, Mac48Address from, Mac48Address to)
Forward the packet up to the device.
Definition: wifi-mac.cc:1100
virtual void Receive(Ptr< const WifiMpdu > mpdu, uint8_t linkId)
This method acts as the MacRxMiddle receive callback and is invoked to notify us that a frame has bee...
Definition: wifi-mac.cc:1107
Mac48Address GetAddress() const
Definition: wifi-mac.cc:443
EhtCapabilities GetEhtCapabilities(uint8_t linkId) const
Return the EHT capabilities of the device for the given link.
Definition: wifi-mac.cc:1727
Callback< void > m_linkUp
Callback when a link is up.
Definition: wifi-mac.h:756
LinkEntity & GetLink(uint8_t linkId) const
Get a reference to the link associated with the given ID.
Definition: wifi-mac.cc:898
HeCapabilities GetHeCapabilities(uint8_t linkId) const
Return the HE capabilities of the device for the given link.
Definition: wifi-mac.cc:1671
Ptr< QosTxop > GetQosTxop(AcIndex ac) const
Accessor for a specified EDCA object.
Definition: wifi-mac.cc:490
void NotifyTxDrop(Ptr< const Packet > packet)
Definition: wifi-mac.cc:577
void DoDispose() override
Destructor implementation.
Definition: wifi-mac.cc:369
Time GetDelayUntilIdle()
Definition: wifi-phy.cc:2040
std::list< uint8_t > GetBssMembershipSelectorList() const
The WifiPhy::BssMembershipSelector() method is used (e.g., by a WifiRemoteStationManager) to determin...
Definition: wifi-phy.cc:1301
void SetSlot(Time slot)
Set the slot duration for this PHY.
Definition: wifi-phy.cc:780
WifiPhyBand GetPhyBand() const
Get the configured Wi-Fi band.
Definition: wifi-phy.cc:996
void SetOffMode()
Put in off mode.
Definition: wifi-phy.cc:1350
bool HasFixedPhyBand() const
Definition: wifi-phy.cc:1044
void ResumeFromOff()
Resume from off mode.
Definition: wifi-phy.cc:1393
std::list< WifiMode > GetModeList() const
The WifiPhy::GetModeList() method is used (e.g., by a WifiRemoteStationManager) to determine the set ...
Definition: wifi-phy.cc:1907
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...
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 AddSupportedMcs(Mac48Address address, WifiMode mcs)
Record the MCS index supported by the station.
void RemoveAllSupportedMcs(Mac48Address address)
Invoked in a STA or AP to delete all of the supported MCS by a destination.
void AddStationVhtCapabilities(Mac48Address from, VhtCapabilities vhtCapabilities)
Records VHT capabilities of the remote station.
void SetShortPreambleEnabled(bool enable)
Enable or disable short PHY preambles.
void SetQosSupport(Mac48Address from, bool qosSupported)
Records QoS support of the remote station.
void AddStationHeCapabilities(Mac48Address from, HeCapabilities heCapabilities)
Records HE capabilities of the remote station.
void AddSupportedMode(Mac48Address address, WifiMode mode)
Invoked in a STA or AP to store the set of modes supported by a destination which is also supported l...
void AddStationEhtCapabilities(Mac48Address from, EhtCapabilities ehtCapabilities)
Records EHT capabilities of the remote station.
void AddStationHtCapabilities(Mac48Address from, HtCapabilities htCapabilities)
Records HT capabilities of the remote station.
std::optional< Mac48Address > GetMldAddress(const Mac48Address &address) const
Get the address of the MLD the given station is affiliated with, if any.
#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
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: pointer.h:231
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: nstime.h:1424
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1360
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
uint8_t QosUtilsGetTidForPacket(Ptr< const Packet > packet)
If a QoS tag is attached to the packet, returns a value < 8.
Definition: qos-utils.cc:160
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:72
@ WIFI_PHY_BAND_UNSPECIFIED
Unspecified.
Definition: wifi-phy-band.h:43
@ WIFI_MOD_CLASS_VHT
VHT (Clause 22)
@ WIFI_MOD_CLASS_HE
HE (Clause 27)
@ AC_BE
Best Effort.
Definition: qos-utils.h:74
@ AC_VO
Voice.
Definition: qos-utils.h:80
@ AC_VI
Video.
Definition: qos-utils.h:78
@ AC_BK
Background.
Definition: qos-utils.h:76
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ STA
Definition: wifi-mac.h:62
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
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
@ WIFI_MAC_MGT_PROBE_REQUEST
@ WIFI_MAC_MGT_BEACON
@ WIFI_MAC_MGT_ASSOCIATION_RESPONSE
@ WIFI_MAC_MGT_ASSOCIATION_REQUEST
@ WIFI_MAC_MGT_REASSOCIATION_REQUEST
@ WIFI_MAC_MGT_PROBE_RESPONSE
@ WIFI_MAC_DATA
@ WIFI_MAC_MGT_REASSOCIATION_RESPONSE
@ WIFI_MAC_QOSDATA
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
value
Definition: second.py:41
channel
Definition: third.py:81
phy
Definition: third.py:82
Struct to hold information regarding observed AP through active/passive scanning.
Definition: sta-wifi-mac.h:144
MgtFrameType m_frame
The body of the management frame used to update AP info.
Definition: sta-wifi-mac.h:148
WifiScanParams::Channel m_channel
The channel the management frame was received on.
Definition: sta-wifi-mac.h:149
Mac48Address m_apAddr
AP MAC address.
Definition: sta-wifi-mac.h:146
uint8_t m_linkId
ID of the link used to communicate with the AP.
Definition: sta-wifi-mac.h:150
Mac48Address m_bssid
BSSID.
Definition: sta-wifi-mac.h:145
double m_snr
SNR in linear scale.
Definition: sta-wifi-mac.h:147
Struct identifying a channel to scan.
Definition: sta-wifi-mac.h:58
WifiPhyBand band
PHY band.
Definition: sta-wifi-mac.h:60
uint16_t number
channel number
Definition: sta-wifi-mac.h:59
Structure holding scan parameters.
Definition: sta-wifi-mac.h:50
std::list< Channel > ChannelList
typedef for a list of channels
Definition: sta-wifi-mac.h:64
std::vector< ChannelList > channelList
list of channels to scan, for each link
Definition: sta-wifi-mac.h:73
Time probeDelay
delay prior to transmitting a Probe Request
Definition: sta-wifi-mac.h:74
Time maxChannelTime
maximum time to spend on each channel
Definition: sta-wifi-mac.h:76
Ssid ssid
desired SSID or wildcard SSID
Definition: sta-wifi-mac.h:72
enum ns3::WifiScanParams::@75 type
indicates either active or passive scanning
Time minChannelTime
minimum time to spend on each channel
Definition: sta-wifi-mac.h:75