diff --git a/examples/star.cc b/examples/star.cc new file mode 100644 index 000000000..1cc58457d --- /dev/null +++ b/examples/star.cc @@ -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/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" +#include "ns3/global-route-manager.h" + +// Network topology (default) +// +// n2 n3 n4 . +// \ | / . +// \|/ . +// n1--- n0---n5 . +// /|\ . +// / | \ . +// n8 n7 n6 . +// + + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("Star"); + +int +main (int argc, char *argv[]) +{ + // + // Make the random number generators generate reproducible results. + // + RandomVariable::UseGlobalSeed (1, 1, 2, 3, 5, 8); + + // + // Set up some default values for the simulation. + // + Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (137)); + + // ??? try and stick 15kb/s into the data rate + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("14kb/s")); + + // + // Default number of nodes in the star. Overridable by command line argument. + // + uint32_t nNodes = 9; + + CommandLine cmd; + cmd.AddValue("nNodes", "Number of nodes to place in the star", nNodes); + cmd.Parse (argc, argv); + + NS_LOG_INFO ("Create nodes."); + NodeContainer hubNode; + NodeContainer spokeNodes; + hubNode.Create (1); + Ptr hub = hubNode.Get (0); + spokeNodes.Create (nNodes - 1); + + NS_LOG_INFO ("Install internet stack on all nodes."); + InternetStackHelper internet; + internet.Install (NodeContainer (hubNode, spokeNodes)); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + + NS_LOG_INFO ("Build star topology."); + NetDeviceContainer hubDevices, spokeDevices; + pointToPoint.InstallStar (hubNode.Get (0), spokeNodes, hubDevices, spokeDevices); + + NS_LOG_INFO ("Assign IP Addresses."); + Ipv4AddressHelper address; + + // + // Assign IPv4 interfaces and IP addresses to the devices we previously + // created. Keep track of the resulting addresses, one for the addresses + // of the hub node, and one for addresses on the spoke nodes. Despite the + // name of the class, what is visible to clients is really the address. + // + Ipv4InterfaceContainer hubAddresses; + Ipv4InterfaceContainer spokeAddresses; + + for(uint32_t i = 0; i < spokeNodes.GetN (); ++i) + { + std::ostringstream subnet; + subnet << "10.1.1." << (i << 2); + NS_LOG_INFO ("Assign IP Addresses for point-to-point subnet " << subnet.str ()); + address.SetBase (subnet.str ().c_str (), "255.255.255.252"); + hubAddresses.Add (address.Assign (hubDevices.Get (i))); + spokeAddresses.Add (address.Assign (spokeDevices.Get (i))); + } + + NS_LOG_INFO ("Create applications."); + // + // Create a packet sink on the star "hub" to receive packets. + // + uint16_t port = 50000; + Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)); + PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress); + ApplicationContainer hubApp = packetSinkHelper.Install (hubNode); + hubApp.Start (Seconds (1.0)); + hubApp.Stop (Seconds (10.0)); + + // + // Create OnOff applications to send TCP to the hub, one on each spoke node. + // + OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ()); + onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); + onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); + + ApplicationContainer spokeApps; + + for (uint32_t i = 0; i < spokeNodes.GetN (); ++i) + { + AddressValue remoteAddress (InetSocketAddress (hubAddresses.GetAddress (i), port)); + onOffHelper.SetAttribute ("Remote", remoteAddress); + spokeApps.Add (onOffHelper.Install (spokeNodes.Get (i))); + } + spokeApps.Start (Seconds (1.0)); + spokeApps.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. + // + GlobalRouteManager::PopulateRoutingTables (); + + NS_LOG_INFO ("Enable pcap tracing."); + // + // Do pcap tracing on all devices on all nodes. + // + PointToPointHelper::EnablePcapAll ("star"); + + NS_LOG_INFO ("Run Simulation."); + Simulator::Run (); + Simulator::Destroy (); + NS_LOG_INFO ("Done."); + + return 0; +} diff --git a/examples/wscript b/examples/wscript index 34673bb1c..0abea1cca 100644 --- a/examples/wscript +++ b/examples/wscript @@ -5,73 +5,77 @@ def build(bld): obj.source = 'hello-simulator.cc' obj = bld.create_ns3_program('mixed-wireless', - ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) + ['core', 'simulator', 'mobility', 'wifi', 'point-to-point', 'internet-stack']) obj.source = 'mixed-wireless.cc' obj = bld.create_ns3_program('simple-global-routing', - ['point-to-point', 'internet-stack', 'global-routing']) + ['point-to-point', 'internet-stack', 'global-routing']) obj.source = 'simple-global-routing.cc' obj = bld.create_ns3_program('simple-alternate-routing', - ['point-to-point', 'internet-stack', 'global-routing']) + ['point-to-point', 'internet-stack', 'global-routing']) obj.source = 'simple-alternate-routing.cc' obj = bld.create_ns3_program('simple-error-model', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'simple-error-model.cc' obj = bld.create_ns3_program('csma-one-subnet', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-one-subnet.cc' obj = bld.create_ns3_program('csma-bridge', - ['bridge', 'csma', 'internet-stack']) + ['bridge', 'csma', 'internet-stack']) obj.source = 'csma-bridge.cc' obj = bld.create_ns3_program('udp-echo', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'udp-echo.cc' obj = bld.create_ns3_program('realtime-udp-echo', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'realtime-udp-echo.cc' obj = bld.create_ns3_program('csma-broadcast', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-broadcast.cc' obj = bld.create_ns3_program('csma-packet-socket', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-packet-socket.cc' obj = bld.create_ns3_program('csma-multicast', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'csma-multicast.cc' obj = bld.create_ns3_program( 'mixed-global-routing', - ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd']) + ['point-to-point', 'internet-stack', 'global-routing' , 'csma-cd']) obj.source = 'mixed-global-routing.cc' obj = bld.create_ns3_program('simple-point-to-point-olsr', - ['point-to-point', 'internet-stack', 'olsr']) + ['point-to-point', 'internet-stack', 'olsr']) obj.source = 'simple-point-to-point-olsr.cc' obj = bld.create_ns3_program('tcp-large-transfer', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-large-transfer.cc' obj = bld.create_ns3_program('tcp-nsc-lfn', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-nsc-lfn.cc' obj = bld.create_ns3_program('tcp-nsc-zoo', - ['csma', 'internet-stack']) + ['csma', 'internet-stack']) obj.source = 'tcp-nsc-zoo.cc' obj = bld.create_ns3_program('tcp-star-server', - ['point-to-point', 'internet-stack']) + ['point-to-point', 'internet-stack']) obj.source = 'tcp-star-server.cc' + obj = bld.create_ns3_program('star', + ['point-to-point', 'internet-stack']) + obj.source = 'star.cc' + obj = bld.create_ns3_program('wifi-adhoc', ['core', 'simulator', 'mobility', 'wifi']) obj.source = 'wifi-adhoc.cc' diff --git a/src/helper/ipv4-interface-container.cc b/src/helper/ipv4-interface-container.cc index 9b57609f3..d31174e30 100644 --- a/src/helper/ipv4-interface-container.cc +++ b/src/helper/ipv4-interface-container.cc @@ -6,11 +6,21 @@ namespace ns3 { Ipv4InterfaceContainer::Ipv4InterfaceContainer () {} +void +Ipv4InterfaceContainer::Add (Ipv4InterfaceContainer other) +{ + for (InterfaceVector::const_iterator i = other.m_interfaces.begin (); i != other.m_interfaces.end (); i++) + { + m_interfaces.push_back (*i); + } +} + uint32_t Ipv4InterfaceContainer::GetN (void) const { return m_interfaces.size (); } + Ipv4Address Ipv4InterfaceContainer::GetAddress (uint32_t i) const { diff --git a/src/helper/ipv4-interface-container.h b/src/helper/ipv4-interface-container.h index 7c38fac15..ed544bef8 100644 --- a/src/helper/ipv4-interface-container.h +++ b/src/helper/ipv4-interface-container.h @@ -20,6 +20,11 @@ public: */ Ipv4InterfaceContainer (); + /** + * Concatenate the entries in the other container with ours. + */ + void Add (Ipv4InterfaceContainer other); + /** * \returns the number of interfaces stored in this Ipv4InterfaceContainer. */ @@ -31,7 +36,9 @@ public: void Add (Ptr ipv4, uint32_t interface); private: - std::vector,uint32_t> > m_interfaces; + + typedef std::vector,uint32_t> > InterfaceVector; + InterfaceVector m_interfaces; }; } // namespace ns3 diff --git a/src/helper/point-to-point-helper.cc b/src/helper/point-to-point-helper.cc index ed951b56e..5ce544627 100644 --- a/src/helper/point-to-point-helper.cc +++ b/src/helper/point-to-point-helper.cc @@ -172,6 +172,7 @@ PointToPointHelper::Install (NodeContainer c) NS_ASSERT (c.GetN () == 2); return Install (c.Get (0), c.Get (1)); } + NetDeviceContainer PointToPointHelper::Install (Ptr a, Ptr b) { @@ -196,6 +197,18 @@ PointToPointHelper::Install (Ptr a, Ptr b) return container; } +void +PointToPointHelper::InstallStar (Ptr hub, NodeContainer spokes, + NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices) +{ + for (uint32_t i = 0; i < spokes.GetN (); ++i) + { + NetDeviceContainer nd = Install (hub, spokes.Get (i)); + hubDevices.Add (nd.Get (0)); + spokeDevices.Add (nd.Get (1)); + } +} + void PointToPointHelper::EnqueueEvent (Ptr writer, Ptr packet) { diff --git a/src/helper/point-to-point-helper.h b/src/helper/point-to-point-helper.h index a86daf52a..a87425fef 100644 --- a/src/helper/point-to-point-helper.h +++ b/src/helper/point-to-point-helper.h @@ -170,6 +170,7 @@ public: * ns3::NetDevice with the ns3::Node and ns3::PointToPointChannel. */ NetDeviceContainer Install (NodeContainer c); + /** * \param a first node * \param b second node @@ -178,6 +179,34 @@ public: */ NetDeviceContainer Install (Ptr a, Ptr b); + /** + * \brief Make a star network topology. + * + * Given a pointer to a node that will become the hub of the star, and a + * NodeContainer containing pointers to the nodes that will become the + * spokes; we construct point to point net devices on the hub (corresponding + * to the spokes) and store them in the hubDevices NetDeviceContainer. We + * add a net device to each spoke node and store them in the spokeDevices + * NetDeviceContainer. A point-to-point channel is created for each spoke. + * + * The ordering of the devices in the hubDevices container is according to + * the order of the spokes container -- that is, hubDevices[0] will be the + * net device used on the hub that talks to spokes[0]. the container entry + * spokeDevices[0] will have the device that hubDevices[0] talks to -- those + * two devices are the ones that connect hub to spokes[0]. + * + * \param hub The central node of the star network + * \param spokes A NodeContainer of the nodes that will be the spoke (leaf) + * nodes + * \param hubDevices A NetDeviceContainer that will be filled with pointers + * to the point-to-point net devices created on the hub. + * \param spokeDevices A NetDeviceContainer that will be filled with pointers + * to the point-to-point net devices created on each of + * the spokes. + */ + void InstallStar (Ptr hub, NodeContainer spokes, + NetDeviceContainer& hubDevices, NetDeviceContainer& spokeDevices); + private: void EnablePcap (Ptr node, Ptr device, Ptr queue); void EnableAscii (Ptr node, Ptr device);