--- a/CHANGES.html Wed Oct 15 07:00:24 2014 -0700
+++ b/CHANGES.html Wed Oct 15 07:06:11 2014 -0700
@@ -57,6 +57,11 @@
<li> It is now possible to print the Neighbor Cache (ARP and NDISC) by using
the RoutingProtocolHelper
</li>
+ <li> A TimeProbe class has been added to the data collection framework in
+ the stats module, enabling TracedValues emitting values of type
+ ns3::Time to be handled by the framework.
+ </li>
+
</ul>
<h2>Changes to existing API:</h2>
--- a/RELEASE_NOTES Wed Oct 15 07:00:24 2014 -0700
+++ b/RELEASE_NOTES Wed Oct 15 07:06:11 2014 -0700
@@ -25,6 +25,8 @@
the RoutingProtocolHelper
- The PrintRoutingTable... and PrintNeighborCache... are now static funtions
i.e., it's not anymore needed to instantiate an helper just to use them.
+- A new TimeProbe class has been added to hook the data collection framework
+ to traced values emitting Time objects
Bugs fixed
----------
--- a/doc/tutorial/source/data-collection.rst Wed Oct 15 07:00:24 2014 -0700
+++ b/doc/tutorial/source/data-collection.rst Wed Oct 15 07:06:11 2014 -0700
@@ -359,6 +359,8 @@
+------------------+-------------------+------------------------------------+
| bool | BooleanProbe | stats/model/uinteger-16-probe.h |
+------------------+-------------------+------------------------------------+
+ | ns3::Time | TimeProbe | stats/model/time-probe.h |
+ +------------------+-------------------+------------------------------------+
The following TraceSource types are supported by Probes as of this writing:
--- a/src/stats/doc/data-collection-helpers.rst Wed Oct 15 07:00:24 2014 -0700
+++ b/src/stats/doc/data-collection-helpers.rst Wed Oct 15 07:06:11 2014 -0700
@@ -605,6 +605,7 @@
- Uinteger8Probe
- Uinteger16Probe
- Uinteger32Probe
+- TimeProbe
- PacketProbe
- ApplicationPacketProbe
- Ipv4PacketProbe
--- a/src/stats/doc/scope-and-limitations.rst Wed Oct 15 07:00:24 2014 -0700
+++ b/src/stats/doc/scope-and-limitations.rst Wed Oct 15 07:06:11 2014 -0700
@@ -18,6 +18,7 @@
- Uinteger8Probe
- Uinteger16Probe
- Uinteger32Probe
+- TimeProbe
- PacketProbe
- ApplicationPacketProbe
- Ipv4PacketProbe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/examples/time-probe-example.cc Wed Oct 15 07:06:11 2014 -0700
@@ -0,0 +1,247 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 University of Washington
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+//
+// This example is designed to show the main features of an ns3::TimeProbe.
+// A test object is used to emit values through a trace source. The
+// example shows three ways to use a ns3::TimeProbe to hook the output
+// of this trace source (in addition to hooking the raw trace source).
+//
+// It produces two types of output. By default, it will generate a
+// gnuplot of interarrival times. If the '--verbose=1' argument is passed,
+// it will also generate debugging output of the form (for example):
+//
+// Emitting at 96.5378 seconds
+// context: raw trace source old 0.293343 new 0.00760254
+// context: probe1 old 0.293343 new 0.00760254
+// context: probe2 old 0.293343 new 0.00760254
+// context: probe3 old 0.293343 new 0.00760254
+//
+// The stopTime defaults to 100 seconds but can be changed by an argument.
+//
+
+#include <string>
+
+#include "ns3/core-module.h"
+#include "ns3/time-probe.h"
+#include "ns3/gnuplot-helper.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("TimeProbeExample");
+
+//
+// This is our test object, an object that emits values according to
+// a Poisson arrival process. It emits a traced Time value as a
+// trace source; this takes the value of interarrival time
+//
+class Emitter : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+ Emitter ();
+private:
+ void DoInitialize (void);
+// void Emit (void);
+ void Emit (void);
+
+ TracedValue<Time> m_interval;
+ Time m_last;
+ Ptr<ExponentialRandomVariable> m_var;
+};
+
+NS_OBJECT_ENSURE_REGISTERED (Emitter);
+
+TypeId
+Emitter::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::Emitter")
+ .AddConstructor<Emitter> ()
+ .SetParent<Object> ()
+ .AddTraceSource ("Interval",
+ "Trace source",
+ MakeTraceSourceAccessor (&Emitter::m_interval))
+ ;
+ return tid;
+}
+
+Emitter::Emitter (void)
+ : m_interval (Seconds (0)),
+ m_last (Seconds (0))
+{
+ m_var = CreateObject<ExponentialRandomVariable> ();
+}
+
+void
+Emitter::DoInitialize (void)
+{
+ Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Emit, this);
+}
+
+void
+Emitter::Emit (void)
+{
+ NS_LOG_DEBUG ("Emitting at " << Simulator::Now ().GetSeconds () << " seconds");
+ m_interval = Simulator::Now () - m_last;
+ m_last = Simulator::Now ();
+ TimeProbe::SetValueByPath ("/Names/probe3", m_interval);
+ Simulator::Schedule (Seconds (m_var->GetValue ()), &Emitter::Emit, this);
+}
+
+// This is a function to test hooking a raw function to the trace source
+void
+NotifyViaTraceSource (std::string context, Time oldVal, Time newVal)
+{
+ BooleanValue verbose;
+ GlobalValue::GetValueByName ("verbose", verbose);
+ if (verbose.Get ())
+ {
+ std::cout << "context: " << context << " old " << oldVal.GetSeconds () << " new " << newVal.GetSeconds () << std::endl;
+ }
+}
+
+// This is a function to test hooking it to the probe output
+void
+NotifyViaProbe (std::string context, double oldVal, double newVal)
+{
+ BooleanValue verbose;
+ GlobalValue::GetValueByName ("verbose", verbose);
+ if (verbose.Get ())
+ {
+ std::cout << "context: " << context << " old " << oldVal << " new " << newVal << std::endl;
+ }
+}
+
+static ns3::GlobalValue g_verbose ("verbose",
+ "Whether to enable verbose output",
+ ns3::BooleanValue (false),
+ ns3::MakeBooleanChecker ());
+
+int main (int argc, char *argv[])
+{
+ double stopTime = 100.0;
+ bool verbose = false;
+
+ CommandLine cmd;
+ cmd.AddValue ("stopTime", "Time (seconds) to terminate simulation", stopTime);
+ cmd.AddValue ("verbose", "Whether to enable verbose output", verbose);
+ cmd.Parse (argc, argv);
+ bool connected;
+
+ // Set a global value, so that the callbacks can access it
+ if (verbose)
+ {
+ GlobalValue::Bind ("verbose", BooleanValue (true));
+ LogComponentEnable ("TimeProbeExample", LOG_LEVEL_ALL);
+ }
+
+ Ptr<Emitter> emitter = CreateObject<Emitter> ();
+ Names::Add ("/Names/Emitter", emitter);
+
+ //
+ // The below shows typical functionality without a probe
+ // (connect a sink function to a trace source)
+ //
+ connected = emitter->TraceConnect ("Interval", "raw trace source", MakeCallback (&NotifyViaTraceSource));
+ NS_ASSERT_MSG (connected, "Trace source not connected");
+
+ //
+ // Next, we'll show several use cases of using a Probe to access and
+ // filter the values of the underlying trace source
+ //
+
+ //
+ // Probe1 will be hooked directly to the Emitter trace source object
+ //
+
+ // probe1 will be hooked to the Emitter trace source
+ Ptr<TimeProbe> probe1 = CreateObject<TimeProbe> ();
+ // the probe's name can serve as its context in the tracing
+ probe1->SetName ("probe1");
+
+ // Connect the probe to the emitter's Interval
+ connected = probe1->ConnectByObject ("Interval", emitter);
+ NS_ASSERT_MSG (connected, "Trace source not connected to probe1");
+
+ // The probe itself should generate output. The context that we provide
+ // to this probe (in this case, the probe name) will help to disambiguate
+ // the source of the trace
+ connected = probe1->TraceConnect ("Output", probe1->GetName (), MakeCallback (&NotifyViaProbe));
+ NS_ASSERT_MSG (connected, "Trace source not connected to probe1 Output");
+
+ //
+ // Probe2 will be hooked to the Emitter trace source object by
+ // accessing it by path name in the Config database
+ //
+
+ // Create another similar probe; this will hook up via a Config path
+ Ptr<TimeProbe> probe2 = CreateObject<TimeProbe> ();
+ probe2->SetName ("probe2");
+
+ // Note, no return value is checked here
+ probe2->ConnectByPath ("/Names/Emitter/Interval");
+
+ // The probe itself should generate output. The context that we provide
+ // to this probe (in this case, the probe name) will help to disambiguate
+ // the source of the trace
+ connected = probe2->TraceConnect ("Output", "probe2", MakeCallback (&NotifyViaProbe));
+ NS_ASSERT_MSG (connected, "Trace source not connected to probe2 Output");
+
+ //
+ // Probe3 will be called by the emitter directly through the
+ // static method SetValueByPath().
+ //
+ Ptr<TimeProbe> probe3 = CreateObject<TimeProbe> ();
+ probe3->SetName ("probe3");
+
+ // By adding to the config database, we can access it later
+ Names::Add ("/Names/probe3", probe3);
+
+ // The probe itself should generate output. The context that we provide
+ // to this probe (in this case, the probe name) will help to disambiguate
+ // the source of the trace
+ connected = probe3->TraceConnect ("Output", "probe3", MakeCallback (&NotifyViaProbe));
+ NS_ASSERT_MSG (connected, "Trace source not connected to probe3 Output");
+
+ // Plot the interval values
+ GnuplotHelper plotHelper;
+ plotHelper.ConfigurePlot ("time-probe-example",
+ "Emitter interarrivals vs. Time",
+ "Simulation time (Seconds)",
+ "Interarrival time (Seconds)",
+ "png");
+
+ // Helper creates a TimeProbe and hooks it to the /Names/Emitter/Interval
+ // source. Helper also takes the Output of the TimeProbe and plots it
+ // as a dataset labeled 'Emitter Interarrival Time'
+ plotHelper.PlotProbe ("ns3::TimeProbe",
+ "/Names/Emitter/Interval",
+ "Output",
+ "Emitter Interarrival Time",
+ GnuplotAggregator::KEY_INSIDE);
+
+ // The Emitter object is not associated with an ns-3 node, so
+ // it won't get started automatically, so we need to do this ourselves
+ Simulator::Schedule (Seconds (0.0), &Emitter::Initialize, emitter);
+
+ Simulator::Stop (Seconds (stopTime));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return 0;
+}
--- a/src/stats/examples/wscript Wed Oct 15 07:00:24 2014 -0700
+++ b/src/stats/examples/wscript Wed Oct 15 07:06:11 2014 -0700
@@ -10,6 +10,9 @@
program = bld.create_ns3_program('double-probe-example', ['network', 'stats'])
program.source = 'double-probe-example.cc'
+ program = bld.create_ns3_program('time-probe-example', ['stats'])
+ program.source = 'time-probe-example.cc'
+
program = bld.create_ns3_program('gnuplot-aggregator-example', ['network', 'stats'])
program.source = 'gnuplot-aggregator-example.cc'
--- a/src/stats/helper/file-helper.cc Wed Oct 15 07:00:24 2014 -0700
+++ b/src/stats/helper/file-helper.cc Wed Oct 15 07:06:11 2014 -0700
@@ -543,6 +543,13 @@
MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32,
m_timeSeriesAdaptorMap[probeContext]));
}
+ else if (m_probeMap[probeName].second == "ns3::TimeProbe")
+ {
+ m_probeMap[probeName].first->TraceConnectWithoutContext
+ (probeTraceSource,
+ MakeCallback (&TimeSeriesAdaptor::TraceSinkDouble,
+ m_timeSeriesAdaptorMap[probeContext]));
+ }
else
{
NS_FATAL_ERROR ("Unknown probe type " << m_probeMap[probeName].second << "; need to add support in the helper for this");
--- a/src/stats/helper/gnuplot-helper.cc Wed Oct 15 07:00:24 2014 -0700
+++ b/src/stats/helper/gnuplot-helper.cc Wed Oct 15 07:06:11 2014 -0700
@@ -403,6 +403,13 @@
MakeCallback (&TimeSeriesAdaptor::TraceSinkUinteger32,
m_timeSeriesAdaptorMap[probeContext]));
}
+ else if (m_probeMap[probeName].second == "ns3::TimeProbe")
+ {
+ m_probeMap[probeName].first->TraceConnectWithoutContext
+ (probeTraceSource,
+ MakeCallback (&TimeSeriesAdaptor::TraceSinkDouble,
+ m_timeSeriesAdaptorMap[probeContext]));
+ }
else
{
NS_FATAL_ERROR ("Unknown probe type " << m_probeMap[probeName].second << "; need to add support in the helper for this");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/model/time-probe.cc Wed Oct 15 07:06:11 2014 -0700
@@ -0,0 +1,111 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: L. Felipe Perrone (perrone@bucknell.edu)
+ * Tiago G. Rodrigues (tgr002@bucknell.edu)
+ *
+ * Modified by: Mitch Watrous (watrous@u.washington.edu)
+ *
+ */
+
+#include "ns3/time-probe.h"
+#include "ns3/object.h"
+#include "ns3/log.h"
+#include "ns3/names.h"
+#include "ns3/config.h"
+#include "ns3/trace-source-accessor.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("TimeProbe");
+
+NS_OBJECT_ENSURE_REGISTERED (TimeProbe);
+
+TypeId
+TimeProbe::GetTypeId ()
+{
+ static TypeId tid = TypeId ("ns3::TimeProbe")
+ .SetParent<Probe> ()
+ .AddConstructor<TimeProbe> ()
+ .AddTraceSource ("Output",
+ "The double valued (units of seconds) probe output",
+ MakeTraceSourceAccessor (&TimeProbe::m_output))
+ ;
+ return tid;
+}
+
+TimeProbe::TimeProbe ()
+{
+ NS_LOG_FUNCTION (this);
+ m_output = 0;
+}
+
+TimeProbe::~TimeProbe ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+double
+TimeProbe::GetValue (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_output;
+}
+void
+TimeProbe::SetValue (Time newVal)
+{
+ NS_LOG_FUNCTION (this << newVal.GetSeconds ());
+ m_output = newVal.GetSeconds ();
+}
+
+void
+TimeProbe::SetValueByPath (std::string path, Time newVal)
+{
+ NS_LOG_FUNCTION (path << newVal.GetSeconds ());
+ Ptr<TimeProbe> probe = Names::Find<TimeProbe> (path);
+ NS_ASSERT_MSG (probe, "Error: Can't find probe for path " << path);
+ probe->SetValue (newVal);
+}
+
+bool
+TimeProbe::ConnectByObject (std::string traceSource, Ptr<Object> obj)
+{
+ NS_LOG_FUNCTION (this << traceSource << obj);
+ NS_LOG_DEBUG ("Name of trace source (if any) in names database: " << Names::FindPath (obj));
+ bool connected = obj->TraceConnectWithoutContext (traceSource, MakeCallback (&ns3::TimeProbe::TraceSink, this));
+ return connected;
+}
+
+void
+TimeProbe::ConnectByPath (std::string path)
+{
+ NS_LOG_FUNCTION (this << path);
+ NS_LOG_DEBUG ("Name of trace source to search for in config database: " << path);
+ Config::ConnectWithoutContext (path, MakeCallback (&ns3::TimeProbe::TraceSink, this));
+}
+
+void
+TimeProbe::TraceSink (Time oldData, Time newData)
+{
+ NS_LOG_FUNCTION (this << oldData.GetSeconds () << newData.GetSeconds ());
+ if (IsEnabled ())
+ {
+ m_output = newData.GetSeconds ();
+ }
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stats/model/time-probe.h Wed Oct 15 07:06:11 2014 -0700
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2011 Bucknell University
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: L. Felipe Perrone (perrone@bucknell.edu)
+ * Tiago G. Rodrigues (tgr002@bucknell.edu)
+ *
+ * Modified by: Mitch Watrous (watrous@u.washington.edu)
+ */
+
+#ifndef TIME_PROBE_H
+#define TIME_PROBE_H
+
+#include "ns3/probe.h"
+#include "ns3/object.h"
+#include "ns3/callback.h"
+#include "ns3/boolean.h"
+#include "ns3/traced-value.h"
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+
+/**
+ * \ingroup probes
+ *
+ * This class is designed to probe an underlying ns3 TraceSource exporting
+ * an ns3::Time. This probe exports a trace source "Output" of type
+ * double, in units of seconds. The Output trace source emits a value when
+ * either the trace source emits a new value, or when SetValue () is called.
+ *
+ * The current value of the probe can be polled with the GetValue ()
+ * method.
+ */
+class TimeProbe : public Probe
+{
+public:
+ /**
+ * \brief Get the type ID.
+ * \return the object TypeId
+ */
+ static TypeId GetTypeId ();
+ TimeProbe ();
+ virtual ~TimeProbe ();
+
+ /**
+ * \return the most recent value (units of seconds)
+ */
+ double GetValue (void) const;
+
+ /**
+ * \param value set the traced Time to a new value
+ */
+ void SetValue (Time value);
+
+ /**
+ * \brief Set a probe value by its name in the Config system
+ *
+ * \param path Config path to access the probe
+ * \param value set the traced Time to a new value
+ */
+ static void SetValueByPath (std::string path, Time value);
+
+ /**
+ * \brief connect to a trace source attribute provided by a given object
+ *
+ * \param traceSource the name of the attribute TraceSource to connect to
+ * \param obj ns3::Object to connect to
+ * \return true if the trace source was successfully connected
+ */
+ virtual bool ConnectByObject (std::string traceSource, Ptr<Object> obj);
+
+ /**
+ * \brief connect to a trace source provided by a config path
+ *
+ * \param path Config path to bind to
+ *
+ * Note, if an invalid path is provided, the probe will not be connected
+ * to anything.
+ */
+ virtual void ConnectByPath (std::string path);
+
+private:
+ /**
+ * \brief Method to connect to an underlying ns3::TraceSource of type Time
+ *
+ * \param oldData previous value of the Time
+ * \param newData new value of the Time
+ */
+ void TraceSink (Time oldData, Time newData);
+
+ TracedValue<double> m_output; //!< Output trace source.
+};
+
+} // namespace ns3
+
+#endif // TIME_PROBE_H
--- a/src/stats/wscript Wed Oct 15 07:00:24 2014 -0700
+++ b/src/stats/wscript Wed Oct 15 07:06:11 2014 -0700
@@ -25,6 +25,7 @@
'model/probe.cc',
'model/boolean-probe.cc',
'model/double-probe.cc',
+ 'model/time-probe.cc',
'model/uinteger-8-probe.cc',
'model/uinteger-16-probe.cc',
'model/uinteger-32-probe.cc',
@@ -58,6 +59,7 @@
'model/probe.h',
'model/boolean-probe.h',
'model/double-probe.h',
+ 'model/time-probe.h',
'model/uinteger-8-probe.h',
'model/uinteger-16-probe.h',
'model/uinteger-32-probe.h',