A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
wifi-default-assoc-manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Universita' degli Studi di Napoli Federico II
3
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Author: Stefano Avallone <stavallo@unina.it>
8 */
9
11
12#include "sta-wifi-mac.h"
13#include "wifi-net-device.h"
14#include "wifi-phy.h"
15
16#include "ns3/log.h"
17#include "ns3/simulator.h"
18#include "ns3/vht-configuration.h"
19
20#include <algorithm>
21
22namespace ns3
23{
24
25NS_LOG_COMPONENT_DEFINE("WifiDefaultAssocManager");
26
27NS_OBJECT_ENSURE_REGISTERED(WifiDefaultAssocManager);
28
29TypeId
31{
32 static TypeId tid =
33 TypeId("ns3::WifiDefaultAssocManager")
36 .SetGroupName("Wifi")
37 .AddAttribute("ChannelSwitchTimeout",
38 "After requesting a channel switch on a link to setup that link, "
39 "wait at most this amount of time. If a channel switch is not "
40 "notified within this amount of time, we give up setting up that link.",
44 return tid;
45}
46
51
56
57void
65
66bool
68{
69 return lhs.m_snr > rhs.m_snr;
70}
71
72void
74{
75 NS_LOG_FUNCTION(this);
76
77 // if there are entries in the sorted list of AP information, reuse them and
78 // do not perform scanning
79 if (!GetSortedList().empty())
80 {
82 return;
83 }
84
87
89 {
90 for (uint8_t linkId = 0; linkId < m_mac->GetNLinks(); linkId++)
91 {
94 m_mac,
95 m_mac->GetProbeRequest(linkId),
96 linkId,
99 }
101 Simulator::Schedule(GetScanParams().probeDelay + GetScanParams().maxChannelTime,
103 this);
104 }
105 else
106 {
109 this);
110 }
111}
112
113void
115{
116 NS_LOG_FUNCTION(this);
117
120 std::list<WifiAssocManager::RnrLinkInfo> apList;
121
122 // If multi-link setup is not possible, just call ScanningTimeout() and return
123 if (!CanSetupMultiLink(mle, rnr) || (apList = GetAllAffiliatedAps(*rnr)).empty())
124 {
126 return;
127 }
128
129 auto& bestAp = *GetSortedList().begin();
131
132 setupLinks.clear();
134 mle->get().GetLinkIdInfo(),
135 bestAp.m_bssid});
136
137 // sort local PHY objects so that radios with constrained PHY band comes first,
138 // then radios with no constraint
139 std::list<uint8_t> localLinkIds;
140
141 for (uint8_t linkId = 0; linkId < m_mac->GetNLinks(); linkId++)
142 {
143 if (linkId == bestAp.m_linkId)
144 {
145 // this link has been already added (it is the link on which the Beacon/Probe
146 // Response was received)
147 continue;
148 }
149
150 if (m_mac->GetWifiPhy(linkId)->HasFixedPhyBand())
151 {
152 localLinkIds.push_front(linkId);
153 }
154 else
155 {
156 localLinkIds.push_back(linkId);
157 }
158 }
159
160 // iterate over all the local links and find if we can setup a link for each of them
161 for (const auto& linkId : localLinkIds)
162 {
163 auto phy = m_mac->GetWifiPhy(linkId);
164 auto apIt = apList.begin();
165
166 while (apIt != apList.end())
167 {
168 auto apChannel = rnr->get().GetOperatingChannel(apIt->m_nbrApInfoId);
169
170 // we cannot setup a link with this affiliated AP if this PHY object is
171 // constrained to operate in the current PHY band and this affiliated AP
172 // is operating in a different PHY band than this PHY object
173 if (phy->HasFixedPhyBand() && phy->GetPhyBand() != apChannel.GetPhyBand())
174 {
175 apIt++;
176 continue;
177 }
178
179 bool needChannelSwitch = false;
180 if (phy->GetOperatingChannel() != apChannel)
181 {
182 needChannelSwitch = true;
183 }
184
185 if (needChannelSwitch && phy->IsStateSwitching())
186 {
187 // skip this affiliated AP, which is operating on a different channel
188 // than ours, because we are already switching channel and cannot
189 // schedule another channel switch to match the affiliated AP channel
190 apIt++;
191 continue;
192 }
193
194 // if we get here, it means we can setup a link with this affiliated AP
195 // set the BSSID for this link
196 Mac48Address bssid = rnr->get().GetBssid(apIt->m_nbrApInfoId, apIt->m_tbttInfoFieldId);
198 linkId,
199 rnr->get().GetMldParameters(apIt->m_nbrApInfoId, apIt->m_tbttInfoFieldId).linkId,
200 bssid});
201
203 {
204 if (phy->IsStateSleep())
205 {
206 // switching channel while a PHY is in sleep state fails
207 phy->ResumeFromSleep();
208 }
209 // switch this link to using the channel used by a reported AP (or its primary80
210 // in case the reported AP is using a 160 MHz and the non-AP MLD does not support
211 // 160 MHz operations)
212 if (apChannel.GetTotalWidth() > MHz_u{80} &&
213 !phy->GetDevice()->GetVhtConfiguration()->m_160MHzSupported)
214 {
215 apChannel = apChannel.GetPrimaryChannel(MHz_u{80});
216 }
217
218 NS_LOG_DEBUG("Switch link " << +linkId << " to using " << apChannel);
219 phy->SetOperatingChannel(apChannel);
220 // actual channel switching may be delayed, thus setup a channel switch timer
221 m_channelSwitchInfo.resize(m_mac->GetNLinks());
222 m_channelSwitchInfo[linkId].timer.Cancel();
223 m_channelSwitchInfo[linkId].timer =
226 this,
227 linkId);
228 m_channelSwitchInfo[linkId].apLinkAddress = bssid;
229 m_channelSwitchInfo[linkId].apMldAddress = mle->get().GetMldMacAddress();
230 }
231
232 // remove the affiliated AP with which we are going to setup a link and move
233 // to the next local linkId
234 apList.erase(apIt);
235 break;
236 }
237 }
238
239 if (std::none_of(m_channelSwitchInfo.begin(), m_channelSwitchInfo.end(), [](auto&& info) {
240 return info.timer.IsPending();
241 }))
242 {
243 // we are done
245 }
246}
247
248void
250{
251 NS_LOG_FUNCTION(this << +linkId);
252 if (m_channelSwitchInfo.size() > linkId && m_channelSwitchInfo[linkId].timer.IsPending())
253 {
254 // we were waiting for this notification
255 m_channelSwitchInfo[linkId].timer.Cancel();
256
257 if (std::none_of(m_channelSwitchInfo.begin(), m_channelSwitchInfo.end(), [](auto&& info) {
258 return info.timer.IsPending();
259 }))
260 {
261 // we are done
263 }
264 }
265}
266
267void
269{
270 NS_LOG_FUNCTION(this << +linkId);
271
272 // we give up setting up this link
273 auto& bestAp = *GetSortedList().begin();
275 auto it = std::find_if(setupLinks.begin(), setupLinks.end(), [&linkId](auto&& linkIds) {
276 return linkIds.localLinkId == linkId;
277 });
278 NS_ASSERT(it != setupLinks.end());
279 setupLinks.erase(it);
280
281 if (std::none_of(m_channelSwitchInfo.begin(), m_channelSwitchInfo.end(), [](auto&& info) {
282 return info.timer.IsPending();
283 }))
284 {
285 // we are done
287 }
288}
289
290bool
295
296bool
298{
299 return true;
300}
301
302} // namespace ns3
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition event-id.cc:44
bool IsPending() const
This method is syntactic sugar for !IsExpired().
Definition event-id.cc:65
an EUI-48 address
static Mac48Address GetBroadcast()
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
void EnqueueProbeRequest(const MgtProbeRequestHeader &probeReq, uint8_t linkId, const Mac48Address &addr1=Mac48Address::GetBroadcast(), const Mac48Address &addr3=Mac48Address::GetBroadcast())
Enqueue the given probe request packet for transmission on the given link.
AttributeValue implementation for Time.
Definition nstime.h:1431
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Abstract base class for the Association Manager, which manages scanning and association for single li...
const SortedList & GetSortedList() const
std::optional< std::reference_wrapper< const MultiLinkElement > > OptMleConstRef
typedef for an optional const reference to a MultiLinkElement object
Ptr< StaWifiMac > m_mac
pointer to the STA wifi MAC
std::list< StaWifiMac::ApInfo::SetupLinksInfo > & GetSetupLinks(const StaWifiMac::ApInfo &apInfo)
Get a reference to the list of the links to setup with the given AP.
void ScanningTimeout()
Extract the best AP to associate with from the sorted list and return it, if any, to the STA wifi MAC...
std::optional< std::reference_wrapper< const ReducedNeighborReport > > OptRnrConstRef
typedef for an optional const reference to a ReducedNeighborReport object
static std::list< WifiAssocManager::RnrLinkInfo > GetAllAffiliatedAps(const ReducedNeighborReport &rnr)
Find all the APs affiliated to the same AP MLD as the reporting AP that sent the given RNR element.
const WifiScanParams & GetScanParams() const
void DoDispose() override
Destructor implementation.
bool CanSetupMultiLink(OptMleConstRef &mle, OptRnrConstRef &rnr)
Check whether 11be Multi-Link setup can be established with the current best AP.
void EndScanning()
Perform operations to do at the end of a scanning procedure, such as identifying the links to setup i...
void DoDispose() override
Destructor implementation.
EventId m_probeRequestEvent
probe request event
void DoStartScanning() override
Start a scanning procedure.
bool CanBeInserted(const StaWifiMac::ApInfo &apInfo) const override
Allow subclasses to choose whether the given ApInfo shall be considered and hence inserted in the sor...
Time m_channelSwitchTimeout
maximum delay for channel switching
void NotifyChannelSwitched(uint8_t linkId) override
Notify that the given link has completed channel switching.
bool Compare(const StaWifiMac::ApInfo &lhs, const StaWifiMac::ApInfo &rhs) const override
Compare two ApInfo objects for the purpose of keeping a sorted list of ApInfo objects.
EventId m_waitBeaconEvent
wait beacon event
static TypeId GetTypeId()
Get the type ID.
void ChannelSwitchTimeout(uint8_t linkId)
Take action upon the expiration of the timer set when requesting channel switch on the given link.
std::vector< ChannelSwitchInfo > m_channelSwitchInfo
per-link channel switch info
bool CanBeReturned(const StaWifiMac::ApInfo &apInfo) const override
Allow subclasses to choose whether the given ApInfo shall be returned or discarded when the STA wifi ...
#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
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
#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(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:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1432
Struct to hold information regarding observed AP through active/passive scanning.
double m_snr
SNR in linear scale.