blob: fa9ab3ae5aef1e447b2a10580ca8bcd767bd8a85 [file] [log] [blame]
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -08001/* -*- 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
Alexander Afanasyev0c395372014-12-20 15:54:02 -080021#include "ndn-app-delay-tracer.hpp"
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080022#include "ns3/node.h"
23#include "ns3/packet.h"
24#include "ns3/config.h"
25#include "ns3/names.h"
26#include "ns3/callback.h"
27
Alexander Afanasyev0c395372014-12-20 15:54:02 -080028#include "ns3/ndn-app.hpp"
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080029#include "ns3/simulator.h"
30#include "ns3/node-list.h"
31#include "ns3/log.h"
32
33#include <boost/lexical_cast.hpp>
34#include <boost/make_shared.hpp>
35
36#include <fstream>
37
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080038NS_LOG_COMPONENT_DEFINE("ndn.AppDelayTracer");
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080039
40using namespace std;
41
42namespace ns3 {
43namespace ndn {
44
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045static std::list<boost::tuple<boost::shared_ptr<std::ostream>, std::list<Ptr<AppDelayTracer>>>>
46 g_tracers;
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070047
Alexander Afanasyev5352af32013-07-15 09:51:28 -070048template<class T>
49static inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080050NullDeleter(T* ptr)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070051{
52}
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080053
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070054void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080055AppDelayTracer::Destroy()
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070056{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 g_tracers.clear();
Alexander Afanasyevdb5f3b62013-08-09 17:42:12 -070058}
59
60void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061AppDelayTracer::InstallAll(const std::string& file)
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080062{
63 using namespace boost;
64 using namespace std;
Alexander Afanasyevfc8425c2013-01-31 13:33:49 -080065
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080066 std::list<Ptr<AppDelayTracer>> tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070067 boost::shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068 if (file != "-") {
69 boost::shared_ptr<std::ofstream> os(new std::ofstream());
70 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080071
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072 if (!os->is_open()) {
73 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
74 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -070075 }
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080076
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080077 outputStream = os;
78 }
79 else {
80 outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
81 }
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080082
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080083 for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
84 Ptr<AppDelayTracer> trace = Install(*node, outputStream);
85 tracers.push_back(trace);
86 }
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080087
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080088 if (tracers.size() > 0) {
89 // *m_l3RateTrace << "# "; // not necessary for R's read.table
90 tracers.front()->PrintHeader(*outputStream);
91 *outputStream << "\n";
92 }
93
94 g_tracers.push_back(boost::make_tuple(outputStream, tracers));
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -080095}
96
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -070097void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080098AppDelayTracer::Install(const NodeContainer& nodes, const std::string& file)
Alexander Afanasyev5352af32013-07-15 09:51:28 -070099{
100 using namespace boost;
101 using namespace std;
102
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800103 std::list<Ptr<AppDelayTracer>> tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700104 boost::shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 if (file != "-") {
106 boost::shared_ptr<std::ofstream> os(new std::ofstream());
107 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700108
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800109 if (!os->is_open()) {
110 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
111 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700112 }
113
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800114 outputStream = os;
115 }
116 else {
117 outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
118 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700119
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800120 for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
121 Ptr<AppDelayTracer> trace = Install(*node, outputStream);
122 tracers.push_back(trace);
123 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700124
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125 if (tracers.size() > 0) {
126 // *m_l3RateTrace << "# "; // not necessary for R's read.table
127 tracers.front()->PrintHeader(*outputStream);
128 *outputStream << "\n";
129 }
130
131 g_tracers.push_back(boost::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700132}
133
Alexander Afanasyev3fe94dc2013-08-09 17:12:12 -0700134void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135AppDelayTracer::Install(Ptr<Node> node, const std::string& file)
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700136{
137 using namespace boost;
138 using namespace std;
139
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140 std::list<Ptr<AppDelayTracer>> tracers;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700141 boost::shared_ptr<std::ostream> outputStream;
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 if (file != "-") {
143 boost::shared_ptr<std::ofstream> os(new std::ofstream());
144 os->open(file.c_str(), std::ios_base::out | std::ios_base::trunc);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700145
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800146 if (!os->is_open()) {
147 NS_LOG_ERROR("File " << file << " cannot be opened for writing. Tracing disabled");
148 return;
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700149 }
150
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151 outputStream = os;
152 }
153 else {
154 outputStream = boost::shared_ptr<std::ostream>(&std::cout, NullDeleter<std::ostream>);
155 }
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700156
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800157 Ptr<AppDelayTracer> trace = Install(node, outputStream);
158 tracers.push_back(trace);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700159
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 if (tracers.size() > 0) {
161 // *m_l3RateTrace << "# "; // not necessary for R's read.table
162 tracers.front()->PrintHeader(*outputStream);
163 *outputStream << "\n";
164 }
165
166 g_tracers.push_back(boost::make_tuple(outputStream, tracers));
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700167}
168
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700169Ptr<AppDelayTracer>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800170AppDelayTracer::Install(Ptr<Node> node, boost::shared_ptr<std::ostream> outputStream)
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700171{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800172 NS_LOG_DEBUG("Node: " << node->GetId());
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700173
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800174 Ptr<AppDelayTracer> trace = Create<AppDelayTracer>(outputStream, node);
Alexander Afanasyev5352af32013-07-15 09:51:28 -0700175
176 return trace;
177}
178
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800179//////////////////////////////////////////////////////////////////////////////
180//////////////////////////////////////////////////////////////////////////////
181//////////////////////////////////////////////////////////////////////////////
182
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800183AppDelayTracer::AppDelayTracer(boost::shared_ptr<std::ostream> os, Ptr<Node> node)
184 : m_nodePtr(node)
185 , m_os(os)
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800186{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800187 m_node = boost::lexical_cast<string>(m_nodePtr->GetId());
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800188
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800189 Connect();
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800190
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800191 string name = Names::FindName(node);
192 if (!name.empty()) {
193 m_node = name;
194 }
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800195}
196
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800197AppDelayTracer::AppDelayTracer(boost::shared_ptr<std::ostream> os, const std::string& node)
198 : m_node(node)
199 , m_os(os)
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800200{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800201 Connect();
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800202}
203
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800204AppDelayTracer::~AppDelayTracer(){};
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800205
206void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800207AppDelayTracer::Connect()
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800208{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800209 Config::ConnectWithoutContext("/NodeList/" + m_node
210 + "/ApplicationList/*/LastRetransmittedInterestDataDelay",
211 MakeCallback(&AppDelayTracer::LastRetransmittedInterestDataDelay,
212 this));
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800213
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800214 Config::ConnectWithoutContext("/NodeList/" + m_node + "/ApplicationList/*/FirstInterestDataDelay",
215 MakeCallback(&AppDelayTracer::FirstInterestDataDelay, this));
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800216}
217
218void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800219AppDelayTracer::PrintHeader(std::ostream& os) const
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800220{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800221 os << "Time"
222 << "\t"
223 << "Node"
224 << "\t"
225 << "AppId"
226 << "\t"
227 << "SeqNo"
228 << "\t"
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800229
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800230 << "Type"
231 << "\t"
232 << "DelayS"
233 << "\t"
234 << "DelayUS"
235 << "\t"
236 << "RetxCount"
237 << "\t"
238 << "HopCount"
239 << "";
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800240}
241
Alexander Afanasyevfc8425c2013-01-31 13:33:49 -0800242void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800243AppDelayTracer::LastRetransmittedInterestDataDelay(Ptr<App> app, uint32_t seqno, Time delay,
244 int32_t hopCount)
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800245{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800246 *m_os << Simulator::Now().ToDouble(Time::S) << "\t" << m_node << "\t" << app->GetId() << "\t"
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800247 << seqno << "\t"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800248 << "LastDelay"
249 << "\t" << delay.ToDouble(Time::S) << "\t" << delay.ToDouble(Time::US) << "\t" << 1 << "\t"
Alexander Afanasyev1a0fff62013-01-19 14:29:51 -0800250 << hopCount << "\n";
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800251}
Alexander Afanasyevfc8425c2013-01-31 13:33:49 -0800252
253void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800254AppDelayTracer::FirstInterestDataDelay(Ptr<App> app, uint32_t seqno, Time delay, uint32_t retxCount,
255 int32_t hopCount)
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800256{
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800257 *m_os << Simulator::Now().ToDouble(Time::S) << "\t" << m_node << "\t" << app->GetId() << "\t"
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800258 << seqno << "\t"
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800259 << "FullDelay"
260 << "\t" << delay.ToDouble(Time::S) << "\t" << delay.ToDouble(Time::US) << "\t" << retxCount
261 << "\t" << hopCount << "\n";
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800262}
263
Alexander Afanasyevdb64ff12013-01-18 16:37:31 -0800264} // namespace ndn
265} // namespace ns3