address bug 393 (need to overload Install methods for python)
authorCraig Dowell <craigdo@ee.washington.edu>
Thu, 06 Nov 2008 13:08:20 -0800
changeset 3848 affd0834debc
parent 3846 265004d6dc15
child 3849 a10653fa0891
address bug 393 (need to overload Install methods for python)
src/helper/application-container.cc
src/helper/application-container.h
src/helper/csma-helper.cc
src/helper/csma-helper.h
src/helper/emu-helper.cc
src/helper/emu-helper.h
src/helper/internet-stack-helper.cc
src/helper/internet-stack-helper.h
src/helper/mobility-helper.cc
src/helper/mobility-helper.h
src/helper/on-off-helper.cc
src/helper/on-off-helper.h
src/helper/packet-sink-helper.cc
src/helper/packet-sink-helper.h
src/helper/packet-socket-helper.cc
src/helper/packet-socket-helper.h
src/helper/udp-echo-helper.cc
src/helper/udp-echo-helper.h
src/helper/v4ping-helper.cc
src/helper/v4ping-helper.h
src/helper/wifi-helper.cc
src/helper/wifi-helper.h
--- a/src/helper/application-container.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/application-container.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -21,6 +21,14 @@
 
 namespace ns3 {
 
+ApplicationContainer::ApplicationContainer ()
+{}
+
+ApplicationContainer::ApplicationContainer (Ptr<Application> app)
+{
+  m_applications.push_back (app);
+}
+
 ApplicationContainer::Iterator 
 ApplicationContainer::Begin (void) const
 {
--- a/src/helper/application-container.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/application-container.h	Thu Nov 06 13:08:20 2008 -0800
@@ -33,6 +33,18 @@
 class ApplicationContainer
 {
 public:
+  /**
+   * Create an empty ApplicationContainer.
+   */
+  ApplicationContainer ();
+
+  /**
+   * Create an ApplicationContainer with exactly one application
+   *
+   * \param node a node to add to the container
+   */
+  ApplicationContainer (Ptr<Application> application);
+
   typedef std::vector<Ptr<Application> >::const_iterator Iterator;
 
   /**
--- a/src/helper/csma-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/csma-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -173,30 +173,51 @@
   EnableAscii (os, NodeContainer::GetGlobal ());
 }
 
+NetDeviceContainer
+CsmaHelper::Install (Ptr<Node> node) const
+{
+  Ptr<CsmaChannel> channel = m_channelFactory.Create ()->GetObject<CsmaChannel> ();
+  return Install (node, channel);
+}
+
+NetDeviceContainer
+CsmaHelper::Install (Ptr<Node> node, Ptr<CsmaChannel> channel) const
+{
+  return NetDeviceContainer (InstallPriv (node, channel));
+}
 
 NetDeviceContainer 
-CsmaHelper::Install (const NodeContainer &c)
+CsmaHelper::Install (const NodeContainer &c) const
 {
   Ptr<CsmaChannel> channel = m_channelFactory.Create ()->GetObject<CsmaChannel> ();
+
   return Install (c, channel);
 }
 
 NetDeviceContainer 
-CsmaHelper::Install (const NodeContainer &c, Ptr<CsmaChannel> channel)
+CsmaHelper::Install (const NodeContainer &c, Ptr<CsmaChannel> channel) const
 {
-  NetDeviceContainer container;
+  NetDeviceContainer devs;
+
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
     {
-      Ptr<Node> node = *i;
-      Ptr<CsmaNetDevice> device = m_deviceFactory.Create<CsmaNetDevice> ();
-      device->SetAddress (Mac48Address::Allocate ());
-      node->AddDevice (device);
-      Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
-      device->SetQueue (queue);
-      device->Attach (channel);
-      container.Add (device);
+      devs.Add (InstallPriv (*i, channel));
     }
-  return container;
+
+  return devs;
+}
+
+Ptr<NetDevice>
+CsmaHelper::InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const
+{
+  Ptr<CsmaNetDevice> device = m_deviceFactory.Create<CsmaNetDevice> ();
+  device->SetAddress (Mac48Address::Allocate ());
+  node->AddDevice (device);
+  Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
+  device->SetQueue (queue);
+  device->Attach (channel);
+
+  return device;
 }
 
 void 
--- a/src/helper/csma-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/csma-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -161,23 +161,50 @@
   static void EnableAsciiAll (std::ostream &os);
 
   /**
-   * \param c a set of nodes
+   * This method creates an ns3::CsmaChannel with the attributes configured by
+   * CsmaHelper::SetChannelAttribute, an ns3::CsmaNetDevice with the attributes
+   * configured by CsmaHelper::SetDeviceAttribute and then adds the device
+   * to the node and attaches the channel to the device.
    *
-   * This method creates a simple ns3::CsmaChannel with the
-   * attributes configured by CsmaHelper::SetChannelAttribute and
-   * then calls CsmaHelper::Install.
+   * \param node The node to install the device in
+   * \returns A containter holding the added net device.
    */
-  NetDeviceContainer Install (const NodeContainer &c);
+  NetDeviceContainer Install (Ptr<Node> node) const;
+
+  /**
+   * This method creates an ns3::CsmaNetDevice with the attributes configured by
+   * CsmaHelper::SetDeviceAttribute and then adds the device to the node and 
+   * attaches the provided channel to the device.
+   *
+   * \param node The node to install the device in
+   * \param channel The chanel to attach to the device.
+   * \returns A containter holding the added net device.
+   */
+  NetDeviceContainer Install (Ptr<Node> node, Ptr<CsmaChannel> channel) const;
 
   /**
-   * \param c a set of nodes
-   * \param channel the channel to use as a backbone.
+   * This method creates an ns3::CsmaChannel with the attributes configured by
+   * CsmaHelper::SetChannelAttribute.  For each Ptr<node> in the provided
+   * container: it creates an ns3::CsmaNetDevice (with the attributes 
+   * configured by CsmaHelper::SetDeviceAttribute); adds the device to the 
+   * node; and attaches the channel to the device.
    *
-   * For each node in the input container, we create a ns3::CsmaNetDevice with
-   * the requested attributes, a queue for this NetDevice, and associate
-   * the resulting ns3::NetDevice with the ns3::Node and ns3::CsmaChannel.
+   * \param c The NodeContainer holding the nodes to be changed.
+   * \returns A containter holding the added net devices.
    */
-  NetDeviceContainer Install (const NodeContainer &c, Ptr<CsmaChannel> channel);
+  NetDeviceContainer Install (const NodeContainer &c) const;
+
+  /**
+   * For each Ptr<node> in the provided container, this method creates an 
+   * ns3::CsmaNetDevice (with the attributes configured by 
+   * CsmaHelper::SetDeviceAttribute); adds the device to the node; and attaches 
+   * the provided channel to the device.
+   *
+   * \param c The NodeContainer holding the nodes to be changed.
+   * \param channel The channel to attach to the devices.
+   * \returns A containter holding the added net devices.
+   */
+  NetDeviceContainer Install (const NodeContainer &c, Ptr<CsmaChannel> channel) const;
 
   /**
    * \brief Make a star network topology.
@@ -213,6 +240,8 @@
                     NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices);
 
 private:
+  Ptr<NetDevice> InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const;
+
   static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
   static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
   static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
--- a/src/helper/emu-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/emu-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -188,29 +188,35 @@
   EnableAscii (os, NodeContainer::GetGlobal ());
 }
 
-  NetDeviceContainer 
-EmuHelper::Install (const NodeContainer &c)
+NetDeviceContainer
+EmuHelper::Install (Ptr<Node> node) const
 {
-  NS_LOG_FUNCTION (&c);
-  NetDeviceContainer container;
+  return NetDeviceContainer (InstallPriv (node));
+}
+
+NetDeviceContainer 
+EmuHelper::Install (const NodeContainer &c) const
+{
+  NetDeviceContainer devs;
+
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
     {
-      Ptr<Node> node = *i;
+      devs.Add (InstallPriv (*i));
+    }
+
+  return devs;
+}
 
-      Ptr<EmuNetDevice> device = m_deviceFactory.Create<EmuNetDevice> ();
-      //
-      // This is a mac address used for ns-3 internal things.  It cannot override the real MAC address on the NIC in
-      // question.  We use it to spoof the MAC address so packets flowing over the network from the emu device will
-      // have this address, and our ARP will resolve it.
-      //
-      device->SetAddress (Mac48Address::Allocate ());
-      node->AddDevice (device);
+  Ptr<NetDevice>
+EmuHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<EmuNetDevice> device = m_deviceFactory.Create<EmuNetDevice> ();
+  device->SetAddress (Mac48Address::Allocate ());
+  node->AddDevice (device);
+  Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
+  device->SetQueue (queue);
 
-      Ptr<Queue> queue = m_queueFactory.Create<Queue> ();
-      device->SetQueue (queue);
-      container.Add (device);
-    }
-  return container;
+  return device;
 }
 
   void 
--- a/src/helper/emu-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/emu-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -155,11 +155,26 @@
   static void EnableAsciiAll (std::ostream &os);
 
   /**
-   * \param c a set of nodes
+   * This method creates an ns3::EmuNetDevice with the attributes configured by 
+   * EmuHelper::SetDeviceAttribute and then adds the device to the node.
+   *
+   * \param node The node to install the device in
+   * \returns A containter holding the added net device.
    */
-  NetDeviceContainer Install (const NodeContainer &c);
+  NetDeviceContainer Install (Ptr<Node> node) const;
+
+  /**
+   * For each Ptr<node> in the provided container this method creates an 
+   * ns3::EmuNetDevice (with the attributes configured by 
+   * EmuHelper::SetDeviceAttribute); adds the device to the node.
+   *
+   * \param c The NodeContainer holding the nodes to be changed.
+   * \returns A containter holding the added net devices.
+   */
+  NetDeviceContainer Install (const NodeContainer &c) const;
 
 private:
+  Ptr<NetDevice> InstallPriv (Ptr<Node> node) const;
   static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
   static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
   static void AsciiEnqueueEvent (std::ostream *os, std::string path, 
--- a/src/helper/internet-stack-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/internet-stack-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -17,6 +17,7 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
+
 #include "ns3/assert.h"
 #include "ns3/log.h"
 #include "ns3/object.h"
@@ -59,25 +60,35 @@
 }
 
 void 
-InternetStackHelper::Install (NodeContainer c)
+InternetStackHelper::Install (NodeContainer c) const
 {
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      if (node->GetObject<Ipv4> () != 0)
-        {
-          NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating " 
-             "an InternetStack to a node with an existing Ipv4 object");
-          return;
-        }
-      if (m_nscLibrary != "")
-        AddNscInternetStack (node, m_nscLibrary);
-      else
-        AddInternetStack (node);
+      Install (*i);
+    }
+}
 
-      Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
-      node->AggregateObject (factory);
+void
+InternetStackHelper::Install (Ptr<Node> node) const
+{
+  if (node->GetObject<Ipv4> () != 0)
+    {
+      NS_FATAL_ERROR ("InternetStackHelper::Install(): Aggregating " 
+                      "an InternetStack to a node with an existing Ipv4 object");
+      return;
     }
+
+  if (m_nscLibrary != "")
+    {
+      AddNscInternetStack (node, m_nscLibrary);
+    }
+  else
+    {
+      AddInternetStack (node);
+    }
+
+  Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
+  node->AggregateObject (factory);
 }
 
 void
@@ -87,9 +98,9 @@
 
   InternetStackHelper::m_pcapBaseFilename = filename;
   Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Tx",
-                              MakeCallback (&InternetStackHelper::LogTxIp));
+                   MakeCallback (&InternetStackHelper::LogTxIp));
   Config::Connect ("/NodeList/*/$ns3::Ipv4L3Protocol/Rx",
-                              MakeCallback (&InternetStackHelper::LogRxIp));
+                   MakeCallback (&InternetStackHelper::LogRxIp));
 }
 
 uint32_t
--- a/src/helper/internet-stack-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/internet-stack-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -17,6 +17,7 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
+
 #ifndef INTERNET_STACK_HELPER_H
 #define INTERNET_STACK_HELPER_H
 
@@ -28,7 +29,7 @@
 namespace ns3 {
 
 /**
- * \brief aggregate ip/tcp/udp functionality to existing Nodes.
+ * \brief aggregate IP/TCP/UDP functionality to existing Nodes.
  */
 class InternetStackHelper
 {
@@ -36,29 +37,44 @@
   InternetStackHelper(void);
 
   /**
-   * \param c the set of nodes
-   *
-   * For each node in the input container, aggregate implementations
-   * of the ns3::Ipv4, ns3::Udp, and, ns3::Tcp classes.  The program
-   * will assert if this method is called on a container with a node
-   * that already has an Ipv4 object aggregated to it.
+   * Aggregate implementations of the ns3::Ipv4, ns3::Udp, and ns3::Tcp classes
+   * onto the provided node.  This method will assert if called on a node that 
+   * already has an Ipv4 object aggregated to it.
    * 
+   * \param node The node on which to install the stack.
    */
-  void Install (NodeContainer c);
+  void Install (Ptr<Node> node) const;
 
   /**
+   * For each node in the input container, aggregate implementations of the 
+   * ns3::Ipv4, ns3::Udp, and, ns3::Tcp classes.  The program will assert 
+   * if this method is called on a container with a node that already has
+   * an Ipv4 object aggregated to it.
+   * 
+   * \param c NodeContainer that holds the set of nodes on which to install the
+   * new stacks.
+   */
+  void Install (NodeContainer c) const;
+
+  /**
+   * \brief Enable or disable use of the Network Simulation Cradle stack.  
+   *
+   * Give the NSC stack a shared library file name to use when creating the 
+   * statck implementation.  By providing a non-empty string as a parameter, you
+   * select the NSC version of the stack.  By providing an empty string, you 
+   * select the ns-3 default version.
+   *
    * \param soname name of the shared library with the nsc tcp stack
-   * to use, e.g. 'liblinux2.6.26.so'. The empty string resets
-   * the InternetStackHelper to use the ns-3 models again.
+   * to use, e.g. 'liblinux2.6.26.so'.
    */
   void SetNscStack(std::string soname);
 
   /**
-   * \param filename filename prefix to use for pcap files.
-   *
    * Enable pcap output on each protocol instance which is of the
    * ns3::Ipv4L3Protocol type.  Both Tx and Rx events will be logged.
    *
+   * \param filename filename prefix to use for pcap files.
+   *
    * \warning If you perform multiple simulations in a single script,
    * each iteration of the simulation will result in the trace files
    * being overwritten.  We don't attempt to anticipate what a user
--- a/src/helper/mobility-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/mobility-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -114,39 +114,45 @@
   return m_mobility.GetTypeId ().GetName ();
 }
 
+void
+MobilityHelper::Install (Ptr<Node> node) const
+{
+  Ptr<Object> object = node;
+  Ptr<MobilityModel> model = object->GetObject<MobilityModel> ();
+  if (model == 0)
+    {
+      model = m_mobility.Create ()->GetObject<MobilityModel> ();
+      if (model == 0)
+        {
+          NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<< 
+                          m_mobility.GetTypeId ().GetName ()<<"\"");
+        }
+      if (m_mobilityStack.empty ())
+        {
+          NS_LOG_DEBUG ("node="<<object<<", mob="<<model);
+          object->AggregateObject (model);
+        }
+      else
+        {
+          // we need to setup a hierarchical mobility model
+          Ptr<MobilityModel> parent = m_mobilityStack.back ();
+          Ptr<MobilityModel> hierarchical = 
+            CreateObject<HierarchicalMobilityModel> ("Child", PointerValue (model),
+                                                     "Parent", PointerValue (parent));
+          object->AggregateObject (hierarchical);
+          NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
+        }
+    }
+  Vector position = m_position->GetNext ();
+  model->SetPosition (position);
+}
+
 void 
-MobilityHelper::Install (NodeContainer c)
+MobilityHelper::Install (NodeContainer c) const
 {
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Object> object = *i;
-      Ptr<MobilityModel> model = object->GetObject<MobilityModel> ();
-      if (model == 0)
-        {
-          model = m_mobility.Create ()->GetObject<MobilityModel> ();
-          if (model == 0)
-            {
-              NS_FATAL_ERROR ("The requested mobility model is not a mobility model: \""<< 
-                              m_mobility.GetTypeId ().GetName ()<<"\"");
-            }
-          if (m_mobilityStack.empty ())
-            {
-              NS_LOG_DEBUG ("node="<<object<<", mob="<<model);
-              object->AggregateObject (model);
-            }
-          else
-            {
-              // we need to setup a hierarchical mobility model
-              Ptr<MobilityModel> parent = m_mobilityStack.back ();
-              Ptr<MobilityModel> hierarchical = 
-                CreateObject<HierarchicalMobilityModel> ("Child", PointerValue (model),
-                                                         "Parent", PointerValue (parent));
-              object->AggregateObject (hierarchical);
-              NS_LOG_DEBUG ("node="<<object<<", mob="<<hierarchical);
-            }
-        }
-      Vector position = m_position->GetNext ();
-      model->SetPosition (position);
+      Install (*i);
     }
 }
 
--- a/src/helper/mobility-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/mobility-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -17,6 +17,7 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
+
 #ifndef MOBILITY_HELPER_H
 #define MOBILITY_HELPER_H
 
@@ -43,10 +44,10 @@
   ~MobilityHelper ();
 
   /**
-   * \param allocator allocate initial node positions
+   * Set the position allocator which will be used to allocate the initial 
+   * position of every node initialized during MobilityModel::Install.
    *
-   * Set the position allocator which will be used to allocate
-   * the initial position of every node in MobilityModel::Install.
+   * \param allocator allocate initial node positions
    */
   void SetPositionAllocator (Ptr<PositionAllocator> allocator);
 
@@ -149,14 +150,31 @@
   std::string GetMobilityModelType (void) const;
 
   /**
-   * \param container the set of nodes to layout.
+   * \brief "Layout" a single node according to the current position allocator
+   * type.
+   *
+   * This method creates an instance of a ns3::MobilityModel subclass (the 
+   * type of which was set with MobilityHelper::SetMobilityModel), aggregates
+   * it to the provided node, and sets an initial position based on the current
+   * position allocator (set through MobilityHelper::SetPositionAllocator). 
    *
-   * For each input node, this method creates an instance of a ns3::MobilityModel
-   * subclass (the type of which was set with MobilityHelper::SetMobilityModel), 
-   * aggregates it to the mode, and sets an initial position based on the current 
-   * position allocator (set through MobilityHelper::SetPositionAllocator). 
+   * \param node The node to "layout."
    */
-  void Install (NodeContainer container);
+  void Install (Ptr<Node> node) const;
+
+  /**
+   * \brief Layout a collection of nodes according to the current position allocator
+   * type.
+   *
+   * For each node in the provided NodeContainer, this method creates an instance 
+   * of a ns3::MobilityModel subclass (the type of which was set with 
+   * MobilityHelper::SetMobilityModel), aggregates it to the node, and sets an 
+   * initial position based on the current position allocator (set through 
+   * MobilityHelper::SetPositionAllocator). 
+   *
+   * \param container The set of nodes to layout.
+   */
+  void Install (NodeContainer container) const;
 
   /**
    * Perform the work of MobilityHelper::Install on _all_ nodes which
--- a/src/helper/on-off-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/on-off-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -38,18 +38,30 @@
 }
 
 ApplicationContainer
-OnOffHelper::Install (NodeContainer c)
+OnOffHelper::Install (Ptr<Node> node) const
+{
+  return ApplicationContainer (InstallPriv (node));
+}
+
+ApplicationContainer
+OnOffHelper::Install (NodeContainer c) const
 {
   ApplicationContainer apps;
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      Ptr<Application> app = m_factory.Create<Application> ();
-      node->AddApplication (app);
-      apps.Add (app);
+      apps.Add (InstallPriv (*i));
     }
+
   return apps;
 }
 
+Ptr<Application>
+OnOffHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<Application> app = m_factory.Create<Application> ();
+  node->AddApplication (app);
+
+  return app;
+}
 
 } // namespace ns3
--- a/src/helper/on-off-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/on-off-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -54,14 +54,24 @@
   void SetAttribute (std::string name, const AttributeValue &value);
 
   /**
-   * \param c the set of nodes on which an OnOffApplication will be installed.
-   *
    * Install an ns3::OnOffApplication on each node of the input container
    * configured with all the attributes set with SetAttribute.
+   *
+   * \param c NodeContainer of the set of nodes on which an OnOffApplication 
+   * will be installed.
    */
-  ApplicationContainer Install (NodeContainer c);
+  ApplicationContainer Install (NodeContainer c) const;
+
+  /**
+   * Install an ns3::OnOffApplication on each node of the input container
+   * configured with all the attributes set with SetAttribute.
+   *
+   * \param c The node on which an OnOffApplication will be installed.
+   */
+  ApplicationContainer Install (Ptr<Node> node) const;
 
 private:
+  Ptr<Application> InstallPriv (Ptr<Node> node) const;
   std::string m_protocol;
   Address m_remote;
   ObjectFactory m_factory;
--- a/src/helper/packet-sink-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/packet-sink-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -17,6 +17,7 @@
  *
  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
  */
+
 #include "packet-sink-helper.h"
 #include "ns3/string.h"
 #include "ns3/inet-socket-address.h"
@@ -52,19 +53,31 @@
 }
 #endif
 
-ApplicationContainer 
-PacketSinkHelper::Install (NodeContainer c)
+ApplicationContainer
+PacketSinkHelper::Install (Ptr<Node> node) const
+{
+  return ApplicationContainer (InstallPriv (node));
+}
+
+ApplicationContainer
+PacketSinkHelper::Install (NodeContainer c) const
 {
   ApplicationContainer apps;
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      Ptr<Application> app = m_factory.Create<Application> ();
-      node->AddApplication (app);
-      apps.Add (app);
+      apps.Add (InstallPriv (*i));
     }
+
   return apps;
 }
 
+Ptr<Application>
+PacketSinkHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<Application> app = m_factory.Create<Application> ();
+  node->AddApplication (app);
+
+  return app;
+}
 
 } // namespace ns3
--- a/src/helper/packet-sink-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/packet-sink-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -34,8 +34,25 @@
 
   void SetAttribute (std::string name, const AttributeValue &value);
 
-  ApplicationContainer Install (NodeContainer c);
+  /**
+   * Install an ns3::PacketSinkApplication on each node of the input container
+   * configured with all the attributes set with SetAttribute.
+   *
+   * \param c NodeContainer of the set of nodes on which a PacketSinkApplication 
+   * will be installed.
+   */
+  ApplicationContainer Install (NodeContainer c) const;
+
+  /**
+   * Install an ns3::PacketSinkApplication on each node of the input container
+   * configured with all the attributes set with SetAttribute.
+   *
+   * \param c The node on which a PacketSinkApplication will be installed.
+   */
+  ApplicationContainer Install (Ptr<Node> node) const;
+
 private:
+  Ptr<Application> InstallPriv (Ptr<Node> node) const;
   ObjectFactory m_factory;
 };
 
--- a/src/helper/packet-socket-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/packet-socket-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -1,17 +1,42 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
 #include "packet-socket-helper.h"
 #include "ns3/packet-socket-factory.h"
 
 namespace ns3 {
 
-void 
-PacketSocketHelper::Install (NodeContainer c)
+void
+PacketSocketHelper::Install (NodeContainer c) const
 {
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
-      node->AggregateObject (factory);
+	Install (*i);
     }
 }
 
+void
+PacketSocketHelper::Install (Ptr<Node> node) const
+{
+    Ptr<PacketSocketFactory> factory = CreateObject<PacketSocketFactory> ();
+    node->AggregateObject (factory);
+}
+
 } // namespace ns3
--- a/src/helper/packet-socket-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/packet-socket-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -1,3 +1,23 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
 #ifndef PACKET_SOCKET_HELPER_H
 #define PACKET_SOCKET_HELPER_H
 
@@ -12,12 +32,21 @@
 {
 public:
   /**
-   * \param c container of node pointers
+   * Aggregate an instance of a ns3::PacketSocketFactory onto the provided
+   * node.
    *
-   * For each node in the input container, aggregate a ns3::PacketSocketFactory
-   * object instance.
+   * \param node Node on which to aggregate the ns3::PacketSocketFactory.
    */
-  void Install (NodeContainer c);
+  void Install (Ptr<Node> node) const;
+
+  /**
+   * For each node in the provided container, aggregate an instance of a
+   * ns3::PacketSocketFactory.
+   *
+   * \param c NodeContainer of the set of nodes to aggregate the 
+   * ns3::PacketSocketFactory on.
+   */
+  void Install (NodeContainer c) const;
 };
 
 } // namespace ns3
--- a/src/helper/udp-echo-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/udp-echo-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -38,21 +38,33 @@
   m_factory.Set (name, value);
 }
 
+ApplicationContainer
+UdpEchoServerHelper::Install (Ptr<Node> node) const
+{
+  return ApplicationContainer (InstallPriv (node));
+}
 
-ApplicationContainer 
-UdpEchoServerHelper::Install (NodeContainer c)
+ApplicationContainer
+UdpEchoServerHelper::Install (NodeContainer c) const
 {
   ApplicationContainer apps;
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      Ptr<UdpEchoServer> server = m_factory.Create<UdpEchoServer> ();
-      node->AddApplication (server);
-      apps.Add (server);
+      apps.Add (InstallPriv (*i));
     }
+
   return apps;
 }
 
+Ptr<Application>
+UdpEchoServerHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<Application> app = m_factory.Create<UdpEchoServer> ();
+  node->AddApplication (app);
+  
+  return app;
+}
+
 UdpEchoClientHelper::UdpEchoClientHelper (Ipv4Address address, uint16_t port)
 {
   m_factory.SetTypeId (UdpEchoClient::GetTypeId ());
@@ -68,18 +80,31 @@
   m_factory.Set (name, value);
 }
 
-ApplicationContainer 
-UdpEchoClientHelper::Install (NodeContainer c)
+ApplicationContainer
+UdpEchoClientHelper::Install (Ptr<Node> node) const
+{
+  return ApplicationContainer (InstallPriv (node));
+}
+
+ApplicationContainer
+UdpEchoClientHelper::Install (NodeContainer c) const
 {
   ApplicationContainer apps;
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      Ptr<UdpEchoClient> client = m_factory.Create<UdpEchoClient> ();
-      node->AddApplication (client);
-      apps.Add (client);
+      apps.Add (InstallPriv (*i));
     }
-  return apps;  
+
+  return apps;
+}
+
+Ptr<Application>
+UdpEchoClientHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<Application> app = m_factory.Create<UdpEchoClient> ();
+  node->AddApplication (app);
+  
+  return app;
 }
 
 } // namespace ns3
--- a/src/helper/udp-echo-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/udp-echo-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -34,9 +34,13 @@
   UdpEchoServerHelper (uint16_t port);
 
   void SetAttribute (std::string name, const AttributeValue &value);
-  ApplicationContainer Install (NodeContainer c);
+
+  ApplicationContainer Install (Ptr<Node> node) const;
+  ApplicationContainer Install (NodeContainer c) const;
 
- private:
+private:
+  Ptr<Application> InstallPriv (Ptr<Node> node) const;
+
   ObjectFactory m_factory;
 };
 
@@ -46,13 +50,15 @@
   UdpEchoClientHelper (Ipv4Address ip, uint16_t port);
 
   void SetAttribute (std::string name, const AttributeValue &value);
-  ApplicationContainer Install (NodeContainer c);
 
- private:
+  ApplicationContainer Install (Ptr<Node> node) const;
+  ApplicationContainer Install (NodeContainer c) const;
+
+private:
+  Ptr<Application> InstallPriv (Ptr<Node> node) const;
   ObjectFactory m_factory;
 };
 
-
 } // namespace ns3
 
 #endif /* UDP_ECHO_HELPER_H */
--- a/src/helper/v4ping-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/v4ping-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -15,19 +15,31 @@
   m_factory.Set (name, value);
 }
 
-ApplicationContainer 
-V4PingHelper::Install (NodeContainer nodes)
+ApplicationContainer
+V4PingHelper::Install (Ptr<Node> node) const
+{
+  return ApplicationContainer (InstallPriv (node));
+}
+
+ApplicationContainer
+V4PingHelper::Install (NodeContainer c) const
 {
   ApplicationContainer apps;
-  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
     {
-      Ptr<Node> node = *i;
-      Ptr<V4Ping> ping = m_factory.Create<V4Ping> ();
-      node->AddApplication (ping);
-      apps.Add (ping);
+      apps.Add (InstallPriv (*i));
     }
+
   return apps;
 }
 
+Ptr<Application>
+V4PingHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<V4Ping> app = m_factory.Create<V4Ping> ();
+  node->AddApplication (app);
+
+  return app;
+}
 
 } // namespace ns3
--- a/src/helper/v4ping-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/v4ping-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -14,9 +14,11 @@
 
   void SetAttribute (std::string name, const AttributeValue &value);
 
-  ApplicationContainer Install (NodeContainer nodes);
+  ApplicationContainer Install (NodeContainer nodes) const;
+  ApplicationContainer Install (Ptr<Node> node) const;
 
 private:
+  Ptr<Application> InstallPriv (Ptr<Node> node) const;
   ObjectFactory m_factory;
 };
 
--- a/src/helper/wifi-helper.cc	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/wifi-helper.cc	Thu Nov 06 13:08:20 2008 -0800
@@ -239,36 +239,58 @@
 }
 
 NetDeviceContainer
-WifiHelper::Install (NodeContainer c) const
+WifiHelper::Install (Ptr<Node> node) const
+{
+  return Install (NodeContainer (node));
+}
+
+NetDeviceContainer
+WifiHelper::Install (Ptr<Node> node, Ptr<WifiChannel> channel) const
+{
+  return NetDeviceContainer (InstallPriv (node, channel));
+}
+
+NetDeviceContainer 
+WifiHelper::Install (const NodeContainer &c) const
 {
   Ptr<WifiChannel> channel = CreateObject<WifiChannel> ();
   channel->SetPropagationDelayModel (CreateObject<ConstantSpeedPropagationDelayModel> ());
   Ptr<LogDistancePropagationLossModel> log = CreateObject<LogDistancePropagationLossModel> ();
   log->SetReferenceModel (CreateObject<FriisPropagationLossModel> ());
   channel->SetPropagationLossModel (log);
+
   return Install (c, channel);
 }
-NetDeviceContainer
-WifiHelper::Install (NodeContainer c, Ptr<WifiChannel> channel) const
+
+NetDeviceContainer 
+WifiHelper::Install (const NodeContainer &c, Ptr<WifiChannel> channel) const
 {
-  NetDeviceContainer devices;
+  NetDeviceContainer devs;
+
   for (NodeContainer::Iterator i = c.Begin (); i != c.End (); i++)
     {
-      Ptr<Node> node = *i;
-      Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
-      Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
-      Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
-      Ptr<WifiPhy> phy = m_phy.Create<WifiPhy> ();
-      mac->SetAddress (Mac48Address::Allocate ());
-      device->SetMac (mac);
-      device->SetPhy (phy);
-      device->SetRemoteStationManager (manager);
-      device->SetChannel (channel);
-      node->AddDevice (device);
-      devices.Add (device);
-      NS_LOG_DEBUG ("node="<<node<<", mob="<<node->GetObject<MobilityModel> ());
+      devs.Add (InstallPriv (*i, channel));
     }
-  return devices;
+
+  return devs;
+}
+
+Ptr<NetDevice>
+WifiHelper::InstallPriv (Ptr<Node> node, Ptr<WifiChannel> channel) const
+{
+  Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
+  Ptr<WifiRemoteStationManager> manager = m_stationManager.Create<WifiRemoteStationManager> ();
+  Ptr<WifiMac> mac = m_mac.Create<WifiMac> ();
+  Ptr<WifiPhy> phy = m_phy.Create<WifiPhy> ();
+  mac->SetAddress (Mac48Address::Allocate ());
+  device->SetMac (mac);
+  device->SetPhy (phy);
+  device->SetRemoteStationManager (manager);
+  device->SetChannel (channel);
+  node->AddDevice (device);
+  NS_LOG_DEBUG ("node="<<node<<", mob="<<node->GetObject<MobilityModel> ());
+
+  return device;
 }
 
 } // namespace ns3
--- a/src/helper/wifi-helper.h	Wed Nov 05 19:53:52 2008 -0800
+++ b/src/helper/wifi-helper.h	Thu Nov 06 13:08:20 2008 -0800
@@ -218,35 +218,65 @@
   static void EnableAsciiAll (std::ostream &os);
 
   /**
-   * \param c a set of nodes
+   * This method creates a new ns3::WifiNetDevice that is configured with an 
+   * ns3::WifiRemoteStationManager, ns3::WifiMac and ns3::WifiPhy, all of which 
+   * are created based on the user-specified attributes in 
+   * WifiHelper::SetRemoteStationManager, WifiHelper::SetMac, and 
+   * WifiHelper::SetPhy.  It attaches this new device to the provided node.  It 
+   * also creates a simple ns3::WifiChannel (with a default ns3::PropagationLossModel
+   * and ns3::PropagationDelayModel) and attaches the new channel to the new device. 
    *
-   * This method creates a simple ns3::WifiChannel (with a default
-   * ns3::PropagationLossModel and ns3::PropagationDelayModel) and 
-   * creates, for each of the input nodes, a new ns3::WifiNetDevice 
-   * attached to this shared channel. Each ns3::WifiNetDevice is also
-   * configured with an ns3::WifiRemoteStationManager, ns3::WifiMac, and,
-   * ns3::WifiPhy, all of which are created based on the user-specified
-   * attributes specified in WifiHelper::SetRemoteStationManager, 
-   * WifiHelper::SetMac, and, WifiHelper::SetPhy.
+   * \param node The node to install the device in
+   * \returns A containter holding the added net device.
    */
-  NetDeviceContainer Install (NodeContainer c) const;
+  NetDeviceContainer Install (Ptr<Node> node) const;
+
+  /**
+   * This method creates a new ns3::WifiNetDevice that is configured with an 
+   * ns3::WifiRemoteStationManager, ns3::WifiMac and ns3::WifiPhy, all of which 
+   * are created based on the user-specified attributes in 
+   * WifiHelper::SetRemoteStationManager, WifiHelper::SetMac, and 
+   * WifiHelper::SetPhy.  It attaches this new device to the provided node and
+   * attaches the new device to the provided channel.
+   *
+   * \param node The node to install the device in
+   * \param channel The chanel to attach to the device.
+   * \returns A containter holding the added net device.
+   */
+  NetDeviceContainer Install (Ptr<Node> node, Ptr<WifiChannel> channel) const;
+
   /**
-   * \param channel a channel to use
-   * \param c a set of nodes
+   * This method creates a simple ns3::WifiChannel (with a default 
+   * ns3::PropagationLossModel and ns3::PropagationDelayModel).  For each 
+   * Ptr<Node> in the provided NodeContainer, this method creates a new 
+   * ns3::WifiNetDevice that is configured with an ns3::WifiRemoteStationManager,
+   * ns3::WifiMac and ns3::WifiPhy, all of which are created based on the 
+   * user-specified attributes in WifiHelper::SetRemoteStationManager, 
+   * WifiHelper::SetMac, and WifiHelper::SetPhy.  It attaches these new devices to
+   * their corresponding nodes and attaches the new devices to the new channel.
    *
-   * For each of the input nodes, a new ns3::WifiNetDevice is attached 
-   * to the shared input channel. Each ns3::WifiNetDevice is also
-   * configured with an ns3::WifiRemoteStationManager, ns3::WifiMac, and,
-   * ns3::WifiPhy, all of which are created based on the user-specified
-   * attributes specified in WifiHelper::SetRemoteStationManager, 
-   * WifiHelper::SetMac, and, WifiHelper::SetPhy.
+   * \param c The NodeContainer holding the nodes to be changed.
+   * \returns A containter holding the added net devices.
+   */
+  NetDeviceContainer Install (const NodeContainer &c) const;
+
+  /**
+   * For each Ptr<Node> in the provided NodeContainer, this method creates a new 
+   * ns3::WifiNetDevice that is configured with an ns3::WifiRemoteStationManager,
+   * ns3::WifiMac and ns3::WifiPhy, all of which are created based on the 
+   * user-specified attributes in WifiHelper::SetRemoteStationManager, 
+   * WifiHelper::SetMac, and WifiHelper::SetPhy.  It attaches these new devices to
+   * their corresponding nodes and attaches the new devices to the provided channel.
    *
-   * The user is expected to attach to the input channel a proper 
-   * ns3::PropagationLossModel, and ns3::PropagationDelayModel.
+   * \param c The NodeContainer holding the nodes to be changed.
+   * \param channel The channel to attach to the devices.
+   * \returns A containter holding the added net devices.
    */
-  NetDeviceContainer Install (NodeContainer c, Ptr<WifiChannel> channel) const;
+  NetDeviceContainer Install (const NodeContainer &c, Ptr<WifiChannel> channel) const;
 
 private:
+  Ptr<NetDevice> InstallPriv (Ptr<Node> node, Ptr<WifiChannel> channel) const;
+
   ObjectFactory m_stationManager;
   ObjectFactory m_mac;
   ObjectFactory m_phy;