A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
dcf-manager.cc
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 
26 #include "dcf-manager.h"
27 #include "wifi-phy.h"
28 #include "wifi-mac.h"
29 #include "mac-low.h"
30 
31 NS_LOG_COMPONENT_DEFINE ("DcfManager");
32 
33 #define MY_DEBUG(x) \
34  NS_LOG_DEBUG (Simulator::Now () << " " << this << " " << x)
35 
36 namespace ns3 {
37 
38 /****************************************************************
39  * Implement the DCF state holder
40  ****************************************************************/
41 
42 DcfState::DcfState ()
43  : m_backoffSlots (0),
44  m_backoffStart (Seconds (0.0)),
45  m_cwMin (0),
46  m_cwMax (0),
47  m_cw (0),
48  m_accessRequested (false)
49 {
50 }
51 
52 DcfState::~DcfState ()
53 {
54 }
55 
56 void
57 DcfState::SetAifsn (uint32_t aifsn)
58 {
59  m_aifsn = aifsn;
60 }
61 void
62 DcfState::SetCwMin (uint32_t minCw)
63 {
64  m_cwMin = minCw;
65  ResetCw ();
66 }
67 void
68 DcfState::SetCwMax (uint32_t maxCw)
69 {
70  m_cwMax = maxCw;
71  ResetCw ();
72 }
73 uint32_t
74 DcfState::GetAifsn (void) const
75 {
76  return m_aifsn;
77 }
78 uint32_t
79 DcfState::GetCwMin (void) const
80 {
81  return m_cwMin;
82 }
83 uint32_t
84 DcfState::GetCwMax (void) const
85 {
86  return m_cwMax;
87 }
88 
89 void
91 {
92  m_cw = m_cwMin;
93 }
94 void
96 {
97  // see 802.11-2007, section 9.9.1.5
98  m_cw = std::min ( 2 * (m_cw + 1) - 1, m_cwMax);
99 }
100 void
101 DcfState::UpdateBackoffSlotsNow (uint32_t nSlots, Time backoffUpdateBound)
102 {
103  m_backoffSlots -= nSlots;
104  m_backoffStart = backoffUpdateBound;
105  MY_DEBUG ("update slots=" << nSlots << " slots, backoff=" << m_backoffSlots);
106 }
107 
108 void
109 DcfState::StartBackoffNow (uint32_t nSlots)
110 {
111  NS_ASSERT (m_backoffSlots == 0);
112  MY_DEBUG ("start backoff=" << nSlots << " slots");
113  m_backoffSlots = nSlots;
114  m_backoffStart = Simulator::Now ();
115 }
116 
117 uint32_t
118 DcfState::GetCw (void) const
119 {
120  return m_cw;
121 }
122 uint32_t
123 DcfState::GetBackoffSlots (void) const
124 {
125  return m_backoffSlots;
126 }
127 Time
128 DcfState::GetBackoffStart (void) const
129 {
130  return m_backoffStart;
131 }
132 bool
134 {
135  return m_accessRequested;
136 }
137 void
138 DcfState::NotifyAccessRequested (void)
139 {
140  m_accessRequested = true;
141 }
142 void
143 DcfState::NotifyAccessGranted (void)
144 {
145  NS_ASSERT (m_accessRequested);
146  m_accessRequested = false;
147  DoNotifyAccessGranted ();
148 }
149 void
150 DcfState::NotifyCollision (void)
151 {
152  DoNotifyCollision ();
153 }
154 void
155 DcfState::NotifyInternalCollision (void)
156 {
157  DoNotifyInternalCollision ();
158 }
159 void
160 DcfState::NotifyChannelSwitching (Time duration, uint16_t toChannel)
161 {
162  DoNotifyChannelSwitching (duration, toChannel);
163 }
164 void
165 DcfState::NotifyChannelSensing (void)
166 {
167  DoNotifyChannelSensing ();
168 }
169 
170 
171 /***************************************************************
172  * Listener for Nav events. Forwards to DcfManager
173  ***************************************************************/
174 
176 {
177 public:
179  : m_dcf (dcf)
180  {
181  }
182  virtual ~LowDcfListener ()
183  {
184  }
185  virtual void NavStart (Time duration)
186  {
187  m_dcf->NotifyNavStartNow (duration);
188  }
189  virtual void NavReset (Time duration)
190  {
191  m_dcf->NotifyNavResetNow (duration);
192  }
193  virtual void AckTimeoutStart (Time duration)
194  {
195  m_dcf->NotifyAckTimeoutStartNow (duration);
196  }
197  virtual void AckTimeoutReset ()
198  {
199  m_dcf->NotifyAckTimeoutResetNow ();
200  }
201  virtual void CtsTimeoutStart (Time duration)
202  {
203  m_dcf->NotifyCtsTimeoutStartNow (duration);
204  }
205  virtual void CtsTimeoutReset ()
206  {
207  m_dcf->NotifyCtsTimeoutResetNow ();
208  }
209 private:
210  ns3::DcfManager *m_dcf;
211 };
212 
213 /***************************************************************
214  * Listener for PHY events. Forwards to DcfManager
215  ***************************************************************/
216 
218 {
219 public:
221  : m_dcf (dcf)
222  {
223  }
224  virtual ~PhyListener ()
225  {
226  }
227  virtual void NotifyRxStart (Time duration)
228  {
229  m_dcf->NotifyRxStartNow (duration);
230  }
231  virtual void NotifyRxEndOk (void)
232  {
233  m_dcf->NotifyRxEndOkNow ();
234  }
235  virtual void NotifyRxEndError (void)
236  {
237  m_dcf->NotifyRxEndErrorNow ();
238  }
239  virtual void NotifyTxStart (Time duration)
240  {
241  m_dcf->NotifyTxStartNow (duration);
242  }
243  virtual void NotifyMaybeCcaBusyStart (Time duration)
244  {
245  m_dcf->NotifyMaybeCcaBusyStartNow (duration);
246  }
247  virtual void NotifySwitchingStart (Time duration, uint16_t toChannel)
248  {
249  m_dcf->NotifySwitchingStartNow (duration, toChannel);
250  }
251  virtual void NotifySensingStart (Time duration)
252  {
253  m_dcf->NotifySensingStartNow (duration);
254  }
255 private:
256  ns3::DcfManager *m_dcf;
257 };
258 
259 /****************************************************************
260  * Implement the DCF manager of all DCF state holders
261  ****************************************************************/
262 
263 DcfManager::DcfManager ()
264  : m_lastAckTimeoutEnd (MicroSeconds (0)),
265  m_lastCtsTimeoutEnd (MicroSeconds (0)),
266  m_lastNavStart (MicroSeconds (0)),
267  m_lastNavDuration (MicroSeconds (0)),
268  m_lastRxStart (MicroSeconds (0)),
269  m_lastRxDuration (MicroSeconds (0)),
270  m_lastRxReceivedOk (true),
271  m_lastRxEnd (MicroSeconds (0)),
272  m_lastTxStart (MicroSeconds (0)),
273  m_lastTxDuration (MicroSeconds (0)),
274  m_lastBusyStart (MicroSeconds (0)),
275  m_lastBusyDuration (MicroSeconds (0)),
276  m_lastSwitchingStart (MicroSeconds (0)),
277  m_lastSensingStart (MicroSeconds (0)),
278  m_lastSwitchingDuration (MicroSeconds (0)),
279  m_lastSensingDuration (MicroSeconds (0)),
280  m_rxing (false),
281  m_slotTimeUs (0),
282  m_sifs (Seconds (0.0)),
283  m_phyListener (0),
284  m_lowListener (0)
285 {
286  NS_LOG_FUNCTION (this);
287 }
288 
289 DcfManager::~DcfManager ()
290 {
291  delete m_phyListener;
292  delete m_lowListener;
293  m_phyListener = 0;
294  m_lowListener = 0;
295 }
296 
297 void
298 DcfManager::SetupPhyListener (Ptr<WifiPhy> phy)
299 {
300  NS_LOG_FUNCTION (this << phy);
301  m_phyListener = new PhyListener (this);
302  phy->RegisterListener (m_phyListener);
303 }
304 void
305 DcfManager::SetupLowListener (Ptr<MacLow> low)
306 {
307  NS_LOG_FUNCTION (this << low);
308  m_lowListener = new LowDcfListener (this);
309  low->RegisterDcfListener (m_lowListener);
310 }
311 
312 void
314 {
315  NS_LOG_FUNCTION (this << slotTime);
316  m_slotTimeUs = slotTime.GetMicroSeconds ();
317 }
318 void
320 {
321  NS_LOG_FUNCTION (this << sifs);
322  m_sifs = sifs;
323 }
324 void
326 {
327  NS_LOG_FUNCTION (this << eifsNoDifs);
328  m_eifsNoDifs = eifsNoDifs;
329 }
330 Time
332 {
333  NS_LOG_FUNCTION (this);
334  return m_eifsNoDifs;
335 }
336 
337 void
339 {
340  NS_LOG_FUNCTION (this << dcf);
341  m_states.push_back (dcf);
342 }
343 
344 Time
345 DcfManager::MostRecent (Time a, Time b) const
346 {
347  NS_LOG_FUNCTION (this << a << b);
348  return Max (a, b);
349 }
350 Time
351 DcfManager::MostRecent (Time a, Time b, Time c) const
352 {
353  NS_LOG_FUNCTION (this << a << b << c);
354  Time retval;
355  retval = Max (a, b);
356  retval = Max (retval, c);
357  return retval;
358 }
359 Time
360 DcfManager::MostRecent (Time a, Time b, Time c, Time d) const
361 {
362  NS_LOG_FUNCTION (this << a << b << c << d);
363  Time e = Max (a, b);
364  Time f = Max (c, d);
365  Time retval = Max (e, f);
366  return retval;
367 }
368 Time
369 DcfManager::MostRecent (Time a, Time b, Time c, Time d, Time e, Time f) const
370 {
371  NS_LOG_FUNCTION (this << a << b << c << d << e << f);
372  Time g = Max (a, b);
373  Time h = Max (c, d);
374  Time i = Max (e, f);
375  Time k = Max (g, h);
376  Time retval = Max (k, i);
377  return retval;
378 }
379 
380 Time
381 DcfManager::MostRecent (Time a, Time b, Time c, Time d, Time e, Time f, Time g, Time h) const
382 {
383  NS_LOG_FUNCTION (this << a << b << c << d << e << f << g);
384  Time i = Max (a, b);
385  Time j = Max (c, d);
386  Time k = Max (e, f);
387  Time l = Max (g, h);
388  Time m = Max (i, j);
389  Time n = Max (k, l);
390  Time retval = Max (m, n);
391  return retval;
392 }
393 
394 bool
395 DcfManager::IsBusy (void) const
396 {
397  NS_LOG_FUNCTION (this);
398  // PHY busy
399  if (m_rxing)
400  {
401  return true;
402  }
403  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
404  if (lastTxEnd > Simulator::Now ())
405  {
406  return true;
407  }
408  // NAV busy
409  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
410  if (lastNavEnd > Simulator::Now ())
411  {
412  return true;
413  }
414  return false;
415 }
416 
417 
418 void
420 {
421  NS_LOG_FUNCTION (this << state);
422  UpdateBackoff ();
423  NS_ASSERT (!state->IsAccessRequested ());
424  state->NotifyAccessRequested ();
429  if (state->GetBackoffSlots () == 0
430  && IsBusy ())
431  {
432  MY_DEBUG ("medium is busy: collision");
433  /* someone else has accessed the medium.
434  * generate a backoff.
435  */
436  state->NotifyCollision ();
437  }
438  DoGrantAccess ();
440 }
441 
442 void
444 {
445  NS_LOG_FUNCTION (this);
446  uint32_t k = 0;
447  for (States::const_iterator i = m_states.begin (); i != m_states.end (); k++)
448  {
449  DcfState *state = *i;
450  if (state->IsAccessRequested ()
451  && GetBackoffEndFor (state) <= Simulator::Now () )
452  {
457  MY_DEBUG ("dcf " << k << " needs access. backoff expired. access granted. slots=" << state->GetBackoffSlots ());
458  i++; // go to the next item in the list.
459  k++;
460  std::vector<DcfState *> internalCollisionStates;
461  for (States::const_iterator j = i; j != m_states.end (); j++, k++)
462  {
463  DcfState *otherState = *j;
464  if (otherState->IsAccessRequested ()
465  && GetBackoffEndFor (otherState) <= Simulator::Now ())
466  {
467  MY_DEBUG ("dcf " << k << " needs access. backoff expired. internal collision. slots=" <<
468  otherState->GetBackoffSlots ());
474  internalCollisionStates.push_back (otherState);
475  }
476  }
477 
485  state->NotifyAccessGranted ();
486  for (std::vector<DcfState *>::const_iterator k = internalCollisionStates.begin ();
487  k != internalCollisionStates.end (); k++)
488  {
489  (*k)->NotifyInternalCollision ();
490  }
491  break;
492  }
493  i++;
494  }
495 }
496 
497 void
498 DcfManager::AccessTimeout (void)
499 {
500  NS_LOG_FUNCTION (this);
501  UpdateBackoff ();
502  DoGrantAccess ();
504 }
505 
506 Time
508 {
509  NS_LOG_FUNCTION (this);
510  Time rxAccessStart;
511  if (!m_rxing)
512  {
513  rxAccessStart = m_lastRxEnd + m_sifs;
514  if (!m_lastRxReceivedOk)
515  {
516  rxAccessStart += m_eifsNoDifs;
517  }
518  }
519  else
520  {
521  rxAccessStart = m_lastRxStart + m_lastRxDuration + m_sifs;
522  }
523  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs;
524  Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs;
525  Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs;
526  Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs;
527  Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs;
528  Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + m_sifs;
529  Time sensingAccessStart = m_lastSensingStart + m_lastSensingDuration + m_sifs;
530  Time accessGrantedStart = MostRecent (rxAccessStart,
531  busyAccessStart,
532  txAccessStart,
533  navAccessStart,
534  ackTimeoutAccessStart,
535  ctsTimeoutAccessStart,
536  switchingAccessStart,
537  sensingAccessStart
538  );
539  NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
540  ", rx access start=" << rxAccessStart <<
541  ", busy access start=" << busyAccessStart <<
542  ", tx access start=" << txAccessStart <<
543  ", nav access start=" << navAccessStart);
544  return accessGrantedStart;
545 }
546 
547 Time
548 DcfManager::GetBackoffStartFor (DcfState *state)
549 {
550  NS_LOG_FUNCTION (this << state);
551  Time mostRecentEvent = MostRecent (state->GetBackoffStart (),
552  GetAccessGrantStart () + MicroSeconds (state->GetAifsn () * m_slotTimeUs));
553 
554  return mostRecentEvent;
555 }
556 
557 Time
558 DcfManager::GetBackoffEndFor (DcfState *state)
559 {
560  return GetBackoffStartFor (state) + MicroSeconds (state->GetBackoffSlots () * m_slotTimeUs);
561 }
562 
563 void
564 DcfManager::UpdateBackoff (void)
565 {
566  NS_LOG_FUNCTION (this);
567  uint32_t k = 0;
568  for (States::const_iterator i = m_states.begin (); i != m_states.end (); i++, k++)
569  {
570  DcfState *state = *i;
571 
572  Time backoffStart = GetBackoffStartFor (state);
573  if (backoffStart <= Simulator::Now ())
574  {
575  uint32_t nus = (Simulator::Now () - backoffStart).GetMicroSeconds ();
576  uint32_t nIntSlots = nus / m_slotTimeUs;
577  uint32_t n = std::min (nIntSlots, state->GetBackoffSlots ());
578  MY_DEBUG ("dcf " << k << " dec backoff slots=" << n);
579  Time backoffUpdateBound = backoffStart + MicroSeconds (n * m_slotTimeUs);
580  state->UpdateBackoffSlotsNow (n, backoffUpdateBound);
581  }
582  }
583 }
584 
585 void
587 {
588  NS_LOG_FUNCTION (this);
593  bool accessTimeoutNeeded = false;
594  Time expectedBackoffEnd = Simulator::GetMaximumSimulationTime ();
595  for (States::const_iterator i = m_states.begin (); i != m_states.end (); i++)
596  {
597  DcfState *state = *i;
598  if (state->IsAccessRequested ())
599  {
600  Time tmp = GetBackoffEndFor (state);
601  if (tmp > Simulator::Now ())
602  {
603  accessTimeoutNeeded = true;
604  expectedBackoffEnd = std::min (expectedBackoffEnd, tmp);
605  }
606  }
607  }
608  if (accessTimeoutNeeded)
609  {
610  MY_DEBUG ("expected backoff end=" << expectedBackoffEnd);
611  Time expectedBackoffDelay = expectedBackoffEnd - Simulator::Now ();
612  if (m_accessTimeout.IsRunning ()
613  && Simulator::GetDelayLeft (m_accessTimeout) > expectedBackoffDelay)
614  {
615  m_accessTimeout.Cancel ();
616  }
617  if (m_accessTimeout.IsExpired ())
618  {
619  m_accessTimeout = Simulator::Schedule (expectedBackoffDelay,
620  &DcfManager::AccessTimeout, this);
621  }
622  }
623 }
624 
625 void
627 {
628  NS_LOG_FUNCTION (this << duration);
629  MY_DEBUG ("rx start for=" << duration);
630  UpdateBackoff ();
631  m_lastRxStart = Simulator::Now ();
632  m_lastRxDuration = duration;
633  m_rxing = true;
634 }
635 void
637 {
638  NS_LOG_FUNCTION (this);
639  MY_DEBUG ("rx end ok");
640  m_lastRxEnd = Simulator::Now ();
641  m_lastRxReceivedOk = true;
642  m_rxing = false;
643 }
644 void
646 {
647  NS_LOG_FUNCTION (this);
648  MY_DEBUG ("rx end error");
649  m_lastRxEnd = Simulator::Now ();
650  m_lastRxReceivedOk = false;
651  m_rxing = false;
652 }
653 void
655 {
656  NS_LOG_FUNCTION (this << duration);
657  if (m_rxing)
658  {
659  //this may be caused only if PHY has started to receive a packet
660  //inside SIFS, so, we check that lastRxStart was maximum a SIFS
661  //ago
662  NS_ASSERT (Simulator::Now () - m_lastRxStart <= m_sifs);
663  m_lastRxEnd = Simulator::Now ();
664  m_lastRxDuration = m_lastRxEnd - m_lastRxStart;
665  m_lastRxReceivedOk = true;
666  m_rxing = false;
667  }
668  MY_DEBUG ("tx start for " << duration);
669  UpdateBackoff ();
670  m_lastTxStart = Simulator::Now ();
671  m_lastTxDuration = duration;
672 }
673 void
675 {
676  NS_LOG_FUNCTION (this << duration);
677  MY_DEBUG ("busy start for " << duration);
678  UpdateBackoff ();
679  m_lastBusyStart = Simulator::Now ();
680  m_lastBusyDuration = duration;
681 }
682 
683 
684 void
685 DcfManager::NotifySwitchingStartNow (Time duration, uint16_t toChannel)
686 {
687  NS_LOG_FUNCTION (this << duration);
688  Time now = Simulator::Now ();
689  NS_ASSERT (m_lastTxStart + m_lastTxDuration <= now);
690  NS_ASSERT (m_lastSwitchingStart + m_lastSwitchingDuration <= now);
691 
692  if (m_rxing)
693  {
694  // channel switching during packet reception
695  m_lastRxEnd = Simulator::Now ();
696  m_lastRxDuration = m_lastRxEnd - m_lastRxStart;
697  m_lastRxReceivedOk = true;
698  m_rxing = false;
699  }
700  if (m_lastNavStart + m_lastNavDuration > now)
701  {
702  m_lastNavDuration = now - m_lastNavStart;
703  }
704  if (m_lastBusyStart + m_lastBusyDuration > now)
705  {
706  m_lastBusyDuration = now - m_lastBusyStart;
707  }
708  if (m_lastAckTimeoutEnd > now)
709  {
710  m_lastAckTimeoutEnd = now;
711  }
712  if (m_lastCtsTimeoutEnd > now)
713  {
714  m_lastCtsTimeoutEnd = now;
715  }
716 
717  // Cancel timeout
718  if (m_accessTimeout.IsRunning ())
719  {
720  m_accessTimeout.Cancel ();
721  }
722 
723  // Reset backoffs
724  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
725  {
726  DcfState *state = *i;
727  uint32_t remainingSlots = state->GetBackoffSlots ();
728  if (remainingSlots > 0)
729  {
730  state->UpdateBackoffSlotsNow (remainingSlots, now);
731  NS_ASSERT (state->GetBackoffSlots () == 0);
732  }
733  state->ResetCw ();
734  state->m_accessRequested = false;
735  state->NotifyChannelSwitching (duration, toChannel);
736  }
737 
738  MY_DEBUG ("switching start for " << duration);
739  m_lastSwitchingStart = Simulator::Now ();
740  m_lastSwitchingDuration = duration;
741 
742 }
743 
744 void
745 DcfManager::NotifySensingStartNow (Time duration)
746 {
747  NS_LOG_FUNCTION (this << duration);
748  Time now = Simulator::Now ();
749  NS_ASSERT (m_lastTxStart + m_lastTxDuration <= now);
750  NS_ASSERT (m_lastSensingStart + m_lastSensingDuration <= now);
751 
752  if (m_rxing)
753  {
754  // channel switching during packet reception
755  m_lastRxEnd = Simulator::Now ();
756  m_lastRxDuration = m_lastRxEnd - m_lastRxStart;
757  m_lastRxReceivedOk = true;
758  m_rxing = false;
759  }
760  if (m_lastNavStart + m_lastNavDuration > now)
761  {
762  m_lastNavDuration = now - m_lastNavStart;
763  }
764  if (m_lastBusyStart + m_lastBusyDuration > now)
765  {
766  m_lastBusyDuration = now - m_lastBusyStart;
767  }
768  if (m_lastAckTimeoutEnd > now)
769  {
770  m_lastAckTimeoutEnd = now;
771  }
772  if (m_lastCtsTimeoutEnd > now)
773  {
774  m_lastCtsTimeoutEnd = now;
775  }
776 
777  // Cancel timeout
778  if (m_accessTimeout.IsRunning ())
779  {
780  m_accessTimeout.Cancel ();
781  }
782 
783  // Reset backoffs
784  for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
785  {
786  DcfState *state = *i;
787  uint32_t remainingSlots = state->GetBackoffSlots ();
788  if (remainingSlots > 0)
789  {
790  state->UpdateBackoffSlotsNow (remainingSlots, now);
791  NS_ASSERT (state->GetBackoffSlots () == 0);
792  }
793  state->ResetCw ();
794  state->m_accessRequested = false;
795  state->NotifyChannelSensing ();
796  }
797 
798  MY_DEBUG ("sensing start for " << duration);
799  m_lastSensingStart = Simulator::Now ();
800  m_lastSensingDuration = duration;
801 
802 }
803 
804 void
806 {
807  NS_LOG_FUNCTION (this << duration);
808  MY_DEBUG ("nav reset for=" << duration);
809  UpdateBackoff ();
810  m_lastNavStart = Simulator::Now ();
811  m_lastNavDuration = duration;
812  UpdateBackoff ();
820 }
821 void
823 {
824  NS_LOG_FUNCTION (this << duration);
825  NS_ASSERT (m_lastNavStart < Simulator::Now ());
826  MY_DEBUG ("nav start for=" << duration);
827  UpdateBackoff ();
828  Time newNavEnd = Simulator::Now () + duration;
829  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
830  if (newNavEnd > lastNavEnd)
831  {
832  m_lastNavStart = Simulator::Now ();
833  m_lastNavDuration = duration;
834  }
835 }
836 void
837 DcfManager::NotifyAckTimeoutStartNow (Time duration)
838 {
839  NS_LOG_FUNCTION (this << duration);
840  NS_ASSERT (m_lastAckTimeoutEnd < Simulator::Now ());
841  m_lastAckTimeoutEnd = Simulator::Now () + duration;
842 }
843 void
844 DcfManager::NotifyAckTimeoutResetNow ()
845 {
846  NS_LOG_FUNCTION (this);
847  m_lastAckTimeoutEnd = Simulator::Now ();
849 }
850 void
851 DcfManager::NotifyCtsTimeoutStartNow (Time duration)
852 {
853  NS_LOG_FUNCTION (this << duration);
854  m_lastCtsTimeoutEnd = Simulator::Now () + duration;
855 }
856 void
857 DcfManager::NotifyCtsTimeoutResetNow ()
858 {
859  NS_LOG_FUNCTION (this);
860  m_lastCtsTimeoutEnd = Simulator::Now ();
862 }
863 } // namespace ns3
static Time GetDelayLeft(const EventId &id)
Definition: simulator.cc:188
keep track of time unit.
Definition: nstime.h:149
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual void NavReset(Time duration)
Definition: dcf-manager.cc:189
virtual void NotifySensingStart(Time duration)
Definition: dcf-manager.cc:251
virtual void NotifyRxStart(Time duration)
Definition: dcf-manager.cc:227
void RequestAccess(DcfState *state)
Definition: dcf-manager.cc:419
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_INFO(msg)
Definition: log.h:264
void SetAifsn(uint32_t aifsn)
Definition: dcf-manager.cc:57
bool IsRunning(void) const
Definition: event-id.cc:59
void ResetCw(void)
Definition: dcf-manager.cc:90
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
void Add(DcfState *dcf)
Definition: dcf-manager.cc:338
virtual void NotifyRxEndOk(void)
Definition: dcf-manager.cc:231
void DoGrantAccess(void)
Definition: dcf-manager.cc:443
void NotifyNavResetNow(Time duration)
Definition: dcf-manager.cc:805
void NotifyRxEndOkNow(void)
Definition: dcf-manager.cc:636
int64_t GetMicroSeconds(void) const
Definition: nstime.h:279
Time GetAccessGrantStart(void) const
Definition: dcf-manager.cc:507
receive notifications about phy events.
Definition: wifi-phy.h:44
void NotifyTxStartNow(Time duration)
Definition: dcf-manager.cc:654
virtual void NavStart(Time duration)
Definition: dcf-manager.cc:185
Manage a set of ns3::DcfStateHandle a set of independent ns3::DcfState, each of which represents a si...
Definition: dcf-manager.h:175
keep track of the state needed for a single DCF function.Multiple instances of a DcfState can be regi...
Definition: dcf-manager.h:46
bool IsAccessRequested(void) const
Definition: dcf-manager.cc:133
void StartBackoffNow(uint32_t nSlots)
Definition: dcf-manager.cc:109
virtual void NotifyMaybeCcaBusyStart(Time duration)
Definition: dcf-manager.cc:243
void NotifyRxEndErrorNow(void)
Definition: dcf-manager.cc:645
void SetEifsNoDifs(Time eifsNoDifs)
Definition: dcf-manager.cc:325
listen to NAV eventsThis class is typically connected to an instance of ns3::Dcf and calls to its met...
Definition: mac-low.h:146
static Time Now(void)
Definition: simulator.cc:179
void NotifyMaybeCcaBusyStartNow(Time duration)
Definition: dcf-manager.cc:674
void SetSlot(Time slotTime)
Definition: dcf-manager.cc:313
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
void NotifyNavStartNow(Time duration)
Definition: dcf-manager.cc:822
uint32_t GetCw(void) const
Definition: dcf-manager.cc:118
void NotifyRxStartNow(Time duration)
Definition: dcf-manager.cc:626
virtual void NotifySwitchingStart(Time duration, uint16_t toChannel)
Definition: dcf-manager.cc:247
Time GetEifsNoDifs() const
Definition: dcf-manager.cc:331
void Cancel(void)
Definition: event-id.cc:47
virtual void NotifyRxEndError(void)
Definition: dcf-manager.cc:235
void DoRestartAccessTimeoutIfNeeded(void)
Definition: dcf-manager.cc:586
void UpdateFailedCw(void)
Definition: dcf-manager.cc:95
bool IsExpired(void) const
Definition: event-id.cc:53
void NotifySwitchingStartNow(Time duration, uint16_t toChannel)
Definition: dcf-manager.cc:685
static Time GetMaximumSimulationTime(void)
Definition: simulator.cc:292
Time MicroSeconds(uint64_t us)
create ns3::Time instances in units of microseconds.
Definition: nstime.h:615
void SetSifs(Time sifs)
Definition: dcf-manager.cc:319
virtual void NotifyTxStart(Time duration)
Definition: dcf-manager.cc:239