# mcast_cbrgen.tcl # # Last Revision: May 13, 2002 # # Jorjeta G. Jetcheva (jorjeta@cs.cmu.edu) # Note: This script currently only generates scenarios with group joins # and leaves, i.e. it does not generate source-specific joins even # though ADMR supports such joins. # # Sources and sinks are distinct by virtue of the for-loop values # # ====================================================================== # Default Script Options # ====================================================================== set opt(nn) 0 ;# Number of Nodes set opt(ng) 0 ;# Number of groups set opt(nspg) 0 ;# Number of sources per group set opt(nrpg) 0 ;# Number of receivers per group set opt(rnspg) 0 ;# Should the number of sources be generated randomly set opt(min_rnspg) 0 ;# Min for the random # of src set opt(max_rnspg) 0 ;# Max for the random # of src set opt(rnrpg) 0 ;# Should the number of receivers be generated randomly? set opt(min_rnrpg) 0 ;# Min for the random # of receivers set opt(max_rnrpg) 0 ;# Max for the random # of receivers set opt(leave_mg) 0 ;# Should the receivers be scheduled to leave the mcast group set opt(join_dur) 0 ;# Default join duration set opt(one_time_leaves) 0 ;# one time leaves or multiple "transactions" set opt(join_dur_r) 0 ;# Should the join duration be random set opt(join_dur_min) 60 ;# if leave is enabled how long should the join last min? set opt(join_dur_max) 180 ;# if leave is enabled how long should the join last max? set opt(seed) 0.0 set opt(pktsize) 64 set opt(rate) 4 set opt(interval) 0.0 ;# inverse of rate set opt(type) "" set opt(sim_length) 900 set opt(mba) 0x8000 ;# addresses greater than the base are considered to be ;# multicast addresses set opt(non_stop_comm) 1 ;# for on and off sources: push set opt(min_comm_duration) 60 set opt(max_comm_duration) 180 set opt(min_stop_duration) 60 set opt(max_stop_duration) 180 # set opt(unique_source_and_sinks) 1 ;# should all sources and sinks be distinct # ====================================================================== proc usage {} { global argv0 puts "\nusage: $argv0 \n \[-type cbr|tcp\] \[-nn nodes\] \[-ng num groups\] \[-seed seed\] \n \[-rate rate\] \[-mba mcast_base_address\] \[-nspg num_srcs\] \[-nrpg num_rcvrs\] \n \[-rnspg random_rnspg\] \[-rnrpg random_nrpg\] \[-min_rnspg min\] \[-max_rnspg max\] \n \[-min_rnrpg min\] \[-max_rnrpg max\] \[-leave_mg leave?\] \[-join_dur_min min_join_duration\]\n \[-join_dur_max max_join_duration\] \[-non_stop_comm non_stop or stop_and_start communcation\] -min_stop_duration -max_stop_duration -min_comm_duration -max_comm_duration communication duration (if in stop and start mode) -stop_duration stop duration (if in stop and start mode)\n" } proc getopt {argc argv} { global opt lappend optlist nn seed rate type ;# ?jj 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 create-cbr-source { src grp} { global rng opt cbr_cnt set stime [$rng uniform 0.0 180.0] if {$opt(non_stop_comm)} { puts "#\n# mcast CBR src $src for group $grp added at time $stime\n#" puts "set cbr_($cbr_cnt) \[\$node_($src) mcast-create-source CBR \$node_($src) $grp 0 $stime \]"; puts "\$cbr_($cbr_cnt) set packetSize_ $opt(pktsize)" puts "\$cbr_($cbr_cnt) set interval_ $opt(interval)" puts "\$cbr_($cbr_cnt) set random_ 1" puts "\$cbr_($cbr_cnt) set maxpkts_ 1000000" puts "\$ns_ at $stime \"\$cbr_($cbr_cnt) start\"" } else { puts "#\n# mcast CBR src $src for group $grp added at time $stime\n#" puts "set cbr_($cbr_cnt) \[\$node_($src) mcast-create-source CBR \$node_($src) $grp 0 $stime \]"; puts "\$cbr_($cbr_cnt) set packetSize_ $opt(pktsize)" puts "\$cbr_($cbr_cnt) set interval_ $opt(interval)" puts "\$cbr_($cbr_cnt) set random_ 1" puts "\$cbr_($cbr_cnt) set maxpkts_ 1000000" puts "\$ns_ at $stime \"\$cbr_($cbr_cnt) start\"" set etime [expr $stime + [$rng uniform $opt(min_comm_duration) $opt(max_comm_duration)]] puts "\$ns_ at $etime \"\$cbr_($cbr_cnt) stop\"" while {$etime < $opt(sim_length)} { set stime [expr $etime + [$rng uniform $opt(min_stop_duration) $opt(max_stop_duration)]] if { $stime < $opt(sim_length)} { puts "\$ns_ at $stime \"\$cbr_($cbr_cnt) start\"" } else { return; } set etime [expr $stime + [$rng uniform $opt(min_comm_duration) $opt(max_comm_duration)]] if {$etime > $opt(sim_length)} { set $etime $opt(sim_length) } else { puts "\$ns_ at $etime \"\$cbr_($cbr_cnt) stop\"" } } puts "\$ns_ at $opt(sim_length) \"\$cbr_($cbr_cnt) stop\"" } } proc create-cbr-sink {sink grp} { global rng opt set jtime [$rng uniform 0.0 180.0] set ltime -1 puts "\$ns_ at $jtime \"\$node_($sink) join-group CBR $grp $grp 0\"" if {$opt(leave_mg) == 0} { return; } if {$opt(one_time_leaves) == 0} { set ltime [expr $jtime + [$rng uniform $opt(join_dur_min) $opt(join_dur_max)]] puts "\$ns_ at $ltime \"\$node_($sink) leave-group $grp $grp\"" while {$ltime < $opt(sim_length)} { set jtime [expr $ltime + [$rng uniform $opt(join_dur_min) $opt(join_dur_max)]] if { $jtime < $opt(sim_length)} { puts "\$ns_ at $jtime \"\$node_($sink) join-group CBR $grp $grp 0\"" } else { return; } set ltime [expr $jtime + [$rng uniform $opt(join_dur_min) $opt(join_dur_max)]] if {$ltime > $opt(sim_length)} { set $ltime $opt(sim_length) } else { puts "\$ns_ at $ltime \"\$node_($sink) leave-group $grp $grp\"" } } puts "\$ns_ at $opt(sim_length) \"\$node_($sink) leave-group $grp $grp\"" } else { ;# one time leaves set jtime [$rng uniform 0.0 180.0] set ltime -1 puts "\$ns_ at $jtime \"\$node_($sink) join-group CBR $grp $grp 0\"" if {$opt(leave_mg) == 1} { if {$opt(join_dur_r) == 1} { while {$jtime >= $ltime} { set ltime [expr $jtime + [$rng uniform $opt(join_dur_min) $opt(join_dur_max)]] } } else { set ltime $opt(join_dur) } puts "\$ns_ at $ltime \"\$node_($sink) leave-group $grp $grp\"" } } } proc create-tcp-sink {src grp} { global rng opt puts "TCP sink not implemented yet!\n" } # jj the tcp function has cbr fields...weird...will prolly have to rewritten proc create-tcp-source { src grp } { global rng tcp_cnt opt set stime [$rng uniform 0.0 180.0] puts "#\n# mcast TCP src $src for group $grp added at time $stime\n#" puts "set tcp_($tcp_cnt) \[\$node_($src) mcast-create-source \ TCP \$node_($src) \$grp 0 $stime \]"; puts "\$tcp_($tcp_cnt) set window_ 32" puts "\$tcp_($tcp_cnt) set packetSize_ $opt(pktsize)" puts "set ftp_($tcp_cnt) \[\$tcp_($tcp_cnt) attach-source FTP\]" puts "\$ns_ at $stime \"\$ftp_($tcp_cnt) start\"" } proc is-src-unique { src num_sources type } { global cbr_sources tcp_sources non_unique_src for {set j 1} {$j < $num_sources } {incr j} { if {$type == "cbr"} { if {$src == $cbr_sources($j)} { set non_unique_src 1 } } else { if {$src == $tcp_sources($j)} { set non_unique_src 1 } } } } proc is-src-or-sink-unique { src_or_sink num_sources_and_sinks type } { global cbr_sources_and_sinks tcp_sources_and_sinks non_unique_src_or_sink for {set j 1} {$j < $num_sources } {incr j} { if {$type == "cbr"} { if {$src == $cbr_sources($j)} { set non_unique_src 1 } } else { if {$src == $tcp_sources($j)} { set non_unique_src_or_sink 1 } } } } # ====================================================================== getopt $argc $argv if { $opt(type) == "" } { usage exit } elseif { $opt(type) == "cbr" } { if { $opt(nn) == 0 || $opt(ng) == 0 || $opt(seed) == 0.0 || $opt(rate) == 0 } { usage exit } set opt(interval) [expr 1.0 / $opt(rate)] if { $opt(interval) <= 0.0 } { puts "\ninvalid sending rate $opt(rate)\n" exit } if { $opt(nn) < $opt(ng)*$opt(nspg) + $opt(ng)*$opt(nrpg) } { puts "\nError: Number of nodes is less than the specified number of sources and receivers.\n" exit } } puts "#\n# nodes: $opt(nn), send rate: $opt(interval), join_dur_r $opt(join_dur_r) (join_dur_min = $opt(join_dur_min), join_dur_max = $opt(join_dur_max)) seed: $opt(seed)\n#" set rng [new RNG] $rng seed $opt(seed) set tcp_cnt 0 set cbr_cnt 0 set u [new RandomVariable/Uniform] $u set min_ 1 $u set max_ 100 $u use-rng $rng set num_cbr_sources 0 set num_tcp_sources 0 for {set j 1} {$j <= $opt(ng) } {incr j} { set grp_id [expr $j+$opt(mba)] # create sources for the group # set num_cbr_sources 0 # set num_tcp_sources 0 global cbr_sources tcp_sources cbr_sources_and_sinks tcp_sources_and_sinks set init_val [expr [expr [expr [expr $j - 1]*$opt(nspg)] + [expr $opt(nrpg)*[expr $j-1]]]] # if {$init_val == 0} { # set init_val 1 # } for {set i $init_val} {$i < [expr $opt(nspg) + $init_val] } {incr i} { set x [$u value] # if { $x < 50 } {continue;} set dst [expr ($i) % [expr $opt(nn) + 1] ] if { $opt(type) == "cbr" } { incr cbr_cnt create-cbr-source $dst $grp_id } else { incr tcp_cnt create-tcp-source $dst $grp_id } } # create receivers for the group for {set k $i} {$k < $i + $opt(nrpg) } {incr k} { set x [$u value] # if { $x < 50 } {continue;} set dst [expr ($k) % [expr $opt(nn) + 1] ] if { $opt(type) == "cbr" } { create-cbr-sink $dst $grp_id } else { create-tcp-sink $dst $grp_id } } } # Notes # If a source joins a group, it doesn't loop its own packets because it can't hear the packets that # it sends (which is of course what's supposed to happen). # # Decide: - should the src of a group not be receivers as well # - should a src be a src for at most 1 or x groups