Thursday, October 7, 2010

Simulating wireless link errors

To attach the error model, add following codes to a TCL simulation script


..........
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) \
                         -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)

Network Simulator 2 script for a complex scenario


#This is an example for DSDV routing with 50 nodes in a 670*670 m2 area
#
# Note that all options listed in the beginning of the file could be initialized 
# with command line arguments by using "getopt $argc $argv"
# ======================================================================
# 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

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]]
 }
}

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)
#}
#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)
#

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

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

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]
}
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 

Debugging ns-2

Enable gdb debugging
./configure --enable-debug
make clean
make
 
Note: After you have done that, the Makefile is initialized again and loose all your changes to Makefile if your did some.


When ns-2 crashes, here are some possible places to check for any causes of errors:
  1. Scheduler: Event UID not valid!. This is probably associated with timers. If a timer has been called to start again before it expires...
  2. Segmentation fault. A pointer goes to a wrong place. A pointer is out of bound. Or null pointer value.
  3. No obvious cause of fault. Program stopped in a place that no obvious coding errors can be found. Try "make clean + make". Sometimes, if *.h file is changed, the cross-included header files needs to be re-compiled into the final program.
Refer to another article: http://wmlab.csie.ncu.edu.tw/~youngway/MTdata/archives/000104.html

Install ns 2.28 in Debian with gcc 4.0 or above

A usual problem is TK8.4.5 compile failure. This is because of lack of  X11 development libraries. Do apt-get install libx11-dev,libxt-dev
For gcc 4.0.3, ns-2.28 source codes are violating programming regulations. So, some files have to be manually modified to let "make" succeed.
Generally, the declaration of  "class A" has to be put before a reference appears in another class definition. For example,
class B
{

   A*  aa;
....
}

Also, declaration as
static const double ALPHA_ = 0.4;
in a header file, is illegal, because initialization of a static variable in header file would lead to multiple initializations occurred in all files including this header file.

So, it must be changed as :
static const double ALPHA_ // in header file
const double XCPQueue::ALPHA_ = 0.4; // in cpp file
A list of paths are given as below: (copying from ns-mail list)

diff -ru ns-allinone-2.28.orig/nam-1.11/agent.h ns-allinone-2.28/nam-1.11/agent.h
--- ns-allinone-2.28.orig/nam-1.11/agent.h 2001-06-15 21:53:10.000000000 -0400
+++ ns-allinone-2.28/nam-1.11/agent.h 2005-06-13 18:10:05.000000000 -0400
@@ -70,7 +70,7 @@
 inline double width() {return width_;}
 inline double height() {return height_;}
 virtual void findClosestCornertoPoint(double x, double y, 
- double &corner_x, double &corner_y) const = NULL; 
+ double &corner_x, double &corner_y) const = 0; 
 virtual void place(double x, double y);
 void label(const char* name, int anchor);
 void color(const char* name);
diff -ru ns-allinone-2.28.orig/ns-2.28/diffusion3/lib/nr/nr.hh ns-allinone-2.28/ns-2.28/diffusion3/lib/nr/nr.hh
--- ns-allinone-2.28.orig/ns-2.28/diffusion3/lib/nr/nr.hh 2005-01-19 13:23:21.000000000 -0500
+++ ns-allinone-2.28/ns-2.28/diffusion3/lib/nr/nr.hh 2005-06-13 18:11:03.000000000 -0400
@@ -43,7 +43,8 @@
 typedef signed int int32_t;
 #endif
 typedef signed short int16_t;
-#if defined (sparc)
+// #if defined (sparc)
+#if defined (__SVR4) && defined (__sun)
 typedef char int8_t;
 #else
 // Conflicts with system declaration of int8_t in Solaris
diff -ru ns-allinone-2.28.orig/ns-2.28/xcp/xcpq.cc ns-allinone-2.28/ns-2.28/xcp/xcpq.cc
--- ns-allinone-2.28.orig/ns-2.28/xcp/xcpq.cc 2005-02-03 13:29:20.000000000 -0500
+++ ns-allinone-2.28/ns-2.28/xcp/xcpq.cc 2005-06-13 18:10:30.000000000 -0400
@@ -33,6 +33,15 @@
 } class_droptail_xcpq;
 
 
+const double XCPQueue::ALPHA_ = 0.4;
+const double XCPQueue::BETA_ = 0.226;
+const double XCPQueue::GAMMA_ = 0.1;
+const double XCPQueue::XCP_MAX_INTERVAL= 1.0;
+const double XCPQueue::XCP_MIN_INTERVAL= .001;
+
+const double XCPQueue::BWIDTH = 0.01;
+
+
 XCPQueue::XCPQueue(): queue_timer_(NULL), 
 estimation_control_timer_(NULL),
 rtt_timer_(NULL), effective_rtt_(0.0),
diff -ru ns-allinone-2.28.orig/ns-2.28/xcp/xcpq.h ns-allinone-2.28/ns-2.28/xcp/xcpq.h
--- ns-allinone-2.28.orig/ns-2.28/xcp/xcpq.h 2005-02-03 13:29:20.000000000 -0500
+++ ns-allinone-2.28/ns-2.28/xcp/xcpq.h 2005-06-13 18:10:36.000000000 -0400
@@ -113,11 +113,11 @@
 XCPTimer* rtt_timer_;
 double link_capacity_bps_;
 
- static const double ALPHA_ = 0.4;
- static const double BETA_ = 0.226;
- static const double GAMMA_ = 0.1;
- static const double XCP_MAX_INTERVAL= 1.0;
- static const double XCP_MIN_INTERVAL= .001;
+ static const double ALPHA_ ;
+ static const double BETA_ ;
+ static const double GAMMA_ ;
+ static const double XCP_MAX_INTERVAL;
+ static const double XCP_MIN_INTERVAL;
 
 double Te_; // control interval
 double Tq_; 
@@ -141,7 +141,7 @@
 double b_[BSIZE];
 double t_[BSIZE];
 int maxb_;alter
- static const double BWIDTH = 0.01;
+ static const double BWIDTH;
 int min_queue_ci_;
 int max_queue_ci_;
 

Solution for another problem when install ns-2.28 in Debian
./configure: line 7068: ` OSF*)' tcl8.3.2 configuration failed! Exiting .

The problem is that there are superfluous "'" characters in unix/configure:
grep in unix/configure for /etc/.relid and change it 
from 
 system=MP-RAS-`awk '{print }' /etc/.relid'`
to
 system=MP-RAS-`awk '{print }' /etc/.relid`

There are more occurrences of that line in tcl, tk and 
octcl with the same problem.

For gcc 4.1.1 or above, there is a lot of coding violations. The best way is to still use gcc-4.0 to compile, change Makefile:

CC      = gcc-4.0
CPP     = g++-4.0

Install ns-2.27 in Red Hat Linux

Follow the following steps to install ns-2.27 in Red Hat Linux distribution
  1. tar -xzf *
  2. ./install
  3. Change .bash_profile and add some environment variables. put /home/zhibinwu/ns-allinone-2.27/bin:/home/zhibinwu/ns-allinone-2.27/tcl8.4.5/unix:/home/zhibinwu/ns-allinone-2.27/tk8.4.5/unix into your PATH environment; so that you'll be able to run itm/tclsh/wish/xgraph.
    IMPORTANT NOTICES:
    (1) You MUST put /home/zhibinwu/ns-allinone-2.27/otcl-1.8, /home/zhibinwu/ns-allinone-2.27/lib into your LD_LIBRARY_PATH environment variable.
     If it complains about X libraries, add path to your X libraries into LD_LIBRARY_PATH.
     If you are using csh, you can set it like:
     setenv LD_LIBRARY_PATH .... If you are using sh, you can set it like:
     export LD_LIBRARY_PATH=....
    
    (2) You MUST put /home/zhibinwu/ns-allinone-2.27/tcl8.4.5/library into your TCL_LIBRARY environmental variable. Otherwise ns/nam will complain during startup.
    
    (3) [OPTIONAL] To save disk space, you can now delete directories tcl8.4.5
     and tk8.4.5. They are now installed under /home/zhibinwu/ns-allinone-2.27/{bin,include,lib}
    so , finally the bash_profile is like this:
    PATH=$PATH:$HOME/bin:/home/zhibinwu/ns2/ns-allinone-2.27/bin:/home/zhibinwu/ns2/ns-allinone-2.27/tcl8.4.5/unix:/home/zhibinwu/ns2/ns-allinone-2.27/tk8.4.5/unix
    
    export LD_LIBRARY_PATH=/home/zhibinwu/ns2/ns-allinone-2.27/otcl-1.8:home/zhibinwu/ns2/ns-allinone-2.27/lib
    
    export TCL_LIBRARY=/home/zhibinwu/ns2/ns-allinone-2.27/tcl8.4.5/library
    
  4. cd ns-2.27; ./validate

Note: The ns installation needs x-develop package. Otherwise, it will fail to build TCL TK.

Installation: A possible problem with CPP_NAMESPACE 
ns-2.27/indep-utils/cmu-scen-gen/setdest/Makefile,
 ns-2.27/indep-utils/webtrace-conv/nlanr/Makefile, and
 ns-2.27/indep-utils/webtrace-conv/dec/Makefile,
 needed to be modified in order to fix a bug in ISI's distribution. The bug
 caused a compile-time error that looked like this:

 g++ -c -Dstand_alone -DSTL_NAMESPACE=@STL_NAMESPACE@ -o setdest.o setdest.cc
 In file included from ../../../config.h:54,
 from setdest.h:5,
 from setdest.cc:57:
 ../../../autoconf.h:85: Error: namespace `CPP_NAMESPACE' undeclared
 setdest.cc:71:1: warning: "INFINITY" redefined
 In file included from /usr/include/math.h:40,
 from setdest.cc:43:
 /usr/include/bits/mathdef.h:35:1: warning: this is the location of the previous definition
 make[1]: *** [setdest.o] Error 1
 make[1]: Leaving directory `/home/iandow/netsim/ns-allinone-2.27/ns-2.27/indep-utils/cmu-scen-gen/setdest'
 make[1]: Entering directory `/home/iandow/netsim/ns-allinone-2.27/ns-2.27/indep-utils/webtrace-conv/dec'

 To fix the bug, edit ns-2.27/indep-utils/cmu-scen-gen/setdest/Makefile and 
 change this line:
 DEFINE = -Dstand_alone -DSTL_NAMESPACE=@STL_NAMESPACE@
 to this line:
 DEFINE = -Dstand_alone -DSTL_NAMESPACE=@STL_NAMESPACE@ -DCPP_NAMESPACE=std

 In the other two makefiles, append -DCPP_NAMESPACE=std to CFLAGS.


REFERENCES:

[1] The Network Simulator - ns-2, http://www.isi.edu/nsnam/ns/
[2] NS news database, http://www.isi.edu/nsnam/htdig/search.html

Friday, January 4, 2008

My Last Day in School

Today is Jan. 4, 2008. The graduate school approved my dissertation and I get a Ph.D. degree in Rutgers University. This 5-year mind-boggling marathon is officially over. What a relief!