diff -r 715c53e80576 src/netanim/examples/tree-animation.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/netanim/examples/tree-animation.cc Thu Apr 28 07:27:06 2011 -0700 @@ -0,0 +1,153 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + * + */ + +#include "ns3/core-module.h" +#include "ns3/applications-module.h" +#include "ns3/netanim-module.h" +#include "ns3/network-module.h" +#include "ns3/point-to-point-layout-module.h" +#include "ns3/internet-module.h" + +/* + Network topology (default) + + R (level=0, fan out=3) + /-----------------------\ + / | \ + / | \ + n1 n2 n3 (level=1, fan out=3) + / | \ / | \ / | \ + n11 n12 n13 n21 n22 n23 n31 n32 n33 (level=2) + +*/ + + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TreeAnimation"); + +int +main (int argc, char *argv[]) +{ + + // + // Defaults + // + uint32_t nLevels = 3; // Number of levels in the tree + uint32_t fan_out = 3; // Number of fan out nodes + std::string animFile = "tree.tr"; // Animation file + uint32_t animPort = 0; // Animation port + int random_fan_out = -1; // Used if random number of fan out + // or branches are to be created at each level + + CommandLine cmd; + cmd.AddValue ("nLevels", "Number of levels in the tree", nLevels); + cmd.AddValue ("fan_out", "Fan out", fan_out); + cmd.AddValue ("animPort", "Port Number for Remote Animation", animPort); + cmd.AddValue ("animFile", "File Name for Animation Output", animFile); + cmd.AddValue ("random_fan_out", "Try a random fan out, usage :--random_fan_out=1, \ + fan_out will be used for the upper bound", random_fan_out); + + cmd.Parse (argc, argv); + + NS_LOG_INFO ("Build tree topology."); + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + + Ptr tree ; + if (random_fan_out == -1) + tree = CreateObject (nLevels,fan_out,pointToPoint); + else + tree = CreateObject (nLevels,UniformVariable(0,fan_out),pointToPoint); + + + NS_LOG_INFO ("Install internet stack on all nodes."); + InternetStackHelper internet; + tree->InstallStack (internet); + + NS_LOG_INFO ("Assign IP Addresses."); + tree->AssignIpv4AddressesHierarchical (Ipv4Address ("10.0.0.0"), Ipv4Mask ("255.0.0.0")); + + NS_LOG_INFO ("Create applications."); + + // Create a packet sink on the last leaf node to receive packets. + + uint16_t port = 50000; + uint32_t last_leaf_node = (tree->GetLeaves ().GetN ())-1; + + // Sink related configurations + Address last_leaf_node_address (InetSocketAddress (Ipv4Address::GetAny (), port)); + PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", last_leaf_node_address); + ApplicationContainer sink_app = packetSinkHelper.Install (tree->GetLeaves ().Get (last_leaf_node)); + sink_app.Start (Seconds (1.0)); + sink_app.Stop (Seconds (10.0)); + + // + // Create OnOff applications to send TCP to the sink node from each leaf node except + // last leaf node + // + OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ()); + onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + + // Create apps on leaves except for last leaf node + ApplicationContainer leafApps; + for (uint32_t i = 0; i < tree->GetLeaves ().GetN (); i++) + { + AddressValue remoteAddress (InetSocketAddress (tree->GetLeafIpv4Address(last_leaf_node), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + leafApps.Add (onOffHelper.Install (tree->GetLeaves ().Get (i))); + leafApps.Start (Seconds (1.0)); + leafApps.Stop (Seconds (10.0)); + } + + // Let us also add an application on level 1 node 2 + ApplicationContainer level1node2App; + level1node2App.Add (onOffHelper.Install (tree->GetNode (1,2))); + level1node2App.Start (Seconds (1.0)); + level1node2App.Stop (Seconds (10.0)); + + NS_LOG_INFO ("Enable static global routing."); + // + // Turn on global static routing so we can actually be routed across the star. + // + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + + // Set the bounding box for animation + tree->BoundingBox (1, 1, 100, 100); + + // Create the animation object and configure for specified output + AnimationInterface anim; + if (animPort > 0) + { + anim.SetServerPort (animPort); + } + else if (!animFile.empty ()) + { + anim.SetOutputFile (animFile); + } + anim.StartAnimation (); + + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); + + return 0; +} + diff -r 715c53e80576 src/netanim/examples/wscript --- a/src/netanim/examples/wscript Wed Apr 27 10:16:08 2011 -0400 +++ b/src/netanim/examples/wscript Thu Apr 28 07:27:06 2011 -0700 @@ -12,3 +12,7 @@ obj = bld.create_ns3_program('star-animation', ['netanim', 'applications', 'point-to-point-layout']) obj.source = 'star-animation.cc' + + obj = bld.create_ns3_program('tree-animation', + ['netanim', 'applications', 'point-to-point-layout']) + obj.source = 'tree-animation.cc' diff -r 715c53e80576 src/point-to-point-layout/model/point-to-point-star.cc --- a/src/point-to-point-layout/model/point-to-point-star.cc Wed Apr 27 10:16:08 2011 -0400 +++ b/src/point-to-point-layout/model/point-to-point-star.cc Thu Apr 28 07:27:06 2011 -0700 @@ -18,17 +18,28 @@ #include // ns3 includes +#include "ns3/point-to-point-helper.h" #include "ns3/animation-interface.h" #include "ns3/point-to-point-star.h" #include "ns3/constant-position-mobility-model.h" - #include "ns3/node-list.h" #include "ns3/point-to-point-net-device.h" #include "ns3/vector.h" +namespace ns3 { + NS_LOG_COMPONENT_DEFINE("PointToPointStarHelper"); +NS_OBJECT_ENSURE_REGISTERED (PointToPointStarHelper); -namespace ns3 { +TypeId +PointToPointStarHelper::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::PointToPointStarHelper") + .SetParent () + .AddConstructor () + ; + return tid; +} PointToPointStarHelper::PointToPointStarHelper (uint32_t numSpokes, PointToPointHelper p2pHelper) @@ -44,8 +55,24 @@ } } +PointToPointStarHelper::PointToPointStarHelper (ns3::NodeContainer hub,uint32_t numSpokes,PointToPointHelper p2pHelper):m_hub(hub) +{ + m_spokes.Create (numSpokes); + for (uint32_t i = 0; i < m_spokes.GetN (); ++i) + { + NetDeviceContainer nd = p2pHelper.Install (m_hub.Get (0), m_spokes.Get (i)); + m_hubDevices.Add (nd.Get (0)); + m_spokeDevices.Add (nd.Get (1)); + } +} + +PointToPointStarHelper::PointToPointStarHelper () +{ +} + PointToPointStarHelper::~PointToPointStarHelper () -{} +{ +} Ptr PointToPointStarHelper::GetHub () const @@ -59,6 +86,12 @@ return m_spokes.Get (i); } +NodeContainer +PointToPointStarHelper::GetSpokeNodes () const +{ + return m_spokes; +} + Ipv4Address PointToPointStarHelper::GetHubIpv4Address (uint32_t i) const { @@ -95,6 +128,14 @@ } } +void +PointToPointStarHelper::AssignIpv4AddressForSingleSpoke (Ipv4AddressHelper address, uint32_t spoke_id) +{ + NS_ASSERT (spoke_id < SpokeCount ()); + m_hubInterfaces.Add (address.Assign (m_hubDevices.Get (spoke_id))); + m_spokeInterfaces.Add (address.Assign (m_spokeDevices.Get (spoke_id))); +} + void PointToPointStarHelper::BoundingBox (double ulx, double uly, double lrx, double lry) @@ -152,8 +193,9 @@ Vector spokeVec (hubVec.x + cos (theta*i) * spokeDist, hubVec.y + sin (theta*i) * spokeDist, 0); - spokeLoc->SetPosition (spokeVec); + spokeLoc->SetPosition (spokeVec); } } } // namespace ns3 + diff -r 715c53e80576 src/point-to-point-layout/model/point-to-point-star.h --- a/src/point-to-point-layout/model/point-to-point-star.h Wed Apr 27 10:16:08 2011 -0400 +++ b/src/point-to-point-layout/model/point-to-point-star.h Thu Apr 28 07:27:06 2011 -0700 @@ -20,11 +20,12 @@ #define POINT_TO_POINT_STAR_HELPER_H #include - -#include "point-to-point-helper.h" -#include "ipv4-address-helper.h" -#include "internet-stack-helper.h" -#include "ipv4-interface-container.h" +#include "ns3/point-to-point-helper.h" +#include "ns3/ipv4-address-helper.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/ipv4-interface-container.h" +#include "ns3/object.h" +#include "ns3/ptr.h" namespace ns3 { @@ -32,7 +33,7 @@ * \brief A helper to make it easier to create a star topology * with PointToPoint links */ -class PointToPointStarHelper +class PointToPointStarHelper : public Object { public: /** @@ -48,8 +49,29 @@ */ PointToPointStarHelper (uint32_t numSpokes, PointToPointHelper p2pHelper); + /** + * Create a PointToPointStarHelper in order to easily create + * star topologies using p2p links.This constructor takes an existent node "hub", + * creates the specified number of spoke nodes (numSpokes) around it and installs + * point-to-point links between the hub and the spoke nodes + * + * \param hub the NodeContainer containing the already-created hub Node + * + * \param numSpokes the number of links attached to + * the hub node, creating a total of + * numSpokes + 1 nodes + * + * \param p2pHelper the link helper for p2p links, + * used to link nodes together + */ + PointToPointStarHelper (NodeContainer hub,uint32_t numSpokes,PointToPointHelper p2pHelper); - ~PointToPointStarHelper (); + /** + * Create a PointToPointStarHelper (Empty constructor) + */ + PointToPointStarHelper (); + + virtual ~PointToPointStarHelper (); public: /** @@ -66,16 +88,20 @@ Ptr GetSpokeNode (uint32_t i) const; /** + * \returns a node Container containing the set of spoke nodes + */ + NodeContainer GetSpokeNodes() const; + /** * \param i index into the hub interfaces * - * \returns Ipv4Address according to indexed hub interface + * \returns Ipv4Address according to indexed hub Interface */ Ipv4Address GetHubIpv4Address (uint32_t i) const; /** * \param i index into the spoke interfaces * - * \returns Ipv4Address according to indexed spoke interface + * \returns Ipv4Address according to indexed spoke Interface */ Ipv4Address GetSpokeIpv4Address (uint32_t i) const; @@ -91,6 +117,8 @@ void InstallStack (InternetStackHelper stack); /** + * Assigns Ipv4 addresses for the interfaces between the hub and + * all spoke nodes * \param address an Ipv4AddressHelper which is used to install * Ipv4 addresses on all the node interfaces in * the star @@ -98,8 +126,21 @@ void AssignIpv4Addresses (Ipv4AddressHelper address); /** + * Assigns Ipv4 addresses for the interfaces between the hub and + * a give spoke node + * + * \param address an Ipv4AddressHelper which is used to install + * Ipv4 addresses on all the node interfaces in + * the star + * + * \param spoke_id Id of the spoke node. Spoke nodes are zero-indexed + * + */ + void AssignIpv4AddressForSingleSpoke (Ipv4AddressHelper address, uint32_t spoke_id); + + /** * Sets up the node canvas locations for every node in the star. - * This is needed for use with the animation interface + * This is needed for use with the animation Interface * * \param ulx upper left x value * \param uly upper left y value @@ -108,6 +149,12 @@ */ void BoundingBox (double ulx, double uly, double lrx, double lry); + /** + * \brief Get the type ID. + * \return type ID + */ + static TypeId GetTypeId (); + private: NodeContainer m_hub; NetDeviceContainer m_hubDevices; @@ -120,3 +167,4 @@ } // namespace ns3 #endif /* POINT_TO_POINT_STAR_HELPER_H */ + diff -r 715c53e80576 src/point-to-point-layout/model/point-to-point-tree.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/point-to-point-layout/model/point-to-point-tree.cc Thu Apr 28 07:27:06 2011 -0700 @@ -0,0 +1,373 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + */ + + +#include "ns3/point-to-point-tree.h" +#include "ns3/ptr.h" +#include "ns3/point-to-point-star.h" +#include "ns3/node.h" +#include "ns3/node-container.h" +#include "ns3/log.h" +#include "ns3/constant-position-mobility-model.h" +#include + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE("PointToPointTreeHelper"); +NS_OBJECT_ENSURE_REGISTERED (PointToPointTreeHelper); + +TypeId +PointToPointTreeHelper::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::PointToPointTreeHelper") + .SetParent () + .AddConstructor () + ; + return tid; +} + + + +PointToPointTreeHelper::PointToPointTreeHelper ( + uint32_t num_levels, + uint32_t fan_out, + PointToPointHelper p2pHelper + ) :m_num_levels (num_levels),m_fan_out (ConstantVariable (fan_out)) +{ + CreateTopologyHelper (num_levels, p2pHelper); +} + +PointToPointTreeHelper::PointToPointTreeHelper( + uint32_t num_levels, + RandomVariable rv, + PointToPointHelper p2pHelper + ) :m_num_levels (num_levels),m_fan_out (rv) +{ + CreateTopologyHelper (num_levels, p2pHelper); +} + +PointToPointTreeHelper::PointToPointTreeHelper () +{ +} + +void +PointToPointTreeHelper::CreateTopologyHelper (uint32_t num_levels, PointToPointHelper p2pHelper) +{ + if (num_levels <= 0) + { + NS_LOG_WARN ("Number of levels:"< star_helper ; + if (level >= this->m_num_levels) + { + NS_LOG_INFO ("Begin creating levels starting from level 1"); + return; + } + + star_helper = parent_node.Get (0)->GetObject (); + if (star_helper == 0) + { + star_helper = CreateObject (parent_node,fan_out,p2pHelper); + PerLevelNodeContainer[level].Add (star_helper->GetSpokeNodes()); + parent_node.Get (0)->AggregateObject (star_helper); + NS_LOG_INFO ("After aggregating star to parent node Id:"<GetId()<<" with fan out="<GetId ()<<" Already contains a star set"); + } + level++; + for (uint32_t i = 0 ; i < fan_out ; i++) + { + NS_LOG_INFO ("Before star for parent node Id:"<GetId()<<" with fan out="<GetSpokeNode (i),level,p2pHelper); + } +} + +PointToPointTreeHelper::~PointToPointTreeHelper () +{ +} + +Ptr +PointToPointTreeHelper::GetNode (uint32_t level, uint32_t index) +{ + if (level >= m_num_levels) + { + NS_LOG_WARN ("Requested level:"<= PerLevelNodeContainer[level].GetN ()) + { + NS_LOG_WARN ("Requested index:"< n = NULL ; + Ptr star_helper = NULL; + + // Go through each node on the penultimate level + // Obtained the star topology aggregated with each node + // Check if the leaf index falls within the spoke count of each star + for (uint32_t i = 0 ; i < nc.GetN ();i++) + { + n = nc.Get (i); + NS_ASSERT (n); + star_helper = n->GetObject (); + if (star_helper == 0) + { + NS_LOG_WARN ("This tree is perhaps has only one node."); + // This can happen due to a bug, or if only one node exists + // in tree (not really a tree in that case!!) + // This can also happen if the user desired random fan out + // which chose '0' as a fan out + } + else + { + // The leaf index does not belong to this star + if (leaf_index > star_helper->SpokeCount ()-1) + { + n = NULL ; + leaf_index -= star_helper->SpokeCount (); + continue; + } + else + { + // Found the star + break; + } + } + } //for loop + NS_ASSERT (n); + NS_ASSERT (star_helper); + + // Found the desired star + return star_helper->GetSpokeIpv4Address (leaf_index); +} + +// A helper function that extends a massk, based on the number of subnets required +// Examples: given a mask such as /8, if 3 subnets are required, the mask has to be +// extended to /10 + +Ipv4Mask +PointToPointTreeHelper::ExtendMaskForSubnets (Ipv4Mask original_mask, uint32_t subnets_required) +{ + // If the original mask is already /31 and over we cannot allocate any more subnets + if (subnets_required) + NS_ASSERT (original_mask.GetPrefixLength () <=30); + + uint8_t num_additional_subnet_bits = 0;//number of additional subnet bits required + for (uint32_t i = 0 ; i < 31 ; i++) //30 is maximum subnets + { + if( pow (2.0,static_cast (i)) >= subnets_required) + { + num_additional_subnet_bits = i ; + break; + } + } + uint32_t tmp = 0x10000000 ; + tmp >>= (original_mask.GetPrefixLength () - 1); //Position 1 at the last "1" bit in the mask + uint32_t new_mask = original_mask.Get (); // Initialize new mask + for (uint8_t i = 0 ; i < num_additional_subnet_bits ; i++) + { + tmp >>= i ; // Move the 1 right for each additional subnet bit + new_mask |= tmp; // Add the 1 to the original mask + } + return Ipv4Mask (new_mask); +} + +/* + The function starts with an allocated network address N and mask M + The mask M is extended to allocate X subnets. where X is the + number of fan out nodes/spokes nodes associated with a node + Each allocated subnet above is further divided into 2 subnets A and B + subnet A is used at the network between the hub and any spoke node + subnet B will be the new network which is used by the spoke nodes + as part of recursion + For example: + 10.0.0.0/8 is allocated for the tree + The Root Node [R] has 4 point-to-point links to 4 spoke nodes + 10.0.0.0/8 is divided into 4 subnets + 10.0.0.0/10, 10.64.0.0/10, 10.128.0.0/10, 10.192.0.0/10 + + 10.0.0.0/10 is divided into 2 subnets + 10.0.0.0/11 and 10.32.0.0/11 + + + o(10.32.0.1/11) + [N1] + o(10.0.0.2/11) + [N3] / + \ / + \ / + o o(10.0.0.1/11) + (10.0.0.0/8) [R] + o o(10.64.0.1/11) + / \ + / \ + [N4] \ + \ + o(10.64.0.2/11) + [N2] + o(10.96.0.1/11) + +*/ + +void +PointToPointTreeHelper::AssignIpv4AddressHierarchicalRecursiveHelper (Ptr n, Ipv4Address network, Ipv4Mask allocated_mask) +{ + Ptr star_helper ; + star_helper = n->GetObject (); + if (star_helper == 0) + { + NS_LOG_INFO ("AssignIpv4AddressRecursiveHelper Node Id:"<GetId ()); + return ; + } + uint32_t fan_out = star_helper->SpokeCount (); + + // Prepare mask and address helper for X subnets + // Where X is the number of fan out nodes + Ipv4Mask outer_mask = ExtendMaskForSubnets (allocated_mask,fan_out); + Ipv4AddressHelper outer_addrhelper (network,outer_mask); + + //Create Mask for Subnet A and Subnet B (2 subnets) + Ipv4Mask inner_mask = ExtendMaskForSubnets (outer_mask,2); + + Ipv4Address inner_network = network; //Initialization + for (uint32_t i = 0; i < fan_out; ++i) + { + Ipv4AddressHelper inner_addrhelper (inner_network, inner_mask); + star_helper->AssignIpv4AddressForSingleSpoke (inner_addrhelper, i); + AssignIpv4AddressHierarchicalRecursiveHelper (star_helper->GetSpokeNode (i), inner_addrhelper.NewNetwork (), inner_mask); + inner_network = outer_addrhelper.NewNetwork (); + + } +} +void +PointToPointTreeHelper::AssignIpv4AddressesHierarchical (Ipv4Address networkaddress, Ipv4Mask mask) +{ + // Assign Ipv4 addresses recursively, starting at level 0 + AssignIpv4AddressHierarchicalRecursiveHelper (PerLevelNodeContainer[0].Get (0),networkaddress,mask); +} + +void +PointToPointTreeHelper::BoundingBoxRecursiveHelper (double xDist, double inter_level_height,uint32_t current_level) +{ + double inter_node_x_distance = 0 ; + uint32_t num_node_in_current_level = 0; + NS_LOG_FUNCTION ("Current level:"<= this->m_num_levels) + { + NS_LOG_INFO ("Recursion complete"); + return ; + } + num_node_in_current_level = PerLevelNodeContainer[current_level].GetN (); // number of nodes in the current level + inter_node_x_distance = (xDist/num_node_in_current_level)/2; // /2 is required to position the nodes at center of each x block + + for (uint32_t i = 0 ; i n = PerLevelNodeContainer[current_level].Get (i); + NS_ASSERT (n); + Ptr loc = n->GetObject (); + if (loc == 0) + { + loc = CreateObject (); + } + else + { + NS_LOG_WARN ("ConstantPositionMobilityModel Aggregated object already exists.Will use this object"); + } + n->AggregateObject (loc); // visualizers can retrieve the aggregated mobility model from a node to position it + Vector spokeVec (inter_node_x_distance+(i*(inter_node_x_distance*2)), + inter_level_height*current_level, + 0); + loc->SetPosition (spokeVec); + } + current_level++; + BoundingBoxRecursiveHelper (xDist,inter_level_height,current_level); +} + +void +PointToPointTreeHelper::BoundingBox (double ulx, double uly, double lrx, double lry) +{ + double yDist; + double xDist; + if (lrx > ulx) + { + xDist = lrx - ulx; + } + else + { + xDist = ulx - lrx; + } + if (lry > uly) + { + yDist = lry - uly; + } + else + { + yDist = uly - lry; + } + double inter_level_height = yDist/(m_num_levels-1) ; + BoundingBoxRecursiveHelper (xDist,inter_level_height,0); + +} + +} // namespace ns3 + diff -r 715c53e80576 src/point-to-point-layout/model/point-to-point-tree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/point-to-point-layout/model/point-to-point-tree.h Thu Apr 28 07:27:06 2011 -0700 @@ -0,0 +1,211 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + */ + +// Define an object to create a Tree topology. + +/* A tree in this context, can be described as below + * A singular root node is the first node created in the tree + * The root node has X branches (X is also called the fan out number for the + * node) + * A level is a horizontal row of nodes. In this sense the root node occupies + * level 0 and is the only node at this level. The nodes at the tip of the + * root node's branches are at level 1 and so on + * Each node at a level can have branches of its own + * The last level (i.e the level with no more branches) carries the leaf nodes + * + * r (level=0,fan out=3) + * | + * ------------------------- + * / | \ + * / | \ + * n1 n2 n3 (level=1,fan out=3) + * / | \ / | \ / | \ + * n11 n12 n13 n21 n22 ns23 n31 n32 n33 (level=2,leaf nodes) + */ + + + + +#ifndef POINT_TO_POINT_TREE_H +#define POINT_TO_POINT_TREE_H + +#include "ns3/point-to-point-star.h" +#include "ns3/random-variable.h" +#include + +using namespace std; + +namespace ns3 { + +/** + * \brief A helper to make it easier to create a tree topology + * with PointToPoint links + */ + +class PointToPointTreeHelper : public Object +{ +public: + + /** + * Create a PointToPointTreeHelper in order to easily create + * tree topologies using p2p links + * + * \param num_levels the number of levels in the tree.Root node is level 0 + * + * \param fan_out the number of fan out nodes for each node (i.e number of branches) + * + * \param p2pHelper the link helper for p2p links, + * used to link nodes together + */ + PointToPointTreeHelper ( + uint32_t num_levels, + uint32_t fan_out, + PointToPointHelper p2pHelper); + + /** + * Create a PointToPointTreeHelper in order to easily create + * tree topologies using p2p links.This constructor needs to be used if the + * fan out (number of branches) for each node has to be chosen at random + * + * \param num_levels the number of levels in the tree.Root node is level 0 + * + * \param rv A random variable that is used to choose + * the number of fan out + * nodes for each node during tree creation + * + * \param p2pHelper the link helper for p2p links, + * used to link nodes together + */ + PointToPointTreeHelper ( + uint32_t num_levels, + RandomVariable rv, + PointToPointHelper p2pHelper); + + /** + * PointToPointTreeHelper empty constructor + */ + PointToPointTreeHelper (); + + /** + * PointToPointTreeHelper destructor + */ + virtual ~PointToPointTreeHelper (); + + /** + * Sets up the node canvas locations for every node in the tree. + * This is needed for use with the animation Interface + * + * \param ulx upper left x value + * \param uly upper left y value + * \param lrx lower right x value + * \param lry lower right y value + */ + void BoundingBox (double ulx, double uly, double lrx, double lry); + + /** + * Gets the Node at a particular index at a given level of the tree + * + * \param level Level of the requested Node [Root node is at level 0.i.e,Tree levels are zero-indexed] + * + * \param index Index of the requested Node [First node at a level has the index 0. i.e, The nodes at a level are zero-indexed + * + * \returns a node pointer to the requested node.NULL is returned if the Node does not exist + */ + Ptr GetNode (uint32_t level, uint32_t index); + + /** + * Gets the Leaves of the tree (Nodes at the final level) + * + * \returns a node container containing the leaves of the tree + */ + NodeContainer GetLeaves (); + + /** + * \brief Get the type ID. + * \return type ID + */ + static TypeId GetTypeId (); + + /** + * \param stack an InternetStackHelper which is used to install + * on every node in the star + */ + void InstallStack (InternetStackHelper stack); + + /** + * Assign Ipv4 addresses hierarchically + * The function starts with an allocated network address N and mask M + * The mask M is extended to allocate X subnets. where X is the + * number of fan out nodes/spokes nodes/branches associated with a node + * Each allocated subnet above is further divided into 2 subnets A and B + * subnet A is used at the network between the hub and any spoke node + * subnet B will be the new network which is used by the spoke nodes + * as part of recursion + * For example: + * 10.0.0.0/8 is allocated for the tree + * The Root Node [R] has 4 point-to-point links to 4 spoke node + * 10.0.0.0/8 is divided into 4 subnets + * 10.0.0.0/10, 10.64.0.0/10, 10.128.0.0/10, 10.192.0.0/10 + * + * 10.0.0.0/10 is divided into 2 subnets + * 10.0.0.0/11 and 10.32.0.0/11 + * + * + * o(10.32.0.1/11) + * [N1] + * o(10.0.0.2/11) + * [N3] / + * \ / + * \ / + * o o(10.0.0.1/11) + * (10.0.0.0/8) [R] + * o o(10.64.0.1/11) + * / \ + * / \ + * [N4] \ + * \ + * o(10.64.0.2/11) + * [N2] + * o(10.96.0.1/11) + * + * \param network The network address allocated for this tree + * + * \param mask The mask allocated for this tree + */ + void AssignIpv4AddressesHierarchical (Ipv4Address network, Ipv4Mask mask); + + /** + * Get the Ipv4Address of the interface of a leaf node + * \param index of the leaf node (zero-indexed) + * + */ + Ipv4Address GetLeafIpv4Address (uint32_t leaf_index); + +private: + void AssignIpv4AddressHierarchicalRecursiveHelper (Ptr n,Ipv4Address network, Ipv4Mask mask); + void CreateTopologyHelper (uint32_t levels, PointToPointHelper p2pHelper); + void AddStarTopologyRecursively (NodeContainer parent_node, uint32_t num_levels, PointToPointHelper p2pHelper); + void BoundingBoxRecursiveHelper (double xDist, double inter_level_height, uint32_t current_level); + Ipv4Mask ExtendMaskForSubnets (Ipv4Mask original_mask, uint32_t subnets_required); + uint32_t m_num_levels; + RandomVariable m_fan_out; + NodeContainer m_root_node; + vector PerLevelNodeContainer; //each tree level maintains a container of nodes at that level +}; + +} // namespace ns3 + +#endif diff -r 715c53e80576 src/point-to-point-layout/wscript --- a/src/point-to-point-layout/wscript Wed Apr 27 10:16:08 2011 -0400 +++ b/src/point-to-point-layout/wscript Thu Apr 28 07:27:06 2011 -0700 @@ -7,6 +7,7 @@ 'model/point-to-point-dumbbell.cc', 'model/point-to-point-grid.cc', 'model/point-to-point-star.cc', + 'model/point-to-point-tree.cc', ] headers = bld.new_task_gen('ns3header') @@ -15,6 +16,7 @@ 'model/point-to-point-dumbbell.h', 'model/point-to-point-grid.h', 'model/point-to-point-star.h', + 'model/point-to-point-tree.h', ] bld.ns3_python_bindings()