A Discrete-Event Network Simulator
API
dcf-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/assert.h"
22 #include "ns3/log.h"
23 #include "ns3/simulator.h"
24 #include <cmath>
25 #include "dcf-manager.h"
26 #include "wifi-phy.h"
27 #include "wifi-mac.h"
28 #include "mac-low.h"
29 
30 #define MY_DEBUG(x) \
31  NS_LOG_DEBUG (Simulator::Now () << " " << this << " " << x)
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("DcfManager");
36 
37 /****************************************************************
38  * Implement the DCF state holder
39  ****************************************************************/
40 
42  : m_backoffSlots (0),
43  m_backoffStart (Seconds (0.0)),
44  m_cwMin (0),
45  m_cwMax (0),
46  m_cw (0),
47  m_accessRequested (false)
48 {
49 }
50 
52 {
53 }
54 
55 void
56 DcfState::SetAifsn (uint32_t aifsn)
57 {
58  m_aifsn = aifsn;
59 }
60 
61 void
63 {
64  NS_ASSERT_MSG ((txopLimit.GetMicroSeconds () % 32 == 0), "The TXOP limit must be expressed in multiple of 32 microseconds!");
65  m_txopLimit = txopLimit;
66 }
67 
68 void
69 DcfState::SetCwMin (uint32_t minCw)
70 {
71  bool changed = (m_cwMin != minCw);
72  m_cwMin = minCw;
73  if (changed == true)
74  {
75  ResetCw ();
76  }
77 }
78 
79 void
80 DcfState::SetCwMax (uint32_t maxCw)
81 {
82  bool changed = (m_cwMax != maxCw);
83  m_cwMax = maxCw;
84  if (changed == true)
85  {
86  ResetCw ();
87  }
88 }
89 
90 uint32_t
91 DcfState::GetAifsn (void) const
92 {
93  return m_aifsn;
94 }
95 
96 Time
98 {
99  return m_txopLimit;
100 }
101 
102 uint32_t
103 DcfState::GetCwMin (void) const
104 {
105  return m_cwMin;
106 }
107 
108 uint32_t
109 DcfState::GetCwMax (void) const
110 {
111  return m_cwMax;
112 }
113 
114 void
116 {
117  m_cw = m_cwMin;
118 }
119 
120 void
122 {
123  //see 802.11-2012, section 9.19.2.5
124  m_cw = std::min ( 2 * (m_cw + 1) - 1, m_cwMax);
125 }
126 
127 void
128 DcfState::UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound)
129 {
130  m_backoffSlots -= nSlots;
131  m_backoffStart = backoffUpdateBound;
132  MY_DEBUG ("update slots=" << nSlots << " slots, backoff=" << m_backoffSlots);
133 }
134 
135 void
136 DcfState::StartBackoffNow (uint32_t nSlots)
137 {
138  if (m_backoffSlots != 0)
139  {
140  MY_DEBUG ("reset backoff from " << m_backoffSlots << " to " << nSlots << " slots");
141  }
142  else
143  {
144  MY_DEBUG ("start backoff=" << nSlots << " slots");
145  }
146  m_backoffSlots = nSlots;
148 }
149 
150 uint32_t
151 DcfState::GetCw (void) const
152 {
153  return m_cw;
154 }
155 
156 uint32_t
158 {
159  return m_backoffSlots;
160 }
161 
162 Time
164 {
165  return m_backoffStart;
166 }
167 
168 bool
170 {
171  return m_accessRequested;
172 }
173 void
175 {
176  m_accessRequested = true;
177 }
178 
179 void
181 {
183  m_accessRequested = false;
185 }
186 
187 void
189 {
191 }
192 
193 void
195 {
197 }
198 
199 void
201 {
203 }
204 
205 void
207 {
208  DoNotifySleep ();
209 }
210 
211 void
213 {
214  DoNotifyWakeUp ();
215 }
216 
217 
222 {
223 public:
230  : m_dcf (dcf)
231  {
232  }
233  virtual ~LowDcfListener ()
234  {
235  }
236  virtual void NavStart (Time duration)
237  {
238  m_dcf->NotifyNavStartNow (duration);
239  }
240  virtual void NavReset (Time duration)
241  {
242  m_dcf->NotifyNavResetNow (duration);
243  }
244  virtual void AckTimeoutStart (Time duration)
245  {
246  m_dcf->NotifyAckTimeoutStartNow (duration);
247  }
248  virtual void AckTimeoutReset ()
249  {
251  }
252  virtual void CtsTimeoutStart (Time duration)
253  {
254  m_dcf->NotifyCtsTimeoutStartNow (duration);
255  }
256  virtual void CtsTimeoutReset ()
257  {
259  }
260 
261 private:
263 };
264 
265 
270 {
271 public:
278  : m_dcf (dcf)
279  {
280  }
281  virtual ~PhyListener ()
282  {
283  }
284  virtual void NotifyRxStart (Time duration)
285  {
286  m_dcf->NotifyRxStartNow (duration);
287  }
288  virtual void NotifyRxEndOk (void)
289  {
291  }
292  virtual void NotifyRxEndError (void)
293  {
295  }
296  virtual void NotifyTxStart (Time duration, double txPowerDbm)
297  {
298  m_dcf->NotifyTxStartNow (duration);
299  }
300  virtual void NotifyMaybeCcaBusyStart (Time duration)
301  {
302  m_dcf->NotifyMaybeCcaBusyStartNow (duration);
303  }
304  virtual void NotifySwitchingStart (Time duration)
305  {
306  m_dcf->NotifySwitchingStartNow (duration);
307  }
308  virtual void NotifySleep (void)
309  {
310  m_dcf->NotifySleepNow ();
311  }
312  virtual void NotifyWakeup (void)
313  {
315  }
316 
317 private:
319 };
320 
321 
322 /****************************************************************
323  * Implement the DCF manager of all DCF state holders
324  ****************************************************************/
325 
327  : m_lastAckTimeoutEnd (MicroSeconds (0)),
328  m_lastCtsTimeoutEnd (MicroSeconds (0)),
329  m_lastNavStart (MicroSeconds (0)),
330  m_lastNavDuration (MicroSeconds (0)),
331  m_lastRxStart (MicroSeconds (0)),
332  m_lastRxDuration (MicroSeconds (0)),
333  m_lastRxReceivedOk (true),
334  m_lastRxEnd (MicroSeconds (0)),
335  m_lastTxStart (MicroSeconds (0)),
336  m_lastTxDuration (MicroSeconds (0)),
337  m_lastBusyStart (MicroSeconds (0)),
338  m_lastBusyDuration (MicroSeconds (0)),
339  m_lastSwitchingStart (MicroSeconds (0)),
340  m_lastSwitchingDuration (MicroSeconds (0)),
341  m_rxing (false),
342  m_sleeping (false),
343  m_slotTimeUs (0),
344  m_sifs (Seconds (0.0)),
345  m_phyListener (0),
346  m_lowListener (0)
347 {
348  NS_LOG_FUNCTION (this);
349 }
350 
352 {
353  delete m_phyListener;
354  delete m_lowListener;
355  m_phyListener = 0;
356  m_lowListener = 0;
357 }
358 
359 void
361 {
362  NS_LOG_FUNCTION (this << phy);
363  if (m_phyListener != 0)
364  {
365  delete m_phyListener;
366  }
367  m_phyListener = new PhyListener (this);
369 }
370 
371 void
373 {
374  NS_LOG_FUNCTION (this << phy);
375  if (m_phyListener != 0)
376  {
378  delete m_phyListener;
379  m_phyListener = 0;
380  }
381 }
382 
383 void
385 {
386  NS_LOG_FUNCTION (this << low);
387  if (m_lowListener != 0)
388  {
389  delete m_lowListener;
390  }
391  m_lowListener = new LowDcfListener (this);
393 }
394 
395 void
397 {
398  NS_LOG_FUNCTION (this << slotTime);
399  m_slotTimeUs = slotTime.GetMicroSeconds ();
400 }
401 
402 void
404 {
405  NS_LOG_FUNCTION (this << sifs);
406  m_sifs = sifs;
407 }
408 
409 void
411 {
412  NS_LOG_FUNCTION (this << eifsNoDifs);
413  m_eifsNoDifs = eifsNoDifs;
414 }
415 
416 Time
418 {
419  NS_LOG_FUNCTION (this);
420  return m_eifsNoDifs;
421 }
422 
423 void
425 {
426  NS_LOG_FUNCTION (this << dcf);
427  m_states.push_back (dcf);
428 }
429 
430 Time
432 {
433  NS_LOG_FUNCTION (this << a << b);
434  return Max (a, b);
435 }
436 
437 Time
439 {
440  NS_LOG_FUNCTION (this << a << b << c);
441  Time retval;
442  retval = Max (a, b);
443  retval = Max (retval, c);
444  return retval;
445 }
446 
447 Time
449 {
450  NS_LOG_FUNCTION (this << a << b << c << d);
451  Time e = Max (a, b);
452  Time f = Max (c, d);
453  Time retval = Max (e, f);
454  return retval;
455 }
456 
457 Time
459 {
460  NS_LOG_FUNCTION (this << a << b << c << d << e << f);
461  Time g = Max (a, b);
462  Time h = Max (c, d);
463  Time i = Max (e, f);
464  Time k = Max (g, h);
465  Time retval = Max (k, i);
466  return retval;
467 }
468 
469 Time
471 {
472  NS_LOG_FUNCTION (this << a << b << c << d << e << f << g);
473  Time h = Max (a, b);
474  Time i = Max (c, d);
475  Time j = Max (e, f);
476  Time k = Max (h, i);
477  Time l = Max (j, g);
478  Time retval = Max (k, l);
479  return retval;
480 }
481 
482 bool
483 DcfManager::IsBusy (void) const
484 {
485  NS_LOG_FUNCTION (this);
486  // PHY busy
487  if (m_rxing)
488  {
489  return true;
490  }
491  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
492  if (lastTxEnd > Simulator::Now ())
493  {
494  return true;
495  }
496  // NAV busy
497  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
498  if (lastNavEnd > Simulator::Now ())
499  {
500  return true;
501  }
502  // CCA busy
503  Time lastCCABusyEnd = m_lastBusyStart + m_lastBusyDuration;
504  if (lastCCABusyEnd > Simulator::Now ())
505  {
506  return true;
507  }
508  return false;
509 }
510 
511 bool
513 {
514  NS_LOG_FUNCTION (this << state);
515  Time ifsEnd = GetAccessGrantStart () + MicroSeconds (state->GetAifsn () * m_slotTimeUs);
516  if (ifsEnd > Simulator::Now ())
517  {
518  NS_LOG_DEBUG ("IsWithinAifs () true; ifsEnd is at " << ifsEnd.GetSeconds ());
519  return true;
520  }
521  NS_LOG_DEBUG ("IsWithinAifs () false; ifsEnd was at " << ifsEnd.GetSeconds ());
522  return false;
523 }
524 
525 void
527 {
528  NS_LOG_FUNCTION (this << state);
529  //Deny access if in sleep mode
530  if (m_sleeping)
531  {
532  return;
533  }
534  UpdateBackoff ();
535  NS_ASSERT (!state->IsAccessRequested ());
536  state->NotifyAccessRequested ();
537  // If currently transmitting; end of transmission (ACK or no ACK) will cause
538  // a later access request if needed from EndTxNoAck, GotAck, or MissedAck
539  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
540  if (lastTxEnd > Simulator::Now ())
541  {
542  NS_LOG_DEBUG ("Internal collision (currently transmitting)");
543  state->NotifyInternalCollision ();
545  return;
546  }
551  if (state->GetBackoffSlots () == 0)
552  {
553  if (IsBusy ())
554  {
555  MY_DEBUG ("medium is busy: collision");
556  // someone else has accessed the medium; generate a backoff.
557  state->NotifyCollision ();
559  return;
560  }
561  else if (IsWithinAifs (state))
562  {
563  MY_DEBUG ("busy within AIFS");
564  state->NotifyCollision ();
566  return;
567  }
568  }
569  DoGrantAccess ();
571 }
572 
573 void
575 {
576  NS_LOG_FUNCTION (this);
577  uint32_t k = 0;
578  for (States::const_iterator i = m_states.begin (); i != m_states.end (); k++)
579  {
580  DcfState *state = *i;
581  if (state->IsAccessRequested ()
582  && GetBackoffEndFor (state) <= Simulator::Now () )
583  {
588  MY_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << state->GetBackoffSlots ());
589  i++; //go to the next item in the list.
590  k++;
591  std::vector<DcfState *> internalCollisionStates;
592  for (States::const_iterator j = i; j != m_states.end (); j++, k++)
593  {
594  DcfState *otherState = *j;
595  if (otherState->IsAccessRequested ()
596  && GetBackoffEndFor (otherState) <= Simulator::Now ())
597  {
598  MY_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
599  otherState->GetBackoffSlots ());
605  internalCollisionStates.push_back (otherState);
606  }
607  }
608 
616  state->NotifyAccessGranted ();
617  for (std::vector<DcfState *>::const_iterator k = internalCollisionStates.begin ();
618  k != internalCollisionStates.end (); k++)
619  {
620  (*k)->NotifyInternalCollision ();
621  }
622  break;
623  }
624  i++;
625  }
626 }
627 
628 void
630 {
631  NS_LOG_FUNCTION (this);
632  UpdateBackoff ();
633  DoGrantAccess ();
635 }
636 
637 Time
639 {
640  NS_LOG_FUNCTION (this);
641  Time rxAccessStart;
642  if (!m_rxing)
643  {
644  rxAccessStart = m_lastRxEnd + m_sifs;
645  if (!m_lastRxReceivedOk)
646  {
647  rxAccessStart += m_eifsNoDifs;
648  }
649  }
650  else
651  {
652  rxAccessStart = m_lastRxStart + m_lastRxDuration + m_sifs;
653  }
654  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs;
655  Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs;
656  Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs;
657  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs;
658  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs;
659  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + m_sifs;
660  Time accessGrantedStart = MostRecent (rxAccessStart,
661  busyAccessStart,
662  txAccessStart,
663  navAccessStart,
664  ackTimeoutAccessStart,
665  ctsTimeoutAccessStart,
666  switchingAccessStart
667  );
668  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
669  ", rx access start=" << rxAccessStart <<
670  ", busy access start=" << busyAccessStart <<
671  ", tx access start=" << txAccessStart <<
672  ", nav access start=" << navAccessStart);
673  return accessGrantedStart;
674 }
675 
676 Time
678 {
679  NS_LOG_FUNCTION (this << state);
680  Time mostRecentEvent = MostRecent (state->GetBackoffStart (),
682 
683  return mostRecentEvent;
684 }
685 
686 Time
688 {
689  NS_LOG_FUNCTION (this << state);
690  NS_LOG_DEBUG ("Backoff start: " << GetBackoffStartFor (state).As (Time::US) <<
691  " end: " << (GetBackoffStartFor (state) +
693  return GetBackoffStartFor (state) + MicroSeconds (state->GetBackoffSlots () * m_slotTimeUs);
694 }
695 
696 void
698 {
699  NS_LOG_FUNCTION (this);
700  uint32_t k = 0;
701  for (States::const_iterator i = m_states.begin (); i != m_states.end (); i++, k++)
702  {
703  DcfState *state = *i;
704 
705  Time backoffStart = GetBackoffStartFor (state);
706  if (backoffStart <= Simulator::Now ())
707  {
708  uint32_t nus = (Simulator::Now () - backoffStart).GetMicroSeconds ();
709  uint32_t nIntSlots = nus / m_slotTimeUs;
710  /*
711  * EDCA behaves slightly different to DCA. For EDCA we
712  * decrement once at the slot boundary at the end of AIFS as
713  * well as once at the end of each clear slot
714  * thereafter. For DCA we only decrement at the end of each
715  * clear slot after DIFS. We account for the extra backoff
716  * by incrementing the slot count here in the case of
717  * EDCA. The if statement whose body we are in has confirmed
718  * that a minimum of AIFS has elapsed since last busy
719  * medium.
720  */
721  if (state->IsEdca ())
722  {
723  nIntSlots++;
724  }
725  uint32_t n = std::min (nIntSlots, state->GetBackoffSlots ());
726  MY_DEBUG ("dcf " << k << " dec backoff slots=" << n);
727  Time backoffUpdateBound = backoffStart + MicroSeconds (n * m_slotTimeUs);
728  state->UpdateBackoffSlotsNow (n, backoffUpdateBound);
729  }
730  }
731 }
732 
733 void
735 {
736  NS_LOG_FUNCTION (this);
741  bool accessTimeoutNeeded = false;
742  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
743  for (States::const_iterator i = m_states.begin (); i != m_states.end (); i++)
744  {
745  DcfState *state = *i;
746  if (state->IsAccessRequested ())
747  {
748  Time tmp = GetBackoffEndFor (state);
749  if (tmp > Simulator::Now ())
750  {
751  accessTimeoutNeeded = true;
752  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
753  }
754  }
755  }
756  NS_LOG_DEBUG ("Access timeout needed: " << accessTimeoutNeeded);
757  if (accessTimeoutNeeded)
758  {
759  MY_DEBUG ("expected backoff end=" << expectedBackoffEnd);
760  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
762  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
763  {
765  }
766  if (m_accessTimeout.IsExpired ())
767  {
768  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
770  }
771  }
772 }
773 
774 void
776 {
777  NS_LOG_FUNCTION (this << duration);
778  MY_DEBUG ("rx start for=" << duration);
779  UpdateBackoff ();
781  m_lastRxDuration = duration;
782  m_rxing = true;
783 }
784 
785 void
787 {
788  NS_LOG_FUNCTION (this);
789  MY_DEBUG ("rx end ok");
791  m_lastRxReceivedOk = true;
792  m_rxing = false;
793 }
794 
795 void
797 {
798  NS_LOG_FUNCTION (this);
799  MY_DEBUG ("rx end error");
801  m_lastRxReceivedOk = false;
802  m_rxing = false;
803 }
804 
805 void
807 {
808  NS_LOG_FUNCTION (this << duration);
809  if (m_rxing)
810  {
811  if (Simulator::Now () - m_lastRxStart <= m_sifs)
812  {
813  //this may be caused if PHY has started to receive a packet
814  //inside SIFS, so, we check that lastRxStart was within a SIFS ago
817  m_lastRxReceivedOk = true;
818  m_rxing = false;
819  }
820  else
821  {
822  // Bug 2477: It is possible for the DCF to fall out of
823  // sync with the PHY state if there are problems
824  // receiving A-MPDUs. PHY will cancel the reception
825  // and start to transmit
826  NS_LOG_DEBUG ("Phy is transmitting despite DCF being in receive state");
829  m_lastRxReceivedOk = false;
830  m_rxing = false;
831  }
832  }
833  MY_DEBUG ("tx start for " << duration);
834  UpdateBackoff ();
836  m_lastTxDuration = duration;
837 }
838 
839 void
841 {
842  NS_LOG_FUNCTION (this << duration);
843  MY_DEBUG ("busy start for " << duration);
844  UpdateBackoff ();
846  m_lastBusyDuration = duration;
847 }
848 
849 void
851 {
852  NS_LOG_FUNCTION (this << duration);
853  Time now = Simulator::Now ();
856 
857  if (m_rxing)
858  {
859  //channel switching during packet reception
862  m_lastRxReceivedOk = true;
863  m_rxing = false;
864  }
865  if (m_lastNavStart + m_lastNavDuration > now)
866  {
868  }
870  {
872  }
873  if (m_lastAckTimeoutEnd > now)
874  {
875  m_lastAckTimeoutEnd = now;
876  }
877  if (m_lastCtsTimeoutEnd > now)
878  {
879  m_lastCtsTimeoutEnd = now;
880  }
881 
882  //Cancel timeout
883  if (m_accessTimeout.IsRunning ())
884  {
886  }
887 
888  //Reset backoffs
889  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
890  {
891  DcfState *state = *i;
892  uint32_t remainingSlots = state->GetBackoffSlots ();
893  if (remainingSlots > 0)
894  {
895  state->UpdateBackoffSlotsNow (remainingSlots, now);
896  NS_ASSERT (state->GetBackoffSlots () == 0);
897  }
898  state->ResetCw ();
899  state->m_accessRequested = false;
900  state->NotifyChannelSwitching ();
901  }
902 
903  MY_DEBUG ("switching start for " << duration);
905  m_lastSwitchingDuration = duration;
906 
907 }
908 
909 void
911 {
912  NS_LOG_FUNCTION (this);
913  m_sleeping = true;
914  //Cancel timeout
915  if (m_accessTimeout.IsRunning ())
916  {
918  }
919 
920  //Reset backoffs
921  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
922  {
923  DcfState *state = *i;
924  state->NotifySleep ();
925  }
926 }
927 
928 void
930 {
931  NS_LOG_FUNCTION (this);
932  m_sleeping = false;
933  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
934  {
935  DcfState *state = *i;
936  uint32_t remainingSlots = state->GetBackoffSlots ();
937  if (remainingSlots > 0)
938  {
939  state->UpdateBackoffSlotsNow (remainingSlots, Simulator::Now ());
940  NS_ASSERT (state->GetBackoffSlots () == 0);
941  }
942  state->ResetCw ();
943  state->m_accessRequested = false;
944  state->NotifyWakeUp ();
945  }
946 }
947 
948 void
950 {
951  NS_LOG_FUNCTION (this << duration);
952  MY_DEBUG ("nav reset for=" << duration);
953  UpdateBackoff ();
955  m_lastNavDuration = duration;
963 }
964 
965 void
967 {
968  NS_LOG_FUNCTION (this << duration);
970  MY_DEBUG ("nav start for=" << duration);
971  UpdateBackoff ();
972  Time newNavEnd = Simulator::Now () + duration;
973  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
974  if (newNavEnd > lastNavEnd)
975  {
977  m_lastNavDuration = duration;
978  }
979 }
980 
981 void
983 {
984  NS_LOG_FUNCTION (this << duration);
986  m_lastAckTimeoutEnd = Simulator::Now () + duration;
987 }
988 
989 void
991 {
992  NS_LOG_FUNCTION (this);
995 }
996 
997 void
999 {
1000  NS_LOG_FUNCTION (this << duration);
1001  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
1002 }
1003 
1004 void
1006 {
1007  NS_LOG_FUNCTION (this);
1010 }
1011 } //namespace ns3
uint32_t m_cwMin
Definition: dcf-manager.h:256
ns3::DcfManager * m_dcf
DcfManager to forward events to.
Definition: dcf-manager.cc:318
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:233
void SetTxopLimit(Time txopLimit)
Set the TXOP limit.
Definition: dcf-manager.cc:62
void NotifyWakeupNow(void)
Notify the DCF that the device has been resumed from sleep mode.
Definition: dcf-manager.cc:929
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
void NotifySleep(void)
Notify that the device has started to sleep.
Definition: dcf-manager.cc:206
ns3::DcfManager * m_dcf
DcfManager to forward events to.
Definition: dcf-manager.cc:262
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual void NavReset(Time duration)
Notify that NAV has resetted.
Definition: dcf-manager.cc:240
void NotifyInternalCollision(void)
Notify that internal collision has occurred.
Definition: dcf-manager.cc:194
bool m_lastRxReceivedOk
Definition: dcf-manager.h:562
uint32_t GetCwMin(void) const
Return the minimum congestion window size.
Definition: dcf-manager.cc:103
#define min(a, b)
Definition: 80211b.c:44
virtual void NotifyRxStart(Time duration)
Definition: dcf-manager.cc:284
void NotifyAccessGranted(void)
Notify that access has been granted.
Definition: dcf-manager.cc:180
void RequestAccess(DcfState *state)
Definition: dcf-manager.cc:526
Time GetBackoffStart(void) const
Return the time when the backoff procedure started.
Definition: dcf-manager.cc:163
void SetupLowListener(Ptr< MacLow > low)
Set up listener for MacLow events.
Definition: dcf-manager.cc:384
#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
Time m_lastAckTimeoutEnd
Definition: dcf-manager.h:556
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
void NotifyWakeUp(void)
Notify that the device has started to wake up.
Definition: dcf-manager.cc:212
virtual void NotifySwitchingStart(Time duration)
Definition: dcf-manager.cc:304
LowDcfListener(ns3::DcfManager *dcf)
Create a LowDcfListener for the given DcfManager.
Definition: dcf-manager.cc:229
void UpdateBackoff(void)
Update backoff slots for all DcfStates.
Definition: dcf-manager.cc:697
virtual void DoNotifyCollision(void)=0
Called by DcfManager to notify a DcfState subclass that a normal collision occured, that is, that the medium was busy when access was requested.
virtual void NotifyWakeup(void)
Notify listeners that we woke up.
Definition: dcf-manager.cc:312
Time m_lastCtsTimeoutEnd
Definition: dcf-manager.h:557
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:244
bool m_accessRequested
Definition: dcf-manager.h:260
void SetAifsn(uint32_t aifsn)
Definition: dcf-manager.cc:56
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
void ResetCw(void)
Update the value of the CW variable to take into account a transmission success or a transmission abo...
Definition: dcf-manager.cc:115
Time m_lastSwitchingDuration
Definition: dcf-manager.h:569
PhyListener(ns3::DcfManager *dcf)
Create a PhyListener for the given DcfManager.
Definition: dcf-manager.cc:277
void Add(DcfState *dcf)
Definition: dcf-manager.cc:424
Time GetTxopLimit(void) const
Return the TXOP limit.
Definition: dcf-manager.cc:97
virtual void NotifyRxEndOk(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
Definition: dcf-manager.cc:288
virtual void RegisterListener(WifiPhyListener *listener)=0
void DoGrantAccess(void)
Grant access to DCF.
Definition: dcf-manager.cc:574
void NotifyNavResetNow(Time duration)
Definition: dcf-manager.cc:949
Time GetBackoffStartFor(DcfState *state)
Return the time when the backoff procedure started for the given DcfState.
Definition: dcf-manager.cc:677
void NotifyCtsTimeoutStartNow(Time duration)
Notify that CTS timer has started for the given duration.
Definition: dcf-manager.cc:998
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void NotifyRxEndOkNow(void)
Notify the DCF that a packet reception was just completed successfully.
Definition: dcf-manager.cc:786
uint32_t m_backoffSlots
Definition: dcf-manager.h:251
tuple phy
Definition: third.py:86
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1238
PhyListener * m_phyListener
Definition: dcf-manager.h:576
int64_t GetMicroSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:349
Time GetAccessGrantStart(void) const
Access will never be granted to the medium before the time returned by this method.
Definition: dcf-manager.cc:638
receive notifications about phy events.
Definition: wifi-phy.h:81
Time GetBackoffEndFor(DcfState *state)
Return the time when the backoff procedure ended (or will ended) for the given DcfState.
Definition: dcf-manager.cc:687
void NotifyTxStartNow(Time duration)
Definition: dcf-manager.cc:806
void RemovePhyListener(Ptr< WifiPhy > phy)
Remove current registered listener for Phy events.
Definition: dcf-manager.cc:372
void NotifyAckTimeoutStartNow(Time duration)
Notify that ACK timer has started for the given duration.
Definition: dcf-manager.cc:982
virtual void NavStart(Time duration)
Norify that NAV has started for the given duration.
Definition: dcf-manager.cc:236
void SetupPhyListener(Ptr< WifiPhy > phy)
Set up listener for Phy events.
Definition: dcf-manager.cc:360
Manage a set of ns3::DcfStateHandle a set of independent ns3::DcfState, each of which represents a si...
Definition: dcf-manager.h:279
int64x64_t Max(const int64x64_t &a, const int64x64_t &b)
Maximum.
Definition: int64x64.h:209
keep track of the state needed for a single DCF function.
Definition: dcf-manager.h:46
bool IsWithinAifs(DcfState *state) const
Check if the device is between frames (in DIFS or AIFS interval)
Definition: dcf-manager.cc:512
virtual void AckTimeoutStart(Time duration)
Notify that ACK timeout has started for a given duration.
Definition: dcf-manager.cc:244
virtual void CtsTimeoutReset()
Notify that CTS timeout has resetted.
Definition: dcf-manager.cc:256
bool IsAccessRequested(void) const
Definition: dcf-manager.cc:169
Listener for PHY events.
Definition: dcf-manager.cc:269
void RegisterDcfListener(MacLowDcfListener *listener)
Definition: mac-low.cc:699
uint32_t GetBackoffSlots(void) const
Return the current number of backoff slots.
Definition: dcf-manager.cc:157
virtual ~DcfState()
Definition: dcf-manager.cc:51
#define MY_DEBUG(x)
Definition: dcf-manager.cc:30
uint32_t GetCwMax(void) const
Return the maximum congestion window size.
Definition: dcf-manager.cc:109
Time m_lastBusyDuration
Definition: dcf-manager.h:567
void SetCwMin(uint32_t minCw)
Set the minimum congestion window size.
Definition: dcf-manager.cc:69
double f(double x, void *params)
Definition: 80211b.c:60
virtual void NotifySleep(void)
Notify listeners that we went to sleep.
Definition: dcf-manager.cc:308
void StartBackoffNow(uint32_t nSlots)
Definition: dcf-manager.cc:136
virtual void DoNotifyWakeUp(void)=0
Called by DcfManager to notify a DcfState subclass that the device has begun to wake up...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void NotifyMaybeCcaBusyStart(Time duration)
Definition: dcf-manager.cc:300
uint32_t m_cwMax
Definition: dcf-manager.h:257
virtual void DoNotifyAccessGranted(void)=0
Called by DcfManager to notify a DcfState subclass that access to the medium is granted and can start...
virtual void UnregisterListener(WifiPhyListener *listener)=0
void NotifyAccessRequested(void)
Notify that access request has been received.
Definition: dcf-manager.cc:174
void NotifyRxEndErrorNow(void)
Notify the DCF that a packet reception was just completed unsuccessfully.
Definition: dcf-manager.cc:796
virtual void CtsTimeoutStart(Time duration)
Notify that CTS timeout has started for a given duration.
Definition: dcf-manager.cc:252
uint32_t m_cw
Definition: dcf-manager.h:258
Time m_lastSwitchingStart
Definition: dcf-manager.h:568
void SetEifsNoDifs(Time eifsNoDifs)
Definition: dcf-manager.cc:410
virtual void DoNotifyInternalCollision(void)=0
Called by DcfManager to notify a DcfState subclass that an 'internal' collision occured, that is, that the backoff timer of a higher priority DcfState expired at the same time and that access was granted to this higher priority DcfState.
listen to NAV eventsThis class is typically connected to an instance of ns3::Dcf and calls to its met...
Definition: mac-low.h:162
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:224
void NotifyMaybeCcaBusyStartNow(Time duration)
Definition: dcf-manager.cc:840
void AccessTimeout(void)
Called when access timeout should occur (e.g.
Definition: dcf-manager.cc:629
Time m_lastNavDuration
Definition: dcf-manager.h:559
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
void SetSlot(Time slotTime)
Definition: dcf-manager.cc:396
microsecond
Definition: nstime.h:116
void SetCwMax(uint32_t maxCw)
Set the maximum congestion window size.
Definition: dcf-manager.cc:80
void NotifyAckTimeoutResetNow()
Notify that ACK timer has resetted.
Definition: dcf-manager.cc:990
LowDcfListener * m_lowListener
Definition: dcf-manager.h:577
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
void NotifyNavStartNow(Time duration)
Definition: dcf-manager.cc:966
void NotifyChannelSwitching(void)
Notify that the device is switching channel.
Definition: dcf-manager.cc:200
uint32_t GetCw(void) const
Definition: dcf-manager.cc:151
uint32_t GetAifsn(void) const
Return the number of slots that make up an AIFS.
Definition: dcf-manager.cc:91
uint32_t m_aifsn
Definition: dcf-manager.h:250
virtual void DoNotifyChannelSwitching(void)=0
Called by DcfManager to notify a DcfState subclass that a channel switching occured.
void NotifyRxStartNow(Time duration)
Definition: dcf-manager.cc:775
virtual void DoNotifySleep(void)=0
Called by DcfManager to notify a DcfState subclass that the device has begun to sleep.
void UpdateBackoffSlotsNow(uint32_t nSlots, Time backoffUpdateBound)
Update backoff slots that nSlots has passed.
Definition: dcf-manager.cc:128
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:895
virtual ~PhyListener()
Definition: dcf-manager.cc:281
Time GetEifsNoDifs() const
Definition: dcf-manager.cc:417
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
virtual void NotifyRxEndError(void)
We have received the last bit of a packet for which NotifyRxStart was invoked first and...
Definition: dcf-manager.cc:292
void NotifySleepNow(void)
Notify the DCF that the device has been put in sleep mode.
Definition: dcf-manager.cc:910
void NotifyCtsTimeoutResetNow()
Notify that CTS timer has resetted.
void NotifyCollision(void)
Notify that collision has occurred.
Definition: dcf-manager.cc:188
virtual void NotifyTxStart(Time duration, double txPowerDbm)
Definition: dcf-manager.cc:296
bool IsBusy(void) const
Check if the device is busy sending or receiving, or NAV or CCA busy.
Definition: dcf-manager.cc:483
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:911
Time m_backoffStart
Definition: dcf-manager.h:255
void DoRestartAccessTimeoutIfNeeded(void)
Definition: dcf-manager.cc:734
EventId m_accessTimeout
Definition: dcf-manager.h:573
virtual ~LowDcfListener()
Definition: dcf-manager.cc:233
void UpdateFailedCw(void)
Update the value of the CW variable to take into account a transmission failure.
Definition: dcf-manager.cc:121
Listener for NAV events.
Definition: dcf-manager.cc:221
void NotifySwitchingStartNow(Time duration)
Definition: dcf-manager.cc:850
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:59
virtual bool IsEdca(void) const =0
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:346
uint32_t m_slotTimeUs
Definition: dcf-manager.h:574
Time MostRecent(Time a, Time b) const
Return the most recent time.
Definition: dcf-manager.cc:431
void SetSifs(Time sifs)
Definition: dcf-manager.cc:403
virtual void AckTimeoutReset()
Notify that ACK timeout has resetted.
Definition: dcf-manager.cc:248