--- a/src/netanim/examples/wscript Thu Jun 30 17:56:18 2011 -0400 +++ a/src/netanim/examples/wscript Tue Jul 05 11:19:15 2011 -0400 @@ -12,3 +12,4 @@ obj = bld.create_ns3_program('star-animation', ['netanim', 'applications', 'point-to-point-layout']) obj.source = 'star-animation.cc' + --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 2a75f23944d6 Tue Jul 05 11:19:15 2011 -0400 @@ -0,0 +1,86 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: John Abraham + */ + +// Animation Interface helpers + +#include "ns3/animation-interface-helper.h" +#include "ns3/log.h" + +#include + +NS_LOG_COMPONENT_DEFINE ("AnimationInterfaceHelper"); + +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)) +{ +} + +AnimPacketInfo::AnimPacketInfo(Ptr nd, 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) +{ +} + +void AnimPacketInfo::AddRxBegin (Ptr nd, const Time& fbRx, + Vector rxLoc) +{ + m_rx[nd->GetNode ()->GetId ()] = AnimRxInfo (fbRx,nd); + m_nRx++; + reception_range = std::max (reception_range,CalculateDistance (transmitter_loc,rxLoc)); +} + +bool AnimPacketInfo::AddRxEnd (Ptr nd, const Time& lbRx) + +{ + uint32_t NodeId = nd->GetNode ()->GetId (); + // Find the RxInfo + if (m_rx.find(NodeId) != m_rx.end ()) + { + if (m_rx[NodeId].m_rxnd != nd) + { + return false; + } + m_rx[NodeId].m_lbRx = lbRx.GetSeconds (); + m_nRxEnd++; + if (m_nRxEnd == m_nRx) + { + return true; + } + return false; // Still more rxEnd expected + } + NS_ASSERT ("Received RxEnd notification but RxInfo never existed"); + return false; // Still more rxEnd expected +} + +void AnimPacketInfo::AddRxDrop (Ptr nd) +{ + if (m_rx.find (nd->GetNode ()->GetId ()) == m_rx.end()) + { + NS_LOG_DEBUG ("Received RxDrop notification"); + return; + } + m_rx.erase (m_rx.find (nd->GetNode ()->GetId ())); + m_nRx--; +} + + +} // namespace ns3 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ 2a75f23944d6 Tue Jul 05 11:19:15 2011 -0400 @@ -0,0 +1,188 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: John Abraham + */ + +// Animation Interface helpers + +#ifndef _ANIMATION_INTERFACE_HELPER_H_ +#define _ANIMATION_INTERFACE_HELPER_H_ + +#include "ns3/node.h" +#include "ns3/mobility-model.h" +#include "ns3/packet.h" +#include "ns3/simulator.h" +#include +#include + +namespace ns3 { + + +/** + * \ingroup netanim + * + * \brief AnimRxInfo helper class + * + * This helper class keeps of wireless packets received + * including info about the first bit received time, + * last bit received time and NetDevice received on + * It is intended only for use by the AnimationInterface + * class. + * + */ + +class AnimRxInfo +{ +public: + + /** + * \brief Default constructor + * + */ + AnimRxInfo () {}; + + /** + * \brief Constructor + * \param First-bit Receive time + * \param Ptr to NetDevice used for reception + * + */ + + + AnimRxInfo (const Time& fbRx, Ptr nd) + : m_fbRx (fbRx.GetSeconds ()), m_lbRx (0), m_rxnd (nd) {} + /* + * First bit receive time + */ + double m_fbRx; + + /* + * Last bit receive time + */ + double m_lbRx; + + /* + * Ptr to receiving Net Device + */ + Ptr m_rxnd; +}; + +/** + * \ingroup netanim + * + * \brief AnimPacketInfo helper class + * + * This helper class keeps of wireless packets transmitted and + * received + * including info about the last bit transmit time, first bit + * transmit time, location of the transmitter and + * NetDevice transmited on + * It is intended only for use by the AnimationInterface + * class. + * + */ + +class AnimPacketInfo + +{ +public: + + /** + * \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 + * + */ + AnimPacketInfo(Ptr nd, + const Time& fbTx, const Time& lbTx,Vector txLoc); + + /** + * Ptr to NetDevice used for transmission + */ + Ptr m_txnd; + + /** + * Number of receivers + */ + uint32_t m_nRx; + + /** + * Number of RxEnd trace callbacks + */ + uint32_t m_nRxEnd; + + /** + * First bit transmission time + */ + double m_fbTx; + + /** + * Last bit transmission time + */ + double m_lbTx; + + /** + * Transmitter's location + */ + Vector transmitter_loc; + + /** + * Receptiion range + */ + double reception_range; + + /** + * Collection of receivers + */ + std::map m_rx; + + /** + * \brief Record RxBegin notification was received + * \param Ptr to NetDevice where packet was received + * \param First bit receive time + * \param Location of the transmitter + * + */ + void AddRxBegin (Ptr nd, const Time& fbRx, + Vector rxLoc); + + /** + * \brief Record RxEnd notification was received + * \param Ptr to NetDevice where packet was received + * \param First bit receive time + * + */ + bool AddRxEnd (Ptr nd, const Time& fbRx); + + /** + * \brief Record RxDrop notification was received + * \param Ptr to NetDevice where packet was dropped on reception + * + */ + void AddRxDrop (Ptr nd); + +}; + +} // namespace ns3 + +#endif --- a/src/netanim/model/animation-interface.cc Thu Jun 30 17:56:18 2011 -0400 +++ a/src/netanim/model/animation-interface.cc Tue Jul 05 11:19:15 2011 -0400 @@ -14,12 +14,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: George F. Riley + * Modified by: John Abraham */ // Interface between ns3 and the network animator #include #include +#include +#include +#include // Socket related includes #if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H) @@ -37,6 +41,7 @@ #include "ns3/mobility-model.h" #include "ns3/packet.h" #include "ns3/simulator.h" +#include "ns3/animation-interface-helper.h" using namespace std; @@ -45,12 +50,19 @@ namespace ns3 { AnimationInterface::AnimationInterface () - : m_fHandle (STDOUT_FILENO), m_model (0) + : m_fHandle (STDOUT_FILENO), m_xml (false), m_model (0), mobilitypollinterval (Seconds(0.25)) { } AnimationInterface::~AnimationInterface () { + StopAnimation (); +} + +void AnimationInterface::SetXMLOutput () +{ + NS_LOG_INFO ("XML output set"); + m_xml = true; } bool AnimationInterface::SetOutputFile (const std::string& fn) @@ -58,6 +70,7 @@ FILE* f = fopen (fn.c_str (), "w"); if (!f) { + NS_FATAL_ERROR ("Unable to output Animation output file"); return false; // Can't open } m_fHandle = fileno (f); // Set the file handle @@ -91,22 +104,75 @@ // which is done to support a platform like MinGW } +Vector AnimationInterface::GetPosition (Ptr n) +{ + Ptr loc = n->GetObject (); + Vector v(0,0,0); + if (!loc) + { + return v; + } + if (loc) + { + v = loc->GetPosition (); + } + return v; +} void AnimationInterface::StartAnimation () { + // 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; + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) + { + Ptr n = *i; + Vector v = GetPosition (n); + if (first) + { + topo_minX = v.x; + topo_minY = v.y; + topo_maxX = v.x; + topo_maxY = v.y; + first = false; + } + else + { + topo_minX = min (topo_minX, v.x); + topo_minY = min (topo_minY, v.y); + topo_maxX = max (topo_maxX, v.x); + topo_maxY = max (topo_maxY, v.y); + } + } + + if (m_xml) + { // output the xml headers + ostringstream oss; + oss << GetXMLOpen_anim (0); + oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY); + WriteN (m_fHandle, oss.str ()); + } // Dump the topology for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) { Ptr n = *i; - Ptr loc = n->GetObject (); - if (loc) + ostringstream oss; + if (m_xml) + { + Vector v = GetPosition (n); + oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y); + } + else { // Location exists, dump it - Vector v = loc->GetPosition (); - ostringstream oss; + Vector v = GetPosition (n); oss << "0.0 N " << n->GetId () << " " << v.x << " " << v.y << endl; - WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); } + + WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); } // Now dump the p2p links for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) @@ -117,10 +183,12 @@ for (uint32_t i = 0; i < nDev; ++i) { Ptr dev = n->GetDevice (i); + NS_ASSERT (dev); Ptr ch = dev->GetChannel (); if (!ch) { - continue; // No channel, can't be p2p device + NS_LOG_DEBUG ("No channel can't be a p2p device"); + continue; } string channelType = ch->GetInstanceTypeId ().GetName (); if (channelType == string ("ns3::PointToPointChannel")) @@ -134,40 +202,90 @@ if (n1Id < n2Id) { // ouptut the p2p link ostringstream oss; - oss << "0.0 L " << n1Id << " " << n2Id << endl; - WriteN (m_fHandle, oss.str ().c_str (), - oss.str ().length ()); + if (m_xml) + { + oss << GetXMLOpenClose_link (0,n1Id,0,n2Id); + } + else + { + oss << "0.0 L " << n1Id << " " << n2Id << endl; + } + WriteN (m_fHandle, oss.str ()); + } } } else { - NS_FATAL_ERROR ("Net animation currently only supports point-to-point links."); + //NS_FATAL_ERROR ("Net animation currently only supports point-to-point links."); } } } + if (m_xml) + { + WriteN (m_fHandle, GetXMLClose ("topology")); + Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this); + } - // Connect the callback for packet tx events + // Connect the callbacks Config::Connect ("/ChannelList/*/TxRxPointToPoint", MakeCallback (&AnimationInterface::DevTxTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin", + MakeCallback (&AnimationInterface::WifiPhyTxBeginTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxEnd", + MakeCallback (&AnimationInterface::WifiPhyTxEndTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin", + MakeCallback (&AnimationInterface::WifiPhyRxBeginTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd", + MakeCallback (&AnimationInterface::WifiPhyRxEndTrace, this)); + Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop", + MakeCallback (&AnimationInterface::WifiPhyRxDropTrace, this)); + Config::ConnectWithoutContext ("/NodeList/*/$ns3::MobilityModel/CourseChange", + MakeCallback (&AnimationInterface::MobilityCourseChangeTrace, this)); + Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx", + MakeCallback (&AnimationInterface::WimaxTxTrace, this)); + Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx", + MakeCallback (&AnimationInterface::WimaxRxTrace, this)); + + + } void AnimationInterface::StopAnimation () { + NS_LOG_INFO ("Stopping Animation"); if (m_fHandle > 0) { + if (m_xml) + { // Terminate the anim element + WriteN (m_fHandle, GetXMLClose ("anim")); + } close (m_fHandle); + m_fHandle = 0; } } +int AnimationInterface::WriteN (int h, const string& st) +{ + return WriteN (h, st.c_str (), st.length ()); +} + // Private methods +void AnimationInterface::RecalcTopoBounds (Vector v) +{ + topo_minX = min (topo_minX, v.x); + topo_minY = min (topo_minY, v.y); + topo_maxX = max (topo_maxX, v.x); + topo_maxY = max (topo_maxY, v.y); + +} + int AnimationInterface::WriteN (int h, const char* data, uint32_t count) { // Write count bytes to h from data uint32_t nLeft = count; const char* p = data; uint32_t written = 0; - while (nLeft) { int n = write (h, p, nLeft); @@ -186,15 +304,288 @@ Ptr tx, Ptr rx, Time txTime, Time rxTime) { + NS_ASSERT (tx); + NS_ASSERT (rx); Time now = Simulator::Now (); ostringstream oss; - oss << now.GetSeconds () << " P " - << tx->GetNode ()->GetId () << " " - << rx->GetNode ()->GetId () << " " - << (now + txTime).GetSeconds () << " " // last bit tx time - << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time - << (now + rxTime).GetSeconds () << endl; // last bit rx time - WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); + double fbTx = now.GetSeconds (); + double lbTx = (now + txTime).GetSeconds (); + double fbRx = (now + rxTime - txTime).GetSeconds (); + double lbRx = (now + rxTime).GetSeconds (); + if (m_xml) + { + oss << GetXMLOpen_packet (0,tx->GetNode ()->GetId (),fbTx,lbTx); + oss << GetXMLOpenClose_rx (0,rx->GetNode ()->GetId (),fbRx,lbRx); + oss << GetXMLClose ("packet"); + } + else + { + oss << setprecision (10); + oss << now.GetSeconds () << " P " + << tx->GetNode ()->GetId () << " " + << rx->GetNode ()->GetId () << " " + << (now + txTime).GetSeconds () << " " // last bit tx time + << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time + << (now + rxTime).GetSeconds () << endl; // last bit rx time + } + WriteN (m_fHandle, oss.str ()); } + +Ptr +AnimationInterface::GetNetDeviceFromContext (std::string context) +{ + // Use "NodeList/*/DeviceList/*/ as reference + // where element [1] is the Node Id + // element [2] is the NetDevice Id + + vector elements = GetElementsFromContext (context); + Ptr n = NodeList::GetNode (atoi (elements[1].c_str ())); + NS_ASSERT (n); + return n->GetDevice (atoi (elements[3].c_str ())); +} + +void AnimationInterface::WifiPhyTxBeginTrace (std::string context, + Ptr p) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + Ptr n = ndev->GetNode (); + NS_ASSERT (n); + // Add a new pending wireless + NS_LOG_INFO ("TxBeginTrace for packet:" << p->GetUid ()); + pendingWifiPackets[p->GetUid ()] = + AnimPacketInfo (ndev, Simulator::Now (), Simulator::Now ()+Seconds(0.5), GetPosition (n)); +} + +void AnimationInterface::WifiPhyTxEndTrace (std::string context, + Ptr p) +{ +} + +void AnimationInterface::WifiPhyTxDropTrace (std::string context, + Ptr p) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + // Erase pending wifi + NS_LOG_INFO ("TxDropTrace for packet:" << p->GetUid ()); + pendingWifiPackets.erase (pendingWifiPackets.find (p->GetUid ())); +} + + +void AnimationInterface::WifiPhyRxBeginTrace (std::string context, + Ptr p) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + Ptr n = ndev->GetNode (); + NS_ASSERT (n); + NS_LOG_INFO ("RxBeginTrace for packet:" << p->GetUid ()); + pendingWifiPackets[p->GetUid ()].AddRxBegin (ndev, Simulator::Now (), GetPosition (n)); +} + + +void AnimationInterface::WifiPhyRxEndTrace (std::string context, + Ptr p) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + uint32_t uid = p->GetUid (); + AnimPacketInfo& pkt = pendingWifiPackets[uid]; + if (pkt.AddRxEnd (ndev, Simulator::Now ())) + { + NS_LOG_INFO ("RxEndTrace for packet:" << uid << " complete"); + OutputWirelessPacket (uid, pkt); + pendingWifiPackets.erase (pendingWifiPackets.find (uid));; + } +} + + +void AnimationInterface::WifiPhyRxDropTrace (std::string context, + Ptr p) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + NS_LOG_INFO ("RxDropTrace for packet:"<< p->GetUid ()); + pendingWifiPackets[p->GetUid ()].AddRxDrop (ndev); +} + +void AnimationInterface::WimaxTxTrace (std::string context, Ptr p, const Mac48Address & m) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + Ptr n = ndev->GetNode (); + NS_ASSERT (n); + NS_LOG_INFO ("WimaxTxTrace for packet:" << p->GetUid ()); + pendingWimaxPackets[p->GetUid ()] = + AnimPacketInfo (ndev, Simulator::Now (), Simulator::Now ()+Seconds(0.5), GetPosition (n)); +} + + +void AnimationInterface::WimaxRxTrace (std::string context, Ptr p, const Mac48Address & m) +{ + Ptr ndev = GetNetDeviceFromContext (context); + NS_ASSERT (ndev); + Ptr n = ndev->GetNode (); + NS_ASSERT (n); + uint32_t uid = p->GetUid (); + AnimPacketInfo& pktinfo = pendingWimaxPackets[uid]; + pktinfo.AddRxBegin (ndev, Simulator::Now (), GetPosition (n)); + pktinfo.AddRxEnd (ndev, Simulator::Now ()+ Seconds (0.0001)); + NS_LOG_INFO ("WimaxRxTrace for packet:" << p->GetUid ()); + OutputWirelessPacket (p->GetUid (), pktinfo); + +} + +void AnimationInterface::MobilityCourseChangeTrace (Ptr mobility) + +{ + Ptr n = mobility->GetObject (); + if (!n) return; + if (!mobility) return; + Vector v ; + v = mobility->GetPosition (); + RecalcTopoBounds (v); + ostringstream oss; + oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY); + oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y); + oss << GetXMLClose ("topology"); + WriteN (m_fHandle, oss.str ()); +} + +void AnimationInterface::MobilityAutoCheck () +{ + Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this); + ostringstream oss; + oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY); + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) + { + Ptr n = *i; + if (!n) continue; + Ptr mobility = n->GetObject (); + if (!mobility) continue; + Vector v ; + v = mobility->GetPosition (); + RecalcTopoBounds (v); + oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y); + WriteN (m_fHandle, oss.str ()); + } + oss << GetXMLClose ("topology"); + WriteN (m_fHandle, oss.str ()); +} + + +// Helper to output a wireless packet. +// For now, only the XML interface is supported + +void AnimationInterface::OutputWirelessPacket (uint32_t uid, AnimPacketInfo& pktInfo) + +{ + if (!m_xml) return; + ostringstream oss; + uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId (); + double lbTx = pktInfo.m_lbTx; + + // Oops, need to figure out about range + oss << GetXMLOpen_wpacket (0,nodeId,pktInfo.m_fbTx,lbTx,pktInfo.reception_range); + // Now add each rx + map ::iterator p; + 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) + oss << GetXMLOpenClose_rx (0,rxId,rx.m_fbRx,rx.m_lbRx); + } + oss << GetXMLClose ("wpacket"); + WriteN (m_fHandle, oss.str ()); +} + + +// XML Private Helpers + +std::string AnimationInterface::GetXMLOpen_anim (uint32_t lp) +{ + ostringstream oss; + oss <<"\n"; + return oss.str (); +} +std::string AnimationInterface::GetXMLOpen_topology (double minX,double minY,double maxX,double maxY) +{ + ostringstream oss; + oss <<"" << endl; + return oss.str (); + +} + +std::string AnimationInterface::GetXMLOpenClose_node (uint32_t lp,uint32_t id,double locX,double locY) +{ + ostringstream oss; + oss <<"\n"; + return oss.str (); +} +std::string AnimationInterface::GetXMLOpenClose_link (uint32_t fromLp,uint32_t fromId, uint32_t toLp, uint32_t toId) +{ + ostringstream oss; + oss << "" << endl; + return oss.str (); +} + + +std::string AnimationInterface::GetXMLOpen_packet (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx) +{ + ostringstream oss; + oss << setprecision (10); + oss << "" << endl; + return oss.str (); +} + +std::string AnimationInterface::GetXMLOpen_wpacket (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx, double range) +{ + ostringstream oss; + oss << setprecision (10); + oss << "" << endl; + return oss.str (); + +} + +std::string AnimationInterface::GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx) +{ + ostringstream oss; + oss << setprecision (10); + oss << "" << endl; + return oss.str (); +} + +std::vector AnimationInterface::GetElementsFromContext (std::string context) +{ + vector 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; +} + + } // namespace ns3 --- a/src/netanim/model/animation-interface.h Thu Jun 30 17:56:18 2011 -0400 +++ a/src/netanim/model/animation-interface.h Tue Jul 05 11:19:15 2011 -0400 @@ -1,4 +1,4 @@ -/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ + /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -14,6 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: George F. Riley + * Modified by: John Abraham */ // Interface between ns3 and the network animator @@ -22,18 +23,21 @@ #define ANIMATION_INTERFACE__H #include - +#include +#include #include "ns3/ptr.h" #include "ns3/net-device.h" #include "ns3/nstime.h" #include "ns3/log.h" #include "ns3/node-list.h" - +#include "ns3/simulator.h" +#include "ns3/config.h" +#include "ns3/animation-interface-helper.h" +#include "ns3/mac48-address.h" namespace ns3 { class NetModel; - /** * \defgroup netanim Netanim * @@ -72,6 +76,15 @@ bool SetOutputFile (const std::string& fn); /** + * @brief Specify that animation commands are to be written + * in XML format. + * + * @returns none + */ + + void SetXMLOutput (); + +/** * @brief Specify that animation commands are to be written to * a socket. * @@ -103,18 +116,77 @@ */ void StopAnimation (); +private: + void DevTxTrace (std::string context, + Ptr p, + Ptr tx, + Ptr rx, + Time txTime, + Time rxTime); + void WifiPhyTxBeginTrace (std::string context, + Ptr p); + void WifiPhyTxEndTrace (std::string context, + Ptr p); + void WifiPhyTxDropTrace (std::string context, + Ptr p); + void WifiPhyRxBeginTrace (std::string context, + Ptr p); + void WifiPhyRxEndTrace (std::string context, + Ptr p); + void WifiPhyRxDropTrace (std::string context, + Ptr p); -private: - // Packet tx animation callback - void DevTxTrace (std::string context, Ptr p, - Ptr tx, Ptr rx, - Time txTime, Time rxTime); + void WimaxTxTrace (std::string context, + Ptr p, + const Mac48Address &); + void WimaxRxTrace (std::string context, + Ptr p, + const Mac48Address &); + void MobilityCourseChangeTrace (Ptr mob); + // Write specified amount of data to the specified handle int WriteN (int, const char*, uint32_t); + // Write a string to the specified handle; + int WriteN (int, const std::string&); + //Helper to output xml wireless packet + void OutputWirelessPacket (uint32_t, AnimPacketInfo&); + void MobilityAutoCheck (); + void SetMobilityPollInterval (Time t) {mobilitypollinterval = t;} private: int m_fHandle; // File handle for output (-1 if none) + bool m_xml; // True if xml format desired NetModel* m_model; // If non nil, points to the internal network model // for the interlan animator + std::map pendingWifiPackets; + std::map pendingWimaxPackets; + + Vector GetPosition (Ptr n); + + // Recalculate topology bounds + void RecalcTopoBounds (Vector v); + + // Path helper + std::vector GetElementsFromContext (std::string context); + Ptr GetNetDeviceFromContext (std::string context); + + // XML helpers + + // Topology element dimensions + double topo_minX; + double topo_minY; + double topo_maxX; + double topo_maxY; + + std::string GetXMLOpen_anim (uint32_t lp); + std::string GetXMLOpen_topology (double minX,double minY,double maxX,double maxY); + std::string GetXMLOpenClose_node (uint32_t lp,uint32_t id,double locX,double locY); + std::string GetXMLOpenClose_link (uint32_t fromLp,uint32_t fromId, uint32_t toLp, uint32_t toId); + std::string GetXMLOpen_packet (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx); + std::string GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx); + std::string GetXMLOpen_wpacket (uint32_t fromLp,uint32_t fromId, double fbTx, double lbTx, double range); + std::string GetXMLClose (std::string name) {return "\n"; } + Time mobilitypollinterval; + }; } #endif --- a/src/netanim/wscript Thu Jun 30 17:56:18 2011 -0400 +++ a/src/netanim/wscript Tue Jul 05 11:19:15 2011 -0400 @@ -1,25 +1,26 @@ -## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +## -*-Mode : python; py-indent-offset : 4; indent-tabs-mode : nil; coding : utf-8; -*- -def build(bld): - module = bld.create_ns3_module('netanim', ['internet', 'mobility']) - module.includes = '.' - module.source = [ - 'model/animation-interface.cc', - ] +def build (bld) : + module = bld.create_ns3_module ('netanim', ['internet', 'mobility', 'wimax', 'wifi']) + module.includes = '.' + module.source = [ + 'model/animation-interface.cc', + 'helper/animation-interface-helper.cc', + ] - headers = bld.new_task_gen('ns3header') - headers.module = 'netanim' - headers.source = [ - 'model/animation-interface.h', - ] + headers = bld.new_task_gen ('ns3header') + headers.module = 'netanim' + headers.source = [ + 'model/animation-interface.h', + 'helper/animation-interface-helper.h', + ] - if (bld.env['ENABLE_EXAMPLES']): - bld.add_subdirs('examples') + if (bld.env['ENABLE_EXAMPLES']) : + bld.add_subdirs ('examples') - bld.ns3_python_bindings() + bld.ns3_python_bindings () +def configure (conf) : + conf.check (header_name='sys/socket.h', define_name='HAVE_SYS_SOCKET_H') + conf.check (header_name='netinet/in.h', define_name='HAVE_NETINET_IN_H') -def configure(conf): - conf.check(header_name='sys/socket.h', define_name='HAVE_SYS_SOCKET_H') - conf.check(header_name='netinet/in.h', define_name='HAVE_NETINET_IN_H') -