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_dcf (dcf)
46  {
47  }
48  virtual ~PhyListener ()
49  {
50  }
51  void NotifyRxStart (Time duration)
52  {
53  m_dcf->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_dcf->NotifyTxStartNow (duration);
66  }
67  void NotifyMaybeCcaBusyStart (Time duration)
68  {
70  }
71  void NotifySwitchingStart (Time duration)
72  {
73  m_dcf->NotifySwitchingStartNow (duration);
74  }
75  void NotifySleep (void)
76  {
78  }
79  void NotifyOff (void)
80  {
81  m_dcf->NotifyOffNow ();
82  }
83  void NotifyWakeup (void)
84  {
86  }
87  void NotifyOn (void)
88  {
89  m_dcf->NotifyOnNow ();
90  }
91 
92 private:
94 };
95 
96 
97 /****************************************************************
98  * Implement the DCF manager of all DCF state 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_lastRxEnd (MicroSeconds (0)),
110  m_lastTxStart (MicroSeconds (0)),
111  m_lastTxDuration (MicroSeconds (0)),
112  m_lastBusyStart (MicroSeconds (0)),
113  m_lastBusyDuration (MicroSeconds (0)),
114  m_lastSwitchingStart (MicroSeconds (0)),
115  m_lastSwitchingDuration (MicroSeconds (0)),
116  m_sleeping (false),
117  m_off (false),
118  m_slot (Seconds (0.0)),
119  m_sifs (Seconds (0.0)),
120  m_phyListener (0)
121 {
122  NS_LOG_FUNCTION (this);
123 }
124 
126 {
127  NS_LOG_FUNCTION (this);
128  delete m_phyListener;
129  m_phyListener = 0;
130 }
131 
132 void
134 {
135  NS_LOG_FUNCTION (this);
136  for (Ptr<Txop> i : m_states)
137  {
138  i->Dispose ();
139  i = 0;
140  }
141  m_phy = 0;
142 }
143 
144 void
146 {
147  NS_LOG_FUNCTION (this << phy);
148  NS_ASSERT (m_phyListener == 0);
149  m_phyListener = new PhyListener (this);
150  phy->RegisterListener (m_phyListener);
151  m_phy = phy;
152 }
153 
154 void
156 {
157  NS_LOG_FUNCTION (this << phy);
158  if (m_phyListener != 0)
159  {
160  phy->UnregisterListener (m_phyListener);
161  delete m_phyListener;
162  m_phyListener = 0;
163  m_phy = 0;
164  }
165 }
166 
167 void
169 {
170  NS_LOG_FUNCTION (this << low);
171  low->RegisterDcf (this);
172 }
173 
174 void
176 {
177  NS_LOG_FUNCTION (this << slotTime);
178  m_slot = slotTime;
179 }
180 
181 void
183 {
184  NS_LOG_FUNCTION (this << sifs);
185  m_sifs = sifs;
186 }
187 
188 void
190 {
191  NS_LOG_FUNCTION (this << eifsNoDifs);
192  m_eifsNoDifs = eifsNoDifs;
193 }
194 
195 Time
197 {
198  NS_LOG_FUNCTION (this);
199  return m_eifsNoDifs;
200 }
201 
202 void
204 {
205  NS_LOG_FUNCTION (this << dcf);
206  m_states.push_back (dcf);
207 }
208 
209 Time
210 ChannelAccessManager::MostRecent (std::initializer_list<Time> list) const
211 {
212  NS_ASSERT (list.size () > 0);
213  return *std::max_element (list.begin (), list.end ());
214 }
215 
216 bool
218 {
219  NS_LOG_FUNCTION (this);
220  // PHY busy
221  if (m_lastRxEnd > Simulator::Now ())
222  {
223  return true;
224  }
225  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
226  if (lastTxEnd > Simulator::Now ())
227  {
228  return true;
229  }
230  // NAV busy
231  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
232  if (lastNavEnd > Simulator::Now ())
233  {
234  return true;
235  }
236  // CCA busy
237  Time lastCCABusyEnd = m_lastBusyStart + m_lastBusyDuration;
238  if (lastCCABusyEnd > Simulator::Now ())
239  {
240  return true;
241  }
242  return false;
243 }
244 
245 bool
247 {
248  NS_LOG_FUNCTION (this << txop);
249 
250  // the Txop might have a stale value of remaining backoff slots
251  UpdateBackoff ();
252 
253  /*
254  * From section 10.3.4.2 "Basic access" of IEEE 802.11-2016:
255  *
256  * A STA may transmit an MPDU when it is operating under the DCF access
257  * method, either in the absence of a PC, or in the CP of the PCF access
258  * method, when the STA determines that the medium is idle when a frame is
259  * queued for transmission, and remains idle for a period of a DIFS, or an
260  * EIFS (10.3.2.3.7) from the end of the immediately preceding medium-busy
261  * event, whichever is the greater, and the backoff timer is zero. Otherwise
262  * the random backoff procedure described in 10.3.4.3 shall be followed.
263  *
264  * From section 10.22.2.2 "EDCA backoff procedure" of IEEE 802.11-2016:
265  *
266  * The backoff procedure shall be invoked by an EDCAF when any of the following
267  * events occurs:
268  * a) An MA-UNITDATA.request primitive is received that causes a frame with that AC
269  * to be queued for transmission such that one of the transmit queues associated
270  * with that AC has now become non-empty and any other transmit queues
271  * associated with that AC are empty; the medium is busy on the primary channel
272  */
273  if (!txop->HasFramesToTransmit () && !txop->GetLow ()->IsCfPeriod () && txop->GetBackoffSlots () == 0)
274  {
275  if (!IsBusy ())
276  {
277  // medium idle. If this is a DCF, use immediate access (we can transmit
278  // in a DIFS if the medium remains idle). If this is an EDCAF, update
279  // the backoff start time kept by the EDCAF to the current time in order
280  // to correctly align the backoff start time at the next slot boundary
281  // (performed by the next call to ChannelAccessManager::RequestAccess())
282  Time delay = (txop->IsQosTxop () ? Seconds (0)
283  : m_sifs + txop->GetAifsn () * m_slot);
284  txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay);
285  }
286  else
287  {
288  // medium busy, backoff is neeeded
289  return true;
290  }
291  }
292  return false;
293 }
294 
295 void
297 {
298  NS_LOG_FUNCTION (this << state);
299  if (m_phy)
300  {
302  }
303  //Deny access if in sleep mode or off
304  if (m_sleeping || m_off)
305  {
306  return;
307  }
308  if (isCfPeriod)
309  {
310  state->NotifyAccessRequested ();
311  Time delay = (MostRecent ({GetAccessGrantStart (true), Simulator::Now ()}) - Simulator::Now ());
313  return;
314  }
315  /*
316  * EDCAF operations shall be performed at slot boundaries (Sec. 10.22.2.4 of 802.11-2016)
317  */
318  Time accessGrantStart = GetAccessGrantStart () + (state->GetAifsn () * m_slot);
319 
320  if (state->IsQosTxop () && state->GetBackoffStart () > accessGrantStart)
321  {
322  // The backoff start time reported by the EDCAF is more recent than the last
323  // time the medium was busy plus an AIFS, hence we need to align it to the
324  // next slot boundary.
325  Time diff = state->GetBackoffStart () - accessGrantStart;
326  uint32_t nIntSlots = (diff / m_slot).GetHigh () + 1;
327  state->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * m_slot));
328  }
329 
330  UpdateBackoff ();
331  NS_ASSERT (!state->IsAccessRequested ());
332  state->NotifyAccessRequested ();
333  DoGrantDcfAccess ();
335 }
336 
337 void
339 {
340  state->NotifyAccessGranted ();
341 }
342 
343 void
345 {
346  NS_LOG_FUNCTION (this);
347  uint32_t k = 0;
348  for (States::iterator i = m_states.begin (); i != m_states.end (); k++)
349  {
350  Ptr<Txop> state = *i;
351  if (state->IsAccessRequested ()
352  && GetBackoffEndFor (state) <= Simulator::Now () )
353  {
358  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << state->GetBackoffSlots ());
359  i++; //go to the next item in the list.
360  k++;
361  std::vector<Ptr<Txop> > internalCollisionStates;
362  for (States::iterator j = i; j != m_states.end (); j++, k++)
363  {
364  Ptr<Txop> otherState = *j;
365  if (otherState->IsAccessRequested ()
366  && GetBackoffEndFor (otherState) <= Simulator::Now ())
367  {
368  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
369  otherState->GetBackoffSlots ());
375  internalCollisionStates.push_back (otherState);
376  }
377  }
378 
386  state->NotifyAccessGranted ();
387  for (std::vector<Ptr<Txop> >::iterator l = internalCollisionStates.begin ();
388  l != internalCollisionStates.end (); l++)
389  {
390  (*l)->NotifyInternalCollision ();
391  }
392  break;
393  }
394  i++;
395  }
396 }
397 
398 void
400 {
401  NS_LOG_FUNCTION (this);
402  UpdateBackoff ();
403  DoGrantDcfAccess ();
405 }
406 
407 Time
409 {
410  NS_LOG_FUNCTION (this);
411  Time rxAccessStart;
412  if (m_lastRxEnd <= Simulator::Now ())
413  {
414  rxAccessStart = m_lastRxEnd + m_sifs;
415  if (!m_lastRxReceivedOk)
416  {
417  rxAccessStart += m_eifsNoDifs;
418  }
419  }
420  else
421  {
422  rxAccessStart = m_lastRxStart + m_lastRxDuration + m_sifs;
423  }
424  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs;
425  Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs;
426  Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs;
427  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs;
428  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs;
429  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + m_sifs;
430  Time accessGrantedStart;
431  if (ignoreNav)
432  {
433  accessGrantedStart = MostRecent ({rxAccessStart,
434  busyAccessStart,
435  txAccessStart,
436  ackTimeoutAccessStart,
437  ctsTimeoutAccessStart,
438  switchingAccessStart}
439  );
440  }
441  else
442  {
443  accessGrantedStart = MostRecent ({rxAccessStart,
444  busyAccessStart,
445  txAccessStart,
446  navAccessStart,
447  ackTimeoutAccessStart,
448  ctsTimeoutAccessStart,
449  switchingAccessStart}
450  );
451  }
452  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
453  ", rx access start=" << rxAccessStart <<
454  ", busy access start=" << busyAccessStart <<
455  ", tx access start=" << txAccessStart <<
456  ", nav access start=" << navAccessStart);
457  return accessGrantedStart;
458 }
459 
460 Time
462 {
463  NS_LOG_FUNCTION (this << state);
464  Time mostRecentEvent = MostRecent ({state->GetBackoffStart (),
465  GetAccessGrantStart () + (state->GetAifsn () * m_slot)});
466  NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
467 
468  return mostRecentEvent;
469 }
470 
471 Time
473 {
474  NS_LOG_FUNCTION (this << state);
475  Time backoffEnd = GetBackoffStartFor (state) + (state->GetBackoffSlots () * m_slot);
476  NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
477 
478  return backoffEnd;
479 }
480 
481 void
483 {
484  NS_LOG_FUNCTION (this);
485  uint32_t k = 0;
486  for (States::iterator i = m_states.begin (); i != m_states.end (); i++, k++)
487  {
488  Ptr<Txop> state = *i;
489 
490  Time backoffStart = GetBackoffStartFor (state);
491  if (backoffStart <= Simulator::Now ())
492  {
493  uint32_t nIntSlots = ((Simulator::Now () - backoffStart) / m_slot).GetHigh ();
494  /*
495  * EDCA behaves slightly different to DCA. For EDCA we
496  * decrement once at the slot boundary at the end of AIFS as
497  * well as once at the end of each clear slot
498  * thereafter. For DCA we only decrement at the end of each
499  * clear slot after DIFS. We account for the extra backoff
500  * by incrementing the slot count here in the case of
501  * EDCA. The if statement whose body we are in has confirmed
502  * that a minimum of AIFS has elapsed since last busy
503  * medium.
504  */
505  if (state->IsQosTxop ())
506  {
507  nIntSlots++;
508  }
509  uint32_t n = std::min (nIntSlots, state->GetBackoffSlots ());
510  NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
511  Time backoffUpdateBound = backoffStart + (n * m_slot);
512  state->UpdateBackoffSlotsNow (n, backoffUpdateBound);
513  }
514  }
515 }
516 
517 void
519 {
520  NS_LOG_FUNCTION (this);
525  bool accessTimeoutNeeded = false;
526  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
527  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
528  {
529  Ptr<Txop> state = *i;
530  if (state->IsAccessRequested ())
531  {
532  Time tmp = GetBackoffEndFor (state);
533  if (tmp > Simulator::Now ())
534  {
535  accessTimeoutNeeded = true;
536  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
537  }
538  }
539  }
540  NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
541  if (accessTimeoutNeeded)
542  {
543  NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd);
544  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
546  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
547  {
549  }
550  if (m_accessTimeout.IsExpired ())
551  {
552  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
554  }
555  }
556 }
557 
558 void
560 {
561  NS_LOG_FUNCTION (this << duration);
562  NS_LOG_DEBUG ("rx start for=" << duration);
563  UpdateBackoff ();
565  m_lastRxDuration = duration;
567 }
568 
569 void
571 {
572  NS_LOG_FUNCTION (this);
573  NS_LOG_DEBUG ("rx end ok");
576  m_lastRxReceivedOk = true;
577 }
578 
579 void
581 {
582  NS_LOG_FUNCTION (this);
583  NS_LOG_DEBUG ("rx end error");
584  if (m_lastRxEnd > Simulator::Now ())
585  {
588  }
591  m_lastRxReceivedOk = false;
592 }
593 
594 void
596 {
597  NS_LOG_FUNCTION (this << duration);
598  if (m_lastRxEnd > Simulator::Now ())
599  {
600  //this may be caused only if PHY has started to receive a packet
601  //inside SIFS, so, we check that lastRxStart was maximum a SIFS ago
605  m_lastRxReceivedOk = true;
606  }
607  NS_LOG_DEBUG ("tx start for " << duration);
608  UpdateBackoff ();
610  m_lastTxDuration = duration;
611 }
612 
613 void
615 {
616  NS_LOG_FUNCTION (this << duration);
617  NS_LOG_DEBUG ("busy start for " << duration);
618  UpdateBackoff ();
620  m_lastBusyDuration = duration;
621 }
622 
623 void
625 {
626  NS_LOG_FUNCTION (this << duration);
627  Time now = Simulator::Now ();
630 
631  if (m_lastRxEnd > Simulator::Now ())
632  {
633  //channel switching during packet reception
636  m_lastRxReceivedOk = true;
637  }
638  if (m_lastNavStart + m_lastNavDuration > now)
639  {
641  }
643  {
645  }
646  if (m_lastAckTimeoutEnd > now)
647  {
648  m_lastAckTimeoutEnd = now;
649  }
650  if (m_lastCtsTimeoutEnd > now)
651  {
652  m_lastCtsTimeoutEnd = now;
653  }
654 
655  //Cancel timeout
656  if (m_accessTimeout.IsRunning ())
657  {
659  }
660 
661  //Reset backoffs
662  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
663  {
664  Ptr<Txop> state = *i;
665  uint32_t remainingSlots = state->GetBackoffSlots ();
666  if (remainingSlots > 0)
667  {
668  state->UpdateBackoffSlotsNow (remainingSlots, now);
669  NS_ASSERT (state->GetBackoffSlots () == 0);
670  }
671  state->ResetCw ();
672  state->m_accessRequested = false;
673  state->NotifyChannelSwitching ();
674  }
675 
676  NS_LOG_DEBUG ("switching start for " << duration);
678  m_lastSwitchingDuration = duration;
679 
680 }
681 
682 void
684 {
685  NS_LOG_FUNCTION (this);
686  m_sleeping = true;
687  //Cancel timeout
688  if (m_accessTimeout.IsRunning ())
689  {
691  }
692 
693  //Reset backoffs
694  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
695  {
696  Ptr<Txop> state = *i;
697  state->NotifySleep ();
698  }
699 }
700 
701 void
703 {
704  NS_LOG_FUNCTION (this);
705  m_off = true;
706  //Cancel timeout
707  if (m_accessTimeout.IsRunning ())
708  {
710  }
711 
712  //Reset backoffs
713  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
714  {
715  Ptr<Txop> state = *i;
716  state->NotifyOff ();
717  }
718 }
719 
720 void
722 {
723  NS_LOG_FUNCTION (this);
724  m_sleeping = false;
725  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
726  {
727  Ptr<Txop> state = *i;
728  uint32_t remainingSlots = state->GetBackoffSlots ();
729  if (remainingSlots > 0)
730  {
731  state->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
732  NS_ASSERT (state->GetBackoffSlots () == 0);
733  }
734  state->ResetCw ();
735  state->m_accessRequested = false;
736  state->NotifyWakeUp ();
737  }
738 }
739 
740 void
742 {
743  NS_LOG_FUNCTION (this);
744  m_off = false;
745  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
746  {
747  Ptr<Txop> state = *i;
748  uint32_t remainingSlots = state->GetBackoffSlots ();
749  if (remainingSlots > 0)
750  {
751  state->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
752  NS_ASSERT (state->GetBackoffSlots () == 0);
753  }
754  state->ResetCw ();
755  state->m_accessRequested = false;
756  state->NotifyOn ();
757  }
758 }
759 
760 void
762 {
763  NS_LOG_FUNCTION (this << duration);
764  NS_LOG_DEBUG ("nav reset for=" << duration);
765  UpdateBackoff ();
767  m_lastNavDuration = duration;
775 }
776 
777 void
779 {
780  NS_LOG_FUNCTION (this << duration);
782  NS_LOG_DEBUG ("nav start for=" << duration);
783  UpdateBackoff ();
784  Time newNavEnd = Simulator::Now () + duration;
785  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
786  if (newNavEnd > lastNavEnd)
787  {
789  m_lastNavDuration = duration;
790  }
791 }
792 
793 void
795 {
796  NS_LOG_FUNCTION (this << duration);
798  m_lastAckTimeoutEnd = Simulator::Now () + duration;
799 }
800 
801 void
803 {
804  NS_LOG_FUNCTION (this);
807 }
808 
809 void
811 {
812  NS_LOG_FUNCTION (this << duration);
813  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
814 }
815 
816 void
818 {
819  NS_LOG_FUNCTION (this);
822 }
823 
824 } //namespace ns3
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:202
Time GetBackoffEndFor(Ptr< Txop > state)
Return the time when the backoff procedure ended (or will ended) for the given Txop.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Time m_eifsNoDifs
EIFS no DIFS time.
microsecond
Definition: nstime.h:116
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:296
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 DCF has frames to transmit.
Definition: txop.cc:308
void NotifyOnNow(void)
Notify the DCF that the device has been resumed from off mode.
virtual void NotifyAccessGranted(void)
Notify the DCF 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:238
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.
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.
#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:244
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:59
Time m_lastRxStart
the last receive start time
virtual void NotifyOff(void)
When off operation occurs, the queue gets cleaned up.
Definition: txop.cc:593
Time m_lastBusyDuration
the last busy duration time
phy
Definition: third.py:93
void NotifyRxEndErrorNow(void)
Notify the DCF 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
Ptr to the PHY.
PhyListener(ns3::ChannelAccessManager *dcf)
Create a PhyListener for the given ChannelAccessManager.
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1390
void SetEifsNoDifs(Time eifsNoDifs)
receive notifications about phy events.
void NotifyOffNow(void)
Notify the DCF that the device has been put in off mode.
Time m_lastRxEnd
the last receive end time
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:2979
Time m_lastSwitchingStart
the last switching start time
void NotifyWakeup(void)
Notify listeners that we woke up.
void NotifySleepNow(void)
Notify the DCF 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:865
#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.
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.
virtual void NotifySleep(void)
When sleep operation occurs, if there is a pending packet transmission, it will be reinserted to the ...
Definition: txop.cc:582
void NotifyOn(void)
Notify listeners that we went to switch on.
void NotifyRxEndOkNow(void)
Notify the DCF 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.
virtual void NotifyOn(void)
When on operation occurs, channel access will be started.
Definition: txop.cc:608
bool m_lastRxReceivedOk
the last receive OK
PhyListener * m_phyListener
the phy listener
void NotifyCtsTimeoutResetNow(void)
Notify that CTS timer has reset.
virtual void NotifyChannelSwitching(void)
When a channel switching occurs, enqueued packets are removed.
Definition: txop.cc:574
ns3::ChannelAccessManager * m_dcf
ChannelAccessManager to forward events to.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
void NotifyRxStart(Time duration)
void DoGrantPcfAccess(Ptr< Txop > state)
Grant access to PCF.
void DoGrantDcfAccess(void)
Grant access to DCF.
bool m_accessRequested
flag whether channel access is already requested
Definition: txop.h:519
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:1064
uint32_t GetBackoffSlots(void) const
Return the current number of backoff slots.
Definition: txop.cc:232
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
void NotifySwitchingStartNow(Time duration)
void NotifyNavStartNow(Time duration)
States m_states
the DCF states
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 MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1080
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
Time GetBackoffStartFor(Ptr< Txop > state)
Return the time when the backoff procedure started for the given Txop.
void SetupLow(Ptr< MacLow > low)
Set up listener for MacLow events.
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: txop.cc:217
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:315
void NotifyWakeupNow(void)
Notify the DCF that the device has been resumed from sleep mode.
void RequestAccess(Ptr< Txop > state, bool isCfPeriod=false)
Time m_lastAckTimeoutEnd
the last ACK timeout end time
virtual void NotifyWakeUp(void)
When wake up operation occurs, channel access will be restarted.
Definition: txop.cc:601
void DoDispose(void)
Destructor implementation.
void NotifyAckTimeoutResetNow(void)
Notify that ACK timer has reset.