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_slot (Seconds (0.0)),
118  m_sifs (Seconds (0.0)),
119  m_phyListener (0)
120 {
121  NS_LOG_FUNCTION (this);
122 }
123 
125 {
126  NS_LOG_FUNCTION (this);
127  delete m_phyListener;
128  m_phyListener = 0;
129 }
130 
131 void
133 {
134  NS_LOG_FUNCTION (this);
135  for (Ptr<Txop> i : m_txops)
136  {
137  i->Dispose ();
138  i = 0;
139  }
140  m_phy = 0;
141 }
142 
143 void
145 {
146  NS_LOG_FUNCTION (this << phy);
147  NS_ASSERT (m_phyListener == 0);
148  m_phyListener = new PhyListener (this);
149  phy->RegisterListener (m_phyListener);
150  m_phy = phy;
151 }
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << phy);
157  if (m_phyListener != 0)
158  {
159  phy->UnregisterListener (m_phyListener);
160  delete m_phyListener;
161  m_phyListener = 0;
162  m_phy = 0;
163  }
164 }
165 
166 void
168 {
169  NS_LOG_FUNCTION (this << low);
170  low->RegisterChannelAccessManager (this);
171 }
172 
173 void
175 {
176  NS_LOG_FUNCTION (this << slotTime);
177  m_slot = slotTime;
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION (this << sifs);
184  m_sifs = sifs;
185 }
186 
187 void
189 {
190  NS_LOG_FUNCTION (this << eifsNoDifs);
191  m_eifsNoDifs = eifsNoDifs;
192 }
193 
194 Time
196 {
197  NS_LOG_FUNCTION (this);
198  return m_eifsNoDifs;
199 }
200 
201 void
203 {
204  NS_LOG_FUNCTION (this << txop);
205  m_txops.push_back (txop);
206 }
207 
208 Time
209 ChannelAccessManager::MostRecent (std::initializer_list<Time> list) const
210 {
211  NS_ASSERT (list.size () > 0);
212  return *std::max_element (list.begin (), list.end ());
213 }
214 
215 bool
217 {
218  NS_LOG_FUNCTION (this);
219  // PHY busy
220  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
221  if (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 needed
289  return true;
290  }
291  }
292  return false;
293 }
294 
295 void
297 {
298  NS_LOG_FUNCTION (this << txop);
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  txop->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 () + (txop->GetAifsn () * m_slot);
319 
320  if (txop->IsQosTxop () && txop->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 = txop->GetBackoffStart () - accessGrantStart;
326  uint32_t nIntSlots = (diff / m_slot).GetHigh () + 1;
327  txop->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * m_slot));
328  }
329 
330  UpdateBackoff ();
331  NS_ASSERT (!txop->IsAccessRequested ());
332  txop->NotifyAccessRequested ();
333  DoGrantDcfAccess ();
335 }
336 
337 void
339 {
340  txop->NotifyAccessGranted ();
341 }
342 
343 void
345 {
346  NS_LOG_FUNCTION (this);
347  uint32_t k = 0;
348  for (Txops::iterator i = m_txops.begin (); i != m_txops.end (); k++)
349  {
350  Ptr<Txop> txop = *i;
351  if (txop->IsAccessRequested ()
352  && GetBackoffEndFor (txop) <= Simulator::Now () )
353  {
358  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots ());
359  i++; //go to the next item in the list.
360  k++;
361  std::vector<Ptr<Txop> > internalCollisionTxops;
362  for (Txops::iterator j = i; j != m_txops.end (); j++, k++)
363  {
364  Ptr<Txop> otherTxop = *j;
365  if (otherTxop->IsAccessRequested ()
366  && GetBackoffEndFor (otherTxop) <= Simulator::Now ())
367  {
368  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
369  otherTxop->GetBackoffSlots ());
375  internalCollisionTxops.push_back (otherTxop);
376  }
377  }
378 
386  txop->NotifyAccessGranted ();
387  for (auto collidingTxop : internalCollisionTxops)
388  {
389  collidingTxop->NotifyInternalCollision ();
390  }
391  break;
392  }
393  i++;
394  }
395 }
396 
397 void
399 {
400  NS_LOG_FUNCTION (this);
401  UpdateBackoff ();
402  DoGrantDcfAccess ();
404 }
405 
406 Time
408 {
409  NS_LOG_FUNCTION (this);
410  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
411  Time rxAccessStart = lastRxEnd + m_sifs;
412  if ((lastRxEnd <= Simulator::Now ()) && !m_lastRxReceivedOk)
413  {
414  rxAccessStart += m_eifsNoDifs;
415  }
416  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs;
417  Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs;
418  Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs;
419  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs;
420  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs;
421  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + m_sifs;
422  Time accessGrantedStart;
423  if (ignoreNav)
424  {
425  accessGrantedStart = MostRecent ({rxAccessStart,
426  busyAccessStart,
427  txAccessStart,
428  ackTimeoutAccessStart,
429  ctsTimeoutAccessStart,
430  switchingAccessStart}
431  );
432  }
433  else
434  {
435  accessGrantedStart = MostRecent ({rxAccessStart,
436  busyAccessStart,
437  txAccessStart,
438  navAccessStart,
439  ackTimeoutAccessStart,
440  ctsTimeoutAccessStart,
441  switchingAccessStart}
442  );
443  }
444  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
445  ", rx access start=" << rxAccessStart <<
446  ", busy access start=" << busyAccessStart <<
447  ", tx access start=" << txAccessStart <<
448  ", nav access start=" << navAccessStart);
449  return accessGrantedStart;
450 }
451 
452 Time
454 {
455  NS_LOG_FUNCTION (this << txop);
456  Time mostRecentEvent = MostRecent ({txop->GetBackoffStart (),
457  GetAccessGrantStart () + (txop->GetAifsn () * m_slot)});
458  NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
459 
460  return mostRecentEvent;
461 }
462 
463 Time
465 {
466  NS_LOG_FUNCTION (this << txop);
467  Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots () * m_slot);
468  NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
469 
470  return backoffEnd;
471 }
472 
473 void
475 {
476  NS_LOG_FUNCTION (this);
477  uint32_t k = 0;
478  for (auto txop : m_txops)
479  {
480  Time backoffStart = GetBackoffStartFor (txop);
481  if (backoffStart <= Simulator::Now ())
482  {
483  uint32_t nIntSlots = ((Simulator::Now () - backoffStart) / m_slot).GetHigh ();
484  /*
485  * EDCA behaves slightly different to DCA. For EDCA we
486  * decrement once at the slot boundary at the end of AIFS as
487  * well as once at the end of each clear slot
488  * thereafter. For DCA we only decrement at the end of each
489  * clear slot after DIFS. We account for the extra backoff
490  * by incrementing the slot count here in the case of
491  * EDCA. The if statement whose body we are in has confirmed
492  * that a minimum of AIFS has elapsed since last busy
493  * medium.
494  */
495  if (txop->IsQosTxop ())
496  {
497  nIntSlots++;
498  }
499  uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots ());
500  NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
501  Time backoffUpdateBound = backoffStart + (n * m_slot);
502  txop->UpdateBackoffSlotsNow (n, backoffUpdateBound);
503  }
504  ++k;
505  }
506 }
507 
508 void
510 {
511  NS_LOG_FUNCTION (this);
516  bool accessTimeoutNeeded = false;
517  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
518  for (auto txop : m_txops)
519  {
520  if (txop->IsAccessRequested ())
521  {
522  Time tmp = GetBackoffEndFor (txop);
523  if (tmp > Simulator::Now ())
524  {
525  accessTimeoutNeeded = true;
526  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
527  }
528  }
529  }
530  NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
531  if (accessTimeoutNeeded)
532  {
533  NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd);
534  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
536  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
537  {
539  }
540  if (m_accessTimeout.IsExpired ())
541  {
542  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
544  }
545  }
546 }
547 
548 void
550 {
551  NS_LOG_FUNCTION (this << duration);
552  NS_LOG_DEBUG ("rx start for=" << duration);
553  UpdateBackoff ();
555  m_lastRxDuration = duration;
556  m_lastRxReceivedOk = true;
557 }
558 
559 void
561 {
562  NS_LOG_FUNCTION (this);
563  NS_LOG_DEBUG ("rx end ok");
565  m_lastRxReceivedOk = true;
566 }
567 
568 void
570 {
571  NS_LOG_FUNCTION (this);
572  NS_LOG_DEBUG ("rx end error");
573  Time now = Simulator::Now ();
574  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
575  if (lastRxEnd > now)
576  {
577  m_lastBusyStart = now;
578  m_lastBusyDuration = lastRxEnd - m_lastBusyStart;
579  }
581  m_lastRxReceivedOk = false;
582 }
583 
584 void
586 {
587  NS_LOG_FUNCTION (this << duration);
588  m_lastRxReceivedOk = true;
589  Time now = Simulator::Now ();
590  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
591  if (lastRxEnd > now)
592  {
593  //this may be caused only if PHY has started to receive a packet
594  //inside SIFS, so, we check that lastRxStart was maximum a SIFS ago
595  NS_ASSERT (now - m_lastRxStart <= m_sifs);
597  }
598  NS_LOG_DEBUG ("tx start for " << duration);
599  UpdateBackoff ();
600  m_lastTxStart = now;
601  m_lastTxDuration = duration;
602 }
603 
604 void
606 {
607  NS_LOG_FUNCTION (this << duration);
608  NS_LOG_DEBUG ("busy start for " << duration);
609  UpdateBackoff ();
611  m_lastBusyDuration = duration;
612 }
613 
614 void
616 {
617  NS_LOG_FUNCTION (this << duration);
618  Time now = Simulator::Now ();
621 
622  m_lastRxReceivedOk = true;
623 
624  if (m_lastRxStart + m_lastRxDuration > now)
625  {
626  //channel switching during packet reception
628  }
629  if (m_lastNavStart + m_lastNavDuration > now)
630  {
632  }
634  {
636  }
637  if (m_lastAckTimeoutEnd > now)
638  {
639  m_lastAckTimeoutEnd = now;
640  }
641  if (m_lastCtsTimeoutEnd > now)
642  {
643  m_lastCtsTimeoutEnd = now;
644  }
645 
646  //Cancel timeout
647  if (m_accessTimeout.IsRunning ())
648  {
650  }
651 
652  //Reset backoffs
653  for (auto txop : m_txops)
654  {
655  uint32_t remainingSlots = txop->GetBackoffSlots ();
656  if (remainingSlots > 0)
657  {
658  txop->UpdateBackoffSlotsNow (remainingSlots, now);
659  NS_ASSERT (txop->GetBackoffSlots () == 0);
660  }
661  txop->ResetCw ();
662  txop->m_accessRequested = false;
663  txop->NotifyChannelSwitching ();
664  }
665 
666  NS_LOG_DEBUG ("switching start for " << duration);
668  m_lastSwitchingDuration = duration;
669 }
670 
671 void
673 {
674  NS_LOG_FUNCTION (this);
675  m_sleeping = true;
676  //Cancel timeout
677  if (m_accessTimeout.IsRunning ())
678  {
680  }
681 
682  //Reset backoffs
683  for (auto txop : m_txops)
684  {
685  txop->NotifySleep ();
686  }
687 }
688 
689 void
691 {
692  NS_LOG_FUNCTION (this);
693  m_off = true;
694  //Cancel timeout
695  if (m_accessTimeout.IsRunning ())
696  {
698  }
699 
700  //Reset backoffs
701  for (auto txop : m_txops)
702  {
703  txop->NotifyOff ();
704  }
705 }
706 
707 void
709 {
710  NS_LOG_FUNCTION (this);
711  m_sleeping = false;
712  for (auto txop : m_txops)
713  {
714  uint32_t remainingSlots = txop->GetBackoffSlots ();
715  if (remainingSlots > 0)
716  {
717  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
718  NS_ASSERT (txop->GetBackoffSlots () == 0);
719  }
720  txop->ResetCw ();
721  txop->m_accessRequested = false;
722  txop->NotifyWakeUp ();
723  }
724 }
725 
726 void
728 {
729  NS_LOG_FUNCTION (this);
730  m_off = false;
731  for (auto txop : m_txops)
732  {
733  uint32_t remainingSlots = txop->GetBackoffSlots ();
734  if (remainingSlots > 0)
735  {
736  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
737  NS_ASSERT (txop->GetBackoffSlots () == 0);
738  }
739  txop->ResetCw ();
740  txop->m_accessRequested = false;
741  txop->NotifyOn ();
742  }
743 }
744 
745 void
747 {
748  NS_LOG_FUNCTION (this << duration);
749  NS_LOG_DEBUG ("nav reset for=" << duration);
750  UpdateBackoff ();
752  m_lastNavDuration = duration;
760 }
761 
762 void
764 {
765  NS_LOG_FUNCTION (this << duration);
767  NS_LOG_DEBUG ("nav start for=" << duration);
768  UpdateBackoff ();
769  Time newNavEnd = Simulator::Now () + duration;
770  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
771  if (newNavEnd > lastNavEnd)
772  {
774  m_lastNavDuration = duration;
775  }
776 }
777 
778 void
780 {
781  NS_LOG_FUNCTION (this << duration);
783  m_lastAckTimeoutEnd = Simulator::Now () + duration;
784 }
785 
786 void
788 {
789  NS_LOG_FUNCTION (this);
792 }
793 
794 void
796 {
797  NS_LOG_FUNCTION (this << duration);
798  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
799 }
800 
801 void
803 {
804  NS_LOG_FUNCTION (this);
807 }
808 
809 } //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
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: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
void SetEifsNoDifs(Time eifsNoDifs)
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:3041
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.
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.
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 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:1062
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)
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:1078
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.