merge with trunk

Mathieu Lacage 2007-08-28 12:05:35 +02:00
commit 04569d27b7
62 changed files with 2256 additions and 2036 deletions

View File

@ -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

View File

@ -3,4 +3,5 @@ Gustavo Carneiro (gjc@inescporto.pt, gjcarneiro@gmail.com)
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)

View File

@ -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)
========================

View File

@ -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()

View File

@ -1 +1 @@
3.0.4
3.0.5

View File

@ -5,23 +5,20 @@ Steps in doing an ns-3 release
- 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

View File

@ -26,7 +26,7 @@
// - 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"
// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
#include <iostream>
#include <fstream>
@ -46,10 +46,10 @@
#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/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"
@ -68,11 +68,11 @@ 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("CsmaNetDevice");
DebugComponentEnable("Ipv4L3Protocol");
DebugComponentEnable("NetDevice");
DebugComponentEnable("Channel");
DebugComponentEnable("CsmaCdChannel");
DebugComponentEnable("CsmaChannel");
DebugComponentEnable("PacketSocket");
#endif
@ -96,30 +96,30 @@ int main (int argc, char *argv[])
Ptr<Node> n3 = Create<InternetNode> ();
// We create the channels first without any IP addressing information
Ptr<CsmaCdChannel> channel0 =
CsmaCdTopology::CreateCsmaCdChannel(
Ptr<CsmaChannel> channel0 =
CsmaTopology::CreateCsmaChannel(
DataRate(5000000), MilliSeconds(2));
uint32_t n0ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0,
uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0,
Eui48Address("10:54:23:54:23:50"));
uint32_t n1ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
Eui48Address("10:54:23:54:23:51"));
uint32_t n2ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0,
Eui48Address("10:54:23:54:23:52"));
uint32_t n3ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0,
Eui48Address("10:54:23:54:23:53"));
// Later, we add IP addresses.
CsmaCdIpv4Topology::AddIpv4Address (
CsmaIpv4Topology::AddIpv4Address (
n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
CsmaCdIpv4Topology::AddIpv4Address (
CsmaIpv4Topology::AddIpv4Address (
n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
CsmaCdIpv4Topology::AddIpv4Address (
CsmaIpv4Topology::AddIpv4Address (
n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
CsmaCdIpv4Topology::AddIpv4Address (
CsmaIpv4Topology::AddIpv4Address (
n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
// Create the OnOff application to send UDP datagrams of size
@ -147,8 +147,8 @@ int main (int argc, char *argv[])
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");
// Trace output will be sent to the csma-one-subnet.tr file
AsciiTrace asciitrace ("csma-one-subnet.tr");
asciitrace.TraceAllNetDeviceRx ();
asciitrace.TraceAllQueues ();
@ -157,7 +157,7 @@ int main (int argc, char *argv[])
// 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 pcaptrace ("csma-one-subnet.pcap");
pcaptrace.TraceAllIp ();
Simulator::Run ();

View File

@ -26,7 +26,7 @@
// - 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"
// - Tracing of queues and packet receptions to file "csma-one-subnet.tr"
#include <iostream>
#include <fstream>
@ -46,8 +46,8 @@
#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-channel.h"
#include "ns3/csma-net-device.h"
#include "ns3/eui48-address.h"
#include "ns3/packet-socket-address.h"
#include "ns3/socket.h"
@ -56,10 +56,10 @@
using namespace ns3;
static Ptr<CsmaCdNetDevice>
CreateCsmaCdDevice (Ptr<Node> node, Ptr<CsmaCdChannel> channel)
static Ptr<CsmaNetDevice>
CreateCsmaDevice (Ptr<Node> node, Ptr<CsmaChannel> channel)
{
Ptr<CsmaCdNetDevice> device = Create<CsmaCdNetDevice> (node);
Ptr<CsmaNetDevice> device = Create<CsmaNetDevice> (node);
device->Attach (channel);
Ptr<Queue> queue = Queue::CreateDefault ();
device->AddQueue (queue);
@ -78,14 +78,14 @@ int main (int argc, char *argv[])
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));
// 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 = CreateCsmaCdDevice (n0, channel);
Ptr<NetDevice> n1If = CreateCsmaCdDevice (n1, channel);
Ptr<NetDevice> n2If = CreateCsmaCdDevice (n2, channel);
Ptr<NetDevice> n3If = CreateCsmaCdDevice (n3, 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
@ -125,8 +125,8 @@ int main (int argc, char *argv[])
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");
// Trace output will be sent to the csma-packet-socket.tr file
AsciiTrace asciitrace ("csma-packet-socket.tr");
asciitrace.TraceAllNetDeviceRx ();
asciitrace.TraceAllQueues ();

View File

@ -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 ();
}

View File

@ -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 ();
}

View File

@ -72,6 +72,7 @@ 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
// remember to add #include "ns3/debug.h" before enabling these
#if 0
DebugComponentEnable("Object");
DebugComponentEnable("Queue");

View File

@ -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'

View File

@ -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 @@ static void
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 @@ GenerateTraffic (Ptr<Socket> socket, uint32_t size)
}
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

View File

@ -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::ScheduleStopEvent()
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;

View File

@ -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

View File

@ -230,6 +230,7 @@ PacketMetadataTest::PacketMetadataTest ()
: Test ("PacketMetadata")
{
m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this));
m_printer.SetSeparator ("");
}
PacketMetadataTest::~PacketMetadataTest ()

View File

@ -128,7 +128,7 @@ Packet::GetUid (void) const
void
Packet::PrintTags (std::ostream &os) const
{
m_tags.Print (os);
m_tags.Print (os, " ");
}
void

View File

@ -119,14 +119,14 @@ Tags::Remove (uint32_t id)
}
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 @@ TagsTest::RunTests (void)
ok = false;
}
g_a = false;
tags.Print (std::cout);
tags.Print (std::cout, "");
if (!g_a)
{
ok = false;
@ -363,7 +363,7 @@ TagsTest::RunTests (void)
}
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 @@ TagsTest::RunTests (void)
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 @@ TagsTest::RunTests (void)
}
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 @@ TagsTest::RunTests (void)
tagZ.z = 0;
testLastTag.Add (tagZ);
g_z = false;
testLastTag.Print (std::cout);
testLastTag.Print (std::cout, "");
if (!g_z)
{
ok = false;

View File

@ -52,7 +52,7 @@ public:
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);

View File

@ -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',
]

View File

@ -19,60 +19,60 @@
* Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
*/
#include "csma-cd-channel.h"
#include "csma-cd-net-device.h"
#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 ("CsmaCdChannel");
NS_DEBUG_COMPONENT_DEFINE ("CsmaChannel");
namespace ns3 {
CsmaCdDeviceRec::CsmaCdDeviceRec()
CsmaDeviceRec::CsmaDeviceRec()
{
active = false;
}
CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr<CsmaCdNetDevice> device)
CsmaDeviceRec::CsmaDeviceRec(Ptr<CsmaNetDevice> device)
{
devicePtr = device;
active = true;
}
bool
CsmaCdDeviceRec::IsActive() {
CsmaDeviceRec::IsActive() {
return active;
}
//
// By default, you get a channel with the name "CsmaCd Channel" that
// By default, you get a channel with the name "Csma Channel" that
// has an "infitely" fast transmission speed and zero delay.
CsmaCdChannel::CsmaCdChannel()
CsmaChannel::CsmaChannel()
:
Channel ("CsmaCd Channel"),
Channel ("Csma Channel"),
m_bps (DataRate(0xffffffff)),
m_delay (Seconds(0))
{
NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()");
NS_DEBUG("CsmaChannel::CsmaChannel ()");
Init();
}
CsmaCdChannel::CsmaCdChannel(
CsmaChannel::CsmaChannel(
const DataRate& bps,
const Time& delay)
:
Channel ("CsmaCd Channel"),
Channel ("Csma Channel"),
m_bps (bps),
m_delay (delay)
{
NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName()
NS_DEBUG("CsmaChannel::CsmaChannel (" << Channel::GetName()
<< ", " << bps.GetBitRate() << ", " << delay << ")");
Init();
}
CsmaCdChannel::CsmaCdChannel(
CsmaChannel::CsmaChannel(
const std::string& name,
const DataRate& bps,
const Time& delay)
@ -81,35 +81,35 @@ CsmaCdChannel::CsmaCdChannel(
m_bps (bps),
m_delay (delay)
{
NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " <<
NS_DEBUG("CsmaChannel::CsmaChannel (" << name << ", " <<
bps.GetBitRate() << ", " << delay << ")");
Init();
}
void CsmaCdChannel::Init() {
void CsmaChannel::Init() {
m_state = IDLE;
m_deviceList.clear();
}
int32_t
CsmaCdChannel::Attach(Ptr<CsmaCdNetDevice> device)
CsmaChannel::Attach(Ptr<CsmaNetDevice> device)
{
NS_DEBUG("CsmaCdChannel::Attach (" << device << ")");
NS_DEBUG("CsmaChannel::Attach (" << device << ")");
NS_ASSERT(device != 0);
CsmaCdDeviceRec rec(device);
CsmaDeviceRec rec(device);
m_deviceList.push_back(rec);
return (m_deviceList.size() - 1);
}
bool
CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
CsmaChannel::Reattach(Ptr<CsmaNetDevice> device)
{
NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
NS_DEBUG("CsmaChannel::Reattach (" << device << ")");
NS_ASSERT(device != 0);
std::vector<CsmaCdDeviceRec>::iterator it;
std::vector<CsmaDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->devicePtr == device)
@ -129,9 +129,9 @@ CsmaCdChannel::Reattach(Ptr<CsmaCdNetDevice> device)
}
bool
CsmaCdChannel::Reattach(uint32_t deviceId)
CsmaChannel::Reattach(uint32_t deviceId)
{
NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")");
NS_DEBUG("CsmaChannel::Reattach (" << deviceId << ")");
if (deviceId < m_deviceList.size())
{
return false;
@ -149,15 +149,15 @@ CsmaCdChannel::Reattach(uint32_t deviceId)
}
bool
CsmaCdChannel::Detach(uint32_t deviceId)
CsmaChannel::Detach(uint32_t deviceId)
{
NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")");
NS_DEBUG("CsmaChannel::Detach (" << deviceId << ")");
if (deviceId < m_deviceList.size())
{
if (!m_deviceList[deviceId].active)
{
NS_DEBUG("CsmaCdChannel::Detach Device is already detached ("
NS_DEBUG("CsmaChannel::Detach Device is already detached ("
<< deviceId << ")");
return false;
}
@ -165,7 +165,7 @@ CsmaCdChannel::Detach(uint32_t deviceId)
m_deviceList[deviceId].active = false;
if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId))
{
NS_DEBUG("CsmaCdChannel::Detach Device is currently"
NS_DEBUG("CsmaChannel::Detach Device is currently"
<< "transmitting (" << deviceId << ")");
// Here we will need to place a warning in the packet
}
@ -179,12 +179,12 @@ CsmaCdChannel::Detach(uint32_t deviceId)
}
bool
CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
CsmaChannel::Detach(Ptr<CsmaNetDevice> device)
{
NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
NS_DEBUG("CsmaChannel::Detach (" << device << ")");
NS_ASSERT(device != 0);
std::vector<CsmaCdDeviceRec>::iterator it;
std::vector<CsmaDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if ((it->devicePtr == device) && (it->active))
@ -197,27 +197,27 @@ CsmaCdChannel::Detach(Ptr<CsmaCdNetDevice> device)
}
bool
CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
CsmaChannel::TransmitStart(Packet& p, uint32_t srcId)
{
NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId
NS_DEBUG ("CsmaChannel::TransmitStart (" << &p << ", " << srcId
<< ")");
NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " <<
NS_DEBUG ("CsmaChannel::TransmitStart (): UID is " <<
p.GetUid () << ")");
if (m_state != IDLE)
{
NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE");
NS_DEBUG("CsmaChannel::TransmitStart (): state is not IDLE");
return false;
}
if (!IsActive(srcId))
{
NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected "
NS_DEBUG("CsmaChannel::TransmitStart (): ERROR: Seclected "
<< "source is not currently attached to network");
return false;
}
NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING");
NS_DEBUG("CsmaChannel::TransmitStart (): switch to TRANSMITTING");
m_currentPkt = p;
m_currentSrc = srcId;
m_state = TRANSMITTING;
@ -225,17 +225,17 @@ CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId)
}
bool
CsmaCdChannel::IsActive(uint32_t deviceId)
CsmaChannel::IsActive(uint32_t deviceId)
{
return (m_deviceList[deviceId].active);
}
bool
CsmaCdChannel::TransmitEnd()
CsmaChannel::TransmitEnd()
{
NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", "
NS_DEBUG("CsmaChannel::TransmitEnd (" << &m_currentPkt << ", "
<< m_currentSrc << ")");
NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " <<
NS_DEBUG("CsmaChannel::TransmitEnd (): UID is " <<
m_currentPkt.GetUid () << ")");
NS_ASSERT(m_state == TRANSMITTING);
@ -244,33 +244,33 @@ CsmaCdChannel::TransmitEnd()
bool retVal = true;
if (!IsActive(m_currentSrc)) {
NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source "
NS_DEBUG("CsmaChannel::TransmitEnd (): ERROR: Seclected source "
<< "was detached before the end of the transmission");
retVal = false;
}
NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " <<
NS_DEBUG ("CsmaChannel::TransmitEnd (): Schedule event in " <<
m_delay.GetSeconds () << "sec");
Simulator::Schedule (m_delay,
&CsmaCdChannel::PropagationCompleteEvent,
&CsmaChannel::PropagationCompleteEvent,
this);
return retVal;
}
void
CsmaCdChannel::PropagationCompleteEvent()
CsmaChannel::PropagationCompleteEvent()
{
NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent ("
NS_DEBUG("CsmaChannel::PropagationCompleteEvent ("
<< &m_currentPkt << ")");
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " <<
NS_DEBUG ("CsmaChannel::PropagationCompleteEvent (): UID is " <<
m_currentPkt.GetUid () << ")");
NS_ASSERT(m_state == PROPAGATING);
NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive");
NS_DEBUG ("CsmaChannel::PropagationCompleteEvent (): Receive");
std::vector<CsmaCdDeviceRec>::iterator it;
std::vector<CsmaDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->IsActive())
@ -283,10 +283,10 @@ CsmaCdChannel::PropagationCompleteEvent()
uint32_t
CsmaCdChannel::GetNumActDevices (void)
CsmaChannel::GetNumActDevices (void)
{
int numActDevices = 0;
std::vector<CsmaCdDeviceRec>::iterator it;
std::vector<CsmaDeviceRec>::iterator it;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
if (it->active)
@ -300,24 +300,24 @@ CsmaCdChannel::GetNumActDevices (void)
// 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
CsmaChannel::GetNDevices (void) const
{
return (m_deviceList.size());
}
Ptr<NetDevice>
CsmaCdChannel::GetDevice (uint32_t i) const
CsmaChannel::GetDevice (uint32_t i) const
{
Ptr< CsmaCdNetDevice > netDevice;
Ptr< CsmaNetDevice > netDevice;
netDevice = m_deviceList[i].devicePtr;
return netDevice;
}
int32_t
CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
CsmaChannel::GetDeviceNum (Ptr<CsmaNetDevice> device)
{
std::vector<CsmaCdDeviceRec>::iterator it;
std::vector<CsmaDeviceRec>::iterator it;
int i = 0;
for (it = m_deviceList.begin(); it < m_deviceList.end(); it++)
{
@ -338,7 +338,7 @@ CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
}
bool
CsmaCdChannel::IsBusy (void)
CsmaChannel::IsBusy (void)
{
if (m_state == IDLE)
{
@ -351,19 +351,19 @@ CsmaCdChannel::IsBusy (void)
}
DataRate
CsmaCdChannel::GetDataRate (void)
CsmaChannel::GetDataRate (void)
{
return m_bps;
}
Time
CsmaCdChannel::GetDelay (void)
CsmaChannel::GetDelay (void)
{
return m_delay;
}
WireState
CsmaCdChannel::GetState(void)
CsmaChannel::GetState(void)
{
return m_state;
}

View File

@ -18,8 +18,8 @@
* Author: Emmanuelle Laprise<emmanuelle.laprise@bluekazoo.ca>
*/
#ifndef CSMA_CD_CHANNEL_H
#define CSMA_CD_CHANNEL_H
#ifndef CSMA_CHANNEL_H
#define CSMA_CHANNEL_H
#include "ns3/channel.h"
#include "ns3/ptr.h"
@ -29,21 +29,21 @@
namespace ns3 {
class CsmaCdNetDevice;
class CsmaNetDevice;
/**
* \brief CsmaCdNetDevice Record
* \brief CsmaNetDevice Record
*
* Stores the information related to each net device that is
* connected to the channel.
*/
class CsmaCdDeviceRec {
class CsmaDeviceRec {
public:
Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device
Ptr< CsmaNetDevice > devicePtr; /// Pointer to the net device
bool active; /// Is net device enabled to TX/RX
CsmaCdDeviceRec();
CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device);
CsmaDeviceRec();
CsmaDeviceRec(Ptr< CsmaNetDevice > device);
/*
* \return If the net device pointed to by the devicePtr is active
* and ready to RX/TX.
@ -65,9 +65,9 @@ class CsmaCdNetDevice;
};
/**
* \brief CsmaCd Channel.
* \brief Csma Channel.
*
* This class represents a simple Csma/Cd channel that can be used
* 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
@ -84,32 +84,32 @@ class CsmaCdNetDevice;
* packet to the channel is really connected to this channel
*
*/
class CsmaCdChannel : public Channel {
class CsmaChannel : public Channel {
public:
/**
* \brief Create a CsmaCdChannel
* \brief Create a CsmaChannel
*
* By default, you get a channel with the name "CsmaCd Channel" that
* By default, you get a channel with the name "Csma Channel" that
* has an "infitely" fast transmission speed and zero delay.
*/
CsmaCdChannel ();
CsmaChannel ();
/**
* \brief Create a CsmaCdChannel
* \brief Create a CsmaChannel
*
* \param bps The bitrate of the channel
* \param delay Transmission delay through the channel
*/
CsmaCdChannel (const DataRate& bps, const Time& delay);
CsmaChannel (const DataRate& bps, const Time& delay);
/**
* \brief Create a CsmaCdChannel
* \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
*/
CsmaCdChannel (const std::string& name,
CsmaChannel (const std::string& name,
const DataRate& bps, const Time& delay);
/**
@ -118,7 +118,7 @@ public:
* \param device Device pointer to the netdevice to attach to the channel
* \return The assigned device number
*/
int32_t Attach (Ptr<CsmaCdNetDevice> device);
int32_t Attach (Ptr<CsmaNetDevice> device);
/**
* \brief Detach a given netdevice from this channel
*
@ -130,7 +130,7 @@ public:
* false if the device is not currently connected to the channel or
* can't be found.
*/
bool Detach (Ptr<CsmaCdNetDevice> device);
bool Detach (Ptr<CsmaNetDevice> device);
/**
* \brief Detach a given netdevice from this channel
*
@ -170,7 +170,7 @@ public:
* channel, false if the device is currently connected to the
* channel or can't be found.
*/
bool Reattach(Ptr<CsmaCdNetDevice> device);
bool Reattach(Ptr<CsmaNetDevice> device);
/**
* \brief Start transmitting a packet over the channel
*
@ -216,7 +216,7 @@ public:
* \param device Device pointer to the netdevice for which the device
* number is needed
*/
int32_t GetDeviceNum (Ptr<CsmaCdNetDevice> device);
int32_t GetDeviceNum (Ptr<CsmaNetDevice> device);
/**
* \return Returns the state of the channel (IDLE -- free,
* TRANSMITTING -- busy, PROPAGATING - busy )
@ -278,7 +278,7 @@ private:
* 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;
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
@ -304,4 +304,4 @@ private:
} // namespace ns3
#endif /* CSMA_CD_CHANNEL_H */
#endif /* CSMA_CHANNEL_H */

View File

@ -28,23 +28,22 @@
#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"
#include "csma-channel.h"
#include "csma-net-device.h"
#include "csma-ipv4-topology.h"
namespace ns3 {
uint32_t
CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
CsmaIpv4Topology::AddIpv4CsmaNode(Ptr<Node> n1,
Ptr<CsmaChannel> ch,
Eui48Address addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
// assume full-duplex
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::IP_ARP,
Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
ns3::CsmaNetDevice::IP_ARP,
true, true);
nd0->AddQueue(q);
nd0->Attach (ch);
@ -53,47 +52,47 @@ CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
void
CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
CsmaIpv4Topology::AddIpv4LlcCsmaNode(Ptr<Node> n1,
Ptr<CsmaChannel> ch,
Eui48Address addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::LLC,
Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
ns3::CsmaNetDevice::LLC,
true, false);
nd0->AddQueue(q);
nd0->Attach (ch);
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::LLC,
Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
ns3::CsmaNetDevice::LLC,
false, true);
nd1->AddQueue(q);
nd1->Attach (ch);
}
void
CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
CsmaIpv4Topology::AddIpv4RawCsmaNode(Ptr<Node> n1,
Ptr<CsmaChannel> ch,
Eui48Address addr)
{
Ptr<Queue> q = Queue::CreateDefault ();
Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::RAW,
Ptr<CsmaNetDevice> nd0 = Create<CsmaNetDevice> (n1, addr,
ns3::CsmaNetDevice::RAW,
true, false);
nd0->AddQueue(q);
nd0->Attach (ch);
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::RAW,
Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
ns3::CsmaNetDevice::RAW,
false, true);
nd1->AddQueue(q);
nd1->Attach (ch);
}
void
CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
CsmaIpv4Topology::AddIpv4Address(Ptr<Node> n1,
int ndNum,
const Ipv4Address& addr1,
const Ipv4Mask& netmask1)
@ -115,7 +114,7 @@ CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> n1,
}
void
CsmaCdIpv4Topology::AddIpv4Routes (
CsmaIpv4Topology::AddIpv4Routes (
Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
{
// Assert that both are Ipv4 nodes

View File

@ -18,22 +18,22 @@
// Author: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
//
#ifndef __CSMA_CD_IPV4_TOPOLOGY_H__
#define __CSMA_CD_IPV4_TOPOLOGY_H__
#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-cd-net-device.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 CsmaCdIpv4Channel;
class CsmaIpv4Channel;
class Node;
class IPAddr;
class DataRate;
@ -41,54 +41,54 @@ class Queue;
/**
* \brief A helper class to create Topologies based on the
* InternetNodes and CsmaCdChannels. Either the
* SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used
* InternetNodes and CsmaChannels. Either the
* SimpleCsmaNetDevice or the LLCCsmaNetDevice can be used
* when constructing these topologies.
*/
class CsmaCdIpv4Topology {
class CsmaIpv4Topology {
public:
/**
* \param n1 Node to be attached to the Csma/Cd channel
* \param ch CsmaCdChannel to which node n1 should be attached
* \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/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
* 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 AddIpv4CsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
static uint32_t AddIpv4CsmaNode( Ptr<Node> n1,
Ptr<CsmaChannel> 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 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/Cd node to a Csma/Cd channel. This function adds
* a RawCsmaCdNetDevice to the nodes so that they can connect
* to a CsmaCdChannel.
* 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 AddIpv4RawCsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
static void AddIpv4RawCsmaNode( Ptr<Node> n1,
Ptr<CsmaChannel> 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 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/Cd node to a Csma/Cd channel. This function adds
* a LlcCsmaCdNetDevice to the nodes so that they can connect
* to a CsmaCdChannel.
* 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 AddIpv4LlcCsmaCdNode( Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
static void AddIpv4LlcCsmaNode( Ptr<Node> n1,
Ptr<CsmaChannel> ch,
Eui48Address addr);
@ -97,11 +97,11 @@ public:
* \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
* \param netmask1 network mask for ndNum of node n1
*
* Add an Ipv4Address to the Ipv4 interface associated with the
* ndNum CsmaCdIpv4NetDevices on the provided
* CsmaCdIpv4Channel
* ndNum CsmaIpv4NetDevices on the provided
* CsmaIpv4Channel
*/
static void AddIpv4Address(Ptr<Node> n1, int ndNum,
const Ipv4Address& addr1,

View File

@ -25,24 +25,24 @@
#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 "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 ("CsmaCdNetDevice");
NS_DEBUG_COMPONENT_DEFINE ("CsmaNetDevice");
namespace ns3 {
CsmaCdTraceType::CsmaCdTraceType (enum Type type)
CsmaTraceType::CsmaTraceType (enum Type type)
: m_type (type)
{}
CsmaCdTraceType::CsmaCdTraceType ()
CsmaTraceType::CsmaTraceType ()
: m_type (RX)
{}
void
CsmaCdTraceType::Print (std::ostream &os) const
CsmaTraceType::Print (std::ostream &os) const
{
switch (m_type) {
case RX:
@ -54,65 +54,65 @@ CsmaCdTraceType::Print (std::ostream &os) const
}
}
uint16_t
CsmaCdTraceType::GetUid (void)
CsmaTraceType::GetUid (void)
{
static uint16_t uid = AllocateUid<CsmaCdTraceType> ("CsmaCdTraceType");
static uint16_t uid = AllocateUid<CsmaTraceType> ("CsmaTraceType");
return uid;
}
std::string
CsmaCdTraceType::GetName (void) const
CsmaTraceType::GetName (void) const
{
return "CsmaCdTraceType";
return "CsmaTraceType";
}
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node)
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node)
: NetDevice (node, Eui48Address::Allocate ()),
m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
m_encapMode = IP_ARP;
Init(true, true);
}
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaCdEncapsulationMode encapMode)
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaEncapsulationMode encapMode)
: NetDevice(node, addr),
m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
m_encapMode = encapMode;
Init(true, true);
}
CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaCdEncapsulationMode encapMode,
CsmaNetDevice::CsmaNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaEncapsulationMode encapMode,
bool sendEnable, bool receiveEnable)
: NetDevice(node, addr),
m_bps (DataRate (0xffffffff))
{
NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
NS_DEBUG ("CsmaNetDevice::CsmaNetDevice (" << node << ")");
m_encapMode = encapMode;
Init(sendEnable, receiveEnable);
}
CsmaCdNetDevice::~CsmaCdNetDevice()
CsmaNetDevice::~CsmaNetDevice()
{
NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
NS_DEBUG ("CsmaNetDevice::~CsmaNetDevice ()");
m_queue = 0;
}
void
CsmaCdNetDevice::DoDispose ()
CsmaNetDevice::DoDispose ()
{
m_channel = 0;
NetDevice::DoDispose ();
}
//
// Assignment operator for CsmaCdNetDevice.
// 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
@ -120,16 +120,16 @@ CsmaCdNetDevice::DoDispose ()
// here is to return the newly constructed net device.
//
/*
CsmaCdNetDevice&
CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd)
CsmaNetDevice&
CsmaNetDevice::operator= (const CsmaNetDevice nd)
{
NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")");
NS_DEBUG ("CsmaNetDevice::operator= (" << &nd << ")");
return *this;
}
*/
void
CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
CsmaNetDevice::Init(bool sendEnable, bool receiveEnable)
{
m_txMachineState = READY;
m_tInterframeGap = Seconds(0);
@ -138,49 +138,48 @@ CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable)
EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff"));
EnableMulticast();
EnablePointToPoint();
SetSendEnable (sendEnable);
SetReceiveEnable (receiveEnable);
}
void
CsmaCdNetDevice::SetSendEnable (bool sendEnable)
CsmaNetDevice::SetSendEnable (bool sendEnable)
{
m_sendEnable = sendEnable;
}
void
CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable)
CsmaNetDevice::SetReceiveEnable (bool receiveEnable)
{
m_receiveEnable = receiveEnable;
}
bool
CsmaCdNetDevice::IsSendEnabled (void)
CsmaNetDevice::IsSendEnabled (void)
{
return (m_sendEnable);
}
bool
CsmaCdNetDevice::IsReceiveEnabled (void)
CsmaNetDevice::IsReceiveEnabled (void)
{
return (m_receiveEnable);
}
void
CsmaCdNetDevice::SetDataRate (DataRate bps)
CsmaNetDevice::SetDataRate (DataRate bps)
{
m_bps = bps;
}
void
CsmaCdNetDevice::SetInterframeGap (Time t)
CsmaNetDevice::SetInterframeGap (Time t)
{
m_tInterframeGap = t;
}
void
CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
CsmaNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
uint32_t maxSlots, uint32_t ceiling,
uint32_t maxRetries)
{
@ -191,7 +190,7 @@ CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots,
m_backoff.m_maxRetries = maxRetries;
}
void
CsmaCdNetDevice::AddHeader (Packet& p, Eui48Address dest,
CsmaNetDevice::AddHeader (Packet& p, Eui48Address dest,
uint16_t protocolNumber)
{
if (m_encapMode == RAW)
@ -228,7 +227,7 @@ CsmaCdNetDevice::AddHeader (Packet& p, Eui48Address dest,
p.AddTrailer(trailer);
}
bool
CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
CsmaNetDevice::ProcessHeader (Packet& p, uint16_t & param)
{
if (m_encapMode == RAW)
{
@ -266,7 +265,7 @@ CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
}
bool
CsmaCdNetDevice::DoNeedsArp (void) const
CsmaNetDevice::DoNeedsArp (void) const
{
if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
{
@ -279,10 +278,14 @@ CsmaCdNetDevice::DoNeedsArp (void) const
}
bool
CsmaCdNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber)
CsmaNetDevice::SendTo (
const Packet& packet,
const Address& dest,
uint16_t protocolNumber)
{
NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")");
NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")");
Packet p = packet;
NS_DEBUG ("CsmaNetDevice::SendTo (" << &p << ")");
NS_DEBUG ("CsmaNetDevice::SendTo (): UID is " << p.GetUid () << ")");
NS_ASSERT (IsLinkUp ());
@ -313,10 +316,10 @@ CsmaCdNetDevice::SendTo (Packet& p, const Address& dest, uint16_t protocolNumber
}
void
CsmaCdNetDevice::TransmitStart ()
CsmaNetDevice::TransmitStart ()
{
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")");
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is "
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.
@ -344,12 +347,12 @@ CsmaCdNetDevice::TransmitStart ()
m_backoff.IncrNumRetries();
Time backoffTime = m_backoff.GetBackoffTime();
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): "
NS_DEBUG ("CsmaNetDevice::TransmitStart (): "
<< "Channel busy, backing off for "
<< backoffTime.GetSeconds () << "sec");
Simulator::Schedule (backoffTime,
&CsmaCdNetDevice::TransmitStart,
&CsmaNetDevice::TransmitStart,
this);
}
}
@ -359,16 +362,16 @@ CsmaCdNetDevice::TransmitStart ()
m_txMachineState = BUSY;
Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize()));
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
NS_DEBUG ("CsmaNetDevice::TransmitStart (): " <<
"Schedule TransmitCompleteEvent in " <<
tEvent.GetSeconds () << "sec");
Simulator::Schedule (tEvent,
&CsmaCdNetDevice::TransmitCompleteEvent,
&CsmaNetDevice::TransmitCompleteEvent,
this);
if (!m_channel->TransmitStart (m_currentPkt, m_deviceId))
{
NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " <<
NS_DEBUG ("CsmaNetDevice::TransmitStart (): " <<
"Channel transmit start did not work at " <<
tEvent.GetSeconds () << "sec");
m_txMachineState = READY;
@ -383,11 +386,11 @@ CsmaCdNetDevice::TransmitStart ()
void
CsmaCdNetDevice::TransmitAbort (void)
CsmaNetDevice::TransmitAbort (void)
{
NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()");
NS_DEBUG ("CsmaNetDevice::TransmitAbort ()");
NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " <<
NS_DEBUG ("CsmaNetDevice::TransmitAbort (): Pkt UID is " <<
m_currentPkt.GetUid () << ")");
// Try to transmit a new packet
@ -400,9 +403,9 @@ CsmaCdNetDevice::TransmitAbort (void)
}
void
CsmaCdNetDevice::TransmitCompleteEvent (void)
CsmaNetDevice::TransmitCompleteEvent (void)
{
NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()");
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
@ -414,24 +417,24 @@ CsmaCdNetDevice::TransmitCompleteEvent (void)
NS_ASSERT(m_channel->GetState() == TRANSMITTING);
m_txMachineState = GAP;
NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
NS_DEBUG ("CsmaNetDevice::TransmitCompleteEvent (): Pkt UID is " <<
m_currentPkt.GetUid () << ")");
m_channel->TransmitEnd ();
NS_DEBUG (
"CsmaCdNetDevice::TransmitCompleteEvent (): " <<
"CsmaNetDevice::TransmitCompleteEvent (): " <<
"Schedule TransmitReadyEvent in "
<< m_tInterframeGap.GetSeconds () << "sec");
Simulator::Schedule (m_tInterframeGap,
&CsmaCdNetDevice::TransmitReadyEvent,
&CsmaNetDevice::TransmitReadyEvent,
this);
}
void
CsmaCdNetDevice::TransmitReadyEvent (void)
CsmaNetDevice::TransmitReadyEvent (void)
{
NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()");
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
@ -455,26 +458,26 @@ CsmaCdNetDevice::TransmitReadyEvent (void)
}
Ptr<TraceResolver>
CsmaCdNetDevice::GetTraceResolver (void)
CsmaNetDevice::GetTraceResolver (void)
{
Ptr<CompositeTraceResolver> resolver = Create<CompositeTraceResolver> ();
resolver->AddChild ("queue", m_queue);
resolver->AddSource ("rx",
"receive MAC packet",
m_rxTrace,
CsmaCdTraceType (CsmaCdTraceType::RX));
CsmaTraceType (CsmaTraceType::RX));
resolver->AddSource ("drop",
"drop MAC packet",
m_dropTrace,
CsmaCdTraceType (CsmaCdTraceType::DROP));
CsmaTraceType (CsmaTraceType::DROP));
resolver->SetParent (NetDevice::GetTraceResolver ());
return resolver;
}
bool
CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
CsmaNetDevice::Attach (Ptr<CsmaChannel> ch)
{
NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")");
NS_DEBUG ("CsmaNetDevice::Attach (" << &ch << ")");
m_channel = ch;
@ -490,15 +493,15 @@ CsmaCdNetDevice::Attach (Ptr<CsmaCdChannel> ch)
}
void
CsmaCdNetDevice::AddQueue (Ptr<Queue> q)
CsmaNetDevice::AddQueue (Ptr<Queue> q)
{
NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")");
NS_DEBUG ("CsmaNetDevice::AddQueue (" << q << ")");
m_queue = q;
}
void
CsmaCdNetDevice::Receive (const Packet& packet)
CsmaNetDevice::Receive (const Packet& packet)
{
EthernetHeader header (false);
EthernetTrailer trailer;
@ -506,7 +509,7 @@ CsmaCdNetDevice::Receive (const Packet& packet)
Eui48Address destination;
Packet p = packet;
NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")");
NS_DEBUG ("CsmaNetDevice::Receive UID is (" << p.GetUid() << ")");
// Only receive if send side of net device is enabled
if (!IsReceiveEnabled())
@ -534,6 +537,8 @@ CsmaCdNetDevice::Receive (const Packet& packet)
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.
@ -556,19 +561,18 @@ CsmaCdNetDevice::Receive (const Packet& packet)
break;
}
m_rxTrace (p);
ForwardUp (p, protocol, header.GetSource ());
return;
}
Ptr<Queue>
CsmaCdNetDevice::GetQueue(void) const
CsmaNetDevice::GetQueue(void) const
{
return m_queue;
}
Ptr<Channel>
CsmaCdNetDevice::DoGetChannel(void) const
CsmaNetDevice::DoGetChannel(void) const
{
return m_channel;
}

View File

@ -19,8 +19,8 @@
* Derived from the p2p net device file
*/
#ifndef CSMA_CD_NET_DEVICE_H
#define CSMA_CD_NET_DEVICE_H
#ifndef CSMA_NET_DEVICE_H
#define CSMA_NET_DEVICE_H
#include <string.h>
#include "ns3/node.h"
@ -39,17 +39,17 @@
namespace ns3 {
class Queue;
class CsmaCdChannel;
class CsmaChannel;
class CsmaCdTraceType : public TraceContextElement
class CsmaTraceType : public TraceContextElement
{
public:
enum Type {
RX,
DROP
};
CsmaCdTraceType (enum Type type);
CsmaCdTraceType ();
CsmaTraceType (enum Type type);
CsmaTraceType ();
void Print (std::ostream &os) const;
static uint16_t GetUid (void);
std::string GetName (void) const;
@ -58,59 +58,74 @@ private:
};
/**
* \class CsmaCdNetDevice
* \brief A Device for a CsmaCd Network Link.
* \class CsmaNetDevice
* \brief A Device for a Csma Network Link.
*
* The Csma/Cd net device class is analogous to layer 1 and 2 of the
* 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/Cd net device class
* 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/Cd net device will receive all
* packets written to the Csma/Cd link. The ProcessHeader function can
* 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 CsmaCdNetDevice : public NetDevice {
class CsmaNetDevice : public NetDevice {
public:
/**
* Enumeration of the types of packets supported in the class.
*
*/
enum CsmaCdEncapsulationMode {
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 */
};
CsmaCdNetDevice (Ptr<Node> node);
CsmaNetDevice (Ptr<Node> node);
/**
* Construct a CsmaCdNetDevice
* Construct a CsmaNetDevice
*
* This is the constructor for the CsmaCdNetDevice. It takes as a
* 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
*/
CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr, CsmaCdEncapsulationMode pktType);
CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
CsmaCdEncapsulationMode pktType,
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 CsmaCdNetDevice
* Destroy a CsmaNetDevice
*
* This is the destructor for the CsmaCdNetDevice.
* This is the destructor for the CsmaNetDevice.
*/
virtual ~CsmaCdNetDevice();
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
@ -147,23 +162,23 @@ enum CsmaCdEncapsulationMode {
/**
* Attach the device to a channel.
*
* The function Attach is used to add a CsmaCdNetDevice to a
* CsmaCdChannel.
* 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<CsmaCdChannel> ch);
bool Attach (Ptr<CsmaChannel> ch);
/**
* Attach a queue to the CsmaCdNetDevice.
* Attach a queue to the CsmaNetDevice.
*
* 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
* 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 CsmaCdTopology::AddCsmaCdLink ()
* @see CsmaTopology::AddCsmaLink ()
* @see Queue
* @see DropTailQueue
* \param queue a pointer to the queue for which object is assuming
@ -171,14 +186,14 @@ enum CsmaCdEncapsulationMode {
*/
void AddQueue (Ptr<Queue> queue);
/**
* Receive a packet from a connected CsmaCdChannel.
* Receive a packet from a connected CsmaChannel.
*
* The CsmaCdNetDevice receives packets from its connected channel
* 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 CsmaCdChannel
* @see CsmaChannel
* \param p a reference to the received packet
*/
void Receive (const Packet& p);
@ -242,14 +257,14 @@ protected:
private:
// disable copy constructor and operator =
CsmaCdNetDevice &operator = (const CsmaCdNetDevice &o);
CsmaCdNetDevice (const CsmaCdNetDevice &o);
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/Cd network
* 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
@ -263,13 +278,13 @@ private:
* \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);
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 CsmaCdNetDevice to begin the process of sending a packet
* 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
@ -278,7 +293,7 @@ private:
* is busy, the method reschedules itself for a later time (within
* the backoff period)
*
* @see CsmaCdChannel::TransmitStart ()
* @see CsmaChannel::TransmitStart ()
* @see TransmitCompleteEvent ()
*/
void TransmitStart ();
@ -295,7 +310,7 @@ private:
* also schedules the TransmitReadyEvent at which time the transmitter
* becomes ready to send the next packet.
*
* @see CsmaCdChannel::TransmitEnd ()
* @see CsmaChannel::TransmitEnd ()
* @see TransmitReadyEvent ()
*/
void TransmitCompleteEvent (void);
@ -361,7 +376,7 @@ private:
* function and that should be processed by the ProcessHeader
* function.
*/
CsmaCdEncapsulationMode m_encapMode;
CsmaEncapsulationMode m_encapMode;
/**
* The data rate that the Net Device uses to simulate packet transmission
* timing.
@ -387,14 +402,14 @@ private:
*/
Packet m_currentPkt;
/**
* The CsmaCdChannel to which this CsmaCdNetDevice has been
* The CsmaChannel to which this CsmaNetDevice has been
* attached.
* @see class CsmaCdChannel
* @see class CsmaChannel
*/
Ptr<CsmaCdChannel> m_channel;
Ptr<CsmaChannel> m_channel;
/**
* The Queue which this CsmaCdNetDevice uses as a packet source.
* Management of this Queue has been delegated to the CsmaCdNetDevice
* 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
@ -415,5 +430,5 @@ private:
}; // namespace ns3
#endif // CSMA_CD_NET_DEVICE_H
#endif // CSMA_NET_DEVICE_H

View File

@ -19,38 +19,38 @@
//
//
// Topology helper for CsmaCd channels in ns3.
// Topology helper for Csma 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 "csma-channel.h"
#include "csma-net-device.h"
#include "csma-topology.h"
#include "ns3/socket-factory.h"
namespace ns3 {
Ptr<CsmaCdChannel>
CsmaCdTopology::CreateCsmaCdChannel(
Ptr<CsmaChannel>
CsmaTopology::CreateCsmaChannel(
const DataRate& bps,
const Time& delay)
{
Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
Ptr<CsmaChannel> channel = Create<CsmaChannel> (bps, delay);
return channel;
}
#if 0
Ptr<CsmaCdNetDevice>
CsmaCdTopology::AddCsmaCdEthernetNode(
Ptr<CsmaNetDevice>
CsmaTopology::AddCsmaEthernetNode(
Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
Ptr<CsmaChannel> ch,
MacAddress addr)
{
Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
ns3::CsmaCdNetDevice::ETHERNET_V1);
Ptr<CsmaNetDevice> nd1 = Create<CsmaNetDevice> (n1, addr,
ns3::CsmaNetDevice::ETHERNET_V1);
Ptr<Queue> q = Queue::CreateDefault ();
nd1->AddQueue(q);
@ -60,9 +60,9 @@ CsmaCdTopology::AddCsmaCdEthernetNode(
}
Ptr<PacketSocket>
CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
Ptr<CsmaCdNetDevice> ndDest)
CsmaTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaNetDevice> ndSrc,
Ptr<CsmaNetDevice> ndDest)
{
Ptr<PacketSocket> socket = Create<PacketSocket> ();
socket->Bind(ndSrc);
@ -73,8 +73,8 @@ CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
}
Ptr<PacketSocket>
CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
CsmaTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaNetDevice> ndSrc,
MacAddress macAddr)
{
Ptr<PacketSocket> socket = Create<PacketSocket> ();
@ -86,7 +86,7 @@ CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
}
Ptr<Socket>
CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
CsmaTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
{
InterfaceId iid = InterfaceId::LookupByName (iid_name);

View File

@ -19,11 +19,11 @@
//
// Topology helper for multipoint channels in ns3.
//
#ifndef CSMA_CD_TOPOLOGY_H
#define CSMA_CD_TOPOLOGY_H
#ifndef CSMA_TOPOLOGY_H
#define CSMA_TOPOLOGY_H
#include "ns3/ptr.h"
#include "ns3/csma-cd-net-device.h"
#include "ns3/csma-net-device.h"
#include "ns3/node.h"
// The topology class consists of only static methods thar are used to
@ -31,16 +31,16 @@
namespace ns3 {
class CsmaCdChannel;
class CsmaChannel;
class Node;
class DataRate;
class Queue;
/**
* \brief A helper class to create CsmaCd Topologies
* \brief A helper class to create Csma Topologies
*
* CsmaCd topologies are created based on the
* ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel
* 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
@ -49,30 +49,30 @@ class Queue;
* EthernetNetDevice class filters received data packets
* according to its destination Mac addresses.
*/
class CsmaCdTopology {
class CsmaTopology {
public:
/**
* \param dataRate Maximum transmission link rate
* \param delay propagation delay between any two nodes
* \return Pointer to the created CsmaCdChannel
* \return Pointer to the created CsmaChannel
*
* Create a CsmaCdChannel. All nodes connected to a multipoint
* Create a CsmaChannel. All nodes connected to a multipoint
* channels will receive all packets written to that channel
*/
static Ptr<CsmaCdChannel> CreateCsmaCdChannel(
static Ptr<CsmaChannel> CreateCsmaChannel(
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 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<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1,
Ptr<CsmaCdChannel> ch,
static Ptr<CsmaNetDevice> AddCsmaEthernetNode(Ptr<Node> n1,
Ptr<CsmaChannel> ch,
MacAddress addr);
/**
@ -86,8 +86,8 @@ public:
* two net devices
*/
static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
Ptr<CsmaCdNetDevice> ndDest);
Ptr<CsmaNetDevice> ndSrc,
Ptr<CsmaNetDevice> ndDest);
/**
* \param app Application that will be sending data to the agent
@ -101,7 +101,7 @@ static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
* net device to a destination MacAddress
*/
static Ptr<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
Ptr<CsmaCdNetDevice> ndSrc,
Ptr<CsmaNetDevice> ndSrc,
MacAddress macAddr);
/**

19
src/devices/csma/wscript Normal file
View File

@ -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',
]

View File

@ -122,9 +122,10 @@ void PointToPointNetDevice::SetInterframeGap(const Time& t)
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 @@ void PointToPointNetDevice::Receive (Packet& p)
uint16_t protocol = 0;
Packet packet = p;
ProcessHeader(packet, protocol);
m_rxTrace (packet);
ProcessHeader(packet, protocol);
ForwardUp (packet, protocol, GetBroadcast ());
}

View File

@ -182,7 +182,6 @@ protected:
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 @@ private:
* @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.

View File

@ -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 @@ void
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 @@ AsciiTrace::TraceAllNetDeviceRx (void)
}
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 @@ AsciiTrace::LogDevQueue (TraceContext const &context, Packet const &packet)
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);

View File

@ -37,7 +37,9 @@ public:
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;
};

View File

@ -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 @@ void
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

View File

@ -57,6 +57,12 @@ UdpSocket::~UdpSocket ()
m_udp = 0;
}
enum Socket::SocketErrno
UdpSocket::GetErrno (void) const
{
return m_errno;
}
Ptr<Node>
UdpSocket::GetNode (void) const
{
@ -118,11 +124,6 @@ UdpSocket::Bind (const Address &address)
return FinishBind ();
}
enum Socket::SocketErrno
UdpSocket::GetErrno (void) const
{
return m_errno;
}
int
UdpSocket::ShutdownSend (void)
{
@ -137,73 +138,42 @@ UdpSocket::ShutdownRecv (void)
}
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 @@ UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port,
}
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 @@ UdpSocket::ForwardUp (const Packet &packet, Ipv4Address ipv4, uint16_t port)
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

View File

@ -47,27 +47,14 @@ public:
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 @@ private:
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;

View File

@ -52,9 +52,9 @@ MobilityModel::Set (const Position &position)
}
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);
}

View File

@ -57,7 +57,7 @@ public:
* \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

View File

@ -147,7 +147,7 @@ std::ostream& operator<< (std::ostream& os, const Address & address)
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 @@ std::ostream& operator<< (std::ostream& os, const Address & address)
// 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;
}

View File

@ -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 @@ EthernetHeader::Print (std::ostream &os) const
{
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;
}

View File

@ -152,7 +152,7 @@ std::ostream& operator<< (std::ostream& os, const Eui48Address & address)
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 @@ std::ostream& operator<< (std::ostream& os, const Eui48Address & address)
// 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;
}

View File

@ -155,7 +155,7 @@ std::ostream& operator<< (std::ostream& os, const Eui64Address & address)
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 @@ std::ostream& operator<< (std::ostream& os, const Eui64Address & address)
// 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;
}

View File

@ -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 @@ InetSocketAddress::ConvertFrom (const Address &address)
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

View File

@ -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 @@ private:
} // namespace ns3
#endif /* IPV4_TRANSPORT_ADDRESS_H */
#endif /* INET_SOCKET_ADDRESS_H */

View File

@ -171,8 +171,11 @@ Ipv4Address::IsBroadcast (void) const
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

View File

@ -172,7 +172,7 @@ NetDevice::DisablePointToPoint (void)
// 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 @@ NetDevice::GetChannel (void) const
// 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;

View File

@ -150,7 +150,7 @@ public:
*
* \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 @@ public:
* 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 @@ public:
* 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.

View File

@ -52,13 +52,18 @@ PacketSocket::DoDispose (void)
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 @@ PacketSocket::DoBind (const PacketSocketAddress &address)
return 0;
}
enum Socket::SocketErrno
PacketSocket::GetErrno (void) const
{
return m_errno;
}
int
PacketSocket::ShutdownSend (void)
{
@ -139,26 +139,20 @@ PacketSocket::ShutdownRecv (void)
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 @@ PacketSocket::DoConnect(const Address &ad,
}
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 @@ PacketSocket::DoSend (const uint8_t* buffer,
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 @@ PacketSocket::DoSendTo(const Address &address,
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 @@ PacketSocket::DoSendTo(const Address &address,
}
}
}
if (!error && !dataSent.IsNull ())
if (!error)
{
dataSent (this, p.GetSize ());
NotifyDataSent (p.GetSize ());
}
if (error)
@ -298,18 +261,6 @@ PacketSocket::DoSendTo(const Address &address,
}
}
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 @@ PacketSocket::ForwardUp (Ptr<NetDevice> device, const Packet &packet,
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

View File

@ -78,27 +78,15 @@ public:
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 @@ private:
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;

View File

@ -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)
{
return DoClose (closeCompleted);
}
int
Socket::Connect(const Address & address,
Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose)
{
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);
}
int
Socket::Send (const uint8_t* buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
return DoSend (buffer, size, dataSent);
}
int
Socket::SendTo(const Address &address,
const uint8_t *buffer,
uint32_t size,
Callback<void, Ptr<Socket>, uint32_t> dataSent)
{
return DoSendTo (address, buffer, size, dataSent);
m_closeCompleted = closeCompleted;
}
void
Socket::Recv(Callback<void, Ptr<Socket>, const uint8_t*, uint32_t,const Address&> callback)
Socket::SetConnectCallback (Callback<void, Ptr<Socket> > connectionSucceeded,
Callback<void, Ptr<Socket> > connectionFailed,
Callback<void, Ptr<Socket> > halfClose)
{
DoRecv (callback);
m_connectionSucceeded = connectionSucceeded;
m_connectionFailed = connectionFailed;
m_halfClose = halfClose;
}
void
Socket::RecvDummy(Callback<void, Ptr<Socket>, uint32_t,const Address&> callback)
Socket::SetAcceptCallback (Callback<bool, Ptr<Socket>, const Address &> connectionRequest,
Callback<void, Ptr<Socket>, const Address&> newConnectionCreated,
Callback<void, Ptr<Socket> > closeRequested)
{
DoRecvDummy (callback);
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;
}
void
Socket::NotifyCloseCompleted (void)
{
if (!m_closeCompleted.IsNull ())
{
m_closeCompleted (this);
}
}
void
Socket::NotifyConnectionSucceeded (void)
{
if (!m_connectionSucceeded.IsNull ())
{
m_connectionSucceeded (this);
}
}
void
Socket::NotifyConnectionFailed (void)
{
if (!m_connectionFailed.IsNull ())
{
m_connectionFailed (this);
}
}
void
Socket::NotifyHalfClose (void)
{
if (!m_halfClose.IsNull ())
{
m_halfClose (this);
}
}
bool
Socket::RefuseAllConnections (Ptr<Socket> socket, const Address& address)
Socket::NotifyConnectionRequest (const Address &from)
{
return false;
if (!m_connectionRequest.IsNull ())
{
return m_connectionRequest (this, from);
}
else
{
// refuse all incomming connections by default.
return false;
}
}
void
Socket::DummyCallbackVoidSocket (Ptr<Socket> socket)
{}
void
Socket::DummyCallbackVoidSocketUi32 (Ptr<Socket> socket, uint32_t)
{}
Socket::NotifyNewConnectionCreated (Ptr<Socket> socket, const Address &from)
{
if (!m_newConnectionCreated.IsNull ())
{
m_newConnectionCreated (socket, from);
}
}
void
Socket::DummyCallbackVoidSocketUi32Address (Ptr<Socket> socket, uint32_t, const Address &)
{}
Socket::NotifyCloseRequested (void)
{
if (!m_closeRequested.IsNull ())
{
m_closeRequested (this);
}
}
void
Socket::DummyCallbackVoidSocketBufferUi32Address (Ptr<Socket> socket, const uint8_t *, uint32_t,
const Address &)
{}
Socket::NotifyDataSent (uint32_t size)
{
if (!m_dataSent.IsNull ())
{
m_dataSent (this, size);
}
}
void
Socket::DummyCallbackVoidSocketAddress (Ptr<Socket> socket, const Address &)
{}
Socket::NotifyDataReceived (const Packet &p, const Address &from)
{
if (!m_receivedData.IsNull ())
{
m_receivedData (this, p, from);
}
}
}//namespace ns3

View File

@ -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 @@ public:
*/
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 @@ public:
*/
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 @@ public:
/**
* \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

View File

@ -48,8 +48,7 @@ SPFVertex::SPFVertex () :
{
}
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 @@ SPFVertex::SPFVertex (GlobalRouterLSA* lsa) :
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 @@ SPFVertex::GetVertexId (void) const
}
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 @@ GlobalRouteManagerLSDB::~GlobalRouteManagerLSDB ()
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 @@ GlobalRouteManagerLSDB::Initialize ()
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 @@ GlobalRouteManagerLSDB::GetLSA (Ipv4Address addr) const
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 @@ GlobalRouteManagerImpl::BuildGlobalRoutingDatabase ()
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::InitializeRoutes ()
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 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
// 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 ();
if (v->GetLSA ()->GetLSType () == GlobalRoutingLSA::RouterLSA)
{
distance = v->GetDistanceFromRoot () + l->GetMetric ();
}
else
{
distance = v->GetDistanceFromRoot ();
}
NS_DEBUG ("SPFNext: Considering w_lsa " <<
w_lsa->GetLinkStateId ());
NS_DEBUG ("SPFNext: Considering w_lsa " << w_lsa->GetLinkStateId ());
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);
//
// 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 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
//
// 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 @@ GlobalRouteManagerImpl::SPFNext (SPFVertex* v, CandidateQueue& candidate)
// 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::SPFNext (SPFVertex* v, CandidateQueue& candidate)
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 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
// 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 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
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 @@ GlobalRouteManagerImpl::SPFNexthopCalculation (
// 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 @@ GlobalRouteManagerImpl::SPFGetNextLink (
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 @@ GlobalRouteManagerImpl::SPFGetNextLink (
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 @@ GlobalRouteManagerImpl::SPFGetNextLink (
// 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 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
//
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 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
// 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 @@ GlobalRouteManagerImpl::SPFCalculate (Ipv4Address root)
// 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).
//
@ -1025,6 +1164,80 @@ GlobalRouteManagerImpl::FindOutgoingInterfaceId (Ipv4Address a)
return 0;
}
//
// 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 ()
//
@ -1109,7 +1322,7 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
// 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 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
//
// 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 @@ GlobalRouteManagerImpl::SPFIntraAddRouter (SPFVertex* v)
}
}
}
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 @@ GlobalRouteManagerImplTest::RunTests (void)
// 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 @@ GlobalRouteManagerImplTest::RunTests (void)
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);

View File

@ -102,10 +102,10 @@ public:
*
* @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 @@ public:
* @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 @@ public:
*
* @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 @@ public:
* 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 @@ public:
* 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 @@ public:
* 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 @@ public:
* 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 @@ public:
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 @@ public:
* 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 @@ public:
* 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 @@ private:
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

View File

@ -28,21 +28,21 @@ namespace ns3 {
// ---------------------------------------------------------------------------
//
// 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 @@ GlobalRouterLinkRecord::GlobalRouterLinkRecord (
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 @@ GlobalRouterLSA::operator= (const GlobalRouterLSA& lsa)
}
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 @@ GlobalRouterLSA::CopyLinkRecords (const GlobalRouterLSA& lsa)
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 @@ GlobalRouterLSA::GetLinkRecord (uint32_t n) const
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 @@ GlobalRouter::ClearLSAs ()
{
NS_DEBUG("GlobalRouter::ClearLSAs (): free LSA");
GlobalRouterLSA *p = *i;
GlobalRoutingLSA *p = *i;
delete p;
p = 0;
@ -373,11 +461,16 @@ GlobalRouter::GetRouterId (void) const
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 @@ GlobalRouter::DiscoverLSAs (void)
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 (): Point-to-point device");
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);
//
// 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);
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();
Ptr<NetDevice> ndRemote = GetAdjacent(ndLocal, ch);
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;
}
}
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);
//
// 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);
//
// 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);
//
// 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 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");
}
plr = new GlobalRouterLinkRecord;
plr->SetLinkType (GlobalRouterLinkRecord::StubNetwork);
plr->SetLinkId (addrRemote);
plr->SetLinkData (Ipv4Address(maskRemote.GetHostOrder())); // Frown
pLSA->AddLinkRecord(plr);
plr = 0;
}
//
// 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 @@ GlobalRouter::GetNumLSAs (void) const
// 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 @@ GlobalRouter::GetLSA (uint32_t n, GlobalRouterLSA &lsa) const
{
if (j == n)
{
GlobalRouterLSA *p = *i;
GlobalRoutingLSA *p = *i;
lsa = *p;
return true;
}

View File

@ -31,16 +31,16 @@ namespace ns3 {
/**
* @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 @@ public:
};
/**
* @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 @@ public:
* @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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
* 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 @@ public:
* 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 @@ private:
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 @@ private:
* 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 @@ public:
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 @@ public:
* @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 @@ public:
* @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 @@ public:
* 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 @@ public:
* 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,10 +410,47 @@ public:
* 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.
*
@ -410,12 +467,17 @@ public:
void SetStatus (SPFStatus status);
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 @@ private:
* 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,10 +503,30 @@ private:
* 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
@ -454,7 +536,7 @@ private:
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 @@ public:
/**
* @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 @@ public:
* 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 @@ public:
* 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 @@ public:
* 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 @@ private:
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;

View File

@ -539,13 +539,14 @@ class SimulatorTests : public Test {
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 @@ private:
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 ()
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 @@ void
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 @@ SimulatorTests::RunOneTest (void)
}
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 @@ SimulatorTests::RunTests (void)
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 ())

View File

@ -163,8 +163,8 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ public:
* @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 @@ private:
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 @@ struct EventMemberImplObjTraits<T *>
}
};
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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (void), OBJ obj)
(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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1), OBJ obj, T1 a1)
(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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2), OBJ obj, T1 a1,
(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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1
(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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3), OBJ obj, T1
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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj,
(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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4), OBJ obj,
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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (T::*mem_ptr) (U1,U2,U3,U4,U5), OBJ ob
(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 @@ Ptr<EventImpl> Simulator::MakeEvent (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T
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 @@ EventId Simulator::Schedule (Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1
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 @@ Simulator::ScheduleNow (void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4,
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));

View File

@ -17,7 +17,7 @@ all_modules = (
'node',
'internet-node',
'devices/point-to-point',
'devices/csma-cd',
'devices/csma',
'applications',
'routing/global-routing',
'mobility',

View File

@ -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 @@ int main (int argc, char *argv[])
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;

View File

@ -37,7 +37,7 @@ def set_options(opt):
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 '