152 void |
152 void |
153 DcfState::NotifyInternalCollision (void) |
153 DcfState::NotifyInternalCollision (void) |
154 { |
154 { |
155 DoNotifyInternalCollision (); |
155 DoNotifyInternalCollision (); |
156 } |
156 } |
|
157 void |
|
158 DcfState::NotifyChannelSwitching (void) |
|
159 { |
|
160 DoNotifyChannelSwitching (); |
|
161 } |
157 |
162 |
158 |
163 |
159 /*************************************************************** |
164 /*************************************************************** |
160 * Listener for Nav events. Forwards to DcfManager |
165 * Listener for Nav events. Forwards to DcfManager |
161 ***************************************************************/ |
166 ***************************************************************/ |
208 virtual void NotifyTxStart (Time duration) { |
213 virtual void NotifyTxStart (Time duration) { |
209 m_dcf->NotifyTxStartNow (duration); |
214 m_dcf->NotifyTxStartNow (duration); |
210 } |
215 } |
211 virtual void NotifyMaybeCcaBusyStart (Time duration) { |
216 virtual void NotifyMaybeCcaBusyStart (Time duration) { |
212 m_dcf->NotifyMaybeCcaBusyStartNow (duration); |
217 m_dcf->NotifyMaybeCcaBusyStartNow (duration); |
|
218 } |
|
219 virtual void NotifySwitchingStart (Time duration) { |
|
220 m_dcf->NotifySwitchingStartNow (duration); |
213 } |
221 } |
214 private: |
222 private: |
215 ns3::DcfManager *m_dcf; |
223 ns3::DcfManager *m_dcf; |
216 }; |
224 }; |
217 |
225 |
230 m_lastRxEnd (MicroSeconds (0)), |
238 m_lastRxEnd (MicroSeconds (0)), |
231 m_lastTxStart (MicroSeconds (0)), |
239 m_lastTxStart (MicroSeconds (0)), |
232 m_lastTxDuration (MicroSeconds (0)), |
240 m_lastTxDuration (MicroSeconds (0)), |
233 m_lastBusyStart (MicroSeconds (0)), |
241 m_lastBusyStart (MicroSeconds (0)), |
234 m_lastBusyDuration (MicroSeconds (0)), |
242 m_lastBusyDuration (MicroSeconds (0)), |
|
243 m_lastSwitchingStart (MicroSeconds (0)), |
|
244 m_lastSwitchingDuration (MicroSeconds (0)), |
235 m_rxing (false), |
245 m_rxing (false), |
236 m_slotTime (Seconds (0.0)), |
246 m_slotTime (Seconds (0.0)), |
237 m_sifs (Seconds (0.0)), |
247 m_sifs (Seconds (0.0)), |
238 m_phyListener (0), |
248 m_phyListener (0), |
239 m_lowListener (0) |
249 m_lowListener (0) |
314 Time g = Max (a, b); |
324 Time g = Max (a, b); |
315 Time h = Max (c, d); |
325 Time h = Max (c, d); |
316 Time i = Max (e, f); |
326 Time i = Max (e, f); |
317 Time k = Max (g, h); |
327 Time k = Max (g, h); |
318 Time retval = Max (k, i); |
328 Time retval = Max (k, i); |
|
329 return retval; |
|
330 } |
|
331 |
|
332 Time |
|
333 DcfManager::MostRecent (Time a, Time b, Time c, Time d, Time e, Time f, Time g) const |
|
334 { |
|
335 Time h = Max (a, b); |
|
336 Time i = Max (c, d); |
|
337 Time j = Max (e, f); |
|
338 Time k = Max (h, i); |
|
339 Time l = Max (j, g); |
|
340 Time retval = Max (k, l); |
319 return retval; |
341 return retval; |
320 } |
342 } |
321 |
343 |
322 bool |
344 bool |
323 DcfManager::IsBusy (void) const |
345 DcfManager::IsBusy (void) const |
452 Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs; |
474 Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + m_sifs; |
453 Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs; |
475 Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs; |
454 Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs; |
476 Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs; |
455 Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs; |
477 Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs; |
456 Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs; |
478 Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs; |
|
479 Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + m_sifs; |
457 Time accessGrantedStart = MostRecent (rxAccessStart, |
480 Time accessGrantedStart = MostRecent (rxAccessStart, |
458 busyAccessStart, |
481 busyAccessStart, |
459 txAccessStart, |
482 txAccessStart, |
460 navAccessStart, |
483 navAccessStart, |
461 ackTimeoutAccessStart, |
484 ackTimeoutAccessStart, |
462 ctsTimeoutAccessStart |
485 ctsTimeoutAccessStart, |
|
486 switchingAccessStart |
463 ); |
487 ); |
464 NS_LOG_INFO ("access grant start=" << accessGrantedStart << |
488 NS_LOG_INFO ("access grant start=" << accessGrantedStart << |
465 ", rx access start=" << rxAccessStart << |
489 ", rx access start=" << rxAccessStart << |
466 ", busy access start=" << busyAccessStart << |
490 ", busy access start=" << busyAccessStart << |
467 ", tx access start=" << txAccessStart << |
491 ", tx access start=" << txAccessStart << |
594 MY_DEBUG ("busy start for "<<duration); |
618 MY_DEBUG ("busy start for "<<duration); |
595 UpdateBackoff (); |
619 UpdateBackoff (); |
596 m_lastBusyStart = Simulator::Now (); |
620 m_lastBusyStart = Simulator::Now (); |
597 m_lastBusyDuration = duration; |
621 m_lastBusyDuration = duration; |
598 } |
622 } |
|
623 |
|
624 |
|
625 void |
|
626 DcfManager::NotifySwitchingStartNow (Time duration) |
|
627 { |
|
628 Time now = Simulator::Now (); |
|
629 NS_ASSERT (m_lastTxStart + m_lastTxDuration <= now); |
|
630 NS_ASSERT (m_lastSwitchingStart + m_lastSwitchingDuration <= now); |
|
631 |
|
632 if (m_rxing) |
|
633 { |
|
634 // channel switching during packet reception |
|
635 m_lastRxEnd = Simulator::Now (); |
|
636 m_lastRxDuration = m_lastRxEnd - m_lastRxStart; |
|
637 m_lastRxReceivedOk = true; |
|
638 m_rxing = false; |
|
639 } |
|
640 if (m_lastNavStart + m_lastNavDuration > now) |
|
641 { |
|
642 m_lastNavDuration = now - m_lastNavStart; |
|
643 } |
|
644 if (m_lastBusyStart + m_lastBusyDuration > now) |
|
645 { |
|
646 m_lastBusyDuration = now - m_lastBusyStart; |
|
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 { |
|
660 m_accessTimeout.Cancel (); |
|
661 } |
|
662 |
|
663 // Reset backoffs |
|
664 for (States::iterator i = m_states.begin (); i != m_states.end (); i++) |
|
665 { |
|
666 DcfState *state = *i; |
|
667 uint32_t remainingSlots = state->GetBackoffSlots (); |
|
668 if (remainingSlots > 0) |
|
669 { |
|
670 state->UpdateBackoffSlotsNow (remainingSlots, now); |
|
671 NS_ASSERT(state->GetBackoffSlots()==0); |
|
672 } |
|
673 state->ResetCw(); |
|
674 state->m_accessRequested = false; |
|
675 state->NotifyChannelSwitching(); |
|
676 } |
|
677 |
|
678 MY_DEBUG ("switching start for "<<duration); |
|
679 m_lastSwitchingStart = Simulator::Now (); |
|
680 m_lastSwitchingDuration = duration; |
|
681 |
|
682 } |
|
683 |
599 void |
684 void |
600 DcfManager::NotifyNavResetNow (Time duration) |
685 DcfManager::NotifyNavResetNow (Time duration) |
601 { |
686 { |
602 MY_DEBUG ("nav reset for="<<duration); |
687 MY_DEBUG ("nav reset for="<<duration); |
603 UpdateBackoff (); |
688 UpdateBackoff (); |