merge with trunk
commit
04569d27b7
1
.hgtags
1
.hgtags
|
@ -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
|
||||
|
|
1
AUTHORS
1
AUTHORS
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
========================
|
||||
|
|
521
SConstruct
521
SConstruct
|
@ -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()
|
|
@ -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
|
||||
|
|
|
@ -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 ();
|
|
@ -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 ();
|
||||
|
|
@ -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 ();
|
||||
}
|
|
@ -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 ();
|
||||
}
|
|
@ -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");
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -230,6 +230,7 @@ PacketMetadataTest::PacketMetadataTest ()
|
|||
: Test ("PacketMetadata")
|
||||
{
|
||||
m_printer.SetPayloadPrinter (MakeCallback (&PacketMetadataTest::PrintPayload, this));
|
||||
m_printer.SetSeparator ("");
|
||||
}
|
||||
|
||||
PacketMetadataTest::~PacketMetadataTest ()
|
||||
|
|
|
@ -128,7 +128,7 @@ Packet::GetUid (void) const
|
|||
void
|
||||
Packet::PrintTags (std::ostream &os) const
|
||||
{
|
||||
m_tags.Print (os);
|
||||
m_tags.Print (os, " ");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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',
|
||||
]
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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,
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
||||
/**
|
|
@ -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',
|
||||
]
|
|
@ -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 ());
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ())
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -17,7 +17,7 @@ all_modules = (
|
|||
'node',
|
||||
'internet-node',
|
||||
'devices/point-to-point',
|
||||
'devices/csma-cd',
|
||||
'devices/csma',
|
||||
'applications',
|
||||
'routing/global-routing',
|
||||
'mobility',
|
||||
|
|
|
@ -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;
|
||||
|
|
2
wscript
2
wscript
|
@ -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 '
|
||||
|
|
Loading…
Reference in New Issue