Bug 1172 Special case handling for duplicates,forwards and some doxygen fixes

This commit is contained in:
John Abraham
2011-07-10 13:20:34 -04:00
parent 145ecf9669
commit 3ab8b373af
4 changed files with 416 additions and 215 deletions

View File

@@ -27,62 +27,58 @@ 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))
: m_txnd (0), m_fbTx (0), m_lbTx (0),
m_txLoc (Vector (0,0,0))
{
}
AnimPacketInfo::AnimPacketInfo(Ptr<const NetDevice> nd, const Time& fbTx,
AnimPacketInfo::AnimPacketInfo(Ptr <const NetDevice> txnd, const Time& fbTx,
const Time& lbTx, Vector txLoc)
: m_txnd (nd), m_nRx (0), m_nRxEnd (0),
m_fbTx (fbTx.GetSeconds ()), m_lbTx (lbTx.GetSeconds ()), transmitter_loc (txLoc),
reception_range (0)
: m_txnd (txnd), m_fbTx (fbTx.GetSeconds ()), m_lbTx (lbTx.GetSeconds ()),
m_txLoc (txLoc)
{
}
void AnimPacketInfo::ProcessRxBegin (Ptr<const NetDevice> nd, const Time& fbRx,
Vector rxLoc)
void AnimPacketInfo::ProcessRxBegin (Ptr<const NetDevice> nd, const Time& fbRx)
{
m_rx[nd->GetNode ()->GetId ()] = AnimRxInfo (fbRx,nd);
m_nRx++;
reception_range = std::max (reception_range,CalculateDistance (transmitter_loc,rxLoc));
m_rx[nd->GetNode ()->GetId ()] = AnimRxInfo (fbRx, nd, 0);
}
bool AnimPacketInfo::ProcessRxEnd (Ptr<const NetDevice> nd, const Time& lbRx)
bool AnimPacketInfo::ProcessRxEnd (Ptr<const NetDevice> nd, const Time& lbRx, Vector rxLoc)
{
uint32_t NodeId = nd->GetNode ()->GetId ();
// Find the RxInfo
if (m_rx.find(NodeId) != m_rx.end ())
{
// Check if the NetDevice matches. A node may have several NetDevices
if (m_rx[NodeId].m_rxnd != nd)
{
return false;
}
m_rx[NodeId].m_lbRx = lbRx.GetSeconds ();
firstlastbitDelta = m_rx[NodeId].m_lbRx - m_rx[NodeId].m_fbRx;
m_nRxEnd++;
if (m_nRxEnd == m_nRx)
{
return true;
}
return false; // Still more RxEnd notifications expected
if (m_rx.find (NodeId) == m_rx.end ())
{
return false;
}
AnimRxInfo& rxInfo = m_rx[NodeId];
// Check if the NetDevice matches. A node may have several NetDevices
if (rxInfo.m_rxnd != nd)
{
return false;
}
NS_ASSERT ("Received RxEnd notification but RxInfo never existed");
return false; // Still more rxEnd expected
rxInfo.rxRange = CalculateDistance (m_txLoc, rxLoc);
rxInfo.m_lbRx = lbRx.GetSeconds ();
firstlastbitDelta = rxInfo.m_lbRx - rxInfo.m_fbRx;
return true;
}
AnimRxInfo AnimPacketInfo::GetRxInfo (Ptr<const NetDevice> nd)
{
uint32_t NodeId = nd->GetNode ()->GetId ();
NS_ASSERT (m_rx.find (NodeId) != m_rx.end ());
return m_rx[NodeId];
}
void AnimPacketInfo::RemoveRxInfo (Ptr<const NetDevice> nd)
{
uint32_t NodeId = nd->GetNode ()->GetId ();
m_rx.erase (m_rx.find (NodeId));
}
void AnimPacketInfo::ProcessRxDrop (Ptr<const NetDevice> nd)
{
if (m_rx.find (nd->GetNode ()->GetId ()) == m_rx.end())
{
NS_LOG_DEBUG ("Received RxDrop notification");
return;
}
// Remove any entry for which an RxBegin notification was received
m_rx.erase (m_rx.find (nd->GetNode ()->GetId ()));
m_nRx--;
}

View File

@@ -56,27 +56,43 @@ public:
/**
* \brief Constructor
* \param First-bit Receive time
* \param Ptr to NetDevice used for reception
* \param fbRx First-bit Receive time
* \param nd NetDevice where packet was received
* \param rxRange Reception range
*
*/
AnimRxInfo (const Time& fbRx, Ptr <const NetDevice> nd)
: m_fbRx (fbRx.GetSeconds ()), m_lbRx (0), m_rxnd (nd) {}
AnimRxInfo (const Time& fbRx, Ptr <const NetDevice> nd ,double rxRange)
: m_fbRx (fbRx.GetSeconds ()), m_lbRx (0), m_rxnd (nd),
rxRange (rxRange) {}
/*
* First bit receive time
/**
* \brief First bit receive time
* \param m_fbRx First bit receive time
*
*/
double m_fbRx;
/*
* Last bit receive time
/**
* \brief Last bit receive time
* \param m_lbRx Last bit receive time
*
*/
double m_lbRx;
/*
* Ptr to receiving Net Device
/**
* \brief Ptr to receiving NetDevice
* \param m_rxnd Ptr to receiving NetDevice
*
*/
Ptr <const NetDevice> m_rxnd;
/**
* \brief Reception range
* \param rxRange Reception range
*
*/
double rxRange;
};
/**
@@ -101,88 +117,99 @@ 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
* \param tx_nd Ptr to NetDevice that is transmitting
* \param fbTx First bit transmit time
* \param lbTx Last bit transmit time
* \param txLoc Transmitter Location
*
*/
AnimPacketInfo(Ptr<const NetDevice> nd,
const Time& fbTx, const Time& lbTx,Vector txLoc);
AnimPacketInfo(Ptr <const NetDevice> tx_nd, const Time& fbTx, const Time& lbTx,Vector txLoc);
/**
* Ptr to NetDevice used for transmission
*/
Ptr<const NetDevice> m_txnd;
/**
* Number of receivers
*/
uint32_t m_nRx;
* \brief Ptr to NetDevice that is transmitting
* \param m_txnd NetDevice that is transmitting
*
*/
Ptr <const NetDevice> m_txnd;
/**
* Number of RxEnd trace callbacks
*/
uint32_t m_nRxEnd;
/**
* First bit transmission time
* \brief First bit transmission time
* \param m_fbTx First bit transmission time
*
*/
double m_fbTx;
/**
* Last bit transmission time
* \brief Last bit transmission time
* \param m_lbTx Last bit transmission time
*
*/
double m_lbTx;
/**
* Transmitter's location
* \brief Transmitter's location
* \param m_txLoc Transmitter's Location
*
*/
Vector transmitter_loc;
Vector m_txLoc;
/**
* Receptiion range
*/
double reception_range;
/**
* Collection of receivers
* \brief Collection of receivers
* \param m_rx Collection of receivers
*
*/
std::map<uint32_t,AnimRxInfo> m_rx;
/**
* \brief Process RxBegin notifications
* \param Ptr to NetDevice where packet was received
* \param First bit receive time
* \param Location of the transmitter
* \param nd Ptr to NetDevice where packet was received
* \param fbRx First bit receive time
*
*/
void ProcessRxBegin (Ptr <const NetDevice> nd, const Time& fbRx,
Vector rxLoc);
void ProcessRxBegin (Ptr <const NetDevice> nd, const Time& fbRx);
/**
* \brief Process RxEnd notifications
* \param Ptr to NetDevice where packet was received
* \param First bit receive time
* \param nd Ptr to NetDevice where packet was received
* \param fbRx First bit receive time
* \param rxLoc Location of receiver
* \returns true if RxEnd notification was expected and processed
*
*/
bool ProcessRxEnd (Ptr <const NetDevice> nd, const Time& fbRx);
bool ProcessRxEnd (Ptr <const NetDevice> nd, const Time& fbRx, Vector rxLoc);
/**
* \brief Process RxDrop notifications
* \param Ptr to NetDevice where packet was dropped on reception
* \param nd Ptr to NetDevice where packet was dropped on reception
*
*/
void ProcessRxDrop (Ptr <const NetDevice> nd);
/**
* \brief GetRxInfo
* \param nd Ptr to NetDevice where packet was received
* \returns AnimRxInfo object
*
*/
AnimRxInfo GetRxInfo (Ptr <const NetDevice> nd);
/**
* \brief RemoveRxInfo
* \param nd Ptr to NetDevice where packet was received
*
*/
void RemoveRxInfo (Ptr <const NetDevice> nd);
/**
* \brief Time delta between First bit Rx and Last bit Rx
*
* \param firstlastbitDelta Time delta between First bit Rx and Last bit Rx
*/
double firstlastbitDelta;

View File

@@ -43,6 +43,8 @@
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "ns3/animation-interface-helper.h"
#include "ns3/wifi-mac-header.h"
#include "ns3/wimax-mac-header.h"
NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
@@ -51,21 +53,21 @@ namespace ns3 {
AnimationInterface::AnimationInterface ()
: m_fHandle (STDOUT_FILENO), m_xml (false), mobilitypollinterval (Seconds(0.25)),
usingSockets (false), mport (0), outputfilename (""),
OutputFileSet (false), ServerPortSet (false)
OutputFileSet (false), ServerPortSet (false), gAnimUid (0)
{
}
AnimationInterface::AnimationInterface (const std::string fn, bool usingXML)
: m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)),
usingSockets (false), mport (0), outputfilename (fn),
OutputFileSet (false), ServerPortSet (false)
OutputFileSet (false), ServerPortSet (false), gAnimUid (0)
{
}
AnimationInterface::AnimationInterface (const uint16_t port, bool usingXML)
: m_fHandle (STDOUT_FILENO), m_xml (usingXML), mobilitypollinterval (Seconds(0.25)),
usingSockets (true), mport (port), outputfilename (""),
OutputFileSet (false), ServerPortSet (false)
OutputFileSet (false), ServerPortSet (false), gAnimUid (0)
{
}
@@ -127,15 +129,15 @@ bool AnimationInterface::SetServerPort (uint16_t port)
// which is done to support a platform like MinGW
}
bool AnimationInterface::WifiPacketIsPending (uint64_t Uid)
bool AnimationInterface::WifiPacketIsPending (uint64_t AnimUid)
{
return (pendingWifiPackets.find (Uid) != pendingWifiPackets.end ());
return (pendingWifiPackets.find (AnimUid) != pendingWifiPackets.end ());
}
bool AnimationInterface::WimaxPacketIsPending (uint64_t Uid)
bool AnimationInterface::WimaxPacketIsPending (uint64_t AnimUid)
{
return (pendingWimaxPackets.find (Uid) != pendingWimaxPackets.end ());
return (pendingWimaxPackets.find (AnimUid) != pendingWimaxPackets.end ());
}
void AnimationInterface::SetMobilityPollInterval (Time t)
@@ -146,15 +148,15 @@ void AnimationInterface::SetMobilityPollInterval (Time t)
Vector AnimationInterface::UpdatePosition (Ptr <Node> n)
{
Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
Vector v(0,0,0);
if (!loc)
{
return v;
}
Vector v(100,100,0);
if (loc)
{
v = loc->GetPosition ();
}
else
{
NS_LOG_WARN ( "Node:" << n->GetId () << " Does not have a mobility model");
}
nodeLocation[n->GetId ()] = v;
return v;
}
@@ -190,28 +192,17 @@ 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;
topo_maxX = 0;
topo_maxY = 0;
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
Ptr<Node> n = *i;
NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
Vector v = UpdatePosition (n);
if (first)
{
topo_minX = v.x;
topo_minY = v.y;
topo_maxX = v.x;
topo_maxY = v.y;
first = false;
}
else
{
topo_minX = std::min (topo_minX, v.x);
topo_minY = std::min (topo_minY, v.y);
topo_maxX = std::max (topo_maxX, v.x);
topo_maxY = std::max (topo_maxY, v.y);
}
topo_minX = std::min (topo_minX, v.x);
topo_minY = std::min (topo_minY, v.y);
topo_maxX = std::max (topo_maxX, v.x);
topo_maxY = std::max (topo_maxY, v.y);
}
AddMargin ();
@@ -223,6 +214,7 @@ void AnimationInterface::StartAnimation ()
oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
WriteN (m_fHandle, oss.str ());
}
NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
// Dump the topology
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
@@ -243,6 +235,7 @@ void AnimationInterface::StartAnimation ()
WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ());
}
NS_LOG_INFO ("Setting p2p links");
// Now dump the p2p links
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
@@ -280,7 +273,6 @@ void AnimationInterface::StartAnimation ()
oss << "0.0 L " << n1Id << " " << n2Id << std::endl;
}
WriteN (m_fHandle, oss.str ());
}
}
}
@@ -350,13 +342,57 @@ void AnimationInterface::AddMargin ()
topo_minY -= h * 0.05;
topo_maxX = topo_minX + w * 1.5;
topo_maxY = topo_minY + h * 1.5;
NS_LOG_INFO ("Added Canvas Margin:" << topo_minX << "," <<
topo_minY << "," << topo_maxX << "," << topo_maxY);
}
std::vector <Ptr <Node> > AnimationInterface::RecalcTopoBounds ()
{
std::vector < Ptr <Node> > MovedNodes;
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
{
Ptr<Node> n = *i;
NS_ASSERT (n);
Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
Vector newLocation;
if (!mobility)
{
newLocation = GetPosition (n);
}
else
{
newLocation = mobility->GetPosition ();
}
if (!NodeHasMoved (n, newLocation))
{
continue; //Location has not changed
}
else
{
UpdatePosition (n, newLocation);
RecalcTopoBounds (newLocation);
MovedNodes.push_back (n);
}
}
return MovedNodes;
}
void AnimationInterface::RecalcTopoBounds (Vector v)
{
double oldminX = topo_minX;
double oldminY = topo_minY;
double oldmaxX = topo_maxX;
double oldmaxY = topo_maxY;
topo_minX = std::min (topo_minX, v.x);
topo_minY = std::min (topo_minY, v.y);
topo_maxX = std::max (topo_maxX, v.x);
topo_maxY = std::max (topo_maxY, v.y);
if ((topo_minX != oldminX) || (topo_minY != oldminY) ||
(topo_maxX != oldmaxX) || (topo_maxY != oldmaxY))
{
AddMargin ();
}
}
int AnimationInterface::WriteN (int h, const char* data, uint32_t count)
@@ -441,6 +477,32 @@ AnimationInterface::GetNetDeviceFromContext (std::string context)
return n->GetDevice (atoi (elements[3].c_str ()));
}
void AnimationInterface::AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
pendingWifiPackets[AnimUid] = pktinfo;
}
void AnimationInterface::AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo &pktinfo)
{
NS_ASSERT (pktinfo.m_txnd);
pendingWimaxPackets[AnimUid] = pktinfo;
}
uint64_t AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
{
AnimByteTag tag;
if (p->FindFirstMatchingByteTag (tag))
{
return tag.Get ();
}
else
{
return 0;
}
}
void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
Ptr<const Packet> p)
{
@@ -449,10 +511,13 @@ void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
Ptr <Node> n = ndev->GetNode ();
NS_ASSERT (n);
// Add a new pending wireless
uint64_t Uid = p->GetUid ();
NS_LOG_INFO ("TxBeginTrace for packet:" << Uid);
pendingWifiPackets[Uid] =
AnimPacketInfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
gAnimUid++;
NS_LOG_INFO ("TxBeginTrace for packet:" << gAnimUid);
AnimByteTag tag;
tag.Set (gAnimUid);
p->AddByteTag (tag);
AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
AddPendingWifiPacket (gAnimUid, pktinfo);
}
void AnimationInterface::WifiPhyTxEndTrace (std::string context,
@@ -466,10 +531,10 @@ void AnimationInterface::WifiPhyTxDropTrace (std::string context,
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
// Erase pending wifi
uint64_t Uid = p->GetUid ();
NS_LOG_INFO ("TxDropTrace for packet:" << Uid);
NS_ASSERT (WifiPacketIsPending (Uid) == true);
pendingWifiPackets.erase (pendingWifiPackets.find (Uid));
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
pendingWifiPackets.erase (pendingWifiPackets.find (AnimUid));
}
@@ -478,12 +543,10 @@ void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
{
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
NS_ASSERT (n);
uint64_t Uid = p->GetUid ();
NS_LOG_INFO ("RxBeginTrace for packet:" << Uid);
NS_ASSERT (WifiPacketIsPending (Uid) == true);
pendingWifiPackets[Uid].ProcessRxBegin (ndev, Simulator::Now (), UpdatePosition (n));
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_LOG_INFO ("RxBeginTrace for packet:" << AnimUid);
NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
}
@@ -492,14 +555,17 @@ void AnimationInterface::WifiPhyRxEndTrace (std::string context,
{
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
uint64_t Uid = p->GetUid ();
NS_ASSERT (WifiPacketIsPending (Uid) == true);
AnimPacketInfo& pkt = pendingWifiPackets[Uid];
if (pkt.ProcessRxEnd (ndev, Simulator::Now ()))
Ptr <Node> n = ndev->GetNode ();
NS_ASSERT (n);
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingWifiPackets[AnimUid];
if (pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n)))
{
NS_LOG_INFO ("RxEndTrace for packet:" << Uid << " complete");
OutputWirelessPacket (Uid, pkt);
pendingWifiPackets.erase (pendingWifiPackets.find (Uid));;
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
NS_LOG_INFO ("RxEndTrace for packet:" << AnimUid << " complete");
OutputWirelessPacket (pktInfo, pktrxInfo);
pktInfo.RemoveRxInfo (ndev);
}
}
@@ -507,12 +573,6 @@ void AnimationInterface::WifiPhyRxEndTrace (std::string context,
void AnimationInterface::WifiPhyRxDropTrace (std::string context,
Ptr<const Packet> p)
{
Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
NS_ASSERT (ndev);
uint64_t Uid = p->GetUid ();
NS_LOG_INFO ("RxDropTrace for packet:"<< Uid);
//NS_ASSERT (WifiPacketIsPending (Uid) == true);
pendingWifiPackets[Uid].ProcessRxDrop (ndev);
}
void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
@@ -521,11 +581,14 @@ void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p,
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
NS_ASSERT (n);
uint64_t Uid = p->GetUid ();
NS_LOG_INFO ("WimaxTxTrace for packet:" << Uid);
pendingWimaxPackets[Uid] =
AnimPacketInfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.0001), UpdatePosition (n));
//HACK:TODO 0.0001 is used until Wimax implements TxBegin and TxEnd traces
gAnimUid++;
NS_LOG_INFO ("WimaxTxTrace for packet:" << gAnimUid);
AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
//TODO 0.0001 is used until Wimax implements TxBegin and TxEnd traces
AnimByteTag tag;
tag.Set (gAnimUid);
p->AddByteTag (tag);
AddPendingWimaxPacket (gAnimUid, pktinfo);
}
@@ -535,25 +598,30 @@ void AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p,
NS_ASSERT (ndev);
Ptr <Node> n = ndev->GetNode ();
NS_ASSERT (n);
uint64_t Uid = p->GetUid ();
NS_ASSERT (WimaxPacketIsPending (Uid) == true);
AnimPacketInfo& pktinfo = pendingWimaxPackets[Uid];
pktinfo.ProcessRxBegin (ndev, Simulator::Now (), UpdatePosition (n));
pktinfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.0001));
//HACK:TODO 0.0001 is used until Wimax implements RxBegin and RxEnd traces
NS_LOG_INFO ("WimaxRxTrace for packet:" << Uid);
OutputWirelessPacket (Uid, pktinfo);
uint64_t AnimUid = GetAnimUidFromPacket (p);
NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
AnimPacketInfo& pktInfo = pendingWimaxPackets[AnimUid];
pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
//TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
OutputWirelessPacket (pktInfo, pktrxInfo);
}
void AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
{
Ptr <Node> n = mobility->GetObject <Node> ();
if (!n) return;
if (!mobility) return;
NS_ASSERT (n);
Vector v ;
v = mobility->GetPosition ();
if (!mobility)
{
v = GetPosition (n);
}
else
{
v = mobility->GetPosition ();
}
UpdatePosition (n,v);
RecalcTopoBounds (v);
std::ostringstream oss;
@@ -581,22 +649,15 @@ bool AnimationInterface::NodeHasMoved (Ptr <Node> n, Vector newLocation)
void AnimationInterface::MobilityAutoCheck ()
{
std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
std::ostringstream oss;
oss << GetXMLOpen_topology (topo_minX,topo_minY,topo_maxX,topo_maxY);
for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
for (uint32_t i = 0; i < MovedNodes.size (); i++)
{
Ptr <Node> n = *i;
if (!n) continue;
Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
if (!mobility) continue;
Vector newLocation = mobility->GetPosition ();
if (!NodeHasMoved (n, newLocation))
{
continue; //Location has not changed
}
UpdatePosition (n, newLocation);
RecalcTopoBounds (newLocation);
oss << GetXMLOpenClose_node (0,n->GetId (),newLocation.x,newLocation.y);
Ptr <Node> n = MovedNodes [i];
NS_ASSERT (n);
Vector v = GetPosition (n);
oss << GetXMLOpenClose_node (0,n->GetId (), v.x, v.y);
}
oss << GetXMLClose ("topology");
WriteN (m_fHandle, oss.str ());
@@ -653,41 +714,24 @@ std::string AnimationInterface::GetPreamble ()
</information>\n";
return s;
}
void AnimationInterface::OutputWirelessPacket (uint32_t uid, AnimPacketInfo& pktInfo)
void AnimationInterface::OutputWirelessPacket (AnimPacketInfo &pktInfo, AnimRxInfo pktrxInfo)
{
if (!m_xml) return;
NS_ASSERT (m_xml);
std::ostringstream oss;
RxInfoIterator p;
NS_ASSERT (pktInfo.m_txnd);
uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
// double lbTx = pktInfo.m_lbTx; //This is not yet implemented
// HACK: TODO figure out lbTx from the delta of the first Rx packet
// Ideally all Phy interfaces should have implemented TxEnd notifications
// But currently that is not the case
double lbTx = pktInfo.firstlastbitDelta + pktInfo.m_fbTx;
oss << GetXMLOpen_wpacket (0, nodeId, pktInfo.m_fbTx, lbTx, pktrxInfo.rxRange);
double lbTx = pktInfo.firstlastbitDelta + pktInfo.m_fbTx;
oss << GetXMLOpen_wpacket (0,nodeId,pktInfo.m_fbTx,lbTx,pktInfo.reception_range);
uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId ();
oss << GetXMLOpenClose_rx (0, rxId, pktrxInfo.m_fbRx, pktrxInfo.m_lbRx);
// Now add each rx
for (p = pktInfo.m_rx.begin (); p != pktInfo.m_rx.end (); p++)
{
AnimRxInfo& rx = p->second;
uint32_t rxId = rx.m_rxnd->GetNode ()->GetId ();
if ((rx.m_lbRx - rx.m_fbRx) != pktInfo.firstlastbitDelta)
{
//TODO: how to handle this case elegantly?
continue;
}
if (rx.m_lbRx)
{
oss << GetXMLOpenClose_rx (0,rxId,rx.m_fbRx,rx.m_lbRx);
}
}
oss << GetXMLClose ("wpacket");
WriteN (m_fHandle, oss.str ());
}
// XML Private Helpers
std::string AnimationInterface::GetXMLOpen_anim (uint32_t lp)
@@ -772,5 +816,52 @@ std::vector<std::string> AnimationInterface::GetElementsFromContext (std::string
return elements;
}
TypeId
AnimByteTag::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::AnimByteTag")
.SetParent<Tag> ()
.AddConstructor<AnimByteTag> ()
;
return tid;
}
TypeId
AnimByteTag::GetInstanceTypeId (void) const
{
return GetTypeId ();
}
uint32_t
AnimByteTag::GetSerializedSize (void) const
{
return sizeof (uint64_t);
}
void
AnimByteTag::Serialize (TagBuffer i) const
{
i.WriteU64 (m_AnimUid);
}
void
AnimByteTag::Deserialize (TagBuffer i)
{
m_AnimUid = i.ReadU64 ();
}
void
AnimByteTag::Print (std::ostream &os) const
{
os << "AnimUid=" << m_AnimUid;
}
void
AnimByteTag::Set (uint64_t AnimUid)
{
m_AnimUid = AnimUid;
}
uint64_t
AnimByteTag::Get (void) const
{
return m_AnimUid;
}
} // namespace ns3

View File

@@ -36,7 +36,6 @@
namespace ns3 {
class NetModel;
/**
* \defgroup netanim Netanim
*
@@ -57,27 +56,29 @@ public:
/**
* \brief Construct the animator interface. No arguments needed.
*
*/
AnimationInterface ();
/**
* \brief Destructor for the animator interface.
*
*/
~AnimationInterface ();
/**
* \brief Constructor
* \param Filename for the trace file used by the Animator
* \param Set to true if XML output traces are required
* \param filename The Filename for the trace file used by the Animator
* \param usingXML Set to true if XML output traces are required
*
*/
AnimationInterface (const std::string filename, bool usingXML = true);
/**
* \brief Constructor
* \param Port on which ns-3 should listen to for connection from the
* \param port Port on which ns-3 should listen to for connection from the
* external netanim application
* \param Set to true if XML output traces are required
* \param usingXML Set to true if XML output traces are required
*
*/
AnimationInterface (uint16_t port, bool usingXML = true);
@@ -91,6 +92,7 @@ public:
*
* \param fn The name of the output file.
* \returns true if successful open.
*
*/
bool SetOutputFile (const std::string& fn);
@@ -99,6 +101,7 @@ public:
* in XML format.
*
* \returns none
*
*/
void SetXMLOutput ();
@@ -113,6 +116,7 @@ public:
*
* \param port Port number to bind to.
* \returns true if connection created, false if bind failed.
*
*/
bool SetServerPort (uint16_t port);
@@ -138,14 +142,14 @@ public:
* \brief Set mobility poll interval:WARNING: setting a low interval can
* cause slowness
*
* \param Time interval between fetching mobility/position information
* \param t Time interval between fetching mobility/position information
* Default: 0.25s
*
*/
void SetMobilityPollInterval (Time t);
private:
int m_fHandle; // File handle for output (-1 if none)
bool m_xml; // True if xml format desired
Time mobilitypollinterval;
@@ -172,7 +176,6 @@ private:
Ptr<const Packet> p);
void WifiPhyRxDropTrace (std::string context,
Ptr<const Packet> p);
void WimaxTxTrace (std::string context,
Ptr<const Packet> p,
const Mac48Address &);
@@ -181,8 +184,6 @@ private:
const Mac48Address &);
void MobilityCourseChangeTrace (Ptr <const MobilityModel> mob);
typedef std::map <uint32_t,AnimRxInfo>::iterator RxInfoIterator;
// Write specified amount of data to the specified handle
int WriteN (int, const char*, uint32_t);
@@ -190,13 +191,21 @@ private:
int WriteN (int, const std::string&);
//Helpers to output xml wireless packet
void OutputWirelessPacket (uint32_t, AnimPacketInfo&);
void OutputWirelessPacket (AnimPacketInfo& pktInfo, AnimRxInfo pktrxInfo);
void MobilityAutoCheck ();
std::map<uint64_t, AnimPacketInfo> pendingWifiPackets;
std::map<uint64_t, AnimPacketInfo> pendingWimaxPackets;
bool WifiPacketIsPending (uint64_t Uid);
bool WimaxPacketIsPending (uint64_t Uid);
uint64_t gAnimUid ; // Packet unique identifier used by Animtion
std::map<uint64_t, AnimPacketInfo> pendingWifiPackets;
void AddPendingWifiPacket (uint64_t AnimUid, AnimPacketInfo&);
bool WifiPacketIsPending (uint64_t AnimUid);
std::map<uint64_t, AnimPacketInfo> pendingWimaxPackets;
void AddPendingWimaxPacket (uint64_t AnimUid, AnimPacketInfo&);
bool WimaxPacketIsPending (uint64_t AnimUid);
uint64_t GetAnimUidFromPacket (Ptr <const Packet>);
std::map<uint32_t, Vector> nodeLocation;
Vector GetPosition (Ptr <Node> n);
Vector UpdatePosition (Ptr <Node> n);
@@ -207,6 +216,7 @@ private:
// Recalculate topology bounds
void RecalcTopoBounds (Vector v);
std::vector < Ptr <Node> > RecalcTopoBounds ();
// Path helper
std::vector<std::string> GetElementsFromContext (std::string context);
@@ -230,6 +240,83 @@ private:
std::string GetXMLClose (std::string name) {return "</" + name + ">\n"; }
};
/**
* \ingroup netanim
*
* \brief Byte tag using by Anim to uniquely identify packets
*
* When Anim receives a Tx Notification we tag the packet with a unique global uint64_t identifier
* before recording Tx information
* When Anim receives Rx notifications the tag is used to retrieve Tx information recorded earlier
*
*/
class AnimByteTag : public Tag
{
public:
/**
* \brief Get Type Id
* \returns Type Id
*
*/
static TypeId GetTypeId (void);
/**
* \brief Get Instance Type Id
* \returns Type Id
*
*/
virtual TypeId GetInstanceTypeId (void) const;
/**
* \brief Get Serialized Size
* \returns Serialized Size (i.e size of uint64_t)
*
*/
virtual uint32_t GetSerializedSize (void) const;
/**
* \brief Serialize function
* \param i Tag Buffer
*
*/
virtual void Serialize (TagBuffer i) const;
/**
* \brief Deserialize function
* \param i Tag Buffer
*
*/
virtual void Deserialize (TagBuffer i);
/**
* \brief Print tag info
* \param os Reference of ostream object
*
*/
virtual void Print (std::ostream &os) const;
/**
* \brief Set global Uid in tag
* \param AnimUid global Uid
*
*/
void Set (uint64_t AnimUid);
/**
* \brief Get Uid in tag
* \returns Uid in tag
*
*/
uint64_t Get (void) const;
private:
uint64_t m_AnimUid;
};
}
#endif