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 * Contributions: Eugene Kalishenko <ydginster@gmail.com> (Open Source and Linux Laboratory http://dev.osll.ru/)
19 * Tommaso Pecorella <tommaso.pecorella@unifi.it>
20 * Pavel Vasilyev <pavel.vasilyev@sredasolutions.com>
21 */
22
23 // Interface between ns-3 and the network animator
24
25
26
27 #include <cstdio>
28 #ifndef WIN32
29 #include <unistd.h>
30 #endif
31 #include <sstream>
32 #include <fstream>
33 #include <string>
34 #include <iomanip>
35 #include <map>
36
37 // ns3 includes
38 #include "ns3/animation-interface.h"
39 #include "ns3/channel.h"
40 #include "ns3/config.h"
41 #include "ns3/node.h"
42 #include "ns3/mobility-model.h"
43 #include "ns3/packet.h"
44 #include "ns3/simulator.h"
45 #include "ns3/wifi-mac-header.h"
46 #include "ns3/wimax-mac-header.h"
47 #include "ns3/wifi-net-device.h"
48 #include "ns3/wifi-mac.h"
49 #include "ns3/wifi-psdu.h"
50 #include "ns3/lr-wpan-mac-header.h"
51 #include "ns3/lr-wpan-net-device.h"
52 #include "ns3/constant-position-mobility-model.h"
53 #include "ns3/lte-ue-phy.h"
54 #include "ns3/lte-enb-phy.h"
55 #include "ns3/uan-net-device.h"
56 #include "ns3/uan-mac.h"
57 #include "ns3/double.h"
58 #include "ns3/ipv4.h"
59 #include "ns3/ipv6.h"
60 #include "ns3/ipv4-routing-protocol.h"
61 #include "ns3/energy-source-container.h"
62 #include "animation-interface.h"
63
64 namespace ns3 {
65
66 NS_LOG_COMPONENT_DEFINE ("AnimationInterface");
67
68 // Globals
69
70 static bool initialized = false; //!< Initialization flag
71
72
73 // Public methods
74
AnimationInterface(const std::string fn)75 AnimationInterface::AnimationInterface (const std::string fn)
76 : m_f (0),
77 m_routingF (0),
78 m_mobilityPollInterval (Seconds (0.25)),
79 m_outputFileName (fn),
80 gAnimUid (0),
81 m_writeCallback (0),
82 m_started (false),
83 m_enablePacketMetadata (false),
84 m_startTime (Seconds (0)),
85 m_stopTime (Seconds (3600 * 1000)),
86 m_maxPktsPerFile (MAX_PKTS_PER_TRACE_FILE),
87 m_originalFileName (fn),
88 m_routingStopTime (Seconds (0)),
89 m_routingFileName (""),
90 m_routingPollInterval (Seconds (5)),
91 m_trackPackets (true)
92 {
93 initialized = true;
94 StartAnimation ();
95 }
96
~AnimationInterface()97 AnimationInterface::~AnimationInterface ()
98 {
99 StopAnimation ();
100 }
101
102 void
SkipPacketTracing()103 AnimationInterface::SkipPacketTracing ()
104 {
105 m_trackPackets = false;
106 }
107
108 void
EnableWifiPhyCounters(Time startTime,Time stopTime,Time pollInterval)109 AnimationInterface::EnableWifiPhyCounters (Time startTime, Time stopTime, Time pollInterval)
110 {
111 m_wifiPhyCountersStopTime = stopTime;
112 m_wifiPhyCountersPollInterval = pollInterval;
113 m_wifiPhyTxDropCounterId = AddNodeCounter ("WifiPhy TxDrop", AnimationInterface::DOUBLE_COUNTER);
114 m_wifiPhyRxDropCounterId = AddNodeCounter ("WifiPhy RxDrop", AnimationInterface::DOUBLE_COUNTER);
115 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
116 {
117 Ptr<Node> n = *i;
118 m_nodeWifiPhyTxDrop[n->GetId ()] = 0;
119 m_nodeWifiPhyRxDrop[n->GetId ()] = 0;
120 UpdateNodeCounter (m_wifiPhyTxDropCounterId, n->GetId (), 0);
121 UpdateNodeCounter (m_wifiPhyRxDropCounterId, n->GetId (), 0);
122 }
123 Simulator::Schedule (startTime, &AnimationInterface::TrackWifiPhyCounters, this);
124
125 }
126
127 void
EnableWifiMacCounters(Time startTime,Time stopTime,Time pollInterval)128 AnimationInterface::EnableWifiMacCounters (Time startTime, Time stopTime, Time pollInterval)
129 {
130 m_wifiMacCountersStopTime = stopTime;
131 m_wifiMacCountersPollInterval = pollInterval;
132 m_wifiMacTxCounterId = AddNodeCounter ("WifiMac Tx", AnimationInterface::DOUBLE_COUNTER);
133 m_wifiMacTxDropCounterId = AddNodeCounter ("WifiMac TxDrop", AnimationInterface::DOUBLE_COUNTER);
134 m_wifiMacRxCounterId = AddNodeCounter ("WifiMac Rx", AnimationInterface::DOUBLE_COUNTER);
135 m_wifiMacRxDropCounterId = AddNodeCounter ("WifiMac RxDrop", AnimationInterface::DOUBLE_COUNTER);
136 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
137 {
138 Ptr<Node> n = *i;
139 m_nodeWifiMacTx[n->GetId ()] = 0;
140 m_nodeWifiMacTxDrop[n->GetId ()] = 0;
141 m_nodeWifiMacRx[n->GetId ()] = 0;
142 m_nodeWifiMacRxDrop[n->GetId ()] = 0;
143 UpdateNodeCounter (m_wifiMacTxCounterId, n->GetId (), 0);
144 UpdateNodeCounter (m_wifiMacTxDropCounterId, n->GetId (), 0);
145 UpdateNodeCounter (m_wifiMacRxCounterId, n->GetId (), 0);
146 UpdateNodeCounter (m_wifiMacRxDropCounterId, n->GetId (), 0);
147 }
148 Simulator::Schedule (startTime, &AnimationInterface::TrackWifiMacCounters, this);
149 }
150
151 void
EnableQueueCounters(Time startTime,Time stopTime,Time pollInterval)152 AnimationInterface::EnableQueueCounters (Time startTime, Time stopTime, Time pollInterval)
153 {
154 m_queueCountersStopTime = stopTime;
155 m_queueCountersPollInterval = pollInterval;
156 m_queueEnqueueCounterId = AddNodeCounter ("Enqueue", AnimationInterface::DOUBLE_COUNTER);
157 m_queueDequeueCounterId = AddNodeCounter ("Dequeue", AnimationInterface::DOUBLE_COUNTER);
158 m_queueDropCounterId = AddNodeCounter ("Queue Drop", AnimationInterface::DOUBLE_COUNTER);
159 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
160 {
161 Ptr<Node> n = *i;
162 m_nodeQueueEnqueue[n->GetId ()] = 0;
163 m_nodeQueueDequeue[n->GetId ()] = 0;
164 m_nodeQueueDrop[n->GetId ()] = 0;
165 UpdateNodeCounter (m_queueEnqueueCounterId, n->GetId (), 0);
166 UpdateNodeCounter (m_queueDequeueCounterId, n->GetId (), 0);
167 UpdateNodeCounter (m_queueDropCounterId, n->GetId (), 0);
168 }
169 Simulator::Schedule (startTime, &AnimationInterface::TrackQueueCounters, this);
170 }
171
172 void
EnableIpv4L3ProtocolCounters(Time startTime,Time stopTime,Time pollInterval)173 AnimationInterface::EnableIpv4L3ProtocolCounters (Time startTime, Time stopTime, Time pollInterval)
174 {
175 m_ipv4L3ProtocolCountersStopTime = stopTime;
176 m_ipv4L3ProtocolCountersPollInterval = pollInterval;
177 m_ipv4L3ProtocolTxCounterId = AddNodeCounter ("Ipv4 Tx", AnimationInterface::DOUBLE_COUNTER);
178 m_ipv4L3ProtocolRxCounterId = AddNodeCounter ("Ipv4 Rx", AnimationInterface::DOUBLE_COUNTER);
179 m_ipv4L3ProtocolDropCounterId = AddNodeCounter ("Ipv4 Drop", AnimationInterface::DOUBLE_COUNTER);
180 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
181 {
182 Ptr<Node> n = *i;
183 m_nodeIpv4Tx[n->GetId ()] = 0;
184 m_nodeIpv4Rx[n->GetId ()] = 0;
185 m_nodeIpv4Drop[n->GetId ()] = 0;
186 UpdateNodeCounter (m_ipv4L3ProtocolTxCounterId, n->GetId (), 0);
187 UpdateNodeCounter (m_ipv4L3ProtocolRxCounterId, n->GetId (), 0);
188 UpdateNodeCounter (m_ipv4L3ProtocolDropCounterId, n->GetId (), 0);
189 }
190 Simulator::Schedule (startTime, &AnimationInterface::TrackIpv4L3ProtocolCounters, this);
191 }
192
193 AnimationInterface &
EnableIpv4RouteTracking(std::string fileName,Time startTime,Time stopTime,Time pollInterval)194 AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, Time pollInterval)
195 {
196 SetOutputFile (fileName, true);
197 m_routingStopTime = stopTime;
198 m_routingPollInterval = pollInterval;
199 WriteXmlAnim (true);
200 Simulator::Schedule (startTime, &AnimationInterface::TrackIpv4Route, this);
201 return *this;
202 }
203
204 AnimationInterface &
EnableIpv4RouteTracking(std::string fileName,Time startTime,Time stopTime,NodeContainer nc,Time pollInterval)205 AnimationInterface::EnableIpv4RouteTracking (std::string fileName, Time startTime, Time stopTime, NodeContainer nc, Time pollInterval)
206 {
207 m_routingNc = nc;
208 return EnableIpv4RouteTracking (fileName, startTime, stopTime, pollInterval);
209 }
210
211 AnimationInterface &
AddSourceDestination(uint32_t fromNodeId,std::string ipv4Address)212 AnimationInterface::AddSourceDestination (uint32_t fromNodeId, std::string ipv4Address)
213 {
214 Ipv4RouteTrackElement element = { ipv4Address, fromNodeId };
215 m_ipv4RouteTrackElements.push_back (element);
216 return *this;
217 }
218
219 void
SetStartTime(Time t)220 AnimationInterface::SetStartTime (Time t)
221 {
222 m_startTime = t;
223 }
224
225 void
SetStopTime(Time t)226 AnimationInterface::SetStopTime (Time t)
227 {
228 m_stopTime = t;
229 }
230
231 void
SetMaxPktsPerTraceFile(uint64_t maxPacketsPerFile)232 AnimationInterface::SetMaxPktsPerTraceFile (uint64_t maxPacketsPerFile)
233 {
234 m_maxPktsPerFile = maxPacketsPerFile;
235 }
236
237 uint32_t
AddNodeCounter(std::string counterName,CounterType counterType)238 AnimationInterface::AddNodeCounter (std::string counterName, CounterType counterType)
239 {
240 m_nodeCounters.push_back (counterName);
241 uint32_t counterId = m_nodeCounters.size () - 1; // counter ID is zero-indexed
242 WriteXmlAddNodeCounter (counterId, counterName, counterType);
243 return counterId;
244 }
245
246 uint32_t
AddResource(std::string resourcePath)247 AnimationInterface::AddResource (std::string resourcePath)
248 {
249 m_resources.push_back (resourcePath);
250 uint32_t resourceId = m_resources.size () - 1; // resource ID is zero-indexed
251 WriteXmlAddResource (resourceId, resourcePath);
252 return resourceId;
253 }
254
255 void
EnablePacketMetadata(bool enable)256 AnimationInterface::EnablePacketMetadata (bool enable)
257 {
258 m_enablePacketMetadata = enable;
259 if (enable)
260 {
261 Packet::EnablePrinting ();
262 }
263 }
264
265 bool
IsInitialized()266 AnimationInterface::IsInitialized ()
267 {
268 return initialized;
269 }
270
271 bool
IsStarted()272 AnimationInterface::IsStarted ()
273 {
274 return m_started;
275 }
276
277 void
SetAnimWriteCallback(AnimWriteCallback cb)278 AnimationInterface::SetAnimWriteCallback (AnimWriteCallback cb)
279 {
280 m_writeCallback = cb;
281 }
282
283 void
ResetAnimWriteCallback()284 AnimationInterface::ResetAnimWriteCallback ()
285 {
286 m_writeCallback = 0;
287 }
288
289 void
SetMobilityPollInterval(Time t)290 AnimationInterface::SetMobilityPollInterval (Time t)
291 {
292 m_mobilityPollInterval = t;
293 }
294
295
296 void
SetConstantPosition(Ptr<Node> n,double x,double y,double z)297 AnimationInterface::SetConstantPosition (Ptr <Node> n, double x, double y, double z)
298 {
299 NS_ASSERT (n);
300 Ptr<ConstantPositionMobilityModel> loc = n->GetObject<ConstantPositionMobilityModel> ();
301 if (loc == 0)
302 {
303 loc = CreateObject<ConstantPositionMobilityModel> ();
304 n->AggregateObject (loc);
305 }
306 Vector hubVec (x, y, z);
307 loc->SetPosition (hubVec);
308 NS_LOG_INFO ("Node:" << n->GetId () << " Position set to:(" << x << "," << y << "," << z << ")");
309
310 }
311
312 void
UpdateNodeImage(uint32_t nodeId,uint32_t resourceId)313 AnimationInterface::UpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
314 {
315 NS_LOG_INFO ("Setting node image for Node Id:" << nodeId);
316 if (resourceId > (m_resources.size () - 1))
317 {
318 NS_FATAL_ERROR ("Resource Id:" << resourceId << " not found. Did you use AddResource?");
319 }
320 WriteXmlUpdateNodeImage (nodeId, resourceId);
321 }
322
323 void
UpdateNodeCounter(uint32_t nodeCounterId,uint32_t nodeId,double counter)324 AnimationInterface::UpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counter)
325 {
326 if (nodeCounterId > (m_nodeCounters.size () - 1))
327 {
328 NS_FATAL_ERROR ("NodeCounter Id:" << nodeCounterId << " not found. Did you use AddNodeCounter?");
329 }
330 WriteXmlUpdateNodeCounter (nodeCounterId, nodeId, counter);
331 }
332
333 void
SetBackgroundImage(std::string fileName,double x,double y,double scaleX,double scaleY,double opacity)334 AnimationInterface::SetBackgroundImage (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
335 {
336 if ((opacity < 0) || (opacity > 1))
337 {
338 NS_FATAL_ERROR ("Opacity must be between 0.0 and 1.0");
339 }
340 WriteXmlUpdateBackground (fileName, x, y, scaleX, scaleY, opacity);
341 }
342
343 void
UpdateNodeSize(uint32_t nodeId,double width,double height)344 AnimationInterface::UpdateNodeSize (uint32_t nodeId, double width, double height)
345 {
346 AnimationInterface::NodeSize s = { width, height };
347 m_nodeSizes[nodeId] = s;
348 WriteXmlUpdateNodeSize (nodeId, s.width, s.height);
349 }
350
351 void
UpdateNodeColor(Ptr<Node> n,uint8_t r,uint8_t g,uint8_t b)352 AnimationInterface::UpdateNodeColor (Ptr <Node> n, uint8_t r, uint8_t g, uint8_t b)
353 {
354 UpdateNodeColor (n->GetId (), r, g, b);
355 }
356
357 void
UpdateNodeColor(uint32_t nodeId,uint8_t r,uint8_t g,uint8_t b)358 AnimationInterface::UpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
359 {
360 NS_ASSERT (NodeList::GetNode (nodeId));
361 NS_LOG_INFO ("Setting node color for Node Id:" << nodeId);
362 Rgb rgb = {r, g, b};
363 m_nodeColors[nodeId] = rgb;
364 WriteXmlUpdateNodeColor (nodeId, r, g, b);
365 }
366
367 void
UpdateLinkDescription(uint32_t fromNode,uint32_t toNode,std::string linkDescription)368 AnimationInterface::UpdateLinkDescription (uint32_t fromNode, uint32_t toNode,
369 std::string linkDescription)
370 {
371 WriteXmlUpdateLink (fromNode, toNode, linkDescription);
372 }
373
374 void
UpdateLinkDescription(Ptr<Node> fromNode,Ptr<Node> toNode,std::string linkDescription)375 AnimationInterface::UpdateLinkDescription (Ptr <Node> fromNode, Ptr <Node> toNode,
376 std::string linkDescription)
377 {
378 NS_ASSERT (fromNode);
379 NS_ASSERT (toNode);
380 WriteXmlUpdateLink (fromNode->GetId (), toNode->GetId (), linkDescription);
381 }
382
383 void
UpdateNodeDescription(Ptr<Node> n,std::string descr)384 AnimationInterface::UpdateNodeDescription (Ptr <Node> n, std::string descr)
385 {
386 UpdateNodeDescription (n->GetId (), descr);
387 }
388
389 void
UpdateNodeDescription(uint32_t nodeId,std::string descr)390 AnimationInterface::UpdateNodeDescription (uint32_t nodeId, std::string descr)
391 {
392 NS_ASSERT (NodeList::GetNode (nodeId));
393 m_nodeDescriptions[nodeId] = descr;
394 WriteXmlUpdateNodeDescription (nodeId);
395 }
396
397 // Private methods
398
399
400 double
GetNodeEnergyFraction(Ptr<const Node> node) const401 AnimationInterface::GetNodeEnergyFraction (Ptr <const Node> node) const
402 {
403 const EnergyFractionMap::const_iterator fractionIter = m_nodeEnergyFraction.find (node->GetId ());
404 NS_ASSERT (fractionIter != m_nodeEnergyFraction.end ());
405 return fractionIter->second;
406 }
407
408 void
MobilityCourseChangeTrace(Ptr<const MobilityModel> mobility)409 AnimationInterface::MobilityCourseChangeTrace (Ptr <const MobilityModel> mobility)
410 {
411 CHECK_STARTED_INTIMEWINDOW;
412 Ptr <Node> n = mobility->GetObject <Node> ();
413 NS_ASSERT (n);
414 Vector v;
415 if (!mobility)
416 {
417 v = GetPosition (n);
418 }
419 else
420 {
421 v = mobility->GetPosition ();
422 }
423 UpdatePosition (n, v);
424 WriteXmlUpdateNodePosition (n->GetId (), v.x, v.y);
425 }
426
427 bool
NodeHasMoved(Ptr<Node> n,Vector newLocation)428 AnimationInterface::NodeHasMoved (Ptr <Node> n, Vector newLocation)
429 {
430 Vector oldLocation = GetPosition (n);
431 bool moved = true;
432 if ((ceil (oldLocation.x) == ceil (newLocation.x))
433 && (ceil (oldLocation.y) == ceil (newLocation.y)))
434 {
435 moved = false;
436 }
437 else
438 {
439 moved = true;
440 }
441 return moved;
442 }
443
444 void
MobilityAutoCheck()445 AnimationInterface::MobilityAutoCheck ()
446 {
447 CHECK_STARTED_INTIMEWINDOW;
448 std::vector <Ptr <Node> > MovedNodes = GetMovedNodes ();
449 for (uint32_t i = 0; i < MovedNodes.size (); i++)
450 {
451 Ptr <Node> n = MovedNodes [i];
452 NS_ASSERT (n);
453 Vector v = GetPosition (n);
454 WriteXmlUpdateNodePosition (n->GetId (), v.x, v.y);
455 }
456 if (!Simulator::IsFinished ())
457 {
458 PurgePendingPackets (AnimationInterface::WIFI);
459 PurgePendingPackets (AnimationInterface::WIMAX);
460 PurgePendingPackets (AnimationInterface::LTE);
461 PurgePendingPackets (AnimationInterface::CSMA);
462 PurgePendingPackets (AnimationInterface::LRWPAN);
463 PurgePendingPackets (AnimationInterface::WAVE);
464 Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
465 }
466 }
467
468 std::vector <Ptr <Node> >
GetMovedNodes()469 AnimationInterface::GetMovedNodes ()
470 {
471 std::vector < Ptr <Node> > movedNodes;
472 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
473 {
474 Ptr<Node> n = *i;
475 NS_ASSERT (n);
476 Ptr <MobilityModel> mobility = n->GetObject <MobilityModel> ();
477 Vector newLocation;
478 if (!mobility)
479 {
480 newLocation = GetPosition (n);
481 }
482 else
483 {
484 newLocation = mobility->GetPosition ();
485 }
486 if (!NodeHasMoved (n, newLocation))
487 {
488 continue; //Location has not changed
489 }
490 else
491 {
492 UpdatePosition (n, newLocation);
493 movedNodes.push_back (n);
494 }
495 }
496 return movedNodes;
497 }
498
499 int
WriteN(const std::string & st,FILE * f)500 AnimationInterface::WriteN (const std::string& st, FILE * f)
501 {
502 if (!f)
503 {
504 return 0;
505 }
506 if (m_writeCallback)
507 {
508 m_writeCallback (st.c_str ());
509 }
510 return WriteN (st.c_str (), st.length (), f);
511 }
512
513 int
WriteN(const char * data,uint32_t count,FILE * f)514 AnimationInterface::WriteN (const char* data, uint32_t count, FILE * f)
515 {
516 if (!f)
517 {
518 return 0;
519 }
520 // Write count bytes to h from data
521 uint32_t nLeft = count;
522 const char* p = data;
523 uint32_t written = 0;
524 while (nLeft)
525 {
526 int n = std::fwrite (p, 1, nLeft, f);
527 if (n <= 0)
528 {
529 return written;
530 }
531 written += n;
532 nLeft -= n;
533 p += n;
534 }
535 return written;
536 }
537
538 void
WriteRoutePath(uint32_t nodeId,std::string destination,Ipv4RoutePathElements rpElements)539 AnimationInterface::WriteRoutePath (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
540 {
541 NS_LOG_INFO ("Writing Route Path From :" << nodeId << " To: " << destination.c_str ());
542 WriteXmlRp (nodeId, destination, rpElements);
543 /*for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
544 i != rpElements.end ();
545 ++i)
546 {
547 Ipv4RoutePathElement rpElement = *i;
548 NS_LOG_INFO ("Node:" << rpElement.nodeId << "-->" << rpElement.nextHop.c_str ());
549 WriteN (GetXmlRp (rpElement.node, GetIpv4RoutingTable (n)), m_routingF);
550
551 }
552 */
553 }
554
555 void
WriteNonP2pLinkProperties(uint32_t id,std::string ipv4Address,std::string channelType)556 AnimationInterface::WriteNonP2pLinkProperties (uint32_t id, std::string ipv4Address, std::string channelType)
557 {
558 WriteXmlNonP2pLinkProperties (id, ipv4Address, channelType);
559 }
560
561 const std::vector<std::string>
GetElementsFromContext(const std::string & context) const562 AnimationInterface::GetElementsFromContext (const std::string& context) const
563 {
564 std::vector <std::string> elements;
565 std::size_t pos1 = 0, pos2;
566 while (pos1 != context.npos)
567 {
568 pos1 = context.find ("/",pos1);
569 pos2 = context.find ("/",pos1 + 1);
570 elements.push_back (context.substr (pos1 + 1,pos2 - (pos1 + 1)));
571 pos1 = pos2;
572 pos2 = context.npos;
573 }
574 return elements;
575 }
576
577 Ptr <Node>
GetNodeFromContext(const std::string & context) const578 AnimationInterface::GetNodeFromContext (const std::string& context) const
579 {
580 // Use "NodeList/*/ as reference
581 // where element [1] is the Node Id
582
583 std::vector <std::string> elements = GetElementsFromContext (context);
584 Ptr <Node> n = NodeList::GetNode (atoi (elements.at (1).c_str ()));
585 NS_ASSERT (n);
586
587 return n;
588 }
589
590 Ptr <NetDevice>
GetNetDeviceFromContext(std::string context)591 AnimationInterface::GetNetDeviceFromContext (std::string context)
592 {
593 // Use "NodeList/*/DeviceList/*/ as reference
594 // where element [1] is the Node Id
595 // element [2] is the NetDevice Id
596
597 std::vector <std::string> elements = GetElementsFromContext (context);
598 Ptr <Node> n = GetNodeFromContext (context);
599
600 return n->GetDevice (atoi (elements.at (3).c_str ()));
601 }
602
603 uint64_t
GetAnimUidFromPacket(Ptr<const Packet> p)604 AnimationInterface::GetAnimUidFromPacket (Ptr <const Packet> p)
605 {
606 AnimByteTag tag;
607 TypeId tid = tag.GetInstanceTypeId ();
608 ByteTagIterator i = p->GetByteTagIterator ();
609 bool found = false;
610 while (i.HasNext ())
611 {
612 ByteTagIterator::Item item = i.Next ();
613 if (tid == item.GetTypeId ())
614 {
615 item.GetTag (tag);
616 found = true;
617 }
618 }
619 if (found)
620 {
621 return tag.Get ();
622 }
623 else
624 {
625 return 0;
626 }
627 }
628
629 void
AddByteTag(uint64_t animUid,Ptr<const Packet> p)630 AnimationInterface::AddByteTag (uint64_t animUid, Ptr<const Packet> p)
631 {
632 AnimByteTag tag;
633 tag.Set (animUid);
634 p->AddByteTag (tag);
635 }
636
637 void
RemainingEnergyTrace(std::string context,double previousEnergy,double currentEnergy)638 AnimationInterface::RemainingEnergyTrace (std::string context, double previousEnergy, double currentEnergy)
639 {
640 CHECK_STARTED_INTIMEWINDOW;
641 const Ptr <const Node> node = GetNodeFromContext (context);
642 const uint32_t nodeId = node->GetId ();
643
644 NS_LOG_INFO ("Remaining energy on one of sources on node " << nodeId << ": " << currentEnergy);
645
646 const Ptr<EnergySource> energySource = node->GetObject<EnergySource> ();
647
648 NS_ASSERT (energySource);
649 // Don't call GetEnergyFraction () because of recursion
650 const double energyFraction = currentEnergy / energySource->GetInitialEnergy ();
651
652 NS_LOG_INFO ("Total energy fraction on node " << nodeId << ": " << energyFraction);
653
654 m_nodeEnergyFraction[nodeId] = energyFraction;
655 UpdateNodeCounter (m_remainingEnergyCounterId, nodeId, energyFraction);
656 }
657
658 void
WifiPhyTxDropTrace(std::string context,Ptr<const Packet> p)659 AnimationInterface::WifiPhyTxDropTrace (std::string context, Ptr<const Packet> p)
660 {
661 const Ptr <const Node> node = GetNodeFromContext (context);
662 ++m_nodeWifiPhyTxDrop[node->GetId ()];
663 }
664
665 void
WifiPhyRxDropTrace(std::string context,Ptr<const Packet> p,WifiPhyRxfailureReason reason)666 AnimationInterface::WifiPhyRxDropTrace (std::string context, Ptr<const Packet> p, WifiPhyRxfailureReason reason)
667 {
668 const Ptr <const Node> node = GetNodeFromContext (context);
669 ++m_nodeWifiPhyRxDrop[node->GetId ()];
670 }
671
672 void
WifiMacTxTrace(std::string context,Ptr<const Packet> p)673 AnimationInterface::WifiMacTxTrace (std::string context, Ptr<const Packet> p)
674 {
675 const Ptr <const Node> node = GetNodeFromContext (context);
676 ++m_nodeWifiMacTx[node->GetId ()];
677 }
678
679 void
WifiMacTxDropTrace(std::string context,Ptr<const Packet> p)680 AnimationInterface::WifiMacTxDropTrace (std::string context, Ptr<const Packet> p)
681 {
682 const Ptr <const Node> node = GetNodeFromContext (context);
683 ++m_nodeWifiMacTxDrop[node->GetId ()];
684 }
685
686 void
WifiMacRxTrace(std::string context,Ptr<const Packet> p)687 AnimationInterface::WifiMacRxTrace (std::string context, Ptr<const Packet> p)
688 {
689 const Ptr <const Node> node = GetNodeFromContext (context);
690 ++m_nodeWifiMacRx[node->GetId ()];
691 }
692
693 void
WifiMacRxDropTrace(std::string context,Ptr<const Packet> p)694 AnimationInterface::WifiMacRxDropTrace (std::string context, Ptr<const Packet> p)
695 {
696 const Ptr <const Node> node = GetNodeFromContext (context);
697 ++m_nodeWifiMacRxDrop[node->GetId ()];
698 }
699
700 void
LrWpanMacTxTrace(std::string context,Ptr<const Packet> p)701 AnimationInterface::LrWpanMacTxTrace (std::string context, Ptr<const Packet> p)
702 {
703 const Ptr <const Node> node = GetNodeFromContext (context);
704 ++m_nodeLrWpanMacTx[node->GetId ()];
705 }
706
707 void
LrWpanMacTxDropTrace(std::string context,Ptr<const Packet> p)708 AnimationInterface::LrWpanMacTxDropTrace (std::string context, Ptr<const Packet> p)
709 {
710 const Ptr <const Node> node = GetNodeFromContext (context);
711 ++m_nodeLrWpanMacTxDrop[node->GetId ()];
712 }
713
714 void
LrWpanMacRxTrace(std::string context,Ptr<const Packet> p)715 AnimationInterface::LrWpanMacRxTrace (std::string context, Ptr<const Packet> p)
716 {
717 const Ptr <const Node> node = GetNodeFromContext (context);
718 ++m_nodeLrWpanMacRx[node->GetId ()];
719 }
720
721 void
LrWpanMacRxDropTrace(std::string context,Ptr<const Packet> p)722 AnimationInterface::LrWpanMacRxDropTrace (std::string context, Ptr<const Packet> p)
723 {
724 const Ptr <const Node> node = GetNodeFromContext (context);
725 ++m_nodeLrWpanMacRxDrop[node->GetId ()];
726 }
727
728 void
Ipv4TxTrace(std::string context,Ptr<const Packet> p,Ptr<Ipv4> ipv4,uint32_t interfaceIndex)729 AnimationInterface::Ipv4TxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
730 {
731 const Ptr <const Node> node = GetNodeFromContext (context);
732 ++m_nodeIpv4Tx[node->GetId ()];
733 }
734
735 void
Ipv4RxTrace(std::string context,Ptr<const Packet> p,Ptr<Ipv4> ipv4,uint32_t interfaceIndex)736 AnimationInterface::Ipv4RxTrace (std::string context, Ptr<const Packet> p, Ptr<Ipv4> ipv4, uint32_t interfaceIndex)
737 {
738 const Ptr <const Node> node = GetNodeFromContext (context);
739 ++m_nodeIpv4Rx[node->GetId ()];
740 }
741
742 void
Ipv4DropTrace(std::string context,const Ipv4Header & ipv4Header,Ptr<const Packet> p,Ipv4L3Protocol::DropReason dropReason,Ptr<Ipv4> ipv4,uint32_t)743 AnimationInterface::Ipv4DropTrace (std::string context,
744 const Ipv4Header & ipv4Header,
745 Ptr<const Packet> p,
746 Ipv4L3Protocol::DropReason dropReason,
747 Ptr<Ipv4> ipv4,
748 uint32_t)
749 {
750 const Ptr <const Node> node = GetNodeFromContext (context);
751 ++m_nodeIpv4Drop[node->GetId ()];
752 }
753
754 void
EnqueueTrace(std::string context,Ptr<const Packet> p)755 AnimationInterface::EnqueueTrace (std::string context,
756 Ptr<const Packet> p)
757 {
758 const Ptr <const Node> node = GetNodeFromContext (context);
759 ++m_nodeQueueEnqueue[node->GetId ()];
760 }
761
762 void
DequeueTrace(std::string context,Ptr<const Packet> p)763 AnimationInterface::DequeueTrace (std::string context,
764 Ptr<const Packet> p)
765 {
766 const Ptr <const Node> node = GetNodeFromContext (context);
767 ++m_nodeQueueDequeue[node->GetId ()];
768 }
769
770 void
QueueDropTrace(std::string context,Ptr<const Packet> p)771 AnimationInterface::QueueDropTrace (std::string context,
772 Ptr<const Packet> p)
773 {
774 const Ptr <const Node> node = GetNodeFromContext (context);
775 ++m_nodeQueueDrop[node->GetId ()];
776 }
777
778 void
DevTxTrace(std::string context,Ptr<const Packet> p,Ptr<NetDevice> tx,Ptr<NetDevice> rx,Time txTime,Time rxTime)779 AnimationInterface::DevTxTrace (std::string context,
780 Ptr<const Packet> p,
781 Ptr<NetDevice> tx,
782 Ptr<NetDevice> rx,
783 Time txTime,
784 Time rxTime)
785 {
786 NS_LOG_FUNCTION (this);
787 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
788 NS_ASSERT (tx);
789 NS_ASSERT (rx);
790 Time now = Simulator::Now ();
791 double fbTx = now.GetSeconds ();
792 double lbTx = (now + txTime).GetSeconds ();
793 double fbRx = (now + rxTime - txTime).GetSeconds ();
794 double lbRx = (now + rxTime).GetSeconds ();
795 CheckMaxPktsPerTraceFile ();
796 WriteXmlP ("p",
797 tx->GetNode ()->GetId (),
798 fbTx,
799 lbTx,
800 rx->GetNode ()->GetId (),
801 fbRx,
802 lbRx,
803 m_enablePacketMetadata ? GetPacketMetadata (p) : "");
804 }
805
806 void
GenericWirelessTxTrace(std::string context,Ptr<const Packet> p,ProtocolType protocolType)807 AnimationInterface::GenericWirelessTxTrace (std::string context, Ptr<const Packet> p, ProtocolType protocolType)
808 {
809 NS_LOG_FUNCTION (this);
810 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
811 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
812 NS_ASSERT (ndev);
813 UpdatePosition (ndev);
814
815 ++gAnimUid;
816 NS_LOG_INFO (ProtocolTypeToString (protocolType).c_str () << " GenericWirelessTxTrace for packet:" << gAnimUid);
817 AddByteTag (gAnimUid, p);
818 AnimPacketInfo pktInfo (ndev, Simulator::Now ());
819 AddPendingPacket (protocolType, gAnimUid, pktInfo);
820
821 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
822 if (netDevice)
823 {
824 Mac48Address nodeAddr = netDevice->GetMac ()->GetAddress ();
825 std::ostringstream oss;
826 oss << nodeAddr;
827 Ptr <Node> n = netDevice->GetNode ();
828 NS_ASSERT (n);
829 m_macToNodeIdMap[oss.str ()] = n->GetId ();
830 NS_LOG_INFO ("Added Mac" << oss.str () << " node:" << m_macToNodeIdMap[oss.str ()]);
831 }
832 AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
833 OutputWirelessPacketTxInfo (p, pendingPackets->at (gAnimUid), gAnimUid);
834 }
835
836 void
GenericWirelessRxTrace(std::string context,Ptr<const Packet> p,ProtocolType protocolType)837 AnimationInterface::GenericWirelessRxTrace (std::string context, Ptr<const Packet> p, ProtocolType protocolType)
838 {
839 NS_LOG_FUNCTION (this);
840 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
841 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
842 NS_ASSERT (ndev);
843 UpdatePosition (ndev);
844 uint64_t animUid = GetAnimUidFromPacket (p);
845 NS_LOG_INFO (ProtocolTypeToString (protocolType).c_str () << " for packet:" << animUid);
846 if (!IsPacketPending (animUid, protocolType))
847 {
848 NS_LOG_WARN (ProtocolTypeToString (protocolType).c_str () << " GenericWirelessRxTrace: unknown Uid");
849 return;
850 }
851 AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
852 pendingPackets->at (animUid).ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
853 OutputWirelessPacketRxInfo (p, pendingPackets->at (animUid), animUid);
854 }
855
856 void
UanPhyGenTxTrace(std::string context,Ptr<const Packet> p)857 AnimationInterface::UanPhyGenTxTrace (std::string context, Ptr<const Packet> p)
858 {
859 NS_LOG_FUNCTION (this);
860 return GenericWirelessTxTrace (context, p, AnimationInterface::UAN);
861 }
862
863 void
UanPhyGenRxTrace(std::string context,Ptr<const Packet> p)864 AnimationInterface::UanPhyGenRxTrace (std::string context, Ptr<const Packet> p)
865 {
866 NS_LOG_FUNCTION (this);
867 return GenericWirelessRxTrace (context, p, AnimationInterface::UAN);
868 }
869
870 void
WifiPhyTxBeginTrace(std::string context,WifiConstPsduMap psduMap,WifiTxVector txVector,double txPowerW)871 AnimationInterface::WifiPhyTxBeginTrace (std::string context, WifiConstPsduMap psduMap, WifiTxVector txVector, double txPowerW)
872 {
873 NS_LOG_FUNCTION (this);
874 NS_UNUSED (txVector);
875 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
876 Ptr<NetDevice> ndev = GetNetDeviceFromContext (context);
877 NS_ASSERT (ndev);
878 UpdatePosition (ndev);
879
880 AnimPacketInfo pktInfo (ndev, Simulator::Now ());
881 AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (WIFI);
882 for (auto& psdu : psduMap)
883 {
884 for (auto& mpdu : *PeekPointer (psdu.second))
885 {
886 ++gAnimUid;
887 NS_LOG_INFO ("WifiPhyTxTrace for MPDU:" << gAnimUid);
888 AddByteTag (gAnimUid, mpdu->GetPacket ()); //the underlying MSDU/A-MSDU should be handed off
889 AddPendingPacket (WIFI, gAnimUid, pktInfo);
890 OutputWirelessPacketTxInfo (mpdu->GetProtocolDataUnit (), pendingPackets->at (gAnimUid), gAnimUid); //PDU should be considered in order to have header
891 }
892 }
893
894 Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev);
895 if (netDevice)
896 {
897 Mac48Address nodeAddr = netDevice->GetMac ()->GetAddress ();
898 std::ostringstream oss;
899 oss << nodeAddr;
900 Ptr<Node> n = netDevice->GetNode ();
901 NS_ASSERT (n);
902 m_macToNodeIdMap[oss.str ()] = n->GetId ();
903 NS_LOG_INFO ("Added Mac" << oss.str () << " node:" << m_macToNodeIdMap[oss.str ()]);
904 }
905 else
906 {
907 NS_ABORT_MSG ("This NetDevice should be a Wi-Fi network device");
908 }
909 }
910
911 void
WifiPhyRxBeginTrace(std::string context,Ptr<const Packet> p,RxPowerWattPerChannelBand rxPowersW)912 AnimationInterface::WifiPhyRxBeginTrace (std::string context, Ptr<const Packet> p, RxPowerWattPerChannelBand rxPowersW)
913 {
914 NS_LOG_FUNCTION (this);
915 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
916 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
917 NS_ASSERT (ndev);
918 UpdatePosition (ndev);
919 uint64_t animUid = GetAnimUidFromPacket (p);
920 NS_LOG_INFO ("Wifi RxBeginTrace for packet: " << animUid);
921 if (!IsPacketPending (animUid, AnimationInterface::WIFI))
922 {
923 NS_ASSERT_MSG (false, "WifiPhyRxBeginTrace: unknown Uid");
924 std::ostringstream oss;
925 WifiMacHeader hdr;
926 if (!p->PeekHeader (hdr))
927 {
928 NS_LOG_WARN ("WifiMacHeader not present");
929 return;
930 }
931 oss << hdr.GetAddr2 ();
932 if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
933 {
934 NS_LOG_WARN ("Transmitter Mac address " << oss.str () << " never seen before. Skipping");
935 return;
936 }
937 Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
938 UpdatePosition (txNode);
939 AnimPacketInfo pktInfo (0, Simulator::Now (), m_macToNodeIdMap[oss.str ()]);
940 AddPendingPacket (AnimationInterface::WIFI, animUid, pktInfo);
941 NS_LOG_WARN ("WifiPhyRxBegin: unknown Uid, but we are adding a wifi packet");
942 }
943 /// \todo NS_ASSERT (WifiPacketIsPending (animUid) == true);
944 m_pendingWifiPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
945 OutputWirelessPacketRxInfo (p, m_pendingWifiPackets[animUid], animUid);
946 }
947
948 void
LrWpanPhyTxBeginTrace(std::string context,Ptr<const Packet> p)949 AnimationInterface::LrWpanPhyTxBeginTrace (std::string context,
950 Ptr<const Packet> p)
951 {
952 NS_LOG_FUNCTION (this);
953 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
954
955 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
956 NS_ASSERT (ndev);
957 Ptr<LrWpanNetDevice> netDevice = DynamicCast<LrWpanNetDevice> (ndev);
958
959 Ptr <Node> n = ndev->GetNode ();
960 NS_ASSERT (n);
961
962 UpdatePosition (n);
963
964 LrWpanMacHeader hdr;
965 if (!p->PeekHeader (hdr))
966 {
967 NS_LOG_WARN ("LrWpanMacHeader not present");
968 return;
969 }
970
971 std::ostringstream oss;
972 if (hdr.GetSrcAddrMode () == 2)
973 {
974 Mac16Address nodeAddr = netDevice->GetMac ()->GetShortAddress ();
975 oss << nodeAddr;
976 }
977 else if (hdr.GetSrcAddrMode () == 3)
978 {
979 Mac64Address nodeAddr = netDevice->GetMac ()->GetExtendedAddress ();
980 oss << nodeAddr;
981 }
982 else
983 {
984 NS_LOG_WARN ("LrWpanMacHeader without source address");
985 return;
986 }
987 m_macToNodeIdMap[oss.str ()] = n->GetId ();
988 NS_LOG_INFO ("Added Mac" << oss.str () << " node:" << m_macToNodeIdMap[oss.str ()]);
989
990 ++gAnimUid;
991 NS_LOG_INFO ("LrWpan TxBeginTrace for packet:" << gAnimUid);
992 AddByteTag (gAnimUid, p);
993
994 AnimPacketInfo pktInfo (ndev, Simulator::Now ());
995 AddPendingPacket (AnimationInterface::LRWPAN, gAnimUid, pktInfo);
996
997 OutputWirelessPacketTxInfo (p, m_pendingLrWpanPackets[gAnimUid], gAnimUid);
998 }
999
1000 void
LrWpanPhyRxBeginTrace(std::string context,Ptr<const Packet> p)1001 AnimationInterface::LrWpanPhyRxBeginTrace (std::string context,
1002 Ptr<const Packet> p)
1003 {
1004 NS_LOG_FUNCTION (this);
1005 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1006 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1007 NS_ASSERT (ndev);
1008 Ptr <Node> n = ndev->GetNode ();
1009 NS_ASSERT (n);
1010
1011 AnimByteTag tag;
1012 if (!p->FindFirstMatchingByteTag (tag))
1013 {
1014 return;
1015 }
1016
1017 uint64_t animUid = GetAnimUidFromPacket (p);
1018 NS_LOG_INFO ("LrWpan RxBeginTrace for packet:" << animUid);
1019 if (!IsPacketPending (animUid, AnimationInterface::LRWPAN))
1020 {
1021 NS_LOG_WARN ("LrWpanPhyRxBeginTrace: unknown Uid - most probably it's an ACK.");
1022 }
1023
1024 UpdatePosition (n);
1025 m_pendingLrWpanPackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1026 OutputWirelessPacketRxInfo (p, m_pendingLrWpanPackets[animUid], animUid);
1027 }
1028
1029 void
WavePhyTxBeginTrace(std::string context,Ptr<const Packet> p)1030 AnimationInterface::WavePhyTxBeginTrace (std::string context, Ptr<const Packet> p)
1031 {
1032 NS_LOG_FUNCTION (this);
1033 return GenericWirelessTxTrace (context, p, AnimationInterface::WAVE);
1034 }
1035
1036 void
WavePhyRxBeginTrace(std::string context,Ptr<const Packet> p)1037 AnimationInterface::WavePhyRxBeginTrace (std::string context, Ptr<const Packet> p)
1038 {
1039 NS_LOG_FUNCTION (this);
1040 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1041 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1042 NS_ASSERT (ndev);
1043 UpdatePosition (ndev);
1044 uint64_t animUid = GetAnimUidFromPacket (p);
1045 NS_LOG_INFO ("Wave RxBeginTrace for packet:" << animUid);
1046 if (!IsPacketPending (animUid, AnimationInterface::WAVE))
1047 {
1048 NS_ASSERT_MSG (false, "WavePhyRxBeginTrace: unknown Uid");
1049 std::ostringstream oss;
1050 WifiMacHeader hdr;
1051 if (!p->PeekHeader (hdr))
1052 {
1053 NS_LOG_WARN ("WaveMacHeader not present");
1054 return;
1055 }
1056 oss << hdr.GetAddr2 ();
1057 if (m_macToNodeIdMap.find (oss.str ()) == m_macToNodeIdMap.end ())
1058 {
1059 NS_LOG_WARN ("Transmitter Mac address " << oss.str () << " never seen before. Skipping");
1060 return;
1061 }
1062 Ptr <Node> txNode = NodeList::GetNode (m_macToNodeIdMap[oss.str ()]);
1063 UpdatePosition (txNode);
1064 AnimPacketInfo pktInfo (0, Simulator::Now (), m_macToNodeIdMap[oss.str ()]);
1065 AddPendingPacket (AnimationInterface::WAVE, animUid, pktInfo);
1066 NS_LOG_WARN ("WavePhyRxBegin: unknown Uid, but we are adding a wave packet");
1067 }
1068 /// \todo NS_ASSERT (WavePacketIsPending (animUid) == true);
1069 m_pendingWavePackets[animUid].ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1070 OutputWirelessPacketRxInfo (p, m_pendingWavePackets[animUid], animUid);
1071 }
1072
1073
1074 void
WimaxTxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1075 AnimationInterface::WimaxTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1076 {
1077 NS_LOG_FUNCTION (this);
1078 return GenericWirelessTxTrace (context, p, AnimationInterface::WIMAX);
1079 }
1080
1081
1082 void
WimaxRxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1083 AnimationInterface::WimaxRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1084 {
1085 NS_LOG_FUNCTION (this);
1086 return GenericWirelessRxTrace (context, p, AnimationInterface::WIMAX);
1087 }
1088
1089 void
LteTxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1090 AnimationInterface::LteTxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1091 {
1092 NS_LOG_FUNCTION (this);
1093 return GenericWirelessTxTrace (context, p, AnimationInterface::LTE);
1094 }
1095
1096 void
LteRxTrace(std::string context,Ptr<const Packet> p,const Mac48Address & m)1097 AnimationInterface::LteRxTrace (std::string context, Ptr<const Packet> p, const Mac48Address & m)
1098 {
1099 NS_LOG_FUNCTION (this);
1100 return GenericWirelessRxTrace (context, p, AnimationInterface::LTE);
1101 }
1102
1103 void
LteSpectrumPhyTxStart(std::string context,Ptr<const PacketBurst> pb)1104 AnimationInterface::LteSpectrumPhyTxStart (std::string context, Ptr<const PacketBurst> pb)
1105 {
1106 NS_LOG_FUNCTION (this);
1107 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1108 if (!pb)
1109 {
1110 NS_LOG_WARN ("pb == 0. Not yet supported");
1111 return;
1112 }
1113 context = "/" + context;
1114 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1115 NS_ASSERT (ndev);
1116 UpdatePosition (ndev);
1117
1118 std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1119 for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
1120 i != pbList.end ();
1121 ++i)
1122 {
1123 Ptr <Packet> p = *i;
1124 ++gAnimUid;
1125 NS_LOG_INFO ("LteSpectrumPhyTxTrace for packet:" << gAnimUid);
1126 AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1127 AddByteTag (gAnimUid, p);
1128 AddPendingPacket (AnimationInterface::LTE, gAnimUid, pktInfo);
1129 OutputWirelessPacketTxInfo (p, pktInfo, gAnimUid);
1130 }
1131 }
1132
1133 void
LteSpectrumPhyRxStart(std::string context,Ptr<const PacketBurst> pb)1134 AnimationInterface::LteSpectrumPhyRxStart (std::string context, Ptr<const PacketBurst> pb)
1135 {
1136 NS_LOG_FUNCTION (this);
1137 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1138 if (!pb)
1139 {
1140 NS_LOG_WARN ("pb == 0. Not yet supported");
1141 return;
1142 }
1143 context = "/" + context;
1144 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1145 NS_ASSERT (ndev);
1146 UpdatePosition (ndev);
1147
1148 std::list <Ptr <Packet> > pbList = pb->GetPackets ();
1149 for (std::list <Ptr <Packet> >::iterator i = pbList.begin ();
1150 i != pbList.end ();
1151 ++i)
1152 {
1153 Ptr <Packet> p = *i;
1154 uint64_t animUid = GetAnimUidFromPacket (p);
1155 NS_LOG_INFO ("LteSpectrumPhyRxTrace for packet:" << gAnimUid);
1156 if (!IsPacketPending (animUid, AnimationInterface::LTE))
1157 {
1158 NS_LOG_WARN ("LteSpectrumPhyRxTrace: unknown Uid");
1159 return;
1160 }
1161 AnimPacketInfo& pktInfo = m_pendingLtePackets[animUid];
1162 pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1163 OutputWirelessPacketRxInfo (p, pktInfo, animUid);
1164 }
1165 }
1166
1167 void
CsmaPhyTxBeginTrace(std::string context,Ptr<const Packet> p)1168 AnimationInterface::CsmaPhyTxBeginTrace (std::string context, Ptr<const Packet> p)
1169 {
1170 NS_LOG_FUNCTION (this);
1171 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1172 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1173 NS_ASSERT (ndev);
1174 UpdatePosition (ndev);
1175 ++gAnimUid;
1176 NS_LOG_INFO ("CsmaPhyTxBeginTrace for packet:" << gAnimUid);
1177 AddByteTag (gAnimUid, p);
1178 UpdatePosition (ndev);
1179 AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1180 AddPendingPacket (AnimationInterface::CSMA, gAnimUid, pktInfo);
1181
1182
1183 }
1184
1185 void
CsmaPhyTxEndTrace(std::string context,Ptr<const Packet> p)1186 AnimationInterface::CsmaPhyTxEndTrace (std::string context, Ptr<const Packet> p)
1187 {
1188 NS_LOG_FUNCTION (this);
1189 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1190 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1191 NS_ASSERT (ndev);
1192 UpdatePosition (ndev);
1193 uint64_t animUid = GetAnimUidFromPacket (p);
1194 NS_LOG_INFO ("CsmaPhyTxEndTrace for packet:" << animUid);
1195 if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1196 {
1197 NS_LOG_WARN ("CsmaPhyTxEndTrace: unknown Uid");
1198 NS_FATAL_ERROR ("CsmaPhyTxEndTrace: unknown Uid");
1199 AnimPacketInfo pktInfo (ndev, Simulator::Now ());
1200 AddPendingPacket (AnimationInterface::CSMA, animUid, pktInfo);
1201 NS_LOG_WARN ("Unknown Uid, but adding Csma Packet anyway");
1202 }
1203 /// \todo NS_ASSERT (IsPacketPending (AnimUid) == true);
1204 AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1205 pktInfo.m_lbTx = Simulator::Now ().GetSeconds ();
1206 }
1207
1208 void
CsmaPhyRxEndTrace(std::string context,Ptr<const Packet> p)1209 AnimationInterface::CsmaPhyRxEndTrace (std::string context, Ptr<const Packet> p)
1210 {
1211 NS_LOG_FUNCTION (this);
1212 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1213 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1214 NS_ASSERT (ndev);
1215 UpdatePosition (ndev);
1216 uint64_t animUid = GetAnimUidFromPacket (p);
1217 if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1218 {
1219 NS_LOG_WARN ("CsmaPhyRxEndTrace: unknown Uid");
1220 return;
1221 }
1222 /// \todo NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1223 AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1224 pktInfo.ProcessRxBegin (ndev, Simulator::Now ().GetSeconds ());
1225 NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid);
1226 NS_LOG_INFO ("CsmaPhyRxEndTrace for packet:" << animUid << " complete");
1227 OutputCsmaPacket (p, pktInfo);
1228 }
1229
1230 void
CsmaMacRxTrace(std::string context,Ptr<const Packet> p)1231 AnimationInterface::CsmaMacRxTrace (std::string context,
1232 Ptr<const Packet> p)
1233 {
1234 NS_LOG_FUNCTION (this);
1235 CHECK_STARTED_INTIMEWINDOW_TRACKPACKETS;
1236 Ptr <NetDevice> ndev = GetNetDeviceFromContext (context);
1237 NS_ASSERT (ndev);
1238 uint64_t animUid = GetAnimUidFromPacket (p);
1239 if (!IsPacketPending (animUid, AnimationInterface::CSMA))
1240 {
1241 NS_LOG_WARN ("CsmaMacRxTrace: unknown Uid");
1242 return;
1243 }
1244 /// \todo NS_ASSERT (CsmaPacketIsPending (AnimUid) == true);
1245 AnimPacketInfo& pktInfo = m_pendingCsmaPackets[animUid];
1246 NS_LOG_INFO ("MacRxTrace for packet:" << animUid << " complete");
1247 OutputCsmaPacket (p, pktInfo);
1248 }
1249
1250 void
OutputWirelessPacketTxInfo(Ptr<const Packet> p,AnimPacketInfo & pktInfo,uint64_t animUid)1251 AnimationInterface::OutputWirelessPacketTxInfo (Ptr<const Packet> p, AnimPacketInfo &pktInfo, uint64_t animUid)
1252 {
1253 CheckMaxPktsPerTraceFile ();
1254 uint32_t nodeId = 0;
1255 if (pktInfo.m_txnd)
1256 {
1257 nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1258 }
1259 else
1260 {
1261 nodeId = pktInfo.m_txNodeId;
1262 }
1263 WriteXmlPRef (animUid, nodeId, pktInfo.m_fbTx, m_enablePacketMetadata ? GetPacketMetadata (p) : "");
1264 }
1265
1266 void
OutputWirelessPacketRxInfo(Ptr<const Packet> p,AnimPacketInfo & pktInfo,uint64_t animUid)1267 AnimationInterface::OutputWirelessPacketRxInfo (Ptr<const Packet> p, AnimPacketInfo & pktInfo, uint64_t animUid)
1268 {
1269 CheckMaxPktsPerTraceFile ();
1270 uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1271 WriteXmlP (animUid, "wpr", rxId, pktInfo.m_fbRx, pktInfo.m_lbRx);
1272 }
1273
1274 void
OutputCsmaPacket(Ptr<const Packet> p,AnimPacketInfo & pktInfo)1275 AnimationInterface::OutputCsmaPacket (Ptr<const Packet> p, AnimPacketInfo &pktInfo)
1276 {
1277 CheckMaxPktsPerTraceFile ();
1278 NS_ASSERT (pktInfo.m_txnd);
1279 uint32_t nodeId = pktInfo.m_txnd->GetNode ()->GetId ();
1280 uint32_t rxId = pktInfo.m_rxnd->GetNode ()->GetId ();
1281
1282 WriteXmlP ("p",
1283 nodeId,
1284 pktInfo.m_fbTx,
1285 pktInfo.m_lbTx,
1286 rxId,
1287 pktInfo.m_fbRx,
1288 pktInfo.m_lbRx,
1289 m_enablePacketMetadata ? GetPacketMetadata (p) : "");
1290 }
1291
1292 void
AddPendingPacket(ProtocolType protocolType,uint64_t animUid,AnimPacketInfo pktInfo)1293 AnimationInterface::AddPendingPacket (ProtocolType protocolType, uint64_t animUid, AnimPacketInfo pktInfo)
1294 {
1295 AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1296 NS_ASSERT (pendingPackets);
1297 pendingPackets->insert (AnimUidPacketInfoMap::value_type (animUid, pktInfo));
1298 }
1299
1300 bool
IsPacketPending(uint64_t animUid,AnimationInterface::ProtocolType protocolType)1301 AnimationInterface::IsPacketPending (uint64_t animUid, AnimationInterface::ProtocolType protocolType)
1302 {
1303 AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1304 NS_ASSERT (pendingPackets);
1305 return (pendingPackets->find (animUid) != pendingPackets->end ());
1306 }
1307
1308 void
PurgePendingPackets(AnimationInterface::ProtocolType protocolType)1309 AnimationInterface::PurgePendingPackets (AnimationInterface::ProtocolType protocolType)
1310 {
1311 AnimUidPacketInfoMap * pendingPackets = ProtocolTypeToPendingPackets (protocolType);
1312 NS_ASSERT (pendingPackets);
1313 if (pendingPackets->empty ())
1314 {
1315 return;
1316 }
1317 std::vector <uint64_t> purgeList;
1318 for (AnimUidPacketInfoMap::iterator i = pendingPackets->begin ();
1319 i != pendingPackets->end ();
1320 ++i)
1321 {
1322
1323 AnimPacketInfo pktInfo = i->second;
1324 double delta = (Simulator::Now ().GetSeconds () - pktInfo.m_fbTx);
1325 if (delta > PURGE_INTERVAL)
1326 {
1327 purgeList.push_back (i->first);
1328 }
1329 }
1330 for (std::vector <uint64_t>::iterator i = purgeList.begin ();
1331 i != purgeList.end ();
1332 ++i)
1333 {
1334 pendingPackets->erase (*i);
1335 }
1336 }
1337
1338 AnimationInterface::AnimUidPacketInfoMap *
ProtocolTypeToPendingPackets(AnimationInterface::ProtocolType protocolType)1339 AnimationInterface::ProtocolTypeToPendingPackets (AnimationInterface::ProtocolType protocolType)
1340 {
1341 AnimUidPacketInfoMap * pendingPackets = 0;
1342 switch (protocolType)
1343 {
1344 case AnimationInterface::WIFI:
1345 {
1346 pendingPackets = &m_pendingWifiPackets;
1347 break;
1348 }
1349 case AnimationInterface::UAN:
1350 {
1351 pendingPackets = &m_pendingUanPackets;
1352 break;
1353 }
1354 case AnimationInterface::CSMA:
1355 {
1356 pendingPackets = &m_pendingCsmaPackets;
1357 break;
1358 }
1359 case AnimationInterface::WIMAX:
1360 {
1361 pendingPackets = &m_pendingWimaxPackets;
1362 break;
1363 }
1364 case AnimationInterface::LTE:
1365 {
1366 pendingPackets = &m_pendingLtePackets;
1367 break;
1368 }
1369 case AnimationInterface::LRWPAN:
1370 {
1371 pendingPackets = &m_pendingLrWpanPackets;
1372 break;
1373 }
1374 case AnimationInterface::WAVE:
1375 {
1376 pendingPackets = &m_pendingWavePackets;
1377 break;
1378 }
1379 }
1380 return pendingPackets;
1381
1382 }
1383
1384 std::string
ProtocolTypeToString(AnimationInterface::ProtocolType protocolType)1385 AnimationInterface::ProtocolTypeToString (AnimationInterface::ProtocolType protocolType)
1386 {
1387 std::string result = "Unknown";
1388 switch (protocolType)
1389 {
1390 case AnimationInterface::WIFI:
1391 {
1392 result = "WIFI";
1393 break;
1394 }
1395 case AnimationInterface::UAN:
1396 {
1397 result = "UAN";
1398 break;
1399 }
1400 case AnimationInterface::CSMA:
1401 {
1402 result = "CSMA";
1403 break;
1404 }
1405 case AnimationInterface::WIMAX:
1406 {
1407 result = "WIMAX";
1408 break;
1409 }
1410 case AnimationInterface::LTE:
1411 {
1412 result = "LTE";
1413 break;
1414 }
1415 case AnimationInterface::LRWPAN:
1416 {
1417 result = "LRWPAN";
1418 break;
1419 }
1420 case AnimationInterface::WAVE:
1421 {
1422 result = "WAVE";
1423 break;
1424 }
1425 }
1426 return result;
1427 }
1428
1429 // Counters
1430
1431 std::string
CounterTypeToString(CounterType counterType)1432 AnimationInterface::CounterTypeToString (CounterType counterType)
1433 {
1434 std::string typeString = "unknown";
1435 switch (counterType)
1436 {
1437 case UINT32_COUNTER:
1438 {
1439 typeString = "UINT32";
1440 break;
1441 }
1442 case DOUBLE_COUNTER:
1443 {
1444 typeString = "DOUBLE";
1445 break;
1446 }
1447 }
1448 return typeString;
1449 }
1450
1451 // General
1452
1453 std::string
GetPacketMetadata(Ptr<const Packet> p)1454 AnimationInterface::GetPacketMetadata (Ptr<const Packet> p)
1455 {
1456 std::ostringstream oss;
1457 p->Print (oss);
1458 return oss.str ();
1459 }
1460
1461 uint64_t
GetTracePktCount()1462 AnimationInterface::GetTracePktCount ()
1463 {
1464 return m_currentPktCount;
1465 }
1466
1467 void
StopAnimation(bool onlyAnimation)1468 AnimationInterface::StopAnimation (bool onlyAnimation)
1469 {
1470 m_started = false;
1471 NS_LOG_INFO ("Stopping Animation");
1472 ResetAnimWriteCallback ();
1473 if (m_f)
1474 {
1475 // Terminate the anim element
1476 WriteXmlClose ("anim");
1477 std::fclose (m_f);
1478 m_f = 0;
1479 }
1480 if (onlyAnimation)
1481 {
1482 return;
1483 }
1484 if (m_routingF)
1485 {
1486 WriteXmlClose ("anim", true);
1487 std::fclose (m_routingF);
1488 m_routingF = 0;
1489 }
1490 }
1491
1492 void
StartAnimation(bool restart)1493 AnimationInterface::StartAnimation (bool restart)
1494 {
1495 m_currentPktCount = 0;
1496 m_started = true;
1497 SetOutputFile (m_outputFileName);
1498 WriteXmlAnim ();
1499 WriteNodes ();
1500 WriteNodeColors ();
1501 WriteLinkProperties ();
1502 WriteIpv4Addresses ();
1503 WriteIpv6Addresses ();
1504 WriteNodeSizes ();
1505 WriteNodeEnergies ();
1506 if (!restart)
1507 {
1508 Simulator::Schedule (m_mobilityPollInterval, &AnimationInterface::MobilityAutoCheck, this);
1509 ConnectCallbacks ();
1510 }
1511 }
1512
1513 void
AddToIpv4AddressNodeIdTable(std::string ipv4Address,uint32_t nodeId)1514 AnimationInterface::AddToIpv4AddressNodeIdTable (std::string ipv4Address, uint32_t nodeId)
1515 {
1516 m_ipv4ToNodeIdMap[ipv4Address] = nodeId;
1517 m_nodeIdIpv4Map.insert (NodeIdIpv4Pair (nodeId, ipv4Address));
1518 }
1519
1520 void
AddToIpv4AddressNodeIdTable(std::vector<std::string> ipv4Addresses,uint32_t nodeId)1521 AnimationInterface::AddToIpv4AddressNodeIdTable (std::vector<std::string> ipv4Addresses, uint32_t nodeId)
1522 {
1523 for (std::vector<std::string>::const_iterator i = ipv4Addresses.begin ();
1524 i != ipv4Addresses.end ();
1525 ++i)
1526 {
1527 AddToIpv4AddressNodeIdTable (*i, nodeId);
1528 }
1529 }
1530
1531 void
AddToIpv6AddressNodeIdTable(std::string ipv6Address,uint32_t nodeId)1532 AnimationInterface::AddToIpv6AddressNodeIdTable (std::string ipv6Address, uint32_t nodeId)
1533 {
1534 m_ipv6ToNodeIdMap[ipv6Address] = nodeId;
1535 m_nodeIdIpv6Map.insert (NodeIdIpv6Pair (nodeId, ipv6Address));
1536 }
1537
1538 void
AddToIpv6AddressNodeIdTable(std::vector<std::string> ipv6Addresses,uint32_t nodeId)1539 AnimationInterface::AddToIpv6AddressNodeIdTable (std::vector<std::string> ipv6Addresses, uint32_t nodeId)
1540 {
1541 for (std::vector<std::string>::const_iterator i = ipv6Addresses.begin ();
1542 i != ipv6Addresses.end ();
1543 ++i)
1544 {
1545 AddToIpv6AddressNodeIdTable (*i, nodeId);
1546 }
1547 }
1548
1549 // Callbacks
1550 void
ConnectLteEnb(Ptr<Node> n,Ptr<LteEnbNetDevice> nd,uint32_t devIndex)1551 AnimationInterface::ConnectLteEnb (Ptr <Node> n, Ptr <LteEnbNetDevice> nd, uint32_t devIndex)
1552 {
1553
1554 Ptr<LteEnbPhy> lteEnbPhy = nd->GetPhy ();
1555 Ptr<LteSpectrumPhy> dlPhy = lteEnbPhy->GetDownlinkSpectrumPhy ();
1556 Ptr<LteSpectrumPhy> ulPhy = lteEnbPhy->GetUplinkSpectrumPhy ();
1557 std::ostringstream oss;
1558 //NodeList/*/DeviceList/*/
1559 oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1560 if (dlPhy)
1561 {
1562 dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1563 dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1564 }
1565 if (ulPhy)
1566 {
1567 ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1568 ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1569 }
1570 }
1571
1572
1573
1574 void
ConnectLteUe(Ptr<Node> n,Ptr<LteUeNetDevice> nd,uint32_t devIndex)1575 AnimationInterface::ConnectLteUe (Ptr <Node> n, Ptr <LteUeNetDevice> nd, uint32_t devIndex)
1576 {
1577
1578 Ptr<LteUePhy> lteUePhy = nd->GetPhy ();
1579 Ptr<LteSpectrumPhy> dlPhy = lteUePhy->GetDownlinkSpectrumPhy ();
1580 Ptr<LteSpectrumPhy> ulPhy = lteUePhy->GetUplinkSpectrumPhy ();
1581 std::ostringstream oss;
1582 //NodeList/*/DeviceList/*/
1583 oss << "NodeList/" << n->GetId () << "/DeviceList/" << devIndex << "/";
1584 if (dlPhy)
1585 {
1586 dlPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1587 dlPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1588 }
1589 if (ulPhy)
1590 {
1591 ulPhy->TraceConnect ("TxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyTxStart, this));
1592 ulPhy->TraceConnect ("RxStart", oss.str (), MakeCallback (&AnimationInterface::LteSpectrumPhyRxStart, this));
1593 }
1594 }
1595
1596 void
ConnectLte()1597 AnimationInterface::ConnectLte ()
1598 {
1599
1600 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1601 {
1602 Ptr<Node> n = *i;
1603 NS_ASSERT (n);
1604 uint32_t nDevices = n->GetNDevices ();
1605 for (uint32_t devIndex = 0; devIndex < nDevices; ++devIndex)
1606 {
1607 Ptr <NetDevice> nd = n->GetDevice (devIndex);
1608 if (!nd)
1609 {
1610 continue;
1611 }
1612 Ptr<LteUeNetDevice> lteUeNetDevice = DynamicCast<LteUeNetDevice> (nd);
1613 if (lteUeNetDevice)
1614 {
1615 ConnectLteUe (n, lteUeNetDevice, devIndex);
1616 continue;
1617 }
1618 Ptr<LteEnbNetDevice> lteEnbNetDevice = DynamicCast<LteEnbNetDevice> (nd);
1619 if (lteEnbNetDevice)
1620 {
1621 ConnectLteEnb (n, lteEnbNetDevice, devIndex);
1622 }
1623 }
1624
1625 }
1626 }
1627
1628 void
ConnectCallbacks()1629 AnimationInterface::ConnectCallbacks ()
1630 {
1631 // Connect the callbacks
1632 Config::ConnectFailSafe ("/ChannelList/*/TxRxPointToPoint",
1633 MakeCallback (&AnimationInterface::DevTxTrace, this));
1634 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxPsduBegin",
1635 MakeCallback (&AnimationInterface::WifiPhyTxBeginTrace, this));
1636 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxBegin",
1637 MakeCallback (&AnimationInterface::WifiPhyRxBeginTrace, this));
1638 Config::ConnectWithoutContextFailSafe ("/NodeList/*/$ns3::MobilityModel/CourseChange",
1639 MakeCallback (&AnimationInterface::MobilityCourseChangeTrace, this));
1640 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Tx",
1641 MakeCallback (&AnimationInterface::WimaxTxTrace, this));
1642 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WimaxNetDevice/Rx",
1643 MakeCallback (&AnimationInterface::WimaxRxTrace, this));
1644 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Tx",
1645 MakeCallback (&AnimationInterface::LteTxTrace, this));
1646 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LteNetDevice/Rx",
1647 MakeCallback (&AnimationInterface::LteRxTrace, this));
1648 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxBegin",
1649 MakeCallback (&AnimationInterface::CsmaPhyTxBeginTrace, this));
1650 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyTxEnd",
1651 MakeCallback (&AnimationInterface::CsmaPhyTxEndTrace, this));
1652 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/PhyRxEnd",
1653 MakeCallback (&AnimationInterface::CsmaPhyRxEndTrace, this));
1654 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacRx",
1655 MakeCallback (&AnimationInterface::CsmaMacRxTrace, this));
1656 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyTxBegin",
1657 MakeCallback (&AnimationInterface::UanPhyGenTxTrace, this));
1658 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::UanNetDevice/Phy/PhyRxBegin",
1659 MakeCallback (&AnimationInterface::UanPhyGenRxTrace, this));
1660 Config::ConnectFailSafe ("/NodeList/*/$ns3::BasicEnergySource/RemainingEnergy",
1661 MakeCallback (&AnimationInterface::RemainingEnergyTrace, this));
1662
1663 ConnectLte ();
1664
1665 Config::ConnectFailSafe ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
1666 MakeCallback (&AnimationInterface::Ipv4TxTrace, this));
1667 Config::ConnectFailSafe ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
1668 MakeCallback (&AnimationInterface::Ipv4RxTrace, this));
1669 Config::ConnectFailSafe ("/NodeList/*/$ns3::Ipv4L3Protocol/Drop",
1670 MakeCallback (&AnimationInterface::Ipv4DropTrace, this));
1671
1672 // Queue Enqueues
1673
1674 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Enqueue",
1675 MakeCallback (&AnimationInterface::EnqueueTrace, this));
1676 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Enqueue",
1677 MakeCallback (&AnimationInterface::EnqueueTrace, this));
1678 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Enqueue",
1679 MakeCallback (&AnimationInterface::EnqueueTrace, this));
1680
1681 // Queue Dequeues
1682
1683 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Dequeue",
1684 MakeCallback (&AnimationInterface::DequeueTrace, this));
1685 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Dequeue",
1686 MakeCallback (&AnimationInterface::DequeueTrace, this));
1687 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Dequeue",
1688 MakeCallback (&AnimationInterface::DequeueTrace, this));
1689
1690 // Queue Drops
1691
1692 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::AlohaNoackNetDevice/Queue/Drop",
1693 MakeCallback (&AnimationInterface::QueueDropTrace, this));
1694 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/TxQueue/Drop",
1695 MakeCallback (&AnimationInterface::QueueDropTrace, this));
1696 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::PointToPointNetDevice/TxQueue/Drop",
1697 MakeCallback (&AnimationInterface::QueueDropTrace, this));
1698
1699
1700 // Wifi Mac
1701 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTx",
1702 MakeCallback (&AnimationInterface::WifiMacTxTrace, this));
1703 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacTxDrop",
1704 MakeCallback (&AnimationInterface::WifiMacTxDropTrace, this));
1705 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRx",
1706 MakeCallback (&AnimationInterface::WifiMacRxTrace, this));
1707 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Mac/MacRxDrop",
1708 MakeCallback (&AnimationInterface::WifiMacRxDropTrace, this));
1709
1710 // Wifi Phy
1711 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyTxDrop",
1712 MakeCallback (&AnimationInterface::WifiPhyTxDropTrace, this));
1713 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxDrop",
1714 MakeCallback (&AnimationInterface::WifiPhyRxDropTrace, this));
1715
1716 // LrWpan
1717 Config::ConnectFailSafe ("NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Phy/PhyTxBegin",
1718 MakeCallback (&AnimationInterface::LrWpanPhyTxBeginTrace, this));
1719 Config::ConnectFailSafe ("NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Phy/PhyRxBegin",
1720 MakeCallback (&AnimationInterface::LrWpanPhyRxBeginTrace, this));
1721 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacTx",
1722 MakeCallback (&AnimationInterface::LrWpanMacTxTrace, this));
1723 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacTxDrop",
1724 MakeCallback (&AnimationInterface::LrWpanMacTxDropTrace, this));
1725 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacRx",
1726 MakeCallback (&AnimationInterface::LrWpanMacRxTrace, this));
1727 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::LrWpanNetDevice/Mac/MacRxDrop",
1728 MakeCallback (&AnimationInterface::LrWpanMacRxDropTrace, this));
1729
1730 // Wave
1731 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/PhyTxBegin",
1732 MakeCallback (&AnimationInterface::WavePhyTxBeginTrace, this));
1733 Config::ConnectFailSafe ("/NodeList/*/DeviceList/*/$ns3::WaveNetDevice/PhyEntities/*/$ns3::WifiPhy/PhyRxBegin",
1734 MakeCallback (&AnimationInterface::WavePhyRxBeginTrace, this));
1735 }
1736
1737 Vector
UpdatePosition(Ptr<Node> n)1738 AnimationInterface::UpdatePosition (Ptr <Node> n)
1739 {
1740 Ptr<MobilityModel> loc = n->GetObject<MobilityModel> ();
1741 if (loc)
1742 {
1743 m_nodeLocation[n->GetId ()] = loc->GetPosition ();
1744 }
1745 else
1746 {
1747 NS_LOG_UNCOND ( "AnimationInterface WARNING:Node:" << n->GetId () << " Does not have a mobility model. Use SetConstantPosition if it is stationary");
1748 Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();
1749 x->SetAttribute ("Min", DoubleValue (0));
1750 x->SetAttribute ("Max", DoubleValue (100));
1751 Ptr<UniformRandomVariable> y = CreateObject<UniformRandomVariable> ();
1752 y->SetAttribute ("Min", DoubleValue (0));
1753 y->SetAttribute ("Max", DoubleValue (100));
1754 m_nodeLocation[n->GetId ()] = Vector (int (x->GetValue ()), int (y->GetValue ()), 0);
1755 }
1756 return m_nodeLocation[n->GetId ()];
1757 }
1758
1759 Vector
UpdatePosition(Ptr<Node> n,Vector v)1760 AnimationInterface::UpdatePosition (Ptr <Node> n, Vector v)
1761 {
1762 m_nodeLocation[n->GetId ()] = v;
1763 return v;
1764 }
1765
1766 Vector
UpdatePosition(Ptr<NetDevice> ndev)1767 AnimationInterface::UpdatePosition (Ptr <NetDevice> ndev)
1768 {
1769 Ptr <Node> n = ndev->GetNode ();
1770 NS_ASSERT (n);
1771 return UpdatePosition (n);
1772 }
1773
1774 Vector
GetPosition(Ptr<Node> n)1775 AnimationInterface::GetPosition (Ptr <Node> n)
1776 {
1777 if (m_nodeLocation.find (n->GetId ()) == m_nodeLocation.end ())
1778 {
1779 NS_FATAL_ERROR ("Node:" << n->GetId () << " not found in Location table");
1780 }
1781 return m_nodeLocation[n->GetId ()];
1782 }
1783
1784
1785 std::string
GetMacAddress(Ptr<NetDevice> nd)1786 AnimationInterface::GetMacAddress (Ptr <NetDevice> nd)
1787 {
1788 Address nodeAddr = nd->GetAddress ();
1789 std::ostringstream oss;
1790 oss << nodeAddr;
1791 return oss.str ().substr (6); // Skip the first 6 chars to get the Mac
1792 }
1793
1794 std::string
GetIpv4Address(Ptr<NetDevice> nd)1795 AnimationInterface::GetIpv4Address (Ptr <NetDevice> nd)
1796 {
1797 Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
1798 if (!ipv4)
1799 {
1800 NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1801 return "0.0.0.0";
1802 }
1803 int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
1804 if (ifIndex == -1)
1805 {
1806 NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1807 return "0.0.0.0";
1808 }
1809 Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, 0);
1810 std::ostringstream oss;
1811 oss << addr.GetLocal ();
1812 return oss.str ();
1813 }
1814
1815 std::string
GetIpv6Address(Ptr<NetDevice> nd)1816 AnimationInterface::GetIpv6Address (Ptr <NetDevice> nd)
1817 {
1818 Ptr<Ipv6> ipv6 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv6> ();
1819 if (!ipv6)
1820 {
1821 NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1822 return "::";
1823 }
1824 int32_t ifIndex = ipv6->GetInterfaceForDevice (nd);
1825 if (ifIndex == -1)
1826 {
1827 NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1828 return "::";
1829 }
1830 bool nonLinkLocalFound = false;
1831 uint32_t nAddresses = ipv6->GetNAddresses (ifIndex);
1832 Ipv6InterfaceAddress addr;
1833 for (uint32_t addressIndex = 0; addressIndex < nAddresses; ++addressIndex)
1834 {
1835 addr = ipv6->GetAddress (ifIndex, addressIndex);
1836 if (!addr.GetAddress ().IsLinkLocal ())
1837 {
1838 nonLinkLocalFound = true;
1839 break;
1840 }
1841 }
1842 if (!nonLinkLocalFound)
1843 {
1844 addr = ipv6->GetAddress (ifIndex, 0);
1845 }
1846 std::ostringstream oss;
1847 oss << addr.GetAddress ();
1848 return oss.str ();
1849 }
1850
1851
1852
1853 std::vector<std::string>
GetIpv4Addresses(Ptr<NetDevice> nd)1854 AnimationInterface::GetIpv4Addresses (Ptr <NetDevice> nd)
1855 {
1856 std::vector<std::string> ipv4Addresses;
1857 Ptr<Ipv4> ipv4 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv4> ();
1858 if (!ipv4)
1859 {
1860 NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv4 object found");
1861 return ipv4Addresses;
1862 }
1863 int32_t ifIndex = ipv4->GetInterfaceForDevice (nd);
1864 if (ifIndex == -1)
1865 {
1866 NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1867 return ipv4Addresses;
1868 }
1869 for (uint32_t index = 0; index < ipv4->GetNAddresses (ifIndex); ++index)
1870 {
1871 Ipv4InterfaceAddress addr = ipv4->GetAddress (ifIndex, index);
1872 std::ostringstream oss;
1873 oss << addr.GetLocal ();
1874 ipv4Addresses.push_back (oss.str ());
1875 }
1876 return ipv4Addresses;
1877 }
1878
1879 std::vector<std::string>
GetIpv6Addresses(Ptr<NetDevice> nd)1880 AnimationInterface::GetIpv6Addresses (Ptr <NetDevice> nd)
1881 {
1882 std::vector<std::string> ipv6Addresses;
1883 Ptr<Ipv6> ipv6 = NodeList::GetNode (nd->GetNode ()->GetId ())->GetObject <Ipv6> ();
1884 if (!ipv6)
1885 {
1886 NS_LOG_WARN ("Node: " << nd->GetNode ()->GetId () << " No ipv6 object found");
1887 return ipv6Addresses;
1888 }
1889 int32_t ifIndex = ipv6->GetInterfaceForDevice (nd);
1890 if (ifIndex == -1)
1891 {
1892 NS_LOG_WARN ("Node :" << nd->GetNode ()->GetId () << " Could not find index of NetDevice");
1893 return ipv6Addresses;
1894 }
1895 for (uint32_t index = 0; index < ipv6->GetNAddresses (ifIndex); ++index)
1896 {
1897 Ipv6InterfaceAddress addr = ipv6->GetAddress (ifIndex, index);
1898 std::ostringstream oss;
1899 oss << addr.GetAddress ();
1900 ipv6Addresses.push_back (oss.str ());
1901 }
1902 return ipv6Addresses;
1903 }
1904
1905
1906 void
WriteIpv4Addresses()1907 AnimationInterface::WriteIpv4Addresses ()
1908 {
1909 for (NodeIdIpv4Map::const_iterator i = m_nodeIdIpv4Map.begin ();
1910 i != m_nodeIdIpv4Map.end ();
1911 ++i)
1912 {
1913 std::vector <std::string> ipv4Addresses;
1914 std::pair<NodeIdIpv4Map::const_iterator, NodeIdIpv4Map::const_iterator> iterPair = m_nodeIdIpv4Map.equal_range (i->first);
1915 for (NodeIdIpv4Map::const_iterator it = iterPair.first;
1916 it != iterPair.second;
1917 ++it)
1918 {
1919 ipv4Addresses.push_back (it->second);
1920 }
1921 WriteXmlIpv4Addresses (i->first, ipv4Addresses);
1922 }
1923 }
1924
1925 void
WriteIpv6Addresses()1926 AnimationInterface::WriteIpv6Addresses ()
1927 {
1928 for (NodeIdIpv6Map::const_iterator i = m_nodeIdIpv6Map.begin ();
1929 i != m_nodeIdIpv6Map.end ();
1930 i = m_nodeIdIpv6Map.upper_bound (i->first))
1931 {
1932 std::vector <std::string> ipv6Addresses;
1933 std::pair<NodeIdIpv6Map::const_iterator, NodeIdIpv6Map::const_iterator> iterPair = m_nodeIdIpv6Map.equal_range (i->first);
1934 for (NodeIdIpv6Map::const_iterator it = iterPair.first;
1935 it != iterPair.second;
1936 ++it)
1937 {
1938 ipv6Addresses.push_back (it->second);
1939 }
1940 WriteXmlIpv6Addresses (i->first, ipv6Addresses);
1941 }
1942 }
1943
1944 void
WriteLinkProperties()1945 AnimationInterface::WriteLinkProperties ()
1946 {
1947 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
1948 {
1949 Ptr<Node> n = *i;
1950 UpdatePosition (n);
1951 uint32_t n1Id = n->GetId ();
1952 uint32_t nDev = n->GetNDevices (); // Number of devices
1953 for (uint32_t i = 0; i < nDev; ++i)
1954 {
1955 Ptr<NetDevice> dev = n->GetDevice (i);
1956 NS_ASSERT (dev);
1957 Ptr<Channel> ch = dev->GetChannel ();
1958 std::string channelType = "Unknown channel";
1959 if (ch)
1960 {
1961 channelType = ch->GetInstanceTypeId ().GetName ();
1962 }
1963 NS_LOG_DEBUG ("Got ChannelType" << channelType);
1964
1965 if (!ch || (channelType != std::string ("ns3::PointToPointChannel")))
1966 {
1967 NS_LOG_DEBUG ("No channel can't be a p2p device");
1968 /*
1969 // Try to see if it is an LTE NetDevice, which does not return a channel
1970 if ((dev->GetInstanceTypeId ().GetName () == "ns3::LteUeNetDevice") ||
1971 (dev->GetInstanceTypeId ().GetName () == "ns3::LteEnbNetDevice")||
1972 (dev->GetInstanceTypeId ().GetName () == "ns3::VirtualNetDevice"))
1973 {
1974 WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
1975 AddToIpv4AddressNodeIdTable (GetIpv4Address (dev), n->GetId ());
1976 }
1977 */
1978 std::vector<std::string> ipv4Addresses = GetIpv4Addresses (dev);
1979 AddToIpv4AddressNodeIdTable (ipv4Addresses, n->GetId ());
1980 std::vector<std::string> ipv6Addresses = GetIpv6Addresses (dev);
1981 AddToIpv6AddressNodeIdTable (ipv6Addresses, n->GetId ());
1982 if (!ipv4Addresses.empty ())
1983 {
1984 NS_LOG_INFO ("Writing Ipv4 link");
1985 WriteNonP2pLinkProperties (n->GetId (), GetIpv4Address (dev) + "~" + GetMacAddress (dev), channelType);
1986 }
1987 else if (!ipv6Addresses.empty ())
1988 {
1989 NS_LOG_INFO ("Writing Ipv6 link");
1990 WriteNonP2pLinkProperties (n->GetId (), GetIpv6Address (dev) + "~" + GetMacAddress (dev), channelType);
1991 }
1992 continue;
1993 }
1994
1995 else if (channelType == std::string ("ns3::PointToPointChannel"))
1996 { // Since these are duplex links, we only need to dump
1997 // if srcid < dstid
1998 std::size_t nChDev = ch->GetNDevices ();
1999 for (std::size_t j = 0; j < nChDev; ++j)
2000 {
2001 Ptr<NetDevice> chDev = ch->GetDevice (j);
2002 uint32_t n2Id = chDev->GetNode ()->GetId ();
2003 if (n1Id < n2Id)
2004 {
2005
2006 std::vector<std::string> ipv4Addresses = GetIpv4Addresses (dev);
2007 AddToIpv4AddressNodeIdTable (ipv4Addresses, n1Id);
2008 ipv4Addresses = GetIpv4Addresses (chDev);
2009 AddToIpv4AddressNodeIdTable (ipv4Addresses, n2Id);
2010 std::vector<std::string> ipv6Addresses = GetIpv6Addresses (dev);
2011 AddToIpv6AddressNodeIdTable (ipv6Addresses, n1Id);
2012 ipv6Addresses = GetIpv6Addresses (chDev);
2013 AddToIpv6AddressNodeIdTable (ipv6Addresses, n2Id);
2014
2015 P2pLinkNodeIdPair p2pPair;
2016 p2pPair.fromNode = n1Id;
2017 p2pPair.toNode = n2Id;
2018 if (!ipv4Addresses.empty ())
2019 {
2020 LinkProperties lp = { GetIpv4Address (dev) + "~" + GetMacAddress (dev), GetIpv4Address (chDev) + "~" + GetMacAddress (chDev), "" };
2021 m_linkProperties[p2pPair] = lp;
2022 }
2023 else if (!ipv6Addresses.empty ())
2024 {
2025 LinkProperties lp = { GetIpv6Address (dev) + "~" + GetMacAddress (dev), GetIpv6Address (chDev) + "~" + GetMacAddress (chDev), "" };
2026 m_linkProperties[p2pPair] = lp;
2027 }
2028 WriteXmlLink (n1Id, 0, n2Id);
2029 }
2030 }
2031 }
2032 }
2033 }
2034 m_linkProperties.clear ();
2035 }
2036
2037 void
WriteNodes()2038 AnimationInterface::WriteNodes ()
2039 {
2040 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2041 {
2042 Ptr<Node> n = *i;
2043 NS_LOG_INFO ("Update Position for Node: " << n->GetId ());
2044 Vector v = UpdatePosition (n);
2045 WriteXmlNode (n->GetId (), n->GetSystemId (), v.x, v.y);
2046 }
2047 }
2048
2049 void
WriteNodeColors()2050 AnimationInterface::WriteNodeColors ()
2051 {
2052 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2053 {
2054 Ptr<Node> n = *i;
2055 Rgb rgb = {255, 0, 0};
2056 if (m_nodeColors.find (n->GetId ()) == m_nodeColors.end ())
2057 {
2058 m_nodeColors[n->GetId ()] = rgb;
2059 }
2060 UpdateNodeColor (n, rgb.r, rgb.g, rgb.b);
2061 }
2062 }
2063
2064 void
WriteNodeSizes()2065 AnimationInterface::WriteNodeSizes ()
2066 {
2067 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2068 {
2069 Ptr<Node> n = *i;
2070 NS_LOG_INFO ("Update Size for Node: " << n->GetId ());
2071 AnimationInterface::NodeSize s = { 1, 1 };
2072 m_nodeSizes[n->GetId ()] = s;
2073 UpdateNodeSize (n->GetId (), s.width, s.height);
2074 }
2075 }
2076
2077 void
WriteNodeEnergies()2078 AnimationInterface::WriteNodeEnergies ()
2079 {
2080 m_remainingEnergyCounterId = AddNodeCounter ("RemainingEnergy", AnimationInterface::DOUBLE_COUNTER);
2081 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2082 {
2083 Ptr<Node> n = *i;
2084 if (NodeList::GetNode (n->GetId ())->GetObject<EnergySource> ())
2085 {
2086 UpdateNodeCounter (m_remainingEnergyCounterId, n->GetId (), 1);
2087 }
2088 }
2089 }
2090
2091 bool
IsInTimeWindow()2092 AnimationInterface::IsInTimeWindow ()
2093 {
2094 if ((Simulator::Now () >= m_startTime)
2095 && (Simulator::Now () <= m_stopTime))
2096 {
2097 return true;
2098 }
2099 else
2100 {
2101 return false;
2102 }
2103 }
2104
2105 void
SetOutputFile(const std::string & fn,bool routing)2106 AnimationInterface::SetOutputFile (const std::string& fn, bool routing)
2107 {
2108 if (!routing && m_f)
2109 {
2110 return;
2111 }
2112 if (routing && m_routingF)
2113 {
2114 NS_FATAL_ERROR ("SetRoutingOutputFile already used once");
2115 return;
2116 }
2117
2118 NS_LOG_INFO ("Creating new trace file:" << fn.c_str ());
2119 FILE * f = 0;
2120 f = std::fopen (fn.c_str (), "w");
2121 if (!f)
2122 {
2123 NS_FATAL_ERROR ("Unable to open output file:" << fn.c_str ());
2124 return; // Can't open output file
2125 }
2126 if (routing)
2127 {
2128 m_routingF = f;
2129 m_routingFileName = fn;
2130 }
2131 else
2132 {
2133 m_f = f;
2134 m_outputFileName = fn;
2135 }
2136 return;
2137 }
2138
2139 void
CheckMaxPktsPerTraceFile()2140 AnimationInterface::CheckMaxPktsPerTraceFile ()
2141 {
2142 // Start a new trace file if the current packet count exceeded nax packets per file
2143 ++m_currentPktCount;
2144 if (m_currentPktCount <= m_maxPktsPerFile)
2145 {
2146 return;
2147 }
2148 NS_LOG_UNCOND ("Max Packets per trace file exceeded");
2149 StopAnimation (true);
2150 }
2151
2152 std::string
GetNetAnimVersion()2153 AnimationInterface::GetNetAnimVersion ()
2154 {
2155 return NETANIM_VERSION;
2156 }
2157
2158
2159 void
TrackQueueCounters()2160 AnimationInterface::TrackQueueCounters ()
2161 {
2162 if (Simulator::Now () > m_queueCountersStopTime)
2163 {
2164 NS_LOG_INFO ("TrackQueueCounters Completed");
2165 return;
2166 }
2167 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2168 {
2169 uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2170 UpdateNodeCounter (m_queueEnqueueCounterId, nodeId, m_nodeQueueEnqueue[nodeId]);
2171 UpdateNodeCounter (m_queueDequeueCounterId, nodeId, m_nodeQueueDequeue[nodeId]);
2172 UpdateNodeCounter (m_queueDropCounterId, nodeId, m_nodeQueueDrop[nodeId]);
2173 }
2174 Simulator::Schedule (m_queueCountersPollInterval, &AnimationInterface::TrackQueueCounters, this);
2175 }
2176
2177 void
TrackWifiMacCounters()2178 AnimationInterface::TrackWifiMacCounters ()
2179 {
2180 if (Simulator::Now () > m_wifiMacCountersStopTime)
2181 {
2182 NS_LOG_INFO ("TrackWifiMacCounters Completed");
2183 return;
2184 }
2185 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2186 {
2187 uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2188 UpdateNodeCounter (m_wifiMacTxCounterId, nodeId, m_nodeWifiMacTx[nodeId]);
2189 UpdateNodeCounter (m_wifiMacTxDropCounterId, nodeId, m_nodeWifiMacTxDrop[nodeId]);
2190 UpdateNodeCounter (m_wifiMacRxCounterId, nodeId, m_nodeWifiMacRx[nodeId]);
2191 UpdateNodeCounter (m_wifiMacRxDropCounterId, nodeId, m_nodeWifiMacRxDrop[nodeId]);
2192 }
2193 Simulator::Schedule (m_wifiMacCountersPollInterval, &AnimationInterface::TrackWifiMacCounters, this);
2194 }
2195
2196 void
TrackWifiPhyCounters()2197 AnimationInterface::TrackWifiPhyCounters ()
2198 {
2199 if (Simulator::Now () > m_wifiPhyCountersStopTime)
2200 {
2201 NS_LOG_INFO ("TrackWifiPhyCounters Completed");
2202 return;
2203 }
2204 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2205 {
2206 uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2207 UpdateNodeCounter (m_wifiPhyTxDropCounterId, nodeId, m_nodeWifiPhyTxDrop[nodeId]);
2208 UpdateNodeCounter (m_wifiPhyRxDropCounterId, nodeId, m_nodeWifiPhyRxDrop[nodeId]);
2209 }
2210 Simulator::Schedule (m_wifiPhyCountersPollInterval, &AnimationInterface::TrackWifiPhyCounters, this);
2211 }
2212
2213 void
TrackIpv4L3ProtocolCounters()2214 AnimationInterface::TrackIpv4L3ProtocolCounters ()
2215 {
2216 if (Simulator::Now () > m_ipv4L3ProtocolCountersStopTime)
2217 {
2218 NS_LOG_INFO ("TrackIpv4L3ProtocolCounters Completed");
2219 return;
2220 }
2221 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2222 {
2223 uint32_t nodeId = Ptr <Node> (*i)->GetId ();
2224 UpdateNodeCounter (m_ipv4L3ProtocolTxCounterId, nodeId, m_nodeIpv4Tx[nodeId]);
2225 UpdateNodeCounter (m_ipv4L3ProtocolRxCounterId, nodeId, m_nodeIpv4Rx[nodeId]);
2226 UpdateNodeCounter (m_ipv4L3ProtocolDropCounterId, nodeId, m_nodeIpv4Drop[nodeId]);
2227 }
2228 Simulator::Schedule (m_ipv4L3ProtocolCountersPollInterval, &AnimationInterface::TrackIpv4L3ProtocolCounters, this);
2229 }
2230
2231
2232
2233
2234
2235 /***** Routing-related *****/
2236
2237 void
TrackIpv4RoutePaths()2238 AnimationInterface::TrackIpv4RoutePaths ()
2239 {
2240 if (m_ipv4RouteTrackElements.empty ())
2241 {
2242 return;
2243 }
2244 for (std::vector <Ipv4RouteTrackElement>::const_iterator i = m_ipv4RouteTrackElements.begin ();
2245 i != m_ipv4RouteTrackElements.end ();
2246 ++i)
2247 {
2248 Ipv4RouteTrackElement trackElement = *i;
2249 Ptr <Node> fromNode = NodeList::GetNode (trackElement.fromNodeId);
2250 if (!fromNode)
2251 {
2252 NS_FATAL_ERROR ("Node: " << trackElement.fromNodeId << " Not found");
2253 continue;
2254 }
2255 Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
2256 if (!ipv4)
2257 {
2258 NS_LOG_WARN ("ipv4 object not found");
2259 continue;
2260 }
2261 Ptr <Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
2262 if (!rp)
2263 {
2264 NS_LOG_WARN ("Routing protocol object not found");
2265 continue;
2266 }
2267 NS_LOG_INFO ("Begin Track Route for: " << trackElement.destination.c_str () << " From:" << trackElement.fromNodeId);
2268 Ptr<Packet> pkt = Create<Packet> ();
2269 Ipv4Header header;
2270 header.SetDestination (Ipv4Address (trackElement.destination.c_str ()));
2271 Socket::SocketErrno sockerr;
2272 Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
2273 Ipv4RoutePathElements rpElements;
2274 if (!rt)
2275 {
2276 NS_LOG_INFO ("No route to :" << trackElement.destination.c_str ());
2277 Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
2278 rpElements.push_back (elem);
2279 WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
2280 continue;
2281 }
2282 std::ostringstream oss;
2283 oss << rt->GetGateway ();
2284 NS_LOG_INFO ("Node:" << trackElement.fromNodeId << "-->" << rt->GetGateway ());
2285 if (rt->GetGateway () == "0.0.0.0")
2286 {
2287 Ipv4RoutePathElement elem = { trackElement.fromNodeId, "C" };
2288 rpElements.push_back (elem);
2289 if ( m_ipv4ToNodeIdMap.find (trackElement.destination) != m_ipv4ToNodeIdMap.end ())
2290 {
2291 Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[trackElement.destination], "L" };
2292 rpElements.push_back (elem2);
2293 }
2294 }
2295 else if (rt->GetGateway () == "127.0.0.1")
2296 {
2297 Ipv4RoutePathElement elem = { trackElement.fromNodeId, "-1" };
2298 rpElements.push_back (elem);
2299 }
2300 else
2301 {
2302 Ipv4RoutePathElement elem = { trackElement.fromNodeId, oss.str () };
2303 rpElements.push_back (elem);
2304 }
2305 RecursiveIpv4RoutePathSearch (oss.str (), trackElement.destination, rpElements);
2306 WriteRoutePath (trackElement.fromNodeId, trackElement.destination, rpElements);
2307 }
2308
2309 }
2310
2311 void
TrackIpv4Route()2312 AnimationInterface::TrackIpv4Route ()
2313 {
2314 if (Simulator::Now () > m_routingStopTime)
2315 {
2316 NS_LOG_INFO ("TrackIpv4Route completed");
2317 return;
2318 }
2319 if (m_routingNc.GetN ())
2320 {
2321 for (NodeContainer::Iterator i = m_routingNc.Begin (); i != m_routingNc.End (); ++i)
2322 {
2323 Ptr <Node> n = *i;
2324 WriteXmlRouting (n->GetId (), GetIpv4RoutingTable (n));
2325 }
2326 }
2327 else
2328 {
2329 for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
2330 {
2331 Ptr <Node> n = *i;
2332 WriteXmlRouting (n->GetId (), GetIpv4RoutingTable (n));
2333 }
2334 }
2335 TrackIpv4RoutePaths ();
2336 Simulator::Schedule (m_routingPollInterval, &AnimationInterface::TrackIpv4Route, this);
2337 }
2338
2339 std::string
GetIpv4RoutingTable(Ptr<Node> n)2340 AnimationInterface::GetIpv4RoutingTable (Ptr <Node> n)
2341 {
2342
2343 NS_ASSERT (n);
2344 Ptr <ns3::Ipv4> ipv4 = n->GetObject <ns3::Ipv4> ();
2345 if (!ipv4)
2346 {
2347 NS_LOG_WARN ("Node " << n->GetId () << " Does not have an Ipv4 object");
2348 return "";
2349 }
2350 std::stringstream stream;
2351 Ptr<OutputStreamWrapper> routingstream = Create<OutputStreamWrapper> (&stream);
2352 ipv4->GetRoutingProtocol ()->PrintRoutingTable (routingstream);
2353 return stream.str ();
2354
2355 }
2356
2357 void
RecursiveIpv4RoutePathSearch(std::string from,std::string to,Ipv4RoutePathElements & rpElements)2358 AnimationInterface::RecursiveIpv4RoutePathSearch (std::string from, std::string to, Ipv4RoutePathElements & rpElements)
2359 {
2360 NS_LOG_INFO ("RecursiveIpv4RoutePathSearch from:" << from.c_str () << " to:" << to.c_str ());
2361 if ((from == "0.0.0.0") || (from == "127.0.0.1"))
2362 {
2363 NS_LOG_INFO ("Got " << from.c_str () << " End recursion");
2364 return;
2365 }
2366 Ptr <Node> fromNode = NodeList::GetNode (m_ipv4ToNodeIdMap[from]);
2367 Ptr <Node> toNode = NodeList::GetNode (m_ipv4ToNodeIdMap[to]);
2368 if (fromNode->GetId () == toNode->GetId ())
2369 {
2370 Ipv4RoutePathElement elem = { fromNode->GetId (), "L" };
2371 rpElements.push_back (elem);
2372 return;
2373 }
2374 if (!fromNode)
2375 {
2376 NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[from] << " Not found");
2377 return;
2378 }
2379 if (!toNode)
2380 {
2381 NS_FATAL_ERROR ("Node: " << m_ipv4ToNodeIdMap[to] << " Not found");
2382 return;
2383 }
2384 Ptr <ns3::Ipv4> ipv4 = fromNode->GetObject <ns3::Ipv4> ();
2385 if (!ipv4)
2386 {
2387 NS_LOG_WARN ("ipv4 object not found");
2388 return;
2389 }
2390 Ptr <Ipv4RoutingProtocol> rp = ipv4->GetRoutingProtocol ();
2391 if (!rp)
2392 {
2393 NS_LOG_WARN ("Routing protocol object not found");
2394 return;
2395 }
2396 Ptr<Packet> pkt = Create<Packet> ();
2397 Ipv4Header header;
2398 header.SetDestination (Ipv4Address (to.c_str ()));
2399 Socket::SocketErrno sockerr;
2400 Ptr <Ipv4Route> rt = rp->RouteOutput (pkt, header, 0, sockerr);
2401 if (!rt)
2402 {
2403 return;
2404 }
2405 NS_LOG_DEBUG ("Node: " << fromNode->GetId () << " G:" << rt->GetGateway ());
2406 std::ostringstream oss;
2407 oss << rt->GetGateway ();
2408 if (oss.str () == "0.0.0.0" && (sockerr != Socket::ERROR_NOROUTETOHOST))
2409 {
2410 NS_LOG_INFO ("Null gw");
2411 Ipv4RoutePathElement elem = { fromNode->GetId (), "C" };
2412 rpElements.push_back (elem);
2413 if ( m_ipv4ToNodeIdMap.find (to) != m_ipv4ToNodeIdMap.end ())
2414 {
2415 Ipv4RoutePathElement elem2 = { m_ipv4ToNodeIdMap[to], "L" };
2416 rpElements.push_back (elem2);
2417 }
2418 return;
2419 }
2420 NS_LOG_INFO ("Node:" << fromNode->GetId () << "-->" << rt->GetGateway ());
2421 Ipv4RoutePathElement elem = { fromNode->GetId (), oss.str () };
2422 rpElements.push_back (elem);
2423 RecursiveIpv4RoutePathSearch (oss.str (), to, rpElements);
2424
2425 }
2426
2427
2428
2429 /***** WriteXml *****/
2430
2431 void
WriteXmlAnim(bool routing)2432 AnimationInterface::WriteXmlAnim (bool routing)
2433 {
2434 AnimXmlElement element ("anim");
2435 element.AddAttribute ("ver", GetNetAnimVersion ());
2436 FILE * f = m_f;
2437 if (!routing)
2438 {
2439 element.AddAttribute ("filetype", "animation");
2440 }
2441 else
2442 {
2443 element.AddAttribute ("filetype", "routing");
2444 f = m_routingF;
2445 }
2446 WriteN (element.ToString (false) + ">\n", f);
2447 }
2448
2449 void
WriteXmlClose(std::string name,bool routing)2450 AnimationInterface::WriteXmlClose (std::string name, bool routing)
2451 {
2452 std::string closeString = "</" + name + ">\n";
2453 if (!routing)
2454 {
2455 WriteN (closeString, m_f);
2456 }
2457 else
2458 {
2459 WriteN (closeString, m_routingF);
2460 }
2461 }
2462
2463 void
WriteXmlNode(uint32_t id,uint32_t sysId,double locX,double locY)2464 AnimationInterface::WriteXmlNode (uint32_t id, uint32_t sysId, double locX, double locY)
2465 {
2466 AnimXmlElement element ("node");
2467 element.AddAttribute ("id", id);
2468 element.AddAttribute ("sysId", sysId);
2469 element.AddAttribute ("locX", locX);
2470 element.AddAttribute ("locY", locY);
2471 WriteN (element.ToString (), m_f);
2472 }
2473
2474 void
WriteXmlUpdateLink(uint32_t fromId,uint32_t toId,std::string linkDescription)2475 AnimationInterface::WriteXmlUpdateLink (uint32_t fromId, uint32_t toId, std::string linkDescription)
2476 {
2477 AnimXmlElement element ("linkupdate");
2478 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2479 element.AddAttribute ("fromId", fromId);
2480 element.AddAttribute ("toId", toId);
2481 element.AddAttribute ("ld", linkDescription, true);
2482 WriteN (element.ToString (), m_f);
2483 }
2484
2485 void
WriteXmlLink(uint32_t fromId,uint32_t toLp,uint32_t toId)2486 AnimationInterface::WriteXmlLink (uint32_t fromId, uint32_t toLp, uint32_t toId)
2487 {
2488 AnimXmlElement element ("link");
2489 element.AddAttribute ("fromId", fromId);
2490 element.AddAttribute ("toId", toId);
2491
2492 LinkProperties lprop;
2493 lprop.fromNodeDescription = "";
2494 lprop.toNodeDescription = "";
2495 lprop.linkDescription = "";
2496
2497 P2pLinkNodeIdPair p1 = { fromId, toId };
2498 P2pLinkNodeIdPair p2 = { toId, fromId };
2499 if (m_linkProperties.find (p1) != m_linkProperties.end ())
2500 {
2501 lprop = m_linkProperties[p1];
2502 }
2503 else if (m_linkProperties.find (p2) != m_linkProperties.end ())
2504 {
2505 lprop = m_linkProperties[p2];
2506 }
2507
2508 element.AddAttribute ("fd", lprop.fromNodeDescription, true);
2509 element.AddAttribute ("td", lprop.toNodeDescription, true);
2510 element.AddAttribute ("ld", lprop.linkDescription, true);
2511 WriteN (element.ToString (), m_f);
2512 }
2513
2514 void
WriteXmlIpv4Addresses(uint32_t nodeId,std::vector<std::string> ipv4Addresses)2515 AnimationInterface::WriteXmlIpv4Addresses (uint32_t nodeId, std::vector<std::string> ipv4Addresses)
2516 {
2517 AnimXmlElement element ("ip");
2518 element.AddAttribute ("n", nodeId);
2519 for (std::vector<std::string>::const_iterator i = ipv4Addresses.begin ();
2520 i != ipv4Addresses.end ();
2521 ++i)
2522 {
2523 AnimXmlElement valueElement ("address");
2524 valueElement.SetText (*i);
2525 element.AppendChild (valueElement);
2526 }
2527 WriteN (element.ToString (), m_f);
2528 }
2529
2530 void
WriteXmlIpv6Addresses(uint32_t nodeId,std::vector<std::string> ipv6Addresses)2531 AnimationInterface::WriteXmlIpv6Addresses (uint32_t nodeId, std::vector<std::string> ipv6Addresses)
2532 {
2533 AnimXmlElement element ("ipv6");
2534 element.AddAttribute ("n", nodeId);
2535 for (std::vector<std::string>::const_iterator i = ipv6Addresses.begin ();
2536 i != ipv6Addresses.end ();
2537 ++i)
2538 {
2539 AnimXmlElement valueElement ("address");
2540 valueElement.SetText (*i);
2541 element.AppendChild (valueElement);
2542 }
2543 WriteN (element.ToString (), m_f);
2544 }
2545
2546 void
WriteXmlRouting(uint32_t nodeId,std::string routingInfo)2547 AnimationInterface::WriteXmlRouting (uint32_t nodeId, std::string routingInfo)
2548 {
2549 AnimXmlElement element ("rt");
2550 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2551 element.AddAttribute ("id", nodeId);
2552 element.AddAttribute ("info", routingInfo.c_str (), true);
2553 WriteN (element.ToString (), m_routingF);
2554 }
2555
2556 void
WriteXmlRp(uint32_t nodeId,std::string destination,Ipv4RoutePathElements rpElements)2557 AnimationInterface::WriteXmlRp (uint32_t nodeId, std::string destination, Ipv4RoutePathElements rpElements)
2558 {
2559 std::string tagName = "rp";
2560 AnimXmlElement element (tagName, false);
2561 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2562 element.AddAttribute ("id", nodeId);
2563 element.AddAttribute ("d", destination.c_str ());
2564 element.AddAttribute ("c", rpElements.size ());
2565 for (Ipv4RoutePathElements::const_iterator i = rpElements.begin ();
2566 i != rpElements.end ();
2567 ++i)
2568 {
2569 Ipv4RoutePathElement rpElement = *i;
2570 AnimXmlElement rpeElement ("rpe");
2571 rpeElement.AddAttribute ("n", rpElement.nodeId);
2572 rpeElement.AddAttribute ("nH", rpElement.nextHop.c_str ());
2573 element.AppendChild (rpeElement);
2574 }
2575 WriteN (element.ToString (), m_routingF);
2576 }
2577
2578
2579 void
WriteXmlPRef(uint64_t animUid,uint32_t fId,double fbTx,std::string metaInfo)2580 AnimationInterface::WriteXmlPRef (uint64_t animUid, uint32_t fId, double fbTx, std::string metaInfo)
2581 {
2582 AnimXmlElement element ("pr");
2583 element.AddAttribute ("uId", animUid);
2584 element.AddAttribute ("fId", fId);
2585 element.AddAttribute ("fbTx", fbTx);
2586 if (!metaInfo.empty ())
2587 {
2588 element.AddAttribute ("meta-info", metaInfo.c_str (), true);
2589 }
2590 WriteN (element.ToString (), m_f);
2591 }
2592
2593 void
WriteXmlP(uint64_t animUid,std::string pktType,uint32_t tId,double fbRx,double lbRx)2594 AnimationInterface::WriteXmlP (uint64_t animUid, std::string pktType, uint32_t tId, double fbRx, double lbRx)
2595 {
2596 AnimXmlElement element (pktType);
2597 element.AddAttribute ("uId", animUid);
2598 element.AddAttribute ("tId", tId);
2599 element.AddAttribute ("fbRx", fbRx);
2600 element.AddAttribute ("lbRx", lbRx);
2601 WriteN (element.ToString (), m_f);
2602 }
2603
2604 void
WriteXmlP(std::string pktType,uint32_t fId,double fbTx,double lbTx,uint32_t tId,double fbRx,double lbRx,std::string metaInfo)2605 AnimationInterface::WriteXmlP (std::string pktType, uint32_t fId, double fbTx, double lbTx,
2606 uint32_t tId, double fbRx, double lbRx, std::string metaInfo)
2607 {
2608 AnimXmlElement element (pktType);
2609 element.AddAttribute ("fId", fId);
2610 element.AddAttribute ("fbTx", fbTx);
2611 element.AddAttribute ("lbTx", lbTx);
2612 if (!metaInfo.empty ())
2613 {
2614 element.AddAttribute ("meta-info", metaInfo.c_str (), true);
2615 }
2616 element.AddAttribute ("tId", tId);
2617 element.AddAttribute ("fbRx", fbRx);
2618 element.AddAttribute ("lbRx", lbRx);
2619 WriteN (element.ToString (), m_f);
2620 }
2621
2622 void
WriteXmlAddNodeCounter(uint32_t nodeCounterId,std::string counterName,CounterType counterType)2623 AnimationInterface::WriteXmlAddNodeCounter (uint32_t nodeCounterId, std::string counterName, CounterType counterType)
2624 {
2625 AnimXmlElement element ("ncs");
2626 element.AddAttribute ("ncId", nodeCounterId);
2627 element.AddAttribute ("n", counterName);
2628 element.AddAttribute ("t", CounterTypeToString (counterType));
2629 WriteN (element.ToString (), m_f);
2630 }
2631
2632 void
WriteXmlAddResource(uint32_t resourceId,std::string resourcePath)2633 AnimationInterface::WriteXmlAddResource (uint32_t resourceId, std::string resourcePath)
2634 {
2635 AnimXmlElement element ("res");
2636 element.AddAttribute ("rid", resourceId);
2637 element.AddAttribute ("p", resourcePath);
2638 WriteN (element.ToString (), m_f);
2639 }
2640
2641 void
WriteXmlUpdateNodeImage(uint32_t nodeId,uint32_t resourceId)2642 AnimationInterface::WriteXmlUpdateNodeImage (uint32_t nodeId, uint32_t resourceId)
2643 {
2644 AnimXmlElement element ("nu");
2645 element.AddAttribute ("p", "i");
2646 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2647 element.AddAttribute ("id", nodeId);
2648 element.AddAttribute ("rid", resourceId);
2649 WriteN (element.ToString (), m_f);
2650 }
2651
2652 void
WriteXmlUpdateNodeSize(uint32_t nodeId,double width,double height)2653 AnimationInterface::WriteXmlUpdateNodeSize (uint32_t nodeId, double width, double height)
2654 {
2655 AnimXmlElement element ("nu");
2656 element.AddAttribute ("p", "s");
2657 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2658 element.AddAttribute ("id", nodeId);
2659 element.AddAttribute ("w", width);
2660 element.AddAttribute ("h", height);
2661 WriteN (element.ToString (), m_f);
2662 }
2663
2664 void
WriteXmlUpdateNodePosition(uint32_t nodeId,double x,double y)2665 AnimationInterface::WriteXmlUpdateNodePosition (uint32_t nodeId, double x, double y)
2666 {
2667 AnimXmlElement element ("nu");
2668 element.AddAttribute ("p", "p");
2669 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2670 element.AddAttribute ("id", nodeId);
2671 element.AddAttribute ("x", x);
2672 element.AddAttribute ("y", y);
2673 WriteN (element.ToString (), m_f);
2674 }
2675
2676 void
WriteXmlUpdateNodeColor(uint32_t nodeId,uint8_t r,uint8_t g,uint8_t b)2677 AnimationInterface::WriteXmlUpdateNodeColor (uint32_t nodeId, uint8_t r, uint8_t g, uint8_t b)
2678 {
2679 AnimXmlElement element ("nu");
2680 element.AddAttribute ("p", "c");
2681 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2682 element.AddAttribute ("id", nodeId);
2683 element.AddAttribute ("r", (uint32_t) r);
2684 element.AddAttribute ("g", (uint32_t) g);
2685 element.AddAttribute ("b", (uint32_t) b);
2686 WriteN (element.ToString (), m_f);
2687 }
2688
2689 void
WriteXmlUpdateNodeDescription(uint32_t nodeId)2690 AnimationInterface::WriteXmlUpdateNodeDescription (uint32_t nodeId)
2691 {
2692 AnimXmlElement element ("nu");
2693 element.AddAttribute ("p", "d");
2694 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2695 element.AddAttribute ("id", nodeId);
2696 if (m_nodeDescriptions.find (nodeId) != m_nodeDescriptions.end ())
2697 {
2698 element.AddAttribute ("descr", m_nodeDescriptions[nodeId], true);
2699 }
2700 WriteN (element.ToString (), m_f);
2701 }
2702
2703
2704 void
WriteXmlUpdateNodeCounter(uint32_t nodeCounterId,uint32_t nodeId,double counterValue)2705 AnimationInterface::WriteXmlUpdateNodeCounter (uint32_t nodeCounterId, uint32_t nodeId, double counterValue)
2706 {
2707 AnimXmlElement element ("nc");
2708 element.AddAttribute ("c", nodeCounterId);
2709 element.AddAttribute ("i", nodeId);
2710 element.AddAttribute ("t", Simulator::Now ().GetSeconds ());
2711 element.AddAttribute ("v", counterValue);
2712 WriteN (element.ToString (), m_f);
2713 }
2714
2715 void
WriteXmlUpdateBackground(std::string fileName,double x,double y,double scaleX,double scaleY,double opacity)2716 AnimationInterface::WriteXmlUpdateBackground (std::string fileName, double x, double y, double scaleX, double scaleY, double opacity)
2717 {
2718 AnimXmlElement element ("bg");
2719 element.AddAttribute ("f", fileName);
2720 element.AddAttribute ("x", x);
2721 element.AddAttribute ("y", y);
2722 element.AddAttribute ("sx", scaleX);
2723 element.AddAttribute ("sy", scaleY);
2724 element.AddAttribute ("o", opacity);
2725 WriteN (element.ToString (), m_f);
2726 }
2727
2728 void
WriteXmlNonP2pLinkProperties(uint32_t id,std::string ipAddress,std::string channelType)2729 AnimationInterface::WriteXmlNonP2pLinkProperties (uint32_t id, std::string ipAddress, std::string channelType)
2730 {
2731 AnimXmlElement element ("nonp2plinkproperties");
2732 element.AddAttribute ("id", id);
2733 element.AddAttribute ("ipAddress", ipAddress);
2734 element.AddAttribute ("channelType", channelType);
2735 WriteN (element.ToString (), m_f);
2736 }
2737
2738
2739
2740 /***** AnimXmlElement *****/
2741
AnimXmlElement(std::string tagName,bool emptyElement)2742 AnimationInterface::AnimXmlElement::AnimXmlElement (std::string tagName, bool emptyElement)
2743 : m_tagName (tagName),
2744 m_text ("")
2745 {
2746 }
2747
2748 template <typename T>
2749 void
AddAttribute(std::string attribute,T value,bool xmlEscape)2750 AnimationInterface::AnimXmlElement::AddAttribute (std::string attribute, T value, bool xmlEscape)
2751 {
2752 std::ostringstream oss;
2753 oss << std::setprecision (10);
2754 oss << value;
2755 std::string attributeString = attribute.c_str ();
2756 if (xmlEscape)
2757 {
2758 attributeString += "=\"";
2759 std::string valueStr = oss.str ();
2760 for (std::string::iterator it = valueStr.begin (); it != valueStr.end (); ++it)
2761 {
2762 switch (*it)
2763 {
2764 case '&':
2765 attributeString += "&";
2766 break;
2767 case '\"':
2768 attributeString += """;
2769 break;
2770 case '\'':
2771 attributeString += "'";
2772 break;
2773 case '<':
2774 attributeString += "<";
2775 break;
2776 case '>':
2777 attributeString += ">";
2778 break;
2779 default:
2780 attributeString += *it;
2781 break;
2782 }
2783 }
2784 attributeString += "\" ";
2785 }
2786 else
2787 {
2788 attributeString += "=\"" + oss.str () + "\" ";
2789 }
2790 m_attributes.push_back (attributeString);
2791 }
2792
2793 void
AppendChild(AnimXmlElement e)2794 AnimationInterface::AnimXmlElement::AppendChild (AnimXmlElement e)
2795 {
2796 m_children.push_back (e.ToString ());
2797 }
2798
2799 void
SetText(std::string text)2800 AnimationInterface::AnimXmlElement::SetText (std::string text)
2801 {
2802 m_text = text;
2803 }
2804
2805 std::string
ToString(bool autoClose)2806 AnimationInterface::AnimXmlElement::ToString (bool autoClose)
2807 {
2808 std::string elementString = "<" + m_tagName + " ";
2809
2810
2811 for (std::vector<std::string>::const_iterator i = m_attributes.begin ();
2812 i != m_attributes.end ();
2813 ++i)
2814 {
2815 elementString += *i;
2816 }
2817 if (m_children.empty () && m_text.empty ())
2818 {
2819 if (autoClose)
2820 {
2821 elementString += "/>";
2822 }
2823 }
2824 else
2825 {
2826 elementString += ">";
2827 if (!m_text.empty ())
2828 {
2829 elementString += m_text;
2830 }
2831 if (!m_children.empty ())
2832 {
2833 elementString += "\n";
2834 for (std::vector<std::string>::const_iterator i = m_children.begin ();
2835 i != m_children.end ();
2836 ++i)
2837 {
2838 elementString += *i + "\n";
2839 }
2840
2841 }
2842 if (autoClose)
2843 {
2844 elementString += "</" + m_tagName + ">";
2845 }
2846 }
2847
2848
2849 return elementString + ((autoClose) ? "\n" : "");
2850 }
2851
2852
2853
2854
2855
2856 /***** AnimByteTag *****/
2857
2858 TypeId
GetTypeId(void)2859 AnimByteTag::GetTypeId (void)
2860 {
2861 static TypeId tid = TypeId ("ns3::AnimByteTag")
2862 .SetParent<Tag> ()
2863 .SetGroupName ("NetAnim")
2864 .AddConstructor<AnimByteTag> ()
2865 ;
2866 return tid;
2867 }
2868
2869 TypeId
GetInstanceTypeId(void) const2870 AnimByteTag::GetInstanceTypeId (void) const
2871 {
2872 return GetTypeId ();
2873 }
2874
2875 uint32_t
GetSerializedSize(void) const2876 AnimByteTag::GetSerializedSize (void) const
2877 {
2878 return sizeof (uint64_t);
2879 }
2880
2881 void
Serialize(TagBuffer i) const2882 AnimByteTag::Serialize (TagBuffer i) const
2883 {
2884 i.WriteU64 (m_AnimUid);
2885 }
2886
2887 void
Deserialize(TagBuffer i)2888 AnimByteTag::Deserialize (TagBuffer i)
2889 {
2890 m_AnimUid = i.ReadU64 ();
2891 }
2892
2893 void
Print(std::ostream & os) const2894 AnimByteTag::Print (std::ostream &os) const
2895 {
2896 os << "AnimUid=" << m_AnimUid;
2897 }
2898
2899 void
Set(uint64_t AnimUid)2900 AnimByteTag::Set (uint64_t AnimUid)
2901 {
2902 m_AnimUid = AnimUid;
2903 }
2904
2905 uint64_t
Get(void) const2906 AnimByteTag::Get (void) const
2907 {
2908 return m_AnimUid;
2909 }
2910
AnimPacketInfo()2911 AnimationInterface::AnimPacketInfo::AnimPacketInfo ()
2912 : m_txnd (0),
2913 m_txNodeId (0),
2914 m_fbTx (0),
2915 m_lbTx (0),
2916 m_lbRx (0)
2917 {
2918 }
2919
AnimPacketInfo(const AnimPacketInfo & pInfo)2920 AnimationInterface::AnimPacketInfo::AnimPacketInfo (const AnimPacketInfo & pInfo)
2921 {
2922 m_txnd = pInfo.m_txnd;
2923 m_txNodeId = pInfo.m_txNodeId;
2924 m_fbTx = pInfo.m_fbTx;
2925 m_lbTx = pInfo.m_lbTx;
2926 m_lbRx = pInfo.m_lbRx;
2927 }
2928
AnimPacketInfo(Ptr<const NetDevice> txnd,const Time fbTx,uint32_t txNodeId)2929 AnimationInterface::AnimPacketInfo::AnimPacketInfo (Ptr <const NetDevice> txnd,
2930 const Time fbTx,
2931 uint32_t txNodeId)
2932 : m_txnd (txnd),
2933 m_txNodeId (0),
2934 m_fbTx (fbTx.GetSeconds ()),
2935 m_lbTx (0),
2936 m_lbRx (0)
2937 {
2938 if (!m_txnd)
2939 {
2940 m_txNodeId = txNodeId;
2941 }
2942 }
2943
2944 void
ProcessRxBegin(Ptr<const NetDevice> nd,const double fbRx)2945 AnimationInterface::AnimPacketInfo::ProcessRxBegin (Ptr<const NetDevice> nd, const double fbRx)
2946 {
2947 Ptr <Node> n = nd->GetNode ();
2948 m_fbRx = fbRx;
2949 m_rxnd = nd;
2950 }
2951
2952 } // namespace ns3
2953