move channel.cc channel.h to node directory; merge ns-3-tracing from mathieu
parent
79568bde6f
commit
327949573d
39
SConstruct
39
SConstruct
|
@ -140,9 +140,15 @@ common.add_sources([
|
|||
'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 @@ common.add_inst_headers([
|
|||
'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 @@ node.add_sources ([
|
|||
'net-device-list.cc',
|
||||
'queue.cc',
|
||||
'drop-tail.cc',
|
||||
'channel.cc',
|
||||
'node-list.cc',
|
||||
])
|
||||
node.add_headers ([
|
||||
'ipv4-header.h',
|
||||
|
@ -229,10 +242,12 @@ node.add_inst_headers ([
|
|||
'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.add_sources ([
|
|||
'serial-channel.cc',
|
||||
'serial-phy.cc',
|
||||
'layer-connector.cc',
|
||||
'channel.cc',
|
||||
])
|
||||
serial.add_headers ([
|
||||
'propagator.h',
|
||||
|
@ -261,7 +275,6 @@ serial.add_inst_headers ([
|
|||
'serial-channel.h',
|
||||
'serial-phy.h',
|
||||
'layer-connector.h',
|
||||
'channel.h',
|
||||
])
|
||||
|
||||
|
||||
|
@ -312,7 +325,7 @@ sample_ptr.add_dep('core')
|
|||
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_simple.add_source('main-simple.cc')
|
|||
|
||||
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')
|
||||
|
||||
|
|
|
@ -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 @@ public:
|
|||
|
||||
~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 @@ int main (int argc, char *argv[])
|
|||
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 @@ int main (int argc, char *argv[])
|
|||
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 @@ int main (int argc, char *argv[])
|
|||
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 @@ int main (int argc, char *argv[])
|
|||
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));
|
||||
|
||||
// create a packet on one node and send it through, reading it
|
||||
// on the other node
|
||||
Packet p;
|
||||
PrintTraffic (sink);
|
||||
GenerateTraffic (source, 100);
|
||||
|
||||
NS_DEBUG_UNCOND("Sending Packet " << &p);
|
||||
arpipv4interfacep->Send(p, Ipv4Address("10.1.1.2"));
|
||||
Simulator::Run ();
|
||||
|
||||
//neta.Send(p, MacAddress()); // Test that all-zero's MacAddress used
|
||||
//netb.Send(p, "00:01:02:03:04:05"); // Dummy function call
|
||||
Simulator::Destroy ();
|
||||
|
||||
delete source;
|
||||
delete sink;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 @@ public:
|
|||
|
||||
~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 @@ PrintRoutingTable (InternetNode *a, std::string name)
|
|||
|
||||
static SerialChannel *
|
||||
AddDuplexLink(
|
||||
std::string &name,
|
||||
std::string name,
|
||||
uint64_t bps,
|
||||
uint32_t delay,
|
||||
InternetNode* a,
|
||||
|
@ -207,12 +224,8 @@ AddDuplexLink(
|
|||
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 @@ AddDuplexLink(
|
|||
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 @@ AddDuplexLink(
|
|||
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 @@ int main (int argc, char *argv[])
|
|||
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);
|
||||
|
||||
channelName = "Channel 2";
|
||||
SerialChannel* ch2 = AddDuplexLink (channelName, 5000000, 2,
|
||||
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"),
|
||||
traceContainer);
|
||||
SetupTrace (traceContainer, tracer);
|
||||
n2, Ipv4Address("10.1.2.2"), MacAddress("00:00:00:00:00:04"));
|
||||
|
||||
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 @@ int main (int argc, char *argv[])
|
|||
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);
|
||||
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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)
|
||||
{}
|
|
@ -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 */
|
|
@ -22,29 +22,32 @@
|
|||
#ifndef F_VARIABLE_TRACER_H
|
||||
#define F_VARIABLE_TRACER_H
|
||||
|
||||
#include "ns3/callback.h"
|
||||
#include "callback-trace-source.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class FVariableTracerBase {
|
||||
class FVTraceSourceBase {
|
||||
public:
|
||||
typedef Callback<void,double, double> ChangeNotifyCallback;
|
||||
typedef CallbackTraceSource<double, double> ChangeNotifyCallback;
|
||||
|
||||
FVariableTracerBase () {}
|
||||
FVariableTracerBase (FVariableTracerBase const &o) {}
|
||||
FVariableTracerBase &operator = (FVariableTracerBase const &o) {
|
||||
FVTraceSourceBase () {}
|
||||
FVTraceSourceBase (FVTraceSourceBase const &o) {}
|
||||
FVTraceSourceBase &operator = (FVTraceSourceBase const &o) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
~FVariableTracerBase () {}
|
||||
~FVTraceSourceBase () {}
|
||||
|
||||
void setCallback(ChangeNotifyCallback callback) {
|
||||
m_callback = callback;
|
||||
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.IsNull ())
|
||||
if (oldVal != newVal)
|
||||
{
|
||||
m_callback (oldVal, newVal);
|
||||
}
|
||||
|
@ -53,6 +56,11 @@ private:
|
|||
ChangeNotifyCallback m_callback;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class FVTraceSource : public FVTraceSourceBase
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
|
@ -19,32 +19,35 @@
|
|||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef SI_VARIABLE_TRACER_H
|
||||
#define SI_VARIABLE_TRACER_H
|
||||
#ifndef SV_TRACE_SOURCE_H
|
||||
#define SV_TRACE_SOURCE_H
|
||||
|
||||
#include "ns3/callback.h"
|
||||
#include "callback-trace-source.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class SiVariableTracerBase {
|
||||
class SVTraceSourceBase {
|
||||
public:
|
||||
typedef Callback<void,int64_t, int64_t> ChangeNotifyCallback;
|
||||
typedef CallbackTraceSource<int64_t, int64_t> ChangeNotifyCallback;
|
||||
|
||||
SiVariableTracerBase () {}
|
||||
SiVariableTracerBase (SiVariableTracerBase const &o) {}
|
||||
SiVariableTracerBase &operator = (SiVariableTracerBase const &o) {
|
||||
SVTraceSourceBase () {}
|
||||
SVTraceSourceBase (SVTraceSourceBase const &o) {}
|
||||
SVTraceSourceBase &operator = (SVTraceSourceBase const &o) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SiVariableTracerBase () {}
|
||||
~SVTraceSourceBase () {}
|
||||
|
||||
void SetCallback(ChangeNotifyCallback callback) {
|
||||
m_callback = callback;
|
||||
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.IsNull ())
|
||||
if (oldVal != newVal)
|
||||
{
|
||||
m_callback (oldVal, newVal);
|
||||
}
|
||||
|
@ -54,11 +57,12 @@ private:
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
class UiVariableTracer;
|
||||
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"
|
||||
|
@ -67,12 +71,12 @@ class UiVariableTracer;
|
|||
*
|
||||
* 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> :
|
||||
* ns3::UVTraceSource<int32_t> :
|
||||
\code
|
||||
#include <stdint.h>
|
||||
#include "ns3/si-traced-variable.tcc"
|
||||
#include "ns3/sv-trace-source.h"
|
||||
|
||||
ns3::SiVariableTracer<uint16_t> var;
|
||||
ns3::SVTraceSource<uint16_t> var;
|
||||
\endcode
|
||||
* and you would use it like any other variable of type int32_t:
|
||||
\code
|
||||
|
@ -82,44 +86,44 @@ class UiVariableTracer;
|
|||
\endcode
|
||||
*/
|
||||
template <typename T>
|
||||
class SiVariableTracer : public SiVariableTracerBase {
|
||||
class SVTraceSource : public SVTraceSourceBase {
|
||||
public:
|
||||
SiVariableTracer ()
|
||||
SVTraceSource ()
|
||||
: m_var (0)
|
||||
{}
|
||||
SiVariableTracer (T const &var)
|
||||
SVTraceSource (T const &var)
|
||||
: m_var (var)
|
||||
{}
|
||||
|
||||
SiVariableTracer &operator = (SiVariableTracer const &o) {
|
||||
SVTraceSource &operator = (SVTraceSource const &o) {
|
||||
Assign (o.Get ());
|
||||
return *this;
|
||||
}
|
||||
template <typename TT>
|
||||
SiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
|
||||
SVTraceSource &operator = (SVTraceSource<TT> const &o) {
|
||||
Assign (o.Get ());
|
||||
return *this;
|
||||
}
|
||||
template <typename TT>
|
||||
SiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
|
||||
SVTraceSource &operator = (UVTraceSource<TT> const &o) {
|
||||
Assign (o.Get ());
|
||||
return *this;
|
||||
}
|
||||
SiVariableTracer &operator++ () {
|
||||
SVTraceSource &operator++ () {
|
||||
Assign (Get () + 1);
|
||||
return *this;
|
||||
}
|
||||
SiVariableTracer &operator-- () {
|
||||
SVTraceSource &operator-- () {
|
||||
Assign (Get () - 1);
|
||||
return *this;
|
||||
}
|
||||
SiVariableTracer operator++ (int) {
|
||||
SiVariableTracer old (*this);
|
||||
SVTraceSource operator++ (int) {
|
||||
SVTraceSource old (*this);
|
||||
++*this;
|
||||
return old;
|
||||
}
|
||||
SiVariableTracer operator-- (int) {
|
||||
SiVariableTracer old (*this);
|
||||
SVTraceSource operator-- (int) {
|
||||
SVTraceSource old (*this);
|
||||
--*this;
|
||||
return old;
|
||||
}
|
||||
|
@ -141,98 +145,98 @@ private:
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator += (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator += (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () + rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator -= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator -= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () - rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator *= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator *= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () * rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator /= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator /= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () / rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator <<= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator <<= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () << rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator >>= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator >>= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () >> rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator &= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator &= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () & rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator |= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator |= (SVTraceSource<T> &lhs, SVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () | rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
SiVariableTracer<T> &operator ^= (SiVariableTracer<T> &lhs, SiVariableTracer<T> const &rhs) {
|
||||
SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator += (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator -= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator *= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator /= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator <<= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator >>= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator &= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator |= (SVTraceSource<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) {
|
||||
SVTraceSource<T> &operator ^= (SVTraceSource<T> &lhs, U const &rhs) {
|
||||
lhs.Assign (lhs.Get () ^ rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* SI_VARIABLE_TRACER_H */
|
||||
#endif /* SV_TRACE_SOURCE_H */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -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
|
|
@ -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 */
|
|
@ -19,35 +19,39 @@
|
|||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef UI_VARIABLE_TRACER_H
|
||||
#define UI_VARIABLE_TRACER_H
|
||||
#ifndef UV_TRACE_SOURCE_H
|
||||
#define UV_TRACE_SOURCE_H
|
||||
|
||||
#include "ns3/callback.h"
|
||||
#include "callback-trace-source.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class UiVariableTracerBase {
|
||||
class UVTraceSourceBase {
|
||||
public:
|
||||
typedef Callback<void, uint64_t, uint64_t> ChangeNotifyCallback;
|
||||
typedef CallbackTraceSource<uint64_t, uint64_t> ChangeNotifyCallback;
|
||||
|
||||
UiVariableTracerBase ()
|
||||
UVTraceSourceBase ()
|
||||
: 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)
|
||||
UVTraceSourceBase (UVTraceSourceBase const &o)
|
||||
: m_callback () {}
|
||||
UiVariableTracerBase &operator = (UiVariableTracerBase const &o) {
|
||||
UVTraceSourceBase &operator = (UVTraceSourceBase const &o) {
|
||||
return *this;
|
||||
}
|
||||
~UiVariableTracerBase () {}
|
||||
~UVTraceSourceBase () {}
|
||||
|
||||
void SetCallback(ChangeNotifyCallback callback) {
|
||||
m_callback = callback;
|
||||
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.IsNull ())
|
||||
if (oldVal != newVal)
|
||||
{
|
||||
m_callback (oldVal, newVal);
|
||||
}
|
||||
|
@ -57,11 +61,12 @@ private:
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
class SiVariableTracer;
|
||||
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"
|
||||
|
@ -70,12 +75,12 @@ class SiVariableTracer;
|
|||
*
|
||||
* 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> :
|
||||
* ns3::UVTraceSource<uint32_t> :
|
||||
\code
|
||||
#include <stdint.h>
|
||||
#include "ns3/ui-traced-variable.tcc"
|
||||
#include "ns3/uv-trace-source.h"
|
||||
|
||||
ns3::UiVariableTracer<uint32_t> var;
|
||||
ns3::UVTraceSource<uint32_t> var;
|
||||
\endcode
|
||||
* and you would use it like any other variable of type uint32_t:
|
||||
\code
|
||||
|
@ -84,44 +89,44 @@ class SiVariableTracer;
|
|||
\endcode
|
||||
*/
|
||||
template <typename T>
|
||||
class UiVariableTracer : public UiVariableTracerBase {
|
||||
class UVTraceSource : public UVTraceSourceBase {
|
||||
public:
|
||||
UiVariableTracer ()
|
||||
UVTraceSource ()
|
||||
: m_var ()
|
||||
{}
|
||||
UiVariableTracer (T const &var)
|
||||
UVTraceSource (T const &var)
|
||||
: m_var (var)
|
||||
{}
|
||||
|
||||
UiVariableTracer &operator = (UiVariableTracer const &o) {
|
||||
UVTraceSource &operator = (UVTraceSource const &o) {
|
||||
Assign (o.Get ());
|
||||
return *this;
|
||||
}
|
||||
template <typename TT>
|
||||
UiVariableTracer &operator = (UiVariableTracer<TT> const &o) {
|
||||
UVTraceSource &operator = (UVTraceSource<TT> const &o) {
|
||||
Assign (o.Get ());
|
||||
return *this;
|
||||
}
|
||||
template <typename TT>
|
||||
UiVariableTracer &operator = (SiVariableTracer<TT> const &o) {
|
||||
UVTraceSource &operator = (SVTraceSource<TT> const &o) {
|
||||
Assign (o.Get ());
|
||||
return *this;
|
||||
}
|
||||
UiVariableTracer &operator++ () {
|
||||
UVTraceSource &operator++ () {
|
||||
Assign (Get () + 1);
|
||||
return *this;
|
||||
}
|
||||
UiVariableTracer &operator-- () {
|
||||
UVTraceSource &operator-- () {
|
||||
Assign (Get () - 1);
|
||||
return *this;
|
||||
}
|
||||
UiVariableTracer operator++ (int) {
|
||||
UiVariableTracer old (*this);
|
||||
UVTraceSource operator++ (int) {
|
||||
UVTraceSource old (*this);
|
||||
++*this;
|
||||
return old;
|
||||
}
|
||||
UiVariableTracer operator-- (int) {
|
||||
UiVariableTracer old (*this);
|
||||
UVTraceSource operator-- (int) {
|
||||
UVTraceSource old (*this);
|
||||
--*this;
|
||||
return old;
|
||||
}
|
||||
|
@ -143,98 +148,98 @@ private:
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator += (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator += (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () + rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator -= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator -= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () - rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator *= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator *= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () * rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator /= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator /= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () / rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator <<= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator <<= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () << rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator >>= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator >>= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () >> rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator &= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator &= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () & rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator |= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator |= (UVTraceSource<T> &lhs, UVTraceSource<T> const &rhs) {
|
||||
lhs.Assign (lhs.Get () | rhs.Get ());
|
||||
return lhs;
|
||||
}
|
||||
template <typename T>
|
||||
UiVariableTracer<T> &operator ^= (UiVariableTracer<T> &lhs, UiVariableTracer<T> const &rhs) {
|
||||
UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator += (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator -= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator *= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator /= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator <<= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator >>= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator &= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator |= (UVTraceSource<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) {
|
||||
UVTraceSource<T> &operator ^= (UVTraceSource<T> &lhs, U const &rhs) {
|
||||
lhs.Assign (lhs.Get () ^ rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif /* UI_VARIABLE_TRACER_H */
|
||||
#endif /* UV_TRACE_SOURCE_H */
|
|
@ -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 @@ namespace ns3 {
|
|||
|
||||
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 @@ public:
|
|||
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 @@ VariableTracerTest::RunSignedUnsignedTests (void)
|
|||
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;
|
||||
|
|
|
@ -47,6 +47,16 @@ int Test7 (int a)
|
|||
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 @@ CallbackTest::RunTests (void)
|
|||
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 @@ CallbackTest::RunTests (void)
|
|||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
|
||||
MakeBoundCallback (&Test7, 0);
|
||||
bool v;
|
||||
MakeBoundCallback (&Test9, &v);
|
||||
MakeBoundCallback (&Test10, &v);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class empty {};
|
|||
class CallbackImplBase {
|
||||
public:
|
||||
virtual ~CallbackImplBase () {}
|
||||
virtual bool IsEqual (CallbackImplBase const *other) const = 0;
|
||||
};
|
||||
|
||||
// declare the CallbackImpl class
|
||||
|
@ -134,6 +135,19 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
* 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 @@ public:
|
|||
}
|
||||
|
||||
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 @@ Callback<R,T1,T2,T3,T4,T5> MakeCallback (R (OBJ::*mem_ptr) (T1,T2,T3,T4,T5), OBJ
|
|||
*/
|
||||
template <typename R>
|
||||
Callback<R> MakeCallback (R (*fnPtr) ()) {
|
||||
return Callback<R> (fnPtr);
|
||||
return Callback<R> (fnPtr, true, true);
|
||||
}
|
||||
/**
|
||||
* \ingroup MakeCallback
|
||||
|
@ -362,7 +397,7 @@ Callback<R> MakeCallback (R (*fnPtr) ()) {
|
|||
*/
|
||||
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 @@ Callback<R,T1> MakeCallback (R (*fnPtr) (T1)) {
|
|||
*/
|
||||
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 @@ Callback<R,T1,T2> MakeCallback (R (*fnPtr) (T1,T2)) {
|
|||
*/
|
||||
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 @@ Callback<R,T1,T2,T3> MakeCallback (R (*fnPtr) (T1,T2,T3)) {
|
|||
*/
|
||||
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 @@ Callback<R,T1,T2,T3,T4> MakeCallback (R (*fnPtr) (T1,T2,T3,T4)) {
|
|||
*/
|
||||
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 @@ public:
|
|||
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 =
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 @@ P2PNetDevice::SendTo (Packet& p, const MacAddress&)
|
|||
return true;
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
P2PNetDevice::DoCreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return new EmptyTraceResolver (context);
|
||||
}
|
||||
|
||||
void
|
||||
P2PNetDevice::Receive(Packet p)
|
||||
{
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
void TxComplete (void);
|
||||
private:
|
||||
virtual bool SendTo (Packet& p, const MacAddress& dest);
|
||||
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
|
||||
|
||||
double m_rate;
|
||||
P2PChannel *m_channel;
|
||||
};
|
||||
|
|
|
@ -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 @@ namespace ns3 {
|
|||
//
|
||||
// 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 @@ SerialChannel::SerialChannel(
|
|||
}
|
||||
|
||||
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 @@ SerialChannel::Attach(SerialNetDevice *device)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SerialChannel::TransmitCompleteEvent(Packet &p, SerialNetDevice *src)
|
||||
void
|
||||
SerialChannel::TransmitCompleteEvent(Packet p, SerialPhy *src)
|
||||
{
|
||||
NS_DEBUG("SerialChannel::TransmitCompleteEvent (" << &p << ", " <<
|
||||
src << ")");
|
||||
|
@ -97,8 +99,8 @@ SerialChannel::TransmitCompleteEvent(Packet &p, SerialNetDevice *src)
|
|||
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 @@ SerialChannel::Propagate(Packet& p, SerialNetDevice* src)
|
|||
// 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;
|
||||
Time tEvent = Seconds (static_cast<double> (p.GetSize() * 8) /
|
||||
static_cast<double> (m_bps)) + m_delay;
|
||||
|
||||
NS_DEBUG("SerialChannel::DoSend (): Schedule Receive at " << tEvent);
|
||||
NS_DEBUG("SerialChannel::DoSend (): Schedule Receive delay " << tEvent);
|
||||
|
||||
#if 0
|
||||
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
|
||||
|
|
|
@ -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 @@ namespace ns3 {
|
|||
|
||||
// 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 @@ public:
|
|||
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 @@ protected:
|
|||
{
|
||||
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];
|
||||
|
|
|
@ -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(Node* node, const MacAddress& addr) :
|
|||
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 @@ SerialNetDevice::SendTo (Packet& p, const MacAddress& dest)
|
|||
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 @@ SerialNetDevice::Receive (Packet& p)
|
|||
// 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 @@ SerialNetDevice::NotifyDataAvailable(void)
|
|||
// send packet to address tag.address
|
||||
#endif
|
||||
NS_DEBUG ("SerialNetDevice::NotifyDataAvailable (): Dequeued");
|
||||
m_channel->Propagate(p, this);
|
||||
m_phy->Send(p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,10 @@ class SerialPhy;
|
|||
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 @@ private:
|
|||
public:
|
||||
bool Attach(SerialChannel* ch);
|
||||
void AddQueue(Queue *);
|
||||
// called by ChannelSerial
|
||||
// called by SerialPhy
|
||||
void Receive (Packet& p);
|
||||
|
||||
protected:
|
||||
|
@ -58,6 +60,7 @@ protected:
|
|||
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;
|
||||
|
|
|
@ -40,30 +40,31 @@ SerialPhy::~SerialPhy()
|
|||
NS_DEBUG ("SerialPhy::~SerialPhy ()");
|
||||
}
|
||||
|
||||
void
|
||||
SerialPhy::NotifyDataAvailable(void)
|
||||
void
|
||||
SerialPhy::Send (Packet &p)
|
||||
{
|
||||
NS_DEBUG ("SerialPhy::NotifyDataAvailable ()");
|
||||
|
||||
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);
|
||||
}
|
||||
m_channel->Propagate (p, this);
|
||||
}
|
||||
void
|
||||
SerialPhy::Attach (SerialChannel *channel)
|
||||
{
|
||||
m_channel = channel;
|
||||
m_channel->Attach (this);
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 (Node *node, NetDevice *device)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -31,11 +31,16 @@ class Node;
|
|||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 @@ Arp::Copy (Node *node) const
|
|||
return new Arp (node);
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
Arp::CreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return new EmptyTraceResolver (context);
|
||||
}
|
||||
|
||||
ArpCache *
|
||||
Arp::FindCache (NetDevice *device)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,8 @@ class ArpCache;
|
|||
class NetDevice;
|
||||
class Node;
|
||||
class Packet;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
class Arp : public L3Protocol
|
||||
{
|
||||
|
@ -42,6 +44,8 @@ public:
|
|||
~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,
|
||||
|
|
|
@ -33,8 +33,8 @@ Channel::Channel ()
|
|||
NS_DEBUG("Channel::Channel ()");
|
||||
}
|
||||
|
||||
Channel::Channel (std::string name)
|
||||
: m_name(name)
|
||||
Channel::Channel (std::string name)
|
||||
: m_name(name)
|
||||
{
|
||||
NS_DEBUG("Channel::Channel (" << name << ")");
|
||||
}
|
|
@ -19,16 +19,16 @@
|
|||
*
|
||||
* 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
|
||||
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class NetDevice;
|
||||
|
||||
/**
|
||||
* \brief Abstract Channel Base Class.
|
||||
*
|
||||
|
@ -42,8 +42,11 @@ public:
|
|||
Channel (std::string name);
|
||||
virtual ~Channel ();
|
||||
|
||||
virtual void SetName(std::string);
|
||||
virtual std::string GetName(void);
|
||||
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;
|
|
@ -25,34 +25,19 @@ NS_DEBUG_COMPONENT_DEFINE ("DropTailQueue");
|
|||
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 @@ DropTailQueue::SetMaxPackets (uint32_t npackets)
|
|||
m_maxPackets = npackets;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
uint32_t
|
||||
DropTailQueue::GetMaxPackets (void)
|
||||
{
|
||||
NS_DEBUG("DropTailQueue::GetMaxPackets () <= " << m_maxPackets);
|
||||
|
@ -68,12 +53,12 @@ DropTailQueue::GetMaxPackets (void)
|
|||
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 @@ DropTailQueue::DoEnqueue (const Packet& p)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
bool
|
||||
DropTailQueue::DoDequeue (Packet& p)
|
||||
{
|
||||
NS_DEBUG("DropTailQueue::DoDequeue (" << &p << ")");
|
||||
|
|
|
@ -33,9 +33,6 @@ const int DTQ_NPACKETS_MAX_DEFAULT = 100;
|
|||
class DropTailQueue : public Queue {
|
||||
public:
|
||||
DropTailQueue ();
|
||||
DropTailQueue (std::string const &name);
|
||||
|
||||
void RegisterTraces (TraceContainer &traceContainer);
|
||||
|
||||
virtual ~DropTailQueue();
|
||||
|
||||
|
|
|
@ -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 @@ InternetNode::Copy() const
|
|||
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
|
||||
|
|
|
@ -35,11 +35,17 @@ namespace ns3 {
|
|||
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;
|
||||
|
|
|
@ -45,6 +45,12 @@ Ipv4Interface::GetDevice (void) const
|
|||
return m_netdevice;
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
Ipv4Interface::CreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return DoCreateTraceResolver (context);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4Interface::SetAddress (Ipv4Address a)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace ns3 {
|
|||
|
||||
class NetDevice;
|
||||
class Packet;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
/**
|
||||
* \brief The IPv4 representation of a network interface
|
||||
|
@ -62,6 +64,7 @@ public:
|
|||
Ipv4Interface (NetDevice *nd);
|
||||
virtual ~Ipv4Interface();
|
||||
|
||||
TraceResolver *CreateTraceResolver (TraceContext const &context);
|
||||
NetDevice *GetDevice (void) const;
|
||||
|
||||
void SetAddress (Ipv4Address a);
|
||||
|
@ -96,6 +99,7 @@ public:
|
|||
|
||||
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;
|
||||
|
|
|
@ -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 @@ Ipv4L4Demux::Copy(Node *node) const
|
|||
}
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -32,12 +32,16 @@ namespace ns3 {
|
|||
|
||||
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*);
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace ns3 {
|
|||
class Node;
|
||||
class Packet;
|
||||
class Ipv4Address;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
class Ipv4L4Protocol {
|
||||
public:
|
||||
|
@ -41,6 +43,7 @@ public:
|
|||
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.
|
||||
|
|
|
@ -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 @@ public:
|
|||
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 @@ Ipv4DummyNetDevice::SendTo (Packet& p, const MacAddress& dest)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
TraceResolver *
|
||||
Ipv4DummyNetDevice::DoCreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return new EmptyTraceResolver (context);
|
||||
}
|
||||
|
||||
|
||||
Ipv4LoopbackInterface::Ipv4LoopbackInterface (Node *node)
|
||||
|
@ -68,6 +75,12 @@ Ipv4LoopbackInterface::GetNode (void) const
|
|||
return m_node;
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
Ipv4LoopbackInterface::DoCreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return new EmptyTraceResolver (context);
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ class Ipv4LoopbackInterface : public Ipv4Interface
|
|||
|
||||
private:
|
||||
virtual void SendTo (Packet p, Ipv4Address dest);
|
||||
virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context);
|
||||
Node *GetNode (void) const;
|
||||
|
||||
Node *m_node;
|
||||
|
|
|
@ -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 @@ Ipv4::~Ipv4 ()
|
|||
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 @@ Ipv4::SetDefaultTtl (uint8_t ttl)
|
|||
|
||||
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 @@ Ipv4::GetInterface (uint32_t index)
|
|||
return 0;
|
||||
}
|
||||
uint32_t
|
||||
Ipv4::GetNInterfaces (void) const
|
||||
Ipv4::GetNInterfaces (void)
|
||||
{
|
||||
return m_nInterfaces;
|
||||
}
|
||||
|
@ -309,7 +336,7 @@ Ipv4::Copy(Node *node) const
|
|||
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 @@ Ipv4::Send (Packet const &packet,
|
|||
if (route == 0)
|
||||
{
|
||||
NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
|
||||
m_dropTrace (packet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -370,7 +398,7 @@ Ipv4::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route
|
|||
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 @@ Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device)
|
|||
// 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 @@ Ipv4::Forwarding (Packet const &packet, Ipv4Header &ipHeader, NetDevice &device)
|
|||
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.");
|
||||
|
|
|
@ -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 Ipv4Address;
|
|||
class Ipv4Header;
|
||||
class Ipv4Route;
|
||||
class Node;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -46,9 +50,19 @@ class Ipv4 : public L3Protocol
|
|||
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 @@ public:
|
|||
|
||||
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 @@ public:
|
|||
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 @@ public:
|
|||
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
|
||||
|
|
|
@ -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 @@ L3Demux::~L3Demux()
|
|||
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
|
||||
{
|
||||
|
|
|
@ -33,14 +33,19 @@ namespace ns3 {
|
|||
|
||||
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
|
||||
|
|
|
@ -33,7 +33,7 @@ L3Protocol::L3Protocol(int protocolNumber, int version)
|
|||
{}
|
||||
L3Protocol::~L3Protocol ()
|
||||
{}
|
||||
|
||||
|
||||
int
|
||||
L3Protocol::GetProtocolNumber (void) const
|
||||
{
|
||||
|
|
|
@ -30,7 +30,8 @@ namespace ns3 {
|
|||
class Packet;
|
||||
class NetDevice;
|
||||
class Node;
|
||||
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
/**
|
||||
* ::Send is always defined in subclasses.
|
||||
|
@ -44,6 +45,8 @@ public:
|
|||
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
|
||||
|
|
|
@ -163,6 +163,11 @@ NetDevice::Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber)
|
|||
}
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
NetDevice::CreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return DoCreateTraceResolver (context);
|
||||
}
|
||||
|
||||
// Receive packet from below
|
||||
bool
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace ns3 {
|
|||
|
||||
class Ipv4L4Demux;
|
||||
class Node;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
/**
|
||||
* \brief Network layer to device interface
|
||||
|
@ -58,6 +60,9 @@ class NetDevice {
|
|||
*/
|
||||
NetDevice(Node* node, const MacAddress& addr);
|
||||
virtual ~NetDevice() {}
|
||||
|
||||
TraceResolver *CreateTraceResolver (TraceContext const &context);
|
||||
|
||||
/**
|
||||
* \return the current MacAddress of this interface.
|
||||
*/
|
||||
|
@ -204,6 +209,7 @@ class NetDevice {
|
|||
* 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;
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
|
@ -99,6 +99,8 @@ class NetDeviceList;
|
|||
class Ipv4;
|
||||
class Udp;
|
||||
class Arp;
|
||||
class TraceContext;
|
||||
class TraceResolver;
|
||||
|
||||
class Node {
|
||||
public:
|
||||
|
@ -107,6 +109,8 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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 @@ Queue::~Queue()
|
|||
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 @@ Queue::Enqueue (const Packet& p)
|
|||
|
||||
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 @@ Queue::Dequeue (Packet &p)
|
|||
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 @@ Queue::IsEmpty (void)
|
|||
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 @@ Queue::Drop (const Packet& p)
|
|||
m_nTotalDroppedBytes += p.GetSize ();
|
||||
|
||||
NS_DEBUG("Queue::Drop (): m_traceDrop (p)");
|
||||
m_traceDrop (m_name, p);
|
||||
m_traceDrop (p);
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
|
|
|
@ -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 @@ public:
|
|||
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 @@ private:
|
|||
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 @@ private:
|
|||
uint32_t m_nTotalDroppedBytes;
|
||||
uint32_t m_nTotalDroppedPackets;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
|
||||
#if 0
|
||||
// Static methods to manage queue default
|
||||
// Set desired queue default
|
||||
|
|
|
@ -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 @@ Udp::~Udp ()
|
|||
delete m_endPoints;
|
||||
}
|
||||
|
||||
TraceResolver *
|
||||
Udp::CreateTraceResolver (TraceContext const &context)
|
||||
{
|
||||
return new EmptyTraceResolver (context);
|
||||
}
|
||||
|
||||
UdpEndPoint *
|
||||
Udp::Allocate (void)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
namespace ns3 {
|
||||
|
||||
class Node;
|
||||
class TraceResolver;
|
||||
class TraceContext;
|
||||
|
||||
class Udp : public Ipv4L4Protocol {
|
||||
public:
|
||||
|
@ -41,6 +43,8 @@ public:
|
|||
Udp (Node *node);
|
||||
virtual ~Udp ();
|
||||
|
||||
virtual TraceResolver *CreateTraceResolver (TraceContext const &context);
|
||||
|
||||
UdpEndPoint *Allocate (void);
|
||||
UdpEndPoint *Allocate (Ipv4Address address);
|
||||
UdpEndPoint *Allocate (uint16_t port);
|
||||
|
|
|
@ -151,11 +151,11 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue