A Discrete-Event Network Simulator
API
channel-access-manager.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/simulator.h"
23 #include "channel-access-manager.h"
24 #include "txop.h"
25 #include "wifi-phy-listener.h"
26 #include "wifi-phy.h"
27 #include "mac-low.h"
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("ChannelAccessManager");
32 
37 {
38 public:
45  : m_cam (cam)
46  {
47  }
48  virtual ~PhyListener ()
49  {
50  }
51  void NotifyRxStart (Time duration)
52  {
53  m_cam->NotifyRxStartNow (duration);
54  }
55  void NotifyRxEndOk (void)
56  {
58  }
59  void NotifyRxEndError (void)
60  {
62  }
63  void NotifyTxStart (Time duration, double txPowerDbm)
64  {
65  m_cam->NotifyTxStartNow (duration);
66  }
67  void NotifyMaybeCcaBusyStart (Time duration)
68  {
70  }
71  void NotifySwitchingStart (Time duration)
72  {
73  m_cam->NotifySwitchingStartNow (duration);
74  }
75  void NotifySleep (void)
76  {
78  }
79  void NotifyOff (void)
80  {
81  m_cam->NotifyOffNow ();
82  }
83  void NotifyWakeup (void)
84  {
86  }
87  void NotifyOn (void)
88  {
89  m_cam->NotifyOnNow ();
90  }
91 
92 private:
94 };
95 
96 
97 /****************************************************************
98  * Implement the channel access manager of all Txop holders
99  ****************************************************************/
100 
102  : m_lastAckTimeoutEnd (MicroSeconds (0)),
103  m_lastCtsTimeoutEnd (MicroSeconds (0)),
104  m_lastNavStart (MicroSeconds (0)),
105  m_lastNavDuration (MicroSeconds (0)),
106  m_lastRxStart (MicroSeconds (0)),
107  m_lastRxDuration (MicroSeconds (0)),
108  m_lastRxReceivedOk (true),
109  m_lastTxStart (MicroSeconds (0)),
110  m_lastTxDuration (MicroSeconds (0)),
111  m_lastBusyStart (MicroSeconds (0)),
112  m_lastBusyDuration (MicroSeconds (0)),
113  m_lastSwitchingStart (MicroSeconds (0)),
114  m_lastSwitchingDuration (MicroSeconds (0)),
115  m_sleeping (false),
116  m_off (false),
117  m_phyListener (0)
118 {
119  NS_LOG_FUNCTION (this);
120 }
121 
123 {
124  NS_LOG_FUNCTION (this);
125  delete m_phyListener;
126  m_phyListener = 0;
127 }
128 
129 void
131 {
132  NS_LOG_FUNCTION (this);
133  for (Ptr<Txop> i : m_txops)
134  {
135  i->Dispose ();
136  i = 0;
137  }
138  m_phy = 0;
139 }
140 
141 void
143 {
144  NS_LOG_FUNCTION (this << phy);
145  NS_ASSERT (m_phyListener == 0);
146  m_phyListener = new PhyListener (this);
147  phy->RegisterListener (m_phyListener);
148  m_phy = phy;
149 }
150 
151 void
153 {
154  NS_LOG_FUNCTION (this << phy);
155  if (m_phyListener != 0)
156  {
157  phy->UnregisterListener (m_phyListener);
158  delete m_phyListener;
159  m_phyListener = 0;
160  m_phy = 0;
161  }
162 }
163 
164 void
166 {
167  NS_LOG_FUNCTION (this << low);
168  low->RegisterChannelAccessManager (this);
169 }
170 
171 Time
173 {
174  return m_phy->GetSlot ();
175 }
176 
177 Time
179 {
180  return m_phy->GetSifs ();
181 }
182 
183 Time
185 {
186  return m_phy->GetSifs () + m_phy->GetAckTxTime ();
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION (this << txop);
193  m_txops.push_back (txop);
194 }
195 
196 Time
197 ChannelAccessManager::MostRecent (std::initializer_list<Time> list) const
198 {
199  NS_ASSERT (list.size () > 0);
200  return *std::max_element (list.begin (), list.end ());
201 }
202 
203 bool
205 {
206  NS_LOG_FUNCTION (this);
207  // PHY busy
208  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
209  if (lastRxEnd > Simulator::Now ())
210  {
211  return true;
212  }
213  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
214  if (lastTxEnd > Simulator::Now ())
215  {
216  return true;
217  }
218  // NAV busy
219  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
220  if (lastNavEnd > Simulator::Now ())
221  {
222  return true;
223  }
224  // CCA busy
225  Time lastCCABusyEnd = m_lastBusyStart + m_lastBusyDuration;
226  if (lastCCABusyEnd > Simulator::Now ())
227  {
228  return true;
229  }
230  return false;
231 }
232 
233 bool
235 {
236  NS_LOG_FUNCTION (this << txop);
237 
238  // No backoff needed if in sleep mode or off
239  if (m_sleeping || m_off)
240  {
241  return false;
242  }
243 
244  // the Txop might have a stale value of remaining backoff slots
245  UpdateBackoff ();
246 
247  /*
248  * From section 10.3.4.2 "Basic access" of IEEE 802.11-2016:
249  *
250  * A STA may transmit an MPDU when it is operating under the DCF access
251  * method, either in the absence of a PC, or in the CP of the PCF access
252  * method, when the STA determines that the medium is idle when a frame is
253  * queued for transmission, and remains idle for a period of a DIFS, or an
254  * EIFS (10.3.2.3.7) from the end of the immediately preceding medium-busy
255  * event, whichever is the greater, and the backoff timer is zero. Otherwise
256  * the random backoff procedure described in 10.3.4.3 shall be followed.
257  *
258  * From section 10.22.2.2 "EDCA backoff procedure" of IEEE 802.11-2016:
259  *
260  * The backoff procedure shall be invoked by an EDCAF when any of the following
261  * events occurs:
262  * a) An MA-UNITDATA.request primitive is received that causes a frame with that AC
263  * to be queued for transmission such that one of the transmit queues associated
264  * with that AC has now become non-empty and any other transmit queues
265  * associated with that AC are empty; the medium is busy on the primary channel
266  */
267  if (!txop->HasFramesToTransmit () && !txop->GetLow ()->IsCfPeriod () && txop->GetBackoffSlots () == 0)
268  {
269  if (!IsBusy ())
270  {
271  // medium idle. If this is a DCF, use immediate access (we can transmit
272  // in a DIFS if the medium remains idle). If this is an EDCAF, update
273  // the backoff start time kept by the EDCAF to the current time in order
274  // to correctly align the backoff start time at the next slot boundary
275  // (performed by the next call to ChannelAccessManager::RequestAccess())
276  Time delay = (txop->IsQosTxop () ? Seconds (0)
277  : GetSifs () + txop->GetAifsn () * GetSlot ());
278  txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay);
279  }
280  else
281  {
282  // medium busy, backoff is needed
283  return true;
284  }
285  }
286  return false;
287 }
288 
289 void
291 {
292  NS_LOG_FUNCTION (this << txop);
293  if (m_phy)
294  {
296  }
297  //Deny access if in sleep mode or off
298  if (m_sleeping || m_off)
299  {
300  return;
301  }
302  if (isCfPeriod)
303  {
304  txop->NotifyAccessRequested ();
305  Time delay = (MostRecent ({GetAccessGrantStart (true), Simulator::Now ()}) - Simulator::Now ());
307  return;
308  }
309  /*
310  * EDCAF operations shall be performed at slot boundaries (Sec. 10.22.2.4 of 802.11-2016)
311  */
312  Time accessGrantStart = GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ());
313 
314  if (txop->IsQosTxop () && txop->GetBackoffStart () > accessGrantStart)
315  {
316  // The backoff start time reported by the EDCAF is more recent than the last
317  // time the medium was busy plus an AIFS, hence we need to align it to the
318  // next slot boundary.
319  Time diff = txop->GetBackoffStart () - accessGrantStart;
320  uint32_t nIntSlots = (diff / GetSlot ()).GetHigh () + 1;
321  txop->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * GetSlot ()));
322  }
323 
324  UpdateBackoff ();
325  NS_ASSERT (!txop->IsAccessRequested ());
326  txop->NotifyAccessRequested ();
327  DoGrantDcfAccess ();
329 }
330 
331 void
333 {
334  txop->NotifyAccessGranted ();
335 }
336 
337 void
339 {
340  NS_LOG_FUNCTION (this);
341  uint32_t k = 0;
342  for (Txops::iterator i = m_txops.begin (); i != m_txops.end (); k++)
343  {
344  Ptr<Txop> txop = *i;
345  if (txop->IsAccessRequested ()
346  && GetBackoffEndFor (txop) <= Simulator::Now () )
347  {
352  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots ());
353  i++; //go to the next item in the list.
354  k++;
355  std::vector<Ptr<Txop> > internalCollisionTxops;
356  for (Txops::iterator j = i; j != m_txops.end (); j++, k++)
357  {
358  Ptr<Txop> otherTxop = *j;
359  if (otherTxop->IsAccessRequested ()
360  && GetBackoffEndFor (otherTxop) <= Simulator::Now ())
361  {
362  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
363  otherTxop->GetBackoffSlots ());
369  internalCollisionTxops.push_back (otherTxop);
370  }
371  }
372 
380  txop->NotifyAccessGranted ();
381  for (auto collidingTxop : internalCollisionTxops)
382  {
383  collidingTxop->NotifyInternalCollision ();
384  }
385  break;
386  }
387  i++;
388  }
389 }
390 
391 void
393 {
394  NS_LOG_FUNCTION (this);
395  UpdateBackoff ();
396  DoGrantDcfAccess ();
398 }
399 
400 Time
402 {
403  NS_LOG_FUNCTION (this);
404  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
405  Time rxAccessStart = lastRxEnd + GetSifs ();
406  if ((lastRxEnd <= Simulator::Now ()) && !m_lastRxReceivedOk)
407  {
408  rxAccessStart += GetEifsNoDifs ();
409  }
410  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + GetSifs ();
411  Time txAccessStart = m_lastTxStart + m_lastTxDuration + GetSifs ();
412  Time navAccessStart = m_lastNavStart + m_lastNavDuration + GetSifs ();
413  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + GetSifs ();
414  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + GetSifs ();
415  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + GetSifs ();
416  Time accessGrantedStart;
417  if (ignoreNav)
418  {
419  accessGrantedStart = MostRecent ({rxAccessStart,
420  busyAccessStart,
421  txAccessStart,
422  ackTimeoutAccessStart,
423  ctsTimeoutAccessStart,
424  switchingAccessStart}
425  );
426  }
427  else
428  {
429  accessGrantedStart = MostRecent ({rxAccessStart,
430  busyAccessStart,
431  txAccessStart,
432  navAccessStart,
433  ackTimeoutAccessStart,
434  ctsTimeoutAccessStart,
435  switchingAccessStart}
436  );
437  }
438  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
439  ", rx access start=" << rxAccessStart <<
440  ", busy access start=" << busyAccessStart <<
441  ", tx access start=" << txAccessStart <<
442  ", nav access start=" << navAccessStart);
443  return accessGrantedStart;
444 }
445 
446 Time
448 {
449  NS_LOG_FUNCTION (this << txop);
450  Time mostRecentEvent = MostRecent ({txop->GetBackoffStart (),
451  GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ())});
452  NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
453 
454  return mostRecentEvent;
455 }
456 
457 Time
459 {
460  NS_LOG_FUNCTION (this << txop);
461  Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots () * GetSlot ());
462  NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
463 
464  return backoffEnd;
465 }
466 
467 void
469 {
470  NS_LOG_FUNCTION (this);
471  uint32_t k = 0;
472  for (auto txop : m_txops)
473  {
474  Time backoffStart = GetBackoffStartFor (txop);
475  if (backoffStart <= Simulator::Now ())
476  {
477  uint32_t nIntSlots = ((Simulator::Now () - backoffStart) / GetSlot ()).GetHigh ();
478  /*
479  * EDCA behaves slightly different to DCA. For EDCA we
480  * decrement once at the slot boundary at the end of AIFS as
481  * well as once at the end of each clear slot
482  * thereafter. For DCA we only decrement at the end of each
483  * clear slot after DIFS. We account for the extra backoff
484  * by incrementing the slot count here in the case of
485  * EDCA. The if statement whose body we are in has confirmed
486  * that a minimum of AIFS has elapsed since last busy
487  * medium.
488  */
489  if (txop->IsQosTxop ())
490  {
491  nIntSlots++;
492  }
493  uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots ());
494  NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
495  Time backoffUpdateBound = backoffStart + (n * GetSlot ());
496  txop->UpdateBackoffSlotsNow (n, backoffUpdateBound);
497  }
498  ++k;
499  }
500 }
501 
502 void
504 {
505  NS_LOG_FUNCTION (this);
510  bool accessTimeoutNeeded = false;
511  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
512  for (auto txop : m_txops)
513  {
514  if (txop->IsAccessRequested ())
515  {
516  Time tmp = GetBackoffEndFor (txop);
517  if (tmp > Simulator::Now ())
518  {
519  accessTimeoutNeeded = true;
520  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
521  }
522  }
523  }
524  NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
525  if (accessTimeoutNeeded)
526  {
527  NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd);
528  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
530  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
531  {
533  }
534  if (m_accessTimeout.IsExpired ())
535  {
536  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
538  }
539  }
540 }
541 
542 void
544 {
545  NS_LOG_FUNCTION (this << duration);
546  NS_LOG_DEBUG ("rx start for=" << duration);
547  UpdateBackoff ();
549  m_lastRxDuration = duration;
550  m_lastRxReceivedOk = true;
551 }
552 
553 void
555 {
556  NS_LOG_FUNCTION (this);
557  NS_LOG_DEBUG ("rx end ok");
559  m_lastRxReceivedOk = true;
560 }
561 
562 void
564 {
565  NS_LOG_FUNCTION (this);
566  NS_LOG_DEBUG ("rx end error");
567  Time now = Simulator::Now ();
568  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
569  if (lastRxEnd > now)
570  {
571  m_lastBusyStart = now;
572  m_lastBusyDuration = lastRxEnd - m_lastBusyStart;
573  }
575  m_lastRxReceivedOk = false;
576 }
577 
578 void
580 {
581  NS_LOG_FUNCTION (this << duration);
582  m_lastRxReceivedOk = true;
583  Time now = Simulator::Now ();
584  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
585  if (lastRxEnd > now)
586  {
587  //this may be caused only if PHY has started to receive a packet
588  //inside SIFS, so, we check that lastRxStart was maximum a SIFS ago
589  NS_ASSERT (now - m_lastRxStart <= GetSifs ());
591  }
592  NS_LOG_DEBUG ("tx start for " << duration);
593  UpdateBackoff ();
594  m_lastTxStart = now;
595  m_lastTxDuration = duration;
596 }
597 
598 void
600 {
601  NS_LOG_FUNCTION (this << duration);
602  NS_LOG_DEBUG ("busy start for " << duration);
603  UpdateBackoff ();
605  m_lastBusyDuration = duration;
606 }
607 
608 void
610 {
611  NS_LOG_FUNCTION (this << duration);
612  Time now = Simulator::Now ();
615 
616  m_lastRxReceivedOk = true;
617 
618  if (m_lastRxStart + m_lastRxDuration > now)
619  {
620  //channel switching during packet reception
622  }
623  if (m_lastNavStart + m_lastNavDuration > now)
624  {
626  }
628  {
630  }
631  if (m_lastAckTimeoutEnd > now)
632  {
633  m_lastAckTimeoutEnd = now;
634  }
635  if (m_lastCtsTimeoutEnd > now)
636  {
637  m_lastCtsTimeoutEnd = now;
638  }
639 
640  //Cancel timeout
641  if (m_accessTimeout.IsRunning ())
642  {
644  }
645 
646  //Reset backoffs
647  for (auto txop : m_txops)
648  {
649  uint32_t remainingSlots = txop->GetBackoffSlots ();
650  if (remainingSlots > 0)
651  {
652  txop->UpdateBackoffSlotsNow (remainingSlots, now);
653  NS_ASSERT (txop->GetBackoffSlots () == 0);
654  }
655  txop->ResetCw ();
656  txop->m_accessRequested = false;
657  txop->NotifyChannelSwitching ();
658  }
659 
660  NS_LOG_DEBUG ("switching start for " << duration);
662  m_lastSwitchingDuration = duration;
663 }
664 
665 void
667 {
668  NS_LOG_FUNCTION (this);
669  m_sleeping = true;
670  //Cancel timeout
671  if (m_accessTimeout.IsRunning ())
672  {
674  }
675 
676  //Reset backoffs
677  for (auto txop : m_txops)
678  {
679  txop->NotifySleep ();
680  }
681 }
682 
683 void
685 {
686  NS_LOG_FUNCTION (this);
687  m_off = true;
688  //Cancel timeout
689  if (m_accessTimeout.IsRunning ())
690  {
692  }
693 
694  //Reset backoffs
695  for (auto txop : m_txops)
696  {
697  txop->NotifyOff ();
698  }
699 }
700 
701 void
703 {
704  NS_LOG_FUNCTION (this);
705  m_sleeping = false;
706  for (auto txop : m_txops)
707  {
708  uint32_t remainingSlots = txop->GetBackoffSlots ();
709  if (remainingSlots > 0)
710  {
711  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
712  NS_ASSERT (txop->GetBackoffSlots () == 0);
713  }
714  txop->ResetCw ();
715  txop->m_accessRequested = false;
716  txop->NotifyWakeUp ();
717  }
718 }
719 
720 void
722 {
723  NS_LOG_FUNCTION (this);
724  m_off = false;
725  for (auto txop : m_txops)
726  {
727  uint32_t remainingSlots = txop->GetBackoffSlots ();
728  if (remainingSlots > 0)
729  {
730  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
731  NS_ASSERT (txop->GetBackoffSlots () == 0);
732  }
733  txop->ResetCw ();
734  txop->m_accessRequested = false;
735  txop->NotifyOn ();
736  }
737 }
738 
739 void
741 {
742  NS_LOG_FUNCTION (this << duration);
743  NS_LOG_DEBUG ("nav reset for=" << duration);
744  UpdateBackoff ();
746  m_lastNavDuration = duration;
754 }
755 
756 void
758 {
759  NS_LOG_FUNCTION (this << duration);
761  NS_LOG_DEBUG ("nav start for=" << duration);
762  UpdateBackoff ();
763  Time newNavEnd = Simulator::Now () + duration;
764  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
765  if (newNavEnd > lastNavEnd)
766  {
768  m_lastNavDuration = duration;
769  }
770 }
771 
772 void
774 {
775  NS_LOG_FUNCTION (this << duration);
777  m_lastAckTimeoutEnd = Simulator::Now () + duration;
778 }
779 
780 void
782 {
783  NS_LOG_FUNCTION (this);
786 }
787 
788 void
790 {
791  NS_LOG_FUNCTION (this << duration);
792  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
793 }
794 
795 void
797 {
798  NS_LOG_FUNCTION (this);
801 }
802 
803 } //namespace ns3
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
virtual Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
microsecond
Definition: nstime.h:117
void UpdateBackoff(void)
Update backoff slots for all Txops.
bool m_off
flag whether it is in off state
uint8_t GetAifsn(void) const
Return the number of slots that make up an AIFS.
Definition: txop.cc:297
void NotifyMaybeCcaBusyStart(Time duration)
Time m_lastRxDuration
the last receive duration time
Time m_lastCtsTimeoutEnd
the last CTS timeout end time
#define min(a, b)
Definition: 80211b.c:42
void NotifySwitchingStart(Time duration)
virtual bool HasFramesToTransmit(void)
Check if the Txop has frames to transmit.
Definition: txop.cc:309
void NotifyOnNow(void)
Notify the Txop that the device has been resumed from off mode.
PhyListener(ns3::ChannelAccessManager *cam)
Create a PhyListener for the given ChannelAccessManager.
virtual void NotifyAccessGranted(void)
Notify the Txop that access has been granted.
Definition: txop.cc:476
void SetupPhyListener(Ptr< WifiPhy > phy)
Set up listener for PHY events.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
void NotifyOff(void)
Notify listeners that we went to switch off.
Time GetBackoffStart(void) const
Return the time when the backoff procedure started.
Definition: txop.cc:239
void NotifyMaybeCcaBusyStartNow(Time duration)
Time m_lastBusyStart
the last busy start time
bool IsBusy(void) const
Check if the device is busy sending or receiving, or NAV or CCA busy.
void RequestAccess(Ptr< Txop > txop, bool isCfPeriod=false)
EventId m_accessTimeout
the access timeout ID
Time MostRecent(std::initializer_list< Time > list) const
Return the most recent time.
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for PHY events.
Time GetBackoffStartFor(Ptr< Txop > txop)
Return the time when the backoff procedure started for the given Txop.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Manage a set of ns3::TxopHandle a set of independent ns3::Txop, each of which represents a single DCF...
bool m_sleeping
flag whether it is in sleeping state
Time m_lastTxDuration
the last transmit duration time
void UpdateBackoffSlotsNow(uint32_t nSlots, Time backoffUpdateBound)
Update backoff slots that nSlots has passed.
Definition: txop.cc:245
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:389
bool NeedBackoffUponAccess(Ptr< Txop > txop)
Determine if a new backoff needs to be generated when a packet is queued for transmission.
void NotifyRxStartNow(Time duration)
void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
ns3::ChannelAccessManager * m_cam
ChannelAccessManager to forward events to.
Time m_lastRxStart
the last receive start time
Time m_lastBusyDuration
the last busy duration time
phy
Definition: third.py:93
void NotifyRxEndErrorNow(void)
Notify the Txop that a packet reception was just completed unsuccessfully.
Time m_lastNavDuration
the last NAV duration time
void NotifyCtsTimeoutStartNow(Time duration)
Notify that CTS timer has started for the given duration.
Ptr< WifiPhy > m_phy
pointer to the PHY
virtual Time GetEifsNoDifs(void) const
Return the EIFS duration minus a DIFS.
receive notifications about PHY events.
void NotifyOffNow(void)
Notify the Txop that the device has been put in off mode.
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:3185
Time m_lastSwitchingStart
the last switching start time
void NotifyWakeup(void)
Notify listeners that we woke up.
void NotifySleepNow(void)
Notify the Txop that the device has been put in sleep mode.
Listener for PHY events.
void NotifyTxStart(Time duration, double txPowerDbm)
virtual bool IsAccessRequested(void) const
Definition: txop.cc:463
virtual bool IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:861
#define list
Time m_lastTxStart
the last transmit start time
void NotifyNavResetNow(Time duration)
void NotifyAckTimeoutStartNow(Time duration)
Notify that ack timer has started for the given duration.
void NotifySleep(void)
Notify listeners that we went to sleep.
Txops m_txops
the vector of managed Txops
void DoGrantPcfAccess(Ptr< Txop > txop)
Grant access to Txop using PCF preemption.
virtual Time GetSlot(void) const
Return the slot duration for this PHY.
Ptr< MacLow > GetLow(void) const
Return the MacLow associated with this Txop.
Definition: txop.cc:366
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void NotifyOn(void)
Notify listeners that we went to switch on.
void NotifyRxEndOkNow(void)
Notify the Txop that a packet reception was just completed successfully.
Time GetAccessGrantStart(bool ignoreNav=false) const
Access will never be granted to the medium before the time returned by this method.
bool m_lastRxReceivedOk
the last receive OK
PhyListener * m_phyListener
the PHY listener
void NotifyCtsTimeoutResetNow(void)
Notify that CTS timer has reset.
Time GetAckTxTime(void) const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:979
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
void NotifyRxStart(Time duration)
void DoGrantDcfAccess(void)
Grant access to Txop using DCF/EDCF contention rules.
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:949
Time m_lastNavStart
the last NAV start time
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
uint32_t GetBackoffSlots(void) const
Return the current number of backoff slots.
Definition: txop.cc:233
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void NotifySwitchingStartNow(Time duration)
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:961
void NotifyNavStartNow(Time duration)
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
Time m_lastSwitchingDuration
the last switching duration time
Time GetBackoffEndFor(Ptr< Txop > txop)
Return the time when the backoff procedure ended (or will ended) for the given Txop.
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1294
void AccessTimeout(void)
Called when access timeout should occur (e.g.
void NotifyTxStartNow(Time duration)
virtual void NotifyAccessRequested(void)
Notify that access request has been received.
Definition: txop.cc:469
void SetupLow(Ptr< MacLow > low)
Set up listener for MacLow events.
void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:293
void NotifyWakeupNow(void)
Notify the Txop that the device has been resumed from sleep mode.
Time m_lastAckTimeoutEnd
the last Ack timeout end time
void DoDispose(void)
Destructor implementation.
void NotifyAckTimeoutResetNow(void)
Notify that ack timer has reset.