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 "frame-exchange-manager.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  m_feManager = 0;
140 }
141 
142 void
144 {
145  NS_LOG_FUNCTION (this << phy);
146  NS_ASSERT (m_phyListener == 0);
147  m_phyListener = new PhyListener (this);
148  phy->RegisterListener (m_phyListener);
149  m_phy = phy;
150 }
151 
152 void
154 {
155  NS_LOG_FUNCTION (this << phy);
156  if (m_phyListener != 0)
157  {
158  phy->UnregisterListener (m_phyListener);
159  delete m_phyListener;
160  m_phyListener = 0;
161  m_phy = 0;
162  }
163 }
164 
165 void
167 {
168  NS_LOG_FUNCTION (this << feManager);
169  m_feManager = feManager;
170  m_feManager->SetChannelAccessManager (this);
171 }
172 
173 Time
175 {
176  return m_phy->GetSlot ();
177 }
178 
179 Time
181 {
182  return m_phy->GetSifs ();
183 }
184 
185 Time
187 {
188  return m_phy->GetSifs () + m_phy->GetAckTxTime ();
189 }
190 
191 void
193 {
194  NS_LOG_FUNCTION (this << txop);
195  m_txops.push_back (txop);
196 }
197 
198 Time
199 ChannelAccessManager::MostRecent (std::initializer_list<Time> list) const
200 {
201  NS_ASSERT (list.size () > 0);
202  return *std::max_element (list.begin (), list.end ());
203 }
204 
205 bool
207 {
208  NS_LOG_FUNCTION (this);
209  // PHY busy
210  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
211  if (lastRxEnd > Simulator::Now ())
212  {
213  return true;
214  }
215  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
216  if (lastTxEnd > Simulator::Now ())
217  {
218  return true;
219  }
220  // NAV busy
221  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
222  if (lastNavEnd > Simulator::Now ())
223  {
224  return true;
225  }
226  // CCA busy
227  Time lastCCABusyEnd = m_lastBusyStart + m_lastBusyDuration;
228  if (lastCCABusyEnd > Simulator::Now ())
229  {
230  return true;
231  }
232  return false;
233 }
234 
235 bool
237 {
238  NS_LOG_FUNCTION (this << txop);
239 
240  // No backoff needed if in sleep mode or off
241  if (m_sleeping || m_off)
242  {
243  return false;
244  }
245 
246  // the Txop might have a stale value of remaining backoff slots
247  UpdateBackoff ();
248 
249  /*
250  * From section 10.3.4.2 "Basic access" of IEEE 802.11-2016:
251  *
252  * A STA may transmit an MPDU when it is operating under the DCF access
253  * method, either in the absence of a PC, or in the CP of the PCF access
254  * method, when the STA determines that the medium is idle when a frame is
255  * queued for transmission, and remains idle for a period of a DIFS, or an
256  * EIFS (10.3.2.3.7) from the end of the immediately preceding medium-busy
257  * event, whichever is the greater, and the backoff timer is zero. Otherwise
258  * the random backoff procedure described in 10.3.4.3 shall be followed.
259  *
260  * From section 10.22.2.2 "EDCA backoff procedure" of IEEE 802.11-2016:
261  *
262  * The backoff procedure shall be invoked by an EDCAF when any of the following
263  * events occurs:
264  * a) An MA-UNITDATA.request primitive is received that causes a frame with that AC
265  * to be queued for transmission such that one of the transmit queues associated
266  * with that AC has now become non-empty and any other transmit queues
267  * associated with that AC are empty; the medium is busy on the primary channel
268  */
269  if (!txop->HasFramesToTransmit () && txop->GetAccessStatus () != Txop::GRANTED
270  && txop->GetBackoffSlots () == 0)
271  {
272  if (!IsBusy ())
273  {
274  // medium idle. If this is a DCF, use immediate access (we can transmit
275  // in a DIFS if the medium remains idle). If this is an EDCAF, update
276  // the backoff start time kept by the EDCAF to the current time in order
277  // to correctly align the backoff start time at the next slot boundary
278  // (performed by the next call to ChannelAccessManager::RequestAccess())
279  Time delay = (txop->IsQosTxop () ? Seconds (0)
280  : GetSifs () + txop->GetAifsn () * GetSlot ());
281  txop->UpdateBackoffSlotsNow (0, Simulator::Now () + delay);
282  }
283  else
284  {
285  // medium busy, backoff is needed
286  return true;
287  }
288  }
289  return false;
290 }
291 
292 void
294 {
295  NS_LOG_FUNCTION (this << txop);
296  if (m_phy)
297  {
299  }
300  //Deny access if in sleep mode or off
301  if (m_sleeping || m_off)
302  {
303  return;
304  }
305  /*
306  * EDCAF operations shall be performed at slot boundaries (Sec. 10.22.2.4 of 802.11-2016)
307  */
308  Time accessGrantStart = GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ());
309 
310  if (txop->IsQosTxop () && txop->GetBackoffStart () > accessGrantStart)
311  {
312  // The backoff start time reported by the EDCAF is more recent than the last
313  // time the medium was busy plus an AIFS, hence we need to align it to the
314  // next slot boundary.
315  Time diff = txop->GetBackoffStart () - accessGrantStart;
316  uint32_t nIntSlots = (diff / GetSlot ()).GetHigh () + 1;
317  txop->UpdateBackoffSlotsNow (0, accessGrantStart + (nIntSlots * GetSlot ()));
318  }
319 
320  UpdateBackoff ();
322  txop->NotifyAccessRequested ();
323  DoGrantDcfAccess ();
325 }
326 
327 void
329 {
330  NS_LOG_FUNCTION (this);
331  uint32_t k = 0;
332  for (Txops::iterator i = m_txops.begin (); i != m_txops.end (); k++)
333  {
334  Ptr<Txop> txop = *i;
335  if (txop->GetAccessStatus () == Txop::REQUESTED
336  && GetBackoffEndFor (txop) <= Simulator::Now () )
337  {
342  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots ());
343  i++; //go to the next item in the list.
344  k++;
345  std::vector<Ptr<Txop> > internalCollisionTxops;
346  for (Txops::iterator j = i; j != m_txops.end (); j++, k++)
347  {
348  Ptr<Txop> otherTxop = *j;
349  if (otherTxop->GetAccessStatus () == Txop::REQUESTED
350  && GetBackoffEndFor (otherTxop) <= Simulator::Now ())
351  {
352  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
353  otherTxop->GetBackoffSlots ());
359  internalCollisionTxops.push_back (otherTxop);
360  }
361  }
362 
371  NS_ASSERT (m_feManager != 0);
372 
373  if (m_feManager->StartTransmission (txop))
374  {
375  for (auto& collidingTxop : internalCollisionTxops)
376  {
377  collidingTxop->NotifyInternalCollision ();
378  }
379  break;
380  }
381  else
382  {
383  // reset the current state to the EDCAF that won the contention
384  // but did not transmit anything
385  i--;
386  k = std::distance (m_txops.begin (), i);
387  }
388  }
389  i++;
390  }
391 }
392 
393 void
395 {
396  NS_LOG_FUNCTION (this);
397  UpdateBackoff ();
398  DoGrantDcfAccess ();
400 }
401 
402 Time
404 {
405  NS_LOG_FUNCTION (this);
406  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
407  Time rxAccessStart = lastRxEnd + GetSifs ();
408  if ((lastRxEnd <= Simulator::Now ()) && !m_lastRxReceivedOk)
409  {
410  rxAccessStart += GetEifsNoDifs ();
411  }
412  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + GetSifs ();
413  Time txAccessStart = m_lastTxStart + m_lastTxDuration + GetSifs ();
414  Time navAccessStart = m_lastNavStart + m_lastNavDuration + GetSifs ();
415  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + GetSifs ();
416  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + GetSifs ();
417  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + GetSifs ();
418  Time accessGrantedStart;
419  if (ignoreNav)
420  {
421  accessGrantedStart = MostRecent ({rxAccessStart,
422  busyAccessStart,
423  txAccessStart,
424  ackTimeoutAccessStart,
425  ctsTimeoutAccessStart,
426  switchingAccessStart}
427  );
428  }
429  else
430  {
431  accessGrantedStart = MostRecent ({rxAccessStart,
432  busyAccessStart,
433  txAccessStart,
434  navAccessStart,
435  ackTimeoutAccessStart,
436  ctsTimeoutAccessStart,
437  switchingAccessStart}
438  );
439  }
440  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
441  ", rx access start=" << rxAccessStart <<
442  ", busy access start=" << busyAccessStart <<
443  ", tx access start=" << txAccessStart <<
444  ", nav access start=" << navAccessStart);
445  return accessGrantedStart;
446 }
447 
448 Time
450 {
451  NS_LOG_FUNCTION (this << txop);
452  Time mostRecentEvent = MostRecent ({txop->GetBackoffStart (),
453  GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ())});
454  NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
455 
456  return mostRecentEvent;
457 }
458 
459 Time
461 {
462  NS_LOG_FUNCTION (this << txop);
463  Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots () * GetSlot ());
464  NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
465 
466  return backoffEnd;
467 }
468 
469 void
471 {
472  NS_LOG_FUNCTION (this);
473  uint32_t k = 0;
474  for (auto txop : m_txops)
475  {
476  Time backoffStart = GetBackoffStartFor (txop);
477  if (backoffStart <= Simulator::Now ())
478  {
479  uint32_t nIntSlots = ((Simulator::Now () - backoffStart) / GetSlot ()).GetHigh ();
480  /*
481  * EDCA behaves slightly different to DCA. For EDCA we
482  * decrement once at the slot boundary at the end of AIFS as
483  * well as once at the end of each clear slot
484  * thereafter. For DCA we only decrement at the end of each
485  * clear slot after DIFS. We account for the extra backoff
486  * by incrementing the slot count here in the case of
487  * EDCA. The if statement whose body we are in has confirmed
488  * that a minimum of AIFS has elapsed since last busy
489  * medium.
490  */
491  if (txop->IsQosTxop ())
492  {
493  nIntSlots++;
494  }
495  uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots ());
496  NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
497  Time backoffUpdateBound = backoffStart + (n * GetSlot ());
498  txop->UpdateBackoffSlotsNow (n, backoffUpdateBound);
499  }
500  ++k;
501  }
502 }
503 
504 void
506 {
507  NS_LOG_FUNCTION (this);
512  bool accessTimeoutNeeded = false;
513  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
514  for (auto txop : m_txops)
515  {
516  if (txop->GetAccessStatus () == Txop::REQUESTED)
517  {
518  Time tmp = GetBackoffEndFor (txop);
519  if (tmp > Simulator::Now ())
520  {
521  accessTimeoutNeeded = true;
522  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
523  }
524  }
525  }
526  NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
527  if (accessTimeoutNeeded)
528  {
529  NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd);
530  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
532  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
533  {
535  }
536  if (m_accessTimeout.IsExpired ())
537  {
538  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
540  }
541  }
542 }
543 
544 void
546 {
547  NS_LOG_FUNCTION (this << duration);
548  NS_LOG_DEBUG ("rx start for=" << duration);
549  UpdateBackoff ();
551  m_lastRxDuration = duration;
552  m_lastRxReceivedOk = true;
553 }
554 
555 void
557 {
558  NS_LOG_FUNCTION (this);
559  NS_LOG_DEBUG ("rx end ok");
561  m_lastRxReceivedOk = true;
562 }
563 
564 void
566 {
567  NS_LOG_FUNCTION (this);
568  NS_LOG_DEBUG ("rx end error");
569  Time now = Simulator::Now ();
570  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
571  if (lastRxEnd > now)
572  {
573  m_lastBusyStart = now;
574  m_lastBusyDuration = lastRxEnd - m_lastBusyStart;
575  }
577  m_lastRxReceivedOk = false;
578 }
579 
580 void
582 {
583  NS_LOG_FUNCTION (this << duration);
584  m_lastRxReceivedOk = true;
585  Time now = Simulator::Now ();
586  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
587  if (lastRxEnd > now)
588  {
589  //this may be caused only if PHY has started to receive a packet
590  //inside SIFS, so, we check that lastRxStart was maximum a SIFS ago
591  NS_ASSERT (now - m_lastRxStart <= GetSifs ());
593  }
594  NS_LOG_DEBUG ("tx start for " << duration);
595  UpdateBackoff ();
596  m_lastTxStart = now;
597  m_lastTxDuration = duration;
598 }
599 
600 void
602 {
603  NS_LOG_FUNCTION (this << duration);
604  NS_LOG_DEBUG ("busy start for " << duration);
605  UpdateBackoff ();
607  m_lastBusyDuration = duration;
608 }
609 
610 void
612 {
613  NS_LOG_FUNCTION (this << duration);
614  Time now = Simulator::Now ();
617 
618  m_lastRxReceivedOk = true;
619 
620  if (m_lastRxStart + m_lastRxDuration > now)
621  {
622  //channel switching during packet reception
624  }
625  if (m_lastNavStart + m_lastNavDuration > now)
626  {
628  }
630  {
632  }
633  if (m_lastAckTimeoutEnd > now)
634  {
635  m_lastAckTimeoutEnd = now;
636  }
637  if (m_lastCtsTimeoutEnd > now)
638  {
639  m_lastCtsTimeoutEnd = now;
640  }
641 
642  //Cancel timeout
643  if (m_accessTimeout.IsRunning ())
644  {
646  }
647 
648  //Reset backoffs
649  for (auto txop : m_txops)
650  {
651  uint32_t remainingSlots = txop->GetBackoffSlots ();
652  if (remainingSlots > 0)
653  {
654  txop->UpdateBackoffSlotsNow (remainingSlots, now);
655  NS_ASSERT (txop->GetBackoffSlots () == 0);
656  }
657  txop->ResetCw ();
658  txop->m_access = Txop::NOT_REQUESTED;
659  txop->NotifyChannelSwitching ();
660  }
661 
662  NS_LOG_DEBUG ("switching start for " << duration);
664  m_lastSwitchingDuration = duration;
665 }
666 
667 void
669 {
670  NS_LOG_FUNCTION (this);
671  m_sleeping = true;
672  //Cancel timeout
673  if (m_accessTimeout.IsRunning ())
674  {
676  }
677 
678  //Reset backoffs
679  for (auto txop : m_txops)
680  {
681  txop->NotifySleep ();
682  }
683 }
684 
685 void
687 {
688  NS_LOG_FUNCTION (this);
689  m_off = true;
690  //Cancel timeout
691  if (m_accessTimeout.IsRunning ())
692  {
694  }
695 
696  //Reset backoffs
697  for (auto txop : m_txops)
698  {
699  txop->NotifyOff ();
700  }
701 }
702 
703 void
705 {
706  NS_LOG_FUNCTION (this);
707  m_sleeping = false;
708  for (auto txop : m_txops)
709  {
710  uint32_t remainingSlots = txop->GetBackoffSlots ();
711  if (remainingSlots > 0)
712  {
713  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
714  NS_ASSERT (txop->GetBackoffSlots () == 0);
715  }
716  txop->ResetCw ();
717  txop->m_access = Txop::NOT_REQUESTED;
718  txop->NotifyWakeUp ();
719  }
720 }
721 
722 void
724 {
725  NS_LOG_FUNCTION (this);
726  m_off = false;
727  for (auto txop : m_txops)
728  {
729  uint32_t remainingSlots = txop->GetBackoffSlots ();
730  if (remainingSlots > 0)
731  {
732  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
733  NS_ASSERT (txop->GetBackoffSlots () == 0);
734  }
735  txop->ResetCw ();
736  txop->m_access = Txop::NOT_REQUESTED;
737  txop->NotifyOn ();
738  }
739 }
740 
741 void
743 {
744  NS_LOG_FUNCTION (this << duration);
745  NS_LOG_DEBUG ("nav reset for=" << duration);
746  UpdateBackoff ();
748  m_lastNavDuration = duration;
756 }
757 
758 void
760 {
761  NS_LOG_FUNCTION (this << duration);
763  NS_LOG_DEBUG ("nav start for=" << duration);
764  UpdateBackoff ();
765  Time newNavEnd = Simulator::Now () + duration;
766  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
767  if (newNavEnd > lastNavEnd)
768  {
770  m_lastNavDuration = duration;
771  }
772 }
773 
774 void
776 {
777  NS_LOG_FUNCTION (this << duration);
779  m_lastAckTimeoutEnd = Simulator::Now () + duration;
780 }
781 
782 void
784 {
785  NS_LOG_FUNCTION (this);
788 }
789 
790 void
792 {
793  NS_LOG_FUNCTION (this << duration);
794  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
795 }
796 
797 void
799 {
800  NS_LOG_FUNCTION (this);
803 }
804 
805 } //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
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:429
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:268
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:280
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.
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:210
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
void DoDispose(void) override
Destructor implementation.
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:216
virtual ChannelAccessStatus GetAccessStatus(void) const
Definition: txop.cc:329
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 SetupFrameExchangeManager(Ptr< FrameExchangeManager > feManager)
Set up the Frame Exchange Manager.
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1958
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 IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:421
#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
virtual Time GetSlot(void) const
Return the slot duration for this PHY.
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:940
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
Ptr< FrameExchangeManager > m_feManager
pointer to the Frame Exchange Manager
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:910
void RequestAccess(Ptr< Txop > txop)
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:1289
uint32_t GetBackoffSlots(void) const
Return the current number of backoff slots.
Definition: txop.cc:204
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:922
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:1305
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:335
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 NotifyAckTimeoutResetNow(void)
Notify that ack timer has reset.