Add SerialTopology functions and remove from simple.cc file
authorTom Henderson <tomh@tomh.org>
Mon, 19 Mar 2007 00:40:44 -0700
changeset 351 3589721585e7
parent 350 32f443f96560
child 352 8fb57ba7b707
Add SerialTopology functions and remove from simple.cc file
SConstruct
samples/ns-2/simple.cc
src/devices/serial/serial-topology.cc
src/devices/serial/serial-topology.h
--- a/SConstruct	Mon Mar 19 00:21:21 2007 -0700
+++ b/SConstruct	Mon Mar 19 00:40:44 2007 -0700
@@ -270,6 +270,7 @@
 serial.add_sources ([
     'serial-net-device.cc',
     'serial-channel.cc',
+    'serial-topology.cc',
     'serial-phy.cc',
     'layer-connector.cc',
     ])
@@ -279,6 +280,7 @@
 serial.add_inst_headers ([
     'serial-net-device.h',
     'serial-channel.h',
+    'serial-topology.h',
     'serial-phy.h',
     'layer-connector.h',
     ])
--- a/samples/ns-2/simple.cc	Mon Mar 19 00:21:21 2007 -0700
+++ b/samples/ns-2/simple.cc	Mon Mar 19 00:40:44 2007 -0700
@@ -64,6 +64,8 @@
 #include "ns3/node-list.h"
 #include "ns3/trace-root.h"
 
+#include "ns3/serial-topology.h"
+
 using namespace ns3;
 
 class Tracer : public TraceWriter{
@@ -217,59 +219,6 @@
 }
 #endif
 
-static SerialChannel * 
-AddDuplexLink(
-  InternetNode* a, 
-  const Ipv4Address& addra,
-  InternetNode* b, 
-  const Ipv4Address& addrb,
-  uint64_t bps,
-  const Time& delay)
-{
-  SerialChannel* channel = new SerialChannel(bps, delay);
-
-  // Duplex link is assumed to be subnetted as a /30
-  // May run this unnumbered in the future?
-  Ipv4Mask netmask("255.255.255.252");
-  assert(netmask.IsMatch(addra,addrb));
-
-  DropTailQueue* dtqa = new DropTailQueue();
-
-  SerialNetDevice* neta = new SerialNetDevice(a);
-  neta->AddQueue(dtqa);
-  Ipv4Interface *interfA = new ArpIpv4Interface (a, neta);
-  uint32_t indexA = a->GetIpv4 ()->AddInterface (interfA);
-  neta->Attach (channel);
-  
-  interfA->SetAddress (addra);
-  interfA->SetNetworkMask (netmask);
-  interfA->SetUp ();
-
-  DropTailQueue* dtqb = new DropTailQueue();
-
-  SerialNetDevice* netb = new SerialNetDevice(b);
-  netb->AddQueue(dtqb);
-  Ipv4Interface *interfB = new ArpIpv4Interface (b, netb);
-  uint32_t indexB = b->GetIpv4 ()->AddInterface (interfB);
-  netb->Attach (channel);
-
-  interfB->SetAddress (addrb);
-  interfB->SetNetworkMask (netmask);
-  interfB->SetUp ();
-
-  a->GetIpv4 ()->AddHostRouteTo (addrb, indexA);
-  b->GetIpv4 ()->AddHostRouteTo (addra, indexB);
-
-  NS_DEBUG_UNCOND("Adding interface " << indexA << " to node " << a->GetId());
-  NS_DEBUG_UNCOND("Adding interface " << indexB << " to node " << b->GetId());
-
-  //PrintRoutingTable (a, "a");
-  //PrintRoutingTable (b, "b");
-
-  return channel;
-}
-
-
 int main (int argc, char *argv[])
 {
 #if 0
@@ -298,14 +247,20 @@
   n2->SetName(std::string("Node 2"));
   n3->SetName(std::string("Node 3"));
   
-  SerialChannel* ch1 = AddDuplexLink (n0, Ipv4Address("10.1.1.1"), 
-      n2, Ipv4Address("10.1.1.2"), 5000000, MilliSeconds(2));
+  SerialChannel* ch1 = SerialTopology::AddSerialLink (
+      n0, Ipv4Address("10.1.1.1"), 
+      n2, Ipv4Address("10.1.1.2"), 
+      5000000, MilliSeconds(2));
   
-  SerialChannel* ch2 = AddDuplexLink (n1, Ipv4Address("10.1.2.1"), 
-      n2, Ipv4Address("10.1.2.2"), 5000000, MilliSeconds(2));
+  SerialChannel* ch2 = SerialTopology::AddSerialLink (
+      n1, Ipv4Address("10.1.2.1"), 
+      n2, Ipv4Address("10.1.2.2"), 
+      5000000, MilliSeconds(2));
 
-  SerialChannel* ch3 = AddDuplexLink (n2, Ipv4Address("10.1.3.1"), 
-      n3, Ipv4Address("10.1.3.2"), 1500000, MilliSeconds(10));
+  SerialChannel* ch3 = SerialTopology::AddSerialLink (
+      n2, Ipv4Address("10.1.3.1"), 
+      n3, Ipv4Address("10.1.3.2"), 
+      1500000, MilliSeconds(10));
   
   DatagramSocket *source0 = new DatagramSocket (n0);
   DatagramSocket *source3 = new DatagramSocket (n3);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/serial/serial-topology.cc	Mon Mar 19 00:40:44 2007 -0700
@@ -0,0 +1,170 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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<riley@ece.gatech.edu>
+//
+
+//
+// Topology helper for ns3.
+// George F. Riley, Georgia Tech, Spring 2007
+
+#include "ns3/debug.h"
+
+#include "ns3/nstime.h"
+
+#include "ns3/internet-node.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/drop-tail.h"
+#include "ns3/arp-ipv4-interface.h"
+#include "ns3/ipv4.h"
+
+#include "serial-channel.h"
+#include "serial-net-device.h"
+#include "serial-topology.h"
+
+#define nil 0
+
+namespace ns3 {
+
+SerialChannel *
+SerialTopology::AddSerialLink(
+  InternetNode* a,
+  const Ipv4Address& addra,
+  InternetNode* b,
+  const Ipv4Address& addrb,
+  uint64_t bps,
+  const Time& delay)
+{
+  SerialChannel* channel = new SerialChannel(bps, delay);
+
+  // Duplex link is assumed to be subnetted as a /30
+  // May run this unnumbered in the future?
+  Ipv4Mask netmask("255.255.255.252");
+  assert(netmask.IsMatch(addra,addrb));
+
+  DropTailQueue* dtqa = new DropTailQueue();
+
+  SerialNetDevice* neta = new SerialNetDevice(a);
+  neta->AddQueue(dtqa);
+  Ipv4Interface *interfA = new ArpIpv4Interface (a, neta);
+  uint32_t indexA = a->GetIpv4 ()->AddInterface (interfA);
+  neta->Attach (channel);
+
+  interfA->SetAddress (addra);
+  interfA->SetNetworkMask (netmask);
+  interfA->SetUp ();
+
+  DropTailQueue* dtqb = new DropTailQueue();
+
+  SerialNetDevice* netb = new SerialNetDevice(b);
+  netb->AddQueue(dtqb);
+  Ipv4Interface *interfB = new ArpIpv4Interface (b, netb);
+  uint32_t indexB = b->GetIpv4 ()->AddInterface (interfB);
+  netb->Attach (channel);
+
+  interfB->SetAddress (addrb);
+  interfB->SetNetworkMask (netmask);
+  interfB->SetUp ();
+
+  a->GetIpv4 ()->AddHostRouteTo (addrb, indexA);
+  b->GetIpv4 ()->AddHostRouteTo (addra, indexB);
+
+  return channel;
+}
+
+
+#if 0
+P2PChannel* Topology::AddDuplexLink(Node* n1, const IPAddr& ip1, 
+                                    Node* n2, const IPAddr& ip2,
+                                    const Rate& rate, const Time& delay)
+{
+  // First get the NetDeviceList capability from each node
+  NetDeviceList* ndl1 = n1->GetNetDeviceList();
+  NetDeviceList* ndl2 = n2->GetNetDeviceList();
+  if (!ndl1 || !ndl2) return nil;  // Both ends must have NetDeviceList
+  // Get the net devices
+  P2PNetDevice* nd1 = ndl1->Add(P2PNetDevice(n1, rate, nil));
+  P2PNetDevice* nd2 = ndl2->Add(P2PNetDevice(n1, rate, nd1->GetChannel()));
+  // Not implemented yet.  Add appropriate layer 2 protocol for
+  // the net devices.
+  // Get the L3 proto for node 1 and configure it with this device
+  L3Demux*    l3demux1 = n1->GetL3Demux();
+  L3Protocol* l3proto1 = nil;
+  // If the node 1 l3 demux exists, find the coresponding l3 protocol
+  if (l3demux1) l3proto1 = l3demux1->Lookup(ip1.L3Proto());
+  // If the l3 protocol exists, configure this net device.  Use a mask
+  // of all ones, since there is only one device on the remote end
+  // of this link
+  if (l3proto1) l3proto1->AddNetDevice(nd1, ip1, ip1.GetMask(ip1.Size()*8));
+  // Same for node 2
+  L3Demux*    l3demux2 = n2->GetL3Demux();
+  L3Protocol* l3proto2 = nil;
+  // If the node 2 l3 demux exists, find the coresponding l3 protocol
+  if (l3demux2) l3proto2 = l3demux2->Lookup(ip2.L3Proto());
+  if (l3proto2) l3proto2->AddNetDevice(nd2, ip2, ip2.GetMask(ip2.Size()*8));
+  return dynamic_cast<P2PChannel*>(nd1->GetChannel());  // Always succeeds
+}
+
+// Get the net device connecting node n1 to n2.  For topologies where
+// there are possibly multiple devices connecting n1 and n2 (for example
+// wireless with two devices on different channels) this will return
+// the first one found.
+NetDevice* Topology::GetNetDevice(Node* n1, Node* n2)
+{
+  // First get the NetDeviceList capability from node 1
+  NetDeviceList* ndl1 = n1->GetNetDeviceList();
+  if (!ndl1) return 0; // No devices, return nil
+  // Get the list of devices
+  const NetDeviceList::NetDevices_t& dlist = ndl1->GetAll();
+  for (NetDeviceList::NetDevices_t::const_iterator i = dlist.Begin();
+       i != dlist.End(); ++i)
+    { // Check each device
+      NetDevice* nd = *i; // next device
+      Channel* c = nd->GetChannel();
+      if (!c) continue; // No channel
+      if (c->NodeIsPeer(n2)) return nd; // found it
+    }
+  return 0; // None found
+}
+  
+// Get the channel connecting node n1 to node n2
+Channel* Topology::GetChannel(Node* n1, Node* n2)
+{
+  NetDevice* nd = GetNetDevice(n1, n2);
+  if (!nd) return 0; // No net device, so no channel
+  return nd->GetChannel();
+}
+
+Queue* Topology::GetQueue(Node* n1, Node* n2)
+{
+  NetDevice* nd = GetNetDevice(n1, n2);
+  if (!nd) return 0; // No net device, so in queue
+  return nd->GetQueue();
+}
+
+Queue* Topology::SetQueue(Node* n1, Node* n2, const Queue& q)
+{
+  NetDevice* nd = GetNetDevice(n1, n2);
+  if (!nd) return 0; // No net device, can't set queue
+  // Add the specified queue to the netdevice
+  return nd->SetQueue(q);
+}
+
+#endif
+
+} // namespace ns3
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/serial/serial-topology.h	Mon Mar 19 00:40:44 2007 -0700
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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<riley@ece.gatech.edu>
+//
+// Topology helper for ns3.
+// George F. Riley, Georgia Tech, Spring 2007
+
+#ifndef __TOPOLOGY_H__
+#define __TOPOLOGY_H__
+
+// The topology class consists of only static methods thar are used to
+// create the topology and data flows for an ns3 simulation
+
+namespace ns3 {
+
+class SerialChannel;
+class InternetNode;
+class IpvrAddress;
+//class SerialNetDevice;
+//class Queue;
+//class Rate;
+//class Time;
+  
+class SerialTopology {
+public:
+  // Manage point to point links
+
+  // Add a full-duplex point-to-point serial link between two nodes
+  // with the specified IP addresses,  with specified maximum transmission rate
+  // and propagation delay.
+  static SerialChannel* AddSerialLink(
+    InternetNode*, const Ipv4Address&, 
+    InternetNode*, const Ipv4Address&,
+    // const Rate&,
+    uint64_t,
+    const Time&);
+
+#if 0
+  // Get the connecting node n1 to node n2
+  static Channel* GetChannel(Node*, Node*);
+  // Get the NetDevice connecting node n1 to n2
+  static NetDevice* GetNetDevice(Node*, Node*);
+  /// Get the queue associated with a link between two nodes
+  static Queue* GetQueue(Node*, Node*);
+  // Set the queue associated with a link between two nodes
+  static Queue* SetQueue(Node*, Node*, const Queue&);
+#endif
+};
+
+} // namespace ns3
+
+#endif
+