NetAnim: add test and examples to run
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
23
src/netanim/test/examples-to-run.py
Normal file
23
src/netanim/test/examples-to-run.py
Normal 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 = []
|
||||
117
src/netanim/test/netanim-test.cc
Normal file
117
src/netanim/test/netanim-test.cc
Normal 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
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user