www.pudn.com > dsr-uu-0.2.rar > ns-mobilenode.tcl
# -*- Mode:tcl; tcl-indent-level:8; tab-width:8; indent-tabs-mode:t -*-
#
# Copyright (c) 1998-2000 Regents of the University of California.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the MASH Research
# Group at the University of California Berkeley.
# 4. Neither the name of the University nor of the Research Group may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $Header$
#
# Ported from CMU-Monarch project's mobility extensions -Padma, 10/98.
#
# IT IS NOT ENCOURAGED TO SUBCLASSS MOBILENODE CLASS DEFINED IN THIS FILE
#======================================================================
# The ARPTable class
#======================================================================
ARPTable instproc init args {
eval $self next $args ;# parent class constructor
}
ARPTable set bandwidth_ 0
ARPTable set delay_ 5us
#======================================================================
# The Node/MobileNodeNode class
#======================================================================
Node/MobileNode instproc init args {
# # I don't care about address classifier; it's not my business
# # All I do is to setup port classifier so we can do broadcast,
# # and to set up interface stuff.
# $self attach-node $node
# $node port-notify $self
eval $self next $args
$self instvar nifs_ arptable_ X_ Y_ Z_ nodetype_
set X_ 0.0
set Y_ 0.0
set Z_ 0.0
set arptable_ "" ;# no ARP table yet
set nifs_ 0 ;# number of network interfaces
# Mobile IP node processing
$self makemip-New$nodetype_
}
#----------------------------------------------------------------------
# XXX Following are the last remnant of nodetype_. Need to be completely
# removed, however, we need a better mechanism to distinguish vanilla
# mobile node from MIP base station, and MIP mobile host.
Node/MobileNode instproc makemip-NewMobile {} {
}
Node/MobileNode instproc makemip-NewBase {} {
}
Node/MobileNode instproc makemip-New {} {
}
Node/MobileNode instproc makemip-NewMIPBS {} {
$self instvar regagent_ encap_ decap_ agents_ id_
set dmux [new Classifier/Port/Reserve]
$dmux set mask_ 0x7fffffff
$dmux set shift_ 0
$self install-demux $dmux
set regagent_ [new Agent/MIPBS $self]
$self attach $regagent_ [Node/MobileNode set REGAGENT_PORT]
$self attach-encap
$self attach-decap
}
Node/MobileNode instproc attach-encap {} {
$self instvar encap_
set encap_ [new MIPEncapsulator]
$encap_ set mask_ [AddrParams NodeMask 1]
$encap_ set shift_ [AddrParams NodeShift 1]
#set mask 0x7fffffff
#set shift 0
set nodeaddr [AddrParams addr2id [$self node-addr]]
$encap_ set addr_ [expr ( ~([AddrParams NodeMask 1] << \
[AddrParams NodeShift 1]) & $nodeaddr )]
$encap_ set port_ 1
$encap_ target [$self entry]
$encap_ set node_ $self
}
Node/MobileNode instproc attach-decap {} {
$self instvar decap_ dmux_ agents_
set decap_ [new Classifier/Addr/MIPDecapsulator]
lappend agents_ $decap_
$decap_ set mask_ [AddrParams NodeMask 1]
$decap_ set shift_ [AddrParams NodeShift 1]
$dmux_ install [Node/MobileNode set DECAP_PORT] $decap_
}
Node/MobileNode instproc makemip-NewMIPMH {} {
$self instvar regagent_
set dmux [new Classifier/Port/Reserve]
$dmux set mask_ 0x7fffffff
$dmux set shift_ 0
$self install-demux $dmux
set regagent_ [new Agent/MIPMH $self]
$self attach $regagent_ [Node/MobileNode set REGAGENT_PORT]
$regagent_ set mask_ [AddrParams NodeMask 1]
$regagent_ set shift_ [AddrParams NodeShift 1]
$regagent_ set dst_addr_ [expr (~0) << [AddrParams NodeShift 1]]
$regagent_ set dst_port_ 0
$regagent_ node $self
}
#----------------------------------------------------------------------
Node/MobileNode instproc reset {} {
$self instvar arptable_ nifs_ netif_ mac_ ifq_ ll_ imep_
for {set i 0} {$i < $nifs_} {incr i} {
$netif_($i) reset
$mac_($i) reset
$ll_($i) reset
$ifq_($i) reset
if { [info exists opt(imep)] && $opt(imep) == "ON" } {
$imep_($i) reset
}
}
if { $arptable_ != "" } {
$arptable_ reset
}
}
#
# Attach an agent to a node. Pick a port and
# bind the agent to the port number.
# if portnumber is 255, default target is set to the routing agent
#
Node/MobileNode instproc add-target { agent port } {
$self instvar dmux_ imep_ toraDebug_
set ns [Simulator instance]
set newapi [$ns imep-support]
$agent set sport_ $port
# special processing for TORA/IMEP node
set toraonly [string first "TORA" [$agent info class]]
if {$toraonly != -1 } {
$agent if-queue [$self set ifq_(0)] ;# ifq between LL and MAC
#
# XXX: The routing protocol and the IMEP agents needs handles
# to each other.
#
$agent imep-agent [$self set imep_(0)]
[$self set imep_(0)] rtagent $agent
}
# Special processing for AODV
set aodvonly [string first "AODV" [$agent info class]]
if {$aodvonly != -1 } {
$agent if-queue [$self set ifq_(0)] ;# ifq between LL and MAC
}
#
# Special processing for ZBR
#set zbronly [string first "ZBR" [$agent info class]]
#if {$zbronly != -1 } {
# $agent if-queue [$self set ifq_(0)] ;# ifq between LL and MAC
#}
#
if { $port == [Node set rtagent_port_] } {
# Ad hoc routing agent setup needs special handling
$self add-target-rtagent $agent $port
return
}
# Attaching a normal agent
set namfp [$ns get-nam-traceall]
if { [Simulator set AgentTrace_] == "ON" } {
#
# Send Target
#
if {$newapi != ""} {
set sndT [$self mobility-trace Send "AGT"]
} else {
set sndT [cmu-trace Send AGT $self]
}
if { $namfp != "" } {
$sndT namattach $namfp
}
$sndT target [$self entry]
$agent target $sndT
#
# Recv Target
#
if {$newapi != ""} {
set rcvT [$self mobility-trace Recv "AGT"]
} else {
set rcvT [cmu-trace Recv AGT $self]
}
if { $namfp != "" } {
$rcvT namattach $namfp
}
$rcvT target $agent
$dmux_ install $port $rcvT
} else {
#
# Send Target
#
$agent target [$self entry]
#
# Recv Target
#
$dmux_ install $port $agent
}
}
Node/MobileNode instproc add-target-rtagent { agent port } {
$self instvar imep_ toraDebug_
set ns [Simulator instance]
set newapi [$ns imep-support]
set namfp [$ns get-nam-traceall]
set dmux_ [$self demux]
set classifier_ [$self entry]
# let the routing agent know about the port dmux
$agent port-dmux $dmux_
if { [Simulator set RouterTrace_] == "ON" } {
#
# Send Target
#
if {$newapi != ""} {
set sndT [$self mobility-trace Send "RTR"]
} else {
set sndT [cmu-trace Send "RTR" $self]
}
if { $namfp != "" } {
$sndT namattach $namfp
}
if { $newapi == "ON" } {
$agent target $imep_(0)
$imep_(0) sendtarget $sndT
# second tracer to see the actual
# types of tora packets before imep packs them
if { [info exists toraDebug_] && $toraDebug_ == "ON"} {
set sndT2 [$self mobility-trace Send "TRP"]
$sndT2 target $imep_(0)
$agent target $sndT2
}
} else { ;# no IMEP
$agent target $sndT
}
$sndT target [$self set ll_(0)]
#
# Recv Target
#
if {$newapi != ""} {
set rcvT [$self mobility-trace Recv "RTR"]
} else {
set rcvT [cmu-trace Recv "RTR" $self]
}
if { $namfp != "" } {
$rcvT namattach $namfp
}
if {$newapi == "ON" } {
[$self set ll_(0)] up-target $imep_(0)
$classifier_ defaulttarget $agent
# need a second tracer to see the actual
# types of tora packets after imep unpacks them
# no need to support any hier node
if {[info exists toraDebug_] && $toraDebug_ == "ON" } {
set rcvT2 [$self mobility-trace Recv "TRP"]
$rcvT2 target $agent
$classifier_ defaulttarget $rcvT2
}
} else {
$rcvT target $agent
$classifier_ defaulttarget $rcvT
$dmux_ install $port $rcvT
}
} else {
#
# Send Target
#
# if tora is used
if { $newapi == "ON" } {
$agent target $imep_(0)
# second tracer to see the actual
# types of tora packets before imep packs them
if { [info exists toraDebug_] && $toraDebug_ == "ON"} {
set sndT2 [$self mobility-trace Send "TRP"]
$sndT2 target $imep_(0)
$agent target $sndT2
}
$imep_(0) sendtarget [$self set ll_(0)]
} else { ;# no IMEP
$agent target [$self set ll_(0)]
}
#
# Recv Target
#
if {$newapi == "ON" } {
[$self set ll_(0)] up-target $imep_(0)
$classifier_ defaulttarget $agent
# need a second tracer to see the actual
# types of tora packets after imep unpacks them
# no need to support any hier node
if {[info exists toraDebug_] && $toraDebug_ == "ON" } {
set rcvT2 [$self mobility-trace Recv "TRP"]
$rcvT2 target $agent
[$self set classifier_] defaulttarget $rcvT2
}
} else {
$classifier_ defaulttarget $agent
$dmux_ install $port $agent
}
}
}
#
# 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_
set ns [Simulator instance]
set imepflag [$ns imep-support]
set t $nifs_
incr nifs_
set netif_($t) [new $iftype] ;# interface
set mac_($t) [new $mactype] ;# mac layer
set ifq_($t) [new $qtype] ;# interface queue
set ll_($t) [new $lltype] ;# link layer
set ant_($t) [new $anttype]
$ns mac-type $mactype
set inerr_($t) ""
if {$inerrproc != ""} {
set inerr_($t) [$inerrproc]
}
set outerr_($t) ""
if {$outerrproc != ""} {
set outerr_($t) [$outerrproc]
}
set fec_($t) ""
if {$fecproc != ""} {
set fec_($t) [$fecproc]
}
set namfp [$ns get-nam-traceall]
if {$imepflag == "ON" } {
# IMEP layer
set imep_($t) [new Agent/IMEP [$self id]]
set imep $imep_($t)
set drpT [$self mobility-trace Drop "RTR"]
if { $namfp != "" } {
$drpT namattach $namfp
}
$imep drop-target $drpT
$ns at 0.[$self id] "$imep_($t) start" ;# start beacon timer
}
#
# Local Variables
#
set nullAgent_ [$ns set nullAgent_]
set netif $netif_($t)
set mac $mac_($t)
set ifq $ifq_($t)
set ll $ll_($t)
set inerr $inerr_($t)
set outerr $outerr_($t)
set fec $fec_($t)
#
# Initialize ARP table only once.
#
if { $arptable_ == "" } {
set arptable_ [new ARPTable $self $mac]
# FOR backward compatibility sake, hack only
if {$imepflag != ""} {
set drpT [$self mobility-trace Drop "IFQ"]
} else {
set drpT [cmu-trace Drop "IFQ" $self]
}
$arptable_ drop-target $drpT
if { $namfp != "" } {
$drpT namattach $namfp
}
}
#
# Link Layer
#
$ll arptable $arptable_
$ll mac $mac
$ll down-target $ifq
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
}
set god_ [God instance]
if {$mactype == "Mac/802_11"} {
$mac nodes [$god_ num_nodes]
}
#
# Network Interface
#
#if {$fec == ""} {
# $netif up-target $mac
#} else {
# $netif up-target $fec
# $fec up-target $mac
#}
$netif channel $channel
if {$inerr == "" && $fec == ""} {
$netif up-target $mac
} elseif {$inerr != "" && $fec == ""} {
$netif up-target $inerr
$inerr target $mac
} elseif {$err == "" && $fec != ""} {
$netif up-target $fec
$fec up-target $mac
} else {
$netif up-target $inerr
$inerr target $fec
$fec up-target $mac
}
$netif propagation $pmodel ;# Propagation Model
$netif node $self ;# Bind node <---> interface
$netif antenna $ant_($t)
#
# Physical Channel
#
$channel addif $netif
# List-based improvement
# For nodes talking to multiple channels this should
# be called multiple times for each channel
$channel add-node $self
# let topo keep handle of channel
$topo channel $channel
# ============================================================
if { [Simulator set MacTrace_] == "ON" } {
#
# Trace RTS/CTS/ACK Packets
#
if {$imepflag != ""} {
set rcvT [$self mobility-trace Recv "MAC"]
} else {
set rcvT [cmu-trace Recv "MAC" $self]
}
$mac log-target $rcvT
if { $namfp != "" } {
$rcvT namattach $namfp
}
#
# Trace Sent Packets
#
if {$imepflag != ""} {
set sndT [$self mobility-trace Send "MAC"]
} else {
set sndT [cmu-trace Send "MAC" $self]
}
$sndT target [$mac down-target]
$mac down-target $sndT
if { $namfp != "" } {
$sndT namattach $namfp
}
#
# Trace Received Packets
#
if {$imepflag != ""} {
set rcvT [$self mobility-trace Recv "MAC"]
} else {
set rcvT [cmu-trace Recv "MAC" $self]
}
$rcvT target [$mac up-target]
$mac up-target $rcvT
if { $namfp != "" } {
$rcvT namattach $namfp
}
#
# Trace Dropped Packets
#
if {$imepflag != ""} {
set drpT [$self mobility-trace Drop "MAC"]
} else {
set drpT [cmu-trace Drop "MAC" $self]
}
$mac drop-target $drpT
if { $namfp != "" } {
$drpT namattach $namfp
}
} else {
$mac log-target [$ns set nullAgent_]
$mac drop-target [$ns set nullAgent_]
}
# change wrt Mike's code
if { [Simulator set EotTrace_] == "ON" } {
#
# Also trace end of transmission time for packets
#
if {$imepflag != ""} {
set eotT [$self mobility-trace EOT "MAC"]
} else {
set eoT [cmu-trace EOT "MAC" $self]
}
$mac eot-target $eotT
}
# ============================================================
$self addif $netif
}
# set transmission power
Node/MobileNode instproc setPt { val } {
$self instvar netif_
$netif_(0) setTxPower $val
}
# set receiving power
Node/MobileNode instproc setPr { val } {
$self instvar netif_
$netif_(0) setRxPower $val
}
# set idle power -- Chalermek
Node/MobileNode instproc setPidle { val } {
$self instvar netif_
$netif_(0) setIdlePower $val
}
# change wrt Mike's code
Node/MobileNode instproc getMac {param0} {
$self instvar mac_
return $mac_($param0)
}
Node/MobileNode instproc CFP { beacon_period cfp_duration } {
if {$mactype == "Mac/802_11"} {
$self instvar mac_
set ns_ [Simulator instance]
set beacon_period [$ns_ delay_parse $beacon_period]
set cfp_duration [$ns_ delay_parse $cfp_duration]
$mac_(0) cfp $beacon_period $cfp_duration
}
}
Node/MobileNode instproc mobility-trace { ttype atype } {
set ns [Simulator instance]
set tracefd [$ns get-ns-traceall]
if { $tracefd == "" } {
puts "Warning: You have not defined you tracefile yet!"
puts "Please use trace-all command to define it."
return ""
}
set T [new CMUTrace/$ttype $atype]
$T newtrace [Simulator set WirelessNewTrace_]
$T tagged [Simulator set TaggedTrace_]
$T target [$ns nullagent]
$T attach $tracefd
$T set src_ [$self id]
$T node $self
return $T
}
Node/MobileNode instproc nodetrace { tracefd } {
#
# This Trace Target is used to log changes in direction
# and velocity for the mobile node.
#
set T [new Trace/Generic]
$T target [[Simulator instance] set nullAgent_]
$T attach $tracefd
$T set src_ [$self id]
$self log-target $T
}
Node/MobileNode instproc agenttrace {tracefd} {
set ns [Simulator instance]
set ragent [$self set ragent_]
#
# Drop Target (always on regardless of other tracing)
#
set drpT [$self mobility-trace Drop "RTR"]
set namfp [$ns get-nam-traceall]
if { $namfp != ""} {
$drpT namattach $namfp
}
$ragent drop-target $drpT
#
# Log Target
#
set T [new Trace/Generic]
$T target [$ns set nullAgent_]
$T attach $tracefd
$T set src_ [$self id]
$ragent tracetarget $T
#
# XXX: let the IMEP agent use the same log target.
#
set imepflag [$ns imep-support]
if {$imepflag == "ON"} {
[$self set imep_(0)] log-target $T
}
}
Node/MobileNode instproc mip-call {ragent} {
$self instvar regagent_
if [info exists regagent_] {
$regagent_ ragent $ragent
}
}
Node/MobileNode instproc attach-gafpartner {} {
$self instvar gafpartner_ address_ ll_
set gafpartner_ [new GAFPartner]
$gafpartner_ set mask_ [AddrParams NodeMask 1]
$gafpartner_ set shift_ [AddrParams NodeShift 1]
set nodeaddr [AddrParams addr2id [$self node-addr]]
#$gafpartner_ set addr_ [expr ( ~([AddrParams NodeMask 1] << \
# [AddrParams NodeShift 1]) & $nodeaddr )]
$gafpartner_ set addr_ $nodeaddr
$gafpartner_ set port_ 254
#puts [$gafpartner_ set addr_]
$gafpartner_ target [$self entry]
$ll_(0) up-target $gafpartner_
}
Node/MobileNode instproc unset-gafpartner {} {
$self instvar gafpartner_
$gafpartner_ set-gafagent 0
}
#
Node/MobileNode instproc sscs args {
$self instvar mac_
eval $mac_(0) sscs $args
}
Node/MobileNode instproc NodeClr {arg1} {
$self instvar mac_
$mac_(0) NodeClr $arg1
}
Node/MobileNode instproc NodeLabel args {
$self instvar mac_
eval $mac_(0) NodeLabel $args
}
Node/MobileNode instproc node-down {} {
$self instvar mac_
$mac_(0) node-down
}
Node/MobileNode instproc node-up {} {
$self instvar mac_
$mac_(0) node-up
}
Node/MobileNode instproc RNType args {
$self instvar ragent_
eval $ragent_ RNType $args
}
#
Class SRNodeNew -superclass Node/MobileNode
SRNodeNew instproc init args {
$self instvar dsr_agent_ dmux_ entry_point_ address_
set ns [Simulator instance]
eval $self next $args ;# parent class constructor
if {$dmux_ == "" } {
# Use the default mash and shift
set dmux_ [new Classifier/Port]
}
if { [$ns set routingAgent_] == "DSRUU" } {
set dsr_agent_ [new Agent/DSRUU]
} else {
set dsr_agent_ [new Agent/DSRAgent]
}
# setup address (supports hier-address) for dsragent
$dsr_agent_ addr $address_
$dsr_agent_ node $self
if [Simulator set mobile_ip_] {
$dsr_agent_ port-dmux [$self set dmux_]
}
# set up IP address
$self addr $address_
if { [Simulator set RouterTrace_] == "ON" } {
# Recv Target
set rcvT [$self mobility-trace Recv "RTR"]
set namfp [$ns get-nam-traceall]
if { $namfp != "" } {
$rcvT namattach $namfp
}
$rcvT target $dsr_agent_
set entry_point_ $rcvT
} else {
# Recv Target
set entry_point_ $dsr_agent_
}
$self set ragent_ $dsr_agent_
$dsr_agent_ target $dmux_
# packets to the DSR port should be dropped, since we've
# already handled them in the DSRAgent at the entry.
set nullAgent_ [$ns set nullAgent_]
$dmux_ install [Node set rtagent_port_] $nullAgent_
# SRNodes don't use the IP addr classifier. The DSRAgent should
# be the entry point
$self instvar classifier_
set classifier_ "srnode made illegal use of classifier_"
return $self
}
SRNodeNew instproc start-dsr {} {
$self instvar dsr_agent_
$dsr_agent_ startdsr
}
SRNodeNew instproc entry {} {
$self instvar entry_point_
return $entry_point_
}
SRNodeNew instproc add-interface args {
eval $self next $args
$self instvar dsr_agent_ ll_ mac_ ifq_
set ns [Simulator instance]
$dsr_agent_ mac-addr [$mac_(0) id]
if { [Simulator set RouterTrace_] == "ON" } {
# Send Target
set sndT [$self mobility-trace Send "RTR"]
set namfp [$ns get-nam-traceall]
if {$namfp != "" } {
$sndT namattach $namfp
}
$sndT target $ll_(0)
$dsr_agent_ add-ll $sndT $ifq_(0)
} else {
# Send Target
$dsr_agent_ add-ll $ll_(0) $ifq_(0)
}
# setup promiscuous tap into mac layer
$dsr_agent_ install-tap $mac_(0)
}
SRNodeNew instproc reset args {
$self instvar dsr_agent_
eval $self next $args
$dsr_agent_ reset
}