Add Mathieu's super object container; add Rx trace on SerialNetDevice
This commit is contained in:
@@ -24,6 +24,7 @@ core.add_sources([
|
||||
'test.cc',
|
||||
'random-variable.cc',
|
||||
'rng-stream.cc',
|
||||
'object-container.cc',
|
||||
])
|
||||
env = Environment()
|
||||
if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
|
||||
@@ -48,7 +49,8 @@ core.add_inst_headers([
|
||||
'fatal-error.h',
|
||||
'test.h',
|
||||
'random-variable.h',
|
||||
'rng-stream.h'
|
||||
'rng-stream.h',
|
||||
'object-container.h'
|
||||
])
|
||||
|
||||
def config_core (env, config):
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
// - Tracing of queues and packet receptions to file "out.tr"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
@@ -63,110 +64,86 @@
|
||||
#include "ns3/udp-header.h"
|
||||
#include "ns3/node-list.h"
|
||||
#include "ns3/trace-root.h"
|
||||
|
||||
#include "ns3/object-container.h"
|
||||
#include "ns3/serial-topology.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
class Tracer : public TraceWriter{
|
||||
class AsciiTrace
|
||||
{
|
||||
public:
|
||||
Tracer ()
|
||||
{
|
||||
};
|
||||
|
||||
Tracer (std::string const &filename)
|
||||
{
|
||||
Open(filename);
|
||||
};
|
||||
|
||||
Tracer (char const *filename) : m_tracer(filename)
|
||||
{
|
||||
Open(filename);
|
||||
};
|
||||
|
||||
~Tracer () {};
|
||||
|
||||
void LogNodeInterface (TraceContext const &context)
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_filestr << "+ " << Simulator::Now().GetSeconds() << " ";
|
||||
LogNodeInterface (context);
|
||||
m_filestr << "pkt-uid=" << p.GetUid () << " ";
|
||||
//PrintLlcPacket (p, m_filestr);
|
||||
m_filestr << std::endl;
|
||||
}
|
||||
|
||||
void LogDequeue (TraceContext const &context, const Packet &p)
|
||||
{
|
||||
m_filestr << "- " << Simulator::Now().GetSeconds() << " ";
|
||||
LogNodeInterface (context);
|
||||
m_filestr << "pkt-uid=" << p.GetUid () << " ";
|
||||
//PrintLlcPacket (p, m_filestr);
|
||||
m_filestr << std::endl;
|
||||
}
|
||||
void LogDrop (TraceContext const &context, const Packet &p)
|
||||
{
|
||||
m_filestr << "d " << Simulator::Now().GetSeconds() << " ";
|
||||
LogNodeInterface (context);
|
||||
m_filestr << "pkt-uid=" << p.GetUid () << " ";
|
||||
//PrintLlcPacket (p, m_filestr);
|
||||
m_filestr << std::endl;
|
||||
}
|
||||
|
||||
void PrintLlcPacket (Packet p, std::ostream &os)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
p.Peek (llc);
|
||||
p.Remove (llc);
|
||||
switch (llc.GetType ())
|
||||
{
|
||||
case 0x0800: {
|
||||
Ipv4Header ipv4;
|
||||
p.Peek (ipv4);
|
||||
p.Remove (ipv4);
|
||||
if (ipv4.GetProtocol () == 17)
|
||||
{
|
||||
UdpHeader udp;
|
||||
p.Peek (udp);
|
||||
p.Remove (udp);
|
||||
os << "udp payload=" << p.GetSize ()
|
||||
<< " from="<< ipv4.GetSource () << ":" << udp.GetSource ()
|
||||
<< " to="<< ipv4.GetDestination () << ":" << udp.GetDestination ();
|
||||
}
|
||||
} break;
|
||||
case 0x0806: {
|
||||
ArpHeader arp;
|
||||
p.Peek (arp);
|
||||
p.Remove (arp);
|
||||
os << "arp ";
|
||||
if (arp.IsRequest ())
|
||||
{
|
||||
os << "request from=" << arp.GetSourceIpv4Address ()
|
||||
<< ", for=" << arp.GetDestinationIpv4Address ();
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "reply from=" << arp.GetSourceIpv4Address ()
|
||||
<< ", for=" << arp.GetDestinationIpv4Address ();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
TraceWriter m_tracer;
|
||||
AsciiTrace (std::string filename);
|
||||
~AsciiTrace ();
|
||||
void TraceAllQueues (void);
|
||||
void TraceAllNetDeviceRx (void);
|
||||
private:
|
||||
void LogDevQueue (TraceContext const &context, const Packet &p);
|
||||
void LogDevRx (TraceContext const &context, Packet &p);
|
||||
std::ofstream m_os;
|
||||
};
|
||||
|
||||
AsciiTrace::AsciiTrace (std::string filename)
|
||||
{
|
||||
m_os.open (filename.c_str ());
|
||||
}
|
||||
AsciiTrace::~AsciiTrace ()
|
||||
{
|
||||
m_os.close ();
|
||||
}
|
||||
void
|
||||
AsciiTrace::TraceAllQueues (void)
|
||||
{
|
||||
TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/*",
|
||||
MakeCallback (&AsciiTrace::LogDevQueue, this));
|
||||
}
|
||||
void
|
||||
AsciiTrace::TraceAllNetDeviceRx (void)
|
||||
{
|
||||
TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/rx",
|
||||
MakeCallback (&AsciiTrace::LogDevRx, this));
|
||||
}
|
||||
|
||||
void
|
||||
AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &p)
|
||||
{
|
||||
enum Queue::TraceType type;
|
||||
context.Get (type);
|
||||
switch (type)
|
||||
{
|
||||
case Queue::ENQUEUE:
|
||||
m_os << "+ ";
|
||||
break;
|
||||
case Queue::DEQUEUE:
|
||||
m_os << "- ";
|
||||
break;
|
||||
case Queue::DROP:
|
||||
m_os << "d ";
|
||||
break;
|
||||
}
|
||||
m_os << Simulator::Now ().GetSeconds () << " ";
|
||||
NodeList::NodeIndex nodeIndex;
|
||||
context.Get (nodeIndex);
|
||||
m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
|
||||
Ipv4::InterfaceIndex interfaceIndex;
|
||||
context.Get (interfaceIndex);
|
||||
m_os << "interface=" << interfaceIndex << " ";
|
||||
m_os << "pkt-uid=" << p.GetUid () << " ";
|
||||
m_os << std::endl;
|
||||
}
|
||||
void
|
||||
AsciiTrace::LogDevRx (TraceContext const &context, Packet &p)
|
||||
{
|
||||
m_os << "r " << Simulator::Now ().GetSeconds () << " ";
|
||||
NodeList::NodeIndex nodeIndex;
|
||||
context.Get (nodeIndex);
|
||||
m_os << "node=" << NodeList::GetNode (nodeIndex)->GetId () << " ";
|
||||
Ipv4::InterfaceIndex interfaceIndex;
|
||||
context.Get (interfaceIndex);
|
||||
m_os << "interface=" << interfaceIndex << " ";
|
||||
m_os << "pkt-uid=" << p.GetUid () << " ";
|
||||
m_os << std::endl;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
GenerateTraffic (DatagramSocket *socket, uint32_t size)
|
||||
@@ -230,6 +207,8 @@ int main (int argc, char *argv[])
|
||||
DebugComponentEnable("SerialPhy");
|
||||
#endif
|
||||
|
||||
ObjectContainer container;
|
||||
|
||||
// ** Here, some kind of factory or topology object will instantiates
|
||||
// ** four identical nodes; for now, we just explicitly create them
|
||||
InternetNode *n0 = new InternetNode();
|
||||
@@ -237,6 +216,11 @@ int main (int argc, char *argv[])
|
||||
InternetNode *n2 = new InternetNode();
|
||||
InternetNode *n3 = new InternetNode();
|
||||
|
||||
container.Acquire (n0);
|
||||
container.Acquire (n1);
|
||||
container.Acquire (n2);
|
||||
container.Acquire (n3);
|
||||
|
||||
NodeList::Add (n0);
|
||||
NodeList::Add (n1);
|
||||
NodeList::Add (n2);
|
||||
@@ -247,17 +231,20 @@ int main (int argc, char *argv[])
|
||||
n2->SetName(std::string("Node 2"));
|
||||
n3->SetName(std::string("Node 3"));
|
||||
|
||||
SerialChannel* ch1 = SerialTopology::AddSerialLink (
|
||||
SerialChannel* ch1;
|
||||
ch1 = SerialTopology::AddSerialLink (
|
||||
n0, Ipv4Address("10.1.1.1"),
|
||||
n2, Ipv4Address("10.1.1.2"),
|
||||
5000000, MilliSeconds(2));
|
||||
|
||||
SerialChannel* ch2 = SerialTopology::AddSerialLink (
|
||||
SerialChannel* ch2;
|
||||
ch2 = SerialTopology::AddSerialLink (
|
||||
n1, Ipv4Address("10.1.2.1"),
|
||||
n2, Ipv4Address("10.1.2.2"),
|
||||
5000000, MilliSeconds(2));
|
||||
|
||||
SerialChannel* ch3 = SerialTopology::AddSerialLink (
|
||||
SerialChannel* ch3;
|
||||
ch3 = SerialTopology::AddSerialLink (
|
||||
n2, Ipv4Address("10.1.3.1"),
|
||||
n3, Ipv4Address("10.1.3.2"),
|
||||
1500000, MilliSeconds(10));
|
||||
@@ -269,6 +256,11 @@ int main (int argc, char *argv[])
|
||||
DatagramSocket *sink1 = new DatagramSocket(n1);
|
||||
sink1->Bind (80);
|
||||
|
||||
container.Acquire (source0);
|
||||
container.Acquire (source3);
|
||||
container.Acquire (sink3);
|
||||
container.Acquire (sink1);
|
||||
|
||||
source3->SetDefaultDestination (Ipv4Address ("10.1.2.1"), 80);
|
||||
source0->SetDefaultDestination (Ipv4Address ("10.1.3.2"), 80);
|
||||
|
||||
@@ -276,18 +268,9 @@ 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("out.tr");
|
||||
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));
|
||||
#if 0
|
||||
TraceRoot::Connect ("/nodes/*/ipv4/interfaces/*/netdevice/queue/receive",
|
||||
MakeCallback (&Tracer::LogReceive, &tracer));
|
||||
#endif
|
||||
|
||||
AsciiTrace trace ("out.tr");
|
||||
trace.TraceAllQueues ();
|
||||
trace.TraceAllNetDeviceRx ();
|
||||
|
||||
PrintTraffic (sink3);
|
||||
GenerateTraffic (source0, 100);
|
||||
@@ -301,17 +284,6 @@ int main (int argc, char *argv[])
|
||||
|
||||
// The below deletes will be managed by future topology objects
|
||||
// or containers or smart pointers
|
||||
delete n0;
|
||||
delete n1;
|
||||
delete n2;
|
||||
delete n3;
|
||||
delete ch1;
|
||||
delete ch2;
|
||||
delete ch3;
|
||||
delete source3;
|
||||
delete source0;
|
||||
delete sink3;
|
||||
delete sink1;
|
||||
|
||||
Simulator::Destroy ();
|
||||
}
|
||||
|
||||
201
src/core/object-container.cc
Normal file
201
src/core/object-container.cc
Normal file
@@ -0,0 +1,201 @@
|
||||
/* -*- 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 "object-container.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
ObjectContainer::DeleterList ObjectContainer::m_deleterList;
|
||||
|
||||
ObjectContainer::~ObjectContainer ()
|
||||
{
|
||||
Cleanup ();
|
||||
}
|
||||
|
||||
void
|
||||
ObjectContainer::Cleanup (void)
|
||||
{
|
||||
for (List::iterator i = m_list.begin (); i != m_list.end (); i++)
|
||||
{
|
||||
uint32_t uid = i->first;
|
||||
std::vector<void *> *vec = i->second;
|
||||
ObjectDeleter deleter = LookupObjectDeleter (uid);
|
||||
for (std::vector<void *>::iterator j = vec->begin ();
|
||||
j != vec->end (); j++)
|
||||
{
|
||||
(deleter) (*j);
|
||||
}
|
||||
delete vec;
|
||||
}
|
||||
m_list.erase (m_list.begin (), m_list.end ());
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ObjectContainer::GetGlobalUid (void) const
|
||||
{
|
||||
static uint32_t globalUid = 0;
|
||||
globalUid ++;
|
||||
return globalUid;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ObjectContainer::RegisterUid (uint32_t uid, ObjectDeleter deleter) const
|
||||
{
|
||||
for (DeleterList::iterator i = m_deleterList.begin ();
|
||||
i != m_deleterList.end (); i++)
|
||||
{
|
||||
NS_ASSERT (i->first != uid);
|
||||
}
|
||||
m_deleterList.push_back (std::make_pair (uid, deleter));
|
||||
return uid;
|
||||
}
|
||||
|
||||
ObjectContainer::ObjectDeleter
|
||||
ObjectContainer::LookupObjectDeleter (uint32_t uid) const
|
||||
{
|
||||
for (DeleterList::iterator i = m_deleterList.begin ();
|
||||
i != m_deleterList.end (); i++)
|
||||
{
|
||||
if (i->first == uid)
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
NS_FATAL_ERROR ("unknown deleter requested.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
#include "test.h"
|
||||
namespace ns3 {
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A () {}
|
||||
~A () {}
|
||||
};
|
||||
|
||||
class WithCopy
|
||||
{
|
||||
public:
|
||||
WithCopy () {}
|
||||
~WithCopy () {}
|
||||
WithCopy *Copy (void) const {return new WithCopy ();}
|
||||
};
|
||||
|
||||
class B
|
||||
{
|
||||
public:
|
||||
B () {}
|
||||
~B () {}
|
||||
};
|
||||
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base () {}
|
||||
virtual ~Base () {}
|
||||
};
|
||||
|
||||
class DerivedA
|
||||
{
|
||||
public:
|
||||
DerivedA () {}
|
||||
virtual ~DerivedA () {}
|
||||
};
|
||||
|
||||
class DerivedB
|
||||
{
|
||||
public:
|
||||
DerivedB () {}
|
||||
virtual ~DerivedB () {}
|
||||
};
|
||||
|
||||
|
||||
class ObjectContainerTest : public Test
|
||||
{
|
||||
public:
|
||||
ObjectContainerTest ();
|
||||
virtual ~ObjectContainerTest ();
|
||||
|
||||
virtual bool RunTests (void);
|
||||
};
|
||||
|
||||
ObjectContainerTest::ObjectContainerTest ()
|
||||
: Test ("ObjectContainer")
|
||||
{}
|
||||
|
||||
ObjectContainerTest::~ObjectContainerTest ()
|
||||
{}
|
||||
|
||||
bool
|
||||
ObjectContainerTest::RunTests (void)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
ObjectContainer container;
|
||||
A *a = new A ();
|
||||
A *firstA = a;
|
||||
container.Acquire (a);
|
||||
a = new A ();
|
||||
container.Acquire (a);
|
||||
a = new A ();
|
||||
container.Acquire (a);
|
||||
B *b = new B ();
|
||||
container.Acquire (b);
|
||||
a = new A ();
|
||||
container.Acquire (a);
|
||||
b = new B ();
|
||||
container.Acquire (b);
|
||||
|
||||
container.Remove (firstA);
|
||||
delete firstA;
|
||||
|
||||
Base *base = new Base ();
|
||||
container.Acquire (base);
|
||||
DerivedA *derivedA = new DerivedA ();
|
||||
container.Acquire (derivedA);
|
||||
DerivedB *derivedB = new DerivedB ();
|
||||
container.Acquire (derivedB);
|
||||
base = new Base ();
|
||||
container.Acquire (base);
|
||||
derivedB = new DerivedB ();
|
||||
container.Acquire (derivedB);
|
||||
|
||||
|
||||
// the following cannot work because no copy method defined.
|
||||
//container.Add (A ());
|
||||
container.Add (WithCopy ());
|
||||
|
||||
container.Cleanup ();
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static ObjectContainerTest g_objectContainerTest;
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
#endif /* RUN_SELF_TESTS */
|
||||
165
src/core/object-container.h
Normal file
165
src/core/object-container.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/* -*- 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 OBJECT_CONTAINER_H
|
||||
#define OBJECT_CONTAINER_H
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include "fatal-error.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
|
||||
class ObjectContainer
|
||||
{
|
||||
public:
|
||||
~ObjectContainer ();
|
||||
void Cleanup (void);
|
||||
|
||||
template <typename T>
|
||||
void Acquire (T *object);
|
||||
|
||||
template <typename T>
|
||||
T *Add (T const &object);
|
||||
|
||||
template <typename T>
|
||||
void Remove (T *object);
|
||||
|
||||
private:
|
||||
typedef void (*ObjectDeleter) (void *);
|
||||
typedef std::list<std::pair<uint32_t,std::vector<void *> *> > List;
|
||||
typedef std::list<std::pair<uint32_t,ObjectDeleter> > DeleterList;
|
||||
template <typename T>
|
||||
static void DeleteObject (void *ptr);
|
||||
template <typename T>
|
||||
uint32_t GetUid (void) const;
|
||||
|
||||
template <typename T>
|
||||
std::vector<T *> *GetVector (void) const;
|
||||
|
||||
uint32_t GetGlobalUid (void) const;
|
||||
uint32_t RegisterUid (uint32_t uid, ObjectDeleter deleter) const;
|
||||
ObjectContainer::ObjectDeleter LookupObjectDeleter (uint32_t uid) const;
|
||||
List m_list;
|
||||
static DeleterList m_deleterList;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
ObjectContainer::Acquire (T *object)
|
||||
{
|
||||
uint32_t uid = GetUid<T> ();
|
||||
for (List::iterator i = m_list.begin (); i != m_list.end (); i++)
|
||||
{
|
||||
if (i->first == uid)
|
||||
{
|
||||
i->second->push_back (object);
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::vector<void *> * vec = new std::vector<void *> ();
|
||||
vec->push_back (object);
|
||||
m_list.push_back (std::make_pair (uid, vec));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *
|
||||
ObjectContainer::Add (T const &object)
|
||||
{
|
||||
T *copy = object.Copy ();
|
||||
Acquire (copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
ObjectContainer::Remove (T *object)
|
||||
{
|
||||
uint32_t uid = GetUid<T> ();
|
||||
for (List::iterator i = m_list.begin (); i != m_list.end (); i++)
|
||||
{
|
||||
if (i->first == uid)
|
||||
{
|
||||
for (std::vector<void *>::iterator j = i->second->begin ();
|
||||
j != i->second->end (); j++)
|
||||
{
|
||||
if ((*j) == object)
|
||||
{
|
||||
i->second->erase (j);
|
||||
return;
|
||||
}
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
error:
|
||||
NS_FATAL_ERROR ("tried to remove non-existant object from object container");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T *> *
|
||||
ObjectContainer::GetVector (void) const
|
||||
{
|
||||
uint32_t uid = GetUid<T> ();
|
||||
for (List::const_iterator i = m_list.begin (); i != m_list.end (); i++)
|
||||
{
|
||||
if (i->first == uid)
|
||||
{
|
||||
std::vector<void *> *vec = i->second;
|
||||
std::vector<T *> *retval = (std::vector<T *> *)vec;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
NS_FATAL_ERROR ("no object registered for requested type.");
|
||||
// quiet compiler
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
ObjectContainer::DeleteObject (void *ptr)
|
||||
{
|
||||
T *object = (T*) ptr;
|
||||
delete object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
uint32_t
|
||||
ObjectContainer::GetUid (void) const
|
||||
{
|
||||
static uint32_t uid = RegisterUid (GetGlobalUid (),
|
||||
&ObjectContainer::DeleteObject<T>);
|
||||
return uid;
|
||||
}
|
||||
|
||||
}//namespace ns3
|
||||
|
||||
|
||||
#endif /* OBJECT_CONTAINER_H */
|
||||
@@ -83,6 +83,9 @@ SerialNetDevice::DoCreateTraceResolver (TraceContext const &context)
|
||||
resolver->Add ("queue",
|
||||
MakeCallback (&Queue::CreateTraceResolver, m_queue),
|
||||
SerialNetDevice::QUEUE);
|
||||
resolver->Add ("rx",
|
||||
m_rxTrace,
|
||||
SerialNetDevice::RX);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@@ -119,6 +122,7 @@ SerialNetDevice::Receive (Packet& p)
|
||||
// ignore return value for now.
|
||||
NS_DEBUG ("SerialNetDevice::Receive (" << &p << ")");
|
||||
|
||||
m_rxTrace (p);
|
||||
ForwardUp (p);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/callback-trace-source.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -38,6 +39,7 @@ class SerialNetDevice : public NetDevice {
|
||||
public:
|
||||
enum TraceType {
|
||||
QUEUE,
|
||||
RX,
|
||||
};
|
||||
SerialNetDevice(Node* node);
|
||||
virtual ~SerialNetDevice();
|
||||
@@ -65,7 +67,7 @@ private:
|
||||
SerialPhy* m_phy;
|
||||
SerialChannel* m_channel;
|
||||
Queue* m_queue;
|
||||
|
||||
CallbackTraceSource<Packet &> m_rxTrace;
|
||||
};
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
// George F. Riley, Georgia Tech, Spring 2007
|
||||
|
||||
#include "ns3/debug.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
@@ -54,7 +55,7 @@ SerialTopology::AddSerialLink(
|
||||
// Duplex link is assumed to be subnetted as a /30
|
||||
// May run this unnumbered in the future?
|
||||
Ipv4Mask netmask("255.255.255.252");
|
||||
assert(netmask.IsMatch(addra,addrb));
|
||||
NS_ASSERT (netmask.IsMatch(addra,addrb));
|
||||
|
||||
DropTailQueue* dtqa = new DropTailQueue();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user