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/simulator.h"
24#include "ns3/sta-wifi-mac.h"
25#include "ns3/wifi-net-device.h"
26#include "ns3/wifi-remote-station-manager.h"
27#include "ns3/wifi-utils.h"
28
29NS_LOG_COMPONENT_DEFINE("WifiStaticSetupHelper");
30
31namespace ns3
32{
33
34void
36 const NetDeviceContainer& clientDevs)
37{
39
40 for (auto i = clientDevs.Begin(); i != clientDevs.End(); ++i)
41 {
42 auto clientDev = DynamicCast<WifiNetDevice>(*i);
43 NS_ASSERT_MSG(clientDev, "WifiNetDevice expected");
44 SetStaticAssociation(bssDev, clientDev);
45 }
46}
47
48void
56
57void
59 Ptr<WifiNetDevice> clientDev)
60{
62
63 auto clientMac = DynamicCast<StaWifiMac>(clientDev->GetMac());
64 auto apMac = DynamicCast<ApWifiMac>(bssDev->GetMac());
65
66 NS_ABORT_MSG_IF(!apMac || !clientMac, "Invalid static capabilities exchange case");
67 SetStaticAssocPostInit(apMac, clientMac);
68}
69
70void
72{
74
75 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
76 NS_ASSERT_MSG(clientMac, "Expected StaWifiMac");
77
78 // disable scanning
79 clientMac->SetAttribute("EnableScanning", BooleanValue(false));
80
81 const auto linkIdMap = GetLinkIdMap(apMac, clientMac);
82 const auto nClientLinks = clientMac->GetNLinks();
83 const auto isMldAssoc = nClientLinks > 1;
84 const auto apMldAddr = apMac->GetAddress();
85 const auto clientMldAddr = clientMac->GetAddress();
86
87 // Swap links at client MAC to match with AP (MLD)
88 clientMac->SwapLinks(linkIdMap);
89 const auto clientLinkIds = clientMac->GetLinkIds();
90 const auto assocLinkId = *clientLinkIds.cbegin();
91 std::optional<MultiLinkElement> apMle;
92 if (isMldAssoc)
93 {
94 apMle = apMac->GetMultiLinkElement(assocLinkId, WIFI_MAC_MGT_BEACON);
95 }
96 std::shared_ptr<CommonInfoBasicMle> mleCommonInfo;
97 for (const auto clientLinkId : clientLinkIds)
98 {
99 // AP Link ID matches with non-AP MLD Link ID after swap operation
100 // using WifiMac::SwapLinks performed above
101 const auto apLinkId = clientLinkId;
102 auto& clientLink = clientMac->GetLink(clientLinkId);
103
104 // Set BSSID
105 auto apLinkAddr = apMac->GetFrameExchangeManager(apLinkId)->GetAddress();
106 clientMac->SetBssid(apLinkAddr, clientLinkId);
107 clientLink.bssid = apLinkAddr;
108 if (!isMldAssoc)
109 {
110 continue;
111 }
112 NS_ASSERT_MSG(apMle.has_value(), "Expected Multi-link Element");
113 if (!mleCommonInfo)
114 {
115 mleCommonInfo = std::make_shared<CommonInfoBasicMle>(apMle->GetCommonInfoBasic());
116 }
117 auto clientManager = clientMac->GetWifiRemoteStationManager(clientLinkId);
118 clientManager->AddStationMleCommonInfo(apLinkAddr, mleCommonInfo);
119 }
120
121 // Association Request
122 auto assocReq = GetAssocReq(clientMac, assocLinkId, isMldAssoc);
123 auto clientLinkAddr = clientMac->GetFrameExchangeManager(assocLinkId)->GetAddress();
125 assocReqHdr.SetAddr2(clientLinkAddr);
126 auto assocSuccess = apMac->ReceiveAssocRequest(assocReq, clientLinkAddr, assocLinkId);
127 apMac->ParseReportedStaInfo(assocReq, clientLinkAddr, assocLinkId);
128 NS_ASSERT_MSG(assocSuccess,
129 "Static Association failed AP: " << apMldAddr << ", STA: " << clientMldAddr);
130
131 // Association Response
132 clientMac->SetState(StaWifiMac::WAIT_ASSOC_RESP);
133 auto assocResp = GetAssocResp(clientLinkAddr, apMac, assocLinkId, isMldAssoc);
134 auto assocRespMacHdr = GetAssocRespMacHdr(clientLinkAddr, apMac, assocLinkId);
135 auto linkIdStaAddrMap = apMac->GetLinkIdStaAddrMap(assocResp, clientLinkAddr, assocLinkId);
136 apMac->SetAid(assocResp, linkIdStaAddrMap);
137 auto packet = Create<Packet>();
138 packet->AddHeader(assocResp);
139 auto mpdu = Create<WifiMpdu>(packet, assocRespMacHdr);
140 clientMac->ReceiveAssocResp(mpdu, assocLinkId);
141
142 // Record Association success in Remote STA manager
143 for (auto clientLinkId : clientLinkIds)
144 {
145 const auto apLinkId = clientLinkId;
146 clientLinkAddr = clientMac->GetFrameExchangeManager(clientLinkId)->GetAddress();
147 apMac->GetWifiRemoteStationManager(apLinkId)->RecordGotAssocTxOk(clientLinkAddr);
148 const auto aid = apMac->GetAssociationId(clientLinkAddr, apLinkId);
149 if (const auto gcrMgr = apMac->GetGcrManager())
150 {
151 const auto extendedCapabilities =
152 apMac->GetWifiRemoteStationManager(apLinkId)->GetStationExtendedCapabilities(
153 clientLinkAddr);
154 gcrMgr->NotifyStaAssociated(clientLinkAddr,
155 extendedCapabilities &&
156 (extendedCapabilities->m_robustAvStreaming > 0));
157 }
158 apMac->m_assocLogger(aid, clientLinkAddr);
159 }
160
161 NS_LOG_DEBUG("Assoc success AP addr=" << apMldAddr << ", STA addr=" << clientMldAddr);
162
163 if (isMldAssoc)
164 {
165 // Update TID-to-Link Mapping in MAC queues
166 apMac->ApplyTidLinkMapping(clientMldAddr, WifiDirection::DOWNLINK);
167 clientMac->ApplyTidLinkMapping(apMldAddr, WifiDirection::UPLINK);
168 }
169}
170
171std::map<linkId_t, linkId_t>
173{
174 auto apMac = DynamicCast<ApWifiMac>(apDev->GetMac());
175 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
176 auto clientMac = DynamicCast<StaWifiMac>(clientDev->GetMac());
177 NS_ASSERT_MSG(clientMac, "Expected StaWifiMac");
178 return GetLinkIdMap(apMac, clientMac);
179}
180
181std::map<linkId_t, linkId_t>
183{
184 NS_ASSERT(apMac && clientMac);
185 const auto nApLinks = apMac->GetNLinks();
186 const auto nClientLinks = clientMac->GetNLinks();
187 // Assumed all links of non-AP MLD need to be associated
189 nApLinks >= nClientLinks,
190 "Expected AP MLD to have at least the same number of links than non-AP MLD, nApLinks="
191 << nApLinks << ", nClientLinks=" << nClientLinks);
192
193 std::map<linkId_t, linkId_t> linkIdMap{};
194 auto apCandidateLinks = apMac->GetLinkIds();
195
196 for (const auto clientLinkId : clientMac->GetLinkIds())
197 {
198 for (const auto apLinkId : apCandidateLinks)
199 {
200 const auto apPhy = apMac->GetWifiPhy(apLinkId);
201 const auto clientPhy = clientMac->GetWifiPhy(clientLinkId);
202 if (!apPhy || !clientPhy)
203 {
204 continue;
205 }
206 NS_LOG_DEBUG("AP channel: " << apPhy->GetOperatingChannel());
207 NS_LOG_DEBUG("Client channel: " << clientPhy->GetOperatingChannel());
208 const auto isMatch = (apPhy->GetOperatingChannel().GetPrimaryChannel(MHz_u{20}) ==
209 clientPhy->GetOperatingChannel().GetPrimaryChannel(MHz_u{20}));
210 NS_LOG_DEBUG("Client Link ID = " << +clientLinkId << ", AP Link ID Candidate="
211 << +apLinkId << ", isMatch=" << isMatch);
212 if (isMatch)
213 {
214 linkIdMap[clientLinkId] = apLinkId;
215 break;
216 }
217 }
218
219 NS_ASSERT_MSG(linkIdMap.contains(clientLinkId),
220 "No matching AP found for STA PHY setting link ID=" << +clientLinkId);
221 apCandidateLinks.erase(linkIdMap.at(clientLinkId));
222 }
223
224 return linkIdMap;
225}
226
229 Ptr<ApWifiMac> apMac,
230 linkId_t apLinkId)
231{
233 hdr.SetAddr1(clientLinkAddr);
234 auto apLinkAddr = apMac->GetFrameExchangeManager(apLinkId)->GetAddress();
235 hdr.SetAddr2(apLinkAddr);
236 hdr.SetAddr3(apLinkAddr);
237 return hdr;
238}
239
242 Ptr<ApWifiMac> apMac,
243 linkId_t apLinkId,
244 bool isMldAssoc)
245{
246 auto assocResp = apMac->GetAssocResp(clientLinkAddr, apLinkId);
247 if (!isMldAssoc)
248 {
249 return assocResp;
250 }
251 auto mle =
252 apMac->GetMultiLinkElement(apLinkId, WIFI_MAC_MGT_ASSOCIATION_RESPONSE, clientLinkAddr);
253 assocResp.Get<MultiLinkElement>() = mle;
254 return assocResp;
255}
256
259{
260 auto frame = clientMac->GetAssociationRequest(false, linkId);
261 auto assocReq = std::get<MgtAssocRequestHeader>(frame);
262 if (!isMldAssoc)
263 {
264 return assocReq;
265 }
266
267 auto mle = clientMac->GetBasicMultiLinkElement(false, linkId);
268 assocReq.Get<MultiLinkElement>() = mle;
269 auto& link = clientMac->GetLink(linkId);
270 auto bssid = *link.bssid;
271 auto remoteManager = clientMac->GetWifiRemoteStationManager(linkId);
272 const auto& mldCap = remoteManager->GetStationMldCapabilities(bssid);
273 NS_ASSERT_MSG(mldCap, "Expected MLD Capabilities info for AP MLD");
274 auto apNegSupport = mldCap->get().tidToLinkMappingSupport;
275 if (apNegSupport > 0)
276 {
277 assocReq.Get<TidToLinkMapping>() = clientMac->GetTidToLinkMappingElements(
278 static_cast<WifiTidToLinkMappingNegSupport>(apNegSupport));
279 }
280
281 return assocReq;
282}
283
284void
286 const NetDeviceContainer& clientDevs,
287 const std::set<tid_t>& tids,
288 std::optional<Mac48Address> gcrGroupAddr)
289{
291
292 for (auto i = clientDevs.Begin(); i != clientDevs.End(); ++i)
293 {
294 auto clientDev = DynamicCast<WifiNetDevice>(*i);
295 NS_ASSERT_MSG(clientDev, "WifiNetDevice expected");
296 if (!clientDev->GetHtConfiguration())
297 {
298 // Block Ack requires HT support
299 continue;
300 }
301 for (const auto tid : tids)
302 {
303 SetStaticBlockAck(apDev, clientDev, tid, gcrGroupAddr); // Downlink setup
304 SetStaticBlockAck(clientDev, apDev, tid, gcrGroupAddr); // Uplink setup
305 }
306 }
307}
308
309void
311 Ptr<WifiNetDevice> recipientDev,
312 tid_t tid,
313 std::optional<Mac48Address> gcrGroupAddr)
314{
316
318 originatorDev,
319 recipientDev,
320 tid,
321 gcrGroupAddr);
322}
323
324void
326 Ptr<WifiNetDevice> recipientDev,
327 tid_t tid,
328 std::optional<Mac48Address> gcrGroupAddr)
329{
331
332 // Originator Device
333 const auto originatorMac = originatorDev->GetMac();
334 const auto originatorLinkId = *(originatorMac->GetLinkIds().begin());
335 const auto originatorFem = DynamicCast<HtFrameExchangeManager>(
336 originatorMac->GetFrameExchangeManager(originatorLinkId));
337 NS_ASSERT_MSG(originatorFem, "Block ACK setup requires HT support");
338 const auto originatorBaManager = originatorMac->GetQosTxop(tid)->GetBaManager();
339
340 // Recipient Device
341 const auto recipientMac = recipientDev->GetMac();
342 const auto recipientLinkId = *(recipientMac->GetLinkIds().begin());
343 const auto recipientFem =
344 DynamicCast<HtFrameExchangeManager>(recipientMac->GetFrameExchangeManager(recipientLinkId));
345 NS_ASSERT_MSG(recipientFem, "Block ACK setup requires HT support");
346 const auto recipientBaManager = recipientMac->GetQosTxop(tid)->GetBaManager();
347
348 const auto originatorAddr = GetBaOriginatorAddr(originatorMac, recipientMac);
349 const auto recipientAddr = GetBaRecipientAddr(originatorMac, recipientMac);
350
351 // Early return if BA Agreement already exists
352 if (originatorMac->GetBaAgreementEstablishedAsOriginator(recipientAddr, tid, gcrGroupAddr))
353 {
354 return;
355 }
356
357 // ADDBA Request
359 reqHdr.SetAmsduSupport(true);
360 reqHdr.SetImmediateBlockAck();
361 reqHdr.SetTid(tid);
362 reqHdr.SetBufferSize(originatorMac->GetMpduBufferSize());
363 reqHdr.SetTimeout(0);
364 reqHdr.SetStartingSequence(0);
365 if (gcrGroupAddr)
366 {
367 reqHdr.SetGcrGroupAddress(gcrGroupAddr.value());
368 }
369
370 // ADDBA Response
372 StatusCode code;
373 code.SetSuccess();
374 respHdr.SetStatusCode(code);
375 respHdr.SetAmsduSupport(true);
376 respHdr.SetImmediateBlockAck();
377 respHdr.SetTid(tid);
378 auto agrBufferSize = std::min(reqHdr.GetBufferSize(), recipientMac->GetMpduBufferSize());
379 respHdr.SetBufferSize(agrBufferSize);
380 respHdr.SetTimeout(0);
381 if (auto gcrGroupAddr = reqHdr.GetGcrGroupAddress())
382 {
383 respHdr.SetGcrGroupAddress(gcrGroupAddr.value());
384 }
385
386 originatorBaManager->CreateOriginatorAgreement(reqHdr, recipientAddr);
387 recipientBaManager->CreateRecipientAgreement(respHdr,
388 originatorAddr,
389 reqHdr.GetStartingSequence(),
390 recipientMac->m_rxMiddle);
391 auto recipientAgr [[maybe_unused]] =
392 recipientBaManager->GetAgreementAsRecipient(originatorAddr,
393 tid,
394 reqHdr.GetGcrGroupAddress());
395 NS_ASSERT_MSG(recipientAgr.has_value(),
396 "No agreement as recipient found for originator " << originatorAddr << ", TID "
397 << +tid);
398 originatorBaManager->UpdateOriginatorAgreement(respHdr,
399 recipientAddr,
400 reqHdr.GetStartingSequence());
401 auto originatorAgr [[maybe_unused]] =
402 originatorBaManager->GetAgreementAsOriginator(recipientAddr,
403 tid,
404 reqHdr.GetGcrGroupAddress());
405 NS_ASSERT_MSG(originatorAgr.has_value(),
406 "No agreement as originator found for recipient " << recipientAddr << ", TID "
407 << +tid);
408}
409
412{
413 // Originator is AdhocWifiMac type
414 // FIXME Restricted to single link operation, as AdHocWifiMac does not support multi-link yet
415 if (const auto origAdhoc = DynamicCast<AdhocWifiMac>(originatorMac))
416 {
417 return origAdhoc->GetAddress();
418 }
419
420 // Recipient is AdhocWifiMac type
421 // Return MAC address of link communicating with recipient
422 if (const auto recAdhoc = DynamicCast<AdhocWifiMac>(recipientMac))
423 {
424 const auto origSta = DynamicCast<StaWifiMac>(originatorMac);
425 NS_ASSERT_MSG(origSta, "Expected originator StaWifiMac type");
426 return origSta->GetLocalAddress(recAdhoc->GetAddress());
427 }
428
429 // Infra WLAN case
430 auto isOriginatorClient{true};
431 auto staMac = DynamicCast<StaWifiMac>(originatorMac);
432 if (!staMac)
433 {
434 staMac = DynamicCast<StaWifiMac>(recipientMac);
435 isOriginatorClient = false;
436 }
437 NS_ASSERT_MSG(staMac, "Expected one of the MACs to be StaWifiMac type");
438
439 const auto setupLinks = staMac->GetSetupLinkIds();
440 const auto nSetupLinks = setupLinks.size();
441 if (nSetupLinks != 1)
442 { // Handle cases other than single link association
443 return originatorMac->GetAddress();
444 }
445
446 // Handle case where one device is MLD and other is single link device
447 // Link MAC address to be used for Block ACK agreement
448 // Required for one device to be StaWifiMac type
449 const auto linkId = *(setupLinks.cbegin());
450 if (isOriginatorClient)
451 {
452 const auto fem = originatorMac->GetFrameExchangeManager(linkId);
453 return fem->GetAddress();
454 }
455 else
456 {
457 const auto fem = recipientMac->GetFrameExchangeManager(linkId);
458 return fem->GetBssid();
459 }
460}
461
464{
465 return GetBaOriginatorAddr(recipientMac, originatorMac);
466}
467
468void
475
476void
478 Ptr<WifiNetDevice> clientDev)
479{
481
482 auto clientMac = DynamicCast<StaWifiMac>(clientDev->GetMac());
483 NS_ASSERT_MSG(clientMac, "Expected StaWifiMac");
484 NS_ASSERT_MSG(clientMac->IsAssociated(), "Expected Association complete");
485 auto setupLinks = clientMac->GetSetupLinkIds();
486
487 if (const auto isMldAssoc = (setupLinks.size() > 1); !isMldAssoc)
488 {
489 NS_LOG_DEBUG("Multi-link setup not performed, skipping EMLSR static setup");
490 return;
491 }
492 if (!clientDev->IsEmlsrActivated())
493 {
494 NS_LOG_DEBUG("Non-AP MLD does not support EMLSR, not performing EMLSR static setup");
495 return;
496 }
497
498 auto emlsrManager = clientMac->GetEmlsrManager();
499 NS_ASSERT_MSG(emlsrManager, "EMLSR Manager not set");
500 emlsrManager->ComputeOperatingChannels();
501 auto emlOmnReq = emlsrManager->GetEmlOmn();
502 auto emlsrLinkId = emlsrManager->GetLinkToSendEmlOmn();
503 emlsrManager->ChangeEmlsrMode();
504 auto clientLinkAddr = clientMac->GetFrameExchangeManager(emlsrLinkId)->GetAddress();
505 auto apMac = DynamicCast<ApWifiMac>(apDev->GetMac());
506 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
507 apMac->ReceiveEmlOmn(emlOmnReq, clientLinkAddr, emlsrLinkId);
508 apMac->EmlOmnExchangeCompleted(emlOmnReq, clientLinkAddr, emlsrLinkId);
509}
510
511void
513 const NetDeviceContainer& clientDevs)
514{
516
517 auto apMac = DynamicCast<ApWifiMac>(apDev->GetMac());
518 NS_ASSERT_MSG(apMac, "Expected ApWifiMac");
519 // Check if AP supports EMLSR
520 if ((!apMac->GetEhtSupported()) || (apMac->GetNLinks() == 1))
521 {
522 NS_LOG_DEBUG("AP does not support MLD, not performing EMLSR static setup");
523 return;
524 }
525
526 if (!apDev->IsEmlsrActivated())
527 {
528 NS_LOG_DEBUG("AP MLD does not support EMLSR, not performing EMLSR static setup");
529 return;
530 }
531
532 for (auto i = clientDevs.Begin(); i != clientDevs.End(); ++i)
533 {
534 auto clientDev = DynamicCast<WifiNetDevice>(*i);
535 NS_ASSERT_MSG(clientDev, "WifiNetDevice expected");
536 SetStaticEmlsr(apDev, clientDev);
537 }
538}
539
540} // 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:67
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
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 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:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:439
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:585
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