📄 ns-leach.tcl
字号:
set mac_dst $MAC_BROADCAST set link_dst $LINK_BROADCAST set msg [list $currentCH_] set datasize [expr $BYTES_ID * [llength $msg]] # Send beacons opt(max_dist) meters so all nodes can hear. $self send $mac_dst $link_dst $ADV_CH $msg $datasize $opt(max_dist) $code_} Application/LEACH instproc findBestCluster {} { global ns_ opt $self instvar now_ dist_ myADVnum_ $self instvar clusterChoices_ clusterDist_ currentCH_ set nodeID [$self nodeID] set min_dist 100000 if [$self isClusterHead?] { # If node is CH, determine code and create a TDMA schedule. set dist_ $opt(max_dist) set currentCH_ $nodeID set myADVnum_ [[$self mac] set myADVnum_] # There are opt(spreading) - 1 codes available b/c need 1 code # for communication with the base station. set numCodesAvail [expr 2 * $opt(spreading) - 1] set ClusterCode [expr int(fmod($myADVnum_, $numCodesAvail)) + 1] $ns_ at [expr $now_ + $opt(ra_adv_total) + $opt(ra_join)] \ "$self createSchedule" } else { # If node is not a CH, find the CH which allows minimum transmit # power for communication. Set the code and "distance" parameters # accordingly. if {$clusterChoices_ == ""} { puts "$nodeID: Warning!!! No Cluster Head ADVs were heard!" set currentCH_ $opt(nn) $self SendMyDataToBS return } foreach element $clusterChoices_ { set chID [lindex $element 0] set clustID [lindex $element 2] set ind [lsearch $clusterChoices_ $element] set d [lindex $clusterDist_ $ind] if {$d < $min_dist} { set min_dist $d set currentCH_ $chID set numCodesAvail [expr 2 * $opt(spreading) - 1] set ClusterCode [expr int(fmod($ind, $numCodesAvail)) + 1] } } set dist_ $min_dist set random_access [$self getRandomNumber 0 \ [expr $opt(ra_join) - $opt(ra_delay)]] $ns_ at [expr $now_ + $opt(ra_adv_total) + $random_access] \ "$self informClusterHead" $self GoToSleep } $self setCode $ClusterCode puts "$nodeID: Current cluster-head is $currentCH_, code is $ClusterCode, \ dist is $dist_" set clusterChoices_ "" set clusterDist_ ""}Application/LEACH instproc informClusterHead {} { global ns_ opt JOIN_REQ MAC_BROADCAST BYTES_ID $self instvar currentCH_ dist_ code_ set nodeID [$self nodeID] set chID $currentCH_ pp "$nodeID: sending Join-REQ to $chID (dist = $dist_) at time [$ns_ now]" set mac_dst $MAC_BROADCAST set link_dst $chID set msg [list $nodeID] set spreading_factor $opt(spreading) set datasize [expr $spreading_factor * $BYTES_ID * [llength $msg]] $self WakeUp # NOTE!!!! Join-Req message sent with enough power so all nodes in # the network can hear the message. This avoids the hidden terminal # problem. $self send $mac_dst $link_dst $JOIN_REQ $msg $datasize $opt(max_dist) $code_}Application/LEACH instproc createSchedule {} { global ns_ opt ADV_SCH MAC_BROADCAST BYTES_ID $self instvar clusterNodes_ TDMAschedule_ $self instvar dist_ code_ now_ beginningE_ set numNodes [llength $clusterNodes_] set chID [$self nodeID] if {$numNodes == 0} { set xmitOrder "" puts "Warning! There are no nodes in this cluster ($chID)!" $self SendMyDataToBS } else { # Set the TDMA schedule and send it to all nodes in the cluster. set xmitOrder $clusterNodes_ set msg [list $xmitOrder] set spreading_factor $opt(spreading) set datasize [expr $spreading_factor * $BYTES_ID * [llength $xmitOrder]] pp "$chID sending TDMA schedule: $xmitOrder at time [$ns_ now]" pp "Packet size is $datasize." set mac_dst $MAC_BROADCAST set link_dst $chID $self send $mac_dst $link_dst $ADV_SCH $msg $datasize $dist_ $code_ } set TDMAschedule_ $xmitOrder set outf [open $opt(dirname)/TDMAschedule.$now_.txt a] puts $outf "$chID\t$TDMAschedule_" close $outf set outf [open $opt(dirname)/startup.energy a] puts $outf "[$ns_ now]\t$chID\t[expr $beginningE_ - [[$self getER] query]] " close $outf}############################################################################## Receiving Functions#############################################################################Application/LEACH instproc recv {args} { global ADV_CH JOIN_REQ ADV_SCH DATA ns_ $self instvar currentCH_ set msg_type [[$self agent] set packetMsg_] set chID [lindex $args 0] set sender [lindex $args 1] set data_size [lindex $args 2] set msg [lrange $args 3 end] set nodeID [$self nodeID] if {$msg_type == $ADV_CH && ![$self isClusterHead?]} { $self recvADV_CH $msg } elseif {$msg_type == $JOIN_REQ && $nodeID == $chID} { $self recvJOIN_REQ $msg } elseif {$msg_type == $ADV_SCH && $chID == $currentCH_} { $self recvADV_SCH $msg } elseif {$msg_type == $DATA && $nodeID == $chID} { $self recvDATA $msg }}Application/LEACH instproc recvADV_CH {msg} { global ns_ $self instvar clusterChoices_ clusterDist_ set chID [lindex $msg 0] set nodeID [$self nodeID] pp "$nodeID rcvd ADV_CH from $chID at [$ns_ now]" set clusterChoices_ [lappend clusterChoices_ $msg] set clusterDist_ [lappend clusterDist_ [[$self agent] set distEst_]]}Application/LEACH instproc recvJOIN_REQ {nodeID} { global ns_ $self instvar clusterNodes_ set chID [$self nodeID] pp "$chID received notice of node $nodeID at time [$ns_ now]" set clusterNodes_ [lappend clusterNodes_ $nodeID]}Application/LEACH instproc recvADV_SCH {order} { global ns_ opt $self instvar xmitTime_ next_change_time_ now_ $self instvar beginningE_ frame_time_ end_frm_time_ set nodeID [$self nodeID] set ind [lsearch [join $order] $nodeID] set outf [open $opt(dirname)/startup.energy a] puts $outf "[$ns_ now]\t$nodeID\t[expr $beginningE_ - [[$self getER] query]]" close $outf if {$ind < 0} { puts "Warning!!!! $nodeID does not have a transmit time!" puts "Must send data directly to BS." set outf [open $opt(dirname)/TDMAschedule.$now_.txt a] puts -nonewline $outf "$nodeID\t" close $outf $self SendMyDataToBS return } # Determine time for a single TDMA frame. Each node sends data once # per frame in the specified slot. set frame_time_ [expr [expr 5 + [llength [join $order]]] * $opt(ss_slot_time)] set xmitTime_ [expr $opt(ss_slot_time) * $ind] set end_frm_time_ [expr $frame_time_ - $xmitTime_] set xmitat [expr [$ns_ now] + $xmitTime_] pp "$nodeID scheduled to transmit at $xmitat. It is now [$ns_ now]." if {[expr $xmitat + $end_frm_time_] < \ [expr $next_change_time_ - 10 * $opt(ss_slot_time)]} { $ns_ at $xmitat "$self sendData" } $self GoToSleep }Application/LEACH instproc recvDATA {msg} { global ns_ opt $self instvar TDMAschedule_ receivedFrom_ dataReceived_ set chID [$self nodeID] set nodeID [lindex $msg 0] pp "CH $chID received data ($msg) from $nodeID at [$ns_ now]" set receivedFrom_ [lappend receivedFrom_ $nodeID] set last_node [expr [llength $TDMAschedule_] - 1] if {$chID == [lindex $TDMAschedule_ $last_node]} { set last_node [expr $last_node - 1] } if {$nodeID == [lindex $TDMAschedule_ $last_node]} { # After an entire frame of data has been received, the cluster-head # must perform data aggregation functions and transmit the aggregate # signal to the base station. pp "CH $chID must now perform comp and xmit to BS." set num_sigs [llength $TDMAschedule_] set compute_energy [bf $opt(sig_size) $num_sigs] pp "\tcompute_energy = $compute_energy" [$self getER] remove $compute_energy set receivedFrom_ [lappend receivedFrom_ $chID] set dataReceived_ $receivedFrom_ set receivedFrom_ "" $self SendDataToBS }}############################################################################## Sending Functions#############################################################################Application/LEACH instproc sendData {} { global ns_ opt DATA MAC_BROADCAST BYTES_ID $self instvar next_change_time_ frame_time_ end_frm_time_ $self instvar currentCH_ dist_ code_ alive_ set nodeID [$self nodeID] set msg [list [list $nodeID , [$ns_ now]]] # Use DS-SS to send data messages to avoid inter-cluster interference. set spreading_factor $opt(spreading) set datasize [expr $spreading_factor * \ [expr [expr $BYTES_ID * [llength $msg]] + $opt(sig_size)]] $self WakeUp pp "$nodeID sending data $msg to $currentCH_ at [$ns_ now] (dist = $dist_)" set mac_dst $MAC_BROADCAST set link_dst $currentCH_ $self send $mac_dst $link_dst $DATA $msg $datasize $dist_ $code_ # Must transmit data again during slot in next TDMA frame. set xmitat [expr [$ns_ now] + $frame_time_] if {$alive_ && [expr $xmitat + $end_frm_time_] < \ [expr $next_change_time_ - 10 * $opt(ss_slot_time)]} { $ns_ at $xmitat "$self sendData" } set sense_energy [expr $opt(Esense) * $opt(sig_size) * 8] pp "Node $nodeID removing sensing energy = $sense_energy J." [$self getER] remove $sense_energy if {$currentCH_ != $nodeID} { $self GoToSleep }}Application/LEACH instproc send {mac_dst link_dst type msg data_size dist code} { global ns_ $self instvar rng_ #set random_delay [expr 0.005 + [$rng_ uniform 0 0.005]] #$ns_ at [expr [$ns_ now] + $random_delay] "$self send_now $mac_dst \ # $link_dst $type $msg $data_size $dist" $ns_ at [$ns_ now] "$self send_now $mac_dst \ $link_dst $type $msg $data_size $dist $code"}Application/LEACH instproc send_now {mac_dst link_dst type msg \ data_size dist code} { [$self agent] set packetMsg_ $type [$self agent] set dst_ $mac_dst [$self agent] sendmsg $data_size $msg $mac_dst $link_dst $dist $code}Application/LEACH instproc SendDataToBS {} { global ns_ opt bs MAC_BROADCAST DATA BYTES_ID $self instvar code_ rng_ now_ # Data must be sent directly to the basestation. set nodeID [$self nodeID] set msg [list [list [list $nodeID , [$ns_ now]]]] # Use DS-SS to send data messages to avoid inter-cluster interference. set spreading_factor $opt(spreading) set datasize [expr $spreading_factor * \ [expr $BYTES_ID * [llength $msg] + $opt(sig_size)]] set dist [nodeToBSDist [$self node] $bs] set mac_dst $MAC_BROADCAST set link_dst $opt(bsID) set random_delay [expr [$ns_ now] + [$rng_ uniform 0 0.01]] pp "Node $nodeID sending $msg to BS at time $random_delay" $ns_ at $random_delay "$self send $mac_dst $link_dst $DATA \ $msg $datasize $dist $opt(bsCode)"}Application/LEACH instproc SendMyDataToBS {} { global ns_ opt $self instvar next_change_time_ alive_ puts "Data being sent to the Base Station" $self SendDataToBS puts "Data was sent to the base station" set xmitat [expr [$ns_ now] + $opt(frame_time)] if {$alive_ && [expr $xmitat + $opt(frame_time)] < \ [expr $next_change_time_ - $opt(frame_time)]} { $ns_ at $xmitat "$self SendMyDataToBS" } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -