src/devices/wifi/dca-txop.cc
changeset 2146 40ad60ac9912
parent 2094 ba3caa8ee26d
child 2159 20f882e85b4a
--- 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.