ns-lib.tcl
上传用户:hzie11
上传日期:2013-10-07
资源大小:1487k
文件大小:61k
源码类别:

网络

开发平台:

C/C++

  1. # -*- Mode:tcl; tcl-indent-level:8; tab-width:8; indent-tabs-mode:t -*-
  2. #
  3. # Copyright (c) 1996 Regents of the University of California.
  4. # All rights reserved.
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions
  7. # are met:
  8. # 1. Redistributions of source code must retain the above copyright
  9. #    notice, this list of conditions and the following disclaimer.
  10. # 2. Redistributions in binary form must reproduce the above copyright
  11. #    notice, this list of conditions and the following disclaimer in the
  12. #    documentation and/or other materials provided with the distribution.
  13. # 3. All advertising materials mentioning features or use of this software
  14. #    must display the following acknowledgement:
  15. #  This product includes software developed by the MASH Research
  16. #  Group at the University of California Berkeley.
  17. # 4. Neither the name of the University nor of the Research Group may be
  18. #    used to endorse or promote products derived from this software without
  19. #    specific prior written permission.
  20. # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. # SUCH DAMAGE.
  31. #
  32. # @(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/tcl/lib/ns-lib.tcl,v 1.271 2005/10/09 19:32:07 tomh Exp $
  33. #
  34. # Word of warning to developers:
  35. # this code (and all it sources) is compiled into the
  36. # ns executable.  You need to rebuild ns or explicitly
  37. # source this code to see changes take effect.
  38. #
  39. proc warn {msg} {
  40. global warned_
  41. if {![info exists warned_($msg)]} {
  42. puts stderr "warning: $msg"
  43. set warned_($msg) 1
  44. }
  45. }
  46. if {[info commands debug] == ""} {
  47. proc debug args {
  48. warn {Script debugging disabled.  Reconfigure with --with-tcldebug, and recompile.}
  49. }
  50. }
  51. proc assert args {
  52.         if [catch "expr $args" ret] {
  53.                 set ret [eval expr $args]
  54.         }
  55.         if {! $ret} {
  56.                 error "assertion failed: $args"
  57.         }
  58. }
  59. proc find-max list {
  60. set max 0
  61. foreach val $list {
  62. if {$val > $max} {
  63. set max $val
  64. }
  65. }
  66. return $max
  67. }
  68. proc bw_parse { bspec } {
  69. if { [scan $bspec "%f%s" b unit] == 1 } {
  70. set unit bps
  71. }
  72. regsub {[/p]s(ec)?$} $unit {} unit
  73. if [string match {*B} $unit] {
  74. set b [expr $b*8]
  75. set unit "[string trimright $unit B]b"
  76. }
  77. switch $unit {
  78. b { return $b }
  79. kb { return [expr $b*1000] }
  80. Mb { return [expr $b*1000000] }
  81. Gb { return [expr $b*1000000000] }
  82. default { 
  83. puts "error: bw_parse: unknown unit `$unit'" 
  84. exit 1
  85. }
  86. }
  87. }
  88. proc time_parse { spec } {
  89. if { [scan $spec "%f%s" t unit] == 1 } {
  90. set unit s
  91. }
  92. regsub {sec$} $unit {s} unit
  93. switch $unit {
  94. s { return $t }
  95. ms { return [expr $t*1e-3] }
  96. us { return [expr $t*1e-6] }
  97. ns { return [expr $t*1e-9] }
  98. ps { return [expr $t*1e-12] }
  99. default { 
  100. puts "error: time_parse: unknown unit `$unit'" 
  101. exit 1
  102. }
  103. }
  104. }
  105. proc delay_parse { spec } {
  106. return [time_parse $spec]
  107. }
  108. #
  109. # Create the core OTcl class called "Simulator".
  110. # This is the principal interface to the simulation engine.
  111. #
  112. #Class Simulator
  113. #
  114. # XXX Whenever you modify the source list below, please also change the
  115. # OTcl script dependency list in Makefile.in
  116. #
  117. source ns-autoconf.tcl
  118. source ns-address.tcl
  119. source ns-node.tcl
  120. source ns-rtmodule.tcl
  121. source ns-hiernode.tcl
  122. source ns-mobilenode.tcl
  123. source ns-bsnode.tcl
  124. source ns-link.tcl
  125. source ns-source.tcl
  126. source ns-compat.tcl
  127. source ns-packet.tcl
  128. source ns-queue.tcl
  129. source ns-trace.tcl
  130. source ns-random.tcl
  131. source ns-agent.tcl
  132. source ns-route.tcl
  133. source ns-errmodel.tcl
  134. source ns-intserv.tcl
  135. source ns-cmutrace.tcl
  136. source ns-mip.tcl
  137. source ns-sat.tcl
  138. #source ns-nix.tcl
  139. source ns-diffusion.tcl
  140. source ../rtp/session-rtp.tcl
  141. source ../interface/ns-iface.tcl
  142. source ../lan/ns-mac.tcl
  143. # Added by Sushmita to support event tracing for mac-simple and 802.11
  144. source ../lan/ns-mac-simple.tcl
  145. source ../lan/ns-mac-802_11.tcl
  146. source ../lan/ns-ll.tcl
  147. source ../lan/vlan.tcl
  148. source ../lan/abslan.tcl
  149. source ../mcast/timer.tcl
  150. source ../mcast/ns-mcast.tcl
  151. source ns-srcrt.tcl
  152. source ../mcast/McastProto.tcl
  153. source ../mcast/DM.tcl
  154. source ../ctr-mcast/CtrMcast.tcl
  155. source ../ctr-mcast/CtrMcastComp.tcl
  156. source ../ctr-mcast/CtrRPComp.tcl
  157. source ../mcast/BST.tcl
  158. source ../mcast/srm.tcl
  159. source ../mcast/srm-ssm.tcl
  160. # These files removed due to licensing conflicts
  161. # source ../mcast/mftp_snd.tcl
  162. # source ../mcast/mftp_rcv.tcl
  163. # source ../mcast/mftp_rcv_stat.tcl
  164. source ../mcast/McastMonitor.tcl
  165. source ../rlm/rlm.tcl
  166. source ../rlm/rlm-ns.tcl
  167. source ../session/session.tcl
  168. source ../webcache/http-server.tcl
  169. source ../webcache/http-cache.tcl
  170. source ../webcache/http-agent.tcl
  171. source ../webcache/http-mcache.tcl
  172. source ../webcache/webtraf.tcl
  173. source ../webcache/empweb.tcl
  174. source ns-namsupp.tcl
  175. source ../mobility/dsdv.tcl
  176. source ../mobility/dsr.tcl
  177. source ../mobility/com.tcl
  178. source ../plm/plm.tcl
  179. source ../plm/plm-ns.tcl
  180. source ../plm/plm-topo.tcl
  181. # MPLS
  182. source ../mpls/ns-mpls-simulator.tcl
  183. source ../mpls/ns-mpls-node.tcl
  184. source ../mpls/ns-mpls-ldpagent.tcl
  185. source ../mpls/ns-mpls-classifier.tcl
  186. source ns-default.tcl
  187. source ../emulate/ns-emulate.tcl
  188. #pushback
  189. source ns-pushback.tcl
  190. # PGM
  191. #source ../pgm/ns-pgm.tcl
  192. #LMS
  193. source ../mcast/ns-lms.tcl
  194. #WIMAX
  195. source ns-wimax.tcl
  196. # STL dependent modules get included
  197. # ONLY when STL is found
  198. if {[ns-hasSTL] == 1} {
  199. source ns-nix.tcl
  200. source ../pgm/ns-pgm.tcl
  201. source ../rtglib/ns-rtProtoLS.tcl
  202. }
  203. source ns-qsnode.tcl
  204. # Obsolete modules
  205. #source ns-wireless-mip.tcl
  206. #source ns-nam.tcl
  207. Simulator instproc init args {
  208. # Debojyoti added this for asim 
  209. $self instvar useasim_
  210. $self instvar slinks_
  211. $self instvar nconn_
  212. $self instvar sflows_
  213. $self instvar nsflows_
  214. set slinks_(0:0) 0
  215. set nconn_ 0
  216. set conn_ ""
  217. # for short flows stuff
  218. set sflows_ "" 
  219. set nsflows_ 0
  220. set useasim_ 0
  221. $self create_packetformat
  222. $self use-scheduler Calendar
  223. #$self use-scheduler List
  224. $self set nullAgent_ [new Agent/Null]
  225. $self set-address-format def
  226. if {[lindex $args 0] == "-multicast"} {
  227. $self multicast $args
  228. }
  229. eval $self next $args
  230. }
  231. Simulator instproc nullagent {} {
  232. $self instvar nullAgent_
  233. return $nullAgent_
  234. }
  235. Simulator instproc use-scheduler type {
  236. $self instvar scheduler_
  237. if [info exists scheduler_] {
  238. if { [$scheduler_ info class] == "Scheduler/$type" } {
  239. return
  240. } else {
  241. delete $scheduler_
  242. }
  243. }
  244. set scheduler_ [new Scheduler/$type]
  245. $scheduler_ now
  246. }
  247. Simulator instproc delay_parse { spec } {
  248. return [time_parse $spec]
  249. }
  250. Simulator instproc bw_parse { spec } {
  251. return [bw_parse $spec]
  252. }
  253. #
  254. # A simple method to wrap any object around
  255. # a trace object that dumps to stdout
  256. #
  257. Simulator instproc dumper obj {
  258. set t [$self alloc-trace hop stdout]
  259. $t target $obj
  260. return $t
  261. }
  262. # New node structure
  263. #
  264. # Add APT to support multi-interface: user can specified multiple channels
  265. # when config nod. Still need modifications in routing agents to make
  266. # multi-interfaces really work.   -chen xuan  07/21/00
  267. #
  268. # Define global node configuration
  269. # $ns_ node-config -addressType flat/hierarchical
  270. #                  -adhocRouting   DSDV/DSR/TORA
  271. #                  -llType
  272. #                  -macType
  273. #                  -propType
  274. #                  -ifqType
  275. #                  -ifqLen
  276. #                  -phyType
  277. #                  -antType
  278. #    -channel
  279. #                  -channelType
  280. #                  -topologyInstance
  281. #                  -wiredRouting   ON/OFF
  282. #                  -mobileIP       ON/OFF
  283. #                  -energyModel    "EnergyModel"
  284. #                  -initialEnergy  (in Joules)
  285. #                  -rxPower        (in W)
  286. #                  -txPower        (in W)
  287. #                  -idlePower      (in W)
  288. #
  289. #                  -sleepPower     (in W)
  290. #
  291. #                  -agentTrace  ON
  292. #                  -routerTrace ON 
  293. #                  -macTrace OFF 
  294. #                  -toraDebug OFF                
  295. #                  -movementTrace OFF
  296. # change wrt Mike's code
  297. #                  -eotTrace OFF
  298. #                  -diffusionFilter "GradientFilter/OnePhasePullFilter/GeoRoutingFilter/RmstFilter/SourceRouteFilter/LogFilter/TagFilter"
  299. Simulator instproc addressType  {val} { $self set addressType_  $val }
  300. Simulator instproc adhocRouting  {val} { $self set routingAgent_  $val }
  301. Simulator instproc llType  {val} { $self set llType_  $val }
  302. Simulator instproc macType  {val} { $self set macType_  $val }
  303. Simulator instproc propType  {val} { $self set propType_  $val }
  304. Simulator instproc propInstance  {val} { $self set propInstance_  $val }
  305. Simulator instproc ifqType  {val} { $self set ifqType_  $val }
  306. Simulator instproc ifqLen  {val} { $self set ifqlen_  $val }
  307. Simulator instproc phyType  {val} { $self set phyType_  $val }
  308. Simulator instproc antType  {val} { $self set antType_  $val }
  309. Simulator instproc channel {val} {$self set channel_ $val}
  310. Simulator instproc channelType {val} {$self set channelType_ $val}
  311. Simulator instproc topoInstance {val} {$self set topoInstance_ $val}
  312. Simulator instproc wiredRouting {val} {$self set wiredRouting_ $val}
  313. Simulator instproc mobileIP {val} {$self set mobileIP_ $val}
  314. Simulator instproc energyModel  {val} { $self set energyModel_  $val }
  315. Simulator instproc initialEnergy  {val} { $self set initialEnergy_  $val }
  316. Simulator instproc txPower  {val} { $self set txPower_  $val }
  317. Simulator instproc rxPower  {val} { $self set rxPower_  $val }
  318. Simulator instproc idlePower  {val} { $self set idlePower_  $val }
  319. #
  320. Simulator instproc sleepPower  {val} { $self set sleepPower_  $val }
  321. Simulator instproc transitionPower  {val} { $self set transitionPower_  $val }
  322. Simulator instproc transitionTime  {val} { $self set transitionTime_  $val }
  323. #
  324. Simulator instproc IncomingErrProc  {val} { $self set inerrProc_  $val }
  325. Simulator instproc OutgoingErrProc  {val} { $self set outerrProc_  $val }
  326. Simulator instproc FECProc  {val} { $self set FECProc_  $val }
  327. Simulator instproc agentTrace  {val} { $self set agentTrace_  $val }
  328. Simulator instproc routerTrace  {val} { $self set routerTrace_  $val }
  329. Simulator instproc macTrace  {val} { $self set macTrace_  $val }
  330. Simulator instproc movementTrace  {val} { $self set movementTrace_  $val }
  331. Simulator instproc toraDebug {val} {$self set toraDebug_ $val }
  332. Simulator instproc satNodeType {val} {$self set satNodeType_ $val}
  333. Simulator instproc downlinkBW {val} {$self set downlinkBW_ $val}
  334. Simulator instproc stopTime {val} {$self set stopTime_ $val}
  335. # change wrt Mike's code
  336. Simulator instproc eotTrace  {val} { $self set eotTrace_  $val }
  337. Simulator instproc diffusionFilter {val} {$self set diffFilter_ $val}
  338. Simulator instproc MPLS { val } { 
  339. if { $val == "ON" } {
  340. Node enable-module "MPLS"
  341. } else {
  342. Node disable-module "MPLS"
  343. }
  344. }
  345. Simulator instproc PGM { val } { 
  346.         if { $val == "ON" } {
  347.                 Node enable-module "PGM"
  348.         } else {
  349.                 Node disable-module "PGM"
  350.         }
  351. }
  352. Simulator instproc LMS { val } {
  353. if { $val == "ON" } {
  354. Node enable-module "LMS"
  355. } else {
  356. Node disable-module "LMS"
  357. }
  358. }
  359. Simulator instproc get-nodetype {} {
  360. $self instvar addressType_ routingAgent_ wiredRouting_ 
  361. set val ""
  362. if { [info exists addressType_] && $addressType_ == "hierarchical" } {
  363. set val Hier
  364. }
  365. if { [info exists routingAgent_] && $routingAgent_ != "" } {
  366. set val Mobile
  367. }
  368. if { [info exists wiredRouting_] && $wiredRouting_ == "ON" } {
  369. set val Base
  370. }
  371. if { [info exists wiredRouting_] && $wiredRouting_ == "OFF"} {
  372. set val Base
  373. }
  374. if { [Simulator set mobile_ip_] } {
  375. if { $val == "Base" && $wiredRouting_ == "ON" } {
  376. set val MIPBS
  377. }
  378. if { $val == "Base" && $wiredRouting_ == "OFF" } {
  379. set val MIPMH
  380. }
  381. }
  382. return $val
  383. }
  384. Simulator instproc node-config args {
  385.         # Object::init-vars{} is defined in ~tclcl/tcl-object.tcl.
  386.         # It initializes all default variables in the following way:
  387.         #  1.  Look for pairs of {-cmd val} in args
  388.         #  2.  If "$self $cmd $val" is not valid then put it in a list of 
  389.         #      arguments to be returned to the caller.
  390.         # 
  391.         # Since we do not handle undefined {-cmd val} pairs, we ignore 
  392.         # return value from init-vars{}.
  393.         set args [eval $self init-vars $args]
  394.         $self instvar addressType_  routingAgent_ propType_  macTrace_ 
  395.     routerTrace_ agentTrace_ movementTrace_ channelType_ channel_ 
  396.     chan topoInstance_ propInstance_ mobileIP_ 
  397.     rxPower_ txPower_ idlePower_ sleepPower_ transitionPower_ 
  398.     transitionTime_ satNodeType_ eotTrace_
  399.         if [info exists macTrace_] {
  400. Simulator set MacTrace_ $macTrace_
  401. }
  402.         if [info exists routerTrace_] {
  403. Simulator set RouterTrace_ $routerTrace_
  404. }
  405.         if [info exists agentTrace_] {
  406. Simulator set AgentTrace_ $agentTrace_
  407. }
  408.         if [info exists movementTrace_] {
  409. Simulator set MovementTrace_ $movementTrace_
  410. }
  411. # change wrt Mike's code
  412. if [info exists eotTrace_] {
  413.                 Simulator set EotTrace_ $eotTrace_
  414.         }
  415.         # hacking for matching old cmu add-interface
  416.         # not good style, for back-compability ONLY
  417. #
  418. # Only create 1 instance of prop
  419. if {[info exists propInstance_]} {
  420. if {[info exists propType_] && [Simulator set propInstCreated_] == 0} {
  421. warn "Both propType and propInstance are set. propType is ignored."
  422. }
  423. } else {
  424. if {[info exists propType_]} {
  425. set propInstance_ [new $propType_]
  426. Simulator set propInstCreated_ 1
  427. }
  428. }
  429. # Add multi-interface support:
  430.   # User can only specify either channelType_ (single_interface as 
  431. # before) or channel_ (multi_interface)
  432.   # If both variables are specified, error!
  433.   if {[info exists channelType_] && [info exists channel_]} { 
  434. error "Can't specify both channel and channelType, error!"
  435. } elseif {[info exists channelType_] && ![info exists satNodeType_]} {
  436. # Single channel, single interface
  437. warn "Please use -channel as shown in tcl/ex/wireless-mitf.tcl"
  438. if {![info exists chan]} {
  439. set chan [new $channelType_]
  440. }
  441.   } elseif {[info exists channel_]} {
  442. # Multiple channel, multiple interfaces
  443. set chan $channel_
  444.   }
  445. if [info exists topoInstance_] {
  446. $propInstance_  topography $topoInstance_
  447. }
  448. # set address type, hierarchical or expanded
  449. if {[string compare $addressType_ ""] != 0} {
  450. $self set-address-format $addressType_ 
  451. }
  452. # set mobileIP flag
  453. if { [info exists mobileIP_] && $mobileIP_ == "ON"} {
  454. Simulator set mobile_ip_  1
  455. } else {
  456. if { [info exists mobileIP_] } {
  457. Simulator set mobile_ip_ 0
  458. }
  459. }
  460. }
  461. # Default behavior is changed: consider nam as not initialized if 
  462. # no shape OR color parameter is given
  463. Simulator instproc node args {
  464. $self instvar Node_ routingAgent_ wiredRouting_ satNodeType_
  465.         if { [Simulator info vars EnableMcast_] != "" } {
  466.                 warn "Flag variable Simulator::EnableMcast_ discontinued.nt
  467.                       Use multicast methods as:ntt
  468.                         % set ns [new Simulator -multicast on]ntt
  469.                         % $ns multicast"
  470.                 $self multicast
  471.                 Simulator unset EnableMcast_
  472.         }
  473.         if { [Simulator info vars NumberInterfaces_] != "" } {
  474.                 warn "Flag variable Simulator::NumberInterfaces_ discontinued.nt
  475.                       Setting this variable will not affect simulations."
  476.                 Simulator unset NumberInterfaces_
  477.         }
  478. # Satellite node
  479. if { [info exists satNodeType_] } {
  480. set node [eval $self create-satnode]
  481. #simulator's nodelist in C++ space
  482. if {[info exists wiredRouting_] && $wiredRouting_ == "ON"} {
  483. # add node to simulator's nodelist in C++ space
  484. $self add-node $node [$node id]
  485. # Want to keep global state of wiredRouting info
  486. SatRouteObject set wiredRouting_ true
  487. }
  488. return $node
  489. }
  490. # wireless-ready node
  491. if { [info exists routingAgent_] && ($routingAgent_ != "") } {
  492. set node [eval $self create-wireless-node $args]
  493. # for base node
  494. if {[info exists wiredRouting_] && $wiredRouting_ == "ON"} {
  495. set Node_([$node id]) $node
  496. #simulator's nodelist in C++ space
  497. $self add-node $node [$node id] 
  498. }
  499. return $node
  500. }
  501. # Enable-mcast is now done automatically inside Node::init{}
  502. # XXX node_factory_ is deprecated, HOWEVER, since it's still used by
  503. # mobile IP, algorithmic routing, manual routing, and backward 
  504. # compability tests of hierarchical routing, we should keep it around
  505. # before all related code are wiped out.
  506. set node [eval new [Simulator set node_factory_] $args]
  507. set Node_([$node id]) $node
  508. #add to simulator's nodelist in C++ space
  509. $self add-node $node [$node id] 
  510. #set the nodeid in c++ Node - ratul
  511. $node nodeid [$node id]
  512. $node set ns_ $self
  513. $self check-node-num
  514. return $node
  515. }
  516. # XXX This is stupid hack. When old code (not using node-config) is used, 
  517. # create-wireless-node{} will not be called, and IMEPFlag_ will remain empty
  518. # (as set in ns-default.tcl), then Node/MobileNode will use global proc 
  519. # cmu-trace to create trace objects; otherwise mobility-trace{} will be 
  520. # triggered.
  521. Simulator instproc imep-support {} {
  522. return [Simulator set IMEPFlag_]
  523. }
  524. # XXX This should be moved into the node initialization procedure instead 
  525. # of standing here in ns-lib.tcl.
  526. Simulator instproc create-wireless-node args {
  527.         $self instvar routingAgent_ wiredRouting_ propInstance_ llType_ 
  528.     macType_ ifqType_ ifqlen_ phyType_ chan antType_ 
  529.     energyModel_ initialEnergy_ txPower_ rxPower_ 
  530.     idlePower_ sleepPower_ transitionPower_ transitionTime_ 
  531.     topoInstance_ level1_ level2_ inerrProc_ outerrProc_ FECProc_
  532. Simulator set IMEPFlag_ OFF
  533.         # create node instance
  534.         set node [eval $self create-node-instance $args]
  535.         
  536.         # basestation address setting
  537.         if { [info exist wiredRouting_] && $wiredRouting_ == "ON" } {
  538. $node base-station [AddrParams addr2id [$node node-addr]]
  539.      }
  540.         switch -exact $routingAgent_ {
  541.     DSDV {
  542.     set ragent [$self create-dsdv-agent $node]
  543.     }
  544.     DSR {
  545.     $self at 0.0 "$node start-dsr"
  546.     }
  547.     AODV {
  548.     set ragent [$self create-aodv-agent $node]
  549.     }
  550.     TORA {
  551.     Simulator set IMEPFlag_ ON
  552.     set ragent [$self create-tora-agent $node]
  553.     }
  554.     DIFFUSION/RATE {
  555.     eval $node addr $args
  556.     set ragent [$self create-diffusion-rate-agent $node]
  557.     }
  558.     DIFFUSION/PROB {
  559.     eval $node addr $args
  560.     set ragent [$self create-diffusion-probability-agent $node]
  561.     }
  562.     Directed_Diffusion {
  563.     eval $node addr $args
  564.     set ragent [$self create-core-diffusion-rtg-agent $node]
  565.     }
  566.     FLOODING {
  567.     eval $node addr $args
  568.     set ragent [$self create-flooding-agent $node]
  569.     }
  570.     OMNIMCAST {
  571.     eval $node addr $args
  572.     set ragent [$self create-omnimcast-agent $node]
  573.     }
  574.     DumbAgent {
  575.     set ragent [$self create-dumb-agent $node]
  576.     }
  577.     ManualRtg {
  578.     set ragent [$self create-manual-rtg-agent $node]
  579.     }
  580.     default {
  581.     eval $node addr $args
  582.     puts "Wrong node routing agent!"
  583.     exit
  584.     }
  585. }
  586. # errProc_ and FECProc_ are an option unlike other 
  587.         # parameters for node interface
  588. if ![info exist inerrProc_] {
  589. set inerrProc_ ""
  590. }
  591. if ![info exist outerrProc_] {
  592. set outerrProc_ ""
  593. }
  594. if ![info exist FECProc_] {
  595. set FECProc_ ""
  596. }
  597. # Add main node interface
  598. $node add-interface $chan $propInstance_ $llType_ $macType_ 
  599.     $ifqType_ $ifqlen_ $phyType_ $antType_ $topoInstance_ 
  600. $inerrProc_ $outerrProc_ $FECProc_
  601. # Attach agent
  602. if {$routingAgent_ != "DSR"} {
  603. $node attach $ragent [Node set rtagent_port_]
  604. }
  605. if {$routingAgent_ == "DIFFUSION/RATE" ||
  606.             $routingAgent_ == "DIFFUSION/PROB" ||
  607.             $routingAgent_ == "FLOODING" ||
  608.             $routingAgent_ == "OMNIMCAST" ||
  609.     $routingAgent_ == "Directed_Diffusion" } {
  610. $ragent port-dmux [$node demux]
  611. $node instvar ll_
  612. $ragent add-ll $ll_(0)
  613. }
  614. if { $routingAgent_ == "DumbAgent" } {
  615. $ragent port-dmux [$node demux]
  616. }
  617. # Bind routing agent and mip agent if existing basestation 
  618. # address setting
  619.         if { [info exist wiredRouting_] && $wiredRouting_ == "ON" } {
  620. if { $routingAgent_ != "DSR" } {
  621. $node mip-call $ragent
  622. }
  623. }
  624. #
  625.         # This Trace Target is used to log changes in direction
  626.         # and velocity for the mobile node.
  627.         #
  628. set tracefd [$self get-ns-traceall]
  629.         if {$tracefd != "" } {
  630. $node nodetrace $tracefd
  631. $node agenttrace $tracefd
  632. }
  633. set namtracefd [$self get-nam-traceall]
  634. if {$namtracefd != "" } {
  635. $node namattach $namtracefd
  636. }
  637. if [info exists energyModel_] {
  638. if  [info exists level1_] {
  639. set l1 $level1_
  640. } else {
  641. set l1 0.5
  642. }
  643. if  [info exists level2_] {
  644. set l2 $level2_
  645. } else {
  646. set l2 0.2
  647. }
  648. $node addenergymodel [new $energyModel_ $node 
  649. $initialEnergy_ $l1 $l2]
  650.         }
  651.         if [info exists txPower_] {
  652. $node setPt $txPower_
  653.         }
  654.         if [info exists rxPower_] {
  655. $node setPr $rxPower_
  656.         }
  657.         if [info exists idlePower_] {
  658. $node setPidle $idlePower_
  659.         }
  660. #
  661. if [info exists sleepPower_] {
  662. $node setPsleep $sleepPower_
  663.         }
  664. if [info exists transitionPower_] {
  665. $node setPtransition $transitionPower_
  666.         }
  667. if [info exists transitionTime_] {
  668. $node setTtransition $transitionTime_
  669.         }
  670. #
  671. $node topography $topoInstance_
  672. return $node
  673. }
  674. Simulator instproc create-node-instance args {
  675. $self instvar routingAgent_
  676. # DSR is a special case
  677. if {$routingAgent_ == "DSR"} {
  678. set nodeclass [$self set-dsr-nodetype]
  679. } else {
  680. set nodeclass Node/MobileNode
  681. }
  682. return [eval new $nodeclass $args]
  683. }
  684. Simulator instproc set-dsr-nodetype {} {
  685. $self instvar wiredRouting_ 
  686. set nodetype SRNodeNew
  687. # MIP mobilenode
  688. if [Simulator set mobile_ip_] {
  689. set nodetype SRNodeNew/MIPMH
  690. # basestation dsr node
  691. if { [info exists wiredRouting_] && $wiredRouting_ == "ON"} {
  692. set nodetype Node/MobileNode/BaseStationNode
  693. }
  694. return $nodetype
  695. }
  696. Simulator instproc create-tora-agent { node } {
  697.         set ragent [new Agent/TORA [$node id]]
  698. $node set ragent_ $ragent
  699. return $ragent
  700. }
  701. Simulator instproc create-dsdv-agent { node } {
  702. # Create a dsdv routing agent for this node
  703. set ragent [new Agent/DSDV]
  704. # Setup address (supports hier-addr) for dsdv agent
  705. # and mobilenode
  706. set addr [$node node-addr]
  707. $ragent addr $addr
  708. $ragent node $node
  709. if [Simulator set mobile_ip_] {
  710. $ragent port-dmux [$node demux]
  711. }
  712. $node addr $addr
  713. $node set ragent_ $ragent
  714. $self at 0.0 "$ragent start-dsdv"    ;# start updates
  715. return $ragent
  716. }
  717. Simulator instproc create-dumb-agent { node } {
  718. # create a simple wireless agent
  719. # that only forwards packets
  720. # used for testing single hop brdcast/unicast mode 
  721. # for wireless macs
  722. set ragent [new Agent/DumbAgent]
  723. $node set ragent_ $ragent
  724. return $ragent
  725. }
  726. Simulator instproc create-manual-rtg-agent { node } {
  727. # create a simple wireless agent
  728. # that only forwards packets
  729. # used for testing single hop brdcast/unicast mode 
  730. # for wireless macs
  731. set ragent [new Agent/ManualRtgAgent]
  732. $node set ragent_ $ragent
  733. $node attach $ragent [Node set rtagent_port_]
  734. return $ragent
  735. }
  736. Simulator instproc create-aodv-agent { node } {
  737.         #  Create AODV routing agent
  738. set ragent [new Agent/AODV [$node node-addr]]
  739.         $self at 0.0 "$ragent start"     ;# start BEACON/HELLO Messages
  740.         $node set ragent_ $ragent
  741.         return $ragent
  742. }
  743. Simulator instproc use-newtrace {} {
  744. Simulator set WirelessNewTrace_ 1
  745. Simulator instproc use-taggedtrace { {tag ON} } {
  746. Simulator set TaggedTrace_ $tag
  747. }
  748. Simulator instproc hier-node haddr {
  749.   error "hier-nodes should be created with [$ns_ node $haddr]"
  750. }
  751. Simulator instproc now {} {
  752. $self instvar scheduler_
  753. return [$scheduler_ now]
  754. }
  755. Simulator instproc at args {
  756. $self instvar scheduler_
  757. return [eval $scheduler_ at $args]
  758. }
  759. Simulator instproc at-now args {
  760. $self instvar scheduler_
  761. return [eval $scheduler_ at-now $args]
  762. }
  763. Simulator instproc cancel args {
  764. $self instvar scheduler_
  765. return [eval $scheduler_ cancel $args]
  766. }
  767. Simulator instproc after {ival args} {
  768.         eval $self at [expr [$self now] + $ival] $args
  769. }
  770. #
  771. # check if total num of nodes exceed 2 to the power n 
  772. # where <n=node field size in address>
  773. #
  774. Simulator instproc check-node-num {} {
  775. if {[Node set nn_] > [expr pow(2, [AddrParams nodebits])]} {
  776. error "Number of nodes exceeds node-field-size of [AddrParams nodebits] bits"
  777. }
  778. }
  779. #
  780. # Check if number of items at each hier level (num of nodes, or clusters or
  781. # domains) exceed size of that hier level field size (in bits). should be 
  782. # modified to support n-level of hierarchies
  783. #
  784. Simulator instproc chk-hier-field-lengths {} {
  785. AddrParams instvar domain_num_ cluster_num_ nodes_num_
  786. if [info exists domain_num_] {
  787. if {[expr $domain_num_ - 1]> [AddrParams NodeMask 1]} {
  788. error "# of domains exceed dom-field-size "
  789. }
  790. if [info exists cluster_num_] {
  791. set maxval [expr [find-max $cluster_num_] - 1] 
  792. if {$maxval > [expr pow(2, [AddrParams NodeMask 2])]} {
  793. error "# of clusters exceed clus-field-size "
  794. }
  795. }
  796. if [info exists nodes_num_] {
  797. set maxval [expr [find-max $nodes_num_] -1]
  798. if {$maxval > [expr pow(2, [AddrParams NodeMask 3])]} {
  799. error "# of nodess exceed node-field-size"
  800. }
  801. }
  802. }
  803. Simulator instproc check-smac {} {
  804. $self instvar macType_
  805. if { [info exist macType_] && $macType_ == "Mac/SMAC" } {
  806. if { [$macType_ set syncFlag_] } {
  807. puts "nNOTE: SMAC is running with sleep-wakeup cycles on. Please make sure to run yr applications AFTER the nodes get sync'ed which is about 40sec for the default settings.n"
  808. }
  809. }
  810. }
  811. Simulator instproc run {} {
  812. # NIXVECTOR?
  813. # global runstart
  814. # set runstart [clock seconds]
  815. $self check-smac                      ;# print warning if in sleep/wakeup cycle
  816. $self check-node-num
  817. $self rtmodel-configure ;# in case there are any
  818. [$self get-routelogic] configure
  819. $self instvar scheduler_ Node_ link_ started_ 
  820. set started_ 1
  821. #
  822. # Reset every node, which resets every agent.
  823. #
  824. foreach nn [array names Node_] {
  825. $Node_($nn) reset
  826. # GFR Additions for NixVector Routing
  827. if { [Simulator set nix-routing] } {
  828. $Node_($nn) populate-objects
  829. }
  830. }
  831. #
  832. # Also reset every queue
  833. #
  834. foreach qn [array names link_] {
  835. set q [$link_($qn) queue]
  836. $q reset
  837. }
  838. # Do all nam-related initialization here
  839. $self init-nam
  840. # NIXVECTOR xxx?
  841. # global simstart
  842. # set simstart [clock seconds]
  843. return [$scheduler_ run]
  844. }
  845. # johnh xxx?
  846. Simulator instproc log-simstart { } {
  847.         # GFR Modification to log actual start
  848.         global simstart
  849.         puts "Starting Actual Simulation"
  850.         set simstart [clock seconds]
  851. }
  852. Simulator instproc halt {} {
  853. $self instvar scheduler_
  854. #puts "time: [clock format [clock seconds] -format %X]"
  855. $scheduler_ halt
  856. }
  857. Simulator instproc dumpq {} {
  858. $self instvar scheduler_
  859. $scheduler_ dumpq
  860. }
  861. Simulator instproc is-started {} {
  862. $self instvar started_
  863. return [info exists started_]
  864. }
  865. Simulator instproc clearMemTrace {} {
  866. $self instvar scheduler_
  867. $scheduler_ clearMemTrace
  868. }
  869. Simulator instproc simplex-link { n1 n2 bw delay qtype args } {
  870. $self instvar link_ queueMap_ nullAgent_ useasim_
  871. set sid [$n1 id]
  872. set did [$n2 id]
  873. # Debo
  874. if { $useasim_ == 1 } {
  875. set slink_($sid:$did) $self
  876. }
  877. if [info exists queueMap_($qtype)] {
  878. set qtype $queueMap_($qtype)
  879. }
  880. # construct the queue
  881. set qtypeOrig $qtype
  882. switch -exact $qtype {
  883. ErrorModule {
  884. if { [llength $args] > 0 } {
  885. set q [eval new $qtype $args]
  886. } else {
  887. set q [new $qtype Fid]
  888. }
  889. }
  890. intserv {
  891. set qtype [lindex $args 0]
  892. set q [new Queue/$qtype]
  893. }
  894. default {
  895. if { [llength $args] == 0} {
  896. set q [new Queue/$qtype]
  897. } else {
  898. set q [new Queue/$qtype $args]
  899. }
  900. }
  901. }
  902. # Now create the link
  903. switch -exact $qtypeOrig {
  904. RTM {
  905.                         set c [lindex $args 1]
  906.                         set link_($sid:$did) [new CBQLink       
  907.                                         $n1 $n2 $bw $delay $q $c]
  908.                 }
  909.                 CBQ -
  910.                 CBQ/WRR {
  911.                         # assume we have a string of form "linktype linkarg"
  912.                         if {[llength $args] == 0} {
  913.                                 # default classifier for cbq is just Fid type
  914.                                 set c [new Classifier/Hash/Fid 33]
  915.                         } else {
  916.                                 set c [lindex $args 0]
  917.                         }
  918.                         set link_($sid:$did) [new CBQLink       
  919.                                         $n1 $n2 $bw $delay $q $c]
  920.                 }
  921. FQ      {
  922. set link_($sid:$did) [new FQLink $n1 $n2 $bw $delay $q]
  923. }
  924.                 intserv {
  925.                         #XX need to clean this up
  926.                         set link_($sid:$did) [new IntServLink   
  927.                                         $n1 $n2 $bw $delay $q
  928. [concat $qtypeOrig $args]]
  929.                 }
  930.                 default {
  931.                         set link_($sid:$did) [new SimpleLink    
  932.                                         $n1 $n2 $bw $delay $q]
  933.                 }
  934.         }
  935. if {$qtype == "RED/Pushback"} {
  936. set pushback 1
  937. } else {
  938. set pushback 0
  939. }
  940. $n1 add-neighbor $n2 $pushback
  941. #XXX yuck
  942. if {[string first "RED" $qtype] != -1 || 
  943.     [string first "PI" $qtype] != -1 || 
  944.     [string first "Vq" $qtype] != -1 ||
  945.     [string first "REM" $qtype] != -1 ||  
  946.     [string first "GK" $qtype] != -1 ||  
  947.     [string first "RIO" $qtype] != -1 ||
  948.     [string first "XCP" $qtype] != -1} {
  949. $q link [$link_($sid:$did) set link_]
  950. }
  951. set trace [$self get-ns-traceall]
  952. if {$trace != ""} {
  953. $self trace-queue $n1 $n2 $trace
  954. }
  955. set trace [$self get-nam-traceall]
  956. if {$trace != ""} {
  957. $self namtrace-queue $n1 $n2 $trace
  958. }
  959. # Register this simplex link in nam link list. Treat it as 
  960. # a duplex link in nam
  961. $self register-nam-linkconfig $link_($sid:$did)
  962. }
  963. #
  964. # This is used by Link::orient to register/update the order in which links 
  965. # should created in nam. This is important because different creation order
  966. # may result in different layout.
  967. #
  968. # A poor hack. :( Any better ideas?
  969. #
  970. Simulator instproc register-nam-linkconfig link {
  971. $self instvar linkConfigList_ link_
  972. if [info exists linkConfigList_] {
  973. # Check whether the reverse simplex link is registered,
  974. # if so, don't register this link again.
  975. # We should have a separate object for duplex link.
  976. set i1 [[$link src] id]
  977. set i2 [[$link dst] id]
  978. if [info exists link_($i2:$i1)] {
  979. set pos [lsearch $linkConfigList_ $link_($i2:$i1)]
  980. if {$pos >= 0} {
  981. set a1 [$link_($i2:$i1) get-attribute 
  982. "ORIENTATION"]
  983. set a2 [$link get-attribute "ORIENTATION"]
  984. if {$a1 == "" && $a2 != ""} {
  985. # If this duplex link has not been 
  986. # assigned an orientation, do it.
  987. set linkConfigList_ [lreplace 
  988. $linkConfigList_ $pos $pos]
  989. } else {
  990. return
  991. }
  992. }
  993. }
  994. # Remove $link from list if it's already there
  995. set pos [lsearch $linkConfigList_ $link]
  996. if {$pos >= 0} {
  997. set linkConfigList_ 
  998. [lreplace $linkConfigList_ $pos $pos]
  999. }
  1000. }
  1001. lappend linkConfigList_ $link
  1002. }
  1003. #
  1004. # GT-ITM may occasionally generate duplicate links, so we need this check
  1005. # to ensure duplicated links do not appear in nam trace files.
  1006. #
  1007. Simulator instproc remove-nam-linkconfig {i1 i2} {
  1008. $self instvar linkConfigList_ link_
  1009. if ![info exists linkConfigList_] {
  1010. return
  1011. }
  1012. set pos [lsearch $linkConfigList_ $link_($i1:$i2)]
  1013. if {$pos >= 0} {
  1014. set linkConfigList_ [lreplace $linkConfigList_ $pos $pos]
  1015. return
  1016. }
  1017. set pos [lsearch $linkConfigList_ $link_($i2:$i1)]
  1018. if {$pos >= 0} {
  1019. set linkConfigList_ [lreplace $linkConfigList_ $pos $pos]
  1020. }
  1021. }
  1022. # Armando L. Caro Jr. <acaro@@cis,udel,edu> 10/22/2001
  1023. #
  1024. # we create a simplex link (NOT duplex) from the core to the interface. we can
  1025. # use arbitrary params (bw, delay, etc) since we'll never actually transmit
  1026. # data on these links. they are only used for routing (ie, to determine which 
  1027. # interface a packet should go out from)
  1028. #
  1029. Simulator instproc multihome-add-interface { core if } {
  1030.    $self instvar link_
  1031.    set coreId [$core id]
  1032.    set ifId [$if id]
  1033. # arbitrary values (doesn't matter since link will NEVER be used!)
  1034. set bw 1Mb
  1035. set delay 100ms
  1036. set type DropTail
  1037. if [info exists link_($coreId:$ifId)] {
  1038. $self remove-nam-linkconfig $coreId $ifId
  1039. }
  1040. eval $self simplex-link $core $if $bw $delay $type 
  1041. # Modified by GFR for nix-vector routing
  1042. if { [Simulator set nix-routing] } {
  1043. # Inform nodes of neighbors
  1044. $n1 set-neighbor [$core id]
  1045. $n2 set-neighbor [$if id]
  1046. }
  1047.      $core instvar multihome_interfaces_ num_interfaces_
  1048.      set interface_ {}
  1049.      # interface node
  1050.      lappend interface_ $if
  1051.      # link from interface node to core node
  1052.      lappend interface_ [$link_($coreId:$ifId) set head_]
  1053.      lappend multihome_interfaces_ $interface_
  1054. }
  1055. Simulator instproc duplex-link { n1 n2 bw delay type args } {
  1056. $self instvar link_
  1057. set i1 [$n1 id]
  1058. set i2 [$n2 id]
  1059. if [info exists link_($i1:$i2)] {
  1060. $self remove-nam-linkconfig $i1 $i2
  1061. }
  1062. eval $self simplex-link $n1 $n2 $bw $delay $type $args
  1063. eval $self simplex-link $n2 $n1 $bw $delay $type $args
  1064. # Modified by GFR for nix-vector routing
  1065. if { [Simulator set nix-routing] } {
  1066. # Inform nodes of neighbors
  1067. $n1 set-neighbor [$n2 id]
  1068. $n2 set-neighbor [$n1 id]
  1069. }
  1070. }
  1071. Simulator instproc duplex-intserv-link { n1 n2 bw pd sched signal adc args } {
  1072. eval $self duplex-link $n1 $n2 $bw $pd intserv $sched $signal $adc $args
  1073. }
  1074. Simulator instproc simplex-link-op { n1 n2 op args } {
  1075. $self instvar link_
  1076. eval $link_([$n1 id]:[$n2 id]) $op $args
  1077. }
  1078. Simulator instproc duplex-link-op { n1 n2 op args } {
  1079. $self instvar link_
  1080. eval $link_([$n1 id]:[$n2 id]) $op $args
  1081. eval $link_([$n2 id]:[$n1 id]) $op $args
  1082. }
  1083. Simulator instproc flush-trace {} {
  1084. $self instvar alltrace_
  1085. if [info exists alltrace_] {
  1086. foreach trace $alltrace_ {
  1087. $trace flush
  1088. }
  1089. }
  1090. }
  1091. Simulator instproc namtrace-all file   {
  1092. $self instvar namtraceAllFile_
  1093. if {$file != ""} {
  1094. set namtraceAllFile_ $file
  1095. } else {
  1096. unset namtraceAllFile_
  1097. }
  1098. }
  1099. Simulator instproc energy-color-change {level1 level2} {
  1100. $self instvar level1_ level2_
  1101.   set level1_ $level1
  1102.   set level2_ $level2
  1103. }
  1104. Simulator instproc namtrace-all-wireless {file optx opty} {
  1105.         $self instvar namtraceAllFile_
  1106. # indicate that we need a W event written to the trace
  1107. $self set namNeedsW_ 1
  1108. if { $optx != "" && $opty != "" } {
  1109. $self set namWx_ $optx
  1110. $self set namWy_ $opty
  1111. }
  1112. $self namtrace-all $file
  1113. }
  1114. Simulator instproc nam-end-wireless {stoptime} {
  1115.         $self instvar namtraceAllFile_
  1116.         if {$namtraceAllFile_ != ""} {
  1117. $self puts-nam-config "W -t $stoptime"
  1118.         }
  1119. }
  1120. Simulator instproc namtrace-some file {
  1121. $self instvar namtraceSomeFile_
  1122. set namtraceSomeFile_ $file
  1123. }
  1124. # Support for event-tracing
  1125.         
  1126. Simulator instproc eventtrace-all {{file ""}} {
  1127. $self instvar eventTraceAll_ eventtraceAllFile_ traceAllFile_
  1128. set eventTraceAll_ 1
  1129. if {$file != ""} {
  1130. set eventtraceAllFile_ $file
  1131. } else {
  1132. set eventtraceAllFile_ $traceAllFile_
  1133. }
  1134. }
  1135. Simulator instproc initial_node_pos {nodep size} {
  1136. $self instvar addressType_
  1137. $self instvar energyModel_ 
  1138. if [info exists energyModel_] {  
  1139. set nodeColor "green"
  1140. } else {
  1141. set nodeColor "black"
  1142. }
  1143. if { [info exists addressType_] && $addressType_ == "hierarchical" } {
  1144. # Hierarchical addressing
  1145. $self puts-nam-config "n -t * -a [$nodep set address_] 
  1146. -s [$nodep id] -x [$nodep set X_] -y [$nodep set Y_] -Z [$nodep set Z_] 
  1147. -z $size -v circle -c $nodeColor"
  1148. } else { 
  1149. # Flat addressing
  1150. $self puts-nam-config "n -t * -s [$nodep id] 
  1151. -x [$nodep set X_] -y [$nodep set Y_] -Z [$nodep set Z_] -z $size 
  1152. -v circle -c $nodeColor"
  1153. }
  1154. }
  1155. Simulator instproc trace-all file {
  1156. $self instvar traceAllFile_
  1157. set traceAllFile_ $file
  1158. }
  1159. Simulator instproc get-nam-traceall {} {
  1160. $self instvar namtraceAllFile_
  1161. if [info exists namtraceAllFile_] {
  1162. return $namtraceAllFile_
  1163. } else {
  1164. return ""
  1165. }
  1166. }
  1167. Simulator instproc get-ns-traceall {} {
  1168. $self instvar traceAllFile_
  1169. if [info exists traceAllFile_] {
  1170. return $traceAllFile_
  1171. } else {
  1172. return ""
  1173. }
  1174. }
  1175. # If exists a traceAllFile_, print $str to $traceAllFile_
  1176. Simulator instproc puts-ns-traceall { str } {
  1177. $self instvar traceAllFile_
  1178. if [info exists traceAllFile_] {
  1179. puts $traceAllFile_ $str
  1180. }
  1181. }
  1182. # If exists a traceAllFile_, print $str to $traceAllFile_
  1183. Simulator instproc puts-nam-traceall { str } {
  1184. $self instvar namtraceAllFile_
  1185. if [info exists namtraceAllFile_] {
  1186. puts $namtraceAllFile_ $str
  1187. } elseif [info exists namtraceSomeFile_] {
  1188. puts $namtraceSomeFile_ $str
  1189. }
  1190. }
  1191. # namConfigFile is used for writing color/link/node/queue/annotations. 
  1192. # XXX It cannot co-exist with namtraceAll.
  1193. Simulator instproc namtrace-config { f } {
  1194. $self instvar namConfigFile_
  1195. set namConfigFile_ $f
  1196. }
  1197. Simulator instproc get-nam-config {} {
  1198. $self instvar namConfigFile_
  1199. if [info exists namConfigFile_] {
  1200. return $namConfigFile_
  1201. } else {
  1202. return ""
  1203. }
  1204. }
  1205. # Used only for writing nam configurations to trace file(s). This is different
  1206. # from puts-nam-traceall because we may want to separate configuration 
  1207. # informations and actual tracing information
  1208. Simulator instproc puts-nam-config { str } {
  1209. $self instvar namtraceAllFile_ namConfigFile_
  1210. if [info exists namConfigFile_] {
  1211. puts $namConfigFile_ $str
  1212. } elseif [info exists namtraceAllFile_] {
  1213. puts $namtraceAllFile_ $str
  1214. } elseif [info exists namtraceSomeFile_] {
  1215. puts $namtraceSomeFile_ $str
  1216. }
  1217. }
  1218. Simulator instproc color { id name } {
  1219. $self instvar color_
  1220. set color_($id) $name
  1221. }
  1222. Simulator instproc get-color { id } {
  1223. $self instvar color_
  1224. return $color_($id)
  1225. }
  1226. # you can pass in {} as a null file
  1227. Simulator instproc create-trace { type file src dst {op ""} } {
  1228. $self instvar alltrace_
  1229. set p [new Trace/$type]
  1230. $p tagged [Simulator set TaggedTrace_]
  1231. if [catch {$p set src_ [$src id]}] {
  1232. $p set src_ $src
  1233. }
  1234. if [catch {$p set dst_ [$dst id]}] {
  1235. $p set dst_ $dst
  1236. }
  1237. lappend alltrace_ $p
  1238. if {$file != ""} {
  1239. $p ${op}attach $file
  1240. }
  1241. return $p
  1242. }
  1243. Simulator instproc create-eventtrace {type owner } {
  1244. $self instvar alltrace_ 
  1245. $self instvar eventTraceAll_ eventtraceAllFile_ namtraceAllFile_
  1246. if ![info exists eventTraceAll_] return
  1247. if { $eventTraceAll_ == 1 } {
  1248. set et [new BaseTrace/$type]
  1249. $owner cmd eventtrace $et
  1250. lappend alltrace_ $et
  1251. $et attach $eventtraceAllFile_
  1252. if [info exists namtraceAllFile_] {
  1253. $et namattach $namtraceAllFile_
  1254. }
  1255. }
  1256. }
  1257. Simulator instproc namtrace-queue { n1 n2 {file ""} } {
  1258. $self instvar link_ namtraceAllFile_
  1259. if {$file == ""} {
  1260. if ![info exists namtraceAllFile_] return
  1261. set file $namtraceAllFile_
  1262. }
  1263. $link_([$n1 id]:[$n2 id]) nam-trace $self $file
  1264.     
  1265. # Added later for queue specific tracing events other than enque, 
  1266. # deque and drop as of now nam does not understand special events. 
  1267. # Changes will have to be made to nam for it to understand events 
  1268. # like early drops if they are prefixed differently than "d". - ratul
  1269. set queue [$link_([$n1 id]:[$n2 id]) queue]
  1270. $queue attach-nam-traces $n1 $n2 $file
  1271. }
  1272. Simulator instproc trace-queue { n1 n2 {file ""} } {
  1273. $self instvar link_ traceAllFile_
  1274. if {$file == ""} {
  1275. if ![info exists traceAllFile_] return
  1276. set file $traceAllFile_
  1277. }
  1278. $link_([$n1 id]:[$n2 id]) trace $self $file
  1279. # Added later for queue specific tracing events other than enque, 
  1280. # deque and drop - ratul
  1281. set queue [$link_([$n1 id]:[$n2 id]) queue]
  1282. $queue attach-traces $n1 $n2 $file
  1283. }
  1284. #
  1285. # arrange for queue length of link between nodes n1 and n2
  1286. # to be tracked and return object that can be queried
  1287. # to learn average q size etc.  XXX this API still rough
  1288. #
  1289. Simulator instproc monitor-queue { n1 n2 qtrace { sampleInterval 0.1 } } {
  1290. $self instvar link_
  1291. return [$link_([$n1 id]:[$n2 id]) init-monitor $self $qtrace $sampleInterval]
  1292. }
  1293. Simulator instproc queue-limit { n1 n2 limit } {
  1294. $self instvar link_
  1295. [$link_([$n1 id]:[$n2 id]) queue] set limit_ $limit
  1296. if {[[$link_([$n1 id]:[$n2 id]) queue] info class] == "Queue/XCP"} {
  1297. [$link_([$n1 id]:[$n2 id]) queue] queue-limit $limit
  1298. }
  1299. }
  1300. Simulator instproc drop-trace { n1 n2 trace } {
  1301. $self instvar link_
  1302. [$link_([$n1 id]:[$n2 id]) queue] drop-target $trace
  1303. }
  1304. Simulator instproc cost {n1 n2 c} {
  1305. $self instvar link_
  1306. $link_([$n1 id]:[$n2 id]) cost $c
  1307. }
  1308. # Armando L. Caro Jr. <acaro@@cis,udel,edu> 10/22/2001
  1309. Simulator instproc multihome-attach-agent { core agent } {
  1310.        $agent set-multihome-core [$core entry]
  1311.        foreach interface [$core set multihome_interfaces_] {
  1312.    set ifNode [lindex $interface 0]
  1313. set coreLink [lindex $interface 1]
  1314.        # attach agent to the node for each interface
  1315.        $ifNode attach $agent
  1316.        set addr [$agent set agent_addr_]
  1317.        set port [$agent set agent_port_]
  1318.        set entry [$ifNode entry]
  1319.        # give the interface info to the agent
  1320. $agent add-multihome-interface $addr $port $entry $coreLink
  1321.        $agent instvar multihome_bindings_
  1322.        set binding_ {}
  1323.        lappend binding_ $addr
  1324.        lappend binding_ $port
  1325.        lappend multihome_bindings_ $binding_
  1326.        }
  1327. }
  1328. Simulator instproc attach-agent { node agent } {
  1329. $node attach $agent
  1330. # $agent set nodeid_ [$node id]
  1331.         # Armando L. Caro Jr. <acaro@@cis,udel,edu> 10/22/2001 
  1332. #
  1333. # list of tuples (addr, port)
  1334. # This is NEEDED so that single homed agents can play with multihomed
  1335. # ones!
  1336. # multihoming only for SCTP agents -Padma H.
  1337. if {[lindex [split [$agent info class] "/"] 1] == "SCTP"} {
  1338. $agent instvar multihome_bindings_
  1339. set binding_ {}
  1340. set addr [$agent set agent_addr_]
  1341. set port [$agent set agent_port_]
  1342. lappend binding_ $addr
  1343. lappend binding_ $port
  1344. lappend multihome_bindings_ $binding_
  1345. }
  1346. }
  1347. Simulator instproc attach-tbf-agent { node agent tbf } {
  1348. $node attach $agent
  1349. $agent attach-tbf $tbf
  1350. }
  1351. Simulator instproc detach-agent { node agent } {
  1352. # Debo added this
  1353. $self instvar conn_ nconn_ sflows_ nsflows_ useasim_
  1354. if {$useasim_ == 1} {
  1355. set list "" 
  1356. set s [$node id]
  1357. set d [[$self get-node-by-addr [$agent set dst_addr_]] id]
  1358. foreach x $conn_ {
  1359. set t [split $x ":"] 
  1360. if {[string compare [lindex $t 0]:[lindex $t 1] $s:$d] != 0} {
  1361. lappend list_ $x
  1362. }
  1363. }
  1364. set conn_ list
  1365. set nconn_ [expr $nconn_ -1]
  1366. # ---------------------------------------
  1367. }
  1368. $self instvar nullAgent_
  1369. $node detach $agent $nullAgent_
  1370. }
  1371. #
  1372. #   Helper proc for setting delay on an existing link
  1373. #
  1374. Simulator instproc delay { n1 n2 delay {type simplex} } {
  1375. $self instvar link_
  1376. set sid [$n1 id]
  1377. set did [$n2 id]
  1378. if [info exists link_($sid:$did)] {
  1379. set d [$link_($sid:$did) link]
  1380. $d set delay_ $delay
  1381. }
  1382. if {$type == "duplex"} {
  1383. if [info exists link_($did:$sid)] {
  1384. set d [$link_($did:$sid) link]
  1385. $d set delay_ $delay
  1386. }
  1387. }
  1388. }
  1389. #   Helper proc for setting bandwidth on an existing link
  1390. #
  1391. Simulator instproc bandwidth { n1 n2 bandwidth {type simplex} } {
  1392.         $self instvar link_
  1393.         set sid [$n1 id]
  1394.         set did [$n2 id]
  1395.         if [info exists link_($sid:$did)] {
  1396.                 set d [$link_($sid:$did) link]
  1397.                 $d set bandwidth_ $bandwidth
  1398.         } 
  1399.         if {$type == "duplex"} {
  1400.                 if [info exists link_($did:$sid)] {
  1401.                         set d [$link_($did:$sid) link]
  1402.                         $d set bandwidth_ $bandwidth
  1403.                 }
  1404.         }
  1405. }
  1406. #XXX need to check that agents are attached to nodes already
  1407. Simulator instproc connect {src dst} {
  1408. $self instvar conn_ nconn_ sflows_ nsflows_ useasim_
  1409.         # Armando L. Caro Jr. <acaro@@cis,udel,edu>
  1410. # does the agent type support multihoming??
  1411. # @@@ do we need to worry about $useasim_ below?? (wasn't in 2.1b8)
  1412.      if {[lindex [split [$src info class] "/"] 1] == "SCTP"} {
  1413.      $self multihome-connect $src $dst
  1414.      }
  1415. $self simplex-connect $src $dst
  1416. $self simplex-connect $dst $src
  1417. # Debo
  1418. if {$useasim_ == 1} {
  1419. set sid [$src nodeid]
  1420. set sport [$src set agent_port_]
  1421. set did [$dst nodeid]
  1422. set dport [$dst set agent_port_]
  1423. if {[lindex [split [$src info class] "/"] 1] == "TCP"} {
  1424. lappend conn_ $sid:$did:$sport:$dport
  1425. incr nconn_
  1426. # set $nconn_ [expr $nconn_ + 1]
  1427. # puts "Set a connection with id $nconn_ between $sid and $did"
  1428. }
  1429. }
  1430. return $src
  1431. }
  1432. # Armando L. Caro Jr. <acaro@@cis,udel,edu> 10/12/2001
  1433. Simulator instproc multihome-connect {src dst} {
  1434.         set destNum 0
  1435. foreach binding [$src set multihome_bindings_] {
  1436. incr destNum
  1437.    set addr [lindex $binding 0]
  1438.    set port [lindex $binding 1]
  1439.        $dst add-multihome-destination $addr $port
  1440.      }
  1441. if {$destNum == 0} {
  1442.         # src isn't multihomed, so make sure we do an
  1443. # add-multihome-destination
  1444. $dst add-multihome-destination 
  1445. [$src set agent_addr_] [$src set agent_port_]
  1446. }
  1447.         set destNum 0
  1448. foreach binding [$dst set multihome_bindings_] {
  1449. incr destNum
  1450.    set addr [lindex $binding 0]
  1451.    set port [lindex $binding 1]
  1452.        $src add-multihome-destination $addr $port
  1453.      }
  1454. if {$destNum == 0} {
  1455.         # dst isn't multihomed, so make sure we do an
  1456. # add-multihome-destination
  1457. $src add-multihome-destination 
  1458. [$dst set agent_addr_] [$dst set agent_port_]
  1459. }
  1460. }
  1461. Simulator instproc simplex-connect { src dst } {
  1462. $src set dst_addr_ [$dst set agent_addr_] 
  1463. $src set dst_port_ [$dst set agent_port_]
  1464.         # Polly Huang: to support abstract TCP simulations
  1465.         if {[lindex [split [$src info class] "/"] 1] == "AbsTCP"} {
  1466.     $self at [$self now] "$self rtt $src $dst"
  1467.     $dst set class_ [$src set class_]
  1468.         }
  1469. return $src
  1470. }
  1471. #
  1472. # Here are a bunch of helper methods.
  1473. #
  1474. Simulator proc instance {} {
  1475. set ns [Simulator info instances]
  1476. if { $ns != "" } {
  1477. return $ns
  1478. }
  1479. foreach sim [Simulator info subclass] {
  1480. set ns [$sim info instances]
  1481. if { $ns != "" } {
  1482. return $ns
  1483. }
  1484. }
  1485. error "Cannot find instance of simulator"
  1486. }
  1487. Simulator instproc get-number-of-nodes {} {
  1488. return  [$self array size Node_]
  1489. }
  1490. Simulator instproc get-node-by-id id {
  1491. $self instvar Node_
  1492. return $Node_($id)
  1493. }
  1494. # Given an node's address, Return the node-id
  1495. Simulator instproc get-node-id-by-addr address {
  1496. $self instvar Node_
  1497. set n [Node set nn_]
  1498. for {set q 0} {$q < $n} {incr q} {
  1499. set nq $Node_($q)
  1500. if {[string compare [$nq node-addr] $address] == 0} {
  1501. return $q
  1502. }
  1503. }
  1504. error "get-node-id-by-addr:Cannot find node with given address"
  1505. }
  1506. # Given an node's address, return the node 
  1507. Simulator instproc get-node-by-addr address {
  1508. return [$self get-node-by-id [$self get-node-id-by-addr $address]]
  1509. }
  1510. Simulator instproc all-nodes-list {} {
  1511. $self instvar Node_
  1512. set nodes ""
  1513. foreach n [lsort -dictionary [array names Node_]] {
  1514. lappend nodes $Node_($n)
  1515. }
  1516. return $nodes
  1517. }
  1518. Simulator instproc link { n1 n2 } {
  1519.         $self instvar Node_ link_
  1520.         if { ![catch "$n1 info class Node"] } {
  1521. set n1 [$n1 id]
  1522. }
  1523.         if { ![catch "$n2 info class Node"] } {
  1524. set n2 [$n2 id]
  1525. }
  1526. if [info exists link_($n1:$n2)] {
  1527. return $link_($n1:$n2)
  1528. }
  1529. return ""
  1530. }
  1531. # Creates connection. First creates a source agent of type s_type and binds
  1532. # it to source.  Next creates a destination agent of type d_type and binds
  1533. # it to dest.  Finally creates bindings for the source and destination agents,
  1534. # connects them, and  returns the source agent.
  1535. Simulator instproc create-connection {s_type source d_type dest pktClass} {
  1536. set s_agent [new Agent/$s_type]
  1537. set d_agent [new Agent/$d_type]
  1538. $s_agent set fid_ $pktClass
  1539. $d_agent set fid_ $pktClass
  1540. $self attach-agent $source $s_agent
  1541. $self attach-agent $dest $d_agent
  1542. $self connect $s_agent $d_agent
  1543. return $s_agent
  1544. }
  1545. # Creates a highspeed connection. Similar to create-connection 
  1546. # above except the sink agent requires additional work -- Sylvia
  1547. Simulator instproc create-highspeed-connection {s_type source d_type dest pktClass} {
  1548.         set s_agent [new Agent/$s_type]
  1549.         set d_agent [new Agent/$d_type]
  1550.         $d_agent resize_buffers
  1551.         $s_agent set fid_ $pktClass
  1552.         $d_agent set fid_ $pktClass
  1553.         $self attach-agent $source $s_agent
  1554.         $self attach-agent $dest $d_agent
  1555.         $self connect $s_agent $d_agent
  1556.         return $s_agent
  1557. }
  1558. # Creates connection. First creates a source agent of type s_type and binds
  1559. # it to source.  Next creates a destination agent of type d_type and binds
  1560. # it to dest.  Finally creates bindings for the source and destination agents,
  1561. # connects them, and  returns a list of source agent and destination agent.
  1562. Simulator instproc create-connection-list {s_type source d_type dest pktClass} {
  1563.     set s_agent [new Agent/$s_type]
  1564.     set d_agent [new Agent/$d_type]
  1565.     $s_agent set fid_ $pktClass
  1566.     $d_agent set fid_ $pktClass
  1567.     $self attach-agent $source $s_agent
  1568.     $self attach-agent $dest $d_agent
  1569.     $self connect $s_agent $d_agent
  1570.     return [list $s_agent $d_agent]
  1571. }   
  1572. # Creates connection. First creates a source agent of type s_type and binds
  1573. # it to source.  Next creates a destination agent of type d_type and binds
  1574. # it to dest.  Finally creates bindings for the source and destination agents,
  1575. # connects them, and  returns the source agent. 
  1576. # The destination agent is set to listen, for full-tcp.
  1577. Simulator instproc create-connection-listen {s_type source d_type dest pktClass} {
  1578.     set s_agent [new Agent/$s_type]
  1579.     set d_agent [new Agent/$d_type]
  1580.     $s_agent set fid_ $pktClass
  1581.     $d_agent set fid_ $pktClass
  1582.     $self attach-agent $source $s_agent
  1583.     $self attach-agent $dest $d_agent
  1584.     $self connect $s_agent $d_agent
  1585.     $d_agent listen
  1586.     return $s_agent 
  1587. }   
  1588. # This seems to be an obsolete procedure.
  1589. Simulator instproc create-tcp-connection {s_type source d_type dest pktClass} {
  1590. set s_agent [new Agent/$s_type]
  1591. set d_agent [new Agent/$d_type]
  1592. $s_agent set fid_ $pktClass
  1593. $d_agent set fid_ $pktClass
  1594. $self attach-agent $source $s_agent
  1595. $self attach-agent $dest $d_agent
  1596. return "$s_agent $d_agent"
  1597. }
  1598. #
  1599. # Other classifier methods overload the instproc-likes to track 
  1600. # and return the installed objects.
  1601. #
  1602. Classifier instproc install {slot val} {
  1603. $self set slots_($slot) $val
  1604. $self cmd install $slot $val
  1605. }
  1606. Classifier instproc installNext val {
  1607. set slot [$self cmd installNext $val]
  1608. $self set slots_($slot) $val
  1609. set slot
  1610. }
  1611. Classifier instproc adjacents {} {
  1612. $self array get slots_
  1613. }
  1614. Classifier instproc in-slot? slot {
  1615. $self instvar slots_
  1616. set ret ""
  1617. if {[array size slots_] < $slot} {
  1618. set ret slots_($slot)
  1619. }
  1620. set ret
  1621. }
  1622. # For debugging
  1623. Classifier instproc dump {} {
  1624. $self instvar slots_ offset_ shift_ mask_
  1625. puts "classifier $self"
  1626. puts "t$offset_ offset"
  1627. puts "t$shift_ shift"
  1628. puts "t$mask_ mask"
  1629. puts "t[array size slots_] slots"
  1630. foreach i [lsort -integer [array names slots_]] {
  1631. set iv $slots_($i)
  1632. puts "ttslot $i: $iv ([$iv info class])"
  1633. }
  1634. }
  1635. Classifier instproc no-slot slot {
  1636.         puts stderr "--- Classfier::no-slot{} default handler (tcl/lib/ns-lib.tcl) ---"
  1637.         puts stderr "t$self: no target for slot $slot"
  1638.         puts stderr "t$self type: [$self info class]"
  1639.         puts stderr "content dump:"
  1640.         $self dump
  1641.         puts stderr "---------- Finished standard no-slot{} default handler ----------"
  1642.         # Clear output before we bail out
  1643.         [Simulator instance] flush-trace
  1644.         exit 1
  1645. }
  1646. Classifier/Hash instproc dump args {
  1647. eval $self next $args
  1648. $self instvar default_
  1649. puts "t$default_ default"
  1650. }
  1651. Classifier/Hash instproc init nbuck {
  1652. # We need to make sure that port shift/mask values are there
  1653. # so we set them after they get their default values
  1654. $self next $nbuck
  1655. $self instvar shift_ mask_
  1656. set shift_ [AddrParams NodeShift 1]
  1657. set mask_ [AddrParams NodeMask 1]
  1658. }
  1659. Classifier/Port/Reserve instproc init args {
  1660.         eval $self next
  1661.         $self reserve-port 2
  1662. }
  1663. Simulator instproc makeflowmon { cltype { clslots 29 } } {
  1664. set flowmon [new QueueMonitor/ED/Flowmon]
  1665. set cl [new Classifier/Hash/$cltype $clslots]
  1666. $cl proc unknown-flow { src dst fid }  {
  1667. set fdesc [new QueueMonitor/ED/Flow]
  1668. set dsamp [new Samples]
  1669. $fdesc set-delay-samples $dsamp
  1670. set slot [$self installNext $fdesc] 
  1671. $self set-hash auto $src $dst $fid $slot
  1672. }
  1673. $cl proc no-slot slotnum {
  1674. #
  1675. # note: we can wind up here when a packet passes
  1676. # through either an Out or a Drop Snoop Queue for
  1677. # a queue that the flow doesn't belong to anymore.
  1678. # Since there is no longer hash state in the
  1679. # hash classifier, we get a -1 return value for the
  1680. # hash classifier's classify() function, and there
  1681. # is no node at slot_[-1].  What to do about this?
  1682. # Well, we are talking about flows that have already
  1683. # been moved and so should rightly have their stats
  1684. # zero'd anyhow, so for now just ignore this case..
  1685. # puts "classifier $self, no-slot for slotnum $slotnum"
  1686. }
  1687. $flowmon classifier $cl
  1688. return $flowmon
  1689. }
  1690. # attach a flow monitor to a link
  1691. # 3rd argument dictates whether early drop support is to be used
  1692. Simulator instproc attach-fmon {lnk fm { edrop 0 } } {
  1693. set isnoop [new SnoopQueue/In]
  1694. set osnoop [new SnoopQueue/Out]
  1695. set dsnoop [new SnoopQueue/Drop]
  1696. $lnk attach-monitors $isnoop $osnoop $dsnoop $fm
  1697. if { $edrop != 0 } {
  1698.     set edsnoop [new SnoopQueue/EDrop]
  1699.     $edsnoop set-monitor $fm
  1700.     [$lnk queue] early-drop-target $edsnoop
  1701.     $edsnoop target [$self set nullAgent_]
  1702. }
  1703. [$lnk queue] drop-target $dsnoop
  1704. }
  1705. # Added by Yun Wang
  1706. Simulator instproc maketbtagger { cltype { clslots 29 } } {
  1707.         set tagger [new QueueMonitor/ED/Tagger]
  1708.         set cl [new Classifier/Hash/$cltype $clslots]
  1709.         $cl proc unknown-flow { src dst fid }  {
  1710.                 set fdesc [new QueueMonitor/ED/Flow/TB]
  1711.                 set dsamp [new Samples]
  1712.                 $fdesc set-delay-samples $dsamp
  1713.                 set slot [$self installNext $fdesc]
  1714.                 $self set-hash auto $src $dst $fid $slot
  1715.         }
  1716.         $cl proc set-rate { src dst fid hashbucket rate depth init} {
  1717.                 set fdesc [new QueueMonitor/ED/Flow/TB]
  1718.                 set dsamp [new Samples]
  1719.                 $fdesc set-delay-samples $dsamp
  1720.                 $fdesc set target_rate_ $rate
  1721.                 $fdesc set bucket_depth_ $depth
  1722.                 # Initialize the bucket as full
  1723.                 $fdesc set tbucket_ $init  
  1724.                 set slot [$self installNext $fdesc]
  1725.                 $self set-hash $hashbucket $src $dst $fid $slot
  1726.         }
  1727.         $cl proc no-slot slotnum {
  1728.                 #
  1729.                 # note: we can wind up here when a packet passes
  1730.                 # through either an Out or a Drop Snoop Queue for
  1731.                 # a queue that the flow doesn't belong to anymore.
  1732.                 # Since there is no longer hash state in the
  1733.                 # hash classifier, we get a -1 return value for the
  1734.                 # hash classifier's classify() function, and there
  1735.                 # is no node at slot_[-1].  What to do about this?
  1736.                 # Well, we are talking about flows that have already
  1737.                 # been moved and so should rightly have their stats
  1738.                 # zero'd anyhow, so for now just ignore this case..
  1739.                 # puts "classifier $self, no-slot for slotnum $slotnum"
  1740.         }
  1741.         $tagger classifier $cl
  1742.         return $tagger
  1743. }
  1744. # Added by Yun Wang
  1745. Simulator instproc maketswtagger { cltype { clslots 29 } } {
  1746.         set tagger [new QueueMonitor/ED/Tagger]
  1747.         set cl [new Classifier/Hash/$cltype $clslots]
  1748.         $cl proc unknown-flow { src dst fid hashbucket }  {
  1749.                 set fdesc [new QueueMonitor/ED/Flow/TSW]
  1750.                 set dsamp [new Samples]
  1751.                 $fdesc set-delay-samples $dsamp
  1752.                 set slot [$self installNext $fdesc]
  1753.                 $self set-hash $hashbucket $src $dst $fid $slot
  1754.         }
  1755.         $cl proc no-slot slotnum {
  1756.                 #
  1757.                 # note: we can wind up here when a packet passes
  1758.                 # through either an Out or a Drop Snoop Queue for
  1759.                 # a queue that the flow doesn't belong to anymore.
  1760.                 # Since there is no longer hash state in the
  1761.                 # hash classifier, we get a -1 return value for the
  1762.                 # hash classifier's classify() function, and there
  1763.                 # is no node at slot_[-1].  What to do about this?
  1764.                 # Well, we are talking about flows that have already
  1765.                 # been moved and so should rightly have their stats
  1766.                 # zero'd anyhow, so for now just ignore this case..
  1767.                 # puts "classifier $self, no-slot for slotnum $slotnum"
  1768.         }
  1769.         $tagger classifier $cl
  1770.         return $tagger
  1771. }
  1772. # attach a Tagger to a link
  1773. # Added by Yun Wang
  1774. Simulator instproc attach-tagger {lnk fm} {
  1775.         set isnoop [new SnoopQueue/Tagger]
  1776.         $lnk attach-taggers $isnoop $fm
  1777. }
  1778. # Imported from session.tcl. It is deleted there.
  1779. ### to insert loss module to regular links in detailed Simulator
  1780. Simulator instproc lossmodel {lossobj from to} {
  1781. set link [$self link $from $to]
  1782. $link errormodule $lossobj
  1783. }
  1784. # This function generates losses that can be visualized by nam.
  1785. Simulator instproc link-lossmodel {lossobj from to} {
  1786. set link [$self link $from $to]
  1787. $link insert-linkloss $lossobj
  1788. }
  1789. #### Polly Huang: Simulator class instproc to support abstract tcp simulations
  1790. Simulator instproc rtt { src dst } {
  1791. $self instvar routingTable_ delay_
  1792. set srcid [[$src set node_] id]
  1793. set dstid [[$dst set node_] id]
  1794. set delay 0
  1795. set tmpid $srcid
  1796. while {$tmpid != $dstid} {
  1797. set nextid [$routingTable_ lookup $tmpid $dstid]
  1798. set tmpnode [$self get-node-by-id $tmpid]
  1799. set nextnode [$self get-node-by-id $nextid]
  1800. set tmplink [[$self link $tmpnode $nextnode] link]
  1801. set delay [expr $delay + [expr 2 * [$tmplink set delay_]]]
  1802. set delay [expr $delay + [expr 8320 / [$tmplink set bandwidth_]]]
  1803. set tmpid $nextid
  1804. }
  1805. $src rtt $delay
  1806. return $delay
  1807. }
  1808. Simulator instproc abstract-tcp {} {
  1809. $self instvar TahoeAckfsm_ RenoAckfsm_ TahoeDelAckfsm_ RenoDelAckfsm_ dropper_ 
  1810. $self set TahoeAckfsm_ [new FSM/TahoeAck]
  1811. $self set RenoAckfsm_ [new FSM/RenoAck]
  1812. $self set TahoeDelAckfsm_ [new FSM/TahoeDelAck]
  1813. $self set RenoDelAckfsm_ [new FSM/RenoDelAck]
  1814. $self set nullAgent_ [new DropTargetAgent]
  1815. }
  1816. # Chalermek: For Diffusion, Flooding, and Omnicient Multicast 
  1817. Simulator instproc create-diffusion-rate-agent {node} {
  1818. global opt
  1819. set diff [new Agent/Diffusion/RateGradient]
  1820. $node set diffagent_ $diff
  1821. $node set ragent_ $diff
  1822. $diff on-node $node
  1823. if [info exist opt(enablePos)] {
  1824. if {$opt(enablePos) == "true"} {
  1825. $diff enable-pos
  1826. } else {
  1827. $diff disable-pos
  1828. }
  1829. if [info exist opt(enableNeg)] {
  1830. if {$opt(enableNeg) == "true"} {
  1831. $diff enable-neg
  1832. } else {
  1833. $diff disable-neg
  1834. }
  1835.     
  1836. if [info exist opt(suppression)] {
  1837. if {$opt(suppression) == "true"} {
  1838. $diff enable-suppression
  1839. } else {
  1840. $diff disable-suppression
  1841. }
  1842. if [info exist opt(subTxType)] {
  1843. $diff set-sub-tx-type $opt(subTxType)
  1844. if [info exist opt(orgTxType)] {
  1845. $diff set-org-tx-type $opt(orgTxType)
  1846. if [info exist opt(posType)] {
  1847. $diff set-pos-type $opt(posType)
  1848. if [info exist opt(posNodeType)] {
  1849. $diff set-pos-node-type $opt(posNodeType)
  1850. if [info exist opt(negWinType)] {
  1851. $diff set-neg-win-type $opt(negWinType)
  1852. if [info exist opt(negThrType)] {
  1853. $diff set-neg-thr-type $opt(negThrType)
  1854. if [info exist opt(negMaxType)] {
  1855. $diff set-neg-max-type $opt(negMaxType)
  1856. $self put-in-list $diff
  1857. $self at 0.0 "$diff start"
  1858. return $diff
  1859. }
  1860. Simulator instproc create-diffusion-probability-agent {node} {
  1861. global opt
  1862. set diff [new Agent/Diffusion/ProbGradient]
  1863. $node set diffagent_ $diff
  1864. $node set ragent_ $diff
  1865. $diff on-node $node
  1866. if [info exist opt(enablePos)] {
  1867. if {$opt(enablePos) == "true"} {
  1868. $diff enable-pos
  1869. } else {
  1870. $diff disable-pos
  1871. }
  1872. if [info exist opt(enableNeg)] {
  1873. if {$opt(enableNeg) == "true"} {
  1874. $diff enable-neg
  1875. } else {
  1876. $diff disable-neg
  1877. }
  1878. $self put-in-list $diff
  1879. $self at 0.0 "$diff start"
  1880. return $diff
  1881. }
  1882. # Diffusioncore agent (in diffusion) maps to the wireless routing agent
  1883. # in ns
  1884. Simulator instproc create-core-diffusion-rtg-agent {node} {
  1885. $self instvar stopTime_ diffFilter_
  1886. Node instvar ragent_ dmux_
  1887. set ragent [new Agent/DiffusionRouting [$node id]]
  1888. $node set ragent_ $ragent
  1889. # at stop-time core-diffusion dumps stats data
  1890. # see diffusion.cc for details
  1891. if { [info exists stopTime_] } {
  1892. $ragent stop-time $stopTime_
  1893. }
  1894. if { ![info exists diffFilter_] } {
  1895. puts stderr "Error: No filter defined for diffusion!n"
  1896. exit 1
  1897. }
  1898. $node create-diffusionApp-agent $diffFilter_
  1899. return $ragent
  1900. }
  1901. Simulator instproc create-flooding-agent {node} {
  1902. set flood [new Agent/Flooding]
  1903. $node set ragent_ $flood
  1904. $flood on-node $node
  1905. $self put-in-list $flood
  1906. $self at 0.0 "$flood start"
  1907. return $flood
  1908. }
  1909. Simulator instproc create-omnimcast-agent {node} {
  1910. set omni [new Agent/OmniMcast]
  1911. $node set ragent_ $omni
  1912. $omni on-node $node
  1913. $self put-in-list $omni
  1914. $self at 0.0 "$omni start"
  1915. return $omni
  1916. }
  1917. # XXX These are very simulation-specific methods, why should they belong here?
  1918. Simulator instproc put-in-list {agent} {
  1919. $self instvar lagent
  1920. lappend lagent $agent
  1921. }
  1922. Simulator instproc terminate-all-agents {} {
  1923. $self instvar lagent
  1924. foreach i $lagent {
  1925. $i terminate
  1926. }
  1927. }
  1928. Simulator instproc prepare-to-stop {} {
  1929. $self instvar lagent
  1930. foreach i $lagent {
  1931. $i stop
  1932. }
  1933. }
  1934.