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"
31 #include <boost/lexical_cast.hpp>
34 NS_LOG_COMPONENT_DEFINE(
"L2RateTracer");
38 static std::list<std::tuple<std::shared_ptr<std::ostream>, std::list<Ptr<L2RateTracer>>>>
50 std::list<Ptr<L2RateTracer>> tracers;
51 std::shared_ptr<std::ostream> outputStream;
53 std::shared_ptr<std::ofstream> os(
new std::ofstream());
54 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
57 NS_LOG_ERROR(
"File " << file <<
" cannot be opened for writing. Tracing disabled");
64 outputStream = std::shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
67 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
68 NS_LOG_DEBUG(
"Node: " << boost::lexical_cast<std::string>((*node)->GetId()));
70 Ptr<L2RateTracer> trace = Create<L2RateTracer>(outputStream, *node);
71 trace->SetAveragingPeriod(averagingPeriod);
72 tracers.push_back(trace);
75 if (tracers.size() > 0) {
77 tracers.front()->PrintHeader(*outputStream);
78 *outputStream <<
"\n";
81 g_tracers.push_back(std::make_tuple(outputStream, tracers));
93 m_printEvent.Cancel();
100 m_printEvent.Cancel();
101 m_printEvent = Simulator::Schedule(m_period, &L2RateTracer::PeriodicPrinter,
this);
105 L2RateTracer::PeriodicPrinter()
110 m_printEvent = Simulator::Schedule(m_period, &L2RateTracer::PeriodicPrinter,
this);
136 L2RateTracer::Reset()
138 std::get<0>(m_stats).Reset();
139 std::get<1>(m_stats).Reset();
144 #define STATS(INDEX) std::get<INDEX>(m_stats)
145 #define RATE(INDEX, fieldName) STATS(INDEX).fieldName / m_period.ToDouble(Time::S)
147 #define PRINTER(printName, fieldName, interface) \
148 STATS(2).fieldName = \
149 alpha * RATE(0, fieldName) + (1 - alpha) * STATS(2).fieldName; \
150 STATS(3).fieldName = alpha * RATE(1, fieldName) / 1024.0 \
151 + (1 - alpha) * STATS(3).fieldName; \
153 os << time.ToDouble(Time::S) << "\t" << m_node << "\t" << interface << "\t" << printName << "\t" \
154 << STATS(2).fieldName << "\t" << STATS(3).fieldName << "\t" << STATS(0).fieldName << "\t" \
155 << STATS(1).fieldName / 1024.0 << "\n";
160 Time
time = Simulator::Now();
162 PRINTER(
"Drop", m_drop,
"combined");
170 std::get<0>(m_stats).m_drop++;
171 std::get<1>(m_stats).m_drop += packet->GetSize();