NetAnim: add test and examples to run

This commit is contained in:
John Abraham
2012-05-19 14:56:43 -07:00
parent 81446ad08f
commit 771399dbab
5 changed files with 330 additions and 132 deletions

View File

@@ -63,33 +63,36 @@ static bool initialized = false;
std::map <uint32_t, std::string> AnimationInterface::nodeDescriptions;
AnimationInterface::AnimationInterface ()
: m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
usingSockets (false), mport (0), outputfilename (""),
OutputFileSet (false), ServerPortSet (false), gAnimUid (0),randomPosition (true),
: m_fHandle (STDOUT_FILENO), m_xml (false), m_mobilityPollInterval (Seconds(0.25)),
m_usingSockets (false), m_port (0), m_outputFileName (""),
m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0),m_randomPosition (true),
m_writeCallback (0), m_started (false),
m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE)
{
initialized = true;
StartAnimation ();
}
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), gAnimUid (0), randomPosition (true),
AnimationInterface::AnimationInterface (const std::string fn, uint64_t maxPktsPerFile, bool usingXML)
: m_fHandle (STDOUT_FILENO), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)),
m_usingSockets (false), m_port (0), m_outputFileName (fn),
m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0), m_randomPosition (true),
m_writeCallback (0), m_started (false),
m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn)
{
initialized = true;
StartAnimation ();
}
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), gAnimUid (0), randomPosition (true),
: m_fHandle (STDOUT_FILENO), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)),
m_usingSockets (true), m_port (port), m_outputFileName (""),
m_outputFileSet (false), m_serverPortSet (false), gAnimUid (0), m_randomPosition (true),
m_writeCallback (0), m_started (false),
m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000))
m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE)
{
initialized = true;
StartAnimation ();
@@ -107,6 +110,22 @@ void AnimationInterface::SetXMLOutput ()
}
void AnimationInterface::StartNewTraceFile ()
{
static int i = 0;
std::ostringstream oss;
oss << i;
++m_currentPktCount;
if (m_currentPktCount <= m_maxPktsPerFile)
{
return;
}
StopAnimation ();
m_outputFileName = m_originalFileName + "-" + oss.str ();
StartAnimation (true);
++i;
}
void AnimationInterface::SetStartTime (Time t)
{
m_startTime = t;
@@ -119,16 +138,17 @@ void AnimationInterface::SetStopTime (Time t)
bool AnimationInterface::SetOutputFile (const std::string& fn)
{
if (OutputFileSet)
if (m_outputFileSet)
{
return true;
}
if (fn == "")
{
m_fHandle = STDOUT_FILENO;
OutputFileSet = true;
m_outputFileSet = true;
return true;
}
NS_LOG_UNCOND (fn.c_str ());
FILE* f = fopen (fn.c_str (), "w");
if (!f)
{
@@ -136,9 +156,9 @@ bool AnimationInterface::SetOutputFile (const std::string& fn)
return false; // Can't open
}
m_fHandle = fileno (f); // Set the file handle
usingSockets = false;
outputfilename = fn;
OutputFileSet = true;
m_usingSockets = false;
m_outputFileName = fn;
m_outputFileSet = true;
return true;
}
@@ -182,7 +202,7 @@ bool AnimationInterface::IsInTimeWindow ()
bool AnimationInterface::SetServerPort (uint16_t port)
{
#if defined(HAVE_SYS_SOCKET_H) && defined(HAVE_NETINET_IN_H)
if (ServerPortSet)
if (m_serverPortSet)
{
return true;
}
@@ -204,8 +224,8 @@ bool AnimationInterface::SetServerPort (uint16_t port)
// set the linger socket option
int t = 1;
setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t));
usingSockets = true;
ServerPortSet = true;
m_usingSockets = true;
m_serverPortSet = true;
return true;
#endif
return false; // never reached unless the above is disabled
@@ -214,33 +234,33 @@ bool AnimationInterface::SetServerPort (uint16_t port)
bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
{
return (pendingWifiPackets.find (AnimUid) != pendingWifiPackets.end ());
return (m_pendingWifiPackets.find (AnimUid) != m_pendingWifiPackets.end ());
}
bool AnimationInterface::CsmaPacketIsPending (uint64_t AnimUid)
{
return (pendingCsmaPackets.find (AnimUid) != pendingCsmaPackets.end ());
return (m_pendingCsmaPackets.find (AnimUid) != m_pendingCsmaPackets.end ());
}
bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
{
return (pendingWimaxPackets.find (AnimUid) != pendingWimaxPackets.end ());
return (m_pendingWimaxPackets.find (AnimUid) != m_pendingWimaxPackets.end ());
}
bool AnimationInterface::LtePacketIsPending (uint64_t AnimUid)
{
return (pendingLtePackets.find (AnimUid) != pendingLtePackets.end ());
return (m_pendingLtePackets.find (AnimUid) != m_pendingLtePackets.end ());
}
void AnimationInterface::SetMobilityPollInterval (Time t)
{
mobilitypollinterval = t;
m_mobilityPollInterval = t;
}
void AnimationInterface::SetRandomPosition (bool setRandPos)
{
randomPosition = setRandPos;
m_randomPosition = setRandPos;
}
Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
@@ -248,49 +268,49 @@ Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
if (loc)
{
nodeLocation[n->GetId ()] = loc->GetPosition ();
m_nodeLocation[n->GetId ()] = loc->GetPosition ();
}
else
{
NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
Vector deterministicVector (100,100,0);
Vector randomVector (UniformVariable (0, topo_maxX-topo_minX).GetValue (), UniformVariable (0, topo_maxY-topo_minY).GetValue (), 0);
if (randomPosition)
Vector randomVector (UniformVariable (0, m_topoMaxX - m_topoMinX).GetValue (), UniformVariable (0, m_topoMaxY - m_topoMinY).GetValue (), 0);
if (m_randomPosition)
{
nodeLocation[n->GetId ()] = randomVector;
m_nodeLocation[n->GetId ()] = randomVector;
}
else
{
nodeLocation[n->GetId ()] = deterministicVector;
m_nodeLocation[n->GetId ()] = deterministicVector;
}
}
return nodeLocation[n->GetId ()];
return m_nodeLocation[n->GetId ()];
}
Vector AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
{
nodeLocation[n->GetId ()] = v;
m_nodeLocation[n->GetId ()] = v;
return v;
}
Vector AnimationInterface::GetPosition (Ptr <Node> n)
{
#ifdef NS_LOG
if (nodeLocation.find (n->GetId()) == nodeLocation.end ())
if (m_nodeLocation.find (n->GetId()) == m_nodeLocation.end ())
{
NS_FATAL_ERROR ("Node:" <<n->GetId() << " not found in Location table");
}
#endif
return nodeLocation[n->GetId ()];
return m_nodeLocation[n->GetId ()];
}
void AnimationInterface::PurgePendingWifi ()
{
if (pendingWifiPackets.empty ())
if (m_pendingWifiPackets.empty ())
return;
std::vector <uint64_t> purgeList;
for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWifiPackets.begin ();
i != pendingWifiPackets.end ();
for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWifiPackets.begin ();
i != m_pendingWifiPackets.end ();
++i)
{
@@ -306,18 +326,18 @@ void AnimationInterface::PurgePendingWifi ()
i != purgeList.end ();
++i)
{
pendingWifiPackets.erase (*i);
m_pendingWifiPackets.erase (*i);
}
}
void AnimationInterface::PurgePendingWimax ()
{
if (pendingWimaxPackets.empty ())
if (m_pendingWimaxPackets.empty ())
return;
std::vector <uint64_t> purgeList;
for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingWimaxPackets.begin ();
i != pendingWimaxPackets.end ();
for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWimaxPackets.begin ();
i != m_pendingWimaxPackets.end ();
++i)
{
@@ -333,7 +353,7 @@ void AnimationInterface::PurgePendingWimax ()
i != purgeList.end ();
++i)
{
pendingWimaxPackets.erase (*i);
m_pendingWimaxPackets.erase (*i);
}
}
@@ -341,11 +361,11 @@ void AnimationInterface::PurgePendingWimax ()
void AnimationInterface::PurgePendingLte ()
{
if (pendingLtePackets.empty ())
if (m_pendingLtePackets.empty ())
return;
std::vector <uint64_t> purgeList;
for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingLtePackets.begin ();
i != pendingLtePackets.end ();
for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingLtePackets.begin ();
i != m_pendingLtePackets.end ();
++i)
{
@@ -361,17 +381,17 @@ void AnimationInterface::PurgePendingLte ()
i != purgeList.end ();
++i)
{
pendingLtePackets.erase (*i);
m_pendingLtePackets.erase (*i);
}
}
void AnimationInterface::PurgePendingCsma ()
{
if (pendingCsmaPackets.empty ())
if (m_pendingCsmaPackets.empty ())
return;
std::vector <uint64_t> purgeList;
for (std::map<uint64_t, AnimPacketInfo>::iterator i = pendingCsmaPackets.begin ();
i != pendingCsmaPackets.end ();
for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingCsmaPackets.begin ();
i != m_pendingCsmaPackets.end ();
++i)
{
@@ -387,37 +407,38 @@ void AnimationInterface::PurgePendingCsma ()
i != purgeList.end ();
++i)
{
pendingCsmaPackets.erase (*i);
m_pendingCsmaPackets.erase (*i);
}
}
void AnimationInterface::StartAnimation ()
void AnimationInterface::StartAnimation (bool restart)
{
m_currentPktCount = 0;
m_started = true;
if (usingSockets)
if (m_usingSockets)
{
SetServerPort (mport);
SetServerPort (m_port);
}
else
{
SetOutputFile (outputfilename);
SetOutputFile (m_outputFileName);
}
// Find the min/max x/y for the xml topology element
topo_minX = -2;
topo_minY = -2;
topo_maxX = 2;
topo_maxY = 2;
m_topoMinX = -2;
m_topoMinY = -2;
m_topoMaxX = 2;
m_topoMaxY = 2;
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);
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);
m_topoMinX = std::min (m_topoMinX, v.x);
m_topoMinY = std::min (m_topoMinY, v.y);
m_topoMaxX = std::max (m_topoMaxX, v.x);
m_topoMaxY = std::max (m_topoMaxY, v.y);
}
AddMargin ();
@@ -426,7 +447,7 @@ void AnimationInterface::StartAnimation ()
std::ostringstream oss;
oss << GetXMLOpen_anim (0);
oss << GetPreamble ();
oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
WriteN (m_fHandle, oss.str ());
}
NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
@@ -497,13 +518,13 @@ void AnimationInterface::StartAnimation ()
}
}
}
if (m_xml)
if (m_xml && !restart)
{
WriteN (m_fHandle, GetXMLClose ("topology"));
Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
}
ConnectCallbacks ();
if (!restart)
ConnectCallbacks ();
}
void AnimationInterface::ConnectCallbacks ()
@@ -553,7 +574,7 @@ void AnimationInterface::StopAnimation ()
{
close (m_fHandle);
}
OutputFileSet = false;
m_outputFileSet = false;
m_fHandle = -1;
}
}
@@ -575,14 +596,14 @@ int AnimationInterface::WriteN (int h, const std::string& st)
void AnimationInterface::AddMargin ()
{
// Compute width/height, and add a small margin
double w = topo_maxX - topo_minX;
double h = topo_maxY - topo_minY;
topo_minX -= w * 0.05;
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);
double w = m_topoMaxX - m_topoMinX;
double h = m_topoMaxY - m_topoMinY;
m_topoMinX -= w * 0.05;
m_topoMinY -= h * 0.05;
m_topoMaxX = m_topoMinX + w * 1.5;
m_topoMaxY = m_topoMinY + h * 1.5;
NS_LOG_INFO ("Added Canvas Margin:" << m_topoMinX << "," <<
m_topoMinY << "," << m_topoMaxX << "," << m_topoMaxY);
}
std::vector <Ptr <Node> > AnimationInterface::RecalcTopoBounds ()
@@ -618,17 +639,17 @@ std::vector <Ptr <Node> > AnimationInterface::RecalcTopoBounds ()
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);
double oldminX = m_topoMinX;
double oldminY = m_topoMinY;
double oldmaxX = m_topoMaxX;
double oldmaxY = m_topoMaxY;
m_topoMinX = std::min (m_topoMinX, v.x);
m_topoMinY = std::min (m_topoMinY, v.y);
m_topoMaxX = std::max (m_topoMaxX, v.x);
m_topoMaxY = std::max (m_topoMaxY, v.y);
if ((topo_minX != oldminX) || (topo_minY != oldminY) ||
(topo_maxX != oldmaxX) || (topo_maxY != oldmaxY))
if ((m_topoMinX != oldminX) || (m_topoMinY != oldminY) ||
(m_topoMaxX != oldmaxX) || (m_topoMaxY != oldmaxY))
{
AddMargin ();
}
@@ -697,6 +718,8 @@ void AnimationInterface::DevTxTrace (std::string context, Ptr<const Packet> p,
if (m_enablePacketMetadata)
oss << GetXMLOpenClose_meta (GetPacketMetadata (p));
oss << GetXMLClose ("packet");
StartNewTraceFile ();
++m_currentPktCount;
}
else
{
@@ -727,25 +750,25 @@ AnimationInterface::GetNetDeviceFromContext (std::string context)
void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
pendingWifiPackets[AnimUid] = pktinfo;
m_pendingWifiPackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
pendingWimaxPackets[AnimUid] = pktinfo;
m_pendingWimaxPackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
pendingLtePackets[AnimUid] = pktinfo;
m_pendingLtePackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
pendingCsmaPackets[AnimUid] = pktinfo;
m_pendingCsmaPackets[AnimUid] = pktinfo;
}
uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
@@ -814,7 +837,7 @@ void AnimationInterface::WifiPhyTxDropTrace (std::string context,
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
pendingWifiPackets.erase (pendingWifiPackets.find (AnimUid));
m_pendingWifiPackets.erase (m_pendingWifiPackets.find (AnimUid));
}
@@ -851,9 +874,9 @@ void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
}
// TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
OutputWirelessPacket (p, pendingWifiPackets[AnimUid], pendingWifiPackets[AnimUid].GetRxInfo (ndev));
m_pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
m_pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
OutputWirelessPacket (p, m_pendingWifiPackets[AnimUid], m_pendingWifiPackets[AnimUid].GetRxInfo (ndev));
}
@@ -874,7 +897,7 @@ void AnimationInterface::WifiPhyRxEndTrace (std::string context,
AddPendingWifiPacket (AnimUid, pktinfo);
}
// TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
if (pktrxInfo.IsPhyRxComplete ())
@@ -900,7 +923,7 @@ void AnimationInterface::WifiMacRxTrace (std::string context,
return;
}
// TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
if (pktrxInfo.IsPhyRxComplete ())
{
@@ -944,7 +967,7 @@ void AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p,
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_LOG_INFO ("WimaxRxTrace for packet:" << AnimUid);
NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingWimaxPackets[AnimUid];
AnimPacketInfo& pktInfo = m_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
@@ -986,7 +1009,7 @@ void AnimationInterface::LteRxTrace (std::string context, Ptr<const Packet> p, c
NS_LOG_WARN ("LteRxTrace: unknown Uid");
return;
}
AnimPacketInfo& pktInfo = pendingLtePackets[AnimUid];
AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
//TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
@@ -1031,7 +1054,7 @@ void AnimationInterface::CsmaPhyTxEndTrace (std::string context, Ptr<const Packe
NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
}
// TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
}
@@ -1050,8 +1073,8 @@ void AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packe
return;
}
// TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
m_pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << AnimUid);
}
@@ -1074,7 +1097,7 @@ void AnimationInterface::CsmaMacRxTrace (std::string context,
return;
}
// TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingCsmaPackets[AnimUid];
AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
if (pktrxInfo.IsPhyRxComplete ())
{
@@ -1103,7 +1126,7 @@ void AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mo
UpdatePosition (n,v);
RecalcTopoBounds (v);
std::ostringstream oss;
oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
oss << GetXMLOpenClose_node (0,n->GetId (),v.x,v.y);
oss << GetXMLClose ("topology");
WriteN (m_fHandle, oss.str ());
@@ -1131,7 +1154,7 @@ void AnimationInterface::MobilityAutoCheck ()
return;
std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
std::ostringstream oss;
oss << GetXMLOpen_topology (topo_minX, topo_minY, topo_maxX, topo_maxY);
oss << GetXMLOpen_topology (m_topoMinX, m_topoMinY, m_topoMaxX, m_topoMaxY);
for (uint32_t i = 0; i < MovedNodes.size (); i++)
{
Ptr <Node> n = MovedNodes [i];
@@ -1148,7 +1171,7 @@ void AnimationInterface::MobilityAutoCheck ()
PurgePendingWimax ();
PurgePendingLte ();
PurgePendingCsma ();
Simulator::Schedule (mobilitypollinterval, &AnimationInterface::MobilityAutoCheck, this);
Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
}
}
@@ -1159,6 +1182,12 @@ std::string AnimationInterface::GetPacketMetadata (Ptr<const Packet> p)
return oss.str ();
}
uint64_t AnimationInterface::GetTracePktCount ()
{
return m_currentPktCount;
}
// Helper to output a wireless packet.
// For now, only the XML interface is supported
@@ -1204,6 +1233,7 @@ return s;
void AnimationInterface::OutputWirelessPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
{
StartNewTraceFile ();
NS_ASSERT (m_xml);
std::ostringstream oss;
uint32_t nodeId = 0;
@@ -1226,6 +1256,7 @@ void AnimationInterface::OutputWirelessPacket (Ptr<const Packet> p, AnimPacketIn
void AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
{
StartNewTraceFile ();
NS_ASSERT (m_xml);
std::ostringstream oss;
NS_ASSERT (pktInfo.m_txnd);

View File

@@ -52,6 +52,8 @@
namespace ns3 {
#define MAX_PKTS_PER_TRACE_FILE 100000
/**
* \defgroup netanim Netanim
*
@@ -85,10 +87,16 @@ public:
/**
* \brief Constructor
* \param filename The Filename for the trace file used by the Animator
* \param maxPktsPerFile The maximum number of packets per trace file.
AnimationInterface will create trace files with the following
filenames : filename, filename-1, filename-2..., filename-N
where each file contains packet info for 'maxPktPerFile' number of packets
* \param usingXML Set to true if XML output traces are required
*
*/
AnimationInterface (const std::string filename, bool usingXML = true);
AnimationInterface (const std::string filename,
uint64_t maxPktsPerFile = MAX_PKTS_PER_TRACE_FILE,
bool usingXML = true);
/**
* \brief Constructor
@@ -169,9 +177,10 @@ public:
* on prior calls to SetOutputFile, SetServerPort, or SetInternalAnimation.
* Then creates the callbacks needed for the animator to start processing
* packets.
*
*
* \param restart True when restarting animation
*/
void StartAnimation ();
void StartAnimation (bool restart = false);
/**
* \brief Closes the interface to the animator.
@@ -269,6 +278,15 @@ public:
void EnablePacketMetadata (bool enable);
/**
*
* \brief Get trace file packet count (This used only for testing)
*
* returns Number of packets recorded in the current trace file
*
*/
uint64_t GetTracePktCount ();
private:
#ifndef WIN32
@@ -280,12 +298,21 @@ private:
int WriteN (SOCKET, const char*, uint32_t);
#endif
bool m_xml; // True if xml format desired
Time mobilitypollinterval;
bool usingSockets;
uint16_t mport;
std::string outputfilename;
bool OutputFileSet;
bool ServerPortSet;
Time m_mobilityPollInterval;
bool m_usingSockets;
uint16_t m_port;
std::string m_outputFileName;
bool m_outputFileSet;
bool m_serverPortSet;
uint64_t gAnimUid ; // Packet unique identifier used by Animtion
bool m_randomPosition;
AnimWriteCallback m_writeCallback;
bool m_started;
bool m_enablePacketMetadata;
Time m_startTime;
Time m_stopTime;
uint64_t m_maxPktsPerFile;
std::string m_originalFileName;
void DevTxTrace (std::string context,
Ptr<const Packet> p,
@@ -339,27 +366,26 @@ private:
void OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
void MobilityAutoCheck ();
uint64_t gAnimUid ; // Packet unique identifier used by Animtion
std::map<uint64_t, AnimPacketInfo> pendingWifiPackets;
std::map<uint64_t, AnimPacketInfo> m_pendingWifiPackets;
void AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo&);
bool WifiPacketIsPending (uint64_t AnimUid);
std::map<uint64_t, AnimPacketInfo> pendingWimaxPackets;
std::map<uint64_t, AnimPacketInfo> m_pendingWimaxPackets;
void AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo&);
bool WimaxPacketIsPending (uint64_t AnimUid);
std::map<uint64_t, AnimPacketInfo> pendingLtePackets;
std::map<uint64_t, AnimPacketInfo> m_pendingLtePackets;
void AddPendingLtePacket (uint64_t AnimUid, AnimPacketInfo&);
bool LtePacketIsPending (uint64_t AnimUid);
std::map<uint64_t, AnimPacketInfo> pendingCsmaPackets;
std::map<uint64_t, AnimPacketInfo> m_pendingCsmaPackets;
void AddPendingCsmaPacket (uint64_t AnimUid, AnimPacketInfo&);
bool CsmaPacketIsPending (uint64_t AnimUid);
uint64_t GetAnimUidFromPacket (Ptr <const Packet>);
std::map<uint32_t, Vector> nodeLocation;
std::map<uint32_t, Vector> m_nodeLocation;
Vector GetPosition (Ptr <Node> n);
Vector UpdatePosition (Ptr <Node> n);
Vector UpdatePosition (Ptr <Node> n, Vector v);
@@ -376,14 +402,8 @@ private:
void RecalcTopoBounds (Vector v);
std::vector < Ptr <Node> > RecalcTopoBounds ();
bool randomPosition;
AnimWriteCallback m_writeCallback;
void ConnectCallbacks ();
bool m_started;
bool m_enablePacketMetadata;
Time m_startTime;
Time m_stopTime;
std::map <std::string, uint32_t> m_macToNodeIdMap;
bool IsInTimeWindow ();
@@ -393,14 +413,17 @@ private:
Ptr <NetDevice> GetNetDeviceFromContext (std::string context);
static std::map <uint32_t, std::string> nodeDescriptions;
uint64_t m_currentPktCount;
void StartNewTraceFile();
// XML helpers
std::string GetPreamble (void);
// Topology element dimensions
double topo_minX;
double topo_minY;
double topo_maxX;
double topo_maxY;
double m_topoMinX;
double m_topoMinY;
double m_topoMaxX;
double m_topoMaxY;
std::string GetPacketMetadata (Ptr<const Packet> p);

View File

@@ -0,0 +1,23 @@
#! /usr/bin/env python
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains
#
# (example_name, do_run, do_valgrind_run).
#
# See test.py for more information.
cpp_examples = [
("dumbbell-animation", "True", "False"),
("star-animation", "True", "False"),
("grid-animation", "True", "False"),
("wireless-animation", "True", "False"),
]
# A list of Python examples to run in order to ensure that they remain
# runnable over time. Each tuple in the list contains
#
# (example_name, do_run).
#
# See test.py for more information.
python_examples = []

View File

@@ -0,0 +1,117 @@
/* -*- 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 <john.abraham@gatech.edu>
*/
#include <iostream>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/netanim-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-layout-module.h"
namespace ns3 {
class AnimationInterfaceTestCase : public TestCase
{
public:
/**
* \brief Constructor.
*/
AnimationInterfaceTestCase ();
/**
* \brief Destructor.
*/
virtual
~AnimationInterfaceTestCase ();
/**
* \brief Run unit tests for this class.
* \return false if all tests have passed, false otherwise
*/
virtual void
DoRun (void);
};
AnimationInterfaceTestCase::AnimationInterfaceTestCase () :
TestCase ("Verify AnimationInterface")
{
}
AnimationInterfaceTestCase::~AnimationInterfaceTestCase ()
{
}
void
AnimationInterfaceTestCase::DoRun (void)
{
NodeContainer nodes;
nodes.Create (2);
AnimationInterface::SetConstantPosition (nodes.Get (0), 0 , 10);
AnimationInterface::SetConstantPosition (nodes.Get (1), 1 , 10);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign (devices);
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (100));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
std::string traceFileName = "testpy-output/netanim-test.xml";
AnimationInterface anim(traceFileName.c_str ());
Simulator::Run ();
NS_TEST_ASSERT_MSG_EQ (anim.GetTracePktCount (), 32, "Expected 32 packets traced");
FILE * fp = fopen (traceFileName.c_str (), "r");
NS_TEST_ASSERT_MSG_NE (fp, 0, "Trace file was not created");
fclose (fp);
Simulator::Destroy ();
}
static class AnimationInterfaceTestSuite : public TestSuite
{
public:
AnimationInterfaceTestSuite () :
TestSuite ("animation-interface", UNIT)
{
AddTestCase (new AnimationInterfaceTestCase ());
}
} g_animationInterfaceTestSuite;
} // namespace ns3

View File

@@ -14,6 +14,10 @@ def build (bld) :
'model/animation-interface.cc',
'helper/animation-interface-helper.cc',
]
netanim_test = bld.create_ns3_module_test_library('netanim')
netanim_test.source = [
'test/netanim-test.cc',
]
headers = bld.new_task_gen (features=['ns3header'])
headers.module = 'netanim'