Fix DSR bug 1608/1609.
authorYufei Cheng <yfcheng@ittc.ku.edu>
Fri, 26 Apr 2013 10:43:20 -0400
changeset 9719 4031f7fdce5c
parent 9718 fe314aeb8ddb
child 9720 2c105df91c1a
Fix DSR bug 1608/1609.
src/dsr/doc/dsr.rst
src/dsr/model/dsr-errorbuff.cc
src/dsr/model/dsr-fs-header.cc
src/dsr/model/dsr-maintain-buff.cc
src/dsr/model/dsr-maintain-buff.h
src/dsr/model/dsr-network-queue.cc
src/dsr/model/dsr-option-header.h
src/dsr/model/dsr-options.cc
src/dsr/model/dsr-options.h
src/dsr/model/dsr-passive-buff.cc
src/dsr/model/dsr-passive-buff.h
src/dsr/model/dsr-rcache.cc
src/dsr/model/dsr-rcache.h
src/dsr/model/dsr-routing.cc
src/dsr/model/dsr-routing.h
src/dsr/model/dsr-rreq-table.h
src/dsr/model/dsr-rsendbuff.cc
src/dsr/model/dsr-rsendbuff.h
--- a/src/dsr/doc/dsr.rst	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/doc/dsr.rst	Fri Apr 26 10:43:20 2013 -0400
@@ -42,13 +42,16 @@
 map container. The key is the destination IP address.
 
 Protocol operation strongly depends on broken link detection mechanism. 
-We implement the three heuristics recommended.
+We implement the three heuristics recommended based the rfc.
     
-First, we use layer 2 feedback when possible. A link is considered to be 
+First, we use link layer feedback when possible, which is also the fastest mechanism
+in these three to detect link errors. A link is considered to be 
 broken if frame transmission results in a transmission failure for all 
 retries. This mechanism is meant for active links and works much faster than 
-in its absence.  Layer 2 feedback implementation relies on TxErrHeader trace 
-source, currently it is supported in AdhocWifiMac only.
+in its absence.  DSR is able to detect the link layer transmission failure and 
+notify that as broken.  Recalculation of routes will be triggered when needed.
+If user does not want to use link layer acknowledgment, it can be tuned by setting
+"LinkAcknowledgment" attribute to false in "dsr-routing.cc".
 
 Second, passive acknowledgment should be used whenever possible. The node 
 turns on "promiscuous" receive mode, in which it can receive packets not 
--- a/src/dsr/model/dsr-errorbuff.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-errorbuff.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -58,6 +58,7 @@
       NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid () << " source " << i->GetSource () << " " << entry.GetSource ()
                                 << " next hop " << i->GetNextHop () << " " << entry.GetNextHop () << " dst " << i->GetDestination () << " " << entry.GetDestination ());
 
+      /// TODO check the source and destination over here
       if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ()) && (i->GetSource () == entry.GetSource ()) && (i->GetNextHop () == entry.GetSource ())
           && (i->GetDestination () == entry.GetDestination ()))
         {
--- a/src/dsr/model/dsr-fs-header.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-fs-header.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -122,7 +122,7 @@
 void DsrFsHeader::Print (std::ostream &os) const
 {
   os
-  << " nextHeader: " << (uint32_t)GetNextHeader () << " messageType: " << (uint32_t)GetMessageType ()
+  << "nextHeader: " << (uint32_t)GetNextHeader () << " messageType: " << (uint32_t)GetMessageType ()
   << " sourceId: " << (uint32_t)GetSourceId () << " destinationId: " << (uint32_t)GetDestId ()
   << " length: " << (uint32_t)GetPayloadLength ();
 }
--- a/src/dsr/model/dsr-maintain-buff.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-maintain-buff.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -55,10 +55,10 @@
   for (std::vector<MaintainBuffEntry>::const_iterator i = m_maintainBuffer.begin (); i
        != m_maintainBuffer.end (); ++i)
     {
-      NS_LOG_INFO ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our add " << i->GetOurAdd () << " " << entry.GetOurAdd ()
-                              << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                              << " ackId " << i->GetAckId () << " " << entry.GetAckId () << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft ()
-                   );
+//      NS_LOG_INFO ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our add " << i->GetOurAdd () << " " << entry.GetOurAdd ()
+//                              << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+//                              << " ackId " << i->GetAckId () << " " << entry.GetAckId () << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft ()
+//                   );
 
       if ((i->GetNextHop () == entry.GetNextHop ()) && (i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetSrc () == entry.GetSrc ())
           && (i->GetDst () == entry.GetDst ()) && (i->GetAckId () == entry.GetAckId ()) && (i->GetSegsLeft () == entry.GetSegsLeft ()))
@@ -75,7 +75,6 @@
       m_maintainBuffer.erase (m_maintainBuffer.begin ());        // Drop the most aged packet
     }
   m_maintainBuffer.push_back (entry);
-  NS_LOG_DEBUG ("The maintain size " << m_maintainBuffer.size ());
   return true;
 }
 
@@ -84,7 +83,7 @@
 {
   NS_LOG_FUNCTION (this << nextHop);
   Purge ();
-  NS_LOG_DEBUG ("Drop Packet With next hop " << nextHop);
+  NS_LOG_INFO ("Drop Packet With next hop " << nextHop);
   m_maintainBuffer.erase (std::remove_if (m_maintainBuffer.begin (), m_maintainBuffer.end (),
                                           std::bind2nd (std::ptr_fun (MaintainBuffer::IsEqual), nextHop)), m_maintainBuffer.end ());
 }
@@ -106,34 +105,6 @@
   return false;
 }
 
-//bool
-//MaintainBuffer::FindMaintainEntry (Ptr<Packet> packet, Ipv4Address ourAdd, Ipv4Address src, Ipv4Address nextHop, Ipv4Address dst, NetworkKey networkKey)
-//{
-//  // TODO if necessary this one can strip the packet header and have more information
-//  for (std::vector<MaintainBuffEntry>::const_iterator i = m_maintainBuffer.begin (); i
-//       != m_maintainBuffer.end (); ++i)
-//    {
-//      NS_LOG_INFO ("packet " << i->GetPacket () << " " << packet << " nexthop " << i->GetNextHop () << " " << nextHop
-//                   << " our add " << i->GetOurAdd () << " " << ourAdd << " src " << i->GetSrc ()
-//                   << " " << src << " dst " << i->GetDst () << " " << dst
-//                   );
-//
-//      if ((i->GetPacket () == packet) && (i->GetNextHop () == nextHop) && (i->GetOurAdd () == ourAdd) && (i->GetSrc () == src)
-//          && (i->GetDst () == dst))
-//        {
-//          NS_LOG_DEBUG ("Same maintenance entry found");
-//          networkKey.m_ackId = newEntry.GetAckId ();
-//          networkKey.m_ourAdd = newEntry.GetOurAdd ();
-//          networkKey.m_nextHop = newEntry.GetNextHop ();
-//          networkKey.m_source = newEntry.GetSrc ();
-//          networkKey.m_destination = newEntry.GetDst ();
-//          // TODO may need a different network key to have
-//          return true;
-//        }
-//    }
-//  return false;
-//}
-
 bool
 MaintainBuffer::Find (Ipv4Address nextHop)
 {
@@ -155,10 +126,9 @@
   for (std::vector<MaintainBuffEntry>::iterator i = m_maintainBuffer.begin (); i
        != m_maintainBuffer.end (); ++i)
     {
-
-      NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
-                               << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                               << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
+//      NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
+//                               << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+//                               << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
 
       if ((i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetNextHop () == entry.GetNextHop ())
           && (i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
@@ -177,10 +147,9 @@
   for (std::vector<MaintainBuffEntry>::iterator i = m_maintainBuffer.begin (); i
        != m_maintainBuffer.end (); ++i)
     {
-
-      NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
-                               << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                               << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
+//      NS_LOG_DEBUG ("nexthop " << i->GetNextHop () << " " << entry.GetNextHop () << " our address " << i->GetOurAdd () << " " << entry.GetOurAdd ()
+//                               << " src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+//                               << " ackId " << i->GetAckId () << " " << entry.GetAckId ());
 
       if ((i->GetOurAdd () == entry.GetOurAdd ()) && (i->GetNextHop () == entry.GetNextHop ())
           && (i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
@@ -200,10 +169,10 @@
   for (std::vector<MaintainBuffEntry>::iterator i = m_maintainBuffer.begin (); i
        != m_maintainBuffer.end (); ++i)
     {
-      NS_LOG_DEBUG ("src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
-                           << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft () << " ackId " << (uint32_t)i->GetAckId () << " "
-                           << (uint32_t)entry.GetAckId ()
-                    );
+//      NS_LOG_DEBUG ("src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+//                           << " SegsLeft " << (uint32_t)i->GetSegsLeft () << " " << (uint32_t)entry.GetSegsLeft () << " ackId " << (uint32_t)i->GetAckId () << " "
+//                           << (uint32_t)entry.GetAckId ()
+//                    );
 
       if ((i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ())
           && (i->GetSegsLeft () == entry.GetSegsLeft ()) && (i->GetAckId () == entry.GetAckId ())
@@ -216,6 +185,29 @@
   return false;
 }
 
+bool
+MaintainBuffer::LinkEqual (MaintainBuffEntry & entry)
+{
+  NS_LOG_DEBUG ("The maintenance buffer size " << m_maintainBuffer.size ());
+  for (std::vector<MaintainBuffEntry>::iterator i = m_maintainBuffer.begin (); i
+       != m_maintainBuffer.end (); ++i)
+    {
+//      NS_LOG_DEBUG ("src " << i->GetSrc () << " " << entry.GetSrc () << " dst " << i->GetDst () << " " << entry.GetDst ()
+//                           << " OurAddress " << i->GetOurAdd () << " " << entry.GetOurAdd () << " next hop " << i->GetNextHop () << " "
+//                           << entry.GetNextHop ()
+//                    );
+
+      if ((i->GetSrc () == entry.GetSrc ()) && (i->GetDst () == entry.GetDst ()) && (i->GetOurAdd () == entry.GetOurAdd ())
+          && (i->GetNextHop () == entry.GetNextHop ())
+          )
+        {
+          m_maintainBuffer.erase (i);   // Erase the same maintain buffer entry for the promisc received packet
+          return true;
+        }
+    }
+  return false;
+}
+
 struct IsExpired
 {
   bool
--- a/src/dsr/model/dsr-maintain-buff.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-maintain-buff.h	Fri Apr 26 10:43:20 2013 -0400
@@ -40,13 +40,29 @@
 
 namespace ns3 {
 namespace dsr {
-/*
+/**
  * The maintenance buffer is responsible for maintaining packet next hop delivery
  * The data packet is saved in maintenance buffer whenever the data packet is sent out of send buffer
  */
-/*
- * The packet timer key for controlling data packet retransmission
- */
+struct LinkKey
+{
+  Ipv4Address m_source;
+  Ipv4Address m_destination;
+  Ipv4Address m_ourAdd;
+  Ipv4Address m_nextHop;
+
+  /**
+   * Compare maintain Buffer entries
+   * \return true if equal
+   */
+  bool operator < (LinkKey const & o) const
+  {
+    return ((m_source < o.m_source) && (m_destination < o.m_destination)
+            && (m_ourAdd < o.m_nextHop) && (m_nextHop < o.m_nextHop)
+            );
+  }
+};
+
 struct NetworkKey
 {
   uint16_t m_ackId;
@@ -178,7 +194,7 @@
 private:
   // / Data packet
   Ptr<const Packet> m_packet;
-  // / our own ip address
+  // / Our own ip address
   Ipv4Address m_ourAdd;
   // / Next hop Ip address
   Ipv4Address m_nextHop;
@@ -235,7 +251,10 @@
   {
     m_maintainBufferTimeout = t;
   }
+  // / Verify if all the elements in the maintainence buffer entry is the same
   bool AllEqual (MaintainBuffEntry & entry);
+  // / Verify if the maintain buffer entry is the same in every field for link ack
+  bool LinkEqual (MaintainBuffEntry & entry);
   // / Verify if the maintain buffer entry is the same in every field for network ack
   bool NetworkEqual (MaintainBuffEntry & entry);
   // / Verify if the maintain buffer entry is the same in every field for promiscuous ack
--- a/src/dsr/model/dsr-network-queue.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-network-queue.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -31,9 +31,9 @@
 
 #include "dsr-network-queue.h"
 #include "ns3/test.h"
+#include <map>
 #include <algorithm>
 #include <functional>
-#include <map>
 #include "ns3/log.h"
 #include "ns3/ipv4-route.h"
 #include "ns3/socket.h"
@@ -60,17 +60,17 @@
     m_maxSize (maxLen),
     m_maxDelay (maxDelay)
 {
-  NS_LOG_FUNCTION (this );
+  NS_LOG_FUNCTION (this);
 }
 
 DsrNetworkQueue::DsrNetworkQueue () : m_size (0)
 {
-  NS_LOG_FUNCTION (this );
+  NS_LOG_FUNCTION (this);
 }
 
 DsrNetworkQueue::~DsrNetworkQueue ()
 {
-  NS_LOG_FUNCTION (this );
+  NS_LOG_FUNCTION (this);
   Flush ();
 }
 
@@ -110,7 +110,7 @@
   entry.SetInsertedTimeStamp (now);
   m_dsrNetworkQueue.push_back (entry);
   m_size++;
-  NS_LOG_DEBUG ("The network queue size for now " << m_size);
+  NS_LOG_LOGIC ("The network queue size is " << m_size);
   return true;
 }
 
@@ -123,7 +123,7 @@
   if (i == m_dsrNetworkQueue.end ())
     {
       // no elements in array
-      NS_LOG_DEBUG ("Does not find the queued packet in the network queue");
+      NS_LOG_LOGIC ("No queued packet in the network queue");
       return false;
     }
   entry = *i;
@@ -151,6 +151,7 @@
         }
       else
         {
+          NS_LOG_LOGIC ("Outdated packet");
           i = m_dsrNetworkQueue.erase (i);
           n++;
         }
--- a/src/dsr/model/dsr-option-header.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-option-header.h	Fri Apr 26 10:43:20 2013 -0400
@@ -338,6 +338,16 @@
    */
   Ipv4Address GetNodeAddress (uint8_t index) const;
   /**
+   * \brief Set the data length.
+   * \param dataLength the data length
+   */
+  void SetDataLength (uint32_t dataLength);
+  /**
+   * \brief Get the data length.
+   * \return the data length
+   */
+  uint32_t GetDataLength () const;
+  /**
    * \brief Set the request id number.
    * \param the identification number
    */
@@ -502,6 +512,12 @@
    * \return the router IPv4 Address
    */
   Ipv4Address GetNodeAddress (uint8_t index) const;
+  /*
+   * \brief Search the next hop Ipv4 address
+   * \param Our own IP address
+   * \return The next hop address of the route
+   */
+  Ipv4Address SearchNextHop (Ipv4Address ipv4Address);
   /**
    * \brief Print some informations about the packet.
    * \param os output stream
--- a/src/dsr/model/dsr-options.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-options.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -562,16 +562,24 @@
   // check whether we have received this request or not, if not, it will save the request in the table for
   // later use, if not found, return false, and push the newly received source request entry in the cache
 
-  bool dupRequest = dsr->FindSourceEntry (sourceAddress, targetAddress, requestId);
+  // Get the TTL value, this is used to test if the packet will be forwarded or not
+  uint8_t ttl = ipv4Header.GetTtl ();
+  bool dupRequest = false;  // initialize the duplicate request check value
+  if (ttl)
+    {
+      // if the ttl value is not 0, then this request will be forwarded, then we need to
+      // save it in the source entry
+      dupRequest = dsr->FindSourceEntry (sourceAddress, targetAddress, requestId);
+    }
   /*
    * Before processing the route request, we need to check two things
    * 1. if this is the exact same request we have just received, ignore it
    * 2. if our address is already in the path list, ignore it
    * 3. otherwise process further
    */
+
   if (dupRequest)
     {
-      NS_LOG_DEBUG ("We have received duplicate request");
       // We have received this same route reqeust before, not forwarding it now
       NS_LOG_LOGIC ("Duplicate request. Drop!");
       m_dropTrace (packet); // call drop trace
@@ -591,7 +599,6 @@
     {
       // A node ignores all RREQs received from any node in its blacklist
       RouteCacheEntry toPrev;
-
       /*
        *  When the reverse route is created or updated, the following actions on the route are also carried out:
        *  3. the next hop in the routing table becomes the node from which the  RREQ was received
@@ -1189,8 +1196,6 @@
   // The route size saved in the source route
   std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
   uint8_t segsLeft = sourceRoute.GetSegmentsLeft ();
-  /// TODO remove this one later
-  NS_LOG_DEBUG ("The segment left here " <<  (uint32_t) segsLeft);
   uint8_t salvage = sourceRoute.GetSalvage ();
   /*
    * Get the node from IP address and get the DSR extension object
@@ -1222,12 +1227,10 @@
       uint16_t fragmentOffset = ipv4Header.GetFragmentOffset ();
       uint16_t identification = ipv4Header.GetIdentification ();
 
-      /// TODO add the link ack over here
-
       if (destAddress != destination)
         {
           NS_LOG_DEBUG ("Process the promiscuously received packet");
-          bool findPassive = false;
+          bool findPassive;
           int32_t nNodes = NodeList::GetNNodes ();
           for (int32_t i = 0; i < nNodes; ++i)
             {
@@ -1255,9 +1258,6 @@
               NS_LOG_DEBUG ("promisc source " << promiscSource);
               Ptr<Node> node = GetNodeWithAddress (promiscSource);
               Ptr<dsr::DsrRouting> dsrSrc = node->GetObject<dsr::DsrRouting> ();
-
-              /// TODO need to think about this part
-              /// TODO this is temporarily disabled to enable other
               dsrSrc->CancelPassiveTimer (packet, source, destination, segsLeft);
             }
           else
--- a/src/dsr/model/dsr-options.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-options.h	Fri Apr 26 10:43:20 2013 -0400
@@ -142,12 +142,12 @@
    * \brief Print out the elements in the route vector
    */
   void PrintVector (std::vector<Ipv4Address>& vec);
-  /*
+  /**
    * \brief Check if the two vectors contain duplicate or not
    * \return true if contains duplicate
    */
   bool IfDuplicates (std::vector<Ipv4Address>& vec, std::vector<Ipv4Address>& vec2);
-  /*
+  /**
    * \brief Check if the route already contains the node ip address
    * \return true if it already exists
    */
@@ -225,7 +225,7 @@
    * \brief The active route timeout value.
    */
   Time ActiveRouteTimeout;
-  /*
+  /**
    * The receive trace back, only triggered when final destination receive data packet
    */
   TracedCallback <const DsrOptionSRHeader &> m_rxPacketTrace;
--- a/src/dsr/model/dsr-passive-buff.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-passive-buff.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -74,10 +74,10 @@
   for (std::vector<PassiveBuffEntry>::const_iterator i = m_passiveBuffer.begin (); i
        != m_passiveBuffer.end (); ++i)
     {
-      NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid () << " source " << i->GetSource () << " " << entry.GetSource ()
-                                     << " dst " << i->GetDestination () << " " << entry.GetDestination () << " identification " << i->GetIdentification () << " "
-                                     << entry.GetIdentification () << " fragment " << i->GetFragmentOffset () << " " << entry.GetFragmentOffset ()
-                                     << " segLeft " << i->GetSegsLeft () << " " << entry.GetSegsLeft ());
+//      NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid () << " source " << i->GetSource () << " " << entry.GetSource ()
+//                                     << " dst " << i->GetDestination () << " " << entry.GetDestination () << " identification " << i->GetIdentification () << " "
+//                                     << entry.GetIdentification () << " fragment " << i->GetFragmentOffset () << " " << entry.GetFragmentOffset ()
+//                                     << " segLeft " << i->GetSegsLeft () << " " << entry.GetSegsLeft ());
 
       if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ()) && (i->GetSource () == entry.GetSource ()) && (i->GetNextHop () == entry.GetNextHop ())
           && (i->GetDestination () == entry.GetDestination ()) && (i->GetIdentification () == entry.GetIdentification ()) && (i->GetFragmentOffset () == entry.GetFragmentOffset ())
@@ -107,10 +107,10 @@
   for (std::vector<PassiveBuffEntry>::iterator i = m_passiveBuffer.begin (); i
        != m_passiveBuffer.end (); ++i)
     {
-      NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid () << " source " << i->GetSource () << " " << entry.GetSource ()
-                                     << " dst " << i->GetDestination () << " " << entry.GetDestination () << " identification " << i->GetIdentification () << " "
-                                     << entry.GetIdentification () << " fragment " << i->GetFragmentOffset () << " " << entry.GetFragmentOffset ()
-                                     << " segLeft " << (uint32_t) i->GetSegsLeft () << " " << (uint32_t) entry.GetSegsLeft ());
+//      NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid () << " source " << i->GetSource () << " " << entry.GetSource ()
+//                                     << " dst " << i->GetDestination () << " " << entry.GetDestination () << " identification " << i->GetIdentification () << " "
+//                                     << entry.GetIdentification () << " fragment " << i->GetFragmentOffset () << " " << entry.GetFragmentOffset ()
+//                                     << " segLeft " << (uint32_t) i->GetSegsLeft () << " " << (uint32_t) entry.GetSegsLeft ());
 
       if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ()) && (i->GetSource () == entry.GetSource ()) && (i->GetNextHop () == entry.GetNextHop ())
           && (i->GetDestination () == entry.GetDestination ()) && (i->GetIdentification () == entry.GetIdentification ()) && (i->GetFragmentOffset () == entry.GetFragmentOffset ())
--- a/src/dsr/model/dsr-passive-buff.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-passive-buff.h	Fri Apr 26 10:43:20 2013 -0400
@@ -214,11 +214,6 @@
   }
   // \}
 
-  std::vector<PassiveBuffEntry> & GetBuffer ()     /// TODO may need to remove this one here
-  {
-    return m_passiveBuffer;
-  }
-
 private:
   // / The send buffer to cache unsent packet
   std::vector<PassiveBuffEntry> m_passiveBuffer;
--- a/src/dsr/model/dsr-rcache.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-rcache.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -97,7 +97,7 @@
 
 void LinkStab::Print ( ) const
 {
-  NS_LOG_DEBUG ("LifeTime: " << GetLinkStability ().GetSeconds ());
+  NS_LOG_LOGIC ("LifeTime: " << GetLinkStability ().GetSeconds ());
 }
 
 typedef std::list<RouteCacheEntry>::value_type route_pair;
@@ -168,7 +168,7 @@
 RouteCache::RemoveLastEntry (std::list<RouteCacheEntry> & rtVector)
 {
   NS_LOG_FUNCTION (this);
-  // release the last entry of route list
+  // Release the last entry of route list
   rtVector.pop_back ();
 }
 
@@ -180,7 +180,7 @@
     m_sortedRoutes.find (dst);
   if (i == m_sortedRoutes.end ())
     {
-      NS_LOG_DEBUG ("Failed to find the route entry for the destination " << dst);
+      NS_LOG_LOGIC ("Failed to find the route entry for the destination " << dst);
       return false;
     }
   else
@@ -190,8 +190,8 @@
       successEntry.SetExpireTime (RouteCacheTimeout);
       rtVector.pop_front ();
       rtVector.push_back (successEntry);
-      rtVector.sort (CompareRoutesExpire);  // sort the route vector first
-      m_sortedRoutes.erase (dst);  // erase the entry first
+      rtVector.sort (CompareRoutesExpire);      // sort the route vector first
+      m_sortedRoutes.erase (dst);               // erase the entry first
       /*
        * Save the new route cache along with the destination address in map
        */
@@ -272,7 +272,7 @@
       std::map<Ipv4Address, std::list<RouteCacheEntry> >::const_iterator m = m_sortedRoutes.find (id);
       if (m == m_sortedRoutes.end ())
         {
-          NS_LOG_DEBUG ("No updated route till last time");
+          NS_LOG_LOGIC ("No updated route till last time");
           return false;
         }
       /*
@@ -280,7 +280,7 @@
        */
       std::list<RouteCacheEntry> rtVector = m->second;
       rt = rtVector.front ();  // use the first entry in the route vector
-      NS_LOG_DEBUG ("Route to " << id << " with route size " << rtVector.size ());
+      NS_LOG_LOGIC ("Route to " << id << " with route size " << rtVector.size ());
       return true;
     }
 }
@@ -299,7 +299,7 @@
     }
   else
     {
-      m_isLinkCache = false;             // use path cache as default
+      m_isLinkCache = true;             // use link cache as default
       NS_LOG_INFO ("Error Cache Type");
     }
 }
@@ -351,7 +351,7 @@
           Ipv4Address ip = j->first;
           if (s.find (ip) == s.end ())
             {
-              /**
+              /*
                * \brief The followings are for comparison
                */
               if (j->second <= temp)
@@ -371,7 +371,7 @@
                   d[k->first] = d[tempip] + k->second;
                   pre[k->first] = tempip;
                 }
-              /**
+              /*
                *  Selects the shortest-length route that has the longest expected lifetime
                *  (highest minimum timeout of any link in the route)
                *  For the computation overhead and complexity
@@ -414,15 +414,13 @@
               iptemp = pre[iptemp];
             }
           route.push_back (source);
-          /**
-           * \brief Reverse the route
-           */
+          // Reverse the route
           RouteCacheEntry::IP_VECTOR reverseroute;
           for (RouteCacheEntry::IP_VECTOR::reverse_iterator j = route.rbegin (); j != route.rend (); ++j)
             {
               reverseroute.push_back (*j);
             }
-          NS_LOG_DEBUG ("Add Route: ");
+          NS_LOG_LOGIC ("Add newly calculated best routes");
           PrintVector (reverseroute);
           m_bestRoutesTable_link[i->first] = reverseroute;
         }
@@ -433,17 +431,19 @@
 RouteCache::LookupRoute_Link (Ipv4Address id, RouteCacheEntry & rt)
 {
   NS_LOG_FUNCTION (this << id);
+  /// We need to purge the link node cache
+  PurgeLinkNode ();
   std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR>::const_iterator i = m_bestRoutesTable_link.find (id);
   if (i == m_bestRoutesTable_link.end ())
     {
-      NS_LOG_INFO ("No Route To " << id);
+      NS_LOG_INFO ("No route find to " << id);
       return false;
     }
   else
     {
       if (i->second.size () < 2)
         {
-          NS_LOG_DEBUG ("Route To " << id << " error");
+          NS_LOG_LOGIC ("Route to " << id << " error");
           return false;
         }
 
@@ -451,7 +451,7 @@
       newEntry.SetVector (i->second);
       newEntry.SetDestination (id);
       newEntry.SetExpireTime (RouteCacheTimeout);
-      NS_LOG_INFO ("Route to " << id << " found with the route length " << i->second.size ());
+      NS_LOG_INFO ("Route to " << id << " found with the length " << i->second.size ());
       rt = newEntry;
       std::vector<Ipv4Address> path = rt.GetVector ();
       PrintVector (path);
@@ -463,10 +463,9 @@
 RouteCache::PurgeLinkNode ()
 {
   NS_LOG_FUNCTION (this);
-  NS_LOG_DEBUG ("The size of the link cache before " << m_linkCache.size ());
   for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); )
     {
-      NS_LOG_DEBUG ("The link stability " << i->second.GetLinkStability ());
+      NS_LOG_DEBUG ("The link stability " << i->second.GetLinkStability ().GetSeconds ());
       std::map<Link, LinkStab>::iterator itmp = i;
       if (i->second.GetLinkStability () <= Seconds (0))
         {
@@ -478,10 +477,10 @@
           ++i;
         }
     }
-  NS_LOG_DEBUG ("The size of the node cache before " << m_nodeCache.size ());
+  /// may need to remove them after verify
   for (std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.begin (); i != m_nodeCache.end (); )
     {
-      NS_LOG_DEBUG ("The node stability " << i->second.GetNodeStability ());
+      NS_LOG_DEBUG ("The node stability " << i->second.GetNodeStability ().GetSeconds ());
       std::map<Ipv4Address, NodeStab>::iterator itmp = i;
       if (i->second.GetNodeStability () <= Seconds (0))
         {
@@ -503,6 +502,7 @@
   for (std::map<Link, LinkStab>::iterator i = m_linkCache.begin (); i != m_linkCache.end (); ++i)
     {
       // Here the weight is set as 1
+      // May need to set different weight for different link here later TODO
       uint32_t weight = 1;
       m_netGraph[i->first.m_low][i->first.m_high] = weight;
       m_netGraph[i->first.m_high][i->first.m_low] = weight;
@@ -523,6 +523,9 @@
     }
   else
     {
+      /// TODO get rid of the debug here
+      NS_LOG_INFO ("The node stability " << i->second.GetNodeStability ().GetSeconds ());
+      NS_LOG_INFO ("The stability here " << Time (i->second.GetNodeStability () * m_stabilityIncrFactor).GetSeconds ());
       NodeStab ns (Time (i->second.GetNodeStability () * m_stabilityIncrFactor));
       m_nodeCache[node] = ns;
       return true;
@@ -543,6 +546,9 @@
     }
   else
     {
+      // TODO remove it here
+      NS_LOG_INFO ("The stability here " << i->second.GetNodeStability ().GetSeconds ());
+      NS_LOG_INFO ("The stability here " << Time (i->second.GetNodeStability () / m_stabilityDecrFactor).GetSeconds ());
       NodeStab ns (Time (i->second.GetNodeStability () / m_stabilityDecrFactor));
       m_nodeCache[node] = ns;
       return true;
@@ -554,10 +560,12 @@
 RouteCache::AddRoute_Link (RouteCacheEntry::IP_VECTOR nodelist, Ipv4Address source)
 {
   NS_LOG_FUNCTION (this << source);
-  NS_LOG_DEBUG ("Use Link Cache");
+  NS_LOG_LOGIC ("Use Link Cache");
+  /// Purge the link node cache first
+  PurgeLinkNode ();
   for (uint32_t i = 0; i < nodelist.size () - 1; i++)
     {
-      NodeStab ns;
+      NodeStab ns;                /// This is the node stability
       ns.SetNodeStability (m_initStability);
 
       if (m_nodeCache.find (nodelist[i]) == m_nodeCache.end ())
@@ -568,9 +576,10 @@
         {
           m_nodeCache[nodelist[i + 1]] = ns;
         }
-      Link link (nodelist[i], nodelist[i + 1]);
-      LinkStab stab;
+      Link link (nodelist[i], nodelist[i + 1]);         /// Link represent the one link for the route
+      LinkStab stab;                /// Link stability
       stab.SetLinkStability (m_initStability);
+      /// Set the link stability as the smallest node stability
       if (m_nodeCache[nodelist[i]].GetNodeStability () < m_nodeCache[nodelist[i + 1]].GetNodeStability ())
         {
           stab.SetLinkStability (m_nodeCache[nodelist[i]].GetNodeStability ());
@@ -581,7 +590,8 @@
         }
       if (stab.GetLinkStability () < m_minLifeTime)
         {
-          NS_LOG_DEBUG ("Stability: " << stab.GetLinkStability ().GetSeconds ());
+          NS_LOG_LOGIC ("Stability: " << stab.GetLinkStability ().GetSeconds ());
+          /// Set the link stability as the m)minLifeTime, default is 1 second
           stab.SetLinkStability (m_minLifeTime);
         }
       m_linkCache[link] = stab;
@@ -590,7 +600,6 @@
       NS_LOG_DEBUG ("Link Info");
       stab.Print ();
     }
-  PurgeLinkNode ();
   UpdateNetGraph ();
   RebuildBestRouteTable (source);
   return true;
@@ -600,9 +609,12 @@
 RouteCache::UseExtends (RouteCacheEntry::IP_VECTOR rt)
 {
   NS_LOG_FUNCTION (this);
+  /// Purge the link node cache first
+  PurgeLinkNode ();
   if (rt.size () < 2)
     {
       NS_LOG_INFO ("The route is too short");
+      return;
     }
   for (RouteCacheEntry::IP_VECTOR::iterator i = rt.begin (); i != rt.end () - 1; ++i)
     {
@@ -612,20 +624,21 @@
           if (m_linkCache[link].GetLinkStability () < m_useExtends)
             {
               m_linkCache[link].SetLinkStability (m_useExtends);
-              NS_LOG_DEBUG ("The time of the link " << m_linkCache[link].GetLinkStability ().GetSeconds ());
+              /// TODO remove after debug
+              NS_LOG_INFO ("The time of the link " << m_linkCache[link].GetLinkStability ().GetSeconds ());
             }
         }
       else
         {
-          NS_LOG_INFO ("we cannot find a link in cache");
+          NS_LOG_INFO ("We cannot find a link in cache");
         }
     }
-  // Increase the stability of the node cache
+  /// Increase the stability of the node cache
   for (RouteCacheEntry::IP_VECTOR::iterator i = rt.begin (); i != rt.end (); ++i)
     {
       if (m_nodeCache.find (*i) != m_nodeCache.end ())
         {
-          NS_LOG_DEBUG ("Increase the stability");
+          NS_LOG_LOGIC ("Increase the stability");
           if (m_nodeCache[*i].GetNodeStability () <= m_initStability)
             {
               IncStability (*i);
@@ -761,16 +774,21 @@
   NS_LOG_FUNCTION (this << errorSrc << unreachNode << node);
   if (IsLinkCache ())
     {
+      // Purge the link node cache first
+      PurgeLinkNode ();
       /*
-       * The followings are for cleaning the broken link in linkcache
-       *
+       * The followings are for cleaning the broken link in link cache
+       * We basically remove the link between errorSrc and unreachNode
        */
       Link link1 (errorSrc, unreachNode);
       Link link2 (unreachNode, errorSrc);
       // erase the two kind of links to make sure the link is removed from the link cache
-      NS_LOG_DEBUG ("Erase the route ");
+      NS_LOG_DEBUG ("Erase the route");
       m_linkCache.erase (link1);
+      /// TODO get rid of this one
+      NS_LOG_DEBUG ("The link cache size " << m_linkCache.size());
       m_linkCache.erase (link2);
+      NS_LOG_DEBUG ("The link cache size " << m_linkCache.size());
 
       std::map<Ipv4Address, NodeStab>::iterator i = m_nodeCache.find (errorSrc);
       if (i == m_nodeCache.end ())
@@ -790,7 +808,6 @@
         {
           DecStability (i->first);
         }
-      PurgeLinkNode ();
       UpdateNetGraph ();
       RebuildBestRouteTable (node);
     }
--- a/src/dsr/model/dsr-rcache.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-rcache.h	Fri Apr 26 10:43:20 2013 -0400
@@ -60,7 +60,7 @@
 class Time;
 namespace dsr {
 
-/*
+/**
  * The route cache structure
   \verbatim
   +-+-+-+-+-+-+-+-+-+-+-+-         +-+-+-+-+-+-+-+-+-+-+-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
@@ -130,6 +130,9 @@
    */
   virtual ~LinkStab ();
 
+  /**
+   * \brief set/get the link stability
+   */
   void SetLinkStability (Time linkStab)
   {
     m_linkStability = linkStab + Simulator::Now ();
@@ -142,7 +145,7 @@
   void Print () const;
 
 private:
-  /*
+  /**
    * The link stability lifetime expected, when the time is due, the link expires the expiration happens
    * when purge the node and link cache before update them when receiving new information
    */
@@ -177,8 +180,8 @@
 class RouteCacheEntry
 {
 public:
-  typedef std::vector<Ipv4Address> IP_VECTOR;                // Define the vector to hold Ip address
-  typedef std::vector<Ipv4Address>::iterator Iterator;       // Define the iterator
+  typedef std::vector<Ipv4Address> IP_VECTOR;                ///< Define the vector to hold Ip address
+  typedef std::vector<Ipv4Address>::iterator Iterator;       ///< Define the iterator
   // / c-tor
   /**
    * \brief Constructor
@@ -273,26 +276,26 @@
   // \}
 
 private:
-  // / RREP_ACK timer
-  Timer m_ackTimer;
-  // / The destination Ip address
-  Ipv4Address m_dst;
-  // / brief The IP address constructed route
-  IP_VECTOR m_path;
-  // / Expire time for queue entry
-  Time m_expire;
-  // / Output interface address
-  Ipv4InterfaceAddress m_iface;
-  // / Number of route requests
-  uint8_t m_reqCount;
-  // / Indicate if this entry is in "blacklist"
-  bool m_blackListState;
-  // / Time for which the node is put into the blacklist
-  Time m_blackListTimeout;
-  // / The Ipv4 route
-  Ptr<Ipv4Route> m_ipv4Route;
-  // / The Ipv4 layer 3
-  Ptr<Ipv4> m_ipv4;
+
+  Timer m_ackTimer;                                                     ///< RREP_ACK timer
+
+  Ipv4Address m_dst;                                                    ///< The destination Ip address
+
+  IP_VECTOR m_path;                                                     ///< brief The IP address constructed route
+
+  Time m_expire;                                                        ///< Expire time for queue entry
+
+  Ipv4InterfaceAddress m_iface;                                         ///< Output interface address
+
+  uint8_t m_reqCount;                                                   ///< Number of route requests
+
+  bool m_blackListState;                                                ///< Indicate if this entry is in "blacklist"
+
+  Time m_blackListTimeout;                                              ///< Time for which the node is put into the blacklist
+
+  Ptr<Ipv4Route> m_ipv4Route;                                           ///< The Ipv4 route
+
+  Ptr<Ipv4> m_ipv4;                                                     ///< The Ipv4 layer 3
 };
 /**
  * \ingroup dsr
@@ -316,10 +319,26 @@
    * \brief Destructor.
    */
   virtual ~RouteCache ();
-  // / Remove the aged route cache entries when the route cache is full
+  /**
+   * \brief Remove the aged route cache entries when the route cache is full
+   */
   void RemoveLastEntry (std::list<RouteCacheEntry> & rtVector);
-  // / Define the vector of route entries.
+  /**
+   * \brief Define the vector of route entries.
+   */
   typedef std::list<RouteCacheEntry::IP_VECTOR> routeVector;
+  /**
+   * \brief Get the destination address of the route.
+   */
+  Ipv4Address GetDestination (void) const;
+  /**
+   * \brief Remove all packets with destination IP address dst
+   */
+  void DropPathWithDst (Ipv4Address dst);
+  /**
+   * \brief To know if the two entries are the same
+   */
+  bool IsEqual (RouteCacheEntry ca);
   // /\name Fields
   // \{
   bool GetSubRoute () const
@@ -404,49 +423,53 @@
   }
   // \}
   /**
-   * Update route cache entry if it has been recently used and successfully delivered the data packet
+   * \brief Update route cache entry if it has been recently used and successfully delivered the data packet
    * \param dst destination address of the route
    * \param vec the route vector
    * \return true in success
    */
   bool UpdateRouteEntry (Ipv4Address dst);
   /**
-   * Add route cache entry if it doesn't yet exist in route cache
+   * \brief Add route cache entry if it doesn't yet exist in route cache
    * \param rt route cache entry
    * \return true in success
    */
   bool AddRoute (RouteCacheEntry & rt);
   /**
-   * Lookup route cache entry with destination address dst
+   * \brief Lookup route cache entry with destination address dst
    * \param dst destination address
    * \param rt entry with destination address dst, if exists
    * \return true on success
    */
   bool LookupRoute (Ipv4Address id, RouteCacheEntry & rt);
   /**
-   * Print the route vector elements
+   * \brief Print the route vector elements
    * \param vec the route vector
    */
   void PrintVector (std::vector<Ipv4Address>& vec);
   /**
-   * Print all the route vector elements from the route list
+   * \brief Print all the route vector elements from the route list
    * \param route the route list
    */
   void PrintRouteVector (std::list<RouteCacheEntry> route);
   /**
-   * Find the same route in the route cache
+   * \brief Find the same route in the route cache
    * \param rt entry with destination address dst, if exists
    * \param rtVector the route vector
    */
   bool FindSameRoute (RouteCacheEntry & rt, std::list<RouteCacheEntry> & rtVector);
   /**
-   * Delete the route with certain destination address
+   * \brief Delete the route with certain destination address
    * \param dst the destination address of the routes that should be deleted
    */
   bool DeleteRoute (Ipv4Address dst);
-  /*
-   * Delete all the routes which includes the link from next hop address that has just been notified
+  /**
+   * \brief Delete all the routes which includes the link from next hop address that has just been notified
    * as unreachable
+   *
+   * \param errorSrc The error source address
+   * \param unreachNode The unreachable node
+   * \param node This node's ip address
    */
   void DeleteAllRoutesIncludeLink (Ipv4Address errorSrc, Ipv4Address unreachNode, Ipv4Address node);
   // / Delete all entries from routing table
@@ -460,16 +483,17 @@
   void Print (std::ostream &os);
 
   //------------------------------------------------------------------------------------------
-  /*
-   * The following code deals with duplicate ack ids
+  /**
+   * \brief Check for duplicate ids and save new entries if the id is not present in the table
    */
-  // / Check for duplicate ids and save new entries if the id is not present in the table
   uint16_t CheckUniqueAckId (Ipv4Address nextHop);
-  // / Get the ack table size
+  /**
+   * \brief Get the ack table size
+   */
   uint16_t GetAckSize ();
 
   // --------------------------------------------------------------------------------------------
-  /*
+  /**
    * The following code handles link-layer acks
    */
   // / Neighbor description
@@ -490,30 +514,47 @@
 
     Neighbor () {} // For Python bindings
   };
-  // / Return expire time for neighbor node with address addr, if exists, else return 0.
+  /**
+   * \brief Return expire time for neighbor node with address addr, if exists, else return 0.
+   */
   Time GetExpireTime (Ipv4Address addr);
-  // / Check that node with address addr  is neighbor
+  /**
+   * \brief Check that node with address addr  is neighbor
+   */
   bool IsNeighbor (Ipv4Address addr);
-  // / Update expire time for entry with address addr, if it exists, else add new entry
+  /**
+   * \brief Update expire time for entry with address addr, if it exists, else add new entry
+   */
   void UpdateNeighbor (std::vector<Ipv4Address> nodeList, Time expire);
-  // / Add to the neighbor list
+  /**
+   * \brief Add to the neighbor list
+   */
   void AddNeighbor (std::vector<Ipv4Address> nodeList, Ipv4Address ownAddress, Time expire);
-  // / Remove all expired mac entries
+  /**
+   * \brief Remove all expired mac entries
+   */
   void PurgeMac ();
-  // / Schedule m_ntimer.
+  /**
+   * \brief Schedule m_ntimer.
+   */
   void ScheduleTimer ();
-  // / Remove all entries
+  /**
+   * \brief Remove all entries
+   */
   void ClearMac ()
   {
     m_nb.clear ();
   }
-  // / Add ARP cache to be used to allow layer 2 notifications processing
+  /**
+   * \brief Add ARP cache to be used to allow layer 2 notifications processing
+   */
   void AddArpCache (Ptr<ArpCache>);
-  // / Don't use given ARP cache any more (interface is down)
+  /**
+   * \brief Don't use given ARP cache any more (interface is down)
+   */
   void DelArpCache (Ptr<ArpCache>);
-  // / Get callback to ProcessTxError
-  /*
-   * This callback is trying to use the wifi mac tx error header to notify a link layer drop event, however,
+  /**
+   * \brief Get callback to ProcessTxError, this callback is trying to use the wifi mac tx error header to notify a link layer drop event, however,
    * it is not fully supported yet
    */
   Callback<void, WifiMacHeader const &> GetTxErrorCallback () const
@@ -534,34 +575,34 @@
 
 private:
   RouteCache & operator= (RouteCache const &);
-  RouteCacheEntry::IP_VECTOR m_vector; // /< The route vector to save the ip addresses for intermediate nodes.
-  uint32_t m_maxCacheLen;              // /< The maximum number of packets that we allow a routing protocol to buffer.
-  Time     RouteCacheTimeout;          // /< The maximum period of time that dsr is allowed to for an unused route.
-  Time     m_badLinkLifetime;          // /< The time for which the neighboring node is put into the blacklist.
-  /*
+  RouteCacheEntry::IP_VECTOR m_vector;                  ///< The route vector to save the ip addresses for intermediate nodes.
+  uint32_t m_maxCacheLen;                               ///< The maximum number of packets that we allow a routing protocol to buffer.
+  Time     RouteCacheTimeout;                           ///< The maximum period of time that dsr is allowed to for an unused route.
+  Time     m_badLinkLifetime;                           ///< The time for which the neighboring node is put into the blacklist.
+  /**
    * Define the parameters for link cache type
    */
-  uint64_t m_stabilityDecrFactor;
-  uint64_t m_stabilityIncrFactor;
+  uint32_t m_stabilityDecrFactor;
+  uint32_t m_stabilityIncrFactor;
   Time m_initStability;
   Time m_minLifeTime;
   Time m_useExtends;
-  /*
+  /**
    * Define the route cache data structure
    */
   typedef std::list<RouteCacheEntry> routeEntryVector;
-  // / Map the ipv4Address to route entry vector
-  std::map<Ipv4Address, routeEntryVector> m_sortedRoutes;
-  // Define the route vector
-  routeEntryVector m_routeEntryVector;
-  // / number of entries for each destination
-  uint32_t m_maxEntriesEachDst;
-  // / The id cache to ensure all the ids are unique
-  std::map<Ipv4Address, uint16_t> m_ackIdCache;
-  // / Check if the route is using path cache or link cache
-  bool m_isLinkCache;
-  // / Check if save the sub route entries or not
-  bool m_subRoute;
+
+  std::map<Ipv4Address, routeEntryVector> m_sortedRoutes;       ///< Map the ipv4Address to route entry vector
+
+  routeEntryVector m_routeEntryVector;                          ///< Define the route vector
+
+  uint32_t m_maxEntriesEachDst;                                 ///< number of entries for each destination
+
+  std::map<Ipv4Address, uint16_t> m_ackIdCache;                 ///< The id cache to ensure all the ids are unique
+
+  bool m_isLinkCache;                                           ///< Check if the route is using path cache or link cache
+
+  bool m_subRoute;                                              ///< Check if save the sub route entries or not
   /**
    * The link cache to update all the link status, bi-link is two link for link is a struct
    * when the weight is calculated we normalized them: 100*weight/max of Weight
@@ -573,27 +614,39 @@
    * change the weight and then recompute the best choice for each node
    */
   std::map<Ipv4Address, std::map<Ipv4Address, uint32_t> > m_netGraph;
-  // for link route cache
-  std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR> m_bestRoutesTable_link;
-  std::map<Link, LinkStab> m_linkCache;
-  std::map<Ipv4Address, NodeStab> m_nodeCache;
-  // used by LookupRoute when LinkCache
+
+  std::map<Ipv4Address, RouteCacheEntry::IP_VECTOR> m_bestRoutesTable_link;     ///< for link route cache
+  std::map<Link, LinkStab> m_linkCache;                                         ///< The data structure to store link info
+  std::map<Ipv4Address, NodeStab> m_nodeCache;                                  ///< The data structure to store node info
+  /**
+   * \brief used by LookupRoute when LinkCache
+   * \param id the ip address we are looking for
+   * \param rt the route cache entry to store the found one
+   */
   bool LookupRoute_Link (Ipv4Address id, RouteCacheEntry & rt);
-
+  /**
+   * \brief increase the stability of the node
+   * \param node the ip address of the node we want to increase stability
+   */
   bool IncStability (Ipv4Address node);
-
+  /**
+   * \brief decrease the stability of the node
+   * \param node the ip address of the node we want to decrease stability
+   */
   bool DecStability (Ipv4Address node);
 
 public:
   /**
    * \brief dijsktra algorithm to get the best route from m_netGraph and update the m_bestRoutesTable_link
    * \when current graph information has changed
+   * \param The type of the cache
    */
   void SetCacheType (std::string type);
   bool IsLinkCache ();
   bool AddRoute_Link (RouteCacheEntry::IP_VECTOR nodelist, Ipv4Address node);
   /**
    *  \brief USE MAXWEIGHT TO REPRESENT MAX; USE BROADCAST ADDRESS TO REPRESENT NULL PRECEEDING ADDRESS
+   *  \param The source address the routes based on
    */
   void RebuildBestRouteTable (Ipv4Address source);
   void PurgeLinkNode ();
@@ -612,22 +665,21 @@
   /**
    * The following code handles link-layer acks
    */
-  // / link failure callback
-  Callback<void, Ipv4Address, uint8_t > m_handleLinkFailure;
-  // / TX error callback
-  Callback<void, WifiMacHeader const &> m_txErrorCallback;
-  // / Timer for neighbor's list. Schedule Purge().
-  Timer m_ntimer;
-  // / vector of entries
-  std::vector<Neighbor> m_nb;
-  // / list of ARP cached to be used for layer 2 notifications processing
-  std::vector<Ptr<ArpCache> > m_arp;
-  // This timeout deals with the passive ack
-  Time m_delay;
-  // / Find MAC address by IP using list of ARP caches
-  Mac48Address LookupMacAddress (Ipv4Address);
-  // / Process layer 2 TX error notification
-  void ProcessTxError (WifiMacHeader const &);
+  Callback<void, Ipv4Address, uint8_t > m_handleLinkFailure;            ///< link failure callback
+
+  Callback<void, WifiMacHeader const &> m_txErrorCallback;              ///< TX error callback
+
+  Timer m_ntimer;                                                       ///< Timer for neighbor's list. Schedule Purge().
+
+  std::vector<Neighbor> m_nb;                                           ///< vector of entries
+
+  std::vector<Ptr<ArpCache> > m_arp;                                    ///< list of ARP cached to be used for layer 2 notifications processing
+
+  Time m_delay;                                                         ///< This timeout deals with the passive ack
+
+  Mac48Address LookupMacAddress (Ipv4Address);                          ///< Find MAC address by IP using list of ARP caches
+
+  void ProcessTxError (WifiMacHeader const &);                          ///< Process layer 2 TX error notification
 };
 } // namespace dsr
 } // namespace ns3
--- a/src/dsr/model/dsr-routing.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-routing.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -39,12 +39,14 @@
 #include <algorithm>
 #include <iostream>
 
+#include "ns3/config.h"
 #include "ns3/enum.h"
 #include "ns3/string.h"
 #include "ns3/ptr.h"
 #include "ns3/log.h"
 #include "ns3/assert.h"
 #include "ns3/uinteger.h"
+#include "ns3/net-device.h"
 #include "ns3/packet.h"
 #include "ns3/boolean.h"
 #include "ns3/node-list.h"
@@ -63,6 +65,8 @@
 #include "ns3/udp-l4-protocol.h"
 #include "ns3/udp-socket-factory.h"
 #include "ns3/tcp-socket-factory.h"
+#include "ns3/llc-snap-header.h"
+#include "ns3/arp-header.h"
 
 #include "dsr-rreq-table.h"
 #include "dsr-rcache.h"
@@ -162,7 +166,7 @@
                    UintegerValue (2),
                    MakeUintegerAccessor (&DsrRouting::m_maxMaintRexmt),
                    MakeUintegerChecker<uint32_t> ())
-    .AddAttribute ("RequestTableSize","Maximum number of request entries in the request table.",
+    .AddAttribute ("RequestTableSize","Maximum number of request entries in the request table, set this as the number of nodes in the simulation.",
                    UintegerValue (64),
                    MakeUintegerAccessor (&DsrRouting::m_requestTableSize),
                    MakeUintegerChecker<uint32_t> ())
@@ -173,7 +177,7 @@
     .AddAttribute ("UniqueRequestIdSize","Maximum number of request Ids in the request table for a single destination.",
                    UintegerValue (256),
                    MakeUintegerAccessor (&DsrRouting::m_maxRreqId),
-                   MakeUintegerChecker<uint16_t> ())
+                   MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("NonPropRequestTimeout","The timeout value for non-propagation request.",
                    TimeValue (MilliSeconds (30)),
                    MakeTimeAccessor (&DsrRouting::m_nonpropRequestTimeout),
@@ -197,7 +201,15 @@
     .AddAttribute ("BroadcastJitter","The jitter time to avoid collision for broadcast packets.",
                    UintegerValue (10),
                    MakeUintegerAccessor (&DsrRouting::m_broadcastJitter),
-                   MakeUintegerChecker<uint16_t> ())
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("LinkAckTimeout","The time a packet in maintenance buffer wait for link acknowledgment.",
+                   TimeValue (MilliSeconds (100)),
+                   MakeTimeAccessor (&DsrRouting::m_linkAckTimeout),
+                   MakeTimeChecker ())
+    .AddAttribute ("TryLinkAcks","The number of link acknowledgment to use.",
+                   UintegerValue (1),
+                   MakeUintegerAccessor (&DsrRouting::m_tryLinkAcks),
+                   MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("PassiveAckTimeout","The time a packet in maintenance buffer wait for passive acknowledgment.",
                    TimeValue (MilliSeconds (100)),
                    MakeTimeAccessor (&DsrRouting::m_passiveAckTimeout),
@@ -225,11 +237,11 @@
     .AddAttribute ("StabilityDecrFactor","The stability decrease factor for link cache",
                    UintegerValue (2),
                    MakeUintegerAccessor (&DsrRouting::m_stabilityDecrFactor),
-                   MakeUintegerChecker<uint64_t> ())
+                   MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("StabilityIncrFactor","The stability increase factor for link cache",
                    UintegerValue (4),
                    MakeUintegerAccessor (&DsrRouting::m_stabilityIncrFactor),
-                   MakeUintegerChecker<uint64_t> ())
+                   MakeUintegerChecker<uint32_t> ())
     .AddAttribute ("InitStability","The initial stability factor for link cache",
                    TimeValue (Seconds (25)),
                    MakeTimeAccessor (&DsrRouting::m_initStability),
@@ -262,6 +274,10 @@
                    UintegerValue (2),
                    MakeUintegerAccessor (&DsrRouting::m_numPriorityQueues),
                    MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("LinkAcknowledgment","Enable Link layer acknowledgment mechanism",
+                   BooleanValue (false),
+                   MakeBooleanAccessor (&DsrRouting::m_linkAck),
+                   MakeBooleanChecker ())
     .AddTraceSource ("Tx", "Send DSR packet.",
                      MakeTraceSourceAccessor (&DsrRouting::m_txPacketTrace))
     .AddTraceSource ("Drop", "Drop DSR packet",
@@ -341,29 +357,42 @@
 void DsrRouting::Start ()
 {
   NS_LOG_FUNCTION (this << "Start DSR Routing protocol");
-  Ptr<dsr::RouteCache> routeCache = CreateObject<dsr::RouteCache> ();
-  // Configure the path cache parameters
-  routeCache->SetCacheType (m_cacheType);
-  routeCache->SetSubRoute (m_subRoute);
-  routeCache->SetMaxCacheLen (m_maxCacheLen);
-  routeCache->SetCacheTimeout (m_maxCacheTime);
-  routeCache->SetMaxEntriesEachDst (m_maxEntriesEachDst);
-  // Parameters for link cache
-  routeCache->SetStabilityDecrFactor (m_stabilityDecrFactor);
-  routeCache->SetStabilityIncrFactor (m_stabilityIncrFactor);
-  routeCache->SetInitStability (m_initStability);
-  routeCache->SetMinLifeTime (m_minLifeTime);
-  routeCache->SetUseExtends (m_useExtends);
-  routeCache->ScheduleTimer ();
-  // The call back to handle link error and send error message to appropriate nodes
-  routeCache->SetCallback (MakeCallback (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
-  SetRouteCache (routeCache);
-// Set the passive buffer parameters using just the send buffer parameters
+
+  NS_LOG_INFO ("The number of network queues " << m_numPriorityQueues);
+  for (uint32_t i = 0; i < m_numPriorityQueues; i++)
+    {
+      // Set the network queue max size and the delay
+      NS_LOG_INFO ("The network queue size " << m_maxNetworkSize << " and the queue delay " << m_maxNetworkDelay.GetSeconds ());
+      Ptr<dsr::DsrNetworkQueue> queue_i = CreateObject<dsr::DsrNetworkQueue> (m_maxNetworkSize,m_maxNetworkDelay);
+      std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator, bool> result_i = m_priorityQueue.insert (std::make_pair (i, queue_i));
+      NS_ASSERT_MSG (result_i.second, "Error in creating queues");
+    }
+  Ptr<dsr::RreqTable> rreqTable = CreateObject<dsr::RreqTable> ();
+  // Set the initial hop limit
+  rreqTable->SetInitHopLimit (m_discoveryHopLimit);
+  // Configure the request table parameters
+  rreqTable->SetRreqTableSize (m_requestTableSize);
+  rreqTable->SetRreqIdSize (m_requestTableIds);
+  rreqTable->SetUniqueRreqIdSize (m_maxRreqId);
+  SetRequestTable (rreqTable);
+  // Set the passive buffer parameters using just the send buffer parameters
   Ptr<dsr::PassiveBuffer> passiveBuffer = CreateObject<dsr::PassiveBuffer> ();
   passiveBuffer->SetMaxQueueLen (m_maxSendBuffLen);
   passiveBuffer->SetPassiveBufferTimeout (m_sendBufferTimeout);
   SetPassiveBuffer (passiveBuffer);
 
+  // Set the send buffer parameters
+  m_sendBuffer.SetMaxQueueLen (m_maxSendBuffLen);
+  m_sendBuffer.SetSendBufferTimeout (m_sendBufferTimeout);
+  // Set the error buffer parameters using just the send buffer parameters
+  m_errorBuffer.SetMaxQueueLen (m_maxSendBuffLen);
+  m_errorBuffer.SetErrorBufferTimeout (m_sendBufferTimeout);
+  // Set the maintenance buffer parameters
+  m_maintainBuffer.SetMaxQueueLen (m_maxMaintainLen);
+  m_maintainBuffer.SetMaintainBufferTimeout (m_maxMaintainTime);
+  // Set the gratuitous reply table size
+  m_graReply.SetGraTableSize (m_graReplyTableSize);
+
   if (m_mainAddress == Ipv4Address ())
     {
       Ipv4Address loopback ("127.0.0.1");
@@ -372,11 +401,30 @@
           // Use primary address, if multiple
           Ipv4Address addr = m_ipv4->GetAddress (i, 0).GetLocal ();
           m_broadcast = m_ipv4->GetAddress (i, 0).GetBroadcast ();
-          NS_LOG_DEBUG ("The addr " << addr);
           if (addr != loopback)
             {
+              /*
+               * Set dsr route cache
+               */
+              Ptr<dsr::RouteCache> routeCache = CreateObject<dsr::RouteCache> ();
+              // Configure the path cache parameters
+              routeCache->SetCacheType (m_cacheType);
+              routeCache->SetSubRoute (m_subRoute);
+              routeCache->SetMaxCacheLen (m_maxCacheLen);
+              routeCache->SetCacheTimeout (m_maxCacheTime);
+              routeCache->SetMaxEntriesEachDst (m_maxEntriesEachDst);
+              // Parameters for link cache
+              routeCache->SetStabilityDecrFactor (m_stabilityDecrFactor);
+              routeCache->SetStabilityIncrFactor (m_stabilityIncrFactor);
+              routeCache->SetInitStability (m_initStability);
+              routeCache->SetMinLifeTime (m_minLifeTime);
+              routeCache->SetUseExtends (m_useExtends);
+              routeCache->ScheduleTimer ();
+              // The call back to handle link error and send error message to appropriate nodes
+              routeCache->SetCallback (MakeCallback (&DsrRouting::SendRerrWhenBreaksLinkToNextHop, this));
+              SetRouteCache (routeCache);
+              // Set the main address as the current ip address
               m_mainAddress = addr;
-              NS_LOG_DEBUG ("The node Address " << m_mainAddress);
 
               m_ipv4->GetNetDevice (1)->SetPromiscReceiveCallback (MakeCallback (&DsrRouting::PromiscReceive, this));
 
@@ -393,44 +441,131 @@
                   break;
                 }
 
-              // trace back to link mac drop event to process tx error call back
-              mac->TraceConnectWithoutContext ("TxErrHeader", routeCache->GetTxErrorCallback ());
               routeCache->AddArpCache (m_ipv4->GetInterface (i)->GetArpCache ());
+              NS_LOG_LOGIC ("Starting DSR on node " << m_mainAddress);
               break;
             }
         }
       NS_ASSERT (m_mainAddress != Ipv4Address () && m_broadcast != Ipv4Address ());
+      ConnectCallbacks ();
     }
-
-  NS_LOG_DEBUG ("The number queues " << m_numPriorityQueues);
-  for (uint32_t i = 0; i < m_numPriorityQueues; i++)
+}
+
+void DsrRouting::ConnectCallbacks ()
+{
+  // Connect the callbacks
+  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd",
+                   MakeCallback (&DsrRouting::NotifyDataReceipt, this));
+}
+
+void DsrRouting::NotifyDataReceipt (std::string context, Ptr<const Packet> p)
+{
+  Ptr<NetDevice> ndev = GetNetDeviceFromContext (context);
+  NS_ASSERT (ndev);
+  Ptr<Node> n = ndev->GetNode ();
+  Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> ();
+  NS_ASSERT (n);
+
+  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
+  Mac48Address nodeAddr = netDevice->GetMac()->GetAddress();
+  std::ostringstream oss;
+  oss << nodeAddr;
+
+  Ptr<Packet> newP = p->Copy();
+  WifiMacHeader hdr;
+  newP->RemoveHeader(hdr);
+  /// TODO this is a hard-coded check, need to find a better way to work on this
+  if (newP->GetSize () == 4)
     {
-      // Set the network queue max size and the delay
-      NS_LOG_DEBUG ("The network size " << m_maxNetworkSize << " and the network delay " << m_maxNetworkDelay.GetSeconds ());
-      Ptr<dsr::DsrNetworkQueue> queue_i = CreateObject<dsr::DsrNetworkQueue> (m_maxNetworkSize,m_maxNetworkDelay);
-      std::pair<std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator, bool> result_i = m_priorityQueue.insert (std::make_pair (i, queue_i));
-      NS_ASSERT_MSG (result_i.second, "Error in creating queues");
+      NS_LOG_WARN ("WifiMacTrailer left, skip this packet");
+      return;
     }
-  Ptr<dsr::RreqTable> rreqTable = CreateObject<dsr::RreqTable> ();
-  // Set the initial hop limit
-  rreqTable->SetInitHopLimit (m_discoveryHopLimit);
-  // Configure the request table parameters
-  rreqTable->SetRreqTableSize (m_requestTableSize);
-  rreqTable->SetRreqIdSize (m_requestTableIds);
-  rreqTable->SetUniqueRreqIdSize (m_maxRreqId);
-  SetRequestTable (rreqTable);
-  // Set the send buffer parameters
-  m_sendBuffer.SetMaxQueueLen (m_maxSendBuffLen);
-  m_sendBuffer.SetSendBufferTimeout (m_sendBufferTimeout);
-  // Set the error buffer parameters using just the send buffer parameters
-  m_errorBuffer.SetMaxQueueLen (m_maxSendBuffLen);
-  m_errorBuffer.SetErrorBufferTimeout (m_sendBufferTimeout);
-  // Set the maintenance buffer parameters
-  m_maintainBuffer.SetMaxQueueLen (m_maxMaintainLen);
-  m_maintainBuffer.SetMaintainBufferTimeout (m_maxMaintainTime);
-  // Set the gratuitous reply table size
-  m_graReply.SetGraTableSize (m_graReplyTableSize);
-  NS_LOG_DEBUG ("Starting DSR on node " << m_mainAddress);
+
+  LlcSnapHeader llc;
+  if(!newP->PeekHeader (llc))
+  {
+    NS_LOG_WARN ("llc snap header not present");
+    NS_ASSERT (newP->GetSize() < 64);
+    return;
+  }
+  newP->RemoveHeader(llc);
+  /*
+   * Tried to use peekheader here, but for ipv4 header here,
+   * dsr removes the Ipv4Header and then pass the packet and the header
+   * separately to Ipv4L3Protocol. Ipv4L3Protocol then re-adds them
+   * together, which causes the problem.  Check Bug 1479
+   */
+  ArpHeader arp;
+  if(newP->PeekHeader (arp))
+  {
+    NS_LOG_WARN ("arp header present, skip this packet");
+    NS_ASSERT (newP->GetSize() < 64);
+    return;
+  }
+  /// Remove the ipv4 header here
+  Ipv4Header ip;
+  newP->RemoveHeader(ip);
+  /// Remove the dsr routing header here
+  DsrRoutingHeader dsrRouting;
+  newP->RemoveHeader(dsrRouting);
+  /*
+   * Message type 2 means the data packet, we will further process the data
+   * packet for delivery notification, safely ignore control packet
+   * Another check here is our own address, if this is the data destinated for us,
+   * process it further, otherwise, just ignore it
+   */
+  Ipv4Address ourAddress = ipv4->GetAddress (1, 0).GetLocal ();
+  // check if the message type is 2 and if the ipv4 address matches
+  if (dsrRouting.GetMessageType () == 2 && ourAddress == m_mainAddress)
+    {
+      NS_LOG_DEBUG ("data packet receives " << p->GetUid());
+      Ipv4Address sourceIp = GetIPfromID (dsrRouting.GetSourceId());
+      Ipv4Address destinationIp = GetIPfromID ( dsrRouting.GetDestId());
+      /// This is the ip address we just received data packet from
+      Ipv4Address previousHop = GetIPfromMAC (hdr.GetAddr2 ());
+
+      Ptr<Packet> p = Create<Packet> ();
+      // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
+      MaintainBuffEntry newEntry;
+      newEntry.SetPacket (p);
+      newEntry.SetSrc (sourceIp);
+      newEntry.SetDst (destinationIp);
+      /// Remember this is the entry for previous node
+      newEntry.SetOurAdd (previousHop);
+      newEntry.SetNextHop (ourAddress);
+      /// Get the previous node's maintenance buffer and passive ack
+      Ptr<Node> node = GetNodeWithAddress (previousHop);
+      Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> ();
+      dsr->CancelLinkPacketTimer (newEntry);
+    }
+}
+
+Ptr<NetDevice>
+DsrRouting::GetNetDeviceFromContext (std::string context)
+{
+  // Use "NodeList/*/DeviceList/*/ as reference
+  // where element [1] is the Node Id
+  // element [2] is the NetDevice Id
+  std::vector <std::string> elements = GetElementsFromContext (context);
+  Ptr<Node> n = NodeList::GetNode (atoi (elements[1].c_str ()));
+  NS_ASSERT (n);
+  return n->GetDevice (atoi (elements[3].c_str ()));
+}
+
+std::vector<std::string>
+DsrRouting::GetElementsFromContext (std::string context)
+{
+  std::vector <std::string> elements;
+  size_t pos1=0, pos2;
+  while (pos1 != context.npos)
+  {
+    pos1 = context.find ("/",pos1);
+    pos2 = context.find ("/",pos1+1);
+    elements.push_back (context.substr (pos1+1,pos2-(pos1+1)));
+    pos1 = pos2;
+    pos2 = context.npos;
+  }
+  return elements;
 }
 
 void
@@ -509,6 +644,24 @@
   return m_passiveBuffer;
 }
 
+Ptr<Node>
+DsrRouting::GetNodeWithAddress (Ipv4Address ipv4Address)
+{
+  NS_LOG_FUNCTION (this << ipv4Address);
+  int32_t nNodes = NodeList::GetNNodes ();
+  for (int32_t i = 0; i < nNodes; ++i)
+    {
+      Ptr<Node> node = NodeList::GetNode (i);
+      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
+      int32_t ifIndex = ipv4->GetInterfaceForAddress (ipv4Address);
+      if (ifIndex != -1)
+        {
+          return node;
+        }
+    }
+  return 0;
+}
+
 bool DsrRouting::IsLinkCache ()
 {
   return m_routeCache->IsLinkCache ();
@@ -615,7 +768,6 @@
         {
           if (ipv4Address == (*i))
             {
-              NS_LOG_DEBUG (ipv4Address << " and " << *i);
               nextHop = *(++i);
               return nextHop;
             }
@@ -713,9 +865,6 @@
           Ipv4Address source = entry.GetSrc ();
           Ipv4Address destination = entry.GetDst ();
 
-          // Send the data packet out before schedule the next packet transmission
-          SendPacket (dequeP, source, nextHop, protocol);
-
           DsrRoutingHeader dsrRoutingHeader;
           p->RemoveHeader (dsrRoutingHeader);
           Ptr<Packet> cleanP = p->Copy ();
@@ -757,11 +906,11 @@
               newSR.SetNodesAddress (nodeList);
               newSR.SetSegmentsLeft ((nodeList.size () - 2));
               newSR.SetSalvage (salvage + 1);
+              /// When found a route and use it, UseExtends to the link cache
               if (m_routeCache->IsLinkCache ())
                 {
                   m_routeCache->UseExtends (nodeList);
                 }
-
               NetworkKey networkKey;
               networkKey.m_ackId = entry.GetAckId ();
               networkKey.m_ourAdd = entry.GetOurAdd ();
@@ -775,17 +924,32 @@
               passiveKey.m_destination = entry.GetDst ();
               passiveKey.m_segsLeft = entry.GetSegsLeft ();
 
+              LinkKey linkKey;
+              linkKey.m_source = entry.GetSrc ();
+              linkKey.m_destination = entry.GetDst ();
+              linkKey.m_ourAdd = entry.GetOurAdd ();
+              linkKey.m_nextHop = entry.GetNextHop ();
+
               m_addressForwardCnt[networkKey] = 0;
               m_passiveCnt[passiveKey] = 0;
-
-              if (nextHop != destination)
+              m_linkCnt[linkKey] = 0;
+
+              if (m_linkAck)
                 {
-                  SchedulePassivePacketRetry (entry, false, protocol);
+                  ScheduleLinkPacketRetry (entry, protocol);
                 }
               else
                 {
-                  // This is the first network retry
-                  ScheduleNetworkPacketRetry (entry, true, protocol);
+                  NS_LOG_LOGIC ("Not using link acknowledgment");
+                  if (nextHop != destination)
+                    {
+                      SchedulePassivePacketRetry (entry, protocol);
+                    }
+                  else
+                    {
+                      // This is the first network retry
+                      ScheduleNetworkPacketRetry (entry, true, protocol);
+                    }
                 }
             }
           else
@@ -892,6 +1056,7 @@
                   DsrOptionSRHeader sourceRoute;
                   std::vector<Ipv4Address> errorRoute = toDst.GetVector ();
                   sourceRoute.SetNodesAddress (errorRoute);
+                  /// When found a route and use it, UseExtends to the link cache
                   if (m_routeCache->IsLinkCache ())
                     {
                       m_routeCache->UseExtends (errorRoute);
@@ -922,21 +1087,24 @@
                   Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
                   m_ipv4Route->SetOutputDevice (dev);
 
-                  uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
+                  uint32_t priority = GetPriority (DSR_CONTROL_PACKET); /// This will be priority 0
                   std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
                   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
-                  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
-
-                  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
-
-                  if (dsrNetworkQueue->Enqueue (newEntry))
-                    {
-                      Scheduler (priority);
-                    }
-                  else
-                    {
-                      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-                    }
+                  NS_LOG_LOGIC ("Will be inserting into priority queue number: " << priority);
+
+                  m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+                  // TODO
+//                  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+//
+//                  if (dsrNetworkQueue->Enqueue (newEntry))
+//                    {
+//                      Scheduler (priority);
+//                    }
+//                  else
+//                    {
+//                      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//                    }
                 }
             }
           else
@@ -958,13 +1126,15 @@
               sourceRoute.SetNodesAddress (nodeList); // Save the whole route in the source route header of the packet
               sourceRoute.SetSegmentsLeft ((nodeList.size () - 2)); // The segmentsLeft field will indicate the hops to go
               sourceRoute.SetSalvage (salvage);
-
+              /// When found a route and use it, UseExtends to the link cache
+              if (m_routeCache->IsLinkCache ())
+                {
+                  m_routeCache->UseExtends (nodeList);
+                }
               uint8_t length = sourceRoute.GetLength ();
               dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
               dsrRoutingHeader.AddDsrOption (sourceRoute);
               cleanP->AddHeader (dsrRoutingHeader);
-              // Send the data packet out before schedule the next packet transmission
-              SendPacket (cleanP, m_mainAddress, nextHop, protocol);
               Ptr<const Packet> mtP = cleanP->Copy ();
               // Put the data packet in the maintenance queue for data packet retransmission
               MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*Ipv4Address=*/ m_mainAddress, /*nextHop=*/ nextHop,
@@ -986,16 +1156,32 @@
                   passiveKey.m_destination = newEntry.GetDst ();
                   passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
 
+                  LinkKey linkKey;
+                  linkKey.m_source = newEntry.GetSrc ();
+                  linkKey.m_destination = newEntry.GetDst ();
+                  linkKey.m_ourAdd = newEntry.GetOurAdd ();
+                  linkKey.m_nextHop = newEntry.GetNextHop ();
+
                   m_addressForwardCnt[networkKey] = 0;
                   m_passiveCnt[passiveKey] = 0;
-                  if (nextHop != destination)
+                  m_linkCnt[linkKey] = 0;
+
+                  if (m_linkAck)
                     {
-                      SchedulePassivePacketRetry (newEntry, false, protocol);
+                      ScheduleLinkPacketRetry (newEntry, protocol);
                     }
                   else
                     {
-                      // This is the first network retry
-                      ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                      NS_LOG_LOGIC ("Not using link acknowledgment");
+                      if (nextHop != destination)
+                        {
+                          SchedulePassivePacketRetry (newEntry, protocol);
+                        }
+                      else
+                        {
+                          // This is the first network retry
+                          ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                        }
                     }
                 }
               // we need to suspend the normal timer that checks the send buffer
@@ -1059,20 +1245,22 @@
           optionType = *(data);
 
           Ptr<dsr::DsrOptions> dsrOption;
-          Ipv4Address promiscSource = GetIPfromMAC (Mac48Address::ConvertFrom (from));
+
           if (optionType == 96)        // This is the source route option
             {
+              Ipv4Address promiscSource = GetIPfromMAC (Mac48Address::ConvertFrom (from));
+              Ipv4Address promiscDestination = GetIPfromMAC (Mac48Address::ConvertFrom (to));
               dsrOption = GetOption (optionType);       // Get the relative DSR option and demux to the process function
-              NS_LOG_DEBUG (Simulator::Now ().GetSeconds () <<
+              NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << 
                             " DSR node " << m_mainAddress <<
                             " overhearing packet PID: " << p->GetUid () <<
                             " from " << promiscSource <<
-                            " to " << GetIPfromMAC (Mac48Address::ConvertFrom (to)) <<
+                            " to " << promiscDestination <<
                             " with source IP " << ipv4Header.GetSource () <<
                             " and destination IP " << ipv4Header.GetDestination () <<
                             " and packet : " << *dsrPacket);
+
               bool isPromisc = true;                     // Set the boolean value isPromisc as true
-
               dsrOption->Process (p, dsrPacket, m_mainAddress, source, ipv4Header, nextHeader, isPromisc, promiscSource);
               return true;
             }
@@ -1134,6 +1322,7 @@
         }
       uint8_t salvage = 0;
       sourceRoute.SetNodesAddress (nodeList);     // Save the whole route in the source route header of the packet
+      /// When found a route and use it, UseExtends to the link cache
       if (m_routeCache->IsLinkCache ())
         {
           m_routeCache->UseExtends (nodeList);
@@ -1145,8 +1334,6 @@
       dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
       dsrRoutingHeader.AddDsrOption (sourceRoute);
       cleanP->AddHeader (dsrRoutingHeader);
-      // Send the data packet out before schedule the next packet transmission
-      SendPacket (cleanP, source, nextHop, protocol);
       Ptr<const Packet> mtP = cleanP->Copy ();
       SetRoute (nextHop, m_mainAddress);
       // Put the data packet in the maintenance queue for data packet retransmission
@@ -1170,16 +1357,32 @@
           passiveKey.m_destination = newEntry.GetDst ();
           passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
 
+          LinkKey linkKey;
+          linkKey.m_source = newEntry.GetSrc ();
+          linkKey.m_destination = newEntry.GetDst ();
+          linkKey.m_ourAdd = newEntry.GetOurAdd ();
+          linkKey.m_nextHop = newEntry.GetNextHop ();
+
           m_addressForwardCnt[networkKey] = 0;
           m_passiveCnt[passiveKey] = 0;
-          if (nextHop != destination)
+          m_linkCnt[linkKey] = 0;
+
+          if (m_linkAck)
             {
-              SchedulePassivePacketRetry (newEntry, false, protocol);
+              ScheduleLinkPacketRetry (newEntry, protocol);
             }
           else
             {
-              // This is the first network retry
-              ScheduleNetworkPacketRetry (newEntry, true, protocol);
+              NS_LOG_LOGIC ("Not using link acknowledgment");
+              if (nextHop != destination)
+                {
+                  SchedulePassivePacketRetry (newEntry, protocol);
+                }
+              else
+                {
+                  // This is the first network retry
+                  ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                }
             }
         }
     }
@@ -1247,6 +1450,7 @@
         }
       DsrOptionSRHeader sourceRoute;
       sourceRoute.SetNodesAddress (nodeList);
+      /// When found a route and use it, UseExtends to the link cache
       if (m_routeCache->IsLinkCache ())
         {
           m_routeCache->UseExtends (nodeList);
@@ -1270,16 +1474,19 @@
       Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
       NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
 
-      DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
-
-      if (dsrNetworkQueue->Enqueue (newEntry))
-        {
-          Scheduler (priority);
-        }
-      else
-        {
-          NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-        }
+      m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+      // TODO
+//      DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+//
+//      if (dsrNetworkQueue->Enqueue (newEntry))
+//        {
+//          Scheduler (priority);
+//        }
+//      else
+//        {
+//          NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//        }
     }
 }
 
@@ -1312,16 +1519,19 @@
   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
   NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
 
-  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, nextHop, Simulator::Now (), route);
-
-  if (dsrNetworkQueue->Enqueue (newEntry))
-    {
-      Scheduler (priority);
-    }
-  else
-    {
-      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-    }
+  m_downTarget (packet, m_mainAddress, nextHop, GetProtocolNumber (), route);
+
+  // TODO
+//  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, nextHop, Simulator::Now (), route);
+//
+//  if (dsrNetworkQueue->Enqueue (newEntry))
+//    {
+//      Scheduler (priority);
+//    }
+//  else
+//    {
+//      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//    }
 }
 
 void
@@ -1355,20 +1565,19 @@
           if (result)
             {
               NS_LOG_INFO (Simulator::Now ().GetSeconds ()
-                           << "s Add packet PID: " << packet->GetUid () << " to queue. Packet: " << *packet);
-              NS_LOG_LOGIC ("Send RREQ to " << destination);
+                           << "s Add packet PID: " << packet->GetUid () << " to send buffer. Packet: " << *packet);
               // Only when there is no existing route request timer when new route request is scheduled
               if ((m_addressReqTimer.find (destination) == m_addressReqTimer.end ()) && (m_nonPropReqTimer.find (destination) == m_nonPropReqTimer.end ()))
                 {
-                  NS_LOG_DEBUG ("When there is no existing route request for " << destination << ", initialize one");
                   /*
-                   * Call the send request function, it will update the request table entry and ttl there
+                   * Call the send request function, it will update the request table entry and ttl value
                    */
+                  NS_LOG_LOGIC ("Send initial RREQ to " << destination);
                   SendInitialRequest (source, destination, protocol);
                 }
               else
                 {
-                  NS_LOG_DEBUG ("There is existing route request timer and the request count here " << m_rreqTable->GetRreqCnt (destination));
+                  NS_LOG_LOGIC ("There is existing route request timer with request count " << m_rreqTable->GetRreqCnt (destination));
                 }
             }
         }
@@ -1391,6 +1600,7 @@
             }
           uint8_t salvage = 0;
           sourceRoute.SetNodesAddress (nodeList);       // Save the whole route in the source route header of the packet
+          /// When found a route and use it, UseExtends to the link cache
           if (m_routeCache->IsLinkCache ())
             {
               m_routeCache->UseExtends (nodeList);
@@ -1403,8 +1613,6 @@
           dsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
           dsrRoutingHeader.AddDsrOption (sourceRoute);
           cleanP->AddHeader (dsrRoutingHeader);
-          // Send the data packet out before schedule the next packet transmission
-          SendPacket (cleanP, source, nextHop, protocol);
 
           Ptr<const Packet> mtP = cleanP->Copy ();
           NS_LOG_DEBUG ("maintain packet size " << cleanP->GetSize ());
@@ -1428,21 +1636,41 @@
               passiveKey.m_destination = newEntry.GetDst ();
               passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
 
+              LinkKey linkKey;
+              linkKey.m_source = newEntry.GetSrc ();
+              linkKey.m_destination = newEntry.GetDst ();
+              linkKey.m_ourAdd = newEntry.GetOurAdd ();
+              linkKey.m_nextHop = newEntry.GetNextHop ();
+
               m_addressForwardCnt[networkKey] = 0;
               m_passiveCnt[passiveKey] = 0;
-              if (nextHop != destination)
+              m_linkCnt[linkKey] = 0;
+
+              if (m_linkAck)
                 {
-                  SchedulePassivePacketRetry (newEntry, false, protocol);
+                  ScheduleLinkPacketRetry (newEntry, protocol);
                 }
               else
                 {
-                  // This is the first network retry
-                  ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                  NS_LOG_LOGIC ("Not using link acknowledgment");
+                  if (nextHop != destination)
+                    {
+                      SchedulePassivePacketRetry (newEntry, protocol);
+                    }
+                  else
+                    {
+                      // This is the first network retry
+                      ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                    }
                 }
             }
-          // Try to send packet from *previously* queued entries from send buffer if any
-          Simulator::Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0,100)),
-                               &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
+
+          if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
+            {
+              // Try to send packet from *previously* queued entries from send buffer if any
+              Simulator::Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0,100)),
+                                   &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
+            }
         }
     }
 }
@@ -1474,7 +1702,6 @@
   DsrOptionAckReqHeader ackReq;
   m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
   ackReq.SetAckId (m_ackId);
-
   uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
   DsrRoutingHeader newDsrRoutingHeader;
   newDsrRoutingHeader.SetNextHeader (protocol);
@@ -1502,18 +1729,21 @@
   uint32_t priority = GetPriority (DSR_DATA_PACKET);
   std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
-  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
-
-  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), m_ipv4Route);
-
-  if (dsrNetworkQueue->Enqueue (newEntry))
-    {
-      Scheduler (priority);
-    }
-  else
-    {
-      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-    }
+  NS_LOG_INFO ("Will be inserting into priority queue number: " << priority);
+
+  m_downTarget (packet, source, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+  //TODO
+//  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), m_ipv4Route);
+//
+//  if (dsrNetworkQueue->Enqueue (newEntry))
+//    {
+//      Scheduler (priority);
+//    }
+//  else
+//    {
+//      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//    }
 }
 
 void
@@ -1527,7 +1757,6 @@
 DsrRouting::PriorityScheduler (uint32_t priority, bool continueWithFirst)
 {
   NS_LOG_FUNCTION (this << priority << continueWithFirst);
-  NS_LOG_DEBUG ("Scheduler looking for packets in network queue");
   uint32_t numPriorities;
   if (continueWithFirst)
     {
@@ -1537,7 +1766,7 @@
     {
       numPriorities = priority;
     }
-  // priorities range from 0 to m_numPriorityQueues, with 0 as the highest priority
+  // priorities ranging from 0 to m_numPriorityQueues, with 0 as the highest priority
   for (uint32_t i = priority; numPriorities < m_numPriorityQueues; numPriorities++)
     {
       std::map<uint32_t, Ptr<DsrNetworkQueue> >::iterator q = m_priorityQueue.find (i);
@@ -1559,9 +1788,9 @@
           uint32_t totalQueueSize = 0;
           for (std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator j = m_priorityQueue.begin (); j != m_priorityQueue.end (); j++)
             {
-              NS_LOG_DEBUG ("The size of the network queue for " << j->first << " is " << j->second->GetSize ());
+              NS_LOG_INFO ("The size of the network queue for " << j->first << " is " << j->second->GetSize ());
               totalQueueSize += j->second->GetSize ();
-              NS_LOG_DEBUG ("And the total size is " << totalQueueSize);
+              NS_LOG_INFO ("The total network queue size is " << totalQueueSize);
             }
           if (totalQueueSize > 5)
             {
@@ -1572,8 +1801,8 @@
           dsrNetworkQueue->Dequeue (newEntry);
           if (SendRealDown (newEntry))
             {
-              NS_LOG_DEBUG ("Packet sent by Dsr. Calling PriorityScheduler after some time");
-              //packet was successfully sent down. call scheduler after some time
+              NS_LOG_LOGIC ("Packet sent by Dsr. Calling PriorityScheduler after some time");
+              // packet was successfully sent down. call scheduler after some time
               Simulator::Schedule (MicroSeconds (m_uniformRandomVariable->GetInteger (0, 1000)),
                                    &DsrRouting::PriorityScheduler,this, i, false);
             }
@@ -1581,9 +1810,10 @@
             {
               // packet was dropped by Dsr. Call scheduler immediately so that we can
               // send another packet immediately.
-              NS_LOG_DEBUG ("Packet dropped by Dsr. Calling PriorityScheduler immediately");
+              NS_LOG_LOGIC ("Packet dropped by Dsr. Calling PriorityScheduler immediately");
               Simulator::Schedule (Seconds (0), &DsrRouting::PriorityScheduler, this, i, false);
             }
+
           if ((i == (m_numPriorityQueues - 1)) && continueWithFirst)
             {
               i = 0;
@@ -1615,7 +1845,6 @@
             {
               NS_LOG_DEBUG ("The network delay left is " << j->second.GetDelayLeft ());
               j->second.SetDelay (j->second.GetDelayLeft () + m_retransIncr);
-              NS_LOG_DEBUG ("The new network delay time is " << j->second.GetDelayLeft ());
             }
         }
     }
@@ -1643,21 +1872,17 @@
   std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
   Ipv4Address destination = nodeList.back ();
   Ipv4Address source = nodeList.front ();       // Get the source address
-
   NS_LOG_INFO ("The nexthop address " << nextHop << " the source " << source << " the destination " << destination);
-
   /*
-   * Here we try to find data packet from send buffer, if packet with this destiantion found, send it out
+   * Here we try to find data packet from send buffer, if packet with this destination found, send it out
    */
   if (m_sendBuffer.Find (destination))
     {
+      NS_LOG_DEBUG ("destination over here " << destination);
       SendBuffEntry entry;
       if (m_sendBuffer.Dequeue (destination, entry))
         {
           Ptr<Packet> packet = entry.GetPacket ()->Copy ();
-          NS_LOG_DEBUG ("The queued packet size " << packet->GetSize ());
-
-          NS_LOG_DEBUG ("This is the data packet");
           Ptr<Packet> p = packet->Copy ();      // get a copy of the packet
           // Set the source route option
           DsrRoutingHeader dsrRoutingHeader;
@@ -1671,15 +1896,12 @@
           dsrRoutingHeader.AddDsrOption (sourceRoute);
 
           p->AddHeader (dsrRoutingHeader);
-          // Send the data packet out before schedule the next packet transmission
-          NS_LOG_DEBUG ("Send out the data packet");
-          SendPacket (p, source, nextHop, protocol);
 
           Ptr<const Packet> mtP = p->Copy ();
           // Put the data packet in the maintenance queue for data packet retransmission
           MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
-                                                  /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
-                                                  /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
+                                      /*source=*/ source, /*destination=*/ destination, /*ackId=*/ 0,
+                                      /*SegsLeft=*/ nodeList.size () - 2, /*expire time=*/ m_maxMaintainTime);
           bool result = m_maintainBuffer.Enqueue (newEntry);       // Enqueue the packet the the maintenance buffer
 
           if (result)
@@ -1697,29 +1919,46 @@
               passiveKey.m_destination = newEntry.GetDst ();
               passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
 
+              LinkKey linkKey;
+              linkKey.m_source = newEntry.GetSrc ();
+              linkKey.m_destination = newEntry.GetDst ();
+              linkKey.m_ourAdd = newEntry.GetOurAdd ();
+              linkKey.m_nextHop = newEntry.GetNextHop ();
+
               m_addressForwardCnt[networkKey] = 0;
               m_passiveCnt[passiveKey] = 0;
-              if (nextHop != destination)
+              m_linkCnt[linkKey] = 0;
+
+              if (m_linkAck)
                 {
-                  SchedulePassivePacketRetry (newEntry, false, protocol);
+                  ScheduleLinkPacketRetry (newEntry, protocol);
                 }
               else
                 {
-                  // This is the first network retry
-                  ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                  NS_LOG_LOGIC ("Not using link acknowledgment");
+                  if (nextHop != destination)
+                    {
+                      SchedulePassivePacketRetry (newEntry, protocol);
+                    }
+                  else
+                    {
+                      // This is the first network retry
+                      ScheduleNetworkPacketRetry (newEntry, true, protocol);
+                    }
                 }
             }
 
+          NS_LOG_DEBUG ("send buffer size here and the destination " << m_sendBuffer.GetSize() << " " << destination);
           if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (destination))
             {
-              NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
+              NS_LOG_LOGIC ("Schedule sending the next packet in send buffer");
               Simulator::Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0,100)),
-                                   &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
+                                   &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
             }
         }
       else
         {
-          NS_LOG_DEBUG ("All queued packets are out-dated for the destination in send buffer");
+          NS_LOG_LOGIC ("All queued packets are out-dated for the destination in send buffer");
         }
     }
   /*
@@ -1782,6 +2021,7 @@
                   newRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
                   newRoutingHeader.AddDsrOption (newUnreach);
                   newRoutingHeader.AddDsrOption (sourceRoute);
+                  /// When found a route and use it, UseExtends to the link cache
                   if (m_routeCache->IsLinkCache ())
                     {
                       m_routeCache->UseExtends (nodeList);
@@ -1797,24 +2037,27 @@
                   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
                   NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
 
-                  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
-
-                  if (dsrNetworkQueue->Enqueue (newEntry))
-                    {
-                      Scheduler (priority);
-                    }
-                  else
-                    {
-                      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-                    }
+                  m_downTarget (newPacket, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+                  // TODO
+//                  DsrNetworkQueueEntry newEntry (newPacket, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+//
+//                  if (dsrNetworkQueue->Enqueue (newEntry))
+//                    {
+//                      Scheduler (priority);
+//                    }
+//                  else
+//                    {
+//                      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//                    }
                 }
             }
 
           if (m_errorBuffer.GetSize () != 0 && m_errorBuffer.Find (destination))
             {
-              NS_LOG_DEBUG ("Schedule sending the next packet in send buffer");
+              NS_LOG_LOGIC ("Schedule sending the next packet in error buffer");
               Simulator::Schedule (MilliSeconds (m_uniformRandomVariable->GetInteger (0,100)),
-                                   &DsrRouting::SendPacketFromBuffer,this,sourceRoute,nextHop,protocol);
+                                   &DsrRouting::SendPacketFromBuffer, this, sourceRoute, nextHop, protocol);
             }
         }
     }
@@ -1840,6 +2083,7 @@
   newEntry.SetFragmentOffset (fragmentOffset);
   newEntry.SetSegsLeft (segsLeft);  // We try to make sure the segments left is larger for 1
 
+
   NS_LOG_DEBUG ("The passive buffer size " << m_passiveBuffer->GetSize());
 
   if (m_passiveBuffer->AllEqual (newEntry) && (!saveEntry))
@@ -1855,7 +2099,6 @@
       mbEntry.SetAckId (0);
       mbEntry.SetSegsLeft (segsLeft + 1);
 
-    /// TODO this needs to be done later
       CancelPassivePacketTimer (mbEntry);
       return true;
     }
@@ -1894,29 +2137,53 @@
   return false;
 }
 
-bool
-DsrRouting::FindSamePackets (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination,
-                             uint8_t segsLeft)
+void
+DsrRouting::CancelLinkPacketTimer (MaintainBuffEntry & mb)
 {
-  NS_LOG_FUNCTION (this << packet << source << destination << (uint32_t)segsLeft);
-
-  Ptr<Packet> p = packet->Copy ();
-  // Here the segments left value need to plus one to check the earlier hop maintain buffer entry
-  MaintainBuffEntry newEntry;
-  newEntry.SetPacket (p);
-  newEntry.SetSrc (source);
-  newEntry.SetDst (destination);
-  newEntry.SetAckId (0);
-  newEntry.SetSegsLeft (segsLeft + 1);
-
-  if (m_maintainBuffer.PromiscEqual (newEntry))
+  NS_LOG_FUNCTION (this);
+  LinkKey linkKey;
+  linkKey.m_ourAdd = mb.GetOurAdd ();
+  linkKey.m_nextHop = mb.GetNextHop ();
+  linkKey.m_source = mb.GetSrc ();
+  linkKey.m_destination = mb.GetDst ();
+  /*
+   * Here we have found the entry for send retries, so we get the value and increase it by one
+   */
+  m_linkCnt[linkKey] = 0;
+  m_linkCnt.erase (linkKey);
+
+  NS_LOG_INFO ("ourAdd " << mb.GetOurAdd () << " nextHop " << mb.GetNextHop ()
+               << " source " << mb.GetSrc () << " destination " << mb.GetDst ()
+               );
+  // Find the link acknowledgment timer
+  std::map<LinkKey, Timer>::const_iterator i =
+      m_linkAckTimer.find (linkKey);
+  if (i == m_linkAckTimer.end ())
     {
-      // The PromiscEqual function will remove the maintain buffer entry if equal value found
-      // It only compares the source and destination address, ackId, and the segments left value
-      CancelPassivePacketTimer (newEntry);
-      return true;
+      NS_LOG_INFO ("did not find the link timer");
     }
-  return false;
+  else
+    {
+      NS_LOG_INFO ("did find the link timer");
+      /*
+       * Schedule the packet retry
+       * Push back the nextHop, source, destination address
+       */
+      m_linkAckTimer[linkKey].Cancel ();
+      m_linkAckTimer[linkKey].Remove ();
+      if (m_linkAckTimer[linkKey].IsRunning ())
+        {
+          NS_LOG_INFO ("Timer not canceled");
+        }
+      m_linkAckTimer.erase (linkKey);
+    }
+  // Erase the maintenance entry
+  // yet this does not check the segments left value here
+  NS_LOG_DEBUG ("The link buffer size " << m_maintainBuffer.GetSize());
+  if (m_maintainBuffer.LinkEqual (mb))
+    {
+      NS_LOG_INFO ("Link acknowledgment received, remove same maintenance buffer entry");
+    }
 }
 
 void
@@ -1926,7 +2193,7 @@
   Ipv4Address sender = ipv4Header.GetDestination ();
   Ipv4Address receiver = ipv4Header.GetSource ();
   /*
-   * Create a packet to fill maintenance buffer, not used to compare
+   * Create a packet to fill maintenance buffer, not used to compare with maintainance entry
    * The reason is ack header doesn't have the original packet copy
    */
   Ptr<Packet> mainP = Create<Packet> ();
@@ -2101,42 +2368,41 @@
       sourceRoute.SetSalvage (salvage);
       sourceRoute.SetNodesAddress (nodeList);     // Save the whole route in the source route header of the packet
       sourceRoute.SetSegmentsLeft ((nodeList.size () - 2));     // The segmentsLeft field will indicate the hops to go
-      DsrOptionAckReqHeader ackReq;
-      m_ackId = m_routeCache->CheckUniqueAckId (nextHop);
-      ackReq.SetAckId (m_ackId);
+      /// When found a route and use it, UseExtends to the link cache
       if (m_routeCache->IsLinkCache ())
         {
           m_routeCache->UseExtends (nodeList);
         }
-
-      uint8_t length = (sourceRoute.GetLength () + ackReq.GetLength ());
-      NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ())
-                                                    << " length of ack request header " << (uint32_t)(ackReq.GetLength ()));
-      newDsrRoutingHeader.SetPayloadLength (uint16_t (length) + 4);
+      uint8_t length = sourceRoute.GetLength ();
+      NS_LOG_INFO ("length of source route header " << (uint32_t)(sourceRoute.GetLength ()));
+      newDsrRoutingHeader.SetPayloadLength (uint16_t (length) + 2);
       newDsrRoutingHeader.AddDsrOption (sourceRoute);
-      newDsrRoutingHeader.AddDsrOption (ackReq);
       p->AddHeader (newDsrRoutingHeader);
 
       SetRoute (nextHop, m_mainAddress);
       Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
       m_ipv4Route->SetOutputDevice (dev);
+
       // Send out the data packet
-
       uint32_t priority = GetPriority (DSR_DATA_PACKET);
       std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
       Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
       NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
 
-      DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
-
-      if (dsrNetworkQueue->Enqueue (newEntry))
-        {
-          Scheduler (priority);
-        }
-      else
-        {
-          NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-        }
+      m_downTarget (p, m_mainAddress, nextHop, GetProtocolNumber (), m_ipv4Route);
+
+      // TODO
+//      DsrNetworkQueueEntry newEntry (p, m_mainAddress, nextHop, Simulator::Now (), m_ipv4Route);
+//
+//      if (dsrNetworkQueue->Enqueue (newEntry))
+//        {
+//          Scheduler (priority);
+//        }
+//      else
+//        {
+//          NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//        }
+
       /*
        * Mark the next hop address in blacklist
        */
@@ -2150,11 +2416,47 @@
 }
 
 void
+DsrRouting::ScheduleLinkPacketRetry (MaintainBuffEntry & mb,
+                                     uint8_t protocol)
+{
+  NS_LOG_FUNCTION (this << (uint32_t) protocol);
+
+  Ptr<Packet> p = mb.GetPacket ()->Copy ();
+  Ipv4Address source = mb.GetSrc ();
+  Ipv4Address nextHop = mb.GetNextHop ();
+
+  // Send the data packet out before schedule the next packet transmission
+  SendPacket (p, source, nextHop, protocol);
+
+  LinkKey linkKey;
+  linkKey.m_source = mb.GetSrc ();
+  linkKey.m_destination = mb.GetDst ();
+  linkKey.m_ourAdd = mb.GetOurAdd ();
+  linkKey.m_nextHop = mb.GetNextHop ();
+
+  if (m_linkAckTimer.find (linkKey) == m_linkAckTimer.end ())
+    {
+      Timer timer (Timer::CANCEL_ON_DESTROY);
+      m_linkAckTimer[linkKey] = timer;
+    }
+  m_linkAckTimer[linkKey].SetFunction (&DsrRouting::LinkScheduleTimerExpire, this);
+  m_linkAckTimer[linkKey].Remove ();
+  m_linkAckTimer[linkKey].SetArguments (mb, protocol);
+  m_linkAckTimer[linkKey].Schedule (m_linkAckTimeout);
+}
+
+void
 DsrRouting::SchedulePassivePacketRetry (MaintainBuffEntry & mb,
-                                        bool onlyPassive,
                                         uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << onlyPassive << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << (uint32_t)protocol);
+
+  Ptr<Packet> p = mb.GetPacket ()->Copy ();
+  Ipv4Address source = mb.GetSrc ();
+  Ipv4Address nextHop = mb.GetNextHop ();
+
+  // Send the data packet out before schedule the next packet transmission
+  SendPacket (p, source, nextHop, protocol);
 
   PassiveKey passiveKey;
   passiveKey.m_ackId = 0;
@@ -2170,7 +2472,7 @@
   NS_LOG_DEBUG ("The passive acknowledgment option for data packet");
   m_passiveAckTimer[passiveKey].SetFunction (&DsrRouting::PassiveScheduleTimerExpire, this);
   m_passiveAckTimer[passiveKey].Remove ();
-  m_passiveAckTimer[passiveKey].SetArguments (mb, onlyPassive, protocol);
+  m_passiveAckTimer[passiveKey].SetArguments (mb, protocol);
   m_passiveAckTimer[passiveKey].Schedule (m_passiveAckTimeout);
 }
 
@@ -2191,6 +2493,12 @@
       p = mb.GetPacket ()->Copy ();
       // Here we add the ack request header to the data packet for network acknowledgement
       uint16_t ackId = AddAckReqHeader (p, nextHop);
+
+      Ipv4Address source = mb.GetSrc ();
+      Ipv4Address nextHop = mb.GetNextHop ();
+      // Send the data packet out before schedule the next packet transmission
+      SendPacket (p, source, nextHop, protocol);
+
       dsrP = p->Copy ();
       MaintainBuffEntry newEntry = mb;
       // The function AllEqual will find the exact entry and delete it if found
@@ -2219,7 +2527,7 @@
       m_addressForwardTimer[networkKey].Remove ();
       m_addressForwardTimer[networkKey].SetArguments (newEntry, protocol);
       NS_LOG_DEBUG ("The packet retries time for " << newEntry.GetAckId () << " is " << m_sendRetries
-                                                   << " and the delay time is " << Time (2 * m_nodeTraversalTime));
+                                                   << " and the delay time is " << Time (2 * m_nodeTraversalTime).GetSeconds ());
       // Back-off mechanism
       m_addressForwardTimer[networkKey].Schedule (Time (2 * m_nodeTraversalTime));
     }
@@ -2239,6 +2547,11 @@
       p = mb.GetPacket ()->Copy ();
       dsrP = mb.GetPacket ()->Copy ();
 
+      Ipv4Address source = mb.GetSrc ();
+      Ipv4Address nextHop = mb.GetNextHop ();
+      // Send the data packet out before schedule the next packet transmission
+      SendPacket (p, source, nextHop, protocol);
+
       NS_LOG_DEBUG ("The packet with dsr header " << dsrP->GetSize ());
       networkKey.m_ackId = mb.GetAckId ();
       networkKey.m_ourAdd = mb.GetOurAdd ();
@@ -2262,20 +2575,98 @@
       m_addressForwardTimer[networkKey].Remove ();
       m_addressForwardTimer[networkKey].SetArguments (mb, protocol);
       NS_LOG_DEBUG ("The packet retries time for " << mb.GetAckId () << " is " << m_sendRetries
-                                                   << " and the delay time is " << Time (2 * m_sendRetries *  m_nodeTraversalTime));
+                                                   << " and the delay time is " << Time (2 * m_sendRetries *  m_nodeTraversalTime).GetSeconds ());
       // Back-off mechanism
       m_addressForwardTimer[networkKey].Schedule (Time (2 * m_sendRetries * m_nodeTraversalTime));
     }
 }
 
 void
+DsrRouting::LinkScheduleTimerExpire  (MaintainBuffEntry & mb,
+                                      uint8_t protocol)
+{
+  NS_LOG_FUNCTION (this << (uint32_t)protocol);
+  Ipv4Address nextHop = mb.GetNextHop ();
+  Ipv4Address source = mb.GetSrc ();
+  Ptr<const Packet> packet = mb.GetPacket ();
+  SetRoute (nextHop, m_mainAddress);
+  Ptr<Packet> p = packet->Copy ();
+
+  LinkKey lk;
+  lk.m_source = mb.GetSrc ();
+  lk.m_destination = mb.GetDst ();
+  lk.m_ourAdd = mb.GetOurAdd ();
+  lk.m_nextHop = mb.GetNextHop ();
+
+  // Cancel passive ack timer
+  m_linkAckTimer[lk].Cancel ();
+  m_linkAckTimer[lk].Remove ();
+  if (m_linkAckTimer[lk].IsRunning ())
+    {
+      NS_LOG_DEBUG ("Timer not canceled");
+    }
+  m_linkAckTimer.erase (lk);
+
+  // Increase the send retry times
+  m_linkRetries = m_linkCnt[lk];
+  if (m_linkRetries < m_tryLinkAcks)
+    {
+      m_linkCnt[lk] = ++m_linkRetries;
+      ScheduleLinkPacketRetry (mb, protocol);
+    }
+  else
+    {
+      NS_LOG_DEBUG ("We may need to send error messages now");
+      Ptr<Packet> dsrP = mb.GetPacket ()->Copy ();
+      // The packet retries time has exceed the max maintenance retransmission times
+      DsrRoutingHeader dsrRoutingHeader;
+      dsrP->RemoveHeader (dsrRoutingHeader);          // Remove the dsr header in whole
+      uint32_t offset = dsrRoutingHeader.GetDsrOptionsOffset ();
+      p->RemoveAtStart (offset);
+
+      // Get the number of routers' address field
+      uint8_t buf[2];
+      p->CopyData (buf, sizeof(buf));
+      uint8_t numberAddress = (buf[1] - 2) / 4;
+      NS_LOG_DEBUG ("The number of addresses " << (uint32_t)numberAddress);
+      DsrOptionSRHeader sourceRoute;
+      sourceRoute.SetNumberAddress (numberAddress);
+      p->RemoveHeader (sourceRoute);
+      std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
+      uint8_t salvage = sourceRoute.GetSalvage ();
+      Ipv4Address address1 = nodeList[1];
+      PrintVector (nodeList);
+
+      // Delete all the routes including the links
+      m_routeCache->DeleteAllRoutesIncludeLink (m_mainAddress, nextHop, m_mainAddress);
+      /*
+       * If the salvage is not 0, use the first address in the route as the error dst in error header
+       * otherwise use the source of packet as the error destination
+       */
+      Ipv4Address errorDst;
+      if (salvage)
+        {
+          errorDst = address1;
+        }
+      else
+        {
+          errorDst = source;
+        }
+      SendUnreachError (nextHop, errorDst, mb.GetDst (), salvage, protocol);
+      /*
+       * here we cancel the packet retransmission time for all the packets have next hop address as nextHop
+       * Also salvage the packet for the all the packet destined for the nextHop address
+       */
+      CancelPacketTimerNextHop (nextHop, protocol);
+    }
+}
+
+void
 DsrRouting::PassiveScheduleTimerExpire  (MaintainBuffEntry & mb,
-                                         bool onlyPassive,
                                          uint8_t protocol)
 {
-  NS_LOG_FUNCTION (this << onlyPassive << (uint32_t)protocol);
+  NS_LOG_FUNCTION (this << (uint32_t)protocol);
   Ipv4Address nextHop = mb.GetNextHop ();
-  Ipv4Address source = mb.GetSrc ();
   Ptr<const Packet> packet = mb.GetPacket ();
   SetRoute (nextHop, m_mainAddress);
   Ptr<Packet> p = packet->Copy ();
@@ -2294,29 +2685,21 @@
       NS_LOG_DEBUG ("Timer not canceled");
     }
   m_passiveAckTimer.erase (pk);
-  // Send the data packet out before schedule the next packet transmission
-  SendPacket (p, source, nextHop, protocol);
+
   // Increase the send retry times
   m_passiveRetries = m_passiveCnt[pk];
   if (m_passiveRetries < m_tryPassiveAcks)
     {
       m_passiveCnt[pk] = ++m_passiveRetries;
-      SchedulePassivePacketRetry (mb, onlyPassive, protocol);
+      SchedulePassivePacketRetry (mb, protocol);
     }
-  else if (!onlyPassive)
+  else
     {
       // This is the first network acknowledgement retry
       // Cancel the passive packet timer now and remove maintenance buffer entry for it
       CancelPassivePacketTimer (mb);
       ScheduleNetworkPacketRetry (mb, true, protocol);
     }
-  else
-    {
-      // This is the end of the data retransmission retries
-      CancelPassivePacketTimer (mb);
-      // The function AllEqual will find the exact entry and delete it if found
-      m_maintainBuffer.AllEqual (mb);
-    }
 }
 
 int64_t
@@ -2343,11 +2726,9 @@
   networkKey.m_source = source;
   networkKey.m_destination = dst;
 
-  // Send the data packet out before schedule the next packet transmission
-  SendPacket (p, source, nextHop, protocol);
   // Increase the send retry times
   m_sendRetries = m_addressForwardCnt[networkKey];
-  NS_LOG_DEBUG ("The send retry time is " << m_sendRetries);
+
   if (m_sendRetries >= m_maxMaintRexmt)
     {
       Ptr<Packet> dsrP = mb.GetPacket ()->Copy ();
@@ -2369,7 +2750,6 @@
       std::vector<Ipv4Address> nodeList = sourceRoute.GetNodesAddress ();
       uint8_t salvage = sourceRoute.GetSalvage ();
       Ipv4Address address1 = nodeList[1];
-      NS_LOG_DEBUG ("address1 " << address1);
       PrintVector (nodeList);
 
       // Delete all the routes including the links
@@ -2427,14 +2807,11 @@
   dsrRoutingHeader.AddDsrOption (sourceRoute);
   p->AddHeader (dsrRoutingHeader);
 
-  // Send the data packet out before schedule the next packet transmission
-  SendPacket (p, source, nextHop, protocol);
-
   Ptr<const Packet> mtP = p->Copy ();
 
   MaintainBuffEntry newEntry (/*Packet=*/ mtP, /*ourAddress=*/ m_mainAddress, /*nextHop=*/ nextHop,
-                                          /*source=*/ source, /*destination=*/ targetAddress,
-                                          /*ackId=*/ m_ackId, /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
+                              /*source=*/ source, /*destination=*/ targetAddress, /*ackId=*/ m_ackId,
+                              /*SegsLeft=*/ sourceRoute.GetSegmentsLeft (), /*expire time=*/ m_maxMaintainTime);
   bool result = m_maintainBuffer.Enqueue (newEntry);
 
   if (result)
@@ -2452,16 +2829,32 @@
       passiveKey.m_destination = newEntry.GetDst ();
       passiveKey.m_segsLeft = newEntry.GetSegsLeft ();
 
+      LinkKey linkKey;
+      linkKey.m_source = newEntry.GetSrc ();
+      linkKey.m_destination = newEntry.GetDst ();
+      linkKey.m_ourAdd = newEntry.GetOurAdd ();
+      linkKey.m_nextHop = newEntry.GetNextHop ();
+
       m_addressForwardCnt[networkKey] = 0;
       m_passiveCnt[passiveKey] = 0;
-      if (nextHop != targetAddress)
+      m_linkCnt[linkKey] = 0;
+
+      if (m_linkAck)
         {
-          SchedulePassivePacketRetry (newEntry, false, protocol);
+          ScheduleLinkPacketRetry (newEntry, protocol);
         }
       else
         {
-          // This is the first network retry
-          ScheduleNetworkPacketRetry (newEntry, true, protocol);
+          NS_LOG_LOGIC ("Not using link acknowledgment");
+          if (nextHop != targetAddress)
+            {
+              SchedulePassivePacketRetry (newEntry, protocol);
+            }
+          else
+            {
+              // This is the first network retry
+              ScheduleNetworkPacketRetry (newEntry, true, protocol);
+            }
         }
     }
 }
@@ -2508,6 +2901,8 @@
   tag.SetTtl (0);
   Ptr<Packet> nonPropPacket = packet->Copy ();
   nonPropPacket->AddPacketTag (tag);
+  // Increase the request count
+  m_rreqTable->FindAndUpdate (destination);
   SendRequest (nonPropPacket, source);
   // Schedule the next route request
   ScheduleRreqRetry (packet, address, nonProp, m_requestId, protocol);
@@ -2532,6 +2927,7 @@
       DsrOptionSRHeader sourceRoute;
       std::vector<Ipv4Address> ip = toDst.GetVector ();
       sourceRoute.SetNodesAddress (ip);
+      /// When found a route and use it, UseExtends to the link cache
       if (m_routeCache->IsLinkCache ())
         {
           m_routeCache->UseExtends (ip);
@@ -2549,7 +2945,11 @@
         }
       SetRoute (nextHop, m_mainAddress);
       CancelRreqTimer (dst, true);
-      SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+      /// Try to send out the packet from the buffer once we found one route
+      if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
+        {
+          SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+        }
       NS_LOG_LOGIC ("Route to " << dst << " found");
       return;
     }
@@ -2711,6 +3111,7 @@
       if (m_rreqTable->GetRreqCnt (dst))
         {
           // When the route request count is larger than 0
+          // This is the exponential back-off mechanism for route request
           rreqDelay = Time (std::pow (static_cast<double> (m_rreqTable->GetRreqCnt (dst)), 2.0) * m_requestPeriod);
         }
       else
@@ -2718,16 +3119,16 @@
           // This is the first route request retry
           rreqDelay = m_requestPeriod;
         }
-      NS_LOG_DEBUG ("The request count for the destination " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with time value " << rreqDelay);
+      NS_LOG_LOGIC ("Request count for " << dst << " " << m_rreqTable->GetRreqCnt (dst) << " with delay time " << rreqDelay.GetSeconds () << " second");
       if (rreqDelay > m_maxRequestPeriod)
         {
           // use the max request period
-          NS_LOG_DEBUG ("The max request delay time " << m_maxRequestPeriod.GetSeconds ());
+          NS_LOG_LOGIC ("The max request delay time " << m_maxRequestPeriod.GetSeconds ());
           m_addressReqTimer[dst].Schedule (m_maxRequestPeriod);
         }
       else
         {
-          NS_LOG_DEBUG ("The request delay time " << rreqDelay.GetSeconds ());
+          NS_LOG_LOGIC ("The request delay time " << rreqDelay.GetSeconds () << " second");
           m_addressReqTimer[dst].Schedule (rreqDelay);
         }
     }
@@ -2753,15 +3154,16 @@
       DsrOptionSRHeader sourceRoute;
       std::vector<Ipv4Address> ip = toDst.GetVector ();
       sourceRoute.SetNodesAddress (ip);
+      // When we found the route and use it, UseExtends for the link cache
       if (m_routeCache->IsLinkCache ())
         {
           m_routeCache->UseExtends (ip);
         }
       sourceRoute.SetSegmentsLeft ((ip.size () - 2));
-      uint8_t salvage = 0;
-      sourceRoute.SetSalvage (salvage);
+      /// Set the salvage value to 0
+      sourceRoute.SetSalvage (0);
       Ipv4Address nextHop = SearchNextHop (m_mainAddress, ip);       // Get the next hop address
-      NS_LOG_DEBUG ("The nextHop address " << nextHop);
+      NS_LOG_INFO ("The nextHop address is " << nextHop);
       if (nextHop == "0.0.0.0")
         {
           NS_LOG_DEBUG ("Error next hop address");
@@ -2770,7 +3172,11 @@
         }
       SetRoute (nextHop, m_mainAddress);
       CancelRreqTimer (dst, true);
-      SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+      /// Try to send out data packet from the send buffer if found
+      if (m_sendBuffer.GetSize () != 0 && m_sendBuffer.Find (dst))
+        {
+          SendPacketFromBuffer (sourceRoute, nextHop, protocol);
+        }
       NS_LOG_LOGIC ("Route to " << dst << " found");
       return;
     }
@@ -2779,7 +3185,7 @@
    *  receiving any RREP, all data packets destined for the corresponding destination SHOULD be
    *  dropped from the buffer and a Destination Unreachable message SHOULD be delivered to the application.
    */
-  NS_LOG_DEBUG ("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt (dst) << " the max " << m_rreqRetries);
+  NS_LOG_LOGIC ("The new request count for " << dst << " is " << m_rreqTable->GetRreqCnt (dst) << " the max " << m_rreqRetries);
   if (m_rreqTable->GetRreqCnt (dst) >= m_rreqRetries)
     {
       NS_LOG_LOGIC ("Route discovery to " << dst << " has been attempted " << m_rreqRetries << " times");
@@ -2807,6 +3213,7 @@
                          Ipv4Address source)
 {
   NS_LOG_FUNCTION (this << packet << source);
+
   NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
   /*
    * The destination address here is directed broadcast address
@@ -2814,18 +3221,20 @@
   uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
   std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
-  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
-
-  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
-
-  if (dsrNetworkQueue->Enqueue (newEntry))
-    {
-      Scheduler (priority);
-    }
-  else
-    {
-      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-    }
+  NS_LOG_LOGIC ("Inserting into priority queue number: " << priority);
+
+  m_downTarget (packet, source, m_broadcast, GetProtocolNumber (), 0);
+
+  // TODO
+//  DsrNetworkQueueEntry newEntry (packet, source, m_broadcast, Simulator::Now (), 0);
+//  if (dsrNetworkQueue->Enqueue (newEntry))
+//    {
+//      Scheduler (priority);
+//    }
+//  else
+//    {
+//      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//    }
 }
 
 void
@@ -2910,6 +3319,7 @@
 {
   NS_LOG_FUNCTION (this << packet << source << nextHop);
   NS_ASSERT_MSG (!m_downTarget.IsNull (), "Error, DsrRouting cannot send downward");
+
   Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (m_mainAddress));
   route->SetOutputDevice (dev);
   NS_LOG_INFO ("The output device " << dev << " packet is: " << *packet);
@@ -2917,18 +3327,20 @@
   uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
   std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
-  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
-
-  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
-
-  if (dsrNetworkQueue->Enqueue (newEntry))
-    {
-      Scheduler (priority);
-    }
-  else
-    {
-      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-    }
+  NS_LOG_INFO ("Inserting into priority queue number: " << priority);
+
+  m_downTarget (packet, source, nextHop, GetProtocolNumber (), route);
+
+  // TODO
+//  DsrNetworkQueueEntry newEntry (packet, source, nextHop, Simulator::Now (), route);
+//  if (dsrNetworkQueue->Enqueue (newEntry))
+//    {
+//      Scheduler (priority);
+//    }
+//  else
+//    {
+//      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//    }
 }
 
 void
@@ -2987,23 +3399,25 @@
   packet->AddHeader (dsrRoutingHeader);
   Ptr<NetDevice> dev = m_ip->GetNetDevice (m_ip->GetInterfaceForAddress (m_mainAddress));
   route->SetOutputDevice (dev);
-  NS_LOG_DEBUG ("Send out the ACK");
 
   uint32_t priority = GetPriority (DSR_CONTROL_PACKET);
   std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> >::iterator i = m_priorityQueue.find (priority);
   Ptr<dsr::DsrNetworkQueue> dsrNetworkQueue = i->second;
-  NS_LOG_DEBUG ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
-
-  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
-
-  if (dsrNetworkQueue->Enqueue (newEntry))
-    {
-      Scheduler (priority);
-    }
-  else
-    {
-      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
-    }
+
+  NS_LOG_LOGIC ("Will be inserting into priority queue " << dsrNetworkQueue << " number: " << priority);
+
+  m_downTarget (packet, m_mainAddress, destination, GetProtocolNumber (), route);
+
+  // TODO
+//  DsrNetworkQueueEntry newEntry (packet, m_mainAddress, destination, Simulator::Now (), route);
+//  if (dsrNetworkQueue->Enqueue (newEntry))
+//    {
+//      Scheduler (priority);
+//    }
+//  else
+//    {
+//      NS_LOG_INFO ("Packet dropped as dsr network queue is full");
+//    }
 }
 
 enum IpL4Protocol::RxStatus
@@ -3022,10 +3436,11 @@
   DsrRoutingHeader dsrRoutingHeader;
   packet->RemoveHeader (dsrRoutingHeader);          // Remove the DSR header in whole
   Ptr<Packet> copy = packet->Copy ();
+
   uint8_t protocol = dsrRoutingHeader.GetNextHeader ();
   uint32_t sourceId = dsrRoutingHeader.GetSourceId ();
   Ipv4Address source = GetIPfromID (sourceId);
-  NS_LOG_DEBUG ("The source address " << source << " with source id " << sourceId);
+  NS_LOG_INFO ("The source address " << source << " with source id " << sourceId);
   /*
    * Get the IP source and destination address
    */
@@ -3051,16 +3466,15 @@
   uint8_t segmentsLeft = 0;
 
   optionType = *(data);
-  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet size " << p->GetSize ());
+  NS_LOG_LOGIC ("The option type value " << (uint32_t)optionType << " with packet id " << p->GetUid());
   dsrOption = GetOption (optionType);       // Get the relative dsr option and demux to the process function
-  // This promisc source is just set as empty, only the promisc received packet will have a promisc source value
-  Ipv4Address promiscSource;
+  Ipv4Address promiscSource;      /// this is just here for the sake of passing in the promisc source
   if (optionType == 1)        // This is the request option
     {
       BlackList *blackList = m_rreqTable->FindUnidirectional (src);
       if (blackList)
         {
-          NS_LOG_DEBUG ("Discard this packet due to unidirectional link");
+          NS_LOG_INFO ("Discard this packet due to unidirectional link");
           m_dropTrace (p);
         }
 
@@ -3069,7 +3483,7 @@
 
       if (optionLength == 0)
         {
-          NS_LOG_DEBUG ("Discard this packet");
+          NS_LOG_INFO ("Discard this packet");
           m_dropTrace (p);
         }
     }
@@ -3080,20 +3494,20 @@
 
       if (optionLength == 0)
         {
-          NS_LOG_DEBUG ("Discard this packet");
+          NS_LOG_INFO ("Discard this packet");
           m_dropTrace (p);
         }
     }
 
   else if (optionType == 32)       // This is the ACK option
     {
-      NS_LOG_DEBUG ("This is the ack option");
+      NS_LOG_INFO ("This is the ack option");
       dsrOption = GetOption (optionType);
       optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
 
       if (optionLength == 0)
         {
-          NS_LOG_DEBUG ("Discard this packet");
+          NS_LOG_INFO ("Discard this packet");
           m_dropTrace (p);
         }
     }
@@ -3101,30 +3515,27 @@
   else if (optionType == 3)       // This is a route error header
     {
       // populate this route error
-      NS_LOG_DEBUG ("The option type value " << (uint32_t)optionType);
+      NS_LOG_INFO ("The option type value " << (uint32_t)optionType);
 
       dsrOption = GetOption (optionType);
       optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
 
       if (optionLength == 0)
         {
-          NS_LOG_DEBUG ("Discard this packet");
+          NS_LOG_INFO ("Discard this packet");
           m_dropTrace (p);
         }
-      NS_LOG_DEBUG ("The option Length " << (uint32_t)optionLength);
+      NS_LOG_INFO ("The option Length " << (uint32_t)optionLength);
     }
 
   else if (optionType == 96)       // This is the source route option
     {
-      NS_LOG_DEBUG ("This is the source route option " << (uint32_t)optionType);
       dsrOption = GetOption (optionType);
       optionLength = dsrOption->Process (p, packet, m_mainAddress, source, ip, protocol, isPromisc, promiscSource);
-
       segmentsLeft = *(data + 3);
-      NS_LOG_DEBUG ("The segments left in source route header " << (uint32_t)segmentsLeft);
       if (optionLength == 0)
         {
-          NS_LOG_DEBUG ("Discard this packet");
+          NS_LOG_INFO ("Discard this packet");
           m_dropTrace (p);
         }
       else
@@ -3140,8 +3551,6 @@
                   // we need to make a copy in the unlikely event we hit the
                   // RX_ENDPOINT_UNREACH code path
                   // Here we can use the packet that has been get off whole DSR header
-                  NS_LOG_DEBUG ("The packet size here " << copy->GetSize ());
-                  NS_LOG_DEBUG ("The packet received " << *copy);
                   enum IpL4Protocol::RxStatus status =
                     nextProto->Receive (copy, ip, incomingInterface);
                   NS_LOG_DEBUG ("The receive status " << status);
@@ -3163,6 +3572,10 @@
                     }
                   return status;
                 }
+              else
+                {
+                  NS_FATAL_ERROR ("Should not have 0 next protocol value");
+                }
             }
           else
             {
--- a/src/dsr/model/dsr-routing.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-routing.h	Fri Apr 26 10:43:20 2013 -0400
@@ -166,6 +166,21 @@
   //\}
 
   /**
+    * \brief Connect the callback for the tracing event.
+    * \return void
+    */
+  void ConnectCallbacks ();
+  /**
+    * \brief Get the netdevice from the context.
+    * \return the netdevice we are looking for
+    */
+  Ptr<NetDevice> GetNetDeviceFromContext (std::string context);
+  /**
+    * \brief Get the elements from the tracing context.
+    * \return the elements we are looking for
+    */
+  std::vector<std::string> GetElementsFromContext (std::string context);
+  /**
     * \brief Get the node id from ip address.
     * \return the node id
     */
@@ -181,6 +196,11 @@
     */
   Ipv4Address GetIPfromMAC (Mac48Address address);
   /**
+    * \brief Get the node with give ip address.
+    * \return the node associated with the ip address
+    */
+  Ptr<Node> GetNodeWithAddress (Ipv4Address ipv4Address);
+  /**
     * \brief Print the route vector.
     */
   void PrintVector (std::vector<Ipv4Address>& vec);
@@ -209,22 +229,22 @@
                        Ipv4Address source,
                        Ipv4Address destination,
                        uint8_t protocol);
-  /*
+  /**
    * \brief Set the route to use for data packets
    * \return the route
    * \used by the option headers when sending data/control packets
    */
   Ptr<Ipv4Route> SetRoute (Ipv4Address nextHop, Ipv4Address srcAddress);
-  /*
+  /**
    * \brief Set the priority of the packet in network queue
    * \return the priority value
    */
   uint32_t GetPriority (DsrMessageType messageType);
-  /*
+  /**
    * \brief This function is responsible for sending error packets in case of break link to next hop
    */
   void SendUnreachError (Ipv4Address errorHop, Ipv4Address destination, Ipv4Address originalDst, uint8_t salvage, uint8_t protocol);
-  /*
+  /**
    * \brief This function is responsible for forwarding error packets along the route
    */
   void ForwardErrPacket (DsrOptionRerrUnreachHeader &rerr,
@@ -232,37 +252,37 @@
                          Ipv4Address nextHop,
                          uint8_t protocol,
                          Ptr<Ipv4Route> route);
-  /*
+  /**
    * \brief This function is called by higher layer protocol when sending packets
    */
   void Send (Ptr<Packet> packet, Ipv4Address source,
              Ipv4Address destination, uint8_t protocol, Ptr<Ipv4Route> route);
-  /*
+  /**
    * \brief This function is called to add ack request header for network acknowledgement
    */
   uint16_t AddAckReqHeader (Ptr<Packet> &packet, Ipv4Address nextHop);
-  /*
+  /**
    * \brief This function is called by when really sending out the packet
    */
   void SendPacket (Ptr<Packet> packet, Ipv4Address source, Ipv4Address nextHop, uint8_t protocol);
-  /*
+  /**
    * \brief This function is called to schedule sending packets from the network queue
    */
   void Scheduler (uint32_t priority);
-  /*
+  /**
    * \brief This function is called to schedule sending packets from the network queue by priority
    */
   void PriorityScheduler (uint32_t priority, bool continueWithFirst);
-  /*
+  /**
    * \brief This function is called to increase the retransmission timer for data packet in the network queue
    */
   void IncreaseRetransTimer ();
-  /*
+  /**
    * \brief This function is called to send packets down stack
    */
   bool SendRealDown (DsrNetworkQueueEntry & newEntry);
-  /*
-   * This function is responsible for sending out data packets when have route, if no route found, it will
+  /**
+   * \brief This function is responsible for sending out data packets when have route, if no route found, it will
    * cache the packet and send out route requests
    */
   void SendPacketFromBuffer (DsrOptionSRHeader const &sourceRoute,
@@ -272,60 +292,75 @@
    * \brief Find the same passive entry
    */
   bool PassiveEntryCheck (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft,
-                      uint16_t fragmentOffset, uint16_t identification, bool saveEntry);
+                          uint16_t fragmentOffset, uint16_t identification, bool saveEntry);
   /**
    * \brief Cancel the passive timer
    */
   bool CancelPassiveTimer (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft);
-  /*
-   * \brief Find the similar entries in the maintenance buffer
-   */
-  bool FindSamePackets (Ptr<Packet> packet, Ipv4Address source, Ipv4Address destination, uint8_t segsLeft);
-  /*
-   * Call the cancel packet retransmission timer function
+  /**
+   * \brief Call the cancel packet retransmission timer function
    */
   void CallCancelPacketTimer (uint16_t ackId, Ipv4Header const& ipv4Header, Ipv4Address realSrc, Ipv4Address realDst);
-  /*
-   * Cancel the network packet retransmission timer for a specific maintenance entry
+  /**
+   * \brief Cancel the network packet retransmission timer for a specific maintenance entry
    */
   void CancelNetworkPacketTimer (MaintainBuffEntry & mb);
-  /*
-   * Cancel the passive packet retransmission timer for a specific maintenance entry
+  /**
+   * \brief Cancel the passive packet retransmission timer for a specific maintenance entry
    */
   void CancelPassivePacketTimer (MaintainBuffEntry & mb);
-  /*
-   * Cancel the packet retransmission timer for a all maintenance entries with nextHop address
+  /**
+   * \brief Cancel the link packet retransmission timer for a specific maintenance entry
+   */
+  void CancelLinkPacketTimer (MaintainBuffEntry & mb);
+  /**
+   * \brief Cancel the packet retransmission timer for a all maintenance entries with nextHop address
    */
   void CancelPacketTimerNextHop (Ipv4Address nextHop, uint8_t protocol);
-  /*
-   * Salvage the packet which has been transmitted for 3 times
+  /**
+   * \brief Salvage the packet which has been transmitted for 3 times
    */
   void SalvagePacket (Ptr<const Packet> packet, Ipv4Address source, Ipv4Address dst, uint8_t protocol);
-  /*
-   * Schedule the packet retransmission when the packet has not reached to the next hop address
+  /**
+   * \brief Schedule the packet retransmission based on link-layer acknowledgment
+   * \param mb maintainenace buffer entry
+   * \param protocol the protocol number
+   */
+  void ScheduleLinkPacketRetry   (MaintainBuffEntry & mb,
+                                  uint8_t protocol);
+  /**
+   * \brief Schedule the packet retransmission based on passive acknowledgment
+   * \param mb maintainenace buffer entry
+   * \param protocol the protocol number
    */
   void SchedulePassivePacketRetry   (MaintainBuffEntry & mb,
-                                     bool onlyPassive,
                                      uint8_t protocol);
-  /*
-   * Schedule the packet retransmission when the packet has not reached to the next hop address
+  /**
+   * \brief Schedule the packet retransmission based on network layer acknowledgment
+   * \param mb maintainenace buffer entry
+   * \param isFirst see if this is the first packet retry or not
+   * \param protocol the protocol number
    */
   void ScheduleNetworkPacketRetry   (MaintainBuffEntry & mb,
                                      bool isFirst,
                                      uint8_t protocol);
-  /*
-   * This function deals with packet retransmission timer expire
+  /**
+   * \brief This function deals with packet retransmission timer expire using link acknowledgment
+   */
+  void LinkScheduleTimerExpire  (MaintainBuffEntry & mb,
+                                 uint8_t protocol);
+  /**
+   * \brief This function deals with packet retransmission timer expire using network acknowledgment
    */
   void NetworkScheduleTimerExpire  (MaintainBuffEntry & mb,
                                     uint8_t protocol);
-  /*
-   * This function deals with packet retransmission timer expire
+  /**
+   * \brief This function deals with packet retransmission timer expire using passive acknowledgment
    */
   void PassiveScheduleTimerExpire  (MaintainBuffEntry & mb,
-                                    bool onlyPassive,
                                     uint8_t protocol);
-  /*
-   * Forward the packet using the route saved in the source route option header
+  /**
+   * \brief Forward the packet using the route saved in the source route option header
    */
   void ForwardPacket (Ptr<const Packet> packet,
                       DsrOptionSRHeader &sourceRoute,
@@ -335,33 +370,42 @@
                       Ipv4Address targetAddress,
                       uint8_t protocol,
                       Ptr<Ipv4Route> route);
-  /*
-   * Broadcast the route request packet in subnet
+  /**
+   * \brief Broadcast the route request packet in subnet
    */
   void SendInitialRequest (Ipv4Address source,
                            Ipv4Address destination,
                            uint8_t protocol);
-  /*
+  /**
    * \brief Send the error request packet
    * \param the route error header
    * \param the protocol number
    */
   void SendErrorRequest (DsrOptionRerrUnreachHeader &rerr, uint8_t protocol);
-  /*
+  /**
+   * \brief Send the route request and increment the request count
+   * \param the original packet
+   * \param source address
+   * \param destination address
+   */
+  void SendRequestAndIncrement (Ptr<Packet> packet,
+                                Ipv4Address source,
+                                Ipv4Address destination);
+  /**
    * \brief Forward the route request if the node is not the destination
    * \param the original packet
    * \param source address
    */
   void SendRequest (Ptr<Packet> packet,
                     Ipv4Address source);
-  /*
+  /**
    * \brief Schedule the intermediate route request
    * \param the original packet
    * \param source The source address
    * \param destination The destination address
    */
   void ScheduleInterRequest (Ptr<Packet> packet);
-  /*
+  /**
    * \brief Send the gratuitous reply
    * \param replyTo The destination address to send the reply to
    * \param replyFrom The source address sending the reply
@@ -370,14 +414,14 @@
                             Ipv4Address replyFrom,
                             std::vector<Ipv4Address> &nodeList,
                             uint8_t protocol);
-  /*
+  /**
    * Send the route reply back to the request originator with the cumulated route
    */
   void SendReply (Ptr<Packet> packet,
                   Ipv4Address source,
                   Ipv4Address nextHop,
                   Ptr<Ipv4Route> route);
-  /*
+  /**
    * this is a generating the initial route reply from the destination address, a random delay time
    * [0, m_broadcastJitter] is used before unicasting back the route reply packet
    */
@@ -385,7 +429,7 @@
                              Ipv4Address source,
                              Ipv4Address nextHop,
                              Ptr<Ipv4Route> route);
-  /*
+  /**
    * Schedule the cached reply to a random start time to avoid possible route reply storm
    */
   void ScheduleCachedReply (Ptr<Packet> packet,
@@ -393,7 +437,7 @@
                             Ipv4Address destination,
                             Ptr<Ipv4Route> route,
                             double hops);
-  /*
+  /**
    * Send network layer acknowledgment back to the earlier hop to notify the receipt of data packet
    */
   void SendAck   (uint16_t ackId,
@@ -431,6 +475,11 @@
   IpL4Protocol::DownTargetCallback GetDownTarget (void) const;
   IpL4Protocol::DownTargetCallback6 GetDownTarget6 (void) const;
   /**
+   * \brief Get the extension number.
+   * \return extension number
+   */
+  uint8_t GetExtensionNumber () const;
+  /**
    * \brief Process method
    * Called from Ipv4L3Protocol::Receive.
    *
@@ -487,20 +536,32 @@
    * \brief Drop trace callback.
    */
   virtual void DoDispose (void);
-  /*
+  /**
    * The trace for drop, receive and send data packets
    */
   TracedCallback<Ptr<const Packet> > m_dropTrace;
   TracedCallback <const DsrOptionSRHeader &> m_txPacketTrace;
 
 private:
+
   void Start ();
   /**
+    * \brief Notify the data receipt.
+    * \return void
+    */
+  void NotifyDataReceipt (std::string context, Ptr<const Packet> p);
+  /**
    * \brief Send the route error message when the link breaks to the next hop.
    */
   void SendRerrWhenBreaksLinkToNextHop (Ipv4Address nextHop, uint8_t protocol);
   /**
    * \brief Promiscuous receive data packets destined to some other node.
+   * \param device The network device
+   * \param packet Data packet we just received
+   * \param protocol The protocol we receive, need to verify it is dsr protocol
+   * \param from The from address we received the packet
+   * \param to The address this packet is destined for
+   * \param packetType The dsr packet type, 0 is for control packet, 1 for data packet
    */
   bool PromiscReceive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &from,
                        const Address &to, NetDevice::PacketType packetType);
@@ -513,144 +574,157 @@
    */
   DsrOptionList_t m_options;
 
-  Ptr<Ipv4L3Protocol> m_ipv4;        // / Ipv4l3Protocol
+  Ptr<Ipv4L3Protocol> m_ipv4;                           ///< Ipv4l3Protocol
+
+  Ptr<Ipv4Route> m_ipv4Route;                           ///< Ipv4 Route
 
-  Ptr<Ipv4Route> m_ipv4Route;        // / Ipv4 Route
+  Ptr<Ipv4> m_ip;                                       ///< The ip ptr
 
-  Ptr<Ipv4> m_ip;                    // / The ip ptr
+  Ptr<Node> m_node;                                     ///< The node ptr
 
-  Ptr<Node> m_node;                  // / The node ptr
+  Ipv4Address m_mainAddress;                            ///< Our own Ip address
 
-  Ipv4Address m_mainAddress;         // / Our own Ip address
+  uint8_t segsLeft;                                     ///< The segment left value from SR header
 
-  uint8_t segsLeft;                  // / The segment left value from SR header
+  IpL4Protocol::DownTargetCallback m_downTarget;        ///< The callback for down layer
 
-  IpL4Protocol::DownTargetCallback m_downTarget;    // The callback for down layer
+  uint32_t m_maxNetworkSize;                            ///< Maximum network queue size
 
-  uint32_t m_maxNetworkSize;             // / Maximum network queue size
+  Time m_maxNetworkDelay;                               ///< Maximum network delay
 
-  Time m_maxNetworkDelay;                // / Maximum network delay
+  uint32_t m_discoveryHopLimit;                         ///< Maximum hops to go for route request
 
-  uint32_t m_discoveryHopLimit;             // / Maximum hops to go for route request
+  uint8_t m_maxSalvageCount;                            ///< Maximum # times to salvage a packet
 
-  uint8_t m_maxSalvageCount;             // / Maximum # times to salvage a packet
+  Time  m_requestPeriod;                                ///< The base time interval between route requests
 
-  Time  m_requestPeriod;                   // / The base time interval between route requests
+  Time m_nonpropRequestTimeout;                         ///< The non-propagation request timeout
 
-  Time m_nonpropRequestTimeout;            // / The non-propagation request timeout
+  uint32_t m_sendRetries;                               ///< # of retries have been sent for network acknowledgment
 
-  uint32_t m_sendRetries;                    // / # of retries have been sent for network acknowledgment
+  uint32_t m_passiveRetries;                            ///< # of retries have been sent for passive acknowledgment
 
-  uint32_t m_passiveRetries;                 // / # of retries have been sent for passive acknowledgment
+  uint32_t m_linkRetries;                               ///< # of retries have been sent for link acknowledgment
 
-  uint32_t m_rreqRetries;                  // /< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
+  uint32_t m_rreqRetries;                               ///< Maximum number of retransmissions of RREQ with TTL = NetDiameter to discover a route
 
-  uint32_t m_maxMaintRexmt;                  // /< Maximum number of retransmissions of data packets
+  uint32_t m_maxMaintRexmt;                             ///< Maximum number of retransmissions of data packets
 
-  Time m_nodeTraversalTime;                // / Time estimated for packet to travel between two nodes
+  Time m_nodeTraversalTime;                             ///< Time estimated for packet to travel between two nodes
 
-  uint32_t m_maxSendBuffLen;             // /< The maximum number of packets that we allow a routing protocol to buffer.
+  uint32_t m_maxSendBuffLen;                            ///< The maximum number of packets that we allow a routing protocol to buffer.
 
-  Time  m_sendBufferTimeout;               // /< The maximum period of time that a routing protocol is allowed to buffer a packet for.
+  Time  m_sendBufferTimeout;                            ///< The maximum period of time that a routing protocol is allowed to buffer a packet for.
 
-  SendBuffer m_sendBuffer;               // / The send buffer
+  SendBuffer m_sendBuffer;                              ///< The send buffer
 
-  ErrorBuffer m_errorBuffer;             // / The error buffer to save the error messages
+  ErrorBuffer m_errorBuffer;                            ///< The error buffer to save the error messages
 
-  uint32_t  m_maxMaintainLen;            // / Max # of entries for maintainance buffer
+  uint32_t  m_maxMaintainLen;                           ///< Max # of entries for maintainance buffer
 
-  Time     m_maxMaintainTime;            // / Time out for maintainance buffer
+  Time     m_maxMaintainTime;                           ///< Time out for maintainance buffer
 
-  uint32_t m_maxCacheLen;                // / Max # of cache entries for route cache
+  uint32_t m_maxCacheLen;                               ///< Max # of cache entries for route cache
 
-  Time   m_maxCacheTime;                 // / Max time for caching the route cache entry
+  Time   m_maxCacheTime;                                ///< Max time for caching the route cache entry
 
-  Time  m_maxRreqTime;                   // / Max time for caching the route request entry
+  Time  m_maxRreqTime;                                  ///< Max time for caching the route request entry
 
-  uint32_t  m_maxEntriesEachDst;         // / Max number of route entries to save for each destination
+  uint32_t  m_maxEntriesEachDst;                        ///< Max number of route entries to save for each destination
 
-  MaintainBuffer m_maintainBuffer;       // / The declaration of maintain buffer
+  MaintainBuffer m_maintainBuffer;                      ///< The declaration of maintain buffer
 
-  uint32_t m_requestId;                  // / The id assigned to each route request
+  uint32_t m_requestId;                                 ///< The id assigned to each route request
 
-  uint16_t m_ackId;                      // / The ack id assigned to each acknowledge
+  uint16_t m_ackId;                                     ///< The ack id assigned to each acknowledge
+
+  uint32_t m_requestTableSize;                          ///< The max size of the request table size
 
-  uint32_t m_requestTableSize;             // / The max size of the request table size
+  uint32_t m_requestTableIds;                           ///< The request table identifiers
+
+  uint32_t m_maxRreqId;                                 ///< The max number of request ids for a single destination
 
-  uint32_t m_requestTableIds;              // / The request table identifiers
+  Time  m_blacklistTimeout;                             ///< The black list time out
 
-  uint32_t m_maxRreqId;                  // / The max number of request ids for a single destination
+  Ipv4Address m_broadcast;                              ///< The broadcast IP address
 
-  Time  m_blacklistTimeout;                // / The black list time out
+  uint32_t m_broadcastJitter;                           ///< The max time to delay route request broadcast.
 
-  Ipv4Address m_broadcast;                 // / The broadcast IP address
+  Time  m_passiveAckTimeout;                            ///< The timeout value for passive acknowledge
 
-  uint32_t m_broadcastJitter;              // / The max time to delay route request broadcast.
+  uint32_t m_tryPassiveAcks;                            ///< Maximum number of packet transmission using passive acknowledgment
 
-  Time  m_passiveAckTimeout;               // / The timeout value for passive acknowledge
+  Time  m_linkAckTimeout;                               ///< The timeout value for link acknowledge
 
-  uint32_t m_tryPassiveAcks;               // /< Maximum number of packet transmission using passive acknowledgment
+  uint32_t m_tryLinkAcks;                               ///< Maximum number of packet transmission using link acknowledgment
 
-  Timer m_sendBuffTimer;                 // / The send buffer timer
+  Timer m_sendBuffTimer;                                ///< The send buffer timer
 
-  Time m_sendBuffInterval;               // / how often to check send buffer
+  Time m_sendBuffInterval;                              ///< how often to check send buffer
 
-  Time  m_gratReplyHoldoff;                // / The max gratuitous reply hold off time
+  Time  m_gratReplyHoldoff;                             ///< The max gratuitous reply hold off time
 
-  Time m_maxRequestPeriod;                 // / The max request period
+  Time m_maxRequestPeriod;                              ///< The max request period
 
-  uint32_t m_graReplyTableSize;            // / Set the gratuitous reply table size
+  uint32_t m_graReplyTableSize;                         ///< Set the gratuitous reply table size
 
-  std::string m_cacheType;                // / The type of route cache
+  std::string m_cacheType;                              ///< The type of route cache
 
-  std::string m_routeSortType;         // / The type of route sort methods
+  std::string m_routeSortType;                          ///< The type of route sort methods
+
+  uint32_t m_stabilityDecrFactor;                       ///< The initial decrease factor for link cache
 
-  uint64_t m_stabilityDecrFactor;           // / The initial decrease factor for link cache
+  uint32_t m_stabilityIncrFactor;                       ///< The initial increase factor for link cache
 
-  uint64_t m_stabilityIncrFactor;           // / The initial increase factor for link cache
+  Time m_initStability;                                 ///< The initial stability value for link cache
 
-  Time m_initStability;                 // / The initial stability value for link cache
+  Time m_minLifeTime;                                   ///< The min life time
 
-  Time m_minLifeTime;                   // / The min life time
+  Time m_useExtends;                                    ///< The use extension of the life time for link cache
 
-  Time m_useExtends;                    // / The use extension of the life time for link cache
+  bool m_subRoute;                                      ///< Whether to save sub route or not
 
-  bool m_subRoute;                        // / Whether to save sub route or not
+  Time m_retransIncr;                                   ///< the increase time for retransmission timer when face network congestion
 
-  Time m_retransIncr;                     // / the increase time for retransmission timer when face network congestion
+  std::vector<Ipv4Address> m_finalRoute;                ///< The route cache
 
-  std::vector<Ipv4Address> m_finalRoute;                 // / The route cache
+  std::map<Ipv4Address, Timer> m_addressReqTimer;       ///< Map IP address + RREQ timer.
 
-  std::map<Ipv4Address, Timer> m_addressReqTimer;        // / Map IP address + RREQ timer.
+  std::map<Ipv4Address, Timer> m_nonPropReqTimer;       ///< Map IP address + RREQ timer.
 
-  std::map<Ipv4Address, Timer> m_nonPropReqTimer;        // / Map IP address + RREQ timer.
+  std::map<NetworkKey, Timer>  m_addressForwardTimer;   ///< Map network key + forward timer.
 
-  std::map<NetworkKey, Timer>  m_addressForwardTimer;    // / Map network key + forward timer.
+  std::map<NetworkKey, uint32_t> m_addressForwardCnt;   ///< Map network key + forward counts.
 
-  std::map<NetworkKey, uint32_t> m_addressForwardCnt;      // / Map network key + forward counts.
+  std::map<PassiveKey, uint32_t> m_passiveCnt;          ///< Map packet key + passive forward counts.
 
-  std::map<PassiveKey, uint32_t> m_passiveCnt;             // / Map packet key + passive forward counts.
+  std::map<PassiveKey, Timer> m_passiveAckTimer;        ///< The timer for passive acknowledgment
 
-  std::map<PassiveKey, Timer> m_passiveAckTimer;         // / The timer for passive acknowledgment
+  std::map<LinkKey, uint32_t> m_linkCnt;                ///< Map packet key + link forward counts.
 
-  Ptr<dsr::RouteCache> m_routeCache;      // / A "drop-front" queue used by the routing layer to cache routes found.
+  std::map<LinkKey, Timer> m_linkAckTimer;              ///< The timer for link acknowledgment
 
-  Ptr<dsr::RreqTable> m_rreqTable;        // / A "drop-front" queue used by the routing layer to cache route request sent.
+  Ptr<dsr::RouteCache> m_routeCache;                    ///< A "drop-front" queue used by the routing layer to cache routes found.
+
+  Ptr<dsr::RreqTable> m_rreqTable;                      ///< A "drop-front" queue used by the routing layer to cache route request sent.
 
   Ptr<dsr::PassiveBuffer> m_passiveBuffer;              ///< A "drop-front" queue used by the routing layer to cache route request sent.
 
-  uint32_t m_numPriorityQueues;
+  uint32_t m_numPriorityQueues;                         ///< The number of priority queues used
+
+  bool m_linkAck;                                       ///< define if we use link acknowledgement or not
 
-  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> > m_priorityQueue;   // / priority queueus
+  std::map<uint32_t, Ptr<dsr::DsrNetworkQueue> > m_priorityQueue;   ///< priority queues
 
-  GraReply m_graReply;                    // / The gratuitous route reply.
+  GraReply m_graReply;                                  ///< The gratuitous route reply.
 
-  std::vector<Ipv4Address> m_clearList;   // / The node that is clear to send packet to
+  std::vector<Ipv4Address> m_clearList;                 ///< The node that is clear to send packet to
+
+  std::vector<Ipv4Address> m_addresses;                 ///< The bind ipv4 addresses with next hop, src, destination address in sequence
 
-  std::vector<Ipv4Address> m_addresses;   // / The bind ipv4 addresses with next hop, src, destination address in sequence
+  std::map <std::string, uint32_t> m_macToNodeIdMap;    ///< The map of mac address to node id
 
-  /// Provides uniform random variables.
-  Ptr<UniformRandomVariable> m_uniformRandomVariable;
+  Ptr<UniformRandomVariable> m_uniformRandomVariable;    ///< Provides uniform random variables.
 };
 }  /* namespace dsr */
 }  /* namespace ns3 */
--- a/src/dsr/model/dsr-rreq-table.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-rreq-table.h	Fri Apr 26 10:43:20 2013 -0400
@@ -70,7 +70,7 @@
   uint32_t m_reqNo;
   Time m_expire;
 };
-/*
+/**
  * The request entry for intermediate nodes to check if they have received this request or not
  * This is used to control the duplication request from being processed
  */
@@ -84,7 +84,7 @@
   {
   }
   /**
-   * Compare send buffer entries
+   * \brief Compare send buffer entries
    * \return true if equal
    */
   bool operator== (ReceivedRreqEntry const & o) const
@@ -213,18 +213,20 @@
    * set the unidirectional entry as QUESTIONABLE state
    */
   void Invalidate ();
-  /** Verify if entry is unidirectional or not(e.g. add this neighbor to "blacklist" for blacklistTimeout period)
+  /**
+   * \brief Verify if entry is unidirectional or not(e.g. add this neighbor to "blacklist" for blacklistTimeout period)
    * \param neighbor - neighbor address link to which assumed to be unidirectional
    * \return true on success
    */
   BlackList* FindUnidirectional (Ipv4Address neighbor);
-  /** Mark entry as unidirectional (e.g. add this neighbor to "blacklist" for blacklistTimeout period)
+  /**
+   * \brief Mark entry as unidirectional (e.g. add this neighbor to "blacklist" for blacklistTimeout period)
    * \param neighbor - neighbor address link to which assumed to be unidirectional
    * \param blacklistTimeout - time for which the neighboring node is put into the blacklist
    * \return true on success
    */
   bool MarkLinkAsUnidirectional (Ipv4Address neighbor, Time blacklistTimeout);
-  // / Remove all expired black list entries
+  ///< Remove all expired black list entries
   void PurgeNeighbor ();
   // ----------------------------------------------------------------------------------------------------------
   /**
--- a/src/dsr/model/dsr-rsendbuff.cc	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-rsendbuff.cc	Fri Apr 26 10:43:20 2013 -0400
@@ -55,8 +55,8 @@
   for (std::vector<SendBuffEntry>::const_iterator i = m_sendBuffer.begin (); i
        != m_sendBuffer.end (); ++i)
     {
-      NS_LOG_INFO ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid ()
-                                << " dst " << i->GetDestination () << " " << entry.GetDestination ());
+//      NS_LOG_DEBUG ("packet id " << i->GetPacket ()->GetUid () << " " << entry.GetPacket ()->GetUid ()
+//                                << " dst " << i->GetDestination () << " " << entry.GetDestination ());
 
       if ((i->GetPacket ()->GetUid () == entry.GetPacket ()->GetUid ())
           && (i->GetDestination () == entry.GetDestination ()))
@@ -153,7 +153,7 @@
   /*
    * Purge the buffer to eliminate expired entries
    */
-  NS_LOG_DEBUG ("The send buffer size " << m_sendBuffer.size ());
+  NS_LOG_INFO ("The send buffer size " << m_sendBuffer.size ());
   IsExpired pred;
   for (std::vector<SendBuffEntry>::iterator i = m_sendBuffer.begin (); i
        != m_sendBuffer.end (); ++i)
--- a/src/dsr/model/dsr-rsendbuff.h	Fri Apr 26 02:00:09 2013 +0200
+++ b/src/dsr/model/dsr-rsendbuff.h	Fri Apr 26 10:43:20 2013 -0400
@@ -156,18 +156,13 @@
   }
 
 private:
-  // / The send buffer to cache unsent packet
-  std::vector<SendBuffEntry> m_sendBuffer;
-  // / Remove all expired entries
-  void Purge ();
-  // / Notify that packet is dropped from queue by timeout
-  void Drop (SendBuffEntry en, std::string reason);
-  // / The maximum number of packets that we allow a routing protocol to buffer.
-  uint32_t m_maxLen;
-  // / The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
-  Time m_sendBufferTimeout;
-  // / Check if the send buffer entry is the same or not
-  static bool IsEqual (SendBuffEntry en, const Ipv4Address dst)
+
+  std::vector<SendBuffEntry> m_sendBuffer;                      ///< The send buffer to cache unsent packet
+  void Purge ();                                                ///< Remove all expired entries
+  void Drop (SendBuffEntry en, std::string reason);             ///< Notify that packet is dropped from queue by timeout
+  uint32_t m_maxLen;                                            ///< The maximum number of packets that we allow a routing protocol to buffer.
+  Time m_sendBufferTimeout;                                     ///< The maximum period of time that a routing protocol is allowed to buffer a packet for, seconds.
+  static bool IsEqual (SendBuffEntry en, const Ipv4Address dst) ///< Check if the send buffer entry is the same or not
   {
     return (en.GetDestination () == dst);
   }