HOWTOs are now on the wiki
authorTom Henderson <tomh@tomh.org>
Fri, 13 Nov 2009 09:37:52 -0800
changeset 5516 57091d4dcf6f
parent 5515 6e8f48fb0372
child 5517 71138d7e477c
HOWTOs are now on the wiki
doc/howtos/howtos-application.h
doc/howtos/howtos-callbacks.h
doc/howtos/howtos-net-device.h
doc/howtos/howtos-packet-header.h
doc/howtos/howtos.h
doc/main.h
--- a/doc/howtos/howtos-application.h	Fri Nov 13 09:19:06 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*!
-  \page application How to create a traffic generator ?
-  \anchor howtos-application
-
-  <b>Question:</b> How do I create a new traffic generator ?
-
-  <b>Answer:</b> It is possible to instanciate \ref ns3::Packet "Packet"
-  objects, schedule events, and call functions from any piece of code
-  in ns-3 so, technically, there is no single answer to the question of
-  how we can write a new traffic generator. However, the 
-  \ref ns3::Socket "Socket" API was really designed to be the single 
-  point of entry for traffic generators or traffic analysers and the
-  \ref ns3::Application "Application" class was designed to hold
-  together any number of sockets.
-
-  Implementing a new traffic generator thus boils down to:
-- implementing a new subclass of the \ref ns3::Application "Application"
-  base class
-- instanciate one or many sockets within that application
-- start scheduling events when \ref ns3::Application::StartApplication "StartApplication"
-  is called
-- stop scheduling events when \ref ns3::Application::StopApplication "StopApplication" 
-  is called
-- create packets and send them over one or many sockets in each event
-
-The following "random" generator generates packets separated by a random
-delay and with a random size.
-
-\code
-class RandomGenerator : public Application
-{
-public:
-  RandomGenerator ();
-  void SetDelay (RandomVariable delay);
-  void SetSize (RandomVariable size);
-  void SetRemote (std::string socketType, 
-                  Address remote);
-private:
-  virtual void StartApplication (void);
-  virtual void StopApplication (void);
-  void DoGenerate (void);
-
-  RandomVariable m_delay;
-  RandomVariable m_size;
-  Ptr<Socket> m_socket;
-};
-\endcode
-
-The socket is created in the SetRemote method:
-\code
-void 
-RandomGenerator::SetRemote (std::string socketType, 
-                            Address remote)
-{
-  TypeId tid = TypeId::LookupByName (socketType);
-  m_socket = Socket::CreateSocket (GetNode (), tid);
-  m_socket->Bind ();
-  m_socket->ShutdownRecv ();
-  m_socket->Connect (remote);
-}
-\endcode
-While the the crux of the logic is located in the DoGenerate method
-which is called from within StartApplication:
-\code
-void
-RandomGenerator::DoGenerate (void)
-{
-  m_next = Simulator::Schedule (Seconds (m_delay.GetValue ()), 
-				&RandomGenerator::DoGenerate, this);
-  Ptr<Packet> p = Create<Packet> (m_size.GetIntValue ());
-  m_socket->Send (p);
-}
-\endcode
-
-To make that application more integrated in ns-3, it needs an associated 
-helper class:
-\code
-class RandomAppHelper
-{
-public:
-  RandomAppHelper (std::string protocol, Address remote);
-  void SetPacketSize (RandomVariable packetSize);
-  void SetDelay (RandomVariable delay);
-  ApplicationContainer Install (NodeContainer nodes);
-private:
-  std::string m_protocol;
-  Address m_remote;
-  RandomVariable m_packetSize;
-  RandomVariable m_delay;
-};
-\endcode
-
-which could be trivially implemented as:
-\code
-ApplicationContainer 
-RandomAppHelper::Install (NodeContainer nodes)
-{
-  ApplicationContainer applications;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
-    {
-      Ptr<RandomAppHelper> app = CreateObject<RandomAppHelper> ();
-      app->SetSize (m_packetSize);
-      app->SetDelay (m_delay);
-      app->SetRemote (m_protocol, m_remote);
-      (*i)->AddApplication (app);
-      applications.Add (app);
-    }
-  return applications;
-}
-\endcode
-
-Despite being functional, this API is not very consistant with the style of 
-the other helper classes, all of which allow you to control the parameters
-of the underlying class through attributes and not explicit setters. The
-following API thus replaces the pair SetPacketSize/SetDelay with a single
-method SetAttribute:
-\code
-class RandomAppHelper
-{
-public:
-  RandomAppHelper (std::string protocol, Address remote);
-  void SetAttribute (std::string name, const AttributeValue &value);
-  ApplicationContainer Install (NodeContainer c);
-private:
-  std::string m_protocol;
-  Address m_remote;
-  ObjectFactory m_factory;
-};
-\endcode
-
-And which can be used as follows:
-\code
-RandomAppHelper app = RandomAppHelper ("ns3::TcpSocketFactory", 
-				       InetSocketAddress (Ipv4Address ("192.168.1.10"), 10));
-app.SetAttribute ("Delay", StringValue ("Constant:2.5"));
-app.SetAttribute ("Size", StringValue ("Constant:2100"));
-app.Install (nodes);
-\endcode
-
-The implementation, in this case, is not necessarily longer but its 
-simplicity hides a lot of behind-the-scenes complexity:
-
-\code
-void 
-RandomAppHelper::SetAttribute (std::string name, const AttributeValue &value)
-{
-  m_factory.Set (name, value);
-}
-ApplicationContainer 
-RandomAppHelper::Install (NodeContainer nodes)
-{
-  ApplicationContainer applications;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
-    {
-      Ptr<RandomAppHelper> app = m_factory.Create<RandomAppHelper> ();
-      app->SetRemote (m_socketType, m_remote);
-      (*i)->AddApplication (app);
-      applications.Add (app);
-    }
-  return applications;
-}
-\endcode
-
-The key difference between this implementation and the previous one
-is that this helper does not handle explicitely the attributes
-delay and packet size. Instead, it stores them in an 
-\ref ns3::ObjectFactory "ObjectFactory" object. This, of course,
-does not work magically, and requires extra support from the
-underlying RandomGenerator class. Specifically, it requires
-that the underlying RandomGenerator defines its attributes
-in its \ref ns3::TypeId "TypeId" in a new public static method:
-
-\code
-class RandomGenerator
-{
-public:
-  static TypeId GetTypeId (void);
-};
-\endcode
-
-The corresponding implementation is shown below:
-
-\code
-TypeId
-RandomGenerator::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("RandomGenerator")
-    .SetParent<Application> ()
-    .AddConstructor<RandomGenerator> ()
-    .AddAttribute ("Delay", "The delay between two packets (s)",
-		   RandomVariableValue (ConstantVariable (1.0)),
-		   MakeRandomVariableAccessor (&RandomGenerator::m_delay),
-		   MakeRandomVariableChecker ())
-    .AddAttribute ("PacketSize", "The size of each packet (bytes)",
-		   RandomVariableValue (ConstantVariable (2000)),
-		   MakeRandomVariableAccessor (&RandomGenerator::m_size),
-		   MakeRandomVariableChecker ())
-    ;
-  return tid;
-}   
-\endcode
-
-*/
--- a/doc/howtos/howtos-callbacks.h	Fri Nov 13 09:19:06 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*!
-\page callbacks Using ns-3 callbacks
-\anchor howtos-callbacks
-
-\section null_callbacks Null Callbacks
-
-<b>Question:</b> The API I am using calls for using a callback (in the 
-function signature), but I do not
-want to provide one.  Is there a way to provide a null callback?
-
-<b>Answer:</b> Use the ns3::MakeNullCallback construct:
-\code
-template<typename R>
-Callback< R, T1, T2, T3, T4, T5, T6 > ns3::MakeNullCallback (void)
-\endcode
-
-Example usage:  The ns3::Socket class uses callbacks to indicate completion
-of events such as a successful TCP connect().  These callbacks are set
-in the following function:
-\code
-  void Socket::SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
-                        Callback<void, Ptr<Socket> > connectionFailed,
-                        Callback<void, Ptr<Socket> > halfClose);
-
-\endcode
-But suppose you do not care about registering a callback for the 
-halfClose event (but you want to register one for the 
-connectionSucceeded and connectionFailed cases).  In that case, you
-can pass a null callback as the third argument.  You just need to
-pass a callback with the matching signature, as follows:
-\code
-  localSocket->SetConnectCallback (
-  MakeCallback (&ConnectionSucceededCallback),
-  MakeCallback (&ConnectionFailedCallback),
-  MakeNullCallback<void, Ptr<Socket> > () );
-\endcode
-
-*/
--- a/doc/howtos/howtos-net-device.h	Fri Nov 13 09:19:06 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*!
-  \page net-device How to create a new OSI layer 1 + 2 implementation ?
-  \anchor howtos-net-device
-
-  <b>Question:</b> How do I integrate a new OSI layer 1 + 2 implementation ?
-
-  <b>Answer:</b> The OSI layers 1 and 2 are represented by the ns3::NetDevice
-  and ns3::Channel classes. To plug transparently in ns-3, a new layer 1+2 model
-  thus simply needs to provide two new subclasses of these two base classes.
-
-  To make that subclassing process easy, two skeleton classes are provided in
-  the src/node directory: simple-net-device.h (ns3::SimpleNetDevice) and 
-  simple-channel.h (ns3::SimpleChannel) implement a broadcast passthru medium 
-  using 48bit MAC addresses without any kind of MAC access algorithm or PHY 
-  layer modeling.
-
-  The ns3::SimpleChannel class is really very simple: it provides
-  an implementation for the ns3::Channel::GetNDevices and ns3::Channel::GetDevice
-  methods defined in the Channel base class and, then defines the channel-specific
-  send and add methods:
-- The Add method is used by SimpleNetDevice::SetChannel to register a new 
-  SimpleNetDevice with its associated channel.
-- The Send method is used by SimpleNetDevice::Send to send a packet over the
-  broadcast medium and ensure that it gets delivered to all associated devices
-  (except the sender).
-
-\code
-class SimpleChannel : public Channel
-{
-public:
-  static TypeId GetTypeId (void);
-  SimpleChannel ();
-
-  void Send (Ptr<Packet> p, uint16_t protocol, Mac48Address to, Mac48Address from,
-	     Ptr<SimpleNetDevice> sender);
-
-  void Add (Ptr<SimpleNetDevice> device);
-
-  // inherited from ns3::Channel
-  virtual uint32_t GetNDevices (void) const;
-  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
-private:
-  std::vector<Ptr<SimpleNetDevice> > m_devices;
-};
-\endcode
-
-The SimpleNetDevice class is also trivial since it implements no special
-MAC-layer processing:
-\code
-class SimpleNetDevice : public NetDevice
-{
-public:
-  static TypeId GetTypeId (void);
-  SimpleNetDevice ();
-
-  void Receive (Ptr<Packet> packet, uint16_t protocol, Mac48Address to, Mac48Address from);
-  void SetChannel (Ptr<SimpleChannel> channel);
-  void SetAddress (Mac48Address address);
-
-  // inherited from NetDevice base class.
-  virtual void SetName(const std::string name);
-  ...
-};
-\endcode
-
-The code below illustrates how the three model-specific methods defined above are
-implemented:
-
-\code
-void 
-SimpleNetDevice::Receive (Ptr<Packet> packet, uint16_t protocol, 
-			  Mac48Address to, Mac48Address from)
-{
-  if (to == m_address || to == Mac48Address::GetBroadcast ())
-    {
-      m_rxCallback (this, packet, protocol, from);
-    }
-}
-void 
-SimpleNetDevice::SetChannel (Ptr<SimpleChannel> channel)
-{
-  m_channel = channel;
-  m_channel->Add (this);
-}
-void 
-SimpleNetDevice::SetAddress (Mac48Address address)
-{
-  m_address = address;
-}
-\endcode
-
-Building a topology with such a device is then a matter of
-instanciating a set of SimpleNetDevice objects connected on a shared
-SimpleChannel:
-\code
-NodeContainer nodes;
-nodes.Create (10);
-Ptr<SimpleChannel> channel = CreateObject<SimpleChannel> ();
-for (uint32_t i = 0; i < nodes.GetN (); ++i)
-  {
-    CreateSimpleDevice (nodes.Get (i), channel);
-  }
-\endcode
-
-With the following CreateSimpleDevice function:
-\code
-static Ptr<SimpleNetDevice>
-CreateSimpleDevice (Ptr<Node> node, Ptr<SimpleChannel> channel)
-{
-  Ptr<SimpleNetDevice> device = CreateObject<SimpleNetDevice> ();
-  device->SetAddress (Mac48Address:Allocate ());
-  device->SetChannel (channel);
-  node->AddDevice (device);
-  return device;
-}
-\endcode
-
-Of course, ultimately, you need to provide a helper class for this new device and channel
-to save each user from having to re-implement their own CreateSimpleDevice helper 
-function:
-
-\code
-class SimpleHelper
-{
-public:
-  NetDeviceContainer Install (NodeContainer nodes, Ptr<SimpleChannel> channel);
-  NetDeviceContainer Install (NodeContainer nodes);
-};
-\endcode
-
-with the following straightforward implementation, inspired by the CreateSimpleDevice 
-function defined above:
-
-\code
-NetDeviceContainer
-SimpleHelper::Install (NodeContainer nodes, Ptr<SimpleChannel> channel)
-{
-  NetDeviceContainer devices;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
-    {
-      Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
-      dev->SetAddress (Mac48Address::Allocate ());
-      dev->SetChannel (channel);
-      (*i)->AddDevice (dev);
-      devices.Add (dev);
-    }
-  return devices;
-}
-NetDeviceContainer
-SimpleHelper::Install (NodeContainer nodes)
-{
-  return Install (nodes, CreateObject<SimpleChannel> ());
-}
-\endcode
-
-Of course, at some point, this device helper class should also contain a couple of 
-ascii and pcap tracing helper functions but, since the default SimpleNetDevice
-class we used as an example here does not report any trace event, it would
-be of little use.
-
-*/
--- a/doc/howtos/howtos-packet-header.h	Fri Nov 13 09:19:06 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*!
-\page packet-header-trailer How to create a new type of protocol header or trailer
-\anchor howtos-packet-header-trailer
-
-<b>Question:</b> I want to implement a new protocol X which uses a new
-type of header Y. How do I implement and use this new header Y in ns-3 ?
-
-<b>Answer:</b> The key is to implement a new subclass of the ns3::Header
-base class to represent your protocol header:
-\code
-class YHeader : public Header
-{
-public:
-  // must be implemented to become a valid new header.
-  static TypeId GetTypeId (void);
-  virtual TypeId GetInstanceTypeId (void) const;
-  virtual uint32_t GetSerializedSize (void) const;
-  virtual void Serialize (Buffer::Iterator start) const;
-  virtual uint32_t Deserialize (Buffer::Iterator start);
-  virtual void Print (std::ostream &os) const;
-
-  // allow protocol-specific access to the header data.
-  void SetData (uint32_t data);
-  uint32_t GetData (void) const;
-private:
-  uint32_t m_data;
-};
-\endcode
-
-Once this class is implemented, you can easily store your protocol
-header into a packet:
-\code
-Ptr<Packet> p = ...;
-YHeader yHeader;
-yHeader.SetData (0xdeadbeaf);
-// copy the header into the packet
-p->AddHeader (yHeader);
-\endcode
-and get it out of a packet:
-\code
-Ptr<Packet> p = ...;
-YHeader yHeader;
-// copy the header from the packet
-p->RemoveHeader (yHeader);
-uint32_t data = yHeader.GetData ();
-\endcode
-
-The implementation of the new header is very simple. First, you need
-to give a TypeId to your YHeader class:
-\code
-TypeId
-YHeader::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("YHeader")
-    .SetParent<Header> ()
-    .AddConstructor<YHeader> ()
-  ;
-  return tid;
-}
-TypeId
-YHeader::GetInstanceTypeId (void)
-{
-  return GetTypeId ();
-}
-\endcode
-
-Then, you need to allow your header to serialize and deserialize itself
-to a byte buffer in its network representation. Here, our new protocol
-header contains first a 2-byte constant, and, then, the data field so,
-the total size of the header is 2+4=6 bytes.
-\code
-uint32_t 
-YHeader::GetSerializedSize (void) const
-{
-  return 6;
-}
-void 
-YHeader::Serialize (Buffer::Iterator start) const
-{
-  // The 2 byte-constant
-  start.WriteU8 (0xfe);
-  start.WriteU8 (0xef);
-  // The data.
-  start.WriteHtonU32 (m_data);
-}
-uint32_t 
-YHeader::Deserialize (Buffer::Iterator start)
-{
-  uint8_t tmp;
-  tmp = start.ReadU8 ();
-  NS_ASSERT (tmp == 0xfe);
-  tmp = start.ReadU8 ();
-  NS_ASSERT (tmp == 0xef);
-  m_data = start.ReadNtohU32 ();
-  return 6; // the number of bytes consumed.
-}
-\endcode
-
-Finally, to make sure that Packet::Print also prints the content
-of your header, just as it prints the content of the other
-headers of the system, you need to provide a Print method:
-\code
-void 
-YHeader::Print (std::ostream &os) const
-{
-  os << "data=" << m_data;
-}
-\endcode
-
-The code will look the same if you want to implement a trailer,
-that is, a protocol data structure which will be appended to the
-end of the packet, not its start: you need to make sure that
-you derive from the ns3::Trailer base class and that you call
-Packet::AddTrailer and Packet::RemoveTrailer. Another important
-detail is that you must make sure to rewind the iterator in your
-Serialize and Deserialize methods writing to or reading from 
-the underlying buffer.
-
-*/
--- a/doc/howtos/howtos.h	Fri Nov 13 09:19:06 2009 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-/*!
-\page howtos ns-3 HOWTOs
-\anchor howtos-anchor
-
-This is an organized set of frequently asked questions (FAQ) and HOWTOs
-for ns-3.  This complements the following wiki pages:
-
-- <a href="http://www.nsnam.org/wiki/index.php/User_FAQ">User FAQ</a>
-- <a href="http://www.nsnam.org/wiki/index.php/Developer_FAQ">Developer FAQ</a>
-
-Please consider contributing tips to either the wiki (yourself) or
-by submitting a patch to this maintained documentation.
-
-- \subpage callbacks
-- \subpage packet-header-trailer
-- \subpage net-device
-- \subpage application
-
-*/
-
--- a/doc/main.h	Fri Nov 13 09:19:06 2009 -0800
+++ b/doc/main.h	Fri Nov 13 09:37:52 2009 -0800
@@ -15,12 +15,12 @@
  *       organizes  all of the public API and supporting manual text 
  *       along the  source code directory structure.   This forms the 
  *       "ns-3 manual", and it is available in HTML and PDF forms.
- *     - \ref howtos-anchor "HOWTOs": A set of HOWTOs and FAQs is
- *       maintained on another Doxygen "Related Page" 
  *     - <a href="http://www.nsnam.org/docs/tutorial/tutorial.html">tutorial</a>:  The ns-3 tutorial is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
+ *     - <a href="http://www.nsnam.org/docs/manual/manual.html">Reference manual</a>:  The ns-3 tutorial is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
+ *     - <a href="http://www.nsnam.org/docs/testing/testing.html">Testing and validation manual</a>:  The ns-3 tutorial is a separate document maintained in <a href="http://www.gnu.org/software/texinfo/"> GNU Texinfo</a>. 
  *     - The <b><a href="http://www.nsnam.org/wiki/index.php/Main_Page">ns-3 wiki</a></b> 
  *       contains additional user-contributed material.  Some wiki-contributed
- *       material may migrate to and overlap with the Doxygen information.
+ *       material may migrate to and overlap with the Doxygen and manual information.
  *
  * \section install-sec Building the Documentation
  *