doxygen improvements to Packet, Tags, and Headers/Trailers
This commit is contained in:
123
samples/main-header.cc
Normal file
123
samples/main-header.cc
Normal file
@@ -0,0 +1,123 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/header.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/* A sample Header implementation
|
||||
*/
|
||||
class MyHeader : public Header
|
||||
{
|
||||
public:
|
||||
static const char *GetUid (void);
|
||||
|
||||
MyHeader ();
|
||||
virtual ~MyHeader ();
|
||||
|
||||
void SetData (uint16_t data);
|
||||
uint16_t GetData (void) const;
|
||||
private:
|
||||
virtual std::string DoGetName (void) const;
|
||||
virtual void PrintTo (std::ostream &os) const;
|
||||
virtual void SerializeTo (Buffer::Iterator start) const;
|
||||
virtual uint32_t DeserializeFrom (Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
uint16_t m_data;
|
||||
};
|
||||
|
||||
MyHeader::MyHeader ()
|
||||
{
|
||||
// we must provide a public default constructor,
|
||||
// implicit or explicit, but never private.
|
||||
}
|
||||
MyHeader::~MyHeader ()
|
||||
{}
|
||||
|
||||
const char *
|
||||
MyHeader::GetUid (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.
|
||||
return "MyHeader.test.nsnam.org";
|
||||
}
|
||||
|
||||
std::string
|
||||
MyHeader::DoGetName (void) const
|
||||
{
|
||||
// This string is used to identify the type of
|
||||
// my header by the packet printing routines.
|
||||
return "MYHEADER";
|
||||
}
|
||||
void
|
||||
MyHeader::PrintTo (std::ostream &os) const
|
||||
{
|
||||
// This method is invoked by the packet printing
|
||||
// routines to print the content of my header.
|
||||
os << "data=" << m_data << std::endl;
|
||||
}
|
||||
uint32_t
|
||||
MyHeader::GetSerializedSize (void) const
|
||||
{
|
||||
// we reserve 2 bytes for our header.
|
||||
return 2;
|
||||
}
|
||||
void
|
||||
MyHeader::SerializeTo (Buffer::Iterator start) const
|
||||
{
|
||||
// we can serialize two bytes at the start of the buffer.
|
||||
// we write them in network byte order.
|
||||
start.WriteHtonU16 (m_data);
|
||||
}
|
||||
uint32_t
|
||||
MyHeader::DeserializeFrom (Buffer::Iterator start)
|
||||
{
|
||||
// we can deserialize two bytes from the start of the buffer.
|
||||
// we read them in network byte order and store them
|
||||
// in host byte order.
|
||||
m_data = start.ReadNtohU16 ();
|
||||
|
||||
// we return the number of bytes effectively read.
|
||||
return 2;
|
||||
}
|
||||
|
||||
void
|
||||
MyHeader::SetData (uint16_t data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
uint16_t
|
||||
MyHeader::GetData (void) const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
// instantiate a header.
|
||||
MyHeader sourceHeader;
|
||||
sourceHeader.SetData (2);
|
||||
|
||||
// instantiate a packet
|
||||
Packet p;
|
||||
// and store my header into the packet.
|
||||
p.AddHeader (sourceHeader);
|
||||
|
||||
// print the content of my packet on the standard output.
|
||||
p.Print (std::cout);
|
||||
|
||||
// you can now remove the header from the packet:
|
||||
MyHeader destinationHeader;
|
||||
p.RemoveHeader (destinationHeader);
|
||||
|
||||
// and check that the destination and source
|
||||
// headers contain the same values.
|
||||
NS_ASSERT (sourceHeader.GetData () == destinationHeader.GetData ());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/header.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
/* A sample Header implementation
|
||||
*/
|
||||
class MyHeader : public Header
|
||||
{
|
||||
public:
|
||||
static const char *GetUid (void);
|
||||
|
||||
MyHeader ();
|
||||
virtual ~MyHeader ();
|
||||
|
||||
void SetData (uint16_t data);
|
||||
uint16_t GetData (void) const;
|
||||
private:
|
||||
virtual std::string DoGetName (void) const;
|
||||
virtual void PrintTo (std::ostream &os) const;
|
||||
virtual void SerializeTo (Buffer::Iterator start) const;
|
||||
virtual uint32_t DeserializeFrom (Buffer::Iterator start);
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
uint16_t m_data;
|
||||
};
|
||||
|
||||
const char *
|
||||
MyHeader::GetUid (void)
|
||||
{
|
||||
// make sure the string is really unique.
|
||||
return "MyHeader.test.nsnam.org";
|
||||
}
|
||||
|
||||
MyHeader::MyHeader ()
|
||||
{}
|
||||
MyHeader::~MyHeader ()
|
||||
{}
|
||||
std::string
|
||||
MyHeader::DoGetName (void) const
|
||||
{
|
||||
return "MyHeader";
|
||||
}
|
||||
void
|
||||
MyHeader::PrintTo (std::ostream &os) const
|
||||
{
|
||||
os << "MyHeader data=" << m_data << std::endl;
|
||||
}
|
||||
uint32_t
|
||||
MyHeader::GetSerializedSize (void) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
void
|
||||
MyHeader::SerializeTo (Buffer::Iterator start) const
|
||||
{
|
||||
// serialize in head of buffer
|
||||
start.WriteHtonU16 (m_data);
|
||||
}
|
||||
uint32_t
|
||||
MyHeader::DeserializeFrom (Buffer::Iterator start)
|
||||
{
|
||||
// deserialize from head of buffer
|
||||
m_data = start.ReadNtohU16 ();
|
||||
return GetSerializedSize ();
|
||||
}
|
||||
|
||||
void
|
||||
MyHeader::SetData (uint16_t data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
uint16_t
|
||||
MyHeader::GetData (void) const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
/* A sample Tag implementation
|
||||
*/
|
||||
class MyTag
|
||||
{
|
||||
public:
|
||||
static const char *GetUid (void) {return "MyTag.test.nsnam.org";}
|
||||
void Print (std::ostream &os) const {}
|
||||
uint32_t GetSerializedSize (void) const {return 0;}
|
||||
void Serialize (Buffer::Iterator i) const {}
|
||||
uint32_t Deserialize (Buffer::Iterator i) {return 0;}
|
||||
|
||||
uint16_t m_streamId;
|
||||
};
|
||||
|
||||
static void
|
||||
Receive (Packet p)
|
||||
{
|
||||
MyHeader my;
|
||||
p.RemoveHeader (my);
|
||||
std::cout << "received data=" << my.GetData () << std::endl;
|
||||
struct MyTag myTag;
|
||||
p.PeekTag (myTag);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
Packet p;
|
||||
MyHeader my;
|
||||
my.SetData (2);
|
||||
std::cout << "send data=2" << std::endl;
|
||||
p.AddHeader (my);
|
||||
struct MyTag myTag;
|
||||
myTag.m_streamId = 5;
|
||||
p.AddTag (myTag);
|
||||
Receive (p);
|
||||
return 0;
|
||||
}
|
||||
@@ -14,7 +14,7 @@ def build(bld):
|
||||
obj = create_ns_prog('main-ptr', 'main-ptr.cc')
|
||||
#obj = create_ns_prog('main-trace', 'main-trace.cc')
|
||||
obj = create_ns_prog('main-simulator', 'main-simulator.cc')
|
||||
obj = create_ns_prog('main-packet', 'main-packet.cc')
|
||||
obj = create_ns_prog('main-header', 'main-header.cc')
|
||||
obj = create_ns_prog('main-test', 'main-test.cc')
|
||||
obj = create_ns_prog('main-simple', 'main-simple.cc',
|
||||
deps=['node', 'internet-node', 'applications'])
|
||||
|
||||
@@ -36,6 +36,29 @@ namespace ns3 {
|
||||
* - ns3::Header::DeserializeFrom
|
||||
* - ns3::Header::GetSerializedSize
|
||||
* - ns3::Header::PrintTo
|
||||
* - ns3::Header::DoGetName
|
||||
*
|
||||
* Each header must also make sure that:
|
||||
* - it defines a public default constructor
|
||||
* - it defines a public static method named GetUid which returns a string.
|
||||
*
|
||||
* The latter should look like the following to ensure that
|
||||
* every header returns a unique string.
|
||||
* \code
|
||||
* class MyHeader : public Header
|
||||
* {
|
||||
* public:
|
||||
* static const char *GetUid (void);
|
||||
* };
|
||||
*
|
||||
* const char *MyHeader::GetUid (void)
|
||||
* {
|
||||
* return "MyHeader.unique.prefix";
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Sample code which shows how to create a new Header, and how to use it,
|
||||
* is shown in the sample file samples/main-header.cc
|
||||
*/
|
||||
class Header : public Chunk {
|
||||
public:
|
||||
|
||||
@@ -58,21 +58,19 @@ class PacketPrinter;
|
||||
* were serialized in the byte buffer. The maintenance of metadata is
|
||||
* optional and disabled by default. To enable it, you must call
|
||||
* Packet::EnableMetadata and this will allow you to get non-empty
|
||||
* output from Packet::Print and Packet::PrintDefault.
|
||||
* output from Packet::Print and Packet::Print.
|
||||
*
|
||||
* Implementing a new type of Header or Trailer for a new protocol is
|
||||
* pretty easy and is a matter of creating a subclass of the ns3::Header
|
||||
* or of the ns3::Trailer base class, and implementing the 4 pure virtual
|
||||
* or of the ns3::Trailer base class, and implementing the 5 pure virtual
|
||||
* methods defined in either of the two base classes. Users _must_
|
||||
* also implement a static public method named GetUid which is
|
||||
* expected to return a unique string which uniquely identifies the
|
||||
* user's new header or trailer.
|
||||
*
|
||||
* Sample code which shows how to create a new Header, and how to use it,
|
||||
* is shown in the sample file samples/main-header.cc
|
||||
* also make sure that they class defines a public default constructor and
|
||||
* a public method named GetUid, as documented in the ns3::Header and ns::Trailer
|
||||
* API documentations.
|
||||
*
|
||||
* Implementing a new type of Tag requires roughly the same amount of
|
||||
* work:
|
||||
* work: users must implement a total of 6 methods which are described in
|
||||
* the ns3::Tags API documentation.
|
||||
*
|
||||
* The current implementation of the byte buffers and tag list is based
|
||||
* on COW (Copy On Write. An introduction to COW can be found in Scott
|
||||
|
||||
@@ -36,6 +36,26 @@ namespace ns3 {
|
||||
* - ns3::Trailer::DeserializeFrom
|
||||
* - ns3::Trailer::GetSerializedSize
|
||||
* - ns3::Trailer::PrintTo
|
||||
* - ns3::Trailer::DoGetName
|
||||
*
|
||||
* Each trailer must also make sure that:
|
||||
* - it defines a public default constructor
|
||||
* - it defines a public static method named GetUid which returns a string.
|
||||
*
|
||||
* The latter should look like the following to ensure that
|
||||
* every trailer returns a unique string.
|
||||
* \code
|
||||
* class MyTrailer : public Header
|
||||
* {
|
||||
* public:
|
||||
* static const char *GetUid (void);
|
||||
* };
|
||||
*
|
||||
* const char *MyTrailer::GetUid (void)
|
||||
* {
|
||||
* return "MyTrailer.unique.prefix";
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Note that the SerializeTo and DeserializeFrom methods behave
|
||||
* in a way which might seem surprising to users: the input iterator
|
||||
|
||||
Reference in New Issue
Block a user