A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-static-setup-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2025
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Sharan Naribole <sharan.naribole@gmail.com>
7 */
8
10
11#include "ns3/adhoc-wifi-mac.h"
12#include "ns3/ap-wifi-mac.h"
13#include "ns3/assert.h"
14#include "ns3/boolean.h"
15#include "ns3/emlsr-manager.h"
16#include "ns3/ht-configuration.h"
17#include "ns3/ht-frame-exchange-manager.h"
18#include "ns3/log.h"
19#include "ns3/mgt-action-headers.h"
20#include "ns3/mgt-headers.h"
21#include "ns3/net-device-container.h"
22#include "ns3/packet.h"
23#include "ns3/power-save-manager.h"
24#include "ns3/simulator.h"
25#include "ns3/sta-wifi-mac.h"
26#include "ns3/wifi-net-device.h"
27#include "ns3/wifi-remote-station-manager.h"
28#include "ns3/wifi-utils.h"
29
30NS_LOG_COMPONENT_DEFINE("WifiStaticSetupHelper");
31
32namespace ns3
33{
34
35void
37 const NetDeviceContainer& clientDevs)
38{
40
41 for (auto i = clientDevs.Begin(); i != clientDevs.End(); ++i)
42 {
43 auto clientDev = DynamicCast<WifiNetDevice>(*i);
44 NS_ASSERT_MSG(clientDev, "WifiNetDevice expected");
45 SetStaticAssociation(bssDev, clientDev);
46 }
47}
48
49void
57
58void
60 Ptr<WifiNetDevice> clientDev)
61{
63
64 auto clientMac = DynamicCast<StaWifiMac>(clientDev->GetMac());
65 auto apMac = DynamicCast<ApWifiMac>(bssDev->GetMac());
66
67 NS_ABORT_MSG_IF(!apMac || !clientMac, "Invalid static capabilities exchange case");
68 SetStaticAssocPostInit(apMac, clientMac);
69}
70
71void
73{
75
76 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
77 NS_ASSERT_MSG(clientMac, "Expected StaWifiMac");
78
79 // disable scanning
80 clientMac->SetAttribute("EnableScanning", BooleanValue(false));
81
82 const auto linkIdMap = GetLinkIdMap(apMac, clientMac);
83 const auto nClientLinks = clientMac->GetNLinks();
84 const auto isMldAssoc = nClientLinks > 1;
85 const auto apMldAddr = apMac->GetAddress();
86 const auto clientMldAddr = clientMac->GetAddress();
87
88 // Swap links at client MAC to match with AP (MLD)
89 clientMac->SwapLinks(linkIdMap);
90 const auto clientLinkIds = clientMac->GetLinkIds();
91 const auto assocLinkId = *clientLinkIds.cbegin();
92 std::optional<MultiLinkElement> apMle;
93 if (isMldAssoc)
94 {
95 apMle = apMac->GetMultiLinkElement(assocLinkId, WIFI_MAC_MGT_BEACON);
96 }
97 std::shared_ptr<CommonInfoBasicMle> mleCommonInfo;
98 for (const auto clientLinkId : clientLinkIds)
99 {
100 // AP Link ID matches with non-AP MLD Link ID after swap operation
101 // using WifiMac::SwapLinks performed above
102 const auto apLinkId = clientLinkId;
103 auto& clientLink = clientMac->GetLink(clientLinkId);
104
105 // Set BSSID
106 auto apLinkAddr = apMac->GetFrameExchangeManager(apLinkId)->GetAddress();
107 clientMac->SetBssid(apLinkAddr, clientLinkId);
108 clientLink.bssid = apLinkAddr;
109 if (!isMldAssoc)
110 {
111 continue;
112 }
113 NS_ASSERT_MSG(apMle.has_value(), "Expected Multi-link Element");
114 if (!mleCommonInfo)
115 {
116 mleCommonInfo = std::make_shared<CommonInfoBasicMle>(apMle->GetCommonInfoBasic());
117 }
118 auto clientManager = clientMac->GetWifiRemoteStationManager(clientLinkId);
119 clientManager->AddStationMleCommonInfo(apLinkAddr, mleCommonInfo);
120 }
121
122 // Association Request
123 auto assocReq = GetAssocReq(clientMac, assocLinkId, isMldAssoc);
124 auto clientLinkAddr = clientMac->GetFrameExchangeManager(assocLinkId)->GetAddress();
126 assocReqHdr.SetAddr2(clientLinkAddr);
127 auto assocSuccess = apMac->ReceiveAssocRequest(assocReq, clientLinkAddr, assocLinkId);
128 apMac->ParseReportedStaInfo(assocReq, clientLinkAddr, assocLinkId);
129 NS_ASSERT_MSG(assocSuccess,
130 "Static Association failed AP: " << apMldAddr << ", STA: " << clientMldAddr);
131
132 // Association Response
133 clientMac->SetState(StaWifiMac::WAIT_ASSOC_RESP);
134 auto assocResp = GetAssocResp(clientLinkAddr, apMac, assocLinkId, isMldAssoc);
135 auto assocRespMacHdr = GetAssocRespMacHdr(clientLinkAddr, apMac, assocLinkId);
136 auto linkIdStaAddrMap = apMac->GetLinkIdStaAddrMap(assocResp, clientLinkAddr, assocLinkId);
137 apMac->SetAid(assocResp, linkIdStaAddrMap);
138 auto packet = Create<Packet>();
139 packet->AddHeader(assocResp);
140 auto mpdu = Create<WifiMpdu>(packet, assocRespMacHdr);
141 clientMac->ReceiveAssocResp(mpdu, assocLinkId);
142
143 // Record Association success in Remote STA manager
144 for (auto clientLinkId : clientLinkIds)
145 {
146 const auto apLinkId = clientLinkId;
147 clientLinkAddr = clientMac->GetFrameExchangeManager(clientLinkId)->GetAddress();
148 apMac->GetWifiRemoteStationManager(apLinkId)->RecordGotAssocTxOk(clientLinkAddr);
149 const auto aid = apMac->GetAssociationId(clientLinkAddr, apLinkId);
150 if (const auto gcrMgr = apMac->GetGcrManager())
151 {
152 const auto extendedCapabilities =
153 apMac->GetWifiRemoteStationManager(apLinkId)->GetStationExtendedCapabilities(
154 clientLinkAddr);
155 gcrMgr->NotifyStaAssociated(clientLinkAddr,
156 extendedCapabilities &&
157 (extendedCapabilities->m_robustAvStreaming > 0));
158 }
159 apMac->m_assocLogger(aid, clientLinkAddr);
160 }
161
162 NS_LOG_DEBUG("Assoc success AP addr=" << apMldAddr << ", STA addr=" << clientMldAddr);
163
164 // Note that the call above to StaWifiMac::ReceiveAssocResp() triggers a call to
165 // StaWifiMac::SetPmModeAfterAssociation(), which sets a callback to intercept the Ack sent in
166 // response to the AssocResp and, at the end of the Ack transmission, schedule the transmission
167 // of Data Null frames to notify the AP about the power management mode each STA has to switch
168 // to based on the value of the StaLinkEntity::pmMode field (which defaults to WIFI_PM_ACTIVE
169 // and can be set via the PowerSaveMode attribute of the PowerSaveManager). When using the
170 // static setup helper, however, no AssocResp is sent, hence no Ack is sent and the transmission
171 // of Data Null frames is not scheduled. Therefore, we need to make the AP aware of the PM mode
172 // of the STAs affiliated with the client device without actually sending Data Null frames.
173 AlignApViewOfStaPmMode(apMac, clientMac);
174
175 // The callback that is set by StaWifiMac::SetPmModeAfterAssociation() to intercept the Ack sent
176 // in response to the AssocResp also schedules a call to notify the Power Save Manager that
177 // association is completed at the end of the transmission of the Ack. Given that no AssocResp
178 // is sent when using the static setup helper, we need to explicitly make the relevant calls
179 // here.
180 if (clientMac->m_powerSaveManager)
181 {
182 for (const auto apLinkId : apMac->GetLinkIds())
183 {
184 if (const auto& beaconEvent = apMac->GetLink(apLinkId).beaconEvent;
185 beaconEvent.IsPending())
186 {
187 clientMac->m_powerSaveManager->NotifyBeaconIntervalAndTimestamp(
188 apMac->GetBeaconInterval(),
189 Simulator::Now() + Simulator::GetDelayLeft(beaconEvent) -
190 apMac->GetBeaconInterval(),
191 apLinkId);
192 }
193 }
194 clientMac->m_powerSaveManager->NotifyAssocCompleted();
195 }
196
197 if (isMldAssoc)
198 {
199 // Update TID-to-Link Mapping in MAC queues
200 apMac->ApplyTidLinkMapping(clientMldAddr, WifiDirection::DOWNLINK);
201 clientMac->ApplyTidLinkMapping(apMldAddr, WifiDirection::UPLINK);
202 }
203}
204
205std::map<linkId_t, linkId_t>
207{
208 auto apMac = DynamicCast<ApWifiMac>(apDev->GetMac());
209 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
210 auto clientMac = DynamicCast<StaWifiMac>(clientDev->GetMac());
211 NS_ASSERT_MSG(clientMac, "Expected StaWifiMac");
212 return GetLinkIdMap(apMac, clientMac);
213}
214
215std::map<linkId_t, linkId_t>
217{
218 NS_ASSERT(apMac && clientMac);
219 const auto nApLinks = apMac->GetNLinks();
220 const auto nClientLinks = clientMac->GetNLinks();
221 // Assumed all links of non-AP MLD need to be associated
223 nApLinks >= nClientLinks,
224 "Expected AP MLD to have at least the same number of links than non-AP MLD, nApLinks="
225 << nApLinks << ", nClientLinks=" << nClientLinks);
226
227 std::map<linkId_t, linkId_t> linkIdMap{};
228 auto apCandidateLinks = apMac->GetLinkIds();
229
230 for (const auto clientLinkId : clientMac->GetLinkIds())
231 {
232 for (const auto apLinkId : apCandidateLinks)
233 {
234 const auto apPhy = apMac->GetWifiPhy(apLinkId);
235 const auto clientPhy = clientMac->GetWifiPhy(clientLinkId);
236 if (!apPhy || !clientPhy)
237 {
238 continue;
239 }
240 NS_LOG_DEBUG("AP channel: " << apPhy->GetOperatingChannel());
241 NS_LOG_DEBUG("Client channel: " << clientPhy->GetOperatingChannel());
242 const auto isMatch = (apPhy->GetOperatingChannel().GetPrimaryChannel(MHz_u{20}) ==
243 clientPhy->GetOperatingChannel().GetPrimaryChannel(MHz_u{20}));
244 NS_LOG_DEBUG("Client Link ID = " << +clientLinkId << ", AP Link ID Candidate="
245 << +apLinkId << ", isMatch=" << isMatch);
246 if (isMatch)
247 {
248 linkIdMap[clientLinkId] = apLinkId;
249 break;
250 }
251 }
252
253 NS_ASSERT_MSG(linkIdMap.contains(clientLinkId),
254 "No matching AP found for STA PHY setting link ID=" << +clientLinkId);
255 apCandidateLinks.erase(linkIdMap.at(clientLinkId));
256 }
257
258 return linkIdMap;
259}
260
263 Ptr<ApWifiMac> apMac,
264 linkId_t apLinkId)
265{
267 hdr.SetAddr1(clientLinkAddr);
268 auto apLinkAddr = apMac->GetFrameExchangeManager(apLinkId)->GetAddress();
269 hdr.SetAddr2(apLinkAddr);
270 hdr.SetAddr3(apLinkAddr);
271 return hdr;
272}
273
276 Ptr<ApWifiMac> apMac,
277 linkId_t apLinkId,
278 bool isMldAssoc)
279{
280 auto assocResp = apMac->GetAssocResp(clientLinkAddr, apLinkId);
281 if (!isMldAssoc)
282 {
283 return assocResp;
284 }
285 auto mle =
286 apMac->GetMultiLinkElement(apLinkId, WIFI_MAC_MGT_ASSOCIATION_RESPONSE, clientLinkAddr);
287 assocResp.Get<MultiLinkElement>() = mle;
288 return assocResp;
289}
290
293{
294 auto frame = clientMac->GetAssociationRequest(false, linkId);
295 auto assocReq = std::get<MgtAssocRequestHeader>(frame);
296 if (!isMldAssoc)
297 {
298 return assocReq;
299 }
300
301 auto mle = clientMac->GetBasicMultiLinkElement(false, linkId);
302 assocReq.Get<MultiLinkElement>() = mle;
303 auto& link = clientMac->GetLink(linkId);
304 auto bssid = *link.bssid;
305 auto remoteManager = clientMac->GetWifiRemoteStationManager(linkId);
306 const auto& mldCap = remoteManager->GetStationMldCapabilities(bssid);
307 NS_ASSERT_MSG(mldCap, "Expected MLD Capabilities info for AP MLD");
308 auto apNegSupport = mldCap->get().tidToLinkMappingSupport;
309 if (apNegSupport > 0)
310 {
311 assocReq.Get<TidToLinkMapping>() = clientMac->GetTidToLinkMappingElements(
312 static_cast<WifiTidToLinkMappingNegSupport>(apNegSupport));
313 }
314
315 return assocReq;
316}
317
318void
320{
321 const auto setupLinks = clientMac->GetSetupLinkIds();
322 for (const auto linkId : setupLinks)
323 {
324 if (clientMac->GetPmMode(linkId) == WIFI_PM_ACTIVE)
325 {
326 apMac->StaSwitchingToActiveModeOrDeassociated(clientMac->GetAddress(), linkId);
327 }
328 else
329 {
330 apMac->StaSwitchingToPsMode(clientMac->GetAddress(), linkId);
331 }
332 }
333}
334
335void
337 const NetDeviceContainer& clientDevs,
338 const std::set<tid_t>& tids,
339 std::optional<Mac48Address> gcrGroupAddr)
340{
342
343 for (auto i = clientDevs.Begin(); i != clientDevs.End(); ++i)
344 {
345 auto clientDev = DynamicCast<WifiNetDevice>(*i);
346 NS_ASSERT_MSG(clientDev, "WifiNetDevice expected");
347 if (!clientDev->GetHtConfiguration())
348 {
349 // Block Ack requires HT support
350 continue;
351 }
352 for (const auto tid : tids)
353 {
354 SetStaticBlockAck(apDev, clientDev, tid, gcrGroupAddr); // Downlink setup
355 SetStaticBlockAck(clientDev, apDev, tid, gcrGroupAddr); // Uplink setup
356 }
357 }
358}
359
360void
362 Ptr<WifiNetDevice> recipientDev,
363 tid_t tid,
364 std::optional<Mac48Address> gcrGroupAddr)
365{
367
369 originatorDev,
370 recipientDev,
371 tid,
372 gcrGroupAddr);
373}
374
375void
377 Ptr<WifiNetDevice> recipientDev,
378 tid_t tid,
379 std::optional<Mac48Address> gcrGroupAddr)
380{
382
383 // Originator Device
384 const auto originatorMac = originatorDev->GetMac();
385 const auto originatorLinkId = *(originatorMac->GetLinkIds().begin());
386 const auto originatorFem = DynamicCast<HtFrameExchangeManager>(
387 originatorMac->GetFrameExchangeManager(originatorLinkId));
388 NS_ASSERT_MSG(originatorFem, "Block ACK setup requires HT support");
389 const auto originatorBaManager = originatorMac->GetQosTxop(tid)->GetBaManager();
390
391 // Recipient Device
392 const auto recipientMac = recipientDev->GetMac();
393 const auto recipientLinkId = *(recipientMac->GetLinkIds().begin());
394 const auto recipientFem =
395 DynamicCast<HtFrameExchangeManager>(recipientMac->GetFrameExchangeManager(recipientLinkId));
396 NS_ASSERT_MSG(recipientFem, "Block ACK setup requires HT support");
397 const auto recipientBaManager = recipientMac->GetQosTxop(tid)->GetBaManager();
398
399 const auto originatorAddr = GetBaOriginatorAddr(originatorMac, recipientMac);
400 const auto recipientAddr = GetBaRecipientAddr(originatorMac, recipientMac);
401
402 // Early return if BA Agreement already exists
403 if (originatorMac->GetBaAgreementEstablishedAsOriginator(recipientAddr, tid, gcrGroupAddr))
404 {
405 return;
406 }
407
408 // ADDBA Request
410 reqHdr.SetAmsduSupport(true);
411 reqHdr.SetImmediateBlockAck();
412 reqHdr.SetTid(tid);
413 reqHdr.SetBufferSize(originatorMac->GetMpduBufferSize());
414 reqHdr.SetTimeout(0);
415 reqHdr.SetStartingSequence(0);
416 if (gcrGroupAddr)
417 {
418 reqHdr.SetGcrGroupAddress(gcrGroupAddr.value());
419 }
420
421 // ADDBA Response
423 StatusCode code;
424 code.SetSuccess();
425 respHdr.SetStatusCode(code);
426 respHdr.SetAmsduSupport(true);
427 respHdr.SetImmediateBlockAck();
428 respHdr.SetTid(tid);
429 auto agrBufferSize = std::min(reqHdr.GetBufferSize(), recipientMac->GetMpduBufferSize());
430 respHdr.SetBufferSize(agrBufferSize);
431 respHdr.SetTimeout(0);
432 if (auto gcrGroupAddr = reqHdr.GetGcrGroupAddress())
433 {
434 respHdr.SetGcrGroupAddress(gcrGroupAddr.value());
435 }
436
437 originatorBaManager->CreateOriginatorAgreement(reqHdr, recipientAddr);
438 recipientBaManager->CreateRecipientAgreement(respHdr,
439 originatorAddr,
440 reqHdr.GetStartingSequence(),
441 recipientMac->m_rxMiddle);
442 auto recipientAgr [[maybe_unused]] =
443 recipientBaManager->GetAgreementAsRecipient(originatorAddr,
444 tid,
445 reqHdr.GetGcrGroupAddress());
446 NS_ASSERT_MSG(recipientAgr.has_value(),
447 "No agreement as recipient found for originator " << originatorAddr << ", TID "
448 << +tid);
449 originatorBaManager->UpdateOriginatorAgreement(respHdr,
450 recipientAddr,
451 reqHdr.GetStartingSequence());
452 auto originatorAgr [[maybe_unused]] =
453 originatorBaManager->GetAgreementAsOriginator(recipientAddr,
454 tid,
455 reqHdr.GetGcrGroupAddress());
456 NS_ASSERT_MSG(originatorAgr.has_value(),
457 "No agreement as originator found for recipient " << recipientAddr << ", TID "
458 << +tid);
459}
460
463{
464 // Originator is AdhocWifiMac type
465 // FIXME Restricted to single link operation, as AdHocWifiMac does not support multi-link yet
466 if (const auto origAdhoc = DynamicCast<AdhocWifiMac>(originatorMac))
467 {
468 return origAdhoc->GetAddress();
469 }
470
471 // Recipient is AdhocWifiMac type
472 // Return MAC address of link communicating with recipient
473 if (const auto recAdhoc = DynamicCast<AdhocWifiMac>(recipientMac))
474 {
475 const auto origSta = DynamicCast<StaWifiMac>(originatorMac);
476 NS_ASSERT_MSG(origSta, "Expected originator StaWifiMac type");
477 return origSta->GetLocalAddress(recAdhoc->GetAddress());
478 }
479
480 // Infra WLAN case
481 auto isOriginatorClient{true};
482 auto staMac = DynamicCast<StaWifiMac>(originatorMac);
483 if (!staMac)
484 {
485 staMac = DynamicCast<StaWifiMac>(recipientMac);
486 isOriginatorClient = false;
487 }
488 NS_ASSERT_MSG(staMac, "Expected one of the MACs to be StaWifiMac type");
489
490 const auto setupLinks = staMac->GetSetupLinkIds();
491 const auto nSetupLinks = setupLinks.size();
492 if (nSetupLinks != 1)
493 { // Handle cases other than single link association
494 return originatorMac->GetAddress();
495 }
496
497 // Handle case where one device is MLD and other is single link device
498 // Link MAC address to be used for Block ACK agreement
499 // Required for one device to be StaWifiMac type
500 const auto linkId = *(setupLinks.cbegin());
501 if (isOriginatorClient)
502 {
503 const auto fem = originatorMac->GetFrameExchangeManager(linkId);
504 return fem->GetAddress();
505 }
506 else
507 {
508 const auto fem = recipientMac->GetFrameExchangeManager(linkId);
509 return fem->GetBssid();
510 }
511}
512
515{
516 return GetBaOriginatorAddr(recipientMac, originatorMac);
517}
518
519void
526
527void
529 Ptr<WifiNetDevice> clientDev)
530{
532
533 auto clientMac = DynamicCast<StaWifiMac>(clientDev->GetMac());
534 NS_ASSERT_MSG(clientMac, "Expected StaWifiMac");
535 NS_ASSERT_MSG(clientMac->IsAssociated(), "Expected Association complete");
536 auto setupLinks = clientMac->GetSetupLinkIds();
537
538 if (const auto isMldAssoc = (setupLinks.size() > 1); !isMldAssoc)
539 {
540 NS_LOG_DEBUG("Multi-link setup not performed, skipping EMLSR static setup");
541 return;
542 }
543 if (!clientDev->IsEmlsrActivated())
544 {
545 NS_LOG_DEBUG("Non-AP MLD does not support EMLSR, not performing EMLSR static setup");
546 return;
547 }
548
549 // The call below to EmlsrManager::ChangeEmlsrMode() triggers a call to
550 // StaWifiMac::NotifyEmlsrModeChanged(), which switches all STAs operating on an EMLSR link to
551 // the active mode, thus possibly overriding settings configured via the PowerSave manager and
552 // already applied after ML setup. Save the current settings so that they can be restored later
553 std::map<linkId_t, WifiPowerManagementMode> pmModes;
554 for (const auto linkId : setupLinks)
555 {
556 pmModes[linkId] = clientMac->GetPmMode(linkId);
557 }
558
559 auto emlsrManager = clientMac->GetEmlsrManager();
560 NS_ASSERT_MSG(emlsrManager, "EMLSR Manager not set");
561 emlsrManager->ComputeOperatingChannels();
562 auto emlOmnReq = emlsrManager->GetEmlOmn();
563 auto emlsrLinkId = emlsrManager->GetLinkToSendEmlOmn();
564 emlsrManager->ChangeEmlsrMode(emlsrLinkId);
565 auto clientLinkAddr = clientMac->GetFrameExchangeManager(emlsrLinkId)->GetAddress();
566 auto apMac = DynamicCast<ApWifiMac>(apDev->GetMac());
567 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
568 apMac->ReceiveEmlOmn(emlOmnReq, clientLinkAddr, emlsrLinkId);
569 apMac->EmlOmnExchangeCompleted(emlOmnReq, clientLinkAddr, emlsrLinkId);
570
571 // restore PM modes for STAs affiliated with the client device
572 for (const auto& [linkId, pmMode] : pmModes)
573 {
574 clientMac->GetLink(linkId).pmMode = pmMode;
575 }
576
577 // ApWifiMac::EmlOmnExchangeCompleted() (called above) causes the AP to consider all STAs
578 // affiliated with the client device and operating on an EMLSR link as in active mode, thus
579 // possibly overriding settings applied after ML setup. Align the views of the PM modes again
580 AlignApViewOfStaPmMode(apMac, clientMac);
581}
582
583void
585 const NetDeviceContainer& clientDevs)
586{
588
589 auto apMac = DynamicCast<ApWifiMac>(apDev->GetMac());
590 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
591 // Check if AP supports EMLSR
592 if ((!apMac->GetEhtSupported()) || (apMac->GetNLinks() == 1))
593 {
594 NS_LOG_DEBUG("AP does not support MLD, not performing EMLSR static setup");
595 return;
596 }
597
598 if (!apDev->IsEmlsrActivated())
599 {
600 NS_LOG_DEBUG("AP MLD does not support EMLSR, not performing EMLSR static setup");
601 return;
602 }
603
604 for (auto i = clientDevs.Begin(); i != clientDevs.End(); ++i)
605 {
606 auto clientDev = DynamicCast<WifiNetDevice>(*i);
607 NS_ASSERT_MSG(clientDev, "WifiNetDevice expected");
608 SetStaticEmlsr(apDev, clientDev);
609 }
610}
611
612} // namespace ns3
AttributeValue implementation for Boolean.
Definition boolean.h:26
an EUI-48 address
Implement the header for management frames of type Add Block Ack request.
std::optional< Mac48Address > GetGcrGroupAddress() const
void SetBufferSize(uint16_t size)
Set buffer size.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
void SetImmediateBlockAck()
Enable immediate BlockAck.
uint16_t GetBufferSize() const
Return the buffer size.
void SetGcrGroupAddress(const Mac48Address &address)
Set the GCR Group address.
uint16_t GetStartingSequence() const
Return the starting sequence number.
void SetTimeout(uint16_t timeout)
Set timeout.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
void SetStartingSequence(uint16_t seq)
Set the starting sequence number.
Implement the header for management frames of type Add Block Ack response.
void SetTid(uint8_t tid)
Set Traffic ID (TID).
void SetTimeout(uint16_t timeout)
Set timeout.
void SetGcrGroupAddress(const Mac48Address &address)
Set the GCR Group address.
void SetBufferSize(uint16_t size)
Set buffer size.
void SetStatusCode(StatusCode code)
Set the status code.
void SetAmsduSupport(bool supported)
Enable or disable A-MSDU support.
void SetImmediateBlockAck()
Enable immediate BlockAck.
Implement the header for management frames of type association request.
Implement the header for management frames of type association and reassociation response.
holds a vector of ns3::NetDevice pointers
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:614
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition simulator.cc:200
Status code for association response.
Definition status-code.h:21
void SetSuccess()
Set success bit to 0 (success).
Implements the IEEE 802.11 MAC header.
void SetAddr1(Mac48Address address)
Fill the Address 1 field with the given address.
void SetAddr2(Mac48Address address)
Fill the Address 2 field with the given address.
void SetAddr3(Mac48Address address)
Fill the Address 3 field with the given address.
static Mac48Address GetBaRecipientAddr(Ptr< WifiMac > originatorMac, Ptr< WifiMac > recipientMac)
Get Block ACK recipient address based on devices MAC config.
static Mac48Address GetBaOriginatorAddr(Ptr< WifiMac > originatorMac, Ptr< WifiMac > recipientMac)
Get Block ACK originator address based on devices MAC config.
static void SetStaticBlockAckPostInit(Ptr< WifiNetDevice > originatorDev, Ptr< WifiNetDevice > recipientDev, tid_t tid, std::optional< Mac48Address > gcrGroupAddr=std::nullopt)
Perform ADDBA Request-Response exchange sequence between input devices for given TID post initializat...
static void AlignApViewOfStaPmMode(Ptr< ApWifiMac > apMac, Ptr< StaWifiMac > clientMac)
Align the knowledge that the AP has about the PM mode of the STAs affiliated with the client device t...
static void SetStaticAssociation(Ptr< WifiNetDevice > bssDev, const NetDeviceContainer &clientDevs)
Bypass static capabilities exchange for input devices.
static std::map< linkId_t, linkId_t > GetLinkIdMap(Ptr< WifiNetDevice > apDev, Ptr< WifiNetDevice > clientDev)
Construct non-AP MLD link ID to AP MLD link ID mapping based on PHY channel settings.
static MgtAssocRequestHeader GetAssocReq(Ptr< StaWifiMac > staMac, linkId_t staLinkId, bool isMldAssoc)
Get Association Request for input STA link address.
static void SetStaticAssocPostInit(Ptr< WifiNetDevice > bssDev, Ptr< WifiNetDevice > clientDev)
Perform static Association Request/Response exchange for input devices post initialization at runtime...
static MgtAssocResponseHeader GetAssocResp(Mac48Address staLinkAddr, Ptr< ApWifiMac > apMac, linkId_t apLinkId, bool isMldAssoc)
Get Association Response for input STA link address from AP MAC including Multi-link Element if MLD A...
static void SetStaticEmlsrPostInit(Ptr< WifiNetDevice > apDev, Ptr< WifiNetDevice > clientDev)
Perform EML Operating Mode Notification exchange sequence between AP MLD and non-AP MLD to enable EML...
static void SetStaticBlockAck(Ptr< WifiNetDevice > apDev, const NetDeviceContainer &clientDevs, const std::set< tid_t > &tids, std::optional< Mac48Address > gcrGroupAddr=std::nullopt)
Bypass ADDBA Request-Response exchange sequence between AP and STAs for given TIDs.
static WifiMacHeader GetAssocRespMacHdr(Mac48Address staLinkAddr, Ptr< ApWifiMac > apMac, linkId_t apLinkId)
Get Association Response MAC Header for input STA link address from AP MAC including Multi-link Eleme...
static void SetStaticEmlsr(Ptr< WifiNetDevice > apDev, const NetDeviceContainer &clientDevs)
Bypass EML Operating Mode Notification exchange sequence between AP MLD and input non-AP devices.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:260
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:454
@ WIFI_PM_ACTIVE
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiTidToLinkMappingNegSupport
TID-to-Link Mapping Negotiation Support.
double MHz_u
MHz weak type.
Definition wifi-units.h:31
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605
uint8_t tid_t
IEEE 802.11-2020 9.2.4.5.2 TID subfield.
Definition wifi-utils.h:71
@ WIFI_MAC_MGT_BEACON
@ WIFI_MAC_MGT_ASSOCIATION_RESPONSE
@ WIFI_MAC_MGT_ASSOCIATION_REQUEST
uint8_t linkId_t
IEEE 802.11be D7.0 Figure 9-207e—Link ID Info field format.
Definition wifi-utils.h:74