--- a/.hgtags Tue Aug 28 11:22:01 2007 +0200
+++ b/.hgtags Tue Aug 28 12:05:35 2007 +0200
@@ -3,3 +3,4 @@
0dc81e76166c56aaae64da48b673b62155943aad packet-history-working
38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3
5701e60bf01a8ac1308945e69001e0cc07948faf release ns-3.0.4
+08046b6aef37932507696a2f2f427b42d693781e release ns-3.0.5
--- a/AUTHORS Tue Aug 28 11:22:01 2007 +0200
+++ b/AUTHORS Tue Aug 28 12:05:35 2007 +0200
@@ -3,4 +3,5 @@
Craig Dowell (craigdo@ee.washington.edu)
Tom Henderson (tomhend@u.washington.edu)
Mathieu Lacage (mathieu.lacage@sophia.inria.fr)
+Emmanuelle Laprise (emmmanuelle.laprise@bluekazoo.ca)
George F. Riley (riley@ece.gatech.edu)
--- a/RELEASE_NOTES Tue Aug 28 11:22:01 2007 +0200
+++ b/RELEASE_NOTES Tue Aug 28 12:05:35 2007 +0200
@@ -3,12 +3,16 @@
This file contains ns-3 release notes (most recent releases first).
-Release 3.0.5 (2007/08/XX)
+Release 3.0.5 (2007/08/15)
========================
- - Add CSMA/CD model (Emmanuelle Laprise)
- - Modularize ipv4 routing support (Gustavo Carneiro)
- - Add mobility framework and basic mobility models
+ - Refactoring to support win32-based unix environments (Cygwin, mingw)
+ - "Packet socket" for allowing applications to access NetDevices directly
+ - Generalized, polymorphic Address class
+ - Add CSMA NetDevice model (from Emmanuelle Laprise)
+ - Modularize IPv4 routing support (from Gustavo Carneiro)
+ - Add mobility framework and basic mobility models
+ - Global unicast centralized routing
Release 3.0.4 (2007/07/15)
========================
--- a/SConstruct Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,521 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-import os.path
-import build
-
-version_file = open ('VERSION', 'r')
-version = version_file.readline ()
-version_file.close ()
-version = version.strip ()
-
-ns3 = build.Ns3()
-ns3.build_dir = 'build-dir'
-ns3.version = version
-ns3.name = 'ns3'
-ns3.distname = 'ns'
-ns3.doxygen_config = os.path.join('doc', 'doxygen.conf')
-ns3.add_extra_dist(os.path.join('doc', 'main.txt'))
-ns3.add_extra_dist ('doc/architecture.pdf')
-ns3.add_extra_dist ('doc/contributing.txt')
-ns3.add_extra_dist ('doc/build.txt')
-ns3.add_extra_dist ('doc/codingstd.txt')
-ns3.add_extra_dist ('doc/mercurial.txt')
-ns3.add_extra_dist ('README')
-ns3.add_extra_dist ('RELEASE_NOTES')
-ns3.add_extra_dist ('AUTHORS')
-ns3.add_extra_dist ('VERSION')
-
-ns3.add_extra_dist('doc/build-waf.txt')
-ns3.add_extra_dist('ns3/_placeholder_')
-for wscript in [
- "src/core/wscript",
- "src/node/wscript",
- "src/devices/p2p/wscript",
- "src/common/wscript",
- "src/applications/wscript",
- "src/simulator/wscript",
- "src/internet-node/wscript",
- "src/wscript",
- "utils/wscript",
- "samples/wscript",
- "examples/wscript",
- "wscript",
- ]:
- ns3.add_extra_dist(wscript)
-ns3.add_extra_dist('waf')
-ns3.add_extra_dist('waf.bat')
-
-#
-# The Core module
-#
-core = build.Ns3Module('core', 'src/core')
-ns3.add(core)
-core.add_sources([
- 'callback-test.cc',
- 'debug.cc',
- 'assert.cc',
- 'ptr.cc',
- 'object.cc',
- 'test.cc',
- 'random-variable.cc',
- 'rng-stream.cc',
- 'uid-manager.cc',
- 'default-value.cc',
- 'command-line.cc',
- 'type-name.cc',
- 'component-manager.cc',
- ])
-env = Environment()
-if env['PLATFORM'] == 'posix' or env['PLATFORM'] == 'darwin' or env['PLATFORM'] == 'cygwin':
- core.add_external_dep('pthread')
- core.add_sources([
- 'unix-system-wall-clock-ms.cc',
- ])
-elif env['PLATFORM'] == 'win32':
- core.add_sources([
- 'win32-system-wall-clock-ms.cc',
- ])
-core.add_headers ([
- 'uid-manager.h',
- 'singleton.h',
-])
-core.add_inst_headers([
- 'system-wall-clock-ms.h',
- 'empty.h',
- 'callback.h',
- 'ptr.h',
- 'object.h',
- 'debug.h',
- 'assert.h',
- 'fatal-error.h',
- 'test.h',
- 'random-variable.h',
- 'rng-stream.h',
- 'default-value.h',
- 'command-line.h',
- 'type-name.h',
- 'component-manager.h',
- ])
-
-def config_core (env, config):
- retval = []
- # XXX This check is primitive but it should be
- # good enough for now.
- if config.CheckCHeader ('stdlib.h') == 1:
- retval.append ('#define HAVE_STDLIB_H 1')
- retval.append ('#define HAVE_GETENV 1')
- else:
- retval.append ('#undef HAVE_STDLIB_H')
- retval.append ('#undef HAVE_GETENV')
- return retval
-core.add_config (config_core)
-
-#
-# The Simulator module
-#
-simu = build.Ns3Module('simulator', 'src/simulator')
-ns3.add(simu)
-simu.add_dep('core')
-simu.add_external_dep('m')
-simu.add_sources([
- 'high-precision.cc',
- 'time.cc',
- 'event-id.cc',
- 'scheduler.cc',
- 'scheduler-factory.cc',
- 'scheduler-list.cc',
- 'scheduler-heap.cc',
- 'scheduler-map.cc',
- 'event-impl.cc',
- 'simulator.cc',
- ])
-simu.add_headers([
- 'scheduler-heap.h',
- 'scheduler-map.h',
- 'scheduler-list.h'
- ])
-simu.add_inst_headers([
- 'high-precision.h',
- 'nstime.h',
- 'event-id.h',
- 'event-impl.h',
- 'simulator.h',
- 'scheduler.h',
- 'scheduler-factory.h',
- 'simulation-singleton.h',
- ])
-high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
-if high_precision_as_double == 'y':
- simu.add_inst_header ('high-precision-double.h')
- simu.add_source ('high-precision-double.cc')
-else:
- simu.add_inst_headers ([
- 'high-precision-128.h',
- 'cairo-wideint-private.h'
- ])
- simu.add_sources ([
- 'high-precision-128.cc',
- 'cairo-wideint.c',
- ])
-
-def config_simulator (env, config):
- retval = []
- high_precision_as_double = ARGUMENTS.get('high-precision-as-double', 'n')
- if high_precision_as_double == 'y':
- retval.append ('#define USE_HIGH_PRECISION_DOUBLE 1')
- else:
- retval.append ('#undef USE_HIGH_PRECISION_DOUBLE')
- if config.CheckCHeader ('stdint.h') == 1:
- retval.append ('#define HAVE_STDINT_H 1')
- elif config.CheckCHeader ('inttypes.h') == 1:
- retval.append ('#define HAVE_INTTYPES_H 1')
- elif config.CheckCHeader ('sys/inttypes.h') == 1:
- retval.append ('#define HAVE_SYS_INT_TYPES_H 1')
- return retval
-simu.add_config (config_simulator)
-
-#
-# The Common module
-#
-common = build.Ns3Module('common', 'src/common')
-common.add_deps(['core', 'simulator'])
-ns3.add(common)
-common.add_sources([
- 'buffer.cc',
- 'chunk.cc',
- 'header.cc',
- 'trailer.cc',
- 'packet-printer.cc',
- 'packet-metadata.cc',
- 'packet.cc',
- 'tags.cc',
- 'pcap-writer.cc',
- 'variable-tracer-test.cc',
- 'trace-context.cc',
- 'trace-resolver.cc',
- 'callback-trace-source.cc',
- 'empty-trace-resolver.cc',
- 'composite-trace-resolver.cc',
- 'trace-root.cc',
- 'data-rate.cc',
- ])
-common.add_headers ([
- ])
-common.add_inst_headers([
- 'buffer.h',
- 'chunk.h',
- 'header.h',
- 'trailer.h',
- 'tags.h',
- 'packet.h',
- 'packet-printer.h',
- 'packet-metadata.h',
- 'uv-trace-source.h',
- 'sv-trace-source.h',
- 'fv-trace-source.h',
- 'pcap-writer.h',
- 'callback-trace-source.h',
- 'trace-context.h',
- 'trace-resolver.h',
- 'empty-trace-resolver.h',
- 'composite-trace-resolver.h',
- 'array-trace-resolver.h',
- 'trace-root.h',
- 'terminal-trace-resolver.h',
- 'data-rate.h',
- ])
-
-#
-# The Node module
-#
-node = build.Ns3Module ('node', 'src/node')
-ns3.add (node)
-node.add_deps (['core', 'common', 'simulator'])
-node.add_sources ([
- 'node.cc',
- 'ipv4-address.cc',
- 'net-device.cc',
- 'mac-address.cc',
- 'llc-snap-header.cc',
- 'ipv4-route.cc',
- 'queue.cc',
- 'drop-tail-queue.cc',
- 'channel.cc',
- 'node-list.cc',
- 'socket.cc',
- 'socket-factory.cc',
- 'udp.cc',
- 'ipv4.cc',
- 'application.cc',
- ])
-node.add_inst_headers ([
- 'node.h',
- 'ipv4-address.h',
- 'net-device.h',
- 'mac-address.h',
- 'ipv4-route.h',
- 'queue.h',
- 'drop-tail-queue.h',
- 'llc-snap-header.h',
- 'channel.h',
- 'node-list.h',
- 'socket.h',
- 'socket-factory.h',
- 'udp.h',
- 'ipv4.h',
- 'application.h',
- ])
-
-#
-# The Applications module
-#
-applications = build.Ns3Module ('applications', 'src/applications')
-ns3.add (applications)
-applications.add_deps (['node'])
-applications.add_sources ([
- 'onoff-application.cc',
-])
-applications.add_inst_headers ([
- 'onoff-application.h',
-])
-
-#
-# The Internet Node module
-#
-inode = build.Ns3Module ('internet-node', 'src/internet-node')
-ns3.add (inode)
-inode.add_deps (['node', 'routing'])
-inode.add_sources ([
- 'internet-node.cc',
- 'l3-demux.cc',
- 'l3-protocol.cc',
- 'ipv4-l4-demux.cc',
- 'ipv4-l4-protocol.cc',
- 'ipv4-header.cc',
- 'udp-header.cc',
- 'ipv4-checksum.cc',
- 'ipv4-interface.cc',
- 'ipv4-l3-protocol.cc',
- 'ipv4-end-point.cc',
- 'udp-l4-protocol.cc',
- 'arp-header.cc',
- 'arp-cache.cc',
- 'arp-ipv4-interface.cc',
- 'arp-l3-protocol.cc',
- 'ipv4-loopback-interface.cc',
- 'header-utils.cc',
- 'udp-socket.cc',
- 'ipv4-end-point-demux.cc',
- 'arp-private.cc',
- 'ipv4-impl.cc',
- 'ipv4-private.cc',
- 'ascii-trace.cc',
- 'pcap-trace.cc',
- 'udp-impl.cc',
-])
-inode.add_headers ([
- 'ipv4-checksum.h',
- 'arp-header.h',
- 'arp-cache.h',
- 'arp-l3-protocol.h',
- 'ipv4-loopback-interface.h',
- 'l3-demux.h',
- 'header-utils.h',
- 'arp-ipv4-interface.h',
- 'udp-socket.h',
- 'udp-l4-protocol.h',
- 'arp-private.h',
- 'ipv4-impl.h',
- 'ipv4-private.h',
- 'ipv4-l3-protocol.h',
- 'l3-protocol.h',
- 'ipv4-l4-protocol.h',
- 'ipv4-l4-demux.h',
- 'ipv4-end-point-demux.h',
- 'ipv4-end-point.h',
- 'ipv4-header.h',
- 'ipv4-interface.h',
- 'udp-header.h',
- 'sgi-hashmap.h',
- 'udp-impl.h',
-])
-inode.add_inst_headers ([
- 'internet-node.h',
- 'ascii-trace.h',
- 'pcap-trace.h',
- 'ipv4-header.h',
- 'udp-header.h',
-])
-
-#
-# The Point-to-point module
-#
-p2p = build.Ns3Module ('p2p', 'src/devices/p2p')
-ns3.add (p2p)
-p2p.add_deps (['node'])
-p2p.add_sources ([
- 'p2p-net-device.cc',
- 'p2p-channel.cc',
- 'p2p-topology.cc',
- ])
-p2p.add_inst_headers ([
- 'p2p-net-device.h',
- 'p2p-channel.h',
- 'p2p-topology.h',
- ])
-
-#
-# The Routing module
-#
-routing = build.Ns3Module('routing', 'src/routing')
-routing.add_deps(['core', 'node'])
-ns3.add(routing)
-routing.add_sources([
- 'routing-environment.cc',
- 'static-router.cc',
- 'static-route-manager.cc',
- 'static-route-manager-impl.cc',
- 'candidate-queue.cc',
- ])
-routing.add_headers ([
- 'candidate-queue.h',
- 'static-route-manager-impl.h',
- ])
-routing.add_inst_headers([
- 'routing-environment.h',
- 'static-router.h',
- 'static-route-manager.h',
- ])
-
-# utils
-run_tests = build.Ns3Module('run-tests', 'utils')
-ns3.add(run_tests)
-run_tests.set_executable()
-run_tests.add_deps(['core', 'simulator', 'common', 'routing'])
-run_tests.add_source('run-tests.cc')
-
-bench_object = build.Ns3Module('bench-object', 'utils')
-ns3.add(bench_object)
-bench_object.set_executable()
-bench_object.add_deps(['core'])
-bench_object.add_source('bench-object.cc')
-
-bench_packets = build.Ns3Module('bench-packets', 'utils')
-ns3.add(bench_packets)
-bench_packets.set_executable()
-bench_packets.add_deps (['core', 'common'])
-bench_packets.add_source('bench-packets.cc')
-
-bench_simu = build.Ns3Module('bench-simulator', 'utils')
-ns3.add(bench_simu)
-bench_simu.set_executable()
-bench_simu.add_dep('simulator')
-bench_simu.add_source('bench-simulator.cc')
-
-replay_simu = build.Ns3Module('replay-simulation', 'utils')
-ns3.add(replay_simu)
-replay_simu.set_executable()
-replay_simu.add_dep('simulator')
-replay_simu.add_source('replay-simulation.cc')
-
-
-# samples
-sample_debug = build.Ns3Module('sample-debug', 'samples')
-sample_debug.set_executable()
-ns3.add(sample_debug)
-sample_debug.add_dep('core')
-sample_debug.add_source('main-debug.cc')
-sample_debug.add_source('main-debug-other.cc')
-
-sample_packet_printer = build.Ns3Module('sample-packet-printer', 'samples')
-sample_packet_printer.set_executable()
-ns3.add(sample_packet_printer)
-sample_packet_printer.add_deps (['common', 'internet-node'])
-sample_packet_printer.add_source('main-packet-printer.cc')
-
-sample_callback = build.Ns3Module('sample-callback', 'samples')
-sample_callback.set_executable()
-ns3.add(sample_callback)
-sample_callback.add_dep('core')
-sample_callback.add_source('main-callback.cc')
-
-sample_ptr = build.Ns3Module('sample-ptr', 'samples')
-sample_ptr.set_executable()
-ns3.add(sample_ptr)
-sample_ptr.add_dep('core')
-sample_ptr.add_source('main-ptr.cc')
-
-sample_trace = build.Ns3Module('sample-trace', 'samples')
-#ns3.add(sample_trace)
-sample_trace.add_dep('common')
-sample_trace.set_executable()
-sample_trace.add_source('main-trace.cc')
-
-sample_query_interface = build.Ns3Module('sample-query-interface', 'samples')
-ns3.add(sample_query_interface)
-sample_query_interface.add_dep('common')
-sample_query_interface.set_executable()
-sample_query_interface.add_source('main-query-interface.cc')
-
-sample_simu = build.Ns3Module('sample-simulator', 'samples')
-ns3.add(sample_simu)
-sample_simu.set_executable()
-sample_simu.add_dep('simulator')
-sample_simu.add_source('main-simulator.cc')
-
-sample_packet = build.Ns3Module('sample-packet', 'samples')
-ns3.add(sample_packet)
-sample_packet.set_executable()
-sample_packet.add_dep('common')
-sample_packet.add_source('main-packet.cc')
-
-sample_test = build.Ns3Module('sample-test', 'samples')
-sample_test.set_executable()
-ns3.add(sample_test)
-sample_test.add_dep('core')
-sample_test.add_source('main-test.cc')
-
-sample_simple = build.Ns3Module('sample-simple', 'samples')
-sample_simple.set_executable()
-ns3.add(sample_simple)
-sample_simple.add_deps(['core', 'simulator', 'node', 'internet-node', 'routing'])
-sample_simple.add_source('main-simple.cc')
-
-sample_sp2p = build.Ns3Module('sample-simple-p2p', 'samples')
-sample_sp2p.set_executable()
-#n3.add(sample_sp2p)
-sample_sp2p.add_deps(['core', 'simulator', 'node', 'internet-node', 'p2p'])
-sample_sp2p.add_source('main-simple-p2p.cc')
-
-sample_default_value = build.Ns3Module('sample-default-value', 'samples')
-sample_default_value.set_executable()
-ns3.add(sample_default_value)
-sample_default_value.add_deps(['core', 'simulator', 'node', 'p2p'])
-sample_default_value.add_source('main-default-value.cc')
-
-sample_object = build.Ns3Module('sample-object', 'samples')
-sample_object.set_executable()
-ns3.add(sample_object)
-sample_object.add_deps(['core'])
-sample_object.add_source('main-object.cc')
-
-sample_component_manager = build.Ns3Module('sample-component-manager', 'samples')
-sample_component_manager.set_executable()
-ns3.add(sample_component_manager)
-sample_component_manager.add_deps(['core'])
-sample_component_manager.add_source('main-component-manager.cc')
-
-# examples
-example_simple_p2p = build.Ns3Module('simple-p2p', 'examples')
-example_simple_p2p.set_executable()
-ns3.add(example_simple_p2p)
-example_simple_p2p.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing'])
-example_simple_p2p.add_source('simple-p2p.cc')
-
-example_static_routing = build.Ns3Module('simple-static-routing', 'examples')
-example_static_routing.set_executable()
-ns3.add(example_static_routing)
-example_static_routing.add_deps(['core', 'simulator', 'node', 'p2p', 'internet-node', 'applications', 'routing'])
-example_static_routing.add_source('simple-static-routing.cc')
-
-ns3.generate_dependencies()
--- a/VERSION Tue Aug 28 11:22:01 2007 +0200
+++ b/VERSION Tue Aug 28 12:05:35 2007 +0200
@@ -1,1 +1,1 @@
-3.0.4
+3.0.5
--- a/doc/release_steps.txt Tue Aug 28 11:22:01 2007 +0200
+++ b/doc/release_steps.txt Tue Aug 28 12:05:35 2007 +0200
@@ -5,23 +5,20 @@
- revise and check in RELEASE_NOTES
- update and check in VERSION to the latest release number
2. make a new "architecture.pdf" document and place it in the doc/ directory
-3. add current version of waf script from subversion:
- - svn checkout http://waf.googlecode.com/svn/tags/ns3/ waf
- - build waf script and put it into top of ns-3-dev
-4. cd ns-3-dev; ./waf configure; ./waf dist
-5. test tarball on release platforms (run-tests and simple-p2p)
-6. tag ns-3-dev with "release ns-3.0.X"
+3. cd ns-3-dev; ./waf configure; ./waf dist
+4. test tarball on release platforms (waf check and maybe some other scripts)
+5. tag ns-3-dev with "release ns-3.0.X"
- hg tag "release ns-3.0.x"
- hg push
-7. clone the tagged ns-3-dev and place it on the repository
+6. clone the tagged ns-3-dev and place it on the repository
- ssh code.nsnam.org; sudo; su code;
- cp -r /home/code/repos/ns-3-dev /home/code/repos/ns-3.0.x
- cd /home/code/repos/ns-3.0.x/.hg and edit the hgrc appropriately
-8. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server
-9. update web page
+7. upload "ns-3.0.x.tar.bz2" to the releases/ directory on the server
+8. update web page
- add link to news.html
- update download.html
- update roadmap.html
- build and update Doxygen directory on the server
- update and upload software architecture document (PDF, HTML)
-10. announce to ns-developers, with summary of release notes
+9. announce to ns-developers, with summary of release notes
--- a/examples/csma-cd-one-subnet.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/* -*- 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
- */
-
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
-// Network topology
-//
-// n0 n1 n2 n3
-// | | | |
-// =====================
-//
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-// (i.e., DataRate of 448,000 bps)
-// - DropTail queues
-// - Tracing of queues and packet receptions to file "csma-cd-one-subnet.tr"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/command-line.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/debug.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-cd-channel.h"
-#include "ns3/csma-cd-net-device.h"
-#include "ns3/csma-cd-topology.h"
-#include "ns3/csma-cd-ipv4-topology.h"
-#include "ns3/eui48-address.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/socket.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/onoff-application.h"
-
-
-using namespace ns3;
-
-
-int main (int argc, char *argv[])
-{
-
- // Users may find it convenient to turn on explicit debugging
- // for selected modules; the below lines suggest how to do this
-#if 0
- DebugComponentEnable("CsmaCdNetDevice");
- DebugComponentEnable("Ipv4L3Protocol");
- DebugComponentEnable("NetDevice");
- DebugComponentEnable("Channel");
- DebugComponentEnable("CsmaCdChannel");
- DebugComponentEnable("PacketSocket");
-#endif
-
- // Set up some default values for the simulation. Use the Bind()
- // technique to tell the system what subclass of Queue to use,
- // and what the queue limit is
-
- // The below Bind command tells the queue factory which class to
- // instantiate, when the queue factory is invoked in the topology code
- DefaultValue::Bind ("Queue", "DropTailQueue");
-
- // Allow the user to override any of the defaults and the above
- // Bind()s at run-time, via command-line arguments
- CommandLine::Parse (argc, argv);
-
- // Here, we will explicitly create four nodes. In more sophisticated
- // topologies, we could configure a node factory.
- Ptr<Node> n0 = Create<InternetNode> ();
- Ptr<Node> n1 = Create<InternetNode> ();
- Ptr<Node> n2 = Create<InternetNode> ();
- Ptr<Node> n3 = Create<InternetNode> ();
-
- // We create the channels first without any IP addressing information
- Ptr<CsmaCdChannel> channel0 =
- CsmaCdTopology::CreateCsmaCdChannel(
- DataRate(5000000), MilliSeconds(2));
-
- uint32_t n0ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0,
- Eui48Address("10:54:23:54:23:50"));
- uint32_t n1ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
- Eui48Address("10:54:23:54:23:51"));
- uint32_t n2ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
- Eui48Address("10:54:23:54:23:52"));
- uint32_t n3ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
- Eui48Address("10:54:23:54:23:53"));
-
- // Later, we add IP addresses.
- CsmaCdIpv4Topology::AddIpv4Address (
- n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
-
- CsmaCdIpv4Topology::AddIpv4Address (
- n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
-
- CsmaCdIpv4Topology::AddIpv4Address (
- n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
-
- CsmaCdIpv4Topology::AddIpv4Address (
- n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
-
- // Create the OnOff application to send UDP datagrams of size
- // 210 bytes at a rate of 448 Kb/s
- // from n0 to n1
- Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
- n0,
- InetSocketAddress ("10.1.1.2", 80),
- "Udp",
- ConstantVariable(1),
- ConstantVariable(0));
- // Start the application
- ooff->Start(Seconds(1.0));
- ooff->Stop (Seconds(10.0));
-
- // Create a similar flow from n3 to n0, starting at time 1.1 seconds
- ooff = Create<OnOffApplication> (
- n3,
- InetSocketAddress ("10.1.1.1", 80),
- "Udp",
- ConstantVariable(1),
- ConstantVariable(0));
- // Start the application
- ooff->Start(Seconds(1.1));
- ooff->Stop (Seconds(10.0));
-
- // Configure tracing of all enqueue, dequeue, and NetDevice receive events
- // Trace output will be sent to the csma-cd-one-subnet.tr file
- AsciiTrace asciitrace ("csma-cd-one-subnet.tr");
- asciitrace.TraceAllNetDeviceRx ();
- asciitrace.TraceAllQueues ();
-
- // Also configure some tcpdump traces; each interface will be traced
- // The output files will be named
- // simple-point-to-point.pcap-<nodeId>-<interfaceId>
- // and can be read by the "tcpdump -r" command (use "-tt" option to
- // display timestamps correctly)
- PcapTrace pcaptrace ("csma-cd-one-subnet.pcap");
- pcaptrace.TraceAllIp ();
-
- Simulator::Run ();
-
- Simulator::Destroy ();
-}
--- a/examples/csma-cd-packet-socket.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-/* -*- 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
- */
-
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
-// Network topology
-//
-// n0 n1 n2 n3
-// | | | |
-// =====================
-//
-// - CBR/UDP flows from n0 to n1, and from n3 to n0
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-// (i.e., DataRate of 448,000 bps)
-// - DropTail queues
-// - Tracing of queues and packet receptions to file "csma-cd-one-subnet.tr"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/command-line.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/debug.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-cd-channel.h"
-#include "ns3/csma-cd-net-device.h"
-#include "ns3/eui48-address.h"
-#include "ns3/packet-socket-address.h"
-#include "ns3/socket.h"
-#include "ns3/onoff-application.h"
-#include "ns3/queue.h"
-
-using namespace ns3;
-
-static Ptr<CsmaCdNetDevice>
-CreateCsmaCdDevice (Ptr<Node> node, Ptr<CsmaCdChannel> channel)
-{
- Ptr<CsmaCdNetDevice> device = Create<CsmaCdNetDevice> (node);
- device->Attach (channel);
- Ptr<Queue> queue = Queue::CreateDefault ();
- device->AddQueue (queue);
- return device;
-}
-
-
-int main (int argc, char *argv[])
-{
- CommandLine::Parse (argc, argv);
-
- // Here, we will explicitly create four nodes. In more sophisticated
- // topologies, we could configure a node factory.
- Ptr<Node> n0 = Create<Node> ();
- Ptr<Node> n1 = Create<Node> ();
- Ptr<Node> n2 = Create<Node> ();
- Ptr<Node> n3 = Create<Node> ();
-
- // create the shared medium used by all csma/cd devices.
- Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (DataRate(5000000), MilliSeconds(2));
-
- // use a helper function to connect our nodes to the shared channel.
- Ptr<NetDevice> n0If = CreateCsmaCdDevice (n0, channel);
- Ptr<NetDevice> n1If = CreateCsmaCdDevice (n1, channel);
- Ptr<NetDevice> n2If = CreateCsmaCdDevice (n2, channel);
- Ptr<NetDevice> n3If = CreateCsmaCdDevice (n3, channel);
-
-
- // create the address which identifies n1 from n0
- PacketSocketAddress n0ToN1;
- n0ToN1.SetSingleDevice (n0If->GetIfIndex ()); // set outgoing interface for outgoing packets
- n0ToN1.SetPhysicalAddress (n1If->GetAddress ()); // set destination address for outgoing packets
- n0ToN1.SetProtocol (2); // set arbitrary protocol for outgoing packets
-
- // create the address which identifies n0 from n3
- PacketSocketAddress n3ToN0;
- n3ToN0.SetSingleDevice (n3If->GetIfIndex ());
- n3ToN0.SetPhysicalAddress (n0If->GetAddress ());
- n3ToN0.SetProtocol (3);
-
- // Create the OnOff application to send raw datagrams of size
- // 210 bytes at a rate of 448 Kb/s
- // from n0 to n1
- Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
- n0,
- n0ToN1,
- "Packet",
- ConstantVariable(1),
- ConstantVariable(0));
- // Start the application
- ooff->Start(Seconds(1.0));
- ooff->Stop (Seconds(10.0));
-
- // Create a similar flow from n3 to n0, starting at time 1.1 seconds
- ooff = Create<OnOffApplication> (
- n3,
- n3ToN0,
- "Packet",
- ConstantVariable(1),
- ConstantVariable(0));
- // Start the application
- ooff->Start(Seconds(1.1));
- ooff->Stop (Seconds(10.0));
-
- // Configure tracing of all enqueue, dequeue, and NetDevice receive events
- // Trace output will be sent to the csma-cd-packet-socket.tr file
- AsciiTrace asciitrace ("csma-cd-packet-socket.tr");
- asciitrace.TraceAllNetDeviceRx ();
- asciitrace.TraceAllQueues ();
-
- Simulator::Run ();
-
- Simulator::Destroy ();
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-one-subnet.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,166 @@
+/* -*- 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
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+// n0 n1 n2 n3
+// | | | |
+// =====================
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+// (i.e., DataRate of 448,000 bps)
+// - DropTail queues
+// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/debug.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/csma-topology.h"
+#include "ns3/csma-ipv4-topology.h"
+#include "ns3/eui48-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/onoff-application.h"
+
+
+using namespace ns3;
+
+
+int main (int argc, char *argv[])
+{
+
+ // Users may find it convenient to turn on explicit debugging
+ // for selected modules; the below lines suggest how to do this
+#if 0
+ DebugComponentEnable("CsmaNetDevice");
+ DebugComponentEnable("Ipv4L3Protocol");
+ DebugComponentEnable("NetDevice");
+ DebugComponentEnable("Channel");
+ DebugComponentEnable("CsmaChannel");
+ DebugComponentEnable("PacketSocket");
+#endif
+
+ // Set up some default values for the simulation. Use the Bind()
+ // technique to tell the system what subclass of Queue to use,
+ // and what the queue limit is
+
+ // The below Bind command tells the queue factory which class to
+ // instantiate, when the queue factory is invoked in the topology code
+ DefaultValue::Bind ("Queue", "DropTailQueue");
+
+ // Allow the user to override any of the defaults and the above
+ // Bind()s at run-time, via command-line arguments
+ CommandLine::Parse (argc, argv);
+
+ // Here, we will explicitly create four nodes. In more sophisticated
+ // topologies, we could configure a node factory.
+ Ptr<Node> n0 = Create<InternetNode> ();
+ Ptr<Node> n1 = Create<InternetNode> ();
+ Ptr<Node> n2 = Create<InternetNode> ();
+ Ptr<Node> n3 = Create<InternetNode> ();
+
+ // We create the channels first without any IP addressing information
+ Ptr<CsmaChannel> channel0 =
+ CsmaTopology::CreateCsmaChannel(
+ DataRate(5000000), MilliSeconds(2));
+
+ uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0,
+ Eui48Address("10:54:23:54:23:50"));
+ uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
+ Eui48Address("10:54:23:54:23:51"));
+ uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0,
+ Eui48Address("10:54:23:54:23:52"));
+ uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0,
+ Eui48Address("10:54:23:54:23:53"));
+
+ // Later, we add IP addresses.
+ CsmaIpv4Topology::AddIpv4Address (
+ n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
+
+ // Create the OnOff application to send UDP datagrams of size
+ // 210 bytes at a rate of 448 Kb/s
+ // from n0 to n1
+ Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+ n0,
+ InetSocketAddress ("10.1.1.2", 80),
+ "Udp",
+ ConstantVariable(1),
+ ConstantVariable(0));
+ // Start the application
+ ooff->Start(Seconds(1.0));
+ ooff->Stop (Seconds(10.0));
+
+ // Create a similar flow from n3 to n0, starting at time 1.1 seconds
+ ooff = Create<OnOffApplication> (
+ n3,
+ InetSocketAddress ("10.1.1.1", 80),
+ "Udp",
+ ConstantVariable(1),
+ ConstantVariable(0));
+ // Start the application
+ ooff->Start(Seconds(1.1));
+ ooff->Stop (Seconds(10.0));
+
+ // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+ // Trace output will be sent to the csma-one-subnet.tr file
+ AsciiTrace asciitrace ("csma-one-subnet.tr");
+ asciitrace.TraceAllNetDeviceRx ();
+ asciitrace.TraceAllQueues ();
+
+ // Also configure some tcpdump traces; each interface will be traced
+ // The output files will be named
+ // simple-point-to-point.pcap-<nodeId>-<interfaceId>
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
+ PcapTrace pcaptrace ("csma-one-subnet.pcap");
+ pcaptrace.TraceAllIp ();
+
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-packet-socket.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,136 @@
+/* -*- 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
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+// n0 n1 n2 n3
+// | | | |
+// =====================
+//
+// - CBR/UDP flows from n0 to n1, and from n3 to n0
+// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
+// (i.e., DataRate of 448,000 bps)
+// - DropTail queues
+// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/debug.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/eui48-address.h"
+#include "ns3/packet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/onoff-application.h"
+#include "ns3/queue.h"
+
+using namespace ns3;
+
+static Ptr<CsmaNetDevice>
+CreateCsmaDevice (Ptr<Node> node, Ptr<CsmaChannel> channel)
+{
+ Ptr<CsmaNetDevice> device = Create<CsmaNetDevice> (node);
+ device->Attach (channel);
+ Ptr<Queue> queue = Queue::CreateDefault ();
+ device->AddQueue (queue);
+ return device;
+}
+
+
+int main (int argc, char *argv[])
+{
+ CommandLine::Parse (argc, argv);
+
+ // Here, we will explicitly create four nodes. In more sophisticated
+ // topologies, we could configure a node factory.
+ Ptr<Node> n0 = Create<Node> ();
+ Ptr<Node> n1 = Create<Node> ();
+ Ptr<Node> n2 = Create<Node> ();
+ Ptr<Node> n3 = Create<Node> ();
+
+ // create the shared medium used by all csma devices.
+ Ptr<CsmaChannel> channel = Create<CsmaChannel> (DataRate(5000000), MilliSeconds(2));
+
+ // use a helper function to connect our nodes to the shared channel.
+ Ptr<NetDevice> n0If = CreateCsmaDevice (n0, channel);
+ Ptr<NetDevice> n1If = CreateCsmaDevice (n1, channel);
+ Ptr<NetDevice> n2If = CreateCsmaDevice (n2, channel);
+ Ptr<NetDevice> n3If = CreateCsmaDevice (n3, channel);
+
+
+ // create the address which identifies n1 from n0
+ PacketSocketAddress n0ToN1;
+ n0ToN1.SetSingleDevice (n0If->GetIfIndex ()); // set outgoing interface for outgoing packets
+ n0ToN1.SetPhysicalAddress (n1If->GetAddress ()); // set destination address for outgoing packets
+ n0ToN1.SetProtocol (2); // set arbitrary protocol for outgoing packets
+
+ // create the address which identifies n0 from n3
+ PacketSocketAddress n3ToN0;
+ n3ToN0.SetSingleDevice (n3If->GetIfIndex ());
+ n3ToN0.SetPhysicalAddress (n0If->GetAddress ());
+ n3ToN0.SetProtocol (3);
+
+ // Create the OnOff application to send raw datagrams of size
+ // 210 bytes at a rate of 448 Kb/s
+ // from n0 to n1
+ Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+ n0,
+ n0ToN1,
+ "Packet",
+ ConstantVariable(1),
+ ConstantVariable(0));
+ // Start the application
+ ooff->Start(Seconds(1.0));
+ ooff->Stop (Seconds(10.0));
+
+ // Create a similar flow from n3 to n0, starting at time 1.1 seconds
+ ooff = Create<OnOffApplication> (
+ n3,
+ n3ToN0,
+ "Packet",
+ ConstantVariable(1),
+ ConstantVariable(0));
+ // Start the application
+ ooff->Start(Seconds(1.1));
+ ooff->Stop (Seconds(10.0));
+
+ // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+ // Trace output will be sent to the csma-packet-socket.tr file
+ AsciiTrace asciitrace ("csma-packet-socket.tr");
+ asciitrace.TraceAllNetDeviceRx ();
+ asciitrace.TraceAllQueues ();
+
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/mixed-global-routing.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,199 @@
+/* -*- 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
+ *
+ */
+
+// This script exercises global routing code in a mixed point-to-point
+// and csma/cd environment
+//
+// Network topology
+//
+// n0
+// \ p-p
+// \ (shared csma/cd)
+// n2 -------------------------n3
+// / | |
+// / p-p n4 n5 ---------- n6
+// n1 p-p
+//
+// - CBR/UDP flows from n0 to n6
+// - Tracing of queues and packet receptions to file "mixed-global-routing.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/debug.h"
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+
+#include "ns3/simulator.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+#include "ns3/ascii-trace.h"
+#include "ns3/pcap-trace.h"
+#include "ns3/internet-node.h"
+#include "ns3/point-to-point-channel.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/csma-channel.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/csma-topology.h"
+#include "ns3/csma-ipv4-topology.h"
+#include "ns3/eui48-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/point-to-point-topology.h"
+#include "ns3/onoff-application.h"
+#include "ns3/global-route-manager.h"
+
+using namespace ns3;
+
+int main (int argc, char *argv[])
+{
+
+ // Users may find it convenient to turn on explicit debugging
+ // for selected modules; the below lines suggest how to do this
+#if 0
+ DebugComponentEnable ("Object");
+ DebugComponentEnable ("Queue");
+ DebugComponentEnable ("DropTailQueue");
+ DebugComponentEnable ("Channel");
+ DebugComponentEnable ("PointToPointChannel");
+ DebugComponentEnable ("PointToPointNetDevice");
+ DebugComponentEnable ("GlobalRouter");
+ DebugComponentEnable ("GlobalRouteManager");
+#endif
+
+ // Set up some default values for the simulation. Use the Bind ()
+ // technique to tell the system what subclass of Queue to use,
+ // and what the queue limit is
+
+ // The below DefaultValue::Bind command tells the queue factory which
+ // class to instantiate, when the queue factory is invoked in the
+ // topology code
+ DefaultValue::Bind ("Queue", "DropTailQueue");
+
+ DefaultValue::Bind ("OnOffApplicationPacketSize", "210");
+ DefaultValue::Bind ("OnOffApplicationDataRate", "448kb/s");
+
+ //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);
+
+ // Allow the user to override any of the defaults and the above
+ // Bind ()s at run-time, via command-line arguments
+ CommandLine::Parse (argc, argv);
+
+ Ptr<Node> n0 = Create<InternetNode> ();
+ Ptr<Node> n1 = Create<InternetNode> ();
+ Ptr<Node> n2 = Create<InternetNode> ();
+ Ptr<Node> n3 = Create<InternetNode> ();
+ Ptr<Node> n4 = Create<InternetNode> ();
+ Ptr<Node> n5 = Create<InternetNode> ();
+ Ptr<Node> n6 = Create<InternetNode> ();
+
+ // We create the channels first without any IP addressing information
+ Ptr<PointToPointChannel> channel0 =
+ PointToPointTopology::AddPointToPointLink (
+ n0, n2, DataRate (5000000), MilliSeconds (2));
+
+ Ptr<PointToPointChannel> channel1 =
+ PointToPointTopology::AddPointToPointLink (
+ n1, n2, DataRate (5000000), MilliSeconds (2));
+
+ Ptr<PointToPointChannel> channel2 =
+ PointToPointTopology::AddPointToPointLink (
+ n5, n6, DataRate (1500000), MilliSeconds (10));
+
+ // We create the channels first without any IP addressing information
+ Ptr<CsmaChannel> channelc0 =
+ CsmaTopology::CreateCsmaChannel(
+ DataRate(5000000), MilliSeconds(2));
+
+ uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channelc0,
+ Eui48Address("10:54:23:54:23:50"));
+ uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channelc0,
+ Eui48Address("10:54:23:54:23:51"));
+ uint32_t n4ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n4, channelc0,
+ Eui48Address("10:54:23:54:23:52"));
+ uint32_t n5ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n5, channelc0,
+ Eui48Address("10:54:23:54:23:53"));
+
+ // Later, we add IP addresses.
+ PointToPointTopology::AddIpv4Addresses (
+ channel0, n0, Ipv4Address ("10.1.1.1"),
+ n2, Ipv4Address ("10.1.1.2"));
+
+ PointToPointTopology::AddIpv4Addresses (
+ channel1, n1, Ipv4Address ("10.1.2.1"),
+ n2, Ipv4Address ("10.1.2.2"));
+
+ PointToPointTopology::AddIpv4Addresses (
+ channel2, n5, Ipv4Address ("10.1.3.1"),
+ n6, Ipv4Address ("10.1.3.2"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n2, n2ifIndex, Ipv4Address("10.250.1.1"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n3, n3ifIndex, Ipv4Address("10.250.1.2"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n4, n4ifIndex, Ipv4Address("10.250.1.3"), Ipv4Mask("255.255.255.0"));
+
+ CsmaIpv4Topology::AddIpv4Address (
+ n5, n5ifIndex, Ipv4Address("10.250.1.4"), Ipv4Mask("255.255.255.0"));
+
+ // Create router nodes, initialize routing database and set up the routing
+ // tables in the nodes.
+ GlobalRouteManager::PopulateRoutingTables ();
+
+ // Create the OnOff application to send UDP datagrams of size
+ // 210 bytes at a rate of 448 Kb/s
+ Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+ n0,
+ InetSocketAddress ("10.1.3.2", 80),
+ "Udp",
+ ConstantVariable (1),
+ ConstantVariable (0),
+ DataRate("300bps"),
+ 50);
+ // Start the application
+ ooff->Start (Seconds (1.0));
+ ooff->Stop (Seconds (10.0));
+
+ // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+ // Trace output will be sent to the simple-global-routing.tr file
+ AsciiTrace asciitrace ("mixed-global-routing.tr");
+ asciitrace.TraceAllQueues ();
+ asciitrace.TraceAllNetDeviceRx ();
+
+ // Also configure some tcpdump traces; each interface will be traced
+ // The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
+ PcapTrace pcaptrace ("mixed-global-routing.pcap");
+ pcaptrace.TraceAllIp ();
+
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+}
--- a/examples/simple-p2p.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/* -*- 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
- *
- * ns-2 simple.tcl script (ported from ns-2)
- * Originally authored by Steve McCanne, 12/19/1996
- */
-
-// Port of ns-2/tcl/ex/simple.tcl to ns-3
-//
-// Network topology
-//
-// n0
-// \ 5 Mb/s, 2ms
-// \ 1.5Mb/s, 10ms
-// n2 -------------------------n3
-// /
-// / 5 Mb/s, 2ms
-// n1
-//
-// - all links are p2p links with indicated one-way BW/delay
-// - CBR/UDP flows from n0 to n3, and from n3 to n1
-// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec.
-// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
-// (i.e., DataRate of 448,000 bps)
-// - DropTail queues
-// - Tracing of queues and packet receptions to file "simple-p2p.tr"
-
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <cassert>
-
-#include "ns3/command-line.h"
-#include "ns3/default-value.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-
-#include "ns3/simulator.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-#include "ns3/ascii-trace.h"
-#include "ns3/pcap-trace.h"
-#include "ns3/internet-node.h"
-#include "ns3/p2p-channel.h"
-#include "ns3/p2p-net-device.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/inet-socket-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/socket.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/p2p-topology.h"
-#include "ns3/onoff-application.h"
-
-using namespace ns3;
-
-int main (int argc, char *argv[])
-{
-
- // Users may find it convenient to turn on explicit debugging
- // for selected modules; the below lines suggest how to do this
-#if 0
- DebugComponentEnable("Object");
- DebugComponentEnable("Queue");
- DebugComponentEnable("DropTailQueue");
- DebugComponentEnable("Channel");
- DebugComponentEnable("PointToPointChannel");
- DebugComponentEnable("PointToPointNetDevice");
-#endif
-
- // Set up some default values for the simulation. Use the Bind()
- // technique to tell the system what subclass of Queue to use,
- // and what the queue limit is
-
- // The below Bind command tells the queue factory which class to
- // instantiate, when the queue factory is invoked in the topology code
- Bind ("Queue", "DropTailQueue");
-
- Bind ("OnOffApplicationPacketSize", "210");
- Bind ("OnOffApplicationDataRate", "448kb/s");
-
- //Bind ("DropTailQueue::m_maxPackets", 30);
-
- // Allow the user to override any of the defaults and the above
- // Bind()s at run-time, via command-line arguments
- CommandLine::Parse (argc, argv);
-
- // Here, we will explicitly create four nodes. In more sophisticated
- // topologies, we could configure a node factory.
- Ptr<Node> n0 = Create<InternetNode> ();
- Ptr<Node> n1 = Create<InternetNode> ();
- Ptr<Node> n2 = Create<InternetNode> ();
- Ptr<Node> n3 = Create<InternetNode> ();
-
- // We create the channels first without any IP addressing information
- Ptr<PointToPointChannel> channel0 =
- PointToPointTopology::AddPointToPointLink (
- n0, n2, DataRate(5000000), MilliSeconds(2));
-
- Ptr<PointToPointChannel> channel1 =
- PointToPointTopology::AddPointToPointLink (
- n1, n2, DataRate(5000000), MilliSeconds(2));
-
- Ptr<PointToPointChannel> channel2 =
- PointToPointTopology::AddPointToPointLink (
- n2, n3, DataRate(1500000), MilliSeconds(10));
-
- // Later, we add IP addresses.
- PointToPointTopology::AddIpv4Addresses (
- channel0, n0, Ipv4Address("10.1.1.1"),
- n2, Ipv4Address("10.1.1.2"));
-
- PointToPointTopology::AddIpv4Addresses (
- channel1, n1, Ipv4Address("10.1.2.1"),
- n2, Ipv4Address("10.1.2.2"));
-
- PointToPointTopology::AddIpv4Addresses (
- channel2, n2, Ipv4Address("10.1.3.1"),
- n3, Ipv4Address("10.1.3.2"));
-
- // Finally, we add static routes. These three steps (Channel and
- // NetDevice creation, IP Address assignment, and routing) are
- // separated because there may be a need to postpone IP Address
- // assignment (emulation) or modify to use dynamic routing
- PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
- PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
- PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
-
-
- // Create the OnOff application to send UDP datagrams of size
- // 210 bytes at a rate of 448 Kb/s
- Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
- n0,
- InetSocketAddress("10.1.3.2", 80).ConvertTo (),
- "Udp",
- ConstantVariable(1),
- ConstantVariable(0));
- // Start the application
- ooff->Start(Seconds(1.0));
- ooff->Stop (Seconds(10.0));
-
- // Create a similar flow from n3 to n1, starting at time 1.1 seconds
- ooff = Create<OnOffApplication> (
- n3,
- InetSocketAddress("10.1.2.1", 80).ConvertTo (),
- "Udp",
- ConstantVariable(1),
- ConstantVariable(0));
- // Start the application
- ooff->Start(Seconds(1.1));
- ooff->Stop (Seconds(10.0));
-
- // Here, finish off packet routing configuration
- // This will likely set by some global StaticRouting object in the future
- Ptr<Ipv4> ipv4;
- ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
- ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
- ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
- ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1);
-
- // Configure tracing of all enqueue, dequeue, and NetDevice receive events
- // Trace output will be sent to the simple-p2p.tr file
- AsciiTrace asciitrace ("simple-p2p.tr");
- asciitrace.TraceAllQueues ();
- asciitrace.TraceAllNetDeviceRx ();
-
- // Also configure some tcpdump traces; each interface will be traced
- // The output files will be named simple-p2p.pcap-<nodeId>-<interfaceId>
- // and can be read by the "tcpdump -r" command (use "-tt" option to
- // display timestamps correctly)
- PcapTrace pcaptrace ("simple-p2p.pcap");
- pcaptrace.TraceAllIp ();
-
- Simulator::Run ();
-
- Simulator::Destroy ();
-}
--- a/examples/simple-point-to-point.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/examples/simple-point-to-point.cc Tue Aug 28 12:05:35 2007 +0200
@@ -72,6 +72,7 @@
// Users may find it convenient to turn on explicit debugging
// for selected modules; the below lines suggest how to do this
+ // remember to add #include "ns3/debug.h" before enabling these
#if 0
DebugComponentEnable("Object");
DebugComponentEnable("Queue");
--- a/examples/wscript Tue Aug 28 11:22:01 2007 +0200
+++ b/examples/wscript Tue Aug 28 12:05:35 2007 +0200
@@ -3,15 +3,21 @@
def build(bld):
obj = bld.create_ns3_program('simple-global-routing',
- ['point-to-point', 'internet-node', 'global-routing'])
+ ['point-to-point', 'internet-node', 'global-routing'])
obj.source = 'simple-global-routing.cc'
- obj = bld.create_ns3_program('simple-point-to-point', ['point-to-point', 'internet-node'])
+ obj = bld.create_ns3_program('simple-point-to-point',
+ ['point-to-point', 'internet-node'])
obj.source = 'simple-point-to-point.cc'
- obj = bld.create_ns3_program('csma-cd-one-subnet', ['csma-cd', 'internet-node'])
- obj.source = 'csma-cd-one-subnet.cc'
+ obj = bld.create_ns3_program('csma-one-subnet',
+ ['csma', 'internet-node'])
+ obj.source = 'csma-one-subnet.cc'
- obj = bld.create_ns3_program('csma-cd-packet-socket', ['csma-cd', 'internet-node'])
- obj.source = 'csma-cd-packet-socket.cc'
+ obj = bld.create_ns3_program('csma-packet-socket',
+ ['csma', 'internet-node'])
+ obj.source = 'csma-packet-socket.cc'
+ obj = bld.create_ns3_program( 'mixed-global-routing',
+ ['point-to-point', 'internet-node', 'global-routing' , 'csma-cd'])
+ obj.source = 'mixed-global-routing.cc'
--- a/samples/main-simple.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/samples/main-simple.cc Tue Aug 28 12:05:35 2007 +0200
@@ -6,6 +6,7 @@
#include "ns3/socket.h"
#include "ns3/inet-socket-address.h"
#include "ns3/nstime.h"
+#include "ns3/packet.h"
using namespace ns3;
@@ -13,7 +14,7 @@
GenerateTraffic (Ptr<Socket> socket, uint32_t size)
{
std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, tx bytes=" << size << std::endl;
- socket->Send (0, size);
+ socket->Send (Packet (size));
if (size > 0)
{
Simulator::Schedule (Seconds (0.5), &GenerateTraffic, socket, size - 50);
@@ -25,15 +26,15 @@
}
static void
-SocketPrinter (Ptr<Socket> socket, uint32_t size, const Address &from)
+SocketPrinter (Ptr<Socket> socket, const Packet &packet, const Address &from)
{
- std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << size << std::endl;
+ std::cout << "at=" << Simulator::Now ().GetSeconds () << "s, rx bytes=" << packet.GetSize () << std::endl;
}
static void
PrintTraffic (Ptr<Socket> socket)
{
- socket->RecvDummy (MakeCallback (&SocketPrinter));
+ socket->SetRecvCallback (MakeCallback (&SocketPrinter));
}
void
--- a/src/applications/onoff-application.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/applications/onoff-application.cc Tue Aug 28 12:05:35 2007 +0200
@@ -31,6 +31,7 @@
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
#include "ns3/default-value.h"
+#include "ns3/packet.h"
#include "onoff-application.h"
using namespace std;
@@ -205,7 +206,7 @@
void OnOffApplication::SendPacket()
{
NS_ASSERT (m_sendEvent.IsExpired ());
- m_socket->Send(0, m_pktSize);
+ m_socket->Send(Packet (m_pktSize));
m_totBytes += m_pktSize;
m_lastStartTime = Simulator::Now();
m_residualBits = 0;
--- a/src/applications/onoff-application.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/applications/onoff-application.h Tue Aug 28 12:05:35 2007 +0200
@@ -28,13 +28,13 @@
#include "ns3/application.h"
#include "ns3/event-id.h"
#include "ns3/ptr.h"
+#include "ns3/data-rate.h"
namespace ns3 {
class Address;
class RandomVariable;
class Socket;
-class DataRate;
/**
* \brief Generate traffic to a single destination according to an
--- a/src/common/packet-metadata-test.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/packet-metadata-test.cc Tue Aug 28 12:05:35 2007 +0200
@@ -230,6 +230,7 @@
: Test ("PacketMetadata")
{
m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this));
+ m_printer.SetSeparator ("");
}
PacketMetadataTest::~PacketMetadataTest ()
--- a/src/common/packet.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/packet.cc Tue Aug 28 12:05:35 2007 +0200
@@ -128,7 +128,7 @@
void
Packet::PrintTags (std::ostream &os) const
{
- m_tags.Print (os);
+ m_tags.Print (os, " ");
}
void
--- a/src/common/tags.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/tags.cc Tue Aug 28 12:05:35 2007 +0200
@@ -119,14 +119,14 @@
}
void
-Tags::Print (std::ostream &os) const
+Tags::Print (std::ostream &os, std::string separator) const
{
for (struct TagData *cur = m_next; cur != 0; cur = cur->m_next)
{
TagRegistry::Print (cur->m_id, cur->m_data, os);
if (cur->m_next != 0)
{
- os << " ";
+ os << separator;
}
}
}
@@ -347,7 +347,7 @@
ok = false;
}
g_a = false;
- tags.Print (std::cout);
+ tags.Print (std::cout, "");
if (!g_a)
{
ok = false;
@@ -363,7 +363,7 @@
}
g_b = false;
g_a = false;
- tags.Print (std::cout);
+ tags.Print (std::cout, "");
if (!g_a || !g_b)
{
ok = false;
@@ -372,14 +372,14 @@
Tags other = tags;
g_b = false;
g_a = false;
- other.Print (std::cout);
+ other.Print (std::cout, "");
if (!g_a || !g_b)
{
ok = false;
}
g_b = false;
g_a = false;
- tags.Print (std::cout);
+ tags.Print (std::cout, "");
if (!g_a || !g_b)
{
ok = false;
@@ -406,7 +406,7 @@
}
g_b = false;
g_a = false;
- other.Print (std::cout);
+ other.Print (std::cout, "");
if (g_a || !g_b)
{
ok = false;
@@ -452,7 +452,7 @@
tagZ.z = 0;
testLastTag.Add (tagZ);
g_z = false;
- testLastTag.Print (std::cout);
+ testLastTag.Print (std::cout, "");
if (!g_z)
{
ok = false;
--- a/src/common/tags.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/common/tags.h Tue Aug 28 12:05:35 2007 +0200
@@ -52,7 +52,7 @@
template <typename T>
bool Peek (T &tag) const;
- void Print (std::ostream &os) const;
+ void Print (std::ostream &os, std::string separator) const;
uint32_t GetSerializedSize (void) const;
void Serialize (Buffer::Iterator i, uint32_t size) const;
uint32_t Deserialize (Buffer::Iterator i);
--- a/src/devices/csma-cd/backoff.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007, Emmanuelle Laprise
- * All rights reserved.
- *
- * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include "backoff.h"
-
-namespace ns3 {
-
-Backoff::Backoff()
-{
- m_slotTime = MicroSeconds(1);
- m_minSlots = 1;
- m_maxSlots = 1000;
- m_ceiling = 10;
- m_maxRetries = 1000;
-
- ResetBackoffTime();
-}
-
-Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
- uint32_t ceiling, uint32_t maxRetries)
-{
- m_slotTime = slotTime;
- m_minSlots = minSlots;
- m_maxSlots = maxSlots;
- m_ceiling = ceiling;
- m_maxRetries = maxRetries;
-}
-
-Time
-Backoff::GetBackoffTime (void)
-{
- Time backoff;
- uint32_t ceiling;
-
- if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
- ceiling = m_ceiling;
- else
- ceiling = m_numBackoffRetries;
-
- uint32_t minSlot = m_minSlots;
- uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
- if (maxSlot > m_maxSlots)
- maxSlot = m_maxSlots;
-
- uint32_t backoffSlots =
- (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
-
- backoff = Scalar(backoffSlots) * m_slotTime;
- return (backoff);
-}
-
-void Backoff::ResetBackoffTime (void)
-{
- m_numBackoffRetries = 0;
-}
-
-bool Backoff::MaxRetriesReached(void) {
- return (m_numBackoffRetries >= m_maxRetries);
-}
-
-void Backoff::IncrNumRetries(void) {
- m_numBackoffRetries++;
-}
-
-} // namespace ns3
--- a/src/devices/csma-cd/backoff.h Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- *
- * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
- * Derived from the p2p net device file
-Transmi */
-
-#ifndef BACKOFF_H
-#define BACKOFF_H
-
-#include <stdint.h>
-#include "ns3/nstime.h"
-#include "ns3/random-variable.h"
-
-namespace ns3 {
-
- /**
- * \brief The backoff class is used for calculating backoff times
- * when many net devices can write to the same channel
- *
- */
-
-class Backoff {
-public:
- uint32_t m_minSlots; // Minimum number of backoff slots (when
- // multiplied by m_slotTime, determines minimum
- // backoff time)
- uint32_t m_maxSlots; // Maximim number of backoff slots (when
- // multiplied by m_slotTime, determines
- // maximum backoff time)
- uint32_t m_ceiling; // Caps the exponential function when the
- // number of retries reaches m_ceiling
- uint32_t m_maxRetries; // Maximum number of transmission retries
- // before the packet is dropped.
- Time m_slotTime; // Length of one slot. A slot time, it usually
- // the packet transmission time, if the packet
- // size is fixed.
-
- Backoff();
- Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
- uint32_t ceiling, uint32_t maxRetries);
-
- /**
- * \return The amount of time that the net device should wait before
- * trying to retransmit the packet
- */
- Time GetBackoffTime();
- /**
- * Indicates to the backoff object that the last packet was
- * successfully transmitted and that the number of retries should be
- * reset to 0.
- */
- void ResetBackoffTime();
- /**
- * \return True if the maximum number of retries has been reached
- */
- bool MaxRetriesReached();
- /**
- * Increments the number of retries by 1.
- */
- void IncrNumRetries();
-
-private:
- uint32_t m_numBackoffRetries; // Number of times that the
- // transmitter has tried to
- // unsuccessfully transmit the current
- // packet
-};
-
-}; // namespace ns3
-
-#endif // BACKOFF_H
-
--- a/src/devices/csma-cd/csma-cd-channel.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- * All rights reserved.
- *
- * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include "csma-cd-channel.h"
-#include "csma-cd-net-device.h"
-#include "ns3/packet.h"
-#include "ns3/simulator.h"
-#include "ns3/debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("CsmaCdChannel");
-
-namespace ns3 {
-
-CsmaCdDeviceRec::CsmaCdDeviceRec()
-{
- active = false;
-}
-
-CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr<CsmaCdNetDevice> device)
-{
- devicePtr = device;
- active = true;
-}
-
-bool
-CsmaCdDeviceRec::IsActive() {
- return active;
-}
-
-
-//
-// By default, you get a channel with the name "CsmaCd Channel" that
-// has an "infitely" fast transmission speed and zero delay.
-CsmaCdChannel::CsmaCdChannel()
-:
- Channel ("CsmaCd Channel"),
- m_bps (DataRate(0xffffffff)),
- m_delay (Seconds(0))
-{
- NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()");
- Init();
-}
-
-CsmaCdChannel::CsmaCdChannel(
- const DataRate& bps,
- const Time& delay)
-:
- Channel ("CsmaCd Channel"),
- m_bps (bps),
- m_delay (delay)
-{
- NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName()
- << ", " << bps.GetBitRate() << ", " << delay << ")");
- Init();
-}
-
-CsmaCdChannel::CsmaCdChannel(
- const std::string& name,
- const DataRate& bps,
- const Time& delay)
-:
- Channel (name),
- m_bps (bps),
- m_delay (delay)
-{
- NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " <<
- bps.GetBitRate() << ", " << delay << ")");
- Init();
-}
-
-void CsmaCdChannel::Init() {
- m_state = IDLE;
- m_deviceList.clear();
-}
-
-int32_t
-CsmaCdChannel::Attach(Ptr<CsmaCdNetDevice> device)
-{
- NS_DEBUG("CsmaCdChannel::Attach (" << device << ")");
- NS_ASSERT(device != 0);
-
- CsmaCdDeviceRec rec(device);
-
- m_deviceList.push_back(rec);
- return (m_deviceList.size() - 1);
-}
-
-bool
-CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
-{
- NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
- NS_ASSERT(device != 0);
-
- std::vector<CsmaCdDeviceRec>::iterator it;
- for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
- {
- if (it->devicePtr == device)
- {
- if (!it->active)
- {
- it->active = true;
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return false;
-}
-
-bool
-CsmaCdChannel::Reattach(uint32_t deviceId)
-{
- NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")");
- if (deviceId < m_deviceList.size())
- {
- return false;
- }
-
- if (m_deviceList[deviceId].active)
- {
- return false;
- }
- else
- {
- m_deviceList[deviceId].active = true;
- return true;
- }
-}
-
-bool
-CsmaCdChannel::Detach(uint32_t deviceId)
-{
- NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")");
-
- if (deviceId < m_deviceList.size())
- {
- if (!m_deviceList[deviceId].active)
- {
- NS_DEBUG("CsmaCdChannel::Detach Device is already detached ("
- << deviceId << ")");
- return false;
- }
-
- m_deviceList[deviceId].active = false;
- if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
- {
- NS_DEBUG("CsmaCdChannel::Detach Device is currently"
- << "transmitting (" << deviceId << ")");
- // Here we will need to place a warning in the packet
- }
-
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool
-CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
-{
- NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
- NS_ASSERT(device != 0);
-
- std::vector<CsmaCdDeviceRec>::iterator it;
- for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
- {
- if ((it->devicePtr == device) && (it->active))
- {
- it->active = false;
- return true;
- }
- }
- return false;
-}
-
-bool
-CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
-{
- NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId
- << ")");
- NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " <<
- p.GetUid () << ")");
-
- if (m_state != IDLE)
- {
- NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE");
- return false;
- }
-
- if (!IsActive(srcId))
- {
- NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected "
- << "source is not currently attached to network");
- return false;
- }
-
- NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING");
- m_currentPkt = p;
- m_currentSrc = srcId;
- m_state = TRANSMITTING;
- return true;
-}
-
-bool
-CsmaCdChannel::IsActive(uint32_t deviceId)
-{
- return (m_deviceList[deviceId].active);
-}
-
-bool
-CsmaCdChannel::TransmitEnd()
-{
- NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", "
- << m_currentSrc << ")");
- NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " <<
- m_currentPkt.GetUid () << ")");
-
- NS_ASSERT(m_state == TRANSMITTING);
- m_state = PROPAGATING;
-
- bool retVal = true;
-
- if (!IsActive(m_currentSrc)) {
- NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source "
- << "was detached before the end of the transmission");
- retVal = false;
- }
-
- NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " <<
- m_delay.GetSeconds () << "sec");
-
- Simulator::Schedule (m_delay,
- &CsmaCdChannel::PropagationCompleteEvent,
- this);
- return retVal;
-}
-
-void
-CsmaCdChannel::PropagationCompleteEvent()
-{
- NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent ("
- << &m_currentPkt << ")");
- NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " <<
- m_currentPkt.GetUid () << ")");
-
- NS_ASSERT(m_state == PROPAGATING);
-
- NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
-
- std::vector<CsmaCdDeviceRec>::iterator it;
- for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
- {
- if (it->IsActive())
- {
- it->devicePtr->Receive (m_currentPkt);
- }
- }
- m_state = IDLE;
-}
-
-
-uint32_t
-CsmaCdChannel::GetNumActDevices (void)
-{
- int numActDevices = 0;
- std::vector<CsmaCdDeviceRec>::iterator it;
- for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
- {
- if (it->active)
- {
- numActDevices++;
- }
- }
- return numActDevices;
-}
-
-// This is not the number of active devices. This is the total number
-// of devices even if some were detached after.
-uint32_t
-CsmaCdChannel::GetNDevices (void) const
-{
- return (m_deviceList.size());
-}
-
-Ptr<NetDevice>
-CsmaCdChannel::GetDevice (uint32_t i) const
-{
- Ptr< CsmaCdNetDevice > netDevice;
-
- netDevice = m_deviceList[i].devicePtr;
- return netDevice;
-}
-
-int32_t
-CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
-{
- std::vector<CsmaCdDeviceRec>::iterator it;
- int i = 0;
- for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
- {
- if (it->devicePtr == device)
- {
- if (it->active)
- {
- return i;
- }
- else
- {
- return -2;
- }
- }
- i++;
- }
- return -1;
-}
-
-bool
-CsmaCdChannel::IsBusy (void)
-{
- if (m_state == IDLE)
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
-DataRate
-CsmaCdChannel::GetDataRate (void)
-{
- return m_bps;
-}
-
-Time
-CsmaCdChannel::GetDelay (void)
-{
- return m_delay;
-}
-
-WireState
-CsmaCdChannel::GetState(void)
-{
- return m_state;
-}
-
-} // namespace ns3
--- a/src/devices/csma-cd/csma-cd-channel.h Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- *
- * 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: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
- */
-
-#ifndef CSMA_CD_CHANNEL_H
-#define CSMA_CD_CHANNEL_H
-
-#include "ns3/channel.h"
-#include "ns3/ptr.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-namespace ns3 {
-
-class CsmaCdNetDevice;
-
- /**
- * \brief CsmaCdNetDevice Record
- *
- * Stores the information related to each net device that is
- * connected to the channel.
- */
- class CsmaCdDeviceRec {
- public:
- Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device
- bool active; /// Is net device enabled to TX/RX
-
- CsmaCdDeviceRec();
- CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device);
- /*
- * \return If the net device pointed to by the devicePtr is active
- * and ready to RX/TX.
- */
- bool IsActive();
- };
-
- /**
- * Current state of the channel
- */
- enum WireState
- {
- IDLE, /**< Channel is IDLE, no packet is being
- transmitted */
- TRANSMITTING, /**< Channel is BUSY, a packet is being written
- by a net device */
- PROPAGATING /**< Channel is BUSY, packet is propagating to
- all attached net devices */
- };
-
-/**
- * \brief CsmaCd Channel.
- *
- * This class represents a simple Csma/Cd channel that can be used
- * when many nodes are connected to one wire. It uses a single busy
- * flag to indicate if the channel is currently in use. It does not
- * take into account the distances between stations or the speed of
- * light to determine collisions.
- *
- * Each net device must query the state of the channel and make sure
- * that it is IDLE before writing a packet to the channel.
- *
- * When the channel is instaniated, the constructor takes parameters
- * for a single speed, in bits per second, and a speed-of-light delay
- * time as a Time object. When a net device is attached to a channel,
- * it is assigned a device ID, this is in order to facilitate the
- * check that makes sure that a net device that is trying to send a
- * packet to the channel is really connected to this channel
- *
- */
-class CsmaCdChannel : public Channel {
-public:
- /**
- * \brief Create a CsmaCdChannel
- *
- * By default, you get a channel with the name "CsmaCd Channel" that
- * has an "infitely" fast transmission speed and zero delay.
- */
- CsmaCdChannel ();
-
- /**
- * \brief Create a CsmaCdChannel
- *
- * \param bps The bitrate of the channel
- * \param delay Transmission delay through the channel
- */
- CsmaCdChannel (const DataRate& bps, const Time& delay);
-
- /**
- * \brief Create a CsmaCdChannel
- *
- * \param name the name of the channel for identification purposes
- * \param bps The bitrate of the channel
- * \param delay Transmission delay through the channel
- */
- CsmaCdChannel (const std::string& name,
- const DataRate& bps, const Time& delay);
-
- /**
- * \brief Attach a given netdevice to this channel
- *
- * \param device Device pointer to the netdevice to attach to the channel
- * \return The assigned device number
- */
- int32_t Attach (Ptr<CsmaCdNetDevice> device);
- /**
- * \brief Detach a given netdevice from this channel
- *
- * The net device is marked as inactive and it is not allowed to
- * receive or transmit packets
- *
- * \param device Device pointer to the netdevice to detach from the channel
- * \return True if the device is found and attached to the channel,
- * false if the device is not currently connected to the channel or
- * can't be found.
- */
- bool Detach (Ptr<CsmaCdNetDevice> device);
- /**
- * \brief Detach a given netdevice from this channel
- *
- * The net device is marked as inactive and it is not allowed to
- * receive or transmit packets
- *
- * \param deviceId The deviceID assigned to the net device when it
- * was connected to the channel
- * \return True if the device is found and attached to the channel,
- * false if the device is not currently connected to the channel or
- * can't be found.
- */
- bool Detach (uint32_t deviceId);
- /**
- * \brief Reattach a previously detached net device to the channel
- *
- * The net device is marked as active. It is now allowed to receive
- * or transmit packets. The net device must have been previously
- * attached to the channel using the attach function.
- *
- * \param deviceId The device ID assigned to the net device when it
- * was connected to the channel
- * \return True if the device is found and is not attached to the
- * channel, false if the device is currently connected to the
- * channel or can't be found.
- */
- bool Reattach(uint32_t deviceId);
- /**
- * \brief Reattach a previously detached net device to the channel
- *
- * The net device is marked as active. It is now allowed to receive
- * or transmit packets. The net device must have been previously
- * attached to the channel using the attach function.
- *
- * \param device Device pointer to the netdevice to detach from the channel
- * \return True if the device is found and is not attached to the
- * channel, false if the device is currently connected to the
- * channel or can't be found.
- */
- bool Reattach(Ptr<CsmaCdNetDevice> device);
- /**
- * \brief Start transmitting a packet over the channel
- *
- * If the srcId belongs to a net device that is connected to the
- * channel, packet transmission begins, and the channel becomes busy
- * until the packet has completely reached all destinations.
- *
- * \param p A reference to the packet that will be transmitted over
- * the channel
- * \param srcId The device Id of the net device that wants to
- * transmit on the channel.
- * \return True if the channel is not busy and the transmitting net
- * device is currently active.
- */
- bool TransmitStart (Packet& p, uint32_t srcId);
- /**
- * \brief Indicates that the net device has finished transmitting
- * the packet over the channel
- *
- * The channel will stay busy until the packet has completely
- * propagated to all net devices attached to the channel. The
- * TransmitEnd function schedules the PropagationCompleteEvent which
- * will free the channel for further transmissions. Stores the
- * packet p as the m_currentPkt, the packet being currently
- * transmitting.
- *
- * \return Returns true unless the source was detached before it
- * completed its transmission.
- */
- bool TransmitEnd ();
- /**
- * \brief Indicates that the channel has finished propagating the
- * current packet. The channel is released and becomes free.
- *
- * Calls the receive function of every active net device that is
- * attached to the channel.
- */
- void PropagationCompleteEvent();
- /**
- * \return Returns the device number assigned to a net device by the
- * channel
- *
- * \param device Device pointer to the netdevice for which the device
- * number is needed
- */
- int32_t GetDeviceNum (Ptr<CsmaCdNetDevice> device);
- /**
- * \return Returns the state of the channel (IDLE -- free,
- * TRANSMITTING -- busy, PROPAGATING - busy )
- */
- WireState GetState();
-
- /**
- * \brief Indicates if the channel is busy. The channel will only
- * accept new packets for transmission if it is not busy.
- *
- * \return Returns true if the channel is busy and false if it is
- * free.
- */
- bool IsBusy();
-
- /**
- * \brief Indicates if a net device is currently attached or
- * detached from the channel.
- *
- * \param deviceId The ID that was assigned to the net device when
- * it was attached to the channel.
- * \return Returns true if the net device is attached to the
- * channel, false otherwise.
- */
- bool IsActive(uint32_t deviceId);
- /**
- * \return Returns the number of net devices that are currently
- * attached to the channel.
- */
- uint32_t GetNumActDevices (void);
- /**
- * \return Returns the total number of devices including devices
- * that have been detached from the channel.
- */
- virtual uint32_t GetNDevices (void) const;
- /**
- * \param i The deviceId of the net device for which we want the
- * pointer.
- * \return Returns the pointer to the net device that is associated
- * with deviceId i.
- */
- virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
- virtual DataRate GetDataRate (void);
- virtual Time GetDelay (void);
-
-private:
- DataRate m_bps; /// Data rate of the channel
- Time m_delay; /// Delay of the channel.
-
- /**
- * List of the net devices that have been or are currently connected
- * to the channel.
- *
- * Devices are nor removed from this list, they are marked as
- * inactive. Otherwise the assigned device IDs will not refer to the
- * correct NetDevice. The DeviceIds are used so that it is possible
- * to have a number to refer to an entry in the list so that the
- * whole list does not have to be searched when making sure that a
- * source is attached to a channel when it is transmitting data.
- */
- std::vector< CsmaCdDeviceRec > m_deviceList;
- /**
- * Packet that is currently being transmitted on the channel (or last
- * packet to have been transmitted on the channel if the channel is
- * free.)
- */
- Packet m_currentPkt;
- /**
- * Device Id of the source that is currently transmitting on the
- * channel. Or last source to have transmitted a packet on the
- * channel, if the channel is currently not busy.
- */
- uint32_t m_currentSrc;
- /**
- * Current state of the channel
- */
- WireState m_state;
- /**
- * Initializes the channel when it is constructed. Resets the
- * deviceList and sets the channel state to IDLE.
- */
- void Init (void);
-};
-
-} // namespace ns3
-
-#endif /* CSMA_CD_CHANNEL_H */
--- a/src/devices/csma-cd/csma-cd-ipv4-topology.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-
-#include <algorithm>
-#include "ns3/assert.h"
-#include "ns3/debug.h"
-#include "ns3/fatal-error.h"
-#include "ns3/nstime.h"
-#include "ns3/internet-node.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/queue.h"
-
-#include "csma-cd-channel.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-ipv4-topology.h"
-
-namespace ns3 {
-
-
-uint32_t
-CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- Eui48Address addr)
-{
- Ptr<Queue> q = Queue::CreateDefault ();
-
- // assume full-duplex
- Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
- ns3::CsmaCdNetDevice::IP_ARP,
- true, true);
- nd0->AddQueue(q);
- nd0->Attach (ch);
- return nd0->GetIfIndex ();
-}
-
-
-void
-CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- Eui48Address addr)
-{
- Ptr<Queue> q = Queue::CreateDefault ();
-
- Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
- ns3::CsmaCdNetDevice::LLC,
- true, false);
- nd0->AddQueue(q);
- nd0->Attach (ch);
-
- Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
- ns3::CsmaCdNetDevice::LLC,
- false, true);
- nd1->AddQueue(q);
- nd1->Attach (ch);
-}
-
-void
-CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- Eui48Address addr)
-{
- Ptr<Queue> q = Queue::CreateDefault ();
-
- Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
- ns3::CsmaCdNetDevice::RAW,
- true, false);
- nd0->AddQueue(q);
- nd0->Attach (ch);
-
- Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
- ns3::CsmaCdNetDevice::RAW,
- false, true);
- nd1->AddQueue(q);
- nd1->Attach (ch);
-}
-
-void
-CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
- int ndNum,
- const Ipv4Address& addr1,
- const Ipv4Mask& netmask1)
-{
-
- // Duplex link is assumed to be subnetted as a /30
- // May run this unnumbered in the future?
- Ipv4Mask netmask(netmask1);
-
- Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
-
- Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
- uint32_t index1 = ip1->AddInterface (nd1);
-
- ip1->SetAddress (index1, addr1);
- ip1->SetNetworkMask (index1, netmask);
- ip1->SetUp (index1);
-
-}
-
-void
-CsmaCdIpv4Topology::AddIpv4Routes (
- Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
-{
- // Assert that both are Ipv4 nodes
- Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
- Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
- NS_ASSERT(ip1 != 0 && ip2 != 0);
-
- // Get interface indexes for both nodes corresponding to the right channel
- uint32_t index1 = 0;
- bool found = false;
- for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
- {
- if (ip1 ->GetNetDevice (i) == nd1)
- {
- index1 = i;
- found = true;
- }
- }
- NS_ASSERT(found);
-
- uint32_t index2 = 0;
- found = false;
- for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
- {
- if (ip2 ->GetNetDevice (i) == nd2)
- {
- index2 = i;
- found = true;
- }
- }
- NS_ASSERT(found);
-
- ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
- ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
-}
-
-} // namespace ns3
-
--- a/src/devices/csma-cd/csma-cd-ipv4-topology.h Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-
-#ifndef __CSMA_CD_IPV4_TOPOLOGY_H__
-#define __CSMA_CD_IPV4_TOPOLOGY_H__
-
-#include "ns3/ptr.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/ipv4.h"
-#include "ns3/ipv4-route.h"
-#include "ns3/internet-node.h"
-#include "ns3/csma-cd-net-device.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 CsmaCdIpv4Channel;
-class Node;
-class IPAddr;
-class DataRate;
-class Queue;
-
-/**
- * \brief A helper class to create Topologies based on the
- * InternetNodes and CsmaCdChannels. Either the
- * SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used
- * when constructing these topologies.
- */
-class CsmaCdIpv4Topology {
-public:
-
- /**
- * \param n1 Node to be attached to the Csma/Cd channel
- * \param ch CsmaCdChannel to which node n1 should be attached
- * \param addr Mac address of the node
- *
- * Add a Csma/Cd node to a Csma/Cd channel. This function adds
- * a EthernetCsmaCdNetDevice to the nodes so that they can
- * connect to a CsmaCdChannel. This means that Ethernet headers
- * and trailers will be added to the packet before sending out on
- * the net device.
- *
- * \return ifIndex of the device
- */
- static uint32_t AddIpv4CsmaCdNode( Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- Eui48Address addr);
-
- /**
- * \param n1 Node to be attached to the Csma/Cd channel
- * \param ch CsmaCdChannel to which node n1 should be attached
- * \param addr Mac address of the node
- *
- * Add a Csma/Cd node to a Csma/Cd channel. This function adds
- * a RawCsmaCdNetDevice to the nodes so that they can connect
- * to a CsmaCdChannel.
- */
- static void AddIpv4RawCsmaCdNode( Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- Eui48Address addr);
-
- /**
- * \param n1 Node to be attached to the Csma/Cd channel
- * \param ch CsmaCdChannel to which node n1 should be attached
- * \param addr Mac address of the node
- *
- * Add a Csma/Cd node to a Csma/Cd channel. This function adds
- * a LlcCsmaCdNetDevice to the nodes so that they can connect
- * to a CsmaCdChannel.
- */
- static void AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- Eui48Address addr);
-
-
-
- /**
- * \param n1 Node
- * \param ndNum NetDevice number with which to associate address
- * \param addr1 Ipv4 Address for ndNum of n1
- * \param network network mask for ndNum of node n1
- *
- * Add an Ipv4Address to the Ipv4 interface associated with the
- * ndNum CsmaCdIpv4NetDevices on the provided
- * CsmaCdIpv4Channel
- */
- static void AddIpv4Address(Ptr<Node> n1, int ndNum,
- const Ipv4Address& addr1,
- const Ipv4Mask& netmask1);
-
- /**
- * \param nd1 Node
- * \param nd2 Node
- *
- * Add an IPV4 host route between the two specified net devices
- */
- static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
-};
-
-} // namespace ns3
-
-#endif
-
--- a/src/devices/csma-cd/csma-cd-net-device.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,576 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- * All rights reserved.
- *
- * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
- */
-
-#include <iostream>
-#include <cassert>
-#include "ns3/debug.h"
-#include "ns3/queue.h"
-#include "ns3/simulator.h"
-#include "ns3/composite-trace-resolver.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-channel.h"
-#include "ns3/ethernet-header.h"
-#include "ns3/ethernet-trailer.h"
-#include "ns3/llc-snap-header.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice");
-
-namespace ns3 {
-
-CsmaCdTraceType::CsmaCdTraceType (enum Type type)
- : m_type (type)
-{}
-CsmaCdTraceType::CsmaCdTraceType ()
- : m_type (RX)
-{}
-void
-CsmaCdTraceType::Print (std::ostream &os) const
-{
- switch (m_type) {
- case RX:
- os << "dev-rx";
- break;
- case DROP:
- os << "dev-drop";
- break;
- }
-}
-uint16_t
-CsmaCdTraceType::GetUid (void)
-{
- static uint16_t uid = AllocateUid<CsmaCdTraceType> ("CsmaCdTraceType");
- return uid;
-}
-std::string
-CsmaCdTraceType::GetName (void) const
-{
- return "CsmaCdTraceType";
-}
-
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node)
- : NetDevice (node, Eui48Address::Allocate ()),
- m_bps (DataRate (0xffffffff))
-{
- NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
- m_encapMode = IP_ARP;
- Init(true, true);
-}
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
- CsmaCdEncapsulationMode encapMode)
- : NetDevice(node, addr),
- m_bps (DataRate (0xffffffff))
-{
- NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
- m_encapMode = encapMode;
-
- Init(true, true);
-}
-
-CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
- CsmaCdEncapsulationMode encapMode,
- bool sendEnable, bool receiveEnable)
- : NetDevice(node, addr),
- m_bps (DataRate (0xffffffff))
-{
- NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
- m_encapMode = encapMode;
-
- Init(sendEnable, receiveEnable);
-}
-
-CsmaCdNetDevice::~CsmaCdNetDevice()
-{
- NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
- m_queue = 0;
-}
-
-void
-CsmaCdNetDevice::DoDispose ()
-{
- m_channel = 0;
- NetDevice::DoDispose ();
-}
-
-//
-// Assignment operator for CsmaCdNetDevice.
-//
-// This uses the non-obvious trick of taking the source net device passed by
-// value instead of by reference. This causes the copy constructor to be
-// invoked (where the real work is done -- see above). All we have to do
-// here is to return the newly constructed net device.
-//
-/*
-CsmaCdNetDevice&
-CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
-{
- NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
- return *this;
-}
-*/
-
-void
-CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
-{
- m_txMachineState = READY;
- m_tInterframeGap = Seconds(0);
- m_channel = 0;
- m_queue = 0;
-
- EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
- EnableMulticast();
- EnablePointToPoint();
-
- SetSendEnable (sendEnable);
- SetReceiveEnable (receiveEnable);
-}
-
-void
-CsmaCdNetDevice::SetSendEnable (bool sendEnable)
-{
- m_sendEnable = sendEnable;
-}
-
-void
-CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
-{
- m_receiveEnable = receiveEnable;
-}
-bool
-CsmaCdNetDevice::IsSendEnabled (void)
-{
- return (m_sendEnable);
-}
-
-bool
-CsmaCdNetDevice::IsReceiveEnabled (void)
-{
- return (m_receiveEnable);
-}
-
-void
-CsmaCdNetDevice::SetDataRate (DataRate bps)
-{
- m_bps = bps;
-}
-
-void
-CsmaCdNetDevice::SetInterframeGap (Time t)
-{
- m_tInterframeGap = t;
-}
-
-void
-CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
- uint32_t maxSlots, uint32_t ceiling,
- uint32_t maxRetries)
-{
- m_backoff.m_slotTime = slotTime;
- m_backoff.m_minSlots = minSlots;
- m_backoff.m_maxSlots = maxSlots;
- m_backoff.m_ceiling = ceiling;
- m_backoff.m_maxRetries = maxRetries;
-}
-void
-CsmaCdNetDevice::AddHeader (Packet& p, Eui48Address dest,
- uint16_t protocolNumber)
-{
- if (m_encapMode == RAW)
- {
- return;
- }
- EthernetHeader header (false);
- EthernetTrailer trailer;
- Eui48Address source = Eui48Address::ConvertFrom (GetAddress ());
- header.SetSource(source);
- header.SetDestination(dest);
-
- uint16_t lengthType = 0;
- switch (m_encapMode)
- {
- case ETHERNET_V1:
- lengthType = p.GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
- break;
- case IP_ARP:
- lengthType = protocolNumber;
- break;
- case LLC: {
- LlcSnapHeader llc;
- llc.SetType (protocolNumber);
- p.AddHeader (llc);
- } break;
- case RAW:
- NS_ASSERT (false);
- break;
- }
- header.SetLengthType (lengthType);
- p.AddHeader(header);
- trailer.CalcFcs(p);
- p.AddTrailer(trailer);
-}
-bool
-CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
-{
- if (m_encapMode == RAW)
- {
- return true;
- }
- EthernetHeader header (false);
- EthernetTrailer trailer;
-
- p.RemoveTrailer(trailer);
- trailer.CheckFcs(p);
- p.RemoveHeader(header);
-
- if ((header.GetDestination() != GetBroadcast ()) &&
- (header.GetDestination() != GetAddress ()))
- {
- return false;
- }
-
- switch (m_encapMode)
- {
- case ETHERNET_V1:
- case IP_ARP:
- param = header.GetLengthType();
- break;
- case LLC: {
- LlcSnapHeader llc;
- p.RemoveHeader (llc);
- param = llc.GetType ();
- } break;
- case RAW:
- NS_ASSERT (false);
- break;
- }
- return true;
-}
-
-bool
-CsmaCdNetDevice::DoNeedsArp (void) const
-{
- if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool
-CsmaCdNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber)
-{
- NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
- NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
-
- NS_ASSERT (IsLinkUp ());
-
- // Only transmit if send side of net device is enabled
- if (!IsSendEnabled())
- return false;
-
- Eui48Address destination = Eui48Address::ConvertFrom (dest);
- AddHeader(p, destination, protocolNumber);
-
- // Place the packet to be sent on the send queue
- if (m_queue->Enqueue(p) == false )
- {
- return false;
- }
- // If the device is idle, we need to start a transmission. Otherwise,
- // the transmission will be started when the current packet finished
- // transmission (see TransmitCompleteEvent)
- if (m_txMachineState == READY)
- {
- // Store the next packet to be transmitted
- if (m_queue->Dequeue (m_currentPkt))
- {
- TransmitStart();
- }
- }
- return true;
-}
-
-void
-CsmaCdNetDevice::TransmitStart ()
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is "
- << m_currentPkt.GetUid () << ")");
-//
-// This function is called to start the process of transmitting a packet.
-// We need to tell the channel that we've started wiggling the wire and
-// schedule an event that will be executed when it's time to tell the
-// channel that we're done wiggling the wire.
-//
- NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF),
- "Must be READY to transmit. Tx state is: "
- << m_txMachineState);
-
- // Only transmit if send side of net device is enabled
- if (!IsSendEnabled())
- return;
-
- if (m_channel->GetState() != IDLE)
- { // Channel busy, backoff and rechedule TransmitStart()
- m_txMachineState = BACKOFF;
- if (m_backoff.MaxRetriesReached())
- { // Too many retries reached, abort transmission of packet
- TransmitAbort();
- }
- else
- {
- m_backoff.IncrNumRetries();
- Time backoffTime = m_backoff.GetBackoffTime();
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): "
- << "Channel busy, backing off for "
- << backoffTime.GetSeconds () << "sec");
-
- Simulator::Schedule (backoffTime,
- &CsmaCdNetDevice::TransmitStart,
- this);
- }
- }
- else
- {
- // Channel is free, transmit packet
- m_txMachineState = BUSY;
- Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
- "Schedule TransmitCompleteEvent in " <<
- tEvent.GetSeconds () << "sec");
-
- Simulator::Schedule (tEvent,
- &CsmaCdNetDevice::TransmitCompleteEvent,
- this);
- if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
- {
- NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
- "Channel transmit start did not work at " <<
- tEvent.GetSeconds () << "sec");
- m_txMachineState = READY;
- }
- else
- {
- // Transmission success, reset backoff time parameters.
- m_backoff.ResetBackoffTime();
- }
- }
-}
-
-
-void
-CsmaCdNetDevice::TransmitAbort (void)
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
- m_currentPkt.GetUid () << ")");
-
- // Try to transmit a new packet
- bool found;
- found = m_queue->Dequeue (m_currentPkt);
- NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
- m_backoff.ResetBackoffTime();
- m_txMachineState = READY;
- TransmitStart ();
-}
-
-void
-CsmaCdNetDevice::TransmitCompleteEvent (void)
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
-//
-// This function is called to finish the process of transmitting a packet.
-// We need to tell the channel that we've stopped wiggling the wire and
-// schedule an event that will be executed when it's time to re-enable
-// the transmitter after the interframe gap.
-//
- NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
- // Channel should be transmitting
- NS_ASSERT(m_channel->GetState() == TRANSMITTING);
- m_txMachineState = GAP;
-
- NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
- m_currentPkt.GetUid () << ")");
- m_channel->TransmitEnd ();
-
- NS_DEBUG (
- "CsmaCdNetDevice::TransmitCompleteEvent (): " <<
- "Schedule TransmitReadyEvent in "
- << m_tInterframeGap.GetSeconds () << "sec");
-
- Simulator::Schedule (m_tInterframeGap,
- &CsmaCdNetDevice::TransmitReadyEvent,
- this);
-}
-
-void
-CsmaCdNetDevice::TransmitReadyEvent (void)
-{
- NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
-//
-// This function is called to enable the transmitter after the interframe
-// gap has passed. If there are pending transmissions, we use this opportunity
-// to start the next transmit.
-//
- NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
- m_txMachineState = READY;
-
- // Get the next packet from the queue for transmitting
- if (m_queue->IsEmpty())
- {
- return;
- }
- else
- {
- bool found;
- found = m_queue->Dequeue (m_currentPkt);
- NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
- TransmitStart ();
- }
-}
-
-Ptr<TraceResolver>
-CsmaCdNetDevice::GetTraceResolver (void)
-{
- Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
- resolver->AddChild ("queue", m_queue);
- resolver->AddSource ("rx",
- "receive MAC packet",
- m_rxTrace,
- CsmaCdTraceType (CsmaCdTraceType::RX));
- resolver->AddSource ("drop",
- "drop MAC packet",
- m_dropTrace,
- CsmaCdTraceType (CsmaCdTraceType::DROP));
- resolver->SetParent (NetDevice::GetTraceResolver ());
- return resolver;
-}
-
-bool
-CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
-{
- NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
-
- m_channel = ch;
-
- m_deviceId = m_channel->Attach(this);
- m_bps = m_channel->GetDataRate ();
- m_tInterframeGap = m_channel->GetDelay ();
-
- /*
- * For now, this device is up whenever a channel is attached to it.
- */
- NotifyLinkUp ();
- return true;
-}
-
-void
-CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
-{
- NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
-
- m_queue = q;
-}
-
-void
-CsmaCdNetDevice::Receive (const Packet& packet)
-{
- EthernetHeader header (false);
- EthernetTrailer trailer;
- Eui48Address broadcast;
- Eui48Address destination;
- Packet p = packet;
-
- NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
-
- // Only receive if send side of net device is enabled
- if (!IsReceiveEnabled())
- {
- m_dropTrace (p);
- return;
- }
-
- if (m_encapMode == RAW)
- {
- ForwardUp (packet, 0, GetBroadcast ());
- m_dropTrace (p);
- return;
- }
- p.RemoveTrailer(trailer);
- trailer.CheckFcs(p);
- p.RemoveHeader(header);
-
- broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
- destination = Eui48Address::ConvertFrom (GetAddress ());
- if ((header.GetDestination() != broadcast) &&
- (header.GetDestination() != destination))
- {
- // not for us.
- m_dropTrace (p);
- return;
- }
-//
-// protocol must be initialized to avoid a compiler warning in the RAW
-// case that breaks the optimized build.
-//
- uint16_t protocol = 0;
-
- switch (m_encapMode)
- {
- case ETHERNET_V1:
- case IP_ARP:
- protocol = header.GetLengthType();
- break;
- case LLC: {
- LlcSnapHeader llc;
- p.RemoveHeader (llc);
- protocol = llc.GetType ();
- } break;
- case RAW:
- NS_ASSERT (false);
- break;
- }
-
- m_rxTrace (p);
- ForwardUp (p, protocol, header.GetSource ());
- return;
-}
-
-Ptr<Queue>
-CsmaCdNetDevice::GetQueue(void) const
-{
- return m_queue;
-}
-
-Ptr<Channel>
-CsmaCdNetDevice::DoGetChannel(void) const
-{
- return m_channel;
-}
-
-} // namespace ns3
--- a/src/devices/csma-cd/csma-cd-net-device.h Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,419 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 Emmanuelle Laprise
- *
- * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
- * Derived from the p2p net device file
- */
-
-#ifndef CSMA_CD_NET_DEVICE_H
-#define CSMA_CD_NET_DEVICE_H
-
-#include <string.h>
-#include "ns3/node.h"
-#include "ns3/backoff.h"
-#include "ns3/address.h"
-#include "ns3/net-device.h"
-#include "ns3/callback.h"
-#include "ns3/packet.h"
-#include "ns3/callback-trace-source.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-#include "ns3/ptr.h"
-#include "ns3/random-variable.h"
-#include "ns3/eui48-address.h"
-
-namespace ns3 {
-
-class Queue;
-class CsmaCdChannel;
-
-class CsmaCdTraceType : public TraceContextElement
-{
-public:
- enum Type {
- RX,
- DROP
- };
- CsmaCdTraceType (enum Type type);
- CsmaCdTraceType ();
- void Print (std::ostream &os) const;
- static uint16_t GetUid (void);
- std::string GetName (void) const;
-private:
- enum Type m_type;
-};
-
-/**
- * \class CsmaCdNetDevice
- * \brief A Device for a CsmaCd Network Link.
- *
- * The Csma/Cd net device class is analogous to layer 1 and 2 of the
- * TCP stack. The NetDevice takes a raw packet of bytes and creates a
- * protocol specific packet from them. The Csma/Cd net device class
- * takes this packet and adds and processes the headers/trailers that
- * are associated with EthernetV1, EthernetV2, RAW or LLC
- * protocols. The EthernetV1 packet type adds and removes Ethernet
- * destination and source addresses. The LLC packet type adds and
- * removes LLC snap headers. The raw packet type does not add or
- * remove any headers. Each Csma/Cd net device will receive all
- * packets written to the Csma/Cd link. The ProcessHeader function can
- * be used to filter out the packets such that higher level layers
- * only receive packets that are addressed to their associated net
- * devices
- *
- */
-class CsmaCdNetDevice : public NetDevice {
-public:
-
- /**
- * Enumeration of the types of packets supported in the class.
- *
- */
-enum CsmaCdEncapsulationMode {
- ETHERNET_V1, /**< Version one ethernet packet, length field */
- IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */
- RAW, /**< Packet that contains no headers */
- LLC, /**< LLC packet encapsulation */
-};
-
- CsmaCdNetDevice (Ptr<Node> node);
- /**
- * Construct a CsmaCdNetDevice
- *
- * This is the constructor for the CsmaCdNetDevice. It takes as a
- * parameter the Node to which this device is connected. Ownership of the
- * Node pointer is not implied and the node must not be deleted.
- *
- * \param node the Node to which this device is connected.
- * \param addr The source MAC address of the net device.
- */
- CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr, CsmaCdEncapsulationMode pktType);
- CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
- CsmaCdEncapsulationMode pktType,
- bool sendEnable, bool receiveEnable);
- /**
- * Destroy a CsmaCdNetDevice
- *
- * This is the destructor for the CsmaCdNetDevice.
- */
- virtual ~CsmaCdNetDevice();
- /**
- * Set the Data Rate used for transmission of packets. The data rate is
- * set in the Attach () method from the corresponding field in the channel
- * to which the device is attached. It can be overridden using this method.
- *
- * @see Attach ()
- * \param bps the data rate at which this object operates
- */
- void SetDataRate (DataRate bps);
- /**
- * Set the inteframe gap used to separate packets. The interframe gap
- * defines the minimum space required between packets sent by this device.
- * It is usually set in the Attach () method based on the speed of light
- * delay of the channel to which the device is attached. It can be
- * overridden using this method if desired.
- *
- * @see Attach ()
- * \param t the interframe gap time
- */
- void SetInterframeGap (Time t);
- /**
- * Set the backoff parameters used to determine the wait to retry
- * transmitting a packet when the channel is busy.
- *
- * @see Attach ()
- * \param slotTime Length of a packet slot (or average packet time)
- * \param minSlots Minimum number of slots to wait
- * \param maxSlots Maximum number of slots to wait
- * \param maxRetries Maximum number of retries before packet is discard
- * \param ceiling Cap on the exponential function when calculating max slots
- */
- void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots,
- uint32_t maxRetries, uint32_t ceiling);
- /**
- * Attach the device to a channel.
- *
- * The function Attach is used to add a CsmaCdNetDevice to a
- * CsmaCdChannel.
- *
- * @see SetDataRate ()
- * @see SetInterframeGap ()
- * \param ch a pointer to the channel to which this object is being attached.
- */
- bool Attach (Ptr<CsmaCdChannel> ch);
- /**
- * Attach a queue to the CsmaCdNetDevice.
- *
- * The CsmaCdNetDevice "owns" a queue. This queue is created by the
- * CsmaCdTopology object and implements a queueing method such as
- * DropTail or RED. The CsmaCdNetDevice assumes ownership of this
- * queue and must delete it when the device is destroyed.
- *
- * @see CsmaCdTopology::AddCsmaCdLink ()
- * @see Queue
- * @see DropTailQueue
- * \param queue a pointer to the queue for which object is assuming
- * ownership.
- */
- void AddQueue (Ptr<Queue> queue);
- /**
- * Receive a packet from a connected CsmaCdChannel.
- *
- * The CsmaCdNetDevice receives packets from its connected channel
- * and forwards them up the protocol stack. This is the public method
- * used by the channel to indicate that the last bit of a packet has
- * arrived at the device.
- *
- * @see CsmaCdChannel
- * \param p a reference to the received packet
- */
- void Receive (const Packet& p);
-
- bool IsSendEnabled (void);
- bool IsReceiveEnabled (void);
-
- void SetSendEnable (bool);
- void SetReceiveEnable (bool);
-
-protected:
- virtual bool DoNeedsArp (void) const;
- virtual void DoDispose (void);
- /**
- * Create a Trace Resolver for events in the net device.
- * (NOT TESTED)
- * @see class TraceResolver
- */
- virtual Ptr<TraceResolver> GetTraceResolver (void);
-
- /**
- * Get a copy of the attached Queue.
- *
- * This method is provided for any derived class that may need to get
- * direct access to the underlying queue.
- *
- * \return a pointer to the queue.
- */
- Ptr<Queue> GetQueue (void) const;
- /**
- * Get a copy of the attached Channel
- *
- * This method is provided for any derived class that may need to get
- * direct access to the connected channel
- *
- * \return a pointer to the channel
- */
- virtual Ptr<Channel> DoGetChannel (void) const;
- /**
- * Adds the necessary headers and trailers to a packet of data in order to
- * respect the packet type
- *
- * \param p Packet to which header should be added
- * \param dest MAC destination address to which packet should be sent
- * \param protocolNumber In some protocols, identifies the type of
- * payload contained in this packet.
- */
- void AddHeader (Packet& p, Eui48Address dest,
- uint16_t protocolNumber);
- /**
- * Removes, from a packet of data, all headers and trailers that
- * relate to the packet type
- *
- * \param p Packet whose headers need to be processed
- * \param param An integer parameter that can be set by the function
- * to return information gathered in the header
- * \return Returns true if the packet should be forwarded up the
- * protocol stack.
- */
- bool ProcessHeader (Packet& p, uint16_t & param);
-
-private:
- // disable copy constructor and operator =
- CsmaCdNetDevice &operator = (const CsmaCdNetDevice &o);
- CsmaCdNetDevice (const CsmaCdNetDevice &o);
- /**
- * Initializes variablea when construction object.
- */
- void Init (bool sendEnable, bool receiveEnable);
- /**
- * Send a Packet on the Csma/Cd network
- *
- * This method does not use a destination address since all packets
- * are broadcast to all NetDevices attached to the channel. Packet
- * should contain all needed headers at this time.
- *
- * If the device is ready to transmit, the next packet is read off
- * of the queue and stored locally until it has been transmitted.
- *
- * \param p a reference to the packet to send
- * \param dest destination address
- * \param protocolNumber -- this parameter is not used here
- * \return true if success, false on failure
- */
- virtual bool SendTo (Packet& p, const Address& dest, uint16_t protocolNumber);
-
- /**
- * Start Sending a Packet Down the Wire.
- *
- * The TransmitStart method is the method that is used internally in
- * the CsmaCdNetDevice to begin the process of sending a packet
- * out on the channel. The corresponding method is called on the
- * channel to let it know that the physical device this class
- * represents has virually started sending signals, this causes the
- * channel to become busy. An event is scheduled for the time at
- * which the bits have been completely transmitted. If the channel
- * is busy, the method reschedules itself for a later time (within
- * the backoff period)
- *
- * @see CsmaCdChannel::TransmitStart ()
- * @see TransmitCompleteEvent ()
- */
- void TransmitStart ();
- /**
- * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
- *
- * The TransmitCompleteEvent method is used internally to finish the process
- * of sending a packet out on the channel. During execution of this method
- * the TransmitEnd method is called on the channel to let it know that the
- * physical device this class represents has virually finished sending
- * signals. The channel uses this event to begin its speed of light delay
- * timer after which it notifies the Net Device at the other end of the
- * link that the bits have arrived. During this method, the net device
- * also schedules the TransmitReadyEvent at which time the transmitter
- * becomes ready to send the next packet.
- *
- * @see CsmaCdChannel::TransmitEnd ()
- * @see TransmitReadyEvent ()
- */
- void TransmitCompleteEvent (void);
- /**
- * Cause the Transmitter to Become Ready to Send Another Packet.
- *
- * The TransmitReadyEvent method is used internally to re-enable the
- * transmit machine of the net device. It is scheduled after a suitable
- * interframe gap after the completion of the previous transmission.
- * The queue is checked at this time, and if there is a packet waiting on
- * the queue, the transmission process is begun.
- *
- * If a packet is in the queue, it is extracted for the queue as the
- * next packet to be transmitted by the net device.
- *
- * @see TransmitStart ()
- */
- void TransmitReadyEvent (void);
-
- /**
- * Aborts the transmission of the current packet
- *
- * If the net device has tried to transmit a packet for more times
- * than the maximum allowed number of retries (channel always busy)
- * then the packet is dropped.
- *
- */
- void TransmitAbort (void);
-
- /**
- * Device ID returned by the attached functions. It is used by the
- * mp-channel to identify each net device to make sure that only
- * active net devices are writing to the channel
- */
- uint32_t m_deviceId;
-
- /**
- * Enable net device to send packets. True by default
- */
- bool m_sendEnable;
- /**
- * Enable net device to receive packets. True by default
- */
- bool m_receiveEnable;
- /**
- * Enumeration of the states of the transmit machine of the net device.
- */
- enum TxMachineState
- {
- READY, /**< The transmitter is ready to begin transmission of a packet */
- BUSY, /**< The transmitter is busy transmitting a packet */
- GAP, /**< The transmitter is in the interframe gap time */
- BACKOFF /**< The transmitter is waiting for the channel to be free */
- };
- /**
- * The state of the Net Device transmit state machine.
- * @see TxMachineState
- */
- TxMachineState m_txMachineState;
-
- /**
- * The type of packet that should be created by the AddHeader
- * function and that should be processed by the ProcessHeader
- * function.
- */
- CsmaCdEncapsulationMode m_encapMode;
- /**
- * The data rate that the Net Device uses to simulate packet transmission
- * timing.
- * @see class DataRate
- */
- DataRate m_bps;
- /**
- * The interframe gap that the Net Device uses to throttle packet
- * transmission
- * @see class Time
- */
- Time m_tInterframeGap;
- /**
- * Holds the backoff parameters and is used to calculate the next
- * backoff time to use when the channel is busy and the net device
- * is ready to transmit
- */
- Backoff m_backoff;
- /**
- * Next packet that will be transmitted (if transmitter is not
- * currently transmitting) or packet that is currently being
- * transmitted.
- */
- Packet m_currentPkt;
- /**
- * The CsmaCdChannel to which this CsmaCdNetDevice has been
- * attached.
- * @see class CsmaCdChannel
- */
- Ptr<CsmaCdChannel> m_channel;
- /**
- * The Queue which this CsmaCdNetDevice uses as a packet source.
- * Management of this Queue has been delegated to the CsmaCdNetDevice
- * and it has the responsibility for deletion.
- * @see class Queue
- * @see class DropTailQueue
- */
- Ptr<Queue> m_queue;
- /**
- * NOT TESTED
- * The trace source for the packet reception events that the device can
- * fire.
- *
- * @see class CallBackTraceSource
- * @see class TraceResolver
- */
- CallbackTraceSource<Packet &> m_rxTrace;
- CallbackTraceSource<Packet &> m_dropTrace;
-
-};
-
-}; // namespace ns3
-
-#endif // CSMA_CD_NET_DEVICE_H
-
--- a/src/devices/csma-cd/csma-cd-topology.cc Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-
-//
-// Topology helper for CsmaCd channels in ns3.
-
-#include "ns3/assert.h"
-#include "ns3/debug.h"
-#include "ns3/queue.h"
-
-#include "csma-cd-channel.h"
-#include "csma-cd-net-device.h"
-#include "csma-cd-topology.h"
-#include "ns3/socket-factory.h"
-
-namespace ns3 {
-
-Ptr<CsmaCdChannel>
-CsmaCdTopology::CreateCsmaCdChannel(
- const DataRate& bps,
- const Time& delay)
-{
- Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
-
- return channel;
-}
-
-#if 0
-Ptr<CsmaCdNetDevice>
-CsmaCdTopology::AddCsmaCdEthernetNode(
- Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- MacAddress addr)
-{
- Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
- ns3::CsmaCdNetDevice::ETHERNET_V1);
-
- Ptr<Queue> q = Queue::CreateDefault ();
- nd1->AddQueue(q);
- nd1->Attach (ch);
-
- return nd1;
-}
-
-Ptr<PacketSocket>
-CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
- Ptr<CsmaCdNetDevice> ndSrc,
- Ptr<CsmaCdNetDevice> ndDest)
-{
- Ptr<PacketSocket> socket = Create<PacketSocket> ();
- socket->Bind(ndSrc);
- socket->Connect(ndDest->GetAddress());
- app->Connect(socket);
-
- return socket;
-}
-
-Ptr<PacketSocket>
-CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
- Ptr<CsmaCdNetDevice> ndSrc,
- MacAddress macAddr)
-{
- Ptr<PacketSocket> socket = Create<PacketSocket> ();
- socket->Bind(ndSrc);
- socket->Connect(macAddr);
- app->Connect(socket);
-
- return socket;
-}
-
-Ptr<Socket>
-CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
-{
- InterfaceId iid = InterfaceId::LookupByName (iid_name);
-
- Ptr<SocketFactory> socketFactory =
- n1->QueryInterface<SocketFactory> (iid);
-
- Ptr<Socket> socket = socketFactory->CreateSocket ();
-
- return socket;
-}
-#endif
-
-} // namespace ns3
-
--- a/src/devices/csma-cd/csma-cd-topology.h Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2007 Emmanuelle Laprise
-//
-// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
-//
-// Topology helper for multipoint channels in ns3.
-//
-#ifndef CSMA_CD_TOPOLOGY_H
-#define CSMA_CD_TOPOLOGY_H
-
-#include "ns3/ptr.h"
-#include "ns3/csma-cd-net-device.h"
-#include "ns3/node.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 CsmaCdChannel;
-class Node;
-class DataRate;
-class Queue;
-
-/**
- * \brief A helper class to create CsmaCd Topologies
- *
- * CsmaCd topologies are created based on the
- * ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel
- * objects. This class uses the EthernetNetDevice and
- * PacketSocket classes in order to create logical connections between
- * net devices. The PacketSocket class generates the data and the
- * EthernetNetDevice class creates ethernet packets from the
- * data, filling in source and destination addresses. The
- * EthernetNetDevice class filters received data packets
- * according to its destination Mac addresses.
- */
-class CsmaCdTopology {
-public:
- /**
- * \param dataRate Maximum transmission link rate
- * \param delay propagation delay between any two nodes
- * \return Pointer to the created CsmaCdChannel
- *
- * Create a CsmaCdChannel. All nodes connected to a multipoint
- * channels will receive all packets written to that channel
- */
- static Ptr<CsmaCdChannel> CreateCsmaCdChannel(
- const DataRate& dataRate, const Time& delay);
-
-#if 0
- /**
- * \param n1 Node to be attached to the multipoint channel
- * \param ch CsmaCdChannel to which node n1 should be attached
- * \param addr MacAddress that should be assigned to the
- * EthernetNetDevice that will be added to the node.
- *
- * Add a multipoint node to a multipoint channel
- */
- static Ptr<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1,
- Ptr<CsmaCdChannel> ch,
- MacAddress addr);
-
- /**
- * \param app Application that will be sending data to the agent
- * \param ndSrc Net Device that will be sending the packets onto the
- * network
- * \param ndDest Net Device to which ndSrc will be sending the packets
- * \return A pointer to the PacketSocket
- *
- * Creates an PacketSocket and configure it to send packets between
- * two net devices
- */
-static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
- Ptr<CsmaCdNetDevice> ndSrc,
- Ptr<CsmaCdNetDevice> ndDest);
-
- /**
- * \param app Application that will be sending data to the agent
- * \param ndSrc Net Device that will be sending the packets onto the
- * network
- * \param macAddr Mac destination address for the packets send by
- * the ndSrc net device \return a Pointer to the created
- * PacketSocket
- *
- * Creates an PacketSocket and configure it to send packets from a
- * net device to a destination MacAddress
- */
-static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
- Ptr<CsmaCdNetDevice> ndSrc,
- MacAddress macAddr);
-
- /**
- * \param n1 Node from which socketfactory should be tested.
- * \param iid_name Interface identifier ("Packet", in this case)
- *
- * This is a test function to make sure that a socket can be created
- * by using the socketfactory interface provided in the
- * netdevicenode.
- */
-static Ptr<Socket> CreatePacketSocket(Ptr<Node> n1,
- std::string iid_name);
-#endif
-
-};
-} // namespace ns3
-
-#endif
-
--- a/src/devices/csma-cd/wscript Tue Aug 28 11:22:01 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
- obj = bld.create_ns3_module('csma-cd', ['node'])
- obj.source = [
- 'backoff.cc',
- 'csma-cd-net-device.cc',
- 'csma-cd-channel.cc',
- 'csma-cd-topology.cc',
- 'csma-cd-ipv4-topology.cc',
- ]
- headers = bld.create_obj('ns3header')
- headers.source = [
- 'backoff.h',
- 'csma-cd-net-device.h',
- 'csma-cd-channel.h',
- 'csma-cd-topology.h',
- 'csma-cd-ipv4-topology.h',
- ]
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/backoff.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007, Emmanuelle Laprise
+ * All rights reserved.
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "backoff.h"
+
+namespace ns3 {
+
+Backoff::Backoff()
+{
+ m_slotTime = MicroSeconds(1);
+ m_minSlots = 1;
+ m_maxSlots = 1000;
+ m_ceiling = 10;
+ m_maxRetries = 1000;
+
+ ResetBackoffTime();
+}
+
+Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
+ uint32_t ceiling, uint32_t maxRetries)
+{
+ m_slotTime = slotTime;
+ m_minSlots = minSlots;
+ m_maxSlots = maxSlots;
+ m_ceiling = ceiling;
+ m_maxRetries = maxRetries;
+}
+
+Time
+Backoff::GetBackoffTime (void)
+{
+ Time backoff;
+ uint32_t ceiling;
+
+ if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling))
+ ceiling = m_ceiling;
+ else
+ ceiling = m_numBackoffRetries;
+
+ uint32_t minSlot = m_minSlots;
+ uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1;
+ if (maxSlot > m_maxSlots)
+ maxSlot = m_maxSlots;
+
+ uint32_t backoffSlots =
+ (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot);
+
+ backoff = Scalar(backoffSlots) * m_slotTime;
+ return (backoff);
+}
+
+void Backoff::ResetBackoffTime (void)
+{
+ m_numBackoffRetries = 0;
+}
+
+bool Backoff::MaxRetriesReached(void) {
+ return (m_numBackoffRetries >= m_maxRetries);
+}
+
+void Backoff::IncrNumRetries(void) {
+ m_numBackoffRetries++;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/backoff.h Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+Transmi */
+
+#ifndef BACKOFF_H
+#define BACKOFF_H
+
+#include <stdint.h>
+#include "ns3/nstime.h"
+#include "ns3/random-variable.h"
+
+namespace ns3 {
+
+ /**
+ * \brief The backoff class is used for calculating backoff times
+ * when many net devices can write to the same channel
+ *
+ */
+
+class Backoff {
+public:
+ uint32_t m_minSlots; // Minimum number of backoff slots (when
+ // multiplied by m_slotTime, determines minimum
+ // backoff time)
+ uint32_t m_maxSlots; // Maximim number of backoff slots (when
+ // multiplied by m_slotTime, determines
+ // maximum backoff time)
+ uint32_t m_ceiling; // Caps the exponential function when the
+ // number of retries reaches m_ceiling
+ uint32_t m_maxRetries; // Maximum number of transmission retries
+ // before the packet is dropped.
+ Time m_slotTime; // Length of one slot. A slot time, it usually
+ // the packet transmission time, if the packet
+ // size is fixed.
+
+ Backoff();
+ Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots,
+ uint32_t ceiling, uint32_t maxRetries);
+
+ /**
+ * \return The amount of time that the net device should wait before
+ * trying to retransmit the packet
+ */
+ Time GetBackoffTime();
+ /**
+ * Indicates to the backoff object that the last packet was
+ * successfully transmitted and that the number of retries should be
+ * reset to 0.
+ */
+ void ResetBackoffTime();
+ /**
+ * \return True if the maximum number of retries has been reached
+ */
+ bool MaxRetriesReached();
+ /**
+ * Increments the number of retries by 1.
+ */
+ void IncrNumRetries();
+
+private:
+ uint32_t m_numBackoffRetries; // Number of times that the
+ // transmitter has tried to
+ // unsuccessfully transmit the current
+ // packet
+};
+
+}; // namespace ns3
+
+#endif // BACKOFF_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-channel.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,371 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * All rights reserved.
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include "csma-channel.h"
+#include "csma-net-device.h"
+#include "ns3/packet.h"
+#include "ns3/simulator.h"
+#include "ns3/debug.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CsmaChannel");
+
+namespace ns3 {
+
+CsmaDeviceRec::CsmaDeviceRec()
+{
+ active = false;
+}
+
+CsmaDeviceRec::CsmaDeviceRec(Ptr<CsmaNetDevice> device)
+{
+ devicePtr = device;
+ active = true;
+}
+
+bool
+CsmaDeviceRec::IsActive() {
+ return active;
+}
+
+
+//
+// By default, you get a channel with the name "Csma Channel" that
+// has an "infitely" fast transmission speed and zero delay.
+CsmaChannel::CsmaChannel()
+:
+ Channel ("Csma Channel"),
+ m_bps (DataRate(0xffffffff)),
+ m_delay (Seconds(0))
+{
+ NS_DEBUG("CsmaChannel::CsmaChannel ()");
+ Init();
+}
+
+CsmaChannel::CsmaChannel(
+ const DataRate& bps,
+ const Time& delay)
+:
+ Channel ("Csma Channel"),
+ m_bps (bps),
+ m_delay (delay)
+{
+ NS_DEBUG("CsmaChannel::CsmaChannel (" << Channel::GetName()
+ << ", " << bps.GetBitRate() << ", " << delay << ")");
+ Init();
+}
+
+CsmaChannel::CsmaChannel(
+ const std::string& name,
+ const DataRate& bps,
+ const Time& delay)
+:
+ Channel (name),
+ m_bps (bps),
+ m_delay (delay)
+{
+ NS_DEBUG("CsmaChannel::CsmaChannel (" << name << ", " <<
+ bps.GetBitRate() << ", " << delay << ")");
+ Init();
+}
+
+void CsmaChannel::Init() {
+ m_state = IDLE;
+ m_deviceList.clear();
+}
+
+int32_t
+CsmaChannel::Attach(Ptr<CsmaNetDevice> device)
+{
+ NS_DEBUG("CsmaChannel::Attach (" << device << ")");
+ NS_ASSERT(device != 0);
+
+ CsmaDeviceRec rec(device);
+
+ m_deviceList.push_back(rec);
+ return (m_deviceList.size() - 1);
+}
+
+bool
+CsmaChannel::Reattach(Ptr<CsmaNetDevice> device)
+{
+ NS_DEBUG("CsmaChannel::Reattach (" << device << ")");
+ NS_ASSERT(device != 0);
+
+ std::vector<CsmaDeviceRec>::iterator it;
+ for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
+ {
+ if (it->devicePtr == device)
+ {
+ if (!it->active)
+ {
+ it->active = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+bool
+CsmaChannel::Reattach(uint32_t deviceId)
+{
+ NS_DEBUG("CsmaChannel::Reattach (" << deviceId << ")");
+ if (deviceId < m_deviceList.size())
+ {
+ return false;
+ }
+
+ if (m_deviceList[deviceId].active)
+ {
+ return false;
+ }
+ else
+ {
+ m_deviceList[deviceId].active = true;
+ return true;
+ }
+}
+
+bool
+CsmaChannel::Detach(uint32_t deviceId)
+{
+ NS_DEBUG("CsmaChannel::Detach (" << deviceId << ")");
+
+ if (deviceId < m_deviceList.size())
+ {
+ if (!m_deviceList[deviceId].active)
+ {
+ NS_DEBUG("CsmaChannel::Detach Device is already detached ("
+ << deviceId << ")");
+ return false;
+ }
+
+ m_deviceList[deviceId].active = false;
+ if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
+ {
+ NS_DEBUG("CsmaChannel::Detach Device is currently"
+ << "transmitting (" << deviceId << ")");
+ // Here we will need to place a warning in the packet
+ }
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+CsmaChannel::Detach(Ptr<CsmaNetDevice> device)
+{
+ NS_DEBUG("CsmaChannel::Detach (" << device << ")");
+ NS_ASSERT(device != 0);
+
+ std::vector<CsmaDeviceRec>::iterator it;
+ for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
+ {
+ if ((it->devicePtr == device) && (it->active))
+ {
+ it->active = false;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+CsmaChannel::TransmitStart(Packet& p, uint32_t srcId)
+{
+ NS_DEBUG ("CsmaChannel::TransmitStart (" << &p << ", " << srcId
+ << ")");
+ NS_DEBUG ("CsmaChannel::TransmitStart (): UID is " <<
+ p.GetUid () << ")");
+
+ if (m_state != IDLE)
+ {
+ NS_DEBUG("CsmaChannel::TransmitStart (): state is not IDLE");
+ return false;
+ }
+
+ if (!IsActive(srcId))
+ {
+ NS_DEBUG("CsmaChannel::TransmitStart (): ERROR: Seclected "
+ << "source is not currently attached to network");
+ return false;
+ }
+
+ NS_DEBUG("CsmaChannel::TransmitStart (): switch to TRANSMITTING");
+ m_currentPkt = p;
+ m_currentSrc = srcId;
+ m_state = TRANSMITTING;
+ return true;
+}
+
+bool
+CsmaChannel::IsActive(uint32_t deviceId)
+{
+ return (m_deviceList[deviceId].active);
+}
+
+bool
+CsmaChannel::TransmitEnd()
+{
+ NS_DEBUG("CsmaChannel::TransmitEnd (" << &m_currentPkt << ", "
+ << m_currentSrc << ")");
+ NS_DEBUG("CsmaChannel::TransmitEnd (): UID is " <<
+ m_currentPkt.GetUid () << ")");
+
+ NS_ASSERT(m_state == TRANSMITTING);
+ m_state = PROPAGATING;
+
+ bool retVal = true;
+
+ if (!IsActive(m_currentSrc)) {
+ NS_DEBUG("CsmaChannel::TransmitEnd (): ERROR: Seclected source "
+ << "was detached before the end of the transmission");
+ retVal = false;
+ }
+
+ NS_DEBUG ("CsmaChannel::TransmitEnd (): Schedule event in " <<
+ m_delay.GetSeconds () << "sec");
+
+ Simulator::Schedule (m_delay,
+ &CsmaChannel::PropagationCompleteEvent,
+ this);
+ return retVal;
+}
+
+void
+CsmaChannel::PropagationCompleteEvent()
+{
+ NS_DEBUG("CsmaChannel::PropagationCompleteEvent ("
+ << &m_currentPkt << ")");
+ NS_DEBUG ("CsmaChannel::PropagationCompleteEvent (): UID is " <<
+ m_currentPkt.GetUid () << ")");
+
+ NS_ASSERT(m_state == PROPAGATING);
+
+ NS_DEBUG ("CsmaChannel::PropagationCompleteEvent (): Receive");
+
+ std::vector<CsmaDeviceRec>::iterator it;
+ for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
+ {
+ if (it->IsActive())
+ {
+ it->devicePtr->Receive (m_currentPkt);
+ }
+ }
+ m_state = IDLE;
+}
+
+
+uint32_t
+CsmaChannel::GetNumActDevices (void)
+{
+ int numActDevices = 0;
+ std::vector<CsmaDeviceRec>::iterator it;
+ for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
+ {
+ if (it->active)
+ {
+ numActDevices++;
+ }
+ }
+ return numActDevices;
+}
+
+// This is not the number of active devices. This is the total number
+// of devices even if some were detached after.
+uint32_t
+CsmaChannel::GetNDevices (void) const
+{
+ return (m_deviceList.size());
+}
+
+Ptr<NetDevice>
+CsmaChannel::GetDevice (uint32_t i) const
+{
+ Ptr< CsmaNetDevice > netDevice;
+
+ netDevice = m_deviceList[i].devicePtr;
+ return netDevice;
+}
+
+int32_t
+CsmaChannel::GetDeviceNum (Ptr<CsmaNetDevice> device)
+{
+ std::vector<CsmaDeviceRec>::iterator it;
+ int i = 0;
+ for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
+ {
+ if (it->devicePtr == device)
+ {
+ if (it->active)
+ {
+ return i;
+ }
+ else
+ {
+ return -2;
+ }
+ }
+ i++;
+ }
+ return -1;
+}
+
+bool
+CsmaChannel::IsBusy (void)
+{
+ if (m_state == IDLE)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+DataRate
+CsmaChannel::GetDataRate (void)
+{
+ return m_bps;
+}
+
+Time
+CsmaChannel::GetDelay (void)
+{
+ return m_delay;
+}
+
+WireState
+CsmaChannel::GetState(void)
+{
+ return m_state;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-channel.h Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,307 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * 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: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#ifndef CSMA_CHANNEL_H
+#define CSMA_CHANNEL_H
+
+#include "ns3/channel.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+namespace ns3 {
+
+class CsmaNetDevice;
+
+ /**
+ * \brief CsmaNetDevice Record
+ *
+ * Stores the information related to each net device that is
+ * connected to the channel.
+ */
+ class CsmaDeviceRec {
+ public:
+ Ptr< CsmaNetDevice > devicePtr; /// Pointer to the net device
+ bool active; /// Is net device enabled to TX/RX
+
+ CsmaDeviceRec();
+ CsmaDeviceRec(Ptr< CsmaNetDevice > device);
+ /*
+ * \return If the net device pointed to by the devicePtr is active
+ * and ready to RX/TX.
+ */
+ bool IsActive();
+ };
+
+ /**
+ * Current state of the channel
+ */
+ enum WireState
+ {
+ IDLE, /**< Channel is IDLE, no packet is being
+ transmitted */
+ TRANSMITTING, /**< Channel is BUSY, a packet is being written
+ by a net device */
+ PROPAGATING /**< Channel is BUSY, packet is propagating to
+ all attached net devices */
+ };
+
+/**
+ * \brief Csma Channel.
+ *
+ * This class represents a simple Csma channel that can be used
+ * when many nodes are connected to one wire. It uses a single busy
+ * flag to indicate if the channel is currently in use. It does not
+ * take into account the distances between stations or the speed of
+ * light to determine collisions.
+ *
+ * Each net device must query the state of the channel and make sure
+ * that it is IDLE before writing a packet to the channel.
+ *
+ * When the channel is instaniated, the constructor takes parameters
+ * for a single speed, in bits per second, and a speed-of-light delay
+ * time as a Time object. When a net device is attached to a channel,
+ * it is assigned a device ID, this is in order to facilitate the
+ * check that makes sure that a net device that is trying to send a
+ * packet to the channel is really connected to this channel
+ *
+ */
+class CsmaChannel : public Channel {
+public:
+ /**
+ * \brief Create a CsmaChannel
+ *
+ * By default, you get a channel with the name "Csma Channel" that
+ * has an "infitely" fast transmission speed and zero delay.
+ */
+ CsmaChannel ();
+
+ /**
+ * \brief Create a CsmaChannel
+ *
+ * \param bps The bitrate of the channel
+ * \param delay Transmission delay through the channel
+ */
+ CsmaChannel (const DataRate& bps, const Time& delay);
+
+ /**
+ * \brief Create a CsmaChannel
+ *
+ * \param name the name of the channel for identification purposes
+ * \param bps The bitrate of the channel
+ * \param delay Transmission delay through the channel
+ */
+ CsmaChannel (const std::string& name,
+ const DataRate& bps, const Time& delay);
+
+ /**
+ * \brief Attach a given netdevice to this channel
+ *
+ * \param device Device pointer to the netdevice to attach to the channel
+ * \return The assigned device number
+ */
+ int32_t Attach (Ptr<CsmaNetDevice> device);
+ /**
+ * \brief Detach a given netdevice from this channel
+ *
+ * The net device is marked as inactive and it is not allowed to
+ * receive or transmit packets
+ *
+ * \param device Device pointer to the netdevice to detach from the channel
+ * \return True if the device is found and attached to the channel,
+ * false if the device is not currently connected to the channel or
+ * can't be found.
+ */
+ bool Detach (Ptr<CsmaNetDevice> device);
+ /**
+ * \brief Detach a given netdevice from this channel
+ *
+ * The net device is marked as inactive and it is not allowed to
+ * receive or transmit packets
+ *
+ * \param deviceId The deviceID assigned to the net device when it
+ * was connected to the channel
+ * \return True if the device is found and attached to the channel,
+ * false if the device is not currently connected to the channel or
+ * can't be found.
+ */
+ bool Detach (uint32_t deviceId);
+ /**
+ * \brief Reattach a previously detached net device to the channel
+ *
+ * The net device is marked as active. It is now allowed to receive
+ * or transmit packets. The net device must have been previously
+ * attached to the channel using the attach function.
+ *
+ * \param deviceId The device ID assigned to the net device when it
+ * was connected to the channel
+ * \return True if the device is found and is not attached to the
+ * channel, false if the device is currently connected to the
+ * channel or can't be found.
+ */
+ bool Reattach(uint32_t deviceId);
+ /**
+ * \brief Reattach a previously detached net device to the channel
+ *
+ * The net device is marked as active. It is now allowed to receive
+ * or transmit packets. The net device must have been previously
+ * attached to the channel using the attach function.
+ *
+ * \param device Device pointer to the netdevice to detach from the channel
+ * \return True if the device is found and is not attached to the
+ * channel, false if the device is currently connected to the
+ * channel or can't be found.
+ */
+ bool Reattach(Ptr<CsmaNetDevice> device);
+ /**
+ * \brief Start transmitting a packet over the channel
+ *
+ * If the srcId belongs to a net device that is connected to the
+ * channel, packet transmission begins, and the channel becomes busy
+ * until the packet has completely reached all destinations.
+ *
+ * \param p A reference to the packet that will be transmitted over
+ * the channel
+ * \param srcId The device Id of the net device that wants to
+ * transmit on the channel.
+ * \return True if the channel is not busy and the transmitting net
+ * device is currently active.
+ */
+ bool TransmitStart (Packet& p, uint32_t srcId);
+ /**
+ * \brief Indicates that the net device has finished transmitting
+ * the packet over the channel
+ *
+ * The channel will stay busy until the packet has completely
+ * propagated to all net devices attached to the channel. The
+ * TransmitEnd function schedules the PropagationCompleteEvent which
+ * will free the channel for further transmissions. Stores the
+ * packet p as the m_currentPkt, the packet being currently
+ * transmitting.
+ *
+ * \return Returns true unless the source was detached before it
+ * completed its transmission.
+ */
+ bool TransmitEnd ();
+ /**
+ * \brief Indicates that the channel has finished propagating the
+ * current packet. The channel is released and becomes free.
+ *
+ * Calls the receive function of every active net device that is
+ * attached to the channel.
+ */
+ void PropagationCompleteEvent();
+ /**
+ * \return Returns the device number assigned to a net device by the
+ * channel
+ *
+ * \param device Device pointer to the netdevice for which the device
+ * number is needed
+ */
+ int32_t GetDeviceNum (Ptr<CsmaNetDevice> device);
+ /**
+ * \return Returns the state of the channel (IDLE -- free,
+ * TRANSMITTING -- busy, PROPAGATING - busy )
+ */
+ WireState GetState();
+
+ /**
+ * \brief Indicates if the channel is busy. The channel will only
+ * accept new packets for transmission if it is not busy.
+ *
+ * \return Returns true if the channel is busy and false if it is
+ * free.
+ */
+ bool IsBusy();
+
+ /**
+ * \brief Indicates if a net device is currently attached or
+ * detached from the channel.
+ *
+ * \param deviceId The ID that was assigned to the net device when
+ * it was attached to the channel.
+ * \return Returns true if the net device is attached to the
+ * channel, false otherwise.
+ */
+ bool IsActive(uint32_t deviceId);
+ /**
+ * \return Returns the number of net devices that are currently
+ * attached to the channel.
+ */
+ uint32_t GetNumActDevices (void);
+ /**
+ * \return Returns the total number of devices including devices
+ * that have been detached from the channel.
+ */
+ virtual uint32_t GetNDevices (void) const;
+ /**
+ * \param i The deviceId of the net device for which we want the
+ * pointer.
+ * \return Returns the pointer to the net device that is associated
+ * with deviceId i.
+ */
+ virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+ virtual DataRate GetDataRate (void);
+ virtual Time GetDelay (void);
+
+private:
+ DataRate m_bps; /// Data rate of the channel
+ Time m_delay; /// Delay of the channel.
+
+ /**
+ * List of the net devices that have been or are currently connected
+ * to the channel.
+ *
+ * Devices are nor removed from this list, they are marked as
+ * inactive. Otherwise the assigned device IDs will not refer to the
+ * correct NetDevice. The DeviceIds are used so that it is possible
+ * to have a number to refer to an entry in the list so that the
+ * whole list does not have to be searched when making sure that a
+ * source is attached to a channel when it is transmitting data.
+ */
+ std::vector< CsmaDeviceRec > m_deviceList;
+ /**
+ * Packet that is currently being transmitted on the channel (or last
+ * packet to have been transmitted on the channel if the channel is
+ * free.)
+ */
+ Packet m_currentPkt;
+ /**
+ * Device Id of the source that is currently transmitting on the
+ * channel. Or last source to have transmitted a packet on the
+ * channel, if the channel is currently not busy.
+ */
+ uint32_t m_currentSrc;
+ /**
+ * Current state of the channel
+ */
+ WireState m_state;
+ /**
+ * Initializes the channel when it is constructed. Resets the
+ * deviceList and sets the channel state to IDLE.
+ */
+ void Init (void);
+};
+
+} // namespace ns3
+
+#endif /* CSMA_CHANNEL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-ipv4-topology.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#include <algorithm>
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/fatal-error.h"
+#include "ns3/nstime.h"
+#include "ns3/internet-node.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/queue.h"
+
+#include "csma-channel.h"
+#include "csma-net-device.h"
+#include "csma-ipv4-topology.h"
+
+namespace ns3 {
+
+uint32_t
+CsmaIpv4Topology::AddIpv4CsmaNode(Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ Eui48Address addr)
+{
+ Ptr<Queue> q = Queue::CreateDefault ();
+
+ // assume full-duplex
+ Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
+ ns3::CsmaNetDevice::IP_ARP,
+ true, true);
+ nd0->AddQueue(q);
+ nd0->Attach (ch);
+ return nd0->GetIfIndex ();
+}
+
+
+void
+CsmaIpv4Topology::AddIpv4LlcCsmaNode(Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ Eui48Address addr)
+{
+ Ptr<Queue> q = Queue::CreateDefault ();
+
+ Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
+ ns3::CsmaNetDevice::LLC,
+ true, false);
+ nd0->AddQueue(q);
+ nd0->Attach (ch);
+
+ Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
+ ns3::CsmaNetDevice::LLC,
+ false, true);
+ nd1->AddQueue(q);
+ nd1->Attach (ch);
+}
+
+void
+CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ Eui48Address addr)
+{
+ Ptr<Queue> q = Queue::CreateDefault ();
+
+ Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
+ ns3::CsmaNetDevice::RAW,
+ true, false);
+ nd0->AddQueue(q);
+ nd0->Attach (ch);
+
+ Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
+ ns3::CsmaNetDevice::RAW,
+ false, true);
+ nd1->AddQueue(q);
+ nd1->Attach (ch);
+}
+
+void
+CsmaIpv4Topology::AddIpv4Address(Ptr<Node> n1,
+ int ndNum,
+ const Ipv4Address& addr1,
+ const Ipv4Mask& netmask1)
+{
+
+ // Duplex link is assumed to be subnetted as a /30
+ // May run this unnumbered in the future?
+ Ipv4Mask netmask(netmask1);
+
+ Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
+
+ Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+ uint32_t index1 = ip1->AddInterface (nd1);
+
+ ip1->SetAddress (index1, addr1);
+ ip1->SetNetworkMask (index1, netmask);
+ ip1->SetUp (index1);
+
+}
+
+void
+CsmaIpv4Topology::AddIpv4Routes (
+ Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
+{
+ // Assert that both are Ipv4 nodes
+ Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+ Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT(ip1 != 0 && ip2 != 0);
+
+ // Get interface indexes for both nodes corresponding to the right channel
+ uint32_t index1 = 0;
+ bool found = false;
+ for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++)
+ {
+ if (ip1 ->GetNetDevice (i) == nd1)
+ {
+ index1 = i;
+ found = true;
+ }
+ }
+ NS_ASSERT(found);
+
+ uint32_t index2 = 0;
+ found = false;
+ for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++)
+ {
+ if (ip2 ->GetNetDevice (i) == nd2)
+ {
+ index2 = i;
+ found = true;
+ }
+ }
+ NS_ASSERT(found);
+
+ ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1);
+ ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2);
+}
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-ipv4-topology.h Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,122 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#ifndef __CSMA_IPV4_TOPOLOGY_H__
+#define __CSMA_IPV4_TOPOLOGY_H__
+
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/internet-node.h"
+#include "ns3/csma-net-device.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 CsmaIpv4Channel;
+class Node;
+class IPAddr;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Topologies based on the
+ * InternetNodes and CsmaChannels. Either the
+ * SimpleCsmaNetDevice or the LLCCsmaNetDevice can be used
+ * when constructing these topologies.
+ */
+class CsmaIpv4Topology {
+public:
+
+ /**
+ * \param n1 Node to be attached to the Csma channel
+ * \param ch CsmaChannel to which node n1 should be attached
+ * \param addr Mac address of the node
+ *
+ * Add a Csma node to a Csma channel. This function adds
+ * a EthernetCsmaNetDevice to the nodes so that they can
+ * connect to a CsmaChannel. This means that Ethernet headers
+ * and trailers will be added to the packet before sending out on
+ * the net device.
+ *
+ * \return ifIndex of the device
+ */
+ static uint32_t AddIpv4CsmaNode( Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ Eui48Address addr);
+
+ /**
+ * \param n1 Node to be attached to the Csma channel
+ * \param ch CsmaChannel to which node n1 should be attached
+ * \param addr Mac address of the node
+ *
+ * Add a Csma node to a Csma channel. This function adds
+ * a RawCsmaNetDevice to the nodes so that they can connect
+ * to a CsmaChannel.
+ */
+ static void AddIpv4RawCsmaNode( Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ Eui48Address addr);
+
+ /**
+ * \param n1 Node to be attached to the Csma channel
+ * \param ch CsmaChannel to which node n1 should be attached
+ * \param addr Mac address of the node
+ *
+ * Add a Csma node to a Csma channel. This function adds
+ * a LlcCsmaNetDevice to the nodes so that they can connect
+ * to a CsmaChannel.
+ */
+ static void AddIpv4LlcCsmaNode( Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ Eui48Address addr);
+
+
+
+ /**
+ * \param n1 Node
+ * \param ndNum NetDevice number with which to associate address
+ * \param addr1 Ipv4 Address for ndNum of n1
+ * \param netmask1 network mask for ndNum of node n1
+ *
+ * Add an Ipv4Address to the Ipv4 interface associated with the
+ * ndNum CsmaIpv4NetDevices on the provided
+ * CsmaIpv4Channel
+ */
+ static void AddIpv4Address(Ptr<Node> n1, int ndNum,
+ const Ipv4Address& addr1,
+ const Ipv4Mask& netmask1);
+
+ /**
+ * \param nd1 Node
+ * \param nd2 Node
+ *
+ * Add an IPV4 host route between the two specified net devices
+ */
+ static void AddIpv4Routes (Ptr<NetDevice> nd1, Ptr<NetDevice> nd2);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-net-device.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,580 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ * All rights reserved.
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include <iostream>
+#include <cassert>
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/composite-trace-resolver.h"
+#include "csma-net-device.h"
+#include "csma-channel.h"
+#include "ns3/ethernet-header.h"
+#include "ns3/ethernet-trailer.h"
+#include "ns3/llc-snap-header.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("CsmaNetDevice");
+
+namespace ns3 {
+
+CsmaTraceType::CsmaTraceType (enum Type type)
+ : m_type (type)
+{}
+CsmaTraceType::CsmaTraceType ()
+ : m_type (RX)
+{}
+void
+CsmaTraceType::Print (std::ostream &os) const
+{
+ switch (m_type) {
+ case RX:
+ os << "dev-rx";
+ break;
+ case DROP:
+ os << "dev-drop";
+ break;
+ }
+}
+uint16_t
+CsmaTraceType::GetUid (void)
+{
+ static uint16_t uid = AllocateUid<CsmaTraceType> ("CsmaTraceType");
+ return uid;
+}
+std::string
+CsmaTraceType::GetName (void) const
+{
+ return "CsmaTraceType";
+}
+
+
+CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
+ : NetDevice (node, Eui48Address::Allocate ()),
+ m_bps (DataRate (0xffffffff))
+{
+ NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
+ m_encapMode = IP_ARP;
+ Init(true, true);
+}
+
+CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
+ CsmaEncapsulationMode encapMode)
+ : NetDevice(node, addr),
+ m_bps (DataRate (0xffffffff))
+{
+ NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
+ m_encapMode = encapMode;
+
+ Init(true, true);
+}
+
+CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
+ CsmaEncapsulationMode encapMode,
+ bool sendEnable, bool receiveEnable)
+ : NetDevice(node, addr),
+ m_bps (DataRate (0xffffffff))
+{
+ NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
+ m_encapMode = encapMode;
+
+ Init(sendEnable, receiveEnable);
+}
+
+CsmaNetDevice::~CsmaNetDevice()
+{
+ NS_DEBUG ("CsmaNetDevice::~CsmaNetDevice ()");
+ m_queue = 0;
+}
+
+void
+CsmaNetDevice::DoDispose ()
+{
+ m_channel = 0;
+ NetDevice::DoDispose ();
+}
+
+//
+// Assignment operator for CsmaNetDevice.
+//
+// This uses the non-obvious trick of taking the source net device passed by
+// value instead of by reference. This causes the copy constructor to be
+// invoked (where the real work is done -- see above). All we have to do
+// here is to return the newly constructed net device.
+//
+/*
+CsmaNetDevice&
+CsmaNetDevice::operator= (const CsmaNetDevice nd)
+{
+ NS_DEBUG ("CsmaNetDevice::operator= (" << &nd << ")");
+ return *this;
+}
+*/
+
+void
+CsmaNetDevice::Init(bool sendEnable, bool receiveEnable)
+{
+ m_txMachineState = READY;
+ m_tInterframeGap = Seconds(0);
+ m_channel = 0;
+ m_queue = 0;
+
+ EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
+ EnableMulticast();
+
+ SetSendEnable (sendEnable);
+ SetReceiveEnable (receiveEnable);
+}
+
+void
+CsmaNetDevice::SetSendEnable (bool sendEnable)
+{
+ m_sendEnable = sendEnable;
+}
+
+void
+CsmaNetDevice::SetReceiveEnable (bool receiveEnable)
+{
+ m_receiveEnable = receiveEnable;
+}
+bool
+CsmaNetDevice::IsSendEnabled (void)
+{
+ return (m_sendEnable);
+}
+
+bool
+CsmaNetDevice::IsReceiveEnabled (void)
+{
+ return (m_receiveEnable);
+}
+
+void
+CsmaNetDevice::SetDataRate (DataRate bps)
+{
+ m_bps = bps;
+}
+
+void
+CsmaNetDevice::SetInterframeGap (Time t)
+{
+ m_tInterframeGap = t;
+}
+
+void
+CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
+ uint32_t maxSlots, uint32_t ceiling,
+ uint32_t maxRetries)
+{
+ m_backoff.m_slotTime = slotTime;
+ m_backoff.m_minSlots = minSlots;
+ m_backoff.m_maxSlots = maxSlots;
+ m_backoff.m_ceiling = ceiling;
+ m_backoff.m_maxRetries = maxRetries;
+}
+void
+CsmaNetDevice::AddHeader (Packet& p, Eui48Address dest,
+ uint16_t protocolNumber)
+{
+ if (m_encapMode == RAW)
+ {
+ return;
+ }
+ EthernetHeader header (false);
+ EthernetTrailer trailer;
+ Eui48Address source = Eui48Address::ConvertFrom (GetAddress ());
+ header.SetSource(source);
+ header.SetDestination(dest);
+
+ uint16_t lengthType = 0;
+ switch (m_encapMode)
+ {
+ case ETHERNET_V1:
+ lengthType = p.GetSize() + header.GetSerializedSize() + trailer.GetSerializedSize();
+ break;
+ case IP_ARP:
+ lengthType = protocolNumber;
+ break;
+ case LLC: {
+ LlcSnapHeader llc;
+ llc.SetType (protocolNumber);
+ p.AddHeader (llc);
+ } break;
+ case RAW:
+ NS_ASSERT (false);
+ break;
+ }
+ header.SetLengthType (lengthType);
+ p.AddHeader(header);
+ trailer.CalcFcs(p);
+ p.AddTrailer(trailer);
+}
+bool
+CsmaNetDevice::ProcessHeader (Packet& p, uint16_t & param)
+{
+ if (m_encapMode == RAW)
+ {
+ return true;
+ }
+ EthernetHeader header (false);
+ EthernetTrailer trailer;
+
+ p.RemoveTrailer(trailer);
+ trailer.CheckFcs(p);
+ p.RemoveHeader(header);
+
+ if ((header.GetDestination() != GetBroadcast ()) &&
+ (header.GetDestination() != GetAddress ()))
+ {
+ return false;
+ }
+
+ switch (m_encapMode)
+ {
+ case ETHERNET_V1:
+ case IP_ARP:
+ param = header.GetLengthType();
+ break;
+ case LLC: {
+ LlcSnapHeader llc;
+ p.RemoveHeader (llc);
+ param = llc.GetType ();
+ } break;
+ case RAW:
+ NS_ASSERT (false);
+ break;
+ }
+ return true;
+}
+
+bool
+CsmaNetDevice::DoNeedsArp (void) const
+{
+ if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+CsmaNetDevice::SendTo (
+ const Packet& packet,
+ const Address& dest,
+ uint16_t protocolNumber)
+{
+ Packet p = packet;
+ NS_DEBUG ("CsmaNetDevice::SendTo (" << &p << ")");
+ NS_DEBUG ("CsmaNetDevice::SendTo (): UID is " << p.GetUid () << ")");
+
+ NS_ASSERT (IsLinkUp ());
+
+ // Only transmit if send side of net device is enabled
+ if (!IsSendEnabled())
+ return false;
+
+ Eui48Address destination = Eui48Address::ConvertFrom (dest);
+ AddHeader(p, destination, protocolNumber);
+
+ // Place the packet to be sent on the send queue
+ if (m_queue->Enqueue(p) == false )
+ {
+ return false;
+ }
+ // If the device is idle, we need to start a transmission. Otherwise,
+ // the transmission will be started when the current packet finished
+ // transmission (see TransmitCompleteEvent)
+ if (m_txMachineState == READY)
+ {
+ // Store the next packet to be transmitted
+ if (m_queue->Dequeue (m_currentPkt))
+ {
+ TransmitStart();
+ }
+ }
+ return true;
+}
+
+void
+CsmaNetDevice::TransmitStart ()
+{
+ NS_DEBUG ("CsmaNetDevice::TransmitStart (" << &m_currentPkt << ")");
+ NS_DEBUG ("CsmaNetDevice::TransmitStart (): UID is "
+ << m_currentPkt.GetUid () << ")");
+//
+// This function is called to start the process of transmitting a packet.
+// We need to tell the channel that we've started wiggling the wire and
+// schedule an event that will be executed when it's time to tell the
+// channel that we're done wiggling the wire.
+//
+ NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF),
+ "Must be READY to transmit. Tx state is: "
+ << m_txMachineState);
+
+ // Only transmit if send side of net device is enabled
+ if (!IsSendEnabled())
+ return;
+
+ if (m_channel->GetState() != IDLE)
+ { // Channel busy, backoff and rechedule TransmitStart()
+ m_txMachineState = BACKOFF;
+ if (m_backoff.MaxRetriesReached())
+ { // Too many retries reached, abort transmission of packet
+ TransmitAbort();
+ }
+ else
+ {
+ m_backoff.IncrNumRetries();
+ Time backoffTime = m_backoff.GetBackoffTime();
+
+ NS_DEBUG ("CsmaNetDevice::TransmitStart (): "
+ << "Channel busy, backing off for "
+ << backoffTime.GetSeconds () << "sec");
+
+ Simulator::Schedule (backoffTime,
+ &CsmaNetDevice::TransmitStart,
+ this);
+ }
+ }
+ else
+ {
+ // Channel is free, transmit packet
+ m_txMachineState = BUSY;
+ Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
+
+ NS_DEBUG ("CsmaNetDevice::TransmitStart (): " <<
+ "Schedule TransmitCompleteEvent in " <<
+ tEvent.GetSeconds () << "sec");
+
+ Simulator::Schedule (tEvent,
+ &CsmaNetDevice::TransmitCompleteEvent,
+ this);
+ if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
+ {
+ NS_DEBUG ("CsmaNetDevice::TransmitStart (): " <<
+ "Channel transmit start did not work at " <<
+ tEvent.GetSeconds () << "sec");
+ m_txMachineState = READY;
+ }
+ else
+ {
+ // Transmission success, reset backoff time parameters.
+ m_backoff.ResetBackoffTime();
+ }
+ }
+}
+
+
+void
+CsmaNetDevice::TransmitAbort (void)
+{
+ NS_DEBUG ("CsmaNetDevice::TransmitAbort ()");
+
+ NS_DEBUG ("CsmaNetDevice::TransmitAbort (): Pkt UID is " <<
+ m_currentPkt.GetUid () << ")");
+
+ // Try to transmit a new packet
+ bool found;
+ found = m_queue->Dequeue (m_currentPkt);
+ NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+ m_backoff.ResetBackoffTime();
+ m_txMachineState = READY;
+ TransmitStart ();
+}
+
+void
+CsmaNetDevice::TransmitCompleteEvent (void)
+{
+ NS_DEBUG ("CsmaNetDevice::TransmitCompleteEvent ()");
+//
+// This function is called to finish the process of transmitting a packet.
+// We need to tell the channel that we've stopped wiggling the wire and
+// schedule an event that will be executed when it's time to re-enable
+// the transmitter after the interframe gap.
+//
+ NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
+ // Channel should be transmitting
+ NS_ASSERT(m_channel->GetState() == TRANSMITTING);
+ m_txMachineState = GAP;
+
+ NS_DEBUG ("CsmaNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
+ m_currentPkt.GetUid () << ")");
+ m_channel->TransmitEnd ();
+
+ NS_DEBUG (
+ "CsmaNetDevice::TransmitCompleteEvent (): " <<
+ "Schedule TransmitReadyEvent in "
+ << m_tInterframeGap.GetSeconds () << "sec");
+
+ Simulator::Schedule (m_tInterframeGap,
+ &CsmaNetDevice::TransmitReadyEvent,
+ this);
+}
+
+void
+CsmaNetDevice::TransmitReadyEvent (void)
+{
+ NS_DEBUG ("CsmaNetDevice::TransmitReadyEvent ()");
+//
+// This function is called to enable the transmitter after the interframe
+// gap has passed. If there are pending transmissions, we use this opportunity
+// to start the next transmit.
+//
+ NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap");
+ m_txMachineState = READY;
+
+ // Get the next packet from the queue for transmitting
+ if (m_queue->IsEmpty())
+ {
+ return;
+ }
+ else
+ {
+ bool found;
+ found = m_queue->Dequeue (m_currentPkt);
+ NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?");
+ TransmitStart ();
+ }
+}
+
+Ptr<TraceResolver>
+CsmaNetDevice::GetTraceResolver (void)
+{
+ Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
+ resolver->AddChild ("queue", m_queue);
+ resolver->AddSource ("rx",
+ "receive MAC packet",
+ m_rxTrace,
+ CsmaTraceType (CsmaTraceType::RX));
+ resolver->AddSource ("drop",
+ "drop MAC packet",
+ m_dropTrace,
+ CsmaTraceType (CsmaTraceType::DROP));
+ resolver->SetParent (NetDevice::GetTraceResolver ());
+ return resolver;
+}
+
+bool
+CsmaNetDevice::Attach (Ptr<CsmaChannel> ch)
+{
+ NS_DEBUG ("CsmaNetDevice::Attach (" << &ch << ")");
+
+ m_channel = ch;
+
+ m_deviceId = m_channel->Attach(this);
+ m_bps = m_channel->GetDataRate ();
+ m_tInterframeGap = m_channel->GetDelay ();
+
+ /*
+ * For now, this device is up whenever a channel is attached to it.
+ */
+ NotifyLinkUp ();
+ return true;
+}
+
+void
+CsmaNetDevice::AddQueue (Ptr<Queue> q)
+{
+ NS_DEBUG ("CsmaNetDevice::AddQueue (" << q << ")");
+
+ m_queue = q;
+}
+
+void
+CsmaNetDevice::Receive (const Packet& packet)
+{
+ EthernetHeader header (false);
+ EthernetTrailer trailer;
+ Eui48Address broadcast;
+ Eui48Address destination;
+ Packet p = packet;
+
+ NS_DEBUG ("CsmaNetDevice::Receive UID is (" << p.GetUid() << ")");
+
+ // Only receive if send side of net device is enabled
+ if (!IsReceiveEnabled())
+ {
+ m_dropTrace (p);
+ return;
+ }
+
+ if (m_encapMode == RAW)
+ {
+ ForwardUp (packet, 0, GetBroadcast ());
+ m_dropTrace (p);
+ return;
+ }
+ p.RemoveTrailer(trailer);
+ trailer.CheckFcs(p);
+ p.RemoveHeader(header);
+
+ broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
+ destination = Eui48Address::ConvertFrom (GetAddress ());
+ if ((header.GetDestination() != broadcast) &&
+ (header.GetDestination() != destination))
+ {
+ // not for us.
+ m_dropTrace (p);
+ return;
+ }
+
+ m_rxTrace (p);
+//
+// protocol must be initialized to avoid a compiler warning in the RAW
+// case that breaks the optimized build.
+//
+ uint16_t protocol = 0;
+
+ switch (m_encapMode)
+ {
+ case ETHERNET_V1:
+ case IP_ARP:
+ protocol = header.GetLengthType();
+ break;
+ case LLC: {
+ LlcSnapHeader llc;
+ p.RemoveHeader (llc);
+ protocol = llc.GetType ();
+ } break;
+ case RAW:
+ NS_ASSERT (false);
+ break;
+ }
+
+ ForwardUp (p, protocol, header.GetSource ());
+ return;
+}
+
+Ptr<Queue>
+CsmaNetDevice::GetQueue(void) const
+{
+ return m_queue;
+}
+
+Ptr<Channel>
+CsmaNetDevice::DoGetChannel(void) const
+{
+ return m_channel;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-net-device.h Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,434 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 Emmanuelle Laprise
+ *
+ * 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+ */
+
+#ifndef CSMA_NET_DEVICE_H
+#define CSMA_NET_DEVICE_H
+
+#include <string.h>
+#include "ns3/node.h"
+#include "ns3/backoff.h"
+#include "ns3/address.h"
+#include "ns3/net-device.h"
+#include "ns3/callback.h"
+#include "ns3/packet.h"
+#include "ns3/callback-trace-source.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.h"
+#include "ns3/eui48-address.h"
+
+namespace ns3 {
+
+class Queue;
+class CsmaChannel;
+
+class CsmaTraceType : public TraceContextElement
+{
+public:
+ enum Type {
+ RX,
+ DROP
+ };
+ CsmaTraceType (enum Type type);
+ CsmaTraceType ();
+ void Print (std::ostream &os) const;
+ static uint16_t GetUid (void);
+ std::string GetName (void) const;
+private:
+ enum Type m_type;
+};
+
+/**
+ * \class CsmaNetDevice
+ * \brief A Device for a Csma Network Link.
+ *
+ * The Csma net device class is analogous to layer 1 and 2 of the
+ * TCP stack. The NetDevice takes a raw packet of bytes and creates a
+ * protocol specific packet from them. The Csma net device class
+ * takes this packet and adds and processes the headers/trailers that
+ * are associated with EthernetV1, EthernetV2, RAW or LLC
+ * protocols. The EthernetV1 packet type adds and removes Ethernet
+ * destination and source addresses. The LLC packet type adds and
+ * removes LLC snap headers. The raw packet type does not add or
+ * remove any headers. Each Csma net device will receive all
+ * packets written to the Csma link. The ProcessHeader function can
+ * be used to filter out the packets such that higher level layers
+ * only receive packets that are addressed to their associated net
+ * devices
+ *
+ */
+class CsmaNetDevice : public NetDevice {
+public:
+
+ /**
+ * Enumeration of the types of packets supported in the class.
+ *
+ */
+enum CsmaEncapsulationMode {
+ ETHERNET_V1, /**< Version one ethernet packet, length field */
+ IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */
+ RAW, /**< Packet that contains no headers */
+ LLC, /**< LLC packet encapsulation */
+};
+
+ CsmaNetDevice (Ptr<Node> node);
+ /**
+ * Construct a CsmaNetDevice
+ *
+ * This is the constructor for the CsmaNetDevice. It takes as a
+ * parameter the Node to which this device is connected. Ownership of the
+ * Node pointer is not implied and the node must not be deleted.
+ *
+ * \param node the Node to which this device is connected.
+ * \param addr The source MAC address of the net device.
+ * \param pktType the type of encapsulation
+ */
+ CsmaNetDevice (Ptr<Node> node, Eui48Address addr, CsmaEncapsulationMode pktType);
+
+ /**
+ * Construct a CsmaNetDevice
+ *
+ * This is the constructor for the CsmaNetDevice. It takes as a
+ * parameter the Node to which this device is connected. Ownership of the
+ * Node pointer is not implied and the node must not be deleted.
+ *
+ * \param node the Node to which this device is connected.
+ * \param addr The source MAC address of the net device.
+ * \param pktType the type of encapsulation
+ * \param sendEnable whether this device is able to send
+ * \param receiveEnable whether this device is able to receive
+ */
+ CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
+ CsmaEncapsulationMode pktType,
+ bool sendEnable, bool receiveEnable);
+ /**
+ * Destroy a CsmaNetDevice
+ *
+ * This is the destructor for the CsmaNetDevice.
+ */
+ virtual ~CsmaNetDevice();
+ /**
+ * Set the Data Rate used for transmission of packets. The data rate is
+ * set in the Attach () method from the corresponding field in the channel
+ * to which the device is attached. It can be overridden using this method.
+ *
+ * @see Attach ()
+ * \param bps the data rate at which this object operates
+ */
+ void SetDataRate (DataRate bps);
+ /**
+ * Set the inteframe gap used to separate packets. The interframe gap
+ * defines the minimum space required between packets sent by this device.
+ * It is usually set in the Attach () method based on the speed of light
+ * delay of the channel to which the device is attached. It can be
+ * overridden using this method if desired.
+ *
+ * @see Attach ()
+ * \param t the interframe gap time
+ */
+ void SetInterframeGap (Time t);
+ /**
+ * Set the backoff parameters used to determine the wait to retry
+ * transmitting a packet when the channel is busy.
+ *
+ * @see Attach ()
+ * \param slotTime Length of a packet slot (or average packet time)
+ * \param minSlots Minimum number of slots to wait
+ * \param maxSlots Maximum number of slots to wait
+ * \param maxRetries Maximum number of retries before packet is discard
+ * \param ceiling Cap on the exponential function when calculating max slots
+ */
+ void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots,
+ uint32_t maxRetries, uint32_t ceiling);
+ /**
+ * Attach the device to a channel.
+ *
+ * The function Attach is used to add a CsmaNetDevice to a
+ * CsmaChannel.
+ *
+ * @see SetDataRate ()
+ * @see SetInterframeGap ()
+ * \param ch a pointer to the channel to which this object is being attached.
+ */
+ bool Attach (Ptr<CsmaChannel> ch);
+ /**
+ * Attach a queue to the CsmaNetDevice.
+ *
+ * The CsmaNetDevice "owns" a queue. This queue is created by the
+ * CsmaTopology object and implements a queueing method such as
+ * DropTail or RED. The CsmaNetDevice assumes ownership of this
+ * queue and must delete it when the device is destroyed.
+ *
+ * @see CsmaTopology::AddCsmaLink ()
+ * @see Queue
+ * @see DropTailQueue
+ * \param queue a pointer to the queue for which object is assuming
+ * ownership.
+ */
+ void AddQueue (Ptr<Queue> queue);
+ /**
+ * Receive a packet from a connected CsmaChannel.
+ *
+ * The CsmaNetDevice receives packets from its connected channel
+ * and forwards them up the protocol stack. This is the public method
+ * used by the channel to indicate that the last bit of a packet has
+ * arrived at the device.
+ *
+ * @see CsmaChannel
+ * \param p a reference to the received packet
+ */
+ void Receive (const Packet& p);
+
+ bool IsSendEnabled (void);
+ bool IsReceiveEnabled (void);
+
+ void SetSendEnable (bool);
+ void SetReceiveEnable (bool);
+
+protected:
+ virtual bool DoNeedsArp (void) const;
+ virtual void DoDispose (void);
+ /**
+ * Create a Trace Resolver for events in the net device.
+ * (NOT TESTED)
+ * @see class TraceResolver
+ */
+ virtual Ptr<TraceResolver> GetTraceResolver (void);
+
+ /**
+ * Get a copy of the attached Queue.
+ *
+ * This method is provided for any derived class that may need to get
+ * direct access to the underlying queue.
+ *
+ * \return a pointer to the queue.
+ */
+ Ptr<Queue> GetQueue (void) const;
+ /**
+ * Get a copy of the attached Channel
+ *
+ * This method is provided for any derived class that may need to get
+ * direct access to the connected channel
+ *
+ * \return a pointer to the channel
+ */
+ virtual Ptr<Channel> DoGetChannel (void) const;
+ /**
+ * Adds the necessary headers and trailers to a packet of data in order to
+ * respect the packet type
+ *
+ * \param p Packet to which header should be added
+ * \param dest MAC destination address to which packet should be sent
+ * \param protocolNumber In some protocols, identifies the type of
+ * payload contained in this packet.
+ */
+ void AddHeader (Packet& p, Eui48Address dest,
+ uint16_t protocolNumber);
+ /**
+ * Removes, from a packet of data, all headers and trailers that
+ * relate to the packet type
+ *
+ * \param p Packet whose headers need to be processed
+ * \param param An integer parameter that can be set by the function
+ * to return information gathered in the header
+ * \return Returns true if the packet should be forwarded up the
+ * protocol stack.
+ */
+ bool ProcessHeader (Packet& p, uint16_t & param);
+
+private:
+ // disable copy constructor and operator =
+ CsmaNetDevice &operator = (const CsmaNetDevice &o);
+ CsmaNetDevice (const CsmaNetDevice &o);
+ /**
+ * Initializes variablea when construction object.
+ */
+ void Init (bool sendEnable, bool receiveEnable);
+ /**
+ * Send a Packet on the Csma network
+ *
+ * This method does not use a destination address since all packets
+ * are broadcast to all NetDevices attached to the channel. Packet
+ * should contain all needed headers at this time.
+ *
+ * If the device is ready to transmit, the next packet is read off
+ * of the queue and stored locally until it has been transmitted.
+ *
+ * \param p a reference to the packet to send
+ * \param dest destination address
+ * \param protocolNumber -- this parameter is not used here
+ * \return true if success, false on failure
+ */
+ virtual bool SendTo (const Packet& p, const Address& dest, uint16_t protocolNumber);
+
+ /**
+ * Start Sending a Packet Down the Wire.
+ *
+ * The TransmitStart method is the method that is used internally in
+ * the CsmaNetDevice to begin the process of sending a packet
+ * out on the channel. The corresponding method is called on the
+ * channel to let it know that the physical device this class
+ * represents has virually started sending signals, this causes the
+ * channel to become busy. An event is scheduled for the time at
+ * which the bits have been completely transmitted. If the channel
+ * is busy, the method reschedules itself for a later time (within
+ * the backoff period)
+ *
+ * @see CsmaChannel::TransmitStart ()
+ * @see TransmitCompleteEvent ()
+ */
+ void TransmitStart ();
+ /**
+ * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
+ *
+ * The TransmitCompleteEvent method is used internally to finish the process
+ * of sending a packet out on the channel. During execution of this method
+ * the TransmitEnd method is called on the channel to let it know that the
+ * physical device this class represents has virually finished sending
+ * signals. The channel uses this event to begin its speed of light delay
+ * timer after which it notifies the Net Device at the other end of the
+ * link that the bits have arrived. During this method, the net device
+ * also schedules the TransmitReadyEvent at which time the transmitter
+ * becomes ready to send the next packet.
+ *
+ * @see CsmaChannel::TransmitEnd ()
+ * @see TransmitReadyEvent ()
+ */
+ void TransmitCompleteEvent (void);
+ /**
+ * Cause the Transmitter to Become Ready to Send Another Packet.
+ *
+ * The TransmitReadyEvent method is used internally to re-enable the
+ * transmit machine of the net device. It is scheduled after a suitable
+ * interframe gap after the completion of the previous transmission.
+ * The queue is checked at this time, and if there is a packet waiting on
+ * the queue, the transmission process is begun.
+ *
+ * If a packet is in the queue, it is extracted for the queue as the
+ * next packet to be transmitted by the net device.
+ *
+ * @see TransmitStart ()
+ */
+ void TransmitReadyEvent (void);
+
+ /**
+ * Aborts the transmission of the current packet
+ *
+ * If the net device has tried to transmit a packet for more times
+ * than the maximum allowed number of retries (channel always busy)
+ * then the packet is dropped.
+ *
+ */
+ void TransmitAbort (void);
+
+ /**
+ * Device ID returned by the attached functions. It is used by the
+ * mp-channel to identify each net device to make sure that only
+ * active net devices are writing to the channel
+ */
+ uint32_t m_deviceId;
+
+ /**
+ * Enable net device to send packets. True by default
+ */
+ bool m_sendEnable;
+ /**
+ * Enable net device to receive packets. True by default
+ */
+ bool m_receiveEnable;
+ /**
+ * Enumeration of the states of the transmit machine of the net device.
+ */
+ enum TxMachineState
+ {
+ READY, /**< The transmitter is ready to begin transmission of a packet */
+ BUSY, /**< The transmitter is busy transmitting a packet */
+ GAP, /**< The transmitter is in the interframe gap time */
+ BACKOFF /**< The transmitter is waiting for the channel to be free */
+ };
+ /**
+ * The state of the Net Device transmit state machine.
+ * @see TxMachineState
+ */
+ TxMachineState m_txMachineState;
+
+ /**
+ * The type of packet that should be created by the AddHeader
+ * function and that should be processed by the ProcessHeader
+ * function.
+ */
+ CsmaEncapsulationMode m_encapMode;
+ /**
+ * The data rate that the Net Device uses to simulate packet transmission
+ * timing.
+ * @see class DataRate
+ */
+ DataRate m_bps;
+ /**
+ * The interframe gap that the Net Device uses to throttle packet
+ * transmission
+ * @see class Time
+ */
+ Time m_tInterframeGap;
+ /**
+ * Holds the backoff parameters and is used to calculate the next
+ * backoff time to use when the channel is busy and the net device
+ * is ready to transmit
+ */
+ Backoff m_backoff;
+ /**
+ * Next packet that will be transmitted (if transmitter is not
+ * currently transmitting) or packet that is currently being
+ * transmitted.
+ */
+ Packet m_currentPkt;
+ /**
+ * The CsmaChannel to which this CsmaNetDevice has been
+ * attached.
+ * @see class CsmaChannel
+ */
+ Ptr<CsmaChannel> m_channel;
+ /**
+ * The Queue which this CsmaNetDevice uses as a packet source.
+ * Management of this Queue has been delegated to the CsmaNetDevice
+ * and it has the responsibility for deletion.
+ * @see class Queue
+ * @see class DropTailQueue
+ */
+ Ptr<Queue> m_queue;
+ /**
+ * NOT TESTED
+ * The trace source for the packet reception events that the device can
+ * fire.
+ *
+ * @see class CallBackTraceSource
+ * @see class TraceResolver
+ */
+ CallbackTraceSource<Packet &> m_rxTrace;
+ CallbackTraceSource<Packet &> m_dropTrace;
+
+};
+
+}; // namespace ns3
+
+#endif // CSMA_NET_DEVICE_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-topology.cc Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+
+//
+// Topology helper for Csma channels in ns3.
+
+#include "ns3/assert.h"
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+
+#include "csma-channel.h"
+#include "csma-net-device.h"
+#include "csma-topology.h"
+#include "ns3/socket-factory.h"
+
+namespace ns3 {
+
+Ptr<CsmaChannel>
+CsmaTopology::CreateCsmaChannel(
+ const DataRate& bps,
+ const Time& delay)
+{
+ Ptr<CsmaChannel> channel = Create<CsmaChannel> (bps, delay);
+
+ return channel;
+}
+
+#if 0
+Ptr<CsmaNetDevice>
+CsmaTopology::AddCsmaEthernetNode(
+ Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ MacAddress addr)
+{
+ Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
+ ns3::CsmaNetDevice::ETHERNET_V1);
+
+ Ptr<Queue> q = Queue::CreateDefault ();
+ nd1->AddQueue(q);
+ nd1->Attach (ch);
+
+ return nd1;
+}
+
+Ptr<PacketSocket>
+CsmaTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaNetDevice> ndSrc,
+ Ptr<CsmaNetDevice> ndDest)
+{
+ Ptr<PacketSocket> socket = Create<PacketSocket> ();
+ socket->Bind(ndSrc);
+ socket->Connect(ndDest->GetAddress());
+ app->Connect(socket);
+
+ return socket;
+}
+
+Ptr<PacketSocket>
+CsmaTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaNetDevice> ndSrc,
+ MacAddress macAddr)
+{
+ Ptr<PacketSocket> socket = Create<PacketSocket> ();
+ socket->Bind(ndSrc);
+ socket->Connect(macAddr);
+ app->Connect(socket);
+
+ return socket;
+}
+
+Ptr<Socket>
+CsmaTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
+{
+ InterfaceId iid = InterfaceId::LookupByName (iid_name);
+
+ Ptr<SocketFactory> socketFactory =
+ n1->QueryInterface<SocketFactory> (iid);
+
+ Ptr<Socket> socket = socketFactory->CreateSocket ();
+
+ return socket;
+}
+#endif
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/csma-topology.h Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,123 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2007 Emmanuelle Laprise
+//
+// 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: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
+//
+// Topology helper for multipoint channels in ns3.
+//
+#ifndef CSMA_TOPOLOGY_H
+#define CSMA_TOPOLOGY_H
+
+#include "ns3/ptr.h"
+#include "ns3/csma-net-device.h"
+#include "ns3/node.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 CsmaChannel;
+class Node;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Csma Topologies
+ *
+ * Csma topologies are created based on the
+ * ns3::CsmaNetDevice subclasses and ns3::CsmaChannel
+ * objects. This class uses the EthernetNetDevice and
+ * PacketSocket classes in order to create logical connections between
+ * net devices. The PacketSocket class generates the data and the
+ * EthernetNetDevice class creates ethernet packets from the
+ * data, filling in source and destination addresses. The
+ * EthernetNetDevice class filters received data packets
+ * according to its destination Mac addresses.
+ */
+class CsmaTopology {
+public:
+ /**
+ * \param dataRate Maximum transmission link rate
+ * \param delay propagation delay between any two nodes
+ * \return Pointer to the created CsmaChannel
+ *
+ * Create a CsmaChannel. All nodes connected to a multipoint
+ * channels will receive all packets written to that channel
+ */
+ static Ptr<CsmaChannel> CreateCsmaChannel(
+ const DataRate& dataRate, const Time& delay);
+
+#if 0
+ /**
+ * \param n1 Node to be attached to the multipoint channel
+ * \param ch CsmaChannel to which node n1 should be attached
+ * \param addr MacAddress that should be assigned to the
+ * EthernetNetDevice that will be added to the node.
+ *
+ * Add a multipoint node to a multipoint channel
+ */
+ static Ptr<CsmaNetDevice> AddCsmaEthernetNode(Ptr<Node> n1,
+ Ptr<CsmaChannel> ch,
+ MacAddress addr);
+
+ /**
+ * \param app Application that will be sending data to the agent
+ * \param ndSrc Net Device that will be sending the packets onto the
+ * network
+ * \param ndDest Net Device to which ndSrc will be sending the packets
+ * \return A pointer to the PacketSocket
+ *
+ * Creates an PacketSocket and configure it to send packets between
+ * two net devices
+ */
+static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaNetDevice> ndSrc,
+ Ptr<CsmaNetDevice> ndDest);
+
+ /**
+ * \param app Application that will be sending data to the agent
+ * \param ndSrc Net Device that will be sending the packets onto the
+ * network
+ * \param macAddr Mac destination address for the packets send by
+ * the ndSrc net device \return a Pointer to the created
+ * PacketSocket
+ *
+ * Creates an PacketSocket and configure it to send packets from a
+ * net device to a destination MacAddress
+ */
+static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaNetDevice> ndSrc,
+ MacAddress macAddr);
+
+ /**
+ * \param n1 Node from which socketfactory should be tested.
+ * \param iid_name Interface identifier ("Packet", in this case)
+ *
+ * This is a test function to make sure that a socket can be created
+ * by using the socketfactory interface provided in the
+ * netdevicenode.
+ */
+static Ptr<Socket> CreatePacketSocket(Ptr<Node> n1,
+ std::string iid_name);
+#endif
+
+};
+} // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma/wscript Tue Aug 28 12:05:35 2007 +0200
@@ -0,0 +1,19 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+ obj = bld.create_ns3_module('csma', ['node'])
+ obj.source = [
+ 'backoff.cc',
+ 'csma-net-device.cc',
+ 'csma-channel.cc',
+ 'csma-topology.cc',
+ 'csma-ipv4-topology.cc',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'backoff.h',
+ 'csma-net-device.h',
+ 'csma-channel.h',
+ 'csma-topology.h',
+ 'csma-ipv4-topology.h',
+ ]
--- a/src/devices/point-to-point/point-to-point-net-device.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.cc Tue Aug 28 12:05:35 2007 +0200
@@ -122,9 +122,10 @@
m_tInterframeGap = t;
}
-bool PointToPointNetDevice::SendTo (Packet& p, const Address& dest,
+bool PointToPointNetDevice::SendTo (const Packet& packet, const Address& dest,
uint16_t protocolNumber)
{
+ Packet p = packet;
NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
@@ -243,8 +244,8 @@
uint16_t protocol = 0;
Packet packet = p;
+ m_rxTrace (packet);
ProcessHeader(packet, protocol);
- m_rxTrace (packet);
ForwardUp (packet, protocol, GetBroadcast ());
}
--- a/src/devices/point-to-point/point-to-point-net-device.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/devices/point-to-point/point-to-point-net-device.h Tue Aug 28 12:05:35 2007 +0200
@@ -182,7 +182,6 @@
virtual Ptr<Channel> DoGetChannel(void) const;
/**
* Set a new default data rate
- * @param Data rate to set for new default
*/
static void SetDefaultRate(const DataRate&);
@@ -219,7 +218,7 @@
* @param protocolNumber Protocol Number used to find protocol touse
* @returns true if success, false on failure
*/
- virtual bool SendTo (Packet& p, const Address& dest,
+ virtual bool SendTo (const Packet& p, const Address& dest,
uint16_t protocolNumber);
/**
* Start Sending a Packet Down the Wire.
--- a/src/internet-node/ascii-trace.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/ascii-trace.cc Tue Aug 28 12:05:35 2007 +0200
@@ -25,6 +25,7 @@
#include "ns3/node.h"
#include "ns3/node-list.h"
#include "ns3/packet.h"
+#include "ns3/queue.h"
namespace ns3 {
@@ -40,8 +41,12 @@
AsciiTrace::TraceAllQueues (void)
{
Packet::EnableMetadata ();
- NodeList::Connect ("/nodes/*/devices/*/queue/*",
- MakeCallback (&AsciiTrace::LogDevQueue, this));
+ NodeList::Connect ("/nodes/*/devices/*/queue/enqueue",
+ MakeCallback (&AsciiTrace::LogDevQueueEnqueue, this));
+ NodeList::Connect ("/nodes/*/devices/*/queue/dequeue",
+ MakeCallback (&AsciiTrace::LogDevQueueDequeue, this));
+ NodeList::Connect ("/nodes/*/devices/*/queue/drop",
+ MakeCallback (&AsciiTrace::LogDevQueueDrop, this));
}
void
AsciiTrace::TraceAllNetDeviceRx (void)
@@ -52,8 +57,34 @@
}
void
-AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet)
+AsciiTrace::LogDevQueueEnqueue (TraceContext const &context,
+ Packet const &packet)
{
+ m_os << "+ ";
+ m_os << Simulator::Now ().GetSeconds () << " ";
+ context.Print (m_os);
+ m_os << " pkt-uid=" << packet.GetUid () << " ";
+ packet.Print (m_os);
+ m_os << std::endl;
+}
+
+void
+AsciiTrace::LogDevQueueDequeue (TraceContext const &context,
+ Packet const &packet)
+{
+ m_os << "- ";
+ m_os << Simulator::Now ().GetSeconds () << " ";
+ context.Print (m_os);
+ m_os << " pkt-uid=" << packet.GetUid () << " ";
+ packet.Print (m_os);
+ m_os << std::endl;
+}
+
+void
+AsciiTrace::LogDevQueueDrop (TraceContext const &context,
+ Packet const &packet)
+{
+ m_os << "d ";
m_os << Simulator::Now ().GetSeconds () << " ";
context.Print (m_os);
m_os << " pkt-uid=" << packet.GetUid () << " ";
@@ -63,7 +94,7 @@
void
AsciiTrace::LogDevRx (TraceContext const &context, Packet &p)
{
- m_os << Simulator::Now ().GetSeconds () << " ";
+ m_os << "r " << Simulator::Now ().GetSeconds () << " ";
context.Print (m_os);
m_os << " pkt-uid=" << p.GetUid () << " ";
p.Print (m_os);
--- a/src/internet-node/ascii-trace.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/ascii-trace.h Tue Aug 28 12:05:35 2007 +0200
@@ -37,7 +37,9 @@
void TraceAllQueues (void);
void TraceAllNetDeviceRx (void);
private:
- void LogDevQueue (TraceContext const &context, const Packet &p);
+ void LogDevQueueEnqueue (TraceContext const &context, const Packet &p);
+ void LogDevQueueDequeue (TraceContext const &context, const Packet &p);
+ void LogDevQueueDrop (TraceContext const &context, const Packet &p);
void LogDevRx (TraceContext const &context, Packet &p);
std::ofstream m_os;
};
--- a/src/internet-node/ipv4-loopback-interface.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/ipv4-loopback-interface.cc Tue Aug 28 12:05:35 2007 +0200
@@ -21,6 +21,7 @@
*/
#include "ns3/net-device.h"
#include "ns3/node.h"
+#include "ns3/eui48-address.h"
#include "ipv4-loopback-interface.h"
#include "ipv4-l3-protocol.h"
@@ -36,7 +37,7 @@
Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest)
{
Ptr<Ipv4L3Protocol> ipv4 = m_node->QueryInterface<Ipv4L3Protocol> (Ipv4L3Protocol::iid);
- ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()->GetAddress ());
+ ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, Eui48Address ("ff:ff:ff:ff:ff:ff"));
}
}//namespace ns3
--- a/src/internet-node/udp-socket.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/udp-socket.cc Tue Aug 28 12:05:35 2007 +0200
@@ -57,6 +57,12 @@
m_udp = 0;
}
+enum Socket::SocketErrno
+UdpSocket::GetErrno (void) const
+{
+ return m_errno;
+}
+
Ptr<Node>
UdpSocket::GetNode (void) const
{
@@ -118,11 +124,6 @@
return FinishBind ();
}
-enum Socket::SocketErrno
-UdpSocket::GetErrno (void) const
-{
- return m_errno;
-}
int
UdpSocket::ShutdownSend (void)
{
@@ -137,73 +138,42 @@
}
int
-UdpSocket::DoClose(Callback<void, Ptr<Socket> > closeCompleted)
+UdpSocket::Close(void)
{
- // XXX: we should set the close state and check it in all API methods.
- if (!closeCompleted.IsNull ())
- {
- closeCompleted (this);
- }
+ NotifyCloseCompleted ();
return 0;
}
+
int
-UdpSocket::DoConnect(const Address & address,
- Callback<void, Ptr<Socket> > connectionSucceeded,
- Callback<void, Ptr<Socket> > connectionFailed,
- Callback<void, Ptr<Socket> > halfClose)
+UdpSocket::Connect(const Address & address)
{
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
m_defaultAddress = transport.GetIpv4 ();
m_defaultPort = transport.GetPort ();
- if (!connectionSucceeded.IsNull ())
- {
- connectionSucceeded (this);
- }
+ NotifyConnectionSucceeded ();
m_connected = true;
return 0;
}
-int
-UdpSocket::DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
- Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
- Callback<void, Ptr<Socket> > closeRequested)
-{
- // calling accept on a udp socket is a programming error.
- m_errno = ERROR_OPNOTSUPP;
- return -1;
-}
int
-UdpSocket::DoSend (const uint8_t* buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::Send (const Packet &p)
{
if (!m_connected)
{
m_errno = ERROR_NOTCONN;
return -1;
}
- Packet p;
- if (buffer == 0)
- {
- p = Packet (size);
- }
- else
- {
- p = Packet (buffer, size);
- }
- return DoSendPacketTo (p, m_defaultAddress, m_defaultPort, dataSent);
+ return DoSendTo (p, m_defaultAddress, m_defaultPort);
}
int
-UdpSocket::DoSendPacketTo (const Packet &p, const Address &address,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::DoSendTo (const Packet &p, const Address &address)
{
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
- return DoSendPacketTo (p, ipv4, port, dataSent);
+ return DoSendTo (p, ipv4, port);
}
int
-UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::DoSendTo (const Packet &p, Ipv4Address ipv4, uint16_t port)
{
if (m_endPoint == 0)
{
@@ -221,46 +191,21 @@
}
m_udp->Send (p, m_endPoint->GetLocalAddress (), ipv4,
m_endPoint->GetLocalPort (), port);
- if (!dataSent.IsNull ())
- {
- dataSent (this, p.GetSize ());
- }
+ NotifyDataSent (p.GetSize ());
return 0;
}
int
-UdpSocket::DoSendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+UdpSocket::SendTo(const Address &address, const Packet &p)
{
if (m_connected)
{
m_errno = ERROR_ISCONN;
return -1;
}
- Packet p;
- if (buffer == 0)
- {
- p = Packet (size);
- }
- else
- {
- p = Packet (buffer, size);
- }
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
uint16_t port = transport.GetPort ();
- return DoSendPacketTo (p, ipv4, port, dataSent);
-}
-void
-UdpSocket::DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
-{
- m_rxCallback = callback;
-}
-void
-UdpSocket::DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
-{
- m_dummyRxCallback = callback;
+ return DoSendTo (p, ipv4, port);
}
void
@@ -273,14 +218,7 @@
Address address = InetSocketAddress (ipv4, port);
Packet p = packet;
- if (!m_dummyRxCallback.IsNull ())
- {
- m_dummyRxCallback (this, p.GetSize (), address);
- }
- if (!m_rxCallback.IsNull ())
- {
- m_rxCallback (this, p.PeekData (), p.GetSize (), address);
- }
+ NotifyDataReceived (p, address);
}
}//namespace ns3
--- a/src/internet-node/udp-socket.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/internet-node/udp-socket.h Tue Aug 28 12:05:35 2007 +0200
@@ -47,27 +47,14 @@
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
virtual int Bind (const Address &address);
+ virtual int Close (void);
virtual int ShutdownSend (void);
virtual int ShutdownRecv (void);
+ virtual int Connect(const Address &address);
+ virtual int Send (const Packet &p);
+ virtual int SendTo(const Address &address,const Packet &p);
private:
- virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
- virtual int DoConnect(const Address & address,
- Callback<void, Ptr<Socket> > connectionSucceeded,
- Callback<void, Ptr<Socket> > connectionFailed,
- Callback<void, Ptr<Socket> > halfClose);
- virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
- Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
- Callback<void, Ptr<Socket> > closeRequested);
- virtual int DoSend (const uint8_t* buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent);
- virtual int DoSendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent);
- virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&>);
- virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
private:
friend class Udp;
@@ -75,10 +62,8 @@
int FinishBind (void);
void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port);
void Destroy (void);
- int DoSendPacketTo (const Packet &p, const Address &daddr,
- Callback<void, Ptr<Socket>, uint32_t> dataSent);
- int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport,
- Callback<void, Ptr<Socket>, uint32_t> dataSent);
+ int DoSendTo (const Packet &p, const Address &daddr);
+ int DoSendTo (const Packet &p, Ipv4Address daddr, uint16_t dport);
Ipv4EndPoint *m_endPoint;
Ptr<Node> m_node;
--- a/src/mobility/mobility-model.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/mobility/mobility-model.cc Tue Aug 28 12:05:35 2007 +0200
@@ -52,9 +52,9 @@
}
double
-MobilityModel::GetDistanceFrom (const MobilityModel &other) const
+MobilityModel::GetDistanceFrom (Ptr<const MobilityModel> other) const
{
- Position oPosition = other.DoGet ();
+ Position oPosition = other->DoGet ();
Position position = DoGet ();
return CalculateDistance (position, oPosition);
}
--- a/src/mobility/mobility-model.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/mobility/mobility-model.h Tue Aug 28 12:05:35 2007 +0200
@@ -57,7 +57,7 @@
* \param position a reference to another mobility model
* \returns the distance between the two objects. Unit is meters.
*/
- double GetDistanceFrom (const MobilityModel &position) const;
+ double GetDistanceFrom (Ptr<const MobilityModel> position) const;
protected:
/**
* Must be invoked by subclasses when the course of the
--- a/src/node/address.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/address.cc Tue Aug 28 12:05:35 2007 +0200
@@ -147,7 +147,7 @@
return os;
}
os.setf (std::ios::hex, std::ios::basefield);
- std::cout.fill('0');
+ os.fill('0');
for (uint8_t i=0; i < (address.m_len-1); i++)
{
os << std::setw(2) << (uint32_t)address.m_data[i] << ":";
@@ -155,7 +155,7 @@
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)address.m_data[address.m_len-1];
os.setf (std::ios::dec, std::ios::basefield);
- std::cout.fill(' ');
+ os.fill(' ');
return os;
}
--- a/src/node/ethernet-header.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/ethernet-header.cc Tue Aug 28 12:05:35 2007 +0200
@@ -19,6 +19,8 @@
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
+#include <iomanip>
+#include <iostream>
#include "ns3/assert.h"
#include "ns3/debug.h"
#include "ns3/header.h"
@@ -118,7 +120,8 @@
{
os << " preamble/sfd=" << m_preambleSfd << ",";
}
- os << " length/type=" << m_lengthType
+
+ os << " length/type=0x" << std::hex << m_lengthType << std::dec
<< ", source=" << m_source
<< ", destination=" << m_destination;
}
--- a/src/node/eui48-address.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/eui48-address.cc Tue Aug 28 12:05:35 2007 +0200
@@ -152,7 +152,7 @@
address.CopyTo (ad);
os.setf (std::ios::hex, std::ios::basefield);
- std::cout.fill('0');
+ os.fill('0');
for (uint8_t i=0; i < 5; i++)
{
os << std::setw(2) << (uint32_t)ad[i] << ":";
@@ -160,7 +160,7 @@
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)ad[5];
os.setf (std::ios::dec, std::ios::basefield);
- std::cout.fill(' ');
+ os.fill(' ');
return os;
}
--- a/src/node/eui64-address.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/eui64-address.cc Tue Aug 28 12:05:35 2007 +0200
@@ -155,7 +155,7 @@
address.CopyTo (ad);
os.setf (std::ios::hex, std::ios::basefield);
- std::cout.fill('0');
+ os.fill('0');
for (uint8_t i=0; i < 7; i++)
{
os << std::setw(2) << (uint32_t)ad[i] << ":";
@@ -163,7 +163,7 @@
// Final byte not suffixed by ":"
os << std::setw(2) << (uint32_t)ad[7];
os.setf (std::ios::dec, std::ios::basefield);
- std::cout.fill(' ');
+ os.fill(' ');
return os;
}
--- a/src/node/inet-socket-address.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/inet-socket-address.cc Tue Aug 28 12:05:35 2007 +0200
@@ -1,3 +1,24 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
#include "inet-socket-address.h"
#include "ns3/assert.h"
@@ -72,7 +93,7 @@
uint8_t buf[6];
address.CopyTo (buf);
Ipv4Address ipv4 = Ipv4Address::Deserialize (buf);
- uint16_t port = buf[0] | (buf[1] << 8);
+ uint16_t port = buf[4] | (buf[5] << 8);
return InetSocketAddress (ipv4, port);
}
uint8_t
--- a/src/node/inet-socket-address.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/inet-socket-address.h Tue Aug 28 12:05:35 2007 +0200
@@ -1,5 +1,26 @@
-#ifndef IPV4_TRANSPORT_ADDRESS_H
-#define IPV4_TRANSPORT_ADDRESS_H
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005 INRIA
+ * All rights reserved.
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef INET_SOCKET_ADDRESS_H
+#define INET_SOCKET_ADDRESS_H
#include "address.h"
#include "ipv4-address.h"
@@ -93,4 +114,4 @@
} // namespace ns3
-#endif /* IPV4_TRANSPORT_ADDRESS_H */
+#endif /* INET_SOCKET_ADDRESS_H */
--- a/src/node/ipv4-address.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/ipv4-address.cc Tue Aug 28 12:05:35 2007 +0200
@@ -171,8 +171,11 @@
bool
Ipv4Address::IsMulticast (void) const
{
- // XXX
- return false;
+//
+// Multicast addresses are defined as ranging from 224.0.0.0 through
+// 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
+//
+ return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
}
uint32_t
--- a/src/node/net-device.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/net-device.cc Tue Aug 28 12:05:35 2007 +0200
@@ -172,7 +172,7 @@
// Receive packet from above
bool
-NetDevice::Send(Packet& p, const Address& dest, uint16_t protocolNumber)
+NetDevice::Send(const Packet& p, const Address& dest, uint16_t protocolNumber)
{
if (m_isUp)
{
@@ -192,7 +192,7 @@
// Receive packets from below
bool
-NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from)
+NetDevice::ForwardUp(const Packet& p, uint16_t param, const Address &from)
{
bool retval = false;
--- a/src/node/net-device.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/net-device.h Tue Aug 28 12:05:35 2007 +0200
@@ -150,7 +150,7 @@
*
* \return whether the Send operation succeeded
*/
- bool Send(Packet& p, const Address& dest, uint16_t protocolNumber);
+ bool Send(const Packet& p, const Address& dest, uint16_t protocolNumber);
/**
* \returns the node base class which contains this network
* interface.
@@ -243,7 +243,7 @@
* forwards it to the higher layers by calling this method
* which is responsible for passing it up to the Rx callback.
*/
- bool ForwardUp (const Packet& p, uint32_t param, const Address &address);
+ bool ForwardUp (const Packet& p, uint16_t param, const Address &address);
/**
@@ -266,7 +266,7 @@
* method. When the link is Up, this method is invoked to ask
* subclasses to forward packets. Subclasses MUST override this method.
*/
- virtual bool SendTo (Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
+ virtual bool SendTo (const Packet& p, const Address &dest, uint16_t protocolNumber) = 0;
/**
* \returns true if this NetDevice needs the higher-layers
* to perform ARP over it, false otherwise.
--- a/src/node/packet-socket.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/packet-socket.cc Tue Aug 28 12:05:35 2007 +0200
@@ -52,13 +52,18 @@
m_device = 0;
}
+enum Socket::SocketErrno
+PacketSocket::GetErrno (void) const
+{
+ return m_errno;
+}
+
Ptr<Node>
PacketSocket::GetNode (void) const
{
return m_node;
}
-
int
PacketSocket::Bind (void)
{
@@ -111,11 +116,6 @@
return 0;
}
-enum Socket::SocketErrno
-PacketSocket::GetErrno (void) const
-{
- return m_errno;
-}
int
PacketSocket::ShutdownSend (void)
{
@@ -139,26 +139,20 @@
return 0;
}
int
-PacketSocket::DoClose(ns3::Callback<void, Ptr<Socket> > closeCompleted)
+PacketSocket::Close(void)
{
if (m_state == STATE_CLOSED)
{
m_errno = ERROR_BADF;
return -1;
}
- if (!closeCompleted.IsNull ())
- {
- closeCompleted (this);
- }
m_state = STATE_CLOSED;
+ NotifyCloseCompleted ();
return 0;
}
int
-PacketSocket::DoConnect(const Address &ad,
- ns3::Callback<void, Ptr<Socket> > connectionSucceeded,
- ns3::Callback<void, Ptr<Socket> > connectionFailed,
- ns3::Callback<void, Ptr<Socket> > halfClose)
+PacketSocket::Connect(const Address &ad)
{
PacketSocketAddress address;
if (m_state == STATE_CLOSED)
@@ -184,33 +178,15 @@
}
m_destAddr = ad;
m_state = STATE_CONNECTED;
- if (!connectionSucceeded.IsNull ())
- {
- connectionSucceeded (this);
- }
+ NotifyConnectionSucceeded ();
return 0;
error:
- if (!connectionFailed.IsNull ())
- {
- connectionFailed (this);
- }
+ NotifyConnectionFailed ();
return -1;
}
int
-PacketSocket::DoAccept(ns3::Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
- ns3::Callback<void, Ptr<Socket>, const Address &> newConnectionCreated,
- ns3::Callback<void, Ptr<Socket> > closeRequested)
-{
- // calling accept on a packet socket is a programming error.
- m_errno = ERROR_OPNOTSUPP;
- return -1;
-}
-
-int
-PacketSocket::DoSend (const uint8_t* buffer,
- uint32_t size,
- ns3::Callback<void, Ptr<Socket>, uint32_t> dataSent)
+PacketSocket::Send (const Packet &p)
{
if (m_state == STATE_OPEN ||
m_state == STATE_BOUND)
@@ -218,14 +194,11 @@
m_errno = ERROR_NOTCONN;
return -1;
}
- return DoSendTo (m_destAddr, buffer, size, dataSent);
+ return SendTo (m_destAddr, p);
}
int
-PacketSocket::DoSendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+PacketSocket::SendTo(const Address &address, const Packet &p)
{
PacketSocketAddress ad;
if (m_state == STATE_CLOSED)
@@ -250,16 +223,6 @@
return -1;
}
ad = PacketSocketAddress::ConvertFrom (address);
-
- Packet p;
- if (buffer == 0)
- {
- p = Packet (size);
- }
- else
- {
- p = Packet (buffer, size);
- }
bool error = false;
Address dest = ad.GetPhysicalAddress ();
@@ -282,9 +245,9 @@
}
}
}
- if (!error && !dataSent.IsNull ())
+ if (!error)
{
- dataSent (this, p.GetSize ());
+ NotifyDataSent (p.GetSize ());
}
if (error)
@@ -299,18 +262,6 @@
}
void
-PacketSocket::DoRecv(ns3::Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address &> callback)
-{
- m_rxCallback = callback;
-}
-
-void
-PacketSocket::DoRecvDummy(ns3::Callback<void, Ptr<Socket>, uint32_t, const Address &> callback)
-{
- m_dummyRxCallback = callback;
-}
-
-void
PacketSocket::ForwardUp (Ptr<NetDevice> device, const Packet &packet,
uint16_t protocol, const Address &from)
{
@@ -328,14 +279,7 @@
NS_DEBUG ("PacketSocket::ForwardUp: UID is " << packet.GetUid()
<< " PacketSocket " << this);
- if (!m_dummyRxCallback.IsNull ())
- {
- m_dummyRxCallback (this, p.GetSize (), address);
- }
- if (!m_rxCallback.IsNull ())
- {
- m_rxCallback (this, p.PeekData (), p.GetSize (), address);
- }
+ NotifyDataReceived (p, address);
}
}//namespace ns3
--- a/src/node/packet-socket.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/packet-socket.h Tue Aug 28 12:05:35 2007 +0200
@@ -78,27 +78,15 @@
virtual Ptr<Node> GetNode (void) const;
virtual int Bind (void);
virtual int Bind (const Address & address);
+ virtual int Close (void);
virtual int ShutdownSend (void);
virtual int ShutdownRecv (void);
+ virtual int Connect(const Address &address);
+ virtual int Send (const Packet &p);
+ virtual int SendTo(const Address &address,const Packet &p);
+
private:
- virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted);
- virtual int DoConnect(const Address & address,
- Callback<void, Ptr<Socket> > connectionSucceeded,
- Callback<void, Ptr<Socket> > connectionFailed,
- Callback<void, Ptr<Socket> > halfClose);
- virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
- Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
- Callback<void, Ptr<Socket> > closeRequested);
- virtual int DoSend (const uint8_t* buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent);
- virtual int DoSendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent);
- virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive);
- virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>);
private:
void Init (void);
@@ -114,8 +102,6 @@
STATE_CLOSED
};
Ptr<Node> m_node;
- Callback<void,Ptr<Socket>,uint32_t,const Address &> m_dummyRxCallback;
- Callback<void,Ptr<Socket>,uint8_t const*,uint32_t, const Address &> m_rxCallback;
enum SocketErrno m_errno;
bool m_shutdownSend;
bool m_shutdownRecv;
--- a/src/node/socket.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/socket.cc Tue Aug 28 12:05:35 2007 +0200
@@ -1,79 +1,144 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ * 2007 INRIA
+ *
+ * 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
+ *
+ * Authors: George F. Riley<riley@ece.gatech.edu>
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
#include "socket.h"
+#include "ns3/packet.h"
namespace ns3 {
Socket::~Socket ()
{}
-int
-Socket::Close(Callback<void, Ptr<Socket> > closeCompleted)
+void
+Socket::SetCloseCallback (Callback<void,Ptr<Socket> > closeCompleted)
+{
+ m_closeCompleted = closeCompleted;
+}
+void
+Socket::SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
+ Callback<void, Ptr<Socket> > connectionFailed,
+ Callback<void, Ptr<Socket> > halfClose)
{
- return DoClose (closeCompleted);
+ m_connectionSucceeded = connectionSucceeded;
+ m_connectionFailed = connectionFailed;
+ m_halfClose = halfClose;
+}
+void
+Socket::SetAcceptCallback (Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
+ Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
+ Callback<void, Ptr<Socket> > closeRequested)
+{
+ m_connectionRequest = connectionRequest;
+ m_newConnectionCreated = newConnectionCreated;
+ m_closeRequested = closeRequested;
+}
+void
+Socket::SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent)
+{
+ m_dataSent = dataSent;
+}
+void
+Socket::SetRecvCallback (Callback<void, Ptr<Socket>, const Packet &,const Address&> receivedData)
+{
+ m_receivedData = receivedData;
}
-int
-Socket::Connect(const Address & address,
- Callback<void, Ptr<Socket> > connectionSucceeded,
- Callback<void, Ptr<Socket> > connectionFailed,
- Callback<void, Ptr<Socket> > halfClose)
+void
+Socket::NotifyCloseCompleted (void)
{
- return DoConnect (address, connectionSucceeded, connectionFailed, halfClose);
-}
-int
-Socket::Accept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
- Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
- Callback<void, Ptr<Socket> > closeRequested)
-{
- return DoAccept (connectionRequest, newConnectionCreated, closeRequested);
+ if (!m_closeCompleted.IsNull ())
+ {
+ m_closeCompleted (this);
+ }
}
-int
-Socket::Send (const uint8_t* buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+void
+Socket::NotifyConnectionSucceeded (void)
{
- return DoSend (buffer, size, dataSent);
+ if (!m_connectionSucceeded.IsNull ())
+ {
+ m_connectionSucceeded (this);
+ }
}
-int
-Socket::SendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent)
+void
+Socket::NotifyConnectionFailed (void)
{
- return DoSendTo (address, buffer, size, dataSent);
+ if (!m_connectionFailed.IsNull ())
+ {
+ m_connectionFailed (this);
+ }
}
void
-Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
+Socket::NotifyHalfClose (void)
+{
+ if (!m_halfClose.IsNull ())
+ {
+ m_halfClose (this);
+ }
+}
+bool
+Socket::NotifyConnectionRequest (const Address &from)
{
- DoRecv (callback);
+ if (!m_connectionRequest.IsNull ())
+ {
+ return m_connectionRequest (this, from);
+ }
+ else
+ {
+ // refuse all incomming connections by default.
+ return false;
+ }
}
void
-Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
+Socket::NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from)
+{
+ if (!m_newConnectionCreated.IsNull ())
+ {
+ m_newConnectionCreated (socket, from);
+ }
+}
+void
+Socket::NotifyCloseRequested (void)
{
- DoRecvDummy (callback);
+ if (!m_closeRequested.IsNull ())
+ {
+ m_closeRequested (this);
+ }
+}
+void
+Socket::NotifyDataSent (uint32_t size)
+{
+ if (!m_dataSent.IsNull ())
+ {
+ m_dataSent (this, size);
+ }
+}
+void
+Socket::NotifyDataReceived (const Packet &p, const Address &from)
+{
+ if (!m_receivedData.IsNull ())
+ {
+ m_receivedData (this, p, from);
+ }
}
-bool
-Socket::RefuseAllConnections (Ptr<Socket> socket, const Address& address)
-{
- return false;
-}
-void
-Socket::DummyCallbackVoidSocket (Ptr<Socket> socket)
-{}
-void
-Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
-{}
-void
-Socket::DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &)
-{}
-void
-Socket::DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
- const Address &)
-{}
-void
-Socket::DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &)
-{}
-
}//namespace ns3
--- a/src/node/socket.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/node/socket.h Tue Aug 28 12:05:35 2007 +0200
@@ -1,22 +1,24 @@
-/* -*- 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>
-//
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 Georgia Tech Research Corporation
+ * 2007 INRIA
+ *
+ * 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
+ *
+ * Authors: George F. Riley<riley@ece.gatech.edu>
+ * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
#ifndef __SOCKET_H__
#define __SOCKET_H__
@@ -30,6 +32,7 @@
namespace ns3 {
class Node;
+class Packet;
/**
* \brief Define a Socket API based on the BSD Socket API.
@@ -70,6 +73,55 @@
*/
virtual Ptr<Node> GetNode (void) const = 0;
+ /**
+ * \param closeCompleted Callback invoked when the close operation is
+ * completed.
+ */
+ void SetCloseCallback (Callback<void,Ptr<Socket> > closeCompleted);
+
+ /**
+ * \param connectionSucceeded this callback is invoked when the connection request
+ * initiated by the user is successfully completed. The callback is passed
+ * back a pointer to the same socket object.
+ * \param connectionFailed this callback is invoked when the connection request
+ * initiated by the user is unsuccessfully completed. The callback is passed
+ * back a pointer to the same socket object.
+ * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
+ * other side closes the connection ? Or when I call Close ?
+ */
+ void SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
+ Callback<void, Ptr<Socket> > connectionFailed,
+ Callback<void, Ptr<Socket> > halfClose);
+ /**
+ * \brief Accept connection requests from remote hosts
+ * \param connectionRequest Callback for connection request from peer.
+ * This user callback is passed a pointer to this socket, the
+ * ip address and the port number of the connection originator.
+ * This callback must return true to accept the incoming connection,
+ * false otherwise. If the connection is accepted, the
+ * "newConnectionCreated" callback will be invoked later to give access
+ * to the user to the socket created to match this new connection. If the
+ * user does not explicitely specify this callback, all incoming
+ * connections will be refused.
+ * \param newConnectionCreated Callback for new connection: when a new
+ * is accepted, it is created and the corresponding socket is passed
+ * back to the user through this callback. This user callback is passed
+ * a pointer to the new socket, and the ip address and port number
+ * of the connection originator.
+ * \param closeRequested Callback for connection close request from peer.
+ * XXX: when is this callback invoked ?
+ */
+ void SetAcceptCallback (Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
+ Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
+ Callback<void, Ptr<Socket> > closeRequested);
+ void SetSendCallback (Callback<void, Ptr<Socket>, uint32_t> dataSent);
+ /**
+ * \brief Receive data
+ * \param receivedData Invoked whenever new data is received.
+ *
+ */
+ void SetRecvCallback (Callback<void, Ptr<Socket>, const Packet &,const Address&> receivedData);
+
/**
* \param address the address to try to allocate
* \returns 0 on success, -1 on failure.
@@ -85,16 +137,13 @@
*/
virtual int Bind () = 0;
-
/**
* \brief Close a socket.
- * \param closeCompleted Callback invoked when the close operation is
- * completed.
*
* After the Close call, the socket is no longer valid, and cannot
* safely be used for subsequent operations.
*/
- int Close(Callback<void, Ptr<Socket> > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket));
+ virtual int Close(void) = 0;
/**
* \returns zero on success, -1 on failure.
@@ -115,120 +164,46 @@
/**
* \brief Initiate a connection to a remote host
* \param address Address of remote.
- * \param connectionSucceeded this callback is invoked when the connection request
- * initiated by the user is successfully completed. The callback is passed
- * back a pointer to the same socket object.
- * \param connectionFailed this callback is invoked when the connection request
- * initiated by the user is unsuccessfully completed. The callback is passed
- * back a pointer to the same socket object.
- * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the
- * other side closes the connection ? Or when I call Close ?
*/
- int Connect(const Address &address,
- Callback<void, Ptr<Socket> > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket),
- Callback<void, Ptr<Socket> > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket),
- Callback<void, Ptr<Socket> > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket));
+ virtual int Connect(const Address &address) = 0;
/**
- * \brief Accept connection requests from remote hosts
- * \param connectionRequest Callback for connection request from peer.
- * This user callback is passed a pointer to this socket, the
- * ip address and the port number of the connection originator.
- * This callback must return true to accept the incoming connection,
- * false otherwise. If the connection is accepted, the
- * "newConnectionCreated" callback will be invoked later to give access
- * to the user to the socket created to match this new connection. If the
- * user does not explicitely specify this callback, all incoming
- * connections will be refused.
- * \param newConnectionCreated Callback for new connection: when a new
- * is accepted, it is created and the corresponding socket is passed
- * back to the user through this callback. This user callback is passed
- * a pointer to the new socket, and the ip address and port number
- * of the connection originator.
- * \param closeRequested Callback for connection close request from peer.
- * XXX: when is this callback invoked ?
- */
- int Accept(Callback<bool, Ptr<Socket>, const Address &> connectionRequest =
- MakeCallback(&Socket::RefuseAllConnections),
- Callback<void, Ptr<Socket>, const Address&> newConnectionCreated =
- MakeCallback (&Socket::DummyCallbackVoidSocketAddress),
- Callback<void, Ptr<Socket> > closeRequested = MakeCallback (&Socket::DummyCallbackVoidSocket));
-
- /**
* \brief Send data (or dummy data) to the remote host
- * \param buffer Data to send (nil if dummy data).
- * \param size Number of bytes to send.
- * \param dataSent Data sent callback.
+ * \param p packet to send
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*/
- int Send (const uint8_t* buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
+ virtual int Send (const Packet &p) = 0;
/**
* \brief Send data to a specified peer.
* \param address IP Address of remote host
- * \param buffer Data to send (nil if dummy data).
- * \param size Number of bytes to send.
- * \param dataSent Data sent callback.
+ * \param p packet to send
* \returns -1 in case of error or the number of bytes copied in the
* internal buffer and accepted for transmission.
*/
- int SendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent = MakeCallback (&Socket::DummyCallbackVoidSocketUi32));
-
- /**
- * \brief Receive data
- * \param receivedData Invoked whenever new data is received.
- *
- * If you wish to transport only dummy packets, this method is not a very
- * efficient way to receive these dummy packets: it will trigger a memory
- * allocation to hold the dummy memory into a buffer which can be passed
- * to the user. Instead, consider using the RecvDummy method.
- */
- void Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receivedData =
- MakeCallback (&Socket::DummyCallbackVoidSocketBufferUi32Address));
-
- /**
- * \brief Receive data
- * \param receivedData Invoked whenever new data is received.
- *
- * This method is included because it is vastly more efficient than the
- * Recv method when you use dummy payload.
- */
- void RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> receivedData =
- MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address));
+ virtual int SendTo(const Address &address,const Packet &p) = 0;
-private:
- virtual int DoClose(Callback<void, Ptr<Socket> > closeCompleted) = 0;
- virtual int DoConnect(const Address & address,
- Callback<void, Ptr<Socket> > connectionSucceeded,
- Callback<void, Ptr<Socket> > connectionFailed,
- Callback<void, Ptr<Socket> > halfClose) = 0;
- virtual int DoAccept(Callback<bool, Ptr<Socket>, const Address&> connectionRequest,
- Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
- Callback<void, Ptr<Socket> > closeRequested) = 0;
- virtual int DoSend (const uint8_t* buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
- virtual int DoSendTo(const Address &address,
- const uint8_t *buffer,
- uint32_t size,
- Callback<void, Ptr<Socket>, uint32_t> dataSent) = 0;
- virtual void DoRecv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> receive) = 0;
- virtual void DoRecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&>) = 0;
+protected:
+ void NotifyCloseCompleted (void);
+ void NotifyConnectionSucceeded (void);
+ void NotifyConnectionFailed (void);
+ void NotifyHalfClose (void);
+ bool NotifyConnectionRequest (const Address &from);
+ void NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from);
+ void NotifyCloseRequested (void);
+ void NotifyDataSent (uint32_t size);
+ void NotifyDataReceived (const Packet &p, const Address &from);
-
- static bool RefuseAllConnections (Ptr<Socket> socket, const Address& address);
- static void DummyCallbackVoidSocket (Ptr<Socket> socket);
- static void DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t);
- static void DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &);
- static void DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
- const Address &);
- static void DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &);
+ Callback<void,Ptr<Socket> > m_closeCompleted;
+ Callback<void, Ptr<Socket> > m_connectionSucceeded;
+ Callback<void, Ptr<Socket> > m_connectionFailed;
+ Callback<void, Ptr<Socket> > m_halfClose;
+ Callback<void, Ptr<Socket> > m_closeRequested;
+ Callback<bool, Ptr<Socket>, const Address &> m_connectionRequest;
+ Callback<void, Ptr<Socket>, const Address&> m_newConnectionCreated;
+ Callback<void, Ptr<Socket>, uint32_t> m_dataSent;
+ Callback<void, Ptr<Socket>, const Packet &,const Address&> m_receivedData;
};
} //namespace ns3
--- a/src/routing/global-routing/global-route-manager-impl.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.cc Tue Aug 28 12:05:35 2007 +0200
@@ -48,8 +48,7 @@
{
}
-SPFVertex::SPFVertex (GlobalRouterLSA* lsa) :
- m_vertexType (VertexRouter),
+SPFVertex::SPFVertex (GlobalRoutingLSA* lsa) :
m_vertexId (lsa->GetLinkStateId ()),
m_lsa (lsa),
m_distanceFromRoot (SPF_INFINITY),
@@ -58,6 +57,16 @@
m_parent (0),
m_children ()
{
+ if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexRouter");
+ m_vertexType = SPFVertex::VertexRouter;
+ }
+ else if (lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA)
+ {
+ NS_DEBUG ("SPFVertex:: setting m_vertexType to VertexNetwork");
+ m_vertexType = SPFVertex::VertexNetwork;
+ }
}
SPFVertex::~SPFVertex ()
@@ -99,12 +108,12 @@
}
void
-SPFVertex::SetLSA (GlobalRouterLSA* lsa)
+SPFVertex::SetLSA (GlobalRoutingLSA* lsa)
{
m_lsa = lsa;
}
- GlobalRouterLSA*
+ GlobalRoutingLSA*
SPFVertex::GetLSA (void) const
{
return m_lsa;
@@ -210,7 +219,7 @@
for (i= m_database.begin (); i!= m_database.end (); i++)
{
NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ():free LSA");
- GlobalRouterLSA* temp = i->second;
+ GlobalRoutingLSA* temp = i->second;
delete temp;
}
NS_DEBUG ("GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB (): clear map");
@@ -225,19 +234,19 @@
LSDBMap_t::iterator i;
for (i= m_database.begin (); i!= m_database.end (); i++)
{
- GlobalRouterLSA* temp = i->second;
- temp->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
+ GlobalRoutingLSA* temp = i->second;
+ temp->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
}
}
void
-GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRouterLSA* lsa)
+GlobalRouteManagerLSDB::Insert (Ipv4Address addr, GlobalRoutingLSA* lsa)
{
NS_DEBUG ("GlobalRouteManagerLSDB::Insert ()");
m_database.insert (LSDBPair_t (addr, lsa));
}
- GlobalRouterLSA*
+ GlobalRoutingLSA*
GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
{
NS_DEBUG ("GlobalRouteManagerLSDB::GetLSA ()");
@@ -255,6 +264,31 @@
return 0;
}
+ GlobalRoutingLSA*
+GlobalRouteManagerLSDB::GetLSAByLinkData (Ipv4Address addr) const
+{
+ NS_DEBUG ("GlobalRouteManagerLSDB::GetLSAByLinkData ()");
+//
+// Look up an LSA by its address.
+//
+ LSDBMap_t::const_iterator i;
+ for (i= m_database.begin (); i!= m_database.end (); i++)
+ {
+ GlobalRoutingLSA* temp = i->second;
+// Iterate among temp's Link Records
+ for (uint32_t j = 0; j < temp->GetNLinkRecords (); j++)
+ {
+ GlobalRoutingLinkRecord *lr = temp->GetLinkRecord (j);
+ if ( lr->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork &&
+ lr->GetLinkData () == addr)
+ {
+ return temp;
+ }
+ }
+ }
+ return 0;
+}
+
// ---------------------------------------------------------------------------
//
// GlobalRouteManagerImpl Implementation
@@ -359,13 +393,12 @@
for (uint32_t j = 0; j < numLSAs; ++j)
{
- GlobalRouterLSA* lsa = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa = new GlobalRoutingLSA ();
//
// This is the call to actually fetch a Link State Advertisement from the
// router.
//
rtr->GetLSA (j, *lsa);
- NS_DEBUG ("LSA " << j);
NS_DEBUG (*lsa);
//
// Write the newly discovered link state advertisement to the database.
@@ -453,52 +486,86 @@
GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
{
SPFVertex* w = 0;
- GlobalRouterLSA* w_lsa = 0;
+ GlobalRoutingLSA* w_lsa = 0;
+ GlobalRoutingLinkRecord *l = 0;
uint32_t distance = 0;
+ uint32_t numRecordsInVertex = 0;
NS_DEBUG ("GlobalRouteManagerImpl::SPFNext ()");
-//
-// Always true for now, since all our LSAs are RouterLSAs.
-//
- if (v->GetVertexType () == SPFVertex::VertexRouter)
+
+// V points to a Router-LSA or Network-LSA
+// Loop over the links in router LSA or attached routers in Network LSA
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
{
- if (true)
+ numRecordsInVertex = v->GetLSA ()->GetNLinkRecords ();
+ }
+ if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ numRecordsInVertex = v->GetLSA ()->GetNAttachedRouters ();
+ }
+
+ for (uint32_t i = 0; i < numRecordsInVertex; i++)
+ {
+// Get w_lsa: In case of V is Router-LSA
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
{
NS_DEBUG ("SPFNext: Examining " << v->GetVertexId () << "'s " <<
v->GetLSA ()->GetNLinkRecords () << " link records");
//
-// Walk the list of link records in the link state advertisement associated
-// with the "current" router (represented by vertex <v>).
-//
- for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
- {
-//
// (a) If this is a link to a stub network, examine the next link in V's LSA.
// Links to stub networks will be considered in the second stage of the
// shortest path calculation.
//
- GlobalRouterLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
- if (l->GetLinkType () == GlobalRouterLinkRecord::StubNetwork)
- {
- NS_DEBUG ("SPFNext: Found a Stub record to " <<
- l->GetLinkId ());
- continue;
- }
+ l = v->GetLSA ()->GetLinkRecord (i);
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+ {
+ NS_DEBUG ("SPFNext: Found a Stub record to " <<
+ l->GetLinkId ());
+ continue;
+ }
//
// (b) Otherwise, W is a transit vertex (router or transit network). Look up
// the vertex W's LSA (router-LSA or network-LSA) in Area A's link state
// database.
//
- if (l->GetLinkType () == GlobalRouterLinkRecord::PointToPoint)
- {
+ if (l->GetLinkType () == GlobalRoutingLinkRecord::PointToPoint)
+ {
//
// Lookup the link state advertisement of the new link -- we call it <w> in
// the link state database.
//
- w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
- NS_ASSERT (w_lsa);
- NS_DEBUG ("SPFNext: Found a P2P record from " <<
- v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+ NS_ASSERT (w_lsa);
+ NS_DEBUG ("SPFNext: Found a P2P record from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+ else if (l->GetLinkType () ==
+ GlobalRoutingLinkRecord::TransitNetwork)
+ {
+ w_lsa = m_lsdb->GetLSA (l->GetLinkId ());
+ NS_ASSERT (w_lsa);
+ NS_DEBUG ("SPFNext: Found a Transit record from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+ else
+ {
+ NS_ASSERT_MSG (0, "illegal Link Type");
+ }
+ }
+// Get w_lsa: In case of V is Network-LSA
+ if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ w_lsa = m_lsdb->GetLSAByLinkData
+ (v->GetLSA ()->GetAttachedRouter (i));
+ if (!w_lsa)
+ {
+ continue;
+ }
+ NS_DEBUG ("SPFNext: Found a Network LSA from " <<
+ v->GetVertexId () << " to " << w_lsa->GetLinkStateId ());
+ }
+
+// Note: w_lsa at this point may be either RouterLSA or NetworkLSA
//
// (c) If vertex W is already on the shortest-path tree, examine the next
// link in the LSA.
@@ -506,57 +573,56 @@
// If the link is to a router that is already in the shortest path first tree
// then we have it covered -- ignore it.
//
- if (w_lsa->GetStatus () ==
- GlobalRouterLSA::LSA_SPF_IN_SPFTREE)
- {
- NS_DEBUG ("SPFNext: Skipping-> LSA "<<
- w_lsa->GetLinkStateId () << " already in SPF tree");
- continue;
- }
-//
-// The link is to a router we haven't dealt with yet.
+ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_IN_SPFTREE)
+ {
+ NS_DEBUG ("SPFNext: Skipping-> LSA "<<
+ w_lsa->GetLinkStateId () << " already in SPF tree");
+ continue;
+ }
//
// (d) Calculate the link state cost D of the resulting path from the root to
// vertex W. D is equal to the sum of the link state cost of the (already
// calculated) shortest path to vertex V and the advertised cost of the link
// between vertices V and W.
//
- distance = v->GetDistanceFromRoot () + l->GetMetric ();
-
- NS_DEBUG ("SPFNext: Considering w_lsa " <<
- w_lsa->GetLinkStateId ());
+ if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
+ {
+ distance = v->GetDistanceFromRoot () + l->GetMetric ();
+ }
+ else
+ {
+ distance = v->GetDistanceFromRoot ();
+ }
- if (w_lsa->GetStatus () ==
- GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
- {
-//
-// If we haven't yet considered the link represented by <w> we have to create
-// a new SPFVertex to represent it.
-//
- w = new SPFVertex (w_lsa);
-//
+ NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ());
+
+// Is there already vertex w in candidate list?
+ if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
+ {
+
+// prepare vertex w
+ w = new SPFVertex (w_lsa);
+// Calculate nexthop to w
// We need to figure out how to actually get to the new router represented
// by <w>. This will (among other things) find the next hop address to send
// packets destined for this network to, and also find the outbound interface
// used to forward the packets.
//
- if (SPFNexthopCalculation (v, w, l, distance))
- {
- w_lsa->SetStatus (
- GlobalRouterLSA::LSA_SPF_CANDIDATE);
+ if (SPFNexthopCalculation (v, w, l, distance))
+ {
+ w_lsa->SetStatus (GlobalRoutingLSA::LSA_SPF_CANDIDATE);
//
// Push this new vertex onto the priority queue (ordered by distance from the
// root node).
//
- candidate.Push (w);
- NS_DEBUG ("SPFNext: Pushing " <<
- w->GetVertexId () << ", parent vertexId: " <<
- v->GetVertexId ());
- }
- }
- } else if (w_lsa->GetStatus () ==
- GlobalRouterLSA::LSA_SPF_CANDIDATE)
- {
+ candidate.Push (w);
+ NS_DEBUG ("SPFNext: Pushing " <<
+ w->GetVertexId () << ", parent vertexId: " <<
+ v->GetVertexId ());
+ }
+ }
+ else if (w_lsa->GetStatus () == GlobalRoutingLSA::LSA_SPF_CANDIDATE)
+ {
//
// We have already considered the link represented by <w>. What wse have to
// do now is to decide if this new router represents a route with a shorter
@@ -564,23 +630,23 @@
//
// So, locate the vertex in the candidate queue and take a look at the
// distance.
- w = candidate.Find (w_lsa->GetLinkStateId ());
- if (w->GetDistanceFromRoot () < distance)
- {
+ w = candidate.Find (w_lsa->GetLinkStateId ());
+ if (w->GetDistanceFromRoot () < distance)
+ {
//
// This is not a shorter path, so don't do anything.
//
- continue;
- }
- else if (w->GetDistanceFromRoot () == distance)
- {
+ continue;
+ }
+ else if (w->GetDistanceFromRoot () == distance)
+ {
//
// This path is one with an equal cost. Do nothing for now -- we're not doing
// equal-cost multipath cases yet.
//
- }
- else
- {
+ }
+ else
+ {
//
// this path represents a new, lower-cost path to <w> (the vertex we found in
// the current link record of the link state advertisement of the current root
@@ -589,27 +655,26 @@
// N.B. the nexthop_calculation is conditional, if it finds a valid nexthop
// it will call spf_add_parents, which will flush the old parents
//
- if (SPFNexthopCalculation (v, w, l, distance))
- {
+ if (SPFNexthopCalculation (v, w, l, distance))
+ {
//
// If we've changed the cost to get to the vertex represented by <w>, we
// must reorder the priority queue keyed to that cost.
//
- candidate.Reorder ();
- }
- }
- } // point-to-point
- } // for loop
- }
- }
+ candidate.Reorder ();
+ }
+ } // new lower cost path found
+ } // end W is already on the candidate list
+ } // end loop over the links in V's LSA
}
//
// This method is derived from quagga ospf_next_hop_calculation() 16.1.1.
//
-// Calculate the next hop IP address and the outgoing interface required to
-// get packets from the root through <v> (parent) to vertex <w> (destination),
-// over a given distance.
+// Calculate nexthop from root through V (parent) to vertex W (destination)
+// with given distance from root->W.
+//
+// As appropriate, set w's parent, distance, and nexthop information
//
// For now, this is greatly simplified from the quagga code
//
@@ -617,10 +682,19 @@
GlobalRouteManagerImpl::SPFNexthopCalculation (
SPFVertex* v,
SPFVertex* w,
- GlobalRouterLinkRecord* l,
+ GlobalRoutingLinkRecord* l,
uint32_t distance)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFNexthopCalculation ()");
+
+// If w is a NetworkVertex, l should be null
+/*
+ if (w->GetVertexType () == SPFVertex::VertexNetwork && l)
+ {
+ NS_ASSERT_MSG(0, "Error: SPFNexthopCalculation parameter problem");
+ }
+*/
+
//
// The vertex m_spfroot is a distinguished vertex representing the node at
// the root of the calculations. That is, it is the node for which we are
@@ -669,7 +743,8 @@
// return the link record describing the link from <w> to <v>. Think of it as
// SPFGetLink.
//
- GlobalRouterLinkRecord *linkRemote = 0;
+ NS_ASSERT(l);
+ GlobalRoutingLinkRecord *linkRemote = 0;
linkRemote = SPFGetNextLink (w, v, linkRemote);
//
// At this point, <l> is the Global Router Link Record describing the point-
@@ -695,6 +770,56 @@
v->GetVertexId () << " to " << w->GetVertexId () <<
" goes through next hop " << w->GetNextHop () <<
" via outgoing interface " << w->GetOutgoingInterfaceId ());
+ } // end W is a router vertes
+ else
+ {
+ NS_ASSERT (w->GetVertexType () == SPFVertex::VertexNetwork);
+// W is a directly connected network; no next hop is required
+ GlobalRoutingLSA* w_lsa = w->GetLSA ();
+ NS_ASSERT (w_lsa->GetLSType () == GlobalRoutingLSA::NetworkLSA);
+// Find outgoing interface ID for this network
+ w->SetOutgoingInterfaceId (
+ FindOutgoingInterfaceId (w_lsa->GetLinkStateId (),
+ w_lsa->GetNetworkLSANetworkMask () ));
+ w->SetDistanceFromRoot (distance);
+ w->SetParent (v);
+ NS_DEBUG ("SPFNexthopCalculation: Next hop from " <<
+ v->GetVertexId () << " to network " << w->GetVertexId () <<
+ " via outgoing interface " << w->GetOutgoingInterfaceId ());
+ return 1;
+ }
+ } // end v is the root
+ else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+// See if any of v's parents are the root
+ if (v->GetParent () == m_spfroot)
+ {
+// 16.1.1 para 5. ...the parent vertex is a network that
+// directly connects the calculating router to the destination
+// router. The list of next hops is then determined by
+// examining the destination's router-LSA...
+ NS_ASSERT (w->GetVertexType () == SPFVertex::VertexRouter);
+ GlobalRoutingLinkRecord *linkRemote = 0;
+ while ((linkRemote = SPFGetNextLink (w, v, linkRemote)))
+ {
+/* ...For each link in the router-LSA that points back to the
+ * parent network, the link's Link Data field provides the IP
+ * address of a next hop router. The outgoing interface to
+ * use can then be derived from the next hop IP address (or
+ * it can be inherited from the parent network).
+ */
+ w->SetNextHop(linkRemote->GetLinkData ());
+ w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
+ NS_DEBUG ("SPFNexthopCalculation: Next hop from " <<
+ v->GetVertexId () << " to " << w->GetVertexId () <<
+ " goes through next hop " << w->GetNextHop () <<
+ " via outgoing interface " << w->GetOutgoingInterfaceId ());
+ }
+ }
+ else
+ {
+ w->SetNextHop (v->GetNextHop ());
+ w->SetOutgoingInterfaceId (v->GetOutgoingInterfaceId ());
}
}
else
@@ -736,19 +861,17 @@
// to <w>. If prev_link is not NULL, we return a Global Router Link Record
// representing a possible *second* link from <v> to <w>.
//
-// BUGBUG FIXME: This seems to be a bug. Shouldn't this function look for
-// any link records after pre_link and not just after the first?
-//
- GlobalRouterLinkRecord*
+ GlobalRoutingLinkRecord*
GlobalRouteManagerImpl::SPFGetNextLink (
SPFVertex* v,
SPFVertex* w,
- GlobalRouterLinkRecord* prev_link)
+ GlobalRoutingLinkRecord* prev_link)
{
NS_DEBUG ("GlobalRouteManagerImpl::SPFGetNextLink ()");
bool skip = true;
- GlobalRouterLinkRecord* l;
+ bool found_prev_link = false;
+ GlobalRoutingLinkRecord* l;
//
// If prev_link is 0, we are really looking for the first link, not the next
// link.
@@ -756,6 +879,7 @@
if (prev_link == 0)
{
skip = false;
+ found_prev_link = true;
}
//
// Iterate through the Global Router Link Records advertised by the vertex
@@ -765,10 +889,6 @@
for (uint32_t i = 0; i < v->GetLSA ()->GetNLinkRecords (); ++i)
{
l = v->GetLSA ()->GetLinkRecord (i);
- if (l->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
- {
- continue;
- }
//
// The link ID of a link record representing a point-to-point link is set to
// the router ID of the neighboring router -- the router to which the link
@@ -777,8 +897,16 @@
// We're just checking to see if the link <l> is actually the link from <v> to
// <w>.
//
- if (l->GetLinkId () == w->GetVertexId ()) {
- NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " <<
+ if (l->GetLinkId () == w->GetVertexId ())
+ {
+ if (!found_prev_link)
+ {
+ NS_DEBUG ("SPFGetNextLink: Skipping links before prev_link found");
+ found_prev_link = true;
+ continue;
+ }
+
+ NS_DEBUG ("SPFGetNextLink: Found matching link l: linkId = " <<
l->GetLinkId () << " linkData = " << l->GetLinkData ());
//
// If skip is false, don't (not too surprisingly) skip the link found -- it's
@@ -849,7 +977,7 @@
//
m_spfroot= v;
v->SetDistanceFromRoot (0);
- v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
+ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
for (;;)
{
@@ -894,7 +1022,7 @@
// Update the status field of the vertex to indicate that it is in the SPF
// tree.
//
- v->GetLSA ()->SetStatus (GlobalRouterLSA::LSA_SPF_IN_SPFTREE);
+ v->GetLSA ()->SetStatus (GlobalRoutingLSA::LSA_SPF_IN_SPFTREE);
//
// The current vertex has a parent pointer. By calling this rather oddly
// named method (blame quagga) we add the current vertex to the list of
@@ -932,7 +1060,18 @@
// through its point-to-point links, adding a *host* route to the local IP
// address (at the <v> side) for each of those links.
//
- SPFIntraAddRouter (v);
+ if (v->GetVertexType () == SPFVertex::VertexRouter)
+ {
+ SPFIntraAddRouter (v);
+ }
+ else if (v->GetVertexType () == SPFVertex::VertexNetwork)
+ {
+ SPFIntraAddTransit (v);
+ }
+ else
+ {
+ NS_ASSERT_MSG(0, "illegal SPFVertex type");
+ }
//
// RFC2328 16.1. (5).
//
@@ -1026,6 +1165,80 @@
}
//
+// XXX This should probably be a method on Ipv4
+//
+// Return the interface index corresponding to a given IP address
+//
+ uint32_t
+GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask)
+{
+//
+// We have an IP address <a> and a vertex ID of the root of the SPF tree.
+// The question is what interface index does this address correspond to.
+// The answer is a little complicated since we have to find a pointer to
+// the node corresponding to the vertex ID, find the Ipv4 interface on that
+// node in order to iterate the interfaces and find the one corresponding to
+// the address in question.
+//
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+//
+// Walk the list of nodes in the system looking for the one corresponding to
+// the node at the root of the SPF tree. This is the node for which we are
+// building the routing table.
+//
+ std::vector<Ptr<Node> >::iterator i = NodeList::Begin ();
+ for (; i != NodeList::End (); i++)
+ {
+ Ptr<Node> node = *i;
+
+ Ptr<GlobalRouter> rtr =
+ node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+//
+// If the node doesn't have a GlobalRouter interface it can't be the one
+// we're interested in.
+//
+ if (rtr == 0)
+ {
+ continue;
+ }
+
+ if (rtr->GetRouterId () == routerId)
+ {
+//
+// This is the node we're building the routing table for. We're going to need
+// the Ipv4 interface to look for the ipv4 interface index. Since this node
+// is participating in routing IP version 4 packets, it certainly must have
+// an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+ "QI for <Ipv4> interface failed");
+//
+// Look through the interfaces on this node for one that has the IP address
+// we're looking for. If we find one, return the corresponding interface
+// index.
+//
+ for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++)
+ {
+ if (ipv4->GetAddress (i).CombineMask(amask) ==
+ a.CombineMask(amask) )
+ {
+ NS_DEBUG (
+ "GlobalRouteManagerImpl::FindOutgoingInterfaceId (): "
+ "Interface match for " << a);
+ return i;
+ }
+ }
+ }
+ }
+//
+// Couldn't find it.
+//
+ return 0;
+}
+
+//
// This method is derived from quagga ospf_intra_add_router ()
//
// This is where we are actually going to add the host routes to the routing
@@ -1109,7 +1322,7 @@
// Link Records corresponding to links off of that vertex / node. We're going
// to be interested in the records corresponding to point-to-point links.
//
- GlobalRouterLSA *lsa = v->GetLSA ();
+ GlobalRoutingLSA *lsa = v->GetLSA ();
NS_ASSERT_MSG (lsa,
"GlobalRouteManagerImpl::SPFIntraAddRouter (): "
"Expected valid LSA in SPFVertex* v");
@@ -1128,8 +1341,8 @@
//
// We are only concerned about point-to-point links
//
- GlobalRouterLinkRecord *lr = lsa->GetLinkRecord (j);
- if (lr->GetLinkType () != GlobalRouterLinkRecord::PointToPoint)
+ GlobalRoutingLinkRecord *lr = lsa->GetLinkRecord (j);
+ if (lr->GetLinkType () != GlobalRoutingLinkRecord::PointToPoint)
{
continue;
}
@@ -1162,6 +1375,91 @@
}
}
}
+ void
+GlobalRouteManagerImpl::SPFIntraAddTransit (SPFVertex* v)
+{
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit ()");
+
+ NS_ASSERT_MSG (m_spfroot,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): Root pointer not set");
+//
+// The root of the Shortest Path First tree is the router to which we are
+// going to write the actual routing table entries. The vertex corresponding
+// to this router has a vertex ID which is the router ID of that node. We're
+// going to use this ID to discover which node it is that we're actually going
+// to update.
+//
+ Ipv4Address routerId = m_spfroot->GetVertexId ();
+
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "Vertex ID = " << routerId);
+//
+// We need to walk the list of nodes looking for the one that has the router
+// ID corresponding to the root vertex. This is the one we're going to write
+// the routing information to.
+//
+ std::vector<Ptr<Node> >::iterator i = NodeList::Begin ();
+ for (; i != NodeList::End (); i++)
+ {
+ Ptr<Node> node = *i;
+//
+// The router ID is accessible through the GlobalRouter interface, so we need
+// to QI for that interface. If there's no GlobalRouter interface, the node
+// in question cannot be the router we want, so we continue.
+//
+ Ptr<GlobalRouter> rtr =
+ node->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+
+ if (rtr == 0)
+ {
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "No GlobalRouter interface on node " << node->GetId ());
+ continue;
+ }
+//
+// If the router ID of the current node is equal to the router ID of the
+// root of the SPF tree, then this node is the one for which we need to
+// write the routing tables.
+//
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "Considering router " << rtr->GetRouterId ());
+
+ if (rtr->GetRouterId () == routerId)
+ {
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "setting routes for node " << node->GetId ());
+//
+// Routing information is updated using the Ipv4 interface. We need to QI
+// for that interface. If the node is acting as an IP version 4 router, it
+// should absolutely have an Ipv4 interface.
+//
+ Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG (ipv4,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "QI for <Ipv4> interface failed");
+//
+// Get the Global Router Link State Advertisement from the vertex we're
+// adding the routes to. The LSA will have a number of attached Global Router
+// Link Records corresponding to links off of that vertex / node. We're going
+// to be interested in the records corresponding to point-to-point links.
+//
+ GlobalRoutingLSA *lsa = v->GetLSA ();
+ NS_ASSERT_MSG (lsa,
+ "GlobalRouteManagerImpl::SPFIntraAddTransit (): "
+ "Expected valid LSA in SPFVertex* v");
+ Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
+ Ipv4Address tempip = lsa->GetLinkStateId ();
+ tempip = tempip.CombineMask (tempmask);
+ ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
+ v->GetOutgoingInterfaceId ());
+ NS_DEBUG ("GlobalRouteManagerImpl::SPFIntraAddNetwork (): "
+ " Node " << node->GetId () <<
+ " add network route to " << tempip <<
+ " using next hop " << v->GetNextHop () <<
+ " via interface " << v->GetOutgoingInterfaceId ());
+ }
+ }
+}
// Derived from quagga ospf_vertex_add_parents ()
//
@@ -1254,81 +1552,84 @@
// link2: 10.1.3.1/30, 10.1.3.2/30
//
// Router 0
- GlobalRouterLinkRecord* lr0 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr0 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2", // router ID 0.0.0.2
"10.1.1.1", // local ID
1); // metric
- GlobalRouterLinkRecord* lr1 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr1 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.1.1",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa0 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa0 = new GlobalRoutingLSA ();
+ lsa0->SetLSType (GlobalRoutingLSA::RouterLSA);
lsa0->SetLinkStateId ("0.0.0.0");
lsa0->SetAdvertisingRouter ("0.0.0.0");
lsa0->AddLinkRecord (lr0);
lsa0->AddLinkRecord (lr1);
// Router 1
- GlobalRouterLinkRecord* lr2 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr2 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2",
"10.1.2.1",
1);
- GlobalRouterLinkRecord* lr3 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr3 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.1",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa1 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa1 = new GlobalRoutingLSA ();
+ lsa1->SetLSType (GlobalRoutingLSA::RouterLSA);
lsa1->SetLinkStateId ("0.0.0.1");
lsa1->SetAdvertisingRouter ("0.0.0.1");
lsa1->AddLinkRecord (lr2);
lsa1->AddLinkRecord (lr3);
// Router 2
- GlobalRouterLinkRecord* lr4 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr4 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.0",
"10.1.1.2",
1);
- GlobalRouterLinkRecord* lr5 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr5 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.1.2",
"255.255.255.252",
1);
- GlobalRouterLinkRecord* lr6 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr6 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.1",
"10.1.2.2",
1);
- GlobalRouterLinkRecord* lr7 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr7 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.2",
"255.255.255.252",
1);
- GlobalRouterLinkRecord* lr8 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr8 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.3",
"10.1.3.2",
1);
- GlobalRouterLinkRecord* lr9 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr9 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.3.2",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa2 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa2 = new GlobalRoutingLSA ();
+ lsa2->SetLSType (GlobalRoutingLSA::RouterLSA);
lsa2->SetLinkStateId ("0.0.0.2");
lsa2->SetAdvertisingRouter ("0.0.0.2");
lsa2->AddLinkRecord (lr4);
@@ -1339,19 +1640,20 @@
lsa2->AddLinkRecord (lr9);
// Router 3
- GlobalRouterLinkRecord* lr10 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::PointToPoint,
+ GlobalRoutingLinkRecord* lr10 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::PointToPoint,
"0.0.0.2",
"10.1.2.1",
1);
- GlobalRouterLinkRecord* lr11 = new GlobalRouterLinkRecord (
- GlobalRouterLinkRecord::StubNetwork,
+ GlobalRoutingLinkRecord* lr11 = new GlobalRoutingLinkRecord (
+ GlobalRoutingLinkRecord::StubNetwork,
"10.1.2.1",
"255.255.255.252",
1);
- GlobalRouterLSA* lsa3 = new GlobalRouterLSA ();
+ GlobalRoutingLSA* lsa3 = new GlobalRoutingLSA ();
+ lsa3->SetLSType (GlobalRoutingLSA::RouterLSA);
lsa3->SetLinkStateId ("0.0.0.3");
lsa3->SetAdvertisingRouter ("0.0.0.3");
lsa3->AddLinkRecord (lr10);
--- a/src/routing/global-routing/global-route-manager-impl.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-route-manager-impl.h Tue Aug 28 12:05:35 2007 +0200
@@ -102,10 +102,10 @@
*
* @see SPFVertex::SPFVertex ()
* @see VertexType
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @param lsa The Link State Advertisement used for finding initial values.
*/
- SPFVertex(GlobalRouterLSA* lsa);
+ SPFVertex(GlobalRoutingLSA* lsa);
/**
* @brief Destroy an SPFVertex (Shortest Path First Vertex).
@@ -181,12 +181,12 @@
* @internal
*
* @see GlobalRouter
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @see GlobalRouter::DiscoverLSAs ()
- * @returns A pointer to the GlobalRouterLSA found by the router represented
+ * @returns A pointer to the GlobalRoutingLSA found by the router represented
* by this SPFVertex object.
*/
- GlobalRouterLSA* GetLSA (void) const;
+ GlobalRoutingLSA* GetLSA (void) const;
/**
* @brief Set the Global Router Link State Advertisement returned by the
@@ -196,13 +196,13 @@
*
* @see SPFVertex::GetLSA ()
* @see GlobalRouter
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @see GlobalRouter::DiscoverLSAs ()
* @warning Ownership of the LSA is transferred to the "this" SPFVertex. You
* must not delete the LSA after calling this method.
- * @param lsa A pointer to the GlobalRouterLSA.
+ * @param lsa A pointer to the GlobalRoutingLSA.
*/
- void SetLSA (GlobalRouterLSA* lsa);
+ void SetLSA (GlobalRoutingLSA* lsa);
/**
* @brief Get the distance from the root vertex to "this" SPFVertex object.
@@ -283,8 +283,8 @@
* SPFVertex."
*
* @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
* @returns The interface index to use when forwarding packets to the host
* or network represented by "this" SPFVertex.
*/
@@ -325,8 +325,8 @@
* by "this" SPFVertex.
*
* @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
* @param id The interface index to use when forwarding packets to the host or
* network represented by "this" SPFVertex.
*/
@@ -368,8 +368,8 @@
* by 'this' SPFVertex."
*
* @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
* @returns The IP address to use when forwarding packets to the host
* or network represented by "this" SPFVertex.
*/
@@ -411,8 +411,8 @@
* host represented by 'this' SPFVertex."
*
* @see GlobalRouter
- * @see GlobalRouterLSA
- * @see GlobalRouterLinkRecord
+ * @see GlobalRoutingLSA
+ * @see GlobalRoutingLinkRecord
* @param nextHop The IP address to use when forwarding packets to the host
* or network represented by "this" SPFVertex.
*/
@@ -543,7 +543,7 @@
private:
VertexType m_vertexType;
Ipv4Address m_vertexId;
- GlobalRouterLSA* m_lsa;
+ GlobalRoutingLSA* m_lsa;
uint32_t m_distanceFromRoot;
uint32_t m_rootOif;
Ipv4Address m_nextHop;
@@ -604,33 +604,47 @@
* State Database.
* @internal
*
- * The IPV4 address and the GlobalRouterLSA given as parameters are converted
+ * The IPV4 address and the GlobalRoutingLSA given as parameters are converted
* to an STL pair and are inserted into the database map.
*
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @see Ipv4Address
* @param addr The IP address associated with the LSA. Typically the Router
* ID.
* @param lsa A pointer to the Link State Advertisement for the router.
*/
- void Insert(Ipv4Address addr, GlobalRouterLSA* lsa);
+ void Insert(Ipv4Address addr, GlobalRoutingLSA* lsa);
/**
* @brief Look up the Link State Advertisement associated with the given
- * IP Address.
+ * link state ID (address).
* @internal
*
* The database map is searched for the given IPV4 address and corresponding
- * GlobalRouterLSA is returned.
+ * GlobalRoutingLSA is returned.
*
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @see Ipv4Address
* @param addr The IP address associated with the LSA. Typically the Router
* ID.
* @returns A pointer to the Link State Advertisement for the router specified
* by the IP address addr.
*/
- GlobalRouterLSA* GetLSA (Ipv4Address addr) const;
+ GlobalRoutingLSA* GetLSA (Ipv4Address addr) const;
+/**
+ * @brief Look up the Link State Advertisement associated with the given
+ * link state ID (address). This is a variation of the GetLSA call
+ * to allow the LSA to be found by matching addr with the LinkData field
+ * of the TransitNetwork link record.
+ * @internal
+ *
+ * @see GetLSA
+ * @param addr The IP address associated with the LSA. Typically the Router
+ * @returns A pointer to the Link State Advertisement for the router specified
+ * by the IP address addr.
+ * ID.
+ */
+ GlobalRoutingLSA* GetLSAByLinkData (Ipv4Address addr) const;
/**
* @brief Set all LSA flags to an initialized state, for SPF computation
@@ -641,14 +655,14 @@
* prior to each SPF calculation to reset the state of the SPFVertex structures
* that will reference the LSAs during the calculation.
*
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @see SPFVertex
*/
void Initialize ();
private:
- typedef std::map<Ipv4Address, GlobalRouterLSA*> LSDBMap_t;
- typedef std::pair<Ipv4Address, GlobalRouterLSA*> LSDBPair_t;
+ typedef std::map<Ipv4Address, GlobalRoutingLSA*> LSDBMap_t;
+ typedef std::pair<Ipv4Address, GlobalRoutingLSA*> LSDBPair_t;
LSDBMap_t m_database;
/**
@@ -734,12 +748,14 @@
void SPFCalculate (Ipv4Address root);
void SPFNext (SPFVertex*, CandidateQueue&);
int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w,
- GlobalRouterLinkRecord* l, uint32_t distance);
+ GlobalRoutingLinkRecord* l, uint32_t distance);
void SPFVertexAddParent (SPFVertex* v);
- GlobalRouterLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w,
- GlobalRouterLinkRecord* prev_link);
+ GlobalRoutingLinkRecord* SPFGetNextLink (SPFVertex* v, SPFVertex* w,
+ GlobalRoutingLinkRecord* prev_link);
void SPFIntraAddRouter (SPFVertex* v);
+ void SPFIntraAddTransit (SPFVertex* v);
uint32_t FindOutgoingInterfaceId (Ipv4Address a);
+ uint32_t FindOutgoingInterfaceId (Ipv4Address a, Ipv4Mask amask);
};
} // namespace ns3
--- a/src/routing/global-routing/global-router-interface.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-router-interface.cc Tue Aug 28 12:05:35 2007 +0200
@@ -28,21 +28,21 @@
// ---------------------------------------------------------------------------
//
-// GlobalRouterLinkRecord Implementation
+// GlobalRoutingLinkRecord Implementation
//
// ---------------------------------------------------------------------------
-GlobalRouterLinkRecord::GlobalRouterLinkRecord ()
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()
:
m_linkId ("0.0.0.0"),
m_linkData ("0.0.0.0"),
m_linkType (Unknown),
m_metric (0)
{
- NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord ()");
}
-GlobalRouterLinkRecord::GlobalRouterLinkRecord (
+GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (
LinkType linkType,
Ipv4Address linkId,
Ipv4Address linkData,
@@ -53,116 +53,126 @@
m_linkType (linkType),
m_metric (metric)
{
- NS_DEBUG("GlobalRouterLinkRecord::GlobalRouterLinkRecord (" <<
+ NS_DEBUG("GlobalRoutingLinkRecord::GlobalRoutingLinkRecord (" <<
linkType << ", " << linkId << ", " << linkData << ", " << metric << ")");
}
-GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()
+GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()
{
- NS_DEBUG("GlobalRouterLinkRecord::~GlobalRouterLinkRecord ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::~GlobalRoutingLinkRecord ()");
}
Ipv4Address
-GlobalRouterLinkRecord::GetLinkId (void) const
+GlobalRoutingLinkRecord::GetLinkId (void) const
{
- NS_DEBUG("GlobalRouterLinkRecord::GetLinkId ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::GetLinkId ()");
return m_linkId;
}
void
-GlobalRouterLinkRecord::SetLinkId (Ipv4Address addr)
+GlobalRoutingLinkRecord::SetLinkId (Ipv4Address addr)
{
- NS_DEBUG("GlobalRouterLinkRecord::SetLinkId ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::SetLinkId ()");
m_linkId = addr;
}
Ipv4Address
-GlobalRouterLinkRecord::GetLinkData (void) const
+GlobalRoutingLinkRecord::GetLinkData (void) const
{
- NS_DEBUG("GlobalRouterLinkRecord::GetLinkData ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::GetLinkData ()");
return m_linkData;
}
void
-GlobalRouterLinkRecord::SetLinkData (Ipv4Address addr)
+GlobalRoutingLinkRecord::SetLinkData (Ipv4Address addr)
{
- NS_DEBUG("GlobalRouterLinkRecord::SetLinkData ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::SetLinkData ()");
m_linkData = addr;
}
- GlobalRouterLinkRecord::LinkType
-GlobalRouterLinkRecord::GetLinkType (void) const
+ GlobalRoutingLinkRecord::LinkType
+GlobalRoutingLinkRecord::GetLinkType (void) const
{
- NS_DEBUG("GlobalRouterLinkRecord::GetLinkType ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::GetLinkType ()");
return m_linkType;
}
void
-GlobalRouterLinkRecord::SetLinkType (
- GlobalRouterLinkRecord::LinkType linkType)
+GlobalRoutingLinkRecord::SetLinkType (
+ GlobalRoutingLinkRecord::LinkType linkType)
{
- NS_DEBUG("GlobalRouterLinkRecord::SetLinkType ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::SetLinkType ()");
m_linkType = linkType;
}
uint32_t
-GlobalRouterLinkRecord::GetMetric (void) const
+GlobalRoutingLinkRecord::GetMetric (void) const
{
- NS_DEBUG("GlobalRouterLinkRecord::GetMetric ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::GetMetric ()");
return m_metric;
}
void
-GlobalRouterLinkRecord::SetMetric (uint32_t metric)
+GlobalRoutingLinkRecord::SetMetric (uint32_t metric)
{
- NS_DEBUG("GlobalRouterLinkRecord::SetMetric ()");
+ NS_DEBUG("GlobalRoutingLinkRecord::SetMetric ()");
m_metric = metric;
}
// ---------------------------------------------------------------------------
//
-// GlobalRouterLSA Implementation
+// GlobalRoutingLSA Implementation
//
// ---------------------------------------------------------------------------
-GlobalRouterLSA::GlobalRouterLSA()
+GlobalRoutingLSA::GlobalRoutingLSA()
:
+ m_lsType (GlobalRoutingLSA::Unknown),
m_linkStateId("0.0.0.0"),
m_advertisingRtr("0.0.0.0"),
m_linkRecords(),
- m_status(GlobalRouterLSA::LSA_SPF_NOT_EXPLORED)
+ m_networkLSANetworkMask("0.0.0.0"),
+ m_attachedRouters(),
+ m_status(GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED)
{
- NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA ()");
+ NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA ()");
}
-GlobalRouterLSA::GlobalRouterLSA (
- GlobalRouterLSA::SPFStatus status,
+GlobalRoutingLSA::GlobalRoutingLSA (
+ GlobalRoutingLSA::SPFStatus status,
Ipv4Address linkStateId,
Ipv4Address advertisingRtr)
:
+ m_lsType (GlobalRoutingLSA::Unknown),
m_linkStateId(linkStateId),
m_advertisingRtr(advertisingRtr),
m_linkRecords(),
+ m_networkLSANetworkMask("0.0.0.0"),
+ m_attachedRouters(),
m_status(status)
{
- NS_DEBUG("GlobalRouterLSA::GlobalRouterLSA (" << status << ", " <<
+ NS_DEBUG("GlobalRoutingLSA::GlobalRoutingLSA (" << status << ", " <<
linkStateId << ", " << advertisingRtr << ")");
}
-GlobalRouterLSA::GlobalRouterLSA (GlobalRouterLSA& lsa)
- : m_linkStateId(lsa.m_linkStateId), m_advertisingRtr(lsa.m_advertisingRtr),
+GlobalRoutingLSA::GlobalRoutingLSA (GlobalRoutingLSA& lsa)
+ : m_lsType(lsa.m_lsType), m_linkStateId(lsa.m_linkStateId),
+ m_advertisingRtr(lsa.m_advertisingRtr),
+ m_networkLSANetworkMask(lsa.m_networkLSANetworkMask),
m_status(lsa.m_status)
{
NS_ASSERT_MSG(IsEmpty(),
- "GlobalRouterLSA::GlobalRouterLSA (): Non-empty LSA in constructor");
+ "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
CopyLinkRecords (lsa);
}
- GlobalRouterLSA&
-GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa)
+ GlobalRoutingLSA&
+GlobalRoutingLSA::operator= (const GlobalRoutingLSA& lsa)
{
+ m_lsType = lsa.m_lsType;
m_linkStateId = lsa.m_linkStateId;
m_advertisingRtr = lsa.m_advertisingRtr;
+ m_networkLSANetworkMask = lsa.m_networkLSANetworkMask,
m_status = lsa.m_status;
ClearLinkRecords ();
@@ -171,14 +181,14 @@
}
void
-GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa)
+GlobalRoutingLSA::CopyLinkRecords (const GlobalRoutingLSA& lsa)
{
for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
i != lsa.m_linkRecords.end ();
i++)
{
- GlobalRouterLinkRecord *pSrc = *i;
- GlobalRouterLinkRecord *pDst = new GlobalRouterLinkRecord;
+ GlobalRoutingLinkRecord *pSrc = *i;
+ GlobalRoutingLinkRecord *pDst = new GlobalRoutingLinkRecord;
pDst->SetLinkType (pSrc->GetLinkType ());
pDst->SetLinkId (pSrc->GetLinkId ());
@@ -187,48 +197,50 @@
m_linkRecords.push_back(pDst);
pDst = 0;
}
+
+ m_attachedRouters = lsa.m_attachedRouters;
}
-GlobalRouterLSA::~GlobalRouterLSA()
+GlobalRoutingLSA::~GlobalRoutingLSA()
{
- NS_DEBUG("GlobalRouterLSA::~GlobalRouterLSA ()");
+ NS_DEBUG("GlobalRoutingLSA::~GlobalRoutingLSA ()");
ClearLinkRecords ();
}
void
-GlobalRouterLSA::ClearLinkRecords(void)
+GlobalRoutingLSA::ClearLinkRecords(void)
{
for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
i != m_linkRecords.end ();
i++)
{
- NS_DEBUG("GlobalRouterLSA::ClearLinkRecords (): free link record");
+ NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords (): free link record");
- GlobalRouterLinkRecord *p = *i;
+ GlobalRoutingLinkRecord *p = *i;
delete p;
p = 0;
*i = 0;
}
- NS_DEBUG("GlobalRouterLSA::ClearLinkRecords(): clear list");
+ NS_DEBUG("GlobalRoutingLSA::ClearLinkRecords(): clear list");
m_linkRecords.clear();
}
uint32_t
-GlobalRouterLSA::AddLinkRecord (GlobalRouterLinkRecord* lr)
+GlobalRoutingLSA::AddLinkRecord (GlobalRoutingLinkRecord* lr)
{
m_linkRecords.push_back (lr);
return m_linkRecords.size ();
}
uint32_t
-GlobalRouterLSA::GetNLinkRecords (void) const
+GlobalRoutingLSA::GetNLinkRecords (void) const
{
return m_linkRecords.size ();
}
- GlobalRouterLinkRecord *
-GlobalRouterLSA::GetLinkRecord (uint32_t n) const
+ GlobalRoutingLinkRecord *
+GlobalRoutingLSA::GetLinkRecord (uint32_t n) const
{
uint32_t j = 0;
for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
@@ -240,70 +252,146 @@
return *i;
}
}
- NS_ASSERT_MSG(false, "GlobalRouterLSA::GetLinkRecord (): invalid index");
+ NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
return 0;
}
bool
-GlobalRouterLSA::IsEmpty (void) const
+GlobalRoutingLSA::IsEmpty (void) const
{
return m_linkRecords.size () == 0;
}
+ GlobalRoutingLSA::LSType
+GlobalRoutingLSA::GetLSType (void) const
+{
+ return m_lsType;
+}
+
+ void
+GlobalRoutingLSA::SetLSType (GlobalRoutingLSA::LSType typ)
+{
+ m_lsType = typ;
+}
+
Ipv4Address
-GlobalRouterLSA::GetLinkStateId (void) const
+GlobalRoutingLSA::GetLinkStateId (void) const
{
return m_linkStateId;
}
void
-GlobalRouterLSA::SetLinkStateId (Ipv4Address addr)
+GlobalRoutingLSA::SetLinkStateId (Ipv4Address addr)
{
m_linkStateId = addr;
}
Ipv4Address
-GlobalRouterLSA::GetAdvertisingRouter (void) const
+GlobalRoutingLSA::GetAdvertisingRouter (void) const
{
return m_advertisingRtr;
}
void
-GlobalRouterLSA::SetAdvertisingRouter (Ipv4Address addr)
+GlobalRoutingLSA::SetAdvertisingRouter (Ipv4Address addr)
{
m_advertisingRtr = addr;
}
- GlobalRouterLSA::SPFStatus
-GlobalRouterLSA::GetStatus (void) const
+ void
+GlobalRoutingLSA::SetNetworkLSANetworkMask (Ipv4Mask mask)
+{
+ m_networkLSANetworkMask = mask;
+}
+
+ Ipv4Mask
+GlobalRoutingLSA::GetNetworkLSANetworkMask (void) const
+{
+ return m_networkLSANetworkMask;
+}
+
+ GlobalRoutingLSA::SPFStatus
+GlobalRoutingLSA::GetStatus (void) const
{
return m_status;
}
+ uint32_t
+GlobalRoutingLSA::AddAttachedRouter (Ipv4Address addr)
+{
+ m_attachedRouters.push_back (addr);
+ return m_attachedRouters.size ();
+}
+
+ uint32_t
+GlobalRoutingLSA::GetNAttachedRouters (void) const
+{
+ return m_attachedRouters.size ();
+}
+
+ Ipv4Address
+GlobalRoutingLSA::GetAttachedRouter (uint32_t n) const
+{
+ uint32_t j = 0;
+ for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
+ i != m_attachedRouters.end ();
+ i++, j++)
+ {
+ if (j == n)
+ {
+ return *i;
+ }
+ }
+ NS_ASSERT_MSG(false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
+ return Ipv4Address("0.0.0.0");
+}
+
void
-GlobalRouterLSA::SetStatus (GlobalRouterLSA::SPFStatus status)
+GlobalRoutingLSA::SetStatus (GlobalRoutingLSA::SPFStatus status)
{
m_status = status;
}
void
-GlobalRouterLSA::Print (std::ostream &os) const
+GlobalRoutingLSA::Print (std::ostream &os) const
{
- os << "m_linkStateId = " << m_linkStateId << std::endl <<
+ os << "m_lsType = " << m_lsType << std::endl <<
+ "m_linkStateId = " << m_linkStateId << std::endl <<
"m_advertisingRtr = " << m_advertisingRtr << std::endl;
- for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
- i != m_linkRecords.end ();
- i++)
+ if (m_lsType == GlobalRoutingLSA::RouterLSA)
+ {
+ for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
+ i != m_linkRecords.end ();
+ i++)
+ {
+ GlobalRoutingLinkRecord *p = *i;
+ os << "----------" << std::endl;
+ os << "m_linkId = " << p->GetLinkId () << std::endl;
+ os << "m_linkData = " << p->GetLinkData () << std::endl;
+ }
+ }
+ else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
{
- GlobalRouterLinkRecord *p = *i;
os << "----------" << std::endl;
- os << "m_linkId = " << p->GetLinkId () << std::endl;
- os << "m_linkData = " << p->GetLinkData () << std::endl;
+ os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask
+ << std::endl;
+ for ( ListOfAttachedRouters_t::const_iterator i =
+ m_attachedRouters.begin ();
+ i != m_attachedRouters.end ();
+ i++)
+ {
+ Ipv4Address p = *i;
+ os << "attachedRouter = " << p << std::endl;
+ }
+ }
+ else
+ {
+ NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
}
}
-std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa)
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
{
lsa.Print (os);
return os;
@@ -350,7 +438,7 @@
{
NS_DEBUG("GlobalRouter::ClearLSAs (): free LSA");
- GlobalRouterLSA *p = *i;
+ GlobalRoutingLSA *p = *i;
delete p;
p = 0;
@@ -373,11 +461,16 @@
uint32_t
GlobalRouter::DiscoverLSAs (void)
{
- NS_DEBUG("GlobalRouter::DiscoverLSAs ()");
+ NS_DEBUG("GlobalRouter::DiscoverLSAs () for node " << m_node->GetId () );
NS_ASSERT_MSG(m_node,
"GlobalRouter::DiscoverLSAs (): <Node> interface not set");
ClearLSAs ();
+
+// While building the router-LSA, keep a list of those NetDevices for
+// which I am the designated router and need to later build a NetworkLSA
+ std::list<Ptr<NetDevice> > listOfDRInterfaces;
+
//
// We're aggregated to a node. We need to ask the node for a pointer to its
// Ipv4 interface. This is where the information regarding the attached
@@ -387,118 +480,252 @@
NS_ASSERT_MSG(ipv4Local,
"GlobalRouter::DiscoverLSAs (): QI for <Ipv4> interface failed");
//
-// We are, for now at least, only going to report RouterLSAs in this method.
-// What this means is that there is going to be one advertisement with some
-// number of link records. This means that GetNumLSAs will actually always
-// return exactly one.
+// Each node originates a Router-LSA
//
- GlobalRouterLSA *pLSA = new GlobalRouterLSA;
+ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+ pLSA->SetLSType (GlobalRoutingLSA::RouterLSA);
pLSA->SetLinkStateId (m_routerId);
pLSA->SetAdvertisingRouter (m_routerId);
- pLSA->SetStatus (GlobalRouterLSA::LSA_SPF_NOT_EXPLORED);
+ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
//
// We need to ask the node for the number of net devices attached. This isn't
// necessarily equal to the number of links to adjacent nodes (other routers)
// as the number of devices may include those for stub networks (e.g.,
-// ethernets, etc.). So we have to walk through the list of net devices and
-// pay attention to those that are directly connected to another router through
-// a point-to-point channel.
+// ethernets, etc.).
//
uint32_t numDevices = m_node->GetNDevices();
NS_DEBUG("GlobalRouter::DiscoverLSAs (): numDevices = " << numDevices);
-//
-// Loop through the devices looking for those connected to a point-to-point
-// channel.
-//
for (uint32_t i = 0; i < numDevices; ++i)
{
Ptr<NetDevice> ndLocal = m_node->GetDevice(i);
- if (!ndLocal->IsPointToPoint ())
+ if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
{
- NS_DEBUG("GlobalRouter::DiscoverLSAs (): non-point-to-point device");
- continue;
+ NS_DEBUG("GlobalRouter::DiscoverLSAs (): broadcast link");
+ GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+//
+// We need to determine whether we are on a transit or stub network
+// If we find at least one more router on this channel, we are a transit
+//
+//
+// Now, we have to find the Ipv4 interface whose netdevice is the one we
+// just found. This is still the IP on the local side of the channel. There
+// is a function to do this used down in the guts of the stack, but it's not
+// exported so we had to whip up an equivalent.
+//
+ uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
+ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+ NS_DEBUG("Working with local address " << addrLocal);
+//
+// Now, we're going to walk over to the remote net device on the other end of
+// the point-to-point channel we now know we have. This is where our adjacent
+// router (to use OSPF lingo) is running.
+//
+ Ptr<Channel> ch = ndLocal->GetChannel();
+ uint32_t nDevices = ch->GetNDevices();
+ if (nDevices == 1)
+ {
+ // This is a stub broadcast interface
+ NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA stub broadcast link");
+ // XXX in future, need to consider if >1 includes other routers
+ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+ // Link ID is IP network number of attached network
+ plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+ // Link Data is network mask; convert to Ipv4Address
+ Ipv4Address maskLocalAddr;
+ maskLocalAddr.Set(maskLocal.GetHostOrder ());
+ plr->SetLinkData (maskLocalAddr);
+ // Cost is interface's configured output cost (NOTYET)
+ plr->SetMetric (1);
+ pLSA->AddLinkRecord(plr);
+ plr = 0;
+ continue;
+ }
+ else
+ {
+ NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Broadcast link");
+ // multiple routers on a broadcast interface
+ // lowest IP address is designated router
+ plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+ // Link ID is IP interface address of designated router
+ Ipv4Address desigRtr =
+ FindDesignatedRouterForLink (m_node, ndLocal);
+ if (desigRtr == addrLocal)
+ {
+ listOfDRInterfaces.push_back (ndLocal);
+ NS_DEBUG("GlobalRouter::DiscoverLSAs (): " <<
+ m_node->GetId () << " is a DR");
+ }
+ plr->SetLinkId (desigRtr);
+ // Link Data is router's own IP address
+ plr->SetLinkData (addrLocal);
+ // Cost is interface's configured output cost (NOTYET)
+ plr->SetMetric (1);
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
+ continue;
+ }
}
-
- NS_DEBUG("GlobalRouter::DiscoverLSAs (): Point-to-point device");
+ else if (ndLocal->IsPointToPoint () )
+ {
+ NS_DEBUG("GlobalRouter::DiscoverLSAs (): Router-LSA Point-to-point device");
//
// Now, we have to find the Ipv4 interface whose netdevice is the one we
// just found. This is still the IP on the local side of the channel. There
// is a function to do this used down in the guts of the stack, but it's not
// exported so we had to whip up an equivalent.
//
- uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
+ uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
//
// Now that we have the Ipv4 interface index, we can get the address and mask
// we need.
//
- Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
- Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
- NS_DEBUG("Working with local address " << addrLocal);
+ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+ NS_DEBUG("Working with local address " << addrLocal);
//
// Now, we're going to walk over to the remote net device on the other end of
// the point-to-point channel we now know we have. This is where our adjacent
// router (to use OSPF lingo) is running.
//
- Ptr<Channel> ch = ndLocal->GetChannel();
- Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
+ Ptr<Channel> ch = ndLocal->GetChannel();
+ Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
//
// The adjacent net device is aggregated to a node. We need to ask that net
// device for its node, then ask that node for its Ipv4 interface.
//
- Ptr<Node> nodeRemote = ndRemote->GetNode();
- Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
- NS_ASSERT_MSG(ipv4Remote,
- "GlobalRouter::DiscoverLSAs (): QI for remote <Ipv4> failed");
+ Ptr<Node> nodeRemote = ndRemote->GetNode();
+ Ptr<Ipv4> ipv4Remote = nodeRemote->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT_MSG(ipv4Remote,
+ "GlobalRouter::DiscoverLSAs (): QI for remote <Ipv4> failed");
//
// Per the OSPF spec, we're going to need the remote router ID, so we might as
// well get it now.
//
- Ptr<GlobalRouter> srRemote =
- nodeRemote->QueryInterface<GlobalRouter> (GlobalRouter::iid);
- NS_ASSERT_MSG(srRemote,
- "GlobalRouter::DiscoverLSAs (): QI for remote <GlobalRouter> failed");
- Ipv4Address rtrIdRemote = srRemote->GetRouterId();
- NS_DEBUG("Working with remote router " << rtrIdRemote);
+ Ptr<GlobalRouter> srRemote =
+ nodeRemote->QueryInterface<GlobalRouter> (GlobalRouter::iid);
+ NS_ASSERT_MSG(srRemote,
+ "GlobalRouter::DiscoverLSAs():QI for remote <GlobalRouter> failed");
+ Ipv4Address rtrIdRemote = srRemote->GetRouterId();
+ NS_DEBUG("Working with remote router " << rtrIdRemote);
//
// Now, just like we did above, we need to get the IP interface index for the
// net device on the other end of the point-to-point channel.
//
- uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote);
+ uint32_t ifIndexRemote = FindIfIndexForDevice(nodeRemote, ndRemote);
//
// Now that we have the Ipv4 interface, we can get the (remote) address and
// mask we need.
//
- Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
- Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
- NS_DEBUG("Working with remote address " << addrRemote);
+ Ipv4Address addrRemote = ipv4Remote->GetAddress(ifIndexRemote);
+ Ipv4Mask maskRemote = ipv4Remote->GetNetworkMask(ifIndexRemote);
+ NS_DEBUG("Working with remote address " << addrRemote);
//
// Now we can fill out the link records for this link. There are always two
// link records; the first is a point-to-point record describing the link and
// the second is a stub network record with the network number.
//
- GlobalRouterLinkRecord *plr = new GlobalRouterLinkRecord;
- plr->SetLinkType (GlobalRouterLinkRecord::PointToPoint);
- plr->SetLinkId (rtrIdRemote);
- plr->SetLinkData (addrLocal);
- pLSA->AddLinkRecord(plr);
- plr = 0;
+ GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+ plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
+ plr->SetLinkId (rtrIdRemote);
+ plr->SetLinkData (addrLocal);
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
- plr = new GlobalRouterLinkRecord;
- plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork);
- plr->SetLinkId (addrRemote);
- plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
- pLSA->AddLinkRecord(plr);
- plr = 0;
+ plr = new GlobalRoutingLinkRecord;
+ plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+ plr->SetLinkId (addrRemote);
+ plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
+ pLSA->AddLinkRecord (plr);
+ plr = 0;
+ }
+ else
+ {
+ NS_ASSERT_MSG(0, "GlobalRouter::DiscoverLSAs (): unknown link type");
+ }
+
}
//
// The LSA goes on a list of LSAs in case we want to begin exporting other
// kinds of advertisements (than Router LSAs).
m_LSAs.push_back (pLSA);
NS_DEBUG(*pLSA);
+
+
+// Now, determine whether we need to build a NetworkLSA
+ if (listOfDRInterfaces.size () > 0)
+ {
+ for (std::list<Ptr<NetDevice> >::iterator i = listOfDRInterfaces.begin ();
+ i != listOfDRInterfaces.end (); i++)
+ {
+// Build one NetworkLSA for each interface that is a DR
+ Ptr<NetDevice> ndLocal = *i;
+ uint32_t ifIndexLocal = FindIfIndexForDevice(m_node, ndLocal);
+ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+
+ GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
+ pLSA->SetLSType (GlobalRoutingLSA::NetworkLSA);
+ pLSA->SetLinkStateId (addrLocal);
+ pLSA->SetAdvertisingRouter (m_routerId);
+ pLSA->SetNetworkLSANetworkMask (maskLocal);
+ pLSA->SetStatus (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED);
+// Build list of AttachedRouters
+ Ptr<Channel> ch = ndLocal->GetChannel();
+ uint32_t nDevices = ch->GetNDevices();
+ NS_ASSERT (nDevices);
+ for (uint32_t i = 0; i < nDevices; i++)
+ {
+ Ptr<NetDevice> tempNd = ch->GetDevice (i);
+ NS_ASSERT (tempNd);
+ Ptr<Node> tempNode = tempNd->GetNode ();
+ uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd);
+ Ptr<Ipv4> tempIpv4 = tempNode->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT (tempIpv4);
+ Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
+ pLSA->AddAttachedRouter (tempAddr);
+ }
+ m_LSAs.push_back (pLSA);
+ NS_DEBUG(*pLSA);
+ }
+ }
+
return m_LSAs.size ();
}
+ Ipv4Address
+GlobalRouter::FindDesignatedRouterForLink (Ptr<Node> node,
+ Ptr<NetDevice> ndLocal) const
+{
+ uint32_t ifIndexLocal = FindIfIndexForDevice(node, ndLocal);
+ Ptr<Ipv4> ipv4Local = m_node->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT (ipv4Local);
+ Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+ Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+
+ Ptr<Channel> ch = ndLocal->GetChannel();
+ uint32_t nDevices = ch->GetNDevices();
+ NS_ASSERT (nDevices);
+ Ipv4Address lowest = addrLocal;
+ // iterate all NetDevices and return the lowest numbered IP address
+ for (uint32_t i = 0; i < nDevices; i++)
+ {
+ Ptr<NetDevice> tempNd = ch->GetDevice (i);
+ NS_ASSERT (tempNd);
+ Ptr<Node> tempNode = tempNd->GetNode ();
+ uint32_t tempIfIndex = FindIfIndexForDevice (tempNode, tempNd);
+ Ptr<Ipv4> tempIpv4 = tempNode->QueryInterface<Ipv4> (Ipv4::iid);
+ NS_ASSERT (tempIpv4);
+ Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
+ if (tempAddr < addrLocal)
+ {
+ addrLocal = tempAddr;
+ }
+ }
+ return addrLocal;
+}
+
uint32_t
GlobalRouter::GetNumLSAs (void) const
{
@@ -510,7 +737,7 @@
// Get the nth link state advertisement from this router.
//
bool
-GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const
+GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
{
NS_ASSERT_MSG(lsa.IsEmpty(), "GlobalRouter::GetLSA (): Must pass empty LSA");
//
@@ -525,7 +752,7 @@
{
if (j == n)
{
- GlobalRouterLSA *p = *i;
+ GlobalRoutingLSA *p = *i;
lsa = *p;
return true;
}
--- a/src/routing/global-routing/global-router-interface.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/routing/global-routing/global-router-interface.h Tue Aug 28 12:05:35 2007 +0200
@@ -31,16 +31,16 @@
/**
* @brief A single link record for a link state advertisement.
*
- * The GlobalRouterLinkRecord is modeled after the OSPF link record field of
+ * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
* a Link State Advertisement. Right now we will only see two types of link
* records corresponding to a stub network and a point-to-point link (channel).
*/
-class GlobalRouterLinkRecord
+class GlobalRoutingLinkRecord
{
public:
/**
* @enum LinkType
- * @brief Enumeration of the possible types of Global Router Link Records.
+ * @brief Enumeration of the possible types of Global Routing Link Records.
*
* These values are defined in the OSPF spec. We currently only use
* PointToPoint and StubNetwork types.
@@ -54,16 +54,16 @@
};
/**
- * @brief Construct an empty ("uninitialized") Global Router Link Record.
+ * @brief Construct an empty ("uninitialized") Global Routing Link Record.
*
* The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
* The Link Type is set to Unknown;
* The metric is set to 0.
*/
- GlobalRouterLinkRecord ();
+ GlobalRoutingLinkRecord ();
/**
- * Construct an initialized Global Router Link Record.
+ * Construct an initialized Global Routing Link Record.
*
* @param linkType The type of link record to construct.
* @param linkId The link ID for the record.
@@ -73,21 +73,21 @@
* @see SetLinkId
* @see SetLinkData
*/
- GlobalRouterLinkRecord (
+ GlobalRoutingLinkRecord (
LinkType linkType,
Ipv4Address linkId,
Ipv4Address linkData,
uint32_t metric);
/**
- * @brief Destroy a Global Router Link Record.
+ * @brief Destroy a Global Routing Link Record.
*
* Currently does nothing. Here as a placeholder only.
*/
- ~GlobalRouterLinkRecord ();
+ ~GlobalRoutingLinkRecord ();
/**
- * Get the Link ID field of the Global Router Link Record.
+ * Get the Link ID field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
* of the neighboring router.
@@ -100,7 +100,7 @@
Ipv4Address GetLinkId(void) const;
/**
- * @brief Set the Link ID field of the Global Router Link Record.
+ * @brief Set the Link ID field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
* of the neighboring router.
@@ -113,7 +113,7 @@
void SetLinkId(Ipv4Address addr);
/**
- * @brief Get the Link Data field of the Global Router Link Record.
+ * @brief Get the Link Data field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
* address of the node of the local side of the link.
@@ -126,7 +126,7 @@
Ipv4Address GetLinkData(void) const;
/**
- * @brief Set the Link Data field of the Global Router Link Record.
+ * @brief Set the Link Data field of the Global Routing Link Record.
*
* For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
* address of the node of the local side of the link.
@@ -139,29 +139,29 @@
void SetLinkData(Ipv4Address addr);
/**
- * @brief Get the Link Type field of the Global Router Link Record.
+ * @brief Get the Link Type field of the Global Routing Link Record.
*
* The Link Type describes the kind of link a given record represents. The
* values are defined by OSPF.
*
* @see LinkType
- * @returns The LinkType of the current Global Router Link Record.
+ * @returns The LinkType of the current Global Routing Link Record.
*/
LinkType GetLinkType(void) const;
/**
- * @brief Set the Link Type field of the Global Router Link Record.
+ * @brief Set the Link Type field of the Global Routing Link Record.
*
* The Link Type describes the kind of link a given record represents. The
* values are defined by OSPF.
*
* @see LinkType
- * @param linkType The new LinkType for the current Global Router Link Record.
+ * @param linkType The new LinkType for the current Global Routing Link Record.
*/
void SetLinkType(LinkType linkType);
/**
- * @brief Get the Metric Data field of the Global Router Link Record.
+ * @brief Get the Metric Data field of the Global Routing Link Record.
*
* The metric is an abstract cost associated with forwarding a packet across
* a link. A sum of metrics must have a well-defined meaning. That is, you
@@ -169,12 +169,12 @@
* two hops relate to the cost of sending a packet); rather you should use
* something like delay.
*
- * @returns The metric field of the Global Router Link Record.
+ * @returns The metric field of the Global Routing Link Record.
*/
uint32_t GetMetric(void) const;
/**
- * @brief Set the Metric Data field of the Global Router Link Record.
+ * @brief Set the Metric Data field of the Global Routing Link Record.
*
* The metric is an abstract cost associated with forwarding a packet across
* a link. A sum of metrics must have a well-defined meaning. That is, you
@@ -182,7 +182,7 @@
* two hops relate to the cost of sending a packet); rather you should use
* something like delay.
*
- * @param metric The new metric for the current Global Router Link Record.
+ * @param metric The new metric for the current Global Routing Link Record.
*/
void SetMetric(uint32_t metric);
@@ -211,7 +211,7 @@
Ipv4Address m_linkData; // for links to RouterLSA,
/**
- * The type of the Global Router Link Record. Defined in the OSPF spec.
+ * The type of the Global Routing Link Record. Defined in the OSPF spec.
* We currently only use PointToPoint and StubNetwork types.
*/
LinkType m_linkType;
@@ -236,12 +236,24 @@
* combined with a list of Link Records. Since it's global, there's
* no need for age or sequence number. See RFC 2328, Appendix A.
*/
-class GlobalRouterLSA
+class GlobalRoutingLSA
{
public:
/**
+ * @enum LSType
+ * @brief corresponds to LS type field of RFC 2328 OSPF LSA header
+ */
+ enum LSType {
+ Unknown = 0, /**< Uninitialized Type */
+ RouterLSA,
+ NetworkLSA,
+ SummaryLSA,
+ SummaryLSA_ASBR,
+ ASExternalLSAs
+ };
+/**
* @enum SPFStatus
- * @brief Enumeration of the possible values of the status flag in the Router
+ * @brief Enumeration of the possible values of the status flag in the Routing
* Link State Advertisements.
*/
enum SPFStatus {
@@ -249,17 +261,16 @@
LSA_SPF_CANDIDATE, /**< Vertex is in the SPF candidate queue */
LSA_SPF_IN_SPFTREE /**< Vertex is in the SPF tree */
};
-
/**
- * @brief Create a blank Global Router Link State Advertisement.
+ * @brief Create a blank Global Routing Link State Advertisement.
*
* On completion Ipv4Address variables initialized to 0.0.0.0 and the
* list of Link State Records is empty.
*/
- GlobalRouterLSA();
+ GlobalRoutingLSA();
/**
- * @brief Create an initialized Global Router Link State Advertisement.
+ * @brief Create an initialized Global Routing Link State Advertisement.
*
* On completion the list of Link State Records is empty.
*
@@ -267,42 +278,42 @@
* @param linkStateId The Ipv4Address for the link state ID field.
* @param advertisingRtr The Ipv4Address for the advertising router field.
*/
- GlobalRouterLSA(SPFStatus status, Ipv4Address linkStateId,
+ GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId,
Ipv4Address advertisingRtr);
/**
- * @brief Copy constructor for a Global Router Link State Advertisement.
+ * @brief Copy constructor for a Global Routing Link State Advertisement.
*
* Takes a piece of memory and constructs a semantically identical copy of
* the given LSA.
*
* @param lsa The existing LSA to be used as the source.
*/
- GlobalRouterLSA (GlobalRouterLSA& lsa);
+ GlobalRoutingLSA (GlobalRoutingLSA& lsa);
/**
- * @brief Destroy an existing Global Router Link State Advertisement.
+ * @brief Destroy an existing Global Routing Link State Advertisement.
*
- * Any Global Router Link Records present in the list are freed.
+ * Any Global Routing Link Records present in the list are freed.
*/
- ~GlobalRouterLSA();
+ ~GlobalRoutingLSA();
/**
- * @brief Assignment operator for a Global Router Link State Advertisement.
+ * @brief Assignment operator for a Global Routing Link State Advertisement.
*
- * Takes an existing Global Router Link State Advertisement and overwrites
+ * Takes an existing Global Routing Link State Advertisement and overwrites
* it to make a semantically identical copy of a given prototype LSA.
*
- * If there are any Global Router Link Records present in the existing
+ * If there are any Global Routing Link Records present in the existing
* LSA, they are freed before the assignment happens.
*
* @param lsa The existing LSA to be used as the source.
* @returns Reference to the overwritten LSA.
*/
- GlobalRouterLSA& operator= (const GlobalRouterLSA& lsa);
+ GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
/**
- * @brief Copy any Global Router Link Records in a given Global Router Link
+ * @brief Copy any Global Routing Link Records in a given Global Routing Link
* State Advertisement to the current LSA.
*
* Existing Link Records are not deleted -- this is a concatenation of Link
@@ -311,57 +322,66 @@
* @see ClearLinkRecords ()
* @param lsa The LSA to copy the Link Records from.
*/
- void CopyLinkRecords (const GlobalRouterLSA& lsa);
+ void CopyLinkRecords (const GlobalRoutingLSA& lsa);
/**
- * @brief Add a given Global Router Link Record to the LSA.
+ * @brief Add a given Global Routing Link Record to the LSA.
*
- * @param lr The Global Router Link Record to be added.
+ * @param lr The Global Routing Link Record to be added.
* @returns The number of link records in the list.
*/
- uint32_t AddLinkRecord (GlobalRouterLinkRecord* lr);
+ uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
/**
- * @brief Return the number of Global Router Link Records in the LSA.
+ * @brief Return the number of Global Routing Link Records in the LSA.
*
* @returns The number of link records in the list.
*/
uint32_t GetNLinkRecords (void) const;
/**
- * @brief Return a pointer to the specified Global Router Link Record.
+ * @brief Return a pointer to the specified Global Routing Link Record.
*
* @param n The LSA number desired.
* @returns The number of link records in the list.
*/
- GlobalRouterLinkRecord* GetLinkRecord (uint32_t n) const;
+ GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
/**
- * @brief Release all of the Global Router Link Records present in the Global
- * Router Link State Advertisement and make the list of link records empty.
+ * @brief Release all of the Global Routing Link Records present in the Global
+ * Routing Link State Advertisement and make the list of link records empty.
*/
void ClearLinkRecords(void);
/**
- * @brief Check to see if the list of Global Router Link Records present in the
- * Global Router Link State Advertisement is empty.
+ * @brief Check to see if the list of Global Routing Link Records present in the
+ * Global Routing Link State Advertisement is empty.
*
* @returns True if the list is empty, false otherwise.
*/
bool IsEmpty(void) const;
/**
- * @brief Print the contents of the Global Router Link State Advertisement and
- * any Global Router Link Records present in the list. Quite verbose.
+ * @brief Print the contents of the Global Routing Link State Advertisement and
+ * any Global Routing Link Records present in the list. Quite verbose.
*/
void Print (std::ostream &os) const;
/**
+ * @brief Return the LSType field of the LSA
+ */
+ LSType GetLSType (void) const;
+/**
+ * @brief Set the LS type field of the LSA
+ */
+ void SetLSType (LSType typ);
+
+/**
* @brief Get the Link State ID as defined by the OSPF spec. We always set it
* to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
* @returns The Ipv4Address stored as the link state ID.
*/
Ipv4Address GetLinkStateId (void) const;
@@ -371,7 +391,7 @@
* to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
*/
void SetLinkStateId (Ipv4Address addr);
@@ -380,7 +400,7 @@
* set it to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
* @returns The Ipv4Address stored as the advetising router.
*/
Ipv4Address GetAdvertisingRouter (void) const;
@@ -390,11 +410,48 @@
* set it to the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
*/
void SetAdvertisingRouter (Ipv4Address rtr);
/**
+ * @brief For a Network LSA, set the Network Mask field that precedes
+ * the list of attached routers.
+ */
+ void SetNetworkLSANetworkMask (Ipv4Mask mask);
+
+/**
+ * @brief For a Network LSA, get the Network Mask field that precedes
+ * the list of attached routers.
+ *
+ * @returns the NetworkLSANetworkMask
+ */
+ Ipv4Mask GetNetworkLSANetworkMask (void) const;
+
+/**
+ * @brief Add an attached router to the list in the NetworkLSA
+ *
+ * @param addr The Ipv4Address of the interface on the network link
+ * @returns The number of addresses in the list.
+ */
+ uint32_t AddAttachedRouter (Ipv4Address addr);
+
+/**
+ * @brief Return the number of attached routers listed in the NetworkLSA
+ *
+ * @returns The number of attached routers.
+ */
+ uint32_t GetNAttachedRouters (void) const;
+
+/**
+ * @brief Return an Ipv4Address corresponding to the specified attached router
+ *
+ * @param n The attached router number desired (number in the list).
+ * @returns The Ipv4Address of the requested router
+ */
+ Ipv4Address GetAttachedRouter (uint32_t n) const;
+
+/**
* @brief Get the SPF status of the advertisement.
*
* @see SPFStatus
@@ -411,11 +468,16 @@
private:
/**
+ * The type of the LSA. Each LSA type has a separate advertisement
+ * format.
+ */
+ LSType m_lsType;
+/**
* The Link State ID is defined by the OSPF spec. We always set it to the
* router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
*/
Ipv4Address m_linkStateId;
@@ -424,14 +486,14 @@
* the router ID of the router making the advertisement.
*
* @see RoutingEnvironment::AllocateRouterId ()
- * @see GlobalRouter::GetRouterId ()
+ * @see GlobalRouting::GetRouterId ()
*/
Ipv4Address m_advertisingRtr;
/**
* A convenience typedef to avoid too much writers cramp.
*/
- typedef std::list<GlobalRouterLinkRecord*> ListOfLinkRecords_t;
+ typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
/**
* Each Link State Advertisement contains a number of Link Records that
@@ -441,11 +503,31 @@
* m_linkRecords is an STL list container to hold the Link Records that have
* been discovered and prepared for the advertisement.
*
- * @see GlobalRouter::DiscoverLSAs ()
+ * @see GlobalRouting::DiscoverLSAs ()
*/
ListOfLinkRecords_t m_linkRecords;
/**
+ * Each Network LSA contains the network mask of the attached network
+ */
+ Ipv4Mask m_networkLSANetworkMask;
+
+/**
+ * A convenience typedef to avoid too much writers cramp.
+ */
+ typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
+
+/**
+ * Each Network LSA contains a list of attached routers
+ *
+ * m_attachedRouters is an STL list container to hold the addresses that have
+ * been discovered and prepared for the advertisement.
+ *
+ * @see GlobalRouting::DiscoverLSAs ()
+ */
+ ListOfAttachedRouters_t m_attachedRouters;
+
+/**
* This is a tristate flag used internally in the SPF computation to mark
* if an SPFVertex (a data structure representing a vertex in the SPF tree
* -- a router) is new, is a candidate for a shortest path, or is in its
@@ -454,7 +536,7 @@
SPFStatus m_status;
};
-std::ostream& operator<< (std::ostream& os, GlobalRouterLSA& lsa);
+std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
/**
* @brief An interface aggregated to a node to provide global routing info
@@ -496,7 +578,7 @@
/**
* @brief Walk the connected channels, discover the adjacent routers and build
- * the associated number of Global Router Link State Advertisements that
+ * the associated number of Global Routing Link State Advertisements that
* this router can export.
*
* This is a fairly expensive operation in that every time it is called
@@ -507,14 +589,14 @@
* advertisements after a network topology change by calling DiscoverLSAs
* and then by reading those advertisements.
*
- * @see GlobalRouterLSA
+ * @see GlobalRoutingLSA
* @see GlobalRouter::GetLSA ()
- * @returns The number of Global Router Link State Advertisements.
+ * @returns The number of Global Routing Link State Advertisements.
*/
uint32_t DiscoverLSAs (void);
/**
- * @brief Get the Number of Global Router Link State Advertisements that this
+ * @brief Get the Number of Global Routing Link State Advertisements that this
* router can export.
*
* To get meaningful information you must have previously called DiscoverLSAs.
@@ -522,19 +604,19 @@
* GetLSA () to retrieve the actual advertisement.
*
* @see GlobalRouterLSA
- * @see GlobalRouter::DiscoverLSAs ()
- * @see GlobalRouter::GetLSA ()
- * @returns The number of Global Router Link State Advertisements.
+ * @see GlobalRouting::DiscoverLSAs ()
+ * @see GlobalRouting::GetLSA ()
+ * @returns The number of Global Routing Link State Advertisements.
*/
uint32_t GetNumLSAs (void) const;
/**
- * @brief Get a Global Router Link State Advertisements that this router has
+ * @brief Get a Global Routing Link State Advertisements that this router has
* said that it can export.
*
* This is a fairly inexpensive expensive operation in that the hard work
- * was done in GetNumLSAs. We just copy the indicated Global Router Link
- * State Advertisement into the requested GlobalRouterLSA object.
+ * was done in GetNumLSAs. We just copy the indicated Global Routing Link
+ * State Advertisement into the requested GlobalRoutingLSA object.
*
* You must call GlobalRouter::GetNumLSAs before calling this method in
* order to discover the adjacent routers and build the advertisements.
@@ -542,13 +624,13 @@
* The parameter n (requested LSA number) must be in the range 0 to
* GetNumLSAs() - 1.
*
- * @see GlobalRouterLSA
- * @see GlobalRouter::GetNumLSAs ()
+ * @see GlobalRoutingLSA
+ * @see GlobalRouting::GetNumLSAs ()
* @param n The index number of the LSA you want to read.
- * @param lsa The GlobalRouterLSA class to receive the LSA information.
+ * @param lsa The GlobalRoutingLSA class to receive the LSA information.
* @returns The number of Global Router Link State Advertisements.
*/
- bool GetLSA (uint32_t n, GlobalRouterLSA &lsa) const;
+ bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
private:
virtual ~GlobalRouter ();
@@ -556,10 +638,12 @@
Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
uint32_t FindIfIndexForDevice(Ptr<Node> node, Ptr<NetDevice> nd) const;
+ Ipv4Address FindDesignatedRouterForLink (Ptr<Node> node,
+ Ptr<NetDevice> ndLocal) const;
Ptr<Node> m_node;
- typedef std::list<GlobalRouterLSA*> ListOfLSAs_t;
+ typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t;
ListOfLSAs_t m_LSAs;
Ipv4Address m_routerId;
--- a/src/simulator/simulator.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/src/simulator/simulator.cc Tue Aug 28 12:05:35 2007 +0200
@@ -539,13 +539,14 @@
public:
SimulatorTests ();
// only here for testing of Ptr<>
- void Ref (void);
- void Unref (void);
+ void Ref (void) const;
+ void Unref (void) const;
virtual ~SimulatorTests ();
virtual bool RunTests (void);
private:
uint64_t NowUs ();
bool RunOneTest (void);
+ void RunTestsConst (void) const;
void A (int a);
void B (int b);
void C (int c);
@@ -566,6 +567,24 @@
void cbaz3 (const int &, const int &, const int &);
void cbaz4 (const int &, const int &, const int &, const int &);
void cbaz5 (const int &, const int &, const int &, const int &, const int &);
+
+ void bar0c (void) const;
+ void bar1c (int) const;
+ void bar2c (int, int) const;
+ void bar3c (int, int, int) const;
+ void bar4c (int, int, int, int) const;
+ void bar5c (int, int, int, int, int) const;
+ void baz1c (int &) const;
+ void baz2c (int &, int &) const;
+ void baz3c (int &, int &, int &) const;
+ void baz4c (int &, int &, int &, int &) const;
+ void baz5c (int &, int &, int &, int &, int &) const;
+ void cbaz1c (const int &) const;
+ void cbaz2c (const int &, const int &) const;
+ void cbaz3c (const int &, const int &, const int &) const;
+ void cbaz4c (const int &, const int &, const int &, const int &) const;
+ void cbaz5c (const int &, const int &, const int &, const int &, const int &) const;
+
void destroy (void);
bool m_b;
@@ -583,10 +602,10 @@
SimulatorTests::~SimulatorTests ()
{}
void
-SimulatorTests::Ref (void)
+SimulatorTests::Ref (void) const
{}
void
-SimulatorTests::Unref (void)
+SimulatorTests::Unref (void) const
{}
uint64_t
SimulatorTests::NowUs (void)
@@ -689,6 +708,57 @@
SimulatorTests::cbaz5 (const int &, const int &, const int &, const int &, const int &)
{}
+void
+SimulatorTests::bar0c (void) const
+{}
+void
+SimulatorTests::bar1c (int) const
+{}
+void
+SimulatorTests::bar2c (int, int) const
+{}
+void
+SimulatorTests::bar3c (int, int, int) const
+{}
+void
+SimulatorTests::bar4c (int, int, int, int) const
+{}
+void
+SimulatorTests::bar5c (int, int, int, int, int) const
+{}
+
+void
+SimulatorTests::baz1c (int &) const
+{}
+void
+SimulatorTests::baz2c (int &, int &) const
+{}
+void
+SimulatorTests::baz3c (int &, int &, int &) const
+{}
+void
+SimulatorTests::baz4c (int &, int &, int &, int &) const
+{}
+void
+SimulatorTests::baz5c (int &, int &, int &, int &, int &) const
+{}
+
+void
+SimulatorTests::cbaz1c (const int &) const
+{}
+void
+SimulatorTests::cbaz2c (const int &, const int &) const
+{}
+void
+SimulatorTests::cbaz3c (const int &, const int &, const int &) const
+{}
+void
+SimulatorTests::cbaz4c (const int &, const int &, const int &, const int &) const
+{}
+void
+SimulatorTests::cbaz5c (const int &, const int &, const int &, const int &, const int &) const
+{}
+
bool
SimulatorTests::RunOneTest (void)
{
@@ -723,6 +793,80 @@
}
return ok;
}
+void
+SimulatorTests::RunTestsConst (void) const
+{
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar0c, this);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar1c, this, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar2c, this, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar3c, this, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar4c, this, 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar5c, this, 0, 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar0c, Ptr<const SimulatorTests> (this));
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar1c, Ptr<const SimulatorTests> (this), 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar2c, Ptr<const SimulatorTests> (this), 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar3c, Ptr<const SimulatorTests> (this), 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar4c, Ptr<const SimulatorTests> (this), 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::bar5c, Ptr<const SimulatorTests> (this), 0, 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz1c, this, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz2c, this, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz3c, this, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz4c, this, 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::cbaz5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar0c, this);
+ Simulator::ScheduleNow (&SimulatorTests::bar1c, this, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar2c, this, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar3c, this, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar4c, this, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::cbaz1c, this, 0);
+ Simulator::ScheduleNow (&SimulatorTests::cbaz2c, this, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::cbaz3c, this, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::cbaz4c, this, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::cbaz5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar0c, Ptr<const SimulatorTests> (this));
+ Simulator::ScheduleNow (&SimulatorTests::bar1c, Ptr<const SimulatorTests> (this), 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar2c, Ptr<const SimulatorTests> (this), 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar3c, Ptr<const SimulatorTests> (this), 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar4c, Ptr<const SimulatorTests> (this), 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::bar5c, Ptr<const SimulatorTests> (this), 0, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar0c, this);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar1c, this, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar2c, this, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar3c, this, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar4c, this, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::cbaz1c, this, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::cbaz2c, this, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::cbaz3c, this, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::cbaz4c, this, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::cbaz5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar0c, Ptr<const SimulatorTests> (this));
+ Simulator::ScheduleDestroy (&SimulatorTests::bar1c, Ptr<const SimulatorTests> (this), 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar2c, Ptr<const SimulatorTests> (this), 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar3c, Ptr<const SimulatorTests> (this), 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar4c, Ptr<const SimulatorTests> (this), 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::bar5c, Ptr<const SimulatorTests> (this), 0, 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz1c, this, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz2c, this, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz3c, this, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz4c, this, 0, 0, 0, 0);
+ Simulator::Schedule (Seconds (0.0), &SimulatorTests::baz5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::baz1c, this, 0);
+ Simulator::ScheduleNow (&SimulatorTests::baz2c, this, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::baz3c, this, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::baz4c, this, 0, 0, 0, 0);
+ Simulator::ScheduleNow (&SimulatorTests::baz5c, this, 0, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::baz1c, this, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::baz2c, this, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::baz3c, this, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::baz4c, this, 0, 0, 0, 0);
+ Simulator::ScheduleDestroy (&SimulatorTests::baz5c, this, 0, 0, 0, 0, 0);
+
+ Simulator::Run ();
+ Simulator::Destroy ();
+}
+
bool
SimulatorTests::RunTests (void)
{
@@ -870,6 +1014,8 @@
Simulator::ScheduleDestroy (&SimulatorTests::baz5, this, 0, 0, 0, 0, 0);
#endif
+ RunTestsConst ();
+
EventId nowId = Simulator::ScheduleNow (&foo0);
m_destroyId = Simulator::ScheduleDestroy (&SimulatorTests::destroy, this);
if (m_destroyId.IsExpired ())
--- a/src/simulator/simulator.h Tue Aug 28 11:22:01 2007 +0200
+++ b/src/simulator/simulator.h Tue Aug 28 12:05:35 2007 +0200
@@ -163,8 +163,8 @@
* @param obj the object on which to invoke the member method
* @returns an id for the scheduled event.
*/
- template <typename T, typename OBJ>
- static EventId Schedule (Time const &time, void (T::*mem_ptr) (void), OBJ obj);
+ template <typename MEM, typename OBJ>
+ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj);
/**
* @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
@@ -172,8 +172,8 @@
* @param a1 the first argument to pass to the invoked method
* @returns an id for the scheduled event.
*/
- template <typename T, typename OBJ, typename U1, typename T1>
- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
+ template <typename MEM, typename OBJ, typename T1>
+ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1);
/**
* @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
@@ -182,8 +182,8 @@
* @param a2 the second argument to pass to the invoked method
* @returns an id for the scheduled event.
*/
- template <typename T, typename OBJ, typename U1, typename U2, typename T1, typename T2>
- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
+ template <typename MEM, typename OBJ, typename T1, typename T2>
+ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
/**
* @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
@@ -193,10 +193,9 @@
* @param a3 the third argument to pass to the invoked method
* @returns an id for the scheduled event.
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
+ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
/**
* @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
@@ -207,10 +206,9 @@
* @param a4 the fourth argument to pass to the invoked method
* @returns an id for the scheduled event.
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
+ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
/**
* @param time the relative expiration time of the event.
* @param mem_ptr member method pointer to invoke
@@ -222,10 +220,9 @@
* @param a5 the fifth argument to pass to the invoked method
* @returns an id for the scheduled event.
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
- static EventId Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
+ static EventId Schedule (Time const &time, MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
/**
* @param time the relative expiration time of the event.
@@ -295,27 +292,25 @@
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
*/
- template <typename T, typename OBJ>
- static EventId ScheduleNow (void (T::*mem_ptr) (void), OBJ obj);
+ template <typename MEM, typename OBJ>
+ static EventId ScheduleNow (MEM mem_ptr, OBJ obj);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1,
+ template <typename MEM, typename OBJ,
typename T1>
- static EventId ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
+ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
* @param a2 the second argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2,
+ template <typename MEM, typename OBJ,
typename T1, typename T2>
- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
+ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
@@ -323,10 +318,9 @@
* @param a2 the second argument to pass to the invoked method
* @param a3 the third argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
+ static EventId ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
@@ -335,11 +329,10 @@
* @param a3 the third argument to pass to the invoked method
* @param a4 the fourth argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4);
+ static EventId ScheduleNow (MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
@@ -349,11 +342,10 @@
* @param a4 the fourth argument to pass to the invoked method
* @param a5 the fifth argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
- static EventId ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+ static EventId ScheduleNow (MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
/**
* @param f the function to invoke
*/
@@ -414,27 +406,25 @@
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
*/
- template <typename T, typename OBJ>
- static EventId ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj);
+ template <typename MEM, typename OBJ>
+ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1,
+ template <typename MEM, typename OBJ,
typename T1>
- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
+ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
* @param a1 the first argument to pass to the invoked method
* @param a2 the second argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2,
+ template <typename MEM, typename OBJ,
typename T1, typename T2>
- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
+ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
@@ -442,10 +432,9 @@
* @param a2 the second argument to pass to the invoked method
* @param a3 the third argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
+ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
@@ -454,11 +443,10 @@
* @param a3 the third argument to pass to the invoked method
* @param a4 the fourth argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4);
+ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4);
/**
* @param mem_ptr member method pointer to invoke
* @param obj the object on which to invoke the member method
@@ -468,11 +456,10 @@
* @param a4 the fourth argument to pass to the invoked method
* @param a5 the fifth argument to pass to the invoked method
*/
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
- static EventId ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+ static EventId ScheduleDestroy (MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
/**
* @param f the function to invoke
*/
@@ -569,29 +556,24 @@
Simulator ();
~Simulator ();
- template <typename T, typename OBJ>
- static Ptr<EventImpl> MakeEvent (void (T::*mem_ptr) (void), OBJ obj);
- template <typename T, typename OBJ,
- typename U1,
+ template <typename MEM, typename OBJ>
+ static Ptr<EventImpl> MakeEvent (MEM mem_ptr, OBJ obj);
+ template <typename MEM, typename OBJ,
typename T1>
- static Ptr<EventImpl> MakeEvent (void (T::*mem_ptr) (U1), OBJ obj, T1 a1);
- template <typename T, typename OBJ,
- typename U1, typename U2,
+ static Ptr<EventImpl> MakeEvent (MEM mem_ptr, OBJ obj, T1 a1);
+ template <typename MEM, typename OBJ,
typename T1, typename T2>
- static Ptr<EventImpl> MakeEvent (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2);
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+ static Ptr<EventImpl> MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
- static Ptr<EventImpl> MakeEvent (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3);
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+ static Ptr<EventImpl> MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
- static Ptr<EventImpl> MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
- template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+ static Ptr<EventImpl> MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
+ template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
- static Ptr<EventImpl> MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
+ static Ptr<EventImpl> MakeEvent (MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
static Ptr<EventImpl> MakeEvent (void (*f) (void));
template <typename U1,
typename T1>
@@ -649,14 +631,13 @@
}
};
-template <typename T, typename OBJ>
-Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (void), OBJ obj)
+template <typename MEM, typename OBJ>
+Ptr<EventImpl> Simulator::MakeEvent (MEM mem_ptr, OBJ obj)
{
// zero argument version
class EventMemberImpl0 : public EventImpl {
public:
- typedef void (T::*F)(void);
- EventMemberImpl0 (OBJ obj, F function)
+ EventMemberImpl0 (OBJ obj, MEM function)
: m_obj (obj),
m_function (function)
{}
@@ -666,22 +647,20 @@
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) ();
}
OBJ m_obj;
- F m_function;
+ MEM m_function;
} * ev = new EventMemberImpl0 (obj, mem_ptr);
return Ptr<EventImpl> (ev, false);
}
-template <typename T, typename OBJ,
- typename U1,
+template <typename MEM, typename OBJ,
typename T1>
-Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1), OBJ obj, T1 a1)
+Ptr<EventImpl> Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1)
{
// one argument version
class EventMemberImpl1 : public EventImpl {
public:
- typedef void (T::*F)(U1);
- EventMemberImpl1 (OBJ obj, F function, T1 a1)
+ EventMemberImpl1 (OBJ obj, MEM function, T1 a1)
: m_obj (obj),
m_function (function),
m_a1 (a1)
@@ -693,23 +672,20 @@
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1);
}
OBJ m_obj;
- F m_function;
+ MEM m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
} *ev = new EventMemberImpl1 (obj, mem_ptr, a1);
return Ptr<EventImpl> (ev, false);
}
-template <typename T, typename OBJ,
- typename U1, typename U2,
+template <typename MEM, typename OBJ,
typename T1, typename T2>
-Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2)
+Ptr<EventImpl> Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
{
// two argument version
class EventMemberImpl2 : public EventImpl {
public:
- typedef void (T::*F)(U1, U2);
-
- EventMemberImpl2 (OBJ obj, F function, T1 a1, T2 a2)
+ EventMemberImpl2 (OBJ obj, MEM function, T1 a1, T2 a2)
: m_obj (obj),
m_function (function),
m_a1 (a1),
@@ -722,24 +698,21 @@
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2);
}
OBJ m_obj;
- F m_function;
+ MEM m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
typename TypeTraits<T2>::ReferencedType m_a2;
} *ev = new EventMemberImpl2 (obj, mem_ptr, a1, a2);
return Ptr<EventImpl> (ev, false);
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
-Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3)
+Ptr<EventImpl> Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
{
// three argument version
class EventMemberImpl3 : public EventImpl {
public:
- typedef void (T::*F)(U1,U2,U3);
-
- EventMemberImpl3 (OBJ obj, F function, T1 a1, T2 a2, T3 a3)
+ EventMemberImpl3 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3)
: m_obj (obj),
m_function (function),
m_a1 (a1),
@@ -753,7 +726,7 @@
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3);
}
OBJ m_obj;
- F m_function;
+ MEM m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
typename TypeTraits<T2>::ReferencedType m_a2;
typename TypeTraits<T3>::ReferencedType m_a3;
@@ -761,17 +734,14 @@
return Ptr<EventImpl> (ev, false);
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
-Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
+Ptr<EventImpl> Simulator::MakeEvent (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
{
// four argument version
class EventMemberImpl4 : public EventImpl {
public:
- typedef void (T::*F)(U1, U2, U3, U4);
-
- EventMemberImpl4 (OBJ obj, F function, T1 a1, T2 a2, T3 a3, T4 a4)
+ EventMemberImpl4 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4)
: m_obj (obj),
m_function (function),
m_a1 (a1),
@@ -786,7 +756,7 @@
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4);
}
OBJ m_obj;
- F m_function;
+ MEM m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
typename TypeTraits<T2>::ReferencedType m_a2;
typename TypeTraits<T3>::ReferencedType m_a3;
@@ -795,18 +765,15 @@
return Ptr<EventImpl> (ev, false);
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
-Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+Ptr<EventImpl> Simulator::MakeEvent (MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
// five argument version
class EventMemberImpl5 : public EventImpl {
public:
- typedef void (T::*F)(U1, U2, U3, U4, U5);
-
- EventMemberImpl5 (OBJ obj, F function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+ EventMemberImpl5 (OBJ obj, MEM function, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
: m_obj (obj),
m_function (function),
m_a1 (a1),
@@ -822,7 +789,7 @@
(EventMemberImplObjTraits<OBJ>::GetReference (m_obj).*m_function) (m_a1, m_a2, m_a3, m_a4, m_a5);
}
OBJ m_obj;
- F m_function;
+ MEM m_function;
typename TypeTraits<T1>::ReferencedType m_a1;
typename TypeTraits<T2>::ReferencedType m_a2;
typename TypeTraits<T3>::ReferencedType m_a3;
@@ -975,50 +942,45 @@
return Ptr<EventImpl> (ev, false);
}
-template <typename T, typename OBJ>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (void), OBJ obj)
+template <typename MEM, typename OBJ>
+EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj)
{
return Schedule (time, MakeEvent (mem_ptr, obj));
}
-template <typename T, typename OBJ,
- typename U1,
+template <typename MEM, typename OBJ,
typename T1>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1), OBJ obj, T1 a1)
+EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1)
{
return Schedule (time, MakeEvent (mem_ptr, obj, a1));
}
-template <typename T, typename OBJ,
- typename U1, typename U2,
+template <typename MEM, typename OBJ,
typename T1, typename T2>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2)
+EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
{
return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3)
+EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
{
return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
+EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
{
return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
-EventId Simulator::Schedule (Time const &time, void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
- T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
+EventId Simulator::Schedule (Time const &time, MEM mem_ptr, OBJ obj,
+ T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
return Schedule (time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
}
@@ -1060,55 +1022,50 @@
-template <typename T, typename OBJ>
+template <typename MEM, typename OBJ>
EventId
-Simulator::ScheduleNow (void (T::*mem_ptr) (void), OBJ obj)
+Simulator::ScheduleNow (MEM mem_ptr, OBJ obj)
{
return ScheduleNow (MakeEvent (mem_ptr, obj));
}
-template <typename T, typename OBJ,
- typename U1,
+template <typename MEM, typename OBJ,
typename T1>
EventId
-Simulator::ScheduleNow (void (T::*mem_ptr) (U1), OBJ obj, T1 a1)
+Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1)
{
return ScheduleNow (MakeEvent (mem_ptr, obj, a1));
}
-template <typename T, typename OBJ,
- typename U1, typename U2,
+template <typename MEM, typename OBJ,
typename T1, typename T2>
EventId
-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2)
+Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
{
return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
EventId
-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3)
+Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
{
return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
EventId
-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
+Simulator::ScheduleNow (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
{
return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
EventId
-Simulator::ScheduleNow (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
+Simulator::ScheduleNow (MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
return ScheduleNow (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
@@ -1156,55 +1113,50 @@
-template <typename T, typename OBJ>
+template <typename MEM, typename OBJ>
EventId
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (void), OBJ obj)
+Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj)
{
return ScheduleDestroy (MakeEvent (mem_ptr, obj));
}
-template <typename T, typename OBJ,
- typename U1,
+template <typename MEM, typename OBJ,
typename T1>
EventId
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1), OBJ obj, T1 a1)
+Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1)
{
return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1));
}
-template <typename T, typename OBJ,
- typename U1, typename U2,
+template <typename MEM, typename OBJ,
typename T1, typename T2>
EventId
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1, T2 a2)
+Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
{
return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3>
EventId
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1 a1, T2 a2, T3 a3)
+Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
{
return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4>
EventId
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
+Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
{
return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
}
-template <typename T, typename OBJ,
- typename U1, typename U2, typename U3, typename U4, typename U5,
+template <typename MEM, typename OBJ,
typename T1, typename T2, typename T3, typename T4, typename T5>
EventId
-Simulator::ScheduleDestroy (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ obj,
+Simulator::ScheduleDestroy (MEM mem_ptr, OBJ obj,
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
{
return ScheduleDestroy (MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
--- a/src/wscript Tue Aug 28 11:22:01 2007 +0200
+++ b/src/wscript Tue Aug 28 12:05:35 2007 +0200
@@ -17,7 +17,7 @@
'node',
'internet-node',
'devices/point-to-point',
- 'devices/csma-cd',
+ 'devices/csma',
'applications',
'routing/global-routing',
'mobility',
--- a/utils/print-trace-sources.cc Tue Aug 28 11:22:01 2007 +0200
+++ b/utils/print-trace-sources.cc Tue Aug 28 12:05:35 2007 +0200
@@ -3,7 +3,7 @@
#include "ns3/trace-resolver.h"
#include "ns3/node-list.h"
#include "ns3/point-to-point-net-device.h"
-#include "ns3/csma-cd-net-device.h"
+#include "ns3/csma-net-device.h"
#include "ns3/queue.h"
#include "ns3/mobility-model-notifier.h"
@@ -16,7 +16,7 @@
Ptr<PointToPointNetDevice> p2p = Create<PointToPointNetDevice> (node);
p2p->AddQueue (Queue::CreateDefault ());
- Ptr<CsmaCdNetDevice> csma = Create<CsmaCdNetDevice> (node);
+ Ptr<CsmaNetDevice> csma = Create<CsmaNetDevice> (node);
csma->AddQueue (Queue::CreateDefault ());
TraceResolver::SourceCollection collection;
--- a/wscript Tue Aug 28 11:22:01 2007 +0200
+++ b/wscript Tue Aug 28 12:05:35 2007 +0200
@@ -37,7 +37,7 @@
opt.add_option('-d', '--debug-level',
action='callback',
- type=str, dest='debug_level', default='debug',
+ type="string", dest='debug_level', default='debug',
help=('Specify the debug level, does nothing if CFLAGS is set'
' in the environment. [Allowed Values: debug, optimized].'
' WARNING: this option only has effect '