ns-lib.tcl
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:61k
源码类别:

通讯编程

开发平台:

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