replace Dcf with DcfManager
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Mon, 19 Nov 2007 16:53:05 +0100
changeset 2146 40ad60ac9912
parent 2145 8f3c8ef34b0a
child 2147 b6243a53c93f
replace Dcf with DcfManager
src/devices/wifi/dca-txop.cc
src/devices/wifi/dca-txop.h
src/devices/wifi/dcf.cc
src/devices/wifi/dcf.h
src/devices/wifi/mac-low.cc
src/devices/wifi/mac-low.h
src/devices/wifi/wifi-net-device.cc
src/devices/wifi/wifi-net-device.h
src/devices/wifi/wscript
--- a/src/devices/wifi/dca-txop.cc	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/dca-txop.cc	Mon Nov 19 16:53:05 2007 +0100
@@ -21,84 +21,45 @@
 #include "ns3/assert.h"
 #include "ns3/packet.h"
 #include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/net-device.h"
+#include "ns3/node.h"
 
 #include "dca-txop.h"
-#include "dcf.h"
+#include "dcf-manager.h"
 #include "mac-parameters.h"
 #include "mac-low.h"
 #include "wifi-mac-queue.h"
 #include "mac-tx-middle.h"
 #include "wifi-phy.h"
+#include "random-stream.h"
 
 NS_LOG_COMPONENT_DEFINE ("DcaTxop");
 
+#define MY_DEBUG(x) \
+  NS_LOG_DEBUG (Simulator::Now () << " " << m_low->GetDevice ()->GetNode ()->GetId () << ":" << \
+                m_low->GetDevice ()->GetIfIndex () << " " << x)
+
 
 namespace ns3 {
 
-class DcaTxop::NavListener : public ns3::MacLowNavListener {
+class DcaTxop::Dcf : public DcfState
+{
 public:
-  NavListener (ns3::Dcf *dcf)
-    : m_dcf (dcf) {}
-  virtual ~NavListener () {}
-  virtual void NavStart (Time now, Time duration) {
-    m_dcf->NotifyNavStart (now, duration);
-  }
-  virtual void NavContinue (Time now, Time duration) {
-    m_dcf->NotifyNavContinue (now, duration);
-  }
-  virtual void NavReset (Time now, Time duration) {
-    m_dcf->NotifyNavReset (now, duration);
-  }
+  Dcf (DcaTxop *txop)
+    : m_txop (txop)
+  {}
 private:
-  ns3::Dcf *m_dcf;
-};
-class DcaTxop::PhyListener : public ns3::WifiPhyListener {
-public:
-  PhyListener (ns3::Dcf *dcf)
-    : m_dcf (dcf) {}
-  virtual ~PhyListener () {}
-  virtual void NotifyRxStart (Time duration) {
-    m_dcf->NotifyRxStartNow (duration);
-  }
-  virtual void NotifyRxEndOk (void) {
-    m_dcf->NotifyRxEndOkNow ();
-  }
-  virtual void NotifyRxEndError (void) {
-    m_dcf->NotifyRxEndErrorNow ();
+  virtual void DoNotifyAccessGranted (void) {
+    m_txop->NotifyAccessGranted ();
   }
-  virtual void NotifyTxStart (Time duration) {
-    m_dcf->NotifyTxStartNow (duration);
-  }
-  virtual void NotifyCcaBusyStart (Time duration) {
-    m_dcf->NotifyCcaBusyStartNow (duration);
+  virtual void DoNotifyInternalCollision (void) {
+    m_txop->NotifyInternalCollision ();
   }
-private:
-  ns3::Dcf *m_dcf;
-};
-
-
-class DcaTxop::AccessListener : public DcfAccessListener {
-public:
-  AccessListener (DcaTxop *txop)
-    : DcfAccessListener (),
-      m_txop (txop) {}
-
-  virtual ~AccessListener () {}
-
-  virtual void AccessGrantedNow (void)
-  {
-    m_txop->AccessGrantedNow ();
-  }
-  virtual bool AccessNeeded (void)
-  {
-    return m_txop->AccessNeeded ();
-  }
-  virtual bool AccessingAndWillNotify (void)
-  {
-    return m_txop->AccessingAndWillNotify ();
+  virtual void DoNotifyCollision (void) {
+    m_txop->NotifyCollision ();
   }
 
-private:
   DcaTxop *m_txop;
 };
 
@@ -133,31 +94,28 @@
   DcaTxop *m_txop;
 };
 
-DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw)
-  : m_accessListener (0),
+DcaTxop::DcaTxop (uint32_t minCw, uint32_t maxCw, uint32_t aifsn, DcfManager *manager)
+  : m_manager (manager),
     m_hasCurrent (false),
     m_ssrc (0),
     m_slrc (0)
+
 {
   m_transmissionListener = new DcaTxop::TransmissionListener (this);
-  m_dcf = new Dcf (minCw, maxCw);
-  m_accessListener = new DcaTxop::AccessListener (this);
-  m_dcf->RegisterAccessListener (m_accessListener);
+  m_dcf = new DcaTxop::Dcf (this);
+  m_dcf->SetCwBounds (minCw, maxCw);
+  m_dcf->SetAifsn (aifsn);
+  m_manager->Add (m_dcf);
   m_queue = new WifiMacQueue ();
+  m_rng = new RealRandomStream ();
 }
 
 DcaTxop::~DcaTxop ()
 {
-  delete m_accessListener;
   delete m_transmissionListener;
-  delete m_navListener;
-  delete m_phyListener;
   delete m_queue;
   delete m_dcf;
-  m_accessListener = 0;
   m_transmissionListener = 0;
-  m_navListener = 0;
-  m_phyListener = 0;
   m_queue = 0;
   m_dcf = 0;
 }
@@ -166,20 +124,11 @@
 DcaTxop::SetLow (MacLow *low)
 {
   m_low = low;
-  m_navListener = new DcaTxop::NavListener (m_dcf);
-  m_low->RegisterNavListener (m_navListener);
-}
-void
-DcaTxop::SetPhy (Ptr<WifiPhy> phy)
-{
-  m_phyListener = new DcaTxop::PhyListener (m_dcf);
-  phy->RegisterListener (m_phyListener);
 }
 void 
 DcaTxop::SetParameters (MacParameters *parameters)
 {
   m_parameters = parameters;
-  m_dcf->SetParameters (parameters);
 }
 void 
 DcaTxop::SetTxMiddle (MacTxMiddle *txMiddle)
@@ -198,21 +147,6 @@
 }
 
 void 
-DcaTxop::SetDifs (Time difs)
-{
-  m_dcf->SetDifs (difs);
-}
-void 
-DcaTxop::SetEifs (Time eifs)
-{
-  m_dcf->SetEifs (eifs);
-}
-void 
-DcaTxop::SetCwBounds (uint32_t min, uint32_t max)
-{
-  m_dcf->SetCwBounds (min, max);
-}
-void 
 DcaTxop::SetMaxQueueSize (uint32_t size)
 {
   m_queue->SetMaxSize (size);
@@ -227,7 +161,29 @@
 DcaTxop::Queue (Packet packet, WifiMacHeader const &hdr)
 {
   m_queue->Enqueue (packet, hdr);
-  m_dcf->RequestAccess ();
+  StartAccessIfNeeded ();
+}
+
+void
+DcaTxop::RestartAccessIfNeeded (void)
+{
+  if ((m_hasCurrent ||
+       !m_queue->IsEmpty ()) &&
+      !m_dcf->IsAccessRequested ())
+    {
+      m_manager->RequestAccess (m_dcf);
+    }
+}
+
+void
+DcaTxop::StartAccessIfNeeded (void)
+{
+  if (!m_hasCurrent &&
+      !m_queue->IsEmpty () &&
+      !m_dcf->IsAccessRequested ())
+    {
+      m_manager->RequestAccess (m_dcf);
+    }
 }
 
 
@@ -350,42 +306,18 @@
 }
 
 bool 
-DcaTxop::AccessingAndWillNotify (void)
-{
-  if (m_hasCurrent) 
-    {
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-
-bool 
-DcaTxop::AccessNeeded (void)
+DcaTxop::NeedsAccess (void) const
 {
-  if (!m_queue->IsEmpty () ||
-      m_hasCurrent) 
-    {
-      NS_LOG_DEBUG ("access needed here");
-      return true;
-    } 
-  else 
-    {
-      NS_LOG_DEBUG ("no access needed here");
-      return false;
-    }
+  return !m_queue->IsEmpty () || m_hasCurrent;
 }
-
-void
-DcaTxop::AccessGrantedNow (void)
+void 
+DcaTxop::NotifyAccessGranted (void)
 {
   if (!m_hasCurrent) 
     {
       if (m_queue->IsEmpty ()) 
         {
-          NS_LOG_DEBUG ("queue empty");
+          MY_DEBUG ("queue empty");
           return;
         }
       bool found;
@@ -400,7 +332,7 @@
       m_ssrc = 0;
       m_slrc = 0;
       m_fragmentNumber = 0;
-      NS_LOG_DEBUG ("dequeued size="<<m_currentPacket.GetSize ()<<
+      MY_DEBUG ("dequeued size="<<m_currentPacket.GetSize ()<<
                     ", to="<<m_currentHdr.GetAddr1 ()<<
                     ", seq="<<m_currentHdr.GetSequenceControl ()); 
     }
@@ -417,8 +349,8 @@
                                  m_transmissionListener);
       m_hasCurrent = false;
       m_dcf->ResetCw ();
-      m_dcf->StartBackoff ();
-      NS_LOG_DEBUG ("tx broadcast");
+      m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+      MY_DEBUG ("tx broadcast");
     } 
   else 
     {
@@ -431,12 +363,12 @@
           Packet fragment = GetFragmentPacket (&hdr);
           if (IsLastFragment ()) 
             {
-              NS_LOG_DEBUG ("fragmenting last fragment size="<<fragment.GetSize ());
+              MY_DEBUG ("fragmenting last fragment size="<<fragment.GetSize ());
               params.DisableNextData ();
             } 
           else 
             {
-              NS_LOG_DEBUG ("fragmenting size="<<fragment.GetSize ());
+              MY_DEBUG ("fragmenting size="<<fragment.GetSize ());
               params.EnableNextData (GetNextFragmentSize ());
             }
           Low ()->StartTransmission (fragment, &hdr, params, 
@@ -447,12 +379,12 @@
           if (NeedRts ()) 
             {
               params.EnableRts ();
-              NS_LOG_DEBUG ("tx unicast rts");
+              MY_DEBUG ("tx unicast rts");
             } 
           else 
             {
               params.DisableRts ();
-              NS_LOG_DEBUG ("tx unicast");
+              MY_DEBUG ("tx unicast");
             }
           params.DisableNextData ();
           // We need to make a copy in case we need to 
@@ -468,31 +400,43 @@
     }
 }
 
+void 
+DcaTxop::NotifyInternalCollision (void)
+{
+  NotifyCollision ();
+}
+void 
+DcaTxop::NotifyCollision (void)
+{
+  MY_DEBUG ("collision");
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
+}
 
 void 
 DcaTxop::GotCts (double snr, WifiMode txMode)
 {
-  NS_LOG_DEBUG ("got cts");
+  MY_DEBUG ("got cts");
   m_ssrc = 0;
 }
 void 
 DcaTxop::MissedCts (void)
 {
-  NS_LOG_DEBUG ("missed cts");
+  MY_DEBUG ("missed cts");
   m_ssrc++;
   m_ctstimeoutTrace (m_ssrc);
   if (m_ssrc > Parameters ()->GetMaxSsrc ()) 
     {
       // to reset the dcf.
+      m_hasCurrent = false;
       m_dcf->ResetCw ();
-      m_dcf->StartBackoff ();
-      m_hasCurrent = false;
     } 
   else 
     {
       m_dcf->UpdateFailedCw ();
-      m_dcf->StartBackoff ();
     }
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
 }
 void 
 DcaTxop::GotAck (double snr, WifiMode txMode)
@@ -501,7 +445,7 @@
   if (!NeedFragmentation () ||
       IsLastFragment ()) 
     {
-      NS_LOG_DEBUG ("got ack. tx done.");
+      MY_DEBUG ("got ack. tx done.");
       if (!m_txOkCallback.IsNull ()) 
         {
           m_txOkCallback (m_currentHdr);
@@ -512,25 +456,25 @@
        */
       m_hasCurrent = false;
       m_dcf->ResetCw ();
-      m_dcf->StartBackoff ();
+      m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+      RestartAccessIfNeeded ();
     } 
   else 
     {
-      NS_LOG_DEBUG ("got ack. tx not done, size="<<m_currentPacket.GetSize ());
+      MY_DEBUG ("got ack. tx not done, size="<<m_currentPacket.GetSize ());
     }
 }
 void 
 DcaTxop::MissedAck (void)
 {
-  NS_LOG_DEBUG ("missed ack");
+  MY_DEBUG ("missed ack");
   m_slrc++;
   m_acktimeoutTrace (m_slrc);
   if (m_slrc > Parameters ()->GetMaxSlrc ()) 
     {
       // to reset the dcf.    
+      m_hasCurrent = false;
       m_dcf->ResetCw ();
-      m_dcf->StartBackoff ();
-      m_hasCurrent = false;
     } 
   else 
     {
@@ -540,14 +484,14 @@
           m_txFailedCallback (m_currentHdr);
         }
       m_dcf->UpdateFailedCw ();
-      m_dcf->StartBackoff ();
     }
-  
+  m_dcf->StartBackoffNow (m_rng->GetNext (0, m_dcf->GetCw ()));
+  RestartAccessIfNeeded ();
 }
 void 
 DcaTxop::StartNext (void)
 {
-  NS_LOG_DEBUG ("start next packet fragment");
+  MY_DEBUG ("start next packet fragment");
   /* this callback is used only for fragments. */
   NextFragment ();
   WifiMacHeader hdr;
@@ -570,7 +514,7 @@
 void
 DcaTxop::Cancel (void)
 {
-  NS_LOG_DEBUG ("transmission cancelled");
+  MY_DEBUG ("transmission cancelled");
   /**
    * This happens in only one case: in an AP, you have two DcaTxop:
    *   - one is used exclusively for beacons and has a high priority.
@@ -582,7 +526,7 @@
    * queue gets a tx oportunity during this backoff, it will trigger
    * a call to this Cancel function.
    *
-   * Since we are already doing a backoff, so we will get access to
+   * Since we are already doing a backoff, we will get access to
    * the medium when we can, we have nothing to do here. We just 
    * ignore the cancel event and wait until we are given again a 
    * tx oportunity.
--- a/src/devices/wifi/dca-txop.h	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/dca-txop.h	Mon Nov 19 16:53:05 2007 +0100
@@ -31,18 +31,19 @@
 
 namespace ns3 {
 
-class Dcf;
+class DcfState;
+class DcfManager;
 class WifiMacQueue;
 class MacLow;
-class WifiPhy;
 class MacParameters;
 class MacTxMiddle;
+class RandomStream;
 
 /**
  * \brief handle packet fragmentation and retransmissions.
  *
  * This class implements the packet fragmentation and 
- * retransmission policy. It uses the ns3::MacLow and ns3::Dcf
+ * retransmission policy. It uses the ns3::MacLow and ns3::DcfManager
  * helper classes to respectively send packets and decide when 
  * to send them. Packets are stored in a ns3::WifiMacQueue until
  * they can be sent.
@@ -65,17 +66,19 @@
   typedef Callback <void, WifiMacHeader const&> TxFailed;
 
   /**
-   * \param minCw forwarded to ns3::Dcf constructor
-   * \param maxCw forwarded to ns3::Dcf constructor
+   * \param minCw forwarded to ns3::DcfState constructor
+   * \param maxCw forwarded to ns3::DcfState constructor
+   * \param aifsn forwarded to ns3::DcfState constructor
+   * \param manager the manager which will be responsible
+   *        for controlling access to this DcaTxop.
    *
    * Initialized from \valueref{WifiMaxSsrc}, \valueref{WifiMaxSlrc},
    * \valueref{WifiRtsCtsThreshold}, and, \valueref{WifiFragmentationThreshold}.
    */
-  DcaTxop (uint32_t minCw, uint32_t maxCw);
+  DcaTxop (uint32_t cwMin, uint32_t cwMax, uint32_t aifsn, DcfManager *manager);
   ~DcaTxop ();
 
   void SetLow (MacLow *low);
-  void SetPhy (Ptr<WifiPhy> phy);
   void SetParameters (MacParameters *parameters);
   void SetTxMiddle (MacTxMiddle *txMiddle);
   /**
@@ -89,9 +92,6 @@
    */
   void SetTxFailedCallback (TxFailed callback);
 
-  void SetDifs (Time difs);
-  void SetEifs (Time eifs);
-  void SetCwBounds (uint32_t min, uint32_t max);
   void SetMaxQueueSize (uint32_t size);
   void SetMaxQueueDelay (Time delay);
 
@@ -103,21 +103,24 @@
    * can be sent safely.
    */
   void Queue (Packet packet, WifiMacHeader const &hdr);
+
 private:
-  class AccessListener;
   class TransmissionListener;
   class NavListener;
   class PhyListener;
-  friend class AccessListener;
+  class Dcf;
+  friend class Dcf;
   friend class TransmissionListener;
 
   MacLow *Low (void);
   MacParameters *Parameters (void);
 
+  /* dcf notifications forwarded here */
+  bool NeedsAccess (void) const;
+  void NotifyAccessGranted (void);
+  void NotifyInternalCollision (void);
+  void NotifyCollision (void);
   /* event handlers */
-  void AccessGrantedNow (void);
-  bool AccessingAndWillNotify (void);
-  bool AccessNeeded (void);
   void GotCts (double snr, WifiMode txMode);
   void MissedCts (void);
   void GotAck (double snr, WifiMode txMode);
@@ -125,6 +128,8 @@
   void StartNext (void);
   void Cancel (void);
 
+  void RestartAccessIfNeeded (void);
+  void StartAccessIfNeeded (void);
   bool NeedRts (void);
   bool NeedFragmentation (void);
   uint32_t GetNFragments (void);
@@ -136,6 +141,7 @@
   Packet GetFragmentPacket (WifiMacHeader *hdr);
 
   Dcf *m_dcf;
+  DcfManager *m_manager;
   TxOk m_txOkCallback;
   TxFailed m_txFailedCallback;
   WifiMacQueue *m_queue;
@@ -143,11 +149,10 @@
   MacLow *m_low;
   MacParameters *m_parameters;
   TransmissionListener *m_transmissionListener;
-  AccessListener *m_accessListener;
-  NavListener *m_navListener;
-  PhyListener *m_phyListener;
+  RandomStream *m_rng;
   
 
+  bool m_accessOngoing;
   Packet m_currentPacket;
   bool m_hasCurrent;
   WifiMacHeader m_currentHdr;
--- a/src/devices/wifi/dcf.cc	Mon Nov 19 16:20:30 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,904 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as 
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include <math.h>
-
-#include "ns3/simulator.h"
-#include "ns3/assert.h"
-#include "ns3/log.h"
-
-#include "dcf.h"
-#include "random-stream.h"
-#include "mac-parameters.h"
-
-
-NS_LOG_COMPONENT_DEFINE ("Dcf");
-
-namespace ns3 {
-
-
-
-
-DcfAccessListener::DcfAccessListener ()
-{}
-DcfAccessListener::~DcfAccessListener ()
-{}
-
-
-
-Dcf::Dcf (uint32_t min, uint32_t max)
-  : m_accessTimerEvent (),
-    m_cwMin (min),
-    m_cwMax (max),
-    m_backoffStart (MicroSeconds (0)),
-    m_backoffLeft (MicroSeconds (0)),
-    m_lastNavStart (MicroSeconds (0)),
-    m_lastNavDuration (MicroSeconds (0)),
-    m_lastRxStart (MicroSeconds (0)),
-    m_lastRxDuration (MicroSeconds (0)),
-    m_lastRxReceivedOk (true),
-    m_lastRxEnd (MicroSeconds (0)),
-    m_lastTxStart (MicroSeconds (0)),
-    m_lastTxDuration (MicroSeconds (0)),
-    m_lastBusyStart (MicroSeconds (0)),
-    m_lastBusyDuration (MicroSeconds (0)),
-    m_rxing (false)
-{
-  ResetCw ();
-  m_rng = new RealRandomStream ();
-}
-
-Dcf::~Dcf ()
-{
-  delete m_rng;
-}
-
-void 
-Dcf::ResetRngForTest (RandomStream *stream)
-{
-  delete m_rng;
-  m_rng = stream;
-}
-void
-Dcf::SetParameters (MacParameters const*parameters)
-{
-  m_parameters = parameters;
-}
-
-void 
-Dcf::SetDifs (Time difs)
-{
-  m_difs = difs;
-}
-void 
-Dcf::SetEifs (Time eifs)
-{
-  m_eifs = eifs;
-}
-void 
-Dcf::SetCwBounds (uint32_t min, uint32_t max)
-{
-  m_cwMin = min;
-  m_cwMax = max;
-  m_cw = min;
-}
-void 
-Dcf::RegisterAccessListener (DcfAccessListener *listener)
-{
-  m_listener = listener;
-}
-
-
-/***************************************************************
- *     public API.
- ***************************************************************/ 
-
-void 
-Dcf::RequestAccess (void)
-{
-  Time delayUntilAccessGranted = GetDelayUntilAccessGranted (Now ());
-  if (m_listener->AccessingAndWillNotify ()) 
-    {
-      /* don't do anything. We will start a backoff and maybe
-       * a timer when the txop notifies us of the end-of-access.
-       */
-      NS_LOG_DEBUG ("accessing. will be notified.");
-    } 
-  else if (m_accessTimerEvent.IsRunning ()) 
-    {
-      /* we don't need to do anything because we have an access
-       * timer which will expire soon.
-       */
-      NS_LOG_DEBUG ("access timer running. will be notified");
-    } 
-  else if (IsBackoffNotCompleted (Now ()) && m_accessTimerEvent.IsExpired ()) 
-    {
-      /* start timer for ongoing backoff.
-       */
-      NS_LOG_DEBUG ("request access X delayed for="<<delayUntilAccessGranted);
-      m_accessTimerEvent = Simulator::Schedule (delayUntilAccessGranted, 
-                                                &Dcf::AccessTimeout, this);
-    } 
-  else if (IsPhyBusy () || IsNavBusy ()) 
-    {
-      /* someone else has accessed the medium.
-       * generate a backoff, start timer.
-       */
-      StartBackoff ();
-    } 
-  else if (delayUntilAccessGranted.IsStrictlyPositive ()) 
-    {
-      /* medium is IDLE, we have no backoff running but we 
-       * need to wait a bit before accessing the medium.
-       */
-      NS_LOG_DEBUG ("request access Y delayed for="<< delayUntilAccessGranted);
-      NS_ASSERT (m_accessTimerEvent.IsExpired ());
-      m_accessTimerEvent = Simulator::Schedule (delayUntilAccessGranted, 
-                                                &Dcf::AccessTimeout, this);
-    } 
-  else 
-    {
-      /* we can access the medium now.
-       */
-      NS_LOG_DEBUG ("access granted immediatly");
-      m_listener->AccessGrantedNow ();
-    }
-}
-
-/***************************************************************
- *     Timeout method. Notifies when Access is Granted.
- ***************************************************************/ 
-
-
-void 
-Dcf::AccessTimeout ()
-{
-  UpdateBackoff (Now ());
-  if (m_backoffLeft.IsZero ()) 
-    {
-      NS_LOG_DEBUG ("timeout access granted");
-      m_listener->AccessGrantedNow ();
-    } 
-  else 
-    {
-      Time delayUntilAccessGranted  = GetDelayUntilAccessGranted (Now ());
-      NS_LOG_DEBUG ("timeout access delayed for "<< delayUntilAccessGranted);
-      m_accessTimerEvent = Simulator::Schedule (delayUntilAccessGranted, 
-                                                &Dcf::AccessTimeout, this);
-    }
-}
-
-
-/***************************************************************
- *     Random trivial helper methods.
- ***************************************************************/ 
-
-Time
-Dcf::PickBackoffDelay (void)
-{
-  uint32_t pickedCw = m_rng->GetNext (0, m_cw);
-  NS_LOG_DEBUG ("cw="<<GetCwMin ()<<
-         "<"<<m_cw<<"<"<<GetCwMax ()<<
-         ", picked="<<pickedCw); 
-  Time delay = Scalar (pickedCw) * m_parameters->GetSlotTime ();
-  return delay;
-}
-void
-Dcf::ResetCw (void)
-{
-  m_cw = GetCwMin ();
-}
-void
-Dcf::UpdateFailedCw (void)
-{
-  uint32_t cw = m_cw;
-  cw *= 2;
-  if (cw > GetCwMax ()) 
-    {
-      cw = GetCwMax ();
-    }
-  m_cw = cw;
-}
-
-Time
-Dcf::MostRecent (Time a, Time b) const
-{
-  return Max (a, b);
-}
-Time
-Dcf::MostRecent (Time a, Time b, Time c) const
-{
-  Time retval;
-  retval = Max (a, b);
-  retval = Max (retval, c);
-  return retval;
-}
-Time
-Dcf::MostRecent (Time a, Time b, Time c, Time d) const
-{
-  Time e = Max (a, b);
-  Time f = Max (c, d);
-  Time retval = Max (e, f);
-  return retval;
-}
-
-Time
-Dcf::GetDifs (void) const
-{
-  return m_difs;
-}
-Time
-Dcf::GetEifs (void) const
-{
-  return m_eifs;
-}
-uint32_t 
-Dcf::GetCwMin (void) const
-{
-  return m_cwMin;
-}
-uint32_t 
-Dcf::GetCwMax (void) const
-{
-  return m_cwMax;
-}
-
-/***************************************************************
- *     Complicated timekeeping backoff methods.
- ***************************************************************/ 
-
-bool 
-Dcf::IsPhyBusy (void) const
-{
-  if (m_rxing) 
-    {
-      return true;
-    }
-  Time lastTxEnd = m_lastTxStart + m_lastTxDuration;
-  if (lastTxEnd > Simulator::Now ()) 
-    {
-      return true;
-    }
-  return false;
-}
-
-bool 
-Dcf::IsNavBusy (void) const
-{
-  Time lastNavEnd = m_lastNavStart + m_lastNavDuration;
-  if (lastNavEnd > Simulator::Now ())
-    {
-      return true;
-    }
-  return false;
-}
-
-void
-Dcf::StartBackoff (void)
-{
-  Time backoffStart = Now ();
-  Time backoffDuration = PickBackoffDelay ();
-  m_backoffTrace (backoffDuration);
-  NS_ASSERT (m_backoffStart <= backoffStart);
-  m_backoffStart = backoffStart;
-  m_backoffLeft = backoffDuration;
-  if (m_listener->AccessNeeded () && m_accessTimerEvent.IsExpired ()) 
-    {
-      Time delayUntilAccessGranted  = GetDelayUntilAccessGranted (Now ());
-      if (delayUntilAccessGranted.IsStrictlyPositive ()) 
-        {
-          NS_LOG_DEBUG ("start at "<<backoffStart<<", for "<<backoffDuration);
-          m_accessTimerEvent = Simulator::Schedule (delayUntilAccessGranted,
-                                                    &Dcf::AccessTimeout, this);
-        } 
-      else 
-        {
-          NS_LOG_DEBUG ("access granted now");
-          m_listener->AccessGrantedNow ();
-        }
-    } 
-  else 
-    {
-      if (m_accessTimerEvent.IsRunning ()) 
-        {
-          NS_LOG_DEBUG ("no access needed because timer running.");
-        } 
-      if (!m_listener->AccessNeeded ()) 
-        {
-          NS_LOG_DEBUG ("no access needed.");
-        }
-      NS_LOG_DEBUG ("no access needed for now.");
-    }
-}
-Time
-Dcf::GetAccessGrantedStart (void) const
-{
-  /* This method evaluates the time where access to the
-   * medium is allowed. The return value could be 
-   * somewhere in the past or in the future.
-   */
-  Time rxAccessStart;
-  if (m_lastRxEnd >= m_lastRxStart) 
-    {
-      if (m_lastRxReceivedOk) 
-        {
-          rxAccessStart = m_lastRxEnd + GetDifs ();
-        } 
-      else
-        {
-          rxAccessStart = m_lastRxEnd + GetEifs ();
-        }
-    } 
-  else 
-    {
-      rxAccessStart = m_lastRxStart + m_lastRxDuration + GetDifs ();
-    }
-  Time busyAccessStart = m_lastBusyStart + m_lastBusyDuration + GetDifs ();
-  Time txAccessStart = m_lastTxStart + m_lastTxDuration + GetDifs ();
-  Time navAccessStart = m_lastNavStart + m_lastNavDuration + GetDifs ();
-  Time accessGrantedStart = MostRecent (rxAccessStart, 
-                                        busyAccessStart,
-                                        txAccessStart, 
-                                        navAccessStart);
-  NS_LOG_DEBUG ("access granted start=" << accessGrantedStart);
-  return accessGrantedStart;
-}
-
-bool
-Dcf::IsBackoffNotCompleted (Time now)
-{
-  UpdateBackoff (now);
-  if (m_backoffLeft.IsStrictlyPositive ()) 
-    {
-      return true;
-    } 
-  else 
-    {
-      return false;
-    }
-}
-
-
-Time
-Dcf::GetDelayUntilAccessGranted (Time now)
-{
-  Time deltaTo = GetAccessGrantedStart () - now;
-  Time retval = Max (deltaTo, Seconds (0));
-  UpdateBackoff (now);
-  retval += m_backoffLeft;
-  return retval;
-}
-void
-Dcf::UpdateBackoff (Time time)
-{
-  if (m_backoffLeft.IsZero ()) 
-    {
-      return;
-    }
-  
-  //NS_LOG_DEBUG ("time: %f, backoffstart: %f\n", time, m_backoffStart);
-  NS_ASSERT (time >= m_backoffStart);
-
-  Time mostRecentEvent = MostRecent (m_backoffStart,
-                                     GetAccessGrantedStart ());
-  if (mostRecentEvent < time) 
-    {
-      Time newBackoffLeft = m_backoffLeft - (time - mostRecentEvent);
-      m_backoffLeft = Max (newBackoffLeft, Seconds (0)); 
-      m_backoffStart = time;
-    }
-  NS_LOG_DEBUG ("backoff at="<<m_backoffStart<<", left="<< m_backoffLeft);
-}
-
-/***************************************************************
- *     Notification methods.
- ***************************************************************/ 
-void
-Dcf::NotifyNavReset (Time navStart, Time duration)
-{
-  NS_LOG_DEBUG ("nav reset at="<<navStart<<", for="<<duration);
-  m_lastNavStart = navStart;
-  m_lastNavDuration = duration;
-  Time navEnd = navStart + duration;
-  Time newDelayUntilAccessGranted = GetDelayUntilAccessGranted (navEnd);
-  NS_ASSERT (newDelayUntilAccessGranted.IsStrictlyPositive ());
-  /* This is quite unfortunate but we need to cancel the access timer
-   * because this nav reset might have brought the time of
-   * possible access closer to us than expected.
-   */
-  if (m_accessTimerEvent.IsRunning ()) 
-    {
-      m_accessTimerEvent.Cancel ();
-      m_accessTimerEvent = Simulator::Schedule (newDelayUntilAccessGranted,
-                                                &Dcf::AccessTimeout, this);
-    }
-}
-void
-Dcf::NotifyNavStart (Time navStart, Time duration)
-{
-  NS_ASSERT (m_lastNavStart < navStart);
-  NS_LOG_DEBUG ("nav start at="<<navStart<<", for="<<duration);
-  UpdateBackoff (navStart);
-  m_lastNavStart = navStart;
-  m_lastNavDuration = duration;
-}
-void
-Dcf::NotifyNavContinue (Time navStart, Time duration)
-{
-  NotifyNavStart (navStart, duration);
-}
-
-void 
-Dcf::NotifyRxStartNow (Time duration)
-{
-  Time now = Now ();
-  NS_LOG_DEBUG ("rx start at="<<now<<", for="<<duration);
-  UpdateBackoff (now);
-  m_lastRxStart = now;
-  m_lastRxDuration = duration;
-  m_rxing = true;
-}
-void 
-Dcf::NotifyRxEndOkNow (void)
-{
-  Time now = Now ();
-  NS_LOG_DEBUG ("rx end ok at="<<now);
-  m_lastRxEnd = now;
-  m_lastRxReceivedOk = true;
-  m_rxing = false;
-}
-void 
-Dcf::NotifyRxEndErrorNow (void)
-{
-  Time now = Now ();
-  NS_LOG_DEBUG ("rx end error at=");
-  m_lastRxEnd = now;
-  m_lastRxReceivedOk = false;
-  m_rxing = false;
-}
-void 
-Dcf::NotifyTxStartNow (Time duration)
-{
-  Time now = Now ();
-  NS_LOG_DEBUG ("tx start at="<<now<<" for "<<duration);
-  UpdateBackoff (now);
-  m_lastTxStart = now;
-  m_lastTxDuration = duration;
-}
-
-void 
-Dcf::NotifyCcaBusyStartNow (Time duration)
-{
-  Time now = Now ();
-  NS_LOG_DEBUG ("busy start at="<<now<<" for "<<duration);
-  UpdateBackoff (now);
-  m_lastBusyStart = now;
-  m_lastBusyDuration = duration;
-}
-
-} // namespace ns3
-
-#ifdef RUN_SELF_TESTS
-#include "ns3/test.h"
-#include <list>
-
-namespace ns3 {
-
-class DcfTest : public Test {
-public:
-  DcfTest ();
-  virtual bool RunTests (void);
-
-  // callback from DcfListener
-  void AccessGrantedNow (void);
-  bool AccessNeeded (void);
-  bool AccessingAndWillNotify (void);
-private:
-
-  void AddRxOkEvt (uint64_t at, uint64_t duration);
-  void AddRxErrorEvt (uint64_t at, uint64_t duration);
-  void AddTxEvt (uint64_t at, uint64_t duration);
-  void AddNavReset (uint64_t at, uint64_t start, uint64_t duration);
-  void AddNavStart (uint64_t at, uint64_t start, uint64_t duration);
-  void AddNavContinue (uint64_t at, uint64_t start, uint64_t duration);
-  void AddAccessRequest (uint64_t time);
-  void AddAccessError (uint64_t time);
-  void AddAccessErrorButOk (uint64_t time);
-  void AddAccessOk (uint64_t time);
-
-  void ExpectAccessGranted (uint64_t time);
-  
-  // callback to forward to DCF
-  void AccessError (uint64_t time);
-  void AccessErrorButOk (uint64_t time);
-  void AccessOk (uint64_t time);
-
-  void StartTest (void);
-  void EndTest (void);
-
-  Dcf *m_dcf;
-  MacParameters *m_parameters;
-  class TestAccessListener *m_listener;
-  std::list<uint64_t> m_accessGrantedExpected;
-  bool m_failed;
-};
-
-class TestAccessListener : public DcfAccessListener {
-public:
-  TestAccessListener (DcfTest *test)
-    : m_test (test) {}
-  virtual ~TestAccessListener () {}
-  virtual void AccessGrantedNow (void) {
-    m_test->AccessGrantedNow ();
-  }
-  virtual bool AccessNeeded (void) {
-    return m_test->AccessNeeded ();
-  }
-  virtual bool AccessingAndWillNotify (void) {
-    return m_test->AccessingAndWillNotify ();
-  }
-private:
-  DcfTest *m_test;
-};
-
-
-
-DcfTest::DcfTest ()
-  : Test ("Dcf") {}
-
-void 
-DcfTest::AccessGrantedNow (void)
-{
-  if (m_accessGrantedExpected.empty ()) 
-    {
-      Failure () << "DCF "
-                 << "Failure: unexpected access granted at="<<Simulator::Now ()
-                 << std::endl;
-      m_failed = true;
-      return;
-    }
-  uint64_t expected = m_accessGrantedExpected.front ();
-  uint64_t actual = Simulator::Now ().GetMicroSeconds ();
-  if (expected != actual) 
-    {
-      Failure () << "DCF "
-                 << "Failure: access granted at=" << Simulator::Now ()
-                 << ", expected at="<<expected<<"us"
-                 << std::endl;
-      m_failed = true;
-      return;
-    }
-  m_accessGrantedExpected.erase (m_accessGrantedExpected.begin ());
-}
-bool 
-DcfTest::AccessNeeded (void)
-{
-  return true;
-}
-bool 
-DcfTest::AccessingAndWillNotify (void)
-{
-  return false;
-}
-
-void 
-DcfTest::AddRxOkEvt (uint64_t at, uint64_t duration)
-{
-  Simulator::Schedule (MicroSeconds (at) - Now (), 
-                       &Dcf::NotifyRxStartNow, m_dcf, 
-                       MicroSeconds (duration));
-  Simulator::Schedule (MicroSeconds (at+duration) - Now (), 
-                       &Dcf::NotifyRxEndOkNow, m_dcf);
-}
-void 
-DcfTest::AddRxErrorEvt (uint64_t at, uint64_t duration)
-{
-  Simulator::Schedule (MicroSeconds (at) - Now (), 
-                       &Dcf::NotifyRxStartNow, m_dcf, 
-                       MicroSeconds (duration));
-  Simulator::Schedule (MicroSeconds (at+duration) - Now (), 
-                       &Dcf::NotifyRxEndErrorNow, m_dcf);
-}
-void 
-DcfTest::AddTxEvt (uint64_t at, uint64_t duration)
-{
-  Simulator::Schedule (MicroSeconds (at) - Now (), 
-                       &Dcf::NotifyTxStartNow, m_dcf, 
-                       MicroSeconds (duration));
-}
-void 
-DcfTest::AddNavReset (uint64_t at, uint64_t start, uint64_t duration)
-{
-  Simulator::Schedule (MicroSeconds (at) - Now (), 
-                       &Dcf::NotifyNavReset, m_dcf, 
-                       MicroSeconds (start), 
-                       MicroSeconds (duration));
-}
-void 
-DcfTest::AddNavStart (uint64_t at, uint64_t start, uint64_t duration)
-{
-  Simulator::Schedule (MicroSeconds (at) - Now (), 
-                       &Dcf::NotifyNavStart, m_dcf, 
-                       MicroSeconds (start), MicroSeconds (duration));
-}
-void 
-DcfTest::AddNavContinue (uint64_t at, uint64_t start, uint64_t duration)
-{
-  Simulator::Schedule (MicroSeconds (at) - Now (), 
-                       &Dcf::NotifyNavContinue, m_dcf, 
-                       MicroSeconds (start), 
-                       MicroSeconds (duration));
-}
-void 
-DcfTest::AddAccessRequest (uint64_t time)
-{
-  Simulator::Schedule (MicroSeconds (time) - Now (), 
-                       &Dcf::RequestAccess, m_dcf);
-}
-void 
-DcfTest::AddAccessError (uint64_t time)
-{
-  Simulator::Schedule (MicroSeconds (time) - Now (), 
-                       &DcfTest::AccessError, this, 
-                       time);
-}
-void 
-DcfTest::AddAccessErrorButOk (uint64_t time)
-{
-  Simulator::Schedule (MicroSeconds (time) - Now (), 
-                       &DcfTest::AccessErrorButOk, this, 
-                       time);
-}
-void 
-DcfTest::AddAccessOk (uint64_t time)
-{
-  Simulator::Schedule (MicroSeconds (time) - Now (), 
-                       &DcfTest::AccessOk, this, 
-                       time);
-}
-
-void 
-DcfTest::AccessError (uint64_t time)
-{
-  m_dcf->UpdateFailedCw ();
-  m_dcf->StartBackoff ();
-}
-void 
-DcfTest::AccessErrorButOk (uint64_t time)
-{
-  m_dcf->ResetCw ();
-  m_dcf->StartBackoff ();
-}
-void 
-DcfTest::AccessOk (uint64_t time)
-{
-  m_dcf->ResetCw ();
-  m_dcf->StartBackoff ();
-}
-
-void 
-DcfTest::ExpectAccessGranted (uint64_t time)
-{
-  m_accessGrantedExpected.push_back (time);
-}
-
-void 
-DcfTest::StartTest (void)
-{
-  m_dcf = new Dcf (8, 64);
-  TestRandomStream *stream = new TestRandomStream ();
-  stream->AddNext (1);
-  stream->AddNext (1);
-  stream->AddNext (1);
-  stream->AddNext (1);
-  stream->AddNext (1);
-  stream->AddNext (1);
-  m_dcf->ResetRngForTest (stream);
-  m_parameters = new MacParameters ();
-  m_listener = new TestAccessListener (this);
-  m_dcf->SetParameters (m_parameters);
-  m_dcf->RegisterAccessListener (m_listener);  
-
-  m_parameters->SetSlotTime (MicroSeconds (1));
-  m_dcf->SetDifs (MicroSeconds (3));
-  m_dcf->SetEifs (MicroSeconds (4));
-}
-void 
-DcfTest::EndTest (void)
-{
-  if (!m_accessGrantedExpected.empty ()) 
-    {
-      Failure () << "DCF: access not granted as expected"
-                 << std::endl;
-    }
-  m_accessGrantedExpected.erase (m_accessGrantedExpected.begin (),
-                                 m_accessGrantedExpected.end ());
-  Simulator::Destroy ();
-  delete m_dcf;
-  delete m_parameters;
-  delete m_listener;
-}
-
-bool
-DcfTest::RunTests (void)
-{
-  m_failed = false;
-
-  //                    32        37
-  //                     | rx ok   |
-  // | idle   |  rx ok | nav busy      | difs  | backoff |
-  // 0       10       30              40      43        44
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 2+8);
-  AddRxOkEvt (32, 5);
-  AddAccessRequest (15);
-  AddAccessRequest (16);
-  AddAccessRequest (20);
-  ExpectAccessGranted (44);
-  Simulator::Run ();
-  EndTest ();
-
-  //                    32           39
-  //                     | rx ok      |
-  // | idle   |  rx ok | nav busy  |  | difs  | backoff |
-  // 0       10       30          37         42        43
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 2+5);
-  AddRxOkEvt (32, 7);
-  AddAccessRequest (15);
-  AddAccessRequest (16);
-  AddAccessRequest (20);
-  ExpectAccessGranted (43);
-  Simulator::Run ();
-  EndTest ();
-
-  StartTest ();
-  AddAccessRequest (10);
-  ExpectAccessGranted (10);
-  Simulator::Run ();
-  EndTest ();
-
-  //                    32        39
-  //                     | rx ok   |
-  // | idle   |  rx ok | nav busy    | difs  |
-  // 0       10       30            40      43
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 2+8);
-  AddRxOkEvt (32, 7);
-  AddAccessRequest (40);
-  ExpectAccessGranted (43);
-  Simulator::Run ();
-  EndTest ();
-
-  //                    32        39
-  //                     | rx ok   |
-  // | idle   |  rx ok | nav busy    | difs  |
-  // 0       10       30            40      43
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 2+8);
-  AddRxOkEvt (32, 7);
-  AddAccessRequest (41);
-  ExpectAccessGranted (43);
-  Simulator::Run ();
-  EndTest ();
-
-  //                    32        39
-  //                     | rx ok   |
-  // | idle   |  rx ok | nav busy    | difs  |
-  // 0       10       30            40      43
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 2+8);
-  AddRxOkEvt (32, 7);
-  AddAccessRequest (43);
-  ExpectAccessGranted (43);
-  Simulator::Run ();
-  EndTest ();
-
-  //
-  // | idle   |  rx error | idle   | rx ok  | difs |
-  // 0       10          30       31       38     41
-  //
-  StartTest ();
-  AddRxErrorEvt (10, 20);
-  AddRxOkEvt (31, 7);
-  AddAccessRequest (39);
-  ExpectAccessGranted (41);
-  Simulator::Run ();
-  EndTest ();
-
-  //
-  // | idle   |  rx error | idle   | rx error  | eifs |
-  // 0       10          30       31          38     42
-  //
-  StartTest ();
-  AddRxErrorEvt (10, 20);
-  AddRxErrorEvt (31, 7);
-  AddAccessRequest (39);
-  ExpectAccessGranted (42);
-  Simulator::Run ();
-  EndTest ();
-
-
-  //
-  //                  30               45
-  //                   | nav busy       |
-  // | idle   |  rx ok | idle   | rx ok | difs | backoff |
-  // 0       10       30       35      45     48        49
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 200);
-  AddRxOkEvt (35, 10);
-  AddNavReset (45, 45, 0);
-  AddAccessRequest (32);
-  ExpectAccessGranted (49);
-  Simulator::Run ();
-  EndTest ();
-
-  //
-  //                  30               45
-  //                   | nav busy       |
-  // | idle   |  rx ok | idle   | rx ok | 
-  // 0       10       30       35      45 
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 200);
-  AddRxOkEvt (35, 10);
-  AddNavReset (45, 45, 0);
-  Simulator::Run ();
-  EndTest ();
-
-  //
-  //                  30               45
-  //                   | nav busy       |
-  // | idle   |  rx ok | idle   | rx ok | difs |
-  // 0       10       30       35      45     48
-  //
-  StartTest ();
-  AddRxOkEvt (10, 20);
-  AddNavStart (30, 30, 200);
-  AddRxOkEvt (35, 10);
-  AddNavReset (45, 45, 0);
-  AddAccessRequest (49);
-  ExpectAccessGranted (49);
-  Simulator::Run ();
-  EndTest ();
-
-
-  return !m_failed;
-}
-
-static DcfTest gDcfTest;
-
-} // namespace ns3
-
-
-#endif /* RUN_SELF_TESTS */
--- a/src/devices/wifi/dcf.h	Mon Nov 19 16:20:30 2007 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005 INRIA
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as 
- * published by the Free Software Foundation;
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef DCF_H
-#define DCF_H
-
-#include <stdint.h>
-#include "ns3/event-id.h"
-#include "ns3/uv-trace-source.h"
-#include "ns3/callback-trace-source.h"
-#include "ns3/nstime.h"
-
-namespace ns3 {
-
-class RandomStream;
-class MacParameters;
-
-/**
- * \brief listen to DCF events
- *
- * If you want to call methods from the ns3::Dcf class,
- * you need to provide an instance of this class
- * to be notified of the DCF evens.
- */
-class DcfAccessListener {
-public:
-  DcfAccessListener ();
-  virtual ~DcfAccessListener ();
-
-  /**
-   * Tell the listener than it can start
-   * accessing the medium right now.
-   */
-  virtual void AccessGrantedNow (void) = 0;
-  /**
-   * ask the listener if there are candidates 
-   * who need access to the medium.
-   *
-   * \return true if access to the medium is 
-   *         needed, false otherwise.
-   */
-  virtual bool AccessNeeded (void) = 0;
-  /**
-   * ask the listener if it is currently
-   * performing an access which was granted 
-   * earlier to him and if it will notify
-   * the Dcf when the access is complete.
-   *
-   * \return true if the listener expects to call
-   *         Dcf::RequestAccess later, false otherwise.
-   */
-  virtual bool AccessingAndWillNotify (void) = 0;
-};
-
-/**
- * \brief the Distributed Coordination Function
- *
- * This class implements the DCF as described in IEEE 802.11-1999
- * section 9.2, p72.
- *
- * This implementation is based on the technique described in
- * <i>Scalable simulation of large-scale wireless networks with
- * bounded inaccuracies.</i>, by Z. Ji, J. Zhou, M. Takai, and R. Bagrodia. 
- */
-class Dcf
-{
-public:
-  /**
-   * \param minCw the minimum value for CW
-   * \param maxCw the maximum value for CW
-   */
-  Dcf (uint32_t minCw, uint32_t maxCw);
-  ~Dcf ();
-
-  /**
-   * \param parameters
-   *
-   * Must be invoked after construction to configure
-   * a set of parameters.
-   */
-  void SetParameters (const MacParameters *parameters);
-  /**
-   * \param difs the difs
-   *
-   * Must be invoked after construction.
-   */
-  void SetDifs (Time difs);
-  /**
-   * \param eifs the eifs
-   *
-   * Must be invoked after construction.
-   */
-  void SetEifs (Time eifs);
-  /**
-   * \param minCw the minimum value for CW
-   * \param maxCw the maximum value for CW
-   *
-   * Reset the cw bounds and CW to minCW.
-   */
-  void SetCwBounds (uint32_t minCw, uint32_t maxCw);
-  /**
-   * \param listener the listener
-   *
-   * This listener is notified of DCF-specific events
-   * when they happen. You _must_ register a listener
-   * before calling Dcf::RequestAccess.
-   */
-  void RegisterAccessListener (DcfAccessListener *listener);
-
-  /**
-   * Request access to the medium. This method will grant
-   * access by calling the DcfAccessListener::AccessGrantedNow
-   * method
-   */
-  void RequestAccess (void);
-
-  /**
-   * Reset the CW to CWmin
-   * This method is typically invoked after a successfully
-   * transmission or after the maximum number of retries has
-   * been reached.
-   */
-  void ResetCw (void);
-  /**
-   * Update the CW to a new value. This method is typically
-   * invoked after a failed transmission before calling
-   * Dcf::StartBackoff.
-   */
-  void UpdateFailedCw (void);
-  /**
-   * Start a backoff now by picking a backoff duration
-   * in the [0, cw] interval.
-   */
-  void StartBackoff (void);
-
-  /**
-   * \param duration expected duration of reception
-   *
-   * Notify the DCF that a packet reception started 
-   * for the expected duration.
-   */
-  void NotifyRxStartNow (Time duration);
-  /**
-   * Notify the DCF that a packet reception was just
-   * completed successfully.
-   */
-  void NotifyRxEndOkNow (void);
-  /**
-   * Notify the DCF that a packet reception was just
-   * completed unsuccessfully.
-   */
-  void NotifyRxEndErrorNow (void);
-  /**
-   * \param duration expected duration of transmission
-   *
-   * Notify the DCF that a packet transmission was
-   * just started and is expected to last for the specified
-   * duration.
-   */
-  void NotifyTxStartNow (Time duration);
-  /**
-   * \param duration expected duration of cca busy period
-   *
-   * Notify the DCF that a CCA busy period has just started.
-   */
-  void NotifyCcaBusyStartNow (Time duration);
-  /**
-   * \param now the time at which a NAV starts
-   * \param duration the value of the received NAV.
-   */
-  void NotifyNavReset (Time now, Time duration);
-  /**
-   * \param now the time at which a NAV starts
-   * \param duration the value of the received NAV.
-   */
-  void NotifyNavStart (Time now, Time duration);
-  /**
-   * \param now the time at which a NAV starts
-   * \param duration the value of the received NAV.
-   */
-  void NotifyNavContinue (Time now, Time duration);
-
-  /**
-   * \param stream a random stream
-   *
-   * This method is used for testing only to force a predictable
-   * set of random numbers to be used.
-   */
-  void ResetRngForTest (RandomStream *stream);
-private:
-  void AccessTimeout (void);
-
-  /* trivial helpers */
-  Time PickBackoffDelay (void);
-  Time MostRecent (Time a, Time b) const;
-  Time MostRecent (Time a, Time b, Time c) const;
-  Time MostRecent (Time a, Time b, Time c, Time d) const;
-  Time GetDifs (void) const;
-  Time GetEifs (void) const;
-  uint32_t GetCwMin (void) const;
-  uint32_t GetCwMax (void) const;
-
-  /* time calculation helpers */
-  bool IsPhyBusy (void) const;
-  bool IsNavBusy (void) const;
-  bool IsBackoffNotCompleted (Time now);
-  Time GetDelayUntilAccessGranted (Time now);
-  Time GetAccessGrantedStart (void) const;
-  void UpdateBackoff (Time time);
-
-  EventId m_accessTimerEvent;
-
-  RandomStream *m_rng;
-  const MacParameters *m_parameters;
-  DcfAccessListener *m_listener;
-  Time m_difs;
-  Time m_eifs;
-  uint32_t m_cwMin;
-  uint32_t m_cwMax;
-
-  UVTraceSource<uint32_t> m_cw;
-  Time m_backoffStart;
-  Time m_backoffLeft;
-  Time m_lastNavStart;
-  Time m_lastNavDuration;
-  Time m_lastRxStart;
-  Time m_lastRxDuration;
-  bool m_lastRxReceivedOk;
-  Time m_lastRxEnd;
-  Time m_lastTxStart;
-  Time m_lastTxDuration;
-  Time m_lastBusyStart;
-  Time m_lastBusyDuration;
-  bool m_rxing;
-  bool m_sleeping;
-  /* "80211-dcf-backoff"
-   * param1: backoff Duration
-   * reports the start of a backoff
-   */
-  CallbackTraceSource<Time> m_backoffTrace;
-};
-
-} // namespace ns3
-
-#endif /* DCF_H */
--- a/src/devices/wifi/mac-low.cc	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/mac-low.cc	Mon Nov 19 16:53:05 2007 +0100
@@ -35,7 +35,8 @@
 NS_LOG_COMPONENT_DEFINE ("MacLow");
 
 #define MY_DEBUG(x) \
-  NS_LOG_DEBUG (Simulator::Now () << " " << m_device->GetNode ()->GetId () << " " << x)
+  NS_LOG_DEBUG (Simulator::Now () << " " << m_device->GetNode ()->GetId () << ":" << \
+                m_device->GetIfIndex () << " " << x)
 
 namespace ns3 {
 
@@ -305,6 +306,11 @@
 {
   m_device = device;
 }
+Ptr<NetDevice> 
+MacLow::GetDevice (void) const
+{
+  return m_device;
+}
 void
 MacLow::SetPhy (Ptr<WifiPhy> phy)
 {
@@ -405,12 +411,17 @@
   WifiMacHeader hdr;
   packet.RemoveHeader (hdr);
   
-  bool isPrevNavZero = IsNavZero (Simulator::Now ());
+  bool isPrevNavZero = IsNavZero ();
   MY_DEBUG ("duration/id=" << hdr.GetDuration ());
-  NotifyNav (Simulator::Now (), &hdr);
+  NotifyNav (hdr, txMode, preamble);
   if (hdr.IsRts ()) 
     {
-      /* XXX see section 9.9.2.2.1 802.11e/D12.1 */
+      /* see section 9.2.5.7 802.11-1999
+       * A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS 
+       * period if the NAV at the STA receiving the RTS frame indicates that the medium is 
+       * idle. If the NAV at the STA receiving the RTS indicates the medium is not idle, 
+       * that STA shall not respond to the RTS frame.
+       */
       if (isPrevNavZero &&
           hdr.GetAddr1 () == m_device->GetSelfAddress ()) 
         {
@@ -656,56 +667,82 @@
   return txTime;
 }
 
+void
+MacLow::NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble)
+{
+  NS_ASSERT (m_lastNavStart <= Simulator::Now ());
+  Time duration = hdr.GetDuration ();
+
+  if (hdr.IsCfpoll () &&
+      hdr.GetAddr2 () == m_device->GetBssid ()) 
+    {
+      // see section 9.3.2.2 802.11-1999
+      DoNavResetNow (duration);
+      return;
+    }
+  // XXX Note that we should also handle CF_END specially here
+  // but we don't for now because we do not generate them.
+  else if (hdr.GetAddr1 () == m_device->GetSelfAddress ())
+    {
+      // see section 9.2.5.4 802.11-1999
+      bool navUpdated = DoNavStartNow (duration);
+      if (hdr.IsRts () && navUpdated)
+        {
+          /**
+           * A STA that used information from an RTS frame as the most recent basis to update its NAV setting 
+           * is permitted to reset its NAV if no PHY-RXSTART.indication is detected from the PHY during a 
+           * period with a duration of (2 * aSIFSTime) + (CTS_Time) + (2 * aSlotTime) starting at the 
+           * PHY-RXEND.indication corresponding to the detection of the RTS frame. The “CTS_Time” shall 
+           * be calculated using the length of the CTS frame and the data rate at which the RTS frame 
+           * used for the most recent NAV update was received.
+           */
+          WifiMacHeader cts;
+          cts.SetType (WIFI_MAC_CTL_CTS);
+          Time navCounterResetCtsMissedDelay = 
+            m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) +
+            Scalar (2) * m_parameters->GetSifs () + Scalar (2) * m_parameters->GetSlotTime ();
+          m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay,
+                                                            &MacLow::NavCounterResetCtsMissed, this,
+                                                            Simulator::Now ());
+        }
+    }
+}
 
 void
-MacLow::NotifyNav (Time at, WifiMacHeader const *hdr)
+MacLow::NavCounterResetCtsMissed (Time rtsEndRxTime)
+{
+  if (m_phy->GetLastRxStartTime () > rtsEndRxTime)
+    {
+      DoNavResetNow (Seconds (0.0));
+    }
+}
+
+void
+MacLow::DoNavResetNow (Time duration)
 {
-  /* XXX
-   * We might need to do something special for the
-   * subtle case of RTS/CTS. I don't know what.
-   *
-   * See section 9.9.2.2.1, 802.11e/D12.1
-   */
-  NS_ASSERT (m_lastNavStart < at);
-  Time oldNavStart = m_lastNavStart;
-  Time oldNavEnd = oldNavStart + m_lastNavDuration;
-  Time newNavStart = at;
-  Time duration = hdr->GetDuration ();
-
-  if (hdr->IsCfpoll () &&
-      hdr->GetAddr2 () == m_device->GetBssid ()) 
+  for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++) 
     {
-      m_lastNavStart = newNavStart;
+      (*i)->NavReset (duration);
+    }
+  m_lastNavStart = Simulator::Now ();
+  m_lastNavStart = duration;
+}
+bool
+MacLow::DoNavStartNow (Time duration)
+{
+  for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++) 
+    {
+      (*i)->NavStart (duration);
+    }
+  Time newNavEnd = Simulator::Now () + duration;
+  Time oldNavEnd = m_lastNavStart + m_lastNavDuration;
+  if (newNavEnd > oldNavEnd)
+    {
+      m_lastNavStart = Simulator::Now ();
       m_lastNavDuration = duration;
-      for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++) 
-        {
-          // XXX !!!!!!!
-          (*i)->NavReset (newNavStart, duration);
-        }
-      return;
+      return true;
     }
-
-  if (oldNavEnd > newNavStart) 
-    {
-      Time newNavEnd = newNavStart + duration;
-      /* The two NAVs overlap */
-      if (newNavEnd > oldNavEnd) 
-        {
-          for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++) 
-            {
-              (*i)->NavContinue (newNavStart, duration);
-            }
-        }
-    } 
-  else 
-    {
-      m_lastNavStart = newNavStart;
-      m_lastNavDuration = duration;
-      for (NavListenersCI i = m_navListeners.begin (); i != m_navListeners.end (); i++) 
-        {
-          (*i)->NavStart (newNavStart, duration);
-        }
-    }
+  return false;
 }
 
 void
@@ -719,11 +756,13 @@
             ", duration=" << hdr->GetDuration () <<
             ", seq=0x"<< std::hex << m_currentHdr.GetSequenceControl () << std::dec);
   m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0);
-  /* Note that it is really important to notify the NAV 
-   * thing _after_ forwarding the packet to the PHY.
+  /* 
+   * We have to notify the NAV of transmitted packets because of the 802.11e
+   * requirement from section 9.9.1.4 that each EDCAF update its NAV from the
+   * transmission of any other EDCAF within the same QSTA.
    */
   Time txDuration = m_phy->CalculateTxDuration (packet.GetSize (), txMode, WIFI_PREAMBLE_LONG);
-  NotifyNav (Simulator::Now ()+txDuration, hdr);
+  Simulator::Schedule (txDuration, &MacLow::NotifyNav, this, *hdr, txMode, WIFI_PREAMBLE_LONG);
 }
 
 void
@@ -904,9 +943,9 @@
 }
 
 bool 
-MacLow::IsNavZero (Time now)
+MacLow::IsNavZero (void) const
 {
-  if (m_lastNavStart + m_lastNavDuration > now) 
+  if (m_lastNavStart + m_lastNavDuration > Simulator::Now ()) 
     {
       return false;
     } 
--- a/src/devices/wifi/mac-low.h	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/mac-low.h	Mon Nov 19 16:53:05 2007 +0100
@@ -111,17 +111,12 @@
    * \param now start of NAV timer
    * \param duration duration of NAV timer
    */
-  virtual void NavStart (Time now, Time duration) = 0;
+  virtual void NavStart (Time duration) = 0;
   /**
    * \param now start of NAV timer
    * \param duration duration of NAV timer
    */
-  virtual void NavContinue (Time now, Time duration) = 0;
-  /**
-   * \param now start of NAV timer
-   * \param duration duration of NAV timer
-   */
-  virtual void NavReset (Time now, Time duration) = 0;
+  virtual void NavReset (Time duration) = 0;
 };
 
 /**
@@ -288,6 +283,7 @@
   void SetPhy (Ptr<WifiPhy> phy);
   void SetStations (MacStations *stations);
   void SetParameters (MacParameters *parameters);
+  Ptr<NetDevice> GetDevice (void) const;
   /**
    * \param callback the callback which receives every incoming packet.
    *
@@ -368,10 +364,13 @@
   WifiMode GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const;
   Time GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const;
   Time GetAckDuration (Mac48Address to, WifiMode dataTxMode) const;
-  void NotifyNav (Time at, WifiMacHeader const*hdr);
-  bool IsNavZero (Time at);
+  void NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble);
+  void DoNavResetNow (Time duration);
+  bool DoNavStartNow (Time duration);
+  bool IsNavZero (void) const;
   void MaybeCancelPrevious (void);
   
+  void NavCounterResetCtsMissed (Time rtsEndRxTime);
   void NormalAckTimeout (void);
   void FastAckTimeout (void);
   void SuperFastAckTimeout (void);
@@ -405,6 +404,7 @@
   EventId m_sendAckEvent;
   EventId m_sendDataEvent;
   EventId m_waitSifsEvent;
+  EventId m_navCounterResetCtsMissed;
 
   Packet m_currentPacket;
   bool m_hasCurrent;
--- a/src/devices/wifi/wifi-net-device.cc	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/wifi-net-device.cc	Mon Nov 19 16:53:05 2007 +0100
@@ -34,6 +34,7 @@
 #include "mac-high-nqsta.h"
 #include "mac-high-nqap.h"
 #include "dca-txop.h"
+#include "dcf-manager.h"
 #include "wifi-default-parameters.h"
 #include "arf-mac-stations.h"
 #include "aarf-mac-stations.h"
@@ -42,6 +43,10 @@
 
 namespace ns3 {
 
+/***************************************************************
+ *         hold an enumeration of the trace types
+ ***************************************************************/
+
 WifiNetDeviceTraceType::WifiNetDeviceTraceType ()
   : m_type (RX)
 {}
@@ -79,6 +84,9 @@
    return "ns3::WifiNetDeviceTraceType";
 }
 
+/***************************************************************
+ *         a static helper
+ ***************************************************************/
 
 static WifiMode 
 GetWifiModeForPhyMode (Ptr<WifiPhy> phy, enum WifiDefaultParameters::PhyModeParameter mode)
@@ -96,6 +104,57 @@
   return WifiMode ();
 }
 
+/***************************************************************
+ *         Listener for Nav events. Forwards to DcfManager
+ ***************************************************************/
+
+class WifiNetDevice::NavListener : public ns3::MacLowNavListener {
+public:
+  NavListener (ns3::DcfManager *dcf)
+    : m_dcf (dcf) {}
+  virtual ~NavListener () {}
+  virtual void NavStart (Time duration) {
+    m_dcf->NotifyNavStartNow (duration);
+  }
+  virtual void NavReset (Time duration) {
+    m_dcf->NotifyNavResetNow (duration);
+  }
+private:
+  ns3::DcfManager *m_dcf;
+};
+
+/***************************************************************
+ *         Listener for PHY events. Forwards to DcfManager
+ ***************************************************************/
+
+class WifiNetDevice::PhyListener : public ns3::WifiPhyListener {
+public:
+  PhyListener (ns3::DcfManager *dcf)
+    : m_dcf (dcf) {}
+  virtual ~PhyListener () {}
+  virtual void NotifyRxStart (Time duration) {
+    m_dcf->NotifyRxStartNow (duration);
+  }
+  virtual void NotifyRxEndOk (void) {
+    m_dcf->NotifyRxEndOkNow ();
+  }
+  virtual void NotifyRxEndError (void) {
+    m_dcf->NotifyRxEndErrorNow ();
+  }
+  virtual void NotifyTxStart (Time duration) {
+    m_dcf->NotifyTxStartNow (duration);
+  }
+  virtual void NotifyCcaBusyStart (Time duration) {
+    m_dcf->NotifyCcaBusyStartNow (duration);
+  }
+private:
+  ns3::DcfManager *m_dcf;
+};
+
+/***************************************************************
+ *              The NetDevice itself
+ ***************************************************************/
+
 
 WifiNetDevice::WifiNetDevice (Ptr<Node> node)
   : NetDevice (node, Mac48Address::Allocate ())
@@ -180,25 +239,24 @@
   MacTxMiddle *txMiddle = new MacTxMiddle ();
   m_txMiddle = txMiddle;
 
+  m_manager = new DcfManager ();
+  Time ackTxDuration = m_phy->CalculateTxDuration (8 * (2+2+6+4), m_phy->GetMode (0), WIFI_PREAMBLE_LONG);
+  m_manager->SetAckTxDuration (ackTxDuration);
+  m_manager->SetSlotTime (m_parameters->GetSlotTime ());
+  m_manager->SetSifs (m_parameters->GetSifs ());
+  m_phyListener = new WifiNetDevice::PhyListener (m_manager);
+  m_phy->RegisterListener (m_phyListener);
+  m_navListener = new WifiNetDevice::NavListener (m_manager);
+  m_low->RegisterNavListener (m_navListener);
 }
 
 DcaTxop *
-WifiNetDevice::CreateDca (uint32_t minCw, uint32_t maxCw) const
+WifiNetDevice::CreateDca (uint32_t minCw, uint32_t maxCw, uint32_t aifsn) const
 {
-  DcaTxop *dca = new DcaTxop (minCw, maxCw);
+  DcaTxop *dca = new DcaTxop (minCw, maxCw, aifsn, m_manager);
   dca->SetParameters (m_parameters);
   dca->SetTxMiddle (m_txMiddle);
   dca->SetLow (m_low);
-  dca->SetPhy (m_phy);
-
-  Time difs = m_parameters->GetSifs () + 
-    m_parameters->GetSlotTime () + 
-    m_parameters->GetSlotTime ();
-  // see 802.11 p85 section 9.2.10
-  Time eifs = difs + m_parameters->GetSifs () + 
-    m_phy->CalculateTxDuration (8 * (2+2+6+4), m_phy->GetMode (0), WIFI_PREAMBLE_LONG);
-  dca->SetDifs (difs);
-  dca->SetEifs (eifs);
   dca->SetMaxQueueSize (400);
   dca->SetMaxQueueDelay (Seconds (10));
   return dca;
@@ -288,6 +346,9 @@
   delete m_rxMiddle;
   delete m_txMiddle;
   delete m_parameters;
+  delete m_manager;
+  delete m_phyListener;
+  delete m_navListener;
   m_phy = 0;
   m_stations = 0;
   m_low = 0;
@@ -305,7 +366,7 @@
   : WifiNetDevice (node)
 {
   m_ssid = WifiDefaultParameters::GetSsid ();
-  m_dca = CreateDca (15, 1023);
+  m_dca = CreateDca (15, 1023, 2);
 
   MacHighAdhoc *high = new MacHighAdhoc ();
   high->SetDevice (this);
@@ -367,7 +428,7 @@
   : WifiNetDevice (node)
 {
   m_ssid = WifiDefaultParameters::GetSsid ();
-  m_dca = CreateDca (15, 1023);
+  m_dca = CreateDca (15, 1023, 2);
   
   MacHighNqsta *high = new MacHighNqsta ();
   high->SetDevice (this);
@@ -447,17 +508,10 @@
 {
   m_ssid = WifiDefaultParameters::GetSsid ();
 
-  m_dca = CreateDca (15, 1023);
-  m_beaconDca = CreateDca (15, 1023);
-  /**
-   * We use a DIFS value for the beacons smaller than the 802.11 default
-   * value to ensure that the beacon queue will get access to the medium
-   * even when a lot of data has been queued. This is an 'extension' of
-   * 802.11 which is a first step towards 802.11e but it is a nice way 
-   * to get timely beacons without a lot of other hacks.
-   */
-  Time beaconDifs = m_parameters->GetSifs () + m_parameters->GetSlotTime ();
-  m_beaconDca->SetDifs (beaconDifs);
+  // The Beacon DCA is higher priority than
+  // the normal DCA so, we create it first.
+  m_beaconDca = CreateDca (0, 0, 1);
+  m_dca = CreateDca (15, 1023, 2);
 
   // By default, we configure the Basic Rate Set to be the set
   // of rates we support which are mandatory.
--- a/src/devices/wifi/wifi-net-device.h	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/wifi-net-device.h	Mon Nov 19 16:53:05 2007 +0100
@@ -41,6 +41,7 @@
 class MacHighAdhoc;
 class MacHighNqsta;
 class MacHighNqap;
+class DcfManager;
 
 /**
  * \brief hold the type of trace event generated by 
@@ -98,6 +99,10 @@
   virtual Ssid GetSsid (void) const = 0;
 
 private:
+  class PhyListener;
+  class NavListener;
+  friend class WifiNetDeviceFactory;
+
   // inherited from parent.
   virtual bool DoNeedsArp (void) const;
   virtual Ptr<Channel> DoGetChannel (void) const;
@@ -109,15 +114,13 @@
   // private helper
   void Construct (void);
 
-  friend class WifiNetDeviceFactory;
-
   CallbackTraceSource<Packet, Mac48Address> m_rxLogger;
   CallbackTraceSource<Packet, Mac48Address> m_txLogger;
 protected:
   WifiNetDevice (Ptr<Node> node);
   void DoForwardUp (Packet packet, const Mac48Address &from);
   virtual void DoDispose (void);
-  DcaTxop *CreateDca (uint32_t minCw, uint32_t maxCw) const;
+  DcaTxop *CreateDca (uint32_t minCw, uint32_t maxCw, uint32_t aifsn) const;
 
   Ptr<WifiChannel> m_channel;
   Ptr<WifiPhy> m_phy;
@@ -126,6 +129,9 @@
   MacRxMiddle *m_rxMiddle;
   MacTxMiddle *m_txMiddle;
   MacParameters *m_parameters;
+  DcfManager *m_manager;
+  PhyListener *m_phyListener;
+  NavListener *m_navListener;
 };
 
 /**
--- a/src/devices/wifi/wscript	Mon Nov 19 16:20:30 2007 +0100
+++ b/src/devices/wifi/wscript	Mon Nov 19 16:53:05 2007 +0100
@@ -17,7 +17,6 @@
         'wifi-mac-trailer.cc',
         'mac-parameters.cc',
         'mac-low.cc',
-        'dcf.cc',
         'wifi-mac-queue.cc',
         'mac-tx-middle.cc',
         'mac-rx-middle.cc',