blob: 280301dff3bbfef89d69a669e4922f3334c712d8 [file] [log] [blame]
Alexander Afanasyev7e71c752012-01-25 21:40:39 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 UCLA
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 "ipv4-rate-l3-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"
Alexander Afanasyev49165862013-01-31 00:38:20 -080027#include "ns3/node-list.h"
28#include "ns3/node.h"
29#include "ns3/log.h"
Alexander Afanasyev7e71c752012-01-25 21:40:39 -080030
31#include "ns3/ipv4-header.h"
32
Alexander Afanasyev49165862013-01-31 00:38:20 -080033#include <boost/lexical_cast.hpp>
34
35using namespace boost;
36using namespace std;
37
38NS_LOG_COMPONENT_DEFINE ("Ipv4RateL3Tracer");
39
Alexander Afanasyev7e71c752012-01-25 21:40:39 -080040namespace ns3 {
Alexander Afanasyev49165862013-01-31 00:38:20 -080041
42boost::tuple< boost::shared_ptr<std::ostream>, std::list<Ptr<Ipv4RateL3Tracer> > >
43Ipv4RateL3Tracer::InstallAll (const std::string &file, Time averagingPeriod/* = Seconds (0.5)*/)
44{
45 std::list<Ptr<Ipv4RateL3Tracer> > tracers;
46 boost::shared_ptr<std::ofstream> outputStream (new std::ofstream ());
47 outputStream->open (file.c_str (), std::ios_base::out | std::ios_base::trunc);
48
49 if (!outputStream->is_open ())
50 return boost::make_tuple (outputStream, tracers);
51
52 for (NodeList::Iterator node = NodeList::Begin ();
53 node != NodeList::End ();
54 node++)
55 {
56 NS_LOG_DEBUG ("Node: " << lexical_cast<string> ((*node)->GetId ()));
57
58 Ptr<Ipv4RateL3Tracer> trace = Create<Ipv4RateL3Tracer> (outputStream, *node);
59 trace->SetAveragingPeriod (averagingPeriod);
60 tracers.push_back (trace);
61 }
62
63 if (tracers.size () > 0)
64 {
65 // *m_l3RateTrace << "# "; // not necessary for R's read.table
66 tracers.front ()->PrintHeader (*outputStream);
67 *outputStream << "\n";
68 }
69
70 return boost::make_tuple (outputStream, tracers);
71}
72
73
74Ipv4RateL3Tracer::Ipv4RateL3Tracer (boost::shared_ptr<std::ostream> os, Ptr<Node> node)
Alexander Afanasyev7e71c752012-01-25 21:40:39 -080075 : Ipv4L3Tracer (node)
76 , m_os (os)
77{
78 SetAveragingPeriod (Seconds (1.0));
79}
80
81Ipv4RateL3Tracer::~Ipv4RateL3Tracer ()
82{
83 m_printEvent.Cancel ();
84}
85
86void
87Ipv4RateL3Tracer::SetAveragingPeriod (const Time &period)
88{
89 m_period = period;
90 m_printEvent.Cancel ();
91 m_printEvent = Simulator::Schedule (m_period, &Ipv4RateL3Tracer::PeriodicPrinter, this);
92}
93
94void
95Ipv4RateL3Tracer::PeriodicPrinter ()
96{
Alexander Afanasyev49165862013-01-31 00:38:20 -080097 Print (*m_os);
Alexander Afanasyev7e71c752012-01-25 21:40:39 -080098 Reset ();
Alexander Afanasyev49165862013-01-31 00:38:20 -080099
Alexander Afanasyev7e71c752012-01-25 21:40:39 -0800100 m_printEvent = Simulator::Schedule (m_period, &Ipv4RateL3Tracer::PeriodicPrinter, this);
101}
102
103void
104Ipv4RateL3Tracer::PrintHeader (std::ostream &os) const
105{
106 os << "Time" << "\t"
107
108 << "Node" << "\t"
109 << "Interface" << "\t"
110
111 << "Type" << "\t"
112 << "Packets" << "\t"
113 << "Kilobytes";
114}
115
116void
117Ipv4RateL3Tracer::Reset ()
118{
119 for (std::map<uint32_t, boost::tuple<Stats, Stats, Stats, Stats> >::iterator stats = m_stats.begin ();
120 stats != m_stats.end ();
121 stats++)
122 {
123 stats->second.get<0> ().Reset ();
124 stats->second.get<1> ().Reset ();
125 }
126}
127
128const double alpha = 0.8;
129
130#define STATS(INDEX) stats->second.get<INDEX> ()
131#define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble (Time::S)
132
133#define PRINTER(printName, fieldName) \
134STATS(2).fieldName = /*new value*/alpha * RATE(0, fieldName) + /*old value*/(1-alpha) * STATS(2).fieldName; \
135STATS(3).fieldName = /*new value*/alpha * RATE(1, fieldName) / 1024.0 + /*old value*/(1-alpha) * STATS(3).fieldName; \
136 \
137os << time.ToDouble (Time::S) << "\t" \
138 << m_node << "\t" \
139 << stats->first << "\t" \
140 << printName << "\t" \
141 << STATS(2).fieldName << "\t" \
142 << STATS(3).fieldName << "\n";
143
144void
145Ipv4RateL3Tracer::Print (std::ostream &os) const
146{
147 for (std::map<uint32_t, boost::tuple<Stats, Stats, Stats, Stats> >::iterator stats = m_stats.begin ();
148 stats != m_stats.end ();
149 stats++)
150 {
151 Time time = Simulator::Now ();
152
153 PRINTER ("In", m_in);
154 PRINTER ("Out", m_out);
155 PRINTER ("Drop", m_drop);
156 }
157}
158
159void
160Ipv4RateL3Tracer::Rx (std::string context,
161 Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t iface)
162{
163 m_stats[iface].get<0> ().m_in ++;
164 m_stats[iface].get<1> ().m_in += packet->GetSize ();
165}
166
167void
168Ipv4RateL3Tracer::Tx (std::string context,
169 Ptr<const Packet> packet, Ptr<Ipv4> ipv4, uint32_t iface)
170{
171 m_stats[iface].get<0> ().m_out ++;
172 m_stats[iface].get<1> ().m_out += packet->GetSize ();
173}
174
175void
176Ipv4RateL3Tracer::Drop (std::string context,
177 const Ipv4Header &header, Ptr<const Packet> packet, Ipv4L3Protocol::DropReason, Ptr<Ipv4> ipv4, uint32_t iface)
178{
179 m_stats[iface].get<0> ().m_drop ++;
180 m_stats[iface].get<1> ().m_drop += packet->GetSize ();
181}
182
183
184} // namespace ns3