Top Banner
NS examples for wireless scenario [ A Simple One | A Complex One | Link Error Example | Back to Network Simulator 2 for Wireless ] This is a simple test scenario for 4x4 grid and 4 flows. # =================================================== # Author: ZHIBIN WU 06/19/2003 # ================================================== set cbr_size 500 set cbr_interval 0.002 set num_row 4 set time_duration 100 set val(chan) Channel/WirelessChannel ;# channel type set val(prop) Propagation/TwoRayGround ;# radio-propagation model set val(netif) Phy/WirelessPhy ;# network interface type set val(mac) Mac/802_11 ;# MAC type set val(ifq) Queue/DropTail/PriQueue ;# interface queue type set val(ll) LL ;# link layer type set val(ant) Antenna/OmniAntenna ;# antenna model set val(ifqlen) 50 ;# max packet in ifq set val(rp) DSDV ;# routing protocol # # Initialize ns # set ns_ [new Simulator] set tracefd [open simple.tr w] $ns_ trace-all $tracefd # set up topography object set topo [new Topography] $topo load_flatgrid 1000 1000 create-god [expr $num_row * $num_row ] $ns_ node-config -adhocRouting $val(rp) -llType $val(ll) \ -macType $val(mac) -ifqType $val(ifq) \ -ifqLen $val(ifqlen) -antType $val(ant) \ -propType $val(prop) -phyType $val(netif) \ -channel [new $val(chan)] -topoInstance $topo \ -agentTrace ON -routerTrace OFF\ -macTrace ON \ -movementTrace OFF for {set i 0} {$i < [expr $num_row*$num_row]} {incr i} { set node_($i) [$ns_ node]
44
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: NS Examples for Wireless Scenario

NS examples for wireless scenario

[ A Simple One | A Complex One | Link Error Example | Back to Network Simulator

2 for Wireless ]

This is a simple test scenario for 4x4 grid and 4 flows.

# ===================================================

# Author: ZHIBIN WU 06/19/2003

# ==================================================

set cbr_size 500

set cbr_interval 0.002

set num_row 4

set time_duration 100

set val(chan) Channel/WirelessChannel ;# channel type

set val(prop) Propagation/TwoRayGround ;# radio-propagation model

set val(netif) Phy/WirelessPhy ;# network interface type

set val(mac) Mac/802_11 ;# MAC type

set val(ifq) Queue/DropTail/PriQueue ;# interface queue type

set val(ll) LL ;# link layer type

set val(ant) Antenna/OmniAntenna ;# antenna model

set val(ifqlen) 50 ;# max packet in ifq

set val(rp) DSDV ;# routing protocol

#

# Initialize ns

#

set ns_ [new Simulator]

set tracefd [open simple.tr w]

$ns_ trace-all $tracefd

# set up topography object

set topo [new Topography]

$topo load_flatgrid 1000 1000

create-god [expr $num_row * $num_row ]

$ns_ node-config -adhocRouting $val(rp) -llType $val(ll) \

-macType $val(mac) -ifqType $val(ifq) \

-ifqLen $val(ifqlen) -antType $val(ant) \

-propType $val(prop) -phyType $val(netif) \

-channel [new $val(chan)] -topoInstance $topo \

-agentTrace ON -routerTrace OFF\

-macTrace ON \

-movementTrace OFF

for {set i 0} {$i < [expr $num_row*$num_row]} {incr i} {

set node_($i) [$ns_ node]

Page 2: NS Examples for Wireless Scenario

}

set k 0;

while {$k < $num_row } {

for {set i 0} {$i < $num_row } {incr i} {

set m [expr $i+$k*$num_row];

$node_($m) set X_ [expr $i*240];

$node_($m) set Y_ [expr $k*240+20.0];

$node_($m) set Z_ 0.0

}

incr k;

};

for {set i 0} {$i < $num_row } {incr i} {

set udp_($i) [new Agent/UDP]

set null_($i) [new Agent/Null]

}

$ns_ attach-agent $node_(0) $udp_(0)

$ns_ attach-agent $node_(7) $udp_(1)

$ns_ attach-agent $node_(2) $udp_(2)

$ns_ attach-agent $node_(7) $udp_(3)

$ns_ attach-agent $node_(6) $null_(0)

$ns_ attach-agent $node_(1) $null_(1)

$ns_ attach-agent $node_(8) $null_(2)

$ns_ attach-agent $node_(15) $null_(3)

for {set i 0} {$i < $num_row } {incr i} {

$ns_ connect $udp_($i) $null_($i)

}

for {set i 0} {$i < $num_row } {incr i} {

set cbr_($i) [new Application/Traffic/CBR]

$cbr_($i) set packetSize_ $cbr_size

$cbr_($i) set interval_ 0.5

$cbr_($i) attach-agent $udp_($i)

}

$ns_ at 11.0234 "$cbr_(0) start"

$ns_ at 10.4578 "$cbr_(1) start"

$ns_ at 12.7184 "$cbr_(2) start"

$ns_ at 12.2456 "$cbr_(3) start"

# Tell nodes when the simulation ends

#

for {set i 0} {$i < [expr $num_row*$num_row] } {incr i} {

$ns_ at [expr $time_duration +10.0] "$node_($i) reset";

}

$ns_ at [expr $time_duration +10.0] "finish"

$ns_ at [expr $time_duration +10.01] "puts \"NS Exiting...\"; $ns_ halt"

proc finish {} {

global ns_ tracefd

$ns_ flush-trace

close $tracefd

}

puts "Starting Simulation..."

$ns_ run

Page 3: NS Examples for Wireless Scenario

However, a more professional way to write the test tcl is to following the way in ns

examples. For example, it is better to write traffic patten file and mobility file

seperately and then source them in the main test tcl. Those files are generated

respectively with cbrgen and setdest tools. Those files are ususally stored in "/ns-

2.??/tcl/mobility/scene" directory.

This is an example for DSDV routing with 50 nodes in a 670*670 m2 area

# ======================================================================

# Default Script Options

# ======================================================================

set opt(chan) Channel/WirelessChannel

set opt(prop) Propagation/TwoRayGround

#set opt(netif) NetIf/SharedMedia

set opt(netif) Phy/WirelessPhy

#set opt(mac) Mac/802_11

set opt(mac) Mac/802_11

set opt(ifq) Queue/DropTail/PriQueue

set opt(ll) LL

set opt(ant) Antenna/OmniAntenna

set opt(x) 670 ;# X dimension of the topography

set opt(y) 670 ;# Y dimension of the topography

set opt(cp) "../mobility/scene/cbr-50-10-4-512"

set opt(sc) "../mobility/scene/scen-670x670-50-600-20-0"

set opt(ifqlen) 50 ;# max packet in ifq

set opt(nn) 50 ;# number of nodes

set opt(seed) 0.0

set opt(stop) 1000.0 ;# simulation time

set opt(tr) out.tr ;# trace file

set opt(rp) dsdv ;# routing protocol script

set opt(lm) "off" ;# log movement

# ======================================================================

#set AgentTrace ON

#set RouterTrace ON

#set MacTrace OFF #useless code, the only way to toggle

Mac trace on is to use node-config

LL set mindelay_ 50us

LL set delay_ 25us

LL set bandwidth_ 0 ;# not used

LL set off_prune_ 0 ;# not used

LL set off_CtrMcast_ 0 ;# not used

Agent/Null set sport_ 0

Agent/Null set dport_ 0

Page 4: NS Examples for Wireless Scenario

Agent/CBR set sport_ 0

Agent/CBR set dport_ 0

Agent/TCPSink set sport_ 0

Agent/TCPSink set dport_ 0

Agent/TCP set sport_ 0

Agent/TCP set dport_ 0

Agent/TCP set packetSize_ 1460

Queue/DropTail/PriQueue set Prefer_Routing_Protocols 1

# unity gain, omni-directional antennas

# set up the antennas to be centered in the node and 1.5 meters above it

Antenna/OmniAntenna set X_ 0

Antenna/OmniAntenna set Y_ 0

Antenna/OmniAntenna set Z_ 1.5

Antenna/OmniAntenna set Gt_ 1.0

Antenna/OmniAntenna set Gr_ 1.0

# Initialize the SharedMedia interface with parameters to make

# it work like the 914MHz Lucent WaveLAN DSSS radio interface

Phy/WirelessPhy set CPThresh_ 10.0

Phy/WirelessPhy set CSThresh_ 1.559e-11

Phy/WirelessPhy set RXThresh_ 3.652e-10

Phy/WirelessPhy set Rb_ 2*1e6

Phy/WirelessPhy set Pt_ 0.2818

Phy/WirelessPhy set freq_ 914e+6

Phy/WirelessPhy set L_ 1.0

# ======================================================================

proc usage { argv0 } {

puts "Usage: $argv0"

puts "\tmandatory arguments:"

puts "\t\t\[-x MAXX\] \[-y MAXY\]"

puts "\toptional arguments:"

puts "\t\t\[-cp conn pattern\] \[-sc scenario\] \[-nn nodes\]"

puts "\t\t\[-seed seed\] \[-stop sec\] \[-tr tracefile\]\n"

}

proc getopt {argc argv} {

global opt

lappend optlist cp nn seed sc stop tr x y

for {set i 0} {$i < $argc} {incr i} {

set arg [lindex $argv $i]

if {[string range $arg 0 0] != "-"} continue

set name [string range $arg 1 end]

set opt($name) [lindex $argv [expr $i+1]]

}

}

Page 5: NS Examples for Wireless Scenario

proc cmu-trace { ttype atype node } {

global ns_ tracefd

if { $tracefd == "" } {

return ""

}

set T [new CMUTrace/$ttype $atype]

$T target [$ns_ set nullAgent_]

$T attach $tracefd

$T set src_ [$node id]

$T node $node

return $T

}

proc log-movement {} {

global logtimer ns_ ns

set ns $ns_

source ../mobility/timer.tcl

Class LogTimer -superclass Timer

LogTimer instproc timeout {} {

global opt node_;

for {set i 0} {$i < $opt(nn)} {incr i} {

$node_($i) log-movement

}

$self sched 0.1

}

set logtimer [new LogTimer]

$logtimer sched 0.1

}

# ======================================================================

# Main Program

# ======================================================================

getopt $argc $argv

#

# Source External TCL Scripts

#

#source ../lib/ns-mobilenode.tcl

#if { $opt(rp) != "" } {

#source ../mobility/$opt(rp).tcl

#} elseif { [catch { set env(NS_PROTO_SCRIPT) } ] == 1 } {

#puts "\nenvironment variable NS_PROTO_SCRIPT not set!\n"

#exit

#} else {

#puts "\n*** using script $env(NS_PROTO_SCRIPT)\n\n";

#source $env(NS_PROTO_SCRIPT)

Page 6: NS Examples for Wireless Scenario

#}

#source ../lib/ns-cmutrace.tcl

source ../lib/ns-bsnode.tcl

source ../mobility/com.tcl

# do the get opt again incase the routing protocol file added some more

# options to look for

getopt $argc $argv

if { $opt(x) == 0 || $opt(y) == 0 } {

usage $argv0

exit 1

}

if {$opt(seed) > 0} {

puts "Seeding Random number generator with $opt(seed)\n"

ns-random $opt(seed)

}

#

# Initialize Global Variables

#

set ns_ [new Simulator]

set chan [new $opt(chan)]

set prop [new $opt(prop)]

set topo [new Topography]

set tracefd [open $opt(tr) w]

$topo load_flatgrid $opt(x) $opt(y)

$prop topography $topo

#

# Create God

#

create-god $opt(nn)

#

# log the mobile nodes movements if desired

#

if { $opt(lm) == "on" } {

log-movement

}

$ns_ node-config -macTrace ON

#

# Create the specified number of nodes $opt(nn) and "attach" them

# the channel.

# Each routing protocol script is expected to have defined a proc

# create-mobile-node that builds a mobile node and inserts it into the

# array global $node_($i)

#

Page 7: NS Examples for Wireless Scenario

if { [string compare $opt(rp) "dsr"] == 0} {

for {set i 0} {$i < $opt(nn) } {incr i} {

dsr-create-mobile-node $i

}

} elseif { [string compare $opt(rp) "dsdv"] == 0} {

for {set i 0} {$i < $opt(nn) } {incr i} {

dsdv-create-mobile-node $i

}

}

#

# Source the Connection and Movement scripts

#

if { $opt(cp) == "" } {

puts "*** NOTE: no connection pattern specified."

set opt(cp) "none"

} else {

puts "Loading connection pattern..."

source $opt(cp)

}

#

# Tell all the nodes when the simulation ends

#

for {set i 0} {$i < $opt(nn) } {incr i} {

$ns_ at $opt(stop).000000001 "$node_($i) reset";

}

$ns_ at $opt(stop).00000001 "puts \"NS EXITING...\" ; $ns_ halt"

if { $opt(sc) == "" } {

puts "*** NOTE: no scenario file specified."

set opt(sc) "none"

} else {

puts "Loading scenario file..."

source $opt(sc)

puts "Load complete..."

}

puts $tracefd "M 0.0 nn $opt(nn) x $opt(x) y $opt(y) rp $opt(rp)"

puts $tracefd "M 0.0 sc $opt(sc) cp $opt(cp) seed $opt(seed)"

puts $tracefd "M 0.0 prop $opt(prop) ant $opt(ant)"

puts "Starting Simulation..."

$ns_ run

Page 8: NS Examples for Wireless Scenario

Note that all options listed in the beginning of the file could be initialized with

command line arguments by using "getopt $argc $argv"

Example 3 : To attach the error model, add following codes:

..........

proc UniformErr {} {

set err [new ErrorModel]

$err unit packet

$err set rate_ 0.05

return $err

}

# $err rate_ 0.5 "invalid command ErrModel::Command does not

support"

# the other valid method is " set err [new ErrorModel/Uniform 0.05

pkt] "

# the parameter rate ( 0 or 0.9) is a threshold that all packets all

going through and 90% packets are

# going to be drop

proc TwoStateMarkovErr {} {

set tmp0 [new ErrorModel/Uniform 0 pkt]

set tmp1 [new ErrorModel/Uniform .7 pkt]

# Array of states (error models)

set m_states [list $tmp0 $tmp1]

# Durations for each of the states, tmp, tmp1 and tmp2,

respectively

set m_periods [list 0.1 .075 ]

# Transition state model matrix

set m_transmx { {0.9 0.1 }

{0.7 0.3 } }

set m_trunit byte

# Use time-based transition

set m_sttype time

set m_nstates 2

set m_nstart [lindex $m_states 0]

set em [new ErrorModel/MultiState $m_states $m_periods $m_transmx \

$m_trunit $m_sttype $m_nstates $m_nstart]

return $em

}

$ns_ node-config -adhocRouting $val(rp) \

-llType $val(ll) \

-macType $val(mac) \

-ifqType $val(ifq) \

-ifqLen $val(ifqlen) \

-antType $val(ant) \

-propType $val(prop) \

-phyType $val(netif) \

Page 9: NS Examples for Wireless Scenario

-channel $chan1 \

-topoInstance $topo \

-agentTrace ON \

-routerTrace OFF\

-macTrace ON \

-movementTrace OFF \

-IncomingErrProc TwoStateMarkovErr

#\

#-OutcomingErrProc TwoStateMarkovErr

#The other way to configure error

# $ns_ node-config --IncomingErrProc $opt(err)

NS examples for wireless scenario

[ A Simple One | A Complex One | Link Error Example | Back to Network Simulator

2 for Wireless ]

This is a simple test scenario for 4x4 grid and 4 flows.

# ===================================================

# Author: ZHIBIN WU 06/19/2003

# ==================================================

set cbr_size 500

set cbr_interval 0.002

set num_row 4

set time_duration 100

set val(chan) Channel/WirelessChannel ;# channel type

set val(prop) Propagation/TwoRayGround ;# radio-propagation model

set val(netif) Phy/WirelessPhy ;# network interface type

set val(mac) Mac/802_11 ;# MAC type

set val(ifq) Queue/DropTail/PriQueue ;# interface queue type

set val(ll) LL ;# link layer type

set val(ant) Antenna/OmniAntenna ;# antenna model

set val(ifqlen) 50 ;# max packet in ifq

set val(rp) DSDV ;# routing protocol

#

# Initialize ns

#

set ns_ [new Simulator]

set tracefd [open simple.tr w]

$ns_ trace-all $tracefd

Page 10: NS Examples for Wireless Scenario

# set up topography object

set topo [new Topography]

$topo load_flatgrid 1000 1000

create-god [expr $num_row * $num_row ]

$ns_ node-config -adhocRouting $val(rp) -llType $val(ll) \

-macType $val(mac) -ifqType $val(ifq) \

-ifqLen $val(ifqlen) -antType $val(ant) \

-propType $val(prop) -phyType $val(netif) \

-channel [new $val(chan)] -topoInstance $topo \

-agentTrace ON -routerTrace OFF\

-macTrace ON \

-movementTrace OFF

for {set i 0} {$i < [expr $num_row*$num_row]} {incr i} {

set node_($i) [$ns_ node]

}

set k 0;

while {$k < $num_row } {

for {set i 0} {$i < $num_row } {incr i} {

set m [expr $i+$k*$num_row];

$node_($m) set X_ [expr $i*240];

$node_($m) set Y_ [expr $k*240+20.0];

$node_($m) set Z_ 0.0

}

incr k;

};

for {set i 0} {$i < $num_row } {incr i} {

set udp_($i) [new Agent/UDP]

set null_($i) [new Agent/Null]

}

$ns_ attach-agent $node_(0) $udp_(0)

$ns_ attach-agent $node_(7) $udp_(1)

$ns_ attach-agent $node_(2) $udp_(2)

$ns_ attach-agent $node_(7) $udp_(3)

$ns_ attach-agent $node_(6) $null_(0)

$ns_ attach-agent $node_(1) $null_(1)

$ns_ attach-agent $node_(8) $null_(2)

$ns_ attach-agent $node_(15) $null_(3)

for {set i 0} {$i < $num_row } {incr i} {

$ns_ connect $udp_($i) $null_($i)

}

for {set i 0} {$i < $num_row } {incr i} {

set cbr_($i) [new Application/Traffic/CBR]

$cbr_($i) set packetSize_ $cbr_size

$cbr_($i) set interval_ 0.5

$cbr_($i) attach-agent $udp_($i)

}

$ns_ at 11.0234 "$cbr_(0) start"

$ns_ at 10.4578 "$cbr_(1) start"

$ns_ at 12.7184 "$cbr_(2) start"

$ns_ at 12.2456 "$cbr_(3) start"

# Tell nodes when the simulation ends

#

Page 11: NS Examples for Wireless Scenario

for {set i 0} {$i < [expr $num_row*$num_row] } {incr i} {

$ns_ at [expr $time_duration +10.0] "$node_($i) reset";

}

$ns_ at [expr $time_duration +10.0] "finish"

$ns_ at [expr $time_duration +10.01] "puts \"NS Exiting...\"; $ns_ halt"

proc finish {} {

global ns_ tracefd

$ns_ flush-trace

close $tracefd

}

puts "Starting Simulation..."

$ns_ run

However, a more professional way to write the test tcl is to following the way in ns

examples. For example, it is better to write traffic patten file and mobility file

seperately and then source them in the main test tcl. Those files are generated

respectively with cbrgen and setdest tools. Those files are ususally stored in "/ns-

2.??/tcl/mobility/scene" directory.

This is an example for DSDV routing with 50 nodes in a 670*670 m2 area

# ======================================================================

# Default Script Options

# ======================================================================

set opt(chan) Channel/WirelessChannel

set opt(prop) Propagation/TwoRayGround

#set opt(netif) NetIf/SharedMedia

set opt(netif) Phy/WirelessPhy

#set opt(mac) Mac/802_11

set opt(mac) Mac/802_11

set opt(ifq) Queue/DropTail/PriQueue

set opt(ll) LL

set opt(ant) Antenna/OmniAntenna

set opt(x) 670 ;# X dimension of the topography

set opt(y) 670 ;# Y dimension of the topography

set opt(cp) "../mobility/scene/cbr-50-10-4-512"

set opt(sc) "../mobility/scene/scen-670x670-50-600-20-0"

set opt(ifqlen) 50 ;# max packet in ifq

set opt(nn) 50 ;# number of nodes

set opt(seed) 0.0

set opt(stop) 1000.0 ;# simulation time

set opt(tr) out.tr ;# trace file

set opt(rp) dsdv ;# routing protocol script

set opt(lm) "off" ;# log movement

Page 12: NS Examples for Wireless Scenario

# ======================================================================

#set AgentTrace ON

#set RouterTrace ON

#set MacTrace OFF #useless code, the only way to toggle

Mac trace on is to use node-config

LL set mindelay_ 50us

LL set delay_ 25us

LL set bandwidth_ 0 ;# not used

LL set off_prune_ 0 ;# not used

LL set off_CtrMcast_ 0 ;# not used

Agent/Null set sport_ 0

Agent/Null set dport_ 0

Agent/CBR set sport_ 0

Agent/CBR set dport_ 0

Agent/TCPSink set sport_ 0

Agent/TCPSink set dport_ 0

Agent/TCP set sport_ 0

Agent/TCP set dport_ 0

Agent/TCP set packetSize_ 1460

Queue/DropTail/PriQueue set Prefer_Routing_Protocols 1

# unity gain, omni-directional antennas

# set up the antennas to be centered in the node and 1.5 meters above it

Antenna/OmniAntenna set X_ 0

Antenna/OmniAntenna set Y_ 0

Antenna/OmniAntenna set Z_ 1.5

Antenna/OmniAntenna set Gt_ 1.0

Antenna/OmniAntenna set Gr_ 1.0

# Initialize the SharedMedia interface with parameters to make

# it work like the 914MHz Lucent WaveLAN DSSS radio interface

Phy/WirelessPhy set CPThresh_ 10.0

Phy/WirelessPhy set CSThresh_ 1.559e-11

Phy/WirelessPhy set RXThresh_ 3.652e-10

Phy/WirelessPhy set Rb_ 2*1e6

Phy/WirelessPhy set Pt_ 0.2818

Phy/WirelessPhy set freq_ 914e+6

Phy/WirelessPhy set L_ 1.0

# ======================================================================

proc usage { argv0 } {

puts "Usage: $argv0"

puts "\tmandatory arguments:"

puts "\t\t\[-x MAXX\] \[-y MAXY\]"

puts "\toptional arguments:"

puts "\t\t\[-cp conn pattern\] \[-sc scenario\] \[-nn nodes\]"

puts "\t\t\[-seed seed\] \[-stop sec\] \[-tr tracefile\]\n"

Page 13: NS Examples for Wireless Scenario

}

proc getopt {argc argv} {

global opt

lappend optlist cp nn seed sc stop tr x y

for {set i 0} {$i < $argc} {incr i} {

set arg [lindex $argv $i]

if {[string range $arg 0 0] != "-"} continue

set name [string range $arg 1 end]

set opt($name) [lindex $argv [expr $i+1]]

}

}

proc cmu-trace { ttype atype node } {

global ns_ tracefd

if { $tracefd == "" } {

return ""

}

set T [new CMUTrace/$ttype $atype]

$T target [$ns_ set nullAgent_]

$T attach $tracefd

$T set src_ [$node id]

$T node $node

return $T

}

proc log-movement {} {

global logtimer ns_ ns

set ns $ns_

source ../mobility/timer.tcl

Class LogTimer -superclass Timer

LogTimer instproc timeout {} {

global opt node_;

for {set i 0} {$i < $opt(nn)} {incr i} {

$node_($i) log-movement

}

$self sched 0.1

}

set logtimer [new LogTimer]

$logtimer sched 0.1

}

# ======================================================================

# Main Program

Page 14: NS Examples for Wireless Scenario

# ======================================================================

getopt $argc $argv

#

# Source External TCL Scripts

#

#source ../lib/ns-mobilenode.tcl

#if { $opt(rp) != "" } {

#source ../mobility/$opt(rp).tcl

#} elseif { [catch { set env(NS_PROTO_SCRIPT) } ] == 1 } {

#puts "\nenvironment variable NS_PROTO_SCRIPT not set!\n"

#exit

#} else {

#puts "\n*** using script $env(NS_PROTO_SCRIPT)\n\n";

#source $env(NS_PROTO_SCRIPT)

#}

#source ../lib/ns-cmutrace.tcl

source ../lib/ns-bsnode.tcl

source ../mobility/com.tcl

# do the get opt again incase the routing protocol file added some more

# options to look for

getopt $argc $argv

if { $opt(x) == 0 || $opt(y) == 0 } {

usage $argv0

exit 1

}

if {$opt(seed) > 0} {

puts "Seeding Random number generator with $opt(seed)\n"

ns-random $opt(seed)

}

#

# Initialize Global Variables

#

set ns_ [new Simulator]

set chan [new $opt(chan)]

set prop [new $opt(prop)]

set topo [new Topography]

set tracefd [open $opt(tr) w]

$topo load_flatgrid $opt(x) $opt(y)

$prop topography $topo

#

# Create God

#

create-god $opt(nn)

#

# log the mobile nodes movements if desired

Page 15: NS Examples for Wireless Scenario

#

if { $opt(lm) == "on" } {

log-movement

}

$ns_ node-config -macTrace ON

#

# Create the specified number of nodes $opt(nn) and "attach" them

# the channel.

# Each routing protocol script is expected to have defined a proc

# create-mobile-node that builds a mobile node and inserts it into the

# array global $node_($i)

#

if { [string compare $opt(rp) "dsr"] == 0} {

for {set i 0} {$i < $opt(nn) } {incr i} {

dsr-create-mobile-node $i

}

} elseif { [string compare $opt(rp) "dsdv"] == 0} {

for {set i 0} {$i < $opt(nn) } {incr i} {

dsdv-create-mobile-node $i

}

}

#

# Source the Connection and Movement scripts

#

if { $opt(cp) == "" } {

puts "*** NOTE: no connection pattern specified."

set opt(cp) "none"

} else {

puts "Loading connection pattern..."

source $opt(cp)

}

#

# Tell all the nodes when the simulation ends

#

for {set i 0} {$i < $opt(nn) } {incr i} {

$ns_ at $opt(stop).000000001 "$node_($i) reset";

}

$ns_ at $opt(stop).00000001 "puts \"NS EXITING...\" ; $ns_ halt"

if { $opt(sc) == "" } {

puts "*** NOTE: no scenario file specified."

set opt(sc) "none"

} else {

puts "Loading scenario file..."

source $opt(sc)

puts "Load complete..."

Page 16: NS Examples for Wireless Scenario

}

puts $tracefd "M 0.0 nn $opt(nn) x $opt(x) y $opt(y) rp $opt(rp)"

puts $tracefd "M 0.0 sc $opt(sc) cp $opt(cp) seed $opt(seed)"

puts $tracefd "M 0.0 prop $opt(prop) ant $opt(ant)"

puts "Starting Simulation..."

$ns_ run

Note that all options listed in the beginning of the file could be initialized with

command line arguments by using "getopt $argc $argv"

Example 3 : To attach the error model, add following codes:

..........

proc UniformErr {} {

set err [new ErrorModel]

$err unit packet

$err set rate_ 0.05

return $err

}

# $err rate_ 0.5 "invalid command ErrModel::Command does not

support"

# the other valid method is " set err [new ErrorModel/Uniform 0.05

pkt] "

# the parameter rate ( 0 or 0.9) is a threshold that all packets all

going through and 90% packets are

# going to be drop

proc TwoStateMarkovErr {} {

set tmp0 [new ErrorModel/Uniform 0 pkt]

set tmp1 [new ErrorModel/Uniform .7 pkt]

# Array of states (error models)

set m_states [list $tmp0 $tmp1]

# Durations for each of the states, tmp, tmp1 and tmp2,

respectively

set m_periods [list 0.1 .075 ]

# Transition state model matrix

set m_transmx { {0.9 0.1 }

{0.7 0.3 } }

set m_trunit byte

# Use time-based transition

set m_sttype time

Page 17: NS Examples for Wireless Scenario

set m_nstates 2

set m_nstart [lindex $m_states 0]

set em [new ErrorModel/MultiState $m_states $m_periods $m_transmx \

$m_trunit $m_sttype $m_nstates $m_nstart]

return $em

}

$ns_ node-config -adhocRouting $val(rp) \

-llType $val(ll) \

-macType $val(mac) \

-ifqType $val(ifq) \

-ifqLen $val(ifqlen) \

-antType $val(ant) \

-propType $val(prop) \

-phyType $val(netif) \

-channel $chan1 \

-topoInstance $topo \

-agentTrace ON \

-routerTrace OFF\

-macTrace ON \

-movementTrace OFF \

-IncomingErrProc TwoStateMarkovErr

#\

#-OutcomingErrProc TwoStateMarkovErr

#The other way to configure error

# $ns_ node-config --IncomingErrProc $opt(err)

A simple example for wireless simulation scenario

#This script creates a 4x4 grid topology and run 4 CBR traffic flows over

four pair of#nodes in this grid.

# ===================================================

# Author: ZHIBIN WU 06/19/2003

# ==================================================

set cbr_size 500

set cbr_interval 0.002

set num_row 4

set time_duration 100

Page 18: NS Examples for Wireless Scenario

set val(chan) Channel/WirelessChannel ;# channel type

set val(prop) Propagation/TwoRayGround ;# radio-propagation model

set val(netif) Phy/WirelessPhy ;# network interface type

set val(mac) Mac/802_11 ;# MAC type

set val(ifq) Queue/DropTail/PriQueue ;# interface queue type

set val(ll) LL ;# link layer type

set val(ant) Antenna/OmniAntenna ;# antenna model

set val(ifqlen) 50 ;# max packet in ifq

set val(rp) DSDV ;# routing protocol

#

# Initialize ns

#

set ns_ [new Simulator]

set tracefd [open simple.tr w]

$ns_ trace-all $tracefd

# set up topography object

set topo [new Topography]

$topo load_flatgrid 1000 1000

create-god [expr $num_row * $num_row ]

$ns_ node-config -adhocRouting $val(rp) -llType $val(ll) \

-macType $val(mac) -ifqType $val(ifq) \

-ifqLen $val(ifqlen) -antType $val(ant) \

-propType $val(prop) -phyType $val(netif) \

-channel [new $val(chan)] -topoInstance $topo \

-agentTrace ON -routerTrace OFF\

-macTrace ON \

-movementTrace OFF

for {set i 0} {$i < [expr $num_row*$num_row]} {incr i} {

Page 19: NS Examples for Wireless Scenario

set node_($i) [$ns_ node]

}

set k 0;

while {$k < $num_row } {

for {set i 0} {$i < $num_row } {incr i} {

set m [expr $i+$k*$num_row];

$node_($m) set X_ [expr $i*240];

$node_($m) set Y_ [expr $k*240+20.0];

$node_($m) set Z_ 0.0

}

incr k;

};

for {set i 0} {$i < $num_row } {incr i} {

set udp_($i) [new Agent/UDP]

set null_($i) [new Agent/Null]

}

$ns_ attach-agent $node_(0) $udp_(0)

$ns_ attach-agent $node_(7) $udp_(1)

$ns_ attach-agent $node_(2) $udp_(2)

$ns_ attach-agent $node_(7) $udp_(3)

$ns_ attach-agent $node_(6) $null_(0)

$ns_ attach-agent $node_(1) $null_(1)

$ns_ attach-agent $node_(8) $null_(2)

$ns_ attach-agent $node_(15) $null_(3)

for {set i 0} {$i < $num_row } {incr i} {

$ns_ connect $udp_($i) $null_($i)

}

for {set i 0} {$i < $num_row } {incr i} {

set cbr_($i) [new Application/Traffic/CBR]

$cbr_($i) set packetSize_ $cbr_size

$cbr_($i) set interval_ 0.5

$cbr_($i) attach-agent $udp_($i)

}

Page 20: NS Examples for Wireless Scenario

$ns_ at 11.0234 "$cbr_(0) start"

$ns_ at 10.4578 "$cbr_(1) start"

$ns_ at 12.7184 "$cbr_(2) start"

$ns_ at 12.2456 "$cbr_(3) start"

# Tell nodes when the simulation ends

#

for {set i 0} {$i < [expr $num_row*$num_row] } {incr i} {

$ns_ at [expr $time_duration +10.0] "$node_($i) reset";

}

$ns_ at [expr $time_duration +10.0] "finish"

$ns_ at [expr $time_duration +10.01] "puts \"NS Exiting...\"; $ns_ halt"

proc finish {} {

global ns_ tracefd

$ns_ flush-trace

close $tracefd

}

puts "Starting Simulation..."

$ns_ run

Ns-2 CMU Trace Analysis

[ Introduction | Trace example | Measure throughput & delay | Back to Network

Simulator 2 for Wireless ]

Ns-2 has two options to generate traces with different fomats. Basically, you could

use

$ns use-newtrace

to generate the new trace and the detailed explanation could be found in Ns Manual.

A very good reference about the trace is the ns-2 wiki page.

See: http://nsnam.isi.edu/nsnam/index.php/NS-2_Trace_Formats

By default, old trace format is used. The source code ./trace/cmu-trace.cc needs to

Page 21: NS Examples for Wireless Scenario

be read to understand it completely. For instance, the function format_ip will explain

the trace of IP part.

void

CMUTrace::format_ip(Packet *p, int offset)

{

struct hdr_cmn *ch = HDR_CMN(p);

struct hdr_ip *ih = HDR_IP(p);

// hack the IP address to convert pkt format to hostid format

// for now until port ids are removed from IP address. -Padma.

int src = Address::instance().get_nodeaddr(ih->saddr());

int dst = Address::instance().get_nodeaddr(ih->daddr());

............

}

void

CMUTrace::format_mac(Packet *p, int offset)

{

else {

sprintf(pt_->buffer() + offset,

" [%x %x %x %x] ",

//*((u_int16_t*) &mh->dh_fc),

mh->dh_duration,

ETHER_ADDR(mh->dh_ra),

ETHER_ADDR(mh->dh_ta),

GET_ETHER_TYPE(mh->dh_body));

}

......

}

A typical trace for a CBR traffic is:

s 20.000000000 _0_ AGT --- 6 cbr 512 [0 0 0 0] ------- [0:0 1:0 32 0] [0] 0

0

r 20.000000000 _0_ RTR --- 6 cbr 512 [0 0 0 0] ------- [0:0 1:0 32 0] [0] 0

0

s 20.000000000 _0_ RTR --- 6 cbr 532 [0 0 0 0] ------- [0:0 1:0 32 1] [0] 0

0

s 20.000275000 _0_ MAC --- 6 cbr 584 [13a 1 0 800] ------- [0:0 1:0 32 1]

[0] 0 0

r 20.004947063 _1_ MAC --- 6 cbr 532 [13a 1 0 800] ------- [0:0 1:0 32 1]

Page 22: NS Examples for Wireless Scenario

[0] 1 0

s 20.004957063 _1_ MAC --- 0 ACK 38 [0 0 0 0]

r 20.004972063 _1_ AGT --- 6 cbr 532 [13a 1 0 800] ------- [0:0 1:0 32 1]

[0] 1 0

r 20.005261125 _0_ MAC --- 0 ACK 38 [0 0 0 0]

An AWK script example to analyze the trace and calculate throughput

For a topology involve 4 flows with distinguishing source and destination nodes, this

following awk script gets throughout data and put in wu.dat file

BEGIN {counter1 = 0; counter2 = 0; counter3 = 0; counter4 = 0;}

$1~/r/ && $2>50 && $2< 100 && /_12_/ && /AGT/ { counter1 += ($8- 20)

size = $8 - 20 }

$1~/r/ && $2>50 && $2 <100 && /_13_/ && /AGT/ { counter2 += ($8- 20)

size = $8 - 20 }

$1~/r/ && $2>50 && $2<100 && /_14_/ && /AGT/ { counter3 += ($8- 20)

size = $8 - 20 }

$1~/r/ && $2>50 && $2<100 && /_15_/ && /AGT/ { counter4 += ($8- 20)

size = $8 - 20 } throughout

END {

print (size , counter1*8/(50), counter2*8/50, counter3*8/(50), counter4*8/50,

(counter1+counter2+counter3+counter4)*8/50 ) >> "wu.dat"}

To analyze the throughout or delay in a finite time duration, we need extract sending

and receiving time from the trace file

$2>100 && $2 < 150 && (/_6_/ || /_2_/) && /AGT/ { print $1, $2, $6 > "dst2.tr" }

$2>100 && $2 <150 && (/_0_/ || /_9_/) && /AGT/ { print $1, $2, $6 > "dst9.tr" }

$2>100 && $2 <150 && (/_12_/ || /_3_/) && /AGT/ { print $1, $2, $6 > "dst3.tr" }

$2>100 && $2 <150 && (/_10_/ || /_4_/) && /AGT/ { print $1, $2, $6 > "dst4.tr" }

$2>100 && $2 <150 && (/_11_/ || /_8_/) && /AGT/ { print $1, $2, $6 > "dst8.tr" }

The respective new trace files such as "dst2.tr" will keep the sending or receiving

time, "s'" or "r" label and, node's MAC address. From those data, we could use a

program to calculate the average throughput or mean value of end-to-end delay of

the flow.

Page 23: NS Examples for Wireless Scenario

The C source file to calcualte delay can be downloaded here:

To use this C code:

$ gcc delay.c -o delaycal

$ ./delaycal dst2.tr wu0.dat wu1.dat

Headers & Addresses in ns-2

[ Common | 802.11 MAC | IP | DSR | Back to Network Simulator 2 for Wireless ]

Notice that by default, all packet headers are included.

A diagram:

Common-header:

Access method:

struct hdr_cmn {

enum dir_t { DOWN= -1, NONE= 0, UP= 1 };

packet_t ptype_; // packet type (see above)

Page 24: NS Examples for Wireless Scenario

int size_; // simulated packet size

int uid_; // unique id

int error_; // error flag

int errbitcnt_; // # of corrupted bits jahn

int fecsize_;

double ts_; // timestamp: for q-delay measurement

int iface_; // receiving interface (label)

dir_t direction_; // direction: 0=none, 1=up, -1=down

// source routing

char src_rt_valid;

//Monarch extn begins

nsaddr_t prev_hop_; // IP addr of forwarding hop

nsaddr_t next_hop_; // next hop for this packet

int addr_type_; // type of next_hop_ addr

nsaddr_t last_hop_; // for tracing on multi-user channels

// called if pkt can't obtain media or isn't ack'd. not called if

// droped by a queue

FailureCallback xmit_failure_;

void *xmit_failure_data_;

/*

* MONARCH wants to know if the MAC layer is passing this back

because

* it could not get the RTS through or because it did not receive

* an ACK.

*/

int xmit_reason_;

#define XMIT_REASON_RTS 0x01

#define XMIT_REASON_ACK 0x02

// filled in by GOD on first transmission, used for trace analysis

int num_forwards_; // how many times this pkt was forwarded

int opt_num_forwards_; // optimal #forwards

// Monarch extn ends;

// tx time for this packet in sec

double txtime_;

inline double& txtime() { return(txtime_); }

static int offset_; // offset for this header

inline static int& offset() { return offset_; }

inline static hdr_cmn* access(const Packet* p) {

return (hdr_cmn*) p->access(offset_);

}

.....

}

hdr_cmn *ch= hdr_cmn::access(pkt); //common header

What's in common header (refer to ./common/packet.h)

Page 25: NS Examples for Wireless Scenario

ch->ptype() : protocl type. e.g. PT_DSR shows this is a signaling message

for DSR protocol, not a normal DATA packet

ch->size();

ch->direction() : Up or Down

ch->uid()

ch->iface(): Interface

ch->next_hop(): next hop for this packet. IP address in format nsaddr_t*. So,

it is amazing to see some codes like, ch->next_hop=MAC_BRPADCST .

MAC_BROADCST is defined as #define MAC_BROADCAST ((u_int32_t)

0xffffffff) and nsaddr_t is also deined as int32_t in config.h (typedef int32_t

nsaddr_t; ). Basically, ns2 use 32bit addressing support.

MAC Ethernet Address in 802.11 MAC Header:

Access method: struct hdr_mac802_11 {

struct frame_control dh_fc;

// 2 byte

u_int16_t dh_duration;

// 2

u_char dh_da[ETHER_ADDR_LEN];

// 6

u_char dh_sa[ETHER_ADDR_LEN];

// 6

u_char dh_bssid[ETHER_ADDR_LEN];

// 6

u_int16_t dh_scontrol;

// 2

u_char dh_body[0]; // XXX Non-ANSI

// 1 //not allocate, the address of ....

};

.....

u_int32_t src,dst;

struct hdr_mac802_11 *dh = HDR_MAC802_11(p);

//method to get a 32bit general descriptor of address

dst = ETHER_ADDR(dh->dh_ra);

src = ETHER_ADDR(dh->dh_ta);

//method to set ....

int src, dst;

STORE4BYTE(&dst, (dh->dh_ra));

STORE4BYTE(&src, (dh->dh_ta));

Ethernet Address is specified in mac.h as (#define ETHER_ADDR_LEN 6 ). Thus,

dh_ra and dh_ta are both six-unsinged-character array. Also, there is another defintion

Page 26: NS Examples for Wireless Scenario

for this operation: #define ETHER_ADDR(x) (GET4BYTE(x)), so only the last 4

bytes are reassembled for a 32-bit address.

How MAC address is set? The addr() function is defined in the Class MAC, and the

index_ is corresponding internal member ( type is integer).

static int MacIndex = 0;

Mac::Mac() :

BiConnector(), abstract_(0), netif_(0), tap_(0), ll_(0), channel_(0),

callback_(0),

hRes_(this), hSend_(this), state_(MAC_IDLE), pktRx_(0), pktTx_(0)

{

index_ = MacIndex++;

bind_bw("bandwidth_", &bandwidth_);

bind_time("delay_", &delay_);

bind_bool("abstract_", &abstract_);

}

class Mac : public BiConnector {

public:

....

inline int addr() { return index_; }

protected:

....

int index_; // MAC address

....

}

//alos, the mac-802.11 use index as its mac address to form MAC frames: (see

in mac-802_11.cc)

....

STORE4BYTE(&index_, (rf->rf_ta));

Space Sharing in MAC-802.11 header

As in packet.h

#define HDR_MAC802_11(p) ((hdr_mac802_11 *)hdr_mac::access(p))

There is no define of access function of struct hdr_mac802_11. The problem is that,

we acccess the header use the struct mac_hdr, and then convert it to a 802.11 header.

Thus, the frame space and frame format should have some realtion:

See.

size of mac header is 36 bytes, but size of mac-802.11 header in ns-2 is only 24 bytes.

Page 27: NS Examples for Wireless Scenario

IP Addr in IP header

Access Method: (refer to ./common/ip.h )

struct hdr_ip {

/* common to IPv{4,6} */

ns_addr_t src_;

ns_addr_t dst_;

int ttl_;

/* Monarch extn */

// u_int16_t sport_;

// u_int16_t dport_;

/* IPv6 */

int fid_; /* flow id */

int prio_;

static int offset_;

inline static int& offset() { return offset_; }

inline static hdr_ip* access(const Packet* p) {

return (hdr_ip*) p->access(offset_);

}

/* per-field member acces functions */

ns_addr_t& src() { return (src_); }

nsaddr_t& saddr() { return (src_.addr_); }

int32_t& sport() { return src_.port_;}

ns_addr_t& dst() { return (dst_); }

nsaddr_t& daddr() { return (dst_.addr_); }

int32_t& dport() { return dst_.port_;}

int& ttl() { return (ttl_); }

/* ipv6 fields */

int& flowid() { return (fid_); }

int& prio() { return (prio_); }

};

......

struct ns_addr_t {

int32_t addr_;

int32_t port_;

#ifdef __cplusplus p.dest = ID((Address::instance().get_nodeaddr(iph-

>daddr())),::IP);

p.src = ID((

ns_addr_t& operator= (const ns_addr_t& n) {

addr_ = n.addr_;

port_ = n.port_;

return (*this);

}

int operator== (const ns_addr_t& n) {

return ((addr_ == n.addr_) && (port_ == n.port_));

} p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);

p.src = ID((

Page 28: NS Examples for Wireless Scenario

#endif // __cplusplus

};

hdr_ip *iph = hdr_ip::access(packet);

//method to set address

iph->saddr() = Address::instance().create_ipaddr(p.src.addr, RT_PORT);

p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);

p.src = ID((

iph->sport() = RT_PORT;

iph->daddr() = Address::instance().create_ipaddr(p.dest.addr, RT_PORT);

iph->dport() = RT_PORT;

iph->ttl() = 255;

// method to read address ??

iph->saddr()

iph->daddr()

p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);

p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);

As seen, ns_addr_t is different from nsaddr_t, it has ip address and port infomation.

Just 32 bit is suitable for ip address.

Very Important! All things above IP ( Routing, TCP are) are implemented as Agent.

Any agent's message must include an IP header.

The class Agent has functions like addr() and daddr() to get the address of IP header. class Agent : public Connector {

public:

....

inline nsaddr_t& addr() { return here_.addr_; }

inline nsaddr_t& port() { return here_.port_; }

inline nsaddr_t& daddr() { return dst_.addr_; }

inline nsaddr_t& dport() { return dst_.port_; }

protected:

...

ns_addr_t here_; // address of this agent

ns_addr_t dst_; // destination address for pkt flow

...

}

int

Agent::delay_bind_dispatch(const char *varName, const char *localName,

TclObject *tracer)

{

if (delay_bind(varName, localName, "agent_addr_",

(int*)&(here_.addr_), tracer)) return TCL_OK;

if (delay_bind(varName, localName, "agent_port_",

(int*)&(here_.port_), tracer)) return TCL_OK;

if (delay_bind(varName, localName, "dst_addr_", (int*)&(dst_.addr_),

tracer)) return TCL_OK;

if (delay_bind(varName, localName, "dst_port_", (int*)&(dst_.port_),

tracer)) return TCL_OK;

Page 29: NS Examples for Wireless Scenario

......

Class Hierarchy : TclObject ---> NSObject ----> Agent

DSR's SR (Source Route) Header

the SR has a path informaton from source to a destination, an SR should have

following basic information for a baseline version of DSR protocol:

a path of IP or other addressses

a type to show this is route-request, route-reply or route-error

an ID to distinguish duplicate requests.

struct sr_addr {

int addr_type; /* same as hdr_cmn in packet.h */

nsaddr_t addr;

/*

* Metrics that I want to collect at each node

*/

double Pt_;

};

struct route_request {

int req_valid_; /* request header is valid? */

int req_id_; /* unique request identifier */

int req_ttl_; /* max propagation */

};

struct route_reply {

int rep_valid_; /* reply header is valid? */

int rep_rtlen_; /* # hops in route reply */

struct sr_addr rep_addrs_[MAX_SR_LEN];

};

struct route_error {

int err_valid_; /* error header is valid? */

int err_count_; /* number of route errors */

struct link_down err_links_[MAX_ROUTE_ERRORS];

};

......

class hdr_sr {

private:

int valid_; /* is this header actually in the packet?

and initialized? */

int salvaged_; /* packet has been salvaged? */

int num_addrs_;

Page 30: NS Examples for Wireless Scenario

int cur_addr_;

struct sr_addr addrs_[MAX_SR_LEN];

struct route_request sr_request_;

struct route_reply sr_reply_;

struct route_error sr_error_;

...

inline struct sr_addr* addrs() { return addrs_; }

...

}

//Constructor of Path, convert a SR header into a PATH object

Path::Path(struct hdr_sr *srh)

{ /* make a path from the bits of an NS source route header */

path = new ID[MAX_SR_LEN];

if (! srh->valid()) {

len = 0;

cur_index = 0;

return;

}

len = srh->num_addrs();

cur_index = srh->cur_addr();

assert(len <= MAX_SR_LEN);

for (int i = 0 ; i < len ; i++)

path[i] = ID(srh->addrs()[i]); //note : both type and addr

are copied

}

hdr_sr *srh = hdr_sr::access(packet);

SRPacket p(packet, srh);

p.dest = ID((Address::instance().get_nodeaddr(iph->daddr())),::IP);

p.src = ID((Address::instance().get_nodeaddr(iph->saddr())),::IP);

To get and set SR header, first we need to turn things into a packet of type SRPacket,

in this class, route[n] is use to access ID[n], for each ID[n], use inline nsaddr_t

getNSAddr_t() to get this addr;

Normally, all SR-related operation are use "ID" not direct 32bit integer to refer.

How the address get set at the very beginning of the DSR Agent, use those : SRNodeNew instproc init args {

......

$dsr_agent_ addr $address_

......

}

Page 31: NS Examples for Wireless Scenario

OTcl ( MIT Object TCL )

[ Back to Network Simulator 2 for Wireless Home Page ]

1. The constructor function of a class (object) is:

Init

The init instproc is used to initialize a freshly allocated object that is a direct or

indirect instance of the class Object. It is normally called by the system (perhaps from

more specialized init instprocs) as part of object creation, but may be called by the

user.

init interprets its arguments as pairs of option keys and option values. Each option

key should be the name of a valid method for the object, preceded by a dash. The

method should take one argument. For each option key and option value pair, init calls

the method on the object, with the option value as its argument. It returns the empty

string.

To customize object creation, write an init instproc for a class, not an alloc proc. If

the option key and option value creation syntax is still desired, then call

the Object init instproc by using next. This is discussed in the create instproc

in OTcl Classes.

% Class Bagel

Bagel

% foreach i {1 2 3 4} {

Bagel instproc $i {v} {puts $v}

}

% Bagel abagel

abagel

% abagel init -1 one -2 two -3 three -4 four!

one

two

three

four!

init is conceptually equivalent to the following.

Object instproc init {args} {

if {[llength $args]%2 != 0} then {

error {uneven number of arguments}

Page 32: NS Examples for Wireless Scenario

}

while {$args != {}} {

set key [lindex $args 0]

if {[string match {-*} $key]} then {

set key [string range $key 1 end]

}

set val [lindex $args 1]

if {[catch {$self $key $val} msg]!=0} then {

set opt [list $self $key $val]

error "$msg during $opt"

}

set args [lrange $args 2 end]

}

return {}

}

Interfaces of Wireless MAC in ns-2

[ Back to Network Simulator 2 for Wireless Home Page ]

General Architecture of a mobile node in ns-2:

Page 33: NS Examples for Wireless Scenario

the relationship of MAC could be found in ns-mobilenode.tcl. The source code:

........

#

# The following setups up link layer, mac layer, network interface

# and physical layer structures for the mobile node.

#

Node/MobileNode instproc add-interface { channel pmodel lltype mactype \

qtype qlen iftype anttype topo inerrproc outerrproc fecproc} {

$self instvar arptable_ nifs_ netif_ mac_ ifq_ ll_ imep_ inerr_

outerr_ fec_

.......

#

# Link Layer

#

$ll arptable $arptable_

$ll mac $mac

$ll down-target $ifq

Page 34: NS Examples for Wireless Scenario

if {$imepflag == "ON" } {

$imep recvtarget [$self entry]

$imep sendtarget $ll

$ll up-target $imep

} else {

$ll up-target [$self entry]

}

#

# Interface Queue

#

$ifq target $mac

$ifq set limit_ $qlen

if {$imepflag != ""} {

set drpT [$self mobility-trace Drop "IFQ"]

} else {

set drpT [cmu-trace Drop "IFQ" $self]

}

$ifq drop-target $drpT

if { $namfp != "" } {

$drpT namattach $namfp

}

# Mac Layer

#

$mac netif $netif

$mac up-target $ll

if {$outerr == "" && $fec == ""} {

$mac down-target $netif

} elseif {$outerr != "" && $fec == ""} {

$mac down-target $outerr

$outerr target $netif

} elseif {$outerr == "" && $fec != ""} {

$mac down-target $fec

$fec down-target $netif

} else {

$mac down-target $fec

$fec down-target $outerr

$err target $netif

}

Actually, from top to down path, the structure is ll ---> ifq ----> mac ---> netif . for

packets going up, it is netif ---> mac --->ll. Thus, ifq is only used for down path of .

however, a scheduler is also only useful to handle outgoing packets. Thus, if we want

to implement a scheduler, we have to use something to replace this "ifq" and remake

the interface in tcl script.

Multi-rate MAC in ns-2

[ Back to Network Simulator 2 for Wireless Home Page ]

Page 35: NS Examples for Wireless Scenario

Introduction

First, an introduction on "how ns-2 handle the 802.11 rate":

There is a file ns-mac.tcl in ./tcl/lib directory, in this file the MAC/802-11 set

datarate_ as 1Mb, and basicRate_ as 1Mb. change these two values could change rate.

We have to consider following questions:

Atomic operations:

1. The sender determine the rate (how??). calculate NAV, assuming ACK use the same rate( or basic rate??). Send DATA

2. How to let the receiver know the rate? We have to use PLCP header. The SIGNAL field in PLCP header is used for this purpose.

3. Why the receiver needs to know the rate? because it wants to correct receive it and might send ACK with same rate.

4. Using Short PLCP? Two major changes, PLCP preamble is 72 instead of 144 bits (still sent with 1Mbps) The PLCP header is sent with 2Mbps.

Control & Feedback for auto-rate

1. Receiver-based Autorate (RBAR). RTS/CTS is necessary, RTS send with lowest rate (1Mbps), the receiver put something in the CTS to tell the sender use which rate (CTS is still sent with lowest rate)

2. ARF (auto-rate fallback), for every 2nd ACK miss( transmission failure) following good transmission, fallback to lower rate and set a timer. Whenever the consecutive 10 good transmission or timer expired, upgrade to higher rate. Then, if miss ACK, fallback to lower rate.

3. Fixed Rate. Assume every node is not moving, the benefits of adaptive autorate is very small. So, for every node pair, we set a fixed rate to follow, either 1,2,5.5,11

Rate .vs. Range

1. Each rate corresponding to a different transmission range. This is to be reflected.

2. Carrier-Sense threshold does not change for different rate. So this is a fixed vaue.

Page 36: NS Examples for Wireless Scenario

Implementation

1. set rate 2. short preamble 3. receive threshold 4. AutoRate Scheme 1: ARF

baisc multirate codes (only Implement Feature 1 & 2) (download zip file)

And also, there is 8db SNR difference from the 1Mbps and 11Mbps rate. It means that

the 1Mbps frames will be decoded in a distance more than 250 meters.

it is a baisc multirate setting with rate info attached as Pxtinfo txinfo

there is no auto rate selection.

Advanced multirate code: Implement Feature 1,2 3

Auto multi-rate codes: (Implement Feature 1,2 3 and a feasible Autorate Scheme)

in addition to basic multirate, auto rate and channel access estimation.

The design is integrated with a new cross-layer MAC design entity which a new structure of Node_Info is involved. (Link to Design of Cross-layer MAC).

For both versions, 6 files need to modified:

in ~/mac directoty:

mac-802_11.h mac-802-11.cc wireless-phy.cc. wireless-phy.h

in ~/common directory

mobilenode.cc .allow node to change its rate. It should has its will to stay in a lower rate as wish.

packet-stamp.h This is a HACK! The receiver cannot know the rate before decoding the PLCP header, but here we put rate as same as SNR.

Note that whenever switch from versions of multi-rate to non-mulitrate ns codes,

make clean & make due to problems with packet-stamp.h otherwise, "segmentation

Page 37: NS Examples for Wireless Scenario

fault" occurs.

Based on the feature, Modifications are described in detail

Set Rate in TCL for each node:

rate is given in tcl code, and no matter what happens, the node has to use this rate as a

fixed value. No matter a received DATA is another rate or not, datarate_ does not

change. Only if an auto-rate scheme is in effect.............

in mac-802.11.cc

getTxrate helps to get the rate info and calculate the timeouts,

setTxrate is only used for autorate..............

in mobilenode.cc:

#include "wireless-phy.h"

#include "mac-802_11.h"

Mac802_11* macptr;

......

//Zhibin - To have an access to change rate!

else if (strcmp(argv[1], "change_rate") == 0) {

macptr = (Mac802_11*) ifhead_.lh_first->uptarget();

if (macptr) {

// Keep attention: supposes only 1

// interface present!

macptr->setRate(atoi(argv[2]));

fprintf(stderr, "Rate changed to: %d\n\n",\

atoi(argv[2]));

return TCL_OK;

} else {

fprintf(stderr, "Error.. Mac not found..\n");

return(TCL_ERROR);

};

return TCL_OK;

}

............

Actually, this change might not useful if u don't set it dynamically from tcl file.

in mac-802_11.h

//zhibin-multirate

inline double setRate(double newvalue){ return dataRate_ =

Page 38: NS Examples for Wireless Scenario

newvalue;};

//-----------------

Short Preamble header & different rate for ACK/RTS/CTS/DATA

in mac-802_11.h

// Zhibin- To introduce the short preamble, variables will be bind

from ns-default.tcl

u_int32_t ShortPreambleLength;

double ShortPLCPDataRate;

double ShortPLCPHeaderThreshold; // we keep this parameter

as part of MIB

inline double getEIFS(double r) {

// see (802.11-1999, 9.2.10)

return(SIFSTime + getDIFS()

+ (8 * getACKlen(r))/PLCPDataRate);

}

inline double getShortPLCPHeaderThreshold() { return

ShortPLCPHeaderThreshold ; }

inline u_int32_t

getShortPreambleLength() { return(ShortPreambleLength); }

inline double getShortPLCPDataRate() { return(ShortPLCPDataRate); }

inline u_int32_t getPLCPHeaderLength() { return(PLCPHeaderLength); }

inline u_int32_t getPLCPhdrLen(double r) {

return ((r>ShortPLCPHeaderThreshold )

?((ShortPreambleLength >> 3)+(PLCPHeaderLength >> 3))

:((PreambleLength >> 3)+(PLCPHeaderLength >> 3)));

}

inline u_int32_t getHdrLen11(double r) {

return(getPLCPhdrLen(r) + sizeof(struct hdr_mac802_11)

+ ETHER_FCS_LEN);

}

inline u_int32_t getRTSlen(double r) {

return(getPLCPhdrLen(r) + sizeof(struct rts_frame));

}

inline u_int32_t getCTSlen(double r) {

return(getPLCPhdrLen(r) + sizeof(struct cts_frame));

}

inline u_int32_t getACKlen(double r) {

return(getPLCPhdrLen(r) + sizeof(struct ack_frame));

Page 39: NS Examples for Wireless Scenario

}

in ns-default.tcl

Mac/802_11 set ShortPreambleLength_ 72 ;

# DataRate of Short PLCP Header. PLCP preample is always sent at

DSSS_PLCPDataRate

Mac/802_11 set ShortPLCPDataRate_ 2.0e6 ;

#-------zhibinwu ----------------

Mac/802_11 set ShortPLCPHeaderThreshold_ 1.0e6;

in mac-802_11.cc

parent->bind("ShortPreambleLength_", &ShortPreambleLength);

parent->bind("ShortPLCPHeaderThreshold_", &ShortPLCPHeaderThreshold);

parent->bind_bw("ShortPLCPDataRate_", &ShortPLCPDataRate);

Has to assume all ACK and RTS/CTS are in basic rate. Thus, probablay 1mbps,

Change :

getCTSlen() ----> getRTSlen(basicRate_);

getRTSlen() ----> getCTSlen(basicRate_);

getACKlen() ----> getACKlen(basicRate_);

getEIFS ----> getEIFS(basicRate_);

getHdrlen11() ----->getHdrlen11(p->txinfo_.getTxRate())

double

Mac802_11::txtime(double psz, double drt)

{

// change wrt Mike's code

// double dsz = psz - PLCP_HDR_LEN;

// int plcp_hdr = PLCP_HDR_LEN << 3;

// double dsz = psz - phymib_.getPLCPhdrLen();

// int plcp_hdr = phymib_.getPLCPhdrLen() << 3;

double dsz = psz - phymib_.getPLCPhdrLen(drt);

int plcp_hdr = phymib_.getPLCPhdrLen(drt) << 3;

int datalen = (int)dsz << 3;

// change wrt Mike's code

// double t = (((double)plcp_hdr)/phymib_->PLCPDataRate) +

Page 40: NS Examples for Wireless Scenario

(((double)datalen)/drt);

// double t = (((double)plcp_hdr)/phymib_.getPLCPDataRate())

// + (((double)datalen)/drt);

double t = 0;

if ( drt >phymib_.getShortPLCPHeaderThreshold() ) {

/* Zhibin - In this case the are sent at 1 Mbps while

* ShortPLCPHeader at 2Mbps and the rest at dataRate_

*/

t =

(((double)phymib_.getShortPreambleLength())/(phymib_.getPLCPDataRate())) +

(((double)phymib_.getPLCPHeaderLength())/(phymib_.getShortPLCPDataRate())) +

(((double)datalen)/drt);

} else {

t = (((double)plcp_hdr)/phymib_.getPLCPDataRate()) +

(((double)datalen)/drt);

};

return(t);

}

Attach and Read Rate information with DATA frame

in packet-stamp.h

inline double getTxRate() {return txRate;}

inline void setTxRate(double r) {txRate = r;}

in 802.11.cc

void

Mac802_11::sendDATA(Packet *p)

{

....

if((u_int32_t)ETHER_ADDR(dh->dh_ra) != MAC_BROADCAST) {

p->txinfo_.setTxRate(dataRate_);

if((u_int32_t)ETHER_ADDR(dh->dh_ra) !=

MAC_BROADCAST) {

ch->size() += phymib_.getHdrLen11(dataRate_);

}else{

// GgX - Broadcast packets are always sent at basicRate_

ch->size() += phymib_.getHdrLen11(basicRate_);

};

Page 41: NS Examples for Wireless Scenario

.....

}

SNR of different Rates ( Drop packets of higher rate if SNR is low)

In wireless-phy.cc

IN sendup fucntion, first get the rate information of the packet. ( The default rate is

1M,if unset in MAC layer)

double rate = p->txinfo_.getTxRate();

int rate_index;

//zhibinwu, find the rate index in rate table

for ( int rate_index=0; rate_index< NUM_RATE_80211b; i++)

{

if ( rate == RXRate_[rate_index]) break;

}

if (rate_index==4) printf ("ERROR! RATE NOT FOUND!\N");

if (Pr < RXThresh_[rate_index]) {

/*

* We can detect, but not successfully receive

* this packet.

*/

hdr_cmn *hdr = HDR_CMN(p);

hdr->error() = 1;

#if DEBUG > 3

printf("SM %f.9 _%d_ drop pkt from %d low POWER

%e/%e\n",

Scheduler::instance().clock(), node()->index(),

p->txinfo_.getNode()->index(),

Pr,RXThresh_[rate_index]);

#endif

}

And

Page 42: NS Examples for Wireless Scenario

RXRate_[0]= 1000000;

RXrate_[1]= 2000000;

RxRate_[2]= 5500000;

RxRate_[3]= 11000000;

RXThresh_[0] = 0.1; // receive power threshold (W) for each rate

RXThresh_[1] = 0.2; // receive power threshold (W) for each rate

RXThresh_[2] = 0.3; // receive power threshold (W) for each rate

RXThresh_[3] = 0.4; // receive power threshold (W) for each rate

in wireless-phy.h

#define NUM_RATE_80211b 4;

double RXRate_[NUM_RATE_80211b];

double RXThresh_[NUM_RATE_80211b]; // receive power threshold (W)

for each rate

ARF

ARF relies on MAC retransmission (set retry limit as 7 will be good)

1. Define rate array in MAC; 2. set a varible in MAC to flag miss ACK event. 3. Set a conunter to counter consecutive transmissions 4. In retransmit data, downgrade-rate, reset ch->size() and ch->txtime(); 5. In recvACK, prepare upgrade-rate

In mac-802_11.cc

//zhibinwu

optRate_[0] = 1000000;

optRate_[1] = 2000000;

optRate_[2] = 5500000;

optRate_[3] = 11000000;

missACK = false;

ACKcounter = 0;

void

Mac802_11::recvACK(Packet *p)

{

//zhibinwu ----------ARF----

Page 43: NS Examples for Wireless Scenario

missACK_ = false;

ACKcounter_++;

if ( ACKcounter_ >10 )

{

//upgrade datarate

int m;

for (m=0;m<4;m++)

{

if ( optRate_[m] == dataRate_ && m!=3)

{

dataRate_ = optRate_[m+1];

break;

}

}

//printf(" the new datarate is %f\n", dataRate_);

ACKcounter_ = 0;

}

//-------------------------------

}

void

Mac802_11::RetransmitDATA()

{

//zhibinwu's code to do ARF (AutoRate Fallback)

ACKcounter_ = 0; // no successive ACKs

if (missACK_ == false))

missACK_ = true; //first missed ACK does not trigger

fallback

else if ( dataRate_ == basicRate_)

{

//already fallback to lowest

}

else

{

//previous rate is datarate_ as same as getTxRate

ch->size() -= phymib_.getHdrLen11(pktTx_-

>txinfo_.getTxRate());

// assert pktTx and change size

int m;

for (m=0;m<4;m++)

{

if ( optRate_[m] == dataRate_ && m!=0)

{

dataRate_ = optRate_[m-1];

}

}

//calculate new size

ch->size() += phymib_.getHdrLen11(dataRate_);

ch->txtime() = txtime(ch->size(), dataRate_);

pktTx_->txinfo_.setTxRate(dataRate_);

Page 44: NS Examples for Wireless Scenario

}

// =============ARF---end=========

}

Appendix: PHY Model

In ns-2, the model is TwoRayground. It is for long range. Basically it means the

attenuation factor 4 is used instead of 2.

Pr = PtGtGrht2hr

2 / (Ld4)

The original setting is:

Tx Power 0.2818W (24.5dbm)

CSThreshold 1.559e-11 W (-102.5db) 550m

RxThreshold 3.652e-10 W (-91.1db) 250m

((3.652/1.559)*10)^0.25 =2.2

2.2*250 = 550

Modified model for 802.11b

TxPower 0.031622777 W (15dbm) Rate distance

CST -100dbm (1e-13 W) 1124m

RxThreshold[0] -94dbm 3.9811e-13 W 1Mbps 796

RxThreshold[1] -91dbm 7.9433e-13W 2Mbps 669

RxThreshold[2] -87dbm 1.9953e-12 W 5.5Mbps 532m

RxThreshold[3] -82dbm 6.3096e-12 W 11Mbps 399m