--- a/src/devices/wifi/dcf-manager.cc Tue Sep 15 00:05:36 2009 -0700
+++ b/src/devices/wifi/dcf-manager.cc Tue Sep 15 10:47:02 2009 +0200
@@ -154,6 +154,11 @@
{
DoNotifyInternalCollision ();
}
+void
+DcfState::NotifyChannelSwitching (void)
+{
+ DoNotifyChannelSwitching ();
+}
/***************************************************************
@@ -211,6 +216,9 @@
virtual void NotifyMaybeCcaBusyStart (Time duration) {
m_dcf->NotifyMaybeCcaBusyStartNow (duration);
}
+ virtual void NotifySwitchingStart (Time duration) {
+ m_dcf->NotifySwitchingStartNow (duration);
+ }
private:
ns3::DcfManager *m_dcf;
};
@@ -232,6 +240,8 @@
m_lastTxDuration (MicroSeconds (0)),
m_lastBusyStart (MicroSeconds (0)),
m_lastBusyDuration (MicroSeconds (0)),
+ m_lastSwitchingStart (MicroSeconds (0)),
+ m_lastSwitchingDuration (MicroSeconds (0)),
m_rxing (false),
m_slotTime (Seconds (0.0)),
m_sifs (Seconds (0.0)),
@@ -319,6 +329,18 @@
return retval;
}
+Time
+DcfManager::MostRecent (Time a, Time b, Time c, Time d, Time e, Time f, Time g) const
+{
+ Time h = Max (a, b);
+ Time i = Max (c, d);
+ Time j = Max (e, f);
+ Time k = Max (h, i);
+ Time l = Max (j, g);
+ Time retval = Max (k, l);
+ return retval;
+}
+
bool
DcfManager::IsBusy (void) const
{
@@ -454,12 +476,14 @@
Time navAccessStart = m_lastNavStart + m_lastNavDuration + m_sifs;
Time ackTimeoutAccessStart = m_lastAckTimeoutEnd + m_sifs;
Time ctsTimeoutAccessStart = m_lastCtsTimeoutEnd + m_sifs;
+ Time switchingAccessStart = m_lastSwitchingStart + m_lastSwitchingDuration + m_sifs;
Time accessGrantedStart = MostRecent (rxAccessStart,
busyAccessStart,
txAccessStart,
navAccessStart,
ackTimeoutAccessStart,
- ctsTimeoutAccessStart
+ ctsTimeoutAccessStart,
+ switchingAccessStart
);
NS_LOG_INFO ("access grant start=" << accessGrantedStart <<
", rx access start=" << rxAccessStart <<
@@ -596,6 +620,67 @@
m_lastBusyStart = Simulator::Now ();
m_lastBusyDuration = duration;
}
+
+
+void
+DcfManager::NotifySwitchingStartNow (Time duration)
+{
+ Time now = Simulator::Now ();
+ NS_ASSERT (m_lastTxStart + m_lastTxDuration <= now);
+ NS_ASSERT (m_lastSwitchingStart + m_lastSwitchingDuration <= now);
+
+ if (m_rxing)
+ {
+ // channel switching during packet reception
+ m_lastRxEnd = Simulator::Now ();
+ m_lastRxDuration = m_lastRxEnd - m_lastRxStart;
+ m_lastRxReceivedOk = true;
+ m_rxing = false;
+ }
+ if (m_lastNavStart + m_lastNavDuration > now)
+ {
+ m_lastNavDuration = now - m_lastNavStart;
+ }
+ if (m_lastBusyStart + m_lastBusyDuration > now)
+ {
+ m_lastBusyDuration = now - m_lastBusyStart;
+ }
+ if (m_lastAckTimeoutEnd > now)
+ {
+ m_lastAckTimeoutEnd = now;
+ }
+ if (m_lastCtsTimeoutEnd > now)
+ {
+ m_lastCtsTimeoutEnd = now;
+ }
+
+ // Cancel timeout
+ if (m_accessTimeout.IsRunning ())
+ {
+ m_accessTimeout.Cancel ();
+ }
+
+ // Reset backoffs
+ for (States::iterator i = m_states.begin (); i != m_states.end (); i++)
+ {
+ DcfState *state = *i;
+ uint32_t remainingSlots = state->GetBackoffSlots ();
+ if (remainingSlots > 0)
+ {
+ state->UpdateBackoffSlotsNow (remainingSlots, now);
+ NS_ASSERT(state->GetBackoffSlots()==0);
+ }
+ state->ResetCw();
+ state->m_accessRequested = false;
+ state->NotifyChannelSwitching();
+ }
+
+ MY_DEBUG ("switching start for "<<duration);
+ m_lastSwitchingStart = Simulator::Now ();
+ m_lastSwitchingDuration = duration;
+
+}
+
void
DcfManager::NotifyNavResetNow (Time duration)
{