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

通讯编程

开发平台:

Visual C++

  1. #
  2. # Copyright (c) 1996 Regents of the University of California.
  3. # All rights reserved.
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. # 1. Redistributions of source code must retain the above copyright
  8. #    notice, this list of conditions and the following disclaimer.
  9. # 2. Redistributions in binary form must reproduce the above copyright
  10. #    notice, this list of conditions and the following disclaimer in the
  11. #    documentation and/or other materials provided with the distribution.
  12. # 3. All advertising materials mentioning features or use of this software
  13. #    must display the following acknowledgement:
  14. #       This product includes software developed by the Daedalus Research
  15. #       Group at the University of California Berkeley.
  16. # 4. Neither the name of the University nor of the Research Group may be
  17. #    used to endorse or promote products derived from this software without
  18. #    specific prior written permission.
  19. # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  20. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. # ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  23. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. # SUCH DAMAGE.
  30. #
  31. # Contributed by the Daedalus Research Group, UC Berkeley 
  32. # (http://daedalus.cs.berkeley.edu)
  33. #
  34. #
  35. # There are three levels to error generation.
  36. # 1. Single State
  37. # rate_:  uniform error rate in pkt or byte
  38. # 2. Two State
  39. # error-free (0) and error (1) states
  40. # each state has a ranvar determining the length each state
  41. # 3. Multi-State:  extending Two-State in OTcl
  42. # each state has a ranvar determining the length each state
  43. # a matrix specifying transition probabilities
  44. #
  45. #    Patched by Jianping Pan (jpan@bbcr.uwaterloo.ca)
  46. #
  47. # Each state is an error model (which could be 1-state or multi-state),
  48. # In addtion, the error model has a matrix of transition probabilities,
  49. # and a start state for the model.  These usually corresond to
  50. # homogeneous Markov chains, but are not restricted to them, because it
  51. # is possible to change the transition probabilities on the fly and
  52. # depending on past history, if you so desire.  Multi-state error models
  53. # reside entirely in Tcl and aren't split between C and Tcl.  One-state
  54. # error models are split objects and ErrorModel is derived from
  55. # Connector.  As an example, a 2-state Markov error model is built-in,
  56. # as ErrorModel/MultiState/TwoStateMarkov Finally, an error *module*
  57. # contains a classifier, a set of dynamically-added ErrorModels, and
  58. # enough plumbing to construct flow-based Errors.
  59. #
  60. ErrorModel instproc init {} {
  61. eval $self next
  62. set ns [Simulator instance]
  63. $ns create-eventtrace Event $self
  64. }
  65. ErrorModel/Trace instproc init {{filename ""}} {
  66. $self instvar file_
  67. $self next
  68. set file_ ""
  69. if {$filename != ""} {
  70. $self open $filename
  71. }
  72. }
  73. ErrorModel/Trace instproc open {filename} {
  74. $self instvar file_
  75. if {! [file readable $filename]} {
  76. puts "$class: cannot open $filename"
  77. return
  78. }
  79. if {$file_ != ""} {
  80. close $file_
  81. }
  82. set file_ [open $filename]
  83. $self read
  84. }
  85. ErrorModel/Trace instproc read {} {
  86. $self instvar file_ good_ loss_
  87. if {$file_ != ""} {
  88. set line [gets $file_]
  89. set good_ [lindex $line 0]
  90. set loss_ [lindex $line 1]
  91. } else {
  92. set good_ 123456789
  93. set loss_ 0
  94. }
  95. }
  96. ErrorModel/TwoState instproc init {rv0 rv1 {unit "pkt"}} {
  97. $self next
  98. $self unit $unit
  99. $self ranvar 0 $rv0
  100. $self ranvar 1 $rv1
  101. }
  102. Class ErrorModel/Uniform -superclass ErrorModel
  103. Class ErrorModel/Expo -superclass ErrorModel/TwoState
  104. Class ErrorModel/Empirical -superclass ErrorModel/TwoState
  105. ErrorModel/Uniform instproc init {rate {unit "pkt"}} {
  106. $self next
  107. $self unit $unit
  108. $self set rate_ $rate
  109. }
  110. ErrorModel/Expo instproc init {avgList {unit "pkt"}} {
  111. set rv0 [new RandomVariable/Exponential]
  112. set rv1 [new RandomVariable/Exponential]
  113. $rv0 set avg_ [lindex $avgList 0]
  114. $rv1 set avg_ [lindex $avgList 1]
  115. $self next $rv0 $rv1 $unit
  116. }
  117. ErrorModel/Empirical instproc init {fileList {unit "pkt"}} {
  118. set rv0 [new RandomVariable/Empirical]
  119. set rv1 [new RandomVariable/Empirical]
  120. $rv0 loadCDF [lindex $fileList 0]
  121. $rv1 loadCDF [lindex $fileList 1]
  122. $self next $rv0 $rv1 $unit
  123. }
  124. ErrorModel/MultiState instproc init {states periods trans transunit sttype nstates start} {
  125. # states_ is an array of states (errmodels),
  126. # periods_ is an array of state duration (sec)
  127. # transmatrix_ is the transition state model matrix,
  128. # sttype is the type of state transitions to use 'time' or 'pkt'
  129. # nstates_ is the number of states
  130. # transunit_ is pkt/byte/time, and curstate_ is the current state
  131. # start is the start state, which curstate_ is initialized to
  132. # error-model is the current error model to use
  133. # curperiod_ is the duration of the current timed-state
  134. $self instvar states_ transmatrix_ transunit_ nstates_ curstate_ eu_ periods_
  135.         $self next
  136. set states_ $states
  137. set periods_ $periods
  138. set transmatrix_ $trans
  139. set transunit_ $transunit
  140. $self sttype $sttype
  141. set nstates_ $nstates
  142. set curstate_ $start
  143. set eu_ $transunit
  144.         $self error-model $start
  145.         # Find current state's duration
  146.         if { [$self sttype] == "time" } {
  147.     for { set i 0 } { $i < $nstates_ } {incr i} {
  148. if { [lindex $states_ $i] == $curstate_ } {
  149.     break
  150. }
  151.     }
  152.     $self set curperiod_ [lindex $periods_ $i]
  153. }
  154. }
  155. ErrorModel/MultiState instproc corrupt { } {
  156. $self instvar states_ transmatrix_ transunit_ curstate_
  157. set cur $curstate_
  158. # XXX
  159.         # check the type of state transitions to use: 'time' or 'pkt'
  160.         # defaults to pkt transitions using transmatrix_
  161.         if { [$self sttype] == "time" } {
  162.     set curstate_ [$self time-transition]
  163.         } else {
  164.     set curstate_ [$self transition]
  165.         }
  166. if { $cur != $curstate_ } {
  167. # If transitioning out, reset current state
  168. $cur reset
  169. $self reset
  170.         $self error-model $curstate_
  171. }
  172. return [$curstate_ next]
  173. }
  174. # XXX eventually want to put in expected times of staying in each state 
  175. # before transition here.  Punt on this for now.
  176. #ErrorModel instproc insert-error { parent } {
  177. # return [$self corrupt $parent]
  178. #}
  179. # Transition based on time spent in the current state
  180. ErrorModel/MultiState instproc time-transition { } {
  181. $self instvar states_ transmatrix_ transunit_ curstate_ nstates_ periods_
  182.     if {[$self set texpired_] != 1} {
  183. return $curstate_
  184.     }
  185. for { set i 0 } { $i < $nstates_ } {incr i} {
  186. if { [lindex $states_ $i] == $curstate_ } {
  187. break
  188. }
  189. }
  190. # get the right transition list
  191. set trans [lindex $transmatrix_ $i]
  192. set p [uniform 0 1]
  193. set total 0
  194. for { set i 0 } { $i < $nstates_ } {incr i } {
  195. set total [expr $total + [lindex $trans $i]]
  196. if { $p <= $total } {
  197.     $self set curperiod_ [lindex $periods_ $i]
  198.     return [lindex $states_ $i]
  199. }
  200. }
  201. puts "Misconfigured state transition: prob $p total $total $nstates_"
  202. return $curstate_
  203. }
  204. # Decide whom to transition to
  205. ErrorModel/MultiState instproc transition { } {
  206. $self instvar states_ transmatrix_ transunit_ curstate_ nstates_
  207. for { set i 0 } { $i < $nstates_ } {incr i} {
  208. if { [lindex $states_ $i] == $curstate_ } {
  209. break
  210. }
  211. }
  212. # get the right transition list
  213. set trans [lindex $transmatrix_ $i]
  214. set p [uniform 0 1]
  215. set total 0
  216. for { set i 0 } { $i < $nstates_ } {incr i } {
  217. set total [expr $total + [lindex $trans $i]]
  218. if { $p <= $total } {
  219. return [lindex $states_ $i]
  220. }
  221. }
  222. puts "Misconfigured state transition: prob $p total $total $nstates_"
  223. return $curstate_
  224. }
  225. Class ErrorModel/TwoStateMarkov -superclass ErrorModel/Expo
  226. ErrorModel/TwoStateMarkov instproc init {rate {unit "time"}} {
  227. $self next $rate $unit
  228. }
  229. ErrorModel/ComplexTwoStateMarkov instproc init {avgList {unit "time"} {rng ""}} {
  230. $self next
  231. $self unit $unit
  232. set rv0 [new RandomVariable/Exponential]
  233. set rv1 [new RandomVariable/Exponential]
  234. set rv2 [new RandomVariable/Exponential]
  235. set rv3 [new RandomVariable/Exponential]
  236. if {$rng != ""} {
  237. $rv0 use-rng $rng
  238. $rv1 use-rng $rng
  239. $rv2 use-rng $rng
  240. $rv3 use-rng $rng
  241. }
  242. $rv0 set avg_ [lindex $avgList 0]
  243. $rv1 set avg_ [lindex $avgList 1]
  244. $rv2 set avg_ [lindex $avgList 2]
  245. $rv3 set avg_ [lindex $avgList 3]
  246. $self ranvar 0 0 $rv0 
  247. $self ranvar 0 1 $rv1 
  248. $self ranvar 1 0 $rv2 
  249. $self ranvar 1 1 $rv3
  250. }
  251. #
  252. # the following is a "ErrorModule";
  253. # it contains a classifier, a set of dynamically-added ErrorModels, and enough
  254. # plumbing to construct flow-based Errors.
  255. #
  256. # It's derived from a connector
  257. #
  258. ErrorModule instproc init { cltype { clslots 29 } } {
  259. $self next
  260. set nullagent [[Simulator instance] set nullAgent_]
  261. set classifier [new Classifier/Hash/$cltype $clslots]
  262. $self cmd classifier $classifier
  263. $self cmd target [new Connector]
  264. $self cmd drop-target [new Connector]
  265. $classifier proc unknown-flow { src dst fid } {
  266. puts "warning: classifier $self unknown flow s:$src, d:$dst, fid:$fid"
  267. }
  268. }
  269. #
  270. # set a default behavior within the error module.
  271. # Called as follows
  272. # $errormodule default $em
  273. # where $em is the name of an error model to pass default traffic to.
  274. # note that if $em is "pass", then default just goes through untouched
  275. #
  276. ErrorModule instproc default errmodel {
  277. set cl [$self cmd classifier]
  278. if { $errmodel == "pass" } {
  279. set target [$self cmd target]
  280. set pslot [$cl installNext $target]
  281. $cl set default_ $pslot
  282. return
  283. }
  284. set emslot [$cl findslot $errmodel]
  285. if { $emslot == -1 } {
  286. puts "ErrorModule: couldn't find classifier entry for error model $errmodel"
  287. return
  288. }
  289. $cl set default_ $emslot
  290. }
  291. ErrorModule instproc insert errmodel {
  292. $self instvar models_
  293. $errmodel target [$self cmd target]
  294. $errmodel drop-target [$self cmd drop-target]
  295. if { [info exists models_] } {
  296. set models_ [concat $models_ $errmodel]
  297. } else {
  298. set models_ $errmodel
  299. }
  300. }
  301. ErrorModule instproc errormodels {} {
  302. $self instvar models_
  303. return $models_
  304. }
  305. ErrorModule instproc bind args {
  306.         # this is to perform '$fem bind $errmod id'
  307.         # and '$fem bind $errmod idstart idend'
  308.     
  309.         set nargs [llength $args]
  310.         set errmod [lindex $args 0]
  311.         set a [lindex $args 1]
  312.         if { $nargs == 3 } {
  313.                 set b [lindex $args 2]
  314.         } else {
  315.                 set b $a
  316.         }       
  317.         # bind the errmodel to the flow id's [a..b]
  318. set cls [$self cmd classifier]
  319.         while { $a <= $b } {
  320.                 # first install the class to get its slot number
  321.                 # use the flow id as the hash bucket
  322.                 set slot [$cls installNext $errmod] 
  323.                 $cls set-hash auto 0 0 $a $slot
  324.                 incr a  
  325.         }
  326. }
  327. ErrorModule instproc target args {
  328. if { $args == "" } {
  329. return [[$self cmd target] target]
  330. }
  331. set obj [lindex $args 0]
  332. [$self cmd target] target $obj
  333. [$self cmd target] drop-target $obj
  334. }
  335. ErrorModule instproc drop-target args {
  336. if { $args == "" } {
  337. return [[$self cmd drop-target] target]
  338. }
  339. set obj [lindex $args 0]
  340. [$self cmd drop-target] drop-target $obj
  341. [$self cmd drop-target] target $obj
  342. }