doc/tutorial/in-process/other.texi
changeset 6754 7ff69b244b5b
parent 6753 c9133c87760d
child 6755 b3da3ed88b6e
equal deleted inserted replaced
6753:c9133c87760d 6754:7ff69b244b5b
     1 @c ========================================================================
       
     2 @c Other Network Topologies
       
     3 @c ========================================================================
       
     4 
       
     5 @node Other-network-topologies
       
     6 @chapter Other Network Topologies
       
     7 @cindex topology
       
     8 @cindex Channel
       
     9 @cindex NetDevice
       
    10 @cindex topology!bus
       
    11 @cindex topology!point-to-point
       
    12 @cindex PointToPointChannel
       
    13 @cindex PointToPointNetDevice
       
    14 
       
    15 @emph{Network topology} is the study of the arrangement of of the elements
       
    16 (in @command{ns-3} represented by the classes @code{Channel} and @code{Node})
       
    17 of a network.  Two fundamental types of physical topologies are the 
       
    18 @emph{point-to-point} and @emph{bus} topologies.  We have already been exposed
       
    19 to the @command{ns-3} channel specialization named @code{CsmaChannel}.  This is
       
    20 a simulation of a bus network.  We also provide a simulation of a 
       
    21 point-to-point channel with associated net devices.  As described previously,
       
    22 the associated C++ classes specialize the @command{ns-3} base classes
       
    23 @code{NetDevice} and @code{Channel} and are called @code{PointToPointNetDevice}
       
    24 and @code{PointToPointChannel} respectively.
       
    25 
       
    26 We will use combinations of these bus and point-to-point topology elements
       
    27 to show how to create several commonly seen network topologies.
       
    28 
       
    29 @section A Point-to-Point Network
       
    30 We're going to take what might be seen as a step backward and look at a simple
       
    31 point-to-point network.  We will be building the simplest network you can 
       
    32 imagine.  A serial link (point to point) between two computers.  When you
       
    33 see this point-to-point network, you can think of an RS-422 (or RS-232 for 
       
    34 you old-timers) cable.  This topology is shown below.
       
    35 
       
    36 @sp 1
       
    37 @center @image{figures/pp,,,,png}
       
    38 
       
    39 @cindex CreateObject
       
    40 @cindex InternetNode
       
    41 We have provided a file for you in the @code{tutorial}
       
    42 directory called @code{tutorial-point-to-point.cc}.  You should now be
       
    43 familiar enough with the system to pick out fairly easily what has been
       
    44 changed.  Let's focus on the following lines:
       
    45 
       
    46 @verbatim
       
    47   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
    48   Ptr<Node> n1 = CreateObject<InternetNode> ();
       
    49 
       
    50   Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
       
    51     n0, n1, DataRate (38400), MilliSeconds (20));
       
    52 
       
    53   PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1",
       
    54     n1, "10.1.1.2");
       
    55 @end verbatim
       
    56 
       
    57 You can see that we created two @code{InternetNode} objects in the usual way.
       
    58 Then, instead of creating a @code{CsmaChannel} we create a 
       
    59 @code{PointToPointChannel}.  This point-to-point channel, which we call
       
    60 @code{link}, connects node zero (@code{n0}) and node one (@code{n1}) over a
       
    61 simulated link that runs at 38400 bits per second and has a 20 millisecond
       
    62 simulated speed-of-light delay.  This call also creates appropriate net devices
       
    63 and attaches them to nodes zero and one.
       
    64 
       
    65 We then add IP addresses to the net devices we just created using the topology
       
    66 helper @code{AddIpv4Addresses}.  Node zero gets the IP address 10.1.1.1 and
       
    67 node one gets the IP address 10.1.1.2 assigned.  
       
    68 
       
    69 The alert tutorial user may wonder what the network number or prefix is of
       
    70 those IP addresses.  The point-to-point topology assumes that you want a
       
    71 @code{/30} subnet and assigns an appropriate net mask for you.  It then then
       
    72 @emph{asserts} that the network numbers of the two net devices match.  So there
       
    73 is an implicit network mask created down in the topology code that looks like,
       
    74 
       
    75 @verbatim
       
    76   Ipv4Mask netmask("255.255.255.252");
       
    77 @end verbatim
       
    78 
       
    79 The rest of the code you should recognize and understand.  We are just going
       
    80 to echo one packet across the point-to-point link.  You should be now be able
       
    81 to build and run this example and to locate and interpret the ASCII trace 
       
    82 file.  This is left as an exercise for you.
       
    83 
       
    84 The file @code{tutorial-point-to-point.cc} is reproduced here for your 
       
    85 convenience:
       
    86 
       
    87 @verbatim
       
    88 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
       
    89 /*
       
    90  * This program is free software; you can redistribute it and/or modify
       
    91  * it under the terms of the GNU General Public License version 2 as
       
    92  * published by the Free Software Foundation;
       
    93  *
       
    94  * This program is distributed in the hope that it will be useful,
       
    95  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    96  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    97  * GNU General Public License for more details.
       
    98  *
       
    99  * You should have received a copy of the GNU General Public License
       
   100  * along with this program; if not, write to the Free Software
       
   101  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
   102  */
       
   103 
       
   104 #include "ns3/log.h"
       
   105 #include "ns3/ptr.h"
       
   106 #include "ns3/internet-stack.h"
       
   107 #include "ns3/point-to-point-channel.h"
       
   108 #include "ns3/mac48-address.h"
       
   109 #include "ns3/point-to-point-net-device.h"
       
   110 #include "ns3/point-to-point-topology.h"
       
   111 #include "ns3/udp-echo-client.h"
       
   112 #include "ns3/udp-echo-server.h"
       
   113 #include "ns3/simulator.h"
       
   114 #include "ns3/nstime.h"
       
   115 #include "ns3/ascii-trace.h"
       
   116 #include "ns3/pcap-trace.h"
       
   117 #include "ns3/global-route-manager.h"
       
   118 
       
   119 NS_LOG_COMPONENT_DEFINE ("PointToPointSimulation");
       
   120 
       
   121 using namespace ns3;
       
   122 
       
   123 // Network topology
       
   124 //
       
   125 //                       point to point
       
   126 //                      +--------------+
       
   127 //                      |              |
       
   128 //                     n0             n1
       
   129 //
       
   130 int 
       
   131 main (int argc, char *argv[])
       
   132 {
       
   133   LogComponentEnable ("PointToPointSimulation", LOG_LEVEL_INFO);
       
   134 
       
   135   NS_LOG_INFO ("Point to Point Topology Simulation");
       
   136 
       
   137   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
   138   Ptr<Node> n1 = CreateObject<InternetNode> ();
       
   139 
       
   140   Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
       
   141     n0, n1, DataRate (38400), MilliSeconds (20));
       
   142 
       
   143   PointToPointTopology::AddIpv4Addresses (link, n0, "10.1.1.1", 
       
   144     n1, "10.1.1.2");
       
   145 
       
   146   uint16_t port = 7;
       
   147 
       
   148   Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2", 
       
   149     port, 1, Seconds(1.), 1024);
       
   150 
       
   151   Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
       
   152 
       
   153   server->Start(Seconds(1.));
       
   154   client->Start(Seconds(2.));
       
   155 
       
   156   server->Stop (Seconds(10.));
       
   157   client->Stop (Seconds(10.));
       
   158 
       
   159   AsciiTrace asciitrace ("tutorial.tr");
       
   160   asciitrace.TraceAllQueues ();
       
   161   asciitrace.TraceAllNetDeviceRx ();
       
   162 
       
   163   Simulator::Run ();
       
   164   Simulator::Destroy ();
       
   165 }
       
   166 @end verbatim
       
   167 
       
   168 @section A Star Network
       
   169 A point-to-point network is considered a special case of a star network.  As
       
   170 you might expect, the process of constructing a star network is an extension
       
   171 of the very simple process used for a point-to-point link.  We have provided
       
   172 a file for you in the @code{tutorial} directory called @code{tutorial-star.cc}
       
   173 that implements a simple star network as seen below.
       
   174 
       
   175 @sp 1
       
   176 @center @image{figures/star,,,,png}
       
   177 
       
   178 In order to create a star network, we need to be able to instantiate some
       
   179 number (greater than one) of net devices on a node.  In the name of simplicity
       
   180 of use, the @code{PointToPointTopology} topology helper does not allow one to
       
   181 do this.  We provided a separate topology helper class, the 
       
   182 @code{PointToPointIpv4Topology} helper class that provides the slightly finer
       
   183 granularity we need to accomplish a star network.  In order to use this new
       
   184 helper we have to load the definitions by including the appropriate file.
       
   185 
       
   186 @verbatim
       
   187   #include "ns3/point-to-point-ipv4-topology.h"
       
   188 @end verbatim
       
   189 
       
   190 The star that we're going to create has a node in the center (@code{n0}) with
       
   191 six nodes surrounding (@code{n1} - @code{n6}).  You should be able to easily
       
   192 find and understand the code that creates these nodes.
       
   193 
       
   194 @verbatim
       
   195   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
   196   Ptr<Node> n1 = CreateObject<InternetNode> ();
       
   197   Ptr<Node> n2 = CreateObject<InternetNode> ();
       
   198   Ptr<Node> n3 = CreateObject<InternetNode> ();
       
   199   Ptr<Node> n4 = CreateObject<InternetNode> ();
       
   200   Ptr<Node> n5 = CreateObject<InternetNode> ();
       
   201   Ptr<Node> n6 = CreateObject<InternetNode> ();
       
   202 @end verbatim
       
   203 
       
   204 Next, we get into the differences between the @code{PointToPointTopology}
       
   205 helper and the @code{PointToPointIpv4Topology} helper.  The
       
   206 @code{PointToPointIpv4Topology} helper looks and feels a little like the 
       
   207 @code{CsmaIpv4Topology} helper.  Just like you created a CSMA channel 
       
   208 previously, you need to create a point-to-point channel.  The following
       
   209 code creates a @code{PointToPointChannel} and calls it @code{link01}.  You can
       
   210 interpret this name as being the channel (or @emph{link}) from node zero to 
       
   211 node one.  
       
   212 
       
   213 @verbatim
       
   214   Ptr<PointToPointChannel> link01 =
       
   215     PointToPointIpv4Topology::CreateChannel (DataRate (38400),
       
   216     MilliSeconds (20));
       
   217 @end verbatim
       
   218 
       
   219 You need to provide a data rate for the channel which we set at 38400 bits 
       
   220 per second.  You must also provide a speed-of-light delay which we set at
       
   221 20 milliseconds.
       
   222 
       
   223 Just as you added a net device to the nodes in the CSMA tutorial section, you
       
   224 do the same here but with a point-to-point net device.  The following code
       
   225 illustrates how we do that:
       
   226 
       
   227 @verbatim
       
   228   uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
       
   229     link01);
       
   230 @end verbatim
       
   231 
       
   232 We call the @code{PointToPointIpv4Topology} helper and ask it to add a net
       
   233 device to node zero (@code{n0}) and connect it to the appropriate 
       
   234 point-to-point link (@code{link01}) which you will recall is the serial link
       
   235 from node zero to node one.
       
   236 
       
   237 If you look at the following code, you will see the same calls are repeated
       
   238 to create the remaining five point-to-point channels and connect them
       
   239 to net devices on node zero.
       
   240 
       
   241 The next new code is found after the ``spokes'' of the star have been created.
       
   242 It looks like the following:
       
   243 
       
   244 @verbatim
       
   245   uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
       
   246   uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
       
   247   uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
       
   248   uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
       
   249   uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
       
   250   uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
       
   251 @end verbatim
       
   252 
       
   253 Here we are creating the net devices on the nodes surrounding the center node.
       
   254 In the first call, we are adding a net device on node one (@code{n1}) and
       
   255 connecting that net device to the channel named @code{link01}.  Remember that
       
   256 we created the channel @code{link01} as the channel connecting node zero and
       
   257 node one.  We previously created a net device on node zero and attached that
       
   258 device to @code{link01}.  Here we are connecting the other side of that link
       
   259 to node one.  The return value from this call is the net device index of the
       
   260 created net device.
       
   261 
       
   262 The next section of code adds addresses to the net devices we just created.
       
   263 The first call adds the IP address 10.1.1.1 to the net device going from 
       
   264 node zero to node one.  Recall that we first created a node named @code{n0}
       
   265 and a channel called @code{link01}.  We added a net device to @code{n0} and
       
   266 remembered the net device index as the @code{uint32_t nd01}.  This meant
       
   267 the net device @emph{nd} on node @emph{0} that we connected to node @emph{1}. 
       
   268 We call @code{AddAddress} to add an IP address (10.1.1.1) to the net device
       
   269 on node zero identified by the net device index @code{nd01}.  We provide a
       
   270 net mask suitable for a point to point network.  This is typically a /30 
       
   271 address but we don't force that in this API.
       
   272 
       
   273 After setting up the address on node zero, we do the same for the node on
       
   274 the other end of the ``spoke'' --- in this case node one, with its single
       
   275 net device.  Note that the network number is the same on both sides of this
       
   276 network.
       
   277 
       
   278 @verbatim
       
   279   PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1",
       
   280     ``255.255.255.252'');
       
   281 
       
   282   PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2",
       
   283     ``255.255.255.252'');
       
   284 @end verbatim
       
   285 
       
   286 The following code repeats this pattern assining similar IP addresses to the
       
   287 remaining net devices.  Note that there are no @code{Mac48Address} address
       
   288 assignments --- they are not required.
       
   289 
       
   290 The rest of the code you should recognize and understand.  We are just going
       
   291 to echo one packet across the point-to-point link.  You should be now be able
       
   292 to build and run this example and to locate and interpret the ASCII trace 
       
   293 file.  This is left as an exercise for you.
       
   294 
       
   295 The file @code{tutorial-star.cc} is reproduced here for your convenience:
       
   296 
       
   297 @verbatim
       
   298 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
       
   299 /*
       
   300  * This program is free software; you can redistribute it and/or modify
       
   301  * it under the terms of the GNU General Public License version 2 as
       
   302  * published by the Free Software Foundation;
       
   303  *
       
   304  * This program is distributed in the hope that it will be useful,
       
   305  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
   306  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
   307  * GNU General Public License for more details.
       
   308  *
       
   309  * You should have received a copy of the GNU General Public License
       
   310  * along with this program; if not, write to the Free Software
       
   311  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
   312  */
       
   313 
       
   314 #include "ns3/log.h"
       
   315 #include "ns3/ptr.h"
       
   316 #include "ns3/internet-stack.h"
       
   317 #include "ns3/point-to-point-channel.h"
       
   318 #include "ns3/mac48-address.h"
       
   319 #include "ns3/point-to-point-net-device.h"
       
   320 #include "ns3/point-to-point-ipv4-topology.h"
       
   321 #include "ns3/udp-echo-client.h"
       
   322 #include "ns3/udp-echo-server.h"
       
   323 #include "ns3/simulator.h"
       
   324 #include "ns3/nstime.h"
       
   325 #include "ns3/ascii-trace.h"
       
   326 #include "ns3/pcap-trace.h"
       
   327 #include "ns3/global-route-manager.h"
       
   328 
       
   329 NS_LOG_COMPONENT_DEFINE ("StarSimulation");
       
   330 
       
   331 using namespace ns3;
       
   332 
       
   333 // Network topology
       
   334 //
       
   335 //                  n3    n2
       
   336 //                   |   /
       
   337 //                    | /
       
   338 //              n4 --- n0 --- n1
       
   339 //                    /  |
       
   340 //                   /    |
       
   341 //                  n5    n6
       
   342 
       
   343 int 
       
   344 main (int argc, char *argv[])
       
   345 {
       
   346   LogComponentEnable ("StarSimulation", LOG_LEVEL_INFO);
       
   347 
       
   348   NS_LOG_INFO ("Star Topology Simulation");
       
   349 
       
   350   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
   351   Ptr<Node> n1 = CreateObject<InternetNode> ();
       
   352   Ptr<Node> n2 = CreateObject<InternetNode> ();
       
   353   Ptr<Node> n3 = CreateObject<InternetNode> ();
       
   354   Ptr<Node> n4 = CreateObject<InternetNode> ();
       
   355   Ptr<Node> n5 = CreateObject<InternetNode> ();
       
   356   Ptr<Node> n6 = CreateObject<InternetNode> ();
       
   357 
       
   358   Ptr<PointToPointChannel> link01 = 
       
   359     PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
       
   360     MilliSeconds (20));
       
   361 
       
   362   uint32_t nd01 = PointToPointIpv4Topology::AddNetDevice (n0,
       
   363     link01);
       
   364 
       
   365   Ptr<PointToPointChannel> link02 = 
       
   366     PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
       
   367     MilliSeconds (20));
       
   368 
       
   369   uint32_t nd02 = PointToPointIpv4Topology::AddNetDevice (n0,
       
   370     link02);
       
   371 
       
   372   Ptr<PointToPointChannel> link03 = 
       
   373     PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
       
   374     MilliSeconds (20));
       
   375 
       
   376   uint32_t nd03 = PointToPointIpv4Topology::AddNetDevice (n0,
       
   377     link03);
       
   378 
       
   379   Ptr<PointToPointChannel> link04 = 
       
   380     PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
       
   381     MilliSeconds (20));
       
   382 
       
   383   uint32_t nd04 = PointToPointIpv4Topology::AddNetDevice (n0, 
       
   384     link04);
       
   385 
       
   386   Ptr<PointToPointChannel> link05 = 
       
   387     PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
       
   388     MilliSeconds (20));
       
   389 
       
   390   uint32_t nd05 = PointToPointIpv4Topology::AddNetDevice (n0,
       
   391     link05);
       
   392 
       
   393   Ptr<PointToPointChannel> link06 = 
       
   394     PointToPointIpv4Topology::CreateChannel (DataRate (38400), 
       
   395     MilliSeconds (20));
       
   396 
       
   397   uint32_t nd06 = PointToPointIpv4Topology::AddNetDevice (n0, link06);
       
   398 
       
   399   uint32_t nd1 = PointToPointIpv4Topology::AddNetDevice (n1, link01);
       
   400   uint32_t nd2 = PointToPointIpv4Topology::AddNetDevice (n2, link02);
       
   401   uint32_t nd3 = PointToPointIpv4Topology::AddNetDevice (n3, link03);
       
   402   uint32_t nd4 = PointToPointIpv4Topology::AddNetDevice (n4, link04);
       
   403   uint32_t nd5 = PointToPointIpv4Topology::AddNetDevice (n5, link05);
       
   404   uint32_t nd6 = PointToPointIpv4Topology::AddNetDevice (n6, link06);
       
   405 
       
   406   PointToPointIpv4Topology::AddAddress (n0, nd01, "10.1.1.1", 
       
   407     "255.255.255.252");
       
   408 
       
   409   PointToPointIpv4Topology::AddAddress (n1, nd1, "10.1.1.2", 
       
   410     "255.255.255.252");
       
   411 
       
   412   PointToPointIpv4Topology::AddAddress (n0, nd02, "10.1.2.1", 
       
   413     "255.255.255.252");
       
   414 
       
   415   PointToPointIpv4Topology::AddAddress (n2, nd2, "10.1.2.2", 
       
   416     "255.255.255.252");
       
   417 
       
   418   PointToPointIpv4Topology::AddAddress (n0, nd03, "10.1.3.1", 
       
   419     "255.255.255.252");
       
   420 
       
   421   PointToPointIpv4Topology::AddAddress (n3, nd3, "10.1.2.2", 
       
   422     "255.255.255.252");
       
   423 
       
   424   PointToPointIpv4Topology::AddAddress (n0, nd04, "10.1.4.1", 
       
   425     "255.255.255.252");
       
   426 
       
   427   PointToPointIpv4Topology::AddAddress (n4, nd4, "10.1.4.2", 
       
   428     "255.255.255.252");
       
   429 
       
   430   PointToPointIpv4Topology::AddAddress (n0, nd05, "10.1.5.1", 
       
   431     "255.255.255.252");
       
   432 
       
   433   PointToPointIpv4Topology::AddAddress (n5, nd5, "10.1.5.2", 
       
   434     "255.255.255.252");
       
   435 
       
   436   PointToPointIpv4Topology::AddAddress (n0, nd06, "10.1.6.1", 
       
   437     "255.255.255.252");
       
   438 
       
   439   PointToPointIpv4Topology::AddAddress (n6, nd6, "10.1.6.2", 
       
   440     "255.255.255.252");
       
   441 
       
   442   uint16_t port = 7;
       
   443 
       
   444   Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n0, "10.1.1.2", 
       
   445     port, 1, Seconds(1.), 1024);
       
   446 
       
   447   Ptr<UdpEchoServer> server = CreateObject<UdpEchoServer> (n1, port);
       
   448 
       
   449   server->Start(Seconds(1.));
       
   450   client->Start(Seconds(2.));
       
   451 
       
   452   server->Stop (Seconds(10.));
       
   453   client->Stop (Seconds(10.));
       
   454 
       
   455   AsciiTrace asciitrace ("tutorial.tr");
       
   456   asciitrace.TraceAllQueues ();
       
   457   asciitrace.TraceAllNetDeviceRx ();
       
   458 
       
   459   Simulator::Run ();
       
   460   Simulator::Destroy ();
       
   461 }
       
   462 @end verbatim
       
   463 
       
   464 @subsection Routing
       
   465 If you are really excited about this simulator you may have already tried to
       
   466 modify the scripts outside the tutorial.  I know that one of the first things
       
   467 that would have occurred to me when I saw the star network would have been to
       
   468 start trying to add applications to echo packets from nodes other than zero.
       
   469 If you tried, for example, to start the echo client on node one instead of
       
   470 node zero, you would have found an empty trace file.  The reason for this
       
   471 is that you have now created an internetwork.  This means you will need to 
       
   472 enable internetwork routing.
       
   473 
       
   474 We have provided a file for you in the @code{tutorial} directory called 
       
   475 @code{tutorial-star-routing.cc} to show you how this is done.  This extremely
       
   476 tricky and difficult change is shown below:
       
   477 
       
   478 @verbatim 
       
   479  GlobalRouteManager::PopulateRoutingTables ();
       
   480 @end verbatim
       
   481 
       
   482 This one-line addition, located just before the simulation runs, tells the 
       
   483 @command{ns-3} @emph{global route manager} to walk the topology you created and 
       
   484 build internetwork routing tables for all of the nodes in the simulation.
       
   485 We changed the client application so that it runs on node four:
       
   486 
       
   487 @verbatim
       
   488   Ptr<UdpEchoClient> client = CreateObject<UdpEchoClient> (n4, "10.1.1.2", 
       
   489     port, 1, Seconds(1.), 1024);
       
   490 @end verbatim
       
   491 
       
   492 Now if you build and run @code{tutorial-star-routing.cc} you can examine the
       
   493 @code{tutorial.tr} file and see that your UDP echo packets are now correctly
       
   494 routed through the topology.
       
   495 
       
   496 @section A Dumbbell Network
       
   497 One of the most interesting simple topologies (from a phenomenological point of
       
   498 view) is commonly called a dumbbell network.  The name derives from a 
       
   499 superficial similarity in form to a piece of exercise equipment.
       
   500 
       
   501 The dumbbell model is typically composed of two bus or star network elements
       
   502 connected via a point-to-point link.  The point-to-point link is usually 
       
   503 configured with a lower bandwidth than the bus elements to provide a 
       
   504 @emph{choke point}.
       
   505 
       
   506 The following is a representation of the topology.
       
   507 
       
   508 @sp 1
       
   509 @center @image{figures/dumbbell,,,,png}
       
   510 
       
   511 We have provided a file that constructs this dumbbell network and creates 
       
   512 enough data flowing across the choke point that some packets will be dropped.
       
   513 The file is called @code{tutorial-linear-dumbbell.cc} and is located in the 
       
   514 @code{tutorial} directory.  We have already covered all of the code used to
       
   515 create this network, so we will just quickly go over the main sections of the
       
   516 script.
       
   517 
       
   518 The first section creates a CSMA lan that will become the left side of the
       
   519 dumbbell network.  This code should be very familiar since we used the same
       
   520 process to create our first example.
       
   521 
       
   522 @verbatim
       
   523 //
       
   524 // Create the lan on the left side of the dumbbell.
       
   525 //
       
   526   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
   527   Ptr<Node> n1 = CreateObject<InternetNode> ();
       
   528   Ptr<Node> n2 = CreateObject<InternetNode> ();
       
   529   Ptr<Node> n3 = CreateObject<InternetNode> ();
       
   530 
       
   531   Ptr<CsmaChannel> lan1 = 
       
   532     CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
       
   533 
       
   534   uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan1, 
       
   535     "08:00:2e:00:00:00");
       
   536 
       
   537   uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan1, 
       
   538     "08:00:2e:00:00:01");
       
   539 
       
   540   uint32_t nd2 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, 
       
   541     "08:00:2e:00:00:02");
       
   542 
       
   543   uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, 
       
   544     "08:00:2e:00:00:03");
       
   545 
       
   546   CsmaIpv4Topology::AddIpv4Address (n0, nd0, "10.1.1.1", "255.255.255.0");
       
   547   CsmaIpv4Topology::AddIpv4Address (n1, nd1, "10.1.1.2", "255.255.255.0");
       
   548   CsmaIpv4Topology::AddIpv4Address (n2, nd2, "10.1.1.3", "255.255.255.0");
       
   549   CsmaIpv4Topology::AddIpv4Address (n3, nd3, "10.1.1.4", "255.255.255.0");
       
   550 @end verbatim
       
   551 
       
   552 The code to generate the CSMA lan on the right side is similar; only the names
       
   553 have been changed.
       
   554  
       
   555 @verbatim
       
   556 //
       
   557 // Create the lan on the right side of the dumbbell.
       
   558 //
       
   559   Ptr<Node> n4 = CreateObject<InternetNode> ();
       
   560   Ptr<Node> n5 = CreateObject<InternetNode> ();
       
   561   Ptr<Node> n6 = CreateObject<InternetNode> ();
       
   562   Ptr<Node> n7 = CreateObject<InternetNode> ();
       
   563 
       
   564   Ptr<CsmaChannel> lan2 = 
       
   565     CsmaTopology::CreateCsmaChannel (DataRate (10000000), MilliSeconds (2));
       
   566 
       
   567   uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan2, 
       
   568     "08:00:2e:00:00:04");
       
   569 
       
   570   uint32_t nd5 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n5, lan2, 
       
   571     "08:00:2e:00:00:05");
       
   572 
       
   573   uint32_t nd6 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n6, lan2, 
       
   574     "08:00:2e:00:00:06");
       
   575 
       
   576   uint32_t nd7 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n7, lan2, 
       
   577     "08:00:2e:00:00:07");
       
   578 
       
   579   CsmaIpv4Topology::AddIpv4Address (n4, nd4, "10.1.2.1", "255.255.255.0");
       
   580   CsmaIpv4Topology::AddIpv4Address (n5, nd5, "10.1.2.2", "255.255.255.0");
       
   581   CsmaIpv4Topology::AddIpv4Address (n6, nd6, "10.1.2.3", "255.255.255.0");
       
   582   CsmaIpv4Topology::AddIpv4Address (n7, nd7, "10.1.2.4", "255.255.255.0");
       
   583 @end verbatim
       
   584 
       
   585 Next, we create a point to point link to connect the two lans.  We connect
       
   586 the point-to-point channel between nodes three (on the left lan) and four
       
   587 (on the right lan).  You should recognize this as substantially similar to
       
   588 the link setup from the @code{point-to-point} example.
       
   589 
       
   590 @verbatim
       
   591 //
       
   592 // Create the point-to-point link to connect the two lans.
       
   593 //
       
   594   Ptr<PointToPointChannel> link = PointToPointTopology::AddPointToPointLink (
       
   595     n3, n4, DataRate (38400), MilliSeconds (20));
       
   596 
       
   597   PointToPointTopology::AddIpv4Addresses (link, n3, "10.1.3.1", 
       
   598     n4, "10.1.3.2");
       
   599 @end verbatim
       
   600 
       
   601 Then we configure data flows.  We create four echo clients that send UDP 
       
   602 packets from the left side lan to servers created on the right side lan.
       
   603 Notice that we send 100 packets with an inter-packet gap of ten milliseconds
       
   604 instead of the single packet we have previously used.  This data rate is
       
   605 sufficient to saturate the point-to-point link and will cause packets to be
       
   606 dropped when the queue on the link net devices overflows (the default maximum
       
   607 queue depth is 100 packets).  Note that we stagger the start of the echo 
       
   608 clients to slowly bring up the data rates.
       
   609 
       
   610 @verbatim
       
   611 //
       
   612 // Create data flows across the link:
       
   613 //   n0 ==> n4 ==> n0
       
   614 //   n1 ==> n5 ==> n1
       
   615 //   n2 ==> n6 ==> n2
       
   616 //   n3 ==> n7 ==> n3
       
   617 //
       
   618   uint16_t port = 7;
       
   619 
       
   620   Ptr<UdpEchoClient> client0 = CreateObject<UdpEchoClient> (n0, "10.1.2.1", 
       
   621     port, 100, Seconds(.01), 1024);
       
   622   Ptr<UdpEchoClient> client1 = CreateObject<UdpEchoClient> (n1, "10.1.2.2", 
       
   623     port, 100, Seconds(.01), 1024);
       
   624   Ptr<UdpEchoClient> client2 = CreateObject<UdpEchoClient> (n2, "10.1.2.3", 
       
   625     port, 100, Seconds(.01), 1024);
       
   626   Ptr<UdpEchoClient> client3 = CreateObject<UdpEchoClient> (n3, "10.1.2.4", 
       
   627     port, 100, Seconds(.01), 1024);
       
   628 
       
   629   Ptr<UdpEchoServer> server4 = CreateObject<UdpEchoServer> (n4, port);
       
   630   Ptr<UdpEchoServer> server5 = CreateObject<UdpEchoServer> (n5, port);
       
   631   Ptr<UdpEchoServer> server6 = CreateObject<UdpEchoServer> (n6, port);
       
   632   Ptr<UdpEchoServer> server7 = CreateObject<UdpEchoServer> (n7, port);
       
   633 
       
   634   server4->Start(Seconds(1.));
       
   635   server5->Start(Seconds(1.));
       
   636   server6->Start(Seconds(1.));
       
   637   server7->Start(Seconds(1.));
       
   638 
       
   639   client0->Start(Seconds(2.));
       
   640   client1->Start(Seconds(2.1));
       
   641   client2->Start(Seconds(2.2));
       
   642   client3->Start(Seconds(2.3));
       
   643 
       
   644   server4->Stop (Seconds(10.));
       
   645   server5->Stop (Seconds(10.));
       
   646   server6->Stop (Seconds(10.));
       
   647   server7->Stop (Seconds(10.));
       
   648 
       
   649   client0->Stop (Seconds(10.));
       
   650   client1->Stop (Seconds(10.));
       
   651   client2->Stop (Seconds(10.));
       
   652   client3->Stop (Seconds(10.));
       
   653 @end verbatim
       
   654 
       
   655 The remainder of the file should be quite familiar to you.  Go ahead and 
       
   656 run @code{tutorial-linear-dumbbell}.  Now take a look at the trace 
       
   657 (@code{tutorial.tr}) file.  You will now see trace lines that begin with 
       
   658 @code{d}.  Alternatively you can search for the string ``queue-drop'' which
       
   659 is the expansion of the drop code ('d').
       
   660 
       
   661 Interpretation of a dropped packet is straightforward.  We have expanded
       
   662 the first @code{queue-drop} trace for you below.  See the section on ASCII 
       
   663 tracing for details.
       
   664 
       
   665 @verbatim
       
   666   00 d 
       
   667   01 2.40938 
       
   668   02 nodeid=3 
       
   669   03 device=1 
       
   670   04 queue-drop 
       
   671   05 pkt-uid=124 
       
   672   06 LLCSNAP(type 0x800) 
       
   673   07   IPV4(
       
   674   08     tos 0x0 
       
   675   09     ttl 63 
       
   676   10     id 20 
       
   677   11     offset 0 
       
   678   12     flags [none] 
       
   679   13     length: 1052) 10.1.1.3 > 10.1.2.3 
       
   680   14     UDP(length: 1032) 
       
   681   15       49153 > 7 
       
   682   16       DATA (length 1024)
       
   683 @end verbatim
       
   684 
       
   685 We leave it as an exercise to examine the trace files in more detail.
       
   686 
       
   687 @c ========================================================================
       
   688 @c Nonlinear Thinking
       
   689 @c ========================================================================
       
   690 
       
   691 @node Nonlinear-Thinking
       
   692 @chapter Nonlinear Thinking
       
   693 
       
   694 One thing that all of our examples so far have in common is that they are
       
   695 composed of a linear collection of calls into the @command{ns-3} system.  The
       
   696 programmers among the readers may have wondered why there is not as much
       
   697 as a for-loop in all of the examples.  The answer is that we wanted to 
       
   698 introduce you to @command{ns-3} scripting with a minimum of conceptual 
       
   699 overhead.  We're going to remedy that situation shortly.
       
   700 
       
   701 We have written a number of @command{ns-3} scripts in C++.  Although we have 
       
   702 been perfectly linear in our script implementations, just like any other C++ 
       
   703 program, an @command{ns-3} script can use any features of the language you
       
   704 desire.  If you will look back at the @code{tutorial-linear-dumbbell.cc}
       
   705 example, you may notice that the code to create the left and right sides of
       
   706 the dumbbell is operationally identical --- only the names change.  An obvious
       
   707 improvement of this program would be to use subroutines to create the sides.
       
   708 Since we are working with C++, we should probably do this in an 
       
   709 object-oriented way.  Since object-oriented design is somewhat of a black art
       
   710 to some people, we'll take some time here and outline a simple methodology 
       
   711 you can follow.
       
   712 
       
   713 @section Object Design 101 --- Class Ipv4BusNetwork
       
   714 If you are a master of object oriented design, feel free to skip or skim this
       
   715 section, in which we derive a simplistic but fully operational bus network 
       
   716 class.
       
   717 
       
   718 So you want to create a BusNetwork class.  Often the biggest hurdle in a 
       
   719 design is figuring out how to get started.  One of the simplest and most 
       
   720 straightforward ways to do an object decomposition of a problem is to simply 
       
   721 write down a description of the problem and take a look at the words 
       
   722 you used.  Let's take some time and do that, first at a very high level.
       
   723 
       
   724 @example
       
   725 A bus network is an implementation of a particular network topology that
       
   726 contains some number of nodes.  Each of these nodes is attached to a single 
       
   727 multi-drop channel.  The network itself has some attributes independent of
       
   728 the topology such as a network mask, network number (prefix) and base IP
       
   729 address.
       
   730 @end example
       
   731 
       
   732 The first thing to do is to focus on the nouns and adjectives.  These will
       
   733 give you a starting point for required classes and member variables.
       
   734 
       
   735 Immediately we can notice that at the highest level we are talking about the
       
   736 noun @emph{network}.  This probably won't surprise you.  We also have an 
       
   737 adjective that modifies the noun --- @emph{bus}.  This should lead us to our 
       
   738 first class definition.  Usually class names are constructed in the same way
       
   739 as an English language sentence would be spoken.  For example, one would speak
       
   740 of a @emph{bus network} in conversation, so we would normally create a
       
   741 @code{class BusNetwork} to represent it.  
       
   742 
       
   743 One thing to note is that we have used two words in our description quite 
       
   744 naturally: @emph{is} and @emph{has}.  When you see these words should should
       
   745 immediately think of the object-oriented concepts of @emph{ISA} (inheritance)
       
   746 and @emph{HASA} (containment) respectively.  We wrote that a bus network
       
   747 @emph{is} an implementation of a particular network topology.  Perhaps you 
       
   748 will agree that there is a natural base class called @code{Network} that 
       
   749 @emph{has} the attributes discussed above.  The fact that a @code{BusNetwork}
       
   750 @emph{ISA} kind of @code{Network} suggests inheritance.  Let's capture that 
       
   751 thought right away remembering that we're focused on IP version four here:
       
   752 
       
   753 @verbatim
       
   754   class Ipv4Network
       
   755   {
       
   756   public:
       
   757     Ipv4Address m_network;
       
   758     Ipv4Mask m_mask;
       
   759     Ipv4Address m_baseAddress;
       
   760   };
       
   761 
       
   762   class Ipv4BusNetwork : public Ipv4Network
       
   763   {
       
   764   };
       
   765 @end verbatim
       
   766 
       
   767 Let's take a look at the @emph{HASA} relationships of the bus network.  Clearly
       
   768 it will @emph{have} a reference to the underlying channel that implements the
       
   769 actual communications medium.  We use smart pointers for those references, so 
       
   770 one member variable is obvious:
       
   771 
       
   772 @verbatim
       
   773   Ptr<CsmaChannel> m_channel;
       
   774 @end verbatim
       
   775 
       
   776 A bus network will also need to contain references to all of the nodes we
       
   777 eventually want to create.  If you are working in C++ and see the words contain
       
   778 or container, you should immediately think of the Standard Template Library
       
   779 or STL.  A quick search of the available containers there will probably lead
       
   780 you to consider the vector class.  A vector is a container that looks like an
       
   781 array.  This is just what we need here.  Again, we want to use smart pointers
       
   782 to reference our nodes, so the declaration of the vector would look like,
       
   783 
       
   784 @verbatim
       
   785   std::vector<Ptr<Node> > m_nodes;
       
   786 @end verbatim
       
   787 
       
   788 It will save you headaches in the future if you notice that the space between
       
   789 the two right brackets is required to differentiate this situation from a
       
   790 right-shift operator.  So we have a pretty good start already after just a
       
   791 little work.  Now we need to turn our attention to actions.  Let's write 
       
   792 another little description of the things you consider doing to a Bus network.
       
   793 
       
   794 @example
       
   795 We need to be able to create a bus network.  We need to be able to delete a
       
   796 bus network.  We need to be able to get a handle to a node in order to add
       
   797 applications.  We need to be able to set the network, mask and base address
       
   798 somehow, specify how many nodes to create and provide the underlying channel
       
   799 its required bandwidth and delay parameters.
       
   800 @end example
       
   801 
       
   802 We now look at the @emph{verbs} in that sentence.  These will give a good 
       
   803 starting point for the methods of the classes.  For example, the verbs 
       
   804 @emph{create} and @emph{delete} should suggest @emph{constructor} and 
       
   805 @emph{destructor}.  The verb @emph{get} leads us to providing a method called
       
   806 @code{GetNode}.  We have to provide a number of parameters so we can either
       
   807 provide @emph{setters} or we can simply pass them in as parameters to our
       
   808 constructors.  Since this is a simple example, we won't bother to implement
       
   809 getters and setters (methods to get and set member variables to enhance data
       
   810 hiding).  Let's use this guidance to finish up our class declarations:
       
   811 
       
   812 @verbatim
       
   813   class Ipv4Network
       
   814   {
       
   815   public:
       
   816     Ipv4Network (Ipv4Address network, Ipv4Mask mask, Ipv4Address address);
       
   817     virtual ~Ipv4Network ();
       
   818 
       
   819     Ipv4Address m_network;
       
   820     Ipv4Mask m_mask;
       
   821     Ipv4Address m_baseAddress;
       
   822   };
       
   823 
       
   824   class Ipv4BusNetwork : public Ipv4Network
       
   825   {
       
   826   public:
       
   827     Ipv4BusNetwork (
       
   828       Ipv4Address   network, 
       
   829       Ipv4Mask      mask, 
       
   830       Ipv4Address   startAddress, 
       
   831       DataRate      bps, 
       
   832       Time          delay, 
       
   833       uint32_t      n);
       
   834 
       
   835     virtual ~Ipv4BusNetwork ();
       
   836 
       
   837     Ptr<Node> GetNode (uint32_t n);
       
   838 
       
   839   private:
       
   840     std::vector<Ptr<Node> > m_nodes;
       
   841     Ptr<CsmaChannel> m_channel;
       
   842   };
       
   843 @end verbatim
       
   844 
       
   845 That's it.  We have actually already walked through almost all of the code
       
   846 required to construct a bus network in our @code{tutorial-csma-echo.cc} 
       
   847 example, so let's just jump forward and take a look at an implementation
       
   848 of this thing.  We provide an implementation for you in the files 
       
   849 @code{ipv4-bus-network.h} and @code{ipv4-bus-network.cc} located in the
       
   850 @code{tutorial} directory.  We also provide an example that uses the new
       
   851 class in the file @code{tutorial-bus-network.cc}.
       
   852 
       
   853 The interesting method from our current perspective is the Ipv4BusNetwork
       
   854 constructor, shown below:
       
   855 
       
   856 @verbatim
       
   857   Ipv4BusNetwork::Ipv4BusNetwork (
       
   858     Ipv4Address   network, 
       
   859     Ipv4Mask      mask, 
       
   860     Ipv4Address   baseAddress, 
       
   861     DataRate      bps, 
       
   862     Time          delay, 
       
   863     uint32_t      n)
       
   864   : 
       
   865     Ipv4Network (network, mask, baseAddress)
       
   866   {
       
   867     Ipv4AddressGenerator::SeedNetwork (mask, network);
       
   868     Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
       
   869   
       
   870     m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
       
   871   
       
   872     for (uint32_t i = 0; i < n; ++i)
       
   873       {
       
   874         Ptr<Node> node = CreateObject<InternetNode> ();
       
   875         uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel, 
       
   876           Mac48Address::Allocate ());
       
   877         Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask, 
       
   878           network);
       
   879         CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
       
   880         m_nodes.push_back (node);
       
   881       }
       
   882   }
       
   883 @end verbatim
       
   884 
       
   885 Notice that we do the simple and straightforward thing and pass all of our
       
   886 parameters to the constructor.  For those unfamiliar with C++, the line after
       
   887 the colon and before the opening brace (shown below),
       
   888 
       
   889 @verbatim
       
   890   : 
       
   891     Ipv4Network (network, mask, baseAddress)
       
   892   {
       
   893 @end verbatim
       
   894 
       
   895 Passes the appropriate parameters to the constructor of the base class
       
   896 @code{Ipv4Network}.  There are two new calls that we haven't seen immediately
       
   897 after this initialization.  They are:
       
   898 
       
   899 @verbatim
       
   900     Ipv4AddressGenerator::SeedNetwork (mask, network);
       
   901     Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
       
   902 @end verbatim
       
   903 
       
   904 We provide an IP address generator class to allow us to programmatically
       
   905 allocate IP addresses.  The first call to @code{SeedNetwork} gives the
       
   906 address generator a starting network number to use when generating addresses.
       
   907 The second call to @code{SeedAddress} gives the address generator a starting
       
   908 IP address to use.  There is a starting network and starting address for each
       
   909 of the 32 possible network masks.  Later in the for loop, you will see a
       
   910 call to @code{AllocateAddress} in which the IP address for each node created
       
   911 in the loop is actually generated.  
       
   912 
       
   913 The only unfamiliar call in the reset of the constructor will be:
       
   914 
       
   915 @verbatim
       
   916   m_nodes.push_back (node);
       
   917 @end verbatim
       
   918 
       
   919 This is the STL code to add the newly created node to the vector of nodes
       
   920 attached to the bus.  
       
   921 
       
   922 For your convenience, we reproduce the entire bus network implementation below:
       
   923 
       
   924 @verbatim
       
   925   /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
   926   /*
       
   927    * Copyright (c) 2007 University of Washington
       
   928    *
       
   929    * This program is free software; you can redistribute it and/or modify
       
   930    * it under the terms of the GNU General Public License version 2 as
       
   931    * published by the Free Software Foundation;
       
   932    *
       
   933    * This program is distributed in the hope that it will be useful,
       
   934    * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
   935    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
   936    * GNU General Public License for more details.
       
   937    *
       
   938    * You should have received a copy of the GNU General Public License
       
   939    * along with this program; if not, write to the Free Software
       
   940    * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
   941    */
       
   942   
       
   943   #include "ns3/mac48-address.h"
       
   944   #include "ns3/csma-net-device.h"
       
   945   #include "ns3/csma-topology.h"
       
   946   #include "ns3/csma-ipv4-topology.h"
       
   947   
       
   948   #include "ipv4-bus-network.h"
       
   949   #include "ipv4-address-generator.h"
       
   950   
       
   951   namespace ns3 {
       
   952   
       
   953   Ipv4Network::Ipv4Network (
       
   954     Ipv4Address   network, 
       
   955     Ipv4Mask      mask, 
       
   956     Ipv4Address   address)
       
   957   : 
       
   958     m_network (network), m_mask (mask), m_baseAddress (address)
       
   959   {
       
   960   }
       
   961   
       
   962   Ipv4Network::~Ipv4Network ()
       
   963   {
       
   964   }
       
   965   
       
   966   Ipv4BusNetwork::Ipv4BusNetwork (
       
   967     Ipv4Address   network, 
       
   968     Ipv4Mask      mask, 
       
   969     Ipv4Address   baseAddress, 
       
   970     DataRate      bps, 
       
   971     Time          delay, 
       
   972     uint32_t      n)
       
   973   : 
       
   974     Ipv4Network (network, mask, baseAddress)
       
   975   {
       
   976     Ipv4AddressGenerator::SeedNetwork (mask, network);
       
   977     Ipv4AddressGenerator::SeedAddress (mask, baseAddress);
       
   978   
       
   979     m_channel = CsmaTopology::CreateCsmaChannel (bps, delay);
       
   980   
       
   981     for (uint32_t i = 0; i < n; ++i)
       
   982       {
       
   983         Ptr<Node> node = CreateObject<InternetNode> ();
       
   984         uint32_t nd = CsmaIpv4Topology::AddIpv4CsmaNetDevice (node, m_channel, 
       
   985           Mac48Address::Allocate ());
       
   986         Ipv4Address address = Ipv4AddressGenerator::AllocateAddress (mask, 
       
   987           network);
       
   988         CsmaIpv4Topology::AddIpv4Address (node, nd, address, mask);
       
   989         m_nodes.push_back (node);
       
   990       }
       
   991   }
       
   992   
       
   993   Ipv4BusNetwork::~Ipv4BusNetwork ()
       
   994   {
       
   995   }
       
   996   
       
   997     Ptr<Node>
       
   998   Ipv4BusNetwork::GetNode (uint32_t n)
       
   999   {
       
  1000     return m_nodes[n];
       
  1001   }
       
  1002   
       
  1003   }; // namespace ns3
       
  1004 @end verbatim
       
  1005 
       
  1006 @section Using Ipv4BusNetwork
       
  1007 If all you ever want to do with a bus network can be captured in a topology
       
  1008 with four nodes on the bus, the preceeding section may seem like a colossal
       
  1009 waste of time.  This is probably not the case, though.  Now that we have a
       
  1010 relatively abstract bus class, we can create bus networks with 4, 40 or 4000
       
  1011 nodes with no additional effort.
       
  1012 
       
  1013 A use of the bus network class is shown in the file 
       
  1014 @code{bus-network.cc} located in the @code{tutorial} directory.  The
       
  1015 interesting code is,
       
  1016 
       
  1017 @verbatim
       
  1018   Ipv4BusNetwork bus ("10.1.0.0", "255.255.0.0", "0.0.0.3",
       
  1019     DataRate(10000000), MilliSeconds(20), 10);
       
  1020 @end verbatim
       
  1021 
       
  1022 Here we create a bus network with the network number ``10.1.0.0'' and the 
       
  1023 network mask ``255.255.0.0'' that completes the IP network definition.  You 
       
  1024 can consider these together as ``10.1.0.0/16'' if you prefer.  The next 
       
  1025 parameter tells the bus to start numbering IP addresses of contained nodes at
       
  1026 ``10.1.0.3'' (remember the network number will be combined).  We provided a
       
  1027 data rate of 10 megabits per second and a latency of 20 milliseconds.  
       
  1028 Finally, we ask the @code{Ipv4BusNetwork} object to create ten nodes in the
       
  1029 network.
       
  1030 
       
  1031 If you are feeling brave, go ahead and change the number of nodes to be 100,
       
  1032 1000, 10,000 or more to generate larger and larger networks.  Before you go 
       
  1033 too far, remember that a trace file will be generated when you run your 
       
  1034 resulting program and ee asked the trace facility to trace all net device 
       
  1035 receive events.  This will include the reception of the broadcast ARP request 
       
  1036 by all of the nodes in the simulation, so this can add up quickly.
       
  1037 
       
  1038 @c ========================================================================
       
  1039 @c Summary
       
  1040 @c ========================================================================
       
  1041 
       
  1042 @node Summary
       
  1043 @chapter Summary
       
  1044 
       
  1045 This concludes the first part of the tutorial.  We have focused on
       
  1046 using the @command{ns-3} system to construct various network topologies and to
       
  1047 simulate sendng data across the networks; and we've shown you how to use the 
       
  1048 trace facility to get access to simulation results.
       
  1049 
       
  1050 We now encourage you to play with the system a little.  Experiment with what
       
  1051 we have provided.  Build a hierarchical network simulation.  Perhaps exercise
       
  1052 your object design skills and create a new @code{Ipv4DumbbellNetwork} class 
       
  1053 to create dumbbell networks using the Ipv4BusNetwork class we just created.
       
  1054 Hint:  An Ipv4DumbbellNetwork @emph{has} two @code{Ipv4BusNetwork} objects; 
       
  1055 a left side and a right side.
       
  1056 
       
  1057 In the next part of the tutorial we are going to drop down a level and begin
       
  1058 examining the lower levels of the system in more detail.  We are going to
       
  1059 explain how to change the behavior of the system and eventually how to write
       
  1060 new models and applications.  This is a good time to make sure that you
       
  1061 thoroughly understand what we've gone over so far.
       
  1062 
       
  1063 @c ========================================================================
       
  1064 @c Object Model
       
  1065 @c ========================================================================
       
  1066 
       
  1067 @node Object-Model
       
  1068 @chapter Object Model
       
  1069 
       
  1070 @cindex Object Model
       
  1071 There are two distinctly different meanings associated with the term Object
       
  1072 Model.  The first speaks to the implementation of an object system --- a system
       
  1073 view; and the second speaks to the application programming interface (classes
       
  1074 or objects) one uses to access some service or system --- an application view.
       
  1075 
       
  1076 As an example of the system view sense of the term, the C++ language has an
       
  1077 associated object model that describes how objects are laid out in memory,
       
  1078 how virtual functions work, how inheritance is implemented, constructor and
       
  1079 destructor execution ordering, template instantiation, etc.
       
  1080 
       
  1081 @cindex API
       
  1082 @cindex DOM
       
  1083 @cindex Document Object Model
       
  1084 In the case of the application view, the Document Object Model is a good
       
  1085 example.  In the words of W3C, the Document Object Model (DOM) is an
       
  1086 application programming interface (API) for HTML and XML documents. It defines
       
  1087 the logical structure of documents and the way a document is accessed and
       
  1088 manipulated.
       
  1089 
       
  1090 @cindex API
       
  1091 @cindex COM
       
  1092 @cindex Component Object Model
       
  1093 The Component Object Model (COM) from Microsoft actually spans both meanings
       
  1094 of the term and extends further into policy statements.  From a system
       
  1095 perspective, COM specifies an interface definition language, the layout of
       
  1096 objects virtual function tables, the formats of Globally Unique Identifiers
       
  1097 and also specifies lifetime management mechanisms for objects via reference
       
  1098 counting.  From the point of view of the API, COM specifies a number of
       
  1099 Interfaces as well as functions such as CoCreateInstance and various
       
  1100 threading models.  The COM specification extends to policy by disallowing
       
  1101 implementation inheritance.
       
  1102 
       
  1103 @cindex Feynman
       
  1104 The @command{ns-3} object model takes the C++ language (system level) object 
       
  1105 model as its basis, and extends that model by providing an API for software
       
  1106 componentry.  You may find terms like Component, Interface and QueryInterface
       
  1107 in the following discussion, or used informally in other discussions about 
       
  1108 @command{ns-3}.  It is important to understand from the outset that this is
       
  1109 the @command{ns-3} object model, and not any other object model.
       
  1110 Richard Feynman (an American physicist) once described the behavior of matter 
       
  1111 and light on a very small scale in the following way,
       
  1112 
       
  1113 @quotation
       
  1114 ``They do not behave like waves, they do not behave like particles, they do
       
  1115 not behave like clouds, or billiard balls, or weights on springs, or like
       
  1116 anything that you have ever seen.''
       
  1117 @end quotation
       
  1118 
       
  1119 Just as students of quantum mechanics must rid themselves of preconceptions
       
  1120 regarding the behavior of matter at small scales, you should rid yourself of
       
  1121 any preconceptions you may have about components, interfaces and APIs for
       
  1122 software componentry before continuing.  To paraphrase Feynman, @command{ns-3}
       
  1123 components do not behave like COM Components, or Java Beans, or CORBA
       
  1124 objects, or clouds or weights on springs, or like anything that you have 
       
  1125 ever seen --- they are @command{ns-3} components.
       
  1126 
       
  1127 @section The C++ Object Model is the Root of all Things
       
  1128 @command{Ns-3} is primarily a C++ system.  The system is written in C++ and
       
  1129 one can use standard C++ mechanisms for creating and using ns-3 objects.  We 
       
  1130 do not change this at all, nor do we make any pronouncements about the 
       
  1131 superiority of one mechanism or another.  What we will do is provide 
       
  1132 convenience functions that we think will make creating and managing simulation
       
  1133 objects easier.
       
  1134   
       
  1135 @cindex CreateObject
       
  1136 Previously, you have seen objects created using the template function 
       
  1137 @code{CreateObject} as in the following example:
       
  1138 
       
  1139 @verbatim
       
  1140   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
  1141 @end verbatim
       
  1142 
       
  1143 This line of code, while it may be unfamiliar to some, is pure C++.  If you
       
  1144 were to look in the header file ptr.h, you would find the following definition
       
  1145 of the @code{CreateObject} template.
       
  1146 
       
  1147 @verbatim
       
  1148   template <typename T>
       
  1149   Ptr<T> CreateObject (void)
       
  1150   {
       
  1151     Ptr<T> p = Ptr<T> (new T (), false);
       
  1152     p->SetTypeId (T::GetTypeId ());
       
  1153     return p;
       
  1154   }
       
  1155 @end verbatim
       
  1156 
       
  1157 @cindex template
       
  1158 As you can see, this template creates objects of type @code{T} using the
       
  1159 operator @code{new}.  Its a little harder to find the corresponding delete ---
       
  1160 it's in the file @code{object.cc} inside the method @code{Object::MaybeDelete},
       
  1161 but when that @code{Ptr} which you see above goes out of scope it will call
       
  1162 @code{Unref} and ultimately the C++ @code{delete} operator will be called.
       
  1163 
       
  1164 @cindex new
       
  1165 @cindex delete
       
  1166 The ns-3 system uses the C++ @code{new} and @code{delete} operators, so there
       
  1167 is really no reason that you as a user of the ns-3 system are forbidden from
       
  1168 using these or any other C++ mechanism.  If you so desire, you can take on
       
  1169 the responsibility for managing object lifetime (i.e., do not use the 
       
  1170 @code{Ptr} smart pointer), work directly with the @code{new} and @code{delete}
       
  1171 operators and call methods like any C++ object as in the following example:
       
  1172 
       
  1173 @verbatim
       
  1174   MyClass *obj = new MyClass ();
       
  1175   obj->Method();
       
  1176   delete obj;
       
  1177 @end verbatim
       
  1178 
       
  1179 @cindex model
       
  1180 You, as a competent model author, are encouraged to use whatever methods you
       
  1181 think are appropriate in your private code.  Remember, however, that the
       
  1182 public ns-3 APIs do use smart pointers to pass objects around in an effort to
       
  1183 reduce the burden of object lifetime management.  If you do intend to export
       
  1184 an API publicly, you should use the same object lifetime management approaches
       
  1185 as those found in the ns-3 public API if only for consistency.
       
  1186 
       
  1187 These APIs are there for convenience and consistency, but do not change the
       
  1188 fact that in ns-3 all of the objects are really just C++ objects, ultimately
       
  1189 created using the C++ new operator with C++ constructor semantics and are
       
  1190 ultimately deleted using the C++ delete operator, following C++ destructor
       
  1191 semantics.  Although it may sometimes appear so, there is really no system-
       
  1192 level magic going on in ns-3.  Ns-3 components and interfaces are C++ objects
       
  1193 just like any other object and our object model is simply a collection of APIs
       
  1194 built on the normal C++ object model.
       
  1195 
       
  1196 @cindex Interface
       
  1197 @cindex Abstract Data Type
       
  1198 @cindex ADT
       
  1199 @cindex Abstract Base Class
       
  1200 @cindex ABC
       
  1201 @section Interface
       
  1202 There are many different ideas floating around of what exactly the term
       
  1203 @emph{interface} means.  Originally an interface just meant a communication
       
  1204 boundary between two entities.  As the concepts of object oriented programming
       
  1205 (OOP) were surfacing in the 1980s, the term interface was applied to the
       
  1206 collection of access methods for the modular entities that were being defined.
       
  1207 
       
  1208 @cindex OOP
       
  1209 @cindex Object Oriented Programming
       
  1210 Two distinct approaches developed regarding specifying access mechanisms for
       
  1211 objects.  The OOP purists were very concerned about object reuse and were led
       
  1212 to Abstract Data Types (ADT).  These were eventually implemented in the case
       
  1213 of C++, as pure virtual methods in Abstract Base Classes (ABC).  Another group
       
  1214 of folks was more interested in simply specifying object access methods in one
       
  1215 place and using inheritance as the primary reuse mechanism.
       
  1216 
       
  1217 Bjarne Stroustroup, the creator of C++, embraced both approaches.  He makes
       
  1218 the following interesting observation:
       
  1219 
       
  1220 @quotation
       
  1221 ``Many classes [@dots{}] are useful both as themselves and also as bases for
       
  1222 derived classes. [@dots{}] Some classes, such as class @strong{Shape},
       
  1223 represent abstract concepts for which objects cannot exist.''
       
  1224 @end quotation
       
  1225 
       
  1226 @cindex PIMPL
       
  1227 @command{Ns-3} does not pick and enforce a particular approach.  In 
       
  1228 @command{ns-3} an interface is determined completely by a class declaration
       
  1229 just as any C++ object interface is declared.  If you think of an object as
       
  1230 an abstract concept that should be implemented by derived classes, by all
       
  1231 means, use the Abstract Base Class approach to interface declaration.  If you
       
  1232 think that an object should be completely concrete and you foresee no need
       
  1233 to ever modify its behavior, feel free to avoid declaring any methods virtual.
       
  1234 If you think that an object could be useful as a base class, feel free to
       
  1235 declare its methods virtual.  If you like to use the PIMPL idiom, again, feel
       
  1236 free.  If you want to use any combination of these techniques, feel free.  
       
  1237 We make no restrictions.
       
  1238 
       
  1239 @cindex API
       
  1240 When we speak of an ns-3 interface, we do not worry about interface definition
       
  1241 languages, or pure virtual classes, or registries  we just think about C++
       
  1242 object declarations and their associated methods.  We tend to think of 
       
  1243 interfaces to objects as simply a private or public API.  When we instantiate
       
  1244 an @command{ns-3} interface, it is the C++ object model that dictates how that
       
  1245 object is brought into existence.  When a method is called on an @command{ns-3}
       
  1246 Interface, it is the C++ object model that dictates how that method is 
       
  1247 dispatched.
       
  1248 
       
  1249 We do, however, provide a base class that endows vanilla C++ objects with 
       
  1250 capabilities that can be seen as conceptually similar to those provided by
       
  1251 Microsoft Component Model @emph{Interfaces}.
       
  1252 
       
  1253 @section The Ns-3 Object and GetObject
       
  1254 @cindex Component Object Model
       
  1255 One thing that Microsoft arguably got right in the Component Object Model was
       
  1256 the idea of Interface aggregation and discovery via QueryInterface.  We have 
       
  1257 embraced these ideas in @command{ns-3}.  This was done primarily to address a 
       
  1258 common problem in large software systems.  A good example of this problem 
       
  1259 happens in the @command{ns-3} Node class.
       
  1260 
       
  1261 @cindex OOP
       
  1262 @cindex weak base class
       
  1263 @cindex base class bloat
       
  1264 @cindex Swiss Army Knife class
       
  1265 @cindex Node
       
  1266 If one were to take the standard OOP view of specializing a @code{Node} into
       
  1267 an internet host, for example, one would typically inherit from the @code{Node}
       
  1268 base class and include functionality to implement such things as internet
       
  1269 routing and a TCP/IP protocol stack.  Other types of @code{Node}s might 
       
  1270 inherit from the node class and specialize in different ways, or further
       
  1271 specialize the internet host class, treating it as a base class.  This can
       
  1272 result in a complicated inheritance tree in which some specializations are
       
  1273 simply not available to other branches of the tree which can make reuse
       
  1274 difficult or impossible.  This is known as the @emph{weak base class} problem
       
  1275 and creates pressure to drive functionality up the inheritance tree into the
       
  1276 base classes.  This, in turn, results in @emph{base class bloat} and the 
       
  1277 resulting @emph{swiss army knife} base classes which end up trying to do
       
  1278 everything in one place.
       
  1279 
       
  1280 Even if one successfully avoided these swiss army knife base classes, one
       
  1281 would also want to be able to treat new specializations of @code{Node}
       
  1282 generically in the system.  This means one would pass references to the base
       
  1283 class (@code{Node}) across public APIs.  This introduces @emph{upcasts} prior
       
  1284 to passing across public APIs and corresponding @emph{downcasts} on the other
       
  1285 side in order to gain access to required specialized functions.  As the
       
  1286 inheritance tree becomes more complicated, this approach can cause another
       
  1287 related problem known as the @emph{fragile base class} problem.  This happens
       
  1288 when changes to the base class cause unexpected problems in the various and 
       
  1289 sundry subclasses.  
       
  1290 
       
  1291 These effects seem always to result in a positive feedback loop driving
       
  1292 everything into the base class and destroying much of the encapsulation which
       
  1293 is a hallmark of the object oriented approach.
       
  1294 
       
  1295 @subsection Interface Composition
       
  1296 @cindex Node
       
  1297 There is a completely different way to address the Node specialization
       
  1298 problem.  Instead of approaching the situation using inheritance, one can
       
  1299 look at the problem as one of composition.  We can look at the @code{Node}
       
  1300 class as a container of sorts that holds other objects.  In this case, the
       
  1301 objects would be instances of the classes implementing the internetwork
       
  1302 routing code, or the TCP/IP protocol stack described above.  This approach
       
  1303 preserves the encapsulation and solves the weak base class, base class bloat
       
  1304 and fragile base class problems; but the question of method dispatch 
       
  1305 immediately comes to mind.
       
  1306 
       
  1307 @cindex delegation
       
  1308 In many systems, @emph{delegation} is used.  The base class, @code{Node},
       
  1309 in this approach would provide methods that simply forward to the objects
       
  1310 implementing the desired functionality.  This situation clearly does not
       
  1311 address the base class bloat problem since dispatch methods must be added
       
  1312 to the base class.  The situation is mitigated somewhat by pushing the
       
  1313 implementation of the dispatch methods to contained objects, but the
       
  1314 fundamental problems are still present.  What is really needed is a way
       
  1315 to compose objects but at the same time keep the interfaces to those
       
  1316 objects separated.
       
  1317 
       
  1318 @cindex aggregation
       
  1319 Composition, usually called @emph{aggregation}, along with runtime Interface
       
  1320 discovery is the solution that Microsoft originally championed and that 
       
  1321 @command{ns-3} has adopted --- albeit with many simplifications and a few name
       
  1322 changes.
       
  1323 
       
  1324 @subsection Objects and Interfaces
       
  1325 @cindex COM
       
  1326 @cindex QueryInterface
       
  1327 Now that we have mentioned Microsoft COM and are almost obligated to mention 
       
  1328 the terms Interface and QueryInterface.  For those familiar with COM, loosely
       
  1329 speaking, QueryInterface is to COM as GetObject is to @command{ns-3}.
       
  1330 The analogy, while good conceptually, is superficial from an implementation 
       
  1331 point of view.
       
  1332 
       
  1333 @cindex Node
       
  1334 Addressing our current example of a @code{Node}, generically speaking, each
       
  1335 node needs to aggregate an object that will implement internetwork routing 
       
  1336 and TCP/IP.  The system will need to provide a mechanism for locating the
       
  1337 aggregated objects and allow a client to discover them.  
       
  1338 
       
  1339 @cindex aggregation
       
  1340 @cindex Object
       
  1341 These aggregated objects have interfaces in the C++ sense of collections of
       
  1342 method signatures.  In @command{ns-3}, when objects are capable of 
       
  1343 participating in this aggregation process, they are called @command{ns-3} 
       
  1344 @code{Objects}.  @code{Objects} receive the functionality required for this
       
  1345  participation by inheriting from the @command{ns-3} base class @code{Object}.
       
  1346 
       
  1347 Note well that when we write the word @code{Object} (note the uppercase 'O' in
       
  1348 the spelling and the change of font) we are referring to a kind of C++ object
       
  1349 that has inherited the capability of participating in an aggregation.  The 
       
  1350 @command{ns-3}-specific word @code{Object} can have a significantly different
       
  1351 meaning than that of a vanilla C++ object outside the aforementioned 
       
  1352 inheritance tree, and the difference is only readily apparent via context.
       
  1353 In this tutorial we will always write the @command{ns-3}-specific kind of 
       
  1354 @code{Object} in a fixed font; and will write the vanilla C++ term object in
       
  1355 normal font.  In conversation, you will need to be careful to understand which
       
  1356 term is meant:  object or @code{Object}.
       
  1357 
       
  1358 Once an object has inherited from class @code{Object} it has the ability to
       
  1359 @emph{host} an aggregation.  This means that it has the ability to add other
       
  1360 @code{Objects} to its aggregation via the method @code{AggregateObject}.  It
       
  1361 also means that it can provide a service to @emph{discover} other objects in
       
  1362 its aggregation via the method @code{GetObject}.
       
  1363 
       
  1364 @cindex base class
       
  1365 Technically, the class named @code{Object} is simply a base class that you
       
  1366 will inherit from if you want your @code{Objects} to support aggregation and
       
  1367 discovery.  Many systems have a base class that implements common 
       
  1368 functionality and these base classes are typically called something like 
       
  1369 Object.  The @command{ns-3} version of this base class relates primarily to
       
  1370 @code{Object} aggregation and discovery, although it does also provide methods
       
  1371 to help with intrusive reference counting and tracing as well.
       
  1372 
       
  1373 When a C++ object inherits from the ns-3 Object base class, it is conceptually
       
  1374 promoted to an ns-3 @code{Object} irrespective of how the object was declared
       
  1375 (e.g., as an abstract base class, concrete class, with virtual methods, etc.).
       
  1376 In ns-3, you should associate inheritance from the class named @code{Object}
       
  1377 with promotion of an object to the status of some locatable @code{Object}
       
  1378 rather than with the form of the class declaration.
       
  1379 
       
  1380 @cindex COM
       
  1381 @cindex CORBA
       
  1382 @cindex ORBit
       
  1383 For those of you unfamiliar with Microsoft COM, CORBA or ORBit, this might 
       
  1384 sound obvious.  For those of with such a background, the point we are making 
       
  1385 is that there is no such thing in @command{ns-3} as a separate Interface
       
  1386 declaration, no such thing as an Interface Definition Language, no such thing
       
  1387 as a UUID or GUID, etc.  In @command{ns-3} we just work with C++ objects that
       
  1388 may be given some very useful abilities by inheriting from the @command{ns-3}
       
  1389 base class @code{Object}.  @command{Ns-3} @code{Objects} are not required to
       
  1390 inherit from classes composed of pure virtual methods in order to define an
       
  1391 Interface.  It's all really just ``plain old C++.''
       
  1392 
       
  1393 To summarize, when you instantiate an object that inherits from the 
       
  1394 @code{Object} class, you will have a C++ object that has four important 
       
  1395 properties:  
       
  1396 
       
  1397 @cindex AggregateObject
       
  1398 @cindex GetObject
       
  1399 @itemize @bullet
       
  1400 @item The @code{Object} has a C++ interface defined by the collection of method signatures in its inheritance tree; 
       
  1401 @item The @code{Object} has some way to identify its underlying class uniquely;
       
  1402 @item The @code{Object} is a kind of container that has the ability to aggregate other @code{Objects} using the method @code{AggregateObject};
       
  1403 @item The @code{Object} exports a method called @code{GetObject} that allows for discovery of other aggregated @code{Objects}.
       
  1404 @end itemize
       
  1405 
       
  1406 @cindex base class
       
  1407 @cindex Object
       
  1408 It is crucially important to understand what we have described here
       
  1409 (especially for those coming from other systems that provide similar 
       
  1410 functionality).  A given C++ class has an object access interface that is
       
  1411 essentially the collection of method signatures specified in its inheritance
       
  1412 tree.  This is a C++ object model thing.  Ns-3 provides a base class from 
       
  1413 which the class in question can inherit and be promoted to the status of
       
  1414 @code{Object}.  Once a class becomes an @code{Object} it has inherited the
       
  1415 ability to aggregate and search for other @code{Objects} that are added to
       
  1416 its aggregation.
       
  1417 
       
  1418 That last detail is important.  In @command{ns-3} @code{Objects} are both
       
  1419 containers and specifications for a object method access.  We have previously
       
  1420 mentioned that the @code{Node} class acts as a container.  In fact, the 
       
  1421 @code{Node} class inherits from @code{Object} and is itself an @command{ns-3} 
       
  1422 @code{Object}.  So, when the @code{Node} object is created it is really an 
       
  1423 aggregation of one @code{Object} and you can call @code{AggregateObject} or
       
  1424 @code{GetObject} on the resulting @code{Node} object.  Along with being an
       
  1425 aggregation, the @code{Node} class also describes a public interface.  This
       
  1426 public interface (API) is declared just as any C++ object is declared, via its
       
  1427 class methods as specified in the inheritance tree.  For those steeped in 
       
  1428 COM or CORBA, this is where the concept of Interface works in @command{ns-3}.
       
  1429 Remember that it is generally true that @code{Objects} are both aggregations
       
  1430 and APIs.
       
  1431 
       
  1432 @subsection Aggregations
       
  1433 @cindex aggregate
       
  1434 The figure below shows how an @code{Object} could be illustrated in detail.
       
  1435 The line with the circle at the top of the diagram represents the appearance 
       
  1436 of the @code{Object} API to the external world.  This circle and line are 
       
  1437 together called a lollipop because of its superficial similarity to a kind of
       
  1438 childs candy.  
       
  1439 
       
  1440 @sp 1
       
  1441 @center @image{oneobj,,,,png}
       
  1442 
       
  1443 @cindex API
       
  1444 You could declare this API and associated @code{Object} quite simply using a
       
  1445 non-virtual class as follows,
       
  1446 
       
  1447 @verbatim
       
  1448   class A : public Object {
       
  1449   public:
       
  1450     static ns3::TypeId GetTypeId (void)
       
  1451     {
       
  1452       static ns3::TypeId tid = ns3::TypeId ("A")
       
  1453         .SetParent (Object::GetTypeId ())
       
  1454         .AddConstructor<A> ();
       
  1455       return tid;
       
  1456     }
       
  1457 
       
  1458     A () 
       
  1459     {
       
  1460     }
       
  1461 
       
  1462     void MethodA (void);
       
  1463   };
       
  1464 @end verbatim
       
  1465 
       
  1466 The methods that are then available via the API labeled @code{A} in the
       
  1467 figure above are the methods inherited from the @code{Object} base class 
       
  1468 (@code{GetObject}, @code{Ref}, and @code{Unref}) and those from class 
       
  1469 @code{A} (@code{MethodA}).
       
  1470 
       
  1471 Note that you must declare a @code{TypeId} in your @code{Object} class, and
       
  1472 it must be declared static to make it class-wide in scope.  This @code{TypeId}
       
  1473 is a unifying element in the @command{ns-3} object model and uniquely
       
  1474 identifies @code{Objects} at run-time as being instantiated from a particular
       
  1475 class.  We'll have much more to say about @code{TypiId} shortly.
       
  1476 
       
  1477 You can think of the arc and arrow device coming off each side of the 
       
  1478 illustrated @code{Objects} as part of a connector.  These connectors allow 
       
  1479 @code{GetObject} to search aggregations for an instance of a class type.
       
  1480 The figure below shows an aggregation of three @code{Objects}: A, B and C.
       
  1481 The class declarations for classes @code{B} and @code{C} are substantially 
       
  1482 similar to that of class @code{A}.
       
  1483 
       
  1484 @sp 1
       
  1485 @center @image{threeobj,,,,png}
       
  1486 
       
  1487 You can visualize these @code{Objects} as being snapped together like Lego
       
  1488 building blocks if you like.  When @code{Objects} are aggregated, a
       
  1489 @code{GetObject} search path is formed through the connectors.  In order
       
  1490 to create this aggregation you will first need to create the @code{Objects}.
       
  1491 These are just normal, everyday C++ objects that we can create using the
       
  1492 @code{CreateObject} template function and manage using smart pointers.  The 
       
  1493 following code should be obvious to you by now:
       
  1494 
       
  1495 @verbatim
       
  1496   Ptr<A> a = CreateObject<A> ();
       
  1497   Ptr<B> b = CreateObject<B> ();
       
  1498   Ptr<C> c = CreateObject<C> ();
       
  1499 @end verbatim
       
  1500 
       
  1501 @cindex aggregation
       
  1502 When you create an aggregation, you pick one of the @code{Objects} of the
       
  1503 aggregation to think of as the container.  In this case well pick @code{Object}
       
  1504 A.  In order to aggregate an @code{Object}, you simply call the method
       
  1505 @code{AggregateObject} that your class has inherited from class @code{Object}.
       
  1506 The following code will aggregate @code{Object B} and @code{Object C} onto
       
  1507 the @code{Object} (and container/aggregation) @code{A}.
       
  1508 
       
  1509 @cindex AggregateObject
       
  1510 @cindex GetObject
       
  1511 @cindex Object
       
  1512 @verbatim
       
  1513   a->AggregateObject (b);
       
  1514   a->AggregateObject (c);
       
  1515 @end verbatim
       
  1516 
       
  1517 Thats all there is to it.  Now that you have those connectors snapped
       
  1518 together, you can ask each of the @code{Objects} in the aggregation for any of
       
  1519 the other @code{Objects} in the aggregation.  Lets look at a simple example:
       
  1520 
       
  1521 @verbatim
       
  1522   Ptr<B> newB = a->GetObject<B> ();
       
  1523 @end verbatim
       
  1524 
       
  1525 Now, the explanation of what this snippet does is not as simple as writing it.
       
  1526 The left hand side of this assignment declares a smart pointer to the class 
       
  1527 @code{B} to help with memory management of the returned @code{Object} pointer.
       
  1528 You should be very familiar with smart pointers at this stage of the tutorial.
       
  1529 
       
  1530 The right hand side illustrates how @code{GetObject} is acutally used.  
       
  1531 The method @code{GetObject} is templated.  The assocated template parameter 
       
  1532 (between the brackets) specifies the @emph{class} that is being requested.
       
  1533 This is important.  Since it is the class type that specifies the search
       
  1534 criterion, there can be only one instance of a particular class present in an
       
  1535 aggregation.  Looking back a little, although the parameter to
       
  1536 @code{AggregateObject} appears to be a vanilla C++ object (@code{b} or @code{c}
       
  1537 above), it actually represents (is an instance of) a class that has an
       
  1538 associated @code{TypeId} and inherits from @code{Object}.  When you call
       
  1539 @code{GetObject} you specify the search criterion (using the template 
       
  1540 parameter) as a class name.  This referenced class must also have an
       
  1541 associated @code{TypeId} and must also have inherited from @code{Object}.
       
  1542 
       
  1543 This may be summarized by saying that @code{AggregateObject} takes an
       
  1544 @emph{instance} of an object of a particular class that inherits from 
       
  1545 @code{Object}. GetObject looks for a @emph{class} of a particular type
       
  1546 (that again inherits from @code{Object}) and possibly returns an aggregated
       
  1547 object instance of that type.
       
  1548 
       
  1549 Now that you have those conceptual connectors snapped together, you can ask 
       
  1550 each of the @code{Objects} in the aggregation for any of the @code{Objects}
       
  1551 in the aggregation.  For example we could walk the @code{Objects} asking each
       
  1552 for the next in the aggregation.  First we would ask the @code{Object} pointed
       
  1553 to by the smart pointer @code{a} to look for the @code{Object} @code{class B}:
       
  1554 
       
  1555 @verbatim
       
  1556   Ptr<B> newB = a->GetObject<B> ();
       
  1557 @end verbatim
       
  1558 
       
  1559 Next, we can ask the @code{Object} pointed to by the smart pointer @code{newB}
       
  1560 to look for the @code{Object} representing @code{class C}:
       
  1561 
       
  1562 @verbatim
       
  1563   Ptr<C> newC = newB->GetObject<C> ();
       
  1564 @end verbatim
       
  1565 
       
  1566 @cindex Object
       
  1567 Then, we can ask the @code{Object} pointed to by the smart pointer @code{newC}
       
  1568 to look for the @code{Object} representing @code{class A} and complete our
       
  1569 circuit of the aggregation:
       
  1570 
       
  1571 @verbatim
       
  1572   Ptr<A> newA = newC->GetObject<A> ();
       
  1573 @end verbatim
       
  1574 
       
  1575 @cindex GetObject
       
  1576 @code{GetObject} has some important properties that we need to go over.
       
  1577 Technically, @code{GetObject} is a @emph{symmetric}, @emph{reflexive} and 
       
  1578 @emph{transitive} operation with respect to the set of aggregated 
       
  1579 @code{Objects}.
       
  1580 
       
  1581 @subsubsection Symmetry
       
  1582 @cindex symmetry
       
  1583 The symmetric nature of @code{GetObject} guarantees that if one performs a 
       
  1584 @code{GetObject} on a given @code{Object} for the class of that same
       
  1585 @code{Object}, that @code{GetObject} must succeed.  In other words, the
       
  1586 fact that you accessed the aggregation via an instance of an @code{Object A}
       
  1587 in the aggregation implies the reachability of that @code{Object} in the
       
  1588 aggregation.  This is usually written (by Microsoft) as,
       
  1589 
       
  1590 @center must succeed (A >> A)
       
  1591 
       
  1592 We can illustrate this property with the code snippet,
       
  1593 
       
  1594 @verbatim
       
  1595   Ptr<A> symmetricA = a->GetObject<A> ();
       
  1596   NS_ASSERT (symmetricA);
       
  1597 @end verbatim
       
  1598 
       
  1599 Here we take as given an interface (smart) pointer --- named @code{a} --- on
       
  1600 which we perform a @code{GetObject} looking for the class that represents that
       
  1601 same @code{Object}.  This call must always succeed and a smart pointer to the
       
  1602 aggregated instance of that class is returned.
       
  1603 
       
  1604 @subsubsection Reflexivity
       
  1605 @cindex reflexivity
       
  1606 Calls to @code{GetObject} must also be reflexive.  This means that if you
       
  1607 successfully @code{GetObject} for @code{Object B} from @code{Object A}, then
       
  1608 you must always be able to @code{GetObject} for @code{A} from @code{B}.  This
       
  1609 is usually written as,
       
  1610 
       
  1611 @center must succeed (A >> B, then B >> A)
       
  1612 
       
  1613 This property can be illustrated with the code snippet,
       
  1614 
       
  1615 @verbatim
       
  1616   Ptr<B> b = a->GetObject<B> ();
       
  1617   Ptr<A> reflexiveA = b->GetObject<A> ();
       
  1618   NS_ASSERT (reflexiveA);
       
  1619 @end verbatim
       
  1620 
       
  1621 If the first @code{GetObject} on @code{Object A} looking for @code{Object B} 
       
  1622 succeeds, then a @code{GetObject} on @code{Object B} looking @code{Object A} 
       
  1623 must succeed.
       
  1624 
       
  1625 @subsubsection Transitivity
       
  1626 @cindex transitivity
       
  1627 @code{GetObject} must also be transitive.  This means that if one can
       
  1628 find @code{Object B} from @code{Object A}, and @code{Object C} from
       
  1629 @code{Object B}, then one must also be able to find @code{Object C} from
       
  1630 @code{Object A}.  This is usually written as,
       
  1631 
       
  1632 @center must succeed (A >> B, and B >> C, then A >> C)
       
  1633 
       
  1634 This property can be illustrated with the code snippet,
       
  1635 
       
  1636 @verbatim
       
  1637   Ptr<B> b = a->GetObject<B> ();
       
  1638   Ptr<C> c = b->GetObject<C> ();
       
  1639   Ptr<C> transitiveC = a->GetObject<C> ();
       
  1640   NS_ASSERT (transitiveC);
       
  1641 @end verbatim
       
  1642 
       
  1643 If you can get to @code{Object B} from @code{Object A}, and you can get to
       
  1644 @code{Object C} from @code{Object B}, then a @code{GetObject} on
       
  1645 @code{Object A} looking for @code{Object C} must also succeed.
       
  1646 
       
  1647 @subsection Creating the TypeId
       
  1648 @cindex TypeId
       
  1649 @cindex GetTypeId
       
  1650 The final piece of this puzzle is the @code{TypeId}.  Recall that the
       
  1651 declaration our example object above included the following code
       
  1652 
       
  1653 @verbatim
       
  1654   static ns3::TypeId GetTypeId (void)
       
  1655   {
       
  1656     static ns3::TypeId tid = ns3::TypeId ("A")
       
  1657       .SetParent (Object::GetTypeId ())
       
  1658       .AddConstructor<A> ();
       
  1659     return tid;
       
  1660   }
       
  1661 @end verbatim
       
  1662 
       
  1663 This is the bit of code that ties this all together.  For those unfamiliar
       
  1664 with the idioms involved, this declaration can be rather dense.  First, let's
       
  1665 examine the function declaration itself.  The following code,
       
  1666 
       
  1667 @verbatim
       
  1668   static ns3::TypeId GetTypeId (void) ...
       
  1669 @end verbatim
       
  1670 
       
  1671 declares a function that will be associated with all of the instances of the
       
  1672 given class.  This is a function, not a method, in that it can be accessed 
       
  1673 without a @emph{this} pointer; but it is associated with the class in a 
       
  1674 namespace sense.  The use of this kind of declaration allows one to write,
       
  1675 
       
  1676 @verbatim
       
  1677   return A::GetTypeId (void);
       
  1678 @end verbatim
       
  1679 
       
  1680 if the @code{TypeId} is needed for our @code{class A}.  More generically the
       
  1681 class name can be substituted in a template, as is done deep in the 
       
  1682 @command{ns-3} object system. 
       
  1683 
       
  1684 From this perspective, if you leave out the middle of the function definition,
       
  1685 the boundaries should make sense to you.
       
  1686 
       
  1687 @verbatim
       
  1688   static ns3::TypeId GetTypeId (void)
       
  1689   {
       
  1690     return tid;
       
  1691   }
       
  1692 @end verbatim
       
  1693 
       
  1694 @cindex function-local variable
       
  1695 You are obviously looking at a global function associated with your class
       
  1696 that simply returns a @code{TypeId}.  Now, what about the rest.  The code
       
  1697 
       
  1698 @verbatim
       
  1699     static ns3::TypeId tid = ns3::TypeId ("A")
       
  1700       .SetParent (Object::GetTypeId ())
       
  1701       .AddConstructor<A> ();
       
  1702 @end verbatim
       
  1703 
       
  1704 when found inside the function declaration is called a function-local variable
       
  1705 with associated initialization.  It'll be easier to pick this statement apart
       
  1706 piece by piece as well.  The first line,
       
  1707 
       
  1708 @verbatim
       
  1709     static ns3::TypeId tid = ...
       
  1710 @end verbatim
       
  1711 
       
  1712 is the declaration of the function-local variable tid.  This is essentially 
       
  1713 an initialized global variable, the scope of which has been reduced to within
       
  1714 the enclosing method.  You can think of this as a kind of global variable
       
  1715 that can only be accessed right there where it is created.  If the variable
       
  1716 is initialized, this amounts to the same behavior as if a global static 
       
  1717 initializer was declared in a namespace of the same name as your class.  
       
  1718 Global static initializers are guaranteed by the C++ language definition to
       
  1719 be executed before your main procedure is entered.  So are function-local
       
  1720 variables.
       
  1721 
       
  1722 The variable that is being initialized is of type @code{ns3::TypeId}, is 
       
  1723 named @code{A::tid} since it is inside the class declaration for 
       
  1724 @code{class A}, and is initialized by a call to the constructor for the class
       
  1725 @code{TypeId}.  The constructor for @code{TypeId} takes a @code{std::string}
       
  1726 that can be used to locate the type information for your class.  We usually
       
  1727 privide the class name as the string.
       
  1728 
       
  1729 Hopefully, this much of the declaration is now clear:
       
  1730 
       
  1731 @verbatim
       
  1732   static ns3::TypeId GetTypeId (void)
       
  1733   {
       
  1734     static ns3::TypeId tid = ns3::TypeId ("A")
       
  1735     ...
       
  1736     return tid;
       
  1737   }
       
  1738 @end verbatim
       
  1739 
       
  1740 All that is left now are the lines including @code{SetParent} and
       
  1741 @code{AddConstructor}.
       
  1742 
       
  1743 @verbatim
       
  1744   static ns3::TypeId tid = ns3::TypeId ("A")
       
  1745     .SetParent (Object::GetTypeId ())
       
  1746     .AddConstructor<A> ();
       
  1747 @end verbatim
       
  1748 
       
  1749 The last bit may seem quite odd at first glance, but don't let the way the
       
  1750 code is broken up over several lines throw you.  If you saw something like,
       
  1751 
       
  1752 @verbatim
       
  1753   pointer->TypeId()->SetParent()->AddConstructor();
       
  1754 @end verbatim
       
  1755 
       
  1756 you probably wouldn't hesitate at all.  Clearly, you would think, a method
       
  1757 called @code{TypeId} is called using the pointer called @code{pointer} as 
       
  1758 shown below.
       
  1759 
       
  1760 @verbatim
       
  1761   pointer->TypeId()
       
  1762 @end verbatim
       
  1763 
       
  1764 The method @code{TypeId} must further return a pointer to an object that has
       
  1765 a method called @code{SetParent}.  Just as clearly, @code{SetParent} must
       
  1766 return a pointer to an object that has a method called @code{AddConstructor}.
       
  1767 The same sort of thing is happening in our code snipped, except we are using
       
  1768 references instead of pointers.  Perhaps if we rearrange this code to live on
       
  1769 one line it will be clearer.
       
  1770 
       
  1771 @verbatim
       
  1772   ns3::TypeId ("A").SetParent (Object::GetTypeId ()).AddConstructor<A> ();
       
  1773 @end verbatim
       
  1774 
       
  1775 It's just a string of method calls.  The remaining question is then, what do
       
  1776 those three methods do.
       
  1777 
       
  1778 The first, @code{ns3::TypeId ("A")}, simply allocates a new type in the system
       
  1779 and allows you to refer to it in the future by a string.  We have mentioned
       
  1780 inheritance trees often in the previous discussion.  The second method,
       
  1781 @code{SetParent} associates the class being defined with its parents in the
       
  1782 tree.  Finally, the @code{AddConstructor} method allows you to specify a 
       
  1783 constructor to be used when an instance of your class is created using
       
  1784 @code{CreateObject}.  
       
  1785 
       
  1786 @verbatim
       
  1787   AddConstructor<A> ();
       
  1788 @end verbatim
       
  1789 
       
  1790 You can interpret this as explaining to the @command{ns-3} object system that
       
  1791 you have a constructor named @code{A::A} which takes no parameters.  You are
       
  1792 saying that this constructor should be used when @code{CreateObject} is called
       
  1793 with no parameters.
       
  1794 
       
  1795 By including the structure of the inheritance tree, in @command{ns-3} we can
       
  1796 use implementation inheritance to easily create new @code{Objects}.  You are
       
  1797 prevented from doing so in Microsoft COM, but this was almost universally
       
  1798 identified as a problem.
       
  1799 
       
  1800 So, looking at the entire @code{GetTypeId} declaration again,
       
  1801 
       
  1802 @verbatim
       
  1803   static ns3::TypeId GetTypeId (void)
       
  1804   {
       
  1805     static ns3::TypeId tid = ns3::TypeId ("A")
       
  1806       .SetParent (Object::GetTypeId ())
       
  1807       .AddConstructor<A> ();
       
  1808     return tid;
       
  1809   }
       
  1810 @end verbatim
       
  1811 
       
  1812 it should be clear what is happening.
       
  1813 
       
  1814 @subsection A Very Real Example
       
  1815 @cindex Node
       
  1816 @cindex AggregateObject
       
  1817 @cindex GetObject
       
  1818 @cindex Object
       
  1819 At this point you may be asking yourself what the point of all of this is,
       
  1820 since you already had those pointers laying around when you created the
       
  1821 objects.  The typical case is that one will create and aggregate some number
       
  1822 of @code{Objects} in a constructor and return only a pointer to a single
       
  1823 @code{Object} as in our canonical example with @code{class Node}.  In this
       
  1824 case, the @code{Node} would be created and the @code{Node} constructor might
       
  1825 create and call @code{AggregateObject} to aggregate the @code{Objects} for
       
  1826 internetwork routing and TCP/IP.  From an external point of view, these 
       
  1827 aggregated objects may be discovered at run-time using @code{GetObject}.
       
  1828 
       
  1829 Generally one tends to think of one of the @code{Objects} in the aggregation
       
  1830 as being the container and other @code{Objects} being aggregated to that
       
  1831 container.  In the case of a Node, for example, it is quite natural to think
       
  1832 of the Node as being the container which contains protocol stacks, internet
       
  1833 routing, etc.  So, lets start thinking about a real example by calling the 
       
  1834 container @code{Object Node} instead of @code{A} as we have been.  The 
       
  1835 creation of this @code{Object} is found all over our example programs.  For 
       
  1836 example, you will find code like the following in 
       
  1837 @code{samples/simple-point-to-point.cc}:
       
  1838 
       
  1839 @verbatim
       
  1840   Ptr<Node> n = CreateObject<InternetNode> ();
       
  1841 @end verbatim
       
  1842 
       
  1843 It may appear obvious to you now that the @code{InternetNode} class name
       
  1844 provided to the template function @code{CreateObject} means that 
       
  1845 @code{InternetNode} is an @command{ns-3} @code{Object} and you will be able to
       
  1846 call @code{GetObject} on the resulting smart pointer.  Well, I'm afraid that's
       
  1847 not entirely true.  It's slightly more complicated.
       
  1848 
       
  1849 Take a look at @code{src/internet-stack/internet-stack.h} and find the class
       
  1850 declaration for @code{InternetNode}.
       
  1851 
       
  1852 @verbatim
       
  1853   class InternetNode : public Node
       
  1854   {
       
  1855   public:
       
  1856     InternetNode();
       
  1857     ...
       
  1858   };
       
  1859 @end verbatim
       
  1860 
       
  1861 @cindex GetTypeId
       
  1862 @cindex TypeId
       
  1863 @cindex Object
       
  1864 There is no declaration of a @code{static TypeId GetTypeId (void)} in this
       
  1865 class.  This means that the @code{InternetNode} is really not an @code{Object}
       
  1866 for which you can @code{GetObject}.  It turns out that the @code{InternetNode}
       
  1867 is an @emph{implementation class} of the @code{Node Object}.
       
  1868 
       
  1869 You may recall that there can be an implicit cast in a smart pointer
       
  1870 assignment if the cast is to a visible, unambiguous base class.  That is, in 
       
  1871 fact, what is happening here.  Now, take a look at @code{src/node/node.h} and
       
  1872 find the class declaration for @code{class Node}.  There you will find,
       
  1873 
       
  1874 @verbatim
       
  1875   class Node : public Object
       
  1876   {
       
  1877   public:
       
  1878     static TypeId GetTypeId (void);
       
  1879     ...
       
  1880   };
       
  1881 @end verbatim
       
  1882 
       
  1883 Class @code{InternetNode} inherits from class @code{Node} that, in turn,
       
  1884 inherits from class @code{Object}.  It is @code{Node} that provides a
       
  1885 @code{GetTypeId} method.  Therefore it is @code{Node} that is an 
       
  1886 @command{ns-3} @code{Object}.  Note well that @code{InternetNode} is not an
       
  1887 @code{Object} in the sense that one should call @code{GetObject} on an 
       
  1888 aggregation looking for an @code{InternetNode} class.  That is, you should not
       
  1889 do,
       
  1890 
       
  1891 @verbatim
       
  1892   Ptr<InternetNode> i = node->GetObject<InternetNode> ();
       
  1893 @end verbatim
       
  1894 
       
  1895 since there really is not InternetNode::GetTypeId.  It is @code{Node} that is 
       
  1896 the @emph{proper} @code{Object} in this case and you should view 
       
  1897 @code{InternetNode} as an implementation of the @code{Node Object}.  This may
       
  1898 become clearer as we look a little deeper.
       
  1899 
       
  1900 We spoke of a protocol stack that is aggregated to a @code{Node} in our
       
  1901 discussions above, what we see in the real @command{ns-3} code is that this
       
  1902 is represented by the @code{Ipv4 Object}.  If you look in 
       
  1903 @code{src/node/ipv4.h} you will find,
       
  1904 
       
  1905 @verbatim
       
  1906   class Ipv4 : public Object
       
  1907   {
       
  1908   public:
       
  1909     static TypeId GetTypeId (void);
       
  1910     ...
       
  1911   };
       
  1912 @end verbatim
       
  1913 
       
  1914 Since class @code{Ipv4} inherits from class @code{Object} and has a 
       
  1915 @code{GetTypeId}, it is an @command{ns-3} @code{Object}.  If you look in
       
  1916 @code{src/node/ipv4.cc} you will find,
       
  1917 
       
  1918 @verbatim
       
  1919 TypeId
       
  1920 Ipv4::GetTypeId (void)
       
  1921 {
       
  1922   static TypeId tid = TypeId ("Ipv4")
       
  1923     .SetParent<Object> ();
       
  1924   return tid;
       
  1925 }
       
  1926 @end verbatim
       
  1927 
       
  1928 After all of this reading you know that this code snippet is asking the
       
  1929 system to create a unique @code{TypeId} for the @code{Ipv4} class and
       
  1930 declares that @code{Ipv4} inherits from class @code{Object}.  This is what
       
  1931 makes an @code{Ipv4} an @code{Object}.
       
  1932 
       
  1933 @cindex Ipv4
       
  1934 It turns out that the Ipv4 class is an abstract base class (ABC).  There are
       
  1935 a number of pure virtual methods declared in that class.  This means that
       
  1936 an @code{Ipv4} object may not be instantiated.  This is reflected by the fact
       
  1937 that there are no constructors registered in the @code{GetTypeId} method above.
       
  1938 What is instantiated in the real system is an implementation class, called 
       
  1939 @code{Ipv4Impl}.  This class inherits from @code{Ipv4} and provides the 
       
  1940 required virtual methods.  This is where understanding what is an 
       
  1941 @code{Object} and what is not can get tricky.  The @code{Object} is the 
       
  1942 @code{Ipv4} class since that is where the @code{GetTypeId} is found.  The fact
       
  1943 that you see @code{GetTypeId} there tells you that the @code{Ipv4} class is
       
  1944 the class for which you can @code{GetObject}.
       
  1945 
       
  1946 @cindex implementation class
       
  1947 The class @code{Ipv4Impl} provides an implementation for the pure virtual
       
  1948 methods in @code{Ipv4}.  Since class @code{Ipv4} cannot be instantiated, one
       
  1949 instantiates the @code{Ipv4Impl} class to create an @code{Ipv4} @code{Object}.
       
  1950 You will use the @code{CreateObject} template function to create an object that
       
  1951 implements the methods of an @code{Object}.  You can probably see how this
       
  1952 gets even more tricky in conversation.
       
  1953 
       
  1954 Once the @code{Ipv4Impl} object is instantiated, the resulting pointer is
       
  1955 immediately cast to an @code{Ipv4} pointer.  Clients will then use the
       
  1956 methods specified in the @code{Ipv4} class to access the @code{Ipv4 Object}
       
  1957 methods which are, in turn, implemented in the @code{Ipv4Impl} object.
       
  1958 
       
  1959 If you now look in the file, @code{src/internet-stack/internet-stack.cc} you
       
  1960 will see the following code in @code{InternetNode::Construct} that creates the
       
  1961 @code{Ipv4} Interface and aggregates it.
       
  1962 
       
  1963 @verbatim
       
  1964   Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> (ipv4);
       
  1965   ...
       
  1966   Object::AggregateObject (ipv4Impl);
       
  1967 @end verbatim
       
  1968 
       
  1969 Note that the parameter @code{ipv4} passed to the @code{CreateObject} template
       
  1970 function is actually a pointer to an @code{Ipv4L3Protocol} which you can
       
  1971 ignore at this point --- it doesn't really have anything to do with the 
       
  1972 @code{Ipv4} Interface.
       
  1973 
       
  1974 This is exactly the same thing that is happening in the case of the 
       
  1975 @code{InternetNode}.
       
  1976 
       
  1977 @verbatim
       
  1978   Ptr<Node> n = CreateObject<InternetNode> ();
       
  1979 @end verbatim
       
  1980 
       
  1981 @cindex implementation object
       
  1982 @code{CreateObject} is being called to create an implementation object,
       
  1983 in this case @code{InternetNode}, which implements the methods of the 
       
  1984 @code{Node Object}.  It is the resulting @code{Node Object} which you would
       
  1985 use as the container and it is the @code{Node} class that you would use as
       
  1986 the template parameter when calling @code{GetObject}.  In the same way, you
       
  1987 would @emph{not} want to do,
       
  1988 
       
  1989 @verbatim
       
  1990   Ptr<Ipv4> ipv4 = node->GetObject<Ipv4Impl> ();
       
  1991 @end verbatim
       
  1992 
       
  1993 Rather you should understand that the @emph{proper} @code{Object} is the 
       
  1994 @code{Ipv4} not the @code{Ipv4Impl} and do the following,
       
  1995 
       
  1996 @verbatim
       
  1997   Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
       
  1998 @end verbatim
       
  1999 
       
  2000 @cindex CreateObject
       
  2001 This does illustrate that the fact that whether an object created by 
       
  2002 @code{CreateObject} is or is not an @code{Object} in the usual sense can be
       
  2003 quite well hidden if you are casually looking at the object creation code.
       
  2004 The designers of the system had long and involved discussions on this issue 
       
  2005 and in the end decided that mnemonic aids such as Hungarian notation were a
       
  2006 stylistic thing and you should just refer to the system documentation to
       
  2007 determine what objects are @command{ns-3} @code{Objects} and what the APIs 
       
  2008 of those @code{Objects} actually are (RTFM --- as in Read the Fine Manual, 
       
  2009 of course).
       
  2010 
       
  2011 @cindex AggregateObject
       
  2012 @cindex Object
       
  2013 In the case of @code{Ipv4Impl}, you know that the class inherits somehow 
       
  2014 from @code{Object} since there is a call to @code{AggregateObject} that
       
  2015 refers to an instance of an @code{Ipv4Impl}.  You will have to go to
       
  2016 the header file @code{src/internet-stack/ipv4-impl.h} and find that
       
  2017 @code{Ipv4Impl} inherits from class @code{Ipv4}.  You will then have go to
       
  2018 the file @code{src/node/ipv4.h} and see that it inherits from @code{Object} and
       
  2019 defines a @code{GetTypeId}.  Thus the @code{Object} for which you can
       
  2020 @code{GetObject} is really the @code{Ipv4 Object}.
       
  2021 
       
  2022 Returning to some real @command{ns-3} example code, lets take a look at 
       
  2023 @code{examples/simple-point-to-point.cc}.  You will find the following
       
  2024 code in this file:
       
  2025 
       
  2026 @verbatim
       
  2027   Ptr<Node> n0 = CreateObject<InternetNode> ();
       
  2028   ...
       
  2029   Ptr<Ipv4> ipv4;
       
  2030   ipv4 = n0->GetObject<Ipv4> ();
       
  2031   ipv4->SetDefaultRoute (Ipv4Address (``10.1.1.2''), 1);
       
  2032 @end verbatim
       
  2033 
       
  2034 @cindex InternetNode
       
  2035 @cindex Node
       
  2036 @cindex Object
       
  2037 @cindex GetObject
       
  2038 The first line creates an @code{InternetNode} implementation object and casts
       
  2039 the resulting smart pointer to a @code{Node} as we have discussed extensively.
       
  2040 The next line shown declares a smart pointer to an @code{Ipv4 Object}.  We
       
  2041 then do a @code{GetObject} on the @code{Node} looking for the 
       
  2042 @code{Ipv4 Object}.  You know since you've read every line of this tutorial
       
  2043 in detail exactly how that @code{Ipv4 Object} got into every @code{Node}.  You
       
  2044 know that the @code{GetObject} will return a smart pointer to its aggregated 
       
  2045 @code{Ipv4} Interface.  Once we have the @code{Ipv4} smart pointer, we simply
       
  2046 use it as if it were any other C++ object.  The last line shows this by
       
  2047 setting the default route for the node.
       
  2048 
       
  2049 @section Caveats
       
  2050 There are a few things that you should remember but which may not be 
       
  2051 immediately obvious.  
       
  2052 
       
  2053 @subsection Ns-3 Objects are Associated with Classes not C++ objects
       
  2054 @cindex Object
       
  2055 @cindex GetObject
       
  2056 @cindex iterate
       
  2057 @cindex aggregation
       
  2058 @cindex GetNDevices
       
  2059 Okay, you can see some of the problems with the terminology popping up again.
       
  2060 We are reminding you that when you do a GetObject you are providing the key
       
  2061 to the lookup by giving a class name and not anything that is unique to a
       
  2062 C++ object.
       
  2063 
       
  2064 You cannot add more than one @code{Object} of a given type (class name) to an
       
  2065 aggregation.  If you need to contain a number of @code{Objects} of the same
       
  2066 type in the same aggregation, you will need to provide a separate container 
       
  2067 over which you can iterate.  For example, the @code{Node} class provides 
       
  2068 methods,
       
  2069 
       
  2070 @verbatim
       
  2071   uint32_t GetNDevices (void) const;
       
  2072   Ptr<NetDevice> GetDevice (uint32_t index) const;
       
  2073 @end verbatim
       
  2074 
       
  2075 that are used iterate over the multiple @code{NetDevice} @code{Objects}
       
  2076 associated with it.
       
  2077 
       
  2078 @emph{Remember:  Object types do not identify objects.}
       
  2079 
       
  2080 @subsection Dont use GetObject to Check Your Own Type.
       
  2081 @cindex GetObject
       
  2082 It is tempting to use @code{GetObject} as a form of runtime type
       
  2083 information.  Dont do it.  You have no control over what @emph{other}
       
  2084 object may be added to your aggregation.  Someone else may have
       
  2085 appropriated (reimplemented) your type and aggregated themselves onto the
       
  2086 aggregation.
       
  2087 
       
  2088 Consider a socket factory implementation.  Sockets can be either UDP sockets
       
  2089 or TCP sockets.  A socket factory will have a generic @code{SocketFactory}
       
  2090 Object and either a UDP specific interface for setting UDP parameters or a
       
  2091 similar TCP-specific interface.
       
  2092 
       
  2093 Consider what might happen if you declared your socket factory as a partially
       
  2094 abstract base class, and then provided separate implementations for UDP and
       
  2095 TCP specific methods of this factory in separate concrete classes.  Now 
       
  2096 consider what might happen if you used @code{GetObject} in your base class
       
  2097 to determine if you were a UDP or a TCP factory.
       
  2098 
       
  2099 If a factory, say the UDP version, were not aggregated to any other 
       
  2100 @code{Object}, the base class could @code{GetObject} on itself for the 
       
  2101 UDP-specific class name.  If the @code{GetObject} succeeded, it could then
       
  2102 infer that it was a UDP implementation and would then do any UDP-specific
       
  2103 tasks it could.  [Experienced C++ folks are cringing about how
       
  2104 horrible this design is, but bear with me --- its a simple illustration of 
       
  2105 a specific and perhaps not-too-obvious problem.]
       
  2106 
       
  2107 If another factory, say the TCP version, were not aggregated to any other
       
  2108 Interface, the base class could @code{GetObject} on itself for the UDP-specific
       
  2109 interface.  If this failed, it could then infer that it had a TCP
       
  2110 implementation and would then do any TCP-specific tasks it could.
       
  2111 
       
  2112 Now, what happens when these two working objects are aggregated together by
       
  2113 some innocent end-user.  Since the @code{Objects} are conceptually snapped
       
  2114 together, the TCP implementation would suddenly begin finding the UDP 
       
  2115 Interface from the other class factory and think it was the UPD implementation.
       
  2116 
       
  2117 @emph{Objects should not be used as run-time type information.}
       
  2118 
       
  2119 @section Connecting the Dots
       
  2120 @cindex Object
       
  2121 @cindex GetObject
       
  2122 @cindex AggregateObject
       
  2123 @cindex GetTypeId
       
  2124 @cindex API
       
  2125 This may all sound very complicated to you if this is your first exposure to
       
  2126 these concepts.  It may be annoying if I tell you that its really not as hard
       
  2127 as it sounds.  Rest assured that if you take some time, look at and understand
       
  2128 the examples and write a little test code it will all come together for you.
       
  2129 Grep around the system for @code{AggregateObject} and @code{GetObject} and
       
  2130 take a look at how we have used them.  This will also give you a good idea of
       
  2131 what our core @code{Objects} and associated APIs are.  If you grep for 
       
  2132 @code{GetTypeId} you will find most, if not all of the @code{Object} API
       
  2133 interface declarations in the system.  The more you see this idiom in
       
  2134 use, the more comfortable you will be with the idea and the more you will see
       
  2135 how this addresses the weak base class, swiss army knife base class, and
       
  2136 fragile base class problems I explained at the beginning.
       
  2137 
       
  2138 As I alluded to earlier, the developers had long discussions regarding how to
       
  2139 make navigating the @code{Object} environment easier.  The primary issue was
       
  2140 how we could make it easier to convey to you, the model writer, that an object
       
  2141 was an @code{Object}.  We originally used similar terminology as Microsoft
       
  2142 COM and used QueryInterface instead of @code{GetObject}.  One suggestion was
       
  2143 to adopt the convention that classes that implemented Interfaces must begin
       
  2144 with the letter I.  Microsoft does this, as exemplified by the class IUnknown.
       
  2145 We also toyed with the idea of beginning our header files with ``i-'' as in 
       
  2146 ``i-ipv4.h.'' We considered forcing some structure on Interfaces with a pure
       
  2147 virtual class specification, the names of which begin with an I; and 
       
  2148 corresponding implementations, the names of which begin with a C.  This all
       
  2149 got out of hand fairly quickly.
       
  2150 
       
  2151 In the end we decided that we were really discussing issues of programming
       
  2152 style, and we really could not come up with a strong reason to impose any
       
  2153 particular solution.  No matter what direction we took, we ended up with some
       
  2154 form of extra confusion or extra complexity somewhere in the system.  The 
       
  2155 resulting system is extremely flexible and easy to use.  It is, unfortunately,
       
  2156 sometimes hard to document and talk about.
       
  2157 
       
  2158 @cindex Feynman
       
  2159 If it helps you to think in terms of Microsoft COM and Interfaces, by all means
       
  2160 do so, just be aware that even though @command{ns-3} @code{Objects} descend
       
  2161 from COM in some sense, there are subtle differences that may get you lost or
       
  2162 into trouble.  So to paraphrase Feynman one more time,
       
  2163 
       
  2164 @quotation
       
  2165 ``@command{Ns-3} @code{Objects} do not behave like COM Components, or Java
       
  2166 Beans, or CORBA objects, or clouds or weights on springs, or like anything 
       
  2167 that you have  ever seen --- they are @command{ns-3} components.''
       
  2168 @end quotation
       
  2169 
       
  2170 Just get very familiar with the @command{ns-3} object model.  It is the heart
       
  2171 of the system and if you do not understand it you will not understand how to
       
  2172 write an @command{ns-3} model properly.
       
  2173 
       
  2174 @c ========================================================================
       
  2175 @c Doxygen
       
  2176 @c ========================================================================
       
  2177 
       
  2178 @node The-Doxygen-Documentation-System
       
  2179 @chapter The Doxygen Documentation System
       
  2180 
       
  2181 @node How-To-Change-Things
       
  2182 @chapter How to Change Things
       
  2183 
       
  2184 @node How-To-Set-Default-Values
       
  2185 @chapter How to Set Default Values
       
  2186 
       
  2187 @node How-To-Write-A-New-Application
       
  2188 @chapter How to Write a New Application
       
  2189