diff --git a/examples/test-dumbbell.cc b/examples/test-dumbbell.cc new file mode 100644 index 000000000..3075dab01 --- /dev/null +++ b/examples/test-dumbbell.cc @@ -0,0 +1,118 @@ +/* -*- 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 + * + * Author: George F. Riley + */ + +#include + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" + +using namespace ns3; + +int main (int argc, char *argv[]) +{ + Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("500kb/s")); + + uint32_t nLeftLeaf = 5; + uint32_t nRightLeaf = 5; + uint32_t nLeaf = 0; // If non-zero, number of both left and right + uint16_t port = 0; // If non zero, port to bind to for anim connection + std::string animFile; // Name of file for animation output + + CommandLine cmd; + cmd.AddValue ("nLeftLeaf", "Number of left side leaf nodes", nLeftLeaf); + cmd.AddValue ("nRightLeaf","Number of right side leaf nodes", nRightLeaf); + cmd.AddValue ("nLeaf", "Number of left and right side leaf nodes", nLeaf); + cmd.AddValue ("port", "Port Number for Remote Animation", port); + cmd.AddValue ("animFile", "File Name for Animation Output", animFile); + + cmd.Parse (argc,argv); + if (nLeaf > 0) + { + nLeftLeaf = nLeaf; + nRightLeaf = nLeaf; + } + + // Create the point-to-point link helpers + PointToPointHelper pointToPointRouter; + pointToPointRouter.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); + pointToPointRouter.SetChannelAttribute ("Delay", StringValue ("1ms")); + PointToPointHelper pointToPointLeaf; + pointToPointLeaf.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); + pointToPointLeaf.SetChannelAttribute ("Delay", StringValue ("1ms")); + + PointToPointDumbbellHelper d(nLeftLeaf, pointToPointLeaf, + nRightLeaf, pointToPointLeaf, + pointToPointRouter); + + // Install Stack + InternetStackHelper stack; + d.InstallStack (stack); + + // Assign IP Addresses + d.AssignAddresses(Ipv4AddressHelper("10.1.1.0", "255.255.255.0"), + Ipv4AddressHelper("10.2.1.0", "255.255.255.0"), + Ipv4AddressHelper("10.3.1.0", "255.255.255.0")); + + // Install on/off app on all right side nodes + OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); + clientHelper.SetAttribute + ("OnTime", RandomVariableValue (UniformVariable (0, 1))); + clientHelper.SetAttribute + ("OffTime", RandomVariableValue (UniformVariable (0, 1))); + ApplicationContainer clientApps; + + for (uint32_t i = 0; i < d.RightCount(); ++i) + { + // Create an on/off app sending packets to the same leaf right side + AddressValue remoteAddress(InetSocketAddress(d.GetLeftAddress(i), 1000)); + clientHelper.SetAttribute("Remote", remoteAddress); + clientApps.Add(clientHelper.Install(d.GetRight(i))); + } + + clientApps.Start (Seconds (0.0)); + clientApps.Stop (Seconds (10.0)); + + // Set the bounding box for animation + d.BoundingBox(1, 1, 10, 10); + + // Create the animation object and configure for specified output + AnimationInterface anim; + if (port > 0) + { + anim.SetServerPort(port); + } + else if (!animFile.empty()) + { + anim.SetOutputFile(animFile); + } + anim.StartAnimation(); + + // Set up the acutal simulation + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + + std::cout << "Running the simulation" << std::endl; + Simulator::Run (); + std::cout << "Destroying the simulation" << std::endl; + Simulator::Destroy (); + std::cout << "Stopping the animation" << std::endl; + anim.StopAnimation(); + return 0; +} diff --git a/examples/test-grid.cc b/examples/test-grid.cc new file mode 100644 index 000000000..7b17910a2 --- /dev/null +++ b/examples/test-grid.cc @@ -0,0 +1,108 @@ +/* -*- 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 + * + * Author: Josh Pelkey + */ + +#include + +#include "ns3/core-module.h" +#include "ns3/simulator-module.h" +#include "ns3/node-module.h" +#include "ns3/helper-module.h" + +using namespace ns3; + +int main (int argc, char *argv[]) +{ + Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); + Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("500kb/s")); + + uint32_t xSize = 5; + uint32_t ySize = 5; + uint16_t port = 0; + std::string animFile; + + CommandLine cmd; + cmd.AddValue ("xSize", "Number of rows of nodes", xSize); + cmd.AddValue ("ySize", "Number of columns of nodes", ySize); + cmd.AddValue ("port", "Port Number for Remote Animation", port); + cmd.AddValue ("animFile", "File Name for Animation Output", animFile); + + cmd.Parse (argc,argv); + if (xSize < 1) + NS_FATAL_ERROR ("Need more nodes for grid."); + if (ySize < 1) + NS_FATAL_ERROR ("Need more nodes for grid."); + if (xSize < 2 && ySize < 2) + NS_FATAL_ERROR ("Need more nodes for grid."); + + PointToPointHelper pointToPoint; + pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms")); + + // Create Grid + PointToPointGridHelper grid (xSize, ySize, pointToPoint); + + // Install stack on Grid + InternetStackHelper stack; + grid.InstallStack (stack); + + // Assign Addresses to Grid + grid.AssignAddresses (Ipv4AddressHelper("10.1.1.0", "255.255.255.0"), + Ipv4AddressHelper("10.2.1.0", "255.255.255.0")); + + + OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); + clientHelper.SetAttribute + ("OnTime", RandomVariableValue (ConstantVariable (1))); + clientHelper.SetAttribute + ("OffTime", RandomVariableValue (ConstantVariable (0))); + ApplicationContainer clientApps; + + // Create an on/off app sending packets + AddressValue remoteAddress(InetSocketAddress(grid.GetAddress (xSize-1,ySize-1), 1000)); + clientHelper.SetAttribute("Remote", remoteAddress); + clientApps.Add(clientHelper.Install(grid.GetNode (0,0))); + + clientApps.Start (Seconds (0.0)); + clientApps.Stop (Seconds (1.5)); + + // Set the bounding box for animation + grid.BoundingBox(1, 1, 10, 10); + + // Create the animation object and configure for specified output + AnimationInterface anim; + if (port > 0) + { + anim.SetServerPort(port); + } + else if (!animFile.empty()) + { + anim.SetOutputFile(animFile); + } + anim.StartAnimation(); + + // Set up the actual simulation + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + + std::cout << "Running the simulation" << std::endl; + Simulator::Run (); + std::cout << "Destroying the simulation" << std::endl; + Simulator::Destroy (); + std::cout << "Stopping the animation" << std::endl; + anim.StopAnimation(); + return 0; +} diff --git a/examples/wscript b/examples/wscript index 5bdca27db..4d5c04bd1 100644 --- a/examples/wscript +++ b/examples/wscript @@ -183,6 +183,14 @@ def build(bld): ['csma', 'internet-stack']) obj.source = 'radvd-two-prefix.cc' + obj = bld.create_ns3_program('test-dumbbell', + ['point-to-point', 'internet-stack']) + obj.source = 'test-dumbbell.cc' + + obj = bld.create_ns3_program('test-grid', + ['point-to-point', 'internet-stack']) + obj.source = 'test-grid.cc' + env = bld.env_of_name('default') if env['ENABLE_EMU']: obj = bld.create_ns3_program('emu-udp-echo', ['emu', 'internet-stack']) diff --git a/src/devices/point-to-point/point-to-point-channel.cc b/src/devices/point-to-point/point-to-point-channel.cc index 6fa1b7bee..d95114428 100644 --- a/src/devices/point-to-point/point-to-point-channel.cc +++ b/src/devices/point-to-point/point-to-point-channel.cc @@ -91,6 +91,9 @@ PointToPointChannel::TransmitStart( Simulator::Schedule (txTime + m_delay, &PointToPointNetDevice::Receive, m_link[wire].m_dst, p); + + // Call the tx anim callback on the net device + src->m_txrxPointToPoint (p, src, m_link[wire].m_dst, txTime, txTime + m_delay); return true; } diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index ff6ec3693..ca02c7344 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -82,6 +82,9 @@ PointToPointNetDevice::GetTypeId (void) // Trace sources at the "top" of the net device, where packets transition // to/from higher layers. // + .AddTraceSource ("TxRxPointToPoint", + "Trace source indicating transmission of packet from the PointToPointChannel, used by the Animation interface.", + MakeTraceSourceAccessor (&PointToPointNetDevice::m_txrxPointToPoint)) .AddTraceSource ("MacTx", "Trace source indicating a packet has arrived for transmission by this device", MakeTraceSourceAccessor (&PointToPointNetDevice::m_macTxTrace)) diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index cb2784085..1dbfd25cb 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -386,6 +386,24 @@ private: */ Ptr m_receiveErrorModel; + /** + * The trace source for the packet transmission animation events that the + * device can fire. + * Arguments to the callback are the packet, transmitting + * net device, receiving net device, transmittion time and + * packet receipt time. + * + * @see class CallBackTraceSource + */ + friend class PointToPointChannel; // Allow the channel to call the callback + TracedCallback, // Packet being transmitted + Ptr, // Transmitting NetDevice + Ptr, // Receiving NetDevice + Time, // Amount of time to transmit the pkt + Time // Last bit receive time (relative to now) + > m_txrxPointToPoint; + + /** * The trace source fired when packets come into the "top" of the device * at the L3/L2 transition, before being queued for transmission. diff --git a/src/helper/animation-interface.cc b/src/helper/animation-interface.cc new file mode 100644 index 000000000..3b80ce8e5 --- /dev/null +++ b/src/helper/animation-interface.cc @@ -0,0 +1,193 @@ +/* -*- 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 + * + * Author: George F. Riley + */ + +// Interface between ns3 and the network animator + +#include +#include + +// Socket related includes +#include +#include + +// ns3 includes +#include "ns3/animation-interface.h" +#include "ns3/channel.h" +#include "ns3/config.h" +#include "ns3/node.h" +#include "ns3/node-location.h" +#include "ns3/packet.h" +#include "ns3/simulator.h" + +using namespace std; + +NS_LOG_COMPONENT_DEFINE ("AnimationInterface"); + +namespace ns3 { + +AnimationInterface::AnimationInterface () + : m_fHandle (STDOUT_FILENO), m_model (0) +{ +} + +bool AnimationInterface::SetOutputFile (const std::string& fn) +{ + FILE* f = fopen (fn.c_str (), "w"); + if (!f) + { + return false; // Can't open + } + m_fHandle = fileno (f); // Set the file handle + return true; +} + +bool AnimationInterface::SetServerPort (uint16_t port) +{ + int s = socket (AF_INET, SOCK_STREAM, 0); + struct sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons (port); + addr.sin_addr.s_addr = htonl (INADDR_ANY); + if (bind (s, (struct sockaddr*)&addr, sizeof (addr)) < 0) + { + NS_LOG_WARN ("Can't bind to port " << port << ", exiting."); + return false; + } + listen (s, 1); + NS_LOG_INFO ("Waiting for animator connection"); + // Now wait for the animator to connect in + m_fHandle = accept (s, 0, 0); + NS_LOG_INFO ("Got animator connection from remote"); + // set the linger socket option + int t = 1; + setsockopt (s, SOL_SOCKET, SO_LINGER, &t, sizeof(t)); + return true; +} + +bool AnimationInterface::SetInternalAnimation () +{ + return false; // Not implemented yet +} + +void AnimationInterface::StartAnimation () +{ + // Dump the topology + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i) + { + Ptr n = *i; + Ptr loc = n->GetObject (); + if (loc) + { + // Location exists, dump it + Vector v = loc->GetLocation (); + ostringstream oss; + oss << "0.0 N " << n->GetId () + << " " << v.x << " " << v.y << endl; + WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); + } + } + // Now dump the p2p links + for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End(); ++i) + { + Ptr n = *i; + uint32_t n1Id = n->GetId (); + uint32_t nDev = n->GetNDevices (); // Number of devices + for (uint32_t i = 0; i < nDev; ++i) + { + Ptr dev = n->GetDevice (i); + Ptr ch = dev->GetChannel (); + if (!ch) + { + continue; // No channel, can't be p2p device + } + string channelType = ch->GetInstanceTypeId ().GetName (); + if (channelType == string ("ns3::PointToPointChannel")) + { // Since these are duplex links, we only need to dump + // if srcid < dstid + uint32_t nChDev = ch->GetNDevices (); + for (uint32_t j = 0; j < nChDev; ++j) + { + Ptr chDev = ch->GetDevice (j); + uint32_t n2Id = chDev->GetNode ()->GetId (); + if (n1Id < n2Id) + { // ouptut the p2p link + ostringstream oss; + oss << "0.0 L " << n1Id << " " << n2Id << endl; + WriteN (m_fHandle, oss.str ().c_str (), + oss.str ().length ()); + } + } + } + else + { + NS_FATAL_ERROR ("Net animation currently only supports point-to-point links."); + } + } + } + + // Connect the callback for packet tx events + Config::Connect ("/NodeList/*/DeviceList/*/TxRxPointToPoint", + MakeCallback (&AnimationInterface::DevTxTrace, this)); +} + +void AnimationInterface::StopAnimation () +{ + if (m_fHandle > 0) + { + close (m_fHandle); + } +} + + +// Private methods +int AnimationInterface::WriteN (int h, const char* data, uint32_t count) +{ // Write count bytes to h from data + uint32_t nLeft = count; + const char* p = data; + uint32_t written = 0; + + while (nLeft) + { + int n = write (h, p, nLeft); + if (n <= 0) + { + return written; + } + written += n; + nLeft -= n; + p += n; + } + return written; +} + +void AnimationInterface::DevTxTrace (std::string context, Ptr p, + Ptr tx, Ptr rx, + Time txTime, Time rxTime) +{ + Time now = Simulator::Now (); + ostringstream oss; + oss << now.GetSeconds() << " P " + << tx->GetNode ()->GetId () << " " + << rx->GetNode ()->GetId () << " " + << (now + txTime).GetSeconds () << " " // last bit tx time + << (now + rxTime - txTime).GetSeconds() << " " // first bit rx time + << (now + rxTime).GetSeconds () << endl; // last bit rx time + WriteN (m_fHandle, oss.str ().c_str (), oss.str ().length ()); +} + +} // namespace ns3 diff --git a/src/helper/animation-interface.h b/src/helper/animation-interface.h new file mode 100644 index 000000000..9ba6ca685 --- /dev/null +++ b/src/helper/animation-interface.h @@ -0,0 +1,120 @@ +/* -*- 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 + * + * Author: George F. Riley + */ + +// Interface between ns3 and the network animator + +#ifndef __ANIMATION_INTERFACE__H__ +#define __ANIMATION_INTERFACE__H__ + +#include + +#include "ns3/ptr.h" +#include "ns3/net-device.h" +#include "ns3/nstime.h" +#include "ns3/log.h" +#include "ns3/node-list.h" + + +namespace ns3 { +class NetModel; + +/** + * \brief Interface to network animator + * + * Provides functions that facilitate communications with an + * external or internal network animator. + */ +class AnimationInterface +{ +public: +/** + * @brief Construct the animator interface. No arguments needed. + */ + AnimationInterface (); +/** + * @brief Specify that animation commands are to be written + * to the specified output file. + * + * This call is used to write the animation information to a text + * file that can later be used as input to the network animator tool. + * + * @param fn The name of the output file. + * @returns true if successful open. + */ + bool SetOutputFile (const std::string& fn); + +/** + * @brief Specify that animation commands are to be written to + * a socket. + * + * This call is used to set the ns3 process in server mode, waiting + * for a TCP connection from the animator. This call will not + * return until the animator connects in, or if the bind to the + * specified port fails. + * + * @param port Port number to bind to. + * @returns true if connection created, false if bind failed. + */ + bool SetServerPort (uint16_t port); + +/** + * @brief Specify that animation window is to be created as part + * of the ns3 process. + * + * This call is used to set the ns3 animator internal to the + * current process. This will fail if the ns3 library was built + * without the QT4 developer packages. + * + * @returns true if animation started, false if failed. + */ + bool SetInternalAnimation (); + +/** + * @brief Writes the topology information and sets up the appropriate + * animation packet tx callback + * + * Writes the topology information to the appropriate output, depending + * on prior calls to SetOutputFile, SetServerPort, or SetInternalAnimation. + * Then creates the callbacks needed for the animator to start processing + * packets. + * + */ + void StartAnimation (); + +/** + * @brief Closes the interface to the animator. + * + */ + void StopAnimation (); + + +private: + // Packet tx animation callback + void DevTxTrace (std::string context, Ptr p, + Ptr tx, Ptr rx, + Time txTime, Time rxTime); + // Write specified amount of data to the specified handle + int WriteN (int, const char*, uint32_t); +private: + int m_fHandle; // File handle for output (-1 if none) + NetModel* m_model; // If non nil, points to the internal network model + // for the interlan animator +}; +} +#endif + diff --git a/src/helper/ipv4-address-helper.cc b/src/helper/ipv4-address-helper.cc index b0ae54691..5ec6efb82 100644 --- a/src/helper/ipv4-address-helper.cc +++ b/src/helper/ipv4-address-helper.cc @@ -46,6 +46,15 @@ Ipv4AddressHelper::Ipv4AddressHelper () m_max = 0xffffffff; } +Ipv4AddressHelper::Ipv4AddressHelper ( + const Ipv4Address network, + const Ipv4Mask mask, + const Ipv4Address address) +{ + NS_LOG_FUNCTION_NOARGS (); + SetBase (network, mask, address); +} + void Ipv4AddressHelper::SetBase ( const Ipv4Address network, diff --git a/src/helper/ipv4-address-helper.h b/src/helper/ipv4-address-helper.h index 761a15576..c1fd7ef70 100644 --- a/src/helper/ipv4-address-helper.h +++ b/src/helper/ipv4-address-helper.h @@ -51,6 +51,14 @@ public: */ Ipv4AddressHelper (); +/** + * @brief Construct a helper class to make life easier while doing simple IPv4 + * address assignment in scripts. This version sets the base and mask + * in the constructor + */ + Ipv4AddressHelper (Ipv4Address network, Ipv4Mask mask, + Ipv4Address base = "0.0.0.1"); + /** * @brief Set the base network mumber, network mask and base address. * diff --git a/src/helper/ipv4-interface-container.cc b/src/helper/ipv4-interface-container.cc index 1666e5ae3..31e4e57c8 100644 --- a/src/helper/ipv4-interface-container.cc +++ b/src/helper/ipv4-interface-container.cc @@ -42,6 +42,10 @@ Ipv4InterfaceContainer::Add (Ptr ipv4, uint32_t interface) { m_interfaces.push_back (std::make_pair (ipv4, interface)); } +void Ipv4InterfaceContainer::Add (std::pair, uint32_t> a) + { + Add (a.first, a.second); + } void Ipv4InterfaceContainer::Add (std::string ipv4Name, uint32_t interface) { @@ -49,4 +53,11 @@ Ipv4InterfaceContainer::Add (std::string ipv4Name, uint32_t interface) m_interfaces.push_back (std::make_pair (ipv4, interface)); } + std::pair, uint32_t> +Ipv4InterfaceContainer::Get(uint32_t i) const + { + return m_interfaces[i]; + } + + } // namespace ns3 diff --git a/src/helper/ipv4-interface-container.h b/src/helper/ipv4-interface-container.h index 58cb7c704..c92dd33b4 100644 --- a/src/helper/ipv4-interface-container.h +++ b/src/helper/ipv4-interface-container.h @@ -49,8 +49,11 @@ public: * \param interface interface index of the Ipv4Interface to add to the container */ void Add (Ptr ipv4, uint32_t interface); + void Add (std::pair, uint32_t>); void Add (std::string ipv4Name, uint32_t interface); + std::pair, uint32_t> Get (uint32_t) const; + private: typedef std::vector,uint32_t> > InterfaceVector; diff --git a/src/helper/node-location.cc b/src/helper/node-location.cc new file mode 100644 index 000000000..add805142 --- /dev/null +++ b/src/helper/node-location.cc @@ -0,0 +1,56 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 Georgia Institute of Technology + * + * 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: George Riley + */ + +#include "node-location.h" + +namespace ns3 { + +TypeId +NodeLocation::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::NodeLocation") + .SetParent () + .AddAttribute ("Position", "The current position of the mobility model.", + TypeId::ATTR_SET | TypeId::ATTR_GET, + VectorValue (Vector (0.0, 0.0, 0.0)), + MakeVectorAccessor (&NodeLocation::SetLocation, + &NodeLocation::GetLocation), + MakeVectorChecker ()) + ; + return tid; +} + +NodeLocation::NodeLocation () +{} + +NodeLocation::~NodeLocation () +{} + +Vector NodeLocation::GetLocation (void) const +{ + return m_location; +} + +void NodeLocation::SetLocation (const Vector &location) +{ + m_location = location; +} + +} // namespace ns3 diff --git a/src/helper/node-location.h b/src/helper/node-location.h new file mode 100644 index 000000000..6119f92e4 --- /dev/null +++ b/src/helper/node-location.h @@ -0,0 +1,61 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2009 Georgia Institute of Technology + * + * 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: George Riley + */ +#ifndef __NODE_LOCATION_H__ +#define __NODE_LOCATION_H__ + +#include "ns3/object.h" +#include "ns3/traced-callback.h" +#include "ns3/vector.h" + +namespace ns3 { + +/** + * \brief Keep track of the current location of an object + * + * This can be used anytime a logical node location is needed + * (as opposed to a physical location used by the wireless PHY + * layer to calculate path loss). One potential use of + * this is by the animator to determine where to position the + * node icon on the animation display. Location units are + * arbitrary and dimensionless. In the case of use by the + * animator they dimensions are in pixels. + */ +class NodeLocation : public Object +{ +public: + static TypeId GetTypeId (void); + NodeLocation (); + virtual ~NodeLocation (); + + /** + * \returns the current location + */ + Vector GetLocation (void) const; + /** + * \param location the location to set. + */ + void SetLocation (const Vector &location); +private: + Vector m_location; +}; + +}; // namespace ns3 + +#endif /* __NODE_LOCATION_H__ */ diff --git a/src/helper/point-to-point-dumbbell-helper.cc b/src/helper/point-to-point-dumbbell-helper.cc new file mode 100644 index 000000000..10d649ed2 --- /dev/null +++ b/src/helper/point-to-point-dumbbell-helper.cc @@ -0,0 +1,253 @@ +/* -*- 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 + * + * Author: George F. Riley + */ + +// Implement an object to create a dumbbell topology. + +#include +#include + +// Socket related includes +#include +#include + +// ns3 includes +#include "animation-interface.h" +#include "point-to-point-dumbbell-helper.h" +#include "node-location.h" + +#include "ns3/node-list.h" +#include "ns3/point-to-point-net-device.h" +#include "ns3/vector.h" + +using namespace std; + +NS_LOG_COMPONENT_DEFINE("PointToPointDumbbellHelper"); + +namespace ns3 { + +PointToPointDumbbellHelper::PointToPointDumbbellHelper (uint32_t nLeftLeaf, + PointToPointHelper& leftHelper, + uint32_t nRightLeaf, + PointToPointHelper& rightHelper, + PointToPointHelper& bottleneckHelper) +{ + // Create the bottleneck routers + m_routers.Create (2); + // Create the leaf nodes + m_leftLeaf.Create (nLeftLeaf); + m_rightLeaf.Create (nRightLeaf); + + // Add the link connecting routers + m_routerDevices = bottleneckHelper.Install (m_routers); + // Add the left side links + for (uint32_t i = 0; i < nLeftLeaf; ++i) + { + NetDeviceContainer c = leftHelper.Install (m_routers.Get (0), + m_leftLeaf.Get (i)); + m_leftRouterDevices.Add (c.Get (0)); + m_leftLeafDevices.Add (c.Get(1)); + } + // Add the right side links + for (uint32_t i = 0; i < nRightLeaf; ++i) + { + NetDeviceContainer c = rightHelper.Install (m_routers.Get (1), + m_rightLeaf.Get (i)); + m_rightRouterDevices.Add (c.Get (0)); + m_rightLeafDevices.Add (c.Get (1)); + } +} + +Ptr PointToPointDumbbellHelper::GetLeft () const +{ // Get the left side bottleneck router + return m_routers.Get (0); +} + +Ptr PointToPointDumbbellHelper::GetLeft (uint32_t i) const +{ // Get the i'th left side leaf + return m_leftLeaf.Get (i); +} + +Ptr PointToPointDumbbellHelper::GetRight () const +{ // Get the right side bottleneck router + return m_routers.Get (1); +} + +Ptr PointToPointDumbbellHelper::GetRight (uint32_t i) const +{ // Get the i'th right side leaf + return m_rightLeaf.Get (i); +} + +Ipv4Address PointToPointDumbbellHelper::GetLeftAddress (uint32_t i) const +{ + return m_leftLeafInterfaces.GetAddress (i); +} + +Ipv4Address PointToPointDumbbellHelper::GetRightAddress (uint32_t i) const +{ + return m_rightLeafInterfaces.GetAddress (i); +} + +uint32_t PointToPointDumbbellHelper::LeftCount () const +{ // Number of left side nodes + return m_leftLeaf.GetN (); +} + +uint32_t PointToPointDumbbellHelper::RightCount () const +{ // Number of right side nodes + return m_rightLeaf.GetN (); +} + +void PointToPointDumbbellHelper::InstallStack (InternetStackHelper stack) +{ + stack.Install (m_routers); + stack.Install (m_leftLeaf); + stack.Install (m_rightLeaf); +} + +void PointToPointDumbbellHelper::AssignAddresses (Ipv4AddressHelper leftIp, + Ipv4AddressHelper rightIp, + Ipv4AddressHelper routerIp) +{ + // Assign the router network + m_routerInterfaces = routerIp.Assign (m_routerDevices); + // Assign to left side + for (uint32_t i = 0; i < LeftCount (); ++i) + { + NetDeviceContainer ndc; + ndc.Add (m_leftLeafDevices.Get (i)); + ndc.Add (m_leftRouterDevices.Get (i)); + Ipv4InterfaceContainer ifc = leftIp.Assign(ndc); + m_leftLeafInterfaces.Add (ifc.Get (0)); + m_leftRouterInterfaces.Add (ifc.Get (1)); + leftIp.NewNetwork (); + } + // Assign to right size + for (uint32_t i = 0; i < RightCount (); ++i) + { + NetDeviceContainer ndc; + ndc.Add (m_rightLeafDevices.Get (i)); + ndc.Add (m_rightRouterDevices.Get (i)); + Ipv4InterfaceContainer ifc = rightIp.Assign (ndc); + m_rightLeafInterfaces.Add (ifc.Get (0)); + m_rightRouterInterfaces.Add (ifc.Get (1)); + rightIp.NewNetwork (); + } +} + + +void PointToPointDumbbellHelper::BoundingBox (double ulx, double uly, // Upper left x/y + double lrx, double lry) // Lower right y +{ + double xDist = lrx - ulx; + double yDist = lry - uly; + double xAdder = xDist / 3.0; + double thetaL = M_PI / (LeftCount () + 1.0); + double thetaR = M_PI / (RightCount () + 1.0); + + // Place the left router + Ptr lr = GetLeft (); + Ptr loc = lr->GetObject (); + if (loc == 0) + { + loc = CreateObject (); + lr->AggregateObject (loc); + } + Vector lrl (ulx + xAdder, uly + yDist/2.0, 0); + loc->SetLocation (lrl); + + // Place the right router + Ptr rr = GetRight (); + loc = rr->GetObject (); + if (loc == 0) + { + loc = CreateObject (); + rr->AggregateObject (loc); + } + Vector rrl (ulx + xAdder * 2, uly + yDist/2.0, 0); // Right router location + loc->SetLocation (rrl); + + // Place the left leaf nodes + double theta = -M_PI_2 + thetaL; + for (uint32_t l = 0; l < LeftCount (); ++l) + { + // Make them in a circular pattern to make all line lengths the same + // Special case when theta = 0, to be sure we get a straight line + if ((LeftCount () % 2) == 1) + { // Count is odd, see if we are in middle + if (l == (LeftCount () / 2)) + { + theta = 0.0; + } + } + Ptr ln = GetLeft (l); + loc = ln->GetObject (); + if (loc == 0) + { + loc = CreateObject (); + ln->AggregateObject (loc); + } + Vector lnl (lrl.x - cos (theta) * xAdder, + lrl.y + sin (theta) * xAdder, 0); // Left Node Location + // Insure did not exceed bounding box + if (lnl.y < uly) + { + lnl.y = uly; // Set to upper right y + } + if (lnl.y > lry) + { + lnl.y = lry; // Set to lower right y + } + loc->SetLocation (lnl); + theta += thetaL; + } + // Place the right nodes + theta = -M_PI_2 + thetaR; + for (uint32_t r = 0; r < RightCount (); ++r) + { + // Special case when theta = 0, to be sure we get a straight line + if ((RightCount () % 2) == 1) + { // Count is odd, see if we are in middle + if (r == (RightCount () / 2)) + { + theta = 0.0; + } + } + Ptr rn = GetRight (r); + loc = rn->GetObject (); + if (loc == 0) + { + loc = CreateObject (); + rn->AggregateObject (loc); + } + Vector rnl (rrl.x + cos (theta) * xAdder, // Right node location + rrl.y + sin (theta) * xAdder, 0); + // Insure did not exceed bounding box + if (rnl.y < uly) + { + rnl.y = uly; // Set to upper right y + } + if (rnl.y > lry) + { + rnl.y = lry; // Set to lower right y + } + loc->SetLocation (rnl); + theta += thetaR; + } +} + +} // namespace ns3 diff --git a/src/helper/point-to-point-dumbbell-helper.h b/src/helper/point-to-point-dumbbell-helper.h new file mode 100644 index 000000000..c54caaeaf --- /dev/null +++ b/src/helper/point-to-point-dumbbell-helper.h @@ -0,0 +1,77 @@ +/* -*- 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 + * + * Author: George F. Riley + */ + +// Define an object to create a dumbbell topology. + +#ifndef __POINT_TO_POINT_DUMBBELL_HELPER_H__ +#define __POINT_TO_POINT_DUMBBELL_HELPER_H__ + +#include + +#include "point-to-point-helper.h" +#include "ipv4-address-helper.h" +#include "internet-stack-helper.h" +#include "ipv4-interface-container.h" + +namespace ns3 { + +class PointToPointDumbbellHelper +{ +public: + PointToPointDumbbellHelper (uint32_t nLeftLeaf, // Number of left size leaf nodes + PointToPointHelper& leftHelper, + uint32_t nRightLeaf, // Number of right side leaf nodes + PointToPointHelper& rightHelper, + PointToPointHelper& bottleneckHelper); +public: + Ptr GetLeft () const; // Get the left side bottleneck router + Ptr GetLeft (uint32_t) const; // Get the i'th left side leaf + Ptr GetRight () const; // Get the right side bottleneck router + Ptr GetRight (uint32_t) const; // Get the i'th right side leaf + Ipv4Address GetLeftAddress (uint32_t) const; // Get left leaf address + Ipv4Address GetRightAddress (uint32_t) const; // Get right leaf address + uint32_t LeftCount () const; // Number of left side nodes + uint32_t RightCount () const; // Number of right side nodes + void InstallStack (InternetStackHelper stack); + void AssignAddresses (Ipv4AddressHelper leftIp, + Ipv4AddressHelper rightIp, + Ipv4AddressHelper routerIp); + // Add locations in the specified bounding box + // Arguments are uppler left x, upper left y, lower right x, lower right y + void BoundingBox (double, double, double, double); + +private: + NodeContainer m_leftLeaf; + NetDeviceContainer m_leftLeafDevices; + NodeContainer m_rightLeaf; + NetDeviceContainer m_rightLeafDevices; + NodeContainer m_routers; + NetDeviceContainer m_routerDevices; // just two connecting the routers + // Device containers for the router devices connecting to the leaf devices + NetDeviceContainer m_leftRouterDevices; + NetDeviceContainer m_rightRouterDevices; + Ipv4InterfaceContainer m_leftLeafInterfaces; + Ipv4InterfaceContainer m_leftRouterInterfaces; + Ipv4InterfaceContainer m_rightLeafInterfaces; + Ipv4InterfaceContainer m_rightRouterInterfaces; + Ipv4InterfaceContainer m_routerInterfaces; +}; +} +#endif + + diff --git a/src/helper/point-to-point-grid-helper.cc b/src/helper/point-to-point-grid-helper.cc new file mode 100644 index 000000000..d2d6933d8 --- /dev/null +++ b/src/helper/point-to-point-grid-helper.cc @@ -0,0 +1,240 @@ +/* -*- 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 + * + * Author: Josh Pelkey + */ + +#include "point-to-point-grid-helper.h" +#include "animation-interface.h" +#include "internet-stack-helper.h" +#include "point-to-point-helper.h" +#include "node-location.h" +#include "ns3/string.h" +#include "ns3/vector.h" +#include "ns3/log.h" + +#ifdef NS3_MPI +#include +#endif + +NS_LOG_COMPONENT_DEFINE("PointToPointGridHelper"); + +namespace ns3 { + +PointToPointGridHelper::PointToPointGridHelper (uint32_t nRows, + uint32_t nCols, + PointToPointHelper pointToPoint) + : m_xSize (nCols), m_ySize (nRows) +{ + InternetStackHelper stack; + + for (uint32_t y = 0; y < nRows; ++y) + { + NodeContainer rowNodes; + NetDeviceContainer rowDevices; + NetDeviceContainer colDevices; + + for (uint32_t x = 0; x < nCols; ++x) + { + rowNodes.Create(1); + + // install p2p links across the row + if (x > 0) + { + rowDevices.Add (pointToPoint. + Install (rowNodes.Get (x-1), rowNodes.Get (x))); + } + + // install vertical p2p links + if (y > 0) + { + colDevices.Add(pointToPoint. + Install ((m_nodes.at (y-1)).Get (x), rowNodes.Get (x))); + } + } + + m_nodes.push_back(rowNodes); + m_rowDevices.push_back (rowDevices); + + if (y > 0) + m_colDevices.push_back (colDevices); + } +} + +PointToPointGridHelper::PointToPointGridHelper (uint32_t nRows, + uint32_t nCols, PointToPointHelper pointToPoint, + uint16_t mpiSize) + : m_xSize (nCols), m_ySize (nRows) +{ +#ifdef NS3_MPI + for (uint32_t y = 0; y < nRows; ++y) + { + NodeContainer rowNodes; + NetDeviceContainer rowDevices; + NetDeviceContainer colDevices; + + for (uint32_t x = 0; x < nCols; ++x) + { + Ptr node = CreateObject (); + // keep it simple for now, and + // split this up on to two + // processors + if (x > xSize/2) + { + node->SetSystemId(1); + } + else + { + node->SetSystemId(0); + } + rowNodes.Add (node); + + // install p2p links across the row + if (x > 0) + { + rowDevices.Add (pointToPoint. + Install (rowNodes.Get (x-1), rowNodes.Get (x))); + } + + // install vertical p2p links + if (y > 0) + { + colDevices.Add(pointToPoint. + Install ((m_nodes.at (y-1)).Get (x), rowNodes.Get (x))); + } + } + + m_nodes.push_back(rowNodes); + m_rowDevices.push_back (rowDevices); + + if (y > 0) + { + m_colDevices.push_back (colDevices); + } + } +#else + NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in"); +#endif +} + +void +PointToPointGridHelper::InstallStack (InternetStackHelper stack) +{ + for (uint32_t i = 0; i < m_nodes.size (); ++i) + { + NodeContainer rowNodes = m_nodes[i]; + for (uint32_t j = 0; j < rowNodes.GetN (); ++j) + { + stack.Install (rowNodes.Get (j)); + } + } +} + +void +PointToPointGridHelper::AssignAddresses (Ipv4AddressHelper rowIp, Ipv4AddressHelper colIp) +{ + // Assign addresses to all row devices in the grid. + // These devices are stored in a vector. Each row + // of the grid has all the row devices in one entry + // of the vector. These entries come in pairs. + for (uint32_t i = 0; i < m_rowDevices.size (); ++i) + { + Ipv4InterfaceContainer rowInterfaces; + NetDeviceContainer rowContainer = m_rowDevices[i]; + for (uint32_t j = 0; j < rowContainer.GetN (); j+=2) + { + rowInterfaces.Add (rowIp.Assign (rowContainer.Get (j))); + rowInterfaces.Add (rowIp.Assign (rowContainer.Get (j+1))); + rowIp.NewNetwork (); + } + m_rowInterfaces.push_back (rowInterfaces); + } + + // Assign addresses to all col devices in the grid. + // These devices are stored in a vector. Each col + // of the grid has all the col devices in one entry + // of the vector. These entries come in pairs. + for (uint32_t i = 0; i < m_colDevices.size (); ++i) + { + Ipv4InterfaceContainer colInterfaces; + NetDeviceContainer colContainer = m_colDevices[i]; + for (uint32_t j = 0; j < colContainer.GetN (); j+=2) + { + colInterfaces.Add (colIp.Assign (colContainer.Get (j))); + colInterfaces.Add (colIp.Assign (colContainer.Get (j+1))); + colIp.NewNetwork (); + } + m_colInterfaces.push_back (colInterfaces); + } +} + +void +PointToPointGridHelper::BoundingBox (double ulx, double uly, + double lrx, double lry) +{ + double xDist = lrx - ulx; + double yDist = lry - uly; + + double xAdder = xDist / m_xSize; + double yAdder = yDist / m_ySize; + double yLoc = yDist / 2; + for (uint32_t i = 0; i < m_ySize; ++i) + { + double xLoc = xDist / 2; + for (uint32_t j = 0; j < m_xSize; ++j) + { + Ptr node = GetNode (i, j); + Ptr loc = node->GetObject (); + if (loc ==0) + { + loc = CreateObject (); + node->AggregateObject (loc); + } + Vector locVec (xLoc, yLoc, 0); + loc->SetLocation (locVec); + + xLoc += xAdder; + } + yLoc += yAdder; + } +} + +Ptr +PointToPointGridHelper::GetNode (uint32_t row, uint32_t col) +{ + return (m_nodes.at (row)).Get (col); +} + +Ipv4Address +PointToPointGridHelper::GetAddress (uint32_t row, uint32_t col) +{ + // Right now this just gets one of the addresses of the + // specified node. The exact device can't be specified. + // If you picture the grid, the address returned is the + // address of the left (row) device of all nodes, with + // the exception of the left-most nodes in the grid; + // in which case the right (row) device address is + // returned + if (col == 0) + { + return (m_rowInterfaces.at (row)).GetAddress (0); + } + else + { + return (m_rowInterfaces.at (row)).GetAddress ((2*col)-1); + } +} + +} // namespace ns3 diff --git a/src/helper/point-to-point-grid-helper.h b/src/helper/point-to-point-grid-helper.h new file mode 100644 index 000000000..1f2781391 --- /dev/null +++ b/src/helper/point-to-point-grid-helper.h @@ -0,0 +1,58 @@ +/* -*- 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 + * + * Author: Josh Pelkey + */ + +#ifndef __POINT_TO_POINT_GRID_HELPER_H__ +#define __POINT_TO_POINT_GRID_HELPER_H__ + +#include + +#include "internet-stack-helper.h" +#include "point-to-point-helper.h" +#include "ipv4-address-helper.h" +#include "ipv4-interface-container.h" +#include "net-device-container.h" + +namespace ns3 { + +class PointToPointGridHelper +{ + public: + PointToPointGridHelper (uint32_t nRows, uint32_t nCols, PointToPointHelper pointToPoint); + PointToPointGridHelper (uint32_t nRows, uint32_t nCols, PointToPointHelper pointToPoint, uint16_t mpiSize); + + Ptr GetNode (uint32_t row, uint32_t col); + Ipv4Address GetAddress (uint32_t row, uint32_t col); + + void InstallStack (InternetStackHelper stack); + void AssignAddresses (Ipv4AddressHelper rowIp, Ipv4AddressHelper colIp); + void BoundingBox (double ulx, double uly, double lrx, double lry); + + private: + uint32_t m_xSize; + uint32_t m_ySize; + std::vector m_rowDevices; + std::vector m_colDevices; + std::vector m_rowInterfaces; + std::vector m_colInterfaces; + std::vector m_nodes; + +}; + +} // namespace ns3 + +#endif /* GRID_HELPER_H */ diff --git a/src/helper/wscript b/src/helper/wscript index 1d6ddd850..edf95f21f 100644 --- a/src/helper/wscript +++ b/src/helper/wscript @@ -39,6 +39,10 @@ def build(bld): 'ipv6-list-routing-helper.cc', 'ipv6-routing-helper.cc', 'ping6-helper.cc', + 'animation-interface.cc', + 'node-location.cc', + 'point-to-point-dumbbell-helper.cc', + 'point-to-point-grid-helper.cc', 'flow-monitor-helper.cc', ] @@ -83,6 +87,10 @@ def build(bld): 'ipv6-routing-helper.h', 'ping6-helper.h', 'flow-monitor-helper.h', + 'animation-interface.h', + 'node-location.h', + 'point-to-point-dumbbell-helper.h', + 'point-to-point-grid-helper.h', ] env = bld.env_of_name('default')