merge TypeId in headers and trailers branch
This commit is contained in:
@@ -47,12 +47,32 @@
|
||||
using namespace ns3;
|
||||
|
||||
void
|
||||
WifiNetDeviceTrace (Ptr<const Packet> p, Mac48Address address)
|
||||
DevTxTrace (std::string context, Ptr<const Packet> p, Mac48Address address)
|
||||
{
|
||||
std::cout << " ad=" << address << " p: " << p << std::endl;
|
||||
std::cout << " TX to=" << address << " p: " << *p << std::endl;
|
||||
}
|
||||
void
|
||||
WifiPhyStateTrace (Time start, Time duration, enum WifiPhy::State state)
|
||||
DevRxTrace (std::string context, Ptr<const Packet> p, Mac48Address address)
|
||||
{
|
||||
std::cout << " RX from=" << address << " p: " << *p << std::endl;
|
||||
}
|
||||
void
|
||||
PhyRxOkTrace (std::string context, Ptr<const Packet> packet, double snr, WifiMode mode, enum WifiPreamble preamble)
|
||||
{
|
||||
std::cout << "PHYRXOK mode=" << mode << " snr=" << snr << " " << *packet << std::endl;
|
||||
}
|
||||
void
|
||||
PhyRxErrorTrace (std::string context, Ptr<const Packet> packet, double snr)
|
||||
{
|
||||
std::cout << "PHYRXERROR snr=" << snr << " " << *packet << std::endl;
|
||||
}
|
||||
void
|
||||
PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
|
||||
{
|
||||
std::cout << "PHYTX mode=" << mode << " " << *packet << std::endl;
|
||||
}
|
||||
void
|
||||
PhyStateTrace (std::string context, Time start, Time duration, enum WifiPhy::State state)
|
||||
{
|
||||
std::cout << " state=";
|
||||
switch (state) {
|
||||
@@ -161,8 +181,12 @@ int main (int argc, char *argv[])
|
||||
|
||||
Simulator::StopAt (Seconds (44.0));
|
||||
|
||||
//NodeList::ConnectWithoutContext ("/nodes/*/devices/*/*", MakeCallback (&WifiNetDeviceTrace));
|
||||
//NodeList::ConnectWithoutContext ("/nodes/*/devices/*/phy/state", MakeCallback (&WifiPhyStateTrace));
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/Tx", MakeCallback (&DevTxTrace));
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/Rx", MakeCallback (&DevRxTrace));
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxOk", MakeCallback (&PhyRxOkTrace));
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/Phy/RxError", MakeCallback (&PhyRxErrorTrace));
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/Phy/Tx", MakeCallback (&PhyTxTrace));
|
||||
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State", MakeCallback (&PhyStateTrace));
|
||||
|
||||
Simulator::Run ();
|
||||
|
||||
@@ -66,4 +66,11 @@ def build(bld):
|
||||
['point-to-point', 'internet-node'])
|
||||
obj.source = 'tcp-small-transfer-oneloss.cc'
|
||||
|
||||
obj = bld.create_ns3_program('wifi-adhoc',
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'wifi-adhoc.cc'
|
||||
|
||||
obj = bld.create_ns3_program('wifi-ap',
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'wifi-ap.cc'
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ using namespace ns3;
|
||||
class MyHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
MyHeader ();
|
||||
virtual ~MyHeader ();
|
||||
@@ -19,11 +18,12 @@ public:
|
||||
void SetData (uint16_t data);
|
||||
uint16_t GetData (void) const;
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
private:
|
||||
uint16_t m_data;
|
||||
};
|
||||
@@ -36,24 +36,20 @@ MyHeader::MyHeader ()
|
||||
MyHeader::~MyHeader ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
MyHeader::GetUid (void)
|
||||
TypeId
|
||||
MyHeader::GetTypeId (void)
|
||||
{
|
||||
// This string is used by the internals of the packet
|
||||
// code to keep track of the packet metadata.
|
||||
// You need to make sure that this string is absolutely
|
||||
// unique. The code will detect any duplicate string.
|
||||
static uint32_t uid = AllocateUid<MyHeader> ("MyHeader.test.nsnam.org");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::MyHeader")
|
||||
.SetParent<Header> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
MyHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
std::string
|
||||
MyHeader::GetName (void) const
|
||||
{
|
||||
// This string is used to identify the type of
|
||||
// my header by the packet printing routines.
|
||||
return "MYHEADER";
|
||||
}
|
||||
void
|
||||
MyHeader::Print (std::ostream &os) const
|
||||
{
|
||||
|
||||
@@ -16,9 +16,6 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('main-packet-tag', ['common', 'simulator'])
|
||||
obj.source = 'main-packet-tag.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-packet-printer', ['common', 'simulator', 'internet-node'])
|
||||
obj.source = 'main-packet-printer.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-test')
|
||||
obj.source = 'main-test.cc'
|
||||
|
||||
@@ -33,14 +30,6 @@ def build(bld):
|
||||
obj = bld.create_ns3_program('main-random-topology',
|
||||
['core', 'simulator', 'mobility'])
|
||||
obj.source = 'main-random-topology.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-adhoc-wifi',
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'main-adhoc-wifi.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-ap-wifi',
|
||||
['core', 'simulator', 'mobility', 'wifi'])
|
||||
obj.source = 'main-ap-wifi.cc'
|
||||
|
||||
obj = bld.create_ns3_program('main-random-walk',
|
||||
['core', 'simulator', 'mobility'])
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 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 "chunk-registry.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
ChunkRegistry::InfoVector *
|
||||
ChunkRegistry::GetInfoVector (void)
|
||||
{
|
||||
static InfoVector vec;
|
||||
return &vec;
|
||||
}
|
||||
|
||||
std::string
|
||||
ChunkRegistry::GetUidStringFromUid (uint32_t uid)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
return info.uidString;
|
||||
}
|
||||
uint32_t
|
||||
ChunkRegistry::GetUidFromUidString (std::string uidString)
|
||||
{
|
||||
uint32_t uid = 1;
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
|
||||
{
|
||||
if (i->uidString == uidString)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
uid++;
|
||||
}
|
||||
NS_FATAL_ERROR ("Trying to access a non-registered Header or Trailer: \"" << uidString << "\". "<<
|
||||
"You could try calling NS_HEADER_ENSURE_REGISTER somewhere.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
ChunkRegistry::GetStaticInstance (uint32_t uid)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
return info.getStaticInstance ();
|
||||
}
|
||||
bool
|
||||
ChunkRegistry::IsHeader (uint32_t uid)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
return info.isHeader;
|
||||
}
|
||||
bool
|
||||
ChunkRegistry::IsTrailer (uint32_t uid)
|
||||
{
|
||||
return !IsHeader (uid);
|
||||
}
|
||||
uint32_t
|
||||
ChunkRegistry::Deserialize (uint32_t uid, uint8_t *instance, Buffer::Iterator i)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
return info.deserialize (instance, i);
|
||||
}
|
||||
void
|
||||
ChunkRegistry::Print (uint32_t uid, uint8_t *instance, std::ostream &os)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
return info.print (instance, os);
|
||||
}
|
||||
std::string
|
||||
ChunkRegistry::GetName (uint32_t uid, uint8_t *instance)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
return info.getName (instance);
|
||||
}
|
||||
void
|
||||
ChunkRegistry::InvokePrintCallback (uint32_t uid, uint8_t *instance, std::ostream &os,
|
||||
uint32_t packetUid, uint32_t size,
|
||||
CallbackBase callback)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
NS_ASSERT (uid >= 1 && uid <= vec->size ());
|
||||
Info info = (*vec)[uid - 1];
|
||||
info.invokePrintCallback (instance, os, packetUid, size, callback);
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
@@ -1,180 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2005 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 CHUNK_REGISTRY_H
|
||||
#define CHUNK_REGISTRY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ostream>
|
||||
#include "buffer.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/callback.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief this registry keeps track of all different
|
||||
* types of headers and trailers and assigns to each of them
|
||||
* a unique integer.
|
||||
* \internal
|
||||
*/
|
||||
class ChunkRegistry
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
static uint32_t RegisterHeader (std::string uuid);
|
||||
template <typename T>
|
||||
static uint32_t RegisterTrailer (std::string uuid);
|
||||
|
||||
static std::string GetUidStringFromUid (uint32_t uid);
|
||||
static uint32_t GetUidFromUidString (std::string uidString);
|
||||
static uint8_t *GetStaticInstance (uint32_t uid);
|
||||
static uint32_t Deserialize (uint32_t uid, uint8_t *instance, Buffer::Iterator i);
|
||||
static void Print (uint32_t uid, uint8_t *instance, std::ostream &os);
|
||||
static std::string GetName (uint32_t uid, uint8_t *instance);
|
||||
static bool IsHeader (uint32_t uid);
|
||||
static bool IsTrailer (uint32_t uid);
|
||||
static void InvokePrintCallback (uint32_t uid, uint8_t *instance, std::ostream &os,
|
||||
uint32_t packetUid, uint32_t size,
|
||||
CallbackBase callback);
|
||||
private:
|
||||
typedef uint8_t *(*GetStaticInstanceCb) (void);
|
||||
typedef uint32_t (*DeserializeCb) (uint8_t *, Buffer::Iterator);
|
||||
typedef void (*PrintCb) (uint8_t *,std::ostream &);
|
||||
typedef std::string (*GetNameCb) (uint8_t *);
|
||||
typedef void (*InvokePrintCallbackCb) (uint8_t *instance, std::ostream &os,
|
||||
uint32_t packetUid, uint32_t size,
|
||||
CallbackBase callback);
|
||||
struct Info {
|
||||
std::string uidString;
|
||||
bool isHeader;
|
||||
GetStaticInstanceCb getStaticInstance;
|
||||
DeserializeCb deserialize;
|
||||
PrintCb print;
|
||||
GetNameCb getName;
|
||||
InvokePrintCallbackCb invokePrintCallback;
|
||||
};
|
||||
typedef std::vector<struct Info> InfoVector;
|
||||
static InfoVector *GetInfoVector (void);
|
||||
template <typename T>
|
||||
static uint8_t *DoGetStaticInstance (void);
|
||||
template <typename T>
|
||||
static uint32_t DoDeserialize (uint8_t *instance, Buffer::Iterator i);
|
||||
template <typename T>
|
||||
static void DoPrint (uint8_t *instance, std::ostream &os);
|
||||
template <typename T>
|
||||
static std::string DoGetName (uint8_t *instance);
|
||||
template <typename T>
|
||||
static void DoInvokePrintCallback (uint8_t *instance, std::ostream &os,
|
||||
uint32_t packetUid, uint32_t size,
|
||||
CallbackBase callback);
|
||||
template <typename T>
|
||||
static uint32_t GetUid (bool isHeader, std::string uidString);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
uint32_t
|
||||
ChunkRegistry::RegisterHeader (std::string uuid)
|
||||
{
|
||||
return GetUid<T> (true, uuid);
|
||||
}
|
||||
template <typename T>
|
||||
uint32_t
|
||||
ChunkRegistry::RegisterTrailer (std::string uuid)
|
||||
{
|
||||
return GetUid<T> (false, uuid);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
uint32_t
|
||||
ChunkRegistry::GetUid (bool isHeader, std::string uidString)
|
||||
{
|
||||
InfoVector *vec = GetInfoVector ();
|
||||
uint32_t uid = 1;
|
||||
for (InfoVector::iterator i = vec->begin (); i != vec->end (); i++)
|
||||
{
|
||||
if (i->uidString == uidString)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
uid++;
|
||||
}
|
||||
Info info;
|
||||
info.getStaticInstance = &ChunkRegistry::DoGetStaticInstance<T>;
|
||||
info.print = &ChunkRegistry::DoPrint<T>;
|
||||
info.getName = &ChunkRegistry::DoGetName<T>;
|
||||
info.deserialize = &ChunkRegistry::DoDeserialize<T>;
|
||||
info.invokePrintCallback = &ChunkRegistry::DoInvokePrintCallback<T>;
|
||||
info.uidString = uidString;
|
||||
info.isHeader = isHeader;
|
||||
vec->push_back (info);
|
||||
return vec->size ();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
uint8_t *
|
||||
ChunkRegistry::DoGetStaticInstance ()
|
||||
{
|
||||
static T instance;
|
||||
return reinterpret_cast<uint8_t *> (&instance);
|
||||
}
|
||||
template <typename T>
|
||||
uint32_t
|
||||
ChunkRegistry::DoDeserialize (uint8_t *instance, Buffer::Iterator i)
|
||||
{
|
||||
T *obj = reinterpret_cast<T *> (instance);
|
||||
return obj->Deserialize (i);
|
||||
}
|
||||
template <typename T>
|
||||
void
|
||||
ChunkRegistry::DoPrint (uint8_t *instance, std::ostream &os)
|
||||
{
|
||||
T *obj = reinterpret_cast<T *> (instance);
|
||||
obj->Print (os);
|
||||
}
|
||||
template <typename T>
|
||||
std::string
|
||||
ChunkRegistry::DoGetName (uint8_t *instance)
|
||||
{
|
||||
T *obj = reinterpret_cast<T *> (instance);
|
||||
return obj->GetName ();
|
||||
}
|
||||
template <typename T>
|
||||
void
|
||||
ChunkRegistry::DoInvokePrintCallback (uint8_t *instance, std::ostream &os,
|
||||
uint32_t packetUid, uint32_t size,
|
||||
CallbackBase callback)
|
||||
{
|
||||
T *obj = reinterpret_cast<T *> (instance);
|
||||
Callback<void,std::ostream&,uint32_t,uint32_t,const T*> cb;
|
||||
cb.Assign (callback);
|
||||
cb (os, packetUid, size, obj);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* CHUNK_H */
|
||||
16
src/common/chunk.cc
Normal file
16
src/common/chunk.cc
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "chunk.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (Chunk);
|
||||
|
||||
TypeId
|
||||
Chunk::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Chunk")
|
||||
.SetParent<ObjectBase> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
20
src/common/chunk.h
Normal file
20
src/common/chunk.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef CHUNK_H
|
||||
#define CHUNK_H
|
||||
|
||||
#include "ns3/object-base.h"
|
||||
#include "buffer.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Chunk : public ObjectBase
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start) = 0;
|
||||
virtual void Print (std::ostream &os) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* CHUNK_H */
|
||||
25
src/common/header.cc
Normal file
25
src/common/header.cc
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "header.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (Header);
|
||||
|
||||
Header::~Header ()
|
||||
{}
|
||||
|
||||
TypeId
|
||||
Header::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Header")
|
||||
.SetParent<Chunk> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream &os, const Header &header)
|
||||
{
|
||||
header.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
@@ -22,29 +22,9 @@
|
||||
#ifndef HEADER_H
|
||||
#define HEADER_H
|
||||
|
||||
#include "chunk-registry.h"
|
||||
|
||||
/**
|
||||
* \relates ns3::Header
|
||||
* \brief this macro should be instantiated exactly once for each
|
||||
* new type of Header
|
||||
*
|
||||
* This macro will ensure that your new Header type is registered
|
||||
* within the packet header registry. In most cases, this macro
|
||||
* is not really needed but, for safety, please, use it all the
|
||||
* time.
|
||||
*
|
||||
* Note: This macro is _absolutely_ needed if you try to run a
|
||||
* distributed simulation.
|
||||
*/
|
||||
#define NS_HEADER_ENSURE_REGISTERED(x) \
|
||||
static class thisisaveryverylongclassname ##x \
|
||||
{ \
|
||||
public: \
|
||||
thisisaveryverylongclassname ##x () \
|
||||
{ uint32_t uid; uid = x::GetUid ();} \
|
||||
} g_thisisanotherveryveryverylongname ## x;
|
||||
|
||||
#include "chunk.h"
|
||||
#include "buffer.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -56,59 +36,62 @@ namespace ns3 {
|
||||
* implement the following public methods:
|
||||
* - a default constructor: is used by the internal implementation
|
||||
* if the Packet class.
|
||||
* - a static method named GetUid: is used to uniquely identify
|
||||
* the type of each header. This method shall return a unique
|
||||
* integer allocated with Header::AllocateUid.
|
||||
* - a method named Serialize: is used by Packet::AddHeader to
|
||||
* store a header into the byte buffer of a packet.
|
||||
* The input iterator points to the start of the byte buffer in
|
||||
* which the header should write its data. The data written
|
||||
* is expected to match bit-for-bit the representation of this
|
||||
* header in a real network.
|
||||
* - a method named GetSerializedSize: is used by Packet::AddHeader
|
||||
* to store a header into the byte buffer of a packet. This method
|
||||
* should return the number of bytes which are needed to store
|
||||
* the full header data by Serialize.
|
||||
* - a method named Deserialize: is used by Packet::RemoveHeader to
|
||||
* re-create a header from the byte buffer of a packet. The input
|
||||
* iterator points to the start of the byte buffer from which
|
||||
* the header should read its data. The data read is expected to
|
||||
* match bit-for-bit the representation of this header in real
|
||||
* networks. This method shall return an integer which identifies
|
||||
* the number of bytes read.
|
||||
* - a method named Print: is used by Packet::Print to print the
|
||||
* content of a header as ascii data to a c++ output stream.
|
||||
* Although the header is free to format its output as it
|
||||
* wishes, it is recommended to follow a few rules to integrate
|
||||
* with the packet pretty printer: start with flags, small field
|
||||
* values located between a pair of parens. Values should be separated
|
||||
* by whitespace. Follow the parens with the important fields,
|
||||
* separated by whitespace.
|
||||
* i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
|
||||
* - a method named GetName: is used by Packet::Print to print
|
||||
* header fragments. This method should return a user-readable
|
||||
* single word as all capitalized letters.
|
||||
*
|
||||
* Sample code which shows how to create a new type of Header, and how to use it,
|
||||
* is shown in the sample file samples/main-packet-header.cc
|
||||
*/
|
||||
class Header
|
||||
class Header : public Chunk
|
||||
{
|
||||
protected:
|
||||
template <typename T>
|
||||
static uint32_t AllocateUid (std::string uuid);
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
virtual ~Header ();
|
||||
/**
|
||||
* \returns the expected size of the header.
|
||||
*
|
||||
* This method is used by Packet::AddHeader
|
||||
* to store a header into the byte buffer of a packet. This method
|
||||
* should return the number of bytes which are needed to store
|
||||
* the full header data by Serialize.
|
||||
*/
|
||||
virtual uint32_t GetSerializedSize (void) const = 0;
|
||||
/**
|
||||
* \param start an iterator which points to where the header should
|
||||
* be written.
|
||||
*
|
||||
* This method is used by Packet::AddHeader to
|
||||
* store a header into the byte buffer of a packet.
|
||||
* The data written
|
||||
* is expected to match bit-for-bit the representation of this
|
||||
* header in a real network.
|
||||
*/
|
||||
virtual void Serialize (Buffer::Iterator start) const = 0;
|
||||
/**
|
||||
* \param start an iterator which points to where the header should
|
||||
* written.
|
||||
* \returns the number of bytes read.
|
||||
*
|
||||
* This method is used by Packet::RemoveHeader to
|
||||
* re-create a header from the byte buffer of a packet.
|
||||
* The data read is expected to
|
||||
* match bit-for-bit the representation of this header in real
|
||||
* networks.
|
||||
*/
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start) = 0;
|
||||
/**
|
||||
* This method is used by Packet::Print to print the
|
||||
* content of a trailer as ascii data to a c++ output stream.
|
||||
* Although the trailer is free to format its output as it
|
||||
* wishes, it is recommended to follow a few rules to integrate
|
||||
* with the packet pretty printer: start with flags, small field
|
||||
* values located between a pair of parens. Values should be separated
|
||||
* by whitespace. Follow the parens with the important fields,
|
||||
* separated by whitespace.
|
||||
* i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
|
||||
*/
|
||||
virtual void Print (std::ostream &os) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
uint32_t
|
||||
Header::AllocateUid (std::string uuid)
|
||||
{
|
||||
return ChunkRegistry::RegisterHeader<T> (uuid);
|
||||
}
|
||||
std::ostream & operator << (std::ostream &os, const Header &header);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "trailer.h"
|
||||
#include "packet.h"
|
||||
#include "packet-metadata.h"
|
||||
#include "packet-printer.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -35,28 +34,18 @@ template <int N>
|
||||
class HistoryHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
HistoryHeader ();
|
||||
bool IsOk (void) const;
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
bool m_ok;
|
||||
};
|
||||
|
||||
template <int N>
|
||||
uint32_t
|
||||
HistoryHeader<N>::GetUid (void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << N << "HistoryHeader.ns3";
|
||||
static uint32_t uid = AllocateUid<HistoryHeader<N> > (oss.str());
|
||||
return uid;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
HistoryHeader<N>::HistoryHeader ()
|
||||
: m_ok (false)
|
||||
@@ -70,14 +59,23 @@ HistoryHeader<N>::IsOk (void) const
|
||||
}
|
||||
|
||||
template <int N>
|
||||
std::string
|
||||
HistoryHeader<N>::GetName (void) const
|
||||
TypeId
|
||||
HistoryHeader<N>::GetTypeId (void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << N;
|
||||
return oss.str ();
|
||||
oss << "ns3::HistoryHeader<"<<N<<">";
|
||||
static TypeId tid = TypeId (oss.str ().c_str ())
|
||||
.SetParent<Header> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
TypeId
|
||||
HistoryHeader<N>::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
template <int N>
|
||||
void
|
||||
HistoryHeader<N>::Print (std::ostream &os) const
|
||||
@@ -115,29 +113,19 @@ template <int N>
|
||||
class HistoryTrailer : public Trailer
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
HistoryTrailer ();
|
||||
bool IsOk (void) const;
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
bool m_ok;
|
||||
};
|
||||
|
||||
template <int N>
|
||||
uint32_t
|
||||
HistoryTrailer<N>::GetUid (void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << N << "HistoryTrailer.ns3";
|
||||
static uint32_t uid = AllocateUid<HistoryTrailer<N> > (oss.str ());
|
||||
return uid;
|
||||
}
|
||||
|
||||
|
||||
template <int N>
|
||||
HistoryTrailer<N>::HistoryTrailer ()
|
||||
: m_ok (false)
|
||||
@@ -151,12 +139,22 @@ HistoryTrailer<N>::IsOk (void) const
|
||||
}
|
||||
|
||||
template <int N>
|
||||
std::string
|
||||
HistoryTrailer<N>::GetName (void) const
|
||||
TypeId
|
||||
HistoryTrailer<N>::GetTypeId (void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << N;
|
||||
return oss.str ();
|
||||
oss << "ns3::HistoryTrailer<"<<N<<">";
|
||||
static TypeId tid = TypeId (oss.str ().c_str ())
|
||||
.SetParent<Trailer> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
TypeId
|
||||
HistoryTrailer<N>::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
template <int N>
|
||||
void
|
||||
@@ -202,135 +200,40 @@ public:
|
||||
bool CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...);
|
||||
virtual bool RunTests (void);
|
||||
private:
|
||||
template <int N>
|
||||
void PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryHeader<N> *header);
|
||||
template <int N>
|
||||
void PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size, const HistoryTrailer<N> *trailer);
|
||||
void PrintFragment (std::ostream &os,uint32_t packetUid,
|
||||
uint32_t size,std::string & name,
|
||||
struct PacketPrinter::FragmentInformation info);
|
||||
void PrintPayload (std::ostream &os,uint32_t packetUid,
|
||||
uint32_t size,
|
||||
struct PacketPrinter::FragmentInformation info);
|
||||
template <int N>
|
||||
void RegisterHeader (void);
|
||||
template <int N>
|
||||
void RegisterTrailer (void);
|
||||
void CleanupPrints (void);
|
||||
Ptr<Packet> DoAddHeader (Ptr<Packet> p);
|
||||
bool Check (const char *file, int line, std::list<int> expected);
|
||||
|
||||
|
||||
bool m_headerError;
|
||||
bool m_trailerError;
|
||||
std::list<int> m_prints;
|
||||
PacketPrinter m_printer;
|
||||
};
|
||||
|
||||
PacketMetadataTest::PacketMetadataTest ()
|
||||
: Test ("PacketMetadata")
|
||||
{
|
||||
m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this));
|
||||
m_printer.SetSeparator ("");
|
||||
}
|
||||
{}
|
||||
|
||||
PacketMetadataTest::~PacketMetadataTest ()
|
||||
{}
|
||||
|
||||
template <int N>
|
||||
void
|
||||
PacketMetadataTest::RegisterHeader (void)
|
||||
bool
|
||||
PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
|
||||
{
|
||||
static bool registered = false;
|
||||
if (!registered)
|
||||
std::list<int> expected;
|
||||
va_list ap;
|
||||
va_start (ap, n);
|
||||
for (uint32_t j = 0; j < n; j++)
|
||||
{
|
||||
m_printer.SetHeaderPrinter (MakeCallback (&PacketMetadataTest::PrintHeader<N>, this),
|
||||
MakeCallback (&PacketMetadataTest::PrintFragment, this));
|
||||
registered = true;
|
||||
int v = va_arg (ap, int);
|
||||
expected.push_back (v);
|
||||
}
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
template <int N>
|
||||
void
|
||||
PacketMetadataTest::RegisterTrailer (void)
|
||||
{
|
||||
static bool registered = false;
|
||||
if (!registered)
|
||||
PacketMetadata::ItemIterator k = p->BeginItem ();
|
||||
std::list<int> got;
|
||||
while (k.HasNext ())
|
||||
{
|
||||
m_printer.SetTrailerPrinter (MakeCallback (&PacketMetadataTest::PrintTrailer<N>, this),
|
||||
MakeCallback (&PacketMetadataTest::PrintFragment, this));
|
||||
registered = true;
|
||||
struct PacketMetadata::Item item = k.Next ();
|
||||
got.push_back (item.currentSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <int N>
|
||||
void
|
||||
PacketMetadataTest::PrintHeader (std::ostream &os, uint32_t packetUid, uint32_t size,
|
||||
const HistoryHeader<N> *header)
|
||||
{
|
||||
if (!header->IsOk ())
|
||||
{
|
||||
m_headerError = true;
|
||||
}
|
||||
m_prints.push_back (N);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
void
|
||||
PacketMetadataTest::PrintTrailer (std::ostream &os, uint32_t packetUid, uint32_t size,
|
||||
const HistoryTrailer<N> *trailer)
|
||||
{
|
||||
if (!trailer->IsOk ())
|
||||
{
|
||||
m_trailerError = true;
|
||||
}
|
||||
m_prints.push_back (N);
|
||||
}
|
||||
void
|
||||
PacketMetadataTest::PrintFragment (std::ostream &os,uint32_t packetUid,
|
||||
uint32_t size,std::string & name,
|
||||
struct PacketPrinter::FragmentInformation info)
|
||||
{
|
||||
m_prints.push_back (size - (info.end + info.start));
|
||||
}
|
||||
void
|
||||
PacketMetadataTest::PrintPayload (std::ostream &os,uint32_t packetUid,
|
||||
uint32_t size,
|
||||
struct PacketPrinter::FragmentInformation info)
|
||||
{
|
||||
m_prints.push_back (size - (info.end + info.start));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PacketMetadataTest::CleanupPrints (void)
|
||||
{
|
||||
m_prints.clear ();
|
||||
}
|
||||
|
||||
bool
|
||||
PacketMetadataTest::Check (const char *file, int line, std::list<int> expected)
|
||||
{
|
||||
if (m_headerError)
|
||||
{
|
||||
Failure () << "PacketMetadata header error. file=" << file
|
||||
<< ", line=" << line << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (m_trailerError)
|
||||
{
|
||||
Failure () << "PacketMetadata trailer error. file=" << file
|
||||
<< ", line=" << line << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (expected.size () != m_prints.size ())
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
for (std::list<int>::iterator i = m_prints.begin (),
|
||||
for (std::list<int>::iterator i = got.begin (),
|
||||
j = expected.begin ();
|
||||
i != m_prints.end (); i++, j++)
|
||||
i != got.end (); i++, j++)
|
||||
{
|
||||
NS_ASSERT (j != expected.end ());
|
||||
if (*j != *i)
|
||||
@@ -342,8 +245,8 @@ PacketMetadataTest::Check (const char *file, int line, std::list<int> expected)
|
||||
error:
|
||||
Failure () << "PacketMetadata error. file="<< file
|
||||
<< ", line=" << line << ", got:\"";
|
||||
for (std::list<int>::iterator i = m_prints.begin ();
|
||||
i != m_prints.end (); i++)
|
||||
for (std::list<int>::iterator i = got.begin ();
|
||||
i != got.end (); i++)
|
||||
{
|
||||
Failure () << *i << ", ";
|
||||
}
|
||||
@@ -357,60 +260,24 @@ PacketMetadataTest::Check (const char *file, int line, std::list<int> expected)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
PacketMetadataTest::CheckHistory (Ptr<Packet> p, const char *file, int line, uint32_t n, ...)
|
||||
{
|
||||
m_headerError = false;
|
||||
m_trailerError = false;
|
||||
std::list<int> expected;
|
||||
va_list ap;
|
||||
va_start (ap, n);
|
||||
for (uint32_t j = 0; j < n; j++)
|
||||
{
|
||||
int v = va_arg (ap, int);
|
||||
expected.push_back (v);
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
m_printer.PrintForward ();
|
||||
p->Print (Failure (), m_printer);
|
||||
bool ok = Check (file, line, expected);
|
||||
CleanupPrints ();
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_printer.PrintBackward ();
|
||||
p->Print (Failure (), m_printer);
|
||||
expected.reverse ();
|
||||
ok = Check (file, line, expected);
|
||||
CleanupPrints ();
|
||||
return ok;
|
||||
}
|
||||
|
||||
#define ADD_HEADER(p, n) \
|
||||
{ \
|
||||
HistoryHeader<n> header; \
|
||||
RegisterHeader<n> (); \
|
||||
p->AddHeader (header); \
|
||||
}
|
||||
#define ADD_TRAILER(p, n) \
|
||||
{ \
|
||||
HistoryTrailer<n> trailer; \
|
||||
RegisterTrailer<n> (); \
|
||||
p->AddTrailer (trailer); \
|
||||
}
|
||||
#define REM_HEADER(p, n) \
|
||||
{ \
|
||||
HistoryHeader<n> header; \
|
||||
RegisterHeader<n> (); \
|
||||
p->RemoveHeader (header); \
|
||||
}
|
||||
#define REM_TRAILER(p, n) \
|
||||
{ \
|
||||
HistoryTrailer<n> trailer; \
|
||||
RegisterTrailer<n> (); \
|
||||
p->RemoveTrailer (trailer); \
|
||||
}
|
||||
#define CHECK_HISTORY(p, ...) \
|
||||
@@ -680,6 +547,63 @@ PacketMetadataTest::RunTests (void)
|
||||
p->RemoveAtStart (8+10+8);
|
||||
CHECK_HISTORY (p, 1, 8);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
REM_HEADER (p, 8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_TRAILER (p, 8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
p->RemoveAtStart (8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_TRAILER (p, 8);
|
||||
REM_HEADER (p, 8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_HEADER (p, 8);
|
||||
REM_TRAILER (p, 8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_TRAILER (p, 8);
|
||||
p->RemoveAtStart (8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_HEADER (p, 8);
|
||||
p->RemoveAtEnd (8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_TRAILER (p, 8);
|
||||
p->RemoveAtEnd (8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
p = Create<Packet> (0);
|
||||
ADD_HEADER (p, 8);
|
||||
ADD_TRAILER (p, 8);
|
||||
REM_HEADER (p, 8);
|
||||
p->RemoveAtStart (8);
|
||||
CHECK_HISTORY (p, 0);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
#include "ns3/log.h"
|
||||
#include "packet-metadata.h"
|
||||
#include "buffer.h"
|
||||
#include "chunk-registry.h"
|
||||
#include "header.h"
|
||||
#include "trailer.h"
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("PacketMetadata");
|
||||
|
||||
@@ -696,6 +697,12 @@ PacketMetadata::CreateFragment (uint32_t start, uint32_t end) const
|
||||
}
|
||||
|
||||
void
|
||||
PacketMetadata::AddHeader (const Header &header, uint32_t size)
|
||||
{
|
||||
uint32_t uid = header.GetInstanceTypeId ().GetUid () << 1;
|
||||
DoAddHeader (uid, size);
|
||||
}
|
||||
void
|
||||
PacketMetadata::DoAddHeader (uint32_t uid, uint32_t size)
|
||||
{
|
||||
if (!m_enable)
|
||||
@@ -703,7 +710,7 @@ PacketMetadata::DoAddHeader (uint32_t uid, uint32_t size)
|
||||
m_metadataSkipped = true;
|
||||
return;
|
||||
}
|
||||
NS_LOG_PARAMS ("(uid=" << uid << ", size=" << size << ")");
|
||||
NS_LOG_PARAMS ("uid=" << uid << "size=" << size << "");
|
||||
|
||||
struct PacketMetadata::SmallItem item;
|
||||
item.next = m_head;
|
||||
@@ -716,8 +723,9 @@ PacketMetadata::DoAddHeader (uint32_t uid, uint32_t size)
|
||||
UpdateHead (written);
|
||||
}
|
||||
void
|
||||
PacketMetadata::DoRemoveHeader (uint32_t uid, uint32_t size)
|
||||
PacketMetadata::RemoveHeader (const Header &header, uint32_t size)
|
||||
{
|
||||
uint32_t uid = header.GetInstanceTypeId ().GetUid () << 1;
|
||||
if (!m_enable)
|
||||
{
|
||||
m_metadataSkipped = true;
|
||||
@@ -742,7 +750,7 @@ PacketMetadata::DoRemoveHeader (uint32_t uid, uint32_t size)
|
||||
{
|
||||
m_used = m_head;
|
||||
}
|
||||
if (item.next == 0xffff)
|
||||
if (m_head == m_tail)
|
||||
{
|
||||
m_head = 0xffff;
|
||||
m_tail = 0xffff;
|
||||
@@ -753,13 +761,15 @@ PacketMetadata::DoRemoveHeader (uint32_t uid, uint32_t size)
|
||||
}
|
||||
}
|
||||
void
|
||||
PacketMetadata::DoAddTrailer (uint32_t uid, uint32_t size)
|
||||
PacketMetadata::AddTrailer (const Trailer &trailer, uint32_t size)
|
||||
{
|
||||
uint32_t uid = trailer.GetInstanceTypeId ().GetUid () << 1;
|
||||
if (!m_enable)
|
||||
{
|
||||
m_metadataSkipped = true;
|
||||
return;
|
||||
}
|
||||
NS_LOG_PARAMS ("(uid=" << uid << ", size=" << size << ")");
|
||||
struct PacketMetadata::SmallItem item;
|
||||
item.next = 0xffff;
|
||||
item.prev = m_tail;
|
||||
@@ -771,13 +781,15 @@ PacketMetadata::DoAddTrailer (uint32_t uid, uint32_t size)
|
||||
UpdateTail (written);
|
||||
}
|
||||
void
|
||||
PacketMetadata::DoRemoveTrailer (uint32_t uid, uint32_t size)
|
||||
PacketMetadata::RemoveTrailer (const Trailer &trailer, uint32_t size)
|
||||
{
|
||||
uint32_t uid = trailer.GetInstanceTypeId ().GetUid () << 1;
|
||||
if (!m_enable)
|
||||
{
|
||||
m_metadataSkipped = true;
|
||||
return;
|
||||
}
|
||||
NS_LOG_PARAMS ("(uid=" << uid << ", size=" << size << ")");
|
||||
struct PacketMetadata::SmallItem item;
|
||||
struct PacketMetadata::ExtraItem extraItem;
|
||||
uint32_t read = ReadItems (m_tail, &item, &extraItem);
|
||||
@@ -796,7 +808,7 @@ PacketMetadata::DoRemoveTrailer (uint32_t uid, uint32_t size)
|
||||
{
|
||||
m_used = m_tail;
|
||||
}
|
||||
if (item.prev == 0xffff)
|
||||
if (m_head == m_tail)
|
||||
{
|
||||
m_head = 0xffff;
|
||||
m_tail = 0xffff;
|
||||
@@ -892,7 +904,15 @@ PacketMetadata::RemoveAtStart (uint32_t start)
|
||||
if (itemRealSize <= leftToRemove)
|
||||
{
|
||||
// remove from list.
|
||||
m_head = item.next;
|
||||
if (m_head == m_tail)
|
||||
{
|
||||
m_head = 0xffff;
|
||||
m_tail = 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_head = item.next;
|
||||
}
|
||||
leftToRemove -= itemRealSize;
|
||||
}
|
||||
else
|
||||
@@ -950,7 +970,15 @@ PacketMetadata::RemoveAtEnd (uint32_t end)
|
||||
if (itemRealSize <= leftToRemove)
|
||||
{
|
||||
// remove from list.
|
||||
m_tail = item.prev;
|
||||
if (m_head == m_tail)
|
||||
{
|
||||
m_head = 0xffff;
|
||||
m_tail = 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tail = item.prev;
|
||||
}
|
||||
leftToRemove -= itemRealSize;
|
||||
}
|
||||
else
|
||||
@@ -988,47 +1016,6 @@ PacketMetadata::RemoveAtEnd (uint32_t end)
|
||||
}
|
||||
NS_ASSERT (leftToRemove == 0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PacketMetadata::DoPrint (const struct PacketMetadata::SmallItem *item,
|
||||
const struct PacketMetadata::ExtraItem *extraItem,
|
||||
Buffer data, uint32_t offset, const PacketPrinter &printer,
|
||||
std::ostream &os) const
|
||||
{
|
||||
uint32_t uid = (item->typeUid & 0xfffffffe) >> 1;
|
||||
if (uid == 0)
|
||||
{
|
||||
// payload.
|
||||
printer.PrintPayload (os, extraItem->packetUid, item->size,
|
||||
extraItem->fragmentStart,
|
||||
item->size - extraItem->fragmentEnd);
|
||||
}
|
||||
else if (extraItem->fragmentStart != 0 ||
|
||||
extraItem->fragmentEnd != item->size)
|
||||
{
|
||||
printer.PrintChunkFragment (uid, os, extraItem->packetUid, item->size,
|
||||
extraItem->fragmentStart,
|
||||
item->size - extraItem->fragmentEnd);
|
||||
}
|
||||
else if (ChunkRegistry::IsHeader (uid))
|
||||
{
|
||||
ns3::Buffer::Iterator j = data.Begin ();
|
||||
j.Next (offset);
|
||||
printer.PrintChunk (uid, j, os, extraItem->packetUid, item->size);
|
||||
}
|
||||
else if (ChunkRegistry::IsTrailer (uid))
|
||||
{
|
||||
ns3::Buffer::Iterator j = data.End ();
|
||||
j.Prev (data.GetSize () - (offset + item->size));
|
||||
printer.PrintChunk (uid, j, os, extraItem->packetUid, item->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
return extraItem->fragmentEnd - extraItem->fragmentStart;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PacketMetadata::GetTotalSize (void) const
|
||||
{
|
||||
@@ -1056,60 +1043,88 @@ PacketMetadata::GetUid (void) const
|
||||
{
|
||||
return m_packetUid;
|
||||
}
|
||||
|
||||
void
|
||||
PacketMetadata::Print (std::ostream &os, Buffer data, const PacketPrinter &printer) const
|
||||
PacketMetadata::ItemIterator
|
||||
PacketMetadata::BeginItem (Buffer buffer) const
|
||||
{
|
||||
if (!m_enable)
|
||||
return ItemIterator (this, buffer);
|
||||
}
|
||||
PacketMetadata::ItemIterator::ItemIterator (const PacketMetadata *metadata, Buffer buffer)
|
||||
: m_metadata (metadata),
|
||||
m_buffer (buffer),
|
||||
m_current (metadata->m_head),
|
||||
m_offset (0),
|
||||
m_hasReadTail (false)
|
||||
{}
|
||||
bool
|
||||
PacketMetadata::ItemIterator::HasNext (void) const
|
||||
{
|
||||
if (m_current == 0xffff)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
NS_ASSERT (m_data != 0);
|
||||
NS_ASSERT (GetTotalSize () == data.GetSize ());
|
||||
struct PacketMetadata::SmallItem item;
|
||||
struct PacketMetadata::ExtraItem extraItem;
|
||||
if (printer.m_forward)
|
||||
if (m_hasReadTail)
|
||||
{
|
||||
uint32_t current = m_head;
|
||||
uint32_t offset = 0;
|
||||
while (current != 0xffff)
|
||||
{
|
||||
ReadItems (current, &item, &extraItem);
|
||||
uint32_t realSize = DoPrint (&item, &extraItem, data, offset, printer, os);
|
||||
offset += realSize;
|
||||
if (current == m_tail)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (item.next != 0xffff)
|
||||
{
|
||||
os << printer.m_separator;
|
||||
}
|
||||
NS_ASSERT (current != item.next);
|
||||
current = item.next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
PacketMetadata::Item
|
||||
PacketMetadata::ItemIterator::Next (void)
|
||||
{
|
||||
struct PacketMetadata::Item item;
|
||||
struct PacketMetadata::SmallItem smallItem;
|
||||
struct PacketMetadata::ExtraItem extraItem;
|
||||
m_metadata->ReadItems (m_current, &smallItem, &extraItem);
|
||||
if (m_current == m_metadata->m_tail)
|
||||
{
|
||||
m_hasReadTail = true;
|
||||
}
|
||||
m_current = smallItem.next;
|
||||
uint32_t uid = (smallItem.typeUid & 0xfffffffe) >> 1;
|
||||
item.tid.SetUid (uid);
|
||||
item.currentTrimedFromStart = extraItem.fragmentStart;
|
||||
item.currentTrimedFromEnd = extraItem.fragmentEnd - smallItem.size;
|
||||
item.currentSize = extraItem.fragmentEnd - extraItem.fragmentStart;
|
||||
if (extraItem.fragmentStart != 0 || extraItem.fragmentEnd != smallItem.size)
|
||||
{
|
||||
item.isFragment = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t current = m_tail;
|
||||
uint32_t offset = data.GetSize ();
|
||||
while (current != 0xffff)
|
||||
item.isFragment = false;
|
||||
}
|
||||
TypeId tid;
|
||||
tid.SetUid (uid);
|
||||
if (uid == 0)
|
||||
{
|
||||
item.type = PacketMetadata::Item::PAYLOAD;
|
||||
}
|
||||
else if (tid.IsChildOf (Header::GetTypeId ()))
|
||||
{
|
||||
item.type = PacketMetadata::Item::HEADER;
|
||||
if (!item.isFragment)
|
||||
{
|
||||
ReadItems (current, &item, &extraItem);
|
||||
uint32_t realSize = DoPrint (&item, &extraItem, data, offset - item.size, printer, os);
|
||||
offset -= realSize;
|
||||
if (current == m_head)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (item.prev != 0xffff)
|
||||
{
|
||||
os << printer.m_separator;
|
||||
}
|
||||
NS_ASSERT (current != item.prev);
|
||||
current = item.prev;
|
||||
ns3::Buffer::Iterator j = m_buffer.Begin ();
|
||||
j.Next (m_offset);
|
||||
item.current = j;
|
||||
}
|
||||
}
|
||||
else if (tid.IsChildOf (Trailer::GetTypeId ()))
|
||||
{
|
||||
item.type = PacketMetadata::Item::TRAILER;
|
||||
if (!item.isFragment)
|
||||
{
|
||||
ns3::Buffer::Iterator j = m_buffer.End ();
|
||||
j.Prev (m_buffer.GetSize () - (m_offset + smallItem.size));
|
||||
item.current = j;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
m_offset += extraItem.fragmentEnd - extraItem.fragmentStart;
|
||||
return item;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -1134,7 +1149,9 @@ PacketMetadata::GetSerializedSize (void) const
|
||||
}
|
||||
else
|
||||
{
|
||||
totalSize += 4 + ChunkRegistry::GetUidStringFromUid (uid).size ();
|
||||
TypeId tid;
|
||||
tid.SetUid (uid);
|
||||
totalSize += 4 + tid.GetName ().size ();
|
||||
}
|
||||
totalSize += 1 + 4 + 2 + 4 + 4 + 4;
|
||||
if (current == m_tail)
|
||||
@@ -1165,7 +1182,9 @@ PacketMetadata::Serialize (Buffer::Iterator i, uint32_t size) const
|
||||
uint32_t uid = (item.typeUid & 0xfffffffe) >> 1;
|
||||
if (uid != 0)
|
||||
{
|
||||
std::string uidString = ChunkRegistry::GetUidStringFromUid (uid);
|
||||
TypeId tid;
|
||||
tid.SetUid (uid);
|
||||
std::string uidString = tid.GetName ();
|
||||
i.WriteU32 (uidString.size ());
|
||||
bytesWritten += 4;
|
||||
i.Write ((uint8_t *)uidString.c_str (), uidString.size ());
|
||||
@@ -1225,7 +1244,8 @@ PacketMetadata::Deserialize (Buffer::Iterator i)
|
||||
uidString.push_back (i.ReadU8 ());
|
||||
size --;
|
||||
}
|
||||
uid = ChunkRegistry::GetUidFromUidString (uidString);
|
||||
TypeId tid = TypeId::LookupByName (uidString);
|
||||
uid = tid.GetUid ();
|
||||
}
|
||||
uint8_t isBig = i.ReadU8 ();
|
||||
size --;
|
||||
|
||||
@@ -25,12 +25,15 @@
|
||||
#include <vector>
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "packet-printer.h"
|
||||
#include "ns3/type-id.h"
|
||||
#include "buffer.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class Chunk;
|
||||
class Buffer;
|
||||
class Header;
|
||||
class Trailer;
|
||||
|
||||
/**
|
||||
* \internal
|
||||
@@ -72,8 +75,55 @@ class Buffer;
|
||||
* The variable-size 32 bit integers are stored using the uleb128
|
||||
* encoding.
|
||||
*/
|
||||
class PacketMetadata {
|
||||
class PacketMetadata
|
||||
{
|
||||
public:
|
||||
struct Item
|
||||
{
|
||||
enum {
|
||||
PAYLOAD,
|
||||
HEADER,
|
||||
TRAILER
|
||||
} type;
|
||||
/* true: this is a fragmented header, trailer, or, payload.
|
||||
* false: this is a whole header, trailer, or, payload.
|
||||
*/
|
||||
bool isFragment;
|
||||
/* TypeId of Header or Trailer. Valid only if type is
|
||||
* header or trailer.
|
||||
*/
|
||||
TypeId tid;
|
||||
/* size of item. If fragment, size of fragment. Otherwise,
|
||||
* size of original item.
|
||||
*/
|
||||
uint32_t currentSize;
|
||||
/* how many bytes were trimed from the start of a fragment.
|
||||
* if isFragment is true, this field is zero.
|
||||
*/
|
||||
uint32_t currentTrimedFromStart;
|
||||
/* how many bytes were trimed from the end of a fragment.
|
||||
* if isFragment is true, this field is zero.
|
||||
*/
|
||||
uint32_t currentTrimedFromEnd;
|
||||
/* an iterator which can be fed to Deserialize. Valid only
|
||||
* if isFragment and isPayload are false.
|
||||
*/
|
||||
Buffer::Iterator current;
|
||||
};
|
||||
class ItemIterator
|
||||
{
|
||||
public:
|
||||
ItemIterator (const PacketMetadata *metadata, Buffer buffer);
|
||||
bool HasNext (void) const;
|
||||
Item Next (void);
|
||||
private:
|
||||
const PacketMetadata *m_metadata;
|
||||
Buffer m_buffer;
|
||||
uint16_t m_current;
|
||||
uint32_t m_offset;
|
||||
bool m_hasReadTail;
|
||||
};
|
||||
|
||||
static void Enable (void);
|
||||
static void SetOptOne (bool optOne);
|
||||
|
||||
@@ -82,15 +132,11 @@ public:
|
||||
inline PacketMetadata &operator = (PacketMetadata const& o);
|
||||
inline ~PacketMetadata ();
|
||||
|
||||
template <typename T>
|
||||
void AddHeader (T const &header, uint32_t size);
|
||||
template <typename T>
|
||||
void RemoveHeader (T const &header, uint32_t size);
|
||||
void AddHeader (Header const &header, uint32_t size);
|
||||
void RemoveHeader (Header const &header, uint32_t size);
|
||||
|
||||
template <typename T>
|
||||
void AddTrailer (T const &trailer, uint32_t size);
|
||||
template <typename T>
|
||||
void RemoveTrailer (T const &trailer, uint32_t size);
|
||||
void AddTrailer (Trailer const &trailer, uint32_t size);
|
||||
void RemoveTrailer (Trailer const &trailer, uint32_t size);
|
||||
|
||||
PacketMetadata CreateFragment (uint32_t start, uint32_t end) const;
|
||||
void AddAtEnd (PacketMetadata const&o);
|
||||
@@ -100,14 +146,14 @@ public:
|
||||
|
||||
uint32_t GetUid (void) const;
|
||||
|
||||
void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const;
|
||||
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator i, uint32_t size) const;
|
||||
uint32_t Deserialize (Buffer::Iterator i);
|
||||
|
||||
static void PrintStats (void);
|
||||
|
||||
ItemIterator BeginItem (Buffer buffer) const;
|
||||
|
||||
private:
|
||||
struct Data {
|
||||
/* number of references to this struct Data instance. */
|
||||
@@ -192,12 +238,9 @@ private:
|
||||
};
|
||||
|
||||
friend DataFreeList::~DataFreeList ();
|
||||
friend class ItemIterator;
|
||||
|
||||
PacketMetadata ();
|
||||
void DoAddHeader (uint32_t uid, uint32_t size);
|
||||
void DoRemoveHeader (uint32_t uid, uint32_t size);
|
||||
void DoAddTrailer (uint32_t uid, uint32_t size);
|
||||
void DoRemoveTrailer (uint32_t uid, uint32_t size);
|
||||
|
||||
inline uint16_t AddSmall (const PacketMetadata::SmallItem *item);
|
||||
uint16_t AddBig (uint32_t head, uint32_t tail,
|
||||
@@ -219,14 +262,11 @@ private:
|
||||
void AppendValueExtra (uint32_t value, uint8_t *buffer);
|
||||
inline void Reserve (uint32_t n);
|
||||
void ReserveCopy (uint32_t n);
|
||||
uint32_t DoPrint (const struct PacketMetadata::SmallItem *item,
|
||||
const struct PacketMetadata::ExtraItem *extraItem,
|
||||
Buffer data, uint32_t offset, const PacketPrinter &printer,
|
||||
std::ostream &os) const;
|
||||
uint32_t GetTotalSize (void) const;
|
||||
uint32_t ReadItems (uint16_t current,
|
||||
struct PacketMetadata::SmallItem *item,
|
||||
struct PacketMetadata::ExtraItem *extraItem) const;
|
||||
void DoAddHeader (uint32_t uid, uint32_t size);
|
||||
|
||||
|
||||
static struct PacketMetadata::Data *Create (uint32_t size);
|
||||
@@ -261,33 +301,6 @@ private:
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PacketMetadata::AddHeader (T const &header, uint32_t size)
|
||||
{
|
||||
DoAddHeader (T::GetUid () << 1, size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PacketMetadata::RemoveHeader (T const &header, uint32_t size)
|
||||
{
|
||||
DoRemoveHeader (T::GetUid () << 1, size);
|
||||
}
|
||||
template <typename T>
|
||||
void
|
||||
PacketMetadata::AddTrailer (T const &trailer, uint32_t size)
|
||||
{
|
||||
DoAddTrailer (T::GetUid () << 1, size);
|
||||
}
|
||||
template <typename T>
|
||||
void
|
||||
PacketMetadata::RemoveTrailer (T const &trailer, uint32_t size)
|
||||
{
|
||||
DoRemoveTrailer (T::GetUid () << 1, size);
|
||||
}
|
||||
|
||||
|
||||
PacketMetadata::PacketMetadata (uint32_t uid, uint32_t size)
|
||||
: m_data (m_data = PacketMetadata::Create (10)),
|
||||
m_head (0xffff),
|
||||
@@ -343,7 +356,7 @@ PacketMetadata::~PacketMetadata ()
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace ns3
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
#endif /* PACKET_METADATA_H */
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/* -*- 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 "packet-printer.h"
|
||||
#include "chunk-registry.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
PacketPrinter::PacketPrinter ()
|
||||
: m_forward (true),
|
||||
m_separator (" ")
|
||||
{}
|
||||
|
||||
void
|
||||
PacketPrinter::PrintForward (void)
|
||||
{
|
||||
m_forward = true;
|
||||
}
|
||||
void
|
||||
PacketPrinter::PrintBackward (void)
|
||||
{
|
||||
m_forward = false;
|
||||
}
|
||||
void
|
||||
PacketPrinter::SetSeparator (std::string separator)
|
||||
{
|
||||
m_separator = separator;
|
||||
}
|
||||
void
|
||||
PacketPrinter::SetPayloadPrinter (PayloadPrinter printer)
|
||||
{
|
||||
m_payloadPrinter = printer;
|
||||
}
|
||||
|
||||
void
|
||||
PacketPrinter::PrintChunk (uint32_t chunkUid,
|
||||
Buffer::Iterator start,
|
||||
std::ostream &os,
|
||||
uint32_t packetUid,
|
||||
uint32_t size) const
|
||||
{
|
||||
uint8_t *instance = ChunkRegistry::GetStaticInstance (chunkUid);
|
||||
ChunkRegistry::Deserialize (chunkUid, instance, start);
|
||||
|
||||
for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++)
|
||||
{
|
||||
if (i->m_chunkUid == chunkUid)
|
||||
{
|
||||
ChunkRegistry::InvokePrintCallback (chunkUid, instance, os, packetUid, size, i->m_printer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if the over did not override this type of chunk,
|
||||
// we print something by default.
|
||||
std::string name = ChunkRegistry::GetName (chunkUid, instance);
|
||||
os << name << " ";
|
||||
ChunkRegistry::Print (chunkUid, instance, os);
|
||||
}
|
||||
void
|
||||
PacketPrinter::PrintChunkFragment (uint32_t chunkUid,
|
||||
std::ostream &os,
|
||||
uint32_t packetUid,
|
||||
uint32_t size,
|
||||
uint32_t fragmentStart,
|
||||
uint32_t fragmentEnd) const
|
||||
{
|
||||
uint8_t *instance = ChunkRegistry::GetStaticInstance (chunkUid);
|
||||
std::string name = ChunkRegistry::GetName (chunkUid, instance);
|
||||
struct PacketPrinter::FragmentInformation info;
|
||||
info.start = fragmentStart;
|
||||
info.end = fragmentEnd;
|
||||
for (PrinterList::const_iterator i = m_printerList.begin (); i != m_printerList.end (); i++)
|
||||
{
|
||||
if (i->m_chunkUid == chunkUid)
|
||||
{
|
||||
|
||||
i->m_fragmentPrinter (os, packetUid, size, name, info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if the user did not override this type of chunk,
|
||||
// we print something by default.
|
||||
NS_ASSERT (info.start != 0 || info.end != 0);
|
||||
os << name << " "
|
||||
<< "("
|
||||
<< "length " << size - (info.end + info.start) << " "
|
||||
<< "trim_start " << info.start << " "
|
||||
<< "trim_end " << info.end
|
||||
<< ")";
|
||||
}
|
||||
void
|
||||
PacketPrinter::PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size,
|
||||
uint32_t fragmentStart, uint32_t fragmentEnd) const
|
||||
{
|
||||
struct PacketPrinter::FragmentInformation info;
|
||||
info.start = fragmentStart;
|
||||
info.end = fragmentEnd;
|
||||
if (!m_payloadPrinter.IsNull ())
|
||||
{
|
||||
m_payloadPrinter (os, packetUid, size, info);
|
||||
return;
|
||||
}
|
||||
// if the user did not override the payload printer,
|
||||
// we print something anyway.
|
||||
os << "DATA ("
|
||||
<< "length " << size - (info.end + info.start);
|
||||
if (info.start != 0 || info.end != 0)
|
||||
{
|
||||
os << " "
|
||||
<< "trim_start " << info.start << " "
|
||||
<< "trim_end " << info.end;
|
||||
}
|
||||
os << ")";
|
||||
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
@@ -1,181 +0,0 @@
|
||||
/* -*- 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 PACKET_PRINTER_H
|
||||
#define PACKET_PRINTER_H
|
||||
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "buffer.h"
|
||||
#include <vector>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief hold a list of print callbacks for packet headers and trailers
|
||||
*
|
||||
* Users can register in instances of this class print callbacks
|
||||
* which are used by Packet::Print to print the content of a packet.
|
||||
*/
|
||||
class PacketPrinter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief indicates how many bytes were trimmed from a header
|
||||
* or a trailer.
|
||||
*/
|
||||
struct FragmentInformation
|
||||
{
|
||||
/**
|
||||
* The number of bytes trimmed from the start of the header or the trailer.
|
||||
*/
|
||||
uint32_t start;
|
||||
/**
|
||||
* The number of bytes trimmed from the end of the header or the trailer.
|
||||
*/
|
||||
uint32_t end;
|
||||
};
|
||||
/**
|
||||
* \brief callback to print payload.
|
||||
*
|
||||
* Arguments: output stream, packet uid, size, fragment information
|
||||
*/
|
||||
typedef Callback<void,std::ostream &,uint32_t,uint32_t,struct PacketPrinter::FragmentInformation>
|
||||
PayloadPrinter;
|
||||
|
||||
/**
|
||||
* \brief callback to print fragmented chunks.
|
||||
*
|
||||
* Arguments: output stream, packet uid, size, header/trailer name, fragment information
|
||||
*/
|
||||
typedef Callback<void,std::ostream &,uint32_t,uint32_t,std::string &,struct PacketPrinter::FragmentInformation>
|
||||
ChunkFragmentPrinter;
|
||||
|
||||
/**
|
||||
* \brief callback to print chunks for which no specific callback was specified.
|
||||
*
|
||||
* Arguments: output stream, packet uid, size, header/trailer name, fragment information
|
||||
*/
|
||||
typedef Callback<void,std::ostream&,uint32_t,uint32_t,std::string&,struct PacketPrinter::FragmentInformation>
|
||||
DefaultPrinter;
|
||||
|
||||
PacketPrinter ();
|
||||
|
||||
/**
|
||||
* Print the content of the packet forward.
|
||||
*/
|
||||
void PrintForward (void);
|
||||
/**
|
||||
* Print the content of the packet backward.
|
||||
*/
|
||||
void PrintBackward (void);
|
||||
/**
|
||||
* \param separator the new separator
|
||||
*
|
||||
* The default separator is a single space character.
|
||||
*/
|
||||
void SetSeparator (std::string separator);
|
||||
/**
|
||||
* \param printer printer for payload
|
||||
*/
|
||||
void SetPayloadPrinter (PayloadPrinter printer);
|
||||
/**
|
||||
* \param printer printer for the specified chunk
|
||||
* \param fragmentPrinter printer for a fragment of the specified chunk
|
||||
*
|
||||
* If the user does not force a user-specific printing function through
|
||||
* a call to SetHeaderPrinter, the default print output is generated.
|
||||
*/
|
||||
template <typename T>
|
||||
void SetHeaderPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
|
||||
ChunkFragmentPrinter fragmentPrinter);
|
||||
/**
|
||||
* \param printer printer for the specified chunk
|
||||
* \param fragmentPrinter printer for a fragment of the specified chunk
|
||||
*
|
||||
* If the user does not force a user-specific printing function through
|
||||
* a call to SetTrailerPrinter, the default print output is generated.
|
||||
*/
|
||||
template <typename T>
|
||||
void SetTrailerPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
|
||||
ChunkFragmentPrinter fragmentPrinter);
|
||||
private:
|
||||
friend class PacketMetadata;
|
||||
void PrintChunk (uint32_t uid,
|
||||
Buffer::Iterator i,
|
||||
std::ostream &os,
|
||||
uint32_t packetUid,
|
||||
uint32_t size) const;
|
||||
void PrintChunkFragment (uint32_t uid,
|
||||
std::ostream &os,
|
||||
uint32_t packetUid,
|
||||
uint32_t size,
|
||||
uint32_t fragmentStart,
|
||||
uint32_t fragmentEnd) const;
|
||||
void PrintPayload (std::ostream &os, uint32_t packetUid, uint32_t size,
|
||||
uint32_t fragmentStart, uint32_t fragmentEnd) const;
|
||||
struct Printer
|
||||
{
|
||||
uint32_t m_chunkUid;
|
||||
CallbackBase m_printer;
|
||||
Callback<void,std::ostream &,uint32_t,uint32_t,std::string &,
|
||||
struct PacketPrinter::FragmentInformation> m_fragmentPrinter;
|
||||
};
|
||||
typedef std::vector<struct PacketPrinter::Printer> PrinterList;
|
||||
|
||||
PrinterList m_printerList;
|
||||
PayloadPrinter m_payloadPrinter;
|
||||
DefaultPrinter m_defaultPrinter;
|
||||
bool m_forward;
|
||||
std::string m_separator;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PacketPrinter::SetHeaderPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
|
||||
ChunkFragmentPrinter fragmentPrinter)
|
||||
{
|
||||
Printer p;
|
||||
p.m_chunkUid = T::GetUid ();
|
||||
p.m_printer = printer;
|
||||
p.m_fragmentPrinter = fragmentPrinter;
|
||||
m_printerList.push_back (p);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
PacketPrinter::SetTrailerPrinter (Callback<void,std::ostream &,uint32_t,uint32_t,const T *> printer,
|
||||
ChunkFragmentPrinter fragmentPrinter)
|
||||
{
|
||||
Printer p;
|
||||
p.m_chunkUid = T::GetUid ();
|
||||
p.m_printer = printer;
|
||||
p.m_fragmentPrinter = fragmentPrinter;
|
||||
m_printerList.push_back (p);
|
||||
}
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* PACKET_PRINTER_H */
|
||||
@@ -19,7 +19,6 @@
|
||||
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
|
||||
*/
|
||||
#include "packet.h"
|
||||
#include "packet-printer.h"
|
||||
#include "ns3/assert.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -124,6 +123,40 @@ Packet::GetSize (void) const
|
||||
return m_buffer.GetSize ();
|
||||
}
|
||||
|
||||
void
|
||||
Packet::AddHeader (const Header &header)
|
||||
{
|
||||
uint32_t size = header.GetSerializedSize ();
|
||||
m_buffer.AddAtStart (size);
|
||||
header.Serialize (m_buffer.Begin ());
|
||||
m_metadata.AddHeader (header, size);
|
||||
}
|
||||
uint32_t
|
||||
Packet::RemoveHeader (Header &header)
|
||||
{
|
||||
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
|
||||
m_buffer.RemoveAtStart (deserialized);
|
||||
m_metadata.RemoveHeader (header, deserialized);
|
||||
return deserialized;
|
||||
}
|
||||
void
|
||||
Packet::AddTrailer (const Trailer &trailer)
|
||||
{
|
||||
uint32_t size = trailer.GetSerializedSize ();
|
||||
m_buffer.AddAtEnd (size);
|
||||
Buffer::Iterator end = m_buffer.End ();
|
||||
trailer.Serialize (end);
|
||||
m_metadata.AddTrailer (trailer, size);
|
||||
}
|
||||
uint32_t
|
||||
Packet::RemoveTrailer (Trailer &trailer)
|
||||
{
|
||||
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
|
||||
m_buffer.RemoveAtEnd (deserialized);
|
||||
m_metadata.RemoveTrailer (trailer, deserialized);
|
||||
return deserialized;
|
||||
}
|
||||
|
||||
void
|
||||
Packet::AddAtEnd (Ptr<const Packet> packet)
|
||||
{
|
||||
@@ -187,13 +220,123 @@ Packet::PrintTags (std::ostream &os) const
|
||||
void
|
||||
Packet::Print (std::ostream &os) const
|
||||
{
|
||||
m_metadata.Print (os, m_buffer, PacketPrinter ());
|
||||
PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
|
||||
while (i.HasNext ())
|
||||
{
|
||||
PacketMetadata::Item item = i.Next ();
|
||||
if (item.isFragment)
|
||||
{
|
||||
switch (item.type) {
|
||||
case PacketMetadata::Item::PAYLOAD:
|
||||
os << "Payload";
|
||||
break;
|
||||
case PacketMetadata::Item::HEADER:
|
||||
case PacketMetadata::Item::TRAILER:
|
||||
os << item.tid.GetName ();
|
||||
break;
|
||||
}
|
||||
os << " Fragment [" << item.currentTrimedFromStart<<":"
|
||||
<< (item.currentTrimedFromStart + item.currentSize) << "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (item.type) {
|
||||
case PacketMetadata::Item::PAYLOAD:
|
||||
os << "Payload (size=" << item.currentSize << ")";
|
||||
break;
|
||||
case PacketMetadata::Item::HEADER:
|
||||
case PacketMetadata::Item::TRAILER:
|
||||
os << item.tid.GetName () << " (";
|
||||
{
|
||||
NS_ASSERT (item.tid.HasConstructor ());
|
||||
Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
|
||||
NS_ASSERT (!constructor.IsNull ());
|
||||
ObjectBase *instance = constructor ();
|
||||
NS_ASSERT (instance != 0);
|
||||
Chunk *chunk = dynamic_cast<Chunk *> (instance);
|
||||
NS_ASSERT (chunk != 0);
|
||||
chunk->Deserialize (item.current);
|
||||
chunk->Print (os);
|
||||
}
|
||||
os << ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i.HasNext ())
|
||||
{
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
// The code below will work only if headers and trailers
|
||||
// define the right attributes which is not the case for
|
||||
// now. So, as a temporary measure, we use the
|
||||
// headers' and trailers' Print method as shown above.
|
||||
PacketMetadata::ItemIterator i = m_metadata.BeginItem (m_buffer);
|
||||
while (i.HasNext ())
|
||||
{
|
||||
PacketMetadata::Item item = i.Next ();
|
||||
if (item.isFragment)
|
||||
{
|
||||
switch (item.type) {
|
||||
case PacketMetadata::Item::PAYLOAD:
|
||||
os << "Payload";
|
||||
break;
|
||||
case PacketMetadata::Item::HEADER:
|
||||
case PacketMetadata::Item::TRAILER:
|
||||
os << item.tid.GetName ();
|
||||
break;
|
||||
}
|
||||
os << " Fragment [" << item.currentTrimedFromStart<<":"
|
||||
<< (item.currentTrimedFromStart + item.currentSize) << "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (item.type) {
|
||||
case PacketMetadata::Item::PAYLOAD:
|
||||
os << "Payload (size=" << item.currentSize << ")";
|
||||
break;
|
||||
case PacketMetadata::Item::HEADER:
|
||||
case PacketMetadata::Item::TRAILER:
|
||||
os << item.tid.GetName () << "(";
|
||||
{
|
||||
NS_ASSERT (item.tid.HasConstructor ());
|
||||
Callback<ObjectBase *> constructor = item.tid.GetConstructor ();
|
||||
NS_ASSERT (constructor.IsNull ());
|
||||
ObjectBase *instance = constructor ();
|
||||
NS_ASSERT (instance != 0);
|
||||
Chunk *chunk = dynamic_cast<Chunk *> (instance);
|
||||
NS_ASSERT (chunk != 0);
|
||||
chunk->Deserialize (item.current);
|
||||
for (uint32_t j = 0; j < item.tid.GetAttributeListN (); j++)
|
||||
{
|
||||
std::string attrName = item.tid.GetAttributeName (j);
|
||||
std::string value;
|
||||
bool ok = chunk->GetAttribute (attrName, value);
|
||||
NS_ASSERT (ok);
|
||||
os << attrName << "=" << value;
|
||||
if ((j + 1) < item.tid.GetAttributeListN ())
|
||||
{
|
||||
os << ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
os << ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i.HasNext ())
|
||||
{
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Packet::Print (std::ostream &os, const PacketPrinter &printer) const
|
||||
PacketMetadata::ItemIterator
|
||||
Packet::BeginItem (void) const
|
||||
{
|
||||
m_metadata.Print (os, m_buffer, printer);
|
||||
return m_metadata.BeginItem (m_buffer);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,12 +31,9 @@
|
||||
#include "ns3/callback.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/object-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class PacketPrinter;
|
||||
|
||||
/**
|
||||
* \brief network packets
|
||||
*
|
||||
@@ -74,7 +71,8 @@ class PacketPrinter;
|
||||
* The performance aspects of the Packet API are discussed in
|
||||
* \ref packetperf
|
||||
*/
|
||||
class Packet : public ObjectBase {
|
||||
class Packet
|
||||
{
|
||||
public:
|
||||
void Ref (void) const;
|
||||
void Unref (void) const;
|
||||
@@ -128,8 +126,7 @@ public:
|
||||
*
|
||||
* \param header a reference to the header to add to this packet.
|
||||
*/
|
||||
template <typename T>
|
||||
void AddHeader (T const &header);
|
||||
void AddHeader (const Header & header);
|
||||
/**
|
||||
* Deserialize and remove the header from the internal buffer.
|
||||
* This method invokes Deserialize.
|
||||
@@ -137,8 +134,7 @@ public:
|
||||
* \param header a reference to the header to remove from the internal buffer.
|
||||
* \returns the number of bytes removed from the packet.
|
||||
*/
|
||||
template <typename T>
|
||||
uint32_t RemoveHeader (T &header);
|
||||
uint32_t RemoveHeader (Header &header);
|
||||
/**
|
||||
* Add trailer to this packet. This method invokes the
|
||||
* GetSerializedSize and Serialize
|
||||
@@ -147,8 +143,7 @@ public:
|
||||
*
|
||||
* \param trailer a reference to the trailer to add to this packet.
|
||||
*/
|
||||
template <typename T>
|
||||
void AddTrailer (T const &trailer);
|
||||
void AddTrailer (const Trailer &trailer);
|
||||
/**
|
||||
* Remove a deserialized trailer from the internal buffer.
|
||||
* This method invokes the Deserialize method.
|
||||
@@ -156,8 +151,7 @@ public:
|
||||
* \param trailer a reference to the trailer to remove from the internal buffer.
|
||||
* \returns the number of bytes removed from the end of the packet.
|
||||
*/
|
||||
template <typename T>
|
||||
uint32_t RemoveTrailer (T &trailer);
|
||||
uint32_t RemoveTrailer (Trailer &trailer);
|
||||
/**
|
||||
* \param tag a pointer to the tag to attach to this packet.
|
||||
*
|
||||
@@ -287,20 +281,8 @@ public:
|
||||
* Trailer::DoPrint methods.
|
||||
*/
|
||||
void Print (std::ostream &os) const;
|
||||
/**
|
||||
* \param os output stream in which the data should be printed.
|
||||
* \param printer the output formatter to use to print
|
||||
* the content of this packet.
|
||||
*
|
||||
* Iterate over the headers and trailers present in this packet,
|
||||
* either in the "forward" (first header to last trailer) or in
|
||||
* the "backward" (last trailer to first header) direction, as
|
||||
* specified by the PacketPrinter::PrintForward or the
|
||||
* PacketPrinter::PrintBackward methods. For each header, trailer,
|
||||
* or fragment of a header or a trailer, invoke the user-specified
|
||||
* print callback stored in the specified PacketPrinter.
|
||||
*/
|
||||
void Print (std::ostream &os, const PacketPrinter &printer) const;
|
||||
|
||||
PacketMetadata::ItemIterator BeginItem (void) const;
|
||||
|
||||
/**
|
||||
* By default, packets do not keep around enough metadata to
|
||||
@@ -408,61 +390,6 @@ std::ostream& operator<< (std::ostream& os, const Packet &packet);
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
Packet::AddHeader (T const &header)
|
||||
{
|
||||
const Header *testHeader;
|
||||
// if the following assignment fails, it is because the
|
||||
// input to this function is not a subclass of the Header class
|
||||
testHeader = &header;
|
||||
uint32_t size = header.GetSerializedSize ();
|
||||
m_buffer.AddAtStart (size);
|
||||
header.Serialize (m_buffer.Begin ());
|
||||
m_metadata.AddHeader (header, size);
|
||||
}
|
||||
template <typename T>
|
||||
uint32_t
|
||||
Packet::RemoveHeader (T &header)
|
||||
{
|
||||
Header *testHeader;
|
||||
// if the following assignment fails, it is because the
|
||||
// input to this function is not a subclass of the Header class
|
||||
testHeader = &header;
|
||||
uint32_t deserialized = header.Deserialize (m_buffer.Begin ());
|
||||
m_buffer.RemoveAtStart (deserialized);
|
||||
m_metadata.RemoveHeader (header, deserialized);
|
||||
return deserialized;
|
||||
}
|
||||
template <typename T>
|
||||
void
|
||||
Packet::AddTrailer (T const &trailer)
|
||||
{
|
||||
const Trailer *testTrailer;
|
||||
// if the following assignment fails, it is because the
|
||||
// input to this function is not a subclass of the Trailer class
|
||||
testTrailer = &trailer;
|
||||
uint32_t size = trailer.GetSerializedSize ();
|
||||
m_buffer.AddAtEnd (size);
|
||||
Buffer::Iterator end = m_buffer.End ();
|
||||
trailer.Serialize (end);
|
||||
m_metadata.AddTrailer (trailer, size);
|
||||
}
|
||||
template <typename T>
|
||||
uint32_t
|
||||
Packet::RemoveTrailer (T &trailer)
|
||||
{
|
||||
Trailer *testTrailer;
|
||||
// if the following assignment fails, it is because the
|
||||
// input to this function is not a subclass of the Trailer class
|
||||
testTrailer = &trailer;
|
||||
uint32_t deserialized = trailer.Deserialize (m_buffer.End ());
|
||||
m_buffer.RemoveAtEnd (deserialized);
|
||||
m_metadata.RemoveTrailer (trailer, deserialized);
|
||||
return deserialized;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void Packet::AddTag (T const& tag) const
|
||||
{
|
||||
|
||||
25
src/common/trailer.cc
Normal file
25
src/common/trailer.cc
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "trailer.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (Trailer);
|
||||
|
||||
Trailer::~Trailer ()
|
||||
{}
|
||||
|
||||
TypeId
|
||||
Trailer::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Trailer")
|
||||
.SetParent<Chunk> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream &os, const Trailer &trailer)
|
||||
{
|
||||
trailer.Print (os);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
@@ -22,28 +22,10 @@
|
||||
#ifndef TRAILER_H
|
||||
#define TRAILER_H
|
||||
|
||||
#include "chunk-registry.h"
|
||||
#include "chunk.h"
|
||||
#include "buffer.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* \relates ns3::Trailer
|
||||
* \brief this macro should be instantiated exactly once for each
|
||||
* new type of Trailer
|
||||
*
|
||||
* This macro will ensure that your new Trailer type is registered
|
||||
* within the packet trailer registry. In most cases, this macro
|
||||
* is not really needed but, for safety, please, use it all the
|
||||
* time.
|
||||
*
|
||||
* Note: This macro is _absolutely_ needed if you try to run a
|
||||
* distributed simulation.
|
||||
*/
|
||||
#define NS_TRAILER_ENSURE_REGISTERED(x) \
|
||||
static class thisisaveryverylongclassname ##x \
|
||||
{ \
|
||||
public: \
|
||||
thisisaveryverylongclassname ##x () \
|
||||
{ uint32_t uid; uid = x::GetUid ();} \
|
||||
} g_thisisanotherveryveryverylongname ##x;
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -55,61 +37,63 @@ namespace ns3 {
|
||||
* implement the following public methods:
|
||||
* - a default constructor: is used by the internal implementation
|
||||
* if the Packet class.
|
||||
* - a static method named GetUid: is used to uniquely identify
|
||||
* the type of each trailer. This method shall return a unique
|
||||
* integer allocated with Trailer::AllocateUid.
|
||||
* - a method named Serialize: is used by Packet::AddTrailer to
|
||||
* store a trailer into the byte buffer of a packet.
|
||||
* The input iterator points to the end of the byte buffer in
|
||||
* which the trailer should write its data: the user is thus
|
||||
* required to call Buffer::Iterator::Prev prior to writing
|
||||
* any data in the buffer. The data written is expected to
|
||||
* match bit-for-bit the representation of this trailer in a
|
||||
* real network.
|
||||
* - a method named GetSerializedSize: is used by Packet::AddTrailer
|
||||
* to store a trailer into the byte buffer of a packet. This method
|
||||
* should return the number of bytes which are needed to store
|
||||
* the full trailer data by Serialize.
|
||||
* - a method named Deserialize: is used by Packet::RemoveTrailer to
|
||||
* re-create a trailer from the byte buffer of a packet. The input
|
||||
* iterator points to the end of the byte buffer from which
|
||||
* the trailer should read its data: the user is thus required to
|
||||
* call Buffer::Iterator::Prev prior to reading any data from the
|
||||
* buffer. The data read is expected to match bit-for-bit the
|
||||
* representation of this trailer in real networks. This method
|
||||
* shall return an integer which identifies the number of bytes read.
|
||||
* - a method named Print: is used by Packet::Print to print the
|
||||
* content of a trailer as ascii data to a c++ output stream.
|
||||
* Although the trailer is free to format its output as it
|
||||
* wishes, it is recommended to follow a few rules to integrate
|
||||
* with the packet pretty printer: start with flags, small field
|
||||
* values located between a pair of parens. Values should be separated
|
||||
* by whitespace. Follow the parens with the important fields,
|
||||
* separated by whitespace.
|
||||
* i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
|
||||
* - a method named GetName: is used by Packet::Print to print
|
||||
* trailer fragments. This method should return a user-readable
|
||||
* single word as all capitalized letters.
|
||||
*
|
||||
*/
|
||||
class Trailer
|
||||
class Trailer : public Chunk
|
||||
{
|
||||
protected:
|
||||
template <typename T>
|
||||
static uint32_t AllocateUid (std::string uidString);
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
virtual ~Trailer ();
|
||||
/**
|
||||
* \returns the expected size of the trailer.
|
||||
*
|
||||
* This method is used by Packet::AddTrailer
|
||||
* to store a trailer into the byte buffer of a packet. This method
|
||||
* should return the number of bytes which are needed to store
|
||||
* the full trailer data by Serialize.
|
||||
*/
|
||||
virtual uint32_t GetSerializedSize (void) const = 0;
|
||||
/**
|
||||
* \param start an iterator which points to where the trailer
|
||||
* should be written.
|
||||
*
|
||||
* This method is used by Packet::AddTrailer to
|
||||
* store a header into the byte buffer of a packet.
|
||||
* The data written is expected to match bit-for-bit the
|
||||
* representation of this trailer in real networks.
|
||||
* The input iterator points to the end of the area where the
|
||||
* data shall be written. This method is thus expected to call
|
||||
* Buffer::Iterator::Prev prior to actually writing any data.
|
||||
*/
|
||||
virtual void Serialize (Buffer::Iterator start) const = 0;
|
||||
/**
|
||||
* \param start an iterator which points to where the trailer
|
||||
* should be read.
|
||||
* \returns the number of bytes read.
|
||||
*
|
||||
* This method is used by Packet::RemoveTrailer to
|
||||
* re-create a trailer from the byte buffer of a packet.
|
||||
* The data read is expected to match bit-for-bit the
|
||||
* representation of this trailer in real networks.
|
||||
* The input iterator points to the end of the area where the
|
||||
* data shall be written. This method is thus expected to call
|
||||
* Buffer::Iterator::Prev prio to actually reading any data.
|
||||
*/
|
||||
virtual uint32_t Deserialize (Buffer::Iterator end) = 0;
|
||||
/**
|
||||
* This method is used by Packet::Print to print the
|
||||
* content of a trailer as ascii data to a c++ output stream.
|
||||
* Although the trailer is free to format its output as it
|
||||
* wishes, it is recommended to follow a few rules to integrate
|
||||
* with the packet pretty printer: start with flags, small field
|
||||
* values located between a pair of parens. Values should be separated
|
||||
* by whitespace. Follow the parens with the important fields,
|
||||
* separated by whitespace.
|
||||
* i.e.: (field1 val1 field2 val2 field3 val3) field4 val4 field5 val5
|
||||
*/
|
||||
virtual void Print (std::ostream &os) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
template <typename T>
|
||||
uint32_t
|
||||
Trailer::AllocateUid (std::string uidString)
|
||||
{
|
||||
return ChunkRegistry::RegisterTrailer<T> (uidString);
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream &os, const Trailer &trailer);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@ def build(bld):
|
||||
common = bld.create_ns3_module('common', ['core', 'simulator'])
|
||||
common.source = [
|
||||
'buffer.cc',
|
||||
'chunk-registry.cc',
|
||||
'packet-printer.cc',
|
||||
'packet-metadata.cc',
|
||||
'packet-metadata-test.cc',
|
||||
'packet.cc',
|
||||
'tags.cc',
|
||||
'tag-registry.cc',
|
||||
'chunk.cc',
|
||||
'header.cc',
|
||||
'trailer.cc',
|
||||
'pcap-writer.cc',
|
||||
'data-rate.cc',
|
||||
'error-model.cc',
|
||||
@@ -20,14 +21,13 @@ def build(bld):
|
||||
headers.module = 'common'
|
||||
headers.source = [
|
||||
'buffer.h',
|
||||
'chunk-registry.h',
|
||||
'chunk.h',
|
||||
'header.h',
|
||||
'trailer.h',
|
||||
'tags.h',
|
||||
'tag-registry.h',
|
||||
'tag.h',
|
||||
'packet.h',
|
||||
'packet-printer.h',
|
||||
'packet-metadata.h',
|
||||
'pcap-writer.h',
|
||||
'data-rate.h',
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#define ATTRIBUTE_HELPER_H
|
||||
|
||||
#include "attribute.h"
|
||||
#include "object-base.h"
|
||||
#include "attribute-accessor-helper.h"
|
||||
#include <sstream>
|
||||
#include "fatal-error.h"
|
||||
@@ -57,8 +56,6 @@ MakeSimpleAttributeChecker (std::string name)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \defgroup AttributeHelper
|
||||
*
|
||||
@@ -281,5 +278,4 @@ MakeSimpleAttributeChecker (std::string name)
|
||||
ATTRIBUTE_VALUE_IMPLEMENT (type);
|
||||
|
||||
|
||||
|
||||
#endif /* ATTRIBUTE_HELPER_H */
|
||||
|
||||
237
src/core/attribute-list.cc
Normal file
237
src/core/attribute-list.cc
Normal file
@@ -0,0 +1,237 @@
|
||||
#include "attribute-list.h"
|
||||
#include "string.h"
|
||||
#include "singleton.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/*********************************************************************
|
||||
* The AttributeList container implementation
|
||||
*********************************************************************/
|
||||
|
||||
AttributeList::AttributeList ()
|
||||
{}
|
||||
|
||||
AttributeList::AttributeList (const AttributeList &o)
|
||||
{
|
||||
for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
|
||||
{
|
||||
struct Attr attr;
|
||||
attr.checker = i->checker;
|
||||
attr.value = i->value.Copy ();
|
||||
m_attributes.push_back (attr);
|
||||
}
|
||||
}
|
||||
AttributeList &
|
||||
AttributeList::operator = (const AttributeList &o)
|
||||
{
|
||||
Reset ();
|
||||
for (Attrs::const_iterator i = o.m_attributes.begin (); i != o.m_attributes.end (); i++)
|
||||
{
|
||||
struct Attr attr;
|
||||
attr.checker = i->checker;
|
||||
attr.value = i->value.Copy ();
|
||||
m_attributes.push_back (attr);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
AttributeList::~AttributeList ()
|
||||
{
|
||||
Reset ();
|
||||
}
|
||||
|
||||
void
|
||||
AttributeList::Set (std::string name, Attribute value)
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
bool ok = TypeId::LookupAttributeByFullName (name, &info);
|
||||
if (!ok)
|
||||
{
|
||||
NS_FATAL_ERROR ("Could not find attribute "<<name);
|
||||
}
|
||||
ok = DoSet (&info, value);
|
||||
if (!ok)
|
||||
{
|
||||
NS_FATAL_ERROR ("Could not set value for attribute "<<name);
|
||||
}
|
||||
}
|
||||
bool
|
||||
AttributeList::SetFailSafe (std::string name, Attribute value)
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
bool ok = TypeId::LookupAttributeByFullName (name, &info);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ok = DoSet (&info, value);
|
||||
return ok;
|
||||
}
|
||||
void
|
||||
AttributeList::SetWithTid (TypeId tid, std::string name, Attribute value)
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
bool ok = tid.LookupAttributeByName (name, &info);
|
||||
if (!ok)
|
||||
{
|
||||
NS_FATAL_ERROR ("Could not find attribute "<<tid.GetName ()<<"::"<<name);
|
||||
}
|
||||
ok = DoSet (&info, value);
|
||||
if (!ok)
|
||||
{
|
||||
NS_FATAL_ERROR ("Could not set value for attribute "<<tid.GetName ()<<"::"<<name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AttributeList::DoSetOne (Ptr<const AttributeChecker> checker, Attribute value)
|
||||
{
|
||||
// get rid of any previous value stored in this
|
||||
// vector of values.
|
||||
for (Attrs::iterator k = m_attributes.begin (); k != m_attributes.end (); k++)
|
||||
{
|
||||
if (k->checker == checker)
|
||||
{
|
||||
m_attributes.erase (k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// store the new value.
|
||||
struct Attr attr;
|
||||
attr.checker = checker;
|
||||
attr.value = value.Copy ();
|
||||
m_attributes.push_back (attr);
|
||||
}
|
||||
bool
|
||||
AttributeList::DoSet (struct TypeId::AttributeInfo *info, Attribute value)
|
||||
{
|
||||
if (info->checker == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ok = info->checker->Check (value);
|
||||
if (!ok)
|
||||
{
|
||||
// attempt to convert to string.
|
||||
const StringValue *str = value.DynCast<const StringValue *> ();
|
||||
if (str == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// attempt to convert back to value.
|
||||
Attribute v = info->checker->Create ();
|
||||
ok = v.DeserializeFromString (str->Get ().Get (), info->checker);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ok = info->checker->Check (v);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
value = v;
|
||||
}
|
||||
DoSetOne (info->checker, value);
|
||||
return true;
|
||||
}
|
||||
void
|
||||
AttributeList::Reset (void)
|
||||
{
|
||||
m_attributes.clear ();
|
||||
}
|
||||
AttributeList *
|
||||
AttributeList::GetGlobal (void)
|
||||
{
|
||||
return Singleton<AttributeList>::Get ();
|
||||
}
|
||||
|
||||
std::string
|
||||
AttributeList::LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const
|
||||
{
|
||||
for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
|
||||
{
|
||||
TypeId tid = TypeId::GetRegistered (i);
|
||||
for (uint32_t j = 0; j < tid.GetAttributeListN (); j++)
|
||||
{
|
||||
if (checker == tid.GetAttributeChecker (j))
|
||||
{
|
||||
return tid.GetAttributeFullName (j);
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_FATAL_ERROR ("Could not find requested Accessor.");
|
||||
// quiet compiler.
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string
|
||||
AttributeList::SerializeToString (void) const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
for (Attrs::const_iterator i = m_attributes.begin (); i != m_attributes.end (); i++)
|
||||
{
|
||||
std::string name = LookupAttributeFullNameByChecker (i->checker);
|
||||
oss << name << "=" << i->value.SerializeToString (i->checker);
|
||||
if (i != m_attributes.end ())
|
||||
{
|
||||
oss << "|";
|
||||
}
|
||||
}
|
||||
return oss.str ();
|
||||
}
|
||||
bool
|
||||
AttributeList::DeserializeFromString (std::string str)
|
||||
{
|
||||
Reset ();
|
||||
|
||||
std::string::size_type cur;
|
||||
cur = 0;
|
||||
do {
|
||||
std::string::size_type equal = str.find ("=", cur);
|
||||
if (equal == std::string::npos)
|
||||
{
|
||||
// XXX: invalid attribute.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = str.substr (cur, equal-cur);
|
||||
struct TypeId::AttributeInfo info;
|
||||
if (!TypeId::LookupAttributeByFullName (name, &info))
|
||||
{
|
||||
// XXX invalid name.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string::size_type next = str.find ("|", cur);
|
||||
std::string value;
|
||||
if (next == std::string::npos)
|
||||
{
|
||||
value = str.substr (equal+1, str.size () - (equal+1));
|
||||
cur = str.size ();
|
||||
}
|
||||
else
|
||||
{
|
||||
value = str.substr (equal+1, next - (equal+1));
|
||||
cur++;
|
||||
}
|
||||
Attribute val = info.checker->Create ();
|
||||
bool ok = val.DeserializeFromString (value, info.checker);
|
||||
if (!ok)
|
||||
{
|
||||
// XXX invalid value
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
DoSetOne (info.checker, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (cur != str.size ());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
93
src/core/attribute-list.h
Normal file
93
src/core/attribute-list.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef ATTRIBUTE_LIST_H
|
||||
#define ATTRIBUTE_LIST_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "attribute.h"
|
||||
#include "type-id.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief a container of attributes to be used during object's construction
|
||||
* and in ns3::Object::Set.
|
||||
*
|
||||
*/
|
||||
class AttributeList
|
||||
{
|
||||
public:
|
||||
AttributeList ();
|
||||
AttributeList (const AttributeList &o);
|
||||
AttributeList &operator = (const AttributeList &o);
|
||||
~AttributeList ();
|
||||
/**
|
||||
* \param name the full name of the attribute to set
|
||||
* \param value the value to set
|
||||
*
|
||||
* This method checks that a attribute with the requested
|
||||
* name exists and that the value specified is an acceptable
|
||||
* value of that attribute. If any of these checks fails,
|
||||
* the program terminates with a message.
|
||||
*/
|
||||
void Set (std::string name, Attribute value);
|
||||
/**
|
||||
* \param name the full name of the attribute to set
|
||||
* \param value the value to set
|
||||
* \returns true if the requested attribute exists and could be
|
||||
* stored, false otherwise.
|
||||
*/
|
||||
bool SetFailSafe (std::string name, Attribute value);
|
||||
/**
|
||||
* \param tid the TypeId associated to this attribute
|
||||
* \param name the name (not full!) of the attribute
|
||||
* \param value the value to set
|
||||
*
|
||||
* This method checks that a attribute with the requested
|
||||
* name exists and that the value specified is an acceptable
|
||||
* value of that attribute. If any of these checks fails,
|
||||
* the program terminates with a message.
|
||||
*/
|
||||
void SetWithTid (TypeId tid, std::string name, Attribute value);
|
||||
|
||||
/**
|
||||
* Clear the content of this instance.
|
||||
*/
|
||||
void Reset (void);
|
||||
|
||||
/**
|
||||
* \returns the global attribute container
|
||||
*
|
||||
* The global attribute container can be used to specify
|
||||
* a set of attribute values without having to re-specify
|
||||
* them for each object when it is created. This container
|
||||
* is checked only during object construction and
|
||||
* it is always checked last, after any per-object
|
||||
* container is checked.
|
||||
*/
|
||||
static AttributeList *GetGlobal (void);
|
||||
|
||||
// XXX: untested.
|
||||
std::string SerializeToString (void) const;
|
||||
bool DeserializeFromString (std::string value);
|
||||
private:
|
||||
friend class ObjectBase;
|
||||
struct Attr {
|
||||
Ptr<const AttributeChecker> checker;
|
||||
Attribute value;
|
||||
};
|
||||
typedef std::vector<struct Attr> Attrs;
|
||||
typedef Attrs::iterator Iterator;
|
||||
typedef Attrs::const_iterator CIterator;
|
||||
|
||||
|
||||
|
||||
bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
|
||||
void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
|
||||
std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
|
||||
|
||||
Attrs m_attributes;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* ATTRIBUTE_LIST_H */
|
||||
@@ -23,13 +23,13 @@
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include "ptr.h"
|
||||
#include "object-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class AttributeAccessor;
|
||||
class AttributeChecker;
|
||||
class Attribute;
|
||||
class ObjectBase;
|
||||
|
||||
/**
|
||||
* \brief Hold a value for an Attribute.
|
||||
@@ -159,7 +159,7 @@ private:
|
||||
* of this base class are usually provided through the MakeAccessorHelper
|
||||
* template functions, hidden behind an ATTRIBUTE_HELPER_* macro.
|
||||
*/
|
||||
class AttributeAccessor : public ObjectBase
|
||||
class AttributeAccessor
|
||||
{
|
||||
public:
|
||||
AttributeAccessor ();
|
||||
@@ -202,7 +202,7 @@ private:
|
||||
* Most subclasses of this base class are implemented by the
|
||||
* ATTRIBUTE_HELPER_* macros.
|
||||
*/
|
||||
class AttributeChecker : public ObjectBase
|
||||
class AttributeChecker
|
||||
{
|
||||
public:
|
||||
AttributeChecker ();
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "fatal-error.h"
|
||||
#include "empty.h"
|
||||
#include "type-traits.h"
|
||||
#include "object-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -71,7 +70,7 @@ struct CallbackTraits<T *>
|
||||
}
|
||||
};
|
||||
|
||||
class CallbackImplBase : public ObjectBase
|
||||
class CallbackImplBase
|
||||
{
|
||||
public:
|
||||
CallbackImplBase ()
|
||||
|
||||
@@ -205,7 +205,7 @@ Resolver::DoResolve (std::string path, Ptr<Object> root)
|
||||
else
|
||||
{
|
||||
// this is a normal attribute.
|
||||
TypeId tid = root->GetRealTypeId ();
|
||||
TypeId tid = root->GetInstanceTypeId ();
|
||||
struct TypeId::AttributeInfo info;
|
||||
if (!tid.LookupAttributeByName (item, &info))
|
||||
{
|
||||
|
||||
@@ -1,3 +1,254 @@
|
||||
#include "object-base.h"
|
||||
#include "log.h"
|
||||
#include "trace-source-accessor.h"
|
||||
#include "string.h"
|
||||
|
||||
ns3::ObjectBase::~ObjectBase () {}
|
||||
NS_LOG_COMPONENT_DEFINE ("ObjectBase");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
static TypeId
|
||||
GetObjectIid (void)
|
||||
{
|
||||
TypeId tid = TypeId ("ns3::ObjectBase");
|
||||
tid.SetParent (tid);
|
||||
return tid;
|
||||
}
|
||||
|
||||
TypeId
|
||||
ObjectBase::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = GetObjectIid ();
|
||||
return tid;
|
||||
}
|
||||
|
||||
ObjectBase::~ObjectBase ()
|
||||
{}
|
||||
|
||||
void
|
||||
ObjectBase::NotifyConstructionCompleted (void)
|
||||
{}
|
||||
|
||||
void
|
||||
ObjectBase::ConstructSelf (const AttributeList &attributes)
|
||||
{
|
||||
// loop over the inheritance tree back to the Object base class.
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
do {
|
||||
// loop over all attributes in object type
|
||||
NS_LOG_DEBUG ("construct tid="<<tid.GetName ()<<", params="<<tid.GetAttributeListN ());
|
||||
for (uint32_t i = 0; i < tid.GetAttributeListN (); i++)
|
||||
{
|
||||
Ptr<const AttributeAccessor> paramSpec = tid.GetAttributeAccessor (i);
|
||||
Attribute initial = tid.GetAttributeInitialValue (i);
|
||||
Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (i);
|
||||
NS_LOG_DEBUG ("try to construct \""<< tid.GetName ()<<"::"<<
|
||||
tid.GetAttributeName (i)<<"\"");
|
||||
if (!(tid.GetAttributeFlags (i) & TypeId::ATTR_CONSTRUCT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
// is this attribute stored in this AttributeList instance ?
|
||||
for (AttributeList::Attrs::const_iterator j = attributes.m_attributes.begin ();
|
||||
j != attributes.m_attributes.end (); j++)
|
||||
{
|
||||
if (j->checker == checker)
|
||||
{
|
||||
// We have a matching attribute value.
|
||||
DoSet (paramSpec, initial, checker, j->value);
|
||||
NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
|
||||
tid.GetAttributeName (i)<<"\"");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// is this attribute stored in the global instance instance ?
|
||||
for (AttributeList::Attrs::const_iterator j = AttributeList::GetGlobal ()->m_attributes.begin ();
|
||||
j != AttributeList::GetGlobal ()->m_attributes.end (); j++)
|
||||
{
|
||||
if (j->checker == checker)
|
||||
{
|
||||
// We have a matching attribute value.
|
||||
DoSet (paramSpec, initial, checker, j->value);
|
||||
NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
|
||||
tid.GetAttributeName (i)<<"\" from global");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
// No matching attribute value so we set the default value.
|
||||
paramSpec->Set (this, initial);
|
||||
NS_LOG_DEBUG ("construct \""<< tid.GetName ()<<"::"<<
|
||||
tid.GetAttributeName (i)<<"\" from initial value.");
|
||||
}
|
||||
}
|
||||
tid = tid.GetParent ();
|
||||
} while (tid != ObjectBase::GetTypeId ());
|
||||
NotifyConstructionCompleted ();
|
||||
}
|
||||
|
||||
bool
|
||||
ObjectBase::DoSet (Ptr<const AttributeAccessor> spec, Attribute initialValue,
|
||||
Ptr<const AttributeChecker> checker, Attribute value)
|
||||
{
|
||||
bool ok = checker->Check (value);
|
||||
if (!ok)
|
||||
{
|
||||
// attempt to convert to string
|
||||
const StringValue *str = value.DynCast<const StringValue *> ();
|
||||
if (str == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// attempt to convert back from string.
|
||||
Attribute v = checker->Create ();
|
||||
ok = v.DeserializeFromString (str->Get ().Get (), checker);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ok = checker->Check (v);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
value = v;
|
||||
}
|
||||
ok = spec->Set (this, value);
|
||||
return ok;
|
||||
}
|
||||
void
|
||||
ObjectBase::SetAttribute (std::string name, Attribute value)
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
if (!tid.LookupAttributeByName (name, &info))
|
||||
{
|
||||
NS_FATAL_ERROR ("Attribute name="<<name<<" does not exist for this object: tid="<<tid.GetName ());
|
||||
}
|
||||
if (!(info.flags & TypeId::ATTR_SET))
|
||||
{
|
||||
NS_FATAL_ERROR ("Attribute name="<<name<<" is not settable for this object: tid="<<tid.GetName ());
|
||||
}
|
||||
if (!DoSet (info.accessor, info.initialValue, info.checker, value))
|
||||
{
|
||||
NS_FATAL_ERROR ("Attribute name="<<name<<" could not be set for this object: tid="<<tid.GetName ());
|
||||
}
|
||||
}
|
||||
bool
|
||||
ObjectBase::SetAttributeFailSafe (std::string name, Attribute value)
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
if (!tid.LookupAttributeByName (name, &info))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(info.flags & TypeId::ATTR_SET))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return DoSet (info.accessor, info.initialValue, info.checker, value);
|
||||
}
|
||||
bool
|
||||
ObjectBase::GetAttribute (std::string name, std::string &value) const
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
if (!tid.LookupAttributeByName (name, &info))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!(info.flags & TypeId::ATTR_GET))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Attribute v = info.checker->Create ();
|
||||
bool ok = info.accessor->Get (this, v);
|
||||
if (ok)
|
||||
{
|
||||
value = v.SerializeToString (info.checker);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
Attribute
|
||||
ObjectBase::GetAttribute (std::string name) const
|
||||
{
|
||||
struct TypeId::AttributeInfo info;
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
if (!tid.LookupAttributeByName (name, &info))
|
||||
{
|
||||
return Attribute ();
|
||||
}
|
||||
if (!(info.flags & TypeId::ATTR_GET))
|
||||
{
|
||||
return Attribute ();
|
||||
}
|
||||
Attribute value = info.checker->Create ();
|
||||
bool ok = info.accessor->Get (this, value);
|
||||
if (!ok)
|
||||
{
|
||||
return Attribute ();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool
|
||||
ObjectBase::TraceConnectWithoutContext (std::string name, const CallbackBase &cb)
|
||||
{
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
|
||||
if (accessor == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ok = accessor->ConnectWithoutContext (this, cb);
|
||||
return ok;
|
||||
}
|
||||
bool
|
||||
ObjectBase::TraceConnectWithoutContext (std::string name, std::string context, const CallbackBase &cb)
|
||||
{
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
|
||||
if (accessor == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ok = accessor->Connect (this, context, cb);
|
||||
return ok;
|
||||
}
|
||||
bool
|
||||
ObjectBase::TraceDisconnectWithoutContext (std::string name, const CallbackBase &cb)
|
||||
{
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
|
||||
if (accessor == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ok = accessor->DisconnectWithoutContext (this, cb);
|
||||
return ok;
|
||||
}
|
||||
bool
|
||||
ObjectBase::TraceDisconnectWithoutContext (std::string name, std::string context, const CallbackBase &cb)
|
||||
{
|
||||
TypeId tid = GetInstanceTypeId ();
|
||||
Ptr<const TraceSourceAccessor> accessor = tid.LookupTraceSourceByName (name);
|
||||
if (accessor == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool ok = accessor->Disconnect (this, context, cb);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
#ifndef OBJECT_BASE_H
|
||||
#define OBJECT_BASE_H
|
||||
|
||||
#include "type-id.h"
|
||||
#include "callback.h"
|
||||
#include "attribute-list.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* This macro should be invoked once for every class which
|
||||
* defines a new GetTypeId method.
|
||||
*/
|
||||
#define NS_OBJECT_ENSURE_REGISTERED(type) \
|
||||
static struct X##type##RegistrationClass \
|
||||
{ \
|
||||
X##type##RegistrationClass () { \
|
||||
ns3::TypeId tid = type::GetTypeId (); \
|
||||
tid.GetParent (); \
|
||||
} \
|
||||
} x_##type##RegistrationVariable
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
@@ -12,7 +30,61 @@ namespace ns3 {
|
||||
class ObjectBase
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
virtual ~ObjectBase ();
|
||||
virtual TypeId GetInstanceTypeId (void) const = 0;
|
||||
|
||||
/**
|
||||
* \param name the name of the attribute to set
|
||||
* \param value the name of the attribute to set
|
||||
*
|
||||
* Set a single attribute. This cannot fail: if the input is invalid,
|
||||
* it will crash immediately.
|
||||
*/
|
||||
void SetAttribute (std::string name, Attribute value);
|
||||
/**
|
||||
* \param name the name of the attribute to set
|
||||
* \param value the name of the attribute to set
|
||||
* \returns true if the requested attribute exists and could be set,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool SetAttributeFailSafe (std::string name, Attribute value);
|
||||
/**
|
||||
* \param name the name of the attribute to read
|
||||
* \param value a reference to the string where the value of the
|
||||
* attribute should be stored.
|
||||
* \returns true if the requested attribute was found, false otherwise.
|
||||
*/
|
||||
bool GetAttribute (std::string name, std::string &value) const;
|
||||
/**
|
||||
* \param name the name of the attribute to read
|
||||
* \returns the attribute read.
|
||||
*
|
||||
* If the input attribute name does not exist, this method crashes.
|
||||
*/
|
||||
Attribute GetAttribute (std::string name) const;
|
||||
|
||||
bool TraceConnectWithoutContext (std::string name, const CallbackBase &cb);
|
||||
bool TraceConnectWithoutContext (std::string name, std::string context, const CallbackBase &cb);
|
||||
bool TraceDisconnectWithoutContext (std::string name, const CallbackBase &cb);
|
||||
bool TraceDisconnectWithoutContext (std::string name, std::string context, const CallbackBase &cb);
|
||||
|
||||
protected:
|
||||
virtual void NotifyConstructionCompleted (void);
|
||||
/**
|
||||
* \param attributes the attribute values used to initialize
|
||||
* the member variables of this object's instance.
|
||||
*
|
||||
* Invoked from subclasses to initialize all of their
|
||||
* attribute members.
|
||||
*/
|
||||
void ConstructSelf (const AttributeList &attributes);
|
||||
|
||||
private:
|
||||
bool DoSet (Ptr<const AttributeAccessor> spec, Attribute intialValue,
|
||||
Ptr<const AttributeChecker> checker, Attribute value);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -59,7 +59,12 @@ ObjectFactory::GetTypeId (void) const
|
||||
Ptr<Object>
|
||||
ObjectFactory::Create (void) const
|
||||
{
|
||||
Ptr<Object> object = m_tid.CreateObject (m_parameters);
|
||||
Callback<ObjectBase *> cb = m_tid.GetConstructor ();
|
||||
ObjectBase *base = cb ();
|
||||
Object *derived = dynamic_cast<Object *> (base);
|
||||
derived->SetTypeId (m_tid);
|
||||
derived->Construct (m_parameters);
|
||||
Ptr<Object> object = Ptr<Object> (derived, false);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
1163
src/core/object.cc
1163
src/core/object.cc
File diff suppressed because it is too large
Load Diff
@@ -25,393 +25,19 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ptr.h"
|
||||
#include "callback.h"
|
||||
#include "attribute.h"
|
||||
#include "object-base.h"
|
||||
#include "attribute-helper.h"
|
||||
|
||||
/**
|
||||
* This macro should be invoked once for every class which
|
||||
* defines a new GetTypeId method.
|
||||
*/
|
||||
#define NS_OBJECT_ENSURE_REGISTERED(type) \
|
||||
static struct X##type##RegistrationClass \
|
||||
{ \
|
||||
X##type##RegistrationClass () { \
|
||||
ns3::TypeId tid = type::GetTypeId (); \
|
||||
tid.GetParent (); \
|
||||
} \
|
||||
} x_##type##RegistrationVariable
|
||||
#include "attribute-list.h"
|
||||
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class CallbackBase;
|
||||
class Object;
|
||||
class AttributeAccessor;
|
||||
class AttributeValue;
|
||||
class AttributeList;
|
||||
class TraceSourceAccessor;
|
||||
|
||||
/**
|
||||
* \brief a unique identifier for an interface.
|
||||
*
|
||||
* This class records a lot of meta-information about a
|
||||
* subclass of the Object base class:
|
||||
* - the base class of the subclass
|
||||
* - the set of accessible constructors in the subclass
|
||||
* - the set of 'attributes' accessible in the subclass
|
||||
*/
|
||||
class TypeId
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
/**
|
||||
* The attribute can be read
|
||||
*/
|
||||
ATTR_GET = 1<<0,
|
||||
/**
|
||||
* The attribute can be written
|
||||
*/
|
||||
ATTR_SET = 1<<1,
|
||||
/**
|
||||
* The attribute can be written at construction-time.
|
||||
*/
|
||||
ATTR_CONSTRUCT = 1<<2,
|
||||
/**
|
||||
* The attribute can be read, and written at any time.
|
||||
*/
|
||||
ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \param name the name of the requested TypeId
|
||||
* \returns the unique id associated with the requested
|
||||
* name.
|
||||
*
|
||||
* This method cannot fail: it will crash if the input
|
||||
* name is not a valid TypeId name.
|
||||
*/
|
||||
static TypeId LookupByName (std::string name);
|
||||
/**
|
||||
* \param name the name of the requested TypeId
|
||||
* \param tid a pointer to the TypeId instance where the
|
||||
* result of this function should be stored.
|
||||
* \returns true if the requested name was found, false otherwise.
|
||||
*/
|
||||
static bool LookupByNameFailSafe (std::string name, TypeId *tid);
|
||||
|
||||
/**
|
||||
* \returns the number of TypeId instances registered.
|
||||
*/
|
||||
static uint32_t GetRegisteredN (void);
|
||||
/**
|
||||
* \param i index
|
||||
* \returns the TypeId instance whose index is i.
|
||||
*/
|
||||
static TypeId GetRegistered (uint32_t i);
|
||||
|
||||
/**
|
||||
* \param name the name of the interface to construct.
|
||||
*
|
||||
* No two instances can share the same name. The name is expected to be
|
||||
* the full c++ typename of associated c++ object.
|
||||
*/
|
||||
TypeId (const char * name);
|
||||
|
||||
/**
|
||||
* \returns the parent of this TypeId
|
||||
*
|
||||
* This method cannot fail. It will return itself
|
||||
* if this TypeId has no parent. i.e., it is at the top
|
||||
* of the TypeId hierarchy. Currently, this is the
|
||||
* case for the TypeId associated to the Object class
|
||||
* only.
|
||||
*/
|
||||
TypeId GetParent (void) const;
|
||||
|
||||
/**
|
||||
* \returns the name of the group associated to this TypeId.
|
||||
*/
|
||||
std::string GetGroupName (void) const;
|
||||
/**
|
||||
* \returns the fully-qualified C++ typename of this TypeId.
|
||||
*/
|
||||
std::string GetTypeName (void) const;
|
||||
|
||||
/**
|
||||
* \returns the name of this interface.
|
||||
*/
|
||||
std::string GetName (void) const;
|
||||
|
||||
/**
|
||||
* \returns true if this TypeId has a constructor
|
||||
*/
|
||||
bool HasConstructor (void) const;
|
||||
|
||||
/**
|
||||
* \returns the number of attributes associated to this TypeId
|
||||
*/
|
||||
uint32_t GetAttributeListN (void) const;
|
||||
/**
|
||||
* \param i index into attribute array
|
||||
* \returns the name associated to the attribute whose
|
||||
* index is i.
|
||||
*/
|
||||
std::string GetAttributeName (uint32_t i) const;
|
||||
std::string GetAttributeHelp (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into attribute array
|
||||
* \returns the full name associated to the attribute whose
|
||||
* index is i.
|
||||
*/
|
||||
std::string GetAttributeFullName (uint32_t i) const;
|
||||
|
||||
Attribute GetAttributeInitialValue (uint32_t i) const;
|
||||
uint32_t GetAttributeFlags (uint32_t i) const;
|
||||
Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
|
||||
|
||||
|
||||
uint32_t GetTraceSourceN (void) const;
|
||||
std::string GetTraceSourceName (uint32_t i) const;
|
||||
std::string GetTraceSourceHelp (uint32_t i) const;
|
||||
Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
|
||||
|
||||
Ptr<Object> CreateObject (const AttributeList &attributes) const;
|
||||
Ptr<Object> CreateObject (void) const;
|
||||
|
||||
bool MustHideFromDocumentation (void) const;
|
||||
|
||||
/**
|
||||
* \param tid the TypeId of the base class.
|
||||
* \return this TypeId instance.
|
||||
*
|
||||
* Record in this TypeId which TypeId is the TypeId
|
||||
* of the base class of the subclass.
|
||||
*/
|
||||
TypeId SetParent (TypeId tid);
|
||||
/**
|
||||
* \return this TypeId instance.
|
||||
*
|
||||
* Record in this TypeId which TypeId is the TypeId
|
||||
* of the base class of the subclass.
|
||||
*/
|
||||
template <typename T>
|
||||
TypeId SetParent (void);
|
||||
|
||||
/**
|
||||
* \param groupName the name of the group this TypeId belongs to.
|
||||
* \returns this TypeId instance.
|
||||
*
|
||||
* The group name is purely an advisory information used to
|
||||
* group together types according to a user-specific grouping
|
||||
* scheme.
|
||||
*/
|
||||
TypeId SetGroupName (std::string groupName);
|
||||
|
||||
/**
|
||||
* \param typeName the fully-qualified C++ typename of this TypeId.
|
||||
* \returns this TypeId instance.
|
||||
*/
|
||||
TypeId SetTypeName (std::string typeName);
|
||||
|
||||
/**
|
||||
* \returns this TypeId instance
|
||||
*
|
||||
* Record in this TypeId the fact that the default constructor
|
||||
* is accessible.
|
||||
*/
|
||||
template <typename T>
|
||||
TypeId AddConstructor (void);
|
||||
|
||||
/**
|
||||
* \param name the name of the new attribute
|
||||
* \param help some help text which describes the purpose of this
|
||||
* attribute.
|
||||
* \param initialValue the initial value for this attribute.
|
||||
* \param accessor an instance of the associated AttributeAccessor subclass.
|
||||
* \param checker an instance of the associated AttributeChecker subclass.
|
||||
* \returns this TypeId instance
|
||||
*
|
||||
* Record in this TypeId the fact that a new attribute exists.
|
||||
*/
|
||||
TypeId AddAttribute (std::string name,
|
||||
std::string help,
|
||||
Attribute initialValue,
|
||||
Ptr<const AttributeAccessor> accessor,
|
||||
Ptr<const AttributeChecker> checker);
|
||||
|
||||
/**
|
||||
* \param name the name of the new attribute
|
||||
* \param help some help text which describes the purpose of this
|
||||
* attribute
|
||||
* \param flags flags which describe how this attribute can be read and/or written.
|
||||
* \param initialValue the initial value for this attribute.
|
||||
* \param accessor an instance of the associated AttributeAccessor subclass.
|
||||
* \param checker an instance of the associated AttributeChecker subclass.
|
||||
* \returns this TypeId instance
|
||||
*
|
||||
* Record in this TypeId the fact that a new attribute exists.
|
||||
*/
|
||||
TypeId AddAttribute (std::string name,
|
||||
std::string help,
|
||||
uint32_t flags,
|
||||
Attribute initialValue,
|
||||
Ptr<const AttributeAccessor> accessor,
|
||||
Ptr<const AttributeChecker> checker);
|
||||
|
||||
/**
|
||||
* \param name the name of the new trace source
|
||||
* \param help some help text which describes the purpose of this
|
||||
* trace source.
|
||||
* \param accessor a pointer to a TraceSourceAccessor which can be
|
||||
* used to connect/disconnect sinks to this trace source.
|
||||
* \returns this TypeId instance.
|
||||
*/
|
||||
TypeId AddTraceSource (std::string name,
|
||||
std::string help,
|
||||
Ptr<const TraceSourceAccessor> accessor);
|
||||
|
||||
TypeId HideFromDocumentation (void);
|
||||
|
||||
/**
|
||||
* \brief store together a set of attribute properties.
|
||||
*/
|
||||
struct AttributeInfo {
|
||||
// The accessor associated to the attribute.
|
||||
Ptr<const AttributeAccessor> accessor;
|
||||
// The initial value associated to the attribute.
|
||||
Attribute initialValue;
|
||||
// The set of access control flags associated to the attribute.
|
||||
uint32_t flags;
|
||||
// The checker associated to the attribute.
|
||||
Ptr<const AttributeChecker> checker;
|
||||
};
|
||||
/**
|
||||
* \param name the name of the requested attribute
|
||||
* \param info a pointer to the TypeId::AttributeInfo data structure
|
||||
* where the result value of this method will be stored.
|
||||
* \returns true if the requested attribute could be found, false otherwise.
|
||||
*/
|
||||
bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
|
||||
|
||||
|
||||
// construct an invalid TypeId.
|
||||
TypeId ();
|
||||
~TypeId ();
|
||||
|
||||
ATTRIBUTE_HELPER_HEADER_1 (TypeId);
|
||||
private:
|
||||
friend class Object;
|
||||
friend class AttributeList;
|
||||
friend bool operator == (TypeId a, TypeId b);
|
||||
friend bool operator != (TypeId a, TypeId b);
|
||||
|
||||
|
||||
Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
|
||||
|
||||
/**
|
||||
* \param fullName the full name of the requested attribute
|
||||
* \param info a pointer to the TypeId::AttributeInfo data structure
|
||||
* where the result value of this method will be stored.
|
||||
* \returns the Accessor associated to the requested attribute
|
||||
*/
|
||||
static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
|
||||
|
||||
explicit TypeId (uint16_t tid);
|
||||
void DoAddConstructor (CallbackBase callback);
|
||||
CallbackBase LookupConstructor (void) const;
|
||||
Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
|
||||
|
||||
uint16_t m_tid;
|
||||
};
|
||||
|
||||
std::ostream & operator << (std::ostream &os, TypeId tid);
|
||||
std::istream & operator >> (std::istream &is, TypeId &tid);
|
||||
|
||||
ATTRIBUTE_HELPER_HEADER_2 (TypeId);
|
||||
|
||||
/**
|
||||
* \brief a container of attributes to be used during object's construction
|
||||
* and in ns3::Object::Set.
|
||||
*
|
||||
*/
|
||||
class AttributeList
|
||||
{
|
||||
public:
|
||||
AttributeList ();
|
||||
AttributeList (const AttributeList &o);
|
||||
AttributeList &operator = (const AttributeList &o);
|
||||
~AttributeList ();
|
||||
/**
|
||||
* \param name the full name of the attribute to set
|
||||
* \param value the value to set
|
||||
*
|
||||
* This method checks that a attribute with the requested
|
||||
* name exists and that the value specified is an acceptable
|
||||
* value of that attribute. If any of these checks fails,
|
||||
* the program terminates with a message.
|
||||
*/
|
||||
void Set (std::string name, Attribute value);
|
||||
/**
|
||||
* \param name the full name of the attribute to set
|
||||
* \param value the value to set
|
||||
* \returns true if the requested attribute exists and could be
|
||||
* stored, false otherwise.
|
||||
*/
|
||||
bool SetFailSafe (std::string name, Attribute value);
|
||||
/**
|
||||
* \param tid the TypeId associated to this attribute
|
||||
* \param name the name (not full!) of the attribute
|
||||
* \param value the value to set
|
||||
*
|
||||
* This method checks that a attribute with the requested
|
||||
* name exists and that the value specified is an acceptable
|
||||
* value of that attribute. If any of these checks fails,
|
||||
* the program terminates with a message.
|
||||
*/
|
||||
void SetWithTid (TypeId tid, std::string name, Attribute value);
|
||||
|
||||
/**
|
||||
* Clear the content of this instance.
|
||||
*/
|
||||
void Reset (void);
|
||||
|
||||
/**
|
||||
* \returns the global attribute container
|
||||
*
|
||||
* The global attribute container can be used to specify
|
||||
* a set of attribute values without having to re-specify
|
||||
* them for each object when it is created. This container
|
||||
* is checked only during object construction and
|
||||
* it is always checked last, after any per-object
|
||||
* container is checked.
|
||||
*/
|
||||
static AttributeList *GetGlobal (void);
|
||||
|
||||
// XXX: untested.
|
||||
std::string SerializeToString (void) const;
|
||||
bool DeserializeFromString (std::string value);
|
||||
private:
|
||||
friend class Object;
|
||||
struct Attr {
|
||||
Ptr<const AttributeChecker> checker;
|
||||
Attribute value;
|
||||
};
|
||||
typedef std::vector<struct Attr> Attrs;
|
||||
typedef Attrs::iterator Iterator;
|
||||
typedef Attrs::const_iterator CIterator;
|
||||
|
||||
|
||||
|
||||
bool DoSet (struct TypeId::AttributeInfo *info, Attribute param);
|
||||
void DoSetOne (Ptr<const AttributeChecker> checker, Attribute param);
|
||||
std::string LookupAttributeFullNameByChecker (Ptr<const AttributeChecker> checker) const;
|
||||
|
||||
Attrs m_attributes;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief a base class which provides memory management and object aggregation
|
||||
*
|
||||
@@ -424,42 +50,7 @@ public:
|
||||
Object ();
|
||||
virtual ~Object ();
|
||||
|
||||
/**
|
||||
* \param name the name of the attribute to set
|
||||
* \param value the name of the attribute to set
|
||||
*
|
||||
* Set a single attribute. This cannot fail: if the input is invalid,
|
||||
* it will crash immediately.
|
||||
*/
|
||||
void SetAttribute (std::string name, Attribute value);
|
||||
/**
|
||||
* \param name the name of the attribute to set
|
||||
* \param value the name of the attribute to set
|
||||
* \returns true if the requested attribute exists and could be set,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool SetAttributeFailSafe (std::string name, Attribute value);
|
||||
/**
|
||||
* \param name the name of the attribute to read
|
||||
* \param value a reference to the string where the value of the
|
||||
* attribute should be stored.
|
||||
* \returns true if the requested attribute was found, false otherwise.
|
||||
*/
|
||||
bool GetAttribute (std::string name, std::string &value) const;
|
||||
/**
|
||||
* \param name the name of the attribute to read
|
||||
* \returns the attribute read.
|
||||
*
|
||||
* If the input attribute name does not exist, this method crashes.
|
||||
*/
|
||||
Attribute GetAttribute (std::string name) const;
|
||||
|
||||
bool TraceConnectWithoutContext (std::string name, const CallbackBase &cb);
|
||||
bool TraceConnectWithoutContext (std::string name, std::string context, const CallbackBase &cb);
|
||||
bool TraceDisconnectWithoutContext (std::string name, const CallbackBase &cb);
|
||||
bool TraceDisconnectWithoutContext (std::string name, std::string context, const CallbackBase &cb);
|
||||
|
||||
TypeId GetRealTypeId (void) const;
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
/**
|
||||
* Increment the reference count. This method should not be called
|
||||
@@ -511,15 +102,14 @@ protected:
|
||||
* up to their parent's implementation once they are done.
|
||||
*/
|
||||
virtual void DoDispose (void);
|
||||
virtual void NotifyConstructionCompleted (void);
|
||||
private:
|
||||
template <typename T>
|
||||
friend Ptr<T> CreateObject (const AttributeList &attributes);
|
||||
template <typename T>
|
||||
friend Ptr<T> CopyObject (Ptr<T> object);
|
||||
|
||||
bool DoSet (Ptr<const AttributeAccessor> spec, Attribute intialValue,
|
||||
Ptr<const AttributeChecker> checker, Attribute value);
|
||||
friend class ObjectFactory;
|
||||
|
||||
Ptr<Object> DoGetObject (TypeId tid) const;
|
||||
bool Check (void) const;
|
||||
bool CheckLoose (void) const;
|
||||
@@ -538,11 +128,11 @@ private:
|
||||
* keep track of the type of this object instance.
|
||||
*/
|
||||
void SetTypeId (TypeId tid);
|
||||
/**
|
||||
/**
|
||||
* \param attributes the attribute values used to initialize
|
||||
* the member variables of this object's instance.
|
||||
*
|
||||
* Invoked from ns3::CreateObject only.
|
||||
* Invoked from ns3::ObjectFactory::Create and ns3::CreateObject only.
|
||||
* Initialize all the member variables which were
|
||||
* registered with the associated TypeId.
|
||||
*/
|
||||
@@ -565,7 +155,6 @@ private:
|
||||
* has run, false otherwise.
|
||||
*/
|
||||
bool m_disposed;
|
||||
mutable bool m_collecting;
|
||||
/**
|
||||
* A pointer to the next aggregate object. This is a circular
|
||||
* linked list of aggregated objects: the last one points
|
||||
@@ -580,31 +169,6 @@ private:
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/*************************************************************************
|
||||
* The TypeId implementation which depends on templates
|
||||
*************************************************************************/
|
||||
|
||||
template <typename T>
|
||||
TypeId
|
||||
TypeId::SetParent (void)
|
||||
{
|
||||
return SetParent (T::GetTypeId ());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TypeId
|
||||
TypeId::AddConstructor (void)
|
||||
{
|
||||
struct Maker {
|
||||
static Ptr<Object> Create (const AttributeList &attributes) {
|
||||
return ns3::CreateObject<T> (attributes);
|
||||
}
|
||||
};
|
||||
CallbackBase cb = MakeCallback (&Maker::Create);
|
||||
DoAddConstructor (cb);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* The Object implementation which depends on templates
|
||||
*************************************************************************/
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#ifdef RUN_SELF_TESTS
|
||||
|
||||
#include "test.h"
|
||||
#include "object-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -46,7 +45,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class Base : public ObjectBase
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base ();
|
||||
|
||||
@@ -21,18 +21,20 @@
|
||||
#define TRACE_SOURCE_ACCESSOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "object-base.h"
|
||||
#include "callback.h"
|
||||
#include "ptr.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class ObjectBase;
|
||||
|
||||
/**
|
||||
* \brief control access to objects' trace sources
|
||||
*
|
||||
* This class abstracts the kind of trace source to which we want to connect.
|
||||
* This class abstracts the kind of trace source to which we want to connect
|
||||
* and provides services to Connect and Disconnect a sink to a trace source.
|
||||
*/
|
||||
class TraceSourceAccessor : public ObjectBase
|
||||
class TraceSourceAccessor
|
||||
{
|
||||
public:
|
||||
TraceSourceAccessor ();
|
||||
|
||||
680
src/core/type-id.cc
Normal file
680
src/core/type-id.cc
Normal file
@@ -0,0 +1,680 @@
|
||||
#include "type-id.h"
|
||||
#include "singleton.h"
|
||||
#include "trace-source-accessor.h"
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
/*********************************************************************
|
||||
* Helper code
|
||||
*********************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
class IidManager
|
||||
{
|
||||
public:
|
||||
IidManager ();
|
||||
uint16_t AllocateUid (std::string name);
|
||||
void SetParent (uint16_t uid, uint16_t parent);
|
||||
void SetGroupName (uint16_t uid, std::string groupName);
|
||||
void AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback);
|
||||
void HideFromDocumentation (uint16_t uid);
|
||||
uint16_t GetUid (std::string name) const;
|
||||
std::string GetName (uint16_t uid) const;
|
||||
uint16_t GetParent (uint16_t uid) const;
|
||||
std::string GetGroupName (uint16_t uid) const;
|
||||
ns3::Callback<ns3::ObjectBase *> GetConstructor (uint16_t uid) const;
|
||||
bool HasConstructor (uint16_t uid) const;
|
||||
uint32_t GetRegisteredN (void) const;
|
||||
uint16_t GetRegistered (uint32_t i) const;
|
||||
void AddAttribute (uint16_t uid,
|
||||
std::string name,
|
||||
std::string help,
|
||||
uint32_t flags,
|
||||
ns3::Attribute initialValue,
|
||||
ns3::Ptr<const ns3::AttributeAccessor> spec,
|
||||
ns3::Ptr<const ns3::AttributeChecker> checker);
|
||||
uint32_t GetAttributeListN (uint16_t uid) const;
|
||||
std::string GetAttributeName (uint16_t uid, uint32_t i) const;
|
||||
std::string GetAttributeHelp (uint16_t uid, uint32_t i) const;
|
||||
uint32_t GetAttributeFlags (uint16_t uid, uint32_t i) const;
|
||||
ns3::Attribute GetAttributeInitialValue (uint16_t uid, uint32_t i) const;
|
||||
ns3::Ptr<const ns3::AttributeAccessor> GetAttributeAccessor (uint16_t uid, uint32_t i) const;
|
||||
ns3::Ptr<const ns3::AttributeChecker> GetAttributeChecker (uint16_t uid, uint32_t i) const;
|
||||
void AddTraceSource (uint16_t uid,
|
||||
std::string name,
|
||||
std::string help,
|
||||
ns3::Ptr<const ns3::TraceSourceAccessor> accessor);
|
||||
uint32_t GetTraceSourceN (uint16_t uid) const;
|
||||
std::string GetTraceSourceName (uint16_t uid, uint32_t i) const;
|
||||
std::string GetTraceSourceHelp (uint16_t uid, uint32_t i) const;
|
||||
ns3::Ptr<const ns3::TraceSourceAccessor> GetTraceSourceAccessor (uint16_t uid, uint32_t i) const;
|
||||
bool MustHideFromDocumentation (uint16_t uid) const;
|
||||
|
||||
private:
|
||||
struct AttributeInformation {
|
||||
std::string name;
|
||||
std::string help;
|
||||
uint32_t flags;
|
||||
ns3::Attribute initialValue;
|
||||
ns3::Ptr<const ns3::AttributeAccessor> param;
|
||||
ns3::Ptr<const ns3::AttributeChecker> checker;
|
||||
};
|
||||
struct TraceSourceInformation {
|
||||
std::string name;
|
||||
std::string help;
|
||||
ns3::Ptr<const ns3::TraceSourceAccessor> accessor;
|
||||
};
|
||||
struct IidInformation {
|
||||
std::string name;
|
||||
uint16_t parent;
|
||||
std::string groupName;
|
||||
bool hasConstructor;
|
||||
ns3::Callback<ns3::ObjectBase *> constructor;
|
||||
bool mustHideFromDocumentation;
|
||||
std::vector<struct AttributeInformation> attributes;
|
||||
std::vector<struct TraceSourceInformation> traceSources;
|
||||
};
|
||||
typedef std::vector<struct IidInformation>::const_iterator Iterator;
|
||||
|
||||
struct IidManager::IidInformation *LookupInformation (uint16_t uid) const;
|
||||
|
||||
std::vector<struct IidInformation> m_information;
|
||||
};
|
||||
|
||||
IidManager::IidManager ()
|
||||
{}
|
||||
|
||||
uint16_t
|
||||
IidManager::AllocateUid (std::string name)
|
||||
{
|
||||
uint16_t j = 1;
|
||||
for (Iterator i = m_information.begin (); i != m_information.end (); i++)
|
||||
{
|
||||
if (i->name == name)
|
||||
{
|
||||
NS_FATAL_ERROR ("Trying to allocate twice the same uid: " << name);
|
||||
return 0;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
struct IidInformation information;
|
||||
information.name = name;
|
||||
information.parent = 0;
|
||||
information.groupName = "";
|
||||
information.hasConstructor = false;
|
||||
information.mustHideFromDocumentation = false;
|
||||
m_information.push_back (information);
|
||||
uint32_t uid = m_information.size ();
|
||||
NS_ASSERT (uid <= 0xffff);
|
||||
return uid;
|
||||
}
|
||||
|
||||
struct IidManager::IidInformation *
|
||||
IidManager::LookupInformation (uint16_t uid) const
|
||||
{
|
||||
NS_ASSERT (uid <= m_information.size ());
|
||||
return const_cast<struct IidInformation *> (&m_information[uid-1]);
|
||||
}
|
||||
|
||||
void
|
||||
IidManager::SetParent (uint16_t uid, uint16_t parent)
|
||||
{
|
||||
NS_ASSERT (parent <= m_information.size ());
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
information->parent = parent;
|
||||
}
|
||||
void
|
||||
IidManager::SetGroupName (uint16_t uid, std::string groupName)
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
information->groupName = groupName;
|
||||
}
|
||||
void
|
||||
IidManager::HideFromDocumentation (uint16_t uid)
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
information->mustHideFromDocumentation = true;
|
||||
}
|
||||
|
||||
void
|
||||
IidManager::AddConstructor (uint16_t uid, ns3::Callback<ns3::ObjectBase *> callback)
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
if (information->hasConstructor)
|
||||
{
|
||||
NS_FATAL_ERROR (information->name<<" already has a constructor.");
|
||||
}
|
||||
information->hasConstructor = true;
|
||||
information->constructor = callback;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
IidManager::GetUid (std::string name) const
|
||||
{
|
||||
uint32_t j = 1;
|
||||
for (Iterator i = m_information.begin (); i != m_information.end (); i++)
|
||||
{
|
||||
if (i->name == name)
|
||||
{
|
||||
NS_ASSERT (j <= 0xffff);
|
||||
return j;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
std::string
|
||||
IidManager::GetName (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->name;
|
||||
}
|
||||
uint16_t
|
||||
IidManager::GetParent (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->parent;
|
||||
}
|
||||
std::string
|
||||
IidManager::GetGroupName (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->groupName;
|
||||
}
|
||||
|
||||
ns3::Callback<ns3::ObjectBase *>
|
||||
IidManager::GetConstructor (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
if (!information->hasConstructor)
|
||||
{
|
||||
NS_FATAL_ERROR ("Requested constructor for "<<information->name<<" but it does not have one.");
|
||||
}
|
||||
return information->constructor;
|
||||
}
|
||||
|
||||
bool
|
||||
IidManager::HasConstructor (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->hasConstructor;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
IidManager::GetRegisteredN (void) const
|
||||
{
|
||||
return m_information.size ();
|
||||
}
|
||||
uint16_t
|
||||
IidManager::GetRegistered (uint32_t i) const
|
||||
{
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
void
|
||||
IidManager::AddAttribute (uint16_t uid,
|
||||
std::string name,
|
||||
std::string help,
|
||||
uint32_t flags,
|
||||
ns3::Attribute initialValue,
|
||||
ns3::Ptr<const ns3::AttributeAccessor> spec,
|
||||
ns3::Ptr<const ns3::AttributeChecker> checker)
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
for (std::vector<struct AttributeInformation>::const_iterator j = information->attributes.begin ();
|
||||
j != information->attributes.end (); j++)
|
||||
{
|
||||
if (j->name == name)
|
||||
{
|
||||
NS_FATAL_ERROR ("Registered the same attribute twice name=\""<<name<<"\" in TypeId=\""<<information->name<<"\"");
|
||||
return;
|
||||
}
|
||||
}
|
||||
struct AttributeInformation param;
|
||||
param.name = name;
|
||||
param.help = help;
|
||||
param.flags = flags;
|
||||
param.initialValue = initialValue;
|
||||
param.param = spec;
|
||||
param.checker = checker;
|
||||
information->attributes.push_back (param);
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
IidManager::GetAttributeListN (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->attributes.size ();
|
||||
}
|
||||
std::string
|
||||
IidManager::GetAttributeName (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->attributes.size ());
|
||||
return information->attributes[i].name;
|
||||
}
|
||||
std::string
|
||||
IidManager::GetAttributeHelp (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->attributes.size ());
|
||||
return information->attributes[i].help;
|
||||
}
|
||||
uint32_t
|
||||
IidManager::GetAttributeFlags (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->attributes.size ());
|
||||
return information->attributes[i].flags;
|
||||
}
|
||||
ns3::Attribute
|
||||
IidManager::GetAttributeInitialValue (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->attributes.size ());
|
||||
return information->attributes[i].initialValue;
|
||||
}
|
||||
ns3::Ptr<const ns3::AttributeAccessor>
|
||||
IidManager::GetAttributeAccessor (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->attributes.size ());
|
||||
return information->attributes[i].param;
|
||||
}
|
||||
ns3::Ptr<const ns3::AttributeChecker>
|
||||
IidManager::GetAttributeChecker (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->attributes.size ());
|
||||
return information->attributes[i].checker;
|
||||
}
|
||||
|
||||
void
|
||||
IidManager::AddTraceSource (uint16_t uid,
|
||||
std::string name,
|
||||
std::string help,
|
||||
ns3::Ptr<const ns3::TraceSourceAccessor> accessor)
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
struct TraceSourceInformation source;
|
||||
source.name = name;
|
||||
source.help = help;
|
||||
source.accessor = accessor;
|
||||
information->traceSources.push_back (source);
|
||||
}
|
||||
uint32_t
|
||||
IidManager::GetTraceSourceN (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->traceSources.size ();
|
||||
}
|
||||
std::string
|
||||
IidManager::GetTraceSourceName (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->traceSources.size ());
|
||||
return information->traceSources[i].name;
|
||||
}
|
||||
std::string
|
||||
IidManager::GetTraceSourceHelp (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->traceSources.size ());
|
||||
return information->traceSources[i].help;
|
||||
}
|
||||
ns3::Ptr<const ns3::TraceSourceAccessor>
|
||||
IidManager::GetTraceSourceAccessor (uint16_t uid, uint32_t i) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
NS_ASSERT (i < information->traceSources.size ());
|
||||
return information->traceSources[i].accessor;
|
||||
}
|
||||
bool
|
||||
IidManager::MustHideFromDocumentation (uint16_t uid) const
|
||||
{
|
||||
struct IidInformation *information = LookupInformation (uid);
|
||||
return information->mustHideFromDocumentation;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/*********************************************************************
|
||||
* The TypeId class
|
||||
*********************************************************************/
|
||||
|
||||
TypeId::TypeId ()
|
||||
: m_tid (0)
|
||||
{}
|
||||
|
||||
TypeId::TypeId (const char *name)
|
||||
{
|
||||
uint16_t uid = Singleton<IidManager>::Get ()->AllocateUid (name);
|
||||
NS_ASSERT (uid != 0);
|
||||
m_tid = uid;
|
||||
}
|
||||
|
||||
|
||||
TypeId::TypeId (uint16_t tid)
|
||||
: m_tid (tid)
|
||||
{}
|
||||
TypeId::~TypeId ()
|
||||
{}
|
||||
TypeId
|
||||
TypeId::LookupByName (std::string name)
|
||||
{
|
||||
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
|
||||
NS_ASSERT (uid != 0);
|
||||
return TypeId (uid);
|
||||
}
|
||||
bool
|
||||
TypeId::LookupByNameFailSafe (std::string name, TypeId *tid)
|
||||
{
|
||||
uint16_t uid = Singleton<IidManager>::Get ()->GetUid (name);
|
||||
if (uid == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*tid = TypeId (uid);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TypeId::LookupAttributeByFullName (std::string fullName, struct TypeId::AttributeInfo *info)
|
||||
{
|
||||
std::string::size_type pos = fullName.rfind ("::");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
std::string tidName = fullName.substr (0, pos);
|
||||
std::string paramName = fullName.substr (pos+2, fullName.size () - (pos+2));
|
||||
TypeId tid;
|
||||
bool ok = LookupByNameFailSafe (tidName, &tid);
|
||||
if (!ok)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return tid.LookupAttributeByName (paramName, info);
|
||||
}
|
||||
uint32_t
|
||||
TypeId::GetRegisteredN (void)
|
||||
{
|
||||
return Singleton<IidManager>::Get ()->GetRegisteredN ();
|
||||
}
|
||||
TypeId
|
||||
TypeId::GetRegistered (uint32_t i)
|
||||
{
|
||||
return TypeId (Singleton<IidManager>::Get ()->GetRegistered (i));
|
||||
}
|
||||
|
||||
bool
|
||||
TypeId::LookupAttributeByName (std::string name, struct TypeId::AttributeInfo *info) const
|
||||
{
|
||||
TypeId tid;
|
||||
TypeId nextTid = *this;
|
||||
do {
|
||||
tid = nextTid;
|
||||
for (uint32_t i = 0; i < tid.GetAttributeListN (); i++)
|
||||
{
|
||||
std::string paramName = tid.GetAttributeName (i);
|
||||
if (paramName == name)
|
||||
{
|
||||
info->accessor = tid.GetAttributeAccessor (i);
|
||||
info->flags = tid.GetAttributeFlags (i);
|
||||
info->initialValue = tid.GetAttributeInitialValue (i);
|
||||
info->checker = tid.GetAttributeChecker (i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
nextTid = tid.GetParent ();
|
||||
} while (nextTid != tid);
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeId
|
||||
TypeId::SetParent (TypeId tid)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->SetParent (m_tid, tid.m_tid);
|
||||
return *this;
|
||||
}
|
||||
TypeId
|
||||
TypeId::SetGroupName (std::string groupName)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->SetGroupName (m_tid, groupName);
|
||||
return *this;
|
||||
}
|
||||
TypeId
|
||||
TypeId::GetParent (void) const
|
||||
{
|
||||
uint16_t parent = Singleton<IidManager>::Get ()->GetParent (m_tid);
|
||||
return TypeId (parent);
|
||||
}
|
||||
bool
|
||||
TypeId::IsChildOf (TypeId other) const
|
||||
{
|
||||
TypeId tmp = *this;
|
||||
while (tmp != other && tmp != tmp.GetParent ())
|
||||
{
|
||||
tmp = tmp.GetParent ();
|
||||
}
|
||||
return tmp == other;
|
||||
}
|
||||
std::string
|
||||
TypeId::GetGroupName (void) const
|
||||
{
|
||||
std::string groupName = Singleton<IidManager>::Get ()->GetGroupName (m_tid);
|
||||
return groupName;
|
||||
}
|
||||
|
||||
std::string
|
||||
TypeId::GetName (void) const
|
||||
{
|
||||
std::string name = Singleton<IidManager>::Get ()->GetName (m_tid);
|
||||
return name;
|
||||
}
|
||||
|
||||
bool
|
||||
TypeId::HasConstructor (void) const
|
||||
{
|
||||
bool hasConstructor = Singleton<IidManager>::Get ()->HasConstructor (m_tid);
|
||||
return hasConstructor;
|
||||
}
|
||||
|
||||
void
|
||||
TypeId::DoAddConstructor (Callback<ObjectBase *> cb)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->AddConstructor (m_tid, cb);
|
||||
}
|
||||
|
||||
TypeId
|
||||
TypeId::AddAttribute (std::string name,
|
||||
std::string help,
|
||||
Attribute initialValue,
|
||||
Ptr<const AttributeAccessor> param,
|
||||
Ptr<const AttributeChecker> checker)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, ATTR_SGC, initialValue, param, checker);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeId
|
||||
TypeId::AddAttribute (std::string name,
|
||||
std::string help,
|
||||
uint32_t flags,
|
||||
Attribute initialValue,
|
||||
Ptr<const AttributeAccessor> param,
|
||||
Ptr<const AttributeChecker> checker)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->AddAttribute (m_tid, name, help, flags, initialValue, param, checker);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Callback<ObjectBase *>
|
||||
TypeId::GetConstructor (void) const
|
||||
{
|
||||
Callback<ObjectBase *> cb = Singleton<IidManager>::Get ()->GetConstructor (m_tid);
|
||||
return cb;
|
||||
}
|
||||
|
||||
bool
|
||||
TypeId::MustHideFromDocumentation (void) const
|
||||
{
|
||||
bool mustHide = Singleton<IidManager>::Get ()->MustHideFromDocumentation (m_tid);
|
||||
return mustHide;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TypeId::GetAttributeListN (void) const
|
||||
{
|
||||
uint32_t n = Singleton<IidManager>::Get ()->GetAttributeListN (m_tid);
|
||||
return n;
|
||||
}
|
||||
std::string
|
||||
TypeId::GetAttributeName (uint32_t i) const
|
||||
{
|
||||
std::string name = Singleton<IidManager>::Get ()->GetAttributeName (m_tid, i);
|
||||
return name;
|
||||
}
|
||||
std::string
|
||||
TypeId::GetAttributeHelp (uint32_t i) const
|
||||
{
|
||||
std::string help = Singleton<IidManager>::Get ()->GetAttributeHelp (m_tid, i);
|
||||
return help;
|
||||
}
|
||||
std::string
|
||||
TypeId::GetAttributeFullName (uint32_t i) const
|
||||
{
|
||||
return GetName () + "::" + GetAttributeName (i);
|
||||
}
|
||||
Attribute
|
||||
TypeId::GetAttributeInitialValue (uint32_t i) const
|
||||
{
|
||||
Attribute value = Singleton<IidManager>::Get ()->GetAttributeInitialValue (m_tid, i);
|
||||
return value;
|
||||
}
|
||||
Ptr<const AttributeAccessor>
|
||||
TypeId::GetAttributeAccessor (uint32_t i) const
|
||||
{
|
||||
// Used exclusively by the Object class.
|
||||
Ptr<const AttributeAccessor> param = Singleton<IidManager>::Get ()->GetAttributeAccessor (m_tid, i);
|
||||
return param;
|
||||
}
|
||||
uint32_t
|
||||
TypeId::GetAttributeFlags (uint32_t i) const
|
||||
{
|
||||
// Used exclusively by the Object class.
|
||||
uint32_t flags = Singleton<IidManager>::Get ()->GetAttributeFlags (m_tid, i);
|
||||
return flags;
|
||||
}
|
||||
Ptr<const AttributeChecker>
|
||||
TypeId::GetAttributeChecker (uint32_t i) const
|
||||
{
|
||||
// Used exclusively by the Object class.
|
||||
Ptr<const AttributeChecker> checker = Singleton<IidManager>::Get ()->GetAttributeChecker (m_tid, i);
|
||||
return checker;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
TypeId::GetTraceSourceN (void) const
|
||||
{
|
||||
return Singleton<IidManager>::Get ()->GetTraceSourceN (m_tid);
|
||||
}
|
||||
std::string
|
||||
TypeId::GetTraceSourceName (uint32_t i) const
|
||||
{
|
||||
return Singleton<IidManager>::Get ()->GetTraceSourceName (m_tid, i);
|
||||
}
|
||||
std::string
|
||||
TypeId::GetTraceSourceHelp (uint32_t i) const
|
||||
{
|
||||
return Singleton<IidManager>::Get ()->GetTraceSourceHelp (m_tid, i);
|
||||
}
|
||||
Ptr<const TraceSourceAccessor>
|
||||
TypeId::GetTraceSourceAccessor (uint32_t i) const
|
||||
{
|
||||
return Singleton<IidManager>::Get ()->GetTraceSourceAccessor (m_tid, i);
|
||||
}
|
||||
|
||||
TypeId
|
||||
TypeId::AddTraceSource (std::string name,
|
||||
std::string help,
|
||||
Ptr<const TraceSourceAccessor> accessor)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->AddTraceSource (m_tid, name, help, accessor);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeId
|
||||
TypeId::HideFromDocumentation (void)
|
||||
{
|
||||
Singleton<IidManager>::Get ()->HideFromDocumentation (m_tid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Ptr<const TraceSourceAccessor>
|
||||
TypeId::LookupTraceSourceByName (std::string name) const
|
||||
{
|
||||
TypeId tid;
|
||||
TypeId nextTid = *this;
|
||||
do {
|
||||
tid = nextTid;
|
||||
for (uint32_t i = 0; i < tid.GetTraceSourceN (); i++)
|
||||
{
|
||||
std::string srcName = tid.GetTraceSourceName (i);
|
||||
if (srcName == name)
|
||||
{
|
||||
return tid.GetTraceSourceAccessor (i);
|
||||
}
|
||||
}
|
||||
nextTid = tid.GetParent ();
|
||||
} while (nextTid != tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
TypeId::GetUid (void) const
|
||||
{
|
||||
return m_tid;
|
||||
}
|
||||
void
|
||||
TypeId::SetUid (uint16_t tid)
|
||||
{
|
||||
m_tid = tid;
|
||||
}
|
||||
|
||||
std::ostream & operator << (std::ostream &os, TypeId tid)
|
||||
{
|
||||
os << tid.GetName ();
|
||||
return os;
|
||||
}
|
||||
std::istream & operator >> (std::istream &is, TypeId &tid)
|
||||
{
|
||||
std::string tidString;
|
||||
is >> tidString;
|
||||
bool ok = TypeId::LookupByNameFailSafe (tidString, &tid);
|
||||
if (!ok)
|
||||
{
|
||||
is.setstate (std::ios_base::badbit);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
ATTRIBUTE_HELPER_CPP (TypeId);
|
||||
|
||||
bool operator == (TypeId a, TypeId b)
|
||||
{
|
||||
return a.m_tid == b.m_tid;
|
||||
}
|
||||
|
||||
bool operator != (TypeId a, TypeId b)
|
||||
{
|
||||
return a.m_tid != b.m_tid;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
372
src/core/type-id.h
Normal file
372
src/core/type-id.h
Normal file
@@ -0,0 +1,372 @@
|
||||
#ifndef TYPE_ID_H
|
||||
#define TYPE_ID_H
|
||||
|
||||
#include "attribute.h"
|
||||
#include "attribute-accessor-helper.h"
|
||||
#include "attribute-helper.h"
|
||||
#include "callback.h"
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class ObjectBase;
|
||||
class TraceSourceAccessor;
|
||||
|
||||
/**
|
||||
* \brief a unique identifier for an interface.
|
||||
*
|
||||
* This class records a lot of meta-information about a
|
||||
* subclass of the Object base class:
|
||||
* - the base class of the subclass
|
||||
* - the set of accessible constructors in the subclass
|
||||
* - the set of 'attributes' accessible in the subclass
|
||||
*/
|
||||
class TypeId
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
/**
|
||||
* The attribute can be read
|
||||
*/
|
||||
ATTR_GET = 1<<0,
|
||||
/**
|
||||
* The attribute can be written
|
||||
*/
|
||||
ATTR_SET = 1<<1,
|
||||
/**
|
||||
* The attribute can be written at construction-time.
|
||||
*/
|
||||
ATTR_CONSTRUCT = 1<<2,
|
||||
/**
|
||||
* The attribute can be read, and written at any time.
|
||||
*/
|
||||
ATTR_SGC = ATTR_GET | ATTR_SET | ATTR_CONSTRUCT,
|
||||
};
|
||||
|
||||
/**
|
||||
* \param name the name of the requested TypeId
|
||||
* \returns the unique id associated with the requested
|
||||
* name.
|
||||
*
|
||||
* This method cannot fail: it will crash if the input
|
||||
* name is not a valid TypeId name.
|
||||
*/
|
||||
static TypeId LookupByName (std::string name);
|
||||
/**
|
||||
* \param name the name of the requested TypeId
|
||||
* \param tid a pointer to the TypeId instance where the
|
||||
* result of this function should be stored.
|
||||
* \returns true if the requested name was found, false otherwise.
|
||||
*/
|
||||
static bool LookupByNameFailSafe (std::string name, TypeId *tid);
|
||||
|
||||
/**
|
||||
* \returns the number of TypeId instances registered.
|
||||
*/
|
||||
static uint32_t GetRegisteredN (void);
|
||||
/**
|
||||
* \param i index
|
||||
* \returns the TypeId instance whose index is i.
|
||||
*/
|
||||
static TypeId GetRegistered (uint32_t i);
|
||||
|
||||
/**
|
||||
* \param name the name of the interface to construct.
|
||||
*
|
||||
* No two instances can share the same name. The name is expected to be
|
||||
* the full c++ typename of associated c++ object.
|
||||
*/
|
||||
TypeId (const char * name);
|
||||
|
||||
/**
|
||||
* \returns the parent of this TypeId
|
||||
*
|
||||
* This method cannot fail. It will return itself
|
||||
* if this TypeId has no parent. i.e., it is at the top
|
||||
* of the TypeId hierarchy. Currently, this is the
|
||||
* case for the TypeId associated to the Object class
|
||||
* only.
|
||||
*/
|
||||
TypeId GetParent (void) const;
|
||||
|
||||
/**
|
||||
* \param other a parent TypeId
|
||||
* \returns true if the input TypeId is really a parent
|
||||
* of this TypeId, false otherwise.
|
||||
*
|
||||
* Calling this method is roughly similar to calling dynamic_cast
|
||||
* except that you do not need object instances: you can do the check
|
||||
* with TypeId instances instead.
|
||||
*/
|
||||
bool IsChildOf (TypeId other) const;
|
||||
|
||||
/**
|
||||
* \returns the name of the group associated to this TypeId.
|
||||
*/
|
||||
std::string GetGroupName (void) const;
|
||||
|
||||
/**
|
||||
* \returns the name of this interface.
|
||||
*/
|
||||
std::string GetName (void) const;
|
||||
|
||||
/**
|
||||
* \returns true if this TypeId has a constructor
|
||||
*/
|
||||
bool HasConstructor (void) const;
|
||||
|
||||
/**
|
||||
* \returns the number of attributes associated to this TypeId
|
||||
*/
|
||||
uint32_t GetAttributeListN (void) const;
|
||||
/**
|
||||
* \param i index into attribute array
|
||||
* \returns the name associated to the attribute whose
|
||||
* index is i.
|
||||
*/
|
||||
std::string GetAttributeName (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into attribute array.
|
||||
* \returns the help text associated to the attribute whose
|
||||
* index is i.
|
||||
*/
|
||||
std::string GetAttributeHelp (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into attribute array
|
||||
* \returns the full name associated to the attribute whose
|
||||
* index is i.
|
||||
*/
|
||||
std::string GetAttributeFullName (uint32_t i) const;
|
||||
|
||||
/**
|
||||
* \param i index into attribute array.
|
||||
* \returns the value with which the associated attribute
|
||||
* is initialized.
|
||||
*/
|
||||
Attribute GetAttributeInitialValue (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into attribute array.
|
||||
* \returns the flags associated to the requested attribute.
|
||||
*/
|
||||
uint32_t GetAttributeFlags (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into attribute array.
|
||||
* \returns the checker associated to the requested attribute.
|
||||
*/
|
||||
Ptr<const AttributeChecker> GetAttributeChecker (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into attribute array.
|
||||
* \returns the accessor associated to the requested attribute.
|
||||
*/
|
||||
Ptr<const AttributeAccessor> GetAttributeAccessor (uint32_t i) const;
|
||||
|
||||
/**
|
||||
* \returns a callback which can be used to instanciate an object
|
||||
* of this type.
|
||||
*/
|
||||
Callback<ObjectBase *> GetConstructor (void) const;
|
||||
|
||||
/**
|
||||
* \returns true if this TypeId should be hidden from the user,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool MustHideFromDocumentation (void) const;
|
||||
|
||||
|
||||
/**
|
||||
* \returns the number of trace sources defined in this TypeId.
|
||||
*/
|
||||
uint32_t GetTraceSourceN (void) const;
|
||||
/**
|
||||
* \param i index into trace source array.
|
||||
* \returns the name of the requested trace source.
|
||||
*/
|
||||
std::string GetTraceSourceName (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into trace source array.
|
||||
* \returns the help text of the requested trace source.
|
||||
*/
|
||||
std::string GetTraceSourceHelp (uint32_t i) const;
|
||||
/**
|
||||
* \param i index into trace source array.
|
||||
* \returns the accessor used to get access to the requested
|
||||
* trace source.
|
||||
*/
|
||||
Ptr<const TraceSourceAccessor> GetTraceSourceAccessor (uint32_t i) const;
|
||||
|
||||
|
||||
/**
|
||||
* \param tid the TypeId of the base class.
|
||||
* \return this TypeId instance.
|
||||
*
|
||||
* Record in this TypeId which TypeId is the TypeId
|
||||
* of the base class of the subclass.
|
||||
*/
|
||||
TypeId SetParent (TypeId tid);
|
||||
/**
|
||||
* \return this TypeId instance.
|
||||
*
|
||||
* Record in this TypeId which TypeId is the TypeId
|
||||
* of the base class of the subclass.
|
||||
*/
|
||||
template <typename T>
|
||||
TypeId SetParent (void);
|
||||
|
||||
/**
|
||||
* \param groupName the name of the group this TypeId belongs to.
|
||||
* \returns this TypeId instance.
|
||||
*
|
||||
* The group name is purely an advisory information used to
|
||||
* group together types according to a user-specific grouping
|
||||
* scheme.
|
||||
*/
|
||||
TypeId SetGroupName (std::string groupName);
|
||||
|
||||
/**
|
||||
* \returns this TypeId instance
|
||||
*
|
||||
* Record in this TypeId the fact that the default constructor
|
||||
* is accessible.
|
||||
*/
|
||||
template <typename T>
|
||||
TypeId AddConstructor (void);
|
||||
|
||||
/**
|
||||
* \param name the name of the new attribute
|
||||
* \param help some help text which describes the purpose of this
|
||||
* attribute.
|
||||
* \param initialValue the initial value for this attribute.
|
||||
* \param accessor an instance of the associated AttributeAccessor subclass.
|
||||
* \param checker an instance of the associated AttributeChecker subclass.
|
||||
* \returns this TypeId instance
|
||||
*
|
||||
* Record in this TypeId the fact that a new attribute exists.
|
||||
*/
|
||||
TypeId AddAttribute (std::string name,
|
||||
std::string help,
|
||||
Attribute initialValue,
|
||||
Ptr<const AttributeAccessor> accessor,
|
||||
Ptr<const AttributeChecker> checker);
|
||||
|
||||
/**
|
||||
* \param name the name of the new attribute
|
||||
* \param help some help text which describes the purpose of this
|
||||
* attribute
|
||||
* \param flags flags which describe how this attribute can be read and/or written.
|
||||
* \param initialValue the initial value for this attribute.
|
||||
* \param accessor an instance of the associated AttributeAccessor subclass.
|
||||
* \param checker an instance of the associated AttributeChecker subclass.
|
||||
* \returns this TypeId instance
|
||||
*
|
||||
* Record in this TypeId the fact that a new attribute exists.
|
||||
*/
|
||||
TypeId AddAttribute (std::string name,
|
||||
std::string help,
|
||||
uint32_t flags,
|
||||
Attribute initialValue,
|
||||
Ptr<const AttributeAccessor> accessor,
|
||||
Ptr<const AttributeChecker> checker);
|
||||
|
||||
/**
|
||||
* \param name the name of the new trace source
|
||||
* \param help some help text which describes the purpose of this
|
||||
* trace source.
|
||||
* \param accessor a pointer to a TraceSourceAccessor which can be
|
||||
* used to connect/disconnect sinks to this trace source.
|
||||
* \returns this TypeId instance.
|
||||
*/
|
||||
TypeId AddTraceSource (std::string name,
|
||||
std::string help,
|
||||
Ptr<const TraceSourceAccessor> accessor);
|
||||
|
||||
TypeId HideFromDocumentation (void);
|
||||
|
||||
/**
|
||||
* \brief store together a set of attribute properties.
|
||||
*/
|
||||
struct AttributeInfo {
|
||||
// The accessor associated to the attribute.
|
||||
Ptr<const AttributeAccessor> accessor;
|
||||
// The initial value associated to the attribute.
|
||||
Attribute initialValue;
|
||||
// The set of access control flags associated to the attribute.
|
||||
uint32_t flags;
|
||||
// The checker associated to the attribute.
|
||||
Ptr<const AttributeChecker> checker;
|
||||
};
|
||||
/**
|
||||
* \param name the name of the requested attribute
|
||||
* \param info a pointer to the TypeId::AttributeInfo data structure
|
||||
* where the result value of this method will be stored.
|
||||
* \returns true if the requested attribute could be found, false otherwise.
|
||||
*/
|
||||
bool LookupAttributeByName (std::string name, struct AttributeInfo *info) const;
|
||||
Ptr<const TraceSourceAccessor> LookupTraceSourceByName (std::string name) const;
|
||||
|
||||
uint16_t GetUid (void) const;
|
||||
void SetUid (uint16_t tid);
|
||||
|
||||
// construct an invalid TypeId.
|
||||
TypeId ();
|
||||
~TypeId ();
|
||||
|
||||
ATTRIBUTE_HELPER_HEADER_1 (TypeId);
|
||||
private:
|
||||
friend class AttributeList;
|
||||
friend bool operator == (TypeId a, TypeId b);
|
||||
friend bool operator != (TypeId a, TypeId b);
|
||||
|
||||
|
||||
/**
|
||||
* \param fullName the full name of the requested attribute
|
||||
* \param info a pointer to the TypeId::AttributeInfo data structure
|
||||
* where the result value of this method will be stored.
|
||||
* \returns the Accessor associated to the requested attribute
|
||||
*/
|
||||
static bool LookupAttributeByFullName (std::string fullName, struct AttributeInfo *info);
|
||||
|
||||
explicit TypeId (uint16_t tid);
|
||||
void DoAddConstructor (Callback<ObjectBase *> callback);
|
||||
|
||||
uint16_t m_tid;
|
||||
};
|
||||
|
||||
std::ostream & operator << (std::ostream &os, TypeId tid);
|
||||
std::istream & operator >> (std::istream &is, TypeId &tid);
|
||||
|
||||
ATTRIBUTE_HELPER_HEADER_2 (TypeId);
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/*************************************************************************
|
||||
* The TypeId implementation which depends on templates
|
||||
*************************************************************************/
|
||||
|
||||
template <typename T>
|
||||
TypeId
|
||||
TypeId::SetParent (void)
|
||||
{
|
||||
return SetParent (T::GetTypeId ());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TypeId
|
||||
TypeId::AddConstructor (void)
|
||||
{
|
||||
struct Maker {
|
||||
static ObjectBase * Create () {
|
||||
ObjectBase * base = new T ();
|
||||
return base;
|
||||
}
|
||||
};
|
||||
Callback<ObjectBase *> cb = MakeCallback (&Maker::Create);
|
||||
DoAddConstructor (cb);
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* TYPE_ID_H */
|
||||
@@ -31,6 +31,8 @@ def build(bld):
|
||||
'callback-test.cc',
|
||||
'log.cc',
|
||||
'breakpoint.cc',
|
||||
'type-id.cc',
|
||||
'attribute-list.cc',
|
||||
'object-base.cc',
|
||||
'ptr.cc',
|
||||
'object.cc',
|
||||
@@ -73,6 +75,8 @@ def build(bld):
|
||||
'empty.h',
|
||||
'callback.h',
|
||||
'object-base.h',
|
||||
'type-id.h',
|
||||
'attribute-list.h',
|
||||
'ptr.h',
|
||||
'object.h',
|
||||
'log.h',
|
||||
|
||||
@@ -111,6 +111,12 @@ CsmaNetDevice::DoDispose ()
|
||||
NetDevice::DoDispose ();
|
||||
}
|
||||
|
||||
void
|
||||
CsmaNetDevice::SetAddress (Mac48Address self)
|
||||
{
|
||||
m_address = self;
|
||||
}
|
||||
|
||||
void
|
||||
CsmaNetDevice::SetSendEnable (bool sendEnable)
|
||||
{
|
||||
|
||||
@@ -180,6 +180,8 @@ enum CsmaEncapsulationMode {
|
||||
void SetSendEnable (bool);
|
||||
void SetReceiveEnable (bool);
|
||||
|
||||
void SetAddress (Mac48Address self);
|
||||
|
||||
|
||||
// inherited from NetDevice base class.
|
||||
virtual void SetName(const std::string name);
|
||||
|
||||
@@ -87,6 +87,12 @@ PointToPointNetDevice::PointToPointNetDevice ()
|
||||
PointToPointNetDevice::~PointToPointNetDevice ()
|
||||
{}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::SetAddress (Mac48Address self)
|
||||
{
|
||||
m_address = self;
|
||||
}
|
||||
|
||||
void
|
||||
PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
|
||||
{
|
||||
|
||||
@@ -145,6 +145,8 @@ public:
|
||||
*/
|
||||
void Receive (Ptr<Packet> p);
|
||||
|
||||
void SetAddress (Mac48Address self);
|
||||
|
||||
// inherited from NetDevice base class.
|
||||
virtual void SetName(const std::string name);
|
||||
virtual std::string GetName(void) const;
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace ns3 {
|
||||
* Probe Request
|
||||
***********************************************************/
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MgtProbeRequestHeader);
|
||||
|
||||
MgtProbeRequestHeader::~MgtProbeRequestHeader ()
|
||||
{}
|
||||
|
||||
@@ -59,16 +61,19 @@ MgtProbeRequestHeader::GetSerializedSize (void) const
|
||||
size += m_rates.GetSerializedSize ();
|
||||
return size;
|
||||
}
|
||||
uint32_t
|
||||
MgtProbeRequestHeader::GetUid (void)
|
||||
TypeId
|
||||
MgtProbeRequestHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<MgtProbeRequestHeader> ("MgtProbeRequestHeader.ns3.inria.fr");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::MgtProbeRequestHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<MgtProbeRequestHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
std::string
|
||||
MgtProbeRequestHeader::GetName (void) const
|
||||
TypeId
|
||||
MgtProbeRequestHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return "PROBEREQ";
|
||||
return GetTypeId ();
|
||||
}
|
||||
void
|
||||
MgtProbeRequestHeader::Print (std::ostream &os) const
|
||||
@@ -97,6 +102,8 @@ MgtProbeRequestHeader::Deserialize (Buffer::Iterator start)
|
||||
* Probe Response
|
||||
***********************************************************/
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MgtProbeResponseHeader);
|
||||
|
||||
MgtProbeResponseHeader::MgtProbeResponseHeader ()
|
||||
{}
|
||||
MgtProbeResponseHeader::~MgtProbeResponseHeader ()
|
||||
@@ -133,16 +140,19 @@ MgtProbeResponseHeader::SetSupportedRates (SupportedRates rates)
|
||||
{
|
||||
m_rates = rates;
|
||||
}
|
||||
uint32_t
|
||||
MgtProbeResponseHeader::GetUid (void)
|
||||
TypeId
|
||||
MgtProbeResponseHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<MgtProbeResponseHeader> ("MgtProbeResponseHeader.ns3.inria.fr");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::MgtProbeResponseHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<MgtProbeResponseHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
std::string
|
||||
MgtProbeResponseHeader::GetName (void) const
|
||||
TypeId
|
||||
MgtProbeResponseHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return "PROBERESP";
|
||||
return GetTypeId ();
|
||||
}
|
||||
uint32_t
|
||||
MgtProbeResponseHeader::GetSerializedSize (void) const
|
||||
@@ -198,6 +208,11 @@ MgtProbeResponseHeader::Deserialize (Buffer::Iterator start)
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Assoc Request
|
||||
***********************************************************/
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MgtAssocRequestHeader);
|
||||
|
||||
MgtAssocRequestHeader::MgtAssocRequestHeader ()
|
||||
{}
|
||||
@@ -234,16 +249,20 @@ MgtAssocRequestHeader::GetListenInterval (void) const
|
||||
{
|
||||
return m_listenInterval;
|
||||
}
|
||||
uint32_t
|
||||
MgtAssocRequestHeader::GetUid (void)
|
||||
|
||||
TypeId
|
||||
MgtAssocRequestHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<MgtAssocRequestHeader> ("MgtAssocRequestHeader.ns3.inria.fr");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::MgtAssocRequestHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<MgtAssocRequestHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
std::string
|
||||
MgtAssocRequestHeader::GetName (void) const
|
||||
TypeId
|
||||
MgtAssocRequestHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return "ASSOCREQ";
|
||||
return GetTypeId ();
|
||||
}
|
||||
uint32_t
|
||||
MgtAssocRequestHeader::GetSerializedSize (void) const
|
||||
@@ -281,6 +300,12 @@ MgtAssocRequestHeader::Deserialize (Buffer::Iterator start)
|
||||
return i.GetDistanceFrom (start);
|
||||
}
|
||||
|
||||
/***********************************************************
|
||||
* Assoc Response
|
||||
***********************************************************/
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MgtAssocResponseHeader);
|
||||
|
||||
MgtAssocResponseHeader::MgtAssocResponseHeader ()
|
||||
{}
|
||||
MgtAssocResponseHeader::~MgtAssocResponseHeader ()
|
||||
@@ -307,16 +332,19 @@ MgtAssocResponseHeader::SetSupportedRates (SupportedRates rates)
|
||||
m_rates = rates;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
MgtAssocResponseHeader::GetUid (void)
|
||||
TypeId
|
||||
MgtAssocResponseHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<MgtAssocResponseHeader> ("MgtAssocResponseHeader.ns3.inria.fr");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::MgtAssocResponseHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<MgtAssocResponseHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
std::string
|
||||
MgtAssocResponseHeader::GetName (void) const
|
||||
TypeId
|
||||
MgtAssocResponseHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return "ASSOCRESP";
|
||||
return GetTypeId ();
|
||||
}
|
||||
uint32_t
|
||||
MgtAssocResponseHeader::GetSerializedSize (void) const
|
||||
|
||||
@@ -44,12 +44,12 @@ public:
|
||||
SupportedRates GetSupportedRates (void) const;
|
||||
uint16_t GetListenInterval (void) const;
|
||||
|
||||
static uint32_t GetUid (void);
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
Ssid m_ssid;
|
||||
@@ -69,12 +69,12 @@ public:
|
||||
void SetSupportedRates (SupportedRates rates);
|
||||
void SetStatusCode (StatusCode code);
|
||||
|
||||
static uint32_t GetUid (void);
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
SupportedRates m_rates;
|
||||
@@ -92,12 +92,12 @@ public:
|
||||
Ssid GetSsid (void) const;
|
||||
SupportedRates GetSupportedRates (void) const;
|
||||
|
||||
static uint32_t GetUid (void);
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
|
||||
Ssid m_ssid;
|
||||
@@ -117,12 +117,12 @@ public:
|
||||
void SetBeaconIntervalUs (uint64_t us);
|
||||
void SetSupportedRates (SupportedRates rates);
|
||||
|
||||
static uint32_t GetUid (void);
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
Ssid m_ssid;
|
||||
|
||||
@@ -34,6 +34,8 @@ std::Cout << "MAC80211HEADER " << x << std::Endl;
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (WifiMacHeader);
|
||||
|
||||
enum {
|
||||
TYPE_MGT = 0,
|
||||
TYPE_CTL = 1,
|
||||
@@ -766,27 +768,28 @@ case WIFI_MAC_ ## x: \
|
||||
return "BIG_ERROR";
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiMacHeader::GetUid (void)
|
||||
TypeId
|
||||
WifiMacHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<WifiMacHeader> ("WifiMacHeader.ns3.inria.fr");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::WifiMacHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<WifiMacHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
std::string
|
||||
WifiMacHeader::GetName (void) const
|
||||
TypeId
|
||||
WifiMacHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return "802.11";
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void
|
||||
WifiMacHeader::PrintFrameControl (std::ostream &os) const
|
||||
{
|
||||
os << "("
|
||||
<< "ToDS=" << m_ctrlToDs << ", FromDS=" << m_ctrlFromDs
|
||||
os << "ToDS=" << m_ctrlToDs << ", FromDS=" << m_ctrlFromDs
|
||||
<< ", MoreFrag=" << m_ctrlMoreFrag << ", Retry=" << m_ctrlRetry
|
||||
<< ", MoreData=" << m_ctrlMoreData
|
||||
<< ")";
|
||||
;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -65,14 +65,16 @@ enum WifiMacType_e {
|
||||
class WifiMacHeader : public Header
|
||||
{
|
||||
public:
|
||||
|
||||
WifiMacHeader ();
|
||||
~WifiMacHeader ();
|
||||
static uint32_t GetUid (void);
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
|
||||
void SetAssocReq (void);
|
||||
|
||||
@@ -22,23 +22,27 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (WifiMacTrailer);
|
||||
|
||||
WifiMacTrailer::WifiMacTrailer ()
|
||||
{}
|
||||
|
||||
WifiMacTrailer::~WifiMacTrailer ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
WifiMacTrailer::GetUid (void)
|
||||
TypeId
|
||||
WifiMacTrailer::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<WifiMacTrailer> ("WifiMacTrailer.ns3.inria.fr");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::WifiMacTrailer")
|
||||
.SetParent<Trailer> ()
|
||||
.AddConstructor<WifiMacTrailer> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
std::string
|
||||
WifiMacTrailer::GetName (void) const
|
||||
TypeId
|
||||
WifiMacTrailer::GetInstanceTypeId (void) const
|
||||
{
|
||||
return "802.11 FCS";
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,12 +31,12 @@ public:
|
||||
WifiMacTrailer ();
|
||||
~WifiMacTrailer ();
|
||||
|
||||
static uint32_t GetUid (void);
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -302,10 +302,10 @@ WifiNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
|
||||
void
|
||||
WifiNetDevice::ForwardUp (Ptr<Packet> packet, const Mac48Address &from)
|
||||
{
|
||||
m_rxLogger (packet, from);
|
||||
LlcSnapHeader llc;
|
||||
packet->RemoveHeader (llc);
|
||||
m_forwardUp (this, packet, llc.GetType (), from);
|
||||
m_rxLogger (packet, from);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "ns3/random-variable.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/object-base.h"
|
||||
#include "ns3/double.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/enum.h"
|
||||
@@ -78,7 +77,7 @@ WifiPhyListener::~WifiPhyListener ()
|
||||
* Phy event class
|
||||
****************************************************************/
|
||||
|
||||
class RxEvent : public ObjectBase
|
||||
class RxEvent
|
||||
{
|
||||
public:
|
||||
RxEvent (uint32_t size, WifiMode payloadMode,
|
||||
@@ -236,6 +235,14 @@ WifiPhy::GetTypeId (void)
|
||||
.AddTraceSource ("State",
|
||||
"The WifiPhy state",
|
||||
MakeTraceSourceAccessor (&WifiPhy::m_stateLogger))
|
||||
.AddTraceSource ("RxOk",
|
||||
"A packet has been received successfully.",
|
||||
MakeTraceSourceAccessor (&WifiPhy::m_rxOkTrace))
|
||||
.AddTraceSource ("RxError",
|
||||
"A packet has been received unsuccessfully.",
|
||||
MakeTraceSourceAccessor (&WifiPhy::m_rxErrorTrace))
|
||||
.AddTraceSource ("Tx", "Packet transmission is starting.",
|
||||
MakeTraceSourceAccessor (&WifiPhy::m_txTrace))
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -473,6 +480,7 @@ WifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble pre
|
||||
*/
|
||||
NS_ASSERT (!IsStateTx ());
|
||||
|
||||
m_txTrace (packet, txMode, preamble, txPower);
|
||||
Time txDuration = CalculateTxDuration (packet->GetSize (), txMode, preamble);
|
||||
NotifyTxStart (txDuration);
|
||||
SwitchToTx (txDuration);
|
||||
@@ -1342,6 +1350,7 @@ WifiPhy::EndSync (Ptr<Packet> packet, Ptr<RxEvent> event)
|
||||
{
|
||||
NotifySyncEndOk ();
|
||||
SwitchFromSync ();
|
||||
m_rxOkTrace (packet, snr, event->GetPayloadMode (), event->GetPreambleType ());
|
||||
m_syncOkCallback (packet, snr, event->GetPayloadMode (), event->GetPreambleType ());
|
||||
}
|
||||
else
|
||||
@@ -1349,6 +1358,7 @@ WifiPhy::EndSync (Ptr<Packet> packet, Ptr<RxEvent> event)
|
||||
/* failure. */
|
||||
NotifySyncEndError ();
|
||||
SwitchFromSync ();
|
||||
m_rxErrorTrace (packet, snr);
|
||||
m_syncErrorCallback (packet, snr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +345,9 @@ private:
|
||||
Ptr<WifiChannel> m_channel;
|
||||
SyncOkCallback m_syncOkCallback;
|
||||
SyncErrorCallback m_syncErrorCallback;
|
||||
TracedCallback<Ptr<const Packet>, double, WifiMode, enum WifiPreamble> m_rxOkTrace;
|
||||
TracedCallback<Ptr<const Packet>, double> m_rxErrorTrace;
|
||||
TracedCallback<Ptr<const Packet>,WifiMode,WifiPreamble,uint8_t> m_txTrace;
|
||||
Modes m_modes;
|
||||
Listeners m_listeners;
|
||||
EventId m_endSyncEvent;
|
||||
|
||||
@@ -55,6 +55,7 @@ CsmaHelper::Build (const NodeContainer &c, Ptr<CsmaChannel> channel)
|
||||
{
|
||||
Ptr<Node> node = *i;
|
||||
Ptr<CsmaNetDevice> device = m_deviceFactory.Create<CsmaNetDevice> ();
|
||||
device->SetAddress (Mac48Address::Allocate ());
|
||||
node->AddDevice (device);
|
||||
Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
|
||||
device->AddQueue (queue);
|
||||
|
||||
@@ -48,10 +48,12 @@ PointToPointHelper::Build (Ptr<Node> a, Ptr<Node> b)
|
||||
NetDeviceContainer container;
|
||||
|
||||
Ptr<PointToPointNetDevice> devA = CreateObject<PointToPointNetDevice> ();
|
||||
devA->SetAddress (Mac48Address::Allocate ());
|
||||
a->AddDevice (devA);
|
||||
Ptr<Queue> queueA = m_queueFactory.Create<Queue> ();
|
||||
devA->AddQueue (queueA);
|
||||
Ptr<PointToPointNetDevice> devB = CreateObject<PointToPointNetDevice> ();
|
||||
devB->SetAddress (Mac48Address::Allocate ());
|
||||
b->AddDevice (devB);
|
||||
Ptr<Queue> queueB = m_queueFactory.Create<Queue> ();
|
||||
devB->AddQueue (queueB);
|
||||
|
||||
@@ -110,6 +110,7 @@ WifiHelper::Build (NodeContainer c, Ptr<WifiChannel> channel) const
|
||||
Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
|
||||
Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
|
||||
Ptr<WifiPhy> phy = m_phy.Create<WifiPhy> ();
|
||||
mac->SetAddress (Mac48Address::Allocate ());
|
||||
device->SetMac (mac);
|
||||
device->SetPhy (phy);
|
||||
device->SetRemoteStationManager (manager);
|
||||
|
||||
@@ -25,14 +25,7 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_HEADER_ENSURE_REGISTERED (ArpHeader);
|
||||
|
||||
uint32_t
|
||||
ArpHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<ArpHeader> ("ArpHeader.ns3");
|
||||
return uid;
|
||||
}
|
||||
NS_OBJECT_ENSURE_REGISTERED (ArpHeader);
|
||||
|
||||
void
|
||||
ArpHeader::SetRequest (Address sourceHardwareAddress,
|
||||
@@ -89,35 +82,40 @@ ArpHeader::GetDestinationIpv4Address (void)
|
||||
return m_ipv4Dest;
|
||||
}
|
||||
|
||||
std::string
|
||||
ArpHeader::GetName (void) const
|
||||
{
|
||||
return "ARP";
|
||||
}
|
||||
|
||||
TypeId
|
||||
ArpHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::ArpHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<ArpHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
ArpHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
void
|
||||
ArpHeader::Print (std::ostream &os) const
|
||||
{
|
||||
if (IsRequest ())
|
||||
{
|
||||
os << "("
|
||||
<< "request "
|
||||
os << "request "
|
||||
<< "source mac: " << m_macSource << " "
|
||||
<< "source ipv4: " << m_ipv4Source << " "
|
||||
<< "dest ipv4: " << m_ipv4Dest
|
||||
<< ")"
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ASSERT (IsReply ());
|
||||
os << "("
|
||||
<< "reply "
|
||||
os << "reply "
|
||||
<< "source mac: " << m_macSource << " "
|
||||
<< "source ipv4: " << m_ipv4Source << " "
|
||||
<< "dest mac: " << m_macDest << " "
|
||||
<< "dest ipv4: " <<m_ipv4Dest
|
||||
<< ")"
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ namespace ns3 {
|
||||
class ArpHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
void SetRequest (Address sourceHardwareAddress,
|
||||
Ipv4Address sourceProtocolAddress,
|
||||
Address destinationHardwareAddress,
|
||||
@@ -51,11 +49,12 @@ public:
|
||||
Ipv4Address GetSourceIpv4Address (void);
|
||||
Ipv4Address GetDestinationIpv4Address (void);
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
enum ArpType_e {
|
||||
ARP_TYPE_REQUEST = 1,
|
||||
|
||||
@@ -28,17 +28,10 @@ NS_LOG_COMPONENT_DEFINE ("Ipv4Header");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_HEADER_ENSURE_REGISTERED (Ipv4Header);
|
||||
NS_OBJECT_ENSURE_REGISTERED (Ipv4Header);
|
||||
|
||||
bool Ipv4Header::m_calcChecksum = false;
|
||||
|
||||
uint32_t
|
||||
Ipv4Header::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<Ipv4Header> ("Ipv4Header.ns3");
|
||||
return uid;
|
||||
}
|
||||
|
||||
Ipv4Header::Ipv4Header ()
|
||||
: m_payloadSize (0),
|
||||
m_identification (0),
|
||||
@@ -186,12 +179,21 @@ Ipv4Header::IsChecksumOk (void) const
|
||||
return m_goodChecksum;
|
||||
}
|
||||
|
||||
std::string
|
||||
Ipv4Header::GetName (void) const
|
||||
{
|
||||
return "IPV4";
|
||||
}
|
||||
|
||||
TypeId
|
||||
Ipv4Header::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Ipv4Header")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<Ipv4Header> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
Ipv4Header::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
void
|
||||
Ipv4Header::Print (std::ostream &os) const
|
||||
{
|
||||
@@ -218,14 +220,13 @@ Ipv4Header::Print (std::ostream &os) const
|
||||
{
|
||||
flags = "XX";
|
||||
}
|
||||
os << "("
|
||||
<< "tos 0x" << std::hex << m_tos << std::dec << " "
|
||||
os << "tos 0x" << std::hex << m_tos << std::dec << " "
|
||||
<< "ttl " << m_ttl << " "
|
||||
<< "id " << m_identification << " "
|
||||
<< "offset " << m_fragmentOffset << " "
|
||||
<< "flags [" << flags << "] "
|
||||
<< "length: " << (m_payloadSize + 5 * 4)
|
||||
<< ") "
|
||||
<< " "
|
||||
<< m_source << " > " << m_destination
|
||||
;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ namespace ns3 {
|
||||
class Ipv4Header : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
/**
|
||||
* \brief Construct a null IPv4 header
|
||||
*/
|
||||
@@ -140,11 +139,12 @@ public:
|
||||
*/
|
||||
bool IsChecksumOk (void) const;
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
|
||||
enum FlagsE {
|
||||
|
||||
@@ -26,17 +26,10 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_HEADER_ENSURE_REGISTERED (TcpHeader);
|
||||
NS_OBJECT_ENSURE_REGISTERED (TcpHeader);
|
||||
|
||||
bool TcpHeader::m_calcChecksum = false;
|
||||
|
||||
uint32_t
|
||||
TcpHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<TcpHeader> ("TcpHeader.ns3");
|
||||
return uid;
|
||||
}
|
||||
|
||||
TcpHeader::TcpHeader ()
|
||||
: m_sourcePort (0),
|
||||
m_destinationPort (0),
|
||||
@@ -141,12 +134,20 @@ TcpHeader::InitializeChecksum (Ipv4Address source,
|
||||
//XXX requires peeking into IP to get length of the TCP segment
|
||||
}
|
||||
|
||||
std::string
|
||||
TcpHeader::GetName (void) const
|
||||
TypeId
|
||||
TcpHeader::GetTypeId (void)
|
||||
{
|
||||
return "TCP";
|
||||
static TypeId tid = TypeId ("ns3::TcpHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<TcpHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
TcpHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void TcpHeader::Print (std::ostream &os) const
|
||||
{
|
||||
//XXX
|
||||
|
||||
@@ -30,10 +30,9 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class TcpHeader : public Header {
|
||||
class TcpHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
TcpHeader ();
|
||||
virtual ~TcpHeader ();
|
||||
|
||||
@@ -136,11 +135,12 @@ public:
|
||||
typedef enum { NONE = 0, FIN = 1, SYN = 2, RST = 4, PSH = 8, ACK = 16,
|
||||
URG = 32} Flags_t;
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
uint16_t m_sourcePort;
|
||||
|
||||
@@ -24,17 +24,10 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_HEADER_ENSURE_REGISTERED (UdpHeader);
|
||||
NS_OBJECT_ENSURE_REGISTERED (UdpHeader);
|
||||
|
||||
bool UdpHeader::m_calcChecksum = false;
|
||||
|
||||
uint32_t
|
||||
UdpHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<UdpHeader> ("UdpHeader.ns3");
|
||||
return uid;
|
||||
}
|
||||
|
||||
/* The magic values below are used only for debugging.
|
||||
* They can be used to easily detect memory corruption
|
||||
* problems so you can see the patterns in memory.
|
||||
@@ -100,18 +93,25 @@ UdpHeader::InitializeChecksum (Ipv4Address source,
|
||||
m_initialChecksum = Ipv4ChecksumCalculate (0, buf, 12);
|
||||
}
|
||||
|
||||
std::string
|
||||
UdpHeader::GetName (void) const
|
||||
TypeId
|
||||
UdpHeader::GetTypeId (void)
|
||||
{
|
||||
return "UDP";
|
||||
static TypeId tid = TypeId ("ns3::UdpHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<UdpHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
UdpHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void
|
||||
UdpHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "("
|
||||
<< "length: " << m_payloadSize + GetSerializedSize ()
|
||||
<< ") "
|
||||
os << "length: " << m_payloadSize + GetSerializedSize ()
|
||||
<< " "
|
||||
<< m_sourcePort << " > " << m_destinationPort
|
||||
;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace ns3 {
|
||||
class UdpHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
/**
|
||||
* \brief Constructor
|
||||
@@ -84,11 +83,12 @@ public:
|
||||
Ipv4Address destination,
|
||||
uint8_t protocol);
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
private:
|
||||
uint16_t m_sourcePort;
|
||||
|
||||
@@ -31,14 +31,7 @@ NS_LOG_COMPONENT_DEFINE ("EthernetHeader");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_HEADER_ENSURE_REGISTERED (EthernetHeader);
|
||||
|
||||
uint32_t
|
||||
EthernetHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<EthernetHeader> ("EthernetHeader.ns3");
|
||||
return uid;
|
||||
}
|
||||
NS_OBJECT_ENSURE_REGISTERED (EthernetHeader);
|
||||
|
||||
EthernetHeader::EthernetHeader (bool hasPreamble)
|
||||
: m_enPreambleSfd (hasPreamble),
|
||||
@@ -106,19 +99,28 @@ EthernetHeader::GetHeaderSize (void) const
|
||||
return GetSerializedSize();
|
||||
}
|
||||
|
||||
std::string
|
||||
EthernetHeader::GetName (void) const
|
||||
{
|
||||
return "ETHERNET";
|
||||
}
|
||||
|
||||
TypeId
|
||||
EthernetHeader::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::EthernetHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<EthernetHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
EthernetHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
void
|
||||
EthernetHeader::Print (std::ostream &os) const
|
||||
{
|
||||
// ethernet, right ?
|
||||
if (m_enPreambleSfd)
|
||||
{
|
||||
os << " preamble/sfd=" << m_preambleSfd << ",";
|
||||
os << "preamble/sfd=" << m_preambleSfd << ",";
|
||||
}
|
||||
|
||||
os << " length/type=0x" << std::hex << m_lengthType << std::dec
|
||||
|
||||
@@ -49,7 +49,6 @@ namespace ns3 {
|
||||
class EthernetHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
/**
|
||||
* \brief Construct a null ethernet header
|
||||
@@ -103,11 +102,12 @@ public:
|
||||
*/
|
||||
uint32_t GetHeaderSize() const;
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
static const int PREAMBLE_SIZE = 8; /// size of the preamble_sfd header field
|
||||
static const int LENGTH_SIZE = 2; /// size of the length_type header field
|
||||
|
||||
@@ -28,17 +28,10 @@ NS_LOG_COMPONENT_DEFINE ("EthernetTrailer");
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_TRAILER_ENSURE_REGISTERED (EthernetTrailer);
|
||||
NS_OBJECT_ENSURE_REGISTERED (EthernetTrailer);
|
||||
|
||||
bool EthernetTrailer::m_calcFcs = false;
|
||||
|
||||
uint32_t
|
||||
EthernetTrailer::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<EthernetTrailer> ("EthernetTrailer.ns3");
|
||||
return uid;
|
||||
}
|
||||
|
||||
EthernetTrailer::EthernetTrailer ()
|
||||
{
|
||||
Init();
|
||||
@@ -61,7 +54,9 @@ EthernetTrailer::CheckFcs (Ptr<Packet> p) const
|
||||
if (!m_calcFcs)
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_WARN ("FCS calculation is not yet enabled");
|
||||
return false;
|
||||
}
|
||||
@@ -90,16 +85,25 @@ EthernetTrailer::GetTrailerSize (void) const
|
||||
{
|
||||
return GetSerializedSize();
|
||||
}
|
||||
std::string
|
||||
EthernetTrailer::GetName (void) const
|
||||
{
|
||||
return "ETHERNET";
|
||||
}
|
||||
|
||||
TypeId
|
||||
EthernetTrailer::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::EthernetTrailer")
|
||||
.SetParent<Trailer> ()
|
||||
.AddConstructor<EthernetTrailer> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
EthernetTrailer::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
void
|
||||
EthernetTrailer::Print (std::ostream &os) const
|
||||
{
|
||||
os << " fcs=" << m_fcs;
|
||||
os << "fcs=" << m_fcs;
|
||||
}
|
||||
uint32_t
|
||||
EthernetTrailer::GetSerializedSize (void) const
|
||||
|
||||
@@ -39,8 +39,6 @@ class Packet;
|
||||
class EthernetTrailer : public Trailer
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
/**
|
||||
* \brief Construct a null ethernet trailer
|
||||
*/
|
||||
@@ -83,11 +81,12 @@ public:
|
||||
*/
|
||||
uint32_t GetTrailerSize() const;
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator end) const;
|
||||
uint32_t Deserialize (Buffer::Iterator end);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator end) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator end);
|
||||
private:
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,14 +25,7 @@
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_HEADER_ENSURE_REGISTERED (LlcSnapHeader);
|
||||
|
||||
uint32_t
|
||||
LlcSnapHeader::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<LlcSnapHeader> ("LlcSnapHeader.ns3");
|
||||
return uid;
|
||||
}
|
||||
NS_OBJECT_ENSURE_REGISTERED (LlcSnapHeader);
|
||||
|
||||
LlcSnapHeader::LlcSnapHeader ()
|
||||
{}
|
||||
@@ -54,20 +47,27 @@ LlcSnapHeader::GetSerializedSize (void) const
|
||||
return 1 + 1 + 1 + 3 + 2;
|
||||
}
|
||||
|
||||
std::string
|
||||
LlcSnapHeader::GetName (void) const
|
||||
TypeId
|
||||
LlcSnapHeader::GetTypeId (void)
|
||||
{
|
||||
return "LLCSNAP";
|
||||
static TypeId tid = TypeId ("ns3::LlcSnapHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<LlcSnapHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
LlcSnapHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
void
|
||||
LlcSnapHeader::Print (std::ostream &os) const
|
||||
{
|
||||
os << "(type 0x";
|
||||
os << "type 0x";
|
||||
os.setf (std::ios::hex, std::ios::basefield);
|
||||
os << m_etherType;
|
||||
os.setf (std::ios::dec, std::ios::basefield);
|
||||
os << ")";
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -31,18 +31,17 @@ namespace ns3 {
|
||||
class LlcSnapHeader : public Header
|
||||
{
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
LlcSnapHeader ();
|
||||
|
||||
void SetType (uint16_t type);
|
||||
uint16_t GetType (void);
|
||||
|
||||
std::string GetName (void) const;
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
uint16_t m_etherType;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace olsr {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("OlsrHeader");
|
||||
|
||||
|
||||
/// Scaling factor used in RFC 3626.
|
||||
#define OLSR_C 0.0625
|
||||
|
||||
@@ -95,18 +94,27 @@ EmfToSeconds (uint8_t olsrFormat)
|
||||
|
||||
// ---------------- OLSR Packet -------------------------------
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (PacketHeader);
|
||||
|
||||
PacketHeader::PacketHeader ()
|
||||
{}
|
||||
|
||||
PacketHeader::~PacketHeader ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
PacketHeader::GetUid (void)
|
||||
TypeId
|
||||
PacketHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<PacketHeader>
|
||||
("PacketHeader.nsnam.org");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::olsr::PacketHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<PacketHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
PacketHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -141,6 +149,8 @@ PacketHeader::Deserialize (Buffer::Iterator start)
|
||||
|
||||
// ---------------- OLSR Message -------------------------------
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (MessageHeader);
|
||||
|
||||
MessageHeader::MessageHeader ()
|
||||
: m_messageType (MessageHeader::MessageType (0))
|
||||
{}
|
||||
@@ -148,12 +158,19 @@ MessageHeader::MessageHeader ()
|
||||
MessageHeader::~MessageHeader ()
|
||||
{}
|
||||
|
||||
uint32_t
|
||||
MessageHeader::GetUid (void)
|
||||
TypeId
|
||||
MessageHeader::GetTypeId (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<MessageHeader>
|
||||
("MessageHeader.nsnam.org");
|
||||
return uid;
|
||||
static TypeId tid = TypeId ("ns3::olsr::MessageHeader")
|
||||
.SetParent<Header> ()
|
||||
.AddConstructor<MessageHeader> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
TypeId
|
||||
MessageHeader::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
||||
@@ -95,12 +95,12 @@ private:
|
||||
uint16_t m_packetSequenceNumber;
|
||||
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
virtual std::string GetName (void) const { return "OlsrPacket"; }
|
||||
};
|
||||
|
||||
|
||||
@@ -200,12 +200,12 @@ private:
|
||||
uint16_t m_messageSize;
|
||||
|
||||
public:
|
||||
static uint32_t GetUid (void);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
virtual std::string GetName (void) const { return "OlsrMessage"; }
|
||||
|
||||
// 5.1. MID Message Format
|
||||
//
|
||||
|
||||
@@ -21,11 +21,10 @@
|
||||
#define EVENT_IMPL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ns3/object-base.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class EventImpl : public ObjectBase
|
||||
class EventImpl
|
||||
{
|
||||
public:
|
||||
EventImpl ();
|
||||
|
||||
@@ -595,7 +595,8 @@ static void cber5 (const int &, const int &, const int &, const int &, const int
|
||||
{}
|
||||
|
||||
|
||||
class SimulatorTests : public Test, public ObjectBase {
|
||||
class SimulatorTests : public Test
|
||||
{
|
||||
public:
|
||||
SimulatorTests ();
|
||||
// only here for testing of Ptr<>
|
||||
|
||||
@@ -33,13 +33,12 @@ public:
|
||||
BenchHeader ();
|
||||
bool IsOk (void) const;
|
||||
|
||||
static uint32_t GetUid (void);
|
||||
|
||||
static std::string GetName (void);
|
||||
void Print (std::ostream &os) const;
|
||||
uint32_t GetSerializedSize (void) const;
|
||||
void Serialize (Buffer::Iterator start) const;
|
||||
uint32_t Deserialize (Buffer::Iterator start);
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
virtual void Print (std::ostream &os) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
private:
|
||||
bool m_ok;
|
||||
};
|
||||
@@ -57,20 +56,21 @@ BenchHeader<N>::IsOk (void) const
|
||||
}
|
||||
|
||||
template <int N>
|
||||
uint32_t
|
||||
BenchHeader<N>::GetUid (void)
|
||||
{
|
||||
static uint32_t uid = AllocateUid<BenchHeader<N> > (GetName ());
|
||||
return uid;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
std::string
|
||||
BenchHeader<N>::GetName (void)
|
||||
TypeId
|
||||
BenchHeader<N>::GetTypeId (void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "BenchHeader" << N;
|
||||
return oss.str ();
|
||||
oss << "ns3::BenchHeader<"<<N<<">";
|
||||
static TypeId tid = TypeId (oss.str ().c_str ())
|
||||
.SetParent<Header> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
template <int N>
|
||||
TypeId
|
||||
BenchHeader<N>::GetInstanceTypeId (void) const
|
||||
{
|
||||
return GetTypeId ();
|
||||
}
|
||||
|
||||
template <int N>
|
||||
|
||||
Reference in New Issue
Block a user