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  && (!txop->IsQosTxop () || !StaticCast<QosTxop> (txop)->EdcaDisabled ())
337  && GetBackoffEndFor (txop) <= Simulator::Now () )
338  {
343  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << txop->GetBackoffSlots ());
344  i++; //go to the next item in the list.
345  k++;
346  std::vector<Ptr<Txop> > internalCollisionTxops;
347  for (Txops::iterator j = i; j != m_txops.end (); j++, k++)
348  {
349  Ptr<Txop> otherTxop = *j;
350  if (otherTxop->GetAccessStatus () == Txop::REQUESTED
351  && GetBackoffEndFor (otherTxop) <= Simulator::Now ())
352  {
353  NS_LOG_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
354  otherTxop->GetBackoffSlots ());
360  internalCollisionTxops.push_back (otherTxop);
361  }
362  }
363 
372  NS_ASSERT (m_feManager != 0);
373 
374  if (m_feManager->StartTransmission (txop))
375  {
376  for (auto& collidingTxop : internalCollisionTxops)
377  {
378  m_feManager->NotifyInternalCollision (collidingTxop);
379  }
380  break;
381  }
382  else
383  {
384  // reset the current state to the EDCAF that won the contention
385  // but did not transmit anything
386  i--;
387  k = std::distance (m_txops.begin (), i);
388  }
389  }
390  i++;
391  }
392 }
393 
394 void
396 {
397  NS_LOG_FUNCTION (this);
398  UpdateBackoff ();
399  DoGrantDcfAccess ();
401 }
402 
403 Time
405 {
406  NS_LOG_FUNCTION (this);
407  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
408  const Time& sifs = GetSifs();
409  Time rxAccessStart = lastRxEnd + sifs;
410  if ((lastRxEnd <= Simulator::Now ()) && !m_lastRxReceivedOk)
411  {
412  rxAccessStart += GetEifsNoDifs ();
413  }
414  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + sifs;
415  Time txAccessStart = m_lastTxStart + m_lastTxDuration + sifs;
416  Time navAccessStart = m_lastNavStart + m_lastNavDuration + sifs;
417  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + sifs;
418  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + sifs;
419  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + sifs;
420  Time accessGrantedStart;
421  if (ignoreNav)
422  {
423  accessGrantedStart = MostRecent ({rxAccessStart,
424  busyAccessStart,
425  txAccessStart,
426  ackTimeoutAccessStart,
427  ctsTimeoutAccessStart,
428  switchingAccessStart}
429  );
430  }
431  else
432  {
433  accessGrantedStart = MostRecent ({rxAccessStart,
434  busyAccessStart,
435  txAccessStart,
436  navAccessStart,
437  ackTimeoutAccessStart,
438  ctsTimeoutAccessStart,
439  switchingAccessStart}
440  );
441  }
442  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
443  ", rx access start=" << rxAccessStart <<
444  ", busy access start=" << busyAccessStart <<
445  ", tx access start=" << txAccessStart <<
446  ", nav access start=" << navAccessStart);
447  return accessGrantedStart;
448 }
449 
450 Time
452 {
453  NS_LOG_FUNCTION (this << txop);
454  Time mostRecentEvent = MostRecent ({txop->GetBackoffStart (),
455  GetAccessGrantStart () + (txop->GetAifsn () * GetSlot ())});
456  NS_LOG_DEBUG ("Backoff start: " << mostRecentEvent.As (Time::US));
457 
458  return mostRecentEvent;
459 }
460 
461 Time
463 {
464  NS_LOG_FUNCTION (this << txop);
465  Time backoffEnd = GetBackoffStartFor (txop) + (txop->GetBackoffSlots () * GetSlot ());
466  NS_LOG_DEBUG ("Backoff end: " << backoffEnd.As (Time::US));
467 
468  return backoffEnd;
469 }
470 
471 void
473 {
474  NS_LOG_FUNCTION (this);
475  uint32_t k = 0;
476  for (auto txop : m_txops)
477  {
478  Time backoffStart = GetBackoffStartFor (txop);
479  if (backoffStart <= Simulator::Now ())
480  {
481  uint32_t nIntSlots = ((Simulator::Now () - backoffStart) / GetSlot ()).GetHigh ();
482  /*
483  * EDCA behaves slightly different to DCA. For EDCA we
484  * decrement once at the slot boundary at the end of AIFS as
485  * well as once at the end of each clear slot
486  * thereafter. For DCA we only decrement at the end of each
487  * clear slot after DIFS. We account for the extra backoff
488  * by incrementing the slot count here in the case of
489  * EDCA. The if statement whose body we are in has confirmed
490  * that a minimum of AIFS has elapsed since last busy
491  * medium.
492  */
493  if (txop->IsQosTxop ())
494  {
495  nIntSlots++;
496  }
497  uint32_t n = std::min (nIntSlots, txop->GetBackoffSlots ());
498  NS_LOG_DEBUG ("dcf " << k << " dec backoff slots=" << n);
499  Time backoffUpdateBound = backoffStart + (n * GetSlot ());
500  txop->UpdateBackoffSlotsNow (n, backoffUpdateBound);
501  }
502  ++k;
503  }
504 }
505 
506 void
508 {
509  NS_LOG_FUNCTION (this);
514  bool accessTimeoutNeeded = false;
515  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
516  for (auto txop : m_txops)
517  {
518  if (txop->GetAccessStatus () == Txop::REQUESTED)
519  {
520  Time tmp = GetBackoffEndFor (txop);
521  if (tmp > Simulator::Now ())
522  {
523  accessTimeoutNeeded = true;
524  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
525  }
526  }
527  }
528  NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
529  if (accessTimeoutNeeded)
530  {
531  NS_LOG_DEBUG ("expected backoff end=" << expectedBackoffEnd);
532  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
534  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
535  {
537  }
538  if (m_accessTimeout.IsExpired ())
539  {
540  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
542  }
543  }
544 }
545 
546 void
548 {
549  NS_LOG_FUNCTION (this << qosTxop << duration);
550  NS_ASSERT (qosTxop->IsQosTxop ());
551  UpdateBackoff ();
552  Time resume = Simulator::Now () + duration;
553  NS_LOG_DEBUG ("Backoff will resume at time " << resume << " with "
554  << qosTxop->GetBackoffSlots () << " remaining slot(s)");
555  qosTxop->UpdateBackoffSlotsNow (0, resume);
557 }
558 
559 void
561 {
562  NS_LOG_FUNCTION (this << duration);
563  NS_LOG_DEBUG ("rx start for=" << duration);
564  UpdateBackoff ();
566  m_lastRxDuration = duration;
567  m_lastRxReceivedOk = true;
568 }
569 
570 void
572 {
573  NS_LOG_FUNCTION (this);
574  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  Time now = Simulator::Now ();
585  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
586  if (lastRxEnd > now)
587  {
588  m_lastBusyStart = now;
589  m_lastBusyDuration = lastRxEnd - m_lastBusyStart;
590  }
592  m_lastRxReceivedOk = false;
593 }
594 
595 void
597 {
598  NS_LOG_FUNCTION (this << duration);
599  m_lastRxReceivedOk = true;
600  Time now = Simulator::Now ();
601  Time lastRxEnd = m_lastRxStart + m_lastRxDuration;
602  if (lastRxEnd > now)
603  {
604  //this may be caused only if PHY has started to receive a packet
605  //inside SIFS, so, we check that lastRxStart was maximum a SIFS ago
606  NS_ASSERT (now - m_lastRxStart <= GetSifs ());
608  }
609  NS_LOG_DEBUG ("tx start for " << duration);
610  UpdateBackoff ();
611  m_lastTxStart = now;
612  m_lastTxDuration = duration;
613 }
614 
615 void
617 {
618  NS_LOG_FUNCTION (this << duration);
619  NS_LOG_DEBUG ("busy start for " << duration);
620  UpdateBackoff ();
622  m_lastBusyDuration = duration;
623 }
624 
625 void
627 {
628  NS_LOG_FUNCTION (this << duration);
629  Time now = Simulator::Now ();
632 
633  m_lastRxReceivedOk = true;
634 
635  if (m_lastRxStart + m_lastRxDuration > now)
636  {
637  //channel switching during packet reception
639  }
640  if (m_lastNavStart + m_lastNavDuration > now)
641  {
643  }
645  {
647  }
648  if (m_lastAckTimeoutEnd > now)
649  {
650  m_lastAckTimeoutEnd = now;
651  }
652  if (m_lastCtsTimeoutEnd > now)
653  {
654  m_lastCtsTimeoutEnd = now;
655  }
656 
657  //Cancel timeout
658  if (m_accessTimeout.IsRunning ())
659  {
661  }
662 
663  // Notify the FEM, which will in turn notify the MAC
664  m_feManager->NotifySwitchingStartNow (duration);
665 
666  //Reset backoffs
667  for (auto txop : m_txops)
668  {
669  uint32_t remainingSlots = txop->GetBackoffSlots ();
670  if (remainingSlots > 0)
671  {
672  txop->UpdateBackoffSlotsNow (remainingSlots, now);
673  NS_ASSERT (txop->GetBackoffSlots () == 0);
674  }
675  txop->ResetCw ();
676  txop->m_access = Txop::NOT_REQUESTED;
677  }
678 
679  NS_LOG_DEBUG ("switching start for " << duration);
681  m_lastSwitchingDuration = duration;
682 }
683 
684 void
686 {
687  NS_LOG_FUNCTION (this);
688  m_sleeping = true;
689  //Cancel timeout
690  if (m_accessTimeout.IsRunning ())
691  {
693  }
694 
695  //Reset backoffs
696  for (auto txop : m_txops)
697  {
698  txop->NotifySleep ();
699  }
700 }
701 
702 void
704 {
705  NS_LOG_FUNCTION (this);
706  m_off = true;
707  //Cancel timeout
708  if (m_accessTimeout.IsRunning ())
709  {
711  }
712 
713  //Reset backoffs
714  for (auto txop : m_txops)
715  {
716  txop->NotifyOff ();
717  }
718 }
719 
720 void
722 {
723  NS_LOG_FUNCTION (this);
724  m_sleeping = 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_access = Txop::NOT_REQUESTED;
735  txop->NotifyWakeUp ();
736  }
737 }
738 
739 void
741 {
742  NS_LOG_FUNCTION (this);
743  m_off = false;
744  for (auto txop : m_txops)
745  {
746  uint32_t remainingSlots = txop->GetBackoffSlots ();
747  if (remainingSlots > 0)
748  {
749  txop->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
750  NS_ASSERT (txop->GetBackoffSlots () == 0);
751  }
752  txop->ResetCw ();
753  txop->m_access = Txop::NOT_REQUESTED;
754  txop->NotifyOn ();
755  }
756 }
757 
758 void
760 {
761  NS_LOG_FUNCTION (this << duration);
762  NS_LOG_DEBUG ("nav reset for=" << duration);
763  UpdateBackoff ();
765  m_lastNavDuration = duration;
773 }
774 
775 void
777 {
778  NS_LOG_FUNCTION (this << duration);
780  NS_LOG_DEBUG ("nav start for=" << duration);
781  UpdateBackoff ();
782  Time newNavEnd = Simulator::Now () + duration;
783  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
784  if (newNavEnd > lastNavEnd)
785  {
787  m_lastNavDuration = duration;
788  }
789 }
790 
791 void
793 {
794  NS_LOG_FUNCTION (this << duration);
796  m_lastAckTimeoutEnd = Simulator::Now () + duration;
797 }
798 
799 void
801 {
802  NS_LOG_FUNCTION (this);
805 }
806 
807 void
809 {
810  NS_LOG_FUNCTION (this << duration);
811  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
812 }
813 
814 void
816 {
817  NS_LOG_FUNCTION (this);
820 }
821 
822 } //namespace ns3
#define min(a, b)
Definition: 80211b.c:42
Manage a set of ns3::Txop.
Time MostRecent(std::initializer_list< Time > list) const
Return the most recent time.
void AccessTimeout(void)
Called when access timeout should occur (e.g.
bool m_off
flag whether it is in off state
void NotifyRxStartNow(Time duration)
void UpdateBackoff(void)
Update backoff slots for all Txops.
Time m_lastRxStart
the last receive start time
Time GetBackoffEndFor(Ptr< Txop > txop)
Return the time when the backoff procedure ended (or will ended) for the given Txop.
void DoDispose(void) override
Destructor implementation.
bool m_lastRxReceivedOk
the last receive OK
void NotifyCtsTimeoutResetNow(void)
Notify that CTS timer has reset.
void NotifyOnNow(void)
Notify the Txop that the device has been resumed from off mode.
Ptr< WifiPhy > m_phy
pointer to the PHY
void NotifyTxStartNow(Time duration)
Time m_lastRxDuration
the last receive duration time
Time m_lastSwitchingDuration
the last switching duration time
Time m_lastSwitchingStart
the last switching start time
Time m_lastAckTimeoutEnd
the last Ack timeout end time
void NotifyAckTimeoutStartNow(Time duration)
Notify that ack timer has started for the given duration.
bool m_sleeping
flag whether it is in sleeping state
void NotifyRxEndOkNow(void)
Notify the Txop that a packet reception was just completed successfully.
void SetupFrameExchangeManager(Ptr< FrameExchangeManager > feManager)
Set up the Frame Exchange Manager.
void NotifyCtsTimeoutStartNow(Time duration)
Notify that CTS timer has started for the given duration.
void RequestAccess(Ptr< Txop > txop)
Time m_lastTxStart
the last transmit start time
bool IsBusy(void) const
Check if the device is busy sending or receiving, or NAV or CCA busy.
void NotifyMaybeCcaBusyStartNow(Time duration)
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for PHY events.
void NotifySleepNow(void)
Notify the Txop that the device has been put in sleep mode.
void SetupPhyListener(Ptr< WifiPhy > phy)
Set up listener for PHY events.
Time m_lastCtsTimeoutEnd
the last CTS timeout end time
void NotifyWakeupNow(void)
Notify the Txop that the device has been resumed from sleep mode.
Ptr< FrameExchangeManager > m_feManager
pointer to the Frame Exchange Manager
void NotifyOffNow(void)
Notify the Txop that the device has been put in off mode.
Time m_lastBusyStart
the last busy start time
Time m_lastNavDuration
the last NAV duration time
PhyListener * m_phyListener
the PHY listener
virtual Time GetSlot(void) const
Return the slot duration for this PHY.
void NotifySwitchingStartNow(Time duration)
void DisableEdcaFor(Ptr< Txop > qosTxop, Time duration)
void DoGrantDcfAccess(void)
Grant access to Txop using DCF/EDCF contention rules.
Txops m_txops
the vector of managed Txops
Time m_lastTxDuration
the last transmit duration time
virtual Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Time m_lastBusyDuration
the last busy duration time
void NotifyAckTimeoutResetNow(void)
Notify that ack timer has reset.
void NotifyNavResetNow(Time duration)
Time GetAccessGrantStart(bool ignoreNav=false) const
Access will never be granted to the medium before the time returned by this method.
bool NeedBackoffUponAccess(Ptr< Txop > txop)
Determine if a new backoff needs to be generated when a packet is queued for transmission.
virtual Time GetEifsNoDifs(void) const
Return the EIFS duration minus a DIFS.
Time GetBackoffStartFor(Ptr< Txop > txop)
Return the time when the backoff procedure started for the given Txop.
Time m_lastNavStart
the last NAV start time
void NotifyNavStartNow(Time duration)
EventId m_accessTimeout
the access timeout ID
void NotifyRxEndErrorNow(void)
Notify the Txop that a packet reception was just completed unsuccessfully.
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
Listener for PHY events.
void NotifySwitchingStart(Time duration)
void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyOn(void)
Notify listeners that we went to switch on.
PhyListener(ns3::ChannelAccessManager *cam)
Create a PhyListener for the given ChannelAccessManager.
ns3::ChannelAccessManager * m_cam
ChannelAccessManager to forward events to.
void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and,...
void NotifyWakeup(void)
Notify listeners that we woke up.
void NotifyMaybeCcaBusyStart(Time duration)
void NotifyOff(void)
Notify listeners that we went to switch off.
void NotifyTxStart(Time duration, double txPowerDbm)
void NotifySleep(void)
Notify listeners that we went to sleep.
void NotifyRxStart(Time duration)
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:293
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:204
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ US
microsecond
Definition: nstime.h:116
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:418
virtual ChannelAccessStatus GetAccessStatus(void) const
Definition: txop.cc:335
@ GRANTED
Definition: txop.h:96
@ NOT_REQUESTED
Definition: txop.h:94
@ REQUESTED
Definition: txop.h:95
virtual void NotifyAccessRequested(void)
Notify that access request has been received.
Definition: txop.cc:341
virtual bool IsQosTxop() const
Check for QoS TXOP.
Definition: txop.cc:412
void UpdateBackoffSlotsNow(uint32_t nSlots, Time backoffUpdateBound)
Update backoff slots that nSlots has passed.
Definition: txop.cc:222
Time GetBackoffStart(void) const
Return the time when the backoff procedure started.
Definition: txop.cc:216
uint32_t GetBackoffSlots(void) const
Return the current number of backoff slots.
Definition: txop.cc:210
virtual bool HasFramesToTransmit(void)
Check if the Txop has frames to transmit.
Definition: txop.cc:286
virtual uint8_t GetAifsn(void) const
Return the number of slots that make up an AIFS.
Definition: txop.cc:274
Time GetSlot(void) const
Return the slot duration for this PHY.
Definition: wifi-phy.cc:688
void NotifyChannelAccessRequested(void)
Notify the PHY that an access to the channel was requested.
Definition: wifi-phy.cc:1672
Time GetSifs(void) const
Return the Short Interframe Space (SIFS) for this PHY.
Definition: wifi-phy.cc:676
Time GetAckTxTime(void) const
Return the estimated Ack TX time for this PHY.
Definition: wifi-phy.cc:706
receive notifications about 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
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1260
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
phy
Definition: third.py:93
#define list