A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
channel-access-manager.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005,2006 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#ifndef CHANNEL_ACCESS_MANAGER_H
21#define CHANNEL_ACCESS_MANAGER_H
22
23#include "wifi-phy-common.h"
25
26#include "ns3/event-id.h"
27#include "ns3/nstime.h"
28#include "ns3/object.h"
29
30#include <algorithm>
31#include <map>
32#include <memory>
33#include <unordered_map>
34#include <vector>
35
36class EmlsrUlTxopTest;
37
38namespace ns3
39{
40
41class WifiPhy;
42class PhyListener;
43class Txop;
44class FrameExchangeManager;
45
46/**
47 * \brief Manage a set of ns3::Txop
48 * \ingroup wifi
49 *
50 * Handle a set of independent ns3::Txop, each of which represents
51 * a single DCF within a MAC stack. Each ns3::Txop has a priority
52 * implicitly associated with it (the priority is determined when the
53 * ns3::Txop is added to the ChannelAccessManager: the first Txop to be
54 * added gets the highest priority, the second, the second highest
55 * priority, and so on.) which is used to handle "internal" collisions.
56 * i.e., when two local Txop are expected to get access to the
57 * medium at the same time, the highest priority local Txop wins
58 * access to the medium and the other Txop suffers a "internal"
59 * collision.
60 */
62{
63 /// Allow test cases to access private members
64 friend class ::EmlsrUlTxopTest;
65
66 public:
68 ~ChannelAccessManager() override;
69
70 /**
71 * \brief Get the type ID.
72 * \return the object TypeId
73 */
74 static TypeId GetTypeId();
75
76 /**
77 * Set up (or reactivate) listener for PHY events on the given PHY. The new (or reactivated)
78 * listener becomes the active listener and the previous active listener attached to another
79 * PHY, if any, is deactivated.
80 *
81 * \param phy the WifiPhy to listen to
82 */
84 /**
85 * Remove current registered listener for PHY events on the given PHY.
86 *
87 * \param phy the WifiPhy to listen to
88 */
90 /**
91 * Deactivate current registered listener for PHY events on the given PHY. All notifications
92 * but channel switch notifications coming from an inactive listener are ignored.
93 *
94 * \param phy the WifiPhy to listen to
95 */
97 /**
98 * Set the ID of the link this Channel Access Manager is associated with.
99 *
100 * \param linkId the ID of the link this Channel Access Manager is associated with
101 */
102 void SetLinkId(uint8_t linkId);
103 /**
104 * Set up the Frame Exchange Manager.
105 *
106 * \param feManager the Frame Exchange Manager
107 */
109
110 /**
111 * \param txop a new Txop.
112 *
113 * The ChannelAccessManager does not take ownership of this pointer so, the callee
114 * must make sure that the Txop pointer will stay valid as long
115 * as the ChannelAccessManager is valid. Note that the order in which Txop
116 * objects are added to a ChannelAccessManager matters: the first Txop added
117 * has the highest priority, the second Txop added, has the second
118 * highest priority, etc.
119 */
120 void Add(Ptr<Txop> txop);
121
122 /**
123 * Determine if a new backoff needs to be generated as per letter a) of Section 10.23.2.2
124 * of IEEE 802.11-2020 ("EDCA backoff procedure"). This method is called upon the occurrence
125 * of events such as the enqueuing of a packet or the unblocking of some links after they
126 * have been blocked for some reason (e.g., wait for ADDBA Response, wait for TX on another
127 * EMLSR link to finish, etc.). The <i>checkMediumBusy</i> argument allows to generate a new
128 * backoff regardless of the busy/idle state of the medium, as per Section 35.3.16.4 of
129 * 802.11be D4.0.
130 *
131 * \param txop the Txop requesting to generate a backoff
132 * \param hadFramesToTransmit whether packets available for transmission were queued just
133 * before the occurrence of the event triggering this call
134 * \param checkMediumBusy whether generation of backoff (also) depends on the busy/idle state
135 * of the medium
136 * \return true if backoff needs to be generated, false otherwise
137 */
138 bool NeedBackoffUponAccess(Ptr<Txop> txop, bool hadFramesToTransmit, bool checkMediumBusy);
139
140 /**
141 * \param txop a Txop
142 *
143 * Notify the ChannelAccessManager that a specific Txop needs access to the
144 * medium. The ChannelAccessManager is then responsible for starting an access
145 * timer and, invoking FrameExchangeManager::StartTransmission when the access
146 * is granted if it ever gets granted.
147 */
148 void RequestAccess(Ptr<Txop> txop);
149
150 /**
151 * Access will never be granted to the medium _before_
152 * the time returned by this method.
153 *
154 * \param ignoreNav flag whether NAV should be ignored
155 *
156 * \returns the absolute time at which access could start to be granted
157 */
158 Time GetAccessGrantStart(bool ignoreNav = false) const;
159
160 /**
161 * \param qosTxop a QosTxop that needs to be disabled
162 * \param duration the amount of time during which the QosTxop is disabled
163 *
164 * Disable the given EDCA for the given amount of time. This EDCA will not be
165 * granted channel access during this period and the backoff timer will be frozen.
166 * After this period, the EDCA will start normal operations again by resuming
167 * the backoff timer.
168 */
169 void DisableEdcaFor(Ptr<Txop> qosTxop, Time duration);
170
171 /**
172 * Set the member variable indicating whether the backoff should be invoked when an AC gains
173 * the right to start a TXOP but it does not transmit any frame (e.g., due to constraints
174 * associated with EMLSR operations), provided that the queue is not actually empty.
175 *
176 * \param enable whether to enable backoff generation when no TX is performed in a TXOP
177 */
178 void SetGenerateBackoffOnNoTx(bool enable);
179
180 /**
181 * \return whether the backoff should be invoked when an AC gains the right to start a TXOP
182 * but it does not transmit any frame (e.g., due to constraints associated with EMLSR
183 * operations), provided that the queue is not actually empty
184 */
185 bool GetGenerateBackoffOnNoTx() const;
186
187 /**
188 * Return the width of the largest primary channel that has been idle for the
189 * given time interval before the given time, if any primary channel has been
190 * idle, or zero, otherwise.
191 *
192 * \param interval the given time interval
193 * \param end the given end time
194 * \return the width of the largest primary channel that has been idle for the
195 * given time interval before the given time, if any primary channel has
196 * been idle, or zero, otherwise
197 */
198 uint16_t GetLargestIdlePrimaryChannel(Time interval, Time end);
199
200 /**
201 * \param indices a set of indices (starting at 0) specifying the 20 MHz channels to test
202 * \return true if per-20 MHz CCA indicates busy for at least one of the
203 * specified 20 MHz channels, false otherwise
204 */
205 bool GetPer20MHzBusy(const std::set<uint8_t>& indices) const;
206
207 /**
208 * \param duration expected duration of reception
209 *
210 * Notify the Txop that a packet reception started
211 * for the expected duration.
212 */
213 void NotifyRxStartNow(Time duration);
214 /**
215 * Notify the Txop that a packet reception was just
216 * completed successfully.
217 */
218 void NotifyRxEndOkNow();
219 /**
220 * Notify the Txop that a packet reception was just
221 * completed unsuccessfuly.
222 */
223 void NotifyRxEndErrorNow();
224 /**
225 * \param duration expected duration of transmission
226 *
227 * Notify the Txop that a packet transmission was
228 * just started and is expected to last for the specified
229 * duration.
230 */
231 void NotifyTxStartNow(Time duration);
232 /**
233 * \param duration expected duration of CCA busy period
234 * \param channelType the channel type for which the CCA busy state is reported.
235 * \param per20MhzDurations vector that indicates for how long each 20 MHz subchannel
236 * (corresponding to the index of the element in the vector) is busy and where a zero
237 * duration indicates that the subchannel is idle. The vector is non-empty if the PHY supports
238 * 802.11ax or later and if the operational channel width is larger than 20 MHz.
239 *
240 * Notify the Txop that a CCA busy period has just started.
241 */
242 void NotifyCcaBusyStartNow(Time duration,
243 WifiChannelListType channelType,
244 const std::vector<Time>& per20MhzDurations);
245 /**
246 * \param phyListener the PHY listener that sent this notification
247 * \param duration expected duration of channel switching period
248 *
249 * Notify the Txop that a channel switching period has just started.
250 * During switching state, new packets can be enqueued in Txop/QosTxop
251 * but they won't access to the medium until the end of the channel switching.
252 */
253 void NotifySwitchingStartNow(PhyListener* phyListener, Time duration);
254 /**
255 * Notify the Txop that the device has been put in sleep mode.
256 */
257 void NotifySleepNow();
258 /**
259 * Notify the Txop that the device has been put in off mode.
260 */
261 void NotifyOffNow();
262 /**
263 * Notify the Txop that the device has been resumed from sleep mode.
264 */
265 void NotifyWakeupNow();
266 /**
267 * Notify the Txop that the device has been resumed from off mode.
268 */
269 void NotifyOnNow();
270 /**
271 * \param duration the value of the received NAV.
272 *
273 * Called at end of RX
274 */
275 void NotifyNavResetNow(Time duration);
276 /**
277 * \param duration the value of the received NAV.
278 *
279 * Called at end of RX
280 */
281 void NotifyNavStartNow(Time duration);
282 /**
283 * Notify that ack timer has started for the given duration.
284 *
285 * \param duration the duration of the timer
286 */
287 void NotifyAckTimeoutStartNow(Time duration);
288 /**
289 * Notify that ack timer has reset.
290 */
292 /**
293 * Notify that CTS timer has started for the given duration.
294 *
295 * \param duration the duration of the timer
296 */
297 void NotifyCtsTimeoutStartNow(Time duration);
298 /**
299 * Notify that CTS timer has reset.
300 */
302
303 /**
304 * Notify that another EMLSR link is being used, hence medium access should be disabled.
305 */
307 /**
308 * Notify that another EMLSR link is no longer being used, hence medium access can be resumed.
309 */
311
312 /**
313 * Check if the device is busy sending or receiving,
314 * or NAV or CCA busy.
315 *
316 * \return true if the device is busy,
317 * false otherwise
318 */
319 bool IsBusy() const;
320
321 /**
322 * Reset the state variables of this channel access manager.
323 */
324 void ResetState();
325 /**
326 * Reset the backoff for the given DCF/EDCAF.
327 *
328 * \param txop the given DCF/EDCAF
329 */
330 void ResetBackoff(Ptr<Txop> txop);
331
332 /**
333 * Reset the backoff for all the DCF/EDCAF. Additionally, cancel the access timeout event.
334 */
335 void ResetAllBackoffs();
336
337 /**
338 * Notify that the given PHY is about to switch to the given operating channel, which is
339 * used by the given link. This notification is sent by the EMLSR Manager when a PHY object
340 * switches operating channel to operate on another link.
341 *
342 * \param phy the PHY object that is going to switch channel
343 * \param channel the new operating channel of the given PHY
344 * \param linkId the ID of the link on which the given PHY is going to operate
345 */
347 const WifiPhyOperatingChannel& channel,
348 uint8_t linkId);
349
350 protected:
351 void DoInitialize() override;
352 void DoDispose() override;
353
354 private:
355 /**
356 * Get current registered listener for PHY events on the given PHY.
357 *
358 * \param phy the given PHY
359 * \return the current registered listener for PHY events on the given PHY
360 */
361 std::shared_ptr<PhyListener> GetPhyListener(Ptr<WifiPhy> phy) const;
362 /**
363 * Initialize the structures holding busy end times per channel type (primary,
364 * secondary, etc.) and per 20 MHz channel.
365 */
366 void InitLastBusyStructs();
367 /**
368 * Update backoff slots for all Txops.
369 */
370 void UpdateBackoff();
371 /**
372 * Return the time when the backoff procedure
373 * started for the given Txop.
374 *
375 * \param txop the Txop
376 *
377 * \return the time when the backoff procedure started
378 */
380 /**
381 * Return the time when the backoff procedure
382 * ended (or will ended) for the given Txop.
383 *
384 * \param txop the Txop
385 *
386 * \return the time when the backoff procedure ended (or will ended)
387 */
389 /**
390 * This method determines whether the medium has been idle during a period (of
391 * non-null duration) immediately preceding the time this method is called. If
392 * so, the last idle start time and end time for each channel type are updated.
393 * Otherwise, no change is made by this method.
394 * This method is normally called when we are notified of the start of a
395 * transmission, reception, CCA Busy or switching to correctly maintain the
396 * information about the last idle period.
397 */
399
401
402 /**
403 * Called when access timeout should occur
404 * (e.g. backoff procedure expired).
405 */
406 void AccessTimeout();
407 /**
408 * Grant access to Txop using DCF/EDCF contention rules
409 */
410 void DoGrantDcfAccess();
411
412 /**
413 * Return the Short Interframe Space (SIFS) for this PHY.
414 *
415 * \return the SIFS duration
416 */
417 virtual Time GetSifs() const;
418 /**
419 * Return the slot duration for this PHY.
420 *
421 * \return the slot duration
422 */
423 virtual Time GetSlot() const;
424 /**
425 * Return the EIFS duration minus a DIFS.
426 *
427 * \return the EIFS duration minus a DIFS
428 */
429 virtual Time GetEifsNoDifs() const;
430
431 /**
432 * Structure defining start time and end time for a given state.
433 */
434 struct Timespan
435 {
436 Time start{0}; //!< start time
437 Time end{0}; //!< end time
438 };
439
440 /**
441 * typedef for a vector of Txops
442 */
443 typedef std::vector<Ptr<Txop>> Txops;
444
445 Txops m_txops; //!< the vector of managed Txops
446 Time m_lastAckTimeoutEnd; //!< the last Ack timeout end time
447 Time m_lastCtsTimeoutEnd; //!< the last CTS timeout end time
448 Time m_lastNavEnd; //!< the last NAV end time
449 Timespan m_lastRx; //!< the last receive start and end time
450 bool m_lastRxReceivedOk; //!< the last receive OK
451 Time m_lastTxEnd; //!< the last transmit end time
452 std::map<WifiChannelListType, Time>
453 m_lastBusyEnd; //!< the last busy end time for each channel type
454 std::vector<Time> m_lastPer20MHzBusyEnd; /**< the last busy end time per 20 MHz channel
455 (HE stations and channel width > 20 MHz only) */
456 std::map<WifiChannelListType, Timespan>
457 m_lastIdle; //!< the last idle start and end time for each channel type
458 Time m_lastSwitchingEnd; //!< the last switching end time
459 bool m_usingOtherEmlsrLink; //!< whether another EMLSR link is being used
460 bool m_sleeping; //!< flag whether it is in sleeping state
461 bool m_off; //!< flag whether it is in off state
462 Time m_eifsNoDifs; //!< EIFS no DIFS time
463 EventId m_accessTimeout; //!< the access timeout ID
464 bool m_generateBackoffOnNoTx; //!< whether the backoff should be invoked when the AC gains the
465 //!< right to start a TXOP but it does not transmit any frame
466 //!< (e.g., due to constraints associated with EMLSR operations),
467 //!< provided that the queue is not actually empty
468
469 /// Information associated with each PHY that is going to operate on another EMLSR link
471 {
472 WifiPhyOperatingChannel channel; //!< new operating channel
473 uint8_t linkId; //!< ID of the EMLSR link on which the PHY is going to operate
474 };
475
476 /// Store information about the PHY objects that are going to operate on another EMLSR link
477 std::unordered_map<Ptr<WifiPhy>, EmlsrLinkSwitchInfo> m_switchingEmlsrLinks;
478
479 /// Maps each PHY listener to the associated PHY
480 using PhyListenerMap = std::unordered_map<Ptr<WifiPhy>, std::shared_ptr<PhyListener>>;
481
482 PhyListenerMap m_phyListeners; //!< the PHY listeners
483 Ptr<WifiPhy> m_phy; //!< pointer to the unique active PHY
484 Ptr<FrameExchangeManager> m_feManager; //!< pointer to the Frame Exchange Manager
485 uint8_t m_linkId; //!< the ID of the link this object is associated with
486};
487
488} // namespace ns3
489
490#endif /* CHANNEL_ACCESS_MANAGER_H */
Test the transmission of UL frames from EMLSR clients.
Manage a set of ns3::Txop.
uint16_t GetLargestIdlePrimaryChannel(Time interval, Time end)
Return the width of the largest primary channel that has been idle for the given time interval before...
std::vector< Time > m_lastPer20MHzBusyEnd
the last busy end time per 20 MHz channel (HE stations and channel width > 20 MHz only)
bool IsBusy() const
Check if the device is busy sending or receiving, or NAV or CCA busy.
void ResetBackoff(Ptr< Txop > txop)
Reset the backoff for the given DCF/EDCAF.
void NotifyRxEndErrorNow()
Notify the Txop that a packet reception was just completed unsuccessfuly.
bool m_off
flag whether it is in off state
void NotifyRxStartNow(Time duration)
void NotifySwitchingStartNow(PhyListener *phyListener, Time duration)
Time GetBackoffEndFor(Ptr< Txop > txop)
Return the time when the backoff procedure ended (or will ended) for the given Txop.
void ResetState()
Reset the state variables of this channel access manager.
void NotifySwitchingEmlsrLink(Ptr< WifiPhy > phy, const WifiPhyOperatingChannel &channel, uint8_t linkId)
Notify that the given PHY is about to switch to the given operating channel, which is used by the giv...
void NotifyStopUsingOtherEmlsrLink()
Notify that another EMLSR link is no longer being used, hence medium access can be resumed.
void ResetAllBackoffs()
Reset the backoff for all the DCF/EDCAF.
void NotifyWakeupNow()
Notify the Txop that the device has been resumed from sleep mode.
bool m_lastRxReceivedOk
the last receive OK
std::unordered_map< Ptr< WifiPhy >, EmlsrLinkSwitchInfo > m_switchingEmlsrLinks
Store information about the PHY objects that are going to operate on another EMLSR link.
std::map< WifiChannelListType, Timespan > m_lastIdle
the last idle start and end time for each channel type
Ptr< WifiPhy > m_phy
pointer to the unique active PHY
void NotifyAckTimeoutResetNow()
Notify that ack timer has reset.
void SetGenerateBackoffOnNoTx(bool enable)
Set the member variable indicating whether the backoff should be invoked when an AC gains the right t...
void NotifyTxStartNow(Time duration)
void NotifyRxEndOkNow()
Notify the Txop that a packet reception was just completed successfully.
virtual Time GetEifsNoDifs() const
Return the EIFS duration minus a DIFS.
uint8_t m_linkId
the ID of the link this object is associated with
void NotifyCcaBusyStartNow(Time duration, WifiChannelListType channelType, const std::vector< Time > &per20MhzDurations)
Time m_lastAckTimeoutEnd
the last Ack timeout end time
Time m_eifsNoDifs
EIFS no DIFS time.
virtual Time GetSlot() const
Return the slot duration for this PHY.
void NotifyAckTimeoutStartNow(Time duration)
Notify that ack timer has started for the given duration.
void AccessTimeout()
Called when access timeout should occur (e.g.
void UpdateBackoff()
Update backoff slots for all Txops.
void DeactivatePhyListener(Ptr< WifiPhy > phy)
Deactivate current registered listener for PHY events on the given PHY.
bool m_sleeping
flag whether it is in sleeping state
void SetLinkId(uint8_t linkId)
Set the ID of the link this Channel Access Manager is associated with.
void SetupFrameExchangeManager(Ptr< FrameExchangeManager > feManager)
Set up the Frame Exchange Manager.
bool NeedBackoffUponAccess(Ptr< Txop > txop, bool hadFramesToTransmit, bool checkMediumBusy)
Determine if a new backoff needs to be generated as per letter a) of Section 10.23....
void NotifyCtsTimeoutStartNow(Time duration)
Notify that CTS timer has started for the given duration.
void RequestAccess(Ptr< Txop > txop)
Time m_lastSwitchingEnd
the last switching end time
Timespan m_lastRx
the last receive start and end time
std::map< WifiChannelListType, Time > m_lastBusyEnd
the last busy end time for each channel type
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for PHY events on the given PHY.
bool m_generateBackoffOnNoTx
whether the backoff should be invoked when the AC gains the right to start a TXOP but it does not tra...
Time m_lastTxEnd
the last transmit end time
void SetupPhyListener(Ptr< WifiPhy > phy)
Set up (or reactivate) listener for PHY events on the given PHY.
void NotifyStartUsingOtherEmlsrLink()
Notify that another EMLSR link is being used, hence medium access should be disabled.
Time m_lastCtsTimeoutEnd
the last CTS timeout end time
void DoDispose() override
Destructor implementation.
void NotifySleepNow()
Notify the Txop that the device has been put in sleep mode.
Ptr< FrameExchangeManager > m_feManager
pointer to the Frame Exchange Manager
bool m_usingOtherEmlsrLink
whether another EMLSR link is being used
void UpdateLastIdlePeriod()
This method determines whether the medium has been idle during a period (of non-null duration) immedi...
std::vector< Ptr< Txop > > Txops
typedef for a vector of Txops
void DisableEdcaFor(Ptr< Txop > qosTxop, Time duration)
void DoInitialize() override
Initialize() implementation.
Txops m_txops
the vector of managed Txops
bool GetPer20MHzBusy(const std::set< uint8_t > &indices) const
static TypeId GetTypeId()
Get the type ID.
void DoGrantDcfAccess()
Grant access to Txop using DCF/EDCF contention rules.
std::shared_ptr< PhyListener > GetPhyListener(Ptr< WifiPhy > phy) const
Get current registered listener for PHY events on the given PHY.
Time m_lastNavEnd
the last NAV end time
void NotifyCtsTimeoutResetNow()
Notify that CTS timer has reset.
void NotifyOffNow()
Notify the Txop that the device has been put in off mode.
Time GetAccessGrantStart(bool ignoreNav=false) const
Access will never be granted to the medium before the time returned by this method.
void NotifyOnNow()
Notify the Txop that the device has been resumed from off mode.
Time GetBackoffStartFor(Ptr< Txop > txop)
Return the time when the backoff procedure started for the given Txop.
PhyListenerMap m_phyListeners
the PHY listeners
virtual Time GetSifs() const
Return the Short Interframe Space (SIFS) for this PHY.
EventId m_accessTimeout
the access timeout ID
void InitLastBusyStructs()
Initialize the structures holding busy end times per channel type (primary, secondary,...
std::unordered_map< Ptr< WifiPhy >, std::shared_ptr< PhyListener > > PhyListenerMap
Maps each PHY listener to the associated PHY.
An identifier for simulation events.
Definition: event-id.h:55
A base class which provides memory management and object aggregation.
Definition: object.h:89
Listener for PHY events.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
Class that keeps track of all information about the current PHY operating channel.
WifiChannelListType
Enumeration of the possible channel-list parameter elements defined in Table 8-5 of IEEE 802....
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Structure defining start time and end time for a given state.
Declaration of the following enums: