From cd132b39ed41d2d3a4b8e75a87445c18515cc8bf Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Mon, 19 Mar 2007 00:40:44 -0700 Subject: [PATCH] Add SerialTopology functions and remove from simple.cc file --- SConstruct | 2 + samples/ns-2/simple.cc | 73 +++-------- src/devices/serial/serial-topology.cc | 170 ++++++++++++++++++++++++++ src/devices/serial/serial-topology.h | 68 +++++++++++ 4 files changed, 254 insertions(+), 59 deletions(-) create mode 100644 src/devices/serial/serial-topology.cc create mode 100644 src/devices/serial/serial-topology.h diff --git a/SConstruct b/SConstruct index 645198ea4..96d68f74a 100644 --- a/SConstruct +++ b/SConstruct @@ -270,6 +270,7 @@ serial.add_deps (['node']) 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_headers ([ serial.add_inst_headers ([ 'serial-net-device.h', 'serial-channel.h', + 'serial-topology.h', 'serial-phy.h', 'layer-connector.h', ]) diff --git a/samples/ns-2/simple.cc b/samples/ns-2/simple.cc index 5c212a33f..b413f2dd7 100644 --- a/samples/ns-2/simple.cc +++ b/samples/ns-2/simple.cc @@ -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 @@ PrintRoutingTable (InternetNode *a, std::string name) } #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 @@ int main (int argc, char *argv[]) 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); diff --git a/src/devices/serial/serial-topology.cc b/src/devices/serial/serial-topology.cc new file mode 100644 index 000000000..8e9d43e6f --- /dev/null +++ b/src/devices/serial/serial-topology.cc @@ -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 +// + +// +// 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(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 + diff --git a/src/devices/serial/serial-topology.h b/src/devices/serial/serial-topology.h new file mode 100644 index 000000000..8c381abd7 --- /dev/null +++ b/src/devices/serial/serial-topology.h @@ -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 +// +// 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 +