NS-3 based Named Data Networking (NDN) simulator
ndnSIM: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
l2-rate-tracer.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2013 University of California, Los Angeles
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19  */
20 
21 #include "l2-rate-tracer.h"
22 #include "ns3/node.h"
23 #include "ns3/packet.h"
24 #include "ns3/config.h"
25 #include "ns3/callback.h"
26 #include "ns3/simulator.h"
27 #include "ns3/node-list.h"
28 #include "ns3/node.h"
29 #include "ns3/log.h"
30 
31 #include <boost/lexical_cast.hpp>
32 #include <fstream>
33 
34 using namespace boost;
35 using namespace std;
36 
37 NS_LOG_COMPONENT_DEFINE ("L2RateTracer");
38 
39 namespace ns3 {
40 
41 static std::list< boost::tuple< boost::shared_ptr<std::ostream>, std::list<Ptr<L2RateTracer> > > > g_tracers;
42 
43 template<class T>
44 static inline void
45 NullDeleter (T *ptr)
46 {
47 }
48 
49 void
50 L2RateTracer::Destroy ()
51 {
52  g_tracers.clear ();
53 }
54 
55 void
56 L2RateTracer::InstallAll (const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
57 {
58  std::list<Ptr<L2RateTracer> > tracers;
59  boost::shared_ptr<std::ostream> outputStream;
60  if (file != "-")
61  {
62  boost::shared_ptr<std::ofstream> os (new std::ofstream ());
63  os->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
64 
65  if (!os->is_open ())
66  {
67  NS_LOG_ERROR ("File " << file << " cannot be opened for writing. Tracing disabled");
68  return;
69  }
70 
71  outputStream = os;
72  }
73  else
74  {
75  outputStream = boost::shared_ptr<std::ostream> (&std::cout, NullDeleter<std::ostream>);
76  }
77 
78  for (NodeList::Iterator node = NodeList::Begin ();
79  node != NodeList::End ();
80  node++)
81  {
82  NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
83 
84  Ptr<L2RateTracer> trace = Create<L2RateTracer> (outputStream, *node);
85  trace->SetAveragingPeriod (averagingPeriod);
86  tracers.push_back (trace);
87  }
88 
89  if (tracers.size () > 0)
90  {
91  // *m_l3RateTrace << "# "; // not necessary for R's read.table
92  tracers.front ()->PrintHeader (*outputStream);
93  *outputStream << "\n";
94  }
95 
96  g_tracers.push_back (boost::make_tuple (outputStream, tracers));
97 }
98 
99 
100 L2RateTracer::L2RateTracer (boost::shared_ptr<std::ostream> os, Ptr<Node> node)
101  : L2Tracer (node)
102  , m_os (os)
103 {
104  SetAveragingPeriod (Seconds (1.0));
105 }
106 
107 L2RateTracer::~L2RateTracer ()
108 {
109  m_printEvent.Cancel ();
110 }
111 
112 void
113 L2RateTracer::SetAveragingPeriod (const Time &period)
114 {
115  m_period = period;
116  m_printEvent.Cancel ();
117  m_printEvent = Simulator::Schedule (m_period, &L2RateTracer::PeriodicPrinter, this);
118 }
119 
120 void
121 L2RateTracer::PeriodicPrinter ()
122 {
123  Print (*m_os);
124  Reset ();
125 
126  m_printEvent = Simulator::Schedule (m_period, &L2RateTracer::PeriodicPrinter, this);
127 }
128 
129 void
130 L2RateTracer::PrintHeader (std::ostream &os) const
131 {
132  os << "Time" << "\t"
133 
134  << "Node" << "\t"
135  << "Interface" << "\t"
136 
137  << "Type" << "\t"
138  << "Packets" << "\t"
139  << "Kilobytes" << "\t"
140  << "PacketsRaw" << "\t"
141  << "KilobytesRaw";
142 }
143 
144 void
145 L2RateTracer::Reset ()
146 {
147  m_stats.get<0> ().Reset ();
148  m_stats.get<1> ().Reset ();
149 }
150 
151 const double alpha = 0.8;
152 
153 #define STATS(INDEX) m_stats.get<INDEX> ()
154 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble (Time::S)
155 
156 #define PRINTER(printName, fieldName, interface) \
157 STATS(2).fieldName = /*new value*/alpha * RATE(0, fieldName) + /*old value*/(1-alpha) * STATS(2).fieldName; \
158 STATS(3).fieldName = /*new value*/alpha * RATE(1, fieldName) / 1024.0 + /*old value*/(1-alpha) * STATS(3).fieldName; \
159  \
160  os << time.ToDouble (Time::S) << "\t" \
161  << m_node << "\t" \
162  << interface << "\t" \
163  << printName << "\t" \
164  << STATS(2).fieldName << "\t" \
165  << STATS(3).fieldName << "\t" \
166  << STATS(0).fieldName << "\t" \
167  << STATS(1).fieldName / 1024.0 << "\n";
168 
169 void
170 L2RateTracer::Print (std::ostream &os) const
171 {
172  Time time = Simulator::Now ();
173 
174  PRINTER ("Drop", m_drop, "combined");
175 }
176 
177 void
178 L2RateTracer::Drop (Ptr<const Packet> packet)
179 {
180  // no interface information... this should be part of this L2Tracer object data
181 
182  m_stats.get<0> ().m_drop ++;
183  m_stats.get<1> ().m_drop += packet->GetSize ();
184 }
185 
186 } // namespace ns3
Link-layer tracer.
Definition: l2-tracer.h:38