158 |
158 |
159 /*************************************************************** |
159 /*************************************************************** |
160 * Listener for Nav events. Forwards to DcfManager |
160 * Listener for Nav events. Forwards to DcfManager |
161 ***************************************************************/ |
161 ***************************************************************/ |
162 |
162 |
163 class LowNavListener : public ns3::MacLowNavListener { |
163 class LowDcfListener : public ns3::MacLowDcfListener { |
164 public: |
164 public: |
165 LowNavListener (ns3::DcfManager *dcf) |
165 LowDcfListener (ns3::DcfManager *dcf) |
166 : m_dcf (dcf) {} |
166 : m_dcf (dcf) {} |
167 virtual ~LowNavListener () {} |
167 virtual ~LowDcfListener () {} |
168 virtual void NavStart (Time duration) { |
168 virtual void NavStart (Time duration) { |
169 m_dcf->NotifyNavStartNow (duration); |
169 m_dcf->NotifyNavStartNow (duration); |
170 } |
170 } |
171 virtual void NavReset (Time duration) { |
171 virtual void NavReset (Time duration) { |
172 m_dcf->NotifyNavResetNow (duration); |
172 m_dcf->NotifyNavResetNow (duration); |
|
173 } |
|
174 virtual void AckTimeoutStart (Time duration) { |
|
175 m_dcf->NotifyAckTimeoutStartNow (duration); |
|
176 } |
|
177 virtual void AckTimeoutReset () { |
|
178 m_dcf->NotifyAckTimeoutResetNow (); |
|
179 } |
|
180 virtual void CtsTimeoutStart (Time duration) { |
|
181 m_dcf->NotifyCtsTimeoutStartNow (duration); |
|
182 } |
|
183 virtual void CtsTimeoutReset () { |
|
184 m_dcf->NotifyCtsTimeoutResetNow (); |
173 } |
185 } |
174 private: |
186 private: |
175 ns3::DcfManager *m_dcf; |
187 ns3::DcfManager *m_dcf; |
176 }; |
188 }; |
177 |
189 |
206 /**************************************************************** |
218 /**************************************************************** |
207 * Implement the DCF manager of all DCF state holders |
219 * Implement the DCF manager of all DCF state holders |
208 ****************************************************************/ |
220 ****************************************************************/ |
209 |
221 |
210 DcfManager::DcfManager () |
222 DcfManager::DcfManager () |
211 : m_lastNavStart (MicroSeconds (0)), |
223 : m_lastAckTimeoutEnd (MicroSeconds (0)), |
|
224 m_lastCtsTimeoutEnd (MicroSeconds (0)), |
|
225 m_lastNavStart (MicroSeconds (0)), |
212 m_lastNavDuration (MicroSeconds (0)), |
226 m_lastNavDuration (MicroSeconds (0)), |
213 m_lastRxStart (MicroSeconds (0)), |
227 m_lastRxStart (MicroSeconds (0)), |
214 m_lastRxDuration (MicroSeconds (0)), |
228 m_lastRxDuration (MicroSeconds (0)), |
215 m_lastRxReceivedOk (true), |
229 m_lastRxReceivedOk (true), |
216 m_lastRxEnd (MicroSeconds (0)), |
230 m_lastRxEnd (MicroSeconds (0)), |
240 phy->RegisterListener (m_phyListener); |
254 phy->RegisterListener (m_phyListener); |
241 } |
255 } |
242 void |
256 void |
243 DcfManager::SetupLowListener (Ptr<MacLow> low) |
257 DcfManager::SetupLowListener (Ptr<MacLow> low) |
244 { |
258 { |
245 m_lowListener = new LowNavListener (this); |
259 m_lowListener = new LowDcfListener (this); |
246 low->RegisterNavListener (m_lowListener); |
260 low->RegisterDcfListener (m_lowListener); |
247 } |
261 } |
248 |
262 |
249 void |
263 void |
250 DcfManager::SetSlot (Time slotTime) |
264 DcfManager::SetSlot (Time slotTime) |
251 { |
265 { |
285 DcfManager::MostRecent (Time a, Time b, Time c, Time d) const |
299 DcfManager::MostRecent (Time a, Time b, Time c, Time d) const |
286 { |
300 { |
287 Time e = Max (a, b); |
301 Time e = Max (a, b); |
288 Time f = Max (c, d); |
302 Time f = Max (c, d); |
289 Time retval = Max (e, f); |
303 Time retval = Max (e, f); |
|
304 return retval; |
|
305 } |
|
306 Time |
|
307 DcfManager::MostRecent (Time a, Time b, Time c, Time d, Time e, Time f) const |
|
308 { |
|
309 Time g = Max (a, b); |
|
310 Time h = Max (c, d); |
|
311 Time i = Max (e, f); |
|
312 Time k = Max (g, h); |
|
313 Time retval = Max (k, i); |
290 return retval; |
314 return retval; |
291 } |
315 } |
292 |
316 |
293 bool |
317 bool |
294 DcfManager::IsBusy (void) const |
318 DcfManager::IsBusy (void) const |
344 uint32_t k = 0; |
368 uint32_t k = 0; |
345 for (States::const_iterator i = m_states.begin (); i != m_states.end (); k++) |
369 for (States::const_iterator i = m_states.begin (); i != m_states.end (); k++) |
346 { |
370 { |
347 DcfState *state = *i; |
371 DcfState *state = *i; |
348 if (state->IsAccessRequested () && |
372 if (state->IsAccessRequested () && |
349 GetBackoffEndFor (state) <= Simulator::Now ()) |
373 GetBackoffEndFor (state).GetTimeStep() <= Simulator::Now ().GetTimeStep ()) |
350 { |
374 { |
351 /** |
375 /** |
352 * This is the first dcf we find with an expired backoff and which |
376 * This is the first dcf we find with an expired backoff and which |
353 * needs access to the medium. i.e., it has data to send. |
377 * needs access to the medium. i.e., it has data to send. |
354 */ |
378 */ |
424 Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs; |
448 Time txAccessStart = m_lastTxStart + m_lastTxDuration + m_sifs; |
425 Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs; |
449 Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs; |
426 Time accessGrantedStart = MostRecent (rxAccessStart, |
450 Time accessGrantedStart = MostRecent (rxAccessStart, |
427 busyAccessStart, |
451 busyAccessStart, |
428 txAccessStart, |
452 txAccessStart, |
429 navAccessStart); |
453 navAccessStart, |
|
454 m_lastAckTimeoutEnd, |
|
455 m_lastCtsTimeoutEnd |
|
456 ); |
430 NS_LOG_INFO ("access grant start=" << accessGrantedStart << |
457 NS_LOG_INFO ("access grant start=" << accessGrantedStart << |
431 ", rx access start=" << rxAccessStart << |
458 ", rx access start=" << rxAccessStart << |
432 ", busy access start=" << busyAccessStart << |
459 ", busy access start=" << busyAccessStart << |
433 ", tx access start=" << txAccessStart << |
460 ", tx access start=" << txAccessStart << |
434 ", nav access start=" << navAccessStart); |
461 ", nav access start=" << navAccessStart); |
484 { |
511 { |
485 DcfState *state = *i; |
512 DcfState *state = *i; |
486 if (state->IsAccessRequested ()) |
513 if (state->IsAccessRequested ()) |
487 { |
514 { |
488 Time tmp = GetBackoffEndFor (state); |
515 Time tmp = GetBackoffEndFor (state); |
489 if (tmp > Simulator::Now ()) |
516 if (tmp.GetTimeStep () > Simulator::Now ().GetTimeStep ()) |
490 { |
517 { |
|
518 //NS_LOG_UNCOND("Now:"<<Simulator::Now ().GetTimeStep ()); |
491 accessTimeoutNeeded = true; |
519 accessTimeoutNeeded = true; |
492 expectedBackoffEnd = std::min (expectedBackoffEnd, tmp); |
520 expectedBackoffEnd = std::min (expectedBackoffEnd, tmp); |
493 } |
521 } |
494 } |
522 } |
495 } |
523 } |
579 { |
607 { |
580 m_lastNavStart = Simulator::Now (); |
608 m_lastNavStart = Simulator::Now (); |
581 m_lastNavDuration = duration; |
609 m_lastNavDuration = duration; |
582 } |
610 } |
583 } |
611 } |
584 |
612 void |
|
613 DcfManager::NotifyAckTimeoutStartNow (Time duration) |
|
614 { |
|
615 m_lastAckTimeoutEnd = Simulator::Now () + duration; |
|
616 } |
|
617 void |
|
618 DcfManager::NotifyAckTimeoutResetNow () |
|
619 { |
|
620 m_lastAckTimeoutEnd = Simulator::Now (); |
|
621 DoRestartAccessTimeoutIfNeeded (); |
|
622 } |
|
623 void |
|
624 DcfManager::NotifyCtsTimeoutStartNow (Time duration) |
|
625 { |
|
626 m_lastCtsTimeoutEnd = Simulator::Now () + duration; |
|
627 } |
|
628 void |
|
629 DcfManager::NotifyCtsTimeoutResetNow () |
|
630 { |
|
631 m_lastCtsTimeoutEnd = Simulator::Now (); |
|
632 DoRestartAccessTimeoutIfNeeded (); |
|
633 } |
585 } // namespace ns3 |
634 } // namespace ns3 |