Bug 1172 Special case handling for duplicates,forwards and some doxygen fixes
authorJohn Abraham <john.abraham@gatech.edu>
Sun, 10 Jul 2011 13:20:34 -0400
changeset 7362 36b42a8b16d1
parent 7361 e15cdf7d15b4
child 7363 0f96f5beb8c7
Bug 1172 Special case handling for duplicates,forwards and some doxygen fixes
src/netanim/helper/animation-interface-helper.cc
src/netanim/helper/animation-interface-helper.h
src/netanim/model/animation-interface.cc
src/netanim/model/animation-interface.h
--- a/src/netanim/helper/animation-interface-helper.cc	Sat Jul 09 17:05:12 2011 +0530
+++ b/src/netanim/helper/animation-interface-helper.cc	Sun Jul 10 13:20:34 2011 -0400
@@ -27,62 +27,58 @@
 
 namespace ns3 {
 AnimPacketInfo::AnimPacketInfo()
-  : m_txnd (0), m_nRx (0), m_nRxEnd (0), m_fbTx (0), m_lbTx (0), 
-    transmitter_loc (Vector (0,0,0))
+  : m_txnd (0), m_fbTx (0), m_lbTx (0), 
+    m_txLoc (Vector (0,0,0))
 {
 }
 
-AnimPacketInfo::AnimPacketInfo(Ptr<const NetDevice> nd, const Time& fbTx, 
+AnimPacketInfo::AnimPacketInfo(Ptr <const NetDevice> txnd, const Time& fbTx, 
   const Time& lbTx, Vector txLoc)
-  : m_txnd (nd), m_nRx (0), m_nRxEnd (0),
-    m_fbTx (fbTx.GetSeconds ()), m_lbTx (lbTx.GetSeconds ()), transmitter_loc (txLoc), 
-    reception_range (0) 
+  : m_txnd (txnd), m_fbTx (fbTx.GetSeconds ()), m_lbTx (lbTx.GetSeconds ()), 
+    m_txLoc (txLoc)
 {
 }
 
-void AnimPacketInfo::ProcessRxBegin (Ptr<const NetDevice> nd, const Time& fbRx,
-                                 Vector rxLoc)
+void AnimPacketInfo::ProcessRxBegin (Ptr<const NetDevice> nd, const Time& fbRx)
 {
-  m_rx[nd->GetNode ()->GetId ()] = AnimRxInfo (fbRx,nd);
-  m_nRx++;
-  reception_range = std::max (reception_range,CalculateDistance (transmitter_loc,rxLoc));
+  m_rx[nd->GetNode ()->GetId ()] = AnimRxInfo (fbRx, nd, 0);
 }
 
-bool AnimPacketInfo::ProcessRxEnd (Ptr<const NetDevice> nd, const Time& lbRx)
-
+bool AnimPacketInfo::ProcessRxEnd (Ptr<const NetDevice> nd, const Time& lbRx, Vector rxLoc)
 {
   uint32_t NodeId = nd->GetNode ()->GetId (); 
   // Find the RxInfo
-  if (m_rx.find(NodeId) != m_rx.end ())
-    { 
-      // Check if the NetDevice matches. A node may have several NetDevices
-      if (m_rx[NodeId].m_rxnd != nd) 
-        {
-          return false; 
-        }
-      m_rx[NodeId].m_lbRx = lbRx.GetSeconds ();
-      firstlastbitDelta = m_rx[NodeId].m_lbRx - m_rx[NodeId].m_fbRx;
-      m_nRxEnd++;
-      if (m_nRxEnd == m_nRx) 
-        {
-          return true;
-        }
-      return false; // Still more RxEnd notifications expected
+  if (m_rx.find (NodeId) == m_rx.end ())
+    {
+      return false;
+    } 
+  AnimRxInfo& rxInfo = m_rx[NodeId];
+  // Check if the NetDevice matches. A node may have several NetDevices
+  if (rxInfo.m_rxnd != nd) 
+    {
+      return false; 
     }
-   NS_ASSERT ("Received RxEnd notification but RxInfo never existed");
-  return false; // Still more rxEnd expected
+  rxInfo.rxRange = CalculateDistance (m_txLoc, rxLoc);
+  rxInfo.m_lbRx = lbRx.GetSeconds ();
+  firstlastbitDelta = rxInfo.m_lbRx - rxInfo.m_fbRx;
+  return true;
+}
+
+AnimRxInfo AnimPacketInfo::GetRxInfo (Ptr<const NetDevice> nd)
+{
+  uint32_t NodeId = nd->GetNode ()->GetId (); 
+  NS_ASSERT (m_rx.find (NodeId) != m_rx.end ()); 
+  return m_rx[NodeId];
+}
+
+void AnimPacketInfo::RemoveRxInfo (Ptr<const NetDevice> nd)
+{
+  uint32_t NodeId = nd->GetNode ()->GetId (); 
+  m_rx.erase (m_rx.find (NodeId));
 }
 
 void AnimPacketInfo::ProcessRxDrop (Ptr<const NetDevice> nd)
 {
-  if (m_rx.find (nd->GetNode ()->GetId ()) == m_rx.end()) 
-    {
-      NS_LOG_DEBUG ("Received RxDrop notification"); 
-      return;
-    }
-  // Remove any entry for which an RxBegin notification was received
-  m_rx.erase (m_rx.find (nd->GetNode ()->GetId ()));
-  m_nRx--;
 }
 
 
--- a/src/netanim/helper/animation-interface-helper.h	Sat Jul 09 17:05:12 2011 +0530
+++ b/src/netanim/helper/animation-interface-helper.h	Sun Jul 10 13:20:34 2011 -0400
@@ -56,27 +56,43 @@
 
   /**
    * \brief Constructor
-   * \param First-bit Receive time
-   * \param Ptr to NetDevice used for reception
+   * \param fbRx First-bit Receive time
+   * \param nd NetDevice where packet was received
+   * \param rxRange Reception range 
    *
    */
-  AnimRxInfo (const Time& fbRx, Ptr <const NetDevice> nd)
-    : m_fbRx (fbRx.GetSeconds ()), m_lbRx (0), m_rxnd (nd) {}
+  AnimRxInfo (const Time& fbRx, Ptr <const NetDevice> nd ,double rxRange)
+    : m_fbRx (fbRx.GetSeconds ()), m_lbRx (0), m_rxnd (nd), 
+      rxRange (rxRange) {}
 
-  /* 
-   * First bit receive time
+  /** 
+   * \brief First bit receive time
+   * \param m_fbRx First bit receive time
+   *
    */
   double m_fbRx;            
   
-  /* 
-   * Last bit receive time
+  /** 
+   * \brief Last bit receive time
+   * \param m_lbRx Last bit receive time
+   *
    */
   double m_lbRx;             
 
-  /*
-   * Ptr to receiving Net Device
+  /**
+   * \brief Ptr to receiving NetDevice
+   * \param m_rxnd Ptr to receiving NetDevice
+   *
    */
   Ptr <const NetDevice> m_rxnd;
+
+  /** 
+   * \brief Reception range
+   * \param rxRange Reception range
+   *
+   */
+  double rxRange;
+
 };
 
 /**
@@ -101,88 +117,99 @@
 
   /**
    * \brief Default constructor
+   *
    */
   AnimPacketInfo ();
   
   /**
    * \brief Constructor
-   * \param Ptr to NetDevice transmitted on
-   * \param First bit transmit time
-   * \param Last bit transmit time
-   * \param Transmitter Location
+   * \param tx_nd Ptr to NetDevice that is transmitting
+   * \param fbTx First bit transmit time
+   * \param lbTx Last bit transmit time
+   * \param txLoc Transmitter Location
    *
    */
-  AnimPacketInfo(Ptr<const NetDevice> nd,
-                 const Time& fbTx, const Time& lbTx,Vector txLoc);
-
+  AnimPacketInfo(Ptr <const NetDevice> tx_nd, const Time& fbTx, const Time& lbTx,Vector txLoc);
+  
   /**
-   * Ptr to NetDevice used for transmission
-   */
-  Ptr<const NetDevice> m_txnd;
-
-  /**
-   * Number of receivers
-   */
-  uint32_t m_nRx;      
+   * \brief Ptr to NetDevice that is transmitting
+   * \param m_txnd NetDevice that is transmitting
+   *
+   */ 
+  Ptr <const NetDevice> m_txnd;
 
   /** 
-   * Number of RxEnd trace callbacks
-   */
-  uint32_t m_nRxEnd;   
-
-  /** 
-   * First bit transmission time
+   * \brief First bit transmission time
+   * \param m_fbTx First bit transmission time
+   *
    */
   double   m_fbTx;     
 
   /**
-   * Last bit transmission time
+   * \brief Last bit transmission time
+   * \param m_lbTx Last bit transmission time
+   *
    */
   double   m_lbTx;     
 
   /**
-   * Transmitter's location
+   * \brief Transmitter's location
+   * \param m_txLoc Transmitter's Location
+   *
    */
-  Vector   transmitter_loc;
+  Vector   m_txLoc;
 
-  /** 
-   * Receptiion range
-   */
-  double reception_range;
 
   /**
-   * Collection of receivers
+   * \brief Collection of receivers
+   * \param m_rx Collection of receivers
+   *
    */
   std::map<uint32_t,AnimRxInfo> m_rx;
 
   /**
    * \brief Process RxBegin notifications
-   * \param Ptr to NetDevice where packet was received
-   * \param First bit receive time
-   * \param Location of the transmitter
+   * \param nd Ptr to NetDevice where packet was received
+   * \param fbRx First bit receive time
    *
    */
-  void ProcessRxBegin (Ptr <const NetDevice> nd, const Time& fbRx,
-                   Vector rxLoc);
+  void ProcessRxBegin (Ptr <const NetDevice> nd, const Time& fbRx);
 
   /**
    * \brief Process RxEnd notifications
-   * \param Ptr to NetDevice where packet was received
-   * \param First bit receive time
+   * \param nd Ptr to NetDevice where packet was received
+   * \param fbRx First bit receive time
+   * \param rxLoc Location of receiver
+   * \returns true if RxEnd notification was expected and processed
    *
    */
-  bool ProcessRxEnd (Ptr <const NetDevice> nd, const Time& fbRx);
+  bool ProcessRxEnd (Ptr <const NetDevice> nd, const Time& fbRx, Vector rxLoc);
 
   /**
    * \brief Process RxDrop notifications
-   * \param Ptr to NetDevice where packet was dropped on reception
+   * \param nd Ptr to NetDevice where packet was dropped on reception
    *
    */
   void ProcessRxDrop (Ptr <const NetDevice> nd);
+  
+  /**
+   * \brief GetRxInfo
+   * \param nd Ptr to NetDevice where packet was received
+   * \returns AnimRxInfo object
+   *
+   */ 
+  AnimRxInfo GetRxInfo (Ptr <const NetDevice> nd);
+
+  /**
+   * \brief RemoveRxInfo
+   * \param nd Ptr to NetDevice where packet was received
+   *
+   */ 
+  void RemoveRxInfo (Ptr <const NetDevice> nd);
 
   /**
    * \brief Time delta between First bit Rx and Last bit Rx
-   *
+   * \param firstlastbitDelta Time delta between First bit Rx and Last bit Rx
    */
    double firstlastbitDelta;
 
--- a/src/netanim/model/animation-interface.cc	Sat Jul 09 17:05:12 2011 +0530
+++ b/src/netanim/model/animation-interface.cc	Sun Jul 10 13:20:34 2011 -0400
@@ -43,6 +43,8 @@
 #include "ns3/packet.h"
 #include "ns3/simulator.h"
 #include "ns3/animation-interface-helper.h"
+#include "ns3/wifi-mac-header.h"
+#include "ns3/wimax-mac-header.h"
 
 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
 
@@ -51,21 +53,21 @@
 AnimationInterface::AnimationInterface ()
   : m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
     usingSockets (false), mport (0), outputfilename (""),
-    OutputFileSet (false), ServerPortSet (false)
+    OutputFileSet (false), ServerPortSet (false), gAnimUid (0)
 {
 }
 
 AnimationInterface::AnimationInterface (const std::string fn, bool usingXML)
   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), 
     usingSockets (false), mport (0), outputfilename (fn),
-    OutputFileSet (false), ServerPortSet (false)
+    OutputFileSet (false), ServerPortSet (false), gAnimUid (0)
 {
 }
 
 AnimationInterface::AnimationInterface (const uint16_t port, bool usingXML)
   : m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)), 
     usingSockets (true), mport (port), outputfilename (""),
-    OutputFileSet (false), ServerPortSet (false)
+    OutputFileSet (false), ServerPortSet (false), gAnimUid (0)
 {
 }
 
@@ -127,15 +129,15 @@
                 // which is done to support a platform like MinGW
 }
 
-bool AnimationInterface::WifiPacketIsPending (uint64_t Uid)
+bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
 {
-  return (pendingWifiPackets.find (Uid) != pendingWifiPackets.end ());
+  return (pendingWifiPackets.find (AnimUid) != pendingWifiPackets.end ());
 }
 
 
-bool AnimationInterface::WimaxPacketIsPending (uint64_t Uid)
+bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
 {
-  return (pendingWimaxPackets.find (Uid) != pendingWimaxPackets.end ());
+  return (pendingWimaxPackets.find (AnimUid) != pendingWimaxPackets.end ());
 }
 
 void AnimationInterface::SetMobilityPollInterval (Time t)
@@ -146,15 +148,15 @@
 Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
 {
   Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
-  Vector v(0,0,0);
-  if (!loc)
-    {
-      return v;
-    }
+  Vector v(100,100,0);
   if (loc)
     {
       v = loc->GetPosition ();
     }
+  else
+   {
+     NS_LOG_WARN ( "Node:" << n->GetId () << " Does not have a mobility model");
+   }
   nodeLocation[n->GetId ()] = v;
   return v;
 }
@@ -190,28 +192,17 @@
   // Find the min/max x/y for the xml topology element
   topo_minX = 0;
   topo_minY = 0;
-  topo_maxX = 1000;
-  topo_maxY = 1000;
-  bool   first = true;
+  topo_maxX = 0;
+  topo_maxY = 0;
   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
     {
       Ptr<Node> n = *i;
+      NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
       Vector v = UpdatePosition (n); 
-      if (first)
-        {
-          topo_minX = v.x;
-          topo_minY = v.y;
-          topo_maxX = v.x;
-          topo_maxY = v.y;
-          first = false;
-        }
-      else
-        {
-          topo_minX = std::min (topo_minX, v.x);
-          topo_minY = std::min (topo_minY, v.y);
-          topo_maxX = std::max (topo_maxX, v.x);
-          topo_maxY = std::max (topo_maxY, v.y);
-        }
+      topo_minX = std::min (topo_minX, v.x);
+      topo_minY = std::min (topo_minY, v.y);
+      topo_maxX = std::max (topo_maxX, v.x);
+      topo_maxY = std::max (topo_maxY, v.y);
     }
 
   AddMargin ();
@@ -223,6 +214,7 @@
       oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
       WriteN (m_fHandle, oss.str ());
     }
+  NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
   // Dump the topology
   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
     {
@@ -243,6 +235,7 @@
 
       WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ());
     }
+  NS_LOG_INFO ("Setting p2p links");
   // Now dump the p2p links
   for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
     {
@@ -280,7 +273,6 @@
                           oss << "0.0 L "  << n1Id << " " << n2Id << std::endl;
                         }
                       WriteN (m_fHandle, oss.str ());
-
                     }
                 }
             }
@@ -350,13 +342,57 @@
   topo_minY -= h * 0.05;
   topo_maxX = topo_minX + w * 1.5;
   topo_maxY = topo_minY + h * 1.5;
+  NS_LOG_INFO ("Added Canvas Margin:" << topo_minX << "," <<
+               topo_minY << "," << topo_maxX << "," << topo_maxY);                 
 }
+
+std::vector <Ptr <Node> >  AnimationInterface::RecalcTopoBounds ()
+{
+  std::vector < Ptr <Node> > MovedNodes;
+  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
+    {
+      Ptr<Node> n = *i;
+      NS_ASSERT (n);
+      Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
+      Vector newLocation;
+      if (!mobility)
+        {
+          newLocation = GetPosition (n);
+        }
+      else
+        {
+          newLocation = mobility->GetPosition ();
+        }
+      if (!NodeHasMoved (n, newLocation))
+        {
+          continue; //Location has not changed
+        }
+      else
+        {
+          UpdatePosition (n, newLocation);
+          RecalcTopoBounds (newLocation);
+          MovedNodes.push_back (n);
+        }
+    }
+  return MovedNodes;
+}
+
 void AnimationInterface::RecalcTopoBounds (Vector v)
 {
+  double oldminX = topo_minX;
+  double oldminY = topo_minY;
+  double oldmaxX = topo_maxX;
+  double oldmaxY = topo_maxY;
   topo_minX = std::min (topo_minX, v.x);
   topo_minY = std::min (topo_minY, v.y);
   topo_maxX = std::max (topo_maxX, v.x);
   topo_maxY = std::max (topo_maxY, v.y);
+  
+  if ((topo_minX != oldminX) || (topo_minY != oldminY) ||
+      (topo_maxX != oldmaxX) || (topo_maxY != oldmaxY))
+    {
+      AddMargin ();
+    } 
 }
 
 int AnimationInterface::WriteN (int h, const char* data, uint32_t count)
@@ -441,6 +477,32 @@
   return n->GetDevice (atoi (elements[3].c_str ()));
 }
                                   
+void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
+{
+  NS_ASSERT (pktinfo.m_txnd);
+  pendingWifiPackets[AnimUid] = pktinfo;
+}
+
+void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
+{
+  NS_ASSERT (pktinfo.m_txnd);
+  pendingWimaxPackets[AnimUid] = pktinfo;
+}
+
+
+uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
+{
+  AnimByteTag tag;
+  if (p->FindFirstMatchingByteTag (tag))
+    {
+      return tag.Get ();
+    }
+  else
+    {
+      return 0;
+    }
+}
+
 void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
                                           Ptr<const Packet> p)
 {
@@ -449,10 +511,13 @@
   Ptr <Node> n = ndev->GetNode ();
   NS_ASSERT (n);
   // Add a new pending wireless
-  uint64_t Uid = p->GetUid ();
-  NS_LOG_INFO ("TxBeginTrace for packet:" << Uid);
-  pendingWifiPackets[Uid] =
-  AnimPacketInfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
+  gAnimUid++;
+  NS_LOG_INFO ("TxBeginTrace for packet:" << gAnimUid);
+  AnimByteTag tag;
+  tag.Set (gAnimUid);
+  p->AddByteTag (tag);
+  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
+  AddPendingWifiPacket (gAnimUid, pktinfo);
 }
 
 void AnimationInterface::WifiPhyTxEndTrace (std::string context,
@@ -466,10 +531,10 @@
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
   // Erase pending wifi
-  uint64_t Uid = p->GetUid ();
-  NS_LOG_INFO ("TxDropTrace for packet:" << Uid);
-  NS_ASSERT (WifiPacketIsPending (Uid) == true);
-  pendingWifiPackets.erase (pendingWifiPackets.find (Uid));
+  uint64_t AnimUid = GetAnimUidFromPacket (p);
+  NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
+  NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
+  pendingWifiPackets.erase (pendingWifiPackets.find (AnimUid));
 }
 
 
@@ -478,12 +543,10 @@
 {
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
-  Ptr <Node> n = ndev->GetNode ();
-  NS_ASSERT (n);
-  uint64_t Uid = p->GetUid ();
-  NS_LOG_INFO ("RxBeginTrace for packet:" << Uid);
-  NS_ASSERT (WifiPacketIsPending (Uid) == true);
-  pendingWifiPackets[Uid].ProcessRxBegin (ndev, Simulator::Now (), UpdatePosition (n));
+  uint64_t AnimUid = GetAnimUidFromPacket (p);
+  NS_LOG_INFO ("RxBeginTrace for packet:" << AnimUid);
+  NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
+  pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
 }
 
 
@@ -492,14 +555,17 @@
 {
   Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
   NS_ASSERT (ndev);
-  uint64_t Uid = p->GetUid ();
-  NS_ASSERT (WifiPacketIsPending (Uid) == true);
-  AnimPacketInfo& pkt = pendingWifiPackets[Uid];
-  if (pkt.ProcessRxEnd (ndev, Simulator::Now ()))
+  Ptr <Node> n = ndev->GetNode ();
+  NS_ASSERT (n);
+  uint64_t AnimUid = GetAnimUidFromPacket (p);
+  NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
+  AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
+  if (pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n)))
     {
-      NS_LOG_INFO ("RxEndTrace for packet:" << Uid << " complete");
-      OutputWirelessPacket (Uid, pkt);
-      pendingWifiPackets.erase (pendingWifiPackets.find (Uid));;
+      AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
+      NS_LOG_INFO ("RxEndTrace for packet:" << AnimUid << " complete");
+      OutputWirelessPacket (pktInfo, pktrxInfo);
+      pktInfo.RemoveRxInfo (ndev);
     }
 }
 
@@ -507,12 +573,6 @@
 void AnimationInterface::WifiPhyRxDropTrace (std::string context,
                                              Ptr<const Packet> p)
 {
-  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
-  NS_ASSERT (ndev);
-  uint64_t Uid = p->GetUid ();
-  NS_LOG_INFO ("RxDropTrace for packet:"<< Uid);
-  //NS_ASSERT (WifiPacketIsPending (Uid) == true);
-  pendingWifiPackets[Uid].ProcessRxDrop (ndev);
 }
 
 void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
@@ -521,11 +581,14 @@
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
   NS_ASSERT (n);
-  uint64_t Uid = p->GetUid ();
-  NS_LOG_INFO ("WimaxTxTrace for packet:" << Uid);
-  pendingWimaxPackets[Uid] =
-  AnimPacketInfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.0001), UpdatePosition (n));
-  //HACK:TODO 0.0001 is used until Wimax implements TxBegin and TxEnd traces
+  gAnimUid++;
+  NS_LOG_INFO ("WimaxTxTrace for packet:" << gAnimUid);
+  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
+  //TODO 0.0001 is used until Wimax implements TxBegin and TxEnd traces
+  AnimByteTag tag;
+  tag.Set (gAnimUid);
+  p->AddByteTag (tag);
+  AddPendingWimaxPacket (gAnimUid, pktinfo);
 }
 
 
@@ -535,25 +598,30 @@
   NS_ASSERT (ndev);
   Ptr <Node> n = ndev->GetNode ();
   NS_ASSERT (n);
-  uint64_t Uid = p->GetUid ();
-  NS_ASSERT (WimaxPacketIsPending (Uid) == true);
-  AnimPacketInfo& pktinfo = pendingWimaxPackets[Uid];
-  pktinfo.ProcessRxBegin (ndev, Simulator::Now (), UpdatePosition (n));
-  pktinfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.0001));
-  //HACK:TODO 0.0001 is used until Wimax implements RxBegin and RxEnd traces
-  NS_LOG_INFO ("WimaxRxTrace for packet:" << Uid);
-  OutputWirelessPacket (Uid, pktinfo);
-
+  uint64_t AnimUid = GetAnimUidFromPacket (p);
+  NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
+  AnimPacketInfo& pktInfo = pendingWimaxPackets[AnimUid];
+  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
+  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
+  //TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
+  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
+  OutputWirelessPacket (pktInfo, pktrxInfo);
 }
 
 void AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
 
 {
   Ptr <Node> n = mobility->GetObject <Node> ();
-  if (!n) return;
-  if (!mobility) return; 
+  NS_ASSERT (n);
   Vector v ;
-  v = mobility->GetPosition ();
+  if (!mobility)
+    {
+      v = GetPosition (n);
+    } 
+  else
+    {
+      v = mobility->GetPosition ();
+    }
   UpdatePosition (n,v);
   RecalcTopoBounds (v);
   std::ostringstream oss; 
@@ -581,22 +649,15 @@
 
 void AnimationInterface::MobilityAutoCheck ()
 {
+  std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
   std::ostringstream oss;
   oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
-  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
+  for (uint32_t i = 0; i < MovedNodes.size (); i++)
     {
-      Ptr <Node> n = *i;
-      if (!n) continue;
-      Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
-      if (!mobility) continue;
-      Vector newLocation = mobility->GetPosition ();
-      if (!NodeHasMoved (n, newLocation))
-        {
-          continue; //Location has not changed
-        }
-      UpdatePosition (n, newLocation);
-      RecalcTopoBounds (newLocation);
-      oss << GetXMLOpenClose_node (0,n->GetId (),newLocation.x,newLocation.y);
+      Ptr <Node> n = MovedNodes [i];
+      NS_ASSERT (n);
+      Vector v = GetPosition (n);
+      oss << GetXMLOpenClose_node (0,n->GetId (), v.x, v.y);
     }
   oss << GetXMLClose ("topology");
   WriteN (m_fHandle, oss.str ());
@@ -653,41 +714,24 @@
     </information>\n";
 return s;
 }
-void AnimationInterface::OutputWirelessPacket (uint32_t uid, AnimPacketInfo& pktInfo)
+
+void AnimationInterface::OutputWirelessPacket (AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
 {
-  if (!m_xml) return;
+  NS_ASSERT (m_xml);
   std::ostringstream oss;
-  RxInfoIterator p;
+  NS_ASSERT (pktInfo.m_txnd);
   uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
 
-  // double lbTx = pktInfo.m_lbTx; //This is not yet implemented
-  // HACK: TODO figure out lbTx from the delta of the first Rx packet
-  // Ideally all Phy interfaces should have implemented TxEnd notifications
-  // But currently that is not the case
-
-  double lbTx = pktInfo.firstlastbitDelta + pktInfo.m_fbTx; 
-  oss << GetXMLOpen_wpacket (0,nodeId,pktInfo.m_fbTx,lbTx,pktInfo.reception_range);
+  double lbTx = pktInfo.firstlastbitDelta + pktInfo.m_fbTx;
+  oss << GetXMLOpen_wpacket (0, nodeId, pktInfo.m_fbTx, lbTx, pktrxInfo.rxRange);
 
-  // Now add each rx
-  for (p = pktInfo.m_rx.begin (); p != pktInfo.m_rx.end (); p++)
-    {
-      AnimRxInfo& rx = p->second;
-      uint32_t rxId = rx.m_rxnd->GetNode ()->GetId ();
-      if ((rx.m_lbRx - rx.m_fbRx) != pktInfo.firstlastbitDelta)
-        {
-          //TODO: how to handle this case elegantly? 
-	  continue; 
-        }
-      if (rx.m_lbRx)
-        {
-          oss << GetXMLOpenClose_rx (0,rxId,rx.m_fbRx,rx.m_lbRx);
-	}
-    }
+  uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId ();
+  oss << GetXMLOpenClose_rx (0, rxId, pktrxInfo.m_fbRx, pktrxInfo.m_lbRx);
+
   oss << GetXMLClose ("wpacket");
   WriteN (m_fHandle, oss.str ());
 }
 
-
 // XML Private Helpers
 
 std::string AnimationInterface::GetXMLOpen_anim (uint32_t lp)
@@ -772,5 +816,52 @@
   return elements;
 }
 
+TypeId
+AnimByteTag::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::AnimByteTag")
+    .SetParent<Tag> ()
+    .AddConstructor<AnimByteTag> ()
+  ;
+  return tid;
+}
+TypeId
+AnimByteTag::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+
+uint32_t
+AnimByteTag::GetSerializedSize (void) const
+{
+  return sizeof (uint64_t);
+}
+void
+AnimByteTag::Serialize (TagBuffer i) const
+{
+  i.WriteU64 (m_AnimUid);
+}
+void
+AnimByteTag::Deserialize (TagBuffer i)
+{
+  m_AnimUid = i.ReadU64 ();
+}
+void
+AnimByteTag::Print (std::ostream &os) const
+{
+  os << "AnimUid=" << m_AnimUid;
+}
+void
+AnimByteTag::Set (uint64_t AnimUid)
+{
+  m_AnimUid = AnimUid;
+}
+
+uint64_t
+AnimByteTag::Get (void) const
+{
+  return m_AnimUid;
+}
+
 
 } // namespace ns3
--- a/src/netanim/model/animation-interface.h	Sat Jul 09 17:05:12 2011 +0530
+++ b/src/netanim/model/animation-interface.h	Sun Jul 10 13:20:34 2011 -0400
@@ -36,7 +36,6 @@
 
 namespace ns3 {
 
-class NetModel;
 /**
  * \defgroup netanim Netanim
  *
@@ -57,27 +56,29 @@
 
   /**
    * \brief Construct the animator interface. No arguments needed.
+   *
    */
   AnimationInterface ();
 
   /**
    * \brief Destructor for the animator interface.
+   *
    */
   ~AnimationInterface ();
 
   /**
    * \brief Constructor
-   * \param Filename for the trace file used by the Animator
-   * \param Set to true if XML output traces are required
+   * \param filename The Filename for the trace file used by the Animator
+   * \param usingXML Set to true if XML output traces are required
    *
    */
   AnimationInterface (const std::string filename, bool usingXML = true);
 
   /**
    * \brief Constructor
-   * \param Port on which ns-3 should listen to for connection from the
+   * \param port Port on which ns-3 should listen to for connection from the
    *        external netanim application
-   * \param Set to true if XML output traces are required
+   * \param usingXML Set to true if XML output traces are required
    *
    */
   AnimationInterface (uint16_t port, bool usingXML = true);
@@ -91,6 +92,7 @@
    *
    * \param fn The name of the output file.
    * \returns true if successful open.
+   *
    */
   bool SetOutputFile (const std::string& fn);
 
@@ -99,6 +101,7 @@
    * in XML format.
    *
    * \returns none
+   *
    */
   void SetXMLOutput ();
 
@@ -113,6 +116,7 @@
    *
    * \param port Port number to bind to.
    * \returns true if connection created, false if bind failed.
+   *
    */
   bool SetServerPort (uint16_t port);
 
@@ -138,14 +142,14 @@
    * \brief Set mobility poll interval:WARNING: setting a low interval can 
    * cause slowness
    *
-   * \param Time interval between fetching mobility/position information
+   * \param t Time interval between fetching mobility/position information
    * Default: 0.25s
    *
    */
   void SetMobilityPollInterval (Time t);
 
 private:
-
+  
   int       m_fHandle;  // File handle for output (-1 if none)
   bool      m_xml;      // True if xml format desired
   Time mobilitypollinterval;
@@ -172,7 +176,6 @@
                           Ptr<const Packet> p);
   void WifiPhyRxDropTrace (std::string context,
                            Ptr<const Packet> p);
-
   void WimaxTxTrace (std::string context,
                      Ptr<const Packet> p,
 		     const Mac48Address &);
@@ -181,8 +184,6 @@
                      const Mac48Address &);
   void MobilityCourseChangeTrace (Ptr <const MobilityModel> mob);
 
-  typedef std::map <uint32_t,AnimRxInfo>::iterator RxInfoIterator;
-
   // Write specified amount of data to the specified handle
   int  WriteN (int, const char*, uint32_t);
 
@@ -190,13 +191,21 @@
   int  WriteN (int, const std::string&);
 
   //Helpers to output xml wireless packet
-  void OutputWirelessPacket (uint32_t, AnimPacketInfo&);
+  void OutputWirelessPacket (AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
   void MobilityAutoCheck ();
+  
+  uint64_t gAnimUid ;    // Packet unique identifier used by Animtion
+
   std::map<uint64_t, AnimPacketInfo> pendingWifiPackets;
+  void AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo&);
+  bool WifiPacketIsPending (uint64_t AnimUid); 
+
   std::map<uint64_t, AnimPacketInfo> pendingWimaxPackets;
-  bool WifiPacketIsPending (uint64_t Uid); 
-  bool WimaxPacketIsPending (uint64_t Uid); 
-  
+  void AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo&);
+  bool WimaxPacketIsPending (uint64_t AnimUid); 
+
+  uint64_t GetAnimUidFromPacket (Ptr <const Packet>);
+
   std::map<uint32_t, Vector> nodeLocation;
   Vector GetPosition (Ptr <Node> n);
   Vector UpdatePosition (Ptr <Node> n);
@@ -207,6 +216,7 @@
 
   // Recalculate topology bounds
   void RecalcTopoBounds (Vector v);
+  std::vector < Ptr <Node> > RecalcTopoBounds ();
 
   // Path helper
   std::vector<std::string> GetElementsFromContext (std::string context);
@@ -230,6 +240,83 @@
   std::string GetXMLClose (std::string name) {return "</" + name + ">\n"; }
 
 };
+
+/**
+ * \ingroup netanim
+ *
+ * \brief Byte tag using by Anim to uniquely identify packets
+ *
+ * When Anim receives a Tx Notification we tag the packet with a unique global uint64_t identifier
+ * before recording Tx information
+ * When Anim receives Rx notifications the tag is used to retrieve Tx information recorded earlier 
+ * 
+ */
+
+class AnimByteTag : public Tag
+{
+public:
+
+  /**
+   * \brief Get Type Id
+   * \returns Type Id
+   *
+   */
+  static TypeId GetTypeId (void);
+  
+  /**
+   * \brief Get Instance Type Id
+   * \returns Type Id
+   *
+   */
+  virtual TypeId GetInstanceTypeId (void) const;
+
+  /**
+   * \brief Get Serialized Size
+   * \returns Serialized Size (i.e size of uint64_t)
+   *
+   */
+  virtual uint32_t GetSerializedSize (void) const;
+
+  /**
+   * \brief Serialize function
+   * \param i Tag Buffer
+   *
+   */
+  virtual void Serialize (TagBuffer i) const;
+
+  /**
+   * \brief Deserialize function
+   * \param i Tag Buffer
+   *
+   */
+  virtual void Deserialize (TagBuffer i);
+
+  /**
+   * \brief Print tag info
+   * \param os Reference of ostream object
+   *
+   */
+  virtual void Print (std::ostream &os) const;
+
+  /**
+   * \brief Set global Uid in tag
+   * \param AnimUid global Uid
+   *
+   */
+  void Set (uint64_t AnimUid);
+
+  /**
+   * \brief Get Uid in tag
+   * \returns Uid in tag
+   *
+   */
+  uint64_t Get (void) const;
+
+private:
+
+  uint64_t m_AnimUid;
+};
+
 }
 #endif