A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
animation-interface.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Author: George F. Riley<riley@ece.gatech.edu>
17  * Modified by: John Abraham <john.abraham@gatech.edu>
18  */
19 
20 // Interface between ns3 and the network animator
21 
22 
23 // ns3 includes
24 #include "ns3/animation-interface.h"
25 #include "ns3/channel.h"
26 #include "ns3/config.h"
27 #include "ns3/node.h"
28 #include "ns3/mobility-model.h"
29 #include "ns3/packet.h"
30 #include "ns3/simulator.h"
31 #include "ns3/animation-interface-helper.h"
32 #include "ns3/wifi-mac-header.h"
33 #include "ns3/wimax-mac-header.h"
34 #include "ns3/wifi-net-device.h"
35 #include "ns3/wifi-mac.h"
36 #include "ns3/constant-position-mobility-model.h"
37 #include "ns3/lte-ue-phy.h"
38 #include "ns3/lte-enb-phy.h"
39 #include "ns3/uan-net-device.h"
40 #include "ns3/uan-mac.h"
41 #include "ns3/ipv4.h"
42 #include "ns3/ipv4-routing-protocol.h"
43 
44 #include <cstdio>
45 #include <unistd.h>
46 #include <sstream>
47 #include <fstream>
48 #include <string>
49 #include <iomanip>
50 #include <map>
51 
52 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
53 
54 namespace ns3 {
55 
56 #define PURGE_INTERVAL 5
57 
58 static bool initialized = false;
59 std::map <uint32_t, std::string> AnimationInterface::nodeDescriptions;
60 std::map <uint32_t, Rgb> AnimationInterface::nodeColors;
61 std::map <P2pLinkNodeIdPair, LinkProperties, LinkPairCompare> AnimationInterface::linkProperties;
62 
63 
64 AnimationInterface::AnimationInterface (const std::string fn, uint64_t maxPktsPerFile, bool usingXML)
65  : m_routingF (0), m_xml (usingXML), m_mobilityPollInterval (Seconds(0.25)),
66  m_outputFileName (fn),
67  m_outputFileSet (false), gAnimUid (0), m_randomPosition (true),
68  m_writeCallback (0), m_started (false),
69  m_enablePacketMetadata (false), m_startTime (Seconds(0)), m_stopTime (Seconds(3600 * 1000)),
70  m_maxPktsPerFile (maxPktsPerFile), m_originalFileName (fn),
71  m_routingStopTime (Seconds (0)), m_routingFileName (""),
72  m_routingPollInterval (Seconds (5))
73 {
74  m_uniformRandomVariable = CreateObject<UniformRandomVariable> ();
75  initialized = true;
76  StartAnimation ();
77 }
78 
80 {
81  StopAnimation ();
82 }
83 
84 void AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, Time pollInterval)
85 {
86  m_routingFileName = fileName;
88  m_routingStopTime = stopTime;
89  m_routingPollInterval = pollInterval;
92 }
93 
94 void AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, NodeContainer nc, Time pollInterval)
95 {
96  m_routingNc = nc;
97  EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
98 }
99 
101 {
102 
103  NS_ASSERT (n);
104  Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
105  if (!ipv4)
106  {
107  NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
108  return "";
109  }
110  std::stringstream stream;
111  Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
112  ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
113  return stream.str();
114 
115 }
116 
118 {
120  {
121  NS_LOG_INFO ("TrackIpv4Route completed");
122  return;
123  }
124  if (m_routingNc.GetN ())
125  {
126  for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
127  {
128  Ptr <Node> n = *i;
130  }
131  }
132  else
133  {
134  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
135  {
136  Ptr <Node> n = *i;
138  }
139  }
141 }
142 
144 {
145  NS_LOG_INFO ("XML output set");
146  m_xml = true;
147 }
148 
149 
151 {
152  static int i = 0;
153  std::ostringstream oss;
154  oss << i;
157  {
158  return;
159  }
160  StopAnimation ();
161  m_outputFileName = m_originalFileName + "-" + oss.str ();
162  StartAnimation (true);
163  ++i;
164 
165 }
166 
168 {
169  return "netanim-3.103";
170 }
171 
173 {
174  m_startTime = t;
175 }
176 
178 {
179  m_stopTime = t;
180 }
181 
182 bool AnimationInterface::SetOutputFile (const std::string& fn)
183 {
184  if (m_outputFileSet)
185  {
186  return true;
187  }
188  NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
189  m_f = std::fopen (fn.c_str (), "w");
190  if (!m_f)
191  {
192  NS_FATAL_ERROR ("Unable to open Animation output file");
193  return false; // Can't open
194  }
195  m_outputFileName = fn;
196  m_outputFileSet = true;
197  return true;
198 }
199 
200 bool AnimationInterface::SetRoutingOutputFile (const std::string& fn)
201 {
202  if (m_routingF)
203  {
204  NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
205  return false;
206  }
207  m_routingF = std::fopen (fn.c_str (), "w");
208  if (!m_routingF)
209  {
210  NS_FATAL_ERROR ("Unable to open Animation Routing output file");
211  return false;
212  }
213  return true;
214 }
215 
217 {
218  m_enablePacketMetadata = enable;
219  if (enable)
221 }
222 
224 {
225  return initialized;
226 }
227 
229 {
230  return m_started;
231 
232 }
233 
234 void AnimationInterface::SetAnimWriteCallback (AnimWriteCallback cb)
235 {
236  m_writeCallback = cb;
237 }
238 
240 {
241  m_writeCallback = 0;
242 }
243 
245 {
246  if ((Simulator::Now () >= m_startTime) &&
247  (Simulator::Now () <= m_stopTime))
248  return true;
249  else
250  return false;
251 }
252 
254 {
255  return (m_pendingUanPackets.find (AnimUid) != m_pendingUanPackets.end ());
256 }
257 
259 {
260  return (m_pendingWifiPackets.find (AnimUid) != m_pendingWifiPackets.end ());
261 }
262 
264 {
265  return (m_pendingCsmaPackets.find (AnimUid) != m_pendingCsmaPackets.end ());
266 }
267 
268 
270 {
271  return (m_pendingWimaxPackets.find (AnimUid) != m_pendingWimaxPackets.end ());
272 }
273 
275 {
276  return (m_pendingLtePackets.find (AnimUid) != m_pendingLtePackets.end ());
277 }
278 
280 {
282 }
283 
285 {
286  m_randomPosition = setRandPos;
287 }
288 
290 {
292  if (loc)
293  {
294  m_nodeLocation[n->GetId ()] = loc->GetPosition ();
295  }
296  else
297  {
298  NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
299  Vector deterministicVector (100,100,0);
301  if (m_randomPosition)
302  {
303  m_nodeLocation[n->GetId ()] = randomVector;
304  }
305  else
306  {
307  m_nodeLocation[n->GetId ()] = deterministicVector;
308  }
309  }
310  return m_nodeLocation[n->GetId ()];
311 }
312 
314 {
315  m_nodeLocation[n->GetId ()] = v;
316  return v;
317 }
318 
320 {
321  #ifdef NS_LOG
322  if (m_nodeLocation.find (n->GetId()) == m_nodeLocation.end ())
323  {
324  NS_FATAL_ERROR ("Node:" <<n->GetId() << " not found in Location table");
325  }
326  #endif
327  return m_nodeLocation[n->GetId ()];
328 }
329 
331 {
332  if (m_pendingWifiPackets.empty ())
333  return;
334  std::vector <uint64_t> purgeList;
335  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWifiPackets.begin ();
336  i != m_pendingWifiPackets.end ();
337  ++i)
338  {
339 
340  AnimPacketInfo pktInfo = i->second;
341  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
342  if (delta > PURGE_INTERVAL)
343  {
344  purgeList.push_back (i->first);
345  }
346  }
347 
348  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
349  i != purgeList.end ();
350  ++i)
351  {
352  m_pendingWifiPackets.erase (*i);
353  }
354 
355 }
356 
358 {
359  if (m_pendingWimaxPackets.empty ())
360  return;
361  std::vector <uint64_t> purgeList;
362  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingWimaxPackets.begin ();
363  i != m_pendingWimaxPackets.end ();
364  ++i)
365  {
366 
367  AnimPacketInfo pktInfo = i->second;
368  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
369  if (delta > PURGE_INTERVAL)
370  {
371  purgeList.push_back (i->first);
372  }
373  }
374 
375  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
376  i != purgeList.end ();
377  ++i)
378  {
379  m_pendingWimaxPackets.erase (*i);
380  }
381 
382 }
383 
384 
386 {
387  if (m_pendingLtePackets.empty ())
388  return;
389  std::vector <uint64_t> purgeList;
390  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingLtePackets.begin ();
391  i != m_pendingLtePackets.end ();
392  ++i)
393  {
394 
395  AnimPacketInfo pktInfo = i->second;
396  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
397  if (delta > PURGE_INTERVAL)
398  {
399  purgeList.push_back (i->first);
400  }
401  }
402 
403  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
404  i != purgeList.end ();
405  ++i)
406  {
407  m_pendingLtePackets.erase (*i);
408  }
409 }
410 
412 {
413  if (m_pendingCsmaPackets.empty ())
414  return;
415  std::vector <uint64_t> purgeList;
416  for (std::map<uint64_t, AnimPacketInfo>::iterator i = m_pendingCsmaPackets.begin ();
417  i != m_pendingCsmaPackets.end ();
418  ++i)
419  {
420 
421  AnimPacketInfo pktInfo = i->second;
422  double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
423  if (delta > PURGE_INTERVAL)
424  {
425  purgeList.push_back (i->first);
426  }
427  }
428 
429  for (std::vector <uint64_t>::iterator i = purgeList.begin ();
430  i != purgeList.end ();
431  ++i)
432  {
433  m_pendingCsmaPackets.erase (*i);
434  }
435 
436 }
437 
439 {
440  Address nodeAddr = nd->GetAddress();
441  std::ostringstream oss;
442  oss << nodeAddr;
443  return oss.str ().substr (6); // Skip the first 6 chars to get the Mac
444 }
445 
447 {
448  Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
449  if (!ipv4)
450  return "0.0.0.0";
451  int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
452  if (ifIndex == -1)
453  {
454  NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
455  return "0.0.0.0";
456  }
457  Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, 0);
458  std::ostringstream oss;
459  oss << addr.GetLocal ();
460  return oss.str ();
461 }
462 
464 {
465  m_currentPktCount = 0;
466  m_started = true;
468 
469  // Find the min/max x/y for the xml topology element
470  m_topoMinX = -2;
471  m_topoMinY = -2;
472  m_topoMaxX = 2;
473  m_topoMaxY = 2;
474  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
475  {
476  Ptr<Node> n = *i;
477  NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
478  Vector v = UpdatePosition (n);
479  m_topoMinX = std::min (m_topoMinX, v.x);
480  m_topoMinY = std::min (m_topoMinY, v.y);
481  m_topoMaxX = std::max (m_topoMaxX, v.x);
482  m_topoMaxY = std::max (m_topoMaxY, v.y);
483  struct Rgb rgb = {255, 0, 0};
484  if (nodeColors.find (n->GetId ()) == nodeColors.end ())
485  {
486  nodeColors[n->GetId ()] = rgb;
487  }
488  }
489 
490 
491  std::ostringstream oss;
492  oss << GetXMLOpen_anim (0);
493  oss << GetPreamble ();
495  WriteN (oss.str (), m_f);
496  NS_LOG_INFO ("Setting topology for "<<NodeList::GetNNodes ()<<" Nodes");
497  // Dump the topology
498  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
499  {
500  Ptr<Node> n = *i;
501  std::ostringstream oss;
502  Vector v = GetPosition (n);
503  struct Rgb rgb = nodeColors[n->GetId ()];
504  oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, rgb);
505  WriteN (oss.str (), m_f);
506  }
507  NS_LOG_INFO ("Setting p2p links");
508  // Now dump the p2p links
509  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
510  {
511  Ptr<Node> n = *i;
512  uint32_t n1Id = n->GetId ();
513  uint32_t nDev = n->GetNDevices (); // Number of devices
514  for (uint32_t i = 0; i < nDev; ++i)
515  {
516  Ptr<NetDevice> dev = n->GetDevice (i);
517  NS_ASSERT (dev);
518  Ptr<Channel> ch = dev->GetChannel ();
519  if (!ch)
520  {
521  NS_LOG_DEBUG ("No channel can't be a p2p device");
522  continue;
523  }
524  std::string channelType = ch->GetInstanceTypeId ().GetName ();
525  if (channelType == std::string ("ns3::PointToPointChannel"))
526  { // Since these are duplex links, we only need to dump
527  // if srcid < dstid
528  uint32_t nChDev = ch->GetNDevices ();
529  for (uint32_t j = 0; j < nChDev; ++j)
530  {
531  Ptr<NetDevice> chDev = ch->GetDevice (j);
532  uint32_t n2Id = chDev->GetNode ()->GetId ();
533  if (n1Id < n2Id)
534  {
535  // ouptut the p2p link
536  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << ":" << GetMacAddress (dev) << "----" << GetIpv4Address (chDev) << ":" << GetMacAddress (chDev) );
537  SetLinkDescription (n1Id, n2Id, "", GetIpv4Address (dev) + "~" + GetMacAddress (dev), GetIpv4Address (chDev) + "~" + GetMacAddress (chDev));
538  std::ostringstream oss;
539  if (m_xml)
540  {
541  oss << GetXMLOpenClose_link (0, n1Id, 0, n2Id);
542  }
543  else
544  {
545  oss << "0.0 L " << n1Id << " " << n2Id << std::endl;
546  }
547  WriteN (oss.str (), m_f);
548  }
549  }
550  }
551  else
552  {
553  NS_LOG_INFO ("Link:" << GetIpv4Address (dev) << " Channel Type:" << channelType << " Mac: " << GetMacAddress (dev));
554  WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
555  }
556  }
557  }
558  linkProperties.clear ();
559  if (m_xml && !restart)
560  {
561  WriteN (GetXMLClose ("topology"), m_f);
563  }
564  if (!restart)
565  ConnectCallbacks ();
566 }
567 
569 {
570 
571  Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy ();
572  Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy ();
573  Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy ();
574  std::ostringstream oss;
575  //NodeList/*/DeviceList/*/
576  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
577  if (dlPhy)
578  {
579  dlPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
580  dlPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
581  }
582  if (ulPhy)
583  {
584  ulPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
585  ulPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
586  }
587 }
588 
589 
590 
592 {
593 
594  Ptr<LteUePhy> lteUePhy = nd->GetPhy ();
595  Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy ();
596  Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy ();
597  std::ostringstream oss;
598  //NodeList/*/DeviceList/*/
599  oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
600  if (dlPhy)
601  {
602  dlPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
603  dlPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
604  }
605  if (ulPhy)
606  {
607  ulPhy->TraceConnect ("TxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
608  ulPhy->TraceConnect ("RxStart",oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
609  }
610 }
611 
613 {
614 
615  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
616  {
617  Ptr<Node> n = *i;
618  NS_ASSERT (n);
619  uint32_t nDevices = n->GetNDevices ();
620  for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
621  {
622  Ptr <NetDevice> nd = n->GetDevice(devIndex);
623  if (!nd)
624  continue;
625  Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice> (nd);
626  if (lteUeNetDevice)
627  {
628  ConnectLteUe (n, lteUeNetDevice, devIndex);
629  continue;
630  }
631  Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice> (nd);
632  if (lteEnbNetDevice)
633  ConnectLteEnb (n, lteEnbNetDevice, devIndex);
634  }
635 
636  }
637 }
638 
640 {
641  // Connect the callbacks
642  Config::Connect ("/ChannelList/*/TxRxPointToPoint",
644  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxBegin",
646  Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
648  Config::ConnectWithoutContext ("/NodeList/*/$ns3::MobilityModel/CourseChange",
650  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
652  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
654  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
656  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
658  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
660  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
662  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
664  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
666  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
668  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
670 
671  ConnectLte ();
672 
673 }
674 
675 
677 {
678  m_started = false;
679  NS_LOG_INFO ("Stopping Animation");
681  if (m_f)
682  {
683  if (m_xml)
684  { // Terminate the anim element
685  WriteN (GetXMLClose ("anim"), m_f);
686  }
687  std::fclose (m_f);
688  }
689  m_outputFileSet = false;
690  if (m_routingF)
691  {
692  WriteN (GetXMLClose ("anim"), m_routingF);
693  std::fclose (m_routingF);
694  }
695 }
696 
697 int AnimationInterface::WriteN (const std::string& st, FILE * f)
698 {
699  if (m_writeCallback)
700  {
701  m_writeCallback (st.c_str ());
702  }
703  return WriteN (st.c_str (), st.length (), f);
704 }
705 
706 std::vector <Ptr <Node> > AnimationInterface::RecalcTopoBounds ()
707 {
708  std::vector < Ptr <Node> > MovedNodes;
709  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
710  {
711  Ptr<Node> n = *i;
712  NS_ASSERT (n);
713  Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
714  Vector newLocation;
715  if (!mobility)
716  {
717  newLocation = GetPosition (n);
718  }
719  else
720  {
721  newLocation = mobility->GetPosition ();
722  }
723  if (!NodeHasMoved (n, newLocation))
724  {
725  continue; //Location has not changed
726  }
727  else
728  {
729  UpdatePosition (n, newLocation);
730  RecalcTopoBounds (newLocation);
731  MovedNodes.push_back (n);
732  }
733  }
734  return MovedNodes;
735 }
736 
738 {
739  m_topoMinX = std::min (m_topoMinX, v.x);
740  m_topoMinY = std::min (m_topoMinY, v.y);
741  m_topoMaxX = std::max (m_topoMaxX, v.x);
742  m_topoMaxY = std::max (m_topoMaxY, v.y);
743 
744 }
745 
746 int AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
747 {
748  // Write count bytes to h from data
749  uint32_t nLeft = count;
750  const char* p = data;
751  uint32_t written = 0;
752  while (nLeft)
753  {
754  int n = std::fwrite (p, 1, nLeft, f);
755  if (n <= 0)
756  {
757  return written;
758  }
759  written += n;
760  nLeft -= n;
761  p += n;
762  }
763  return written;
764 }
765 
767 {
768  Time now = Simulator::Now ();
769  std::ostringstream oss;
770  double fbTx = now.GetSeconds ();
771  double lbTx = now.GetSeconds ();
772  double fbRx = now.GetSeconds ();
773  double lbRx = now.GetSeconds ();
774  oss << GetXMLOpenClose_p ("p", 0, fbTx, lbTx, 0, fbRx, lbRx, "", "DummyPktIgnoreThis");
775  WriteN (oss.str (), m_f);
776 
777 
778 }
779 
780 
781 void AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
782 {
783  std::ostringstream oss;
784  oss << GetXMLOpenClose_NonP2pLinkProperties (id, ipv4Address, channelType);
785  WriteN (oss.str (), m_f);
786 }
787 
790  Time txTime, Time rxTime)
791 {
792  if (!m_started || !IsInTimeWindow ())
793  return;
794  NS_ASSERT (tx);
795  NS_ASSERT (rx);
796  Time now = Simulator::Now ();
797  std::ostringstream oss;
798  double fbTx = now.GetSeconds ();
799  double lbTx = (now + txTime).GetSeconds ();
800  double fbRx = (now + rxTime - txTime).GetSeconds ();
801  double lbRx = (now + rxTime).GetSeconds ();
802  if (m_xml)
803  {
804  oss << GetXMLOpenClose_p ("p", tx->GetNode ()->GetId (), fbTx, lbTx, rx->GetNode ()->GetId (),
805  fbRx, lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
808  }
809  else
810  {
811  oss << std::setprecision (10);
812  oss << now.GetSeconds () << " P "
813  << tx->GetNode ()->GetId () << " "
814  << rx->GetNode ()->GetId () << " "
815  << (now + txTime).GetSeconds () << " " // last bit tx time
816  << (now + rxTime - txTime).GetSeconds () << " " // first bit rx time
817  << (now + rxTime).GetSeconds () << std::endl; // last bit rx time
818  }
819  WriteN (oss.str (), m_f);
820 }
821 
822 
825 {
826  // Use "NodeList/*/DeviceList/*/ as reference
827  // where element [1] is the Node Id
828  // element [2] is the NetDevice Id
829 
830  std::vector <std::string> elements = GetElementsFromContext (context);
831  Ptr <Node> n = NodeList::GetNode (atoi (elements[1].c_str ()));
832  NS_ASSERT (n);
833  return n->GetDevice (atoi (elements[3].c_str ()));
834 }
835 
837 {
838  m_pendingUanPackets[AnimUid] = pktinfo;
839 }
840 
841 
843 {
844  m_pendingWifiPackets[AnimUid] = pktinfo;
845 }
846 
848 {
849  NS_ASSERT (pktinfo.m_txnd);
850  m_pendingWimaxPackets[AnimUid] = pktinfo;
851 }
852 
854 {
855  NS_ASSERT (pktinfo.m_txnd);
856  m_pendingLtePackets[AnimUid] = pktinfo;
857 }
858 
860 {
861  NS_ASSERT (pktinfo.m_txnd);
862  m_pendingCsmaPackets[AnimUid] = pktinfo;
863 }
864 
866 {
867  AnimByteTag tag;
868  TypeId tid = tag.GetInstanceTypeId ();
870  bool found = false;
871  while (i.HasNext ())
872  {
873  ByteTagIterator::Item item = i.Next ();
874  if (tid == item.GetTypeId ())
875  {
876  item.GetTag (tag);
877  found = true;
878  }
879  }
880  if (found)
881  {
882  return tag.Get ();
883  }
884  else
885  {
886  return 0;
887  }
888 }
889 
891 {
892  if (!m_started || !IsInTimeWindow ())
893  return;
894  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
895  NS_ASSERT (ndev);
896  Ptr <Node> n = ndev->GetNode ();
897  NS_ASSERT (n);
898  gAnimUid++;
899  NS_LOG_INFO ("Uan TxBeginTrace for packet:" << gAnimUid);
900  AnimByteTag tag;
901  tag.Set (gAnimUid);
902  p->AddByteTag (tag);
903  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
904  AddPendingUanPacket (gAnimUid, pktinfo);
905 
906 
907 }
908 
910 {
911  if (!m_started || !IsInTimeWindow ())
912  return;
913  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
914  NS_ASSERT (ndev);
915  Ptr <Node> n = ndev->GetNode ();
916  NS_ASSERT (n);
917  uint64_t AnimUid = GetAnimUidFromPacket (p);
918  NS_LOG_INFO ("UanPhyGenRxTrace for packet:" << AnimUid);
919  if (!UanPacketIsPending (AnimUid))
920  {
921  NS_LOG_WARN ("UanPhyGenRxBeginTrace: unknown Uid");
922  return;
923  }
924  m_pendingUanPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
925  m_pendingUanPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
926  OutputWirelessPacket (p, m_pendingUanPackets[AnimUid], m_pendingUanPackets[AnimUid].GetRxInfo (ndev));
927 
928 }
929 
930 
931 void AnimationInterface::WifiPhyTxBeginTrace (std::string context,
933 {
934  if (!m_started || !IsInTimeWindow ())
935  return;
936  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
937  NS_ASSERT (ndev);
938  Ptr <Node> n = ndev->GetNode ();
939  NS_ASSERT (n);
940  // Add a new pending wireless
941  gAnimUid++;
942  NS_LOG_INFO ("Wifi TxBeginTrace for packet:" << gAnimUid);
943  AnimByteTag tag;
944  tag.Set (gAnimUid);
945  p->AddByteTag (tag);
946  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
947  AddPendingWifiPacket (gAnimUid, pktinfo);
948  Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
949  Mac48Address nodeAddr = netDevice->GetMac()->GetAddress();
950  std::ostringstream oss;
951  oss << nodeAddr;
952  m_macToNodeIdMap[oss.str ()] = n->GetId ();
953  NS_LOG_INFO ("Added Mac" << oss.str () << " node:" <<m_macToNodeIdMap[oss.str ()]);
954 }
955 
956 void AnimationInterface::WifiPhyTxEndTrace (std::string context,
958 {
959 }
960 
961 void AnimationInterface::WifiPhyTxDropTrace (std::string context,
963 {
964  if (!m_started || !IsInTimeWindow ())
965  return;
966  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
967  NS_ASSERT (ndev);
968  // Erase pending wifi
969  uint64_t AnimUid = GetAnimUidFromPacket (p);
970  NS_LOG_INFO ("TxDropTrace for packet:" << AnimUid);
971  NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
972  m_pendingWifiPackets.erase (m_pendingWifiPackets.find (AnimUid));
973 }
974 
975 
976 void AnimationInterface::WifiPhyRxBeginTrace (std::string context,
978 {
979  if (!m_started || !IsInTimeWindow ())
980  return;
981  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
982  NS_ASSERT (ndev);
983  Ptr <Node> n = ndev->GetNode ();
984  NS_ASSERT (n);
985  uint64_t AnimUid = GetAnimUidFromPacket (p);
986  NS_LOG_INFO ("Wifi RxBeginTrace for packet:" << AnimUid);
987  if (!WifiPacketIsPending (AnimUid))
988  {
989  NS_LOG_WARN ("WifiPhyRxBeginTrace: unknown Uid");
990  std::ostringstream oss;
991  WifiMacHeader hdr;
992  if(!p->PeekHeader (hdr))
993  {
994  NS_LOG_WARN ("WifiMacHeader not present");
995  return;
996  }
997  oss << hdr.GetAddr2 ();
998  if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
999  {
1000  //NS_LOG_UNCOND (oss.str ());
1001  return;
1002  }
1003  Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
1004  AnimPacketInfo pktinfo (0, Simulator::Now (), Simulator::Now (), UpdatePosition (txNode), m_macToNodeIdMap[oss.str ()]);
1005  AddPendingWifiPacket (AnimUid, pktinfo);
1006  NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
1007  }
1008  // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1009  m_pendingWifiPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
1010  m_pendingWifiPackets[AnimUid].ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1011  OutputWirelessPacket (p, m_pendingWifiPackets[AnimUid], m_pendingWifiPackets[AnimUid].GetRxInfo (ndev));
1012 }
1013 
1014 
1015 void AnimationInterface::WifiPhyRxEndTrace (std::string context,
1017 {
1018  if (!m_started || !IsInTimeWindow ())
1019  return;
1020  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1021  NS_ASSERT (ndev);
1022  Ptr <Node> n = ndev->GetNode ();
1023  NS_ASSERT (n);
1024  uint64_t AnimUid = GetAnimUidFromPacket (p);
1025  if (!WifiPacketIsPending (AnimUid))
1026  {
1027  NS_LOG_WARN ("WifiPhyRxEndTrace: unknown Uid");
1028  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1029  AddPendingWifiPacket (AnimUid, pktinfo);
1030  }
1031  // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1032  AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
1033  pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1034  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1035  if (pktrxInfo.IsPhyRxComplete ())
1036  {
1037  NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
1038  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1039  }
1040 }
1041 
1042 void AnimationInterface::WifiMacRxTrace (std::string context,
1044 {
1045  if (!m_started || !IsInTimeWindow ())
1046  return;
1047  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1048  NS_ASSERT (ndev);
1049  Ptr <Node> n = ndev->GetNode ();
1050  NS_ASSERT (n);
1051  uint64_t AnimUid = GetAnimUidFromPacket (p);
1052  if (!WifiPacketIsPending (AnimUid))
1053  {
1054  NS_LOG_WARN ("WifiMacRxTrace: unknown Uid");
1055  return;
1056  }
1057  // TODO: NS_ASSERT (WifiPacketIsPending (AnimUid) == true);
1058  AnimPacketInfo& pktInfo = m_pendingWifiPackets[AnimUid];
1059  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1060  if (pktrxInfo.IsPhyRxComplete ())
1061  {
1062  NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
1063  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1064  }
1065 
1066 }
1067 void AnimationInterface::WifiPhyRxDropTrace (std::string context,
1069 {
1070 }
1071 
1072 void AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1073 {
1074  if (!m_started || !IsInTimeWindow ())
1075  return;
1076  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1077  NS_ASSERT (ndev);
1078  Ptr <Node> n = ndev->GetNode ();
1079  NS_ASSERT (n);
1080  gAnimUid++;
1081  NS_LOG_INFO ("WimaxTxTrace for packet:" << gAnimUid);
1082  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1083  //TODO 0.0001 is used until Wimax implements TxBegin and TxEnd traces
1084  AnimByteTag tag;
1085  tag.Set (gAnimUid);
1086  p->AddByteTag (tag);
1087  AddPendingWimaxPacket (gAnimUid, pktinfo);
1088 }
1089 
1090 
1091 void AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1092 {
1093  if (!m_started || !IsInTimeWindow ())
1094  return;
1095  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1096  NS_ASSERT (ndev);
1097  Ptr <Node> n = ndev->GetNode ();
1098  NS_ASSERT (n);
1099  uint64_t AnimUid = GetAnimUidFromPacket (p);
1100  NS_LOG_INFO ("WimaxRxTrace for packet:" << AnimUid);
1101  NS_ASSERT (WimaxPacketIsPending (AnimUid) == true);
1102  AnimPacketInfo& pktInfo = m_pendingWimaxPackets[AnimUid];
1103  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
1104  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1105  //TODO 0.001 is used until Wimax implements RxBegin and RxEnd traces
1106  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1107  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1108 }
1109 
1110 void AnimationInterface::LteTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1111 {
1112  if (!m_started || !IsInTimeWindow ())
1113  return;
1114  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1115  NS_ASSERT (ndev);
1116  Ptr <Node> n = ndev->GetNode ();
1117  NS_ASSERT (n);
1118  gAnimUid++;
1119  NS_LOG_INFO ("LteTxTrace for packet:" << gAnimUid);
1120  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1121  //TODO 0.0001 is used until Lte implements TxBegin and TxEnd traces
1122  AnimByteTag tag;
1123  tag.Set (gAnimUid);
1124  p->AddByteTag (tag);
1125  AddPendingLtePacket (gAnimUid, pktinfo);
1126 }
1127 
1128 
1129 void AnimationInterface::LteRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1130 {
1131  if (!m_started || !IsInTimeWindow ())
1132  return;
1133  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1134  NS_ASSERT (ndev);
1135  Ptr <Node> n = ndev->GetNode ();
1136  NS_ASSERT (n);
1137  uint64_t AnimUid = GetAnimUidFromPacket (p);
1138  NS_LOG_INFO ("LteRxTrace for packet:" << gAnimUid);
1139  if (!LtePacketIsPending (AnimUid))
1140  {
1141  NS_LOG_WARN ("LteRxTrace: unknown Uid");
1142  return;
1143  }
1144  AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
1145  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
1146  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1147  //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
1148  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1149  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1150 }
1151 
1153 {
1154  if (!m_started || !IsInTimeWindow ())
1155  return;
1156  if (!pb)
1157  {
1158  NS_LOG_WARN ("pb == 0. Not yet supported");
1159  return;
1160  }
1161  context = "/" + context;
1162  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1163  NS_ASSERT (ndev);
1164  Ptr <Node> n = ndev->GetNode ();
1165  NS_ASSERT (n);
1166 
1167  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1168  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
1169  i != pbList.end ();
1170  ++i)
1171  {
1172  Ptr <Packet> p = *i;
1173  gAnimUid++;
1174  NS_LOG_INFO ("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
1175  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1176  //TODO 0.0001 is used until Lte implements TxBegin and TxEnd traces
1177  AnimByteTag tag;
1178  tag.Set (gAnimUid);
1179  p->AddByteTag (tag);
1180  AddPendingLtePacket (gAnimUid, pktinfo);
1181  }
1182 }
1183 
1185 {
1186  if (!m_started || !IsInTimeWindow ())
1187  return;
1188  if (!pb)
1189  {
1190  NS_LOG_WARN ("pb == 0. Not yet supported");
1191  return;
1192  }
1193  context = "/" + context;
1194  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1195  NS_ASSERT (ndev);
1196  Ptr <Node> n = ndev->GetNode ();
1197  NS_ASSERT (n);
1198 
1199  std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1200  for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
1201  i != pbList.end ();
1202  ++i)
1203  {
1204  Ptr <Packet> p = *i;
1205  uint64_t AnimUid = GetAnimUidFromPacket (p);
1206  NS_LOG_INFO ("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
1207  if (!LtePacketIsPending (AnimUid))
1208  {
1209  NS_LOG_WARN ("LteSpectrumPhyRxTrace: unknown Uid");
1210  return;
1211  }
1212  AnimPacketInfo& pktInfo = m_pendingLtePackets[AnimUid];
1213  pktInfo.ProcessRxBegin (ndev, Simulator::Now ());
1214  pktInfo.ProcessRxEnd (ndev, Simulator::Now () + Seconds (0.001), UpdatePosition (n));
1215  //TODO 0.001 is used until Lte implements RxBegin and RxEnd traces
1216  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1217  OutputWirelessPacket (p, pktInfo, pktrxInfo);
1218  }
1219 }
1220 
1222 {
1223  if (!m_started || !IsInTimeWindow ())
1224  return;
1225  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1226  NS_ASSERT (ndev);
1227  Ptr <Node> n = ndev->GetNode ();
1228  NS_ASSERT (n);
1229  gAnimUid++;
1230  NS_LOG_INFO ("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
1231  AnimByteTag tag;
1232  tag.Set (gAnimUid);
1233  p->AddByteTag (tag);
1234  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1235  AddPendingCsmaPacket (gAnimUid, pktinfo);
1236 
1237 }
1238 
1240 {
1241  if (!m_started || !IsInTimeWindow ())
1242  return;
1243  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1244  NS_ASSERT (ndev);
1245  Ptr <Node> n = ndev->GetNode ();
1246  NS_ASSERT (n);
1247  uint64_t AnimUid = GetAnimUidFromPacket (p);
1248  NS_LOG_INFO ("CsmaPhyTxEndTrace for packet:" << AnimUid);
1249  if (!CsmaPacketIsPending (AnimUid))
1250  {
1251  NS_LOG_WARN ("CsmaPhyTxEndTrace: unknown Uid");
1252  AnimPacketInfo pktinfo (ndev, Simulator::Now (), Simulator::Now (), UpdatePosition (n));
1253  AddPendingCsmaPacket (AnimUid, pktinfo);
1254  NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
1255  }
1256  // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1257  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
1258  pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
1259 }
1260 
1262 {
1263  if (!m_started || !IsInTimeWindow ())
1264  return;
1265  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1266  NS_ASSERT (ndev);
1267  Ptr <Node> n = ndev->GetNode ();
1268  NS_ASSERT (n);
1269  uint64_t AnimUid = GetAnimUidFromPacket (p);
1270  if (!CsmaPacketIsPending (AnimUid))
1271  {
1272  NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid");
1273  return;
1274  }
1275  // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1276  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
1277  m_pendingCsmaPackets[AnimUid].ProcessRxBegin (ndev, Simulator::Now ());
1278  pktInfo.ProcessRxEnd (ndev, Simulator::Now (), UpdatePosition (n));
1279  NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << AnimUid);
1280 }
1281 
1282 
1283 void AnimationInterface::CsmaMacRxTrace (std::string context,
1285 {
1286  if (!m_started || !IsInTimeWindow ())
1287  return;
1288  NS_LOG_FUNCTION (this);
1289  Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1290  NS_ASSERT (ndev);
1291  Ptr <Node> n = ndev->GetNode ();
1292  NS_ASSERT (n);
1293  uint64_t AnimUid = GetAnimUidFromPacket (p);
1294  if (!CsmaPacketIsPending (AnimUid))
1295  {
1296  NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid");
1297  return;
1298  }
1299  // TODO: NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1300  AnimPacketInfo& pktInfo = m_pendingCsmaPackets[AnimUid];
1301  AnimRxInfo pktrxInfo = pktInfo.GetRxInfo (ndev);
1302  if (pktrxInfo.IsPhyRxComplete ())
1303  {
1304  NS_LOG_INFO ("MacRxTrace for packet:" << AnimUid << " complete");
1305  OutputCsmaPacket (p, pktInfo, pktrxInfo);
1306  }
1307 }
1308 
1309 
1311 
1312 {
1313  if (!m_started || !IsInTimeWindow ())
1314  return;
1315  Ptr <Node> n = mobility->GetObject <Node> ();
1316  NS_ASSERT (n);
1317  Vector v ;
1318  if (!mobility)
1319  {
1320  v = GetPosition (n);
1321  }
1322  else
1323  {
1324  v = mobility->GetPosition ();
1325  }
1326  UpdatePosition (n,v);
1327  RecalcTopoBounds (v);
1328  std::ostringstream oss;
1330  oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y, nodeColors[n->GetId ()]);
1331  oss << GetXMLClose ("topology");
1332  WriteN (oss.str (), m_f);
1333  WriteDummyPacket ();
1334 }
1335 
1337 {
1338  Vector oldLocation = GetPosition (n);
1339  if ((ceil (oldLocation.x) == ceil (newLocation.x)) &&
1340  (ceil (oldLocation.y) == ceil (newLocation.y)))
1341  {
1342 
1343  return false;
1344  }
1345  else
1346  {
1347  return true;
1348  }
1349 }
1350 
1352 {
1353  if (!m_started || !IsInTimeWindow ())
1354  return;
1355  std::vector <Ptr <Node> > MovedNodes = RecalcTopoBounds ();
1356  std::ostringstream oss;
1358  for (uint32_t i = 0; i < MovedNodes.size (); i++)
1359  {
1360  Ptr <Node> n = MovedNodes [i];
1361  NS_ASSERT (n);
1362  Vector v = GetPosition (n);
1363  oss << GetXMLOpenClose_node (0, n->GetId (), v.x, v.y);
1364  }
1365  oss << GetXMLClose ("topology");
1366  WriteN (oss.str (), m_f);
1367  WriteDummyPacket ();
1368  if (!Simulator::IsFinished ())
1369  {
1370  PurgePendingWifi ();
1371  PurgePendingWimax ();
1372  PurgePendingLte ();
1373  PurgePendingCsma ();
1375  }
1376 }
1377 
1379 {
1380  std::ostringstream oss;
1381  p->Print (oss);
1382  return oss.str ();
1383 }
1384 
1386 {
1387  return m_currentPktCount;
1388 }
1389 
1390 int64_t
1392 {
1393  NS_LOG_FUNCTION (this << stream);
1395  return 1;
1396 }
1397 
1398 // Helper to output a wireless packet.
1399 // For now, only the XML interface is supported
1400 
1401 
1403 {
1404  std::string s =
1405  "<information><!-- \n\
1406  Description of attributes:\n\
1407  =========================\n\
1408  anim\n\
1409  * ver = Current version\n\
1410  topology\n\
1411  * minX = minimum X coordinate of the canvas\n\
1412  * minY = minimum Y coordinate of the canvas\n\
1413  * maxX = maximum X coordinate of the canvas\n\
1414  * maxY = maximum Y coordinate of the canvas\n\
1415  node\n\
1416  * id = Node Id\n\
1417  * locX = X coordinate\n\
1418  * locY = Y coordinate\n\
1419  * r = Red component\n\
1420  * g = Green component\n\
1421  * b = Blue component\n\
1422  link\n\
1423  * fromId = From Node Id\n\
1424  * toId = To Node Id\n\
1425  * fd = From Node description (for IP Address)\n\
1426  * td = To Node description (for IP Address)\n\
1427  * ld = Link description (for Bandwidth, delay etc)\n\
1428  linkupdate\n\
1429  * t = Simulation time\n\
1430  * ld = Link description (for Bandwidth, delay etc)\n\
1431  nodeupdate\n\
1432  * t = Simulation time\n\
1433  * descr = Node description\n\
1434  * r = Red component\n\
1435  * g = Green component\n\
1436  * b = Blue component\n\
1437  * visible = Node visibility\n\
1438  p\n\
1439  * fId = From Node Id\n\
1440  * fbTx = First bit transmit time\n\
1441  * lbTx = Last bit transmit time\n\
1442  * tId = To Node Id\n\
1443  * fbRx = First bit Rx Time\n\
1444  * lbRx = Last bit Rx\n\
1445  * meta-info = Packet meta data\n\
1446  wp\n\
1447  * fId = From Node Id\n\
1448  * fbTx = First bit transmit time\n\
1449  * lbTx = Last bit transmit time\n\
1450  * range = Reception range\n\
1451  * tId = To Node Id\n\
1452  * fbRx = First bit Rx time\n\
1453  * meta-info = Packet meta data\n\
1454  * lbRx = Last bit Rx time-->\n\
1455  </information>\n";
1456 return s;
1457 }
1458 
1460 {
1461  StartNewTraceFile ();
1462  NS_ASSERT (m_xml);
1463  std::ostringstream oss;
1464  uint32_t nodeId = 0;
1465  if (pktInfo.m_txnd)
1466  nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1467  else
1468  nodeId = pktInfo.m_txNodeId;
1469 
1470  double lbTx = pktInfo.firstlastbitDelta + pktInfo.m_fbTx;
1471  uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId ();
1472 
1473  oss << GetXMLOpenClose_p ("wp", nodeId, pktInfo.m_fbTx, lbTx, rxId,
1474  pktrxInfo.m_fbRx, pktrxInfo.m_lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
1475  WriteN (oss.str (), m_f);
1476 }
1477 
1479 {
1480  StartNewTraceFile ();
1481  NS_ASSERT (m_xml);
1482  std::ostringstream oss;
1483  NS_ASSERT (pktInfo.m_txnd);
1484  uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1485  uint32_t rxId = pktrxInfo.m_rxnd->GetNode ()->GetId ();
1486 
1487  oss << GetXMLOpenClose_p ("p", nodeId, pktInfo.m_fbTx, pktInfo.m_lbTx, rxId,
1488  pktrxInfo.m_fbRx, pktrxInfo.m_lbRx, m_enablePacketMetadata? GetPacketMetadata (p):"");
1489  WriteN (oss.str (), m_f);
1490 }
1491 
1492 void AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
1493 {
1494  NS_ASSERT (n);
1496  if (hubLoc == 0)
1497  {
1498  hubLoc = CreateObject<ConstantPositionMobilityModel> ();
1499  n->AggregateObject (hubLoc);
1500  }
1501  Vector hubVec (x, y, z);
1502  hubLoc->SetPosition (hubVec);
1503  NS_LOG_INFO ("Node:" << n->GetId () << " Position set to:(" << x << "," << y << "," << z << ")");
1504 
1505 }
1506 
1507 void AnimationInterface::SetNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
1508 {
1509  if (initialized)
1510  NS_FATAL_ERROR ("SetNodeColor must be used prior to creating the AnimationInterface object");
1511  NS_ASSERT (n);
1512  NS_LOG_INFO ("Setting node color for Node Id:" << n->GetId ());
1513  struct Rgb rgb = {r, g, b};
1514  nodeColors[n->GetId ()] = rgb;
1515 }
1516 
1517 void AnimationInterface::ShowNode (uint32_t nodeId, bool show)
1518 {
1519  NS_ASSERT (NodeList::GetNode (nodeId));
1520  NS_LOG_INFO ("Setting node visibility for Node Id:" << nodeId);
1521  std::ostringstream oss;
1522  oss << GetXMLOpenClose_nodeupdate (nodeId, show);
1523  WriteN (oss.str (), m_f);
1524 
1525 }
1526 
1528 {
1529  ShowNode (n, show);
1530 }
1531 
1532 void AnimationInterface::UpdateNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
1533 {
1534  UpdateNodeColor (n->GetId (), r, g, b);
1535 }
1536 
1537 void AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
1538 {
1539  NS_ASSERT (NodeList::GetNode (nodeId));
1540  NS_LOG_INFO ("Setting node color for Node Id:" << nodeId);
1541  struct Rgb rgb = {r, g, b};
1542  nodeColors[nodeId] = rgb;
1543  std::ostringstream oss;
1544  oss << GetXMLOpenClose_nodeupdate (nodeId);
1545  WriteN (oss.str (), m_f);
1546 }
1547 
1548 
1549 
1550 void AnimationInterface::SetNodeColor (NodeContainer nc, uint8_t r, uint8_t g, uint8_t b)
1551 {
1552  for (uint32_t i = 0; i < nc.GetN (); ++i)
1553  {
1554  Ptr <Node> n = nc.Get (i);
1555  NS_ASSERT (n);
1556  SetNodeColor (n, r, g, b);
1557  }
1558 }
1559 
1560 
1561 void AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNode,
1562  std::string linkDescription)
1563 {
1564  std::ostringstream oss;
1565  oss << GetXMLOpenClose_linkupdate (fromNode, toNode, linkDescription);
1566  WriteN (oss.str (), m_f);
1567 }
1568 
1570  std::string linkDescription)
1571 {
1572  NS_ASSERT (fromNode);
1573  NS_ASSERT (toNode);
1574  std::ostringstream oss;
1575  oss << GetXMLOpenClose_linkupdate (fromNode->GetId (), toNode->GetId (), linkDescription);
1576  WriteN (oss.str (), m_f);
1577 }
1578 
1579 void AnimationInterface::SetLinkDescription (uint32_t fromNode, uint32_t toNode,
1580  std::string linkDescription,
1581  std::string fromNodeDescription,
1582  std::string toNodeDescription)
1583 {
1584 
1585  P2pLinkNodeIdPair p2pPair;
1586  p2pPair.fromNode = fromNode;
1587  p2pPair.toNode = toNode;
1588  LinkProperties lp = { fromNodeDescription, toNodeDescription, linkDescription };
1589  linkProperties[p2pPair] = lp;
1590  /* DEBUG */
1591  /*
1592  for (std::map <P2pLinkNodeIdPair, LinkProperties>::const_iterator i = linkProperties.begin ();
1593  i != linkProperties.end(); ++i)
1594  {
1595  P2pLinkNodeIdPair ppair = i->first;
1596  LinkProperties l = i->second;
1597  NS_LOG_UNCOND ("A:" << ppair.fromNode << " B:" << ppair.toNode << " ad:" << l.fromNodeDescription << " bd:" << l.toNodeDescription << " ld:" << l.linkDescription);
1598 
1599  }
1600  */
1601 }
1602 
1604  std::string linkDescription,
1605  std::string fromNodeDescription,
1606  std::string toNodeDescription)
1607 {
1608  NS_ASSERT (fromNode);
1609  NS_ASSERT (toNode);
1610  SetLinkDescription (fromNode->GetId (), toNode->GetId (), linkDescription, fromNodeDescription, toNodeDescription);
1611 }
1612 
1613 
1615 {
1616  if (initialized)
1617  NS_FATAL_ERROR ("SetNodeDescription must be used prior to creating the AnimationInterface object");
1618  NS_ASSERT (n);
1619  nodeDescriptions[n->GetId ()] = descr;
1620 }
1621 
1623 {
1624  UpdateNodeDescription (n->GetId (), descr);
1625 }
1626 
1627 void AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string descr)
1628 {
1629  NS_ASSERT (NodeList::GetNode (nodeId));
1630  nodeDescriptions[nodeId] = descr;
1631  std::ostringstream oss;
1632  oss << GetXMLOpenClose_nodeupdate (nodeId);
1633  WriteN (oss.str (), m_f);
1634 }
1635 
1636 
1637 
1639 {
1640  if (initialized)
1641  NS_FATAL_ERROR ("SetNodeDescription must be used prior to creating the AnimationInterface object");
1642  for (uint32_t i = 0; i < nc.GetN (); ++i)
1643  {
1644  Ptr <Node> n = nc.Get (i);
1645  NS_ASSERT (n);
1646  nodeDescriptions[n->GetId ()] = descr;
1647  }
1648 }
1649 
1650 
1651 // XML Private Helpers
1652 
1653 std::string AnimationInterface::GetXMLOpen_anim (uint32_t lp)
1654 {
1655  std::ostringstream oss;
1656  oss <<"<anim ver=\"" << GetNetAnimVersion () << "\">\n";
1657  return oss.str ();
1658 }
1659 std::string AnimationInterface::GetXMLOpen_topology (double minX, double minY, double maxX, double maxY)
1660 {
1661  std::ostringstream oss;
1662  oss << "<topology minX = \"" << minX << "\" minY = \"" << minY
1663  << "\" maxX = \"" << maxX << "\" maxY = \"" << maxY
1664  << "\">" << std::endl;
1665  return oss.str ();
1666 
1667 }
1668 
1669 std::string AnimationInterface::GetXMLOpenClose_nodeupdate (uint32_t id, bool visible)
1670 {
1671  struct Rgb rgb = nodeColors[id];
1672  uint8_t r = rgb.r;
1673  uint8_t g = rgb.g;
1674  uint8_t b = rgb.b;
1675  std::ostringstream oss;
1676  oss << "<nodeupdate id=\"" << id << "\"";
1677  oss << " t=\"" << Simulator::Now ().GetSeconds () << "\"";
1678  if (visible)
1679  oss << " visible=\"" << 1 << "\"";
1680  else
1681  oss << " visible=\"" << 0 << "\"";
1682  if (nodeDescriptions.find (id) != nodeDescriptions.end ())
1683  {
1684  oss << " descr=\""<< nodeDescriptions[id] << "\"";
1685  }
1686  else
1687  {
1688  oss << " descr=\"\"";
1689  }
1690  oss << " r=\"" << (uint32_t)r << "\" "
1691  << " g=\"" << (uint32_t)g << "\" b=\"" << (uint32_t)b <<"\"/>\n";
1692  return oss.str ();
1693 
1694 }
1695 
1696 std::string AnimationInterface::GetXMLOpenClose_node (uint32_t lp, uint32_t id, double locX, double locY)
1697 {
1698  std::ostringstream oss;
1699  oss <<"<node id=\"" << id << "\"";
1700  if (nodeDescriptions.find (id) != nodeDescriptions.end ())
1701  {
1702  oss << " descr=\""<< nodeDescriptions[id] << "\"";
1703  }
1704  else
1705  {
1706  oss << " descr=\"\"";
1707  }
1708  oss << " locX = \"" << locX << "\" " << "locY = \"" << locY << "\" />\n";
1709  return oss.str ();
1710 }
1711 
1712 std::string AnimationInterface::GetXMLOpenClose_node (uint32_t lp, uint32_t id, double locX, double locY, struct Rgb rgb)
1713 {
1714  uint8_t r = rgb.r;
1715  uint8_t g = rgb.g;
1716  uint8_t b = rgb.b;
1717  std::ostringstream oss;
1718  oss <<"<node id = \"" << id << "\"";
1719  if (nodeDescriptions.find (id) != nodeDescriptions.end ())
1720  {
1721  oss << " descr=\""<< nodeDescriptions[id] << "\"";
1722  }
1723  else
1724  {
1725  oss << " descr=\"\"";
1726  }
1727  oss << " locX=\"" << locX << "\" " << "locY=\"" << locY << "\"" << " r=\"" << (uint32_t)r << "\" "
1728  << " g=\"" << (uint32_t)g << "\" b=\"" << (uint32_t)b <<"\"/>\n";
1729  return oss.str ();
1730 }
1731 
1732 std::string AnimationInterface::GetXMLOpenClose_linkupdate (uint32_t fromId, uint32_t toId, std::string linkDescription)
1733 {
1734  std::ostringstream oss;
1735  oss << "<linkupdate t=\"" << Simulator::Now ().GetSeconds () << "\""
1736  << " fromId=\"" << fromId
1737  << "\" toId=\"" << toId
1738  << "\" ";
1739 
1740  oss << " ld=\"" << linkDescription << "\""
1741  << " />\n";
1742  return oss.str ();
1743 
1744 }
1745 
1746 std::string AnimationInterface::GetXMLOpenClose_link (uint32_t fromLp, uint32_t fromId, uint32_t toLp, uint32_t toId)
1747 {
1748  std::ostringstream oss;
1749  oss << "<link fromId=\"" << fromId
1750  << "\" toId=\"" << toId
1751  << "\" ";
1752 
1753  LinkProperties lprop ;
1754  lprop.fromNodeDescription = "";
1755  lprop.toNodeDescription = "";
1756  lprop.linkDescription = "";
1757 
1758  P2pLinkNodeIdPair p1 = { fromId, toId };
1759  P2pLinkNodeIdPair p2 = { toId, fromId };
1760  if (linkProperties.find (p1) != linkProperties.end())
1761  {
1762  lprop = linkProperties[p1];
1763  }
1764  else if (linkProperties.find (p2) != linkProperties.end())
1765  {
1766  lprop = linkProperties[p2];
1767  }
1768 
1769  oss << " fd=\"" << lprop.fromNodeDescription << "\""
1770  << " td=\"" << lprop.toNodeDescription << "\""
1771  << " ld=\"" << lprop.linkDescription << "\""
1772  << " />\n";
1773  return oss.str ();
1774 }
1775 
1776 
1777 std::string AnimationInterface::GetXMLOpen_packet (uint32_t fromLp, uint32_t fromId, double fbTx, double lbTx, std::string auxInfo)
1778 {
1779  std::ostringstream oss;
1780  oss << std::setprecision (10);
1781  oss << "<p fId=\"" << fromId
1782  << "\" fbTx=\"" << fbTx
1783  << "\" lbTx=\"" << lbTx
1784  << (auxInfo.empty()?"":"\" aux=\"") << auxInfo.c_str () << "\">";
1785  return oss.str ();
1786 }
1787 
1788 std::string AnimationInterface::GetXMLOpenClose_routing (uint32_t nodeId, std::string routingInfo)
1789 {
1790  std::ostringstream oss;
1791  oss << "<" << "rt" << " t=\"" << Simulator::Now ().GetSeconds () << "\""
1792  << " id=\"" << nodeId << "\""
1793  << " info=\"" << routingInfo.c_str () << "\""
1794  << "/>" << std::endl;
1795  return oss.str ();
1796 }
1797 
1798 std::string AnimationInterface::GetXMLOpenClose_p (std::string pktType, uint32_t fId, double fbTx, double lbTx,
1799  uint32_t tId, double fbRx, double lbRx, std::string metaInfo,
1800  std::string auxInfo)
1801 {
1802  std::ostringstream oss;
1803  oss << std::setprecision (10);
1804  oss << "<" << pktType << " fId=\"" << fId
1805  << "\" fbTx=\"" << fbTx
1806  << "\" lbTx=\"" << lbTx << "\"";
1807  if (!auxInfo.empty ())
1808  {
1809  oss << " aux=\"" << auxInfo.c_str () << "\"";
1810  }
1811  if (!metaInfo.empty ())
1812  {
1813  oss << " meta-info=\"" << metaInfo.c_str () << "\"";
1814  }
1815  oss << " tId=\"" << tId << "\" fbRx=\"" << fbRx << "\" lbRx=\"" << lbRx << "\">" << std::endl;
1816  return oss.str ();
1817 }
1818 
1819 
1820 
1821 std::string AnimationInterface::GetXMLOpen_wpacket (uint32_t fromLp, uint32_t fromId, double fbTx, double lbTx, double range)
1822 {
1823  std::ostringstream oss;
1824  oss << std::setprecision (10);
1825  oss << "<wpacket fromId=\"" << fromId
1826  << "\" fbTx=\"" << fbTx
1827  << "\" lbTx=\"" << lbTx
1828  << "\" range=\"" << range << "\">" << std::endl;
1829  return oss.str ();
1830 
1831 }
1832 
1833 std::string AnimationInterface::GetXMLOpenClose_rx (uint32_t toLp, uint32_t toId, double fbRx, double lbRx)
1834 {
1835  std::ostringstream oss;
1836  oss << std::setprecision (10);
1837  oss << "<rx toId=\"" << toId
1838  << "\" fbRx=\"" << fbRx
1839  << "\" lbRx=\"" << lbRx
1840  << "\"/>" << std::endl;
1841  return oss.str ();
1842 }
1843 
1844 std::string AnimationInterface::GetXMLOpenClose_meta (std::string metaInfo)
1845 {
1846  std::ostringstream oss;
1847  oss << "<meta info=\""
1848  << metaInfo << "\" />" << std::endl;
1849  return oss.str ();
1850 }
1851 
1852 
1853 std::string AnimationInterface::GetXMLOpenClose_NonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
1854 {
1855  std::ostringstream oss;
1856  oss << "<nonp2plinkproperties id=\""
1857  << id << "\""
1858  << " ipv4Address=\"" << ipv4Address << "\""
1859  << " channelType=\"" << channelType << "\""
1860  << "/>" << std::endl;
1861  return oss.str ();
1862 }
1863 
1864 
1865 std::vector<std::string> AnimationInterface::GetElementsFromContext (std::string context)
1866 {
1867  std::vector <std::string> elements;
1868  size_t pos1=0, pos2;
1869  while (pos1 != context.npos)
1870  {
1871  pos1 = context.find ("/",pos1);
1872  pos2 = context.find ("/",pos1+1);
1873  elements.push_back (context.substr (pos1+1,pos2-(pos1+1)));
1874  pos1 = pos2;
1875  pos2 = context.npos;
1876  }
1877  return elements;
1878 }
1879 
1880 TypeId
1882 {
1883  static TypeId tid = TypeId ("ns3::AnimByteTag")
1884  .SetParent<Tag> ()
1885  .AddConstructor<AnimByteTag> ()
1886  ;
1887  return tid;
1888 }
1889 TypeId
1891 {
1892  return GetTypeId ();
1893 }
1894 
1895 uint32_t
1897 {
1898  return sizeof (uint64_t);
1899 }
1900 void
1902 {
1903  i.WriteU64 (m_AnimUid);
1904 }
1905 void
1907 {
1908  m_AnimUid = i.ReadU64 ();
1909 }
1910 void
1911 AnimByteTag::Print (std::ostream &os) const
1912 {
1913  os << "AnimUid=" << m_AnimUid;
1914 }
1915 void
1916 AnimByteTag::Set (uint64_t AnimUid)
1917 {
1918  m_AnimUid = AnimUid;
1919 }
1920 
1921 uint64_t
1922 AnimByteTag::Get (void) const
1923 {
1924  return m_AnimUid;
1925 }
1926 
1927 
1928 } // namespace ns3