NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ndn-app-delay-tracer.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
20 #include "ndn-app-delay-tracer.hpp"
21 #include "ns3/node.h"
22 #include "ns3/packet.h"
23 #include "ns3/config.h"
24 #include "ns3/names.h"
25 #include "ns3/callback.h"
26 
27 #include "apps/ndn-app.hpp"
28 #include "ns3/simulator.h"
29 #include "ns3/node-list.h"
30 #include "ns3/log.h"
31 
32 #include <boost/lexical_cast.hpp>
33 #include <boost/make_shared.hpp>
34 
35 #include <fstream>
36 
37 NS_LOG_COMPONENT_DEFINE("ndn.AppDelayTracer");
38 
39 namespace ns3 {
40 namespace ndn {
41 
42 static std::list<std::tuple<shared_ptr<std::ostream>, std::list<Ptr<AppDelayTracer>>>>
44 
45 void
47 {
48  g_tracers.clear();
49 }
50 
51 void
52 AppDelayTracer::InstallAll(const std::string& file)
53 {
54  using namespace boost;
55  using namespace std;
56 
57  std::list<Ptr<AppDelayTracer>> tracers;
58  shared_ptr<std::ostream> outputStream;
59  if (file != "-") {
60  shared_ptr<std::ofstream> os(new std::ofstream());
61  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
62 
63  if (!os->is_open()) {
64  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
65  return;
66  }
67 
68  outputStream = os;
69  }
70  else {
71  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
72  }
73 
74  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
75  Ptr<AppDelayTracer> trace = Install(*node, outputStream);
76  tracers.push_back(trace);
77  }
78 
79  if (tracers.size() > 0) {
80  // *m_l3RateTrace << "# "; // not necessary for R's read.table
81  tracers.front()->PrintHeader(*outputStream);
82  *outputStream << "\n";
83  }
84 
85  g_tracers.push_back(std::make_tuple(outputStream, tracers));
86 }
87 
88 void
89 AppDelayTracer::Install(const NodeContainer& nodes, const std::string& file)
90 {
91  using namespace boost;
92  using namespace std;
93 
94  std::list<Ptr<AppDelayTracer>> tracers;
95  shared_ptr<std::ostream> outputStream;
96  if (file != "-") {
97  shared_ptr<std::ofstream> os(new std::ofstream());
98  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
99 
100  if (!os->is_open()) {
101  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
102  return;
103  }
104 
105  outputStream = os;
106  }
107  else {
108  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
109  }
110 
111  for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
112  Ptr<AppDelayTracer> trace = Install(*node, outputStream);
113  tracers.push_back(trace);
114  }
115 
116  if (tracers.size() > 0) {
117  // *m_l3RateTrace << "# "; // not necessary for R's read.table
118  tracers.front()->PrintHeader(*outputStream);
119  *outputStream << "\n";
120  }
121 
122  g_tracers.push_back(std::make_tuple(outputStream, tracers));
123 }
124 
125 void
126 AppDelayTracer::Install(Ptr<Node> node, const std::string& file)
127 {
128  using namespace boost;
129  using namespace std;
130 
131  std::list<Ptr<AppDelayTracer>> tracers;
132  shared_ptr<std::ostream> outputStream;
133  if (file != "-") {
134  shared_ptr<std::ofstream> os(new std::ofstream());
135  os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
136 
137  if (!os->is_open()) {
138  NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
139  return;
140  }
141 
142  outputStream = os;
143  }
144  else {
145  outputStream = shared_ptr<std::ostream>(&std::cout, std::bind([]{}));
146  }
147 
148  Ptr<AppDelayTracer> trace = Install(node, outputStream);
149  tracers.push_back(trace);
150 
151  if (tracers.size() > 0) {
152  // *m_l3RateTrace << "# "; // not necessary for R's read.table
153  tracers.front()->PrintHeader(*outputStream);
154  *outputStream << "\n";
155  }
156 
157  g_tracers.push_back(std::make_tuple(outputStream, tracers));
158 }
159 
160 Ptr<AppDelayTracer>
161 AppDelayTracer::Install(Ptr<Node> node, shared_ptr<std::ostream> outputStream)
162 {
163  NS_LOG_DEBUG("Node: " << node->GetId());
164 
165  Ptr<AppDelayTracer> trace = Create<AppDelayTracer>(outputStream, node);
166 
167  return trace;
168 }
169 
173 
174 AppDelayTracer::AppDelayTracer(shared_ptr<std::ostream> os, Ptr<Node> node)
175  : m_nodePtr(node)
176  , m_os(os)
177 {
178  m_node = boost::lexical_cast<std::string>(m_nodePtr->GetId());
179 
180  Connect();
181 
182  std::string name = Names::FindName(node);
183  if (!name.empty()) {
184  m_node = name;
185  }
186 }
187 
188 AppDelayTracer::AppDelayTracer(shared_ptr<std::ostream> os, const std::string& node)
189  : m_node(node)
190  , m_os(os)
191 {
192  Connect();
193 }
194 
196 
197 void
198 AppDelayTracer::Connect()
199 {
200  Config::ConnectWithoutContext("/NodeList/" + m_node
201  + "/ApplicationList/*/LastRetransmittedInterestDataDelay",
202  MakeCallback(&AppDelayTracer::LastRetransmittedInterestDataDelay,
203  this));
204 
205  Config::ConnectWithoutContext("/NodeList/" + m_node + "/ApplicationList/*/FirstInterestDataDelay",
206  MakeCallback(&AppDelayTracer::FirstInterestDataDelay, this));
207 }
208 
209 void
210 AppDelayTracer::PrintHeader(std::ostream& os) const
211 {
212  os << "Time"
213  << "\t"
214  << "Node"
215  << "\t"
216  << "AppId"
217  << "\t"
218  << "SeqNo"
219  << "\t"
220 
221  << "Type"
222  << "\t"
223  << "DelayS"
224  << "\t"
225  << "DelayUS"
226  << "\t"
227  << "RetxCount"
228  << "\t"
229  << "HopCount"
230  << "";
231 }
232 
233 void
234 AppDelayTracer::LastRetransmittedInterestDataDelay(Ptr<App> app, uint32_t seqno, Time delay,
235  int32_t hopCount)
236 {
237  *m_os << Simulator::Now().ToDouble(Time::S) << "\t" << m_node << "\t" << app->GetId() << "\t"
238  << seqno << "\t"
239  << "LastDelay"
240  << "\t" << delay.ToDouble(Time::S) << "\t" << delay.ToDouble(Time::US) << "\t" << 1 << "\t"
241  << hopCount << "\n";
242 }
243 
244 void
245 AppDelayTracer::FirstInterestDataDelay(Ptr<App> app, uint32_t seqno, Time delay, uint32_t retxCount,
246  int32_t hopCount)
247 {
248  *m_os << Simulator::Now().ToDouble(Time::S) << "\t" << m_node << "\t" << app->GetId() << "\t"
249  << seqno << "\t"
250  << "FullDelay"
251  << "\t" << delay.ToDouble(Time::S) << "\t" << delay.ToDouble(Time::US) << "\t" << retxCount
252  << "\t" << hopCount << "\n";
253 }
254 
255 } // namespace ndn
256 } // namespace ns3
static void Install(const NodeContainer &nodes, const std::string &file)
Helper method to install tracers on the selected simulation nodes.
static std::list< std::tuple< shared_ptr< std::ostream >, std::list< Ptr< AppDelayTracer > > > > g_tracers
static void Destroy()
Explicit request to remove all statically created tracers.
AppDelayTracer(shared_ptr< std::ostream > os, Ptr< Node > node)
Trace constructor that attaches to all applications on the node using node's pointer.
static void InstallAll(const std::string &file)
Helper method to install tracers on all simulation nodes.
void PrintHeader(std::ostream &os) const
Print head of the trace (e.g., for post-processing)