--- a/SConstruct Sun Mar 18 19:31:32 2007 +0100
+++ b/SConstruct Sun Mar 18 14:06:51 2007 -0700
@@ -140,9 +140,15 @@
'tags.cc',
'pcap-writer.cc',
'trace-writer.cc',
- 'trace-container.cc',
'variable-tracer-test.cc',
- 'stream-tracer-test.cc',
+ 'trace-context.cc',
+ 'trace-resolver.cc',
+ 'callback-trace-source.cc',
+ 'empty-trace-resolver.cc',
+ 'composite-trace-resolver.cc',
+ 'trace-root.cc',
+ ])
+common.add_headers ([
])
common.add_inst_headers([
'buffer.h',
@@ -150,14 +156,19 @@
'trailer.h',
'tags.h',
'packet.h',
- 'ui-variable-tracer.h',
- 'si-variable-tracer.h',
- 'f-variable-tracer.h',
- 'callback-tracer.h',
- 'stream-tracer.h',
+ 'uv-trace-source.h',
+ 'sv-trace-source.h',
+ 'fv-trace-source.h',
'trace-writer.h',
- 'trace-container.h',
'pcap-writer.h',
+ 'callback-trace-source.h',
+ 'trace-context.h',
+ 'trace-resolver.h',
+ 'empty-trace-resolver.h',
+ 'composite-trace-resolver.h',
+ 'array-trace-resolver.h',
+ 'trace-root.h',
+ 'terminal-trace-resolver.h',
])
node = build.Ns3Module ('node', 'src/node')
@@ -193,6 +204,8 @@
'net-device-list.cc',
'queue.cc',
'drop-tail.cc',
+ 'channel.cc',
+ 'node-list.cc',
])
node.add_headers ([
'ipv4-header.h',
@@ -229,10 +242,12 @@
'arp-header.h',
'ipv4-header.h',
'udp-header.h',
+ 'channel.h',
+ 'node-list.h',
])
p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
-ns3.add (p2p)
+#ns3.add (p2p)
p2p.add_deps (['node'])
p2p.add_sources ([
'p2p-net-device.cc',
@@ -251,7 +266,6 @@
'serial-channel.cc',
'serial-phy.cc',
'layer-connector.cc',
- 'channel.cc',
])
serial.add_headers ([
'propagator.h',
@@ -261,7 +275,6 @@
'serial-channel.h',
'serial-phy.h',
'layer-connector.h',
- 'channel.h',
])
@@ -312,7 +325,7 @@
sample_ptr.add_source('main-ptr.cc')
sample_trace = build.Ns3Module('sample-trace', 'samples')
-ns3.add(sample_trace)
+#ns3.add(sample_trace)
sample_trace.add_dep('common')
sample_trace.set_executable()
sample_trace.add_source('main-trace.cc')
@@ -349,7 +362,7 @@
sample_sp2p = build.Ns3Module('sample-simple-p2p', 'samples')
sample_sp2p.set_executable()
-ns3.add(sample_sp2p)
+#n3.add(sample_sp2p)
sample_sp2p.add_deps(['core', 'simulator', 'node', 'p2p'])
sample_sp2p.add_source('main-simple-p2p.cc')
--- a/samples/main-serial-net-device-if.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/samples/main-serial-net-device-if.cc Sun Mar 18 14:06:51 2007 -0700
@@ -31,12 +31,15 @@
#include "ns3/serial-channel.h"
#include "ns3/serial-net-device.h"
#include "ns3/trace-writer.h"
-#include "ns3/trace-container.h"
#include "ns3/drop-tail.h"
#include "ns3/arp-ipv4-interface.h"
#include "ns3/ipv4.h"
+#include "ns3/trace-context.h"
+#include "ns3/udp-socket.h"
+#include "ns3/simulator.h"
+#include "ns3/node-list.h"
+#include "ns3/trace-root.h"
-#include "ns3/pcap-writer.h"
using namespace ns3;
@@ -61,27 +64,74 @@
~Logger () {}
- void Log (std::string const &name, const Packet &p)
+ void Log (TraceContext const &context, const Packet &p)
{
- NS_DEBUG_UNCOND("**** LogEnque ("<< name << " " << &p << ")");
- m_filestr << name << " " << &p << std::endl;
+ NodeList::NodeIndex nodeIndex;
+ context.Get (nodeIndex);
+ m_filestr << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
+ Ipv4::InterfaceIndex interfaceIndex;
+ context.Get (interfaceIndex);
+ m_filestr << "interface=" << interfaceIndex << " ";
+ enum Queue::TraceType type;
+ context.Get (type);
+ switch (type)
+ {
+ case Queue::ENQUEUE:
+ m_filestr << "enqueue";
+ break;
+ case Queue::DEQUEUE:
+ m_filestr << "dequeue";
+ break;
+ case Queue::DROP:
+ m_filestr << "drop";
+ break;
+ }
+ m_filestr << " bytes=" << p.GetSize () << std::endl;
}
protected:
TraceWriter m_tracer;
};
+static void
+GenerateTraffic (UdpSocket *socket, uint32_t size)
+{
+ std::cout << "Node: " << socket->GetNode()->GetId ()
+ << " at=" << Simulator::Now ().GetSeconds () << "s,"
+ << " tx bytes=" << size << std::endl;
+ socket->SendDummy (size);
+ if (size > 50)
+ {
+ Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50);
+ }
+}
+
+static void
+UdpSocketPrinter (UdpSocket *socket, uint32_t size, Ipv4Address from, uint16_t fromPort)
+{
+ std::cout << "Node: " << socket->GetNode()->GetId ()
+ << " at=" << Simulator::Now ().GetSeconds () << "s,"
+ << " rx bytes=" << size << std::endl;
+}
+
+static void
+PrintTraffic (UdpSocket *socket)
+{
+ socket->SetDummyRxCallback (MakeCallback (&UdpSocketPrinter));
+}
+
+
int main (int argc, char *argv[])
{
NS_DEBUG_UNCOND("Serial Net Device Test");
- TraceContainer traceContainerA;
- TraceContainer traceContainerB;
-
// create two nodes and a simple SerialChannel
InternetNode a;
InternetNode b;
- SerialChannel ch;
+ SerialChannel ch = SerialChannel ("Test Channel", 1000, Seconds (0.1));
+
+ NodeList::Add (&a);
+ NodeList::Add (&b);
// create two NetDevices and assign one to each node
// Note: this would normally be done also in conjunction with
@@ -94,8 +144,7 @@
MacAddress addra("00:00:00:00:00:01");
SerialNetDevice neta(&a, addra);
- DropTailQueue dtqa ("a");
- dtqa.RegisterTraces (traceContainerA);
+ DropTailQueue dtqa;
neta.AddQueue(&dtqa);
neta.SetName("a.eth0");
@@ -103,16 +152,15 @@
MacAddress addrb("00:00:00:00:00:02");
SerialNetDevice netb(&b, addrb);
- DropTailQueue dtqb ("b");
- dtqb.RegisterTraces (traceContainerB);
+ DropTailQueue dtqb;
netb.AddQueue(&dtqb);
netb.SetName("b.eth0");
// bind the two NetDevices together by using a simple Channel
// this method changed to do a bidirectional binding
- ch.Attach(&neta);
- ch.Attach(&netb);
+ neta.Attach (&ch);
+ netb.Attach (&ch);
// Some simple prints to see whether it is working
NS_DEBUG_UNCOND("neta.GetMtu() <= " << neta.GetMtu());
@@ -153,6 +201,9 @@
NS_DEBUG_UNCOND("Setting ARP interface to UP");
arpipv4interfacep->SetUp();
+ a.GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
+
+
NS_DEBUG_UNCOND("Adding ARP Interface to InternetNode b");
ArpIpv4Interface* arpipv4interfacepb = new ArpIpv4Interface(&b, &netb);
uint32_t indexB = (&b)->GetIpv4 ()->AddInterface (arpipv4interfacepb);
@@ -170,20 +221,28 @@
NS_DEBUG_UNCOND("Setting ARP interface to UP");
arpipv4interfacepb->SetUp();
+ b.GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.1.1"), 1);
+
+
+ UdpSocket *source = new UdpSocket (&a);
+ UdpSocket *sink = new UdpSocket(&b);
+ sink->Bind (80);
+ source->SetDefaultDestination (Ipv4Address ("10.1.1.2"), 80);
+
Logger logger("serial-net-test.log");
- traceContainerA.SetCallback ("Queue::Enque",
- MakeCallback (&Logger::Log, &logger));
+ TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/*",
+ MakeCallback (&Logger::Log, &logger));
+
+ PrintTraffic (sink);
+ GenerateTraffic (source, 100);
- // create a packet on one node and send it through, reading it
- // on the other node
- Packet p;
+ Simulator::Run ();
- NS_DEBUG_UNCOND("Sending Packet " << &p);
- arpipv4interfacep->Send(p, Ipv4Address("10.1.1.2"));
+ Simulator::Destroy ();
- //neta.Send(p, MacAddress()); // Test that all-zero's MacAddress used
- //netb.Send(p, "00:01:02:03:04:05"); // Dummy function call
+ delete source;
+ delete sink;
return 0;
}
--- a/samples/main-trace.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/samples/main-trace.cc Sun Mar 18 14:06:51 2007 -0700
@@ -9,10 +9,10 @@
using namespace ns3;
-CallbackTracer<Packet> a;
+CallbackTraceSourcer<Packet> a;
UiVariableTracer<unsigned short> b;
StreamTracer c;
-CallbackTracer<double, int> d;
+CallbackTraceSourcer<double, int> d;
void
RegisterAllTraceSources (TraceContainer *container)
--- a/samples/ns-2/simple.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/samples/ns-2/simple.cc Sun Mar 18 14:06:51 2007 -0700
@@ -48,6 +48,7 @@
#include "ns3/internet-node.h"
#include "ns3/serial-channel.h"
+#include "ns3/serial-net-device.h"
#include "ns3/mac-address.h"
#include "ns3/ipv4-address.h"
#include "ns3/arp-ipv4-interface.h"
@@ -60,6 +61,8 @@
#include "ns3/arp-header.h"
#include "ns3/ipv4-header.h"
#include "ns3/udp-header.h"
+#include "ns3/node-list.h"
+#include "ns3/trace-root.h"
using namespace ns3;
@@ -81,23 +84,37 @@
~Tracer () {};
- void LogEnqueue (std::string const &name, const Packet &p)
+ void LogNodeInterface (TraceContext const &context)
{
- m_filestr << name << " que ";
- PrintLlcPacket (p, m_filestr);
+ NodeList::NodeIndex nodeIndex;
+ context.Get (nodeIndex);
+ m_filestr << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
+ Ipv4::InterfaceIndex interfaceIndex;
+ context.Get (interfaceIndex);
+ m_filestr << "interface=" << interfaceIndex << " ";
+ }
+
+
+ void LogEnqueue (TraceContext const &context, const Packet &p)
+ {
+ LogNodeInterface (context);
+ m_filestr << " que p=" << p.GetUid ();
+ //PrintLlcPacket (p, m_filestr);
m_filestr << std::endl;
}
- void LogDequeue (std::string const &name, const Packet &p)
+ void LogDequeue (TraceContext const &context, const Packet &p)
{
- m_filestr << name << " deq ";
- PrintLlcPacket (p, m_filestr);
+ LogNodeInterface (context);
+ m_filestr << " deq p=" << p.GetUid ();
+ //PrintLlcPacket (p, m_filestr);
m_filestr << std::endl;
}
- void LogDrop (std::string const &name, const Packet &p)
+ void LogDrop (TraceContext const &context, const Packet &p)
{
- m_filestr << name << " dro ";
- PrintLlcPacket (p, m_filestr);
+ LogNodeInterface (context);
+ m_filestr << " dro p=" << p.GetUid ();
+ //PrintLlcPacket (p, m_filestr);
m_filestr << std::endl;
}
@@ -199,7 +216,7 @@
static SerialChannel *
AddDuplexLink(
- std::string &name,
+ std::string name,
uint64_t bps,
uint32_t delay,
InternetNode* a,
@@ -207,12 +224,8 @@
const MacAddress& macaddra,
InternetNode* b,
const Ipv4Address& addrb,
- const MacAddress& macaddrb,
- // const Rate& rate,
- // const Time& delay,
- TraceContainer &traceContainer)
+ const MacAddress& macaddrb)
{
- std::string qName;
SerialChannel* channel = new SerialChannel(name, bps, MilliSeconds(delay));
// Duplex link is assumed to be subnetted as a /30
@@ -220,30 +233,24 @@
Ipv4Mask netmask("255.255.255.252");
assert(netmask.IsMatch(addra,addrb));
- qName = name + "::Queue A";
- DropTailQueue* dtqa = new DropTailQueue(qName);
- dtqa->RegisterTraces (traceContainer);
+ DropTailQueue* dtqa = new DropTailQueue();
SerialNetDevice* neta = new SerialNetDevice(a, macaddra);
neta->AddQueue(dtqa);
Ipv4Interface *interfA = new ArpIpv4Interface (a, neta);
uint32_t indexA = a->GetIpv4 ()->AddInterface (interfA);
- channel->Attach (neta);
neta->Attach (channel);
interfA->SetAddress (addra);
interfA->SetNetworkMask (netmask);
interfA->SetUp ();
- qName = name + "::Queue B";
- DropTailQueue* dtqb = new DropTailQueue(qName);
- dtqb->RegisterTraces (traceContainer);
+ DropTailQueue* dtqb = new DropTailQueue();
SerialNetDevice* netb = new SerialNetDevice(b, macaddrb);
netb->AddQueue(dtqb);
Ipv4Interface *interfB = new ArpIpv4Interface (b, netb);
uint32_t indexB = b->GetIpv4 ()->AddInterface (interfB);
- channel->Attach (netb);
netb->Attach (channel);
interfB->SetAddress (addrb);
@@ -262,19 +269,6 @@
return channel;
}
-static void
-SetupTrace (TraceContainer &container, Tracer &tracer)
-{
- container.SetCallback ("Queue::Enqueue",
- MakeCallback (&Tracer::LogEnqueue, &tracer));
-
- container.SetCallback ("Queue::Dequeue",
- MakeCallback (&Tracer::LogDequeue, &tracer));
-
- container.SetCallback ("Queue::Drop",
- MakeCallback (&Tracer::LogDrop, &tracer));
-
-}
int main (int argc, char *argv[])
{
@@ -295,37 +289,27 @@
InternetNode *n2 = new InternetNode();
InternetNode *n3 = new InternetNode();
- TraceContainer traceContainer;
+ NodeList::Add (n0);
+ NodeList::Add (n1);
+ NodeList::Add (n2);
+ NodeList::Add (n3);
n0->SetName(std::string("Node 0"));
n1->SetName(std::string("Node 1"));
n2->SetName(std::string("Node 2"));
n3->SetName(std::string("Node 3"));
- Tracer tracer("serial-net-test.log");
-
- std::string channelName;
-
- channelName = "Channel 1";
- SerialChannel* ch1 = AddDuplexLink (channelName, 5000000, 2,
+ SerialChannel* ch1 = AddDuplexLink ("Channel 1", 5000000, 2,
n0, Ipv4Address("10.1.1.1"), MacAddress("00:00:00:00:00:01"),
- n2, Ipv4Address("10.1.1.2"), MacAddress("00:00:00:00:00:02"),
- traceContainer);
- SetupTrace (traceContainer, tracer);
+ n2, Ipv4Address("10.1.1.2"), MacAddress("00:00:00:00:00:02"));
+
+ SerialChannel* ch2 = AddDuplexLink ("Channel 2", 5000000, 2,
+ n1, Ipv4Address("10.1.2.1"), MacAddress("00:00:00:00:00:03"),
+ n2, Ipv4Address("10.1.2.2"), MacAddress("00:00:00:00:00:04"));
- channelName = "Channel 2";
- SerialChannel* ch2 = AddDuplexLink (channelName, 5000000, 2,
- n1, Ipv4Address("10.1.2.1"), MacAddress("00:00:00:00:00:03"),
- n2, Ipv4Address("10.1.2.2"), MacAddress("00:00:00:00:00:04"),
- traceContainer);
- SetupTrace (traceContainer, tracer);
-
- channelName = "Channel 3";
- SerialChannel* ch3 = AddDuplexLink (channelName, 1500000, 10,
+ SerialChannel* ch3 = AddDuplexLink ("Channel 3", 1500000, 10,
n2, Ipv4Address("10.1.3.1"), MacAddress("00:00:00:00:00:05"),
- n3, Ipv4Address("10.1.3.2"), MacAddress("00:00:00:00:00:06"),
- traceContainer);
- SetupTrace (traceContainer, tracer);
+ n3, Ipv4Address("10.1.3.2"), MacAddress("00:00:00:00:00:06"));
UdpSocket *source0 = new UdpSocket (n0);
UdpSocket *source3 = new UdpSocket (n3);
@@ -341,6 +325,15 @@
n0->GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
n3->GetIpv4()->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
+ Tracer tracer("serial-net-test.log");
+ TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/enqueue",
+ MakeCallback (&Tracer::LogEnqueue, &tracer));
+ TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/dequeue",
+ MakeCallback (&Tracer::LogDequeue, &tracer));
+ TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/drop",
+ MakeCallback (&Tracer::LogDrop, &tracer));
+
+
PrintTraffic (sink3);
GenerateTraffic (source0, 100);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/array-trace-resolver.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,138 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ARRAY_TRACE_RESOLVER_H
+#define ARRAY_TRACE_RESOLVER_H
+
+#include <stdint.h>
+#include <string>
+#include "ns3/callback.h"
+#include "trace-resolver.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to offer trace resolution for an array of objects.
+ * \ingroup tracing
+ */
+template <typename T>
+class ArrayTraceResolver : public TraceResolver
+{
+public:
+ /**
+ * \brief array index trace context
+ *
+ * During namespace parsing, ns3::ArrayTraceResolver will
+ * embed an instance of this class in the TraceContext
+ * associated to every child object of the object stored
+ * at the index.
+ *
+ * The reason why this class exists is to ensure that we
+ * need to ensure that we can store a unique type as context
+ * into the TraceContext associated to this trace resolver.
+ */
+ class Index
+ {
+ public:
+ Index ();
+ Index (uint32_t index);
+ /**
+ * The Index is automatically convertible to the
+ * uin32_t type such that it really behaves like a uint32_t
+ * array index for the user.
+ *
+ * \returns the index itself
+ */
+ operator uint32_t ();
+ private:
+ uint32_t m_index;
+ };
+ /**
+ * \param context trace context associated to this trace resolver
+ * \param getSize callback which returns dynamically the size of underlying array
+ * \param get callback which returns any element in the underlying array
+ *
+ * Construct a trace resolver which can match any input integer
+ * against an element in an array. The array is accessed using a
+ * pair of callbacks. It is the responsability of the user to
+ * provide two such callbacks whose job is to adapt the array
+ * API to the resolver needs. Each element of the array is expected
+ * to provide a method named CreateTraceResolver which takes as
+ * only argument a reference to a const TraceContext and returns
+ * a pointer to a TraceResolver. i.e. the signature is:
+ * TraceResolver * (*) (TraceContext const &)
+ */
+ ArrayTraceResolver (TraceContext const &context,
+ Callback<uint32_t> getSize,
+ Callback<T *, uint32_t> get);
+private:
+ virtual TraceResolverList DoLookup (std::string id) const;
+ Callback<uint32_t> m_getSize;
+ Callback<T *, uint32_t> m_get;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+ArrayTraceResolver<T>::Index::Index ()
+ : m_index ()
+{}
+template <typename T>
+ArrayTraceResolver<T>::Index::Index (uint32_t index)
+ : m_index (index)
+{}
+template <typename T>
+ArrayTraceResolver<T>::Index::operator uint32_t ()
+{
+ return m_index;
+}
+
+template <typename T>
+ArrayTraceResolver<T>::ArrayTraceResolver (TraceContext const &context,
+ Callback<uint32_t> getSize,
+ Callback<T *, uint32_t> get)
+ : TraceResolver (context),
+ m_getSize (getSize),
+ m_get (get)
+{}
+template <typename T>
+TraceResolver::TraceResolverList
+ArrayTraceResolver<T>::DoLookup (std::string id) const
+{
+ TraceResolverList list;
+ if (id == "*")
+ {
+ for (uint32_t i = 0; i < m_getSize (); i++)
+ {
+ TraceContext context = GetContext ();
+ typename ArrayTraceResolver<T>::Index index = typename ArrayTraceResolver<T>::Index (i);
+ context.Add (index);
+ list.push_back (m_get (i)->CreateTraceResolver (context));
+ }
+ }
+ return list;
+}
+
+
+}//namespace ns3
+
+#endif /* ARRAY_TRACE_RESOLVER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/callback-trace-source.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,95 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "callback-trace-source.h"
+#include "ns3/test.h"
+
+namespace ns3 {
+
+class CallbackTraceSourceTest : public Test
+{
+public:
+ CallbackTraceSourceTest ();
+ virtual ~CallbackTraceSourceTest ();
+ virtual bool RunTests (void);
+private:
+ void CbOne (TraceContext const &context, uint8_t a, double b);
+ void CbTwo (TraceContext const &context, uint8_t a, double b);
+
+ bool m_one;
+ bool m_two;
+};
+
+CallbackTraceSourceTest::CallbackTraceSourceTest ()
+ : Test ("CallbackTraceSource")
+{}
+CallbackTraceSourceTest::~CallbackTraceSourceTest ()
+{}
+void
+CallbackTraceSourceTest::CbOne (TraceContext const &context, uint8_t a, double b)
+{
+ m_one = true;
+}
+void
+CallbackTraceSourceTest::CbTwo (TraceContext const &context, uint8_t a, double b)
+{
+ m_two = true;
+}
+bool
+CallbackTraceSourceTest::RunTests (void)
+{
+ bool ok = true;
+ TraceContext ctx;
+
+ CallbackTraceSource<uint8_t,double> trace;
+ trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this), ctx);
+ trace.AddCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this), ctx);
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ if (!m_one || !m_two)
+ {
+ ok = false;
+ }
+ trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbOne, this));
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ if (m_one || !m_two)
+ {
+ ok = false;
+ }
+ trace.RemoveCallback (MakeCallback (&CallbackTraceSourceTest::CbTwo, this));
+ m_one = false;
+ m_two = false;
+ trace (1, 2);
+ if (m_one || m_two)
+ {
+ ok = false;
+ }
+
+ return ok;
+}
+
+CallbackTraceSourceTest g_callbackTraceTest;
+
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/callback-trace-source.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,163 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006,2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef CALLBACK_TRACE_H
+#define CALLBACK_TRACE_H
+
+#include <list>
+#include "ns3/callback.h"
+#include "ns3/fatal-error.h"
+#include "trace-context.h"
+
+namespace ns3 {
+
+
+/**
+ * \brief log arbitrary number of parameters to a matching ns3::Callback
+ * \ingroup tracing
+ *
+ * Whenever operator () is invoked on this class, the call and its arguments
+ * are forwarded to the internal matching ns3::Callback.
+ */
+template<typename T1 = empty, typename T2 = empty,
+ typename T3 = empty, typename T4 = empty>
+class CallbackTraceSource {
+public:
+ CallbackTraceSource ();
+ void AddCallback (CallbackBase const & callback, TraceContext const & context);
+ void RemoveCallback (CallbackBase const & callback);
+ void operator() (void);
+ void operator() (T1 a1);
+ void operator() (T1 a1, T2 a2);
+ void operator() (T1 a1, T2 a2, T3 a3);
+ void operator() (T1 a1, T2 a2, T3 a3, T4 a4);
+
+private:
+ typedef std::list<Callback<void,TraceContext const &,T1,T2,T3,T4> > CallbackList;
+ TraceContext m_context;
+ CallbackList m_callbackList;
+};
+
+}; // namespace ns3
+
+// implementation below.
+
+namespace ns3 {
+
+template<typename T1, typename T2,
+ typename T3, typename T4>
+CallbackTraceSource<T1,T2,T3,T4>::CallbackTraceSource ()
+ : m_callbackList ()
+{}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::AddCallback (CallbackBase const & callback,
+ TraceContext const &context)
+{
+ Callback<void,TraceContext const &,T1,T2,T3,T4> cb;
+ if (!cb.CheckType (callback))
+ {
+ NS_FATAL_ERROR ("Incompatible callbacks. (feed to \"c++filt -t\"): got=\"" <<
+ typeid (callback).name () << "\" expected=\"" <<
+ typeid (cb).name () << "\"");
+ }
+ m_context.Add (context);
+ cb = *static_cast<Callback<void,TraceContext const &,T1,T2,T3,T4> const *> (&callback);
+ m_callbackList.push_back (cb);
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::RemoveCallback (CallbackBase const & callback)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); /* empty */)
+ {
+ if ((*i).IsEqual (callback))
+ {
+ i = m_callbackList.erase (i);
+ }
+ else
+ {
+ i++;
+ }
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (void)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1, a2);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1, a2, a3);
+ }
+}
+template<typename T1, typename T2,
+ typename T3, typename T4>
+void
+CallbackTraceSource<T1,T2,T3,T4>::operator() (T1 a1, T2 a2, T3 a3, T4 a4)
+{
+ for (typename CallbackList::iterator i = m_callbackList.begin ();
+ i != m_callbackList.end (); i++)
+ {
+ (*i) (m_context, a1, a2, a3, a4);
+ }
+}
+
+}//namespace ns3
+
+#endif /* CALLBACK_TRACE_H */
--- a/src/common/callback-tracer.h Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2005,2006 INRIA
- * All rights reserved.
- *
- * 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef CALLBACK_TRACER_H
-#define CALLBACK_TRACER_H
-
-#include "ns3/callback.h"
-
-namespace ns3 {
-
-class CallbackTracerBase {
-public:
- virtual ~CallbackTracerBase () {}
- bool CheckCallbackType (CallbackBase const&callback)
- {
- return CheckType (callback);
- }
-private:
- virtual bool CheckType (CallbackBase const&callback) = 0;
-};
-
-
-/**
- * \brief log arbitrary number of parameters to a matching ns3::Callback
- *
- * Whenever operator () is invoked on this class, the call and its arguments
- * are forwarded to the internal matching ns3::Callback.
- */
-template<typename T1 = empty, typename T2 = empty,
- typename T3 = empty, typename T4 = empty,
- typename T5 = empty>
-class CallbackTracer : public CallbackTracerBase {
-public:
- CallbackTracer ()
- : m_callback () {}
- void SetCallback (Callback<void,T1,T2,T3,T4,T5> callback)
- {
- m_callback = callback;
- }
- void operator() (void)
- {
- if (!m_callback.IsNull ())
- {
- m_callback ();
- }
- }
- void operator() (T1 a1)
- {
- if (!m_callback.IsNull ())
- {
- m_callback (a1);
- }
- }
- void operator() (T1 a1, T2 a2)
- {
- if (!m_callback.IsNull ())
- {
- m_callback (a1,a2);
- }
- }
- void operator() (T1 a1, T2 a2, T3 a3)
- {
- if (!m_callback.IsNull ())
- {
- m_callback (a1,a2,a3);
- }
- }
- void operator() (T1 a1, T2 a2, T3 a3, T4 a4)
- {
- if (!m_callback.IsNull ())
- {
- m_callback (a1,a2,a3,a4);
- }
- }
- void operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5)
- {
- if (!m_callback.IsNull ())
- {
- m_callback (a1,a2,a3,a4,a5);
- }
- }
-
-private:
- virtual bool CheckType (CallbackBase const&callback)
- {
- return m_callback.CheckType (callback);
- }
- Callback<void,T1,T2,T3,T4,T5> m_callback;
-};
-
-}; // namespace ns3
-
-#endif /* CALLBACK_TRACER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/composite-trace-resolver.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,331 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "composite-trace-resolver.h"
+
+namespace ns3 {
+
+CompositeTraceResolver::CompositeTraceResolver (TraceContext const &context)
+ : TraceResolver (context)
+{}
+
+CompositeTraceResolver::~CompositeTraceResolver ()
+{}
+
+void
+CompositeTraceResolver::DoAdd (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver,
+ TraceContext const &context)
+{
+ struct CallbackTraceSourceItem item;
+ item.name = name;
+ item.createResolver = createResolver;
+ item.context = context;
+ m_items.push_back (item);
+}
+
+TraceResolver::TraceResolverList
+CompositeTraceResolver::DoLookup (std::string id) const
+{
+ if (id == "*")
+ {
+ TraceResolver::TraceResolverList list;
+ for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ list.push_back (i->createResolver (i->context));
+ }
+ return list;
+ }
+ std::string::size_type start, end;
+ start = id.find_first_of ("(", 0);
+ end = id.find_first_of (")", 0);
+ if (start != 0 || end != (id.size ()-1))
+ {
+ for (TraceItems::const_iterator i = m_items.begin (); i != m_items.end (); i++)
+ {
+ if (i->name == id)
+ {
+ TraceResolver::TraceResolverList list;
+ list.push_back (i->createResolver (i->context));
+ return list;
+ }
+ }
+ }
+ std::list<std::string> names;
+ std::string alternatives = std::string (id, start+1, end-1);
+ std::string::size_type next, cur;
+ next = 0;
+ cur = 0;
+ while (true)
+ {
+ std::string element;
+ next = alternatives.find ("|", cur);
+ if (next == std::string::npos)
+ {
+ element = std::string (alternatives, cur, alternatives.size ());
+ names.push_back (element);
+ break;
+ }
+ element = std::string (alternatives, cur, next);
+ names.push_back (element);
+ cur = next + 1;
+ }
+ TraceResolver::TraceResolverList list;
+ for (std::list<std::string>::const_iterator i = names.begin (); i != names.end (); i++)
+ {
+ for (TraceItems::const_iterator j = m_items.begin (); j != m_items.end (); j++)
+ {
+ if (j->name == *i)
+ {
+ list.push_back (j->createResolver (j->context));
+ break;
+ }
+ }
+ }
+ return list;
+}
+
+}//namespace ns3
+
+#ifdef RUN_SELF_TESTS
+
+#include "ns3/test.h"
+
+namespace ns3 {
+
+class CompositeTraceResolverTest : public Test
+{
+public:
+ enum TraceSources {
+ TEST_TRACE_DOUBLEA,
+ TEST_TRACE_DOUBLEB,
+ TEST_TRACE_SUBRESOLVER,
+ };
+ enum SubTraceSources {
+ TEST_SUBTRACE_INT,
+ };
+ CompositeTraceResolverTest ();
+ virtual ~CompositeTraceResolverTest ();
+ virtual bool RunTests (void);
+private:
+ void TraceDouble (TraceContext const &context, double v);
+ void TraceInt (TraceContext const &context, int v);
+ TraceResolver *CreateSubResolver (TraceContext const &context);
+
+
+ bool m_gotDoubleA;
+ bool m_gotDoubleB;
+ CallbackTraceSource<int> m_traceInt;
+ bool m_gotInt;
+};
+
+CompositeTraceResolverTest::CompositeTraceResolverTest ()
+ : Test ("CompositeTraceResolver")
+{}
+CompositeTraceResolverTest::~CompositeTraceResolverTest ()
+{}
+void
+CompositeTraceResolverTest::TraceDouble (TraceContext const &context, double v)
+{
+ enum CompositeTraceResolverTest::TraceSources source;
+ context.Get (source);
+ switch (source)
+ {
+ case TEST_TRACE_DOUBLEA:
+ m_gotDoubleA = true;
+ break;
+ case TEST_TRACE_DOUBLEB:
+ m_gotDoubleB = true;
+ break;
+ default:
+ NS_FATAL_ERROR ("should not get any other trace source in this sink");
+ break;
+ }
+
+}
+
+void
+CompositeTraceResolverTest::TraceInt (TraceContext const &context, int v)
+{
+ m_gotInt = true;
+}
+
+TraceResolver *
+CompositeTraceResolverTest::CreateSubResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *subresolver = new CompositeTraceResolver (context);
+ subresolver->Add ("trace-int", m_traceInt, TEST_SUBTRACE_INT);
+ return subresolver;
+}
+bool
+CompositeTraceResolverTest::RunTests (void)
+{
+ bool ok = true;
+
+ CallbackTraceSource<double> traceDoubleA;
+ CallbackTraceSource<double> traceDoubleB;
+ TraceContext context;
+
+ CompositeTraceResolver resolver (context) ;
+
+ resolver.Add ("trace-double-a", traceDoubleA, TEST_TRACE_DOUBLEA);
+ resolver.Add ("trace-double-b", traceDoubleB, TEST_TRACE_DOUBLEB);
+
+ resolver.Connect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ if (!m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+ m_gotDoubleA = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || !m_gotDoubleB)
+ {
+ ok = false;
+ }
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+
+ resolver.Disconnect ("/*", MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+
+ resolver.Connect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+ resolver.Disconnect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ resolver.Connect ("/(trace-double-a)",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+ resolver.Disconnect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+
+ resolver.Connect ("/(trace-double-a|trace-double-b)",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (!m_gotDoubleA || !m_gotDoubleB)
+ {
+ ok = false;
+ }
+ resolver.Disconnect ("/trace-double-a",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (m_gotDoubleA || !m_gotDoubleB)
+ {
+ ok = false;
+ }
+
+
+ resolver.Disconnect ("/(trace-double-a|trace-double-b)",
+ MakeCallback (&CompositeTraceResolverTest::TraceDouble, this));
+ m_gotDoubleA = false;
+ m_gotDoubleB = false;
+ traceDoubleA (0);
+ traceDoubleB (0);
+ if (m_gotDoubleA || m_gotDoubleB)
+ {
+ ok = false;
+ }
+
+ resolver.Add ("subresolver",
+ MakeCallback (&CompositeTraceResolverTest::CreateSubResolver, this),
+ TEST_TRACE_SUBRESOLVER);
+
+ resolver.Connect ("/subresolver/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+ m_gotInt = false;
+ m_traceInt (1);
+ if (!m_gotInt)
+ {
+ ok = false;
+ }
+
+ resolver.Disconnect ("/subresolver/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+ m_gotInt = false;
+ m_traceInt (1);
+ if (m_gotInt)
+ {
+ ok = false;
+ }
+
+ resolver.Connect ("/*/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+ m_gotInt = false;
+ m_traceInt (1);
+ if (!m_gotInt)
+ {
+ ok = false;
+ }
+
+ resolver.Disconnect ("/subresolver/trace-int",
+ MakeCallback (&CompositeTraceResolverTest::TraceInt, this));
+ m_gotInt = false;
+ m_traceInt (1);
+ if (m_gotInt)
+ {
+ ok = false;
+ }
+
+
+
+
+ return ok;
+}
+
+static CompositeTraceResolverTest g_compositeTraceResolverTest;
+
+}//namespace ns3
+
+
+#endif /* RUN_SELF_TESTS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/composite-trace-resolver.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,211 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef COMPOSITE_TRACE_RESOLVER_H
+#define COMPOSITE_TRACE_RESOLVER_H
+
+#include "ns3/callback.h"
+#include "trace-resolver.h"
+#include "callback-trace-source.h"
+#include "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "fv-trace-source.h"
+#include "terminal-trace-resolver.h"
+
+namespace ns3 {
+
+/**
+ * \brief a helper class to aggregate contained TraceResolver and other trace sources.
+ * \ingroup tracing
+ */
+class CompositeTraceResolver : public TraceResolver
+{
+public:
+ CompositeTraceResolver (TraceContext const &context);
+ virtual ~CompositeTraceResolver ();
+ /**
+ * \param name name of trace source
+ * \param trace a callback trace source
+ * \param context the context associated to this trace source
+ *
+ * Add a callback trace source in this resolver. This trace
+ * source will match the name specified during namespace
+ * resolution. The TraceContext of this trace source will also
+ * be automatically extended to contain the input context.
+ */
+ template <typename T1, typename T2,
+ typename T3, typename T4,
+ typename T>
+ void Add (std::string name,
+ CallbackTraceSource<T1,T2,T3,T4> &trace, T const &context);
+ /**
+ * \param name name of trace source
+ * \param trace a signed variable trace source
+ * \param context the context associated to this trace source
+ *
+ * Add a signed variable trace source in this resolver.
+ * This trace source will match the name specified during namespace
+ * resolution. The TraceContext of this trace source will also
+ * be automatically extended to contain the input context.
+ */
+ template <typename T>
+ void Add (std::string name,
+ SVTraceSource<T> &trace, T const &context);
+ /**
+ * \param name name of trace source
+ * \param trace an unsigned variable trace source
+ * \param context the context associated to this trace source
+ *
+ * Add an unsigned variable trace source in this resolver.
+ * This trace source will match the name specified during namespace
+ * resolution. The TraceContext of this trace source will also
+ * be automatically extended to contain the input context.
+ */
+ template <typename T>
+ void Add (std::string name,
+ UVTraceSource<T> &trace, T const &context);
+ /**
+ * \param name name of trace source
+ * \param trace a floating-point variable trace source
+ * \param context the context associated to this trace source
+ *
+ * Add a floating-point variable trace source in this resolver.
+ * This trace source will match the name specified during namespace
+ * resolution. The TraceContext of this trace source will also
+ * be automatically extended to contain the input context.
+ */
+ template <typename T>
+ void Add (std::string name,
+ FVTraceSource<T> &trace, T const &context);
+
+ /**
+ * \param name name of child trace resolver
+ * \param createResolver a trace resolver constructor
+ * \param context the context associated to this entry
+ *
+ * Add a child trace resolver to this resolver. This child
+ * trace resolver will match the name specified during
+ * namespace resolution. When this happens, the constructor
+ * will be invoked to create the child trace resolver and
+ * the associated TraceContext will be automatically extended
+ * to contain the input context.
+ */
+ template <typename T>
+ void Add (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver,
+ T const &context);
+private:
+ template <typename SOURCE, typename CONTEXT>
+ void DoAddTraceSource (std::string name,
+ SOURCE &traceSource, CONTEXT const &context);
+ template <typename SOURCE>
+ static TraceResolver *CreateTerminalTraceResolver (SOURCE *trace,
+ TraceContext const &context);
+ void DoAdd (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver,
+ TraceContext const &context);
+ virtual TraceResolverList DoLookup (std::string id) const;
+
+ struct CallbackTraceSourceItem
+ {
+ std::string name;
+ Callback<TraceResolver *,TraceContext const &> createResolver;
+ TraceContext context;
+ };
+
+ typedef std::list<struct CallbackTraceSourceItem> TraceItems;
+ TraceItems m_items;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename SOURCE, typename CONTEXT>
+void
+CompositeTraceResolver::DoAddTraceSource (std::string name,
+ SOURCE &traceSource, CONTEXT const &context)
+{
+ TraceContext traceContext = GetContext ();
+ traceContext.Add (context);
+ TraceResolver *(*create) (SOURCE *trace, TraceContext const &context);
+ create = &CompositeTraceResolver::CreateTerminalTraceResolver<SOURCE>;
+ Callback<TraceResolver *,TraceContext const &> createResolver =
+ MakeBoundCallback (create, &traceSource);
+ DoAdd (name, createResolver, traceContext);
+}
+
+template <typename SOURCE>
+TraceResolver *
+CompositeTraceResolver::CreateTerminalTraceResolver (SOURCE *traceSource,
+ TraceContext const &context)
+{
+ return new TerminalTraceResolver<SOURCE> (*traceSource, context);
+}
+
+
+
+
+template <typename T1, typename T2,
+ typename T3, typename T4,
+ typename T>
+void
+CompositeTraceResolver::Add (std::string name,
+ CallbackTraceSource<T1,T2,T3,T4> &trace,
+ T const &context)
+{
+ DoAddTraceSource (name, trace, context);
+}
+template <typename T>
+void
+CompositeTraceResolver::Add (std::string name,
+ SVTraceSource<T> &trace, T const &context)
+{
+ DoAddTraceSource (name, trace, context);
+}
+template <typename T>
+void
+CompositeTraceResolver::Add (std::string name,
+ UVTraceSource<T> &trace, T const &context)
+{
+ DoAddTraceSource (name, trace, context);
+}
+template <typename T>
+void
+CompositeTraceResolver::Add (std::string name,
+ FVTraceSource<T> &trace, T const &context)
+{
+ DoAddTraceSource (name, trace, context);
+}
+template <typename T>
+void
+CompositeTraceResolver::Add (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver,
+ T const &context)
+{
+ TraceContext traceContext = GetContext ();
+ traceContext.Add (context);
+ DoAdd (name, createResolver, traceContext);
+}
+
+
+}//namespace ns3
+
+#endif /* COMPOSITE_TRACE_RESOLVER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/empty-trace-resolver.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,25 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "empty-trace-resolver.h"
+
+ns3::EmptyTraceResolver::EmptyTraceResolver (TraceContext const &context)
+ : TraceResolver (context)
+{}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/empty-trace-resolver.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,52 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef EMPTY_TRACE_RESOLVER_H
+#define EMPTY_TRACE_RESOLVER_H
+
+#include "trace-resolver.h"
+
+namespace ns3 {
+
+class TraceContext;
+
+/**
+ * \brief a TraceResolver instance which does not resolve anything.
+ * \ingroup tracing
+ *
+ * Trying to resolve against this class will yield no matches and no
+ * connections. Returning an instance of this class from a
+ * CreateTraceResolver method is a hand way of not implementing
+ * any Tracing code.
+ */
+class EmptyTraceResolver : public TraceResolver
+{
+public:
+ /**
+ * \param o necessary context for this class.
+ *
+ * The only constructor exported by this class.
+ */
+ EmptyTraceResolver (TraceContext const &o);
+};
+
+}//namespace ns3
+
+#endif /* EMPTY_TRACE_RESOLVER_H */
--- a/src/common/f-variable-tracer.h Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef F_VARIABLE_TRACER_H
-#define F_VARIABLE_TRACER_H
-
-#include "ns3/callback.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class FVariableTracerBase {
-public:
- typedef Callback<void,double, double> ChangeNotifyCallback;
-
- FVariableTracerBase () {}
- FVariableTracerBase (FVariableTracerBase const &o) {}
- FVariableTracerBase &operator = (FVariableTracerBase const &o) {
- return *this;
- }
-
- ~FVariableTracerBase () {}
-
- void setCallback(ChangeNotifyCallback callback) {
- m_callback = callback;
- }
-protected:
- void notify (double oldVal, double newVal) {
- if (oldVal != newVal && !m_callback.IsNull ())
- {
- m_callback (oldVal, newVal);
- }
- }
-private:
- ChangeNotifyCallback m_callback;
-};
-
-
-}; // namespace ns3
-
-#endif /* F_VARIABLE_TRACER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/fv-trace-source.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,67 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef F_VARIABLE_TRACER_H
+#define F_VARIABLE_TRACER_H
+
+#include "callback-trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class FVTraceSourceBase {
+public:
+ typedef CallbackTraceSource<double, double> ChangeNotifyCallback;
+
+ FVTraceSourceBase () {}
+ FVTraceSourceBase (FVTraceSourceBase const &o) {}
+ FVTraceSourceBase &operator = (FVTraceSourceBase const &o) {
+ return *this;
+ }
+
+ ~FVTraceSourceBase () {}
+
+ void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+ m_callback.AddCallback (callback, context);
+ }
+ void RemoveCallback (CallbackBase const & callback) {
+ m_callback.RemoveCallback (callback);
+ }
+protected:
+ void notify (double oldVal, double newVal) {
+ if (oldVal != newVal)
+ {
+ m_callback (oldVal, newVal);
+ }
+ }
+private:
+ ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class FVTraceSource : public FVTraceSourceBase
+{
+public:
+};
+
+}; // namespace ns3
+
+#endif /* F_VARIABLE_TRACER_H */
--- a/src/common/si-variable-tracer.h Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef SI_VARIABLE_TRACER_H
-#define SI_VARIABLE_TRACER_H
-
-#include "ns3/callback.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class SiVariableTracerBase {
-public:
- typedef Callback<void,int64_t, int64_t> ChangeNotifyCallback;
-
- SiVariableTracerBase () {}
- SiVariableTracerBase (SiVariableTracerBase const &o) {}
- SiVariableTracerBase &operator = (SiVariableTracerBase const &o) {
- return *this;
- }
-
- ~SiVariableTracerBase () {}
-
- void SetCallback(ChangeNotifyCallback callback) {
- m_callback = callback;
- }
-protected:
- void Notify (int64_t oldVal, int64_t newVal) {
- if (oldVal != newVal && !m_callback.IsNull ())
- {
- m_callback (oldVal, newVal);
- }
- }
-private:
- ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class UiVariableTracer;
-
-
-/**
- * \brief trace variables of type "signed integer"
- *
- * This template class implements a POD type: it
- * behaves like any other variable of type "signed integer"
- * except that it also reports any changes to its
- * value with its internal callback.
- *
- * To instantiate a 32-bit signed variable (to store
- * a TCP counter for example), you would create a variable of type
- * ns3::UiVariableTracer<int32_t> :
- \code
- #include <stdint.h>
- #include "ns3/si-traced-variable.tcc"
-
- ns3::SiVariableTracer<uint16_t> var;
- \endcode
- * and you would use it like any other variable of type int32_t:
- \code
- var += 12;
- var = 10;
- var = -10;
- \endcode
- */
-template <typename T>
-class SiVariableTracer : public SiVariableTracerBase {
-public:
- SiVariableTracer ()
- : m_var (0)
- {}
- SiVariableTracer (T const &var)
- : m_var (var)
- {}
-
- SiVariableTracer &operator = (SiVariableTracer const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- SiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- SiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- SiVariableTracer &operator++ () {
- Assign (Get () + 1);
- return *this;
- }
- SiVariableTracer &operator-- () {
- Assign (Get () - 1);
- return *this;
- }
- SiVariableTracer operator++ (int) {
- SiVariableTracer old (*this);
- ++*this;
- return old;
- }
- SiVariableTracer operator-- (int) {
- SiVariableTracer old (*this);
- --*this;
- return old;
- }
- operator T () const {
- return Get ();
- }
-
-
- void Assign (T var) {
- Notify (m_var, var);
- m_var = var;
- }
- T Get (void) const {
- return m_var;
- }
-
-private:
- T m_var;
-};
-
-template <typename T>
-SiVariableTracer<T> &operator += (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () + rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator -= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () - rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator *= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () * rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator /= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () / rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator <<= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () << rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator >>= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () >> rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator &= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () & rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator |= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () | rhs.Get ());
- return lhs;
-}
-template <typename T>
-SiVariableTracer<T> &operator ^= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs.Get ());
- return lhs;
-}
-
-
-template <typename T, typename U>
-SiVariableTracer<T> &operator += (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () + rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator -= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () - rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator *= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () * rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator /= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () / rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator <<= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () << rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator >>= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () >> rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator &= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () & rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator |= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () | rhs);
- return lhs;
-}
-template <typename T, typename U>
-SiVariableTracer<T> &operator ^= (SiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs);
- return lhs;
-}
-
-}; // namespace ns3
-
-#endif /* SI_VARIABLE_TRACER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/sv-trace-source.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,242 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SV_TRACE_SOURCE_H
+#define SV_TRACE_SOURCE_H
+
+#include "callback-trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class SVTraceSourceBase {
+public:
+ typedef CallbackTraceSource<int64_t, int64_t> ChangeNotifyCallback;
+
+ SVTraceSourceBase () {}
+ SVTraceSourceBase (SVTraceSourceBase const &o) {}
+ SVTraceSourceBase &operator = (SVTraceSourceBase const &o) {
+ return *this;
+ }
+
+ ~SVTraceSourceBase () {}
+
+ void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+ m_callback.AddCallback (callback, context);
+ }
+ void RemoveCallback (CallbackBase const & callback) {
+ m_callback.RemoveCallback (callback);
+ }
+protected:
+ void Notify (int64_t oldVal, int64_t newVal) {
+ if (oldVal != newVal)
+ {
+ m_callback (oldVal, newVal);
+ }
+ }
+private:
+ ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class UVTraceSource;
+
+
+/**
+ * \brief trace variables of type "signed integer"
+ * \ingroup tracing
+ *
+ * This template class implements a POD type: it
+ * behaves like any other variable of type "signed integer"
+ * except that it also reports any changes to its
+ * value with its internal callback.
+ *
+ * To instantiate a 32-bit signed variable (to store
+ * a TCP counter for example), you would create a variable of type
+ * ns3::UVTraceSource<int32_t> :
+ \code
+ #include <stdint.h>
+ #include "ns3/sv-trace-source.h"
+
+ ns3::SVTraceSource<uint16_t> var;
+ \endcode
+ * and you would use it like any other variable of type int32_t:
+ \code
+ var += 12;
+ var = 10;
+ var = -10;
+ \endcode
+ */
+template <typename T>
+class SVTraceSource : public SVTraceSourceBase {
+public:
+ SVTraceSource ()
+ : m_var (0)
+ {}
+ SVTraceSource (T const &var)
+ : m_var (var)
+ {}
+
+ SVTraceSource &operator = (SVTraceSource const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ SVTraceSource &operator = (SVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ SVTraceSource &operator = (UVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ SVTraceSource &operator++ () {
+ Assign (Get () + 1);
+ return *this;
+ }
+ SVTraceSource &operator-- () {
+ Assign (Get () - 1);
+ return *this;
+ }
+ SVTraceSource operator++ (int) {
+ SVTraceSource old (*this);
+ ++*this;
+ return old;
+ }
+ SVTraceSource operator-- (int) {
+ SVTraceSource old (*this);
+ --*this;
+ return old;
+ }
+ operator T () const {
+ return Get ();
+ }
+
+
+ void Assign (T var) {
+ Notify (m_var, var);
+ m_var = var;
+ }
+ T Get (void) const {
+ return m_var;
+ }
+
+private:
+ T m_var;
+};
+
+template <typename T>
+SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () + rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () - rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () * rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () / rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () << rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () & rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () | rhs.Get ());
+ return lhs;
+}
+template <typename T>
+SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs.Get ());
+ return lhs;
+}
+
+
+template <typename T, typename U>
+SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () + rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () - rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () * rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () / rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () << rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () & rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () | rhs);
+ return lhs;
+}
+template <typename T, typename U>
+SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs);
+ return lhs;
+}
+
+}; // namespace ns3
+
+#endif /* SV_TRACE_SOURCE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/terminal-trace-resolver.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TERMINAL_TRACE_RESOLVER_H
+#define TERMINAL_TRACE_RESOLVER_H
+
+#include "trace-resolver.h"
+
+namespace ns3 {
+
+class TraceContext;
+
+template <typename T>
+class TerminalTraceResolver : public TraceResolver
+{
+ public:
+ TerminalTraceResolver (T &traceSource, TraceContext const &context);
+ private:
+ virtual void DoConnect (CallbackBase const &cb);
+ virtual void DoDisconnect (CallbackBase const &cb);
+ T &m_traceSource;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+TerminalTraceResolver<T>::TerminalTraceResolver (T &traceSource,
+ TraceContext const &context)
+ : TraceResolver (context),
+ m_traceSource (traceSource)
+{}
+template <typename T>
+void
+TerminalTraceResolver<T>::DoConnect (CallbackBase const &cb)
+{
+ m_traceSource.AddCallback (cb, GetContext ());
+}
+template <typename T>
+void
+TerminalTraceResolver<T>::DoDisconnect (CallbackBase const &cb)
+{
+ m_traceSource.RemoveCallback (cb);
+}
+
+}//namespace ns3
+
+#endif /* TERMINAL_TRACE_RESOLVER_H */
--- a/src/common/trace-container.cc Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#include "trace-container.h"
-#include "stream-tracer.h"
-#include <utility>
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-TraceContainer::TraceContainer ()
-{}
-TraceContainer::~TraceContainer ()
-{
- m_uiList.erase (m_uiList.begin (), m_uiList.end ());
- m_siList.erase (m_siList.begin (), m_siList.end ());
- m_fList.erase (m_fList.begin (), m_fList.end ());
-}
-
-void
-TraceContainer::SetUiVariableCallback (std::string const&name, Callback<void,uint64_t, uint64_t> callback)
-{
- for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++)
- {
- if ((*i).second == name)
- {
- (*i).first->SetCallback (callback);
- return;
- }
- }
- NS_ASSERT (false);
-}
-void
-TraceContainer::SetSiVariableCallback (std::string const&name, Callback<void,int64_t, int64_t> callback)
-{
- for (SiListI i = m_siList.begin (); i != m_siList.end (); i++)
- {
- if ((*i).second == name)
- {
- (*i).first->SetCallback (callback);
- return;
- }
- }
- NS_ASSERT (false);
-}
-void
-TraceContainer::SetFVariableCallback (std::string const&name, Callback<void,double, double> callback)
-{
- NS_ASSERT (false);
-}
-void
-TraceContainer::SetStream (std::string const&name, std::ostream *os)
-{
- for (StreamTracerListI i = m_traceStreamList.begin (); i != m_traceStreamList.end (); i++)
- {
- if ((*i).second == name)
- {
- (*i).first->SetStream (os);
- return;
- }
- }
- NS_ASSERT (false);
-}
-
-void
-TraceContainer::RegisterUiVariable (std::string const&name, UiVariableTracerBase *var)
-{
- // ensure unicity
- for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++)
- {
- if (i->second == name)
- {
- m_uiList.erase (i);
- break;
- }
- }
- m_uiList.push_back (std::make_pair (var, name));
-}
-void
-TraceContainer::RegisterSiVariable (std::string const&name, SiVariableTracerBase *var)
-{
- // ensure unicity
- for (SiListI i = m_siList.begin (); i != m_siList.end (); i++)
- {
- if (i->second == name)
- {
- m_siList.erase (i);
- break;
- }
- }
- m_siList.push_back (std::make_pair (var, name));
-}
-void
-TraceContainer::RegisterFVariable (std::string const&name, FVariableTracerBase *var)
-{
- NS_ASSERT (false);
-}
-
-void
-TraceContainer::RegisterStream (std::string const&name, StreamTracer *stream)
-{
- // ensure unicity
- for (StreamTracerListI i = m_traceStreamList.begin (); i != m_traceStreamList.end (); i++)
- {
- if (i->second == name)
- {
- m_traceStreamList.erase (i);
- break;
- }
- }
- m_traceStreamList.push_back (std::make_pair (stream,name));
-
-}
-
-void
-TraceContainer::RegisterCallback (std::string const&name, CallbackTracerBase *tracer)
-{
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- if (i->second == name)
- {
- m_callbackList.erase (i);
- break;
- }
- }
- m_callbackList.push_back (std::make_pair (tracer, name));
-}
-
-
-
-
-}; // namespace ns3
-
-#include <iostream>
-void
-ns3::TraceContainer::PrintDebug (void)
-{
- if (!m_uiList.empty ())
- {
- std::cout << "ui var: " << std::endl;
- for (UiListI i = m_uiList.begin (); i != m_uiList.end (); i++)
- {
- std::cout << " \"" << (*i).second << "\""<<std::endl;
- }
- }
- if (!m_siList.empty ())
- {
- std::cout << "si var: " << std::endl;
- for (SiListI i = m_siList.begin (); i != m_siList.end (); i++)
- {
- std::cout << " \"" << (*i).second << "\""<<std::endl;
- }
- }
- if (!m_fList.empty ())
- {
- std::cout << "f var: " << std::endl;
- for (FListI i = m_fList.begin (); i != m_fList.end (); i++)
- {
- std::cout << " \"" << (*i).second << "\""<<std::endl;
- }
- }
- if (!m_callbackList.empty ())
- {
- std::cout << "callback list: "<<std::endl;
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- std::cout << " \"" << i->second << "\""<<std::endl;
- }
- }
-}
--- a/src/common/trace-container.h Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,312 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef TRACE_CONTAINER_H
-#define TRACE_CONTAINER_H
-
-#include "ui-variable-tracer.h"
-#include "si-variable-tracer.h"
-#include "f-variable-tracer.h"
-#include "callback-tracer.h"
-#include "ns3/callback.h"
-#include <list>
-#include <string>
-
-namespace ns3 {
-
-class StreamTracer;
-
-/**
- * \brief register every source of trace events
- *
- * Model authors use the TraceContainer class to register
- * their trace event sources. Model users use the TraceContainer
- * class to connect their trace event listeners to the
- * model trace event sources.
- *
- * TraceContainer can be used to register the following event sources:
- * - ns3::StreamTracer : can be connected to any std::ostream
- * - ns3::CallbackTracer: can be connected to any ns3::Callback
- * - ns3::UiVariableTracer
- * - ns3::SiVariableTracer
- * - ns3::FVariableTracer
- *
- * The following sample code shows how you can:
- * - create trace event sources
- * - register the trace event sources in a trace container
- * - set event sinks to each event source
- *
- * \include samples/main-trace.cc
- */
-class TraceContainer {
-public:
- TraceContainer ();
- ~TraceContainer ();
-
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source
- *
- * This method targets only event sources which are variables of any unsigned
- * integer type.
- */
- void SetUiVariableCallback (std::string const &name,
- Callback<void,uint64_t, uint64_t> callback);
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source
- *
- * This method targets only event sources which are variables of any signed
- * integer type.
- */
- void SetSiVariableCallback (std::string const &name, Callback<void,int64_t, int64_t> callback);
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source
- *
- * This method targets only event sources which are variables of any double type.
- */
- void SetFVariableCallback (std::string const &name, Callback<void,double, double> callback);
- /**
- * \param name the name of the target event source
- * \param os the output stream being connected to the source trace stream
- *
- * This method targets only event sources which are of type StreamTracer.
- */
- void SetStream (std::string const &name, std::ostream *os);
-
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source.
- *
- * This method targets only event sources which are of type CallbackTracer<T1>
- */
- template <typename T1>
- void SetCallback (std::string const &name, Callback<void,T1> callback);
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source.
- *
- * This method targets only event sources which are of type CallbackTracer<T1,T2>
- */
- template <typename T1, typename T2>
- void SetCallback (std::string const &name, Callback<void,T1,T2> callback);
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source.
- *
- * This method targets only event sources which are of type CallbackTracer<T1,T2,T3>
- */
- template <typename T1, typename T2, typename T3>
- void SetCallback (std::string const &name, Callback<void,T1,T2,T3> callback);
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source.
- *
- * This method targets only event sources which are of type CallbackTracer<T1,T2,T3,T4>
- */
- template <typename T1, typename T2, typename T3, typename T4>
- void SetCallback (std::string const&name, Callback<void,T1,T2,T3,T4> callback);
- /**
- * \param name the name of the target event source
- * \param callback the callback being connected to the target event source.
- *
- * This method targets only event sources which are of type CallbackTracer<T1,T2,T3,T4,T5>
- */
- template <typename T1, typename T2, typename T3, typename T4, typename T5>
- void SetCallback (std::string const &name, Callback<void,T1,T2,T3,T4,T5> callback);
-
- /**
- * \param name the name of the registered event source
- * \param var the event source being registered
- *
- * This method registers only event sources of type "unsigned integer".
- */
- void RegisterUiVariable (std::string const&name, UiVariableTracerBase *var);
- /**
- * \param name the name of the registered event source
- * \param var the event source being registered
- *
- * This method registers only event sources of type "signed integer".
- */
- void RegisterSiVariable (std::string const&name, SiVariableTracerBase *var);
- /**
- * \param name the name of the registered event source
- * \param var the event source being registered
- *
- * This method registers only event sources of type "double".
- */
- void RegisterFVariable (std::string const&name, FVariableTracerBase *var);
- /**
- * \param name the name of the registered event source
- * \param stream the event source being registered
- *
- * This method registers only event sources of type StreamTracer.
- */
- void RegisterStream (std::string const&name, StreamTracer *stream);
-
- /**
- * \param name the name of the registeref event source
- * \param tracer the callback tracer being registered.
- *
- * This method registers only event sources of type CallbackTracer
- */
- void RegisterCallback (std::string const&name, CallbackTracerBase*tracer);
-
- /**
- * Print the list of registered event sources in this container only.
- */
- void PrintDebug (void);
-private:
- typedef std::list<std::pair<UiVariableTracerBase *, std::string> > UiList;
- typedef std::list<std::pair<UiVariableTracerBase *, std::string> >::iterator UiListI;
- typedef std::list<std::pair<SiVariableTracerBase *, std::string> > SiList;
- typedef std::list<std::pair<SiVariableTracerBase *, std::string> >::iterator SiListI;
- typedef std::list<std::pair<FVariableTracerBase *, std::string> > FList;
- typedef std::list<std::pair<FVariableTracerBase *, std::string> >::iterator FListI;
- typedef std::list<std::pair<StreamTracer *, std::string> > StreamTracerList;
- typedef std::list<std::pair<StreamTracer *, std::string> >::iterator StreamTracerListI;
- typedef std::list<std::pair<CallbackTracerBase *, std::string> > CallbackList;
- typedef std::list<std::pair<CallbackTracerBase *, std::string> >::iterator CallbackListI;
-
- UiList m_uiList;
- SiList m_siList;
- FList m_fList;
- StreamTracerList m_traceStreamList;
- CallbackList m_callbackList;
-};
-
-}; // namespace ns3
-
-#include "ns3/assert.h"
-
-namespace ns3 {
-
-template <typename T1>
-void
-TraceContainer::SetCallback (std::string const&name, Callback<void,T1> callback)
-{
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- if (i->second == name)
- {
- if (i->first->CheckCallbackType (callback))
- {
- static_cast<CallbackTracer<T1> *> (i->first)->SetCallback (callback);
- return;
- }
- else
- {
- NS_ASSERT (!"non-matching callback");
- }
- }
- }
- NS_ASSERT (false);
-}
-template <typename T1, typename T2>
-void
-TraceContainer::SetCallback (std::string const&name, Callback<void,T1,T2> callback)
-{
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- if (i->second == name)
- {
- if (i->first->CheckCallbackType (callback))
- {
- static_cast<CallbackTracer<T1,T2> *> (i->first)->SetCallback (callback);
- return;
- }
- else
- {
- NS_ASSERT (!"non-matching callback");
- }
- }
- }
- NS_ASSERT (false);
-}
-template <typename T1, typename T2, typename T3>
-void
-TraceContainer::SetCallback (std::string const&name, Callback<void,T1,T2,T3> callback)
-{
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- if (i->second == name)
- {
- if (i->first->CheckCallbackType (callback))
- {
- static_cast<CallbackTracer<T1,T2,T3> *> (i->first)->SetCallback (callback);
- return;
- }
- else
- {
- NS_ASSERT (!"non-matching callback");
- }
- }
- }
- NS_ASSERT (false);
-}
-template <typename T1, typename T2, typename T3, typename T4>
-void
-TraceContainer::SetCallback (std::string const&name, Callback<void,T1,T2,T3,T4> callback)
-{
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- if (i->second == name)
- {
- if (i->first->CheckCallbackType (callback))
- {
- static_cast<CallbackTracer<T1,T2,T3,T4> *> (i->first)->SetCallback (callback);
- return;
- }
- else
- {
- NS_ASSERT (!"non-matching callback");
- }
- }
- }
- NS_ASSERT (false);
-}
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-void
-TraceContainer::SetCallback (std::string const&name, Callback<void,T1,T2,T3,T4,T5> callback)
-{
- for (CallbackListI i = m_callbackList.begin (); i != m_callbackList.end (); i++)
- {
- if (i->second == name)
- {
- if (i->first->CheckCallbackType (callback))
- {
- static_cast<CallbackTracer<T1,T2,T3,T4,T5> *> (i->first)->SetCallback (callback);
- return;
- }
- else
- {
- NS_ASSERT (!"non-matching callback");
- }
- }
- }
- NS_ASSERT (false);
-}
-
-
-}; // namespace ns3
-
-#endif /* TRACED_VARIABLE_CONTAINER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-context.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,320 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-context.h"
+#include "ns3/assert.h"
+
+namespace ns3 {
+
+std::vector<uint8_t> TraceContext::m_sizes;
+
+TraceContext::TraceContext ()
+ : m_data (0)
+{}
+TraceContext::TraceContext (TraceContext const &o)
+ : m_data (o.m_data)
+{
+ if (m_data != 0)
+ {
+ m_data->count++;
+ }
+}
+TraceContext const &
+TraceContext::operator = (TraceContext const &o)
+{
+ if (m_data != 0)
+ {
+ m_data->count--;
+ if (m_data->count == 0)
+ {
+ uint8_t *buffer = (uint8_t *)m_data;
+ delete [] buffer;
+ }
+ }
+ m_data = o.m_data;
+ if (m_data != 0)
+ {
+ m_data->count++;
+ }
+ return *this;
+}
+TraceContext::~TraceContext ()
+{
+ if (m_data != 0)
+ {
+ m_data->count--;
+ if (m_data->count == 0)
+ {
+ uint8_t *buffer = (uint8_t *)m_data;
+ delete [] buffer;
+ }
+ }
+}
+
+uint8_t
+TraceContext::GetSize (uint8_t uid)
+{
+ return m_sizes[uid];
+}
+
+void
+TraceContext::Add (TraceContext const &o)
+{
+ if (o.m_data == 0)
+ {
+ return;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ while (i < o.m_data->size)
+ {
+ currentUid = o.m_data->data[i];
+ uint8_t size = TraceContext::GetSize (currentUid);
+ uint8_t *selfBuffer = CheckPresent (currentUid);
+ uint8_t *otherBuffer = &(o.m_data->data[i+1]);
+ if (selfBuffer != 0)
+ {
+ if (memcmp (selfBuffer, otherBuffer, size) != 0)
+ {
+ NS_FATAL_ERROR ("You cannot add TraceContexts which "<<
+ "have different values stored in them.");
+ }
+ }
+ else
+ {
+ DoAdd (currentUid, otherBuffer);
+ }
+ i += 1 + size;
+ }
+}
+
+uint8_t *
+TraceContext::CheckPresent (uint8_t uid) const
+{
+ if (m_data == 0)
+ {
+ return false;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = TraceContext::GetSize (currentUid);
+ if (currentUid == uid)
+ {
+ return &m_data->data[i+1];
+ }
+ i += 1 + size;
+ } while (i < m_data->size && currentUid != 0);
+ return 0;
+}
+
+
+bool
+TraceContext::DoAdd (uint8_t uid, uint8_t const *buffer)
+{
+ NS_ASSERT (uid != 0);
+ uint8_t size = TraceContext::GetSize (uid);
+ uint8_t *present = CheckPresent (uid);
+ if (present != 0) {
+ if (memcmp (present, buffer, size) == 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ if (m_data == 0)
+ {
+ uint16_t newSize = 1 + size;
+ uint16_t allocatedSize;
+ if (newSize > 4)
+ {
+ allocatedSize = sizeof (struct Data) + newSize - 4;
+ }
+ else
+ {
+ allocatedSize = sizeof (struct Data);
+ }
+ struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
+ data->size = newSize;
+ data->count = 1;
+ data->data[0] = uid;
+ memcpy (data->data + 1, buffer, size);
+ m_data = data;
+ }
+ else
+ {
+ uint16_t newSize = m_data->size + 1 + size;
+ uint16_t allocatedSize;
+ if (newSize > 4)
+ {
+ allocatedSize = sizeof (struct Data) + newSize - 4;
+ }
+ else
+ {
+ allocatedSize = sizeof (struct Data);
+ }
+ struct Data *data = (struct Data *) (new uint8_t [allocatedSize] ());
+ data->size = newSize;
+ data->count = 1;
+ memcpy (data->data, m_data->data, m_data->size);
+ data->data[m_data->size] = uid;
+ memcpy (data->data + m_data->size + 1, buffer, size);
+ m_data->count--;
+ if (m_data->count == 0)
+ {
+ uint8_t *buffer = (uint8_t *)m_data;
+ delete [] buffer;
+ }
+ m_data = data;
+ }
+ return true;
+}
+bool
+TraceContext::DoGet (uint8_t uid, uint8_t *buffer) const
+{
+ if (m_data == 0)
+ {
+ return false;
+ }
+ uint8_t currentUid;
+ uint16_t i = 0;
+ do {
+ currentUid = m_data->data[i];
+ uint8_t size = TraceContext::GetSize (currentUid);
+ if (currentUid == uid)
+ {
+ memcpy (buffer, &m_data->data[i+1], size);
+ return true;
+ }
+ i += 1 + size;
+ } while (i < m_data->size && currentUid != 0);
+ return false;
+}
+
+uint8_t
+TraceContext::DoGetNextUid (void)
+{
+ static uint8_t uid = 0;
+ if (uid == 0)
+ {
+ m_sizes.push_back (0);
+ }
+ uid++;
+ return uid;
+}
+
+
+}//namespace ns3
+
+#include "ns3/test.h"
+
+namespace ns3 {
+
+template <int N>
+class Ctx
+{
+public:
+ Ctx () : m_v (0) {}
+ Ctx (int v) : m_v (v) {}
+ int Get (void) const { return N;}
+private:
+ int m_v;
+};
+
+class TraceContextTest : public Test
+{
+public:
+ TraceContextTest ();
+ virtual bool RunTests (void);
+};
+
+TraceContextTest::TraceContextTest ()
+ : Test ("TraceContext")
+{}
+bool
+TraceContextTest::RunTests (void)
+{
+ bool ok = true;
+
+ TraceContext ctx;
+ Ctx<0> v0;
+ Ctx<0> v01 = Ctx<0> (1);
+ Ctx<1> v1;
+ Ctx<2> v2;
+ Ctx<3> v3;
+
+ if (ctx.SafeGet (v0))
+ {
+ ok = false;
+ }
+ ctx.Add (v0);
+ ctx.Add (v0);
+ if (ctx.SafeAdd (v01))
+ {
+ ok = false;
+ }
+ ctx.Get (v0);
+ ctx.Add (v1);
+ ctx.Get (v1);
+ ctx.Get (v0);
+ ctx.Get (v1);
+
+ TraceContext copy = ctx;
+ ctx.Get (v0);
+ ctx.Get (v1);
+ copy.Get (v0);
+ copy.Get (v1);
+ copy.Add (v2);
+ copy.Get (v0);
+ copy.Get (v1);
+ copy.Get (v2);
+ ctx.Add (v3);
+ ctx.Get (v0);
+ ctx.Get (v1);
+ ctx.Get (v3);
+
+ if (ctx.SafeGet (v2))
+ {
+ ok = false;
+ }
+ if (copy.SafeGet (v3))
+ {
+ ok = false;
+ }
+ ctx.Add (copy);
+ ctx.Get (v2);
+ if (copy.SafeGet (v3))
+ {
+ ok = false;
+ }
+ copy.Add (ctx);
+ copy.Get (v3);
+
+ return ok;
+}
+
+static TraceContextTest g_traceContextTest;
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-context.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,167 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TRACE_CONTEXT_H
+#define TRACE_CONTEXT_H
+
+#include <stdint.h>
+#include <vector>
+#include "ns3/fatal-error.h"
+
+namespace ns3 {
+
+/**
+ * \brief Provide context to trace sources
+ * \ingroup tracing
+ *
+ * Instances of this class are used to hold context
+ * for each trace source. Each instance holds a list of
+ * 'contexts'. Trace sinks can lookup these contexts
+ * from this list with the ns3::TraceContext::Get method.
+ *
+ * This class is implemented
+ * using Copy On Write which means that copying unmodified
+ * versions of this class is very cheap. However, modifying
+ * the content of this class through a call
+ * to ns3::TraceContext::Add will trigger a costly memory
+ * reallocation if needed.
+ */
+class TraceContext
+{
+public:
+ TraceContext ();
+ TraceContext (TraceContext const &o);
+ TraceContext const & operator = (TraceContext const &o);
+ ~TraceContext ();
+
+ /**
+ * \param context add context to list of trace contexts.
+ */
+ template <typename T>
+ void Add (T const &context);
+
+ /**
+ * \param o the other context
+ *
+ * Perform the Union operation (in the sense of set theory) on the
+ * two input lists of elements. This method is used in the
+ * ns3::CallbackTraceSourceSource class when multiple sinks are connected
+ * to a single source to ensure that the source does not need
+ * to store a single TraceContext instance per connected sink.
+ * Instead, all sinks share the same TraceContext.
+ */
+ void Add (TraceContext const &o);
+
+ /**
+ * \param context context to get from this list of trace contexts.
+ *
+ * This method cannot fail. If the requested trace context is not
+ * stored in this TraceContext, then, the program will halt.
+ */
+ template <typename T>
+ void Get (T &context) const;
+private:
+ friend class TraceContextTest;
+ // used exclusively for testing code.
+ template <typename T>
+ bool SafeGet (T &context) const;
+ template <typename T>
+ bool SafeAdd (T &context);
+
+ template <typename T>
+ static uint8_t GetUid (void);
+ template <typename T>
+ static uint8_t GetNextUid (void);
+ static uint8_t DoGetNextUid (void);
+ static uint8_t GetSize (uint8_t uid);
+ uint8_t *CheckPresent (uint8_t uid) const;
+ bool DoAdd (uint8_t uid, uint8_t const *buffer);
+ bool DoGet (uint8_t uid, uint8_t *buffer) const;
+
+ static std::vector<uint8_t> m_sizes;
+ struct Data {
+ uint16_t count;
+ uint16_t size;
+ uint8_t data[4];
+ } * m_data;
+};
+
+}//namespace ns3
+
+namespace ns3 {
+
+template <typename T>
+void
+TraceContext::Add (T const &context)
+{
+ uint8_t *data = (uint8_t *) &context;
+ bool ok = DoAdd (TraceContext::GetUid<T> (), data);
+ if (!ok)
+ {
+ NS_FATAL_ERROR ("Trying to add twice the same type with different values is invalid.");
+ }
+}
+template <typename T>
+void
+TraceContext::Get (T &context) const
+{
+ uint8_t *data = (uint8_t *) &context;
+ bool found = DoGet (TraceContext::GetUid<T> (), data);
+ if (!found)
+ {
+ NS_FATAL_ERROR ("Type not stored in TraceContext");
+ }
+}
+template <typename T>
+bool
+TraceContext::SafeGet (T &context) const
+{
+ uint8_t *data = (uint8_t *) &context;
+ bool found = DoGet (TraceContext::GetUid<T> (), data);
+ return found;
+}
+template <typename T>
+bool
+TraceContext::SafeAdd (T &context)
+{
+ uint8_t *data = (uint8_t *) &context;
+ bool ok = DoAdd (TraceContext::GetUid<T> (), data);
+ return ok;
+}
+template <typename T>
+uint8_t
+TraceContext::GetUid (void)
+{
+ static uint8_t uid = GetNextUid<T> ();
+ return uid;
+}
+
+template <typename T>
+uint8_t
+TraceContext::GetNextUid (void)
+{
+ uint8_t uid = DoGetNextUid ();
+ m_sizes.push_back (sizeof (T));
+ return uid;
+}
+
+}//namespace ns3
+
+#endif /* TRACE_CONTEXT_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-resolver.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-resolver.h"
+
+namespace ns3 {
+
+TraceResolver::TraceResolver (TraceContext const &context)
+ : m_context (context)
+{}
+
+TraceResolver::~TraceResolver ()
+{}
+
+TraceContext const &
+TraceResolver::GetContext (void) const
+{
+ return m_context;
+}
+
+void
+TraceResolver::Connect (std::string path, CallbackBase const &cb)
+{
+ std::string::size_type cur = 1;
+ // check that first char is "/"
+ std::string::size_type next = path.find ("/", cur);
+ std::string element = std::string (path, cur, next-1);
+ TraceResolverList resolverList = DoLookup (element);
+ for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
+ {
+ TraceResolver *resolver = *i;
+ if (next == std::string::npos)
+ {
+ // we really break the recursion here.
+ resolver->DoConnect (cb);
+ }
+ else
+ {
+ std::string subpath = std::string (path, next, std::string::npos);
+ resolver->Connect (subpath, cb);
+ }
+ delete resolver;
+ }
+ resolverList.erase (resolverList.begin (), resolverList.end ());
+}
+
+void
+TraceResolver::Disconnect (std::string path, CallbackBase const &cb)
+{
+ std::string::size_type cur = 1;
+ // check that first char is "/"
+ std::string::size_type next = path.find ("/", cur);
+ std::string element = std::string (path, cur, next-1);
+ TraceResolverList resolverList = DoLookup (element);
+ for (TraceResolverList::iterator i = resolverList.begin (); i != resolverList.end (); i++)
+ {
+ TraceResolver *resolver = *i;
+ if (next == std::string::npos)
+ {
+ // we really break the recursion here.
+ resolver->DoDisconnect (cb);
+ }
+ else
+ {
+ std::string subpath = std::string (path, next, std::string::npos);
+ resolver->Disconnect (subpath, cb);
+ }
+ delete resolver;
+ }
+ resolverList.erase (resolverList.begin (), resolverList.end ());
+}
+
+TraceResolver::TraceResolverList
+TraceResolver::DoLookup (std::string id) const
+{
+ return TraceResolverList ();
+}
+void
+TraceResolver::DoConnect (CallbackBase const &cb)
+{}
+
+void
+TraceResolver::DoDisconnect (CallbackBase const &cb)
+{}
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-resolver.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,119 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TRACE_RESOLVER_H
+#define TRACE_RESOLVER_H
+
+#include <string>
+#include <list>
+#include "trace-context.h"
+
+namespace ns3 {
+
+class CallbackBase;
+
+/**
+ * \brief the base class which is used to incremental perform trace
+ * namespace resolution.
+ * \ingroup tracing
+ *
+ * This class provides a public API to the ns3::TraceRoot object:
+ * - ns3::TraceResolver::Connect
+ * - ns3::TraceResolver::Disconnect
+ *
+ * It also provides an API for its subclasses. Each subclass should
+ * implement one of:
+ * - ns3::TraceResolver::DoLookup
+ * - ns3::TraceResolver::DoConnect and ns3::TraceResolver::DoDisconnect
+ * Each subclass must also provide an ns3::TraceContext to the TraceResolver
+ * constructor. Finally, each subclass can access the ns3::TraceContext
+ * associated to this ns3::TraceResolver through the
+ * ns3::TraceResolver::GetContext method.
+ */
+class TraceResolver
+{
+public:
+ virtual ~TraceResolver ();
+ /**
+ * \param path the namespace path to resolver
+ * \param cb the callback to connect to the matching namespace
+ *
+ * This method is typically invoked by ns3::TraceRoot but advanced
+ * users could also conceivably call it directly if they want to
+ * skip the ns3::TraceRoot.
+ */
+ void Connect (std::string path, CallbackBase const &cb);
+ /**
+ * \param path the namespace path to resolver
+ * \param cb the callback to disconnect in the matching namespace
+ *
+ * This method is typically invoked by ns3::TraceRoot but advanced
+ * users could also conceivably call it directly if they want to
+ * skip the ns3::TraceRoot.
+ */
+ void Disconnect (std::string path, CallbackBase const &cb);
+protected:
+ /**
+ * \param context the context used to initialize this TraceResolver.
+ *
+ * Every subclass must call this constructor
+ */
+ TraceResolver (TraceContext const &context);
+ /**
+ * \returns the ns3::TraceContext stored in this ns3::TraceResolver.
+ *
+ * Subclasses usually invoke this method to get access to the
+ * TraceContext stored here to pass it down to the TraceResolver
+ * constructors invoked from within the DoLookup method.
+ */
+ TraceContext const &GetContext (void) const;
+ typedef std::list<TraceResolver *> TraceResolverList;
+private:
+ TraceResolver ();
+ /**
+ * \param id the id to resolve. This is supposed to be
+ * one element of the global tracing namespace.
+ * \returns a list of reslvers which match the input namespace element
+ *
+ * A subclass which overrides this method should return a potentially
+ * empty list of pointers to ns3::TraceResolver instances which match
+ * the input namespace element. Each of these TraceResolver should be
+ * instanciated with a TraceContext which holds enough context
+ * information to identify the type of the TraceResolver.
+ */
+ virtual TraceResolverList DoLookup (std::string id) const;
+ /**
+ * \param cb callback to connect
+ *
+ * This method is invoked on leaf trace resolvers.
+ */
+ virtual void DoConnect (CallbackBase const &cb);
+ /**
+ * \param cb callback to disconnect
+ *
+ * This method is invoked on leaf trace resolvers.
+ */
+ virtual void DoDisconnect (CallbackBase const &cb);
+ TraceContext m_context;
+};
+
+}//namespace ns3
+
+#endif /* TRACE_RESOLVER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-root.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "trace-root.h"
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/trace-context.h"
+
+namespace ns3 {
+
+void
+TraceRoot::Connect (std::string path, CallbackBase const &cb)
+{
+ TraceResolver *resolver = GetComposite ();
+ resolver->Connect (path, cb);
+}
+void
+TraceRoot::Disconnect (std::string path, CallbackBase const &cb)
+{
+ TraceResolver *resolver = GetComposite ();
+ resolver->Disconnect (path, cb);
+}
+void
+TraceRoot::Register (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver)
+{
+ CompositeTraceResolver *resolver = GetComposite ();
+ resolver->Add (name, createResolver, TraceRoot::NOTHING);
+}
+
+CompositeTraceResolver *
+TraceRoot::GetComposite (void)
+{
+ static CompositeTraceResolver resolver = CompositeTraceResolver (TraceContext ());
+ return &resolver;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/trace-root.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,255 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef TRACE_ROOT_H
+#define TRACE_ROOT_H
+
+#include <string>
+#include "ns3/callback.h"
+
+/**
+ * \defgroup tracing Tracing
+ *
+ * The low-level tracing framework is built around a few very simple
+ * concepts:
+ * - There can be any number of trace source objects. Each trace source
+ * object can generate any number of trace events. The current
+ * trace source objects are: ns3::CallbackTraceSourceSource, ns3::UVTraceSource,
+ * ns3::SVTraceSource, and, ns3::FVTraceSource.
+ * - Each trace source can be connected to any number of trace sinks.
+ * A trace sink is a ns3::Callback with a very special signature. Its
+ * first argument is always a ns3::TraceContext.
+ * - Every trace source is uniquely identified by a ns3::TraceContext. Every
+ * trace sink can query a ns3::TraceContext for information. This allows
+ * a trace sink which is connected to multiple trace sources to identify
+ * from which source each event is coming from.
+ *
+ * To allow the user to connect his own trace sinks to each trace source
+ * defined by any of the models he is using, the tracing framework defines
+ * a hierarchical namespace. The root of this namespace is accessed through
+ * the ns3::TraceRoot class. The namespace is represented as a string made
+ * of multiple elements, each of which is separated from the other elements
+ * by the '/' character. A namespace string always starts with a '/'.
+ *
+ * By default, the simulation models provide a '/nodes' tracing root. This
+ * '/nodes' namespace is structured as follows:
+ * \code
+ * /nodes/n/udp
+ * /nodes/n/ipv4
+ * /tx
+ * /rx
+ * /drop
+ * /interfaces/n/netdevice
+ * (NetDevice only) /queue/
+ * /enque
+ * /deque
+ * /drop
+ * /nodes/n/arp
+ * \endcode
+ *
+ * The 'n' element which follows the /nodes and /interfaces namespace elements
+ * identify a specific node and interface through their index within the
+ * ns3::NodeList and ns3::Ipv4 objects respectively.
+ *
+ * To connect a trace sink to a trace source identified by a namespace string,
+ * a user can call the ns3::TraceRoot::Connect method (the ns3::TraceRoot::Disconnect
+ * method does the symmetric operation). This connection method can accept
+ * fully-detailed namespace strings but it can also perform pattern matching
+ * on the user-provided namespace strings to connect multiple trace sources
+ * to a single trace sink in a single connection operation.
+ *
+ * The syntax of the pattern matching rules are loosely based on regular
+ * expressions:
+ * - the '*' character matches every element
+ * - the (a|b) construct matches element 'a' or 'b'
+ * - the [ss-ee] construct matches all numerical values which belong
+ * to the interval which includes ss and ee
+ *
+ * For example, the user could use the following to connect a single sink
+ * to the ipv4 tx, rx, and drop trace events:
+ *
+ * \code
+ * void MyTraceSink (TraceContext const &context, Packet &packet);
+ * TraceRoot::Connect ("/nodes/ * /ipv4/ *", MakeCallback (&MyTraceSink));
+ * \endcode
+ *
+ * Of course, this code would work only if the signature of the trace sink
+ * is exactly equal to the signature of all the trace sources which match
+ * the namespace string (if one of the matching trace source does not match
+ * exactly, a fatal error will be triggered at runtime during the connection
+ * process). The ns3::TraceContext extra argument contains
+ * information on where the trace source is located in the namespace tree.
+ * In that example, if there are multiple nodes in this scenario, each
+ * call to the MyTraceSink function would receive a different TraceContext,
+ * each of which would contain a different NodeList::Index object.
+ *
+ * It is important to understand exactly what an ns3::TraceContext
+ * is. It is a container for a number of type instances. Each instance of
+ * a ns3::TraceContext contains one and only one instance of a given type.
+ * ns3::TraceContext::Add can be called to add a type instance into a
+ * TraceContext instance and ns3::TraceContext::Get can be called to get
+ * a copy of a type instance stored into the ns3::TraceContext. If ::Get
+ * cannot retrieve the requested type, a fatal error is triggered at
+ * runtime. The values stored into an ns3::TraceContext attached to a
+ * trace source are automatically determined during the namespace
+ * resolution process. To retrieve a value from a ns3::TraceContext, the
+ * code can be as simple as this:
+ * \code
+ * void MyTraceSink (TraceContext const &context, Packet &packet)
+ * {
+ * NodeList::Index index;
+ * context.Get (index);
+ * std::cout << "node id=" << NodeList::GetNode (index)->GetId () << std::endl;
+ * }
+ * \endcode
+ *
+ * To define new trace sources, a model author needs to instante one trace source
+ * object for each kind of tracing event he wants to export. The trace source objects
+ * currently defined are:
+ * - ns3::CallbackTraceSourceSource: this trace source can be used to convey any kind of
+ * trace event to the user. It is a functor, that is, it is a variable
+ * which behaves like a function which will forward every event to every
+ * connected trace sink (i.e., ns3::Callback). This trace source takes
+ * up to four arguments and forwards these 4 arguments together with the
+ * ns3::TraceContext which identifies this trace source to the connected
+ * trace sinks.
+ * - ns3::UVTraceSource: this trace source is used to convey key state variable
+ * changes to the user. It behaves like a normal integer unsigned variable:
+ * you can apply every normal arithmetic operator to it. It will forward
+ * every change in the value of the variable back to every connected trace
+ * sink by providing a TraceContext, the old value and the new value.
+ * - ns3::SVTraceSource: this is the signed integer equivalent of
+ * ns3::UVTraceSource.
+ * - ns3::FVTraceSource: this is the floating point equivalent of
+ * ns3::UVTraceSource and ns3::SVTraceSource.
+ *
+ * Once the model author has instantiated these objects and has wired them
+ * in his simulation code (that is, he calls them wherever he wants to
+ * trigger a trace event), he needs to hook these trace sources into the
+ * global tracing namespace. The first step to do this is to define a method
+ * which returns a pointer to a ns3::TraceResolver object and which takes
+ * as argument a reference to a const ns3::TraceContext. The name of this method
+ * depends on how you will hook into the global tracing namespace. Before
+ * we get there, you need to implement this method. To do this, you could
+ * attempt to do everything by hand: define a subclass of the
+ * ns3::TraceResolver base class and implement its DoConnect, DoDisconnect
+ * and DoLookup methods. Because doing this can be a bit tedious, our
+ * tracing framework provides a number of helper template classes which
+ * should save you from having to implement your own in most cases:
+ * - ns3::CompositeTraceResolver: this subclass of ns3::TraceResolver
+ * can be used to aggregate together multiple trace sources and
+ * multiple other ns3::TraceResolver instances.
+ * - ns3::ArrayTraceResolver: this subclass of ns3::TraceResolver
+ * can be used to match any number of elements within an array
+ * where every element is identified by its index.
+ *
+ * Once you can instantiate your own ns3::TraceResolver object instance,
+ * you have to hook it up into the global namespace. There are two ways
+ * to do this:
+ * - you can hook your ns3::TraceResolver creation method as a new trace
+ * root by using the ns3::TraceRoot::Register method
+ * - you can hook your new ns3::TraceResolver creation method into
+ * the container of your model.
+ * For example, if you wrote a new l3 protocol, all you have to do
+ * to hook into your container L3Demux class is to implement
+ * the pure virtual method inherited from the L3Protocol class
+ * whose name is ns3::L3protocol::CreateTraceResolver.
+ *
+ * If you really want to have fun and implement your own ns3::TraceResolver
+ * subclass, you need to understand the basic Connection and Disconnection
+ * algorithm. The code of that algorithm is wholy contained in the
+ * ns3::TraceResolver::Connect and ns3::TraceResolver::Disconnect methods.
+ * The idea is that we recursively parse the input namespace string by removing
+ * the first namespace element. This element is 'resolved' is calling
+ * the ns3::TraceResolver::DoLookup method which returns a list of
+ * TraceResolver instances. Each of the returned TraceResolver instance is
+ * then given what is left of the namespace by calling ns3::TraceResolver::Connect
+ * until the last namespace element is processed. At this point, we invoke
+ * the ns3::TraceResolver::DoConnect or ns3::TraceResolver::DoDisconnect
+ * methods to break the recursion. A good way to understand this algorithm
+ * is to trace its behavior. Let's say that you want to connect to
+ * '/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *'. It would generate
+ * the following call traces:
+ *
+ * \code
+ * TraceRoot::Connect (/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *);
+ * resolver = NodeList::CreateTraceResolver ();
+ * resolver->Connect (/nodes/ * /ipv4/interfaces/ * /netdevice/queue/ *);
+ * list = CompositeTraceResolver::DoLookup ('nodes');
+ * resolver->Connect (/ * /ipv4/interfaces/ * /netdevice/queue/ *);
+ * list = ArrayTraceResolver::DoLookup ('*');
+ * resolver->Connect ('/ipv4/interfaces/ * /netdevice/queue/ *');
+ * list = CompositeTraceResolver::DoLookup ('ipv4');
+ * resolver->Connect ('/interfaces/ * /netdevice/queue/ *');
+ * list = CompositeTraceResolver::DoLookup ('interfaces');
+ * resolver->Connect ('/ * /netdevice/queue/ *');
+ * list = ArrayTraceResolver::DoLookup ('*');
+ * resolver->Connect ('/netdevice/queue/ *');
+ * list = CompositeTraceResolver::DoLookup ('netdevice');
+ * resolver->Connect ('/queue/ *');
+ * list = CompositeTraceResolver::DoLookup ('queue');
+ * resolver->Connect ('/ *');
+ * list = CompositeTraceResolver::DoLookup ('*');
+ * resolver->DoConnect ();
+ * \endcode
+ *
+ * This namespace resolution algorithm makes sure that each subpart of the
+ * namespace is resolved separately by each component. It allows you to
+ * never have to know the entire namespace structure to resolve a namespace
+ * string. All namespace knowledge is local which makes it very easy to plug
+ * in new components and have them extend the global tracing namespace.
+ *
+ * What is central to this namespace parsing and resolution algorithm is the
+ * construction of an ns3::TraceContext for each trace source during the
+ * connection process. The root trace context is intialized to be empty and
+ * TraceResolver::DoLookup method is responsible for incrementally constructing
+ * the TraceContext assigned to each terminal TraceSource object.
+ */
+
+namespace ns3 {
+
+class CompositeTraceResolver;
+class TraceResolver;
+class TraceContext;
+class CallbackBase;
+
+/**
+ * \brief The main class used to access tracing functionality for
+ * a user.
+ *
+ * \ingroup tracing
+ */
+class TraceRoot
+{
+public:
+ static void Connect (std::string path, CallbackBase const &cb);
+ static void Disconnect (std::string path, CallbackBase const &cb);
+ static void Register (std::string name,
+ Callback<TraceResolver *,TraceContext const &> createResolver);
+private:
+ static CompositeTraceResolver *GetComposite (void);
+ enum TraceType {
+ NOTHING,
+ };
+};
+
+}// namespace ns3
+
+#endif /* TRACE_ROOT_H */
--- a/src/common/ui-variable-tracer.h Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 INRIA
- * All rights reserved.
- *
- * 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
- *
- * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-
-#ifndef UI_VARIABLE_TRACER_H
-#define UI_VARIABLE_TRACER_H
-
-#include "ns3/callback.h"
-#include <stdint.h>
-
-namespace ns3 {
-
-class UiVariableTracerBase {
-public:
- typedef Callback<void, uint64_t, uint64_t> ChangeNotifyCallback;
-
- UiVariableTracerBase ()
- : m_callback () {}
- /* We don't want to copy the base callback. Only setCallback on
- * a specific instance will do something to it. */
- UiVariableTracerBase (UiVariableTracerBase const &o)
- : m_callback () {}
- UiVariableTracerBase &operator = (UiVariableTracerBase const &o) {
- return *this;
- }
- ~UiVariableTracerBase () {}
-
- void SetCallback(ChangeNotifyCallback callback) {
- m_callback = callback;
- }
-protected:
- void Notify (uint64_t oldVal, uint64_t newVal) {
- if (oldVal != newVal && !m_callback.IsNull ())
- {
- m_callback (oldVal, newVal);
- }
- }
-private:
- ChangeNotifyCallback m_callback;
-};
-
-template <typename T>
-class SiVariableTracer;
-
-
-/**
- * \brief trace variables of type "unsigned integer"
- *
- * This template class implements a POD type: it
- * behaves like any other variable of type "unsigned integer"
- * except that it also reports any changes to its
- * value with its internal callback.
- *
- * To instantiate a 32-bit unsigned variable (to store
- * a TCP counter for example), you would create a variable of type
- * ns3::UiVariableTracer<uint32_t> :
- \code
- #include <stdint.h>
- #include "ns3/ui-traced-variable.tcc"
-
- ns3::UiVariableTracer<uint32_t> var;
- \endcode
- * and you would use it like any other variable of type uint32_t:
- \code
- var += 12;
- var = 10;
- \endcode
- */
-template <typename T>
-class UiVariableTracer : public UiVariableTracerBase {
-public:
- UiVariableTracer ()
- : m_var ()
- {}
- UiVariableTracer (T const &var)
- : m_var (var)
- {}
-
- UiVariableTracer &operator = (UiVariableTracer const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- UiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- template <typename TT>
- UiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
- Assign (o.Get ());
- return *this;
- }
- UiVariableTracer &operator++ () {
- Assign (Get () + 1);
- return *this;
- }
- UiVariableTracer &operator-- () {
- Assign (Get () - 1);
- return *this;
- }
- UiVariableTracer operator++ (int) {
- UiVariableTracer old (*this);
- ++*this;
- return old;
- }
- UiVariableTracer operator-- (int) {
- UiVariableTracer old (*this);
- --*this;
- return old;
- }
- operator T () const {
- return Get ();
- }
-
-
- void Assign (T var) {
- Notify (m_var, var);
- m_var = var;
- }
- T Get (void) const {
- return m_var;
- }
-
-private:
- T m_var;
-};
-
-template <typename T>
-UiVariableTracer<T> &operator += (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () + rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator -= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () - rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator *= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () * rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator /= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () / rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator <<= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () << rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator >>= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () >> rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator &= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () & rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator |= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () | rhs.Get ());
- return lhs;
-}
-template <typename T>
-UiVariableTracer<T> &operator ^= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs.Get ());
- return lhs;
-}
-
-
-template <typename T, typename U>
-UiVariableTracer<T> &operator += (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () + rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator -= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () - rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator *= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () * rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator /= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () / rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator <<= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () << rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator >>= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () >> rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator &= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () & rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator |= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () | rhs);
- return lhs;
-}
-template <typename T, typename U>
-UiVariableTracer<T> &operator ^= (UiVariableTracer<T> &lhs, U const &rhs) {
- lhs.Assign (lhs.Get () ^ rhs);
- return lhs;
-}
-
-}; // namespace ns3
-
-#endif /* UI_VARIABLE_TRACER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/common/uv-trace-source.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,245 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 INRIA
+ * All rights reserved.
+ *
+ * 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
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef UV_TRACE_SOURCE_H
+#define UV_TRACE_SOURCE_H
+
+#include "callback-trace-source.h"
+#include <stdint.h>
+
+namespace ns3 {
+
+class UVTraceSourceBase {
+public:
+ typedef CallbackTraceSource<uint64_t, uint64_t> ChangeNotifyCallback;
+
+ UVTraceSourceBase ()
+ : m_callback () {}
+ /* We don't want to copy the base callback. Only setCallback on
+ * a specific instance will do something to it. */
+ UVTraceSourceBase (UVTraceSourceBase const &o)
+ : m_callback () {}
+ UVTraceSourceBase &operator = (UVTraceSourceBase const &o) {
+ return *this;
+ }
+ ~UVTraceSourceBase () {}
+
+ void AddCallback (CallbackBase const & callback, TraceContext const & context) {
+ m_callback.AddCallback (callback, context);
+ }
+ void RemoveCallback (CallbackBase const & callback) {
+ m_callback.RemoveCallback (callback);
+ }
+
+protected:
+ void Notify (uint64_t oldVal, uint64_t newVal) {
+ if (oldVal != newVal)
+ {
+ m_callback (oldVal, newVal);
+ }
+ }
+private:
+ ChangeNotifyCallback m_callback;
+};
+
+template <typename T>
+class SVTraceSource;
+
+
+/**
+ * \brief trace variables of type "unsigned integer"
+ * \ingroup tracing
+ *
+ * This template class implements a POD type: it
+ * behaves like any other variable of type "unsigned integer"
+ * except that it also reports any changes to its
+ * value with its internal callback.
+ *
+ * To instantiate a 32-bit unsigned variable (to store
+ * a TCP counter for example), you would create a variable of type
+ * ns3::UVTraceSource<uint32_t> :
+ \code
+ #include <stdint.h>
+ #include "ns3/uv-trace-source.h"
+
+ ns3::UVTraceSource<uint32_t> var;
+ \endcode
+ * and you would use it like any other variable of type uint32_t:
+ \code
+ var += 12;
+ var = 10;
+ \endcode
+ */
+template <typename T>
+class UVTraceSource : public UVTraceSourceBase {
+public:
+ UVTraceSource ()
+ : m_var ()
+ {}
+ UVTraceSource (T const &var)
+ : m_var (var)
+ {}
+
+ UVTraceSource &operator = (UVTraceSource const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ UVTraceSource &operator = (UVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ template <typename TT>
+ UVTraceSource &operator = (SVTraceSource<TT> const &o) {
+ Assign (o.Get ());
+ return *this;
+ }
+ UVTraceSource &operator++ () {
+ Assign (Get () + 1);
+ return *this;
+ }
+ UVTraceSource &operator-- () {
+ Assign (Get () - 1);
+ return *this;
+ }
+ UVTraceSource operator++ (int) {
+ UVTraceSource old (*this);
+ ++*this;
+ return old;
+ }
+ UVTraceSource operator-- (int) {
+ UVTraceSource old (*this);
+ --*this;
+ return old;
+ }
+ operator T () const {
+ return Get ();
+ }
+
+
+ void Assign (T var) {
+ Notify (m_var, var);
+ m_var = var;
+ }
+ T Get (void) const {
+ return m_var;
+ }
+
+private:
+ T m_var;
+};
+
+template <typename T>
+UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () + rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () - rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () * rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () / rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () << rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () & rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () | rhs.Get ());
+ return lhs;
+}
+template <typename T>
+UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs.Get ());
+ return lhs;
+}
+
+
+template <typename T, typename U>
+UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () + rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () - rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () * rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () / rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () << rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () >> rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () & rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () | rhs);
+ return lhs;
+}
+template <typename T, typename U>
+UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, U const &rhs) {
+ lhs.Assign (lhs.Get () ^ rhs);
+ return lhs;
+}
+
+}; // namespace ns3
+
+#endif /* UV_TRACE_SOURCE_H */
--- a/src/common/variable-tracer-test.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/common/variable-tracer-test.cc Sun Mar 18 14:06:51 2007 -0700
@@ -19,8 +19,9 @@
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
-#include "ui-variable-tracer.h"
-#include "si-variable-tracer.h"
+#include "uv-trace-source.h"
+#include "sv-trace-source.h"
+#include "trace-context.h"
#include "ns3/test.h"
#include "ns3/callback.h"
@@ -29,7 +30,7 @@
class Foo {
public:
- void Notify (uint64_t oldVal, uint64_t newVal) {}
+ void Notify (TraceContext const &contex, uint64_t oldVal, uint64_t newVal) {}
};
class VariableTracerTest: public Test {
@@ -42,11 +43,11 @@
void
VariableTracerTest::RunUnsignedTests (void)
{
- UiVariableTracer<uint32_t> var, ovar, tmp;
+ UVTraceSource<uint32_t> var, ovar, tmp;
uint32_t utmp;
Foo *foo = new Foo ();
- var.SetCallback (MakeCallback (&Foo::Notify, foo));
+ var.AddCallback (MakeCallback (&Foo::Notify, foo), TraceContext ());
var = 10;
ovar = var;
@@ -227,10 +228,10 @@
uitmp = utmp;
utmp = uitmp;
- UiVariableTracer<unsigned short> uvar = 10;
- UiVariableTracer<unsigned int> uivar = 5;
- SiVariableTracer<short> svar = 5;
- SiVariableTracer<int> sivar = 5;
+ UVTraceSource<unsigned short> uvar = 10;
+ UVTraceSource<unsigned int> uivar = 5;
+ SVTraceSource<short> svar = 5;
+ SVTraceSource<int> sivar = 5;
uvar = svar;
svar = uvar;
uvar += svar;
--- a/src/core/callback-test.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/core/callback-test.cc Sun Mar 18 14:06:51 2007 -0700
@@ -47,6 +47,16 @@
return a;
}
+void *Test9 (bool *a)
+{
+ return a;
+}
+
+void *Test10 (bool *a, int const & b)
+{
+ return a;
+}
+
class CallbackTest : public ns3::Test {
private:
bool m_test1;
@@ -147,9 +157,9 @@
b0 = B (this, &CallbackTest::Test2);
C c0 = C (this, &CallbackTest::Test3);
D d0 = D (this, &CallbackTest::Test4);
- E e0 = E (&Test5);
- F f0 = F (&Test6);
- G g0 = G (&Test7);
+ E e0 = E (&Test5, true, true);
+ F f0 = F (&Test6, true, true);
+ G g0 = G (&Test7, true, true);
a0 ();
b0 ();
@@ -190,6 +200,13 @@
{
ok = false;
}
+
+
+ MakeBoundCallback (&Test7, 0);
+ bool v;
+ MakeBoundCallback (&Test9, &v);
+ MakeBoundCallback (&Test10, &v);
+
return ok;
}
--- a/src/core/callback.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/core/callback.h Sun Mar 18 14:06:51 2007 -0700
@@ -60,6 +60,7 @@
class CallbackImplBase {
public:
virtual ~CallbackImplBase () {}
+ virtual bool IsEqual (CallbackImplBase const *other) const = 0;
};
// declare the CallbackImpl class
@@ -134,6 +135,19 @@
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (a1,a2,a3,a4,a5);
}
+ virtual bool IsEqual (CallbackImplBase const *other) const {
+ FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5> const *otherDerived =
+ dynamic_cast<FunctorCallbackImpl<T,R,T1,T2,T3,T4,T5> const *> (other);
+ if (otherDerived == 0)
+ {
+ return false;
+ }
+ else if (otherDerived->m_functor != m_functor)
+ {
+ return false;
+ }
+ return true;
+ }
private:
T m_functor;
};
@@ -163,6 +177,20 @@
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return ((*m_objPtr).*m_memPtr) (a1,a2,a3,a4,a5);
}
+ virtual bool IsEqual (CallbackImplBase const *other) const {
+ MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> const *otherDerived =
+ dynamic_cast<MemPtrCallbackImpl<OBJ_PTR,MEM_PTR,R,T1,T2,T3,T4,T5> const *> (other);
+ if (otherDerived == 0)
+ {
+ return false;
+ }
+ else if (otherDerived->m_objPtr != m_objPtr ||
+ otherDerived->m_memPtr != m_memPtr)
+ {
+ return false;
+ }
+ return true;
+ }
private:
OBJ_PTR const m_objPtr;
MEM_PTR m_memPtr;
@@ -202,14 +230,17 @@
* as well as the function templates \ref MakeCallback :
* \include samples/main-callback.cc
*/
+
template<typename R,
typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty,
typename T5 = empty>
class Callback : public CallbackBase {
public:
+ // There are two dummy args below to ensure that this constructor is
+ // always properly disambiguited by the c++ compiler
template <typename FUNCTOR>
- Callback (FUNCTOR const &functor)
+ Callback (FUNCTOR const &functor, bool, bool)
: m_impl (new FunctorCallbackImpl<FUNCTOR,R,T1,T2,T3,T4,T5> (functor))
{}
@@ -227,25 +258,29 @@
}
Callback () : m_impl () {}
- R operator() (void) {
+ R operator() (void) const {
return (*(m_impl.Get ())) ();
}
- R operator() (T1 a1) {
+ R operator() (T1 a1) const {
return (*(m_impl.Get ())) (a1);
}
- R operator() (T1 a1, T2 a2) {
+ R operator() (T1 a1, T2 a2) const {
return (*(m_impl).Get ()) (a1,a2);
}
- R operator() (T1 a1, T2 a2, T3 a3) {
+ R operator() (T1 a1, T2 a2, T3 a3) const {
return (*(m_impl).Get ()) (a1,a2,a3);
}
- R operator() (T1 a1, T2 a2, T3 a3, T4 a4) {
+ R operator() (T1 a1, T2 a2, T3 a3, T4 a4) const {
return (*(m_impl).Get ()) (a1,a2,a3,a4);
}
- R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) {
+ R operator() (T1 a1, T2 a2, T3 a3, T4 a4,T5 a5) const {
return (*(m_impl).Get ()) (a1,a2,a3,a4,a5);
}
+ bool IsEqual (CallbackBase const &other) {
+ return PeekImpl ()->IsEqual (other.PeekImpl ());
+ }
+
bool CheckType (CallbackBase const& other) {
CallbackImplBase *otherBase = other.PeekImpl ();
if (dynamic_cast<CallbackImpl<R,T1,T2,T3,T4,T5> *> (otherBase) != 0)
@@ -351,7 +386,7 @@
*/
template <typename R>
Callback<R> MakeCallback (R (*fnPtr) ()) {
- return Callback<R> (fnPtr);
+ return Callback<R> (fnPtr, true, true);
}
/**
* \ingroup MakeCallback
@@ -362,7 +397,7 @@
*/
template <typename R, typename T1>
Callback<R,T1> MakeCallback (R (*fnPtr) (T1)) {
- return Callback<R,T1> (fnPtr);
+ return Callback<R,T1> (fnPtr, true, true);
}
/**
* \ingroup MakeCallback
@@ -373,7 +408,7 @@
*/
template <typename R, typename T1, typename T2>
Callback<R,T1,T2> MakeCallback (R (*fnPtr) (T1,T2)) {
- return Callback<R,T1,T2> (fnPtr);
+ return Callback<R,T1,T2> (fnPtr, true, true);
}
/**
* \ingroup MakeCallback
@@ -384,7 +419,7 @@
*/
template <typename R, typename T1, typename T2,typename T3>
Callback<R,T1,T2,T3> MakeCallback (R (*fnPtr) (T1,T2,T3)) {
- return Callback<R,T1,T2,T3> (fnPtr);
+ return Callback<R,T1,T2,T3> (fnPtr, true, true);
}
/**
* \ingroup MakeCallback
@@ -395,7 +430,7 @@
*/
template <typename R, typename T1, typename T2,typename T3,typename T4>
Callback<R,T1,T2,T3,T4> MakeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
- return Callback<R,T1,T2,T3,T4> (fnPtr);
+ return Callback<R,T1,T2,T3,T4> (fnPtr, true, true);
}
/**
* \ingroup MakeCallback
@@ -406,7 +441,7 @@
*/
template <typename R, typename T1, typename T2,typename T3,typename T4,typename T5>
Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (*fnPtr) (T1,T2,T3,T4,T5)) {
- return Callback<R,T1,T2,T3,T4,T5> (fnPtr);
+ return Callback<R,T1,T2,T3,T4,T5> (fnPtr, true, true);
}
@@ -503,11 +538,34 @@
R operator() (T1 a1,T2 a2,T3 a3,T4 a4,T5 a5) {
return m_functor (m_a,a1,a2,a3,a4,a5);
}
+ virtual bool IsEqual (CallbackImplBase const *other) const {
+ BoundFunctorCallbackImpl<T,R,TX,T1,T2,T3,T4,T5> const *otherDerived =
+ dynamic_cast<BoundFunctorCallbackImpl<T,R,TX,T1,T2,T3,T4,T5> const *> (other);
+ if (otherDerived == 0)
+ {
+ return false;
+ }
+ else if (otherDerived->m_functor != m_functor ||
+ otherDerived->m_a != m_a)
+ {
+ return false;
+ }
+ return true;
+ }
private:
T m_functor;
TX m_a;
};
+template <typename R, typename TX>
+Callback<R> MakeBoundCallback (R (*fnPtr) (TX), TX a) {
+ ReferenceList<CallbackImpl<R,empty,empty,empty,empty,empty>*> impl =
+ ReferenceList<CallbackImpl<R,empty,empty,empty,empty,empty>*> (
+ new BoundFunctorCallbackImpl<R (*) (TX),R,TX,empty,empty,empty,empty,empty> (fnPtr, a)
+ );
+ return Callback<R> (impl);
+}
+
template <typename R, typename TX, typename T1>
Callback<R,T1> MakeBoundCallback (R (*fnPtr) (TX,T1), TX a) {
ReferenceList<CallbackImpl<R,T1,empty,empty,empty,empty>*> impl =
--- a/src/core/fatal-error.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/core/fatal-error.h Sun Mar 18 14:06:51 2007 -0700
@@ -22,10 +22,9 @@
#define FATAL_ERROR_H
#include "assert.h"
-#include <iostream>
/**
- * \defgroup error
+ * \defgroup error Error
* \brief fatal error handling
*
* \param msg message to output when this macro is hit.
--- a/src/devices/p2p/p2p-net-device.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/p2p/p2p-net-device.cc Sun Mar 18 14:06:51 2007 -0700
@@ -22,6 +22,7 @@
// Implementation of a point-to-point network device
// George F. Riley, Georgia Tech, Spring 2007
+#include "ns3/empty-trace-resolver.h"
#include "p2p-net-device.h"
#include "p2p-channel.h"
@@ -60,6 +61,12 @@
return true;
}
+TraceResolver *
+P2PNetDevice::DoCreateTraceResolver (TraceContext const &context)
+{
+ return new EmptyTraceResolver (context);
+}
+
void
P2PNetDevice::Receive(Packet p)
{
--- a/src/devices/p2p/p2p-net-device.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/p2p/p2p-net-device.h Sun Mar 18 14:06:51 2007 -0700
@@ -42,6 +42,8 @@
void TxComplete (void);
private:
virtual bool SendTo (Packet& p, const MacAddress& dest);
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
+
double m_rate;
P2PChannel *m_channel;
};
--- a/src/devices/serial/channel.cc Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * Author: Craig Dowell <craigdo@ee.washingon.edu>
- *
- * Thu Feb 15 14:50:46 PST 2007 craigdo: Created.
- */
-
-#include "ns3/debug.h"
-#include "channel.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("Channel");
-
-namespace ns3 {
-
-Channel::Channel ()
- : m_name("Channel")
-{
- NS_DEBUG("Channel::Channel ()");
-}
-
- Channel::Channel (std::string name)
- : m_name(name)
-{
- NS_DEBUG("Channel::Channel (" << name << ")");
-}
-
-Channel::~Channel ()
-{
- NS_DEBUG("Channel::~Channel ()");
-}
-
- void
-Channel::SetName(std::string name)
-{
- m_name = name;
-}
-
- std::string
-Channel::GetName(void)
-{
- return m_name;
-}
-
-} // namespace ns3
--- a/src/devices/serial/channel.h Sun Mar 18 19:31:32 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 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
- *
- * Author: Craig Dowell <craigdo@ee.washingon.edu>
- *
- * Wed Feb 14 16:05:46 PST 2007 craigdo: Created
- */
-
-#include <list>
-#include "ns3/packet.h"
-#include "layer-connector.h"
-
-#ifndef CHANNEL_H
-#define CHANNEL_H
-
-namespace ns3 {
-
-/**
- * \brief Abstract Channel Base Class.
- *
- * A channel is a logical path over which information flows. The path can
- * be as simple as a short piece of wire, or as complicated as space-time.
- */
-class Channel
-{
-public:
- Channel ();
- Channel (std::string name);
- virtual ~Channel ();
-
- virtual void SetName(std::string);
- virtual std::string GetName(void);
-
-protected:
- std::string m_name;
-
-private:
-};
-
-}; // namespace ns3
-
-#endif /* CHANNEL_H */
--- a/src/devices/serial/serial-channel.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/serial/serial-channel.cc Sun Mar 18 14:06:51 2007 -0700
@@ -21,6 +21,7 @@
#include "serial-channel.h"
#include "serial-net-device.h"
+#include "serial-phy.h"
#include "ns3/packet.h"
#include "ns3/simulator.h"
#include "ns3/debug.h"
@@ -32,7 +33,8 @@
//
// By default, you get a channel with the name "Serial Channel" that has an
// "infitely" fast transmission speed and zero delay.
-//
+// XXX: this does not work because m_bps = 0 results in infinitely slow transmission
+// speed.
SerialChannel::SerialChannel()
:
Channel ("Serial Channel"),
@@ -58,13 +60,13 @@
}
void
-SerialChannel::Attach(SerialNetDevice *device)
+SerialChannel::Attach(SerialPhy *phy)
{
- NS_DEBUG("SerialChannel::Attach (" << device << ")");
+ NS_DEBUG("SerialChannel::Attach (" << phy << ")");
NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
- NS_ASSERT(device);
+ NS_ASSERT(phy);
- m_link[m_nDevices].m_src = device;
+ m_link[m_nDevices].m_src = phy;
++m_nDevices;
//
// If we have both devices connected to the channel, then finish introducing
@@ -79,8 +81,8 @@
}
}
- void
-SerialChannel::TransmitCompleteEvent(Packet &p, SerialNetDevice *src)
+void
+SerialChannel::TransmitCompleteEvent(Packet p, SerialPhy *src)
{
NS_DEBUG("SerialChannel::TransmitCompleteEvent (" << &p << ", " <<
src << ")");
@@ -97,8 +99,8 @@
m_link[wire].m_dst->Receive (p);
}
- bool
-SerialChannel::Propagate(Packet& p, SerialNetDevice* src)
+bool
+SerialChannel::Propagate(Packet& p, SerialPhy* src)
{
NS_DEBUG("SerialChannel::DoPropagate (" << &p << ", " << src << ")");
@@ -119,19 +121,27 @@
// I believe Raj has a method in the DataRate class to do this. Should use
// it when it is available.
//
- Time tEvent = Simulator::Now () +
- Seconds (static_cast<double> (p.GetSize() * 8) /
- static_cast<double> (m_bps)) + m_delay;
-
- NS_DEBUG("SerialChannel::DoSend (): Schedule Receive at " << tEvent);
+ Time tEvent = Seconds (static_cast<double> (p.GetSize() * 8) /
+ static_cast<double> (m_bps)) + m_delay;
-#if 0
+ NS_DEBUG("SerialChannel::DoSend (): Schedule Receive delay " << tEvent);
+
+ Packet packet = p;
Simulator::Schedule (tEvent, &SerialChannel::TransmitCompleteEvent, this,
- p, src);
-#else
- TransmitCompleteEvent (p, src);
-#endif
+ p, src);
return true;
}
+uint32_t
+SerialChannel::GetNDevices (void) const
+{
+ return m_nDevices;
+}
+NetDevice *
+SerialChannel::GetDevice (uint32_t i) const
+{
+ return m_link[i].m_src->GetDevice ();
+}
+
+
} // namespace ns3
--- a/src/devices/serial/serial-channel.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/serial/serial-channel.h Sun Mar 18 14:06:51 2007 -0700
@@ -20,8 +20,7 @@
#define SERIAL_CHANNEL_H
#include <list>
-#include "channel.h"
-#include "serial-phy.h"
+#include "ns3/channel.h"
#include "ns3/packet.h"
#include "ns3/nstime.h"
@@ -29,6 +28,8 @@
// temporary until Raj's code makes it into the dev tree
typedef uint64_t DataRate;
+class SerialPhy;
+class NetDevice;
/**
* \brief Simple Serial Channel.
@@ -60,11 +61,15 @@
SerialChannel ();
SerialChannel (std::string name, DataRate bps, Time delay);
- void Attach (SerialNetDevice* nd);
- bool Propagate (Packet& p, SerialNetDevice *src);
+ void Attach (SerialPhy* phy);
+ bool Propagate (Packet& p, SerialPhy *src);
-protected:
- void TransmitCompleteEvent (Packet &p, SerialNetDevice *src);
+ virtual uint32_t GetNDevices (void) const;
+ virtual NetDevice *GetDevice (uint32_t i) const;
+
+
+private:
+ void TransmitCompleteEvent (Packet p, SerialPhy *src);
std::string m_name;
DataRate m_bps;
@@ -83,9 +88,9 @@
{
public:
Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
- WireState m_state;
- SerialNetDevice *m_src;
- SerialNetDevice *m_dst;
+ WireState m_state;
+ SerialPhy *m_src;
+ SerialPhy *m_dst;
};
Link m_link[N_DEVICES];
--- a/src/devices/serial/serial-net-device.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/serial/serial-net-device.cc Sun Mar 18 14:06:51 2007 -0700
@@ -23,6 +23,7 @@
#include <cassert>
#include "ns3/debug.h"
#include "ns3/queue.h"
+#include "ns3/composite-trace-resolver.h"
#include "serial-net-device.h"
#include "serial-channel.h"
#include "serial-phy.h"
@@ -51,10 +52,11 @@
SerialNetDevice::~SerialNetDevice()
{
NS_DEBUG ("SerialNetDevice::~SerialNetDevice ()");
+ delete m_phy;
}
- bool
+bool
SerialNetDevice::SendTo (Packet& p, const MacAddress& dest)
{
NS_DEBUG ("SerialNetDevice::SendTo (" << &p << ", " << &dest << ")");
@@ -74,12 +76,23 @@
return false;
}
- bool
+TraceResolver *
+SerialNetDevice::DoCreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ resolver->Add ("queue",
+ MakeCallback (&Queue::CreateTraceResolver, m_queue),
+ SerialNetDevice::QUEUE);
+ return resolver;
+}
+
+bool
SerialNetDevice::Attach (SerialChannel* ch)
{
NS_DEBUG ("SerialNetDevice::Attach (" << &ch << ")");
m_channel = ch;
+ m_phy->Attach (m_channel);
/*
* For now, this device is up whenever a channel is attached to it.
* In fact, it should become up only when the second device
@@ -106,8 +119,7 @@
// ignore return value for now.
NS_DEBUG ("SerialNetDevice::Receive (" << &p << ")");
- // Dispatch this to SerialPhy::Receive
- m_phy->Receive (p);
+ ForwardUp (p);
}
void
@@ -125,7 +137,7 @@
// send packet to address tag.address
#endif
NS_DEBUG ("SerialNetDevice::NotifyDataAvailable (): Dequeued");
- m_channel->Propagate(p, this);
+ m_phy->Send(p);
}
}
--- a/src/devices/serial/serial-net-device.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/serial/serial-net-device.h Sun Mar 18 14:06:51 2007 -0700
@@ -35,8 +35,10 @@
class Queue;
class SerialNetDevice : public NetDevice {
-friend class SerialPhy;
public:
+ enum TraceType {
+ QUEUE,
+ };
SerialNetDevice(Node* node, const MacAddress& addr);
virtual ~SerialNetDevice();
@@ -48,7 +50,7 @@
public:
bool Attach(SerialChannel* ch);
void AddQueue(Queue *);
- // called by ChannelSerial
+ // called by SerialPhy
void Receive (Packet& p);
protected:
@@ -58,6 +60,7 @@
private:
virtual void NotifyDataAvailable (void);
virtual bool SendTo (Packet& p, const MacAddress& dest);
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
SerialPhy* m_phy;
SerialChannel* m_channel;
--- a/src/devices/serial/serial-phy.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/serial/serial-phy.cc Sun Mar 18 14:06:51 2007 -0700
@@ -40,30 +40,31 @@
NS_DEBUG ("SerialPhy::~SerialPhy ()");
}
-void
-SerialPhy::NotifyDataAvailable(void)
+void
+SerialPhy::Send (Packet &p)
{
- NS_DEBUG ("SerialPhy::NotifyDataAvailable ()");
+ m_channel->Propagate (p, this);
+}
+void
+SerialPhy::Attach (SerialChannel *channel)
+{
+ m_channel = channel;
+ m_channel->Attach (this);
+}
- Packet p;
- bool found = m_netdevice->GetQueue ()->Dequeue (p);
- if (found)
- {
-#ifdef NOTYET
- struct NetDevicePacketDestAddress tag;
- p.PeekTag (tag);
- // send packet to address tag.address
-#endif
- NS_DEBUG ("SerialPhy::NotifyDataAvailable (): Dequeued");
- m_netdevice->GetChannel()->Propagate(p, m_netdevice);
- }
+SerialNetDevice *
+SerialPhy::GetDevice (void)
+{
+ return m_netdevice;
}
+
+
void
SerialPhy::Receive (Packet& p)
{
NS_DEBUG ("SerialPhy::Receive (" << &p << ")");
- m_netdevice->ForwardUp (p);
+ m_netdevice->Receive (p);
}
} // namespace ns3
--- a/src/devices/serial/serial-phy.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/devices/serial/serial-phy.h Sun Mar 18 14:06:51 2007 -0700
@@ -21,22 +21,27 @@
#ifndef SERIAL_PHY_H
#define SERIAL_PHY_H
-#include <string.h>
-#include "ns3/internet-node.h"
-#include "ns3/packet.h"
-#include "serial-net-device.h"
+namespace ns3 {
-namespace ns3 {
+class SerialNetDevice;
+class SerialChannel;
+class Node;
+class Packet;
class SerialPhy {
public:
SerialPhy(Node* node, SerialNetDevice* netdevice);
virtual ~SerialPhy();
- virtual void NotifyDataAvailable (void);
+
+ void Send (Packet &p);
void Receive (Packet& p);
+ void Attach (SerialChannel *channel);
+
+ SerialNetDevice *GetDevice (void);
private:
Node* m_node;
+ SerialChannel *m_channel;
SerialNetDevice* m_netdevice;
};
--- a/src/node/arp-ipv4-interface.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/arp-ipv4-interface.cc Sun Mar 18 14:06:51 2007 -0700
@@ -21,6 +21,7 @@
*/
#include "ns3/packet.h"
+#include "ns3/composite-trace-resolver.h"
#include "arp-ipv4-interface.h"
#include "arp.h"
@@ -37,6 +38,20 @@
ArpIpv4Interface::~ArpIpv4Interface ()
{}
+TraceResolver *
+ArpIpv4Interface::DoCreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ if (GetDevice () != 0)
+ {
+ resolver->Add ("netdevice",
+ MakeCallback (&NetDevice::CreateTraceResolver, GetDevice ()),
+ ArpIpv4Interface::NETDEVICE);
+ }
+
+ return resolver;
+}
+
void
ArpIpv4Interface::SendTo (Packet p, Ipv4Address dest)
{
--- a/src/node/arp-ipv4-interface.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/arp-ipv4-interface.h Sun Mar 18 14:06:51 2007 -0700
@@ -31,11 +31,16 @@
class ArpIpv4Interface : public Ipv4Interface
{
public:
+ enum TraceType {
+ NETDEVICE,
+ ARP,
+ };
ArpIpv4Interface (Node *node, NetDevice *device);
virtual ~ArpIpv4Interface ();
private:
virtual void SendTo (Packet p, Ipv4Address dest);
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
Node *m_node;
};
--- a/src/node/arp.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/arp.cc Sun Mar 18 14:06:51 2007 -0700
@@ -20,6 +20,7 @@
*/
#include "ns3/packet.h"
#include "ns3/debug.h"
+#include "ns3/empty-trace-resolver.h"
#include "arp.h"
#include "arp-header.h"
#include "arp-cache.h"
@@ -53,6 +54,12 @@
return new Arp (node);
}
+TraceResolver *
+Arp::CreateTraceResolver (TraceContext const &context)
+{
+ return new EmptyTraceResolver (context);
+}
+
ArpCache *
Arp::FindCache (NetDevice *device)
{
--- a/src/node/arp.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/arp.h Sun Mar 18 14:06:51 2007 -0700
@@ -32,6 +32,8 @@
class NetDevice;
class Node;
class Packet;
+class TraceResolver;
+class TraceContext;
class Arp : public L3Protocol
{
@@ -42,6 +44,8 @@
~Arp ();
virtual Arp *Copy (Node *node) const;
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+
virtual void Receive(Packet& p, NetDevice &device);
bool Lookup (Packet &p, Ipv4Address destination,
NetDevice *device,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/channel.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,59 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Craig Dowell <craigdo@ee.washingon.edu>
+ *
+ * Thu Feb 15 14:50:46 PST 2007 craigdo: Created.
+ */
+
+#include "ns3/debug.h"
+#include "channel.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("Channel");
+
+namespace ns3 {
+
+Channel::Channel ()
+ : m_name("Channel")
+{
+ NS_DEBUG("Channel::Channel ()");
+}
+
+Channel::Channel (std::string name)
+ : m_name(name)
+{
+ NS_DEBUG("Channel::Channel (" << name << ")");
+}
+
+Channel::~Channel ()
+{
+ NS_DEBUG("Channel::~Channel ()");
+}
+
+ void
+Channel::SetName(std::string name)
+{
+ m_name = name;
+}
+
+ std::string
+Channel::GetName(void)
+{
+ return m_name;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/channel.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,59 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 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
+ *
+ * Author: Craig Dowell <craigdo@ee.washingon.edu>
+ *
+ * Wed Feb 14 16:05:46 PST 2007 craigdo: Created
+ */
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include <string>
+#include <stdint.h>
+
+namespace ns3 {
+
+class NetDevice;
+
+/**
+ * \brief Abstract Channel Base Class.
+ *
+ * A channel is a logical path over which information flows. The path can
+ * be as simple as a short piece of wire, or as complicated as space-time.
+ */
+class Channel
+{
+public:
+ Channel ();
+ Channel (std::string name);
+ virtual ~Channel ();
+
+ void SetName(std::string);
+ std::string GetName(void);
+
+ virtual uint32_t GetNDevices (void) const = 0;
+ virtual NetDevice *GetDevice (uint32_t i) const = 0;
+
+protected:
+ std::string m_name;
+
+private:
+};
+
+}; // namespace ns3
+
+#endif /* CHANNEL_H */
--- a/src/node/drop-tail.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/drop-tail.cc Sun Mar 18 14:06:51 2007 -0700
@@ -25,34 +25,19 @@
namespace ns3 {
DropTailQueue::DropTailQueue () :
- Queue (""),
+ Queue (),
m_packets (),
m_maxPackets(DTQ_NPACKETS_MAX_DEFAULT)
{
NS_DEBUG("DropTailQueue::DropTailQueue ()");
}
-
-DropTailQueue::DropTailQueue (std::string const&name)
- : Queue (name),
- m_packets(),
- m_maxPackets(DTQ_NPACKETS_MAX_DEFAULT)
-{
- NS_DEBUG("DropTailQueue::DropTailQueue");
-}
-
DropTailQueue::~DropTailQueue ()
{
NS_DEBUG("DropTailQueue::~DropTailQueue ()");
}
void
-DropTailQueue::RegisterTraces (TraceContainer &traceContainer)
-{
- Queue::QueueRegisterTraces (traceContainer);
-}
-
- void
DropTailQueue::SetMaxPackets (uint32_t npackets)
{
NS_DEBUG("DropTailQueue::SetMaxPackets (" << npackets << ")");
@@ -60,7 +45,7 @@
m_maxPackets = npackets;
}
- uint32_t
+uint32_t
DropTailQueue::GetMaxPackets (void)
{
NS_DEBUG("DropTailQueue::GetMaxPackets () <= " << m_maxPackets);
@@ -68,12 +53,12 @@
return m_maxPackets;
}
- bool
+bool
DropTailQueue::DoEnqueue (const Packet& p)
{
NS_DEBUG("DropTailQueue::DoEnqueue (" << &p << ")");
- if (GetNPackets () >= m_maxPackets)
+ if (m_packets.size () >= m_maxPackets)
{
NS_DEBUG("DropTailQueue::DoEnqueue (): Queue full -- droppping pkt");
Drop (p);
@@ -84,7 +69,7 @@
return true;
}
- bool
+bool
DropTailQueue::DoDequeue (Packet& p)
{
NS_DEBUG("DropTailQueue::DoDequeue (" << &p << ")");
--- a/src/node/drop-tail.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/drop-tail.h Sun Mar 18 14:06:51 2007 -0700
@@ -33,9 +33,6 @@
class DropTailQueue : public Queue {
public:
DropTailQueue ();
- DropTailQueue (std::string const &name);
-
- void RegisterTraces (TraceContainer &traceContainer);
virtual ~DropTailQueue();
--- a/src/node/internet-node.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/internet-node.cc Sun Mar 18 14:06:51 2007 -0700
@@ -21,6 +21,8 @@
// Implementation of the InternetNode class for ns3.
// George F. Riley, Georgia Tech, Fall 2006
+#include "ns3/composite-trace-resolver.h"
+
#include "net-device-list.h"
#include "l3-demux.h"
#include "ipv4-l4-demux.h"
@@ -96,6 +98,22 @@
return copy;
}
+TraceResolver *
+InternetNode::CreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ resolver->Add ("ipv4",
+ MakeCallback (&Ipv4::CreateTraceResolver, GetIpv4 ()),
+ InternetNode::IPV4);
+ resolver->Add ("arp",
+ MakeCallback (&Arp::CreateTraceResolver, GetArp ()),
+ InternetNode::ARP);
+ resolver->Add ("udp",
+ MakeCallback (&Udp::CreateTraceResolver, GetUdp ()),
+ InternetNode::UDP);
+ return resolver;
+}
+
NetDeviceList*
InternetNode::GetNetDeviceList() const
--- a/src/node/internet-node.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/internet-node.h Sun Mar 18 14:06:51 2007 -0700
@@ -35,11 +35,17 @@
class InternetNode : public Node
{
public:
+ enum TraceType {
+ IPV4,
+ UDP,
+ ARP,
+ };
InternetNode();
InternetNode(const InternetNode&);
InternetNode const &operator = (InternetNode const &o);
virtual ~InternetNode ();
virtual InternetNode* Copy() const;
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
// Capability access
virtual NetDeviceList* GetNetDeviceList() const;
virtual L3Demux* GetL3Demux() const;
--- a/src/node/ipv4-interface.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-interface.cc Sun Mar 18 14:06:51 2007 -0700
@@ -45,6 +45,12 @@
return m_netdevice;
}
+TraceResolver *
+Ipv4Interface::CreateTraceResolver (TraceContext const &context)
+{
+ return DoCreateTraceResolver (context);
+}
+
void
Ipv4Interface::SetAddress (Ipv4Address a)
{
--- a/src/node/ipv4-interface.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-interface.h Sun Mar 18 14:06:51 2007 -0700
@@ -30,6 +30,8 @@
class NetDevice;
class Packet;
+class TraceResolver;
+class TraceContext;
/**
* \brief The IPv4 representation of a network interface
@@ -62,6 +64,7 @@
Ipv4Interface (NetDevice *nd);
virtual ~Ipv4Interface();
+ TraceResolver *CreateTraceResolver (TraceContext const &context);
NetDevice *GetDevice (void) const;
void SetAddress (Ipv4Address a);
@@ -96,6 +99,7 @@
private:
virtual void SendTo (Packet p, Ipv4Address dest) = 0;
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
NetDevice* m_netdevice;
bool m_ifup;
Ipv4Address m_address;
--- a/src/node/ipv4-l4-demux.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-l4-demux.cc Sun Mar 18 14:06:51 2007 -0700
@@ -22,6 +22,8 @@
// Define the layer 4 demultiplexer object for ns3.
// George F. Riley, Georgia Tech, Fall 2006
+#include <sstream>
+#include "ns3/composite-trace-resolver.h"
#include "ipv4-l4-demux.h"
#include "ipv4-l4-protocol.h"
@@ -48,6 +50,23 @@
}
return copy;
}
+TraceResolver *
+Ipv4L4Demux::CreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+ {
+ Ipv4L4Protocol *protocol = *i;
+ std::string protValue;
+ std::ostringstream oss (protValue);
+ oss << (*i)->GetProtocolNumber ();
+ Ipv4L4ProtocolTraceType protocolNumber = (*i)->GetProtocolNumber ();
+ resolver->Add (protValue,
+ MakeCallback (&Ipv4L4Protocol::CreateTraceResolver, protocol),
+ protocolNumber);
+ }
+ return resolver;
+}
Ipv4L4Protocol*
Ipv4L4Demux::Insert(const Ipv4L4Protocol&protocol)
{
--- a/src/node/ipv4-l4-demux.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-l4-demux.h Sun Mar 18 14:06:51 2007 -0700
@@ -32,12 +32,16 @@
class Ipv4L4Protocol;
class Node;
+class TraceResolver;
+class TraceContext;
class Ipv4L4Demux {
public:
+ typedef int Ipv4L4ProtocolTraceType;
Ipv4L4Demux (Node *node);
virtual ~Ipv4L4Demux();
Ipv4L4Demux* Copy(Node *node) const;
+ TraceResolver *CreateTraceResolver (TraceContext const &context);
Ipv4L4Protocol* Insert(const Ipv4L4Protocol&);
Ipv4L4Protocol* Lookup(int protocolNumber);
void Erase(Ipv4L4Protocol*);
--- a/src/node/ipv4-l4-protocol.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-l4-protocol.h Sun Mar 18 14:06:51 2007 -0700
@@ -31,6 +31,8 @@
class Node;
class Packet;
class Ipv4Address;
+class TraceResolver;
+class TraceContext;
class Ipv4L4Protocol {
public:
@@ -41,6 +43,7 @@
int GetVersion() const;
virtual Ipv4L4Protocol* Copy(Node *node) const = 0;
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
/**
* Called from lower-level layers to send the packet up
* in the stack.
--- a/src/node/ipv4-loopback-interface.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-loopback-interface.cc Sun Mar 18 14:06:51 2007 -0700
@@ -19,6 +19,7 @@
* Authors:
* Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
*/
+#include "ns3/empty-trace-resolver.h"
#include "ipv4-loopback-interface.h"
#include "net-device.h"
#include "node.h"
@@ -33,6 +34,7 @@
Node *PeekNode (void) const;
private:
virtual bool SendTo (Packet& p, const MacAddress& dest);
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
};
Ipv4DummyNetDevice::Ipv4DummyNetDevice (Node *node)
@@ -50,6 +52,11 @@
{
return false;
}
+TraceResolver *
+Ipv4DummyNetDevice::DoCreateTraceResolver (TraceContext const &context)
+{
+ return new EmptyTraceResolver (context);
+}
Ipv4LoopbackInterface::Ipv4LoopbackInterface (Node *node)
@@ -68,6 +75,12 @@
return m_node;
}
+TraceResolver *
+Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
+{
+ return new EmptyTraceResolver (context);
+}
+
void
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
{
--- a/src/node/ipv4-loopback-interface.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4-loopback-interface.h Sun Mar 18 14:06:51 2007 -0700
@@ -36,6 +36,7 @@
private:
virtual void SendTo (Packet p, Ipv4Address dest);
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
Node *GetNode (void) const;
Node *m_node;
--- a/src/node/ipv4.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4.cc Sun Mar 18 14:06:51 2007 -0700
@@ -21,6 +21,9 @@
#include "ns3/packet.h"
#include "ns3/debug.h"
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/array-trace-resolver.h"
+#include "ns3/callback.h"
#include "ipv4.h"
#include "ipv4-l4-protocol.h"
@@ -68,6 +71,30 @@
delete m_defaultRoute;
}
+TraceResolver *
+Ipv4::CreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ resolver->Add ("tx", m_txTrace, Ipv4::TX);
+ resolver->Add ("rx", m_rxTrace, Ipv4::RX);
+ resolver->Add ("drop", m_dropTrace, Ipv4::DROP);
+ resolver->Add ("interfaces",
+ MakeCallback (&Ipv4::InterfacesCreateTraceResolver, this),
+ Ipv4::INTERFACES);
+ return resolver;
+}
+
+TraceResolver *
+Ipv4::InterfacesCreateTraceResolver (TraceContext const &context)
+{
+ ArrayTraceResolver<Ipv4Interface> *resolver =
+ new ArrayTraceResolver<Ipv4Interface>
+ (context,
+ MakeCallback (&Ipv4::GetNInterfaces, this),
+ MakeCallback (&Ipv4::GetInterface, this));
+ return resolver;
+}
+
void
Ipv4::SetDefaultTtl (uint8_t ttl)
{
@@ -77,8 +104,8 @@
void
Ipv4::AddHostRouteTo (Ipv4Address dest,
- Ipv4Address nextHop,
- uint32_t interface)
+ Ipv4Address nextHop,
+ uint32_t interface)
{
Ipv4Route *route = new Ipv4Route ();
*route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
@@ -281,7 +308,7 @@
return 0;
}
uint32_t
-Ipv4::GetNInterfaces (void) const
+Ipv4::GetNInterfaces (void)
{
return m_nInterfaces;
}
@@ -309,7 +336,7 @@
void
Ipv4::Receive(Packet& packet, NetDevice &device)
{
- // XXX trace here.
+ m_rxTrace (packet);
Ipv4Header ipHeader;
packet.Peek (ipHeader);
packet.Remove (ipHeader);
@@ -357,6 +384,7 @@
if (route == 0)
{
NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
+ m_dropTrace (packet);
return;
}
@@ -370,7 +398,7 @@
packet.Add (ip);
Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
- // XXX log trace here.
+ m_txTrace (packet);
if (route.IsGateway ())
{
outInterface->Send (packet, route.GetGateway ());
@@ -425,6 +453,7 @@
// Should send ttl expired here
// XXX
NS_DEBUG ("not for me -- ttl expired. drop.");
+ m_dropTrace (packet);
return true;
}
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
@@ -432,6 +461,7 @@
if (route == 0)
{
NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
+ m_dropTrace (packet);
return true;
}
NS_DEBUG ("not for me -- forwarding.");
--- a/src/node/ipv4.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/ipv4.h Sun Mar 18 14:06:51 2007 -0700
@@ -24,6 +24,8 @@
#include <list>
#include <stdint.h>
+#include "ns3/callback-trace-source.h"
+#include "ns3/array-trace-resolver.h"
#include "ipv4-address.h"
#include "l3-protocol.h"
@@ -36,6 +38,8 @@
class Ipv4Header;
class Ipv4Route;
class Node;
+class TraceResolver;
+class TraceContext;
/**
@@ -46,9 +50,19 @@
public:
static const uint16_t PROT_NUMBER;
+ enum TraceType {
+ TX,
+ RX,
+ DROP,
+ INTERFACES,
+ };
+ typedef ArrayTraceResolver<Ipv4Interface>::Index InterfaceIndex;
+
Ipv4(Node *node);
virtual ~Ipv4 ();
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+
void SetDefaultTtl (uint8_t ttl);
/* add route to host dest through host nextHop
@@ -88,7 +102,7 @@
uint32_t AddInterface (Ipv4Interface *interface);
Ipv4Interface * GetInterface (uint32_t i);
- uint32_t GetNInterfaces (void) const;
+ uint32_t GetNInterfaces (void);
Ipv4Interface *FindInterfaceForDevice (NetDevice const*device);
@@ -109,6 +123,7 @@
void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device);
void ForwardUp (Packet p, Ipv4Header const&ip);
+ TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context);
typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
typedef std::list<Ipv4Route *> HostRoutes;
@@ -126,6 +141,9 @@
NetworkRoutes m_networkRoutes;
Ipv4Route *m_defaultRoute;
Node *m_node;
+ CallbackTraceSource<Packet const &> m_txTrace;
+ CallbackTraceSource<Packet const &> m_rxTrace;
+ CallbackTraceSource<Packet const &> m_dropTrace;
};
} // Namespace ns3
--- a/src/node/l3-demux.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/l3-demux.cc Sun Mar 18 14:06:51 2007 -0700
@@ -20,7 +20,9 @@
//
// Implement the L3Protocols capability for ns3.
// George F. Riley, Georgia Tech, Fall 2006
-
+#include <sstream>
+#include <string>
+#include "ns3/composite-trace-resolver.h"
#include "l3-demux.h"
#include "l3-protocol.h"
@@ -37,6 +39,23 @@
delete i->second;
}
}
+
+TraceResolver *
+L3Demux::CreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ for (L3Map_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+ {
+ std::string protValue;
+ std::ostringstream oss (protValue);
+ oss << (i->second)->GetProtocolNumber ();
+ ProtocolTraceType context = (i->second)->GetProtocolNumber ();
+ resolver->Add (protValue,
+ MakeCallback (&L3Protocol::CreateTraceResolver, i->second),
+ context);
+ }
+ return resolver;
+}
L3Demux* L3Demux::Copy(Node *node) const
{
--- a/src/node/l3-demux.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/l3-demux.h Sun Mar 18 14:06:51 2007 -0700
@@ -33,14 +33,19 @@
class L3Protocol;
class Node;
+class TraceResolver;
+class TraceContext;
class L3Demux
{
public:
+ typedef int ProtocolTraceType;
L3Demux(Node *node);
virtual ~L3Demux();
L3Demux* Copy(Node *node) const;
+ TraceResolver *CreateTraceResolver (TraceContext const &context);
+
// Insert a new protocol
ns3::L3Protocol* Insert(const ns3::L3Protocol&);
// Look up a protocol by protocol number
--- a/src/node/l3-protocol.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/l3-protocol.cc Sun Mar 18 14:06:51 2007 -0700
@@ -33,7 +33,7 @@
{}
L3Protocol::~L3Protocol ()
{}
-
+
int
L3Protocol::GetProtocolNumber (void) const
{
--- a/src/node/l3-protocol.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/l3-protocol.h Sun Mar 18 14:06:51 2007 -0700
@@ -30,7 +30,8 @@
class Packet;
class NetDevice;
class Node;
-
+class TraceResolver;
+class TraceContext;
/**
* ::Send is always defined in subclasses.
@@ -44,6 +45,8 @@
int GetVersion() const;
virtual L3Protocol* Copy(Node *node) const = 0;
+
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
/**
* Lower layer calls this method after calling L3Demux::Lookup
* The ARP subclass needs to know from which NetDevice this
--- a/src/node/net-device.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/net-device.cc Sun Mar 18 14:06:51 2007 -0700
@@ -163,6 +163,11 @@
}
}
+TraceResolver *
+NetDevice::CreateTraceResolver (TraceContext const &context)
+{
+ return DoCreateTraceResolver (context);
+}
// Receive packet from below
bool
--- a/src/node/net-device.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/net-device.h Sun Mar 18 14:06:51 2007 -0700
@@ -31,6 +31,8 @@
class Ipv4L4Demux;
class Node;
+class TraceResolver;
+class TraceContext;
/**
* \brief Network layer to device interface
@@ -58,6 +60,9 @@
*/
NetDevice(Node* node, const MacAddress& addr);
virtual ~NetDevice() {}
+
+ TraceResolver *CreateTraceResolver (TraceContext const &context);
+
/**
* \return the current MacAddress of this interface.
*/
@@ -204,6 +209,7 @@
* MUST override this method.
*/
virtual bool SendTo (Packet& p, const MacAddress& dest) = 0;
+ virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context) = 0;
Node* m_node;
std::string m_name;
uint16_t m_ifIndex;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/node-list.cc Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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:
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ */
+
+#include "ns3/array-trace-resolver.h"
+#include "ns3/trace-root.h"
+#include "node-list.h"
+#include "node.h"
+
+namespace ns3 {
+
+void
+NodeList::Add (Node *node)
+{
+ GetNodes ()->push_back (node);
+}
+NodeList::Iterator
+NodeList::Begin (void)
+{
+ return GetNodes ()->begin ();
+}
+NodeList::Iterator
+NodeList::End (void)
+{
+ return GetNodes ()->end ();
+}
+
+std::vector<Node *> *
+NodeList::GetNodes (void)
+{
+ static bool firstTime = true;
+ if (firstTime)
+ {
+ TraceRoot::Register ("nodes", MakeCallback (&NodeList::CreateTraceResolver));
+ }
+ static std::vector<Node *> nodes;
+ return &nodes;
+}
+uint32_t
+NodeList::GetNNodes (void)
+{
+ return GetNodes ()->size ();
+}
+Node *
+NodeList::GetNode (uint32_t n)
+{
+ return (*GetNodes ())[n];
+}
+
+TraceResolver *
+NodeList::CreateTraceResolver (TraceContext const &context)
+{
+ ArrayTraceResolver<Node> *resolver =
+ new ArrayTraceResolver<Node>
+ (context,
+ MakeCallback (&NodeList::GetNNodes),
+ MakeCallback (&NodeList::GetNode));
+ return resolver;
+}
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/node-list.h Sun Mar 18 14:06:51 2007 -0700
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 INRIA
+ * All rights reserved.
+ *
+ * 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:
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>,
+ */
+#ifndef NODE_LIST_H
+#define NODE_LIST_H
+
+#include <vector>
+#include <string>
+#include "ns3/array-trace-resolver.h"
+
+namespace ns3 {
+
+class Node;
+class CallbackBase;
+class TraceResolver;
+class TraceContext;
+
+class NodeList
+{
+public:
+ typedef ArrayTraceResolver<Node>::Index NodeIndex;
+ typedef std::vector<Node *>::iterator Iterator;
+
+ static void Add (Node *node);
+ static Iterator Begin (void);
+ static Iterator End (void);
+ static TraceResolver *CreateTraceResolver (TraceContext const &context);
+
+ static Node *GetNode (uint32_t n);
+
+private:
+ static std::vector<Node *> *GetNodes (void);
+ static uint32_t GetNNodes (void);
+
+};
+
+}//namespace ns3
+
+
+#endif /* NODE_LIST_H */
--- a/src/node/node.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/node.h Sun Mar 18 14:06:51 2007 -0700
@@ -99,6 +99,8 @@
class Ipv4;
class Udp;
class Arp;
+class TraceContext;
+class TraceResolver;
class Node {
public:
@@ -107,6 +109,8 @@
virtual ~Node();
virtual Node* Copy() const = 0;// Make a copy of this node
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context) = 0;
+
uint32_t GetId (void) const;
uint32_t GetSystemId (void) const;
void SetSystemId(uint32_t s);
--- a/src/node/queue.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/queue.cc Sun Mar 18 14:06:51 2007 -0700
@@ -18,20 +18,20 @@
*/
#include "ns3/debug.h"
+#include "ns3/composite-trace-resolver.h"
#include "queue.h"
NS_DEBUG_COMPONENT_DEFINE ("Queue");
namespace ns3 {
- Queue::Queue(std::string const &name) :
+Queue::Queue() :
m_nBytes(0),
m_nTotalReceivedBytes(0),
m_nPackets(0),
m_nTotalReceivedPackets(0),
m_nTotalDroppedBytes(0),
- m_nTotalDroppedPackets(0),
- m_name (name)
+ m_nTotalDroppedPackets(0)
{
NS_DEBUG("Queue::Queue ()");
}
@@ -41,6 +41,16 @@
NS_DEBUG("Queue::~Queue ()");
}
+TraceResolver *
+Queue::CreateTraceResolver (TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ resolver->Add ("enqueue", m_traceEnqueue, Queue::ENQUEUE);
+ resolver->Add ("dequeue", m_traceDequeue, Queue::DEQUEUE);
+ resolver->Add ("drop", m_traceDrop, Queue::DROP);
+ return resolver;
+}
+
bool
Queue::Enqueue (const Packet& p)
{
@@ -48,7 +58,7 @@
NS_DEBUG("Queue::Enqueue (): m_traceEnqueue (p)");
- m_traceEnqueue (m_name, p);
+ m_traceEnqueue (p);
bool retval = DoEnqueue (p);
if (retval)
@@ -77,7 +87,7 @@
NS_DEBUG("Queue::Dequeue (): m_traceDequeue (p)");
const Packet packet = p;
- m_traceDequeue (m_name, packet);
+ m_traceDequeue (packet);
}
return retval;
@@ -115,19 +125,6 @@
return m_nPackets == 0;
}
-void
-Queue::QueueRegisterTraces (TraceContainer &container)
-{
- NS_DEBUG("Queue::RegisterTraces (" << &container << ")");
-
- container.RegisterCallback ("Queue::Enqueue",
- &m_traceEnqueue);
- container.RegisterCallback ("Queue::Dequeue",
- &m_traceDequeue);
- container.RegisterCallback ("Queue::Drop",
- &m_traceDrop);
-}
-
uint32_t
Queue::GetTotalReceivedBytes (void)
{
@@ -182,7 +179,7 @@
m_nTotalDroppedBytes += p.GetSize ();
NS_DEBUG("Queue::Drop (): m_traceDrop (p)");
- m_traceDrop (m_name, p);
+ m_traceDrop (p);
}
}; // namespace ns3
--- a/src/node/queue.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/queue.h Sun Mar 18 14:06:51 2007 -0700
@@ -27,17 +27,25 @@
#include <string>
#include "ns3/packet.h"
-#include "ns3/callback-tracer.h"
-#include "ns3/trace-container.h"
+#include "ns3/callback-trace-source.h"
+#include "ns3/trace-resolver.h"
namespace ns3 {
class Queue
{
public:
- Queue (std::string const &name);
+ enum TraceType {
+ ENQUEUE,
+ DEQUEUE,
+ DROP,
+ };
+ Queue ();
virtual ~Queue ();
+ TraceResolver *CreateTraceResolver (TraceContext const &context);
+
+ bool IsEmpty (void);
bool Enqueue (const Packet& p);
bool Dequeue (Packet &p);
@@ -45,8 +53,6 @@
uint32_t GetNPackets (void);
uint32_t GetNBytes (void);
- bool IsEmpty (void);
-
uint32_t GetTotalReceivedBytes (void);
uint32_t GetTotalReceivedPackets (void);
uint32_t GetTotalDroppedBytes (void);
@@ -85,12 +91,11 @@
protected:
// called by subclasses to notify parent of packet drops.
void Drop (const Packet& p);
- void QueueRegisterTraces (TraceContainer &container);
private:
- CallbackTracer<std::string const &, const Packet &> m_traceEnqueue;
- CallbackTracer<std::string const &, const Packet &> m_traceDequeue;
- CallbackTracer<std::string const &, const Packet &> m_traceDrop;
+ CallbackTraceSource<const Packet &> m_traceEnqueue;
+ CallbackTraceSource<const Packet &> m_traceDequeue;
+ CallbackTraceSource<const Packet &> m_traceDrop;
uint32_t m_nBytes;
uint32_t m_nTotalReceivedBytes;
@@ -99,9 +104,6 @@
uint32_t m_nTotalDroppedBytes;
uint32_t m_nTotalDroppedPackets;
- std::string m_name;
-
-
#if 0
// Static methods to manage queue default
// Set desired queue default
--- a/src/node/udp.cc Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/udp.cc Sun Mar 18 14:06:51 2007 -0700
@@ -21,6 +21,8 @@
#include "ns3/assert.h"
#include "ns3/packet.h"
+#include "ns3/empty-trace-resolver.h"
+
#include "udp.h"
#include "udp-header.h"
#include "ipv4-end-point-demux.h"
@@ -46,6 +48,12 @@
delete m_endPoints;
}
+TraceResolver *
+Udp::CreateTraceResolver (TraceContext const &context)
+{
+ return new EmptyTraceResolver (context);
+}
+
UdpEndPoint *
Udp::Allocate (void)
{
--- a/src/node/udp.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/node/udp.h Sun Mar 18 14:06:51 2007 -0700
@@ -33,6 +33,8 @@
namespace ns3 {
class Node;
+class TraceResolver;
+class TraceContext;
class Udp : public Ipv4L4Protocol {
public:
@@ -41,6 +43,8 @@
Udp (Node *node);
virtual ~Udp ();
+ virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
+
UdpEndPoint *Allocate (void);
UdpEndPoint *Allocate (Ipv4Address address);
UdpEndPoint *Allocate (uint16_t port);
--- a/src/simulator/simulator.h Sun Mar 18 19:31:32 2007 +0100
+++ b/src/simulator/simulator.h Sun Mar 18 14:06:51 2007 -0700
@@ -151,11 +151,11 @@
static void StopAt (Time const &time);
/**
- * Schedule an event to expire when time is reached.
- * When the event expires, the input method will be invoked
- * on the input object.
+ * Schedule an event to expire when the time "now + time"
+ * is reached. When the event expires, the input method
+ * will be invoked on the input object.
*
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @returns an id for the scheduled event.
@@ -163,7 +163,7 @@
template <typename T>
static EventId Schedule (Time const &time, void (T::*mem_ptr) (void), T *obj);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
@@ -172,7 +172,7 @@
template <typename T, typename T1>
static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1), T* obj, T1 a1);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
@@ -182,7 +182,7 @@
template <typename T, typename T1, typename T2>
static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2), T* obj, T1 a1, T2 a2);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
@@ -193,7 +193,7 @@
template <typename T, typename T1, typename T2, typename T3>
static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3), T* obj, T1 a1, T2 a2, T3 a3);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
@@ -205,7 +205,7 @@
template <typename T, typename T1, typename T2, typename T3, typename T4>
static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4), T* obj, T1 a1, T2 a2, T3 a3, T4 a4);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
@@ -219,13 +219,13 @@
static EventId Schedule (Time const &time, void (T::*mem_ptr) (T1,T2,T3,T4,T5), T* obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param f the function to invoke
* @returns an id for the scheduled event.
*/
static EventId Schedule (Time const &time, void (*f) (void));
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param f the function to invoke
* @param a1 the first argument to pass to the function to invoke
* @returns an id for the scheduled event.
@@ -233,7 +233,7 @@
template <typename T1>
static EventId Schedule (Time const &time, void (*f) (T1), T1 a1);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param f the function to invoke
* @param a1 the first argument to pass to the function to invoke
* @param a2 the second argument to pass to the function to invoke
@@ -242,7 +242,7 @@
template <typename T1, typename T2>
static EventId Schedule (Time const &time, void (*f) (T1,T2), T1 a1, T2 a2);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param f the function to invoke
* @param a1 the first argument to pass to the function to invoke
* @param a2 the second argument to pass to the function to invoke
@@ -252,7 +252,7 @@
template <typename T1, typename T2, typename T3>
static EventId Schedule (Time const &time, void (*f) (T1,T2,T3), T1 a1, T2 a2, T3 a3);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param f the function to invoke
* @param a1 the first argument to pass to the function to invoke
* @param a2 the second argument to pass to the function to invoke
@@ -263,7 +263,7 @@
template <typename T1, typename T2, typename T3, typename T4>
static EventId Schedule (Time const &time, void (*f) (T1,T2,T3,T4), T1 a1, T2 a2, T3 a3, T4 a4);
/**
- * @param time the expiration time of the event.
+ * @param time the relative expiration time of the event.
* @param f the function to invoke
* @param a1 the first argument to pass to the function to invoke
* @param a2 the second argument to pass to the function to invoke